net/bnx2x: update link/PHY management
[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                 /* Should not happen. This function called upon interrupt
5207                  * triggered by GPIO ( since EPIO can only generate interrupts
5208                  * to MCP).
5209                  * So if this function was called and none of the GPIOs was set,
5210                  * it means the shit hit the fan.
5211                  */
5212                 if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
5213                     (cfg_pin > PIN_CFG_GPIO3_P1)) {
5214                         ELINK_DEBUG_P1(sc,
5215                            "No cfg pin %x for module detect indication",
5216                            cfg_pin);
5217                         return ELINK_STATUS_ERROR;
5218                 }
5219
5220                 *gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
5221                 *gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
5222         } else {
5223                 *gpio_num = MISC_REGISTERS_GPIO_3;
5224                 *gpio_port = port;
5225         }
5226
5227         return ELINK_STATUS_OK;
5228 }
5229
5230 static int elink_is_sfp_module_plugged(__rte_unused struct elink_phy *phy,
5231                                        struct elink_params *params)
5232 {
5233         struct bnx2x_softc *sc = params->sc;
5234         uint8_t gpio_num, gpio_port;
5235         uint32_t gpio_val;
5236         if (elink_get_mod_abs_int_cfg(sc, params->chip_id,
5237                                       params->shmem_base, params->port,
5238                                       &gpio_num, &gpio_port) != ELINK_STATUS_OK)
5239                 return 0;
5240         gpio_val = elink_cb_gpio_read(sc, gpio_num, gpio_port);
5241
5242         /* Call the handling function in case module is detected */
5243         if (gpio_val == 0)
5244                 return 1;
5245         else
5246                 return 0;
5247 }
5248 static int elink_warpcore_get_sigdet(struct elink_phy *phy,
5249                                      struct elink_params *params)
5250 {
5251         uint16_t gp2_status_reg0, lane;
5252         struct bnx2x_softc *sc = params->sc;
5253
5254         lane = elink_get_warpcore_lane(phy, params);
5255
5256         elink_cl45_read(sc, phy, MDIO_WC_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_0,
5257                                  &gp2_status_reg0);
5258
5259         return (gp2_status_reg0 >> (8 + lane)) & 0x1;
5260 }
5261
5262 static void elink_warpcore_config_runtime(struct elink_phy *phy,
5263                                           struct elink_params *params,
5264                                           struct elink_vars *vars)
5265 {
5266         struct bnx2x_softc *sc = params->sc;
5267         uint32_t serdes_net_if;
5268         uint16_t gp_status1 = 0, lnkup = 0, lnkup_kr = 0;
5269
5270         vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1;
5271
5272         if (!vars->turn_to_run_wc_rt)
5273                 return;
5274
5275         if (vars->rx_tx_asic_rst) {
5276                 uint16_t lane = elink_get_warpcore_lane(phy, params);
5277                 serdes_net_if = (REG_RD(sc, params->shmem_base +
5278                                 offsetof(struct shmem_region, dev_info.
5279                                 port_hw_config[params->port].default_cfg)) &
5280                                 PORT_HW_CFG_NET_SERDES_IF_MASK);
5281
5282                 switch (serdes_net_if) {
5283                 case PORT_HW_CFG_NET_SERDES_IF_KR:
5284                         /* Do we get link yet? */
5285                         elink_cl45_read(sc, phy, MDIO_WC_DEVAD, 0x81d1,
5286                                         &gp_status1);
5287                         lnkup = (gp_status1 >> (8 + lane)) & 0x1;/* 1G */
5288                                 /*10G KR*/
5289                         lnkup_kr = (gp_status1 >> (12 + lane)) & 0x1;
5290
5291                         if (lnkup_kr || lnkup) {
5292                                 vars->rx_tx_asic_rst = 0;
5293                         } else {
5294                                 /* Reset the lane to see if link comes up.*/
5295                                 elink_warpcore_reset_lane(sc, phy, 1);
5296                                 elink_warpcore_reset_lane(sc, phy, 0);
5297
5298                                 /* Restart Autoneg */
5299                                 elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
5300                                         MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
5301
5302                                 vars->rx_tx_asic_rst--;
5303                                 ELINK_DEBUG_P1(sc, "0x%x retry left",
5304                                 vars->rx_tx_asic_rst);
5305                         }
5306                         break;
5307
5308                 default:
5309                         break;
5310                 }
5311
5312         } /*params->rx_tx_asic_rst*/
5313 }
5314
5315 static void elink_warpcore_config_sfi(struct elink_phy *phy,
5316                                       struct elink_params *params)
5317 {
5318         uint16_t lane = elink_get_warpcore_lane(phy, params);
5319         struct bnx2x_softc *sc = params->sc;
5320         elink_warpcore_clear_regs(phy, params, lane);
5321         if ((params->req_line_speed[ELINK_LINK_CONFIG_IDX(ELINK_INT_PHY)] ==
5322              ELINK_SPEED_10000) &&
5323             (phy->media_type != ELINK_ETH_PHY_SFP_1G_FIBER)) {
5324                 ELINK_DEBUG_P0(sc, "Setting 10G SFI");
5325                 elink_warpcore_set_10G_XFI(phy, params, 0);
5326         } else {
5327                 ELINK_DEBUG_P0(sc, "Setting 1G Fiber");
5328                 elink_warpcore_set_sgmii_speed(phy, params, 1, 0);
5329         }
5330 }
5331
5332 static void elink_sfp_e3_set_transmitter(struct elink_params *params,
5333                                          struct elink_phy *phy,
5334                                          uint8_t tx_en)
5335 {
5336         struct bnx2x_softc *sc = params->sc;
5337         uint32_t cfg_pin;
5338         uint8_t port = params->port;
5339
5340         cfg_pin = REG_RD(sc, params->shmem_base +
5341                          offsetof(struct shmem_region,
5342                                   dev_info.port_hw_config[port].e3_sfp_ctrl)) &
5343                 PORT_HW_CFG_E3_TX_LASER_MASK;
5344         /* Set the !tx_en since this pin is DISABLE_TX_LASER */
5345         ELINK_DEBUG_P1(sc, "Setting WC TX to %d", tx_en);
5346
5347         /* For 20G, the expected pin to be used is 3 pins after the current */
5348         elink_set_cfg_pin(sc, cfg_pin, tx_en ^ 1);
5349         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
5350                 elink_set_cfg_pin(sc, cfg_pin + 3, tx_en ^ 1);
5351 }
5352
5353 static uint8_t elink_warpcore_config_init(struct elink_phy *phy,
5354                                        struct elink_params *params,
5355                                        struct elink_vars *vars)
5356 {
5357         struct bnx2x_softc *sc = params->sc;
5358         uint32_t serdes_net_if;
5359         uint8_t fiber_mode;
5360         uint16_t lane = elink_get_warpcore_lane(phy, params);
5361         serdes_net_if = (REG_RD(sc, params->shmem_base +
5362                          offsetof(struct shmem_region, dev_info.
5363                                   port_hw_config[params->port].default_cfg)) &
5364                          PORT_HW_CFG_NET_SERDES_IF_MASK);
5365         ELINK_DEBUG_P2(sc, "Begin Warpcore init, link_speed %d, "
5366                            "serdes_net_if = 0x%x",
5367                        vars->line_speed, serdes_net_if);
5368         elink_set_aer_mmd(params, phy);
5369         elink_warpcore_reset_lane(sc, phy, 1);
5370         vars->phy_flags |= PHY_XGXS_FLAG;
5371         if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
5372             (phy->req_line_speed &&
5373              ((phy->req_line_speed == ELINK_SPEED_100) ||
5374               (phy->req_line_speed == ELINK_SPEED_10)))) {
5375                 vars->phy_flags |= PHY_SGMII_FLAG;
5376                 ELINK_DEBUG_P0(sc, "Setting SGMII mode");
5377                 elink_warpcore_clear_regs(phy, params, lane);
5378                 elink_warpcore_set_sgmii_speed(phy, params, 0, 1);
5379         } else {
5380                 switch (serdes_net_if) {
5381                 case PORT_HW_CFG_NET_SERDES_IF_KR:
5382                         /* Enable KR Auto Neg */
5383                         if (params->loopback_mode != ELINK_LOOPBACK_EXT)
5384                                 elink_warpcore_enable_AN_KR(phy, params, vars);
5385                         else {
5386                                 ELINK_DEBUG_P0(sc, "Setting KR 10G-Force");
5387                                 elink_warpcore_set_10G_KR(phy, params, vars);
5388                         }
5389                         break;
5390
5391                 case PORT_HW_CFG_NET_SERDES_IF_XFI:
5392                         elink_warpcore_clear_regs(phy, params, lane);
5393                         if (vars->line_speed == ELINK_SPEED_10000) {
5394                                 ELINK_DEBUG_P0(sc, "Setting 10G XFI");
5395                                 elink_warpcore_set_10G_XFI(phy, params, 1);
5396                         } else {
5397                                 if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
5398                                         ELINK_DEBUG_P0(sc, "1G Fiber");
5399                                         fiber_mode = 1;
5400                                 } else {
5401                                         ELINK_DEBUG_P0(sc, "10/100/1G SGMII");
5402                                         fiber_mode = 0;
5403                                 }
5404                                 elink_warpcore_set_sgmii_speed(phy,
5405                                                                 params,
5406                                                                 fiber_mode,
5407                                                                 0);
5408                         }
5409
5410                         break;
5411
5412                 case PORT_HW_CFG_NET_SERDES_IF_SFI:
5413                         /* Issue Module detection if module is plugged, or
5414                          * enabled transmitter to avoid current leakage in case
5415                          * no module is connected
5416                          */
5417                         if ((params->loopback_mode == ELINK_LOOPBACK_NONE) ||
5418                             (params->loopback_mode == ELINK_LOOPBACK_EXT)) {
5419                                 if (elink_is_sfp_module_plugged(phy, params))
5420                                         elink_sfp_module_detection(phy, params);
5421                                 else
5422                                         elink_sfp_e3_set_transmitter(params,
5423                                                                      phy, 1);
5424                         }
5425
5426                         elink_warpcore_config_sfi(phy, params);
5427                         break;
5428
5429                 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
5430                         if (vars->line_speed != ELINK_SPEED_20000) {
5431                                 ELINK_DEBUG_P0(sc, "Speed not supported yet");
5432                                 return 0;
5433                         }
5434                         ELINK_DEBUG_P0(sc, "Setting 20G DXGXS");
5435                         elink_warpcore_set_20G_DXGXS(sc, phy, lane);
5436                         /* Issue Module detection */
5437
5438                         elink_sfp_module_detection(phy, params);
5439                         break;
5440                 case PORT_HW_CFG_NET_SERDES_IF_KR2:
5441                         if (!params->loopback_mode) {
5442                                 elink_warpcore_enable_AN_KR(phy, params, vars);
5443                         } else {
5444                                 ELINK_DEBUG_P0(sc, "Setting KR 20G-Force");
5445                                 elink_warpcore_set_20G_force_KR2(phy, params);
5446                         }
5447                         break;
5448                 default:
5449                         ELINK_DEBUG_P1(sc,
5450                            "Unsupported Serdes Net Interface 0x%x",
5451                            serdes_net_if);
5452                         return 0;
5453                 }
5454         }
5455
5456         /* Take lane out of reset after configuration is finished */
5457         elink_warpcore_reset_lane(sc, phy, 0);
5458         ELINK_DEBUG_P0(sc, "Exit config init");
5459
5460         return 0;
5461 }
5462
5463 static void elink_warpcore_link_reset(struct elink_phy *phy,
5464                                       struct elink_params *params)
5465 {
5466         struct bnx2x_softc *sc = params->sc;
5467         uint16_t val16, lane;
5468         elink_sfp_e3_set_transmitter(params, phy, 0);
5469         elink_set_mdio_emac_per_phy(sc, params);
5470         elink_set_aer_mmd(params, phy);
5471         /* Global register */
5472         elink_warpcore_reset_lane(sc, phy, 1);
5473
5474         /* Clear loopback settings (if any) */
5475         /* 10G & 20G */
5476         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5477                                   MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0xBFFF);
5478
5479         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5480                                   MDIO_WC_REG_IEEE0BLK_MIICNTL, 0xfffe);
5481
5482         /* Update those 1-copy registers */
5483         CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
5484                           MDIO_AER_BLOCK_AER_REG, 0);
5485         /* Enable 1G MDIO (1-copy) */
5486         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5487                                   MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
5488                                   ~0x10);
5489
5490         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5491                                   MDIO_WC_REG_XGXSBLK1_LANECTRL2, 0xff00);
5492         lane = elink_get_warpcore_lane(phy, params);
5493         /* Disable CL36 PCS Tx */
5494         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5495                         MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
5496         val16 |= (0x11 << lane);
5497         if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
5498                 val16 |= (0x22 << lane);
5499         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5500                          MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
5501
5502         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5503                         MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
5504         val16 &= ~(0x0303 << (lane << 1));
5505         val16 |= (0x0101 << (lane << 1));
5506         if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE) {
5507                 val16 &= ~(0x0c0c << (lane << 1));
5508                 val16 |= (0x0404 << (lane << 1));
5509         }
5510
5511         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5512                          MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
5513         /* Restore AER */
5514         elink_set_aer_mmd(params, phy);
5515
5516 }
5517
5518 static void elink_set_warpcore_loopback(struct elink_phy *phy,
5519                                         struct elink_params *params)
5520 {
5521         struct bnx2x_softc *sc = params->sc;
5522         uint16_t val16;
5523         uint32_t lane;
5524         ELINK_DEBUG_P2(sc, "Setting Warpcore loopback type %x, speed %d",
5525                        params->loopback_mode, phy->req_line_speed);
5526
5527         if (phy->req_line_speed < ELINK_SPEED_10000 ||
5528             phy->supported & ELINK_SUPPORTED_20000baseKR2_Full) {
5529                 /* 10/100/1000/20G-KR2 */
5530
5531                 /* Update those 1-copy registers */
5532                 CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
5533                                   MDIO_AER_BLOCK_AER_REG, 0);
5534                 /* Enable 1G MDIO (1-copy) */
5535                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5536                                          MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
5537                                          0x10);
5538                 /* Set 1G loopback based on lane (1-copy) */
5539                 lane = elink_get_warpcore_lane(phy, params);
5540                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5541                                 MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
5542                 val16 |= (1 << lane);
5543                 if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
5544                         val16 |= (2 << lane);
5545                 elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5546                                  MDIO_WC_REG_XGXSBLK1_LANECTRL2,
5547                                  val16);
5548
5549                 /* Switch back to 4-copy registers */
5550                 elink_set_aer_mmd(params, phy);
5551         } else {
5552                 /* 10G / 20G-DXGXS */
5553                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5554                                          MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
5555                                          0x4000);
5556                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5557                                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1);
5558         }
5559 }
5560
5561
5562
5563 static void elink_sync_link(struct elink_params *params,
5564                              struct elink_vars *vars)
5565 {
5566         struct bnx2x_softc *sc = params->sc;
5567         uint8_t link_10g_plus;
5568         if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
5569                 vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
5570         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
5571         if (vars->link_up) {
5572                 ELINK_DEBUG_P0(sc, "phy link up");
5573                 ELINK_DEBUG_P1(sc, "link status = %x", vars->link_status);
5574
5575                 vars->phy_link_up = 1;
5576                 vars->duplex = DUPLEX_FULL;
5577                 switch (vars->link_status &
5578                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
5579                 case ELINK_LINK_10THD:
5580                         vars->duplex = DUPLEX_HALF;
5581                         /* Fall thru */
5582                 case ELINK_LINK_10TFD:
5583                         vars->line_speed = ELINK_SPEED_10;
5584                         break;
5585
5586                 case ELINK_LINK_100TXHD:
5587                         vars->duplex = DUPLEX_HALF;
5588                         /* Fall thru */
5589                 case ELINK_LINK_100T4:
5590                 case ELINK_LINK_100TXFD:
5591                         vars->line_speed = ELINK_SPEED_100;
5592                         break;
5593
5594                 case ELINK_LINK_1000THD:
5595                         vars->duplex = DUPLEX_HALF;
5596                         /* Fall thru */
5597                 case ELINK_LINK_1000TFD:
5598                         vars->line_speed = ELINK_SPEED_1000;
5599                         break;
5600
5601                 case ELINK_LINK_2500THD:
5602                         vars->duplex = DUPLEX_HALF;
5603                         /* Fall thru */
5604                 case ELINK_LINK_2500TFD:
5605                         vars->line_speed = ELINK_SPEED_2500;
5606                         break;
5607
5608                 case ELINK_LINK_10GTFD:
5609                         vars->line_speed = ELINK_SPEED_10000;
5610                         break;
5611                 case ELINK_LINK_20GTFD:
5612                         vars->line_speed = ELINK_SPEED_20000;
5613                         break;
5614                 default:
5615                         break;
5616                 }
5617                 vars->flow_ctrl = 0;
5618                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
5619                         vars->flow_ctrl |= ELINK_FLOW_CTRL_TX;
5620
5621                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
5622                         vars->flow_ctrl |= ELINK_FLOW_CTRL_RX;
5623
5624                 if (!vars->flow_ctrl)
5625                         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
5626
5627                 if (vars->line_speed &&
5628                     ((vars->line_speed == ELINK_SPEED_10) ||
5629                      (vars->line_speed == ELINK_SPEED_100))) {
5630                         vars->phy_flags |= PHY_SGMII_FLAG;
5631                 } else {
5632                         vars->phy_flags &= ~PHY_SGMII_FLAG;
5633                 }
5634                 if (vars->line_speed &&
5635                     USES_WARPCORE(sc) &&
5636                     (vars->line_speed == ELINK_SPEED_1000))
5637                         vars->phy_flags |= PHY_SGMII_FLAG;
5638                 /* Anything 10 and over uses the bmac */
5639                 link_10g_plus = (vars->line_speed >= ELINK_SPEED_10000);
5640
5641                 if (link_10g_plus) {
5642                         if (USES_WARPCORE(sc))
5643                                 vars->mac_type = ELINK_MAC_TYPE_XMAC;
5644                         else
5645                                 vars->mac_type = ELINK_MAC_TYPE_BMAC;
5646                 } else {
5647                         if (USES_WARPCORE(sc))
5648                                 vars->mac_type = ELINK_MAC_TYPE_UMAC;
5649                         else
5650                                 vars->mac_type = ELINK_MAC_TYPE_EMAC;
5651                 }
5652         } else { /* Link down */
5653                 ELINK_DEBUG_P0(sc, "phy link down");
5654
5655                 vars->phy_link_up = 0;
5656
5657                 vars->line_speed = 0;
5658                 vars->duplex = DUPLEX_FULL;
5659                 vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
5660
5661                 /* Indicate no mac active */
5662                 vars->mac_type = ELINK_MAC_TYPE_NONE;
5663                 if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
5664                         vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
5665                 if (vars->link_status & LINK_STATUS_SFP_TX_FAULT)
5666                         vars->phy_flags |= PHY_SFP_TX_FAULT_FLAG;
5667         }
5668 }
5669
5670 void elink_link_status_update(struct elink_params *params,
5671                               struct elink_vars *vars)
5672 {
5673         struct bnx2x_softc *sc = params->sc;
5674         uint8_t port = params->port;
5675         uint32_t sync_offset, media_types;
5676         /* Update PHY configuration */
5677         set_phy_vars(params, vars);
5678
5679         vars->link_status = REG_RD(sc, params->shmem_base +
5680                                    offsetof(struct shmem_region,
5681                                             port_mb[port].link_status));
5682
5683         /* Force link UP in non LOOPBACK_EXT loopback mode(s) */
5684         if (params->loopback_mode != ELINK_LOOPBACK_NONE &&
5685             params->loopback_mode != ELINK_LOOPBACK_EXT)
5686                 vars->link_status |= LINK_STATUS_LINK_UP;
5687
5688         if (elink_eee_has_cap(params))
5689                 vars->eee_status = REG_RD(sc, params->shmem2_base +
5690                                           offsetof(struct shmem2_region,
5691                                                    eee_status[params->port]));
5692
5693         vars->phy_flags = PHY_XGXS_FLAG;
5694         elink_sync_link(params, vars);
5695         /* Sync media type */
5696         sync_offset = params->shmem_base +
5697                         offsetof(struct shmem_region,
5698                                  dev_info.port_hw_config[port].media_type);
5699         media_types = REG_RD(sc, sync_offset);
5700
5701         params->phy[ELINK_INT_PHY].media_type =
5702                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
5703                 PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
5704         params->phy[ELINK_EXT_PHY1].media_type =
5705                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
5706                 PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
5707         params->phy[ELINK_EXT_PHY2].media_type =
5708                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
5709                 PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
5710         ELINK_DEBUG_P1(sc, "media_types = 0x%x", media_types);
5711
5712         /* Sync AEU offset */
5713         sync_offset = params->shmem_base +
5714                         offsetof(struct shmem_region,
5715                                  dev_info.port_hw_config[port].aeu_int_mask);
5716
5717         vars->aeu_int_mask = REG_RD(sc, sync_offset);
5718
5719         /* Sync PFC status */
5720         if (vars->link_status & LINK_STATUS_PFC_ENABLED)
5721                 params->feature_config_flags |=
5722                                         ELINK_FEATURE_CONFIG_PFC_ENABLED;
5723         else
5724                 params->feature_config_flags &=
5725                                         ~ELINK_FEATURE_CONFIG_PFC_ENABLED;
5726
5727         if (SHMEM2_HAS(sc, link_attr_sync))
5728                 params->link_attr_sync = SHMEM2_RD(sc,
5729                                                  link_attr_sync[params->port]);
5730
5731         ELINK_DEBUG_P3(sc, "link_status 0x%x  phy_link_up %x int_mask 0x%x",
5732                  vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
5733         ELINK_DEBUG_P3(sc, "line_speed %x  duplex %x  flow_ctrl 0x%x",
5734                  vars->line_speed, vars->duplex, vars->flow_ctrl);
5735 }
5736
5737 static void elink_set_master_ln(struct elink_params *params,
5738                                 struct elink_phy *phy)
5739 {
5740         struct bnx2x_softc *sc = params->sc;
5741         uint16_t new_master_ln, ser_lane;
5742         ser_lane = ((params->lane_config &
5743                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
5744                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
5745
5746         /* Set the master_ln for AN */
5747         CL22_RD_OVER_CL45(sc, phy,
5748                           MDIO_REG_BANK_XGXS_BLOCK2,
5749                           MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
5750                           &new_master_ln);
5751
5752         CL22_WR_OVER_CL45(sc, phy,
5753                           MDIO_REG_BANK_XGXS_BLOCK2,
5754                           MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
5755                           (new_master_ln | ser_lane));
5756 }
5757
5758 static elink_status_t elink_reset_unicore(struct elink_params *params,
5759                                struct elink_phy *phy,
5760                                uint8_t set_serdes)
5761 {
5762         struct bnx2x_softc *sc = params->sc;
5763         uint16_t mii_control;
5764         uint16_t i;
5765         CL22_RD_OVER_CL45(sc, phy,
5766                           MDIO_REG_BANK_COMBO_IEEE0,
5767                           MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
5768
5769         /* Reset the unicore */
5770         CL22_WR_OVER_CL45(sc, phy,
5771                           MDIO_REG_BANK_COMBO_IEEE0,
5772                           MDIO_COMBO_IEEE0_MII_CONTROL,
5773                           (mii_control |
5774                            MDIO_COMBO_IEEO_MII_CONTROL_RESET));
5775         if (set_serdes)
5776                 elink_set_serdes_access(sc, params->port);
5777
5778         /* Wait for the reset to self clear */
5779         for (i = 0; i < ELINK_MDIO_ACCESS_TIMEOUT; i++) {
5780                 DELAY(5);
5781
5782                 /* The reset erased the previous bank value */
5783                 CL22_RD_OVER_CL45(sc, phy,
5784                                   MDIO_REG_BANK_COMBO_IEEE0,
5785                                   MDIO_COMBO_IEEE0_MII_CONTROL,
5786                                   &mii_control);
5787
5788                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
5789                         DELAY(5);
5790                         return ELINK_STATUS_OK;
5791                 }
5792         }
5793
5794         elink_cb_event_log(sc, ELINK_LOG_ID_PHY_UNINITIALIZED, params->port);
5795                              /* "Warning: PHY was not initialized,"
5796                               * " Port %d",
5797                               */
5798
5799         ELINK_DEBUG_P0(sc, "BUG! XGXS is still in reset!");
5800         return ELINK_STATUS_ERROR;
5801
5802 }
5803
5804 static void elink_set_swap_lanes(struct elink_params *params,
5805                                  struct elink_phy *phy)
5806 {
5807         struct bnx2x_softc *sc = params->sc;
5808         /* Each two bits represents a lane number:
5809          * No swap is 0123 => 0x1b no need to enable the swap
5810          */
5811         uint16_t rx_lane_swap, tx_lane_swap;
5812
5813         rx_lane_swap = ((params->lane_config &
5814                          PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
5815                         PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
5816         tx_lane_swap = ((params->lane_config &
5817                          PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
5818                         PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
5819
5820         if (rx_lane_swap != 0x1b) {
5821                 CL22_WR_OVER_CL45(sc, phy,
5822                                   MDIO_REG_BANK_XGXS_BLOCK2,
5823                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP,
5824                                   (rx_lane_swap |
5825                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
5826                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
5827         } else {
5828                 CL22_WR_OVER_CL45(sc, phy,
5829                                   MDIO_REG_BANK_XGXS_BLOCK2,
5830                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
5831         }
5832
5833         if (tx_lane_swap != 0x1b) {
5834                 CL22_WR_OVER_CL45(sc, phy,
5835                                   MDIO_REG_BANK_XGXS_BLOCK2,
5836                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP,
5837                                   (tx_lane_swap |
5838                                    MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
5839         } else {
5840                 CL22_WR_OVER_CL45(sc, phy,
5841                                   MDIO_REG_BANK_XGXS_BLOCK2,
5842                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
5843         }
5844 }
5845
5846 static void elink_set_parallel_detection(struct elink_phy *phy,
5847                                          struct elink_params *params)
5848 {
5849         struct bnx2x_softc *sc = params->sc;
5850         uint16_t control2;
5851         CL22_RD_OVER_CL45(sc, phy,
5852                           MDIO_REG_BANK_SERDES_DIGITAL,
5853                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
5854                           &control2);
5855         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
5856                 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
5857         else
5858                 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
5859         ELINK_DEBUG_P2(sc, "phy->speed_cap_mask = 0x%x, control2 = 0x%x",
5860                 phy->speed_cap_mask, control2);
5861         CL22_WR_OVER_CL45(sc, phy,
5862                           MDIO_REG_BANK_SERDES_DIGITAL,
5863                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
5864                           control2);
5865
5866         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
5867              (phy->speed_cap_mask &
5868                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
5869                 ELINK_DEBUG_P0(sc, "XGXS");
5870
5871                 CL22_WR_OVER_CL45(sc, phy,
5872                                  MDIO_REG_BANK_10G_PARALLEL_DETECT,
5873                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
5874                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
5875
5876                 CL22_RD_OVER_CL45(sc, phy,
5877                                   MDIO_REG_BANK_10G_PARALLEL_DETECT,
5878                                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
5879                                   &control2);
5880
5881
5882                 control2 |=
5883                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
5884
5885                 CL22_WR_OVER_CL45(sc, phy,
5886                                   MDIO_REG_BANK_10G_PARALLEL_DETECT,
5887                                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
5888                                   control2);
5889
5890                 /* Disable parallel detection of HiG */
5891                 CL22_WR_OVER_CL45(sc, phy,
5892                                   MDIO_REG_BANK_XGXS_BLOCK2,
5893                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
5894                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
5895                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
5896         }
5897 }
5898
5899 static void elink_set_autoneg(struct elink_phy *phy,
5900                               struct elink_params *params,
5901                               struct elink_vars *vars,
5902                               uint8_t enable_cl73)
5903 {
5904         struct bnx2x_softc *sc = params->sc;
5905         uint16_t reg_val;
5906
5907         /* CL37 Autoneg */
5908         CL22_RD_OVER_CL45(sc, phy,
5909                           MDIO_REG_BANK_COMBO_IEEE0,
5910                           MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
5911
5912         /* CL37 Autoneg Enabled */
5913         if (vars->line_speed == ELINK_SPEED_AUTO_NEG)
5914                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
5915         else /* CL37 Autoneg Disabled */
5916                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
5917                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
5918
5919         CL22_WR_OVER_CL45(sc, phy,
5920                           MDIO_REG_BANK_COMBO_IEEE0,
5921                           MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
5922
5923         /* Enable/Disable Autodetection */
5924
5925         CL22_RD_OVER_CL45(sc, phy,
5926                           MDIO_REG_BANK_SERDES_DIGITAL,
5927                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
5928         reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
5929                     MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
5930         reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
5931         if (vars->line_speed == ELINK_SPEED_AUTO_NEG)
5932                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
5933         else
5934                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
5935
5936         CL22_WR_OVER_CL45(sc, phy,
5937                           MDIO_REG_BANK_SERDES_DIGITAL,
5938                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
5939
5940         /* Enable TetonII and BAM autoneg */
5941         CL22_RD_OVER_CL45(sc, phy,
5942                           MDIO_REG_BANK_BAM_NEXT_PAGE,
5943                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
5944                           &reg_val);
5945         if (vars->line_speed == ELINK_SPEED_AUTO_NEG) {
5946                 /* Enable BAM aneg Mode and TetonII aneg Mode */
5947                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
5948                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
5949         } else {
5950                 /* TetonII and BAM Autoneg Disabled */
5951                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
5952                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
5953         }
5954         CL22_WR_OVER_CL45(sc, phy,
5955                           MDIO_REG_BANK_BAM_NEXT_PAGE,
5956                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
5957                           reg_val);
5958
5959         if (enable_cl73) {
5960                 /* Enable Cl73 FSM status bits */
5961                 CL22_WR_OVER_CL45(sc, phy,
5962                                   MDIO_REG_BANK_CL73_USERB0,
5963                                   MDIO_CL73_USERB0_CL73_UCTRL,
5964                                   0xe);
5965
5966                 /* Enable BAM Station Manager*/
5967                 CL22_WR_OVER_CL45(sc, phy,
5968                         MDIO_REG_BANK_CL73_USERB0,
5969                         MDIO_CL73_USERB0_CL73_BAM_CTRL1,
5970                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
5971                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
5972                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
5973
5974                 /* Advertise CL73 link speeds */
5975                 CL22_RD_OVER_CL45(sc, phy,
5976                                   MDIO_REG_BANK_CL73_IEEEB1,
5977                                   MDIO_CL73_IEEEB1_AN_ADV2,
5978                                   &reg_val);
5979                 if (phy->speed_cap_mask &
5980                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
5981                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
5982                 if (phy->speed_cap_mask &
5983                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
5984                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
5985
5986                 CL22_WR_OVER_CL45(sc, phy,
5987                                   MDIO_REG_BANK_CL73_IEEEB1,
5988                                   MDIO_CL73_IEEEB1_AN_ADV2,
5989                                   reg_val);
5990
5991                 /* CL73 Autoneg Enabled */
5992                 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
5993
5994         } else /* CL73 Autoneg Disabled */
5995                 reg_val = 0;
5996
5997         CL22_WR_OVER_CL45(sc, phy,
5998                           MDIO_REG_BANK_CL73_IEEEB0,
5999                           MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
6000 }
6001
6002 /* Program SerDes, forced speed */
6003 static void elink_program_serdes(struct elink_phy *phy,
6004                                  struct elink_params *params,
6005                                  struct elink_vars *vars)
6006 {
6007         struct bnx2x_softc *sc = params->sc;
6008         uint16_t reg_val;
6009
6010         /* Program duplex, disable autoneg and sgmii*/
6011         CL22_RD_OVER_CL45(sc, phy,
6012                           MDIO_REG_BANK_COMBO_IEEE0,
6013                           MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
6014         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
6015                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
6016                      MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
6017         if (phy->req_duplex == DUPLEX_FULL)
6018                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
6019         CL22_WR_OVER_CL45(sc, phy,
6020                           MDIO_REG_BANK_COMBO_IEEE0,
6021                           MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
6022
6023         /* Program speed
6024          *  - needed only if the speed is greater than 1G (2.5G or 10G)
6025          */
6026         CL22_RD_OVER_CL45(sc, phy,
6027                           MDIO_REG_BANK_SERDES_DIGITAL,
6028                           MDIO_SERDES_DIGITAL_MISC1, &reg_val);
6029         /* Clearing the speed value before setting the right speed */
6030         ELINK_DEBUG_P1(sc, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x", reg_val);
6031
6032         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
6033                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
6034
6035         if (!((vars->line_speed == ELINK_SPEED_1000) ||
6036               (vars->line_speed == ELINK_SPEED_100) ||
6037               (vars->line_speed == ELINK_SPEED_10))) {
6038
6039                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
6040                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
6041                 if (vars->line_speed == ELINK_SPEED_10000)
6042                         reg_val |=
6043                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
6044         }
6045
6046         CL22_WR_OVER_CL45(sc, phy,
6047                           MDIO_REG_BANK_SERDES_DIGITAL,
6048                           MDIO_SERDES_DIGITAL_MISC1, reg_val);
6049
6050 }
6051
6052 static void elink_set_brcm_cl37_advertisement(struct elink_phy *phy,
6053                                               struct elink_params *params)
6054 {
6055         struct bnx2x_softc *sc = params->sc;
6056         uint16_t val = 0;
6057
6058         /* Set extended capabilities */
6059         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
6060                 val |= MDIO_OVER_1G_UP1_2_5G;
6061         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
6062                 val |= MDIO_OVER_1G_UP1_10G;
6063         CL22_WR_OVER_CL45(sc, phy,
6064                           MDIO_REG_BANK_OVER_1G,
6065                           MDIO_OVER_1G_UP1, val);
6066
6067         CL22_WR_OVER_CL45(sc, phy,
6068                           MDIO_REG_BANK_OVER_1G,
6069                           MDIO_OVER_1G_UP3, 0x400);
6070 }
6071
6072 static void elink_set_ieee_aneg_advertisement(struct elink_phy *phy,
6073                                               struct elink_params *params,
6074                                               uint16_t ieee_fc)
6075 {
6076         struct bnx2x_softc *sc = params->sc;
6077         uint16_t val;
6078         /* For AN, we are always publishing full duplex */
6079
6080         CL22_WR_OVER_CL45(sc, phy,
6081                           MDIO_REG_BANK_COMBO_IEEE0,
6082                           MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
6083         CL22_RD_OVER_CL45(sc, phy,
6084                           MDIO_REG_BANK_CL73_IEEEB1,
6085                           MDIO_CL73_IEEEB1_AN_ADV1, &val);
6086         val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
6087         val |= ((ieee_fc << 3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
6088         CL22_WR_OVER_CL45(sc, phy,
6089                           MDIO_REG_BANK_CL73_IEEEB1,
6090                           MDIO_CL73_IEEEB1_AN_ADV1, val);
6091 }
6092
6093 static void elink_restart_autoneg(struct elink_phy *phy,
6094                                   struct elink_params *params,
6095                                   uint8_t enable_cl73)
6096 {
6097         struct bnx2x_softc *sc = params->sc;
6098         uint16_t mii_control;
6099
6100         ELINK_DEBUG_P0(sc, "elink_restart_autoneg");
6101         /* Enable and restart BAM/CL37 aneg */
6102
6103         if (enable_cl73) {
6104                 CL22_RD_OVER_CL45(sc, phy,
6105                                   MDIO_REG_BANK_CL73_IEEEB0,
6106                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6107                                   &mii_control);
6108
6109                 CL22_WR_OVER_CL45(sc, phy,
6110                                   MDIO_REG_BANK_CL73_IEEEB0,
6111                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6112                                   (mii_control |
6113                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
6114                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
6115         } else {
6116
6117                 CL22_RD_OVER_CL45(sc, phy,
6118                                   MDIO_REG_BANK_COMBO_IEEE0,
6119                                   MDIO_COMBO_IEEE0_MII_CONTROL,
6120                                   &mii_control);
6121                 ELINK_DEBUG_P1(sc,
6122                          "elink_restart_autoneg mii_control before = 0x%x",
6123                          mii_control);
6124                 CL22_WR_OVER_CL45(sc, phy,
6125                                   MDIO_REG_BANK_COMBO_IEEE0,
6126                                   MDIO_COMBO_IEEE0_MII_CONTROL,
6127                                   (mii_control |
6128                                    MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
6129                                    MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
6130         }
6131 }
6132
6133 static void elink_initialize_sgmii_process(struct elink_phy *phy,
6134                                            struct elink_params *params,
6135                                            struct elink_vars *vars)
6136 {
6137         struct bnx2x_softc *sc = params->sc;
6138         uint16_t control1;
6139
6140         /* In SGMII mode, the unicore is always slave */
6141
6142         CL22_RD_OVER_CL45(sc, phy,
6143                           MDIO_REG_BANK_SERDES_DIGITAL,
6144                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
6145                           &control1);
6146         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
6147         /* Set sgmii mode (and not fiber) */
6148         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
6149                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
6150                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
6151         CL22_WR_OVER_CL45(sc, phy,
6152                           MDIO_REG_BANK_SERDES_DIGITAL,
6153                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
6154                           control1);
6155
6156         /* If forced speed */
6157         if (!(vars->line_speed == ELINK_SPEED_AUTO_NEG)) {
6158                 /* Set speed, disable autoneg */
6159                 uint16_t mii_control;
6160
6161                 CL22_RD_OVER_CL45(sc, phy,
6162                                   MDIO_REG_BANK_COMBO_IEEE0,
6163                                   MDIO_COMBO_IEEE0_MII_CONTROL,
6164                                   &mii_control);
6165                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
6166                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK |
6167                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
6168
6169                 switch (vars->line_speed) {
6170                 case ELINK_SPEED_100:
6171                         mii_control |=
6172                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
6173                         break;
6174                 case ELINK_SPEED_1000:
6175                         mii_control |=
6176                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
6177                         break;
6178                 case ELINK_SPEED_10:
6179                         /* There is nothing to set for 10M */
6180                         break;
6181                 default:
6182                         /* Invalid speed for SGMII */
6183                         ELINK_DEBUG_P1(sc, "Invalid line_speed 0x%x",
6184                                   vars->line_speed);
6185                         break;
6186                 }
6187
6188                 /* Setting the full duplex */
6189                 if (phy->req_duplex == DUPLEX_FULL)
6190                         mii_control |=
6191                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
6192                 CL22_WR_OVER_CL45(sc, phy,
6193                                   MDIO_REG_BANK_COMBO_IEEE0,
6194                                   MDIO_COMBO_IEEE0_MII_CONTROL,
6195                                   mii_control);
6196
6197         } else { /* AN mode */
6198                 /* Enable and restart AN */
6199                 elink_restart_autoneg(phy, params, 0);
6200         }
6201 }
6202
6203 /* Link management
6204  */
6205 static elink_status_t elink_direct_parallel_detect_used(struct elink_phy *phy,
6206                                              struct elink_params *params)
6207 {
6208         struct bnx2x_softc *sc = params->sc;
6209         uint16_t pd_10g, status2_1000x;
6210         if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
6211                 return ELINK_STATUS_OK;
6212         CL22_RD_OVER_CL45(sc, phy,
6213                           MDIO_REG_BANK_SERDES_DIGITAL,
6214                           MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
6215                           &status2_1000x);
6216         CL22_RD_OVER_CL45(sc, phy,
6217                           MDIO_REG_BANK_SERDES_DIGITAL,
6218                           MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
6219                           &status2_1000x);
6220         if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
6221                 ELINK_DEBUG_P1(sc, "1G parallel detect link on port %d",
6222                          params->port);
6223                 return 1;
6224         }
6225
6226         CL22_RD_OVER_CL45(sc, phy,
6227                           MDIO_REG_BANK_10G_PARALLEL_DETECT,
6228                           MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
6229                           &pd_10g);
6230
6231         if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
6232                 ELINK_DEBUG_P1(sc, "10G parallel detect link on port %d",
6233                          params->port);
6234                 return 1;
6235         }
6236         return ELINK_STATUS_OK;
6237 }
6238
6239 static void elink_update_adv_fc(struct elink_phy *phy,
6240                                 struct elink_params *params,
6241                                 struct elink_vars *vars,
6242                                 uint32_t gp_status)
6243 {
6244         uint16_t ld_pause;   /* local driver */
6245         uint16_t lp_pause;   /* link partner */
6246         uint16_t pause_result;
6247         struct bnx2x_softc *sc = params->sc;
6248         if ((gp_status &
6249              (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
6250               MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
6251             (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
6252              MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
6253
6254                 CL22_RD_OVER_CL45(sc, phy,
6255                                   MDIO_REG_BANK_CL73_IEEEB1,
6256                                   MDIO_CL73_IEEEB1_AN_ADV1,
6257                                   &ld_pause);
6258                 CL22_RD_OVER_CL45(sc, phy,
6259                                   MDIO_REG_BANK_CL73_IEEEB1,
6260                                   MDIO_CL73_IEEEB1_AN_LP_ADV1,
6261                                   &lp_pause);
6262                 pause_result = (ld_pause &
6263                                 MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK) >> 8;
6264                 pause_result |= (lp_pause &
6265                                  MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK) >> 10;
6266                 ELINK_DEBUG_P1(sc, "pause_result CL73 0x%x", pause_result);
6267         } else {
6268                 CL22_RD_OVER_CL45(sc, phy,
6269                                   MDIO_REG_BANK_COMBO_IEEE0,
6270                                   MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
6271                                   &ld_pause);
6272                 CL22_RD_OVER_CL45(sc, phy,
6273                         MDIO_REG_BANK_COMBO_IEEE0,
6274                         MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
6275                         &lp_pause);
6276                 pause_result = (ld_pause &
6277                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) >> 5;
6278                 pause_result |= (lp_pause &
6279                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) >> 7;
6280                 ELINK_DEBUG_P1(sc, "pause_result CL37 0x%x", pause_result);
6281         }
6282         elink_pause_resolve(phy, params, vars, pause_result);
6283
6284 }
6285
6286 static void elink_flow_ctrl_resolve(struct elink_phy *phy,
6287                                     struct elink_params *params,
6288                                     struct elink_vars *vars,
6289                                     uint32_t gp_status)
6290 {
6291         struct bnx2x_softc *sc = params->sc;
6292         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
6293
6294         /* Resolve from gp_status in case of AN complete and not sgmii */
6295         if (phy->req_flow_ctrl != ELINK_FLOW_CTRL_AUTO) {
6296                 /* Update the advertised flow-controled of LD/LP in AN */
6297                 if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
6298                         elink_update_adv_fc(phy, params, vars, gp_status);
6299                 /* But set the flow-control result as the requested one */
6300                 vars->flow_ctrl = phy->req_flow_ctrl;
6301         } else if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
6302                 vars->flow_ctrl = params->req_fc_auto_adv;
6303         else if ((gp_status & ELINK_MDIO_AN_CL73_OR_37_COMPLETE) &&
6304                  (!(vars->phy_flags & PHY_SGMII_FLAG))) {
6305                 if (elink_direct_parallel_detect_used(phy, params)) {
6306                         vars->flow_ctrl = params->req_fc_auto_adv;
6307                         return;
6308                 }
6309                 elink_update_adv_fc(phy, params, vars, gp_status);
6310         }
6311         ELINK_DEBUG_P1(sc, "flow_ctrl 0x%x", vars->flow_ctrl);
6312 }
6313
6314 static void elink_check_fallback_to_cl37(struct elink_phy *phy,
6315                                          struct elink_params *params)
6316 {
6317         struct bnx2x_softc *sc = params->sc;
6318         uint16_t rx_status, ustat_val, cl37_fsm_received;
6319         ELINK_DEBUG_P0(sc, "elink_check_fallback_to_cl37");
6320         /* Step 1: Make sure signal is detected */
6321         CL22_RD_OVER_CL45(sc, phy,
6322                           MDIO_REG_BANK_RX0,
6323                           MDIO_RX0_RX_STATUS,
6324                           &rx_status);
6325         if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
6326             (MDIO_RX0_RX_STATUS_SIGDET)) {
6327                 ELINK_DEBUG_P1(sc, "Signal is not detected. Restoring CL73."
6328                              "rx_status(0x80b0) = 0x%x", rx_status);
6329                 CL22_WR_OVER_CL45(sc, phy,
6330                                   MDIO_REG_BANK_CL73_IEEEB0,
6331                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6332                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
6333                 return;
6334         }
6335         /* Step 2: Check CL73 state machine */
6336         CL22_RD_OVER_CL45(sc, phy,
6337                           MDIO_REG_BANK_CL73_USERB0,
6338                           MDIO_CL73_USERB0_CL73_USTAT1,
6339                           &ustat_val);
6340         if ((ustat_val &
6341              (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
6342               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
6343             (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
6344               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
6345                 ELINK_DEBUG_P1(sc, "CL73 state-machine is not stable. "
6346                              "ustat_val(0x8371) = 0x%x", ustat_val);
6347                 return;
6348         }
6349         /* Step 3: Check CL37 Message Pages received to indicate LP
6350          * supports only CL37
6351          */
6352         CL22_RD_OVER_CL45(sc, phy,
6353                           MDIO_REG_BANK_REMOTE_PHY,
6354                           MDIO_REMOTE_PHY_MISC_RX_STATUS,
6355                           &cl37_fsm_received);
6356         if ((cl37_fsm_received &
6357              (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
6358              MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
6359             (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
6360               MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
6361                 ELINK_DEBUG_P1(sc, "No CL37 FSM were received. "
6362                              "misc_rx_status(0x8330) = 0x%x",
6363                          cl37_fsm_received);
6364                 return;
6365         }
6366         /* The combined cl37/cl73 fsm state information indicating that
6367          * we are connected to a device which does not support cl73, but
6368          * does support cl37 BAM. In this case we disable cl73 and
6369          * restart cl37 auto-neg
6370          */
6371
6372         /* Disable CL73 */
6373         CL22_WR_OVER_CL45(sc, phy,
6374                           MDIO_REG_BANK_CL73_IEEEB0,
6375                           MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6376                           0);
6377         /* Restart CL37 autoneg */
6378         elink_restart_autoneg(phy, params, 0);
6379         ELINK_DEBUG_P0(sc, "Disabling CL73, and restarting CL37 autoneg");
6380 }
6381
6382 static void elink_xgxs_an_resolve(struct elink_phy *phy,
6383                                   struct elink_params *params,
6384                                   struct elink_vars *vars,
6385                                   uint32_t gp_status)
6386 {
6387         if (gp_status & ELINK_MDIO_AN_CL73_OR_37_COMPLETE)
6388                 vars->link_status |=
6389                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6390
6391         if (elink_direct_parallel_detect_used(phy, params))
6392                 vars->link_status |=
6393                         LINK_STATUS_PARALLEL_DETECTION_USED;
6394 }
6395 static elink_status_t elink_get_link_speed_duplex(struct elink_phy *phy,
6396                                      struct elink_params *params,
6397                                       struct elink_vars *vars,
6398                                       uint16_t is_link_up,
6399                                       uint16_t speed_mask,
6400                                       uint16_t is_duplex)
6401 {
6402         struct bnx2x_softc *sc = params->sc;
6403         if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
6404                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
6405         if (is_link_up) {
6406                 ELINK_DEBUG_P0(sc, "phy link up");
6407
6408                 vars->phy_link_up = 1;
6409                 vars->link_status |= LINK_STATUS_LINK_UP;
6410
6411                 switch (speed_mask) {
6412                 case ELINK_GP_STATUS_10M:
6413                         vars->line_speed = ELINK_SPEED_10;
6414                         if (is_duplex == DUPLEX_FULL)
6415                                 vars->link_status |= ELINK_LINK_10TFD;
6416                         else
6417                                 vars->link_status |= ELINK_LINK_10THD;
6418                         break;
6419
6420                 case ELINK_GP_STATUS_100M:
6421                         vars->line_speed = ELINK_SPEED_100;
6422                         if (is_duplex == DUPLEX_FULL)
6423                                 vars->link_status |= ELINK_LINK_100TXFD;
6424                         else
6425                                 vars->link_status |= ELINK_LINK_100TXHD;
6426                         break;
6427
6428                 case ELINK_GP_STATUS_1G:
6429                 case ELINK_GP_STATUS_1G_KX:
6430                         vars->line_speed = ELINK_SPEED_1000;
6431                         if (is_duplex == DUPLEX_FULL)
6432                                 vars->link_status |= ELINK_LINK_1000TFD;
6433                         else
6434                                 vars->link_status |= ELINK_LINK_1000THD;
6435                         break;
6436
6437                 case ELINK_GP_STATUS_2_5G:
6438                         vars->line_speed = ELINK_SPEED_2500;
6439                         if (is_duplex == DUPLEX_FULL)
6440                                 vars->link_status |= ELINK_LINK_2500TFD;
6441                         else
6442                                 vars->link_status |= ELINK_LINK_2500THD;
6443                         break;
6444
6445                 case ELINK_GP_STATUS_5G:
6446                 case ELINK_GP_STATUS_6G:
6447                         ELINK_DEBUG_P1(sc,
6448                                  "link speed unsupported  gp_status 0x%x",
6449                                   speed_mask);
6450                         return ELINK_STATUS_ERROR;
6451
6452                 case ELINK_GP_STATUS_10G_KX4:
6453                 case ELINK_GP_STATUS_10G_HIG:
6454                 case ELINK_GP_STATUS_10G_CX4:
6455                 case ELINK_GP_STATUS_10G_KR:
6456                 case ELINK_GP_STATUS_10G_SFI:
6457                 case ELINK_GP_STATUS_10G_XFI:
6458                         vars->line_speed = ELINK_SPEED_10000;
6459                         vars->link_status |= ELINK_LINK_10GTFD;
6460                         break;
6461                 case ELINK_GP_STATUS_20G_DXGXS:
6462                 case ELINK_GP_STATUS_20G_KR2:
6463                         vars->line_speed = ELINK_SPEED_20000;
6464                         vars->link_status |= ELINK_LINK_20GTFD;
6465                         break;
6466                 default:
6467                         ELINK_DEBUG_P1(sc,
6468                                   "link speed unsupported gp_status 0x%x",
6469                                   speed_mask);
6470                         return ELINK_STATUS_ERROR;
6471                 }
6472         } else { /* link_down */
6473                 ELINK_DEBUG_P0(sc, "phy link down");
6474
6475                 vars->phy_link_up = 0;
6476
6477                 vars->duplex = DUPLEX_FULL;
6478                 vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
6479                 vars->mac_type = ELINK_MAC_TYPE_NONE;
6480         }
6481         ELINK_DEBUG_P2(sc, " in elink_get_link_speed_duplex vars->link_status = %x, vars->duplex = %x",
6482                         vars->link_status, vars->duplex);
6483         ELINK_DEBUG_P2(sc, " phy_link_up %x line_speed %d",
6484                     vars->phy_link_up, vars->line_speed);
6485         return ELINK_STATUS_OK;
6486 }
6487
6488 static uint8_t elink_link_settings_status(struct elink_phy *phy,
6489                                       struct elink_params *params,
6490                                       struct elink_vars *vars)
6491 {
6492         struct bnx2x_softc *sc = params->sc;
6493
6494         uint16_t gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask;
6495         elink_status_t rc = ELINK_STATUS_OK;
6496
6497         /* Read gp_status */
6498         CL22_RD_OVER_CL45(sc, phy,
6499                           MDIO_REG_BANK_GP_STATUS,
6500                           MDIO_GP_STATUS_TOP_AN_STATUS1,
6501                           &gp_status);
6502         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS) {
6503                 duplex = DUPLEX_FULL;
6504                 ELINK_DEBUG_P1(sc, "duplex status read from phy is = %x",
6505                                 duplex);
6506         } else {
6507                 ELINK_DEBUG_P1(sc, "phy status does not allow interface to be FULL_DUPLEX : %x",
6508                         gp_status);
6509         }
6510
6511
6512         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)
6513                 link_up = 1;
6514         speed_mask = gp_status & ELINK_GP_STATUS_SPEED_MASK;
6515         ELINK_DEBUG_P3(sc, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x",
6516                        gp_status, link_up, speed_mask);
6517         rc = elink_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
6518                                          duplex);
6519         if (rc == ELINK_STATUS_ERROR)
6520                 return rc;
6521
6522         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
6523                 if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
6524                         vars->duplex = duplex;
6525                         elink_flow_ctrl_resolve(phy, params, vars, gp_status);
6526                         if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
6527                                 elink_xgxs_an_resolve(phy, params, vars,
6528                                                       gp_status);
6529                 }
6530         } else { /* Link_down */
6531                 if ((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
6532                     ELINK_SINGLE_MEDIA_DIRECT(params)) {
6533                         /* Check signal is detected */
6534                         elink_check_fallback_to_cl37(phy, params);
6535                 }
6536         }
6537
6538         /* Read LP advertised speeds*/
6539         if (ELINK_SINGLE_MEDIA_DIRECT(params) &&
6540             (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)) {
6541                 uint16_t val;
6542
6543                 CL22_RD_OVER_CL45(sc, phy, MDIO_REG_BANK_CL73_IEEEB1,
6544                                   MDIO_CL73_IEEEB1_AN_LP_ADV2, &val);
6545
6546                 if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
6547                         vars->link_status |=
6548                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
6549                 if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
6550                            MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
6551                         vars->link_status |=
6552                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6553
6554                 CL22_RD_OVER_CL45(sc, phy, MDIO_REG_BANK_OVER_1G,
6555                                   MDIO_OVER_1G_LP_UP1, &val);
6556
6557                 if (val & MDIO_OVER_1G_UP1_2_5G)
6558                         vars->link_status |=
6559                                 LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
6560                 if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
6561                         vars->link_status |=
6562                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6563         }
6564
6565         ELINK_DEBUG_P3(sc, "duplex %x  flow_ctrl 0x%x link_status 0x%x",
6566                    vars->duplex, vars->flow_ctrl, vars->link_status);
6567         return rc;
6568 }
6569
6570 static uint8_t elink_warpcore_read_status(struct elink_phy *phy,
6571                                      struct elink_params *params,
6572                                      struct elink_vars *vars)
6573 {
6574         struct bnx2x_softc *sc = params->sc;
6575         uint8_t lane;
6576         uint16_t gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL;
6577         elink_status_t rc = ELINK_STATUS_OK;
6578         lane = elink_get_warpcore_lane(phy, params);
6579         /* Read gp_status */
6580         if ((params->loopback_mode) &&
6581             (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)) {
6582                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6583                                 MDIO_WC_REG_DIGITAL5_LINK_STATUS, &link_up);
6584                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6585                                 MDIO_WC_REG_DIGITAL5_LINK_STATUS, &link_up);
6586                 link_up &= 0x1;
6587                 ELINK_DEBUG_P1(sc, "params->loopback_mode link_up read = %x",
6588                                 link_up);
6589         } else if ((phy->req_line_speed > ELINK_SPEED_10000) &&
6590                 (phy->supported & ELINK_SUPPORTED_20000baseMLD2_Full)) {
6591                 uint16_t temp_link_up;
6592                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6593                                 1, &temp_link_up);
6594                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6595                                 1, &link_up);
6596                 ELINK_DEBUG_P2(sc, "PCS RX link status = 0x%x-->0x%x",
6597                                temp_link_up, link_up);
6598                 link_up &= (1 << 2);
6599                 if (link_up)
6600                         elink_ext_phy_resolve_fc(phy, params, vars);
6601         } else {
6602                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6603                                 MDIO_WC_REG_GP2_STATUS_GP_2_1,
6604                                 &gp_status1);
6605                 ELINK_DEBUG_P1(sc, "0x81d1 = 0x%x", gp_status1);
6606                 /* Check for either KR, 1G, or AN up. */
6607                 link_up = ((gp_status1 >> 8) |
6608                            (gp_status1 >> 12) |
6609                            (gp_status1)) &
6610                         (1 << lane);
6611                 if (phy->supported & ELINK_SUPPORTED_20000baseKR2_Full) {
6612                         uint16_t an_link;
6613                         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
6614                                         MDIO_AN_REG_STATUS, &an_link);
6615                         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
6616                                         MDIO_AN_REG_STATUS, &an_link);
6617                         link_up |= (an_link & (1 << 2));
6618                         ELINK_DEBUG_P2(sc, "an_link = %x, link_up = %x",
6619                                         an_link, link_up);
6620                 }
6621                 if (link_up && ELINK_SINGLE_MEDIA_DIRECT(params)) {
6622                         uint16_t pd, gp_status4;
6623                         if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
6624                                 /* Check Autoneg complete */
6625                                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6626                                                 MDIO_WC_REG_GP2_STATUS_GP_2_4,
6627                                                 &gp_status4);
6628                                 if (gp_status4 & ((1 << 12) << lane))
6629                                         vars->link_status |=
6630                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6631
6632                                 /* Check parallel detect used */
6633                                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6634                                                 MDIO_WC_REG_PAR_DET_10G_STATUS,
6635                                                 &pd);
6636                                 if (pd & (1 << 15))
6637                                         vars->link_status |=
6638                                         LINK_STATUS_PARALLEL_DETECTION_USED;
6639                                 ELINK_DEBUG_P2(sc, "pd = %x, link_status = %x",
6640                                                 pd, vars->link_status);
6641                         }
6642                         elink_ext_phy_resolve_fc(phy, params, vars);
6643                         vars->duplex = duplex;
6644                         ELINK_DEBUG_P3(sc, " ELINK_SINGLE_MEDIA_DIRECT duplex %x  flow_ctrl 0x%x link_status 0x%x",
6645                                         vars->duplex, vars->flow_ctrl,
6646                                         vars->link_status);
6647                 }
6648         }
6649         ELINK_DEBUG_P3(sc, "duplex %x  flow_ctrl 0x%x link_status 0x%x",
6650                         vars->duplex, vars->flow_ctrl, vars->link_status);
6651         if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) &&
6652             ELINK_SINGLE_MEDIA_DIRECT(params)) {
6653                 uint16_t val;
6654
6655                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
6656                                 MDIO_AN_REG_LP_AUTO_NEG2, &val);
6657
6658                 if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
6659                         vars->link_status |=
6660                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
6661                 if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
6662                            MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
6663                         vars->link_status |=
6664                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6665                 ELINK_DEBUG_P2(sc, "val = %x, link_status = %x",
6666                                 val, vars->link_status);
6667                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6668                                 MDIO_WC_REG_DIGITAL3_LP_UP1, &val);
6669
6670                 if (val & MDIO_OVER_1G_UP1_2_5G)
6671                         vars->link_status |=
6672                                 LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
6673                 if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
6674                         vars->link_status |=
6675                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6676                 ELINK_DEBUG_P2(sc, "val = %x, link_status = %x",
6677                                 val, vars->link_status);
6678
6679         }
6680
6681
6682         if (lane < 2) {
6683                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6684                                 MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed);
6685         } else {
6686                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6687                                 MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed);
6688         }
6689         ELINK_DEBUG_P2(sc, "lane %d gp_speed 0x%x", lane, gp_speed);
6690
6691         if ((lane & 1) == 0)
6692                 gp_speed <<= 8;
6693         gp_speed &= 0x3f00;
6694         link_up = !!link_up;
6695
6696         /* Reset the TX FIFO to fix SGMII issue */
6697         rc = elink_get_link_speed_duplex(phy, params, vars, link_up, gp_speed,
6698                                          duplex);
6699
6700         /* In case of KR link down, start up the recovering procedure */
6701         if ((!link_up) && (phy->media_type == ELINK_ETH_PHY_KR) &&
6702             (!(phy->flags & ELINK_FLAGS_WC_DUAL_MODE)))
6703                 vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
6704
6705         ELINK_DEBUG_P3(sc, "duplex %x  flow_ctrl 0x%x link_status 0x%x",
6706                    vars->duplex, vars->flow_ctrl, vars->link_status);
6707         return rc;
6708 }
6709 static void elink_set_gmii_tx_driver(struct elink_params *params)
6710 {
6711         struct bnx2x_softc *sc = params->sc;
6712         struct elink_phy *phy = &params->phy[ELINK_INT_PHY];
6713         uint16_t lp_up2;
6714         uint16_t tx_driver;
6715         uint16_t bank;
6716
6717         /* Read precomp */
6718         CL22_RD_OVER_CL45(sc, phy,
6719                           MDIO_REG_BANK_OVER_1G,
6720                           MDIO_OVER_1G_LP_UP2, &lp_up2);
6721
6722         /* Bits [10:7] at lp_up2, positioned at [15:12] */
6723         lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
6724                    MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
6725                   MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
6726
6727         if (lp_up2 == 0)
6728                 return;
6729
6730         for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
6731               bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
6732                 CL22_RD_OVER_CL45(sc, phy,
6733                                   bank,
6734                                   MDIO_TX0_TX_DRIVER, &tx_driver);
6735
6736                 /* Replace tx_driver bits [15:12] */
6737                 if (lp_up2 !=
6738                     (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
6739                         tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
6740                         tx_driver |= lp_up2;
6741                         CL22_WR_OVER_CL45(sc, phy,
6742                                           bank,
6743                                           MDIO_TX0_TX_DRIVER, tx_driver);
6744                 }
6745         }
6746 }
6747
6748 static elink_status_t elink_emac_program(struct elink_params *params,
6749                               struct elink_vars *vars)
6750 {
6751         struct bnx2x_softc *sc = params->sc;
6752         uint8_t port = params->port;
6753         uint16_t mode = 0;
6754
6755         ELINK_DEBUG_P0(sc, "setting link speed & duplex");
6756         elink_bits_dis(sc, GRCBASE_EMAC0 + port * 0x400 +
6757                        EMAC_REG_EMAC_MODE,
6758                        (EMAC_MODE_25G_MODE |
6759                         EMAC_MODE_PORT_MII_10M |
6760                         EMAC_MODE_HALF_DUPLEX));
6761         switch (vars->line_speed) {
6762         case ELINK_SPEED_10:
6763                 mode |= EMAC_MODE_PORT_MII_10M;
6764                 break;
6765
6766         case ELINK_SPEED_100:
6767                 mode |= EMAC_MODE_PORT_MII;
6768                 break;
6769
6770         case ELINK_SPEED_1000:
6771                 mode |= EMAC_MODE_PORT_GMII;
6772                 break;
6773
6774         case ELINK_SPEED_2500:
6775                 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
6776                 break;
6777
6778         default:
6779                 /* 10G not valid for EMAC */
6780                 ELINK_DEBUG_P1(sc, "Invalid line_speed 0x%x",
6781                            vars->line_speed);
6782                 return ELINK_STATUS_ERROR;
6783         }
6784
6785         if (vars->duplex == DUPLEX_HALF)
6786                 mode |= EMAC_MODE_HALF_DUPLEX;
6787         elink_bits_en(sc,
6788                       GRCBASE_EMAC0 + port * 0x400 + EMAC_REG_EMAC_MODE,
6789                       mode);
6790
6791         elink_set_led(params, vars, ELINK_LED_MODE_OPER, vars->line_speed);
6792         return ELINK_STATUS_OK;
6793 }
6794
6795 static void elink_set_preemphasis(struct elink_phy *phy,
6796                                   struct elink_params *params)
6797 {
6798
6799         uint16_t bank, i = 0;
6800         struct bnx2x_softc *sc = params->sc;
6801
6802         for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
6803              bank += (MDIO_REG_BANK_RX1 - MDIO_REG_BANK_RX0), i++) {
6804                 CL22_WR_OVER_CL45(sc, phy,
6805                                   bank,
6806                                   MDIO_RX0_RX_EQ_BOOST,
6807                                   phy->rx_preemphasis[i]);
6808         }
6809
6810         for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
6811              bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
6812                 CL22_WR_OVER_CL45(sc, phy,
6813                                   bank,
6814                                   MDIO_TX0_TX_DRIVER,
6815                                   phy->tx_preemphasis[i]);
6816         }
6817 }
6818
6819 static uint8_t elink_xgxs_config_init(struct elink_phy *phy,
6820                                    struct elink_params *params,
6821                                    struct elink_vars *vars)
6822 {
6823         struct bnx2x_softc *sc = params->sc;
6824         uint8_t enable_cl73 = (ELINK_SINGLE_MEDIA_DIRECT(params) ||
6825                           (params->loopback_mode == ELINK_LOOPBACK_XGXS));
6826         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
6827                 if (ELINK_SINGLE_MEDIA_DIRECT(params) &&
6828                     (params->feature_config_flags &
6829                      ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
6830                         elink_set_preemphasis(phy, params);
6831
6832                 /* Forced speed requested? */
6833                 if (vars->line_speed != ELINK_SPEED_AUTO_NEG ||
6834                     (ELINK_SINGLE_MEDIA_DIRECT(params) &&
6835                      params->loopback_mode == ELINK_LOOPBACK_EXT)) {
6836                         ELINK_DEBUG_P0(sc, "not SGMII, no AN");
6837
6838                         /* Disable autoneg */
6839                         elink_set_autoneg(phy, params, vars, 0);
6840
6841                         /* Program speed and duplex */
6842                         elink_program_serdes(phy, params, vars);
6843
6844                 } else { /* AN_mode */
6845                         ELINK_DEBUG_P0(sc, "not SGMII, AN");
6846
6847                         /* AN enabled */
6848                         elink_set_brcm_cl37_advertisement(phy, params);
6849
6850                         /* Program duplex & pause advertisement (for aneg) */
6851                         elink_set_ieee_aneg_advertisement(phy, params,
6852                                                           vars->ieee_fc);
6853
6854                         /* Enable autoneg */
6855                         elink_set_autoneg(phy, params, vars, enable_cl73);
6856
6857                         /* Enable and restart AN */
6858                         elink_restart_autoneg(phy, params, enable_cl73);
6859                 }
6860
6861         } else { /* SGMII mode */
6862                 ELINK_DEBUG_P0(sc, "SGMII");
6863
6864                 elink_initialize_sgmii_process(phy, params, vars);
6865         }
6866
6867         return 0;
6868 }
6869
6870 static elink_status_t elink_prepare_xgxs(struct elink_phy *phy,
6871                           struct elink_params *params,
6872                           struct elink_vars *vars)
6873 {
6874         elink_status_t rc;
6875         vars->phy_flags |= PHY_XGXS_FLAG;
6876         if ((phy->req_line_speed &&
6877              ((phy->req_line_speed == ELINK_SPEED_100) ||
6878               (phy->req_line_speed == ELINK_SPEED_10))) ||
6879             (!phy->req_line_speed &&
6880              (phy->speed_cap_mask >=
6881               PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
6882              (phy->speed_cap_mask <
6883               PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
6884             (phy->type == PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD))
6885                 vars->phy_flags |= PHY_SGMII_FLAG;
6886         else
6887                 vars->phy_flags &= ~PHY_SGMII_FLAG;
6888
6889         elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
6890         elink_set_aer_mmd(params, phy);
6891         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
6892                 elink_set_master_ln(params, phy);
6893
6894         rc = elink_reset_unicore(params, phy, 0);
6895         /* Reset the SerDes and wait for reset bit return low */
6896         if (rc != ELINK_STATUS_OK)
6897                 return rc;
6898
6899         elink_set_aer_mmd(params, phy);
6900         /* Setting the masterLn_def again after the reset */
6901         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
6902                 elink_set_master_ln(params, phy);
6903                 elink_set_swap_lanes(params, phy);
6904         }
6905
6906         return rc;
6907 }
6908
6909 static uint16_t elink_wait_reset_complete(struct bnx2x_softc *sc,
6910                                      struct elink_phy *phy,
6911                                      struct elink_params *params)
6912 {
6913         uint16_t cnt, ctrl;
6914         /* Wait for soft reset to get cleared up to 1 sec */
6915         for (cnt = 0; cnt < 1000; cnt++) {
6916                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE)
6917                         elink_cl22_read(sc, phy,
6918                                 MDIO_PMA_REG_CTRL, &ctrl);
6919                 else
6920                         elink_cl45_read(sc, phy,
6921                                 MDIO_PMA_DEVAD,
6922                                 MDIO_PMA_REG_CTRL, &ctrl);
6923                 if (!(ctrl & (1 << 15)))
6924                         break;
6925                 DELAY(1000 * 1);
6926         }
6927
6928         if (cnt == 1000)
6929                 elink_cb_event_log(sc, ELINK_LOG_ID_PHY_UNINITIALIZED,
6930                                    params->port);
6931                                      /* "Warning: PHY was not initialized,"
6932                                       * " Port %d",
6933                                       */
6934
6935         ELINK_DEBUG_P2(sc, "control reg 0x%x (after %d ms)", ctrl, cnt);
6936         return cnt;
6937 }
6938
6939 static void elink_link_int_enable(struct elink_params *params)
6940 {
6941         uint8_t port = params->port;
6942         uint32_t mask;
6943         struct bnx2x_softc *sc = params->sc;
6944
6945         /* Setting the status to report on link up for either XGXS or SerDes */
6946         if (CHIP_IS_E3(sc)) {
6947                 mask = ELINK_NIG_MASK_XGXS0_LINK_STATUS;
6948                 if (!(ELINK_SINGLE_MEDIA_DIRECT(params)))
6949                         mask |= ELINK_NIG_MASK_MI_INT;
6950         } else if (params->switch_cfg == ELINK_SWITCH_CFG_10G) {
6951                 mask = (ELINK_NIG_MASK_XGXS0_LINK10G |
6952                         ELINK_NIG_MASK_XGXS0_LINK_STATUS);
6953                 ELINK_DEBUG_P0(sc, "enabled XGXS interrupt");
6954                 if (!(ELINK_SINGLE_MEDIA_DIRECT(params)) &&
6955                         params->phy[ELINK_INT_PHY].type !=
6956                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
6957                         mask |= ELINK_NIG_MASK_MI_INT;
6958                         ELINK_DEBUG_P0(sc, "enabled external phy int");
6959                 }
6960
6961         } else { /* SerDes */
6962                 mask = ELINK_NIG_MASK_SERDES0_LINK_STATUS;
6963                 ELINK_DEBUG_P0(sc, "enabled SerDes interrupt");
6964                 if (!(ELINK_SINGLE_MEDIA_DIRECT(params)) &&
6965                         params->phy[ELINK_INT_PHY].type !=
6966                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
6967                         mask |= ELINK_NIG_MASK_MI_INT;
6968                         ELINK_DEBUG_P0(sc, "enabled external phy int");
6969                 }
6970         }
6971         elink_bits_en(sc,
6972                       NIG_REG_MASK_INTERRUPT_PORT0 + port * 4,
6973                       mask);
6974
6975         ELINK_DEBUG_P3(sc, "port %x, is_xgxs %x, int_status 0x%x", port,
6976                  (params->switch_cfg == ELINK_SWITCH_CFG_10G),
6977                  REG_RD(sc, NIG_REG_STATUS_INTERRUPT_PORT0 + port * 4));
6978         ELINK_DEBUG_P3(sc, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x",
6979                  REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 + port * 4),
6980                  REG_RD(sc, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port * 0x18),
6981                  REG_RD(sc, NIG_REG_SERDES0_STATUS_LINK_STATUS + port * 0x3c));
6982         ELINK_DEBUG_P2(sc, " 10G %x, XGXS_LINK %x",
6983            REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK10G + port * 0x68),
6984            REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK_STATUS + port * 0x68));
6985 }
6986
6987 static void elink_rearm_latch_signal(struct bnx2x_softc *sc, uint8_t port,
6988                                      uint8_t exp_mi_int)
6989 {
6990         uint32_t latch_status = 0;
6991
6992         /* Disable the MI INT ( external phy int ) by writing 1 to the
6993          * status register. Link down indication is high-active-signal,
6994          * so in this case we need to write the status to clear the XOR
6995          */
6996         /* Read Latched signals */
6997         latch_status = REG_RD(sc,
6998                                     NIG_REG_LATCH_STATUS_0 + port * 8);
6999         ELINK_DEBUG_P1(sc, "latch_status = 0x%x", latch_status);
7000         /* Handle only those with latched-signal=up.*/
7001         if (exp_mi_int)
7002                 elink_bits_en(sc,
7003                               NIG_REG_STATUS_INTERRUPT_PORT0
7004                               + port * 4,
7005                               ELINK_NIG_STATUS_EMAC0_MI_INT);
7006         else
7007                 elink_bits_dis(sc,
7008                                NIG_REG_STATUS_INTERRUPT_PORT0
7009                                + port * 4,
7010                                ELINK_NIG_STATUS_EMAC0_MI_INT);
7011
7012         if (latch_status & 1) {
7013
7014                 /* For all latched-signal=up : Re-Arm Latch signals */
7015                 REG_WR(sc, NIG_REG_LATCH_STATUS_0 + port * 8,
7016                        (latch_status & 0xfffe) | (latch_status & 1));
7017         }
7018         /* For all latched-signal=up,Write original_signal to status */
7019 }
7020
7021 static void elink_link_int_ack(struct elink_params *params,
7022                                struct elink_vars *vars, uint8_t is_10g_plus)
7023 {
7024         struct bnx2x_softc *sc = params->sc;
7025         uint8_t port = params->port;
7026         uint32_t mask;
7027         /* First reset all status we assume only one line will be
7028          * change at a time
7029          */
7030         elink_bits_dis(sc, NIG_REG_STATUS_INTERRUPT_PORT0 + port * 4,
7031                        (ELINK_NIG_STATUS_XGXS0_LINK10G |
7032                         ELINK_NIG_STATUS_XGXS0_LINK_STATUS |
7033                         ELINK_NIG_STATUS_SERDES0_LINK_STATUS));
7034         if (vars->phy_link_up) {
7035                 if (USES_WARPCORE(sc))
7036                         mask = ELINK_NIG_STATUS_XGXS0_LINK_STATUS;
7037                 else {
7038                         if (is_10g_plus)
7039                                 mask = ELINK_NIG_STATUS_XGXS0_LINK10G;
7040                         else if (params->switch_cfg == ELINK_SWITCH_CFG_10G) {
7041                                 /* Disable the link interrupt by writing 1 to
7042                                  * the relevant lane in the status register
7043                                  */
7044                                 uint32_t ser_lane =
7045                                         ((params->lane_config &
7046                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
7047                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
7048                                 mask = ((1 << ser_lane) <<
7049                                        ELINK_NIG_STATUS_XGXS0_LINK_STATUS_SIZE);
7050                         } else
7051                                 mask = ELINK_NIG_STATUS_SERDES0_LINK_STATUS;
7052                 }
7053                 ELINK_DEBUG_P1(sc, "Ack link up interrupt with mask 0x%x",
7054                                mask);
7055                 elink_bits_en(sc,
7056                               NIG_REG_STATUS_INTERRUPT_PORT0 + port * 4,
7057                               mask);
7058         }
7059 }
7060
7061 static elink_status_t elink_format_ver(uint32_t num, uint8_t *str,
7062                                        uint16_t *len)
7063 {
7064         uint8_t *str_ptr = str;
7065         uint32_t mask = 0xf0000000;
7066         uint8_t shift = 8 * 4;
7067         uint8_t digit;
7068         uint8_t remove_leading_zeros = 1;
7069         if (*len < 10) {
7070                 /* Need more than 10chars for this format */
7071                 *str_ptr = '\0';
7072                 (*len)--;
7073                 return ELINK_STATUS_ERROR;
7074         }
7075         while (shift > 0) {
7076
7077                 shift -= 4;
7078                 digit = ((num & mask) >> shift);
7079                 if (digit == 0 && remove_leading_zeros) {
7080                         mask = mask >> 4;
7081                         continue;
7082                 } else if (digit < 0xa)
7083                         *str_ptr = digit + '0';
7084                 else
7085                         *str_ptr = digit - 0xa + 'a';
7086                 remove_leading_zeros = 0;
7087                 str_ptr++;
7088                 (*len)--;
7089                 mask = mask >> 4;
7090                 if (shift == 4 * 4) {
7091                         *str_ptr = '.';
7092                         str_ptr++;
7093                         (*len)--;
7094                         remove_leading_zeros = 1;
7095                 }
7096         }
7097         return ELINK_STATUS_OK;
7098 }
7099
7100
7101 static elink_status_t elink_null_format_ver(__rte_unused uint32_t spirom_ver,
7102                                  uint8_t *str,
7103                                  uint16_t *len)
7104 {
7105         str[0] = '\0';
7106         (*len)--;
7107         return ELINK_STATUS_OK;
7108 }
7109
7110 elink_status_t elink_get_ext_phy_fw_version(struct elink_params *params,
7111                                  uint8_t *version,
7112                                  uint16_t len)
7113 {
7114         struct bnx2x_softc *sc;
7115         uint32_t spirom_ver = 0;
7116         elink_status_t status = ELINK_STATUS_OK;
7117         uint8_t *ver_p = version;
7118         uint16_t remain_len = len;
7119         if (version == NULL || params == NULL)
7120                 return ELINK_STATUS_ERROR;
7121         sc = params->sc;
7122
7123         /* Extract first external phy*/
7124         version[0] = '\0';
7125         spirom_ver = REG_RD(sc, params->phy[ELINK_EXT_PHY1].ver_addr);
7126
7127         if (params->phy[ELINK_EXT_PHY1].format_fw_ver) {
7128                 status |= params->phy[ELINK_EXT_PHY1].format_fw_ver(spirom_ver,
7129                                                               ver_p,
7130                                                               &remain_len);
7131                 ver_p += (len - remain_len);
7132         }
7133         if ((params->num_phys == ELINK_MAX_PHYS) &&
7134             (params->phy[ELINK_EXT_PHY2].ver_addr != 0)) {
7135                 spirom_ver = REG_RD(sc, params->phy[ELINK_EXT_PHY2].ver_addr);
7136                 if (params->phy[ELINK_EXT_PHY2].format_fw_ver) {
7137                         *ver_p = '/';
7138                         ver_p++;
7139                         remain_len--;
7140                         status |= params->phy[ELINK_EXT_PHY2].format_fw_ver(
7141                                 spirom_ver,
7142                                 ver_p,
7143                                 &remain_len);
7144                         ver_p = version + (len - remain_len);
7145                 }
7146         }
7147         *ver_p = '\0';
7148         return status;
7149 }
7150
7151 static void elink_set_xgxs_loopback(struct elink_phy *phy,
7152                                     struct elink_params *params)
7153 {
7154         uint8_t port = params->port;
7155         struct bnx2x_softc *sc = params->sc;
7156
7157         if (phy->req_line_speed != ELINK_SPEED_1000) {
7158                 uint32_t md_devad = 0;
7159
7160                 ELINK_DEBUG_P0(sc, "XGXS 10G loopback enable");
7161
7162                 if (!CHIP_IS_E3(sc)) {
7163                         /* Change the uni_phy_addr in the nig */
7164                         md_devad = REG_RD(sc, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
7165                                                port * 0x18));
7166
7167                         REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_DEVAD + port * 0x18,
7168                                0x5);
7169                 }
7170
7171                 elink_cl45_write(sc, phy,
7172                                  5,
7173                                  (MDIO_REG_BANK_AER_BLOCK +
7174                                   (MDIO_AER_BLOCK_AER_REG & 0xf)),
7175                                  0x2800);
7176
7177                 elink_cl45_write(sc, phy,
7178                                  5,
7179                                  (MDIO_REG_BANK_CL73_IEEEB0 +
7180                                   (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
7181                                  0x6041);
7182                 DELAY(1000 * 200);
7183                 /* Set aer mmd back */
7184                 elink_set_aer_mmd(params, phy);
7185
7186                 if (!CHIP_IS_E3(sc)) {
7187                         /* And md_devad */
7188                         REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_DEVAD + port * 0x18,
7189                                md_devad);
7190                 }
7191         } else {
7192                 uint16_t mii_ctrl;
7193                 ELINK_DEBUG_P0(sc, "XGXS 1G loopback enable");
7194                 elink_cl45_read(sc, phy, 5,
7195                                 (MDIO_REG_BANK_COMBO_IEEE0 +
7196                                 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
7197                                 &mii_ctrl);
7198                 elink_cl45_write(sc, phy, 5,
7199                                  (MDIO_REG_BANK_COMBO_IEEE0 +
7200                                  (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
7201                                  mii_ctrl |
7202                                  MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
7203         }
7204 }
7205
7206 elink_status_t elink_set_led(struct elink_params *params,
7207                   struct elink_vars *vars, uint8_t mode, uint32_t speed)
7208 {
7209         uint8_t port = params->port;
7210         uint16_t hw_led_mode = params->hw_led_mode;
7211         elink_status_t rc = ELINK_STATUS_OK;
7212         uint8_t phy_idx;
7213         uint32_t tmp;
7214         uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
7215         struct bnx2x_softc *sc = params->sc;
7216         ELINK_DEBUG_P2(sc, "elink_set_led: port %x, mode %d", port, mode);
7217         ELINK_DEBUG_P2(sc, "speed 0x%x, hw_led_mode 0x%x",
7218                  speed, hw_led_mode);
7219         /* In case */
7220         for (phy_idx = ELINK_EXT_PHY1; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
7221                 if (params->phy[phy_idx].set_link_led) {
7222                         params->phy[phy_idx].set_link_led(
7223                                 &params->phy[phy_idx], params, mode);
7224                 }
7225         }
7226 #ifdef ELINK_INCLUDE_EMUL
7227         if (params->feature_config_flags &
7228             ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC)
7229                 return rc;
7230 #endif
7231
7232         switch (mode) {
7233         case ELINK_LED_MODE_FRONT_PANEL_OFF:
7234         case ELINK_LED_MODE_OFF:
7235                 REG_WR(sc, NIG_REG_LED_10G_P0 + port * 4, 0);
7236                 REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4,
7237                        SHARED_HW_CFG_LED_MAC1);
7238
7239                 tmp = elink_cb_reg_read(sc, emac_base + EMAC_REG_EMAC_LED);
7240                 if (params->phy[ELINK_EXT_PHY1].type ==
7241                         PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE)
7242                         tmp &= ~(EMAC_LED_1000MB_OVERRIDE |
7243                                 EMAC_LED_100MB_OVERRIDE |
7244                                 EMAC_LED_10MB_OVERRIDE);
7245                 else
7246                         tmp |= EMAC_LED_OVERRIDE;
7247
7248                 elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED, tmp);
7249                 break;
7250
7251         case ELINK_LED_MODE_OPER:
7252                 /* For all other phys, OPER mode is same as ON, so in case
7253                  * link is down, do nothing
7254                  */
7255                 if (!vars->link_up)
7256                         break;
7257                 /* fallthrough */
7258         case ELINK_LED_MODE_ON:
7259                 if (((params->phy[ELINK_EXT_PHY1].type ==
7260                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727) ||
7261                          (params->phy[ELINK_EXT_PHY1].type ==
7262                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722)) &&
7263                     CHIP_IS_E2(sc) && params->num_phys == 2) {
7264                         /* This is a work-around for E2 + 8727 Configurations */
7265                         if (mode == ELINK_LED_MODE_ON ||
7266                                 speed == ELINK_SPEED_10000){
7267                                 REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4, 0);
7268                                 REG_WR(sc, NIG_REG_LED_10G_P0 + port * 4, 1);
7269
7270                                 tmp = elink_cb_reg_read(sc, emac_base +
7271                                                         EMAC_REG_EMAC_LED);
7272                                 elink_cb_reg_write(sc, emac_base +
7273                                                    EMAC_REG_EMAC_LED,
7274                                                    (tmp | EMAC_LED_OVERRIDE));
7275                                 /* Return here without enabling traffic
7276                                  * LED blink and setting rate in ON mode.
7277                                  * In oper mode, enabling LED blink
7278                                  * and setting rate is needed.
7279                                  */
7280                                 if (mode == ELINK_LED_MODE_ON)
7281                                         return rc;
7282                         }
7283                 } else if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
7284                         /* This is a work-around for HW issue found when link
7285                          * is up in CL73
7286                          */
7287                         if ((!CHIP_IS_E3(sc)) ||
7288                             (CHIP_IS_E3(sc) &&
7289                              mode == ELINK_LED_MODE_ON))
7290                                 REG_WR(sc, NIG_REG_LED_10G_P0 + port * 4, 1);
7291
7292                         if (CHIP_IS_E1x(sc) ||
7293                             CHIP_IS_E2(sc) ||
7294                             (mode == ELINK_LED_MODE_ON))
7295                                 REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4, 0);
7296                         else
7297                                 REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4,
7298                                        hw_led_mode);
7299                 } else if ((params->phy[ELINK_EXT_PHY1].type ==
7300                             PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE) &&
7301                            (mode == ELINK_LED_MODE_ON)) {
7302                         REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4, 0);
7303                         tmp = elink_cb_reg_read(sc, emac_base +
7304                                                 EMAC_REG_EMAC_LED);
7305                         elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED,
7306                                            tmp | EMAC_LED_OVERRIDE |
7307                                            EMAC_LED_1000MB_OVERRIDE);
7308                         /* Break here; otherwise, it'll disable the
7309                          * intended override.
7310                          */
7311                         break;
7312                 } else {
7313                         uint32_t nig_led_mode = ((params->hw_led_mode <<
7314                                              SHARED_HW_CFG_LED_MODE_SHIFT) ==
7315                                             SHARED_HW_CFG_LED_EXTPHY2) ?
7316                                 (SHARED_HW_CFG_LED_PHY1 >>
7317                                  SHARED_HW_CFG_LED_MODE_SHIFT) : hw_led_mode;
7318                         REG_WR(sc, NIG_REG_LED_MODE_P0 + port * 4,
7319                                nig_led_mode);
7320                 }
7321
7322                 REG_WR(sc, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port * 4,
7323                        0);
7324                 /* Set blinking rate to ~15.9Hz */
7325                 if (CHIP_IS_E3(sc))
7326                         REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port * 4,
7327                                LED_BLINK_RATE_VAL_E3);
7328                 else
7329                         REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port * 4,
7330                                LED_BLINK_RATE_VAL_E1X_E2);
7331                 REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
7332                        port * 4, 1);
7333                 tmp = elink_cb_reg_read(sc, emac_base + EMAC_REG_EMAC_LED);
7334                 elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED,
7335                         (tmp & (~EMAC_LED_OVERRIDE)));
7336
7337                 if (CHIP_IS_E1(sc) &&
7338                     ((speed == ELINK_SPEED_2500) ||
7339                      (speed == ELINK_SPEED_1000) ||
7340                      (speed == ELINK_SPEED_100) ||
7341                      (speed == ELINK_SPEED_10))) {
7342                         /* For speeds less than 10G LED scheme is different */
7343                         REG_WR(sc, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
7344                                + port * 4, 1);
7345                         REG_WR(sc, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
7346                                port * 4, 0);
7347                         REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
7348                                port * 4, 1);
7349                 }
7350                 break;
7351
7352         default:
7353                 rc = ELINK_STATUS_ERROR;
7354                 ELINK_DEBUG_P1(sc, "elink_set_led: Invalid led mode %d",
7355                          mode);
7356                 break;
7357         }
7358         return rc;
7359
7360 }
7361
7362 /* This function comes to reflect the actual link state read DIRECTLY from the
7363  * HW
7364  */
7365 elink_status_t elink_test_link(struct elink_params *params,
7366                                __rte_unused struct elink_vars *vars,
7367                     uint8_t is_serdes)
7368 {
7369         struct bnx2x_softc *sc = params->sc;
7370         uint16_t gp_status = 0, phy_index = 0;
7371         uint8_t ext_phy_link_up = 0, serdes_phy_type;
7372         struct elink_vars temp_vars;
7373         struct elink_phy *int_phy = &params->phy[ELINK_INT_PHY];
7374 #ifdef ELINK_INCLUDE_FPGA
7375         if (CHIP_REV_IS_FPGA(sc))
7376                 return ELINK_STATUS_OK;
7377 #endif
7378 #ifdef ELINK_INCLUDE_EMUL
7379         if (CHIP_REV_IS_EMUL(sc))
7380                 return ELINK_STATUS_OK;
7381 #endif
7382
7383         if (CHIP_IS_E3(sc)) {
7384                 uint16_t link_up;
7385                 if (params->req_line_speed[ELINK_LINK_CONFIG_IDX(ELINK_INT_PHY)]
7386                     > ELINK_SPEED_10000) {
7387                         /* Check 20G link */
7388                         elink_cl45_read(sc, int_phy, MDIO_WC_DEVAD,
7389                                         1, &link_up);
7390                         elink_cl45_read(sc, int_phy, MDIO_WC_DEVAD,
7391                                         1, &link_up);
7392                         link_up &= (1 << 2);
7393                 } else {
7394                         /* Check 10G link and below*/
7395                         uint8_t lane = elink_get_warpcore_lane(int_phy, params);
7396                         elink_cl45_read(sc, int_phy, MDIO_WC_DEVAD,
7397                                         MDIO_WC_REG_GP2_STATUS_GP_2_1,
7398                                         &gp_status);
7399                         gp_status = ((gp_status >> 8) & 0xf) |
7400                                 ((gp_status >> 12) & 0xf);
7401                         link_up = gp_status & (1 << lane);
7402                 }
7403                 if (!link_up)
7404                         return ELINK_STATUS_NO_LINK;
7405         } else {
7406                 CL22_RD_OVER_CL45(sc, int_phy,
7407                           MDIO_REG_BANK_GP_STATUS,
7408                           MDIO_GP_STATUS_TOP_AN_STATUS1,
7409                           &gp_status);
7410         /* Link is up only if both local phy and external phy are up */
7411         if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
7412                 return ELINK_STATUS_NO_LINK;
7413         }
7414         /* In XGXS loopback mode, do not check external PHY */
7415         if (params->loopback_mode == ELINK_LOOPBACK_XGXS)
7416                 return ELINK_STATUS_OK;
7417
7418         switch (params->num_phys) {
7419         case 1:
7420                 /* No external PHY */
7421                 return ELINK_STATUS_OK;
7422         case 2:
7423                 ext_phy_link_up = params->phy[ELINK_EXT_PHY1].read_status(
7424                         &params->phy[ELINK_EXT_PHY1],
7425                         params, &temp_vars);
7426                 break;
7427         case 3: /* Dual Media */
7428                 for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7429                       phy_index++) {
7430                         serdes_phy_type = ((params->phy[phy_index].media_type ==
7431                                             ELINK_ETH_PHY_SFPP_10G_FIBER) ||
7432                                            (params->phy[phy_index].media_type ==
7433                                             ELINK_ETH_PHY_SFP_1G_FIBER) ||
7434                                            (params->phy[phy_index].media_type ==
7435                                             ELINK_ETH_PHY_XFP_FIBER) ||
7436                                            (params->phy[phy_index].media_type ==
7437                                             ELINK_ETH_PHY_DA_TWINAX));
7438
7439                         if (is_serdes != serdes_phy_type)
7440                                 continue;
7441                         if (params->phy[phy_index].read_status) {
7442                                 ext_phy_link_up |=
7443                                         params->phy[phy_index].read_status(
7444                                                 &params->phy[phy_index],
7445                                                 params, &temp_vars);
7446                         }
7447                 }
7448                 break;
7449         }
7450         if (ext_phy_link_up)
7451                 return ELINK_STATUS_OK;
7452         return ELINK_STATUS_NO_LINK;
7453 }
7454
7455 static elink_status_t elink_link_initialize(struct elink_params *params,
7456                                  struct elink_vars *vars)
7457 {
7458         uint8_t phy_index, non_ext_phy;
7459         struct bnx2x_softc *sc = params->sc;
7460         /* In case of external phy existence, the line speed would be the
7461          * line speed linked up by the external phy. In case it is direct
7462          * only, then the line_speed during initialization will be
7463          * equal to the req_line_speed
7464          */
7465         vars->line_speed = params->phy[ELINK_INT_PHY].req_line_speed;
7466
7467         /* Initialize the internal phy in case this is a direct board
7468          * (no external phys), or this board has external phy which requires
7469          * to first.
7470          */
7471         if (!USES_WARPCORE(sc))
7472                 elink_prepare_xgxs(&params->phy[ELINK_INT_PHY], params, vars);
7473         /* init ext phy and enable link state int */
7474         non_ext_phy = (ELINK_SINGLE_MEDIA_DIRECT(params) ||
7475                        (params->loopback_mode == ELINK_LOOPBACK_XGXS));
7476
7477         if (non_ext_phy ||
7478             (params->phy[ELINK_EXT_PHY1].flags & ELINK_FLAGS_INIT_XGXS_FIRST) ||
7479             (params->loopback_mode == ELINK_LOOPBACK_EXT_PHY)) {
7480                 struct elink_phy *phy = &params->phy[ELINK_INT_PHY];
7481                 if (vars->line_speed == ELINK_SPEED_AUTO_NEG &&
7482                     (CHIP_IS_E1x(sc) ||
7483                      CHIP_IS_E2(sc)))
7484                         elink_set_parallel_detection(phy, params);
7485                 if (params->phy[ELINK_INT_PHY].config_init)
7486                         params->phy[ELINK_INT_PHY].config_init(phy, params,
7487                                                                vars);
7488         }
7489
7490         /* Re-read this value in case it was changed inside config_init due to
7491          * limitations of optic module
7492          */
7493         vars->line_speed = params->phy[ELINK_INT_PHY].req_line_speed;
7494
7495         /* Init external phy*/
7496         if (non_ext_phy) {
7497                 if (params->phy[ELINK_INT_PHY].supported &
7498                     ELINK_SUPPORTED_FIBRE)
7499                         vars->link_status |= LINK_STATUS_SERDES_LINK;
7500         } else {
7501                 for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7502                       phy_index++) {
7503                         /* No need to initialize second phy in case of first
7504                          * phy only selection. In case of second phy, we do
7505                          * need to initialize the first phy, since they are
7506                          * connected.
7507                          */
7508                         if (params->phy[phy_index].supported &
7509                             ELINK_SUPPORTED_FIBRE)
7510                                 vars->link_status |= LINK_STATUS_SERDES_LINK;
7511
7512                         if (phy_index == ELINK_EXT_PHY2 &&
7513                             (elink_phy_selection(params) ==
7514                              PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
7515                                 ELINK_DEBUG_P0(sc,
7516                                    "Not initializing second phy");
7517                                 continue;
7518                         }
7519                         params->phy[phy_index].config_init(
7520                                 &params->phy[phy_index],
7521                                 params, vars);
7522                 }
7523         }
7524         /* Reset the interrupt indication after phy was initialized */
7525         elink_bits_dis(sc, NIG_REG_STATUS_INTERRUPT_PORT0 +
7526                        params->port * 4,
7527                        (ELINK_NIG_STATUS_XGXS0_LINK10G |
7528                         ELINK_NIG_STATUS_XGXS0_LINK_STATUS |
7529                         ELINK_NIG_STATUS_SERDES0_LINK_STATUS |
7530                         ELINK_NIG_MASK_MI_INT));
7531         return ELINK_STATUS_OK;
7532 }
7533
7534 static void elink_int_link_reset(__rte_unused struct elink_phy *phy,
7535                                  struct elink_params *params)
7536 {
7537         /* Reset the SerDes/XGXS */
7538         REG_WR(params->sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
7539                (0x1ff << (params->port * 16)));
7540 }
7541
7542 static void elink_common_ext_link_reset(__rte_unused struct elink_phy *phy,
7543                                         struct elink_params *params)
7544 {
7545         struct bnx2x_softc *sc = params->sc;
7546         uint8_t gpio_port;
7547         /* HW reset */
7548         if (CHIP_IS_E2(sc))
7549                 gpio_port = SC_PATH(sc);
7550         else
7551                 gpio_port = params->port;
7552         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
7553                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
7554                        gpio_port);
7555         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
7556                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
7557                        gpio_port);
7558         ELINK_DEBUG_P0(sc, "reset external PHY");
7559 }
7560
7561 static elink_status_t elink_update_link_down(struct elink_params *params,
7562                                   struct elink_vars *vars)
7563 {
7564         struct bnx2x_softc *sc = params->sc;
7565         uint8_t port = params->port;
7566
7567         ELINK_DEBUG_P1(sc, "Port %x: Link is down", port);
7568         elink_set_led(params, vars, ELINK_LED_MODE_OFF, 0);
7569         vars->phy_flags &= ~PHY_PHYSICAL_LINK_FLAG;
7570         /* Indicate no mac active */
7571         vars->mac_type = ELINK_MAC_TYPE_NONE;
7572
7573         /* Update shared memory */
7574         vars->link_status &= ~ELINK_LINK_UPDATE_MASK;
7575         vars->line_speed = 0;
7576         elink_update_mng(params, vars->link_status);
7577
7578         /* Activate nig drain */
7579         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + port * 4, 1);
7580
7581         /* Disable emac */
7582         if (!CHIP_IS_E3(sc))
7583                 REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port * 4, 0);
7584
7585         DELAY(1000 * 10);
7586         /* Reset BigMac/Xmac */
7587         if (CHIP_IS_E1x(sc) ||
7588             CHIP_IS_E2(sc))
7589                 elink_set_bmac_rx(sc, params->chip_id, params->port, 0);
7590
7591         if (CHIP_IS_E3(sc)) {
7592                 /* Prevent LPI Generation by chip */
7593                 REG_WR(sc, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2),
7594                        0);
7595                 REG_WR(sc, MISC_REG_CPMU_LP_MASK_ENT_P0 + (params->port << 2),
7596                        0);
7597                 vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
7598                                       SHMEM_EEE_ACTIVE_BIT);
7599
7600                 elink_update_mng_eee(params, vars->eee_status);
7601                 elink_set_xmac_rxtx(params, 0);
7602                 elink_set_umac_rxtx(params, 0);
7603         }
7604
7605         return ELINK_STATUS_OK;
7606 }
7607
7608 static elink_status_t elink_update_link_up(struct elink_params *params,
7609                                 struct elink_vars *vars,
7610                                 uint8_t link_10g)
7611 {
7612         struct bnx2x_softc *sc = params->sc;
7613         uint8_t phy_idx, port = params->port;
7614         elink_status_t rc = ELINK_STATUS_OK;
7615
7616         vars->link_status |= (LINK_STATUS_LINK_UP |
7617                               LINK_STATUS_PHYSICAL_LINK_FLAG);
7618         vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
7619
7620         if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
7621                 vars->link_status |=
7622                         LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
7623
7624         if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
7625                 vars->link_status |=
7626                         LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
7627         if (USES_WARPCORE(sc)) {
7628                 if (link_10g) {
7629                         if (elink_xmac_enable(params, vars, 0) ==
7630                             ELINK_STATUS_NO_LINK) {
7631                                 ELINK_DEBUG_P0(sc, "Found errors on XMAC");
7632                                 vars->link_up = 0;
7633                                 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
7634                                 vars->link_status &= ~LINK_STATUS_LINK_UP;
7635                         }
7636                 } else
7637                         elink_umac_enable(params, vars, 0);
7638                 elink_set_led(params, vars,
7639                               ELINK_LED_MODE_OPER, vars->line_speed);
7640
7641                 if ((vars->eee_status & SHMEM_EEE_ACTIVE_BIT) &&
7642                     (vars->eee_status & SHMEM_EEE_LPI_REQUESTED_BIT)) {
7643                         ELINK_DEBUG_P0(sc, "Enabling LPI assertion");
7644                         REG_WR(sc, MISC_REG_CPMU_LP_FW_ENABLE_P0 +
7645                                (params->port << 2), 1);
7646                         REG_WR(sc, MISC_REG_CPMU_LP_DR_ENABLE, 1);
7647                         REG_WR(sc, MISC_REG_CPMU_LP_MASK_ENT_P0 +
7648                                (params->port << 2), 0xfc20);
7649                 }
7650         }
7651         if ((CHIP_IS_E1x(sc) ||
7652              CHIP_IS_E2(sc))) {
7653                 if (link_10g) {
7654                         if (elink_bmac_enable(params, vars, 0, 1) ==
7655                             ELINK_STATUS_NO_LINK) {
7656                                 ELINK_DEBUG_P0(sc, "Found errors on BMAC");
7657                                 vars->link_up = 0;
7658                                 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
7659                                 vars->link_status &= ~LINK_STATUS_LINK_UP;
7660                         }
7661
7662                         elink_set_led(params, vars,
7663                                       ELINK_LED_MODE_OPER, ELINK_SPEED_10000);
7664                 } else {
7665                         rc = elink_emac_program(params, vars);
7666                         elink_emac_enable(params, vars, 0);
7667
7668                         /* AN complete? */
7669                         if ((vars->link_status &
7670                              LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
7671                             && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
7672                             ELINK_SINGLE_MEDIA_DIRECT(params))
7673                                 elink_set_gmii_tx_driver(params);
7674                 }
7675         }
7676
7677         /* PBF - link up */
7678         if (CHIP_IS_E1x(sc))
7679                 rc |= elink_pbf_update(params, vars->flow_ctrl,
7680                                        vars->line_speed);
7681
7682         /* Disable drain */
7683         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + port * 4, 0);
7684
7685         /* Update shared memory */
7686         elink_update_mng(params, vars->link_status);
7687         elink_update_mng_eee(params, vars->eee_status);
7688         /* Check remote fault */
7689         for (phy_idx = ELINK_INT_PHY; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
7690                 if (params->phy[phy_idx].flags & ELINK_FLAGS_TX_ERROR_CHECK) {
7691                         elink_check_half_open_conn(params, vars, 0);
7692                         break;
7693                 }
7694         }
7695         DELAY(1000 * 20);
7696         return rc;
7697 }
7698
7699 static void elink_chng_link_count(struct elink_params *params, uint8_t clear)
7700 {
7701         struct bnx2x_softc *sc = params->sc;
7702         uint32_t addr, val;
7703
7704         /* Verify the link_change_count is supported by the MFW */
7705         if (!(SHMEM2_HAS(sc, link_change_count)))
7706                 return;
7707
7708         addr = params->shmem2_base +
7709                 offsetof(struct shmem2_region, link_change_count[params->port]);
7710         if (clear)
7711                 val = 0;
7712         else
7713                 val = REG_RD(sc, addr) + 1;
7714         REG_WR(sc, addr, val);
7715 }
7716
7717 /* The elink_link_update function should be called upon link
7718  * interrupt.
7719  * Link is considered up as follows:
7720  * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
7721  *   to be up
7722  * - SINGLE_MEDIA - The link between the 577xx and the external
7723  *   phy (XGXS) need to up as well as the external link of the
7724  *   phy (PHY_EXT1)
7725  * - DUAL_MEDIA - The link between the 577xx and the first
7726  *   external phy needs to be up, and at least one of the 2
7727  *   external phy link must be up.
7728  */
7729 elink_status_t elink_link_update(struct elink_params *params,
7730                                  struct elink_vars *vars)
7731 {
7732         struct bnx2x_softc *sc = params->sc;
7733         struct elink_vars phy_vars[ELINK_MAX_PHYS];
7734         uint8_t port = params->port;
7735         uint8_t link_10g_plus, phy_index;
7736         uint32_t prev_link_status = vars->link_status;
7737         uint8_t ext_phy_link_up = 0, cur_link_up;
7738         elink_status_t rc = ELINK_STATUS_OK;
7739         uint16_t ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
7740         uint8_t active_external_phy = ELINK_INT_PHY;
7741         vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
7742         vars->link_status &= ~ELINK_LINK_UPDATE_MASK;
7743         for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
7744               phy_index++) {
7745                 phy_vars[phy_index].flow_ctrl = 0;
7746                 phy_vars[phy_index].link_status = 0;
7747                 phy_vars[phy_index].line_speed = 0;
7748                 phy_vars[phy_index].duplex = DUPLEX_FULL;
7749                 phy_vars[phy_index].phy_link_up = 0;
7750                 phy_vars[phy_index].link_up = 0;
7751                 phy_vars[phy_index].fault_detected = 0;
7752                 /* different consideration, since vars holds inner state */
7753                 phy_vars[phy_index].eee_status = vars->eee_status;
7754         }
7755
7756         if (USES_WARPCORE(sc))
7757                 elink_set_aer_mmd(params, &params->phy[ELINK_INT_PHY]);
7758
7759         ELINK_DEBUG_P3(sc, "port %x, XGXS?%x, int_status 0x%x",
7760                  port, (vars->phy_flags & PHY_XGXS_FLAG),
7761                  REG_RD(sc, NIG_REG_STATUS_INTERRUPT_PORT0 + port * 4));
7762
7763         ELINK_DEBUG_P3(sc, "int_mask 0x%x MI_INT %x, SERDES_LINK %x",
7764                  REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 + port * 4),
7765                  REG_RD(sc, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port * 0x18) > 0,
7766                  REG_RD(sc, NIG_REG_SERDES0_STATUS_LINK_STATUS + port * 0x3c));
7767
7768         ELINK_DEBUG_P2(sc, " 10G %x, XGXS_LINK %x",
7769           REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK10G + port * 0x68),
7770           REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK_STATUS + port * 0x68));
7771
7772         /* Disable emac */
7773         if (!CHIP_IS_E3(sc))
7774                 REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port * 4, 0);
7775
7776         /* Step 1:
7777          * Check external link change only for external phys, and apply
7778          * priority selection between them in case the link on both phys
7779          * is up. Note that instead of the common vars, a temporary
7780          * vars argument is used since each phy may have different link/
7781          * speed/duplex result
7782          */
7783         for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7784               phy_index++) {
7785                 struct elink_phy *phy = &params->phy[phy_index];
7786                 if (!phy->read_status)
7787                         continue;
7788                 /* Read link status and params of this ext phy */
7789                 cur_link_up = phy->read_status(phy, params,
7790                                                &phy_vars[phy_index]);
7791                 if (cur_link_up) {
7792                         ELINK_DEBUG_P1(sc, "phy in index %d link is up",
7793                                    phy_index);
7794                 } else {
7795                         ELINK_DEBUG_P1(sc, "phy in index %d link is down",
7796                                    phy_index);
7797                         continue;
7798                 }
7799
7800                 if (!ext_phy_link_up) {
7801                         ext_phy_link_up = 1;
7802                         active_external_phy = phy_index;
7803                 } else {
7804                         switch (elink_phy_selection(params)) {
7805                         case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
7806                         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
7807                         /* In this option, the first PHY makes sure to pass the
7808                          * traffic through itself only.
7809                          * Its not clear how to reset the link on the second phy
7810                          */
7811                                 active_external_phy = ELINK_EXT_PHY1;
7812                                 break;
7813                         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
7814                         /* In this option, the first PHY makes sure to pass the
7815                          * traffic through the second PHY.
7816                          */
7817                                 active_external_phy = ELINK_EXT_PHY2;
7818                                 break;
7819                         default:
7820                         /* Link indication on both PHYs with the following cases
7821                          * is invalid:
7822                          * - FIRST_PHY means that second phy wasn't initialized,
7823                          * hence its link is expected to be down
7824                          * - SECOND_PHY means that first phy should not be able
7825                          * to link up by itself (using configuration)
7826                          * - DEFAULT should be overridden during initialiazation
7827                          */
7828                                 ELINK_DEBUG_P1(sc, "Invalid link indication"
7829                                                " mpc=0x%x. DISABLING LINK !!!",
7830                                            params->multi_phy_config);
7831                                 ext_phy_link_up = 0;
7832                                 break;
7833                         }
7834                 }
7835         }
7836         prev_line_speed = vars->line_speed;
7837         /* Step 2:
7838          * Read the status of the internal phy. In case of
7839          * DIRECT_SINGLE_MEDIA board, this link is the external link,
7840          * otherwise this is the link between the 577xx and the first
7841          * external phy
7842          */
7843         if (params->phy[ELINK_INT_PHY].read_status)
7844                 params->phy[ELINK_INT_PHY].read_status(
7845                         &params->phy[ELINK_INT_PHY],
7846                         params, vars);
7847         /* The INT_PHY flow control reside in the vars. This include the
7848          * case where the speed or flow control are not set to AUTO.
7849          * Otherwise, the active external phy flow control result is set
7850          * to the vars. The ext_phy_line_speed is needed to check if the
7851          * speed is different between the internal phy and external phy.
7852          * This case may be result of intermediate link speed change.
7853          */
7854         if (active_external_phy > ELINK_INT_PHY) {
7855                 vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
7856                 /* Link speed is taken from the XGXS. AN and FC result from
7857                  * the external phy.
7858                  */
7859                 vars->link_status |= phy_vars[active_external_phy].link_status;
7860
7861                 /* if active_external_phy is first PHY and link is up - disable
7862                  * disable TX on second external PHY
7863                  */
7864                 if (active_external_phy == ELINK_EXT_PHY1) {
7865                         if (params->phy[ELINK_EXT_PHY2].phy_specific_func) {
7866                                 ELINK_DEBUG_P0(sc,
7867                                    "Disabling TX on EXT_PHY2");
7868                                 params->phy[ELINK_EXT_PHY2].phy_specific_func(
7869                                         &params->phy[ELINK_EXT_PHY2],
7870                                         params, ELINK_DISABLE_TX);
7871                         }
7872                 }
7873
7874                 ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
7875                 vars->duplex = phy_vars[active_external_phy].duplex;
7876                 if (params->phy[active_external_phy].supported &
7877                     ELINK_SUPPORTED_FIBRE)
7878                         vars->link_status |= LINK_STATUS_SERDES_LINK;
7879                 else
7880                         vars->link_status &= ~LINK_STATUS_SERDES_LINK;
7881
7882                 vars->eee_status = phy_vars[active_external_phy].eee_status;
7883
7884                 ELINK_DEBUG_P1(sc, "Active external phy selected: %x",
7885                            active_external_phy);
7886         }
7887
7888         ELINK_DEBUG_P3(sc, "vars : phy_flags = %x, mac_type = %x, phy_link_up = %x",
7889                        vars->phy_flags, vars->mac_type, vars->phy_link_up);
7890         ELINK_DEBUG_P3(sc, "vars : link_up = %x, line_speed = %x, duplex = %x",
7891                        vars->link_up, vars->line_speed, vars->duplex);
7892         ELINK_DEBUG_P3(sc, "vars : flow_ctrl = %x, ieee_fc = %x, link_status = %x",
7893                        vars->flow_ctrl, vars->ieee_fc, vars->link_status);
7894         ELINK_DEBUG_P3(sc, "vars : eee_status = %x, fault_detected = %x, check_kr2_recovery_cnt = %x",
7895                        vars->eee_status, vars->fault_detected,
7896                        vars->check_kr2_recovery_cnt);
7897         ELINK_DEBUG_P3(sc, "vars : periodic_flags = %x, aeu_int_mask = %x, rx_tx_asic_rst = %x",
7898                        vars->periodic_flags, vars->aeu_int_mask,
7899                        vars->rx_tx_asic_rst);
7900         ELINK_DEBUG_P2(sc, "vars : turn_to_run_wc_rt = %x, rsrv2 = %x",
7901                        vars->turn_to_run_wc_rt, vars->rsrv2);
7902
7903         for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7904               phy_index++) {
7905                 if (params->phy[phy_index].flags &
7906                     ELINK_FLAGS_REARM_LATCH_SIGNAL) {
7907                         elink_rearm_latch_signal(sc, port,
7908                                                  phy_index ==
7909                                                  active_external_phy);
7910                         break;
7911                 }
7912         }
7913         ELINK_DEBUG_P3(sc, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
7914                    " ext_phy_line_speed = %d", vars->flow_ctrl,
7915                    vars->link_status, ext_phy_line_speed);
7916         /* Upon link speed change set the NIG into drain mode. Comes to
7917          * deals with possible FIFO glitch due to clk change when speed
7918          * is decreased without link down indicator
7919          */
7920
7921         if (vars->phy_link_up) {
7922                 if (!(ELINK_SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
7923                     (ext_phy_line_speed != vars->line_speed)) {
7924                         ELINK_DEBUG_P2(sc, "Internal link speed %d is"
7925                                    " different than the external"
7926                                    " link speed %d", vars->line_speed,
7927                                    ext_phy_line_speed);
7928                         vars->phy_link_up = 0;
7929                         ELINK_DEBUG_P0(sc, "phy_link_up set to 0");
7930                 } else if (prev_line_speed != vars->line_speed) {
7931                         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE +
7932                                params->port * 4, 0);
7933                         DELAY(1000 * 1);
7934                 }
7935         }
7936
7937         /* Anything 10 and over uses the bmac */
7938         link_10g_plus = (vars->line_speed >= ELINK_SPEED_10000);
7939
7940         elink_link_int_ack(params, vars, link_10g_plus);
7941
7942         /* In case external phy link is up, and internal link is down
7943          * (not initialized yet probably after link initialization, it
7944          * needs to be initialized.
7945          * Note that after link down-up as result of cable plug, the xgxs
7946          * link would probably become up again without the need
7947          * initialize it
7948          */
7949         if (!(ELINK_SINGLE_MEDIA_DIRECT(params))) {
7950                 ELINK_DEBUG_P3(sc, "ext_phy_link_up = %d, int_link_up = %d,"
7951                            " init_preceding = %d", ext_phy_link_up,
7952                            vars->phy_link_up,
7953                            params->phy[ELINK_EXT_PHY1].flags &
7954                            ELINK_FLAGS_INIT_XGXS_FIRST);
7955                 if (!(params->phy[ELINK_EXT_PHY1].flags &
7956                       ELINK_FLAGS_INIT_XGXS_FIRST)
7957                     && ext_phy_link_up && !vars->phy_link_up) {
7958                         vars->line_speed = ext_phy_line_speed;
7959                         if (vars->line_speed < ELINK_SPEED_1000)
7960                                 vars->phy_flags |= PHY_SGMII_FLAG;
7961                         else
7962                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
7963
7964                         if (params->phy[ELINK_INT_PHY].config_init)
7965                                 params->phy[ELINK_INT_PHY].config_init(
7966                                         &params->phy[ELINK_INT_PHY], params,
7967                                                 vars);
7968                 }
7969         }
7970         /* Link is up only if both local phy and external phy (in case of
7971          * non-direct board) are up and no fault detected on active PHY.
7972          */
7973         vars->link_up = (vars->phy_link_up &&
7974                          (ext_phy_link_up ||
7975                           ELINK_SINGLE_MEDIA_DIRECT(params)) &&
7976                          (phy_vars[active_external_phy].fault_detected == 0));
7977
7978         if (vars->link_up)
7979                 ELINK_DEBUG_P0(sc, "local phy and external phy are up");
7980         else
7981                 ELINK_DEBUG_P0(sc, "either local phy or external phy or both are down");
7982
7983         /* Update the PFC configuration in case it was changed */
7984         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
7985                 vars->link_status |= LINK_STATUS_PFC_ENABLED;
7986         else
7987                 vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
7988
7989         if (vars->link_up)
7990                 rc = elink_update_link_up(params, vars, link_10g_plus);
7991         else
7992                 rc = elink_update_link_down(params, vars);
7993
7994         if ((prev_link_status ^ vars->link_status) & LINK_STATUS_LINK_UP)
7995                 elink_chng_link_count(params, 0);
7996
7997         /* Update MCP link status was changed */
7998         if (params->feature_config_flags &
7999             ELINK_FEATURE_CONFIG_BC_SUPPORTS_AFEX)
8000                 elink_cb_fw_command(sc, DRV_MSG_CODE_LINK_STATUS_CHANGED, 0);
8001
8002         return rc;
8003 }
8004
8005 /*****************************************************************************/
8006 /*                          External Phy section                             */
8007 /*****************************************************************************/
8008 void elink_ext_phy_hw_reset(struct bnx2x_softc *sc, uint8_t port)
8009 {
8010         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
8011                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
8012         DELAY(1000 * 1);
8013         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
8014                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
8015 }
8016
8017 static void elink_save_spirom_version(struct bnx2x_softc *sc, uint8_t port,
8018                                       uint32_t spirom_ver, uint32_t ver_addr)
8019 {
8020         ELINK_DEBUG_P3(sc, "FW version 0x%x:0x%x for port %d",
8021                  (uint16_t)(spirom_ver >> 16), (uint16_t)spirom_ver, port);
8022
8023         if (ver_addr)
8024                 REG_WR(sc, ver_addr, spirom_ver);
8025 }
8026
8027 static void elink_save_bnx2x_spirom_ver(struct bnx2x_softc *sc,
8028                                       struct elink_phy *phy,
8029                                       uint8_t port)
8030 {
8031         uint16_t fw_ver1, fw_ver2;
8032
8033         elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
8034                         MDIO_PMA_REG_ROM_VER1, &fw_ver1);
8035         elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
8036                         MDIO_PMA_REG_ROM_VER2, &fw_ver2);
8037         elink_save_spirom_version(sc, port, (uint32_t)(fw_ver1 << 16 | fw_ver2),
8038                                   phy->ver_addr);
8039 }
8040
8041 static void elink_ext_phy_10G_an_resolve(struct bnx2x_softc *sc,
8042                                        struct elink_phy *phy,
8043                                        struct elink_vars *vars)
8044 {
8045         uint16_t val;
8046         elink_cl45_read(sc, phy,
8047                         MDIO_AN_DEVAD,
8048                         MDIO_AN_REG_STATUS, &val);
8049         elink_cl45_read(sc, phy,
8050                         MDIO_AN_DEVAD,
8051                         MDIO_AN_REG_STATUS, &val);
8052         if (val & (1 << 5))
8053                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
8054         if ((val & (1 << 0)) == 0)
8055                 vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
8056 }
8057
8058 /******************************************************************/
8059 /*              common BNX2X8073/BNX2X8727 PHY SECTION            */
8060 /******************************************************************/
8061 static void elink_8073_resolve_fc(struct elink_phy *phy,
8062                                   struct elink_params *params,
8063                                   struct elink_vars *vars)
8064 {
8065         struct bnx2x_softc *sc = params->sc;
8066         if (phy->req_line_speed == ELINK_SPEED_10 ||
8067             phy->req_line_speed == ELINK_SPEED_100) {
8068                 vars->flow_ctrl = phy->req_flow_ctrl;
8069                 return;
8070         }
8071
8072         if (elink_ext_phy_resolve_fc(phy, params, vars) &&
8073             (vars->flow_ctrl == ELINK_FLOW_CTRL_NONE)) {
8074                 uint16_t pause_result;
8075                 uint16_t ld_pause;              /* local */
8076                 uint16_t lp_pause;              /* link partner */
8077                 elink_cl45_read(sc, phy,
8078                                 MDIO_AN_DEVAD,
8079                                 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
8080
8081                 elink_cl45_read(sc, phy,
8082                                 MDIO_AN_DEVAD,
8083                                 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
8084                 pause_result = (ld_pause &
8085                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
8086                 pause_result |= (lp_pause &
8087                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
8088
8089                 elink_pause_resolve(phy, params, vars, pause_result);
8090                 ELINK_DEBUG_P1(sc, "Ext PHY CL37 pause result 0x%x",
8091                            pause_result);
8092         }
8093 }
8094 static elink_status_t elink_8073_8727_external_rom_boot(struct bnx2x_softc *sc,
8095                                              struct elink_phy *phy,
8096                                              uint8_t port)
8097 {
8098         uint32_t count = 0;
8099         uint16_t fw_ver1, fw_msgout;
8100         elink_status_t rc = ELINK_STATUS_OK;
8101
8102         /* Boot port from external ROM  */
8103         /* EDC grst */
8104         elink_cl45_write(sc, phy,
8105                          MDIO_PMA_DEVAD,
8106                          MDIO_PMA_REG_GEN_CTRL,
8107                          0x0001);
8108
8109         /* Ucode reboot and rst */
8110         elink_cl45_write(sc, phy,
8111                          MDIO_PMA_DEVAD,
8112                          MDIO_PMA_REG_GEN_CTRL,
8113                          0x008c);
8114
8115         elink_cl45_write(sc, phy,
8116                          MDIO_PMA_DEVAD,
8117                          MDIO_PMA_REG_MISC_CTRL1, 0x0001);
8118
8119         /* Reset internal microprocessor */
8120         elink_cl45_write(sc, phy,
8121                          MDIO_PMA_DEVAD,
8122                          MDIO_PMA_REG_GEN_CTRL,
8123                          MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
8124
8125         /* Release srst bit */
8126         elink_cl45_write(sc, phy,
8127                          MDIO_PMA_DEVAD,
8128                          MDIO_PMA_REG_GEN_CTRL,
8129                          MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
8130
8131         /* Delay 100ms per the PHY specifications */
8132         DELAY(1000 * 100);
8133
8134         /* 8073 sometimes taking longer to download */
8135         do {
8136                 count++;
8137                 if (count > 300) {
8138                         ELINK_DEBUG_P2(sc,
8139                                  "elink_8073_8727_external_rom_boot port %x:"
8140                                  "Download failed. fw version = 0x%x",
8141                                  port, fw_ver1);
8142                         rc = ELINK_STATUS_ERROR;
8143                         break;
8144                 }
8145
8146                 elink_cl45_read(sc, phy,
8147                                 MDIO_PMA_DEVAD,
8148                                 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
8149                 elink_cl45_read(sc, phy,
8150                                 MDIO_PMA_DEVAD,
8151                                 MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
8152
8153                 DELAY(1000 * 1);
8154         } while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
8155                         ((fw_msgout & 0xff) != 0x03 && (phy->type ==
8156                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8073)));
8157
8158         /* Clear ser_boot_ctl bit */
8159         elink_cl45_write(sc, phy,
8160                          MDIO_PMA_DEVAD,
8161                          MDIO_PMA_REG_MISC_CTRL1, 0x0000);
8162         elink_save_bnx2x_spirom_ver(sc, phy, port);
8163
8164         ELINK_DEBUG_P2(sc,
8165                  "elink_8073_8727_external_rom_boot port %x:"
8166                  "Download complete. fw version = 0x%x",
8167                  port, fw_ver1);
8168
8169         return rc;
8170 }
8171
8172 /******************************************************************/
8173 /*                      BNX2X8073 PHY SECTION                     */
8174 /******************************************************************/
8175 static elink_status_t elink_8073_is_snr_needed(struct bnx2x_softc *sc,
8176                                                struct elink_phy *phy)
8177 {
8178         /* This is only required for 8073A1, version 102 only */
8179         uint16_t val;
8180
8181         /* Read 8073 HW revision*/
8182         elink_cl45_read(sc, phy,
8183                         MDIO_PMA_DEVAD,
8184                         MDIO_PMA_REG_8073_CHIP_REV, &val);
8185
8186         if (val != 1) {
8187                 /* No need to workaround in 8073 A1 */
8188                 return ELINK_STATUS_OK;
8189         }
8190
8191         elink_cl45_read(sc, phy,
8192                         MDIO_PMA_DEVAD,
8193                         MDIO_PMA_REG_ROM_VER2, &val);
8194
8195         /* SNR should be applied only for version 0x102 */
8196         if (val != 0x102)
8197                 return ELINK_STATUS_OK;
8198
8199         return 1;
8200 }
8201
8202 static elink_status_t elink_8073_xaui_wa(struct bnx2x_softc *sc,
8203                                          struct elink_phy *phy)
8204 {
8205         uint16_t val, cnt, cnt1;
8206
8207         elink_cl45_read(sc, phy,
8208                         MDIO_PMA_DEVAD,
8209                         MDIO_PMA_REG_8073_CHIP_REV, &val);
8210
8211         if (val > 0) {
8212                 /* No need to workaround in 8073 A1 */
8213                 return ELINK_STATUS_OK;
8214         }
8215         /* XAUI workaround in 8073 A0: */
8216
8217         /* After loading the boot ROM and restarting Autoneg, poll
8218          * Dev1, Reg $C820:
8219          */
8220
8221         for (cnt = 0; cnt < 1000; cnt++) {
8222                 elink_cl45_read(sc, phy,
8223                                 MDIO_PMA_DEVAD,
8224                                 MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
8225                                 &val);
8226                   /* If bit [14] = 0 or bit [13] = 0, continue on with
8227                    * system initialization (XAUI work-around not required, as
8228                    * these bits indicate 2.5G or 1G link up).
8229                    */
8230                 if (!(val & (1 << 14)) || !(val & (1 << 13))) {
8231                         ELINK_DEBUG_P0(sc, "XAUI work-around not required");
8232                         return ELINK_STATUS_OK;
8233                 } else if (!(val & (1 << 15))) {
8234                         ELINK_DEBUG_P0(sc, "bit 15 went off");
8235                         /* If bit 15 is 0, then poll Dev1, Reg $C841 until it's
8236                          * MSB (bit15) goes to 1 (indicating that the XAUI
8237                          * workaround has completed), then continue on with
8238                          * system initialization.
8239                          */
8240                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
8241                                 elink_cl45_read(sc, phy,
8242                                         MDIO_PMA_DEVAD,
8243                                         MDIO_PMA_REG_8073_XAUI_WA, &val);
8244                                 if (val & (1 << 15)) {
8245                                         ELINK_DEBUG_P0(sc,
8246                                           "XAUI workaround has completed");
8247                                         return ELINK_STATUS_OK;
8248                                 }
8249                                 DELAY(1000 * 3);
8250                         }
8251                         break;
8252                 }
8253                 DELAY(1000 * 3);
8254         }
8255         ELINK_DEBUG_P0(sc, "Warning: XAUI work-around timeout !!!");
8256         return ELINK_STATUS_ERROR;
8257 }
8258
8259 static void elink_807x_force_10G(struct bnx2x_softc *sc, struct elink_phy *phy)
8260 {
8261         /* Force KR or KX */
8262         elink_cl45_write(sc, phy,
8263                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
8264         elink_cl45_write(sc, phy,
8265                          MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
8266         elink_cl45_write(sc, phy,
8267                          MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
8268         elink_cl45_write(sc, phy,
8269                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
8270 }
8271
8272 static void elink_8073_set_pause_cl37(struct elink_params *params,
8273                                       struct elink_phy *phy,
8274                                       struct elink_vars *vars)
8275 {
8276         uint16_t cl37_val;
8277         struct bnx2x_softc *sc = params->sc;
8278         elink_cl45_read(sc, phy,
8279                         MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
8280
8281         cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
8282         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
8283         elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
8284         if ((vars->ieee_fc &
8285             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
8286             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
8287                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
8288         }
8289         if ((vars->ieee_fc &
8290             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
8291             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
8292                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
8293         }
8294         if ((vars->ieee_fc &
8295             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
8296             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
8297                 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
8298         }
8299         ELINK_DEBUG_P1(sc,
8300                  "Ext phy AN advertize cl37 0x%x", cl37_val);
8301
8302         elink_cl45_write(sc, phy,
8303                          MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
8304         DELAY(1000 * 500);
8305 }
8306
8307 static void elink_8073_specific_func(struct elink_phy *phy,
8308                                      struct elink_params *params,
8309                                      uint32_t action)
8310 {
8311         struct bnx2x_softc *sc = params->sc;
8312         switch (action) {
8313         case ELINK_PHY_INIT:
8314                 /* Enable LASI */
8315                 elink_cl45_write(sc, phy,
8316                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8317                                  (1 << 2));
8318                 elink_cl45_write(sc, phy,
8319                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,  0x0004);
8320                 break;
8321         }
8322 }
8323
8324 static uint8_t elink_8073_config_init(struct elink_phy *phy,
8325                                   struct elink_params *params,
8326                                   struct elink_vars *vars)
8327 {
8328         struct bnx2x_softc *sc = params->sc;
8329         uint16_t val = 0, tmp1;
8330         uint8_t gpio_port;
8331         ELINK_DEBUG_P0(sc, "Init 8073");
8332
8333         if (CHIP_IS_E2(sc))
8334                 gpio_port = SC_PATH(sc);
8335         else
8336                 gpio_port = params->port;
8337         /* Restore normal power mode*/
8338         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
8339                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
8340
8341         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
8342                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
8343
8344         elink_8073_specific_func(phy, params, ELINK_PHY_INIT);
8345         elink_8073_set_pause_cl37(params, phy, vars);
8346
8347         elink_cl45_read(sc, phy,
8348                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
8349
8350         elink_cl45_read(sc, phy,
8351                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
8352
8353         ELINK_DEBUG_P1(sc, "Before rom RX_ALARM(port1): 0x%x", tmp1);
8354
8355         /* Swap polarity if required - Must be done only in non-1G mode */
8356         if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
8357                 /* Configure the 8073 to swap _P and _N of the KR lines */
8358                 ELINK_DEBUG_P0(sc, "Swapping polarity for the 8073");
8359                 /* 10G Rx/Tx and 1G Tx signal polarity swap */
8360                 elink_cl45_read(sc, phy,
8361                                 MDIO_PMA_DEVAD,
8362                                 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
8363                 elink_cl45_write(sc, phy,
8364                                  MDIO_PMA_DEVAD,
8365                                  MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
8366                                  (val | (3 << 9)));
8367         }
8368
8369
8370         /* Enable CL37 BAM */
8371         if (REG_RD(sc, params->shmem_base +
8372                          offsetof(struct shmem_region, dev_info.
8373                                   port_hw_config[params->port].default_cfg)) &
8374             PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
8375
8376                 elink_cl45_read(sc, phy,
8377                                 MDIO_AN_DEVAD,
8378                                 MDIO_AN_REG_8073_BAM, &val);
8379                 elink_cl45_write(sc, phy,
8380                                  MDIO_AN_DEVAD,
8381                                  MDIO_AN_REG_8073_BAM, val | 1);
8382                 ELINK_DEBUG_P0(sc, "Enable CL37 BAM on KR");
8383         }
8384         if (params->loopback_mode == ELINK_LOOPBACK_EXT) {
8385                 elink_807x_force_10G(sc, phy);
8386                 ELINK_DEBUG_P0(sc, "Forced speed 10G on 807X");
8387                 return ELINK_STATUS_OK;
8388         } else {
8389                 elink_cl45_write(sc, phy,
8390                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
8391         }
8392         if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG) {
8393                 if (phy->req_line_speed == ELINK_SPEED_10000) {
8394                         val = (1 << 7);
8395                 } else if (phy->req_line_speed ==  ELINK_SPEED_2500) {
8396                         val = (1 << 5);
8397                         /* Note that 2.5G works only when used with 1G
8398                          * advertisement
8399                          */
8400                 } else
8401                         val = (1 << 5);
8402         } else {
8403                 val = 0;
8404                 if (phy->speed_cap_mask &
8405                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
8406                         val |= (1 << 7);
8407
8408                 /* Note that 2.5G works only when used with 1G advertisement */
8409                 if (phy->speed_cap_mask &
8410                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
8411                          PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
8412                         val |= (1 << 5);
8413                 ELINK_DEBUG_P1(sc, "807x autoneg val = 0x%x", val);
8414         }
8415
8416         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
8417         elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
8418
8419         if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
8420              (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)) ||
8421             (phy->req_line_speed == ELINK_SPEED_2500)) {
8422                 uint16_t phy_ver;
8423                 /* Allow 2.5G for A1 and above */
8424                 elink_cl45_read(sc, phy,
8425                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
8426                                 &phy_ver);
8427                 ELINK_DEBUG_P0(sc, "Add 2.5G");
8428                 if (phy_ver > 0)
8429                         tmp1 |= 1;
8430                 else
8431                         tmp1 &= 0xfffe;
8432         } else {
8433                 ELINK_DEBUG_P0(sc, "Disable 2.5G");
8434                 tmp1 &= 0xfffe;
8435         }
8436
8437         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
8438         /* Add support for CL37 (passive mode) II */
8439
8440         elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
8441         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
8442                          (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
8443                                   0x20 : 0x40)));
8444
8445         /* Add support for CL37 (passive mode) III */
8446         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8447
8448         /* The SNR will improve about 2db by changing BW and FEE main
8449          * tap. Rest commands are executed after link is up
8450          * Change FFE main cursor to 5 in EDC register
8451          */
8452         if (elink_8073_is_snr_needed(sc, phy))
8453                 elink_cl45_write(sc, phy,
8454                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
8455                                  0xFB0C);
8456
8457         /* Enable FEC (Forware Error Correction) Request in the AN */
8458         elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
8459         tmp1 |= (1 << 15);
8460         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
8461
8462         elink_ext_phy_set_pause(params, phy, vars);
8463
8464         /* Restart autoneg */
8465         DELAY(1000 * 500);
8466         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
8467         ELINK_DEBUG_P2(sc, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x",
8468                    ((val & (1 << 5)) > 0), ((val & (1 << 7)) > 0));
8469         return ELINK_STATUS_OK;
8470 }
8471
8472 static uint8_t elink_8073_read_status(struct elink_phy *phy,
8473                                  struct elink_params *params,
8474                                  struct elink_vars *vars)
8475 {
8476         struct bnx2x_softc *sc = params->sc;
8477         uint8_t link_up = 0;
8478         uint16_t val1, val2;
8479         uint16_t link_status = 0;
8480         uint16_t an1000_status = 0;
8481
8482         elink_cl45_read(sc, phy,
8483                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
8484
8485         ELINK_DEBUG_P1(sc, "8703 LASI status 0x%x", val1);
8486
8487         /* Clear the interrupt LASI status register */
8488         elink_cl45_read(sc, phy,
8489                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
8490         elink_cl45_read(sc, phy,
8491                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
8492         ELINK_DEBUG_P2(sc, "807x PCS status 0x%x->0x%x", val2, val1);
8493         /* Clear MSG-OUT */
8494         elink_cl45_read(sc, phy,
8495                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
8496
8497         /* Check the LASI */
8498         elink_cl45_read(sc, phy,
8499                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
8500
8501         ELINK_DEBUG_P1(sc, "KR 0x9003 0x%x", val2);
8502
8503         /* Check the link status */
8504         elink_cl45_read(sc, phy,
8505                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
8506         ELINK_DEBUG_P1(sc, "KR PCS status 0x%x", val2);
8507
8508         elink_cl45_read(sc, phy,
8509                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
8510         elink_cl45_read(sc, phy,
8511                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
8512         link_up = ((val1 & 4) == 4);
8513         ELINK_DEBUG_P1(sc, "PMA_REG_STATUS=0x%x", val1);
8514
8515         if (link_up &&
8516              ((phy->req_line_speed != ELINK_SPEED_10000))) {
8517                 if (elink_8073_xaui_wa(sc, phy) != 0)
8518                         return 0;
8519         }
8520         elink_cl45_read(sc, phy,
8521                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
8522         elink_cl45_read(sc, phy,
8523                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
8524
8525         /* Check the link status on 1.1.2 */
8526         elink_cl45_read(sc, phy,
8527                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
8528         elink_cl45_read(sc, phy,
8529                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
8530         ELINK_DEBUG_P3(sc, "KR PMA status 0x%x->0x%x,"
8531                    "an_link_status=0x%x", val2, val1, an1000_status);
8532
8533         link_up = (((val1 & 4) == 4) || (an1000_status & (1 << 1)));
8534         if (link_up && elink_8073_is_snr_needed(sc, phy)) {
8535                 /* The SNR will improve about 2dbby changing the BW and FEE main
8536                  * tap. The 1st write to change FFE main tap is set before
8537                  * restart AN. Change PLL Bandwidth in EDC register
8538                  */
8539                 elink_cl45_write(sc, phy,
8540                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
8541                                  0x26BC);
8542
8543                 /* Change CDR Bandwidth in EDC register */
8544                 elink_cl45_write(sc, phy,
8545                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
8546                                  0x0333);
8547         }
8548         elink_cl45_read(sc, phy,
8549                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
8550                         &link_status);
8551
8552         /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
8553         if ((link_status & (1 << 2)) && (!(link_status & (1 << 15)))) {
8554                 link_up = 1;
8555                 vars->line_speed = ELINK_SPEED_10000;
8556                 ELINK_DEBUG_P1(sc, "port %x: External link up in 10G",
8557                            params->port);
8558         } else if ((link_status & (1 << 1)) && (!(link_status & (1 << 14)))) {
8559                 link_up = 1;
8560                 vars->line_speed = ELINK_SPEED_2500;
8561                 ELINK_DEBUG_P1(sc, "port %x: External link up in 2.5G",
8562                            params->port);
8563         } else if ((link_status & (1 << 0)) && (!(link_status & (1 << 13)))) {
8564                 link_up = 1;
8565                 vars->line_speed = ELINK_SPEED_1000;
8566                 ELINK_DEBUG_P1(sc, "port %x: External link up in 1G",
8567                            params->port);
8568         } else {
8569                 link_up = 0;
8570                 ELINK_DEBUG_P1(sc, "port %x: External link is down",
8571                            params->port);
8572         }
8573
8574         if (link_up) {
8575                 /* Swap polarity if required */
8576                 if (params->lane_config &
8577                     PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
8578                         /* Configure the 8073 to swap P and N of the KR lines */
8579                         elink_cl45_read(sc, phy,
8580                                         MDIO_XS_DEVAD,
8581                                         MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
8582                         /* Set bit 3 to invert Rx in 1G mode and clear this bit
8583                          * when it`s in 10G mode.
8584                          */
8585                         if (vars->line_speed == ELINK_SPEED_1000) {
8586                                 ELINK_DEBUG_P0(sc, "Swapping 1G polarity for"
8587                                                " the 8073");
8588                                 val1 |= (1 << 3);
8589                         } else
8590                                 val1 &= ~(1 << 3);
8591
8592                         elink_cl45_write(sc, phy,
8593                                          MDIO_XS_DEVAD,
8594                                          MDIO_XS_REG_8073_RX_CTRL_PCIE,
8595                                          val1);
8596                 }
8597                 elink_ext_phy_10G_an_resolve(sc, phy, vars);
8598                 elink_8073_resolve_fc(phy, params, vars);
8599                 vars->duplex = DUPLEX_FULL;
8600         }
8601
8602         if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
8603                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
8604                                 MDIO_AN_REG_LP_AUTO_NEG2, &val1);
8605
8606                 if (val1 & (1 << 5))
8607                         vars->link_status |=
8608                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
8609                 if (val1 & (1 << 7))
8610                         vars->link_status |=
8611                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
8612         }
8613
8614         return link_up;
8615 }
8616
8617 static void elink_8073_link_reset(__rte_unused struct elink_phy *phy,
8618                                   struct elink_params *params)
8619 {
8620         struct bnx2x_softc *sc = params->sc;
8621         uint8_t gpio_port;
8622         if (CHIP_IS_E2(sc))
8623                 gpio_port = SC_PATH(sc);
8624         else
8625                 gpio_port = params->port;
8626         ELINK_DEBUG_P1(sc, "Setting 8073 port %d into low power mode",
8627            gpio_port);
8628         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
8629                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
8630                        gpio_port);
8631 }
8632
8633 /******************************************************************/
8634 /*                      BNX2X8705 PHY SECTION                     */
8635 /******************************************************************/
8636 static uint8_t elink_8705_config_init(struct elink_phy *phy,
8637                                   struct elink_params *params,
8638                                   __rte_unused struct elink_vars *vars)
8639 {
8640         struct bnx2x_softc *sc = params->sc;
8641         ELINK_DEBUG_P0(sc, "init 8705");
8642         /* Restore normal power mode*/
8643         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
8644                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
8645         /* HW reset */
8646         elink_ext_phy_hw_reset(sc, params->port);
8647         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
8648         elink_wait_reset_complete(sc, phy, params);
8649
8650         elink_cl45_write(sc, phy,
8651                          MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
8652         elink_cl45_write(sc, phy,
8653                          MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
8654         elink_cl45_write(sc, phy,
8655                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
8656         elink_cl45_write(sc, phy,
8657                          MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
8658         /* BNX2X8705 doesn't have microcode, hence the 0 */
8659         elink_save_spirom_version(sc, params->port, params->shmem_base, 0);
8660         return ELINK_STATUS_OK;
8661 }
8662
8663 static uint8_t elink_8705_read_status(struct elink_phy *phy,
8664                                  struct elink_params *params,
8665                                  struct elink_vars *vars)
8666 {
8667         uint8_t link_up = 0;
8668         uint16_t val1, rx_sd;
8669         struct bnx2x_softc *sc = params->sc;
8670         ELINK_DEBUG_P0(sc, "read status 8705");
8671         elink_cl45_read(sc, phy,
8672                       MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
8673         ELINK_DEBUG_P1(sc, "8705 LASI status 0x%x", val1);
8674
8675         elink_cl45_read(sc, phy,
8676                       MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
8677         ELINK_DEBUG_P1(sc, "8705 LASI status 0x%x", val1);
8678
8679         elink_cl45_read(sc, phy,
8680                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
8681
8682         elink_cl45_read(sc, phy,
8683                       MDIO_PMA_DEVAD, 0xc809, &val1);
8684         elink_cl45_read(sc, phy,
8685                       MDIO_PMA_DEVAD, 0xc809, &val1);
8686
8687         ELINK_DEBUG_P1(sc, "8705 1.c809 val=0x%x", val1);
8688         link_up = ((rx_sd & 0x1) && (val1 & (1 << 9)) &&
8689                    ((val1 & (1 << 8)) == 0));
8690         if (link_up) {
8691                 vars->line_speed = ELINK_SPEED_10000;
8692                 elink_ext_phy_resolve_fc(phy, params, vars);
8693         }
8694         return link_up;
8695 }
8696
8697 /******************************************************************/
8698 /*                      SFP+ module Section                       */
8699 /******************************************************************/
8700 static void elink_set_disable_pmd_transmit(struct elink_params *params,
8701                                            struct elink_phy *phy,
8702                                            uint8_t pmd_dis)
8703 {
8704         struct bnx2x_softc *sc = params->sc;
8705         /* Disable transmitter only for bootcodes which can enable it afterwards
8706          * (for D3 link)
8707          */
8708         if (pmd_dis) {
8709                 if (params->feature_config_flags &
8710                      ELINK_FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED) {
8711                         ELINK_DEBUG_P0(sc, "Disabling PMD transmitter");
8712                 } else {
8713                         ELINK_DEBUG_P0(sc, "NOT disabling PMD transmitter");
8714                         return;
8715                 }
8716         } else
8717                 ELINK_DEBUG_P0(sc, "Enabling PMD transmitter");
8718         elink_cl45_write(sc, phy,
8719                          MDIO_PMA_DEVAD,
8720                          MDIO_PMA_REG_TX_DISABLE, pmd_dis);
8721 }
8722
8723 static uint8_t elink_get_gpio_port(struct elink_params *params)
8724 {
8725         uint8_t gpio_port;
8726         uint32_t swap_val, swap_override;
8727         struct bnx2x_softc *sc = params->sc;
8728         if (CHIP_IS_E2(sc))
8729                 gpio_port = SC_PATH(sc);
8730         else
8731                 gpio_port = params->port;
8732         swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
8733         swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
8734         return gpio_port ^ (swap_val && swap_override);
8735 }
8736
8737 static void elink_sfp_e1e2_set_transmitter(struct elink_params *params,
8738                                            struct elink_phy *phy,
8739                                            uint8_t tx_en)
8740 {
8741         uint16_t val;
8742         uint8_t port = params->port;
8743         struct bnx2x_softc *sc = params->sc;
8744         uint32_t tx_en_mode;
8745
8746         /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
8747         tx_en_mode = REG_RD(sc, params->shmem_base +
8748                             offsetof(struct shmem_region,
8749                                      dev_info.port_hw_config[port].sfp_ctrl)) &
8750                 PORT_HW_CFG_TX_LASER_MASK;
8751         ELINK_DEBUG_P3(sc, "Setting transmitter tx_en=%x for port %x "
8752                            "mode = %x", tx_en, port, tx_en_mode);
8753         switch (tx_en_mode) {
8754         case PORT_HW_CFG_TX_LASER_MDIO:
8755
8756                 elink_cl45_read(sc, phy,
8757                                 MDIO_PMA_DEVAD,
8758                                 MDIO_PMA_REG_PHY_IDENTIFIER,
8759                                 &val);
8760
8761                 if (tx_en)
8762                         val &= ~(1 << 15);
8763                 else
8764                         val |= (1 << 15);
8765
8766                 elink_cl45_write(sc, phy,
8767                                  MDIO_PMA_DEVAD,
8768                                  MDIO_PMA_REG_PHY_IDENTIFIER,
8769                                  val);
8770         break;
8771         case PORT_HW_CFG_TX_LASER_GPIO0:
8772         case PORT_HW_CFG_TX_LASER_GPIO1:
8773         case PORT_HW_CFG_TX_LASER_GPIO2:
8774         case PORT_HW_CFG_TX_LASER_GPIO3:
8775         {
8776                 uint16_t gpio_pin;
8777                 uint8_t gpio_port, gpio_mode;
8778                 if (tx_en)
8779                         gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH;
8780                 else
8781                         gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW;
8782
8783                 gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0;
8784                 gpio_port = elink_get_gpio_port(params);
8785                 elink_cb_gpio_write(sc, gpio_pin, gpio_mode, gpio_port);
8786                 break;
8787         }
8788         default:
8789                 ELINK_DEBUG_P1(sc, "Invalid TX_LASER_MDIO 0x%x", tx_en_mode);
8790                 break;
8791         }
8792 }
8793
8794 static void elink_sfp_set_transmitter(struct elink_params *params,
8795                                       struct elink_phy *phy,
8796                                       uint8_t tx_en)
8797 {
8798         struct bnx2x_softc *sc = params->sc;
8799         ELINK_DEBUG_P1(sc, "Setting SFP+ transmitter to %d", tx_en);
8800         if (CHIP_IS_E3(sc))
8801                 elink_sfp_e3_set_transmitter(params, phy, tx_en);
8802         else
8803                 elink_sfp_e1e2_set_transmitter(params, phy, tx_en);
8804 }
8805
8806 static elink_status_t elink_8726_read_sfp_module_eeprom(struct elink_phy *phy,
8807                              struct elink_params *params,
8808                              uint8_t dev_addr, uint16_t addr,
8809                              uint8_t byte_cnt,
8810                              uint8_t *o_buf, __rte_unused uint8_t is_init)
8811 {
8812         struct bnx2x_softc *sc = params->sc;
8813         uint16_t val = 0;
8814         uint16_t i;
8815         if (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) {
8816                 ELINK_DEBUG_P0(sc,
8817                    "Reading from eeprom is limited to 0xf");
8818                 return ELINK_STATUS_ERROR;
8819         }
8820         /* Set the read command byte count */
8821         elink_cl45_write(sc, phy,
8822                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
8823                          (byte_cnt | (dev_addr << 8)));
8824
8825         /* Set the read command address */
8826         elink_cl45_write(sc, phy,
8827                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
8828                          addr);
8829
8830         /* Activate read command */
8831         elink_cl45_write(sc, phy,
8832                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
8833                          0x2c0f);
8834
8835         /* Wait up to 500us for command complete status */
8836         for (i = 0; i < 100; i++) {
8837                 elink_cl45_read(sc, phy,
8838                                 MDIO_PMA_DEVAD,
8839                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
8840                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
8841                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
8842                         break;
8843                 DELAY(5);
8844         }
8845
8846         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
8847                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
8848                 ELINK_DEBUG_P1(sc,
8849                          "Got bad status 0x%x when reading from SFP+ EEPROM",
8850                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
8851                 return ELINK_STATUS_ERROR;
8852         }
8853
8854         /* Read the buffer */
8855         for (i = 0; i < byte_cnt; i++) {
8856                 elink_cl45_read(sc, phy,
8857                                 MDIO_PMA_DEVAD,
8858                                 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
8859                 o_buf[i] = (uint8_t)
8860                                 (val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
8861         }
8862
8863         for (i = 0; i < 100; i++) {
8864                 elink_cl45_read(sc, phy,
8865                                 MDIO_PMA_DEVAD,
8866                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
8867                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
8868                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
8869                         return ELINK_STATUS_OK;
8870                 DELAY(1000 * 1);
8871         }
8872         return ELINK_STATUS_ERROR;
8873 }
8874
8875 static void elink_warpcore_power_module(struct elink_params *params,
8876                                         uint8_t power)
8877 {
8878         uint32_t pin_cfg;
8879         struct bnx2x_softc *sc = params->sc;
8880
8881         pin_cfg = (REG_RD(sc, params->shmem_base +
8882                           offsetof(struct shmem_region,
8883                         dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
8884                         PORT_HW_CFG_E3_PWR_DIS_MASK) >>
8885                         PORT_HW_CFG_E3_PWR_DIS_SHIFT;
8886
8887         if (pin_cfg == PIN_CFG_NA)
8888                 return;
8889         ELINK_DEBUG_P2(sc, "Setting SFP+ module power to %d using pin cfg %d",
8890                        power, pin_cfg);
8891         /* Low ==> corresponding SFP+ module is powered
8892          * high ==> the SFP+ module is powered down
8893          */
8894         elink_set_cfg_pin(sc, pin_cfg, power ^ 1);
8895 }
8896 static elink_status_t elink_warpcore_read_sfp_module_eeprom(
8897                                          __rte_unused struct elink_phy *phy,
8898                                          struct elink_params *params,
8899                                          uint8_t dev_addr,
8900                                          uint16_t addr,
8901                                          uint8_t byte_cnt,
8902                                          uint8_t *o_buf,
8903                                          uint8_t is_init)
8904 {
8905         elink_status_t rc = ELINK_STATUS_OK;
8906         uint8_t i, j = 0, cnt = 0;
8907         uint32_t data_array[4];
8908         uint16_t addr32;
8909         struct bnx2x_softc *sc = params->sc;
8910
8911         if (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) {
8912                 ELINK_DEBUG_P0(sc,
8913                    "Reading from eeprom is limited to 16 bytes");
8914                 return ELINK_STATUS_ERROR;
8915         }
8916
8917         /* 4 byte aligned address */
8918         addr32 = addr & (~0x3);
8919         do {
8920                 if ((!is_init) && (cnt == I2C_WA_PWR_ITER)) {
8921                         elink_warpcore_power_module(params, 0);
8922                         /* Note that 100us are not enough here */
8923                         DELAY(1000 * 1);
8924                         elink_warpcore_power_module(params, 1);
8925                 }
8926
8927                 elink_bsc_module_sel(params);
8928                 rc = elink_bsc_read(sc, dev_addr, addr32, 0, byte_cnt,
8929                                     data_array);
8930         } while ((rc != ELINK_STATUS_OK) && (++cnt < I2C_WA_RETRY_CNT));
8931
8932         if (rc == ELINK_STATUS_OK) {
8933                 for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) {
8934                         o_buf[j] = *((uint8_t *)data_array + i);
8935                         j++;
8936                 }
8937         }
8938
8939         return rc;
8940 }
8941
8942 static elink_status_t elink_8727_read_sfp_module_eeprom(struct elink_phy *phy,
8943                                              struct elink_params *params,
8944                                              uint8_t dev_addr, uint16_t addr,
8945                                              uint8_t byte_cnt,
8946                                              uint8_t *o_buf,
8947                                              __rte_unused uint8_t is_init)
8948 {
8949         struct bnx2x_softc *sc = params->sc;
8950         uint16_t val, i;
8951
8952         if (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) {
8953                 ELINK_DEBUG_P0(sc,
8954                    "Reading from eeprom is limited to 0xf");
8955                 return ELINK_STATUS_ERROR;
8956         }
8957
8958         /* Set 2-wire transfer rate of SFP+ module EEPROM
8959          * to 100Khz since some DACs(direct attached cables) do
8960          * not work at 400Khz.
8961          */
8962         elink_cl45_write(sc, phy,
8963                          MDIO_PMA_DEVAD,
8964                          MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
8965                          ((dev_addr << 8) | 1));
8966
8967         /* Need to read from 1.8000 to clear it */
8968         elink_cl45_read(sc, phy,
8969                         MDIO_PMA_DEVAD,
8970                         MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
8971                         &val);
8972
8973         /* Set the read command byte count */
8974         elink_cl45_write(sc, phy,
8975                          MDIO_PMA_DEVAD,
8976                          MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
8977                          ((byte_cnt < 2) ? 2 : byte_cnt));
8978
8979         /* Set the read command address */
8980         elink_cl45_write(sc, phy,
8981                          MDIO_PMA_DEVAD,
8982                          MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
8983                          addr);
8984         /* Set the destination address */
8985         elink_cl45_write(sc, phy,
8986                          MDIO_PMA_DEVAD,
8987                          0x8004,
8988                          MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
8989
8990         /* Activate read command */
8991         elink_cl45_write(sc, phy,
8992                          MDIO_PMA_DEVAD,
8993                          MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
8994                          0x8002);
8995         /* Wait appropriate time for two-wire command to finish before
8996          * polling the status register
8997          */
8998         DELAY(1000 * 1);
8999
9000         /* Wait up to 500us for command complete status */
9001         for (i = 0; i < 100; i++) {
9002                 elink_cl45_read(sc, phy,
9003                                 MDIO_PMA_DEVAD,
9004                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
9005                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
9006                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
9007                         break;
9008                 DELAY(5);
9009         }
9010
9011         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
9012                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
9013                 ELINK_DEBUG_P1(sc,
9014                          "Got bad status 0x%x when reading from SFP+ EEPROM",
9015                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
9016                 return ELINK_STATUS_TIMEOUT;
9017         }
9018
9019         /* Read the buffer */
9020         for (i = 0; i < byte_cnt; i++) {
9021                 elink_cl45_read(sc, phy,
9022                                 MDIO_PMA_DEVAD,
9023                                 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
9024                 o_buf[i] = (uint8_t)
9025                                 (val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
9026         }
9027
9028         for (i = 0; i < 100; i++) {
9029                 elink_cl45_read(sc, phy,
9030                                 MDIO_PMA_DEVAD,
9031                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
9032                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
9033                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
9034                         return ELINK_STATUS_OK;
9035                 DELAY(1000 * 1);
9036         }
9037
9038         return ELINK_STATUS_ERROR;
9039 }
9040 elink_status_t elink_read_sfp_module_eeprom(struct elink_phy *phy,
9041                                  struct elink_params *params, uint8_t dev_addr,
9042                                  uint16_t addr, uint16_t byte_cnt,
9043                                  uint8_t *o_buf)
9044 {
9045         elink_status_t rc = 0;
9046         struct bnx2x_softc *sc = params->sc;
9047         uint8_t xfer_size;
9048         uint8_t *user_data = o_buf;
9049         read_sfp_module_eeprom_func_p read_func;
9050         if ((dev_addr != 0xa0) && (dev_addr != 0xa2)) {
9051                 ELINK_DEBUG_P1(sc, "invalid dev_addr 0x%x", dev_addr);
9052                 return ELINK_STATUS_ERROR;
9053         }
9054
9055         switch (phy->type) {
9056         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726:
9057                 read_func = elink_8726_read_sfp_module_eeprom;
9058                 break;
9059         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727:
9060         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722:
9061                 read_func = elink_8727_read_sfp_module_eeprom;
9062                 break;
9063         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
9064                 read_func = elink_warpcore_read_sfp_module_eeprom;
9065                 break;
9066         default:
9067                 return ELINK_OP_NOT_SUPPORTED;
9068         }
9069
9070         while (!rc && (byte_cnt > 0)) {
9071                 xfer_size = (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) ?
9072                         ELINK_SFP_EEPROM_PAGE_SIZE : byte_cnt;
9073                 rc = read_func(phy, params, dev_addr, addr, xfer_size,
9074                                user_data, 0);
9075                 byte_cnt -= xfer_size;
9076                 user_data += xfer_size;
9077                 addr += xfer_size;
9078         }
9079         return rc;
9080 }
9081
9082 static elink_status_t elink_get_edc_mode(struct elink_phy *phy,
9083                               struct elink_params *params,
9084                               uint16_t *edc_mode)
9085 {
9086         struct bnx2x_softc *sc = params->sc;
9087         uint32_t sync_offset = 0, phy_idx, media_types;
9088         uint8_t val[ELINK_SFP_EEPROM_FC_TX_TECH_ADDR + 1];
9089         uint8_t check_limiting_mode = 0;
9090         *edc_mode = ELINK_EDC_MODE_LIMITING;
9091         phy->media_type = ELINK_ETH_PHY_UNSPECIFIED;
9092         /* First check for copper cable */
9093         if (elink_read_sfp_module_eeprom(phy,
9094                                          params,
9095                                          ELINK_I2C_DEV_ADDR_A0,
9096                                          0,
9097                                          ELINK_SFP_EEPROM_FC_TX_TECH_ADDR + 1,
9098                                          (uint8_t *)val) != 0) {
9099                 ELINK_DEBUG_P0(sc, "Failed to read from SFP+ module EEPROM");
9100                 return ELINK_STATUS_ERROR;
9101         }
9102         params->link_attr_sync &= ~LINK_SFP_EEPROM_COMP_CODE_MASK;
9103         params->link_attr_sync |= val[ELINK_SFP_EEPROM_10G_COMP_CODE_ADDR] <<
9104                 LINK_SFP_EEPROM_COMP_CODE_SHIFT;
9105         elink_update_link_attr(params, params->link_attr_sync);
9106         switch (val[ELINK_SFP_EEPROM_CON_TYPE_ADDR]) {
9107         case ELINK_SFP_EEPROM_CON_TYPE_VAL_COPPER:
9108         {
9109                 uint8_t copper_module_type;
9110                 phy->media_type = ELINK_ETH_PHY_DA_TWINAX;
9111                 /* Check if its active cable (includes SFP+ module)
9112                  * of passive cable
9113                  */
9114                 copper_module_type = val[ELINK_SFP_EEPROM_FC_TX_TECH_ADDR];
9115                 if (copper_module_type &
9116                     ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
9117                         ELINK_DEBUG_P0(sc, "Active Copper cable detected");
9118                         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
9119                                 *edc_mode = ELINK_EDC_MODE_ACTIVE_DAC;
9120                         else
9121                                 check_limiting_mode = 1;
9122                 } else {
9123                         *edc_mode = ELINK_EDC_MODE_PASSIVE_DAC;
9124                         /* Even in case PASSIVE_DAC indication is not set,
9125                          * treat it as a passive DAC cable, since some cables
9126                          * don't have this indication.
9127                          */
9128                         if (copper_module_type &
9129                            ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
9130                                 ELINK_DEBUG_P0(sc,
9131                                                "Passive Copper cable detected");
9132                         } else {
9133                                 ELINK_DEBUG_P0(sc,
9134                                                "Unknown copper-cable-type");
9135                         }
9136                 }
9137                 break;
9138         }
9139         case ELINK_SFP_EEPROM_CON_TYPE_VAL_UNKNOWN:
9140         case ELINK_SFP_EEPROM_CON_TYPE_VAL_LC:
9141         case ELINK_SFP_EEPROM_CON_TYPE_VAL_RJ45:
9142                 check_limiting_mode = 1;
9143                 /* Module is considered as 1G in case it's NOT compliant with
9144                  * any 10G ethernet protocol, but is 1G Ethernet compliant.
9145                  */
9146                 if (((val[ELINK_SFP_EEPROM_10G_COMP_CODE_ADDR] &
9147                       (ELINK_SFP_EEPROM_10G_COMP_CODE_SR_MASK |
9148                        ELINK_SFP_EEPROM_10G_COMP_CODE_LR_MASK |
9149                        ELINK_SFP_EEPROM_10G_COMP_CODE_LRM_MASK)) == 0) &&
9150                     (val[ELINK_SFP_EEPROM_1G_COMP_CODE_ADDR] != 0)) {
9151                         ELINK_DEBUG_P0(sc, "1G SFP module detected");
9152                         phy->media_type = ELINK_ETH_PHY_SFP_1G_FIBER;
9153                         if (phy->req_line_speed != ELINK_SPEED_1000) {
9154                                 uint8_t gport = params->port;
9155                                 phy->req_line_speed = ELINK_SPEED_1000;
9156                                 if (!CHIP_IS_E1x(sc)) {
9157                                         gport = SC_PATH(sc) +
9158                                         (params->port << 1);
9159                                 }
9160                                 elink_cb_event_log(sc,
9161                                                    ELINK_LOG_ID_NON_10G_MODULE,
9162                                                    gport);
9163                                  /*"Warning: Link speed was forced to 1000Mbps."
9164                                   *" Current SFP module in port %d is not"
9165                                   *" compliant with 10G Ethernet",
9166                                   */
9167                         }
9168
9169                         if (val[ELINK_SFP_EEPROM_1G_COMP_CODE_ADDR] &
9170                             ELINK_SFP_EEPROM_1G_COMP_CODE_BASE_T) {
9171                                 /* Some 1G-baseT modules will not link up,
9172                                  * unless TX_EN is toggled with long delay in
9173                                  * between.
9174                                  */
9175                                 elink_sfp_set_transmitter(params, phy, 0);
9176                                 DELAY(1000 * 40);
9177                                 elink_sfp_set_transmitter(params, phy, 1);
9178                         }
9179                 } else {
9180                         int idx, cfg_idx = 0;
9181                         ELINK_DEBUG_P0(sc, "10G Optic module detected");
9182                         for (idx = ELINK_INT_PHY; idx < ELINK_MAX_PHYS; idx++) {
9183                                 if (params->phy[idx].type == phy->type) {
9184                                         cfg_idx = ELINK_LINK_CONFIG_IDX(idx);
9185                                         break;
9186                                 }
9187                         }
9188                         phy->media_type = ELINK_ETH_PHY_SFPP_10G_FIBER;
9189                         phy->req_line_speed = params->req_line_speed[cfg_idx];
9190                 }
9191                 break;
9192         default:
9193                 ELINK_DEBUG_P1(sc, "Unable to determine module type 0x%x !!!",
9194                          val[ELINK_SFP_EEPROM_CON_TYPE_ADDR]);
9195                 return ELINK_STATUS_ERROR;
9196         }
9197         sync_offset = params->shmem_base +
9198                 offsetof(struct shmem_region,
9199                          dev_info.port_hw_config[params->port].media_type);
9200         media_types = REG_RD(sc, sync_offset);
9201         /* Update media type for non-PMF sync */
9202         for (phy_idx = ELINK_INT_PHY; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
9203                 if (&(params->phy[phy_idx]) == phy) {
9204                         media_types &= ~(PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
9205                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
9206                         media_types |= ((phy->media_type &
9207                                         PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
9208                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
9209                         break;
9210                 }
9211         }
9212         REG_WR(sc, sync_offset, media_types);
9213         if (check_limiting_mode) {
9214                 uint8_t options[ELINK_SFP_EEPROM_OPTIONS_SIZE];
9215                 if (elink_read_sfp_module_eeprom(phy,
9216                                                  params,
9217                                                  ELINK_I2C_DEV_ADDR_A0,
9218                                                  ELINK_SFP_EEPROM_OPTIONS_ADDR,
9219                                                  ELINK_SFP_EEPROM_OPTIONS_SIZE,
9220                                                  options) != 0) {
9221                         ELINK_DEBUG_P0(sc,
9222                            "Failed to read Option field from module EEPROM");
9223                         return ELINK_STATUS_ERROR;
9224                 }
9225                 if ((options[0] & ELINK_SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
9226                         *edc_mode = ELINK_EDC_MODE_LINEAR;
9227                 else
9228                         *edc_mode = ELINK_EDC_MODE_LIMITING;
9229         }
9230         ELINK_DEBUG_P1(sc, "EDC mode is set to 0x%x", *edc_mode);
9231         return ELINK_STATUS_OK;
9232 }
9233 /* This function read the relevant field from the module (SFP+), and verify it
9234  * is compliant with this board
9235  */
9236 static elink_status_t elink_verify_sfp_module(struct elink_phy *phy,
9237                                    struct elink_params *params)
9238 {
9239         struct bnx2x_softc *sc = params->sc;
9240         uint32_t val, cmd;
9241         uint32_t fw_resp, fw_cmd_param;
9242         char vendor_name[ELINK_SFP_EEPROM_VENDOR_NAME_SIZE + 1];
9243         char vendor_pn[ELINK_SFP_EEPROM_PART_NO_SIZE + 1];
9244         phy->flags &= ~ELINK_FLAGS_SFP_NOT_APPROVED;
9245         val = REG_RD(sc, params->shmem_base +
9246                          offsetof(struct shmem_region, dev_info.
9247                                   port_feature_config[params->port].config));
9248         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9249             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
9250                 ELINK_DEBUG_P0(sc, "NOT enforcing module verification");
9251                 return ELINK_STATUS_OK;
9252         }
9253
9254         if (params->feature_config_flags &
9255             ELINK_FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
9256                 /* Use specific phy request */
9257                 cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
9258         } else if (params->feature_config_flags &
9259                    ELINK_FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
9260                 /* Use first phy request only in case of non-dual media*/
9261                 if (ELINK_DUAL_MEDIA(params)) {
9262                         ELINK_DEBUG_P0(sc,
9263                            "FW does not support OPT MDL verification");
9264                         return ELINK_STATUS_ERROR;
9265                 }
9266                 cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
9267         } else {
9268                 /* No support in OPT MDL detection */
9269                 ELINK_DEBUG_P0(sc,
9270                    "FW does not support OPT MDL verification");
9271                 return ELINK_STATUS_ERROR;
9272         }
9273
9274         fw_cmd_param = ELINK_FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
9275         fw_resp = elink_cb_fw_command(sc, cmd, fw_cmd_param);
9276         if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
9277                 ELINK_DEBUG_P0(sc, "Approved module");
9278                 return ELINK_STATUS_OK;
9279         }
9280
9281         /* Format the warning message */
9282         if (elink_read_sfp_module_eeprom(phy,
9283                                          params,
9284                                          ELINK_I2C_DEV_ADDR_A0,
9285                                          ELINK_SFP_EEPROM_VENDOR_NAME_ADDR,
9286                                          ELINK_SFP_EEPROM_VENDOR_NAME_SIZE,
9287                                          (uint8_t *)vendor_name))
9288                 vendor_name[0] = '\0';
9289         else
9290                 vendor_name[ELINK_SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
9291         if (elink_read_sfp_module_eeprom(phy,
9292                                          params,
9293                                          ELINK_I2C_DEV_ADDR_A0,
9294                                          ELINK_SFP_EEPROM_PART_NO_ADDR,
9295                                          ELINK_SFP_EEPROM_PART_NO_SIZE,
9296                                          (uint8_t *)vendor_pn))
9297                 vendor_pn[0] = '\0';
9298         else
9299                 vendor_pn[ELINK_SFP_EEPROM_PART_NO_SIZE] = '\0';
9300
9301         elink_cb_event_log(sc, ELINK_LOG_ID_UNQUAL_IO_MODULE, params->port,
9302                            vendor_name, vendor_pn);
9303                              /* "Warning: Unqualified SFP+ module detected,"
9304                               * " Port %d from %s part number %s",
9305                               */
9306
9307         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
9308             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_WARNING_MSG)
9309                 phy->flags |= ELINK_FLAGS_SFP_NOT_APPROVED;
9310         return ELINK_STATUS_ERROR;
9311 }
9312
9313 static elink_status_t elink_wait_for_sfp_module_initialized(
9314                                                  struct elink_phy *phy,
9315                                                  struct elink_params *params)
9316
9317 {
9318         uint8_t val;
9319         elink_status_t rc;
9320         struct bnx2x_softc *sc = params->sc;
9321         uint16_t timeout;
9322         /* Initialization time after hot-plug may take up to 300ms for
9323          * some phys type ( e.g. JDSU )
9324          */
9325
9326         for (timeout = 0; timeout < 60; timeout++) {
9327                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
9328                         rc = elink_warpcore_read_sfp_module_eeprom(
9329                                 phy, params, ELINK_I2C_DEV_ADDR_A0, 1, 1, &val,
9330                                 1);
9331                 else
9332                         rc = elink_read_sfp_module_eeprom(phy, params,
9333                                                           ELINK_I2C_DEV_ADDR_A0,
9334                                                           1, 1, &val);
9335                 if (rc == 0) {
9336                         ELINK_DEBUG_P1(sc,
9337                            "SFP+ module initialization took %d ms",
9338                            timeout * 5);
9339                         return ELINK_STATUS_OK;
9340                 }
9341                 DELAY(1000 * 5);
9342         }
9343         rc = elink_read_sfp_module_eeprom(phy, params, ELINK_I2C_DEV_ADDR_A0,
9344                                           1, 1, &val);
9345         return rc;
9346 }
9347
9348 static void elink_8727_power_module(struct bnx2x_softc *sc,
9349                                     struct elink_phy *phy,
9350                                     uint8_t is_power_up) {
9351         /* Make sure GPIOs are not using for LED mode */
9352         uint16_t val;
9353         /* In the GPIO register, bit 4 is use to determine if the GPIOs are
9354          * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
9355          * output
9356          * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0
9357          * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1
9358          * where the 1st bit is the over-current(only input), and 2nd bit is
9359          * for power( only output )
9360          *
9361          * In case of NOC feature is disabled and power is up, set GPIO control
9362          *  as input to enable listening of over-current indication
9363          */
9364         if (phy->flags & ELINK_FLAGS_NOC)
9365                 return;
9366         if (is_power_up)
9367                 val = (1 << 4);
9368         else
9369                 /* Set GPIO control to OUTPUT, and set the power bit
9370                  * to according to the is_power_up
9371                  */
9372                 val = (1 << 1);
9373
9374         elink_cl45_write(sc, phy,
9375                          MDIO_PMA_DEVAD,
9376                          MDIO_PMA_REG_8727_GPIO_CTRL,
9377                          val);
9378 }
9379
9380 static elink_status_t elink_8726_set_limiting_mode(struct bnx2x_softc *sc,
9381                                         struct elink_phy *phy,
9382                                         uint16_t edc_mode)
9383 {
9384         uint16_t cur_limiting_mode;
9385
9386         elink_cl45_read(sc, phy,
9387                         MDIO_PMA_DEVAD,
9388                         MDIO_PMA_REG_ROM_VER2,
9389                         &cur_limiting_mode);
9390         ELINK_DEBUG_P1(sc, "Current Limiting mode is 0x%x",
9391                  cur_limiting_mode);
9392
9393         if (edc_mode == ELINK_EDC_MODE_LIMITING) {
9394                 ELINK_DEBUG_P0(sc, "Setting LIMITING MODE");
9395                 elink_cl45_write(sc, phy,
9396                                  MDIO_PMA_DEVAD,
9397                                  MDIO_PMA_REG_ROM_VER2,
9398                                  ELINK_EDC_MODE_LIMITING);
9399         } else { /* LRM mode ( default )*/
9400
9401                 ELINK_DEBUG_P0(sc, "Setting LRM MODE");
9402
9403                 /* Changing to LRM mode takes quite few seconds. So do it only
9404                  * if current mode is limiting (default is LRM)
9405                  */
9406                 if (cur_limiting_mode != ELINK_EDC_MODE_LIMITING)
9407                         return ELINK_STATUS_OK;
9408
9409                 elink_cl45_write(sc, phy,
9410                                  MDIO_PMA_DEVAD,
9411                                  MDIO_PMA_REG_LRM_MODE,
9412                                  0);
9413                 elink_cl45_write(sc, phy,
9414                                  MDIO_PMA_DEVAD,
9415                                  MDIO_PMA_REG_ROM_VER2,
9416                                  0x128);
9417                 elink_cl45_write(sc, phy,
9418                                  MDIO_PMA_DEVAD,
9419                                  MDIO_PMA_REG_MISC_CTRL0,
9420                                  0x4008);
9421                 elink_cl45_write(sc, phy,
9422                                  MDIO_PMA_DEVAD,
9423                                  MDIO_PMA_REG_LRM_MODE,
9424                                  0xaaaa);
9425         }
9426         return ELINK_STATUS_OK;
9427 }
9428
9429 static elink_status_t elink_8727_set_limiting_mode(struct bnx2x_softc *sc,
9430                                         struct elink_phy *phy,
9431                                         uint16_t edc_mode)
9432 {
9433         uint16_t phy_identifier;
9434         uint16_t rom_ver2_val;
9435         elink_cl45_read(sc, phy,
9436                         MDIO_PMA_DEVAD,
9437                         MDIO_PMA_REG_PHY_IDENTIFIER,
9438                         &phy_identifier);
9439
9440         elink_cl45_write(sc, phy,
9441                          MDIO_PMA_DEVAD,
9442                          MDIO_PMA_REG_PHY_IDENTIFIER,
9443                          (phy_identifier & ~(1 << 9)));
9444
9445         elink_cl45_read(sc, phy,
9446                         MDIO_PMA_DEVAD,
9447                         MDIO_PMA_REG_ROM_VER2,
9448                         &rom_ver2_val);
9449         /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
9450         elink_cl45_write(sc, phy,
9451                          MDIO_PMA_DEVAD,
9452                          MDIO_PMA_REG_ROM_VER2,
9453                          (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
9454
9455         elink_cl45_write(sc, phy,
9456                          MDIO_PMA_DEVAD,
9457                          MDIO_PMA_REG_PHY_IDENTIFIER,
9458                          (phy_identifier | (1 << 9)));
9459
9460         return ELINK_STATUS_OK;
9461 }
9462
9463 static void elink_8727_specific_func(struct elink_phy *phy,
9464                                      struct elink_params *params,
9465                                      uint32_t action)
9466 {
9467         struct bnx2x_softc *sc = params->sc;
9468         uint16_t val;
9469         switch (action) {
9470         case ELINK_DISABLE_TX:
9471                 elink_sfp_set_transmitter(params, phy, 0);
9472                 break;
9473         case ELINK_ENABLE_TX:
9474                 if (!(phy->flags & ELINK_FLAGS_SFP_NOT_APPROVED))
9475                         elink_sfp_set_transmitter(params, phy, 1);
9476                 break;
9477         case ELINK_PHY_INIT:
9478                 elink_cl45_write(sc, phy,
9479                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9480                                  (1 << 2) | (1 << 5));
9481                 elink_cl45_write(sc, phy,
9482                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
9483                                  0);
9484                 elink_cl45_write(sc, phy,
9485                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x0006);
9486                 /* Make MOD_ABS give interrupt on change */
9487                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
9488                                 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
9489                                 &val);
9490                 val |= (1 << 12);
9491                 if (phy->flags & ELINK_FLAGS_NOC)
9492                         val |= (3 << 5);
9493                 /* Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
9494                  * status which reflect SFP+ module over-current
9495                  */
9496                 if (!(phy->flags & ELINK_FLAGS_NOC))
9497                         val &= 0xff8f; /* Reset bits 4-6 */
9498                 elink_cl45_write(sc, phy,
9499                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
9500                                  val);
9501                 break;
9502         default:
9503                 ELINK_DEBUG_P1(sc, "Function 0x%x not supported by 8727",
9504                    action);
9505                 return;
9506         }
9507 }
9508
9509 static void elink_set_e1e2_module_fault_led(struct elink_params *params,
9510                                            uint8_t gpio_mode)
9511 {
9512         struct bnx2x_softc *sc = params->sc;
9513
9514         uint32_t fault_led_gpio = REG_RD(sc, params->shmem_base +
9515                             offsetof(struct shmem_region,
9516                         dev_info.port_hw_config[params->port].sfp_ctrl)) &
9517                 PORT_HW_CFG_FAULT_MODULE_LED_MASK;
9518         switch (fault_led_gpio) {
9519         case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED:
9520                 return;
9521         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0:
9522         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1:
9523         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2:
9524         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3:
9525         {
9526                 uint8_t gpio_port = elink_get_gpio_port(params);
9527                 uint16_t gpio_pin = fault_led_gpio -
9528                         PORT_HW_CFG_FAULT_MODULE_LED_GPIO0;
9529                 ELINK_DEBUG_P3(sc, "Set fault module-detected led "
9530                                    "pin %x port %x mode %x",
9531                                gpio_pin, gpio_port, gpio_mode);
9532                 elink_cb_gpio_write(sc, gpio_pin, gpio_mode, gpio_port);
9533         }
9534         break;
9535         default:
9536                 ELINK_DEBUG_P1(sc, "Error: Invalid fault led mode 0x%x",
9537                                fault_led_gpio);
9538         }
9539 }
9540
9541 static void elink_set_e3_module_fault_led(struct elink_params *params,
9542                                           uint8_t gpio_mode)
9543 {
9544         uint32_t pin_cfg;
9545         uint8_t port = params->port;
9546         struct bnx2x_softc *sc = params->sc;
9547         pin_cfg = (REG_RD(sc, params->shmem_base +
9548                          offsetof(struct shmem_region,
9549                                   dev_info.port_hw_config[port].e3_sfp_ctrl)) &
9550                 PORT_HW_CFG_E3_FAULT_MDL_LED_MASK) >>
9551                 PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT;
9552         ELINK_DEBUG_P2(sc, "Setting Fault LED to %d using pin cfg %d",
9553                        gpio_mode, pin_cfg);
9554         elink_set_cfg_pin(sc, pin_cfg, gpio_mode);
9555 }
9556
9557 static void elink_set_sfp_module_fault_led(struct elink_params *params,
9558                                            uint8_t gpio_mode)
9559 {
9560         struct bnx2x_softc *sc = params->sc;
9561         ELINK_DEBUG_P1(sc, "Setting SFP+ module fault LED to %d", gpio_mode);
9562         if (CHIP_IS_E3(sc)) {
9563                 /* Low ==> if SFP+ module is supported otherwise
9564                  * High ==> if SFP+ module is not on the approved vendor list
9565                  */
9566                 elink_set_e3_module_fault_led(params, gpio_mode);
9567         } else
9568                 elink_set_e1e2_module_fault_led(params, gpio_mode);
9569 }
9570
9571 static void elink_warpcore_hw_reset(__rte_unused struct elink_phy *phy,
9572                                     struct elink_params *params)
9573 {
9574         struct bnx2x_softc *sc = params->sc;
9575         elink_warpcore_power_module(params, 0);
9576         /* Put Warpcore in low power mode */
9577         REG_WR(sc, MISC_REG_WC0_RESET, 0x0c0e);
9578
9579         /* Put LCPLL in low power mode */
9580         REG_WR(sc, MISC_REG_LCPLL_E40_PWRDWN, 1);
9581         REG_WR(sc, MISC_REG_LCPLL_E40_RESETB_ANA, 0);
9582         REG_WR(sc, MISC_REG_LCPLL_E40_RESETB_DIG, 0);
9583 }
9584
9585 static void elink_power_sfp_module(struct elink_params *params,
9586                                    struct elink_phy *phy,
9587                                    uint8_t power)
9588 {
9589         struct bnx2x_softc *sc = params->sc;
9590         ELINK_DEBUG_P1(sc, "Setting SFP+ power to %x", power);
9591
9592         switch (phy->type) {
9593         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727:
9594         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722:
9595                 elink_8727_power_module(params->sc, phy, power);
9596                 break;
9597         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
9598                 elink_warpcore_power_module(params, power);
9599                 break;
9600         default:
9601                 break;
9602         }
9603 }
9604 static void elink_warpcore_set_limiting_mode(struct elink_params *params,
9605                                              struct elink_phy *phy,
9606                                              uint16_t edc_mode)
9607 {
9608         uint16_t val = 0;
9609         uint16_t mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
9610         struct bnx2x_softc *sc = params->sc;
9611
9612         uint8_t lane = elink_get_warpcore_lane(phy, params);
9613         /* This is a global register which controls all lanes */
9614         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
9615                         MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
9616         val &= ~(0xf << (lane << 2));
9617
9618         switch (edc_mode) {
9619         case ELINK_EDC_MODE_LINEAR:
9620         case ELINK_EDC_MODE_LIMITING:
9621                 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
9622                 break;
9623         case ELINK_EDC_MODE_PASSIVE_DAC:
9624         case ELINK_EDC_MODE_ACTIVE_DAC:
9625                 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC;
9626                 break;
9627         default:
9628                 break;
9629         }
9630
9631         val |= (mode << (lane << 2));
9632         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
9633                          MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, val);
9634         /* A must read */
9635         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
9636                         MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
9637
9638         /* Restart microcode to re-read the new mode */
9639         elink_warpcore_reset_lane(sc, phy, 1);
9640         elink_warpcore_reset_lane(sc, phy, 0);
9641
9642 }
9643
9644 static void elink_set_limiting_mode(struct elink_params *params,
9645                                     struct elink_phy *phy,
9646                                     uint16_t edc_mode)
9647 {
9648         switch (phy->type) {
9649         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726:
9650                 elink_8726_set_limiting_mode(params->sc, phy, edc_mode);
9651                 break;
9652         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727:
9653         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722:
9654                 elink_8727_set_limiting_mode(params->sc, phy, edc_mode);
9655                 break;
9656         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
9657                 elink_warpcore_set_limiting_mode(params, phy, edc_mode);
9658                 break;
9659         }
9660 }
9661
9662 elink_status_t elink_sfp_module_detection(struct elink_phy *phy,
9663                                struct elink_params *params)
9664 {
9665         struct bnx2x_softc *sc = params->sc;
9666         uint16_t edc_mode;
9667         elink_status_t rc = ELINK_STATUS_OK;
9668
9669         uint32_t val = REG_RD(sc, params->shmem_base +
9670                              offsetof(struct shmem_region, dev_info.
9671                                      port_feature_config[params->port].config));
9672         /* Enabled transmitter by default */
9673         elink_sfp_set_transmitter(params, phy, 1);
9674         ELINK_DEBUG_P1(sc, "SFP+ module plugged in/out detected on port %d",
9675                  params->port);
9676         /* Power up module */
9677         elink_power_sfp_module(params, phy, 1);
9678         if (elink_get_edc_mode(phy, params, &edc_mode) != 0) {
9679                 ELINK_DEBUG_P0(sc, "Failed to get valid module type");
9680                 return ELINK_STATUS_ERROR;
9681         } else if (elink_verify_sfp_module(phy, params) != 0) {
9682                 /* Check SFP+ module compatibility */
9683                 ELINK_DEBUG_P0(sc, "Module verification failed!!");
9684                 rc = ELINK_STATUS_ERROR;
9685                 /* Turn on fault module-detected led */
9686                 elink_set_sfp_module_fault_led(params,
9687                                                MISC_REGISTERS_GPIO_HIGH);
9688
9689                 /* Check if need to power down the SFP+ module */
9690                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9691                      PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN) {
9692                         ELINK_DEBUG_P0(sc, "Shutdown SFP+ module!!");
9693                         elink_power_sfp_module(params, phy, 0);
9694                         return rc;
9695                 }
9696         } else {
9697                 /* Turn off fault module-detected led */
9698                 elink_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
9699         }
9700
9701         /* Check and set limiting mode / LRM mode on 8726. On 8727 it
9702          * is done automatically
9703          */
9704         elink_set_limiting_mode(params, phy, edc_mode);
9705
9706         /* Disable transmit for this module if the module is not approved, and
9707          * laser needs to be disabled.
9708          */
9709         if ((rc != 0) &&
9710             ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9711              PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER))
9712                 elink_sfp_set_transmitter(params, phy, 0);
9713
9714         return rc;
9715 }
9716
9717 void elink_handle_module_detect_int(struct elink_params *params)
9718 {
9719         struct bnx2x_softc *sc = params->sc;
9720         struct elink_phy *phy;
9721         uint32_t gpio_val;
9722         uint8_t gpio_num, gpio_port;
9723         if (CHIP_IS_E3(sc)) {
9724                 phy = &params->phy[ELINK_INT_PHY];
9725                 /* Always enable TX laser, will be disabled in case of fault */
9726                 elink_sfp_set_transmitter(params, phy, 1);
9727         } else {
9728                 phy = &params->phy[ELINK_EXT_PHY1];
9729         }
9730         if (elink_get_mod_abs_int_cfg(sc, params->chip_id, params->shmem_base,
9731                                       params->port, &gpio_num, &gpio_port) ==
9732             ELINK_STATUS_ERROR) {
9733                 ELINK_DEBUG_P0(sc, "Failed to get MOD_ABS interrupt config");
9734                 return;
9735         }
9736
9737         /* Set valid module led off */
9738         elink_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH);
9739
9740         /* Get current gpio val reflecting module plugged in / out*/
9741         gpio_val = elink_cb_gpio_read(sc, gpio_num, gpio_port);
9742
9743         /* Call the handling function in case module is detected */
9744         if (gpio_val == 0) {
9745                 elink_set_mdio_emac_per_phy(sc, params);
9746                 elink_set_aer_mmd(params, phy);
9747
9748                 elink_power_sfp_module(params, phy, 1);
9749                 elink_cb_gpio_int_write(sc, gpio_num,
9750                                    MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
9751                                    gpio_port);
9752                 if (elink_wait_for_sfp_module_initialized(phy, params) == 0) {
9753                         elink_sfp_module_detection(phy, params);
9754                         if (CHIP_IS_E3(sc)) {
9755                                 uint16_t rx_tx_in_reset;
9756                                 /* In case WC is out of reset, reconfigure the
9757                                  * link speed while taking into account 1G
9758                                  * module limitation.
9759                                  */
9760                                 elink_cl45_read(sc, phy,
9761                                                 MDIO_WC_DEVAD,
9762                                                 MDIO_WC_REG_DIGITAL5_MISC6,
9763                                                 &rx_tx_in_reset);
9764                                 if ((!rx_tx_in_reset) &&
9765                                     (params->link_flags &
9766                                      ELINK_PHY_INITIALIZED)) {
9767                                         elink_warpcore_reset_lane(sc, phy, 1);
9768                                         elink_warpcore_config_sfi(phy, params);
9769                                         elink_warpcore_reset_lane(sc, phy, 0);
9770                                 }
9771                         }
9772                 } else {
9773                         ELINK_DEBUG_P0(sc, "SFP+ module is not initialized");
9774                 }
9775         } else {
9776                 elink_cb_gpio_int_write(sc, gpio_num,
9777                                    MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
9778                                    gpio_port);
9779                 /* Module was plugged out.
9780                  * Disable transmit for this module
9781                  */
9782                 phy->media_type = ELINK_ETH_PHY_NOT_PRESENT;
9783         }
9784 }
9785
9786 /******************************************************************/
9787 /*              Used by 8706 and 8727                             */
9788 /******************************************************************/
9789 static void elink_sfp_mask_fault(struct bnx2x_softc *sc,
9790                                  struct elink_phy *phy,
9791                                  uint16_t alarm_status_offset,
9792                                  uint16_t alarm_ctrl_offset)
9793 {
9794         uint16_t alarm_status, val;
9795         elink_cl45_read(sc, phy,
9796                         MDIO_PMA_DEVAD, alarm_status_offset,
9797                         &alarm_status);
9798         elink_cl45_read(sc, phy,
9799                         MDIO_PMA_DEVAD, alarm_status_offset,
9800                         &alarm_status);
9801         /* Mask or enable the fault event. */
9802         elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, &val);
9803         if (alarm_status & (1 << 0))
9804                 val &= ~(1 << 0);
9805         else
9806                 val |= (1 << 0);
9807         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, val);
9808 }
9809 /******************************************************************/
9810 /*              common BNX2X8706/BNX2X8726 PHY SECTION            */
9811 /******************************************************************/
9812 static uint8_t elink_8706_8726_read_status(struct elink_phy *phy,
9813                                       struct elink_params *params,
9814                                       struct elink_vars *vars)
9815 {
9816         uint8_t link_up = 0;
9817         uint16_t val1, val2, rx_sd, pcs_status;
9818         struct bnx2x_softc *sc = params->sc;
9819         ELINK_DEBUG_P0(sc, "XGXS 8706/8726");
9820         /* Clear RX Alarm*/
9821         elink_cl45_read(sc, phy,
9822                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
9823
9824         elink_sfp_mask_fault(sc, phy, MDIO_PMA_LASI_TXSTAT,
9825                              MDIO_PMA_LASI_TXCTRL);
9826
9827         /* Clear LASI indication*/
9828         elink_cl45_read(sc, phy,
9829                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
9830         elink_cl45_read(sc, phy,
9831                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
9832         ELINK_DEBUG_P2(sc, "8706/8726 LASI status 0x%x--> 0x%x", val1, val2);
9833
9834         elink_cl45_read(sc, phy,
9835                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
9836         elink_cl45_read(sc, phy,
9837                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
9838         elink_cl45_read(sc, phy,
9839                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
9840         elink_cl45_read(sc, phy,
9841                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
9842
9843         ELINK_DEBUG_P3(sc, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
9844                         " link_status 0x%x", rx_sd, pcs_status, val2);
9845         /* Link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
9846          * are set, or if the autoneg bit 1 is set
9847          */
9848         link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1 << 1)));
9849         if (link_up) {
9850                 if (val2 & (1 << 1))
9851                         vars->line_speed = ELINK_SPEED_1000;
9852                 else
9853                         vars->line_speed = ELINK_SPEED_10000;
9854                 elink_ext_phy_resolve_fc(phy, params, vars);
9855                 vars->duplex = DUPLEX_FULL;
9856         }
9857
9858         /* Capture 10G link fault. Read twice to clear stale value. */
9859         if (vars->line_speed == ELINK_SPEED_10000) {
9860                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
9861                             MDIO_PMA_LASI_TXSTAT, &val1);
9862                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
9863                             MDIO_PMA_LASI_TXSTAT, &val1);
9864                 if (val1 & (1 << 0))
9865                         vars->fault_detected = 1;
9866         }
9867
9868         return link_up;
9869 }
9870
9871 /******************************************************************/
9872 /*                      BNX2X8706 PHY SECTION                     */
9873 /******************************************************************/
9874 static uint8_t elink_8706_config_init(struct elink_phy *phy,
9875                                  struct elink_params *params,
9876                                  __rte_unused struct elink_vars *vars)
9877 {
9878         uint32_t tx_en_mode;
9879         uint16_t cnt, val, tmp1;
9880         struct bnx2x_softc *sc = params->sc;
9881
9882         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
9883                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
9884         /* HW reset */
9885         elink_ext_phy_hw_reset(sc, params->port);
9886         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
9887         elink_wait_reset_complete(sc, phy, params);
9888
9889         /* Wait until fw is loaded */
9890         for (cnt = 0; cnt < 100; cnt++) {
9891                 elink_cl45_read(sc, phy,
9892                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
9893                 if (val)
9894                         break;
9895                 DELAY(1000 * 10);
9896         }
9897         ELINK_DEBUG_P1(sc, "XGXS 8706 is initialized after %d ms", cnt);
9898         if ((params->feature_config_flags &
9899              ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
9900                 uint8_t i;
9901                 uint16_t reg;
9902                 for (i = 0; i < 4; i++) {
9903                         reg = MDIO_XS_8706_REG_BANK_RX0 +
9904                                 i * (MDIO_XS_8706_REG_BANK_RX1 -
9905                                      MDIO_XS_8706_REG_BANK_RX0);
9906                         elink_cl45_read(sc, phy, MDIO_XS_DEVAD, reg, &val);
9907                         /* Clear first 3 bits of the control */
9908                         val &= ~0x7;
9909                         /* Set control bits according to configuration */
9910                         val |= (phy->rx_preemphasis[i] & 0x7);
9911                         ELINK_DEBUG_P2(sc, "Setting RX Equalizer to BNX2X8706"
9912                                    " reg 0x%x <-- val 0x%x", reg, val);
9913                         elink_cl45_write(sc, phy, MDIO_XS_DEVAD, reg, val);
9914                 }
9915         }
9916         /* Force speed */
9917         if (phy->req_line_speed == ELINK_SPEED_10000) {
9918                 ELINK_DEBUG_P0(sc, "XGXS 8706 force 10Gbps");
9919
9920                 elink_cl45_write(sc, phy,
9921                                  MDIO_PMA_DEVAD,
9922                                  MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
9923                 elink_cl45_write(sc, phy,
9924                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
9925                                  0);
9926                 /* Arm LASI for link and Tx fault. */
9927                 elink_cl45_write(sc, phy,
9928                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 3);
9929         } else {
9930                 /* Force 1Gbps using autoneg with 1G advertisement */
9931
9932                 /* Allow CL37 through CL73 */
9933                 ELINK_DEBUG_P0(sc, "XGXS 8706 AutoNeg");
9934                 elink_cl45_write(sc, phy,
9935                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
9936
9937                 /* Enable Full-Duplex advertisement on CL37 */
9938                 elink_cl45_write(sc, phy,
9939                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
9940                 /* Enable CL37 AN */
9941                 elink_cl45_write(sc, phy,
9942                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
9943                 /* 1G support */
9944                 elink_cl45_write(sc, phy,
9945                                  MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1 << 5));
9946
9947                 /* Enable clause 73 AN */
9948                 elink_cl45_write(sc, phy,
9949                                  MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
9950                 elink_cl45_write(sc, phy,
9951                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9952                                  0x0400);
9953                 elink_cl45_write(sc, phy,
9954                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
9955                                  0x0004);
9956         }
9957         elink_save_bnx2x_spirom_ver(sc, phy, params->port);
9958
9959         /* If TX Laser is controlled by GPIO_0, do not let PHY go into low
9960          * power mode, if TX Laser is disabled
9961          */
9962
9963         tx_en_mode = REG_RD(sc, params->shmem_base +
9964                             offsetof(struct shmem_region,
9965                                 dev_info.port_hw_config[params->port].sfp_ctrl))
9966                         & PORT_HW_CFG_TX_LASER_MASK;
9967
9968         if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
9969                 ELINK_DEBUG_P0(sc, "Enabling TXONOFF_PWRDN_DIS");
9970                 elink_cl45_read(sc, phy,
9971                         MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1);
9972                 tmp1 |= 0x1;
9973                 elink_cl45_write(sc, phy,
9974                         MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1);
9975         }
9976
9977         return ELINK_STATUS_OK;
9978 }
9979
9980 static uint8_t elink_8706_read_status(struct elink_phy *phy,
9981                                   struct elink_params *params,
9982                                   struct elink_vars *vars)
9983 {
9984         return elink_8706_8726_read_status(phy, params, vars);
9985 }
9986
9987 /******************************************************************/
9988 /*                      BNX2X8726 PHY SECTION                     */
9989 /******************************************************************/
9990 static void elink_8726_config_loopback(struct elink_phy *phy,
9991                                        struct elink_params *params)
9992 {
9993         struct bnx2x_softc *sc = params->sc;
9994         ELINK_DEBUG_P0(sc, "PMA/PMD ext_phy_loopback: 8726");
9995         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
9996 }
9997
9998 static void elink_8726_external_rom_boot(struct elink_phy *phy,
9999                                          struct elink_params *params)
10000 {
10001         struct bnx2x_softc *sc = params->sc;
10002         /* Need to wait 100ms after reset */
10003         DELAY(1000 * 100);
10004
10005         /* Micro controller re-boot */
10006         elink_cl45_write(sc, phy,
10007                          MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
10008
10009         /* Set soft reset */
10010         elink_cl45_write(sc, phy,
10011                          MDIO_PMA_DEVAD,
10012                          MDIO_PMA_REG_GEN_CTRL,
10013                          MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
10014
10015         elink_cl45_write(sc, phy,
10016                          MDIO_PMA_DEVAD,
10017                          MDIO_PMA_REG_MISC_CTRL1, 0x0001);
10018
10019         elink_cl45_write(sc, phy,
10020                          MDIO_PMA_DEVAD,
10021                          MDIO_PMA_REG_GEN_CTRL,
10022                          MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
10023
10024         /* Wait for 150ms for microcode load */
10025         DELAY(1000 * 150);
10026
10027         /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
10028         elink_cl45_write(sc, phy,
10029                          MDIO_PMA_DEVAD,
10030                          MDIO_PMA_REG_MISC_CTRL1, 0x0000);
10031
10032         DELAY(1000 * 200);
10033         elink_save_bnx2x_spirom_ver(sc, phy, params->port);
10034 }
10035
10036 static uint8_t elink_8726_read_status(struct elink_phy *phy,
10037                                  struct elink_params *params,
10038                                  struct elink_vars *vars)
10039 {
10040         struct bnx2x_softc *sc = params->sc;
10041         uint16_t val1;
10042         uint8_t link_up = elink_8706_8726_read_status(phy, params, vars);
10043         if (link_up) {
10044                 elink_cl45_read(sc, phy,
10045                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
10046                                 &val1);
10047                 if (val1 & (1 << 15)) {
10048                         ELINK_DEBUG_P0(sc, "Tx is disabled");
10049                         link_up = 0;
10050                         vars->line_speed = 0;
10051                 }
10052         }
10053         return link_up;
10054 }
10055
10056
10057 static uint8_t elink_8726_config_init(struct elink_phy *phy,
10058                                   struct elink_params *params,
10059                                   struct elink_vars *vars)
10060 {
10061         struct bnx2x_softc *sc = params->sc;
10062         ELINK_DEBUG_P0(sc, "Initializing BNX2X8726");
10063
10064         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1 << 15);
10065         elink_wait_reset_complete(sc, phy, params);
10066
10067         elink_8726_external_rom_boot(phy, params);
10068
10069         /* Need to call module detected on initialization since the module
10070          * detection triggered by actual module insertion might occur before
10071          * driver is loaded, and when driver is loaded, it reset all
10072          * registers, including the transmitter
10073          */
10074         elink_sfp_module_detection(phy, params);
10075
10076         if (phy->req_line_speed == ELINK_SPEED_1000) {
10077                 ELINK_DEBUG_P0(sc, "Setting 1G force");
10078                 elink_cl45_write(sc, phy,
10079                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
10080                 elink_cl45_write(sc, phy,
10081                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
10082                 elink_cl45_write(sc, phy,
10083                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x5);
10084                 elink_cl45_write(sc, phy,
10085                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
10086                                  0x400);
10087         } else if ((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10088                    (phy->speed_cap_mask &
10089                       PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
10090                    ((phy->speed_cap_mask &
10091                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
10092                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
10093                 ELINK_DEBUG_P0(sc, "Setting 1G clause37");
10094                 /* Set Flow control */
10095                 elink_ext_phy_set_pause(params, phy, vars);
10096                 elink_cl45_write(sc, phy,
10097                                  MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
10098                 elink_cl45_write(sc, phy,
10099                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
10100                 elink_cl45_write(sc, phy,
10101                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
10102                 elink_cl45_write(sc, phy,
10103                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
10104                 elink_cl45_write(sc, phy,
10105                                 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
10106                 /* Enable RX-ALARM control to receive interrupt for 1G speed
10107                  * change
10108                  */
10109                 elink_cl45_write(sc, phy,
10110                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x4);
10111                 elink_cl45_write(sc, phy,
10112                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
10113                                  0x400);
10114
10115         } else { /* Default 10G. Set only LASI control */
10116                 elink_cl45_write(sc, phy,
10117                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 1);
10118         }
10119
10120         /* Set TX PreEmphasis if needed */
10121         if ((params->feature_config_flags &
10122              ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
10123                 ELINK_DEBUG_P2(sc,
10124                    "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x",
10125                          phy->tx_preemphasis[0],
10126                          phy->tx_preemphasis[1]);
10127                 elink_cl45_write(sc, phy,
10128                                  MDIO_PMA_DEVAD,
10129                                  MDIO_PMA_REG_8726_TX_CTRL1,
10130                                  phy->tx_preemphasis[0]);
10131
10132                 elink_cl45_write(sc, phy,
10133                                  MDIO_PMA_DEVAD,
10134                                  MDIO_PMA_REG_8726_TX_CTRL2,
10135                                  phy->tx_preemphasis[1]);
10136         }
10137
10138         return ELINK_STATUS_OK;
10139
10140 }
10141
10142 static void elink_8726_link_reset(struct elink_phy *phy,
10143                                   struct elink_params *params)
10144 {
10145         struct bnx2x_softc *sc = params->sc;
10146         ELINK_DEBUG_P1(sc, "elink_8726_link_reset port %d", params->port);
10147         /* Set serial boot control for external load */
10148         elink_cl45_write(sc, phy,
10149                          MDIO_PMA_DEVAD,
10150                          MDIO_PMA_REG_GEN_CTRL, 0x0001);
10151 }
10152
10153 /******************************************************************/
10154 /*                      BNX2X8727 PHY SECTION                     */
10155 /******************************************************************/
10156
10157 static void elink_8727_set_link_led(struct elink_phy *phy,
10158                                     struct elink_params *params, uint8_t mode)
10159 {
10160         struct bnx2x_softc *sc = params->sc;
10161         uint16_t led_mode_bitmask = 0;
10162         uint16_t gpio_pins_bitmask = 0;
10163         uint16_t val;
10164         /* Only NOC flavor requires to set the LED specifically */
10165         if (!(phy->flags & ELINK_FLAGS_NOC))
10166                 return;
10167         switch (mode) {
10168         case ELINK_LED_MODE_FRONT_PANEL_OFF:
10169         case ELINK_LED_MODE_OFF:
10170                 led_mode_bitmask = 0;
10171                 gpio_pins_bitmask = 0x03;
10172                 break;
10173         case ELINK_LED_MODE_ON:
10174                 led_mode_bitmask = 0;
10175                 gpio_pins_bitmask = 0x02;
10176                 break;
10177         case ELINK_LED_MODE_OPER:
10178                 led_mode_bitmask = 0x60;
10179                 gpio_pins_bitmask = 0x11;
10180                 break;
10181         }
10182         elink_cl45_read(sc, phy,
10183                         MDIO_PMA_DEVAD,
10184                         MDIO_PMA_REG_8727_PCS_OPT_CTRL,
10185                         &val);
10186         val &= 0xff8f;
10187         val |= led_mode_bitmask;
10188         elink_cl45_write(sc, phy,
10189                          MDIO_PMA_DEVAD,
10190                          MDIO_PMA_REG_8727_PCS_OPT_CTRL,
10191                          val);
10192         elink_cl45_read(sc, phy,
10193                         MDIO_PMA_DEVAD,
10194                         MDIO_PMA_REG_8727_GPIO_CTRL,
10195                         &val);
10196         val &= 0xffe0;
10197         val |= gpio_pins_bitmask;
10198         elink_cl45_write(sc, phy,
10199                          MDIO_PMA_DEVAD,
10200                          MDIO_PMA_REG_8727_GPIO_CTRL,
10201                          val);
10202 }
10203 static void elink_8727_hw_reset(__rte_unused struct elink_phy *phy,
10204                                 struct elink_params *params) {
10205         uint32_t swap_val, swap_override;
10206         uint8_t port;
10207         /* The PHY reset is controlled by GPIO 1. Fake the port number
10208          * to cancel the swap done in set_gpio()
10209          */
10210         struct bnx2x_softc *sc = params->sc;
10211         swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
10212         swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
10213         port = (swap_val && swap_override) ^ 1;
10214         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
10215                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
10216 }
10217
10218 static void elink_8727_config_speed(struct elink_phy *phy,
10219                                     struct elink_params *params)
10220 {
10221         struct bnx2x_softc *sc = params->sc;
10222         uint16_t tmp1, val;
10223         /* Set option 1G speed */
10224         if ((phy->req_line_speed == ELINK_SPEED_1000) ||
10225             (phy->media_type == ELINK_ETH_PHY_SFP_1G_FIBER)) {
10226                 ELINK_DEBUG_P0(sc, "Setting 1G force");
10227                 elink_cl45_write(sc, phy,
10228                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
10229                 elink_cl45_write(sc, phy,
10230                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
10231                 elink_cl45_read(sc, phy,
10232                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
10233                 ELINK_DEBUG_P1(sc, "1.7 = 0x%x", tmp1);
10234                 /* Power down the XAUI until link is up in case of dual-media
10235                  * and 1G
10236                  */
10237                 if (ELINK_DUAL_MEDIA(params)) {
10238                         elink_cl45_read(sc, phy,
10239                                         MDIO_PMA_DEVAD,
10240                                         MDIO_PMA_REG_8727_PCS_GP, &val);
10241                         val |= (3 << 10);
10242                         elink_cl45_write(sc, phy,
10243                                          MDIO_PMA_DEVAD,
10244                                          MDIO_PMA_REG_8727_PCS_GP, val);
10245                 }
10246         } else if ((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10247                    ((phy->speed_cap_mask &
10248                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
10249                    ((phy->speed_cap_mask &
10250                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
10251                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
10252
10253                 ELINK_DEBUG_P0(sc, "Setting 1G clause37");
10254                 elink_cl45_write(sc, phy,
10255                                  MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
10256                 elink_cl45_write(sc, phy,
10257                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
10258         } else {
10259                 /* Since the 8727 has only single reset pin, need to set the 10G
10260                  * registers although it is default
10261                  */
10262                 elink_cl45_write(sc, phy,
10263                                  MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
10264                                  0x0020);
10265                 elink_cl45_write(sc, phy,
10266                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
10267                 elink_cl45_write(sc, phy,
10268                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
10269                 elink_cl45_write(sc, phy,
10270                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
10271                                  0x0008);
10272         }
10273 }
10274
10275 static uint8_t elink_8727_config_init(struct elink_phy *phy,
10276                                   struct elink_params *params,
10277                                   __rte_unused struct elink_vars *vars)
10278 {
10279         uint32_t tx_en_mode;
10280         uint16_t tmp1, mod_abs, tmp2;
10281         struct bnx2x_softc *sc = params->sc;
10282         /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
10283
10284         elink_wait_reset_complete(sc, phy, params);
10285
10286         ELINK_DEBUG_P0(sc, "Initializing BNX2X8727");
10287
10288         elink_8727_specific_func(phy, params, ELINK_PHY_INIT);
10289         /* Initially configure MOD_ABS to interrupt when module is
10290          * presence( bit 8)
10291          */
10292         elink_cl45_read(sc, phy,
10293                         MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
10294         /* Set EDC off by setting OPTXLOS signal input to low (bit 9).
10295          * When the EDC is off it locks onto a reference clock and avoids
10296          * becoming 'lost'
10297          */
10298         mod_abs &= ~(1 << 8);
10299         if (!(phy->flags & ELINK_FLAGS_NOC))
10300                 mod_abs &= ~(1 << 9);
10301         elink_cl45_write(sc, phy,
10302                          MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
10303
10304         /* Enable/Disable PHY transmitter output */
10305         elink_set_disable_pmd_transmit(params, phy, 0);
10306
10307         elink_8727_power_module(sc, phy, 1);
10308
10309         elink_cl45_read(sc, phy,
10310                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
10311
10312         elink_cl45_read(sc, phy,
10313                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
10314
10315         elink_8727_config_speed(phy, params);
10316
10317
10318         /* Set TX PreEmphasis if needed */
10319         if ((params->feature_config_flags &
10320              ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
10321                 ELINK_DEBUG_P2(sc, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x",
10322                            phy->tx_preemphasis[0],
10323                            phy->tx_preemphasis[1]);
10324                 elink_cl45_write(sc, phy,
10325                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
10326                                  phy->tx_preemphasis[0]);
10327
10328                 elink_cl45_write(sc, phy,
10329                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
10330                                  phy->tx_preemphasis[1]);
10331         }
10332
10333         /* If TX Laser is controlled by GPIO_0, do not let PHY go into low
10334          * power mode, if TX Laser is disabled
10335          */
10336         tx_en_mode = REG_RD(sc, params->shmem_base +
10337                             offsetof(struct shmem_region,
10338                                 dev_info.port_hw_config[params->port].sfp_ctrl))
10339                         & PORT_HW_CFG_TX_LASER_MASK;
10340
10341         if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
10342
10343                 ELINK_DEBUG_P0(sc, "Enabling TXONOFF_PWRDN_DIS");
10344                 elink_cl45_read(sc, phy,
10345                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2);
10346                 tmp2 |= 0x1000;
10347                 tmp2 &= 0xFFEF;
10348                 elink_cl45_write(sc, phy,
10349                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
10350                 elink_cl45_read(sc, phy,
10351                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
10352                                 &tmp2);
10353                 elink_cl45_write(sc, phy,
10354                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
10355                                  (tmp2 & 0x7fff));
10356         }
10357
10358         return ELINK_STATUS_OK;
10359 }
10360
10361 static void elink_8727_handle_mod_abs(struct elink_phy *phy,
10362                                       struct elink_params *params)
10363 {
10364         struct bnx2x_softc *sc = params->sc;
10365         uint16_t mod_abs, rx_alarm_status;
10366         uint32_t val = REG_RD(sc, params->shmem_base +
10367                              offsetof(struct shmem_region, dev_info.
10368                                       port_feature_config[params->port].
10369                                       config));
10370         elink_cl45_read(sc, phy,
10371                         MDIO_PMA_DEVAD,
10372                         MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
10373         if (mod_abs & (1 << 8)) {
10374
10375                 /* Module is absent */
10376                 ELINK_DEBUG_P0(sc,
10377                    "MOD_ABS indication show module is absent");
10378                 phy->media_type = ELINK_ETH_PHY_NOT_PRESENT;
10379                 /* 1. Set mod_abs to detect next module
10380                  *    presence event
10381                  * 2. Set EDC off by setting OPTXLOS signal input to low
10382                  *    (bit 9).
10383                  *    When the EDC is off it locks onto a reference clock and
10384                  *    avoids becoming 'lost'.
10385                  */
10386                 mod_abs &= ~(1 << 8);
10387                 if (!(phy->flags & ELINK_FLAGS_NOC))
10388                         mod_abs &= ~(1 << 9);
10389                 elink_cl45_write(sc, phy,
10390                                  MDIO_PMA_DEVAD,
10391                                  MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
10392
10393                 /* Clear RX alarm since it stays up as long as
10394                  * the mod_abs wasn't changed
10395                  */
10396                 elink_cl45_read(sc, phy,
10397                                 MDIO_PMA_DEVAD,
10398                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
10399
10400         } else {
10401                 /* Module is present */
10402                 ELINK_DEBUG_P0(sc,
10403                    "MOD_ABS indication show module is present");
10404                 /* First disable transmitter, and if the module is ok, the
10405                  * module_detection will enable it
10406                  * 1. Set mod_abs to detect next module absent event ( bit 8)
10407                  * 2. Restore the default polarity of the OPRXLOS signal and
10408                  * this signal will then correctly indicate the presence or
10409                  * absence of the Rx signal. (bit 9)
10410                  */
10411                 mod_abs |= (1 << 8);
10412                 if (!(phy->flags & ELINK_FLAGS_NOC))
10413                         mod_abs |= (1 << 9);
10414                 elink_cl45_write(sc, phy,
10415                                  MDIO_PMA_DEVAD,
10416                                  MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
10417
10418                 /* Clear RX alarm since it stays up as long as the mod_abs
10419                  * wasn't changed. This is need to be done before calling the
10420                  * module detection, otherwise it will clear* the link update
10421                  * alarm
10422                  */
10423                 elink_cl45_read(sc, phy,
10424                                 MDIO_PMA_DEVAD,
10425                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
10426
10427
10428                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
10429                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
10430                         elink_sfp_set_transmitter(params, phy, 0);
10431
10432                 if (elink_wait_for_sfp_module_initialized(phy, params) == 0)
10433                         elink_sfp_module_detection(phy, params);
10434                 else
10435                         ELINK_DEBUG_P0(sc, "SFP+ module is not initialized");
10436
10437                 /* Reconfigure link speed based on module type limitations */
10438                 elink_8727_config_speed(phy, params);
10439         }
10440
10441         ELINK_DEBUG_P1(sc, "8727 RX_ALARM_STATUS 0x%x",
10442                    rx_alarm_status);
10443         /* No need to check link status in case of module plugged in/out */
10444 }
10445
10446 static uint8_t elink_8727_read_status(struct elink_phy *phy,
10447                                  struct elink_params *params,
10448                                  struct elink_vars *vars)
10449
10450 {
10451         struct bnx2x_softc *sc = params->sc;
10452         uint8_t link_up = 0;
10453         uint16_t link_status = 0;
10454         uint16_t rx_alarm_status, lasi_ctrl, val1;
10455
10456         /* If PHY is not initialized, do not check link status */
10457         elink_cl45_read(sc, phy,
10458                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
10459                         &lasi_ctrl);
10460         if (!lasi_ctrl)
10461                 return 0;
10462
10463         /* Check the LASI on Rx */
10464         elink_cl45_read(sc, phy,
10465                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT,
10466                         &rx_alarm_status);
10467         vars->line_speed = 0;
10468         ELINK_DEBUG_P1(sc, "8727 RX_ALARM_STATUS  0x%x", rx_alarm_status);
10469
10470         elink_sfp_mask_fault(sc, phy, MDIO_PMA_LASI_TXSTAT,
10471                              MDIO_PMA_LASI_TXCTRL);
10472
10473         elink_cl45_read(sc, phy,
10474                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
10475
10476         ELINK_DEBUG_P1(sc, "8727 LASI status 0x%x", val1);
10477
10478         /* Clear MSG-OUT */
10479         elink_cl45_read(sc, phy,
10480                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
10481
10482         /* If a module is present and there is need to check
10483          * for over current
10484          */
10485         if (!(phy->flags & ELINK_FLAGS_NOC) && !(rx_alarm_status & (1 << 5))) {
10486                 /* Check over-current using 8727 GPIO0 input*/
10487                 elink_cl45_read(sc, phy,
10488                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
10489                                 &val1);
10490
10491                 if ((val1 & (1 << 8)) == 0) {
10492                         uint8_t oc_port = params->port;
10493                         if (!CHIP_IS_E1x(sc))
10494                                 oc_port = SC_PATH(sc) + (params->port << 1);
10495                         ELINK_DEBUG_P1(sc,
10496                            "8727 Power fault has been detected on port %d",
10497                            oc_port);
10498                         elink_cb_event_log(sc, ELINK_LOG_ID_OVER_CURRENT,
10499                                            oc_port);
10500                                         /* "Error: Power fault on Port %d has "
10501                                          *  "been detected and the power to "
10502                                          *  "that SFP+ module has been removed "
10503                                          *  "to prevent failure of the card. "
10504                                          *  "Please remove the SFP+ module and "
10505                                          *  "restart the system to clear this "
10506                                          *  "error.",
10507                                          */
10508                         /* Disable all RX_ALARMs except for mod_abs */
10509                         elink_cl45_write(sc, phy,
10510                                          MDIO_PMA_DEVAD,
10511                                          MDIO_PMA_LASI_RXCTRL, (1 << 5));
10512
10513                         elink_cl45_read(sc, phy,
10514                                         MDIO_PMA_DEVAD,
10515                                         MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
10516                         /* Wait for module_absent_event */
10517                         val1 |= (1 << 8);
10518                         elink_cl45_write(sc, phy,
10519                                          MDIO_PMA_DEVAD,
10520                                          MDIO_PMA_REG_PHY_IDENTIFIER, val1);
10521                         /* Clear RX alarm */
10522                         elink_cl45_read(sc, phy,
10523                                 MDIO_PMA_DEVAD,
10524                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
10525                         elink_8727_power_module(params->sc, phy, 0);
10526                         return 0;
10527                 }
10528         } /* Over current check */
10529
10530         /* When module absent bit is set, check module */
10531         if (rx_alarm_status & (1 << 5)) {
10532                 elink_8727_handle_mod_abs(phy, params);
10533                 /* Enable all mod_abs and link detection bits */
10534                 elink_cl45_write(sc, phy,
10535                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
10536                                  ((1 << 5) | (1 << 2)));
10537         }
10538
10539         if (!(phy->flags & ELINK_FLAGS_SFP_NOT_APPROVED)) {
10540                 ELINK_DEBUG_P0(sc, "Enabling 8727 TX laser");
10541                 elink_sfp_set_transmitter(params, phy, 1);
10542         } else {
10543                 ELINK_DEBUG_P0(sc, "Tx is disabled");
10544                 return 0;
10545         }
10546
10547         elink_cl45_read(sc, phy,
10548                         MDIO_PMA_DEVAD,
10549                         MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
10550
10551         /* Bits 0..2 --> speed detected,
10552          * Bits 13..15--> link is down
10553          */
10554         if ((link_status & (1 << 2)) && (!(link_status & (1 << 15)))) {
10555                 link_up = 1;
10556                 vars->line_speed = ELINK_SPEED_10000;
10557                 ELINK_DEBUG_P1(sc, "port %x: External link up in 10G",
10558                            params->port);
10559         } else if ((link_status & (1 << 0)) && (!(link_status & (1 << 13)))) {
10560                 link_up = 1;
10561                 vars->line_speed = ELINK_SPEED_1000;
10562                 ELINK_DEBUG_P1(sc, "port %x: External link up in 1G",
10563                            params->port);
10564         } else {
10565                 link_up = 0;
10566                 ELINK_DEBUG_P1(sc, "port %x: External link is down",
10567                            params->port);
10568         }
10569
10570         /* Capture 10G link fault. */
10571         if (vars->line_speed == ELINK_SPEED_10000) {
10572                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
10573                             MDIO_PMA_LASI_TXSTAT, &val1);
10574
10575                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
10576                             MDIO_PMA_LASI_TXSTAT, &val1);
10577
10578                 if (val1 & (1 << 0)) {
10579                         vars->fault_detected = 1;
10580                 }
10581         }
10582
10583         if (link_up) {
10584                 elink_ext_phy_resolve_fc(phy, params, vars);
10585                 vars->duplex = DUPLEX_FULL;
10586                 ELINK_DEBUG_P1(sc, "duplex = 0x%x", vars->duplex);
10587         }
10588
10589         if ((ELINK_DUAL_MEDIA(params)) &&
10590             (phy->req_line_speed == ELINK_SPEED_1000)) {
10591                 elink_cl45_read(sc, phy,
10592                                 MDIO_PMA_DEVAD,
10593                                 MDIO_PMA_REG_8727_PCS_GP, &val1);
10594                 /* In case of dual-media board and 1G, power up the XAUI side,
10595                  * otherwise power it down. For 10G it is done automatically
10596                  */
10597                 if (link_up)
10598                         val1 &= ~(3 << 10);
10599                 else
10600                         val1 |= (3 << 10);
10601                 elink_cl45_write(sc, phy,
10602                                  MDIO_PMA_DEVAD,
10603                                  MDIO_PMA_REG_8727_PCS_GP, val1);
10604         }
10605         return link_up;
10606 }
10607
10608 static void elink_8727_link_reset(struct elink_phy *phy,
10609                                   struct elink_params *params)
10610 {
10611         struct bnx2x_softc *sc = params->sc;
10612
10613         /* Enable/Disable PHY transmitter output */
10614         elink_set_disable_pmd_transmit(params, phy, 1);
10615
10616         /* Disable Transmitter */
10617         elink_sfp_set_transmitter(params, phy, 0);
10618         /* Clear LASI */
10619         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0);
10620
10621 }
10622
10623 /******************************************************************/
10624 /*              BNX2X8481/BNX2X84823/BNX2X84833 PHY SECTION               */
10625 /******************************************************************/
10626 static int elink_is_8483x_8485x(struct elink_phy *phy)
10627 {
10628         return ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84833) ||
10629                 (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834) ||
10630                 (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858));
10631 }
10632
10633 static void elink_save_848xx_spirom_version(struct elink_phy *phy,
10634                                             struct bnx2x_softc *sc,
10635                                             uint8_t port)
10636 {
10637         uint16_t val, fw_ver2, cnt, i;
10638         static struct elink_reg_set reg_set[] = {
10639                 {MDIO_PMA_DEVAD, 0xA819, 0x0014},
10640                 {MDIO_PMA_DEVAD, 0xA81A, 0xc200},
10641                 {MDIO_PMA_DEVAD, 0xA81B, 0x0000},
10642                 {MDIO_PMA_DEVAD, 0xA81C, 0x0300},
10643                 {MDIO_PMA_DEVAD, 0xA817, 0x0009}
10644         };
10645         uint16_t fw_ver1;
10646
10647         if (elink_is_8483x_8485x(phy)) {
10648                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD, 0x400f, &fw_ver1);
10649                 elink_save_spirom_version(sc, port, fw_ver1 & 0xfff,
10650                                 phy->ver_addr);
10651         } else {
10652                 /* For 32-bit registers in 848xx, access via MDIO2ARM i/f. */
10653                 /* (1) set reg 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
10654                 for (i = 0; i < ARRAY_SIZE(reg_set); i++)
10655                         elink_cl45_write(sc, phy, reg_set[i].devad,
10656                                          reg_set[i].reg, reg_set[i].val);
10657
10658                 for (cnt = 0; cnt < 100; cnt++) {
10659                         elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA818, &val);
10660                         if (val & 1)
10661                                 break;
10662                         DELAY(5);
10663                 }
10664                 if (cnt == 100) {
10665                         ELINK_DEBUG_P0(sc, "Unable to read 848xx "
10666                                         "phy fw version(1)");
10667                         elink_save_spirom_version(sc, port, 0,
10668                                                   phy->ver_addr);
10669                         return;
10670                 }
10671
10672
10673                 /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
10674                 elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
10675                 elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
10676                 elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
10677                 for (cnt = 0; cnt < 100; cnt++) {
10678                         elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA818, &val);
10679                         if (val & 1)
10680                                 break;
10681                         DELAY(5);
10682                 }
10683                 if (cnt == 100) {
10684                         ELINK_DEBUG_P0(sc, "Unable to read 848xx phy fw "
10685                                         "version(2)");
10686                         elink_save_spirom_version(sc, port, 0,
10687                                                   phy->ver_addr);
10688                         return;
10689                 }
10690
10691                 /* lower 16 bits of the register SPI_FW_STATUS */
10692                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
10693                 /* upper 16 bits of register SPI_FW_STATUS */
10694                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
10695
10696                 elink_save_spirom_version(sc, port, (fw_ver2 << 16) | fw_ver1,
10697                                           phy->ver_addr);
10698         }
10699
10700 }
10701 static void elink_848xx_set_led(struct bnx2x_softc *sc,
10702                                 struct elink_phy *phy)
10703 {
10704         uint16_t val, offset, i;
10705         static struct elink_reg_set reg_set[] = {
10706                 {MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED1_MASK, 0x0080},
10707                 {MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED2_MASK, 0x0018},
10708                 {MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED3_MASK, 0x0006},
10709                 {MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED3_BLINK, 0x0000},
10710                 {MDIO_PMA_DEVAD, MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH,
10711                         MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ},
10712                 {MDIO_AN_DEVAD, 0xFFFB, 0xFFFD}
10713         };
10714         /* PHYC_CTL_LED_CTL */
10715         elink_cl45_read(sc, phy,
10716                         MDIO_PMA_DEVAD,
10717                         MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
10718         val &= 0xFE00;
10719         val |= 0x0092;
10720
10721         elink_cl45_write(sc, phy,
10722                          MDIO_PMA_DEVAD,
10723                          MDIO_PMA_REG_8481_LINK_SIGNAL, val);
10724
10725         for (i = 0; i < ARRAY_SIZE(reg_set); i++)
10726                 elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
10727                                  reg_set[i].val);
10728
10729         if (elink_is_8483x_8485x(phy))
10730                 offset = MDIO_PMA_REG_84833_CTL_LED_CTL_1;
10731         else
10732                 offset = MDIO_PMA_REG_84823_CTL_LED_CTL_1;
10733
10734         /* stretch_en for LED3*/
10735         elink_cl45_read_or_write(sc, phy,
10736                                  MDIO_PMA_DEVAD, offset,
10737                                  MDIO_PMA_REG_84823_LED3_STRETCH_EN);
10738 }
10739
10740 static void elink_848xx_specific_func(struct elink_phy *phy,
10741                                       struct elink_params *params,
10742                                       uint32_t action)
10743 {
10744         struct bnx2x_softc *sc = params->sc;
10745         switch (action) {
10746         case ELINK_PHY_INIT:
10747                 if (!elink_is_8483x_8485x(phy)) {
10748                         /* Save spirom version */
10749                         elink_save_848xx_spirom_version(phy, sc, params->port);
10750                 }
10751                 /* This phy uses the NIG latch mechanism since link indication
10752                  * arrives through its LED4 and not via its LASI signal, so we
10753                  * get steady signal instead of clear on read
10754                  */
10755                 elink_bits_en(sc, NIG_REG_LATCH_BC_0 + params->port * 4,
10756                               1 << ELINK_NIG_LATCH_BC_ENABLE_MI_INT);
10757
10758                 elink_848xx_set_led(sc, phy);
10759                 break;
10760         }
10761 }
10762
10763 static elink_status_t elink_848xx_cmn_config_init(struct elink_phy *phy,
10764                                        struct elink_params *params,
10765                                        struct elink_vars *vars)
10766 {
10767         struct bnx2x_softc *sc = params->sc;
10768         uint16_t autoneg_val, an_1000_val, an_10_100_val;
10769
10770         elink_848xx_specific_func(phy, params, ELINK_PHY_INIT);
10771         elink_cl45_write(sc, phy,
10772                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
10773
10774         /* set 1000 speed advertisement */
10775         elink_cl45_read(sc, phy,
10776                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
10777                         &an_1000_val);
10778
10779         elink_ext_phy_set_pause(params, phy, vars);
10780         elink_cl45_read(sc, phy,
10781                         MDIO_AN_DEVAD,
10782                         MDIO_AN_REG_8481_LEGACY_AN_ADV,
10783                         &an_10_100_val);
10784         elink_cl45_read(sc, phy,
10785                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
10786                         &autoneg_val);
10787         /* Disable forced speed */
10788         autoneg_val &= ~((1 << 6) | (1 << 8) | (1 << 9) | (1 << 12) |
10789                          (1 << 13));
10790         an_10_100_val &= ~((1 << 5) | (1 << 6) | (1 << 7) | (1 << 8));
10791
10792         if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10793              (phy->speed_cap_mask &
10794              PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
10795             (phy->req_line_speed == ELINK_SPEED_1000)) {
10796                 an_1000_val |= (1 << 8);
10797                 autoneg_val |= (1 << 9 | 1 << 12);
10798                 if (phy->req_duplex == DUPLEX_FULL)
10799                         an_1000_val |= (1 << 9);
10800                 ELINK_DEBUG_P0(sc, "Advertising 1G");
10801         } else
10802                 an_1000_val &= ~((1 << 8) | (1 << 9));
10803
10804         elink_cl45_write(sc, phy,
10805                          MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
10806                          an_1000_val);
10807
10808         /* Set 10/100 speed advertisement */
10809         if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
10810                 if (phy->speed_cap_mask &
10811                     PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) {
10812                         /* Enable autoneg and restart autoneg for legacy speeds
10813                          */
10814                         autoneg_val |= (1 << 9 | 1 << 12);
10815                         an_10_100_val |= (1 << 8);
10816                         ELINK_DEBUG_P0(sc, "Advertising 100M-FD");
10817                 }
10818
10819                 if (phy->speed_cap_mask &
10820                     PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) {
10821                         /* Enable autoneg and restart autoneg for legacy speeds
10822                          */
10823                         autoneg_val |= (1 << 9 | 1 << 12);
10824                         an_10_100_val |= (1 << 7);
10825                         ELINK_DEBUG_P0(sc, "Advertising 100M-HD");
10826                 }
10827
10828                 if ((phy->speed_cap_mask &
10829                      PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
10830                     (phy->supported & ELINK_SUPPORTED_10baseT_Full)) {
10831                         an_10_100_val |= (1 << 6);
10832                         autoneg_val |= (1 << 9 | 1 << 12);
10833                         ELINK_DEBUG_P0(sc, "Advertising 10M-FD");
10834                 }
10835
10836                 if ((phy->speed_cap_mask &
10837                      PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) &&
10838                     (phy->supported & ELINK_SUPPORTED_10baseT_Half)) {
10839                         an_10_100_val |= (1 << 5);
10840                         autoneg_val |= (1 << 9 | 1 << 12);
10841                         ELINK_DEBUG_P0(sc, "Advertising 10M-HD");
10842                 }
10843         }
10844
10845         /* Only 10/100 are allowed to work in FORCE mode */
10846         if ((phy->req_line_speed == ELINK_SPEED_100) &&
10847             (phy->supported &
10848              (ELINK_SUPPORTED_100baseT_Half |
10849               ELINK_SUPPORTED_100baseT_Full))) {
10850                 autoneg_val |= (1 << 13);
10851                 /* Enabled AUTO-MDIX when autoneg is disabled */
10852                 elink_cl45_write(sc, phy,
10853                                  MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
10854                                  (1 << 15 | 1 << 9 | 7 << 0));
10855                 /* The PHY needs this set even for forced link. */
10856                 an_10_100_val |= (1 << 8) | (1 << 7);
10857                 ELINK_DEBUG_P0(sc, "Setting 100M force");
10858         }
10859         if ((phy->req_line_speed == ELINK_SPEED_10) &&
10860             (phy->supported &
10861              (ELINK_SUPPORTED_10baseT_Half |
10862               ELINK_SUPPORTED_10baseT_Full))) {
10863                 /* Enabled AUTO-MDIX when autoneg is disabled */
10864                 elink_cl45_write(sc, phy,
10865                                  MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
10866                                  (1 << 15 | 1 << 9 | 7 << 0));
10867                 ELINK_DEBUG_P0(sc, "Setting 10M force");
10868         }
10869
10870         elink_cl45_write(sc, phy,
10871                          MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
10872                          an_10_100_val);
10873
10874         if (phy->req_duplex == DUPLEX_FULL)
10875                 autoneg_val |= (1 << 8);
10876
10877         /* Always write this if this is not 84833/4.
10878          * For 84833/4, write it only when it's a forced speed.
10879          */
10880         if (!elink_is_8483x_8485x(phy) ||
10881             ((autoneg_val & (1 << 12)) == 0))
10882                 elink_cl45_write(sc, phy,
10883                          MDIO_AN_DEVAD,
10884                          MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
10885
10886         if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10887              (phy->speed_cap_mask &
10888               PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
10889             (phy->req_line_speed == ELINK_SPEED_10000)) {
10890                 ELINK_DEBUG_P0(sc, "Advertising 10G");
10891                 /* Restart autoneg for 10G*/
10892
10893                 elink_cl45_read_or_write(
10894                         sc, phy,
10895                         MDIO_AN_DEVAD,
10896                         MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
10897                         0x1000);
10898                 elink_cl45_write(sc, phy,
10899                                  MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
10900                                  0x3200);
10901         } else
10902                 elink_cl45_write(sc, phy,
10903                                  MDIO_AN_DEVAD,
10904                                  MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
10905                                  1);
10906
10907         return ELINK_STATUS_OK;
10908 }
10909
10910 static uint8_t elink_8481_config_init(struct elink_phy *phy,
10911                                   struct elink_params *params,
10912                                   struct elink_vars *vars)
10913 {
10914         struct bnx2x_softc *sc = params->sc;
10915         /* Restore normal power mode*/
10916         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
10917                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
10918
10919         /* HW reset */
10920         elink_ext_phy_hw_reset(sc, params->port);
10921         elink_wait_reset_complete(sc, phy, params);
10922
10923         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1 << 15);
10924         return elink_848xx_cmn_config_init(phy, params, vars);
10925 }
10926
10927 #define PHY848xx_CMDHDLR_WAIT 300
10928 #define PHY848xx_CMDHDLR_MAX_ARGS 5
10929
10930 static elink_status_t elink_84858_cmd_hdlr(struct elink_phy *phy,
10931                                            struct elink_params *params,
10932                                            uint16_t fw_cmd,
10933                                            uint16_t cmd_args[], int argc)
10934 {
10935         int idx;
10936         uint16_t val;
10937         struct bnx2x_softc *sc = params->sc;
10938
10939         /* Step 1: Poll the STATUS register to see whether the previous command
10940          * is in progress or the system is busy (CMD_IN_PROGRESS or
10941          * SYSTEM_BUSY). If previous command is in progress or system is busy,
10942          * check again until the previous command finishes execution and the
10943          * system is available for taking command
10944          */
10945
10946         for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
10947                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
10948                                 MDIO_848xx_CMD_HDLR_STATUS, &val);
10949                 if ((val != PHY84858_STATUS_CMD_IN_PROGRESS) &&
10950                     (val != PHY84858_STATUS_CMD_SYSTEM_BUSY))
10951                         break;
10952                 DELAY(1000 * 1);
10953         }
10954         if (idx >= PHY848xx_CMDHDLR_WAIT) {
10955                 ELINK_DEBUG_P0(sc, "FW cmd: FW not ready.");
10956                 return ELINK_STATUS_ERROR;
10957         }
10958
10959         /* Step2: If any parameters are required for the function, write them
10960          * to the required DATA registers
10961          */
10962
10963         for (idx = 0; idx < argc; idx++) {
10964                 elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10965                                  MDIO_848xx_CMD_HDLR_DATA1 + idx,
10966                                  cmd_args[idx]);
10967         }
10968
10969         /* Step3: When the firmware is ready for commands, write the 'Command
10970          * code' to the CMD register
10971          */
10972         elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10973                          MDIO_848xx_CMD_HDLR_COMMAND, fw_cmd);
10974
10975         /* Step4: Once the command has been written, poll the STATUS register
10976          * to check whether the command has completed (CMD_COMPLETED_PASS/
10977          * CMD_FOR_CMDS or CMD_COMPLETED_ERROR).
10978          */
10979
10980         for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
10981                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
10982                                 MDIO_848xx_CMD_HDLR_STATUS, &val);
10983                 if ((val == PHY84858_STATUS_CMD_COMPLETE_PASS) ||
10984                     (val == PHY84858_STATUS_CMD_COMPLETE_ERROR))
10985                         break;
10986                 DELAY(1000 * 1);
10987         }
10988         if ((idx >= PHY848xx_CMDHDLR_WAIT) ||
10989             (val == PHY84858_STATUS_CMD_COMPLETE_ERROR)) {
10990                 ELINK_DEBUG_P0(sc, "FW cmd failed.");
10991                 return ELINK_STATUS_ERROR;
10992         }
10993         /* Step5: Once the command has completed, read the specficied DATA
10994          * registers for any saved results for the command, if applicable
10995          */
10996
10997         /* Gather returning data */
10998         for (idx = 0; idx < argc; idx++) {
10999                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11000                                 MDIO_848xx_CMD_HDLR_DATA1 + idx,
11001                                 &cmd_args[idx]);
11002         }
11003
11004         return ELINK_STATUS_OK;
11005 }
11006
11007 static elink_status_t elink_84833_cmd_hdlr(struct elink_phy *phy,
11008                                 struct elink_params *params, uint16_t fw_cmd,
11009                                 uint16_t cmd_args[], int argc, int process)
11010 {
11011         int idx;
11012         uint16_t val;
11013         struct bnx2x_softc *sc = params->sc;
11014         elink_status_t rc = ELINK_STATUS_OK;
11015
11016         if (process == PHY84833_MB_PROCESS2) {
11017         /* Write CMD_OPEN_OVERRIDE to STATUS reg */
11018         elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11019                                  MDIO_848xx_CMD_HDLR_STATUS,
11020                         PHY84833_STATUS_CMD_OPEN_OVERRIDE);
11021         }
11022
11023         for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
11024                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11025                                MDIO_848xx_CMD_HDLR_STATUS, &val);
11026                 if (val == PHY84833_STATUS_CMD_OPEN_FOR_CMDS)
11027                         break;
11028                 DELAY(1000 * 1);
11029         }
11030         if (idx >= PHY848xx_CMDHDLR_WAIT) {
11031                 ELINK_DEBUG_P0(sc, "FW cmd: FW not ready.");
11032                 /* if the status is CMD_COMPLETE_PASS or CMD_COMPLETE_ERROR
11033                  * clear the status to CMD_CLEAR_COMPLETE
11034                  */
11035                 if (val == PHY84833_STATUS_CMD_COMPLETE_PASS ||
11036                     val == PHY84833_STATUS_CMD_COMPLETE_ERROR) {
11037                         elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11038                                          MDIO_848xx_CMD_HDLR_STATUS,
11039                                          PHY84833_STATUS_CMD_CLEAR_COMPLETE);
11040                 }
11041                 return ELINK_STATUS_ERROR;
11042         }
11043         if (process == PHY84833_MB_PROCESS1 ||
11044             process == PHY84833_MB_PROCESS2) {
11045                 /* Prepare argument(s) */
11046         for (idx = 0; idx < argc; idx++) {
11047                 elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11048                                          MDIO_848xx_CMD_HDLR_DATA1 + idx,
11049                                 cmd_args[idx]);
11050         }
11051         }
11052
11053         /* Issue command */
11054         elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11055                         MDIO_848xx_CMD_HDLR_COMMAND, fw_cmd);
11056         for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
11057                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11058                                MDIO_848xx_CMD_HDLR_STATUS, &val);
11059                 if ((val == PHY84833_STATUS_CMD_COMPLETE_PASS) ||
11060                         (val == PHY84833_STATUS_CMD_COMPLETE_ERROR))
11061                         break;
11062                 DELAY(1000 * 1);
11063         }
11064         if ((idx >= PHY848xx_CMDHDLR_WAIT) ||
11065                 (val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) {
11066                 ELINK_DEBUG_P0(sc, "FW cmd failed.");
11067                 rc = ELINK_STATUS_ERROR;
11068         }
11069         if (process == PHY84833_MB_PROCESS3 && rc == ELINK_STATUS_OK) {
11070         /* Gather returning data */
11071         for (idx = 0; idx < argc; idx++) {
11072                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11073                                         MDIO_848xx_CMD_HDLR_DATA1 + idx,
11074                                 &cmd_args[idx]);
11075         }
11076         }
11077         if (val == PHY84833_STATUS_CMD_COMPLETE_ERROR ||
11078             val == PHY84833_STATUS_CMD_COMPLETE_PASS) {
11079         elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11080                                  MDIO_848xx_CMD_HDLR_STATUS,
11081                         PHY84833_STATUS_CMD_CLEAR_COMPLETE);
11082         }
11083         return rc;
11084 }
11085
11086 static elink_status_t elink_848xx_cmd_hdlr(struct elink_phy *phy,
11087                                            struct elink_params *params,
11088                                            uint16_t fw_cmd,
11089                                            uint16_t cmd_args[], int argc,
11090                                            int process)
11091 {
11092         struct bnx2x_softc *sc = params->sc;
11093
11094         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858) ||
11095             (REG_RD(sc, params->shmem2_base +
11096                     offsetof(struct shmem2_region,
11097                              link_attr_sync[params->port])) &
11098                              LINK_ATTR_84858)) {
11099                 return elink_84858_cmd_hdlr(phy, params, fw_cmd, cmd_args,
11100                                             argc);
11101         } else {
11102                 return elink_84833_cmd_hdlr(phy, params, fw_cmd, cmd_args,
11103                                             argc, process);
11104         }
11105 }
11106
11107 static elink_status_t elink_848xx_pair_swap_cfg(struct elink_phy *phy,
11108                                    struct elink_params *params,
11109                                    __rte_unused struct elink_vars *vars)
11110 {
11111         uint32_t pair_swap;
11112         uint16_t data[PHY848xx_CMDHDLR_MAX_ARGS];
11113         elink_status_t status;
11114         struct bnx2x_softc *sc = params->sc;
11115
11116         /* Check for configuration. */
11117         pair_swap = REG_RD(sc, params->shmem_base +
11118                            offsetof(struct shmem_region,
11119                         dev_info.port_hw_config[params->port].xgbt_phy_cfg)) &
11120                 PORT_HW_CFG_RJ45_PAIR_SWAP_MASK;
11121
11122         if (pair_swap == 0)
11123                 return ELINK_STATUS_OK;
11124
11125         /* Only the second argument is used for this command */
11126         data[1] = (uint16_t)pair_swap;
11127
11128         status = elink_848xx_cmd_hdlr(phy, params,
11129                                       PHY848xx_CMD_SET_PAIR_SWAP, data,
11130                                       2, PHY84833_MB_PROCESS2);
11131         if (status == ELINK_STATUS_OK)
11132                 ELINK_DEBUG_P1(sc, "Pairswap OK, val=0x%x", data[1]);
11133
11134         return status;
11135 }
11136
11137 static uint8_t elink_84833_get_reset_gpios(struct bnx2x_softc *sc,
11138                                       uint32_t shmem_base_path[],
11139                                       __rte_unused uint32_t chip_id)
11140 {
11141         uint32_t reset_pin[2];
11142         uint32_t idx;
11143         uint8_t reset_gpios;
11144         if (CHIP_IS_E3(sc)) {
11145                 /* Assume that these will be GPIOs, not EPIOs. */
11146                 for (idx = 0; idx < 2; idx++) {
11147                         /* Map config param to register bit. */
11148                         reset_pin[idx] = REG_RD(sc, shmem_base_path[idx] +
11149                                 offsetof(struct shmem_region,
11150                                 dev_info.port_hw_config[0].e3_cmn_pin_cfg));
11151                         reset_pin[idx] = (reset_pin[idx] &
11152                                 PORT_HW_CFG_E3_PHY_RESET_MASK) >>
11153                                 PORT_HW_CFG_E3_PHY_RESET_SHIFT;
11154                         reset_pin[idx] -= PIN_CFG_GPIO0_P0;
11155                         reset_pin[idx] = (1 << reset_pin[idx]);
11156                 }
11157                 reset_gpios = (uint8_t)(reset_pin[0] | reset_pin[1]);
11158         } else {
11159                 /* E2, look from diff place of shmem. */
11160                 for (idx = 0; idx < 2; idx++) {
11161                         reset_pin[idx] = REG_RD(sc, shmem_base_path[idx] +
11162                                 offsetof(struct shmem_region,
11163                                 dev_info.port_hw_config[0].default_cfg));
11164                         reset_pin[idx] &= PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK;
11165                         reset_pin[idx] -= PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0;
11166                         reset_pin[idx] >>= PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT;
11167                         reset_pin[idx] = (1 << reset_pin[idx]);
11168                 }
11169                 reset_gpios = (uint8_t)(reset_pin[0] | reset_pin[1]);
11170         }
11171
11172         return reset_gpios;
11173 }
11174
11175 static void elink_84833_hw_reset_phy(struct elink_phy *phy,
11176                                 struct elink_params *params)
11177 {
11178         struct bnx2x_softc *sc = params->sc;
11179         uint8_t reset_gpios;
11180         uint32_t other_shmem_base_addr = REG_RD(sc, params->shmem2_base +
11181                                 offsetof(struct shmem2_region,
11182                                 other_shmem_base_addr));
11183
11184         uint32_t shmem_base_path[2];
11185
11186         /* Work around for 84833 LED failure inside RESET status */
11187         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
11188                 MDIO_AN_REG_8481_LEGACY_MII_CTRL,
11189                 MDIO_AN_REG_8481_MII_CTRL_FORCE_1G);
11190         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
11191                 MDIO_AN_REG_8481_1G_100T_EXT_CTRL,
11192                 MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF);
11193
11194         shmem_base_path[0] = params->shmem_base;
11195         shmem_base_path[1] = other_shmem_base_addr;
11196
11197         reset_gpios = elink_84833_get_reset_gpios(sc, shmem_base_path,
11198                                                   params->chip_id);
11199
11200         elink_cb_gpio_mult_write(sc, reset_gpios,
11201                                  MISC_REGISTERS_GPIO_OUTPUT_LOW);
11202         DELAY(10);
11203         ELINK_DEBUG_P1(sc, "84833 hw reset on pin values 0x%x",
11204                 reset_gpios);
11205 }
11206
11207 static elink_status_t elink_8483x_disable_eee(struct elink_phy *phy,
11208                                    struct elink_params *params,
11209                                    struct elink_vars *vars)
11210 {
11211         elink_status_t rc;
11212         struct bnx2x_softc *sc = params->sc;
11213         uint16_t cmd_args = 0;
11214
11215         ELINK_DEBUG_P0(sc, "Don't Advertise 10GBase-T EEE");
11216
11217         /* Prevent Phy from working in EEE and advertising it */
11218         rc = elink_848xx_cmd_hdlr(phy, params, PHY848xx_CMD_SET_EEE_MODE,
11219                                   &cmd_args, 1, PHY84833_MB_PROCESS1);
11220         if (rc != ELINK_STATUS_OK) {
11221                 ELINK_DEBUG_P0(sc, "EEE disable failed.");
11222                 return rc;
11223         }
11224
11225         return elink_eee_disable(phy, params, vars);
11226 }
11227
11228 static elink_status_t elink_8483x_enable_eee(struct elink_phy *phy,
11229                                    struct elink_params *params,
11230                                    struct elink_vars *vars)
11231 {
11232         elink_status_t rc;
11233         struct bnx2x_softc *sc = params->sc;
11234         uint16_t cmd_args = 1;
11235
11236         rc = elink_848xx_cmd_hdlr(phy, params, PHY848xx_CMD_SET_EEE_MODE,
11237                                   &cmd_args, 1, PHY84833_MB_PROCESS1);
11238         if (rc != ELINK_STATUS_OK) {
11239                 ELINK_DEBUG_P0(sc, "EEE enable failed.");
11240                 return rc;
11241         }
11242
11243         return elink_eee_advertise(phy, params, vars, SHMEM_EEE_10G_ADV);
11244 }
11245
11246 #define PHY84833_CONSTANT_LATENCY 1193
11247 static uint8_t elink_848x3_config_init(struct elink_phy *phy,
11248                                    struct elink_params *params,
11249                                    struct elink_vars *vars)
11250 {
11251         struct bnx2x_softc *sc = params->sc;
11252         uint8_t port, initialize = 1;
11253         uint16_t val;
11254         uint32_t actual_phy_selection;
11255         uint16_t cmd_args[PHY848xx_CMDHDLR_MAX_ARGS];
11256         elink_status_t rc = ELINK_STATUS_OK;
11257
11258         DELAY(1000 * 1);
11259
11260         if (!(CHIP_IS_E1x(sc)))
11261                 port = SC_PATH(sc);
11262         else
11263                 port = params->port;
11264
11265         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84823) {
11266                 elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_3,
11267                                MISC_REGISTERS_GPIO_OUTPUT_HIGH,
11268                                port);
11269         } else {
11270                 /* MDIO reset */
11271                 elink_cl45_write(sc, phy,
11272                                 MDIO_PMA_DEVAD,
11273                                 MDIO_PMA_REG_CTRL, 0x8000);
11274         }
11275
11276         elink_wait_reset_complete(sc, phy, params);
11277
11278         /* Wait for GPHY to come out of reset */
11279         DELAY(1000 * 50);
11280         if (!elink_is_8483x_8485x(phy)) {
11281                 /* BNX2X84823 requires that XGXS links up first @ 10G for normal
11282                  * behavior.
11283                  */
11284                 uint16_t temp;
11285                 temp = vars->line_speed;
11286                 vars->line_speed = ELINK_SPEED_10000;
11287                 elink_set_autoneg(&params->phy[ELINK_INT_PHY], params, vars, 0);
11288                 elink_program_serdes(&params->phy[ELINK_INT_PHY], params, vars);
11289                 vars->line_speed = temp;
11290         }
11291         /* Check if this is actually BNX2X84858 */
11292         if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858) {
11293                 uint16_t hw_rev;
11294
11295                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11296                                 MDIO_AN_REG_848xx_ID_MSB, &hw_rev);
11297                 if (hw_rev == BNX2X84858_PHY_ID) {
11298                         params->link_attr_sync |= LINK_ATTR_84858;
11299                         elink_update_link_attr(params, params->link_attr_sync);
11300                 }
11301         }
11302
11303         /* Set dual-media configuration according to configuration */
11304         elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11305                         MDIO_CTL_REG_84823_MEDIA, &val);
11306         val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
11307                  MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
11308                  MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
11309                  MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
11310                  MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
11311
11312         if (CHIP_IS_E3(sc)) {
11313                 val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
11314                          MDIO_CTL_REG_84823_MEDIA_LINE_MASK);
11315         } else {
11316                 val |= (MDIO_CTL_REG_84823_CTRL_MAC_XFI |
11317                         MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L);
11318         }
11319
11320         actual_phy_selection = elink_phy_selection(params);
11321
11322         switch (actual_phy_selection) {
11323         case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
11324                 /* Do nothing. Essentially this is like the priority copper */
11325                 break;
11326         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
11327                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
11328                 break;
11329         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
11330                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
11331                 break;
11332         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
11333                 /* Do nothing here. The first PHY won't be initialized at all */
11334                 break;
11335         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
11336                 val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
11337                 initialize = 0;
11338                 break;
11339         }
11340         if (params->phy[ELINK_EXT_PHY2].req_line_speed == ELINK_SPEED_1000)
11341                 val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
11342
11343         elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11344                          MDIO_CTL_REG_84823_MEDIA, val);
11345         ELINK_DEBUG_P2(sc, "Multi_phy config = 0x%x, Media control = 0x%x",
11346                    params->multi_phy_config, val);
11347
11348         if (elink_is_8483x_8485x(phy)) {
11349                 elink_848xx_pair_swap_cfg(phy, params, vars);
11350
11351                 /* Keep AutogrEEEn disabled. */
11352                 cmd_args[0] = 0x0;
11353                 cmd_args[1] = 0x0;
11354                 cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1;
11355                 cmd_args[3] = PHY84833_CONSTANT_LATENCY;
11356                 rc = elink_848xx_cmd_hdlr(phy, params,
11357                                           PHY848xx_CMD_SET_EEE_MODE, cmd_args,
11358                                           4, PHY84833_MB_PROCESS1);
11359                 if (rc != ELINK_STATUS_OK)
11360                         ELINK_DEBUG_P0(sc, "Cfg AutogrEEEn failed.");
11361         }
11362         if (initialize)
11363                 rc = elink_848xx_cmn_config_init(phy, params, vars);
11364         else
11365                 elink_save_848xx_spirom_version(phy, sc, params->port);
11366         /* 84833 PHY has a better feature and doesn't need to support this. */
11367         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84823) {
11368                 uint32_t cms_enable = REG_RD(sc, params->shmem_base +
11369                         offsetof(struct shmem_region,
11370                         dev_info.port_hw_config[params->port].default_cfg)) &
11371                         PORT_HW_CFG_ENABLE_CMS_MASK;
11372
11373                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11374                                 MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
11375                 if (cms_enable)
11376                         val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
11377                 else
11378                         val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
11379                 elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11380                                  MDIO_CTL_REG_84823_USER_CTRL_REG, val);
11381         }
11382
11383         elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11384                         MDIO_84833_TOP_CFG_FW_REV, &val);
11385
11386         /* Configure EEE support */
11387         if ((val >= MDIO_84833_TOP_CFG_FW_EEE) &&
11388             (val != MDIO_84833_TOP_CFG_FW_NO_EEE) &&
11389             elink_eee_has_cap(params)) {
11390                 rc = elink_eee_initial_config(params, vars, SHMEM_EEE_10G_ADV);
11391                 if (rc != ELINK_STATUS_OK) {
11392                         ELINK_DEBUG_P0(sc, "Failed to configure EEE timers");
11393                         elink_8483x_disable_eee(phy, params, vars);
11394                         return rc;
11395                 }
11396
11397                 if ((phy->req_duplex == DUPLEX_FULL) &&
11398                     (params->eee_mode & ELINK_EEE_MODE_ADV_LPI) &&
11399                     (elink_eee_calc_timer(params) ||
11400                      !(params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI)))
11401                         rc = elink_8483x_enable_eee(phy, params, vars);
11402                 else
11403                         rc = elink_8483x_disable_eee(phy, params, vars);
11404                 if (rc != ELINK_STATUS_OK) {
11405                         ELINK_DEBUG_P0(sc, "Failed to set EEE advertisement");
11406                         return rc;
11407                 }
11408         } else {
11409                 vars->eee_status &= ~SHMEM_EEE_SUPPORTED_MASK;
11410         }
11411
11412         if (elink_is_8483x_8485x(phy)) {
11413                 /* Bring PHY out of super isolate mode as the final step. */
11414                 elink_cl45_read_and_write(sc, phy,
11415                                           MDIO_CTL_DEVAD,
11416                                           MDIO_84833_TOP_CFG_XGPHY_STRAP1,
11417                                           (uint16_t)~MDIO_84833_SUPER_ISOLATE);
11418         }
11419         return rc;
11420 }
11421
11422 static uint8_t elink_848xx_read_status(struct elink_phy *phy,
11423                                   struct elink_params *params,
11424                                   struct elink_vars *vars)
11425 {
11426         struct bnx2x_softc *sc = params->sc;
11427         uint16_t val, val1, val2;
11428         uint8_t link_up = 0;
11429
11430
11431         /* Check 10G-BaseT link status */
11432         /* Check PMD signal ok */
11433         elink_cl45_read(sc, phy,
11434                         MDIO_AN_DEVAD, 0xFFFA, &val1);
11435         elink_cl45_read(sc, phy,
11436                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
11437                         &val2);
11438         ELINK_DEBUG_P1(sc, "BNX2X848xx: PMD_SIGNAL 1.a811 = 0x%x", val2);
11439
11440         /* Check link 10G */
11441         if (val2 & (1 << 11)) {
11442                 vars->line_speed = ELINK_SPEED_10000;
11443                 vars->duplex = DUPLEX_FULL;
11444                 link_up = 1;
11445                 elink_ext_phy_10G_an_resolve(sc, phy, vars);
11446         } else { /* Check Legacy speed link */
11447                 uint16_t legacy_status, legacy_speed;
11448
11449                 /* Enable expansion register 0x42 (Operation mode status) */
11450                 elink_cl45_write(sc, phy,
11451                                  MDIO_AN_DEVAD,
11452                                  MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
11453
11454                 /* Get legacy speed operation status */
11455                 elink_cl45_read(sc, phy,
11456                                 MDIO_AN_DEVAD,
11457                                 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
11458                                 &legacy_status);
11459
11460                 ELINK_DEBUG_P1(sc, "Legacy speed status = 0x%x",
11461                    legacy_status);
11462                 link_up = ((legacy_status & (1 << 11)) == (1 << 11));
11463                 legacy_speed = (legacy_status & (3 << 9));
11464                 if (legacy_speed == (0 << 9))
11465                         vars->line_speed = ELINK_SPEED_10;
11466                 else if (legacy_speed == (1 << 9))
11467                         vars->line_speed = ELINK_SPEED_100;
11468                 else if (legacy_speed == (2 << 9))
11469                         vars->line_speed = ELINK_SPEED_1000;
11470                 else { /* Should not happen: Treat as link down */
11471                         vars->line_speed = 0;
11472                         link_up = 0;
11473                 }
11474
11475                 if (params->feature_config_flags &
11476                         ELINK_FEATURE_CONFIG_IEEE_PHY_TEST) {
11477                         uint16_t mii_ctrl;
11478
11479                         elink_cl45_read(sc, phy,
11480                                         MDIO_AN_DEVAD,
11481                                         MDIO_AN_REG_8481_LEGACY_MII_CTRL,
11482                                         &mii_ctrl);
11483                         /* For IEEE testing, check for a fake link. */
11484                         link_up |= ((mii_ctrl & 0x3040) == 0x40);
11485                 }
11486
11487                 if (link_up) {
11488                         if (legacy_status & (1 << 8))
11489                                 vars->duplex = DUPLEX_FULL;
11490                         else
11491                                 vars->duplex = DUPLEX_HALF;
11492
11493                         ELINK_DEBUG_P2(sc,
11494                            "Link is up in %dMbps, is_duplex_full= %d",
11495                            vars->line_speed,
11496                            (vars->duplex == DUPLEX_FULL));
11497                         /* Check legacy speed AN resolution */
11498                         elink_cl45_read(sc, phy,
11499                                         MDIO_AN_DEVAD,
11500                                         MDIO_AN_REG_8481_LEGACY_MII_STATUS,
11501                                         &val);
11502                         if (val & (1 << 5))
11503                                 vars->link_status |=
11504                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
11505                         elink_cl45_read(sc, phy,
11506                                         MDIO_AN_DEVAD,
11507                                         MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
11508                                         &val);
11509                         if ((val & (1 << 0)) == 0)
11510                                 vars->link_status |=
11511                                         LINK_STATUS_PARALLEL_DETECTION_USED;
11512                 }
11513         }
11514         if (link_up) {
11515                 ELINK_DEBUG_P1(sc, "BNX2X848x3: link speed is %d",
11516                            vars->line_speed);
11517                 elink_ext_phy_resolve_fc(phy, params, vars);
11518
11519                 /* Read LP advertised speeds */
11520                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11521                                 MDIO_AN_REG_CL37_FC_LP, &val);
11522                 if (val & (1 << 5))
11523                         vars->link_status |=
11524                                 LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
11525                 if (val & (1 << 6))
11526                         vars->link_status |=
11527                                 LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
11528                 if (val & (1 << 7))
11529                         vars->link_status |=
11530                                 LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
11531                 if (val & (1 << 8))
11532                         vars->link_status |=
11533                                 LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
11534                 if (val & (1 << 9))
11535                         vars->link_status |=
11536                                 LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
11537
11538                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11539                                 MDIO_AN_REG_1000T_STATUS, &val);
11540
11541                 if (val & (1 << 10))
11542                         vars->link_status |=
11543                                 LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
11544                 if (val & (1 << 11))
11545                         vars->link_status |=
11546                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
11547
11548                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11549                                 MDIO_AN_REG_MASTER_STATUS, &val);
11550
11551                 if (val & (1 << 11))
11552                         vars->link_status |=
11553                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
11554
11555                 /* Determine if EEE was negotiated */
11556                 if (elink_is_8483x_8485x(phy))
11557                         elink_eee_an_resolve(phy, params, vars);
11558         }
11559
11560         return link_up;
11561 }
11562
11563 static elink_status_t elink_848xx_format_ver(uint32_t raw_ver, uint8_t *str,
11564                                              uint16_t *len)
11565 {
11566         elink_status_t status = ELINK_STATUS_OK;
11567         uint32_t spirom_ver;
11568         spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
11569         status = elink_format_ver(spirom_ver, str, len);
11570         return status;
11571 }
11572
11573 static void elink_8481_hw_reset(__rte_unused struct elink_phy *phy,
11574                                 struct elink_params *params)
11575 {
11576         elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_1,
11577                        MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
11578         elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_1,
11579                        MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
11580 }
11581
11582 static void elink_8481_link_reset(struct elink_phy *phy,
11583                                         struct elink_params *params)
11584 {
11585         elink_cl45_write(params->sc, phy,
11586                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
11587         elink_cl45_write(params->sc, phy,
11588                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
11589 }
11590
11591 static void elink_848x3_link_reset(struct elink_phy *phy,
11592                                    struct elink_params *params)
11593 {
11594         struct bnx2x_softc *sc = params->sc;
11595         uint8_t port;
11596         uint16_t val16;
11597
11598         if (!(CHIP_IS_E1x(sc)))
11599                 port = SC_PATH(sc);
11600         else
11601                 port = params->port;
11602
11603         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84823) {
11604                 elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_3,
11605                                MISC_REGISTERS_GPIO_OUTPUT_LOW,
11606                                port);
11607         } else {
11608                 elink_cl45_read(sc, phy,
11609                                 MDIO_CTL_DEVAD,
11610                                 MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val16);
11611                 val16 |= MDIO_84833_SUPER_ISOLATE;
11612                 elink_cl45_write(sc, phy,
11613                                  MDIO_CTL_DEVAD,
11614                                  MDIO_84833_TOP_CFG_XGPHY_STRAP1, val16);
11615         }
11616 }
11617
11618 static void elink_848xx_set_link_led(struct elink_phy *phy,
11619                                      struct elink_params *params, uint8_t mode)
11620 {
11621         struct bnx2x_softc *sc = params->sc;
11622         uint16_t val;
11623         uint8_t port;
11624
11625         if (!(CHIP_IS_E1x(sc)))
11626                 port = SC_PATH(sc);
11627         else
11628                 port = params->port;
11629         switch (mode) {
11630         case ELINK_LED_MODE_OFF:
11631
11632                 ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE OFF", port);
11633
11634                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11635                     SHARED_HW_CFG_LED_EXTPHY1) {
11636
11637                         /* Set LED masks */
11638                         elink_cl45_write(sc, phy,
11639                                         MDIO_PMA_DEVAD,
11640                                         MDIO_PMA_REG_8481_LED1_MASK,
11641                                         0x0);
11642
11643                         elink_cl45_write(sc, phy,
11644                                         MDIO_PMA_DEVAD,
11645                                         MDIO_PMA_REG_8481_LED2_MASK,
11646                                         0x0);
11647
11648                         elink_cl45_write(sc, phy,
11649                                         MDIO_PMA_DEVAD,
11650                                         MDIO_PMA_REG_8481_LED3_MASK,
11651                                         0x0);
11652
11653                         elink_cl45_write(sc, phy,
11654                                         MDIO_PMA_DEVAD,
11655                                         MDIO_PMA_REG_8481_LED5_MASK,
11656                                         0x0);
11657
11658                 } else {
11659                         elink_cl45_write(sc, phy,
11660                                          MDIO_PMA_DEVAD,
11661                                          MDIO_PMA_REG_8481_LED1_MASK,
11662                                          0x0);
11663                 }
11664                 break;
11665         case ELINK_LED_MODE_FRONT_PANEL_OFF:
11666
11667                 ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE FRONT PANEL OFF",
11668                    port);
11669
11670                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11671                     SHARED_HW_CFG_LED_EXTPHY1) {
11672
11673                         /* Set LED masks */
11674                         elink_cl45_write(sc, phy,
11675                                          MDIO_PMA_DEVAD,
11676                                          MDIO_PMA_REG_8481_LED1_MASK,
11677                                          0x0);
11678
11679                         elink_cl45_write(sc, phy,
11680                                          MDIO_PMA_DEVAD,
11681                                          MDIO_PMA_REG_8481_LED2_MASK,
11682                                          0x0);
11683
11684                         elink_cl45_write(sc, phy,
11685                                          MDIO_PMA_DEVAD,
11686                                          MDIO_PMA_REG_8481_LED3_MASK,
11687                                          0x0);
11688
11689                         elink_cl45_write(sc, phy,
11690                                          MDIO_PMA_DEVAD,
11691                                          MDIO_PMA_REG_8481_LED5_MASK,
11692                                          0x20);
11693
11694                 } else {
11695                         elink_cl45_write(sc, phy,
11696                                          MDIO_PMA_DEVAD,
11697                                          MDIO_PMA_REG_8481_LED1_MASK,
11698                                          0x0);
11699                         if (phy->type ==
11700                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834) {
11701                                 /* Disable MI_INT interrupt before setting LED4
11702                                  * source to constant off.
11703                                  */
11704                                 if (REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
11705                                            params->port * 4) &
11706                                     ELINK_NIG_MASK_MI_INT) {
11707                                         params->link_flags |=
11708                                         ELINK_LINK_FLAGS_INT_DISABLED;
11709
11710                                         elink_bits_dis(
11711                                                 sc,
11712                                                 NIG_REG_MASK_INTERRUPT_PORT0 +
11713                                                 params->port * 4,
11714                                                 ELINK_NIG_MASK_MI_INT);
11715                                 }
11716                                 elink_cl45_write(sc, phy,
11717                                                  MDIO_PMA_DEVAD,
11718                                                  MDIO_PMA_REG_8481_SIGNAL_MASK,
11719                                                  0x0);
11720                         }
11721                 }
11722                 break;
11723         case ELINK_LED_MODE_ON:
11724
11725                 ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE ON", port);
11726
11727                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11728                     SHARED_HW_CFG_LED_EXTPHY1) {
11729                         /* Set control reg */
11730                         elink_cl45_read(sc, phy,
11731                                         MDIO_PMA_DEVAD,
11732                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
11733                                         &val);
11734                         val &= 0x8000;
11735                         val |= 0x2492;
11736
11737                         elink_cl45_write(sc, phy,
11738                                          MDIO_PMA_DEVAD,
11739                                          MDIO_PMA_REG_8481_LINK_SIGNAL,
11740                                          val);
11741
11742                         /* Set LED masks */
11743                         elink_cl45_write(sc, phy,
11744                                          MDIO_PMA_DEVAD,
11745                                          MDIO_PMA_REG_8481_LED1_MASK,
11746                                          0x0);
11747
11748                         elink_cl45_write(sc, phy,
11749                                          MDIO_PMA_DEVAD,
11750                                          MDIO_PMA_REG_8481_LED2_MASK,
11751                                          0x20);
11752
11753                         elink_cl45_write(sc, phy,
11754                                          MDIO_PMA_DEVAD,
11755                                          MDIO_PMA_REG_8481_LED3_MASK,
11756                                          0x20);
11757
11758                         elink_cl45_write(sc, phy,
11759                                          MDIO_PMA_DEVAD,
11760                                          MDIO_PMA_REG_8481_LED5_MASK,
11761                                          0x0);
11762                 } else {
11763                         elink_cl45_write(sc, phy,
11764                                          MDIO_PMA_DEVAD,
11765                                          MDIO_PMA_REG_8481_LED1_MASK,
11766                                          0x20);
11767                         if (phy->type ==
11768                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834) {
11769                                 /* Disable MI_INT interrupt before setting LED4
11770                                  * source to constant on.
11771                                  */
11772                                 if (REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
11773                                            params->port * 4) &
11774                                     ELINK_NIG_MASK_MI_INT) {
11775                                         params->link_flags |=
11776                                         ELINK_LINK_FLAGS_INT_DISABLED;
11777
11778                                         elink_bits_dis(
11779                                                 sc,
11780                                                 NIG_REG_MASK_INTERRUPT_PORT0 +
11781                                                 params->port * 4,
11782                                                 ELINK_NIG_MASK_MI_INT);
11783                                 }
11784                                 elink_cl45_write(sc, phy,
11785                                                  MDIO_PMA_DEVAD,
11786                                                  MDIO_PMA_REG_8481_SIGNAL_MASK,
11787                                                  0x20);
11788                         }
11789                 }
11790                 break;
11791
11792         case ELINK_LED_MODE_OPER:
11793
11794                 ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE OPER", port);
11795
11796                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11797                     SHARED_HW_CFG_LED_EXTPHY1) {
11798
11799                         /* Set control reg */
11800                         elink_cl45_read(sc, phy,
11801                                         MDIO_PMA_DEVAD,
11802                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
11803                                         &val);
11804
11805                         if (!((val &
11806                                MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
11807                           >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) {
11808                                 ELINK_DEBUG_P0(sc, "Setting LINK_SIGNAL");
11809                                 elink_cl45_write(sc, phy,
11810                                                  MDIO_PMA_DEVAD,
11811                                                  MDIO_PMA_REG_8481_LINK_SIGNAL,
11812                                                  0xa492);
11813                         }
11814
11815                         /* Set LED masks */
11816                         elink_cl45_write(sc, phy,
11817                                          MDIO_PMA_DEVAD,
11818                                          MDIO_PMA_REG_8481_LED1_MASK,
11819                                          0x10);
11820
11821                         elink_cl45_write(sc, phy,
11822                                          MDIO_PMA_DEVAD,
11823                                          MDIO_PMA_REG_8481_LED2_MASK,
11824                                          0x80);
11825
11826                         elink_cl45_write(sc, phy,
11827                                          MDIO_PMA_DEVAD,
11828                                          MDIO_PMA_REG_8481_LED3_MASK,
11829                                          0x98);
11830
11831                         elink_cl45_write(sc, phy,
11832                                          MDIO_PMA_DEVAD,
11833                                          MDIO_PMA_REG_8481_LED5_MASK,
11834                                          0x40);
11835
11836                 } else {
11837                         /* EXTPHY2 LED mode indicate that the 100M/1G/10G LED
11838                          * sources are all wired through LED1, rather than only
11839                          * 10G in other modes.
11840                          */
11841                         val = ((params->hw_led_mode <<
11842                                 SHARED_HW_CFG_LED_MODE_SHIFT) ==
11843                                SHARED_HW_CFG_LED_EXTPHY2) ? 0x98 : 0x80;
11844
11845                         elink_cl45_write(sc, phy,
11846                                          MDIO_PMA_DEVAD,
11847                                          MDIO_PMA_REG_8481_LED1_MASK,
11848                                          val);
11849
11850                         /* Tell LED3 to blink on source */
11851                         elink_cl45_read(sc, phy,
11852                                         MDIO_PMA_DEVAD,
11853                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
11854                                         &val);
11855                         val &= ~(7 << 6);
11856                         val |= (1 << 6); /* A83B[8:6]= 1 */
11857                         elink_cl45_write(sc, phy,
11858                                          MDIO_PMA_DEVAD,
11859                                          MDIO_PMA_REG_8481_LINK_SIGNAL,
11860                                          val);
11861                         if (phy->type ==
11862                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834) {
11863                                 /* Restore LED4 source to external link,
11864                                  * and re-enable interrupts.
11865                                  */
11866                                 elink_cl45_write(sc, phy,
11867                                                  MDIO_PMA_DEVAD,
11868                                                  MDIO_PMA_REG_8481_SIGNAL_MASK,
11869                                                  0x40);
11870                                 if (params->link_flags &
11871                                     ELINK_LINK_FLAGS_INT_DISABLED) {
11872                                         elink_link_int_enable(params);
11873                                         params->link_flags &=
11874                                                 ~ELINK_LINK_FLAGS_INT_DISABLED;
11875                                 }
11876                         }
11877                 }
11878                 break;
11879         }
11880
11881         /* This is a workaround for E3 + 84833 until autoneg
11882          * restart is fixed in f/w
11883          */
11884         if (CHIP_IS_E3(sc)) {
11885                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
11886                                 MDIO_WC_REG_GP2_STATUS_GP_2_1, &val);
11887         }
11888 }
11889
11890 /******************************************************************/
11891 /*                      54618SE PHY SECTION                       */
11892 /******************************************************************/
11893 static void elink_54618se_specific_func(struct elink_phy *phy,
11894                                         struct elink_params *params,
11895                                         uint32_t action)
11896 {
11897         struct bnx2x_softc *sc = params->sc;
11898         uint16_t temp;
11899         switch (action) {
11900         case ELINK_PHY_INIT:
11901                 /* Configure LED4: set to INTR (0x6). */
11902                 /* Accessing shadow register 0xe. */
11903                 elink_cl22_write(sc, phy,
11904                                  MDIO_REG_GPHY_SHADOW,
11905                                  MDIO_REG_GPHY_SHADOW_LED_SEL2);
11906                 elink_cl22_read(sc, phy,
11907                                 MDIO_REG_GPHY_SHADOW,
11908                                 &temp);
11909                 temp &= ~(0xf << 4);
11910                 temp |= (0x6 << 4);
11911                 elink_cl22_write(sc, phy,
11912                                  MDIO_REG_GPHY_SHADOW,
11913                                  MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
11914                 /* Configure INTR based on link status change. */
11915                 elink_cl22_write(sc, phy,
11916                                  MDIO_REG_INTR_MASK,
11917                                  ~MDIO_REG_INTR_MASK_LINK_STATUS);
11918                 break;
11919         }
11920 }
11921
11922 static uint8_t elink_54618se_config_init(struct elink_phy *phy,
11923                                                struct elink_params *params,
11924                                                struct elink_vars *vars)
11925 {
11926         struct bnx2x_softc *sc = params->sc;
11927         uint8_t port;
11928         uint16_t autoneg_val, an_1000_val, an_10_100_val, fc_val, temp;
11929         uint32_t cfg_pin;
11930
11931         ELINK_DEBUG_P0(sc, "54618SE cfg init");
11932         DELAY(1000 * 1);
11933
11934         /* This works with E3 only, no need to check the chip
11935          * before determining the port.
11936          */
11937         port = params->port;
11938
11939         cfg_pin = (REG_RD(sc, params->shmem_base +
11940                         offsetof(struct shmem_region,
11941                         dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
11942                         PORT_HW_CFG_E3_PHY_RESET_MASK) >>
11943                         PORT_HW_CFG_E3_PHY_RESET_SHIFT;
11944
11945         /* Drive pin high to bring the GPHY out of reset. */
11946         elink_set_cfg_pin(sc, cfg_pin, 1);
11947
11948         /* wait for GPHY to reset */
11949         DELAY(1000 * 50);
11950
11951         /* reset phy */
11952         elink_cl22_write(sc, phy,
11953                          MDIO_PMA_REG_CTRL, 0x8000);
11954         elink_wait_reset_complete(sc, phy, params);
11955
11956         /* Wait for GPHY to reset */
11957         DELAY(1000 * 50);
11958
11959
11960         elink_54618se_specific_func(phy, params, ELINK_PHY_INIT);
11961         /* Flip the signal detect polarity (set 0x1c.0x1e[8]). */
11962         elink_cl22_write(sc, phy,
11963                         MDIO_REG_GPHY_SHADOW,
11964                         MDIO_REG_GPHY_SHADOW_AUTO_DET_MED);
11965         elink_cl22_read(sc, phy,
11966                         MDIO_REG_GPHY_SHADOW,
11967                         &temp);
11968         temp |= MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD;
11969         elink_cl22_write(sc, phy,
11970                         MDIO_REG_GPHY_SHADOW,
11971                         MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
11972
11973         /* Set up fc */
11974         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
11975         elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
11976         fc_val = 0;
11977         if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
11978                         MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC)
11979                 fc_val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
11980
11981         if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
11982                         MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
11983                 fc_val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
11984
11985         /* Read all advertisement */
11986         elink_cl22_read(sc, phy,
11987                         0x09,
11988                         &an_1000_val);
11989
11990         elink_cl22_read(sc, phy,
11991                         0x04,
11992                         &an_10_100_val);
11993
11994         elink_cl22_read(sc, phy,
11995                         MDIO_PMA_REG_CTRL,
11996                         &autoneg_val);
11997
11998         /* Disable forced speed */
11999         autoneg_val &= ~((1 << 6) | (1 << 8) | (1 << 9) | (1 << 12) |
12000                          (1 << 13));
12001         an_10_100_val &= ~((1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) |
12002                            (1 << 10) | (1 << 11));
12003
12004         if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
12005                         (phy->speed_cap_mask &
12006                         PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
12007                         (phy->req_line_speed == ELINK_SPEED_1000)) {
12008                 an_1000_val |= (1 << 8);
12009                 autoneg_val |= (1 << 9 | 1 << 12);
12010                 if (phy->req_duplex == DUPLEX_FULL)
12011                         an_1000_val |= (1 << 9);
12012                 ELINK_DEBUG_P0(sc, "Advertising 1G");
12013         } else
12014                 an_1000_val &= ~((1 << 8) | (1 << 9));
12015
12016         elink_cl22_write(sc, phy,
12017                         0x09,
12018                         an_1000_val);
12019         elink_cl22_read(sc, phy,
12020                         0x09,
12021                         &an_1000_val);
12022
12023         /* Advertise 10/100 link speed */
12024         if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
12025                 if (phy->speed_cap_mask &
12026                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) {
12027                         an_10_100_val |= (1 << 5);
12028                         autoneg_val |= (1 << 9 | 1 << 12);
12029                         ELINK_DEBUG_P0(sc, "Advertising 10M-HD");
12030                 }
12031                 if (phy->speed_cap_mask &
12032                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) {
12033                         an_10_100_val |= (1 << 6);
12034                         autoneg_val |= (1 << 9 | 1 << 12);
12035                         ELINK_DEBUG_P0(sc, "Advertising 10M-FD");
12036                 }
12037                 if (phy->speed_cap_mask &
12038                     PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) {
12039                         an_10_100_val |= (1 << 7);
12040                         autoneg_val |= (1 << 9 | 1 << 12);
12041                         ELINK_DEBUG_P0(sc, "Advertising 100M-HD");
12042                 }
12043                 if (phy->speed_cap_mask &
12044                     PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) {
12045                         an_10_100_val |= (1 << 8);
12046                         autoneg_val |= (1 << 9 | 1 << 12);
12047                         ELINK_DEBUG_P0(sc, "Advertising 100M-FD");
12048                 }
12049         }
12050
12051         /* Only 10/100 are allowed to work in FORCE mode */
12052         if (phy->req_line_speed == ELINK_SPEED_100) {
12053                 autoneg_val |= (1 << 13);
12054                 /* Enabled AUTO-MDIX when autoneg is disabled */
12055                 elink_cl22_write(sc, phy,
12056                                 0x18,
12057                                 (1 << 15 | 1 << 9 | 7 << 0));
12058                 ELINK_DEBUG_P0(sc, "Setting 100M force");
12059         }
12060         if (phy->req_line_speed == ELINK_SPEED_10) {
12061                 /* Enabled AUTO-MDIX when autoneg is disabled */
12062                 elink_cl22_write(sc, phy,
12063                                 0x18,
12064                                 (1 << 15 | 1 << 9 | 7 << 0));
12065                 ELINK_DEBUG_P0(sc, "Setting 10M force");
12066         }
12067
12068         if ((phy->flags & ELINK_FLAGS_EEE) && elink_eee_has_cap(params)) {
12069                 elink_status_t rc;
12070
12071                 elink_cl22_write(sc, phy, MDIO_REG_GPHY_EXP_ACCESS,
12072                                  MDIO_REG_GPHY_EXP_ACCESS_TOP |
12073                                  MDIO_REG_GPHY_EXP_TOP_2K_BUF);
12074                 elink_cl22_read(sc, phy, MDIO_REG_GPHY_EXP_ACCESS_GATE, &temp);
12075                 temp &= 0xfffe;
12076                 elink_cl22_write(sc, phy, MDIO_REG_GPHY_EXP_ACCESS_GATE, temp);
12077
12078                 rc = elink_eee_initial_config(params, vars, SHMEM_EEE_1G_ADV);
12079                 if (rc != ELINK_STATUS_OK) {
12080                         ELINK_DEBUG_P0(sc, "Failed to configure EEE timers");
12081                         elink_eee_disable(phy, params, vars);
12082                 } else if ((params->eee_mode & ELINK_EEE_MODE_ADV_LPI) &&
12083                            (phy->req_duplex == DUPLEX_FULL) &&
12084                            (elink_eee_calc_timer(params) ||
12085                             !(params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI))) {
12086                         /* Need to advertise EEE only when requested,
12087                          * and either no LPI assertion was requested,
12088                          * or it was requested and a valid timer was set.
12089                          * Also notice full duplex is required for EEE.
12090                          */
12091                         elink_eee_advertise(phy, params, vars,
12092                                             SHMEM_EEE_1G_ADV);
12093                 } else {
12094                         ELINK_DEBUG_P0(sc, "Don't Advertise 1GBase-T EEE");
12095                         elink_eee_disable(phy, params, vars);
12096                 }
12097         } else {
12098                 vars->eee_status &= ((uint32_t)(~SHMEM_EEE_1G_ADV) <<
12099                                     SHMEM_EEE_SUPPORTED_SHIFT);
12100
12101                 if (phy->flags & ELINK_FLAGS_EEE) {
12102                         /* Handle legacy auto-grEEEn */
12103                         if (params->feature_config_flags &
12104                             ELINK_FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
12105                                 temp = 6;
12106                                 ELINK_DEBUG_P0(sc, "Enabling Auto-GrEEEn");
12107                         } else {
12108                                 temp = 0;
12109                                 ELINK_DEBUG_P0(sc, "Don't Adv. EEE");
12110                         }
12111                         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
12112                                          MDIO_AN_REG_EEE_ADV, temp);
12113                 }
12114         }
12115
12116         elink_cl22_write(sc, phy,
12117                         0x04,
12118                         an_10_100_val | fc_val);
12119
12120         if (phy->req_duplex == DUPLEX_FULL)
12121                 autoneg_val |= (1 << 8);
12122
12123         elink_cl22_write(sc, phy,
12124                         MDIO_PMA_REG_CTRL, autoneg_val);
12125
12126         return ELINK_STATUS_OK;
12127 }
12128
12129
12130 static void elink_5461x_set_link_led(struct elink_phy *phy,
12131                                      struct elink_params *params, uint8_t mode)
12132 {
12133         struct bnx2x_softc *sc = params->sc;
12134         uint16_t temp;
12135
12136         elink_cl22_write(sc, phy,
12137                 MDIO_REG_GPHY_SHADOW,
12138                 MDIO_REG_GPHY_SHADOW_LED_SEL1);
12139         elink_cl22_read(sc, phy,
12140                 MDIO_REG_GPHY_SHADOW,
12141                 &temp);
12142         temp &= 0xff00;
12143
12144         ELINK_DEBUG_P1(sc, "54618x set link led (mode=%x)", mode);
12145         switch (mode) {
12146         case ELINK_LED_MODE_FRONT_PANEL_OFF:
12147         case ELINK_LED_MODE_OFF:
12148                 temp |= 0x00ee;
12149                 break;
12150         case ELINK_LED_MODE_OPER:
12151                 temp |= 0x0001;
12152                 break;
12153         case ELINK_LED_MODE_ON:
12154                 temp |= 0x00ff;
12155                 break;
12156         default:
12157                 break;
12158         }
12159         elink_cl22_write(sc, phy,
12160                 MDIO_REG_GPHY_SHADOW,
12161                 MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
12162         return;
12163 }
12164
12165
12166 static void elink_54618se_link_reset(struct elink_phy *phy,
12167                                      struct elink_params *params)
12168 {
12169         struct bnx2x_softc *sc = params->sc;
12170         uint32_t cfg_pin;
12171         uint8_t port;
12172
12173         /* In case of no EPIO routed to reset the GPHY, put it
12174          * in low power mode.
12175          */
12176         elink_cl22_write(sc, phy, MDIO_PMA_REG_CTRL, 0x800);
12177         /* This works with E3 only, no need to check the chip
12178          * before determining the port.
12179          */
12180         port = params->port;
12181         cfg_pin = (REG_RD(sc, params->shmem_base +
12182                         offsetof(struct shmem_region,
12183                         dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
12184                         PORT_HW_CFG_E3_PHY_RESET_MASK) >>
12185                         PORT_HW_CFG_E3_PHY_RESET_SHIFT;
12186
12187         /* Drive pin low to put GPHY in reset. */
12188         elink_set_cfg_pin(sc, cfg_pin, 0);
12189 }
12190
12191 static uint8_t elink_54618se_read_status(struct elink_phy *phy,
12192                                     struct elink_params *params,
12193                                     struct elink_vars *vars)
12194 {
12195         struct bnx2x_softc *sc = params->sc;
12196         uint16_t val;
12197         uint8_t link_up = 0;
12198         uint16_t legacy_status, legacy_speed;
12199
12200         /* Get speed operation status */
12201         elink_cl22_read(sc, phy,
12202                         MDIO_REG_GPHY_AUX_STATUS,
12203                         &legacy_status);
12204         ELINK_DEBUG_P1(sc, "54618SE read_status: 0x%x", legacy_status);
12205
12206         /* Read status to clear the PHY interrupt. */
12207         elink_cl22_read(sc, phy,
12208                         MDIO_REG_INTR_STATUS,
12209                         &val);
12210
12211         link_up = ((legacy_status & (1 << 2)) == (1 << 2));
12212
12213         if (link_up) {
12214                 legacy_speed = (legacy_status & (7 << 8));
12215                 if (legacy_speed == (7 << 8)) {
12216                         vars->line_speed = ELINK_SPEED_1000;
12217                         vars->duplex = DUPLEX_FULL;
12218                 } else if (legacy_speed == (6 << 8)) {
12219                         vars->line_speed = ELINK_SPEED_1000;
12220                         vars->duplex = DUPLEX_HALF;
12221                 } else if (legacy_speed == (5 << 8)) {
12222                         vars->line_speed = ELINK_SPEED_100;
12223                         vars->duplex = DUPLEX_FULL;
12224                 }
12225                 /* Omitting 100Base-T4 for now */
12226                 else if (legacy_speed == (3 << 8)) {
12227                         vars->line_speed = ELINK_SPEED_100;
12228                         vars->duplex = DUPLEX_HALF;
12229                 } else if (legacy_speed == (2 << 8)) {
12230                         vars->line_speed = ELINK_SPEED_10;
12231                         vars->duplex = DUPLEX_FULL;
12232                 } else if (legacy_speed == (1 << 8)) {
12233                         vars->line_speed = ELINK_SPEED_10;
12234                         vars->duplex = DUPLEX_HALF;
12235                 } else /* Should not happen */
12236                         vars->line_speed = 0;
12237
12238                 ELINK_DEBUG_P2(sc,
12239                    "Link is up in %dMbps, is_duplex_full= %d",
12240                    vars->line_speed,
12241                    (vars->duplex == DUPLEX_FULL));
12242
12243                 /* Check legacy speed AN resolution */
12244                 elink_cl22_read(sc, phy,
12245                                 0x01,
12246                                 &val);
12247                 if (val & (1 << 5))
12248                         vars->link_status |=
12249                                 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
12250                 elink_cl22_read(sc, phy,
12251                                 0x06,
12252                                 &val);
12253                 if ((val & (1 << 0)) == 0)
12254                         vars->link_status |=
12255                                 LINK_STATUS_PARALLEL_DETECTION_USED;
12256
12257                 ELINK_DEBUG_P1(sc, "BNX2X4618SE: link speed is %d",
12258                            vars->line_speed);
12259
12260                 elink_ext_phy_resolve_fc(phy, params, vars);
12261
12262                 if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
12263                         /* Report LP advertised speeds */
12264                         elink_cl22_read(sc, phy, 0x5, &val);
12265
12266                         if (val & (1 << 5))
12267                                 vars->link_status |=
12268                                   LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
12269                         if (val & (1 << 6))
12270                                 vars->link_status |=
12271                                   LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
12272                         if (val & (1 << 7))
12273                                 vars->link_status |=
12274                                   LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
12275                         if (val & (1 << 8))
12276                                 vars->link_status |=
12277                                   LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
12278                         if (val & (1 << 9))
12279                                 vars->link_status |=
12280                                   LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
12281
12282                         elink_cl22_read(sc, phy, 0xa, &val);
12283                         if (val & (1 << 10))
12284                                 vars->link_status |=
12285                                   LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
12286                         if (val & (1 << 11))
12287                                 vars->link_status |=
12288                                   LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
12289
12290                         if ((phy->flags & ELINK_FLAGS_EEE) &&
12291                             elink_eee_has_cap(params))
12292                                 elink_eee_an_resolve(phy, params, vars);
12293                 }
12294         }
12295         return link_up;
12296 }
12297
12298 static void elink_54618se_config_loopback(struct elink_phy *phy,
12299                                           struct elink_params *params)
12300 {
12301         struct bnx2x_softc *sc = params->sc;
12302         uint16_t val;
12303         uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
12304
12305         ELINK_DEBUG_P0(sc, "2PMA/PMD ext_phy_loopback: 54618se");
12306
12307         /* Enable master/slave manual mmode and set to master */
12308         /* mii write 9 [bits set 11 12] */
12309         elink_cl22_write(sc, phy, 0x09, 3 << 11);
12310
12311         /* forced 1G and disable autoneg */
12312         /* set val [mii read 0] */
12313         /* set val [expr $val & [bits clear 6 12 13]] */
12314         /* set val [expr $val | [bits set 6 8]] */
12315         /* mii write 0 $val */
12316         elink_cl22_read(sc, phy, 0x00, &val);
12317         val &= ~((1 << 6) | (1 << 12) | (1 << 13));
12318         val |= (1 << 6) | (1 << 8);
12319         elink_cl22_write(sc, phy, 0x00, val);
12320
12321         /* Set external loopback and Tx using 6dB coding */
12322         /* mii write 0x18 7 */
12323         /* set val [mii read 0x18] */
12324         /* mii write 0x18 [expr $val | [bits set 10 15]] */
12325         elink_cl22_write(sc, phy, 0x18, 7);
12326         elink_cl22_read(sc, phy, 0x18, &val);
12327         elink_cl22_write(sc, phy, 0x18, val | (1 << 10) | (1 << 15));
12328
12329         /* This register opens the gate for the UMAC despite its name */
12330         REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port * 4, 1);
12331
12332         /* Maximum Frame Length (RW). Defines a 14-Bit maximum frame
12333          * length used by the MAC receive logic to check frames.
12334          */
12335         REG_WR(sc, umac_base + UMAC_REG_MAXFR, 0x2710);
12336 }
12337
12338 /******************************************************************/
12339 /*                      SFX7101 PHY SECTION                       */
12340 /******************************************************************/
12341 static void elink_7101_config_loopback(struct elink_phy *phy,
12342                                        struct elink_params *params)
12343 {
12344         struct bnx2x_softc *sc = params->sc;
12345         /* SFX7101_XGXS_TEST1 */
12346         elink_cl45_write(sc, phy,
12347                          MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
12348 }
12349
12350 static uint8_t elink_7101_config_init(struct elink_phy *phy,
12351                                   struct elink_params *params,
12352                                   struct elink_vars *vars)
12353 {
12354         uint16_t fw_ver1, fw_ver2, val;
12355         struct bnx2x_softc *sc = params->sc;
12356         ELINK_DEBUG_P0(sc, "Setting the SFX7101 LASI indication");
12357
12358         /* Restore normal power mode*/
12359         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
12360                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
12361         /* HW reset */
12362         elink_ext_phy_hw_reset(sc, params->port);
12363         elink_wait_reset_complete(sc, phy, params);
12364
12365         elink_cl45_write(sc, phy,
12366                          MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x1);
12367         ELINK_DEBUG_P0(sc, "Setting the SFX7101 LED to blink on traffic");
12368         elink_cl45_write(sc, phy,
12369                          MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1 << 3));
12370
12371         elink_ext_phy_set_pause(params, phy, vars);
12372         /* Restart autoneg */
12373         elink_cl45_read(sc, phy,
12374                         MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
12375         val |= 0x200;
12376         elink_cl45_write(sc, phy,
12377                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
12378
12379         /* Save spirom version */
12380         elink_cl45_read(sc, phy,
12381                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
12382
12383         elink_cl45_read(sc, phy,
12384                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
12385         elink_save_spirom_version(sc, params->port,
12386                                   (uint32_t)(fw_ver1 << 16 | fw_ver2),
12387                                   phy->ver_addr);
12388         return ELINK_STATUS_OK;
12389 }
12390
12391 static uint8_t elink_7101_read_status(struct elink_phy *phy,
12392                                  struct elink_params *params,
12393                                  struct elink_vars *vars)
12394 {
12395         struct bnx2x_softc *sc = params->sc;
12396         uint8_t link_up;
12397         uint16_t val1, val2;
12398         elink_cl45_read(sc, phy,
12399                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
12400         elink_cl45_read(sc, phy,
12401                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
12402         ELINK_DEBUG_P2(sc, "10G-base-T LASI status 0x%x->0x%x",
12403                    val2, val1);
12404         elink_cl45_read(sc, phy,
12405                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
12406         elink_cl45_read(sc, phy,
12407                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
12408         ELINK_DEBUG_P2(sc, "10G-base-T PMA status 0x%x->0x%x",
12409                    val2, val1);
12410         link_up = ((val1 & 4) == 4);
12411         /* If link is up print the AN outcome of the SFX7101 PHY */
12412         if (link_up) {
12413                 elink_cl45_read(sc, phy,
12414                                 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
12415                                 &val2);
12416                 vars->line_speed = ELINK_SPEED_10000;
12417                 vars->duplex = DUPLEX_FULL;
12418                 ELINK_DEBUG_P2(sc, "SFX7101 AN status 0x%x->Master=%x",
12419                            val2, (val2 & (1 << 14)));
12420                 elink_ext_phy_10G_an_resolve(sc, phy, vars);
12421                 elink_ext_phy_resolve_fc(phy, params, vars);
12422
12423                 /* Read LP advertised speeds */
12424                 if (val2 & (1 << 11))
12425                         vars->link_status |=
12426                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
12427         }
12428         return link_up;
12429 }
12430
12431 static elink_status_t elink_7101_format_ver(uint32_t spirom_ver, uint8_t *str,
12432                                             uint16_t *len)
12433 {
12434         if (*len < 5)
12435                 return ELINK_STATUS_ERROR;
12436         str[0] = (spirom_ver & 0xFF);
12437         str[1] = (spirom_ver & 0xFF00) >> 8;
12438         str[2] = (spirom_ver & 0xFF0000) >> 16;
12439         str[3] = (spirom_ver & 0xFF000000) >> 24;
12440         str[4] = '\0';
12441         *len -= 5;
12442         return ELINK_STATUS_OK;
12443 }
12444
12445 void elink_sfx7101_sp_sw_reset(struct bnx2x_softc *sc, struct elink_phy *phy)
12446 {
12447         uint16_t val, cnt;
12448
12449         elink_cl45_read(sc, phy,
12450                         MDIO_PMA_DEVAD,
12451                         MDIO_PMA_REG_7101_RESET, &val);
12452
12453         for (cnt = 0; cnt < 10; cnt++) {
12454                 DELAY(1000 * 50);
12455                 /* Writes a self-clearing reset */
12456                 elink_cl45_write(sc, phy,
12457                                  MDIO_PMA_DEVAD,
12458                                  MDIO_PMA_REG_7101_RESET,
12459                                  (val | (1 << 15)));
12460                 /* Wait for clear */
12461                 elink_cl45_read(sc, phy,
12462                                 MDIO_PMA_DEVAD,
12463                                 MDIO_PMA_REG_7101_RESET, &val);
12464
12465                 if ((val & (1 << 15)) == 0)
12466                         break;
12467         }
12468 }
12469
12470 static void elink_7101_hw_reset(__rte_unused struct elink_phy *phy,
12471                                 struct elink_params *params) {
12472         /* Low power mode is controlled by GPIO 2 */
12473         elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_2,
12474                        MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
12475         /* The PHY reset is controlled by GPIO 1 */
12476         elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_1,
12477                        MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
12478 }
12479
12480 static void elink_7101_set_link_led(struct elink_phy *phy,
12481                                     struct elink_params *params, uint8_t mode)
12482 {
12483         uint16_t val = 0;
12484         struct bnx2x_softc *sc = params->sc;
12485         switch (mode) {
12486         case ELINK_LED_MODE_FRONT_PANEL_OFF:
12487         case ELINK_LED_MODE_OFF:
12488                 val = 2;
12489                 break;
12490         case ELINK_LED_MODE_ON:
12491                 val = 1;
12492                 break;
12493         case ELINK_LED_MODE_OPER:
12494                 val = 0;
12495                 break;
12496         }
12497         elink_cl45_write(sc, phy,
12498                          MDIO_PMA_DEVAD,
12499                          MDIO_PMA_REG_7107_LINK_LED_CNTL,
12500                          val);
12501 }
12502
12503 /******************************************************************/
12504 /*                      STATIC PHY DECLARATION                    */
12505 /******************************************************************/
12506
12507 static const struct elink_phy phy_null = {
12508         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
12509         .addr           = 0,
12510         .def_md_devad   = 0,
12511         .flags          = ELINK_FLAGS_INIT_XGXS_FIRST,
12512         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12513         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12514         .mdio_ctrl      = 0,
12515         .supported      = 0,
12516         .media_type     = ELINK_ETH_PHY_NOT_PRESENT,
12517         .ver_addr       = 0,
12518         .req_flow_ctrl  = 0,
12519         .req_line_speed = 0,
12520         .speed_cap_mask = 0,
12521         .req_duplex     = 0,
12522         .rsrv           = 0,
12523         .config_init    = (config_init_t)NULL,
12524         .read_status    = (read_status_t)NULL,
12525         .link_reset     = (link_reset_t)NULL,
12526         .config_loopback = (config_loopback_t)NULL,
12527         .format_fw_ver  = (format_fw_ver_t)NULL,
12528         .hw_reset       = (hw_reset_t)NULL,
12529         .set_link_led   = (set_link_led_t)NULL,
12530         .phy_specific_func = (phy_specific_func_t)NULL
12531 };
12532
12533 static const struct elink_phy phy_serdes = {
12534         .type           = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
12535         .addr           = 0xff,
12536         .def_md_devad   = 0,
12537         .flags          = 0,
12538         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12539         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12540         .mdio_ctrl      = 0,
12541         .supported      = (ELINK_SUPPORTED_10baseT_Half |
12542                            ELINK_SUPPORTED_10baseT_Full |
12543                            ELINK_SUPPORTED_100baseT_Half |
12544                            ELINK_SUPPORTED_100baseT_Full |
12545                            ELINK_SUPPORTED_1000baseT_Full |
12546                            ELINK_SUPPORTED_2500baseX_Full |
12547                            ELINK_SUPPORTED_TP |
12548                            ELINK_SUPPORTED_Autoneg |
12549                            ELINK_SUPPORTED_Pause |
12550                            ELINK_SUPPORTED_Asym_Pause),
12551         .media_type     = ELINK_ETH_PHY_BASE_T,
12552         .ver_addr       = 0,
12553         .req_flow_ctrl  = 0,
12554         .req_line_speed = 0,
12555         .speed_cap_mask = 0,
12556         .req_duplex     = 0,
12557         .rsrv           = 0,
12558         .config_init    = (config_init_t)elink_xgxs_config_init,
12559         .read_status    = (read_status_t)elink_link_settings_status,
12560         .link_reset     = (link_reset_t)elink_int_link_reset,
12561         .config_loopback = (config_loopback_t)NULL,
12562         .format_fw_ver  = (format_fw_ver_t)NULL,
12563         .hw_reset       = (hw_reset_t)NULL,
12564         .set_link_led   = (set_link_led_t)NULL,
12565         .phy_specific_func = (phy_specific_func_t)NULL
12566 };
12567
12568 static const struct elink_phy phy_xgxs = {
12569         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
12570         .addr           = 0xff,
12571         .def_md_devad   = 0,
12572         .flags          = 0,
12573         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12574         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12575         .mdio_ctrl      = 0,
12576         .supported      = (ELINK_SUPPORTED_10baseT_Half |
12577                            ELINK_SUPPORTED_10baseT_Full |
12578                            ELINK_SUPPORTED_100baseT_Half |
12579                            ELINK_SUPPORTED_100baseT_Full |
12580                            ELINK_SUPPORTED_1000baseT_Full |
12581                            ELINK_SUPPORTED_2500baseX_Full |
12582                            ELINK_SUPPORTED_10000baseT_Full |
12583                            ELINK_SUPPORTED_FIBRE |
12584                            ELINK_SUPPORTED_Autoneg |
12585                            ELINK_SUPPORTED_Pause |
12586                            ELINK_SUPPORTED_Asym_Pause),
12587         .media_type     = ELINK_ETH_PHY_CX4,
12588         .ver_addr       = 0,
12589         .req_flow_ctrl  = 0,
12590         .req_line_speed = 0,
12591         .speed_cap_mask = 0,
12592         .req_duplex     = 0,
12593         .rsrv           = 0,
12594         .config_init    = (config_init_t)elink_xgxs_config_init,
12595         .read_status    = (read_status_t)elink_link_settings_status,
12596         .link_reset     = (link_reset_t)elink_int_link_reset,
12597         .config_loopback = (config_loopback_t)elink_set_xgxs_loopback,
12598         .format_fw_ver  = (format_fw_ver_t)NULL,
12599         .hw_reset       = (hw_reset_t)NULL,
12600         .set_link_led   = (set_link_led_t)NULL,
12601         .phy_specific_func = (phy_specific_func_t)elink_xgxs_specific_func
12602 };
12603 static const struct elink_phy phy_warpcore = {
12604         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
12605         .addr           = 0xff,
12606         .def_md_devad   = 0,
12607         .flags          = ELINK_FLAGS_TX_ERROR_CHECK,
12608         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12609         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12610         .mdio_ctrl      = 0,
12611         .supported      = (ELINK_SUPPORTED_10baseT_Half |
12612                            ELINK_SUPPORTED_10baseT_Full |
12613                            ELINK_SUPPORTED_100baseT_Half |
12614                            ELINK_SUPPORTED_100baseT_Full |
12615                            ELINK_SUPPORTED_1000baseT_Full |
12616                            ELINK_SUPPORTED_1000baseKX_Full |
12617                            ELINK_SUPPORTED_10000baseT_Full |
12618                            ELINK_SUPPORTED_10000baseKR_Full |
12619                            ELINK_SUPPORTED_20000baseKR2_Full |
12620                            ELINK_SUPPORTED_20000baseMLD2_Full |
12621                            ELINK_SUPPORTED_FIBRE |
12622                            ELINK_SUPPORTED_Autoneg |
12623                            ELINK_SUPPORTED_Pause |
12624                            ELINK_SUPPORTED_Asym_Pause),
12625         .media_type     = ELINK_ETH_PHY_UNSPECIFIED,
12626         .ver_addr       = 0,
12627         .req_flow_ctrl  = 0,
12628         .req_line_speed = 0,
12629         .speed_cap_mask = 0,
12630         /* req_duplex = */0,
12631         /* rsrv = */0,
12632         .config_init    = (config_init_t)elink_warpcore_config_init,
12633         .read_status    = (read_status_t)elink_warpcore_read_status,
12634         .link_reset     = (link_reset_t)elink_warpcore_link_reset,
12635         .config_loopback = (config_loopback_t)elink_set_warpcore_loopback,
12636         .format_fw_ver  = (format_fw_ver_t)NULL,
12637         .hw_reset       = (hw_reset_t)elink_warpcore_hw_reset,
12638         .set_link_led   = (set_link_led_t)NULL,
12639         .phy_specific_func = (phy_specific_func_t)NULL
12640 };
12641
12642
12643 static const struct elink_phy phy_7101 = {
12644         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
12645         .addr           = 0xff,
12646         .def_md_devad   = 0,
12647         .flags          = ELINK_FLAGS_FAN_FAILURE_DET_REQ,
12648         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12649         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12650         .mdio_ctrl      = 0,
12651         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12652                            ELINK_SUPPORTED_TP |
12653                            ELINK_SUPPORTED_Autoneg |
12654                            ELINK_SUPPORTED_Pause |
12655                            ELINK_SUPPORTED_Asym_Pause),
12656         .media_type     = ELINK_ETH_PHY_BASE_T,
12657         .ver_addr       = 0,
12658         .req_flow_ctrl  = 0,
12659         .req_line_speed = 0,
12660         .speed_cap_mask = 0,
12661         .req_duplex     = 0,
12662         .rsrv           = 0,
12663         .config_init    = (config_init_t)elink_7101_config_init,
12664         .read_status    = (read_status_t)elink_7101_read_status,
12665         .link_reset     = (link_reset_t)elink_common_ext_link_reset,
12666         .config_loopback = (config_loopback_t)elink_7101_config_loopback,
12667         .format_fw_ver  = (format_fw_ver_t)elink_7101_format_ver,
12668         .hw_reset       = (hw_reset_t)elink_7101_hw_reset,
12669         .set_link_led   = (set_link_led_t)elink_7101_set_link_led,
12670         .phy_specific_func = (phy_specific_func_t)NULL
12671 };
12672 static const struct elink_phy phy_8073 = {
12673         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8073,
12674         .addr           = 0xff,
12675         .def_md_devad   = 0,
12676         .flags          = 0,
12677         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12678         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12679         .mdio_ctrl      = 0,
12680         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12681                            ELINK_SUPPORTED_2500baseX_Full |
12682                            ELINK_SUPPORTED_1000baseT_Full |
12683                            ELINK_SUPPORTED_FIBRE |
12684                            ELINK_SUPPORTED_Autoneg |
12685                            ELINK_SUPPORTED_Pause |
12686                            ELINK_SUPPORTED_Asym_Pause),
12687         .media_type     = ELINK_ETH_PHY_KR,
12688         .ver_addr       = 0,
12689         .req_flow_ctrl  = 0,
12690         .req_line_speed = 0,
12691         .speed_cap_mask = 0,
12692         .req_duplex     = 0,
12693         .rsrv           = 0,
12694         .config_init    = (config_init_t)elink_8073_config_init,
12695         .read_status    = (read_status_t)elink_8073_read_status,
12696         .link_reset     = (link_reset_t)elink_8073_link_reset,
12697         .config_loopback = (config_loopback_t)NULL,
12698         .format_fw_ver  = (format_fw_ver_t)elink_format_ver,
12699         .hw_reset       = (hw_reset_t)NULL,
12700         .set_link_led   = (set_link_led_t)NULL,
12701         .phy_specific_func = (phy_specific_func_t)elink_8073_specific_func
12702 };
12703 static const struct elink_phy phy_8705 = {
12704         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8705,
12705         .addr           = 0xff,
12706         .def_md_devad   = 0,
12707         .flags          = ELINK_FLAGS_INIT_XGXS_FIRST,
12708         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12709         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12710         .mdio_ctrl      = 0,
12711         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12712                            ELINK_SUPPORTED_FIBRE |
12713                            ELINK_SUPPORTED_Pause |
12714                            ELINK_SUPPORTED_Asym_Pause),
12715         .media_type     = ELINK_ETH_PHY_XFP_FIBER,
12716         .ver_addr       = 0,
12717         .req_flow_ctrl  = 0,
12718         .req_line_speed = 0,
12719         .speed_cap_mask = 0,
12720         .req_duplex     = 0,
12721         .rsrv           = 0,
12722         .config_init    = (config_init_t)elink_8705_config_init,
12723         .read_status    = (read_status_t)elink_8705_read_status,
12724         .link_reset     = (link_reset_t)elink_common_ext_link_reset,
12725         .config_loopback = (config_loopback_t)NULL,
12726         .format_fw_ver  = (format_fw_ver_t)elink_null_format_ver,
12727         .hw_reset       = (hw_reset_t)NULL,
12728         .set_link_led   = (set_link_led_t)NULL,
12729         .phy_specific_func = (phy_specific_func_t)NULL
12730 };
12731 static const struct elink_phy phy_8706 = {
12732         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8706,
12733         .addr           = 0xff,
12734         .def_md_devad   = 0,
12735         .flags          = ELINK_FLAGS_INIT_XGXS_FIRST,
12736         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12737         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12738         .mdio_ctrl      = 0,
12739         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12740                            ELINK_SUPPORTED_1000baseT_Full |
12741                            ELINK_SUPPORTED_FIBRE |
12742                            ELINK_SUPPORTED_Pause |
12743                            ELINK_SUPPORTED_Asym_Pause),
12744         .media_type     = ELINK_ETH_PHY_SFPP_10G_FIBER,
12745         .ver_addr       = 0,
12746         .req_flow_ctrl  = 0,
12747         .req_line_speed = 0,
12748         .speed_cap_mask = 0,
12749         .req_duplex     = 0,
12750         .rsrv           = 0,
12751         .config_init    = (config_init_t)elink_8706_config_init,
12752         .read_status    = (read_status_t)elink_8706_read_status,
12753         .link_reset     = (link_reset_t)elink_common_ext_link_reset,
12754         .config_loopback = (config_loopback_t)NULL,
12755         .format_fw_ver  = (format_fw_ver_t)elink_format_ver,
12756         .hw_reset       = (hw_reset_t)NULL,
12757         .set_link_led   = (set_link_led_t)NULL,
12758         .phy_specific_func = (phy_specific_func_t)NULL
12759 };
12760
12761 static const struct elink_phy phy_8726 = {
12762         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726,
12763         .addr           = 0xff,
12764         .def_md_devad   = 0,
12765         .flags          = (ELINK_FLAGS_INIT_XGXS_FIRST |
12766                            ELINK_FLAGS_TX_ERROR_CHECK),
12767         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12768         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12769         .mdio_ctrl      = 0,
12770         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12771                            ELINK_SUPPORTED_1000baseT_Full |
12772                            ELINK_SUPPORTED_Autoneg |
12773                            ELINK_SUPPORTED_FIBRE |
12774                            ELINK_SUPPORTED_Pause |
12775                            ELINK_SUPPORTED_Asym_Pause),
12776         .media_type     = ELINK_ETH_PHY_NOT_PRESENT,
12777         .ver_addr       = 0,
12778         .req_flow_ctrl  = 0,
12779         .req_line_speed = 0,
12780         .speed_cap_mask = 0,
12781         .req_duplex     = 0,
12782         .rsrv           = 0,
12783         .config_init    = (config_init_t)elink_8726_config_init,
12784         .read_status    = (read_status_t)elink_8726_read_status,
12785         .link_reset     = (link_reset_t)elink_8726_link_reset,
12786         .config_loopback = (config_loopback_t)elink_8726_config_loopback,
12787         .format_fw_ver  = (format_fw_ver_t)elink_format_ver,
12788         .hw_reset       = (hw_reset_t)NULL,
12789         .set_link_led   = (set_link_led_t)NULL,
12790         .phy_specific_func = (phy_specific_func_t)NULL
12791 };
12792
12793 static const struct elink_phy phy_8727 = {
12794         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727,
12795         .addr           = 0xff,
12796         .def_md_devad   = 0,
12797         .flags          = (ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12798                            ELINK_FLAGS_TX_ERROR_CHECK),
12799         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12800         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12801         .mdio_ctrl      = 0,
12802         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12803                            ELINK_SUPPORTED_1000baseT_Full |
12804                            ELINK_SUPPORTED_FIBRE |
12805                            ELINK_SUPPORTED_Pause |
12806                            ELINK_SUPPORTED_Asym_Pause),
12807         .media_type     = ELINK_ETH_PHY_NOT_PRESENT,
12808         .ver_addr       = 0,
12809         .req_flow_ctrl  = 0,
12810         .req_line_speed = 0,
12811         .speed_cap_mask = 0,
12812         .req_duplex     = 0,
12813         .rsrv           = 0,
12814         .config_init    = (config_init_t)elink_8727_config_init,
12815         .read_status    = (read_status_t)elink_8727_read_status,
12816         .link_reset     = (link_reset_t)elink_8727_link_reset,
12817         .config_loopback = (config_loopback_t)NULL,
12818         .format_fw_ver  = (format_fw_ver_t)elink_format_ver,
12819         .hw_reset       = (hw_reset_t)elink_8727_hw_reset,
12820         .set_link_led   = (set_link_led_t)elink_8727_set_link_led,
12821         .phy_specific_func = (phy_specific_func_t)elink_8727_specific_func
12822 };
12823 static const struct elink_phy phy_8481 = {
12824         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8481,
12825         .addr           = 0xff,
12826         .def_md_devad   = 0,
12827         .flags          = ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12828                           ELINK_FLAGS_REARM_LATCH_SIGNAL,
12829         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12830         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12831         .mdio_ctrl      = 0,
12832         .supported      = (ELINK_SUPPORTED_10baseT_Half |
12833                            ELINK_SUPPORTED_10baseT_Full |
12834                            ELINK_SUPPORTED_100baseT_Half |
12835                            ELINK_SUPPORTED_100baseT_Full |
12836                            ELINK_SUPPORTED_1000baseT_Full |
12837                            ELINK_SUPPORTED_10000baseT_Full |
12838                            ELINK_SUPPORTED_TP |
12839                            ELINK_SUPPORTED_Autoneg |
12840                            ELINK_SUPPORTED_Pause |
12841                            ELINK_SUPPORTED_Asym_Pause),
12842         .media_type     = ELINK_ETH_PHY_BASE_T,
12843         .ver_addr       = 0,
12844         .req_flow_ctrl  = 0,
12845         .req_line_speed = 0,
12846         .speed_cap_mask = 0,
12847         .req_duplex     = 0,
12848         .rsrv           = 0,
12849         .config_init    = (config_init_t)elink_8481_config_init,
12850         .read_status    = (read_status_t)elink_848xx_read_status,
12851         .link_reset     = (link_reset_t)elink_8481_link_reset,
12852         .config_loopback = (config_loopback_t)NULL,
12853         .format_fw_ver  = (format_fw_ver_t)elink_848xx_format_ver,
12854         .hw_reset       = (hw_reset_t)elink_8481_hw_reset,
12855         .set_link_led   = (set_link_led_t)elink_848xx_set_link_led,
12856         .phy_specific_func = (phy_specific_func_t)NULL
12857 };
12858
12859 static const struct elink_phy phy_84823 = {
12860         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84823,
12861         .addr           = 0xff,
12862         .def_md_devad   = 0,
12863         .flags          = (ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12864                            ELINK_FLAGS_REARM_LATCH_SIGNAL |
12865                            ELINK_FLAGS_TX_ERROR_CHECK),
12866         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12867         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12868         .mdio_ctrl      = 0,
12869         .supported      = (ELINK_SUPPORTED_10baseT_Half |
12870                            ELINK_SUPPORTED_10baseT_Full |
12871                            ELINK_SUPPORTED_100baseT_Half |
12872                            ELINK_SUPPORTED_100baseT_Full |
12873                            ELINK_SUPPORTED_1000baseT_Full |
12874                            ELINK_SUPPORTED_10000baseT_Full |
12875                            ELINK_SUPPORTED_TP |
12876                            ELINK_SUPPORTED_Autoneg |
12877                            ELINK_SUPPORTED_Pause |
12878                            ELINK_SUPPORTED_Asym_Pause),
12879         .media_type     = ELINK_ETH_PHY_BASE_T,
12880         .ver_addr       = 0,
12881         .req_flow_ctrl  = 0,
12882         .req_line_speed = 0,
12883         .speed_cap_mask = 0,
12884         .req_duplex     = 0,
12885         .rsrv           = 0,
12886         .config_init    = (config_init_t)elink_848x3_config_init,
12887         .read_status    = (read_status_t)elink_848xx_read_status,
12888         .link_reset     = (link_reset_t)elink_848x3_link_reset,
12889         .config_loopback = (config_loopback_t)NULL,
12890         .format_fw_ver  = (format_fw_ver_t)elink_848xx_format_ver,
12891         .hw_reset       = (hw_reset_t)NULL,
12892         .set_link_led   = (set_link_led_t)elink_848xx_set_link_led,
12893         .phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12894 };
12895
12896 static const struct elink_phy phy_84833 = {
12897         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84833,
12898         .addr           = 0xff,
12899         .def_md_devad   = 0,
12900         .flags          = (ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12901                            ELINK_FLAGS_REARM_LATCH_SIGNAL |
12902                            ELINK_FLAGS_TX_ERROR_CHECK |
12903                            ELINK_FLAGS_TEMPERATURE),
12904         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12905         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12906         .mdio_ctrl      = 0,
12907         .supported      = (ELINK_SUPPORTED_100baseT_Half |
12908                            ELINK_SUPPORTED_100baseT_Full |
12909                            ELINK_SUPPORTED_1000baseT_Full |
12910                            ELINK_SUPPORTED_10000baseT_Full |
12911                            ELINK_SUPPORTED_TP |
12912                            ELINK_SUPPORTED_Autoneg |
12913                            ELINK_SUPPORTED_Pause |
12914                            ELINK_SUPPORTED_Asym_Pause),
12915         .media_type     = ELINK_ETH_PHY_BASE_T,
12916         .ver_addr       = 0,
12917         .req_flow_ctrl  = 0,
12918         .req_line_speed = 0,
12919         .speed_cap_mask = 0,
12920         .req_duplex     = 0,
12921         .rsrv           = 0,
12922         .config_init    = (config_init_t)elink_848x3_config_init,
12923         .read_status    = (read_status_t)elink_848xx_read_status,
12924         .link_reset     = (link_reset_t)elink_848x3_link_reset,
12925         .config_loopback = (config_loopback_t)NULL,
12926         .format_fw_ver  = (format_fw_ver_t)elink_848xx_format_ver,
12927         .hw_reset       = (hw_reset_t)elink_84833_hw_reset_phy,
12928         .set_link_led   = (set_link_led_t)elink_848xx_set_link_led,
12929         .phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12930 };
12931
12932 static const struct elink_phy phy_84834 = {
12933         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834,
12934         .addr           = 0xff,
12935         .def_md_devad   = 0,
12936         .flags          = ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12937                             ELINK_FLAGS_REARM_LATCH_SIGNAL,
12938         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12939         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12940         .mdio_ctrl      = 0,
12941         .supported      = (ELINK_SUPPORTED_100baseT_Half |
12942                            ELINK_SUPPORTED_100baseT_Full |
12943                            ELINK_SUPPORTED_1000baseT_Full |
12944                            ELINK_SUPPORTED_10000baseT_Full |
12945                            ELINK_SUPPORTED_TP |
12946                            ELINK_SUPPORTED_Autoneg |
12947                            ELINK_SUPPORTED_Pause |
12948                            ELINK_SUPPORTED_Asym_Pause),
12949         .media_type     = ELINK_ETH_PHY_BASE_T,
12950         .ver_addr       = 0,
12951         .req_flow_ctrl  = 0,
12952         .req_line_speed = 0,
12953         .speed_cap_mask = 0,
12954         .req_duplex     = 0,
12955         .rsrv           = 0,
12956         .config_init    = (config_init_t)elink_848x3_config_init,
12957         .read_status    = (read_status_t)elink_848xx_read_status,
12958         .link_reset     = (link_reset_t)elink_848x3_link_reset,
12959         .config_loopback = (config_loopback_t)NULL,
12960         .format_fw_ver  = (format_fw_ver_t)elink_848xx_format_ver,
12961         .hw_reset       = (hw_reset_t)elink_84833_hw_reset_phy,
12962         .set_link_led   = (set_link_led_t)elink_848xx_set_link_led,
12963         .phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12964 };
12965
12966 static const struct elink_phy phy_84858 = {
12967         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858,
12968         .addr           = 0xff,
12969         .def_md_devad   = 0,
12970         .flags          = ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12971                             ELINK_FLAGS_REARM_LATCH_SIGNAL,
12972         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12973         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12974         .mdio_ctrl      = 0,
12975         .supported      = (ELINK_SUPPORTED_100baseT_Half |
12976                            ELINK_SUPPORTED_100baseT_Full |
12977                            ELINK_SUPPORTED_1000baseT_Full |
12978                            ELINK_SUPPORTED_10000baseT_Full |
12979                            ELINK_SUPPORTED_TP |
12980                            ELINK_SUPPORTED_Autoneg |
12981                            ELINK_SUPPORTED_Pause |
12982                            ELINK_SUPPORTED_Asym_Pause),
12983         .media_type     = ELINK_ETH_PHY_BASE_T,
12984         .ver_addr       = 0,
12985         .req_flow_ctrl  = 0,
12986         .req_line_speed = 0,
12987         .speed_cap_mask = 0,
12988         .req_duplex     = 0,
12989         .rsrv           = 0,
12990         .config_init    = (config_init_t)elink_848x3_config_init,
12991         .read_status    = (read_status_t)elink_848xx_read_status,
12992         .link_reset     = (link_reset_t)elink_848x3_link_reset,
12993         .config_loopback = (config_loopback_t)NULL,
12994         .format_fw_ver  = (format_fw_ver_t)elink_848xx_format_ver,
12995         .hw_reset       = (hw_reset_t)elink_84833_hw_reset_phy,
12996         .set_link_led   = (set_link_led_t)elink_848xx_set_link_led,
12997         .phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12998 };
12999
13000
13001 static const struct elink_phy phy_54618se = {
13002         .type           = PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE,
13003         .addr           = 0xff,
13004         .def_md_devad   = 0,
13005         .flags          = ELINK_FLAGS_INIT_XGXS_FIRST,
13006         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
13007         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
13008         .mdio_ctrl      = 0,
13009         .supported      = (ELINK_SUPPORTED_10baseT_Half |
13010                            ELINK_SUPPORTED_10baseT_Full |
13011                            ELINK_SUPPORTED_100baseT_Half |
13012                            ELINK_SUPPORTED_100baseT_Full |
13013                            ELINK_SUPPORTED_1000baseT_Full |
13014                            ELINK_SUPPORTED_TP |
13015                            ELINK_SUPPORTED_Autoneg |
13016                            ELINK_SUPPORTED_Pause |
13017                            ELINK_SUPPORTED_Asym_Pause),
13018         .media_type     = ELINK_ETH_PHY_BASE_T,
13019         .ver_addr       = 0,
13020         .req_flow_ctrl  = 0,
13021         .req_line_speed = 0,
13022         .speed_cap_mask = 0,
13023         /* req_duplex = */0,
13024         /* rsrv = */0,
13025         .config_init    = (config_init_t)elink_54618se_config_init,
13026         .read_status    = (read_status_t)elink_54618se_read_status,
13027         .link_reset     = (link_reset_t)elink_54618se_link_reset,
13028         .config_loopback = (config_loopback_t)elink_54618se_config_loopback,
13029         .format_fw_ver  = (format_fw_ver_t)NULL,
13030         .hw_reset       = (hw_reset_t)NULL,
13031         .set_link_led   = (set_link_led_t)elink_5461x_set_link_led,
13032         .phy_specific_func = (phy_specific_func_t)elink_54618se_specific_func
13033 };
13034 /*****************************************************************/
13035 /*                                                               */
13036 /* Populate the phy according. Main function: elink_populate_phy   */
13037 /*                                                               */
13038 /*****************************************************************/
13039
13040 static void elink_populate_preemphasis(struct bnx2x_softc *sc,
13041                                      uint32_t shmem_base,
13042                                      struct elink_phy *phy, uint8_t port,
13043                                      uint8_t phy_index)
13044 {
13045         /* Get the 4 lanes xgxs config rx and tx */
13046         uint32_t rx = 0, tx = 0, i;
13047         for (i = 0; i < 2; i++) {
13048                 /* INT_PHY and ELINK_EXT_PHY1 share the same value location in
13049                  * the shmem. When num_phys is greater than 1, than this value
13050                  * applies only to ELINK_EXT_PHY1
13051                  */
13052                 if (phy_index == ELINK_INT_PHY || phy_index == ELINK_EXT_PHY1) {
13053                         rx = REG_RD(sc, shmem_base +
13054                                     offsetof(struct shmem_region,
13055                         dev_info.port_hw_config[port].xgxs_config_rx[i << 1]));
13056
13057                         tx = REG_RD(sc, shmem_base +
13058                                     offsetof(struct shmem_region,
13059                         dev_info.port_hw_config[port].xgxs_config_tx[i << 1]));
13060                 } else {
13061                         rx = REG_RD(sc, shmem_base +
13062                                     offsetof(struct shmem_region,
13063                         dev_info.port_hw_config[port].xgxs_config2_rx[i << 1]));
13064
13065                         tx = REG_RD(sc, shmem_base +
13066                                     offsetof(struct shmem_region,
13067                         dev_info.port_hw_config[port].xgxs_config2_rx[i << 1]));
13068                 }
13069
13070                 phy->rx_preemphasis[i << 1] = ((rx >> 16) & 0xffff);
13071                 phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
13072
13073                 phy->tx_preemphasis[i << 1] = ((tx >> 16) & 0xffff);
13074                 phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
13075                 ELINK_DEBUG_P2(sc, "phy->rx_preemphasis = %x, phy->tx_preemphasis = %x",
13076                         phy->rx_preemphasis[i << 1],
13077                         phy->tx_preemphasis[i << 1]);
13078         }
13079 }
13080
13081 static uint32_t elink_get_ext_phy_config(struct bnx2x_softc *sc,
13082                                     uint32_t shmem_base,
13083                                     uint8_t phy_index, uint8_t port)
13084 {
13085         uint32_t ext_phy_config = 0;
13086         switch (phy_index) {
13087         case ELINK_EXT_PHY1:
13088                 ext_phy_config = REG_RD(sc, shmem_base +
13089                                               offsetof(struct shmem_region,
13090                         dev_info.port_hw_config[port].external_phy_config));
13091                 break;
13092         case ELINK_EXT_PHY2:
13093                 ext_phy_config = REG_RD(sc, shmem_base +
13094                                               offsetof(struct shmem_region,
13095                         dev_info.port_hw_config[port].external_phy_config2));
13096                 break;
13097         default:
13098                 ELINK_DEBUG_P1(sc, "Invalid phy_index %d", phy_index);
13099                 return ELINK_STATUS_ERROR;
13100         }
13101
13102         return ext_phy_config;
13103 }
13104 static elink_status_t elink_populate_int_phy(struct bnx2x_softc *sc,
13105                                   uint32_t shmem_base, uint8_t port,
13106                                   struct elink_phy *phy)
13107 {
13108         uint32_t phy_addr;
13109         uint32_t chip_id;
13110         uint32_t switch_cfg = (REG_RD(sc, shmem_base +
13111                                        offsetof(struct shmem_region,
13112                         dev_info.port_feature_config[port].link_config)) &
13113                           PORT_FEATURE_CONNECTED_SWITCH_MASK);
13114         chip_id = (REG_RD(sc, MISC_REG_CHIP_NUM) << 16) |
13115                 ((REG_RD(sc, MISC_REG_CHIP_REV) & 0xf) << 12);
13116
13117         ELINK_DEBUG_P1(sc, ":chip_id = 0x%x", chip_id);
13118         if (USES_WARPCORE(sc)) {
13119                 uint32_t serdes_net_if;
13120                 phy_addr = REG_RD(sc,
13121                                   MISC_REG_WC0_CTRL_PHY_ADDR);
13122                 *phy = phy_warpcore;
13123                 if (REG_RD(sc, MISC_REG_PORT4MODE_EN_OVWR) == 0x3)
13124                         phy->flags |= ELINK_FLAGS_4_PORT_MODE;
13125                 else
13126                         phy->flags &= ~ELINK_FLAGS_4_PORT_MODE;
13127                         /* Check Dual mode */
13128                 serdes_net_if = (REG_RD(sc, shmem_base +
13129                                         offsetof(struct shmem_region, dev_info.
13130                                         port_hw_config[port].default_cfg)) &
13131                                  PORT_HW_CFG_NET_SERDES_IF_MASK);
13132                 /* Set the appropriate supported and flags indications per
13133                  * interface type of the chip
13134                  */
13135                 switch (serdes_net_if) {
13136                 case PORT_HW_CFG_NET_SERDES_IF_SGMII:
13137                         phy->supported &= (ELINK_SUPPORTED_10baseT_Half |
13138                                            ELINK_SUPPORTED_10baseT_Full |
13139                                            ELINK_SUPPORTED_100baseT_Half |
13140                                            ELINK_SUPPORTED_100baseT_Full |
13141                                            ELINK_SUPPORTED_1000baseT_Full |
13142                                            ELINK_SUPPORTED_FIBRE |
13143                                            ELINK_SUPPORTED_Autoneg |
13144                                            ELINK_SUPPORTED_Pause |
13145                                            ELINK_SUPPORTED_Asym_Pause);
13146                         phy->media_type = ELINK_ETH_PHY_BASE_T;
13147                         break;
13148                 case PORT_HW_CFG_NET_SERDES_IF_XFI:
13149                         phy->supported &= (ELINK_SUPPORTED_1000baseT_Full |
13150                                            ELINK_SUPPORTED_10000baseT_Full |
13151                                            ELINK_SUPPORTED_FIBRE |
13152                                            ELINK_SUPPORTED_Pause |
13153                                            ELINK_SUPPORTED_Asym_Pause);
13154                         phy->media_type = ELINK_ETH_PHY_XFP_FIBER;
13155                         break;
13156                 case PORT_HW_CFG_NET_SERDES_IF_SFI:
13157                         phy->supported &= (ELINK_SUPPORTED_1000baseT_Full |
13158                                            ELINK_SUPPORTED_10000baseT_Full |
13159                                            ELINK_SUPPORTED_FIBRE |
13160                                            ELINK_SUPPORTED_Pause |
13161                                            ELINK_SUPPORTED_Asym_Pause);
13162                         phy->media_type = ELINK_ETH_PHY_SFPP_10G_FIBER;
13163                         break;
13164                 case PORT_HW_CFG_NET_SERDES_IF_KR:
13165                         phy->media_type = ELINK_ETH_PHY_KR;
13166                         phy->supported &= (ELINK_SUPPORTED_1000baseKX_Full |
13167                                            ELINK_SUPPORTED_10000baseKR_Full |
13168                                            ELINK_SUPPORTED_FIBRE |
13169                                            ELINK_SUPPORTED_Autoneg |
13170                                            ELINK_SUPPORTED_Pause |
13171                                            ELINK_SUPPORTED_Asym_Pause);
13172                         break;
13173                 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
13174                         phy->media_type = ELINK_ETH_PHY_KR;
13175                         phy->flags |= ELINK_FLAGS_WC_DUAL_MODE;
13176                         phy->supported &= (ELINK_SUPPORTED_20000baseMLD2_Full |
13177                                            ELINK_SUPPORTED_FIBRE |
13178                                            ELINK_SUPPORTED_Pause |
13179                                            ELINK_SUPPORTED_Asym_Pause);
13180                         break;
13181                 case PORT_HW_CFG_NET_SERDES_IF_KR2:
13182                         phy->media_type = ELINK_ETH_PHY_KR;
13183                         phy->flags |= ELINK_FLAGS_WC_DUAL_MODE;
13184                         phy->supported &= (ELINK_SUPPORTED_20000baseKR2_Full |
13185                                            ELINK_SUPPORTED_10000baseKR_Full |
13186                                            ELINK_SUPPORTED_1000baseKX_Full |
13187                                            ELINK_SUPPORTED_Autoneg |
13188                                            ELINK_SUPPORTED_FIBRE |
13189                                            ELINK_SUPPORTED_Pause |
13190                                            ELINK_SUPPORTED_Asym_Pause);
13191                         phy->flags &= ~ELINK_FLAGS_TX_ERROR_CHECK;
13192                         break;
13193                 default:
13194                         ELINK_DEBUG_P1(sc, "Unknown WC interface type 0x%x",
13195                                        serdes_net_if);
13196                         break;
13197                 }
13198
13199                 /* Enable MDC/MDIO work-around for E3 A0 since free running MDC
13200                  * was not set as expected. For B0, ECO will be enabled so there
13201                  * won't be an issue there
13202                  */
13203                 if (CHIP_REV(sc) == CHIP_REV_Ax)
13204                         phy->flags |= ELINK_FLAGS_MDC_MDIO_WA;
13205                 else
13206                         phy->flags |= ELINK_FLAGS_MDC_MDIO_WA_B0;
13207                 ELINK_DEBUG_P3(sc, "media_type = %x, flags = %x, supported = %x",
13208                                 phy->media_type, phy->flags, phy->supported);
13209         } else {
13210                 switch (switch_cfg) {
13211                 case ELINK_SWITCH_CFG_1G:
13212                         phy_addr = REG_RD(sc,
13213                                           NIG_REG_SERDES0_CTRL_PHY_ADDR +
13214                                           port * 0x10);
13215                         *phy = phy_serdes;
13216                         break;
13217                 case ELINK_SWITCH_CFG_10G:
13218                         phy_addr = REG_RD(sc,
13219                                           NIG_REG_XGXS0_CTRL_PHY_ADDR +
13220                                           port * 0x18);
13221                         *phy = phy_xgxs;
13222                         break;
13223                 default:
13224                         ELINK_DEBUG_P0(sc, "Invalid switch_cfg");
13225                         return ELINK_STATUS_ERROR;
13226                 }
13227         }
13228         phy->addr = (uint8_t)phy_addr;
13229         phy->mdio_ctrl = elink_get_emac_base(sc,
13230                                             SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
13231                                             port);
13232         if (CHIP_IS_E2(sc))
13233                 phy->def_md_devad = ELINK_E2_DEFAULT_PHY_DEV_ADDR;
13234         else
13235                 phy->def_md_devad = ELINK_DEFAULT_PHY_DEV_ADDR;
13236
13237         ELINK_DEBUG_P3(sc, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x",
13238                    port, phy->addr, phy->mdio_ctrl);
13239
13240         elink_populate_preemphasis(sc, shmem_base, phy, port, ELINK_INT_PHY);
13241         return ELINK_STATUS_OK;
13242 }
13243
13244 static elink_status_t elink_populate_ext_phy(struct bnx2x_softc *sc,
13245                                   uint8_t phy_index,
13246                                   uint32_t shmem_base,
13247                                   uint32_t shmem2_base,
13248                                   uint8_t port,
13249                                   struct elink_phy *phy)
13250 {
13251         uint32_t ext_phy_config, phy_type, config2;
13252         uint32_t mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
13253         ext_phy_config = elink_get_ext_phy_config(sc, shmem_base,
13254                                                   phy_index, port);
13255         phy_type = ELINK_XGXS_EXT_PHY_TYPE(ext_phy_config);
13256         /* Select the phy type */
13257         switch (phy_type) {
13258         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8073:
13259                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
13260                 *phy = phy_8073;
13261                 break;
13262         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8705:
13263                 *phy = phy_8705;
13264                 break;
13265         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8706:
13266                 *phy = phy_8706;
13267                 break;
13268         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726:
13269                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
13270                 *phy = phy_8726;
13271                 break;
13272         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727_NOC:
13273                 /* BNX2X8727_NOC => BNX2X8727 no over current */
13274                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
13275                 *phy = phy_8727;
13276                 phy->flags |= ELINK_FLAGS_NOC;
13277                 break;
13278         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722:
13279         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727:
13280                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
13281                 *phy = phy_8727;
13282                 break;
13283         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8481:
13284                 *phy = phy_8481;
13285                 break;
13286         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84823:
13287                 *phy = phy_84823;
13288                 break;
13289         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84833:
13290                 *phy = phy_84833;
13291                 break;
13292         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834:
13293                 *phy = phy_84834;
13294                 break;
13295         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858:
13296                 *phy = phy_84858;
13297                 break;
13298         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X54616:
13299         case PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE:
13300                 *phy = phy_54618se;
13301                 if (phy_type == PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BNX2X54618SE)
13302                         phy->flags |= ELINK_FLAGS_EEE;
13303                 break;
13304         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
13305                 *phy = phy_7101;
13306                 break;
13307         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
13308                 *phy = phy_null;
13309                 return ELINK_STATUS_ERROR;
13310         default:
13311                 *phy = phy_null;
13312                 /* In case external PHY wasn't found */
13313                 if ((phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
13314                     (phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN))
13315                         return ELINK_STATUS_ERROR;
13316                 return ELINK_STATUS_OK;
13317         }
13318
13319         phy->addr = ELINK_XGXS_EXT_PHY_ADDR(ext_phy_config);
13320         elink_populate_preemphasis(sc, shmem_base, phy, port, phy_index);
13321
13322         /* The shmem address of the phy version is located on different
13323          * structures. In case this structure is too old, do not set
13324          * the address
13325          */
13326         config2 = REG_RD(sc, shmem_base + offsetof(struct shmem_region,
13327                                         dev_info.shared_hw_config.config2));
13328         if (phy_index == ELINK_EXT_PHY1) {
13329                 phy->ver_addr = shmem_base + offsetof(struct shmem_region,
13330                                 port_mb[port].ext_phy_fw_version);
13331
13332                 /* Check specific mdc mdio settings */
13333                 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
13334                         mdc_mdio_access = config2 &
13335                         SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
13336         } else {
13337                 uint32_t size = REG_RD(sc, shmem2_base);
13338
13339                 if (size >
13340                     offsetof(struct shmem2_region, ext_phy_fw_version2)) {
13341                         phy->ver_addr = shmem2_base +
13342                             offsetof(struct shmem2_region,
13343                                      ext_phy_fw_version2[port]);
13344                 }
13345                 /* Check specific mdc mdio settings */
13346                 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
13347                         mdc_mdio_access = (config2 &
13348                         SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
13349                         (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
13350                          SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
13351         }
13352         phy->mdio_ctrl = elink_get_emac_base(sc, mdc_mdio_access, port);
13353
13354         if (elink_is_8483x_8485x(phy) && (phy->ver_addr)) {
13355                 /* Remove 100Mb link supported for BNX2X84833/4 when phy fw
13356                  * version lower than or equal to 1.39
13357                  */
13358                 uint32_t raw_ver = REG_RD(sc, phy->ver_addr);
13359                 if (((raw_ver & 0x7F) <= 39) &&
13360                     (((raw_ver & 0xF80) >> 7) <= 1))
13361                         phy->supported &= ~(ELINK_SUPPORTED_100baseT_Half |
13362                                             ELINK_SUPPORTED_100baseT_Full);
13363         }
13364
13365         ELINK_DEBUG_P3(sc, "phy_type 0x%x port %d found in index %d",
13366                    phy_type, port, phy_index);
13367         ELINK_DEBUG_P2(sc, "             addr=0x%x, mdio_ctl=0x%x",
13368                    phy->addr, phy->mdio_ctrl);
13369         return ELINK_STATUS_OK;
13370 }
13371
13372 static elink_status_t elink_populate_phy(struct bnx2x_softc *sc,
13373                               uint8_t phy_index, uint32_t shmem_base,
13374                               uint32_t shmem2_base, uint8_t port,
13375                               struct elink_phy *phy)
13376 {
13377         elink_status_t status = ELINK_STATUS_OK;
13378         phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
13379         if (phy_index == ELINK_INT_PHY)
13380                 return elink_populate_int_phy(sc, shmem_base, port, phy);
13381         status = elink_populate_ext_phy(sc, phy_index, shmem_base, shmem2_base,
13382                                         port, phy);
13383         return status;
13384 }
13385
13386 static void elink_phy_def_cfg(struct elink_params *params,
13387                               struct elink_phy *phy,
13388                               uint8_t phy_index)
13389 {
13390         struct bnx2x_softc *sc = params->sc;
13391         uint32_t link_config;
13392         /* Populate the default phy configuration for MF mode */
13393         if (phy_index == ELINK_EXT_PHY2) {
13394                 link_config = REG_RD(sc, params->shmem_base +
13395                                      offsetof(struct shmem_region, dev_info.
13396                         port_feature_config[params->port].link_config2));
13397                 phy->speed_cap_mask = REG_RD(sc, params->shmem_base +
13398                                              offsetof(struct shmem_region,
13399                                                       dev_info.
13400                         port_hw_config[params->port].speed_capability_mask2));
13401         } else {
13402                 link_config = REG_RD(sc, params->shmem_base +
13403                                      offsetof(struct shmem_region, dev_info.
13404                                 port_feature_config[params->port].link_config));
13405                 phy->speed_cap_mask = REG_RD(sc, params->shmem_base +
13406                                              offsetof(struct shmem_region,
13407                                                       dev_info.
13408                         port_hw_config[params->port].speed_capability_mask));
13409         }
13410         ELINK_DEBUG_P3(sc,
13411            "Default config phy idx %x cfg 0x%x speed_cap_mask 0x%x",
13412            phy_index, link_config, phy->speed_cap_mask);
13413
13414         phy->req_duplex = DUPLEX_FULL;
13415         switch (link_config  & PORT_FEATURE_LINK_SPEED_MASK) {
13416         case PORT_FEATURE_LINK_SPEED_10M_HALF:
13417                 phy->req_duplex = DUPLEX_HALF;
13418                 /* fallthrough */
13419         case PORT_FEATURE_LINK_SPEED_10M_FULL:
13420                 phy->req_line_speed = ELINK_SPEED_10;
13421                 break;
13422         case PORT_FEATURE_LINK_SPEED_100M_HALF:
13423                 phy->req_duplex = DUPLEX_HALF;
13424                 /* fallthrough */
13425         case PORT_FEATURE_LINK_SPEED_100M_FULL:
13426                 phy->req_line_speed = ELINK_SPEED_100;
13427                 break;
13428         case PORT_FEATURE_LINK_SPEED_1G:
13429                 phy->req_line_speed = ELINK_SPEED_1000;
13430                 break;
13431         case PORT_FEATURE_LINK_SPEED_2_5G:
13432                 phy->req_line_speed = ELINK_SPEED_2500;
13433                 break;
13434         case PORT_FEATURE_LINK_SPEED_10G_CX4:
13435                 phy->req_line_speed = ELINK_SPEED_10000;
13436                 break;
13437         default:
13438                 phy->req_line_speed = ELINK_SPEED_AUTO_NEG;
13439                 break;
13440         }
13441
13442         ELINK_DEBUG_P2(sc, "Default config phy idx %x, req_duplex config %x",
13443                         phy_index, phy->req_duplex);
13444
13445         switch (link_config  & PORT_FEATURE_FLOW_CONTROL_MASK) {
13446         case PORT_FEATURE_FLOW_CONTROL_AUTO:
13447                 phy->req_flow_ctrl = ELINK_FLOW_CTRL_AUTO;
13448                 break;
13449         case PORT_FEATURE_FLOW_CONTROL_TX:
13450                 phy->req_flow_ctrl = ELINK_FLOW_CTRL_TX;
13451                 break;
13452         case PORT_FEATURE_FLOW_CONTROL_RX:
13453                 phy->req_flow_ctrl = ELINK_FLOW_CTRL_RX;
13454                 break;
13455         case PORT_FEATURE_FLOW_CONTROL_BOTH:
13456                 phy->req_flow_ctrl = ELINK_FLOW_CTRL_BOTH;
13457                 break;
13458         default:
13459                 phy->req_flow_ctrl = ELINK_FLOW_CTRL_NONE;
13460                 break;
13461         }
13462         ELINK_DEBUG_P3(sc, "Requested Duplex = %x, line_speed = %x, flow_ctrl = %x",
13463                        phy->req_duplex, phy->req_line_speed,
13464                        phy->req_flow_ctrl);
13465 }
13466
13467 uint32_t elink_phy_selection(struct elink_params *params)
13468 {
13469         uint32_t phy_config_swapped, prio_cfg;
13470         uint32_t return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
13471
13472         phy_config_swapped = params->multi_phy_config &
13473                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
13474
13475         prio_cfg = params->multi_phy_config &
13476                         PORT_HW_CFG_PHY_SELECTION_MASK;
13477
13478         if (phy_config_swapped) {
13479                 switch (prio_cfg) {
13480                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
13481                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
13482                         break;
13483                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
13484                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
13485                         break;
13486                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
13487                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
13488                         break;
13489                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
13490                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
13491                         break;
13492                 }
13493         } else
13494                 return_cfg = prio_cfg;
13495
13496         return return_cfg;
13497 }
13498
13499 elink_status_t elink_phy_probe(struct elink_params *params)
13500 {
13501         uint8_t phy_index, actual_phy_idx;
13502         uint32_t phy_config_swapped, sync_offset, media_types;
13503         struct bnx2x_softc *sc = params->sc;
13504         struct elink_phy *phy;
13505         params->num_phys = 0;
13506         ELINK_DEBUG_P0(sc, "Begin phy probe");
13507 #ifdef ELINK_INCLUDE_EMUL
13508         if (CHIP_REV_IS_EMUL(sc))
13509                 return ELINK_STATUS_OK;
13510 #endif
13511         phy_config_swapped = params->multi_phy_config &
13512                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
13513
13514         for (phy_index = ELINK_INT_PHY; phy_index < ELINK_MAX_PHYS;
13515               phy_index++) {
13516                 actual_phy_idx = phy_index;
13517                 if (phy_config_swapped) {
13518                         if (phy_index == ELINK_EXT_PHY1)
13519                                 actual_phy_idx = ELINK_EXT_PHY2;
13520                         else if (phy_index == ELINK_EXT_PHY2)
13521                                 actual_phy_idx = ELINK_EXT_PHY1;
13522                 }
13523                 ELINK_DEBUG_P3(sc, "phy_config_swapped %x, phy_index %x,"
13524                                " actual_phy_idx %x", phy_config_swapped,
13525                            phy_index, actual_phy_idx);
13526                 phy = &params->phy[actual_phy_idx];
13527                 if (elink_populate_phy(sc, phy_index, params->shmem_base,
13528                                        params->shmem2_base, params->port,
13529                                        phy) != ELINK_STATUS_OK) {
13530                         params->num_phys = 0;
13531                         ELINK_DEBUG_P1(sc, "phy probe failed in phy index %d",
13532                                    phy_index);
13533                         for (phy_index = ELINK_INT_PHY;
13534                               phy_index < ELINK_MAX_PHYS;
13535                               phy_index++)
13536                                 *phy = phy_null;
13537                         return ELINK_STATUS_ERROR;
13538                 }
13539                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
13540                         break;
13541
13542                 if (params->feature_config_flags &
13543                     ELINK_FEATURE_CONFIG_DISABLE_REMOTE_FAULT_DET)
13544                         phy->flags &= ~ELINK_FLAGS_TX_ERROR_CHECK;
13545
13546                 if (!(params->feature_config_flags &
13547                       ELINK_FEATURE_CONFIG_MT_SUPPORT))
13548                         phy->flags |= ELINK_FLAGS_MDC_MDIO_WA_G;
13549
13550                 sync_offset = params->shmem_base +
13551                         offsetof(struct shmem_region,
13552                         dev_info.port_hw_config[params->port].media_type);
13553                 media_types = REG_RD(sc, sync_offset);
13554
13555                 /* Update media type for non-PMF sync only for the first time
13556                  * In case the media type changes afterwards, it will be updated
13557                  * using the update_status function
13558                  */
13559                 if ((media_types & (PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
13560                                     (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
13561                                      actual_phy_idx))) == 0) {
13562                         media_types |= ((phy->media_type &
13563                                         PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
13564                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
13565                                  actual_phy_idx));
13566                 }
13567                 REG_WR(sc, sync_offset, media_types);
13568
13569                 elink_phy_def_cfg(params, phy, phy_index);
13570                 params->num_phys++;
13571         }
13572
13573         ELINK_DEBUG_P1(sc, "End phy probe. #phys found %x", params->num_phys);
13574         return ELINK_STATUS_OK;
13575 }
13576
13577 #ifdef ELINK_INCLUDE_EMUL
13578 static elink_status_t elink_init_e3_emul_mac(struct elink_params *params,
13579                                              struct elink_vars *vars)
13580 {
13581         struct bnx2x_softc *sc = params->sc;
13582         vars->line_speed = params->req_line_speed[0];
13583         /* In case link speed is auto, set speed the highest as possible */
13584         if (params->req_line_speed[0] == ELINK_SPEED_AUTO_NEG) {
13585                 if (params->feature_config_flags &
13586                     ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC)
13587                         vars->line_speed = ELINK_SPEED_2500;
13588                 else if (elink_is_4_port_mode(sc))
13589                         vars->line_speed = ELINK_SPEED_10000;
13590                 else
13591                         vars->line_speed = ELINK_SPEED_20000;
13592         }
13593         if (vars->line_speed < ELINK_SPEED_10000) {
13594                 if ((params->feature_config_flags &
13595                      ELINK_FEATURE_CONFIG_EMUL_DISABLE_UMAC)) {
13596                         ELINK_DEBUG_P1(sc, "Invalid line speed %d while UMAC is"
13597                                    " disabled!", params->req_line_speed[0]);
13598                         return ELINK_STATUS_ERROR;
13599                 }
13600                 switch (vars->line_speed) {
13601                 case ELINK_SPEED_10:
13602                         vars->link_status = ELINK_LINK_10TFD;
13603                         break;
13604                 case ELINK_SPEED_100:
13605                         vars->link_status = ELINK_LINK_100TXFD;
13606                         break;
13607                 case ELINK_SPEED_1000:
13608                         vars->link_status = ELINK_LINK_1000TFD;
13609                         break;
13610                 case ELINK_SPEED_2500:
13611                         vars->link_status = ELINK_LINK_2500TFD;
13612                         break;
13613                 default:
13614                         ELINK_DEBUG_P1(sc, "Invalid line speed %d for UMAC",
13615                                    vars->line_speed);
13616                         return ELINK_STATUS_ERROR;
13617                 }
13618                 vars->link_status |= LINK_STATUS_LINK_UP;
13619
13620                 if (params->loopback_mode == ELINK_LOOPBACK_UMAC)
13621                         elink_umac_enable(params, vars, 1);
13622                 else
13623                         elink_umac_enable(params, vars, 0);
13624         } else {
13625                 /* Link speed >= 10000 requires XMAC enabled */
13626                 if (params->feature_config_flags &
13627                     ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC) {
13628                         ELINK_DEBUG_P1(sc, "Invalid line speed %d while XMAC is"
13629                                    " disabled!", params->req_line_speed[0]);
13630                 return ELINK_STATUS_ERROR;
13631         }
13632                 /* Check link speed */
13633                 switch (vars->line_speed) {
13634                 case ELINK_SPEED_10000:
13635                         vars->link_status = ELINK_LINK_10GTFD;
13636                         break;
13637                 case ELINK_SPEED_20000:
13638                         vars->link_status = ELINK_LINK_20GTFD;
13639                         break;
13640                 default:
13641                         ELINK_DEBUG_P1(sc, "Invalid line speed %d for XMAC",
13642                                    vars->line_speed);
13643                         return ELINK_STATUS_ERROR;
13644                 }
13645                 vars->link_status |= LINK_STATUS_LINK_UP;
13646                 if (params->loopback_mode == ELINK_LOOPBACK_XMAC)
13647                         elink_xmac_enable(params, vars, 1);
13648                 else
13649                         elink_xmac_enable(params, vars, 0);
13650         }
13651                 return ELINK_STATUS_OK;
13652 }
13653
13654 static elink_status_t elink_init_emul(struct elink_params *params,
13655                             struct elink_vars *vars)
13656 {
13657         struct bnx2x_softc *sc = params->sc;
13658         if (CHIP_IS_E3(sc)) {
13659                 if (elink_init_e3_emul_mac(params, vars) !=
13660                     ELINK_STATUS_OK)
13661                         return ELINK_STATUS_ERROR;
13662         } else {
13663                 if (params->feature_config_flags &
13664                     ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC) {
13665                         vars->line_speed = ELINK_SPEED_1000;
13666                         vars->link_status = (LINK_STATUS_LINK_UP |
13667                                              ELINK_LINK_1000XFD);
13668                         if (params->loopback_mode ==
13669                             ELINK_LOOPBACK_EMAC)
13670                                 elink_emac_enable(params, vars, 1);
13671                         else
13672                                 elink_emac_enable(params, vars, 0);
13673                 } else {
13674                         vars->line_speed = ELINK_SPEED_10000;
13675                         vars->link_status = (LINK_STATUS_LINK_UP |
13676                                              ELINK_LINK_10GTFD);
13677                         if (params->loopback_mode ==
13678                             ELINK_LOOPBACK_BMAC)
13679                                 elink_bmac_enable(params, vars, 1, 1);
13680                         else
13681                                 elink_bmac_enable(params, vars, 0, 1);
13682                 }
13683         }
13684         vars->link_up = 1;
13685         vars->duplex = DUPLEX_FULL;
13686         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13687
13688                 if (CHIP_IS_E1x(sc))
13689                         elink_pbf_update(params, vars->flow_ctrl,
13690                                          vars->line_speed);
13691                 /* Disable drain */
13692                 REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13693
13694                 /* update shared memory */
13695                 elink_update_mng(params, vars->link_status);
13696         return ELINK_STATUS_OK;
13697 }
13698 #endif
13699 #ifdef ELINK_INCLUDE_FPGA
13700 static elink_status_t elink_init_fpga(struct elink_params *params,
13701                             struct elink_vars *vars)
13702 {
13703         /* Enable on E1.5 FPGA */
13704         struct bnx2x_softc *sc = params->sc;
13705         vars->duplex = DUPLEX_FULL;
13706         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13707         if (!(CHIP_IS_E1(sc))) {
13708                 vars->flow_ctrl = (ELINK_FLOW_CTRL_TX |
13709                                    ELINK_FLOW_CTRL_RX);
13710                 vars->link_status |= (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
13711                                       LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
13712         }
13713         if (CHIP_IS_E3(sc)) {
13714                 vars->line_speed = params->req_line_speed[0];
13715                 switch (vars->line_speed) {
13716                 case ELINK_SPEED_AUTO_NEG:
13717                         vars->line_speed = ELINK_SPEED_2500;
13718                 case ELINK_SPEED_2500:
13719                         vars->link_status = ELINK_LINK_2500TFD;
13720                         break;
13721                 case ELINK_SPEED_1000:
13722                         vars->link_status = ELINK_LINK_1000XFD;
13723                         break;
13724                 case ELINK_SPEED_100:
13725                         vars->link_status = ELINK_LINK_100TXFD;
13726                         break;
13727                 case ELINK_SPEED_10:
13728                         vars->link_status = ELINK_LINK_10TFD;
13729                         break;
13730                 default:
13731                         ELINK_DEBUG_P1(sc, "Invalid link speed %d",
13732                                    params->req_line_speed[0]);
13733                         return ELINK_STATUS_ERROR;
13734                 }
13735                 vars->link_status |= LINK_STATUS_LINK_UP;
13736                 if (params->loopback_mode == ELINK_LOOPBACK_UMAC)
13737                         elink_umac_enable(params, vars, 1);
13738                 else
13739                         elink_umac_enable(params, vars, 0);
13740         } else {
13741                 vars->line_speed = ELINK_SPEED_10000;
13742                 vars->link_status = (LINK_STATUS_LINK_UP | ELINK_LINK_10GTFD);
13743                 if (params->loopback_mode == ELINK_LOOPBACK_EMAC)
13744                         elink_emac_enable(params, vars, 1);
13745                 else
13746                         elink_emac_enable(params, vars, 0);
13747         }
13748         vars->link_up = 1;
13749
13750         if (CHIP_IS_E1x(sc))
13751                 elink_pbf_update(params, vars->flow_ctrl,
13752                                  vars->line_speed);
13753         /* Disable drain */
13754         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13755
13756         /* Update shared memory */
13757         elink_update_mng(params, vars->link_status);
13758                 return ELINK_STATUS_OK;
13759 }
13760 #endif
13761 static void elink_init_bmac_loopback(struct elink_params *params,
13762                                      struct elink_vars *vars)
13763 {
13764         struct bnx2x_softc *sc = params->sc;
13765                 vars->link_up = 1;
13766                 vars->line_speed = ELINK_SPEED_10000;
13767                 vars->duplex = DUPLEX_FULL;
13768                 vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13769                 vars->mac_type = ELINK_MAC_TYPE_BMAC;
13770
13771                 vars->phy_flags = PHY_XGXS_FLAG;
13772
13773                 elink_xgxs_deassert(params);
13774
13775                 /* Set bmac loopback */
13776                 elink_bmac_enable(params, vars, 1, 1);
13777
13778                 REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13779 }
13780
13781 static void elink_init_emac_loopback(struct elink_params *params,
13782                                      struct elink_vars *vars)
13783 {
13784         struct bnx2x_softc *sc = params->sc;
13785                 vars->link_up = 1;
13786                 vars->line_speed = ELINK_SPEED_1000;
13787                 vars->duplex = DUPLEX_FULL;
13788                 vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13789                 vars->mac_type = ELINK_MAC_TYPE_EMAC;
13790
13791                 vars->phy_flags = PHY_XGXS_FLAG;
13792
13793                 elink_xgxs_deassert(params);
13794                 /* Set bmac loopback */
13795                 elink_emac_enable(params, vars, 1);
13796                 elink_emac_program(params, vars);
13797                 REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13798 }
13799
13800 static void elink_init_xmac_loopback(struct elink_params *params,
13801                                      struct elink_vars *vars)
13802 {
13803         struct bnx2x_softc *sc = params->sc;
13804         vars->link_up = 1;
13805         if (!params->req_line_speed[0])
13806                 vars->line_speed = ELINK_SPEED_10000;
13807         else
13808                 vars->line_speed = params->req_line_speed[0];
13809         vars->duplex = DUPLEX_FULL;
13810         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13811         vars->mac_type = ELINK_MAC_TYPE_XMAC;
13812         vars->phy_flags = PHY_XGXS_FLAG;
13813         /* Set WC to loopback mode since link is required to provide clock
13814          * to the XMAC in 20G mode
13815          */
13816         elink_set_aer_mmd(params, &params->phy[0]);
13817         elink_warpcore_reset_lane(sc, &params->phy[0], 0);
13818         params->phy[ELINK_INT_PHY].config_loopback(
13819                         &params->phy[ELINK_INT_PHY],
13820                         params);
13821
13822         elink_xmac_enable(params, vars, 1);
13823         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13824 }
13825
13826 static void elink_init_umac_loopback(struct elink_params *params,
13827                                      struct elink_vars *vars)
13828 {
13829         struct bnx2x_softc *sc = params->sc;
13830         vars->link_up = 1;
13831         vars->line_speed = ELINK_SPEED_1000;
13832         vars->duplex = DUPLEX_FULL;
13833         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13834         vars->mac_type = ELINK_MAC_TYPE_UMAC;
13835         vars->phy_flags = PHY_XGXS_FLAG;
13836         elink_umac_enable(params, vars, 1);
13837
13838         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13839 }
13840
13841 static void elink_init_xgxs_loopback(struct elink_params *params,
13842                                      struct elink_vars *vars)
13843 {
13844         struct bnx2x_softc *sc = params->sc;
13845         struct elink_phy *int_phy = &params->phy[ELINK_INT_PHY];
13846         vars->link_up = 1;
13847         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13848         vars->duplex = DUPLEX_FULL;
13849         if (params->req_line_speed[0] == ELINK_SPEED_1000)
13850                 vars->line_speed = ELINK_SPEED_1000;
13851         else if ((params->req_line_speed[0] == ELINK_SPEED_20000) ||
13852                  (int_phy->flags & ELINK_FLAGS_WC_DUAL_MODE))
13853                 vars->line_speed = ELINK_SPEED_20000;
13854         else
13855                 vars->line_speed = ELINK_SPEED_10000;
13856
13857         if (!USES_WARPCORE(sc))
13858                 elink_xgxs_deassert(params);
13859         elink_link_initialize(params, vars);
13860
13861         if (params->req_line_speed[0] == ELINK_SPEED_1000) {
13862                 if (USES_WARPCORE(sc))
13863                         elink_umac_enable(params, vars, 0);
13864                 else {
13865                         elink_emac_program(params, vars);
13866                         elink_emac_enable(params, vars, 0);
13867                 }
13868         } else {
13869                 if (USES_WARPCORE(sc))
13870                         elink_xmac_enable(params, vars, 0);
13871                 else
13872                         elink_bmac_enable(params, vars, 0, 1);
13873         }
13874
13875         if (params->loopback_mode == ELINK_LOOPBACK_XGXS) {
13876                 /* Set 10G XGXS loopback */
13877                 int_phy->config_loopback(int_phy, params);
13878         } else {
13879                 /* Set external phy loopback */
13880                 uint8_t phy_index;
13881                 for (phy_index = ELINK_EXT_PHY1;
13882                       phy_index < params->num_phys; phy_index++)
13883                         if (params->phy[phy_index].config_loopback)
13884                                 params->phy[phy_index].config_loopback(
13885                                         &params->phy[phy_index],
13886                                         params);
13887         }
13888         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13889
13890         elink_set_led(params, vars, ELINK_LED_MODE_OPER, vars->line_speed);
13891 }
13892
13893 void elink_set_rx_filter(struct elink_params *params, uint8_t en)
13894 {
13895         struct bnx2x_softc *sc = params->sc;
13896         uint8_t val = en * 0x1F;
13897
13898         /* Open / close the gate between the NIG and the BRB */
13899         if (!CHIP_IS_E1x(sc))
13900                 val |= en * 0x20;
13901         REG_WR(sc, NIG_REG_LLH0_BRB1_DRV_MASK + params->port * 4, val);
13902
13903         if (!CHIP_IS_E1(sc)) {
13904                 REG_WR(sc, NIG_REG_LLH0_BRB1_DRV_MASK_MF + params->port * 4,
13905                        en * 0x3);
13906         }
13907
13908         REG_WR(sc, (params->port ? NIG_REG_LLH1_BRB1_NOT_MCP :
13909                     NIG_REG_LLH0_BRB1_NOT_MCP), en);
13910 }
13911 static elink_status_t elink_avoid_link_flap(struct elink_params *params,
13912                                             struct elink_vars *vars)
13913 {
13914         uint32_t phy_idx;
13915         uint32_t dont_clear_stat, lfa_sts;
13916         struct bnx2x_softc *sc = params->sc;
13917
13918         elink_set_mdio_emac_per_phy(sc, params);
13919         /* Sync the link parameters */
13920         elink_link_status_update(params, vars);
13921
13922         /*
13923          * The module verification was already done by previous link owner,
13924          * so this call is meant only to get warning message
13925          */
13926
13927         for (phy_idx = ELINK_INT_PHY; phy_idx < params->num_phys; phy_idx++) {
13928                 struct elink_phy *phy = &params->phy[phy_idx];
13929                 if (phy->phy_specific_func) {
13930                         ELINK_DEBUG_P0(sc, "Calling PHY specific func");
13931                         phy->phy_specific_func(phy, params, ELINK_PHY_INIT);
13932                 }
13933                 if ((phy->media_type == ELINK_ETH_PHY_SFPP_10G_FIBER) ||
13934                     (phy->media_type == ELINK_ETH_PHY_SFP_1G_FIBER) ||
13935                     (phy->media_type == ELINK_ETH_PHY_DA_TWINAX))
13936                         elink_verify_sfp_module(phy, params);
13937         }
13938         lfa_sts = REG_RD(sc, params->lfa_base +
13939                          offsetof(struct shmem_lfa,
13940                                   lfa_sts));
13941
13942         dont_clear_stat = lfa_sts & SHMEM_LFA_DONT_CLEAR_STAT;
13943
13944         /* Re-enable the NIG/MAC */
13945         if (CHIP_IS_E3(sc)) {
13946                 if (!dont_clear_stat) {
13947                         REG_WR(sc, GRCBASE_MISC +
13948                                MISC_REGISTERS_RESET_REG_2_CLEAR,
13949                                (MISC_REGISTERS_RESET_REG_2_MSTAT0 <<
13950                                 params->port));
13951                         REG_WR(sc, GRCBASE_MISC +
13952                                MISC_REGISTERS_RESET_REG_2_SET,
13953                                (MISC_REGISTERS_RESET_REG_2_MSTAT0 <<
13954                                 params->port));
13955                 }
13956                 if (vars->line_speed < ELINK_SPEED_10000)
13957                         elink_umac_enable(params, vars, 0);
13958                 else
13959                         elink_xmac_enable(params, vars, 0);
13960         } else {
13961                 if (vars->line_speed < ELINK_SPEED_10000)
13962                         elink_emac_enable(params, vars, 0);
13963                 else
13964                         elink_bmac_enable(params, vars, 0, !dont_clear_stat);
13965         }
13966
13967         /* Increment LFA count */
13968         lfa_sts = ((lfa_sts & ~LINK_FLAP_AVOIDANCE_COUNT_MASK) |
13969                    (((((lfa_sts & LINK_FLAP_AVOIDANCE_COUNT_MASK) >>
13970                        LINK_FLAP_AVOIDANCE_COUNT_OFFSET) + 1) & 0xff)
13971                     << LINK_FLAP_AVOIDANCE_COUNT_OFFSET));
13972         /* Clear link flap reason */
13973         lfa_sts &= ~LFA_LINK_FLAP_REASON_MASK;
13974
13975         REG_WR(sc, params->lfa_base +
13976                offsetof(struct shmem_lfa, lfa_sts), lfa_sts);
13977
13978         /* Disable NIG DRAIN */
13979         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
13980
13981         /* Enable interrupts */
13982         elink_link_int_enable(params);
13983         return ELINK_STATUS_OK;
13984 }
13985
13986 static void elink_cannot_avoid_link_flap(struct elink_params *params,
13987                                          struct elink_vars *vars,
13988                                          int lfa_status)
13989 {
13990         uint32_t lfa_sts, cfg_idx, tmp_val;
13991         struct bnx2x_softc *sc = params->sc;
13992
13993         elink_link_reset(params, vars, 1);
13994
13995         if (!params->lfa_base)
13996                 return;
13997         /* Store the new link parameters */
13998         REG_WR(sc, params->lfa_base +
13999                offsetof(struct shmem_lfa, req_duplex),
14000                params->req_duplex[0] | (params->req_duplex[1] << 16));
14001
14002         REG_WR(sc, params->lfa_base +
14003                offsetof(struct shmem_lfa, req_flow_ctrl),
14004                params->req_flow_ctrl[0] | (params->req_flow_ctrl[1] << 16));
14005
14006         REG_WR(sc, params->lfa_base +
14007                offsetof(struct shmem_lfa, req_line_speed),
14008                params->req_line_speed[0] | (params->req_line_speed[1] << 16));
14009
14010         for (cfg_idx = 0; cfg_idx < SHMEM_LINK_CONFIG_SIZE; cfg_idx++) {
14011                 REG_WR(sc, params->lfa_base +
14012                        offsetof(struct shmem_lfa,
14013                                 speed_cap_mask[cfg_idx]),
14014                        params->speed_cap_mask[cfg_idx]);
14015         }
14016
14017         tmp_val = REG_RD(sc, params->lfa_base +
14018                          offsetof(struct shmem_lfa, additional_config));
14019         tmp_val &= ~REQ_FC_AUTO_ADV_MASK;
14020         tmp_val |= params->req_fc_auto_adv;
14021
14022         REG_WR(sc, params->lfa_base +
14023                offsetof(struct shmem_lfa, additional_config), tmp_val);
14024
14025         lfa_sts = REG_RD(sc, params->lfa_base +
14026                          offsetof(struct shmem_lfa, lfa_sts));
14027
14028         /* Clear the "Don't Clear Statistics" bit, and set reason */
14029         lfa_sts &= ~SHMEM_LFA_DONT_CLEAR_STAT;
14030
14031         /* Set link flap reason */
14032         lfa_sts &= ~LFA_LINK_FLAP_REASON_MASK;
14033         lfa_sts |= ((lfa_status & LFA_LINK_FLAP_REASON_MASK) <<
14034                     LFA_LINK_FLAP_REASON_OFFSET);
14035
14036         /* Increment link flap counter */
14037         lfa_sts = ((lfa_sts & ~LINK_FLAP_COUNT_MASK) |
14038                    (((((lfa_sts & LINK_FLAP_COUNT_MASK) >>
14039                        LINK_FLAP_COUNT_OFFSET) + 1) & 0xff)
14040                     << LINK_FLAP_COUNT_OFFSET));
14041         REG_WR(sc, params->lfa_base +
14042                offsetof(struct shmem_lfa, lfa_sts), lfa_sts);
14043         /* Proceed with regular link initialization */
14044 }
14045
14046 elink_status_t elink_phy_init(struct elink_params *params,
14047                               struct elink_vars *vars)
14048 {
14049         int lfa_status;
14050         struct bnx2x_softc *sc = params->sc;
14051         ELINK_DEBUG_P0(sc, "Phy Initialization started");
14052         ELINK_DEBUG_P2(sc, "(1) req_speed %d, req_flowctrl %d",
14053                    params->req_line_speed[0], params->req_flow_ctrl[0]);
14054         ELINK_DEBUG_P2(sc, "(2) req_speed %d, req_flowctrl %d",
14055                    params->req_line_speed[1], params->req_flow_ctrl[1]);
14056         ELINK_DEBUG_P1(sc, "req_adv_flow_ctrl 0x%x", params->req_fc_auto_adv);
14057         vars->link_status = 0;
14058         vars->phy_link_up = 0;
14059         vars->link_up = 0;
14060         vars->line_speed = 0;
14061         vars->duplex = DUPLEX_FULL;
14062         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
14063         vars->mac_type = ELINK_MAC_TYPE_NONE;
14064         vars->phy_flags = 0;
14065         vars->check_kr2_recovery_cnt = 0;
14066         params->link_flags = ELINK_PHY_INITIALIZED;
14067         /* Driver opens NIG-BRB filters */
14068         elink_set_rx_filter(params, 1);
14069         elink_chng_link_count(params, 1);
14070         /* Check if link flap can be avoided */
14071         lfa_status = elink_check_lfa(params);
14072
14073         ELINK_DEBUG_P3(sc, " params : port = %x, loopback_mode = %x req_duplex = %x",
14074                        params->port, params->loopback_mode,
14075                        params->req_duplex[0]);
14076         ELINK_DEBUG_P3(sc, " params : switch_cfg = %x, lane_config = %x req_duplex[1] = %x",
14077                        params->switch_cfg, params->lane_config,
14078                        params->req_duplex[1]);
14079         ELINK_DEBUG_P3(sc, " params : chip_id = %x, feature_config_flags = %x, num_phys = %x",
14080                        params->chip_id, params->feature_config_flags,
14081                        params->num_phys);
14082         ELINK_DEBUG_P3(sc, " params : rsrv = %x, eee_mode = %x, hw_led_mode = %x",
14083                        params->rsrv, params->eee_mode, params->hw_led_mode);
14084         ELINK_DEBUG_P3(sc, " params : multi_phy = %x, req_fc_auto_adv = %x, link_flags = %x",
14085                        params->multi_phy_config, params->req_fc_auto_adv,
14086                        params->link_flags);
14087         ELINK_DEBUG_P2(sc, " params : lfa_base = %x, link_attr = %x",
14088                        params->lfa_base, params->link_attr_sync);
14089         if (lfa_status == 0) {
14090                 ELINK_DEBUG_P0(sc, "Link Flap Avoidance in progress");
14091                 return elink_avoid_link_flap(params, vars);
14092         }
14093
14094         ELINK_DEBUG_P1(sc, "Cannot avoid link flap lfa_sta=0x%x",
14095                        lfa_status);
14096         elink_cannot_avoid_link_flap(params, vars, lfa_status);
14097
14098         /* Disable attentions */
14099         elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 + params->port * 4,
14100                        (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14101                         ELINK_NIG_MASK_XGXS0_LINK10G |
14102                         ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14103                         ELINK_NIG_MASK_MI_INT));
14104 #ifdef ELINK_INCLUDE_EMUL
14105         if (!(params->feature_config_flags &
14106               ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC))
14107 #endif
14108
14109         elink_emac_init(params, vars);
14110
14111         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
14112                 vars->link_status |= LINK_STATUS_PFC_ENABLED;
14113
14114         if ((params->num_phys == 0) &&
14115             !CHIP_REV_IS_SLOW(sc)) {
14116                 ELINK_DEBUG_P0(sc, "No phy found for initialization !!");
14117                 return ELINK_STATUS_ERROR;
14118         }
14119         set_phy_vars(params, vars);
14120
14121         ELINK_DEBUG_P1(sc, "Num of phys on board: %d", params->num_phys);
14122 #ifdef ELINK_INCLUDE_FPGA
14123         if (CHIP_REV_IS_FPGA(sc)) {
14124                 return elink_init_fpga(params, vars);
14125         } else
14126 #endif
14127 #ifdef ELINK_INCLUDE_EMUL
14128         if (CHIP_REV_IS_EMUL(sc)) {
14129                 return elink_init_emul(params, vars);
14130         } else
14131 #endif
14132         switch (params->loopback_mode) {
14133         case ELINK_LOOPBACK_BMAC:
14134                 elink_init_bmac_loopback(params, vars);
14135                 break;
14136         case ELINK_LOOPBACK_EMAC:
14137                 elink_init_emac_loopback(params, vars);
14138                 break;
14139         case ELINK_LOOPBACK_XMAC:
14140                 elink_init_xmac_loopback(params, vars);
14141                 break;
14142         case ELINK_LOOPBACK_UMAC:
14143                 elink_init_umac_loopback(params, vars);
14144                 break;
14145         case ELINK_LOOPBACK_XGXS:
14146         case ELINK_LOOPBACK_EXT_PHY:
14147                 elink_init_xgxs_loopback(params, vars);
14148                 break;
14149         default:
14150                 if (!CHIP_IS_E3(sc)) {
14151                         if (params->switch_cfg == ELINK_SWITCH_CFG_10G)
14152                                 elink_xgxs_deassert(params);
14153                         else
14154                                 elink_serdes_deassert(sc, params->port);
14155                 }
14156                 elink_link_initialize(params, vars);
14157                 DELAY(1000 * 30);
14158                 elink_link_int_enable(params);
14159                 break;
14160         }
14161         elink_update_mng(params, vars->link_status);
14162
14163         elink_update_mng_eee(params, vars->eee_status);
14164         return ELINK_STATUS_OK;
14165 }
14166
14167 elink_status_t elink_link_reset(struct elink_params *params,
14168                      struct elink_vars *vars,
14169                      uint8_t reset_ext_phy)
14170 {
14171         struct bnx2x_softc *sc = params->sc;
14172         uint8_t phy_index, port = params->port, clear_latch_ind = 0;
14173         ELINK_DEBUG_P1(sc, "Resetting the link of port %d", port);
14174         /* Disable attentions */
14175         vars->link_status = 0;
14176         elink_chng_link_count(params, 1);
14177         elink_update_mng(params, vars->link_status);
14178         vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
14179                               SHMEM_EEE_ACTIVE_BIT);
14180         elink_update_mng_eee(params, vars->eee_status);
14181         elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 + port * 4,
14182                        (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14183                         ELINK_NIG_MASK_XGXS0_LINK10G |
14184                         ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14185                         ELINK_NIG_MASK_MI_INT));
14186
14187         /* Activate nig drain */
14188         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + port * 4, 1);
14189
14190         /* Disable nig egress interface */
14191         if (!CHIP_IS_E3(sc)) {
14192                 REG_WR(sc, NIG_REG_BMAC0_OUT_EN + port * 4, 0);
14193                 REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port * 4, 0);
14194         }
14195
14196 #ifdef ELINK_INCLUDE_EMUL
14197         /* Stop BigMac rx */
14198         if (!(params->feature_config_flags &
14199               ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC))
14200 #endif
14201                 if (!CHIP_IS_E3(sc))
14202                         elink_set_bmac_rx(sc, params->chip_id, port, 0);
14203 #ifdef ELINK_INCLUDE_EMUL
14204         /* Stop XMAC/UMAC rx */
14205         if (!(params->feature_config_flags &
14206               ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC))
14207 #endif
14208                 if (CHIP_IS_E3(sc) &&
14209                 !CHIP_REV_IS_FPGA(sc)) {
14210                         elink_set_xmac_rxtx(params, 0);
14211                         elink_set_umac_rxtx(params, 0);
14212                 }
14213         /* Disable emac */
14214         if (!CHIP_IS_E3(sc))
14215                 REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port * 4, 0);
14216
14217         DELAY(1000 * 10);
14218         /* The PHY reset is controlled by GPIO 1
14219          * Hold it as vars low
14220          */
14221          /* Clear link led */
14222         elink_set_mdio_emac_per_phy(sc, params);
14223         elink_set_led(params, vars, ELINK_LED_MODE_OFF, 0);
14224
14225         if (reset_ext_phy && (!CHIP_REV_IS_SLOW(sc))) {
14226                 for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
14227                       phy_index++) {
14228                         if (params->phy[phy_index].link_reset) {
14229                                 elink_set_aer_mmd(params,
14230                                                   &params->phy[phy_index]);
14231                                 params->phy[phy_index].link_reset(
14232                                         &params->phy[phy_index],
14233                                         params);
14234                         }
14235                         if (params->phy[phy_index].flags &
14236                             ELINK_FLAGS_REARM_LATCH_SIGNAL)
14237                                 clear_latch_ind = 1;
14238                 }
14239         }
14240
14241         if (clear_latch_ind) {
14242                 /* Clear latching indication */
14243                 elink_rearm_latch_signal(sc, port, 0);
14244                 elink_bits_dis(sc, NIG_REG_LATCH_BC_0 + port * 4,
14245                                1 << ELINK_NIG_LATCH_BC_ENABLE_MI_INT);
14246         }
14247 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
14248         if (!CHIP_REV_IS_SLOW(sc))
14249 #endif
14250         if (params->phy[ELINK_INT_PHY].link_reset)
14251                 params->phy[ELINK_INT_PHY].link_reset(
14252                         &params->phy[ELINK_INT_PHY], params);
14253
14254         /* Disable nig ingress interface */
14255         if (!CHIP_IS_E3(sc)) {
14256                 /* Reset BigMac */
14257                 REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
14258                        (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
14259                 REG_WR(sc, NIG_REG_BMAC0_IN_EN + port * 4, 0);
14260                 REG_WR(sc, NIG_REG_EMAC0_IN_EN + port * 4, 0);
14261         } else {
14262                 uint32_t xmac_base = (params->port) ? GRCBASE_XMAC1 :
14263                                                       GRCBASE_XMAC0;
14264                 elink_set_xumac_nig(params, 0, 0);
14265                 if (REG_RD(sc, MISC_REG_RESET_REG_2) &
14266                     MISC_REGISTERS_RESET_REG_2_XMAC)
14267                         REG_WR(sc, xmac_base + XMAC_REG_CTRL,
14268                                XMAC_CTRL_REG_SOFT_RESET);
14269         }
14270         vars->link_up = 0;
14271         vars->phy_flags = 0;
14272         return ELINK_STATUS_OK;
14273 }
14274 elink_status_t elink_lfa_reset(struct elink_params *params,
14275                                struct elink_vars *vars)
14276 {
14277         struct bnx2x_softc *sc = params->sc;
14278         vars->link_up = 0;
14279         vars->phy_flags = 0;
14280         params->link_flags &= ~ELINK_PHY_INITIALIZED;
14281         if (!params->lfa_base)
14282                 return elink_link_reset(params, vars, 1);
14283         /*
14284          * Activate NIG drain so that during this time the device won't send
14285          * anything while it is unable to response.
14286          */
14287         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 1);
14288
14289         /*
14290          * Close gracefully the gate from BMAC to NIG such that no half packets
14291          * are passed.
14292          */
14293         if (!CHIP_IS_E3(sc))
14294                 elink_set_bmac_rx(sc, params->chip_id, params->port, 0);
14295
14296         if (CHIP_IS_E3(sc)) {
14297                 elink_set_xmac_rxtx(params, 0);
14298                 elink_set_umac_rxtx(params, 0);
14299         }
14300         /* Wait 10ms for the pipe to clean up*/
14301         DELAY(1000 * 10);
14302
14303         /* Clean the NIG-BRB using the network filters in a way that will
14304          * not cut a packet in the middle.
14305          */
14306         elink_set_rx_filter(params, 0);
14307
14308         /*
14309          * Re-open the gate between the BMAC and the NIG, after verifying the
14310          * gate to the BRB is closed, otherwise packets may arrive to the
14311          * firmware before driver had initialized it. The target is to achieve
14312          * minimum management protocol down time.
14313          */
14314         if (!CHIP_IS_E3(sc))
14315                 elink_set_bmac_rx(sc, params->chip_id, params->port, 1);
14316
14317         if (CHIP_IS_E3(sc)) {
14318                 elink_set_xmac_rxtx(params, 1);
14319                 elink_set_umac_rxtx(params, 1);
14320         }
14321         /* Disable NIG drain */
14322         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
14323         return ELINK_STATUS_OK;
14324 }
14325
14326 /****************************************************************************/
14327 /*                              Common function                             */
14328 /****************************************************************************/
14329 static elink_status_t elink_8073_common_init_phy(struct bnx2x_softc *sc,
14330                                       uint32_t shmem_base_path[],
14331                                       uint32_t shmem2_base_path[],
14332                                       uint8_t phy_index,
14333                                       __rte_unused uint32_t chip_id)
14334 {
14335         struct elink_phy phy[PORT_MAX];
14336         struct elink_phy *phy_blk[PORT_MAX];
14337         uint16_t val;
14338         int8_t port = 0;
14339         int8_t port_of_path = 0;
14340         uint32_t swap_val, swap_override;
14341         swap_val = REG_RD(sc,  NIG_REG_PORT_SWAP);
14342         swap_override = REG_RD(sc,  NIG_REG_STRAP_OVERRIDE);
14343         port ^= (swap_val && swap_override);
14344         elink_ext_phy_hw_reset(sc, port);
14345         /* PART1 - Reset both phys */
14346         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14347                 uint32_t shmem_base, shmem2_base;
14348                 /* In E2, same phy is using for port0 of the two paths */
14349                 if (CHIP_IS_E1x(sc)) {
14350                         shmem_base = shmem_base_path[0];
14351                         shmem2_base = shmem2_base_path[0];
14352                         port_of_path = port;
14353                 } else {
14354                         shmem_base = shmem_base_path[port];
14355                         shmem2_base = shmem2_base_path[port];
14356                         port_of_path = 0;
14357                 }
14358
14359                 /* Extract the ext phy address for the port */
14360                 if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
14361                                        port_of_path, &phy[port]) !=
14362                     ELINK_STATUS_OK) {
14363                         ELINK_DEBUG_P0(sc, "populate_phy failed");
14364                         return ELINK_STATUS_ERROR;
14365                 }
14366                 /* Disable attentions */
14367                 elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
14368                                port_of_path * 4,
14369                                (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14370                                 ELINK_NIG_MASK_XGXS0_LINK10G |
14371                                 ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14372                                 ELINK_NIG_MASK_MI_INT));
14373
14374                 /* Need to take the phy out of low power mode in order
14375                  * to write to access its registers
14376                  */
14377                 elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
14378                                MISC_REGISTERS_GPIO_OUTPUT_HIGH,
14379                                port);
14380
14381                 /* Reset the phy */
14382                 elink_cl45_write(sc, &phy[port],
14383                                  MDIO_PMA_DEVAD,
14384                                  MDIO_PMA_REG_CTRL,
14385                                  1 << 15);
14386         }
14387
14388         /* Add delay of 150ms after reset */
14389         DELAY(1000 * 150);
14390
14391         if (phy[PORT_0].addr & 0x1) {
14392                 phy_blk[PORT_0] = &(phy[PORT_1]);
14393                 phy_blk[PORT_1] = &(phy[PORT_0]);
14394         } else {
14395                 phy_blk[PORT_0] = &(phy[PORT_0]);
14396                 phy_blk[PORT_1] = &(phy[PORT_1]);
14397         }
14398
14399         /* PART2 - Download firmware to both phys */
14400         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14401                 if (CHIP_IS_E1x(sc))
14402                         port_of_path = port;
14403                 else
14404                         port_of_path = 0;
14405
14406                 ELINK_DEBUG_P1(sc, "Loading spirom for phy address 0x%x",
14407                            phy_blk[port]->addr);
14408                 if (elink_8073_8727_external_rom_boot(sc, phy_blk[port],
14409                                                       port_of_path))
14410                         return ELINK_STATUS_ERROR;
14411
14412                 /* Only set bit 10 = 1 (Tx power down) */
14413                 elink_cl45_read(sc, phy_blk[port],
14414                                 MDIO_PMA_DEVAD,
14415                                 MDIO_PMA_REG_TX_POWER_DOWN, &val);
14416
14417                 /* Phase1 of TX_POWER_DOWN reset */
14418                 elink_cl45_write(sc, phy_blk[port],
14419                                  MDIO_PMA_DEVAD,
14420                                  MDIO_PMA_REG_TX_POWER_DOWN,
14421                                  (val | 1 << 10));
14422         }
14423
14424         /* Toggle Transmitter: Power down and then up with 600ms delay
14425          * between
14426          */
14427         DELAY(1000 * 600);
14428
14429         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
14430         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14431                 /* Phase2 of POWER_DOWN_RESET */
14432                 /* Release bit 10 (Release Tx power down) */
14433                 elink_cl45_read(sc, phy_blk[port],
14434                                 MDIO_PMA_DEVAD,
14435                                 MDIO_PMA_REG_TX_POWER_DOWN, &val);
14436
14437                 elink_cl45_write(sc, phy_blk[port],
14438                                 MDIO_PMA_DEVAD,
14439                                 MDIO_PMA_REG_TX_POWER_DOWN,
14440                                 (val & (~(1 << 10))));
14441                 DELAY(1000 * 15);
14442
14443                 /* Read modify write the SPI-ROM version select register */
14444                 elink_cl45_read(sc, phy_blk[port],
14445                                 MDIO_PMA_DEVAD,
14446                                 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
14447                 elink_cl45_write(sc, phy_blk[port],
14448                                  MDIO_PMA_DEVAD,
14449                                  MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1 << 12)));
14450
14451                 /* set GPIO2 back to LOW */
14452                 elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
14453                                MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
14454         }
14455         return ELINK_STATUS_OK;
14456 }
14457 static elink_status_t elink_8726_common_init_phy(struct bnx2x_softc *sc,
14458                                       uint32_t shmem_base_path[],
14459                                       uint32_t shmem2_base_path[],
14460                                       uint8_t phy_index,
14461                                       __rte_unused uint32_t chip_id)
14462 {
14463         uint32_t val;
14464         int8_t port;
14465         struct elink_phy phy;
14466         /* Use port1 because of the static port-swap */
14467         /* Enable the module detection interrupt */
14468         val = REG_RD(sc, MISC_REG_GPIO_EVENT_EN);
14469         val |= ((1 << MISC_REGISTERS_GPIO_3) |
14470                 (1 << (MISC_REGISTERS_GPIO_3 +
14471                  MISC_REGISTERS_GPIO_PORT_SHIFT)));
14472         REG_WR(sc, MISC_REG_GPIO_EVENT_EN, val);
14473
14474         elink_ext_phy_hw_reset(sc, 0);
14475         DELAY(1000 * 5);
14476         for (port = 0; port < PORT_MAX; port++) {
14477                 uint32_t shmem_base, shmem2_base;
14478
14479                 /* In E2, same phy is using for port0 of the two paths */
14480                 if (CHIP_IS_E1x(sc)) {
14481                         shmem_base = shmem_base_path[0];
14482                         shmem2_base = shmem2_base_path[0];
14483                 } else {
14484                         shmem_base = shmem_base_path[port];
14485                         shmem2_base = shmem2_base_path[port];
14486                 }
14487                 /* Extract the ext phy address for the port */
14488                 if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
14489                                        port, &phy) !=
14490                     ELINK_STATUS_OK) {
14491                         ELINK_DEBUG_P0(sc, "populate phy failed");
14492                         return ELINK_STATUS_ERROR;
14493                 }
14494
14495                 /* Reset phy*/
14496                 elink_cl45_write(sc, &phy,
14497                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
14498
14499
14500                 /* Set fault module detected LED on */
14501                 elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_0,
14502                                MISC_REGISTERS_GPIO_HIGH,
14503                                port);
14504         }
14505
14506         return ELINK_STATUS_OK;
14507 }
14508 static void elink_get_ext_phy_reset_gpio(struct bnx2x_softc *sc,
14509                                          uint32_t shmem_base,
14510                                          uint8_t *io_gpio, uint8_t *io_port)
14511 {
14512
14513         uint32_t phy_gpio_reset = REG_RD(sc, shmem_base +
14514                                           offsetof(struct shmem_region,
14515                                 dev_info.port_hw_config[PORT_0].default_cfg));
14516         switch (phy_gpio_reset) {
14517         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0:
14518                 *io_gpio = 0;
14519                 *io_port = 0;
14520                 break;
14521         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0:
14522                 *io_gpio = 1;
14523                 *io_port = 0;
14524                 break;
14525         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0:
14526                 *io_gpio = 2;
14527                 *io_port = 0;
14528                 break;
14529         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0:
14530                 *io_gpio = 3;
14531                 *io_port = 0;
14532                 break;
14533         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1:
14534                 *io_gpio = 0;
14535                 *io_port = 1;
14536                 break;
14537         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1:
14538                 *io_gpio = 1;
14539                 *io_port = 1;
14540                 break;
14541         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1:
14542                 *io_gpio = 2;
14543                 *io_port = 1;
14544                 break;
14545         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1:
14546                 *io_gpio = 3;
14547                 *io_port = 1;
14548                 break;
14549         default:
14550                 /* Don't override the io_gpio and io_port */
14551                 break;
14552         }
14553 }
14554
14555 static elink_status_t elink_8727_common_init_phy(struct bnx2x_softc *sc,
14556                                       uint32_t shmem_base_path[],
14557                                       uint32_t shmem2_base_path[],
14558                                       uint8_t phy_index,
14559                                       __rte_unused uint32_t chip_id)
14560 {
14561         int8_t port, reset_gpio;
14562         uint32_t swap_val, swap_override;
14563         struct elink_phy phy[PORT_MAX];
14564         struct elink_phy *phy_blk[PORT_MAX];
14565         int8_t port_of_path;
14566         swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
14567         swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
14568
14569         reset_gpio = MISC_REGISTERS_GPIO_1;
14570         port = 1;
14571
14572         /* Retrieve the reset gpio/port which control the reset.
14573          * Default is GPIO1, PORT1
14574          */
14575         elink_get_ext_phy_reset_gpio(sc, shmem_base_path[0],
14576                                      (uint8_t *)&reset_gpio, (uint8_t *)&port);
14577
14578         /* Calculate the port based on port swap */
14579         port ^= (swap_val && swap_override);
14580
14581         /* Initiate PHY reset*/
14582         elink_cb_gpio_write(sc, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW,
14583                        port);
14584         DELAY(1000 * 1);
14585         elink_cb_gpio_write(sc, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH,
14586                        port);
14587
14588         DELAY(1000 * 5);
14589
14590         /* PART1 - Reset both phys */
14591         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14592                 uint32_t shmem_base, shmem2_base;
14593
14594                 /* In E2, same phy is using for port0 of the two paths */
14595                 if (CHIP_IS_E1x(sc)) {
14596                         shmem_base = shmem_base_path[0];
14597                         shmem2_base = shmem2_base_path[0];
14598                         port_of_path = port;
14599                 } else {
14600                         shmem_base = shmem_base_path[port];
14601                         shmem2_base = shmem2_base_path[port];
14602                         port_of_path = 0;
14603                 }
14604
14605                 /* Extract the ext phy address for the port */
14606                 if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
14607                                        port_of_path, &phy[port]) !=
14608                                        ELINK_STATUS_OK) {
14609                         ELINK_DEBUG_P0(sc, "populate phy failed");
14610                         return ELINK_STATUS_ERROR;
14611                 }
14612                 /* disable attentions */
14613                 elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
14614                                port_of_path * 4,
14615                                (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14616                                 ELINK_NIG_MASK_XGXS0_LINK10G |
14617                                 ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14618                                 ELINK_NIG_MASK_MI_INT));
14619
14620
14621                 /* Reset the phy */
14622                 elink_cl45_write(sc, &phy[port],
14623                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1 << 15);
14624         }
14625
14626         /* Add delay of 150ms after reset */
14627         DELAY(1000 * 150);
14628         if (phy[PORT_0].addr & 0x1) {
14629                 phy_blk[PORT_0] = &(phy[PORT_1]);
14630                 phy_blk[PORT_1] = &(phy[PORT_0]);
14631         } else {
14632                 phy_blk[PORT_0] = &(phy[PORT_0]);
14633                 phy_blk[PORT_1] = &(phy[PORT_1]);
14634         }
14635         /* PART2 - Download firmware to both phys */
14636         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14637                 if (CHIP_IS_E1x(sc))
14638                         port_of_path = port;
14639                 else
14640                         port_of_path = 0;
14641                 ELINK_DEBUG_P1(sc, "Loading spirom for phy address 0x%x",
14642                            phy_blk[port]->addr);
14643                 if (elink_8073_8727_external_rom_boot(sc, phy_blk[port],
14644                                                       port_of_path))
14645                         return ELINK_STATUS_ERROR;
14646                 /* Disable PHY transmitter output */
14647                 elink_cl45_write(sc, phy_blk[port],
14648                                  MDIO_PMA_DEVAD,
14649                                  MDIO_PMA_REG_TX_DISABLE, 1);
14650
14651         }
14652         return ELINK_STATUS_OK;
14653 }
14654
14655 static elink_status_t elink_84833_common_init_phy(struct bnx2x_softc *sc,
14656                                 uint32_t shmem_base_path[],
14657                                 __rte_unused uint32_t shmem2_base_path[],
14658                                 __rte_unused uint8_t phy_index,
14659                                 uint32_t chip_id)
14660 {
14661         uint8_t reset_gpios;
14662         reset_gpios = elink_84833_get_reset_gpios(sc, shmem_base_path, chip_id);
14663         elink_cb_gpio_mult_write(sc, reset_gpios,
14664                                  MISC_REGISTERS_GPIO_OUTPUT_LOW);
14665         DELAY(10);
14666         elink_cb_gpio_mult_write(sc, reset_gpios,
14667                                  MISC_REGISTERS_GPIO_OUTPUT_HIGH);
14668         ELINK_DEBUG_P1(sc, "84833 reset pulse on pin values 0x%x",
14669                 reset_gpios);
14670         return ELINK_STATUS_OK;
14671 }
14672 static elink_status_t elink_ext_phy_common_init(struct bnx2x_softc *sc,
14673                                      uint32_t shmem_base_path[],
14674                                      uint32_t shmem2_base_path[],
14675                                      uint8_t phy_index,
14676                                      uint32_t ext_phy_type, uint32_t chip_id)
14677 {
14678         elink_status_t rc = ELINK_STATUS_OK;
14679
14680         switch (ext_phy_type) {
14681         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8073:
14682                 rc = elink_8073_common_init_phy(sc, shmem_base_path,
14683                                                 shmem2_base_path,
14684                                                 phy_index, chip_id);
14685                 break;
14686         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8722:
14687         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727:
14688         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8727_NOC:
14689                 rc = elink_8727_common_init_phy(sc, shmem_base_path,
14690                                                 shmem2_base_path,
14691                                                 phy_index, chip_id);
14692                 break;
14693
14694         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726:
14695                 /* GPIO1 affects both ports, so there's need to pull
14696                  * it for single port alone
14697                  */
14698                 rc = elink_8726_common_init_phy(sc, shmem_base_path,
14699                                                 shmem2_base_path,
14700                                                 phy_index, chip_id);
14701                 break;
14702         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84833:
14703         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84834:
14704         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X84858:
14705                 /* GPIO3's are linked, and so both need to be toggled
14706                  * to obtain required 2us pulse.
14707                  */
14708                 rc = elink_84833_common_init_phy(sc, shmem_base_path,
14709                                                 shmem2_base_path,
14710                                                 phy_index, chip_id);
14711                 break;
14712         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
14713                 rc = ELINK_STATUS_ERROR;
14714                 break;
14715         default:
14716                 ELINK_DEBUG_P1(sc,
14717                            "ext_phy 0x%x common init not required",
14718                            ext_phy_type);
14719                 break;
14720         }
14721
14722         if (rc != ELINK_STATUS_OK)
14723                 elink_cb_event_log(sc, ELINK_LOG_ID_PHY_UNINITIALIZED, 0);
14724                                      /* "Warning: PHY was not initialized,"
14725                                       * " Port %d",
14726                                       */
14727
14728         return rc;
14729 }
14730
14731 elink_status_t elink_common_init_phy(struct bnx2x_softc *sc,
14732                           uint32_t shmem_base_path[],
14733                           uint32_t shmem2_base_path[], uint32_t chip_id,
14734                           __rte_unused uint8_t one_port_enabled)
14735 {
14736         elink_status_t rc = ELINK_STATUS_OK;
14737         uint32_t phy_ver, val;
14738         uint8_t phy_index = 0;
14739         uint32_t ext_phy_type, ext_phy_config;
14740 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
14741         if (CHIP_REV_IS_EMUL(sc) || CHIP_REV_IS_FPGA(sc))
14742                 return ELINK_STATUS_OK;
14743 #endif
14744
14745         elink_set_mdio_clk(sc, chip_id, GRCBASE_EMAC0);
14746         elink_set_mdio_clk(sc, chip_id, GRCBASE_EMAC1);
14747         ELINK_DEBUG_P0(sc, "Begin common phy init");
14748         if (CHIP_IS_E3(sc)) {
14749                 /* Enable EPIO */
14750                 val = REG_RD(sc, MISC_REG_GEN_PURP_HWG);
14751                 REG_WR(sc, MISC_REG_GEN_PURP_HWG, val | 1);
14752         }
14753         /* Check if common init was already done */
14754         phy_ver = REG_RD(sc, shmem_base_path[0] +
14755                          offsetof(struct shmem_region,
14756                                   port_mb[PORT_0].ext_phy_fw_version));
14757         if (phy_ver) {
14758                 ELINK_DEBUG_P1(sc, "Not doing common init; phy ver is 0x%x",
14759                                phy_ver);
14760                 return ELINK_STATUS_OK;
14761         }
14762
14763         /* Read the ext_phy_type for arbitrary port(0) */
14764         for (phy_index = ELINK_EXT_PHY1; phy_index < ELINK_MAX_PHYS;
14765               phy_index++) {
14766                 ext_phy_config = elink_get_ext_phy_config(sc,
14767                                                           shmem_base_path[0],
14768                                                           phy_index, 0);
14769                 ext_phy_type = ELINK_XGXS_EXT_PHY_TYPE(ext_phy_config);
14770                 rc |= elink_ext_phy_common_init(sc, shmem_base_path,
14771                                                 shmem2_base_path,
14772                                                 phy_index, ext_phy_type,
14773                                                 chip_id);
14774         }
14775         return rc;
14776 }
14777
14778 static void elink_check_over_curr(struct elink_params *params,
14779                                   struct elink_vars *vars)
14780 {
14781         struct bnx2x_softc *sc = params->sc;
14782         uint32_t cfg_pin;
14783         uint8_t port = params->port;
14784         uint32_t pin_val;
14785
14786         cfg_pin = (REG_RD(sc, params->shmem_base +
14787                           offsetof(struct shmem_region,
14788                                dev_info.port_hw_config[port].e3_cmn_pin_cfg1)) &
14789                    PORT_HW_CFG_E3_OVER_CURRENT_MASK) >>
14790                 PORT_HW_CFG_E3_OVER_CURRENT_SHIFT;
14791
14792         /* Ignore check if no external input PIN available */
14793         if (elink_get_cfg_pin(sc, cfg_pin, &pin_val) != ELINK_STATUS_OK)
14794                 return;
14795
14796         if (!pin_val) {
14797                 if ((vars->phy_flags & PHY_OVER_CURRENT_FLAG) == 0) {
14798                         elink_cb_event_log(sc, ELINK_LOG_ID_OVER_CURRENT,
14799                                            params->port);
14800                                         /* "Error:  Power fault on Port %d has"
14801                                          *  " been detected and the power to "
14802                                          *  "that SFP+ module has been removed"
14803                                          *  " to prevent failure of the card."
14804                                          *  " Please remove the SFP+ module and"
14805                                          *  " restart the system to clear this"
14806                                          *  " error.",
14807                                          */
14808                         vars->phy_flags |= PHY_OVER_CURRENT_FLAG;
14809                         elink_warpcore_power_module(params, 0);
14810                 }
14811         } else
14812                 vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG;
14813 }
14814
14815 /* Returns 0 if no change occurred since last check; 1 otherwise. */
14816 static uint8_t elink_analyze_link_error(struct elink_params *params,
14817                                     struct elink_vars *vars, uint32_t status,
14818                                     uint32_t phy_flag, uint32_t link_flag,
14819                                     uint8_t notify)
14820 {
14821         struct bnx2x_softc *sc = params->sc;
14822         /* Compare new value with previous value */
14823         uint8_t led_mode;
14824         uint32_t old_status = (vars->phy_flags & phy_flag) ? 1 : 0;
14825
14826         if ((status ^ old_status) == 0)
14827                 return 0;
14828
14829         /* If values differ */
14830         switch (phy_flag) {
14831         case PHY_HALF_OPEN_CONN_FLAG:
14832                 ELINK_DEBUG_P0(sc, "Analyze Remote Fault");
14833                 break;
14834         case PHY_SFP_TX_FAULT_FLAG:
14835                 ELINK_DEBUG_P0(sc, "Analyze TX Fault");
14836                 break;
14837         default:
14838                 ELINK_DEBUG_P0(sc, "Analyze UNKNOWN");
14839         }
14840         ELINK_DEBUG_P3(sc, "Link changed:[%x %x]->%x", vars->link_up,
14841            old_status, status);
14842
14843         /* Do not touch the link in case physical link down */
14844         if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0)
14845                 return 1;
14846
14847         /* a. Update shmem->link_status accordingly
14848          * b. Update elink_vars->link_up
14849          */
14850         if (status) {
14851                 vars->link_status &= ~LINK_STATUS_LINK_UP;
14852                 vars->link_status |= link_flag;
14853                 vars->link_up = 0;
14854                 vars->phy_flags |= phy_flag;
14855
14856                 /* activate nig drain */
14857                 REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 1);
14858                 /* Set LED mode to off since the PHY doesn't know about these
14859                  * errors
14860                  */
14861                 led_mode = ELINK_LED_MODE_OFF;
14862         } else {
14863                 vars->link_status |= LINK_STATUS_LINK_UP;
14864                 vars->link_status &= ~link_flag;
14865                 vars->link_up = 1;
14866                 vars->phy_flags &= ~phy_flag;
14867                 led_mode = ELINK_LED_MODE_OPER;
14868
14869                 /* Clear nig drain */
14870                 REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
14871         }
14872         elink_sync_link(params, vars);
14873         /* Update the LED according to the link state */
14874         elink_set_led(params, vars, led_mode, ELINK_SPEED_10000);
14875
14876         /* Update link status in the shared memory */
14877         elink_update_mng(params, vars->link_status);
14878
14879         /* C. Trigger General Attention */
14880         vars->periodic_flags |= ELINK_PERIODIC_FLAGS_LINK_EVENT;
14881         if (notify)
14882                 elink_cb_notify_link_changed(sc);
14883
14884         return 1;
14885 }
14886
14887 /******************************************************************************
14888  * Description:
14889  *      This function checks for half opened connection change indication.
14890  *      When such change occurs, it calls the elink_analyze_link_error
14891  *      to check if Remote Fault is set or cleared. Reception of remote fault
14892  *      status message in the MAC indicates that the peer's MAC has detected
14893  *      a fault, for example, due to break in the TX side of fiber.
14894  *
14895  ******************************************************************************/
14896 static
14897 elink_status_t elink_check_half_open_conn(struct elink_params *params,
14898                                 struct elink_vars *vars,
14899                                 uint8_t notify)
14900 {
14901         struct bnx2x_softc *sc = params->sc;
14902         uint32_t lss_status = 0;
14903         uint32_t mac_base;
14904         /* In case link status is physically up @ 10G do */
14905         if (((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0) ||
14906             (REG_RD(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port * 4)))
14907                 return ELINK_STATUS_OK;
14908
14909         if (CHIP_IS_E3(sc) &&
14910             (REG_RD(sc, MISC_REG_RESET_REG_2) &
14911               (MISC_REGISTERS_RESET_REG_2_XMAC))) {
14912                 /* Check E3 XMAC */
14913                 /* Note that link speed cannot be queried here, since it may be
14914                  * zero while link is down. In case UMAC is active, LSS will
14915                  * simply not be set
14916                  */
14917                 mac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
14918
14919                 /* Clear stick bits (Requires rising edge) */
14920                 REG_WR(sc, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
14921                 REG_WR(sc, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
14922                        XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
14923                        XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
14924                 if (REG_RD(sc, mac_base + XMAC_REG_RX_LSS_STATUS))
14925                         lss_status = 1;
14926
14927                 elink_analyze_link_error(params, vars, lss_status,
14928                                          PHY_HALF_OPEN_CONN_FLAG,
14929                                          LINK_STATUS_NONE, notify);
14930         } else if (REG_RD(sc, MISC_REG_RESET_REG_2) &
14931                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) {
14932                 /* Check E1X / E2 BMAC */
14933                 uint32_t lss_status_reg;
14934                 uint32_t wb_data[2];
14935                 mac_base = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
14936                         NIG_REG_INGRESS_BMAC0_MEM;
14937                 /*  Read BIGMAC_REGISTER_RX_LSS_STATUS */
14938                 if (CHIP_IS_E2(sc))
14939                         lss_status_reg = BIGMAC2_REGISTER_RX_LSS_STAT;
14940                 else
14941                         lss_status_reg = BIGMAC_REGISTER_RX_LSS_STATUS;
14942
14943                 REG_RD_DMAE(sc, mac_base + lss_status_reg, wb_data, 2);
14944                 lss_status = (wb_data[0] > 0);
14945
14946                 elink_analyze_link_error(params, vars, lss_status,
14947                                          PHY_HALF_OPEN_CONN_FLAG,
14948                                          LINK_STATUS_NONE, notify);
14949         }
14950         return ELINK_STATUS_OK;
14951 }
14952 static void elink_sfp_tx_fault_detection(struct elink_phy *phy,
14953                                          struct elink_params *params,
14954                                          struct elink_vars *vars)
14955 {
14956         struct bnx2x_softc *sc = params->sc;
14957         uint32_t cfg_pin, value = 0;
14958         uint8_t led_change, port = params->port;
14959
14960         /* Get The SFP+ TX_Fault controlling pin ([eg]pio) */
14961         cfg_pin = (REG_RD(sc, params->shmem_base + offsetof(struct shmem_region,
14962                           dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
14963                    PORT_HW_CFG_E3_TX_FAULT_MASK) >>
14964                   PORT_HW_CFG_E3_TX_FAULT_SHIFT;
14965
14966         if (elink_get_cfg_pin(sc, cfg_pin, &value)) {
14967                 ELINK_DEBUG_P1(sc, "Failed to read pin 0x%02x", cfg_pin);
14968                 return;
14969         }
14970
14971         led_change = elink_analyze_link_error(params, vars, value,
14972                                               PHY_SFP_TX_FAULT_FLAG,
14973                                               LINK_STATUS_SFP_TX_FAULT, 1);
14974
14975         if (led_change) {
14976                 /* Change TX_Fault led, set link status for further syncs */
14977                 uint8_t led_mode;
14978
14979                 if (vars->phy_flags & PHY_SFP_TX_FAULT_FLAG) {
14980                         led_mode = MISC_REGISTERS_GPIO_HIGH;
14981                         vars->link_status |= LINK_STATUS_SFP_TX_FAULT;
14982                 } else {
14983                         led_mode = MISC_REGISTERS_GPIO_LOW;
14984                         vars->link_status &= ~LINK_STATUS_SFP_TX_FAULT;
14985                 }
14986
14987                 /* If module is unapproved, led should be on regardless */
14988                 if (!(phy->flags & ELINK_FLAGS_SFP_NOT_APPROVED)) {
14989                         ELINK_DEBUG_P1(sc, "Change TX_Fault LED: ->%x",
14990                            led_mode);
14991                         elink_set_e3_module_fault_led(params, led_mode);
14992                 }
14993         }
14994 }
14995 static void elink_kr2_recovery(struct elink_params *params,
14996                                struct elink_vars *vars,
14997                                struct elink_phy *phy)
14998 {
14999         struct bnx2x_softc *sc = params->sc;
15000         ELINK_DEBUG_P0(sc, "KR2 recovery");
15001         elink_warpcore_enable_AN_KR2(phy, params, vars);
15002         elink_warpcore_restart_AN_KR(phy, params);
15003 }
15004
15005 static void elink_check_kr2_wa(struct elink_params *params,
15006                                struct elink_vars *vars,
15007                                struct elink_phy *phy)
15008 {
15009         struct bnx2x_softc *sc = params->sc;
15010         uint16_t base_page, next_page, not_kr2_device, lane;
15011         int sigdet;
15012
15013         /* Once KR2 was disabled, wait 5 seconds before checking KR2 recovery
15014          * Since some switches tend to reinit the AN process and clear the
15015          * the advertised BP/NP after ~2 seconds causing the KR2 to be disabled
15016          * and recovered many times
15017          */
15018         if (vars->check_kr2_recovery_cnt > 0) {
15019                 vars->check_kr2_recovery_cnt--;
15020                 return;
15021         }
15022
15023         sigdet = elink_warpcore_get_sigdet(phy, params);
15024         if (!sigdet) {
15025                 if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
15026                         elink_kr2_recovery(params, vars, phy);
15027                         ELINK_DEBUG_P0(sc, "No sigdet");
15028                 }
15029                 return;
15030         }
15031
15032         lane = elink_get_warpcore_lane(phy, params);
15033         CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
15034                           MDIO_AER_BLOCK_AER_REG, lane);
15035         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
15036                         MDIO_AN_REG_LP_AUTO_NEG, &base_page);
15037         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
15038                         MDIO_AN_REG_LP_AUTO_NEG2, &next_page);
15039         elink_set_aer_mmd(params, phy);
15040
15041         /* CL73 has not begun yet */
15042         if (base_page == 0) {
15043                 if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
15044                         elink_kr2_recovery(params, vars, phy);
15045                         ELINK_DEBUG_P0(sc, "No BP");
15046                 }
15047                 return;
15048         }
15049
15050         /* In case NP bit is not set in the BasePage, or it is set,
15051          * but only KX is advertised, declare this link partner as non-KR2
15052          * device.
15053          */
15054         not_kr2_device = (((base_page & 0x8000) == 0) ||
15055                           (((base_page & 0x8000) &&
15056                             ((next_page & 0xe0) == 0x20))));
15057
15058         /* In case KR2 is already disabled, check if we need to re-enable it */
15059         if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
15060                 if (!not_kr2_device) {
15061                         ELINK_DEBUG_P2(sc, "BP=0x%x, NP=0x%x", base_page,
15062                            next_page);
15063                         elink_kr2_recovery(params, vars, phy);
15064                 }
15065                 return;
15066         }
15067         /* KR2 is enabled, but not KR2 device */
15068         if (not_kr2_device) {
15069                 /* Disable KR2 on both lanes */
15070                 ELINK_DEBUG_P2(sc, "BP=0x%x, NP=0x%x", base_page, next_page);
15071                 elink_disable_kr2(params, vars, phy);
15072                 /* Restart AN on leading lane */
15073                 elink_warpcore_restart_AN_KR(phy, params);
15074                 return;
15075         }
15076 }
15077
15078 void elink_period_func(struct elink_params *params, struct elink_vars *vars)
15079 {
15080         uint16_t phy_idx;
15081         struct bnx2x_softc *sc = params->sc;
15082         for (phy_idx = ELINK_INT_PHY; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
15083                 if (params->phy[phy_idx].flags & ELINK_FLAGS_TX_ERROR_CHECK) {
15084                         elink_set_aer_mmd(params, &params->phy[phy_idx]);
15085                         if (elink_check_half_open_conn(params, vars, 1) !=
15086                             ELINK_STATUS_OK)
15087                                 ELINK_DEBUG_P0(sc, "Fault detection failed");
15088                         break;
15089                 }
15090         }
15091
15092         if (CHIP_IS_E3(sc)) {
15093                 struct elink_phy *phy = &params->phy[ELINK_INT_PHY];
15094                 elink_set_aer_mmd(params, phy);
15095                 if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
15096                      (phy->speed_cap_mask &
15097                       PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)) ||
15098                     (phy->req_line_speed == ELINK_SPEED_20000))
15099                         elink_check_kr2_wa(params, vars, phy);
15100                 elink_check_over_curr(params, vars);
15101                 if (vars->rx_tx_asic_rst)
15102                         elink_warpcore_config_runtime(phy, params, vars);
15103
15104                 if ((REG_RD(sc, params->shmem_base +
15105                             offsetof(struct shmem_region, dev_info.
15106                                 port_hw_config[params->port].default_cfg))
15107                     & PORT_HW_CFG_NET_SERDES_IF_MASK) ==
15108                     PORT_HW_CFG_NET_SERDES_IF_SFI) {
15109                         if (elink_is_sfp_module_plugged(phy, params)) {
15110                                 elink_sfp_tx_fault_detection(phy, params, vars);
15111                         } else if (vars->link_status &
15112                                 LINK_STATUS_SFP_TX_FAULT) {
15113                                 /* Clean trail, interrupt corrects the leds */
15114                                 vars->link_status &= ~LINK_STATUS_SFP_TX_FAULT;
15115                                 vars->phy_flags &= ~PHY_SFP_TX_FAULT_FLAG;
15116                                 /* Update link status in the shared memory */
15117                                 elink_update_mng(params, vars->link_status);
15118                         }
15119                 }
15120         }
15121 }
15122
15123 uint8_t elink_fan_failure_det_req(struct bnx2x_softc *sc,
15124                              uint32_t shmem_base,
15125                              uint32_t shmem2_base,
15126                              uint8_t port)
15127 {
15128         uint8_t phy_index, fan_failure_det_req = 0;
15129         struct elink_phy phy;
15130         for (phy_index = ELINK_EXT_PHY1; phy_index < ELINK_MAX_PHYS;
15131               phy_index++) {
15132                 if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
15133                                        port, &phy)
15134                     != ELINK_STATUS_OK) {
15135                         ELINK_DEBUG_P0(sc, "populate phy failed");
15136                         return 0;
15137                 }
15138                 fan_failure_det_req |= (phy.flags &
15139                                         ELINK_FLAGS_FAN_FAILURE_DET_REQ);
15140         }
15141         return fan_failure_det_req;
15142 }
15143
15144 void elink_hw_reset_phy(struct elink_params *params)
15145 {
15146         uint8_t phy_index;
15147         struct bnx2x_softc *sc = params->sc;
15148         elink_update_mng(params, 0);
15149         elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 + params->port * 4,
15150                        (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
15151                         ELINK_NIG_MASK_XGXS0_LINK10G |
15152                         ELINK_NIG_MASK_SERDES0_LINK_STATUS |
15153                         ELINK_NIG_MASK_MI_INT));
15154
15155         for (phy_index = ELINK_INT_PHY; phy_index < ELINK_MAX_PHYS;
15156               phy_index++) {
15157                 if (params->phy[phy_index].hw_reset) {
15158                         params->phy[phy_index].hw_reset(
15159                                 &params->phy[phy_index],
15160                                 params);
15161                         params->phy[phy_index] = phy_null;
15162                 }
15163         }
15164 }
15165
15166 void elink_init_mod_abs_int(struct bnx2x_softc *sc, struct elink_vars *vars,
15167                             uint32_t chip_id, uint32_t shmem_base,
15168                             uint32_t shmem2_base,
15169                             uint8_t port)
15170 {
15171         uint8_t gpio_num = 0xff, gpio_port = 0xff, phy_index;
15172         uint32_t val;
15173         uint32_t offset, aeu_mask, swap_val, swap_override, sync_offset;
15174         if (CHIP_IS_E3(sc)) {
15175                 if (elink_get_mod_abs_int_cfg(sc, chip_id,
15176                                               shmem_base,
15177                                               port,
15178                                               &gpio_num,
15179                                               &gpio_port) != ELINK_STATUS_OK)
15180                         return;
15181         } else {
15182                 struct elink_phy phy;
15183                 for (phy_index = ELINK_EXT_PHY1; phy_index < ELINK_MAX_PHYS;
15184                       phy_index++) {
15185                         if (elink_populate_phy(sc, phy_index, shmem_base,
15186                                                shmem2_base, port, &phy)
15187                             != ELINK_STATUS_OK) {
15188                                 ELINK_DEBUG_P0(sc, "populate phy failed");
15189                                 return;
15190                         }
15191                         if (phy.type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BNX2X8726) {
15192                                 gpio_num = MISC_REGISTERS_GPIO_3;
15193                                 gpio_port = port;
15194                                 break;
15195                         }
15196                 }
15197         }
15198
15199         if (gpio_num == 0xff)
15200                 return;
15201
15202         /* Set GPIO3 to trigger SFP+ module insertion/removal */
15203         elink_cb_gpio_write(sc, gpio_num, MISC_REGISTERS_GPIO_INPUT_HI_Z,
15204                             gpio_port);
15205
15206         swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
15207         swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
15208         gpio_port ^= (swap_val && swap_override);
15209
15210         vars->aeu_int_mask = AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 <<
15211                 (gpio_num + (gpio_port << 2));
15212
15213         sync_offset = shmem_base +
15214                 offsetof(struct shmem_region,
15215                          dev_info.port_hw_config[port].aeu_int_mask);
15216         REG_WR(sc, sync_offset, vars->aeu_int_mask);
15217
15218         ELINK_DEBUG_P3(sc, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x",
15219                        gpio_num, gpio_port, vars->aeu_int_mask);
15220
15221         if (port == 0)
15222                 offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
15223         else
15224                 offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
15225
15226         /* Open appropriate AEU for interrupts */
15227         aeu_mask = REG_RD(sc, offset);
15228         aeu_mask |= vars->aeu_int_mask;
15229         REG_WR(sc, offset, aeu_mask);
15230
15231         /* Enable the GPIO to trigger interrupt */
15232         val = REG_RD(sc, MISC_REG_GPIO_EVENT_EN);
15233         val |= 1 << (gpio_num + (gpio_port << 2));
15234         REG_WR(sc, MISC_REG_GPIO_EVENT_EN, val);
15235 }