]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/bxe/bxe_elink.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / bxe / bxe_elink.c
1 /*-
2  * Copyright (c) 2007-2013 Broadcom Corporation. All rights reserved.
3  *
4  * Eric Davis        <edavis@broadcom.com>
5  * David Christensen <davidch@broadcom.com>
6  * Gary Zambrano     <zambrano@broadcom.com>
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of Broadcom Corporation nor the name of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written consent.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31  * THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 #include "bxe.h"
38 #include "bxe_elink.h"
39 #include "ecore_mfw_req.h"
40 #include "ecore_fw_defs.h"
41 #include "ecore_hsi.h"
42 #include "ecore_reg.h"
43
44
45 #define MDIO_REG_BANK_CL73_IEEEB0                       0x0
46         #define MDIO_CL73_IEEEB0_CL73_AN_CONTROL                0x0
47                 #define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN     0x0200
48                 #define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN          0x1000
49                 #define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_MAIN_RST       0x8000
50
51 #define MDIO_REG_BANK_CL73_IEEEB1                       0x10
52         #define MDIO_CL73_IEEEB1_AN_ADV1                        0x00
53                 #define MDIO_CL73_IEEEB1_AN_ADV1_PAUSE                  0x0400
54                 #define MDIO_CL73_IEEEB1_AN_ADV1_ASYMMETRIC             0x0800
55                 #define MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH             0x0C00
56                 #define MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK             0x0C00
57         #define MDIO_CL73_IEEEB1_AN_ADV2                                0x01
58                 #define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M             0x0000
59                 #define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX          0x0020
60                 #define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4           0x0040
61                 #define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR            0x0080
62         #define MDIO_CL73_IEEEB1_AN_LP_ADV1                     0x03
63                 #define MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE               0x0400
64                 #define MDIO_CL73_IEEEB1_AN_LP_ADV1_ASYMMETRIC          0x0800
65                 #define MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_BOTH          0x0C00
66                 #define MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK          0x0C00
67         #define MDIO_CL73_IEEEB1_AN_LP_ADV2                     0x04
68
69 #define MDIO_REG_BANK_RX0                               0x80b0
70         #define MDIO_RX0_RX_STATUS                              0x10
71                 #define MDIO_RX0_RX_STATUS_SIGDET                       0x8000
72                 #define MDIO_RX0_RX_STATUS_RX_SEQ_DONE                  0x1000
73         #define MDIO_RX0_RX_EQ_BOOST                            0x1c
74                 #define MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK        0x7
75                 #define MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL                0x10
76
77 #define MDIO_REG_BANK_RX1                               0x80c0
78         #define MDIO_RX1_RX_EQ_BOOST                            0x1c
79                 #define MDIO_RX1_RX_EQ_BOOST_EQUALIZER_CTRL_MASK        0x7
80                 #define MDIO_RX1_RX_EQ_BOOST_OFFSET_CTRL                0x10
81
82 #define MDIO_REG_BANK_RX2                               0x80d0
83         #define MDIO_RX2_RX_EQ_BOOST                            0x1c
84                 #define MDIO_RX2_RX_EQ_BOOST_EQUALIZER_CTRL_MASK        0x7
85                 #define MDIO_RX2_RX_EQ_BOOST_OFFSET_CTRL                0x10
86
87 #define MDIO_REG_BANK_RX3                               0x80e0
88         #define MDIO_RX3_RX_EQ_BOOST                            0x1c
89                 #define MDIO_RX3_RX_EQ_BOOST_EQUALIZER_CTRL_MASK        0x7
90                 #define MDIO_RX3_RX_EQ_BOOST_OFFSET_CTRL                0x10
91
92 #define MDIO_REG_BANK_RX_ALL                            0x80f0
93         #define MDIO_RX_ALL_RX_EQ_BOOST                         0x1c
94                 #define MDIO_RX_ALL_RX_EQ_BOOST_EQUALIZER_CTRL_MASK     0x7
95                 #define MDIO_RX_ALL_RX_EQ_BOOST_OFFSET_CTRL     0x10
96
97 #define MDIO_REG_BANK_TX0                               0x8060
98         #define MDIO_TX0_TX_DRIVER                              0x17
99                 #define MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK             0xf000
100                 #define MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT            12
101                 #define MDIO_TX0_TX_DRIVER_IDRIVER_MASK                 0x0f00
102                 #define MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT                8
103                 #define MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK              0x00f0
104                 #define MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT             4
105                 #define MDIO_TX0_TX_DRIVER_IFULLSPD_MASK                0x000e
106                 #define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT               1
107                 #define MDIO_TX0_TX_DRIVER_ICBUF1T                      1
108
109 #define MDIO_REG_BANK_TX1                               0x8070
110         #define MDIO_TX1_TX_DRIVER                              0x17
111                 #define MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK             0xf000
112                 #define MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT            12
113                 #define MDIO_TX0_TX_DRIVER_IDRIVER_MASK                 0x0f00
114                 #define MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT                8
115                 #define MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK              0x00f0
116                 #define MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT             4
117                 #define MDIO_TX0_TX_DRIVER_IFULLSPD_MASK                0x000e
118                 #define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT               1
119                 #define MDIO_TX0_TX_DRIVER_ICBUF1T                      1
120
121 #define MDIO_REG_BANK_TX2                               0x8080
122         #define MDIO_TX2_TX_DRIVER                              0x17
123                 #define MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK             0xf000
124                 #define MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT            12
125                 #define MDIO_TX0_TX_DRIVER_IDRIVER_MASK                 0x0f00
126                 #define MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT                8
127                 #define MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK              0x00f0
128                 #define MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT             4
129                 #define MDIO_TX0_TX_DRIVER_IFULLSPD_MASK                0x000e
130                 #define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT               1
131                 #define MDIO_TX0_TX_DRIVER_ICBUF1T                      1
132
133 #define MDIO_REG_BANK_TX3                               0x8090
134         #define MDIO_TX3_TX_DRIVER                              0x17
135                 #define MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK             0xf000
136                 #define MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT            12
137                 #define MDIO_TX0_TX_DRIVER_IDRIVER_MASK                 0x0f00
138                 #define MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT                8
139                 #define MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK              0x00f0
140                 #define MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT             4
141                 #define MDIO_TX0_TX_DRIVER_IFULLSPD_MASK                0x000e
142                 #define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT               1
143                 #define MDIO_TX0_TX_DRIVER_ICBUF1T                      1
144
145 #define MDIO_REG_BANK_XGXS_BLOCK0                       0x8000
146         #define MDIO_BLOCK0_XGXS_CONTROL                        0x10
147
148 #define MDIO_REG_BANK_XGXS_BLOCK1                       0x8010
149         #define MDIO_BLOCK1_LANE_CTRL0                          0x15
150         #define MDIO_BLOCK1_LANE_CTRL1                          0x16
151         #define MDIO_BLOCK1_LANE_CTRL2                          0x17
152         #define MDIO_BLOCK1_LANE_PRBS                           0x19
153
154 #define MDIO_REG_BANK_XGXS_BLOCK2                       0x8100
155         #define MDIO_XGXS_BLOCK2_RX_LN_SWAP                     0x10
156                 #define MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE              0x8000
157                 #define MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE        0x4000
158                 #define MDIO_XGXS_BLOCK2_TX_LN_SWAP             0x11
159                 #define MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE              0x8000
160                 #define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G       0x14
161                 #define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS      0x0001
162                 #define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS    0x0010
163                 #define MDIO_XGXS_BLOCK2_TEST_MODE_LANE         0x15
164
165 #define MDIO_REG_BANK_GP_STATUS                         0x8120
166 #define MDIO_GP_STATUS_TOP_AN_STATUS1                           0x1B
167         #define MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE     0x0001
168         #define MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE     0x0002
169         #define MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS               0x0004
170         #define MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS             0x0008
171         #define MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE     0x0010
172         #define MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_LP_NP_BAM_ABLE       0x0020
173         #define MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE    0x0040
174         #define MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE    0x0080
175         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK         0x3f00
176         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M          0x0000
177         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M         0x0100
178         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G           0x0200
179         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G         0x0300
180         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G           0x0400
181         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G           0x0500
182         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG      0x0600
183         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4      0x0700
184         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG      0x0800
185         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G        0x0900
186         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G          0x0A00
187         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G          0x0B00
188         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G          0x0C00
189         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX        0x0D00
190         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4      0x0E00
191         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR       0x0F00
192         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI      0x1B00
193         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS    0x1E00
194         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI      0x1F00
195         #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_KR2      0x3900
196
197
198 #define MDIO_REG_BANK_10G_PARALLEL_DETECT               0x8130
199 #define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS             0x10
200 #define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK             0x8000
201 #define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL            0x11
202 #define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN       0x1
203 #define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK               0x13
204 #define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT           (0xb71<<1)
205
206 #define MDIO_REG_BANK_SERDES_DIGITAL                    0x8300
207 #define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1                    0x10
208 #define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE                 0x0001
209 #define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_TBI_IF                     0x0002
210 #define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN           0x0004
211 #define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT       0x0008
212 #define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET                    0x0010
213 #define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE                  0x0020
214 #define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2                    0x11
215 #define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN                  0x0001
216 #define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_AN_FST_TMR                 0x0040
217 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1                     0x14
218 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SGMII                       0x0001
219 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_LINK                        0x0002
220 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_DUPLEX                      0x0004
221 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_MASK                  0x0018
222 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_SHIFT                 3
223 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_2_5G                  0x0018
224 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_1G                    0x0010
225 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_100M                  0x0008
226 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_10M                   0x0000
227 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS2                     0x15
228 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED                 0x0002
229 #define MDIO_SERDES_DIGITAL_MISC1                               0x18
230 #define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_MASK                       0xE000
231 #define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_25M                        0x0000
232 #define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_100M                       0x2000
233 #define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_125M                       0x4000
234 #define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M                    0x6000
235 #define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_187_5M                     0x8000
236 #define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL                       0x0010
237 #define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK                      0x000f
238 #define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_2_5G                      0x0000
239 #define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_5G                        0x0001
240 #define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_6G                        0x0002
241 #define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_HIG                   0x0003
242 #define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4                   0x0004
243 #define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_12G                       0x0005
244 #define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_12_5G                     0x0006
245 #define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G                       0x0007
246 #define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_15G                       0x0008
247 #define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_16G                       0x0009
248
249 #define MDIO_REG_BANK_OVER_1G                           0x8320
250 #define MDIO_OVER_1G_DIGCTL_3_4                                 0x14
251 #define MDIO_OVER_1G_DIGCTL_3_4_MP_ID_MASK                              0xffe0
252 #define MDIO_OVER_1G_DIGCTL_3_4_MP_ID_SHIFT                             5
253 #define MDIO_OVER_1G_UP1                                        0x19
254 #define MDIO_OVER_1G_UP1_2_5G                                           0x0001
255 #define MDIO_OVER_1G_UP1_5G                                             0x0002
256 #define MDIO_OVER_1G_UP1_6G                                             0x0004
257 #define MDIO_OVER_1G_UP1_10G                                            0x0010
258 #define MDIO_OVER_1G_UP1_10GH                                           0x0008
259 #define MDIO_OVER_1G_UP1_12G                                            0x0020
260 #define MDIO_OVER_1G_UP1_12_5G                                          0x0040
261 #define MDIO_OVER_1G_UP1_13G                                            0x0080
262 #define MDIO_OVER_1G_UP1_15G                                            0x0100
263 #define MDIO_OVER_1G_UP1_16G                                            0x0200
264 #define MDIO_OVER_1G_UP2                                        0x1A
265 #define MDIO_OVER_1G_UP2_IPREDRIVER_MASK                                0x0007
266 #define MDIO_OVER_1G_UP2_IDRIVER_MASK                                   0x0038
267 #define MDIO_OVER_1G_UP2_PREEMPHASIS_MASK                               0x03C0
268 #define MDIO_OVER_1G_UP3                                        0x1B
269 #define MDIO_OVER_1G_UP3_HIGIG2                                         0x0001
270 #define MDIO_OVER_1G_LP_UP1                                     0x1C
271 #define MDIO_OVER_1G_LP_UP2                                     0x1D
272 #define MDIO_OVER_1G_LP_UP2_MR_ADV_OVER_1G_MASK                         0x03ff
273 #define MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK                            0x0780
274 #define MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT                           7
275 #define MDIO_OVER_1G_LP_UP3                                             0x1E
276
277 #define MDIO_REG_BANK_REMOTE_PHY                        0x8330
278 #define MDIO_REMOTE_PHY_MISC_RX_STATUS                          0x10
279 #define MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG     0x0010
280 #define MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG   0x0600
281
282 #define MDIO_REG_BANK_BAM_NEXT_PAGE                     0x8350
283 #define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL                   0x10
284 #define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE                  0x0001
285 #define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN                  0x0002
286
287 #define MDIO_REG_BANK_CL73_USERB0               0x8370
288 #define MDIO_CL73_USERB0_CL73_UCTRL                             0x10
289 #define MDIO_CL73_USERB0_CL73_UCTRL_USTAT1_MUXSEL                       0x0002
290 #define MDIO_CL73_USERB0_CL73_USTAT1                            0x11
291 #define MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK                  0x0100
292 #define MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37                0x0400
293 #define MDIO_CL73_USERB0_CL73_BAM_CTRL1                         0x12
294 #define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN                          0x8000
295 #define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN             0x4000
296 #define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN              0x2000
297 #define MDIO_CL73_USERB0_CL73_BAM_CTRL3                         0x14
298 #define MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR                 0x0001
299
300 #define MDIO_REG_BANK_AER_BLOCK                 0xFFD0
301 #define MDIO_AER_BLOCK_AER_REG                                  0x1E
302
303 #define MDIO_REG_BANK_COMBO_IEEE0               0xFFE0
304 #define MDIO_COMBO_IEEE0_MII_CONTROL                            0x10
305 #define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK                   0x2040
306 #define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_10                     0x0000
307 #define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100                    0x2000
308 #define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000                   0x0040
309 #define MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX                         0x0100
310 #define MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN                          0x0200
311 #define MDIO_COMBO_IEEO_MII_CONTROL_AN_EN                               0x1000
312 #define MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK                            0x4000
313 #define MDIO_COMBO_IEEO_MII_CONTROL_RESET                               0x8000
314 #define MDIO_COMBO_IEEE0_MII_STATUS                             0x11
315 #define MDIO_COMBO_IEEE0_MII_STATUS_LINK_PASS                           0x0004
316 #define MDIO_COMBO_IEEE0_MII_STATUS_AUTONEG_COMPLETE                    0x0020
317 #define MDIO_COMBO_IEEE0_AUTO_NEG_ADV                           0x14
318 #define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX                       0x0020
319 #define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_HALF_DUPLEX                       0x0040
320 #define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK                        0x0180
321 #define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE                        0x0000
322 #define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC                   0x0080
323 #define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC                  0x0100
324 #define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH                        0x0180
325 #define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_NEXT_PAGE                         0x8000
326 #define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1         0x15
327 #define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_NEXT_PAGE       0x8000
328 #define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_ACK             0x4000
329 #define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_MASK      0x0180
330 #define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_NONE      0x0000
331 #define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_BOTH      0x0180
332 #define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_HALF_DUP_CAP    0x0040
333 #define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_FULL_DUP_CAP    0x0020
334 /*WhenthelinkpartnerisinSGMIImode(bit0=1),then
335 bit15=link,bit12=duplex,bits11:10=speed,bit14=acknowledge.
336 Theotherbitsarereservedandshouldbezero*/
337 #define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_SGMII_MODE      0x0001
338
339
340 #define MDIO_PMA_DEVAD                  0x1
341 /*ieee*/
342 #define MDIO_PMA_REG_CTRL               0x0
343 #define MDIO_PMA_REG_STATUS             0x1
344 #define MDIO_PMA_REG_10G_CTRL2          0x7
345 #define MDIO_PMA_REG_TX_DISABLE         0x0009
346 #define MDIO_PMA_REG_RX_SD              0xa
347 /*bcm*/
348 #define MDIO_PMA_REG_BCM_CTRL           0x0096
349 #define MDIO_PMA_REG_FEC_CTRL           0x00ab
350 #define MDIO_PMA_LASI_RXCTRL            0x9000
351 #define MDIO_PMA_LASI_TXCTRL            0x9001
352 #define MDIO_PMA_LASI_CTRL              0x9002
353 #define MDIO_PMA_LASI_RXSTAT            0x9003
354 #define MDIO_PMA_LASI_TXSTAT            0x9004
355 #define MDIO_PMA_LASI_STAT              0x9005
356 #define MDIO_PMA_REG_PHY_IDENTIFIER     0xc800
357 #define MDIO_PMA_REG_DIGITAL_CTRL       0xc808
358 #define MDIO_PMA_REG_DIGITAL_STATUS     0xc809
359 #define MDIO_PMA_REG_TX_POWER_DOWN      0xca02
360 #define MDIO_PMA_REG_CMU_PLL_BYPASS     0xca09
361 #define MDIO_PMA_REG_MISC_CTRL          0xca0a
362 #define MDIO_PMA_REG_GEN_CTRL           0xca10
363         #define MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP     0x0188
364         #define MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET           0x018a
365 #define MDIO_PMA_REG_M8051_MSGIN_REG    0xca12
366 #define MDIO_PMA_REG_M8051_MSGOUT_REG   0xca13
367 #define MDIO_PMA_REG_ROM_VER1           0xca19
368 #define MDIO_PMA_REG_ROM_VER2           0xca1a
369 #define MDIO_PMA_REG_EDC_FFE_MAIN       0xca1b
370 #define MDIO_PMA_REG_PLL_BANDWIDTH      0xca1d
371 #define MDIO_PMA_REG_PLL_CTRL           0xca1e
372 #define MDIO_PMA_REG_MISC_CTRL0         0xca23
373 #define MDIO_PMA_REG_LRM_MODE           0xca3f
374 #define MDIO_PMA_REG_CDR_BANDWIDTH      0xca46
375 #define MDIO_PMA_REG_MISC_CTRL1         0xca85
376
377 #define MDIO_PMA_REG_SFP_TWO_WIRE_CTRL          0x8000
378         #define MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK      0x000c
379                 #define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE           0x0000
380                 #define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE       0x0004
381                 #define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IN_PROGRESS    0x0008
382                 #define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_FAILED         0x000c
383 #define MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT      0x8002
384 #define MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR      0x8003
385 #define MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF     0xc820
386         #define MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK 0xff
387 #define MDIO_PMA_REG_8726_TX_CTRL1              0xca01
388 #define MDIO_PMA_REG_8726_TX_CTRL2              0xca05
389
390 #define MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR   0x8005
391 #define MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF     0x8007
392         #define MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK 0xff
393 #define MDIO_PMA_REG_8727_MISC_CTRL             0x8309
394 #define MDIO_PMA_REG_8727_TX_CTRL1              0xca02
395 #define MDIO_PMA_REG_8727_TX_CTRL2              0xca05
396 #define MDIO_PMA_REG_8727_PCS_OPT_CTRL          0xc808
397 #define MDIO_PMA_REG_8727_GPIO_CTRL             0xc80e
398 #define MDIO_PMA_REG_8727_PCS_GP                0xc842
399 #define MDIO_PMA_REG_8727_OPT_CFG_REG           0xc8e4
400
401 #define MDIO_AN_REG_8727_MISC_CTRL              0x8309
402 #define MDIO_PMA_REG_8073_CHIP_REV                      0xc801
403 #define MDIO_PMA_REG_8073_SPEED_LINK_STATUS             0xc820
404 #define MDIO_PMA_REG_8073_XAUI_WA                       0xc841
405 #define MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL              0xcd08
406
407 #define MDIO_PMA_REG_7101_RESET         0xc000
408 #define MDIO_PMA_REG_7107_LED_CNTL      0xc007
409 #define MDIO_PMA_REG_7107_LINK_LED_CNTL 0xc009
410 #define MDIO_PMA_REG_7101_VER1          0xc026
411 #define MDIO_PMA_REG_7101_VER2          0xc027
412
413 #define MDIO_PMA_REG_8481_PMD_SIGNAL    0xa811
414 #define MDIO_PMA_REG_8481_LED1_MASK     0xa82c
415 #define MDIO_PMA_REG_8481_LED2_MASK     0xa82f
416 #define MDIO_PMA_REG_8481_LED3_MASK     0xa832
417 #define MDIO_PMA_REG_8481_LED3_BLINK    0xa834
418 #define MDIO_PMA_REG_8481_LED5_MASK                     0xa838
419 #define MDIO_PMA_REG_8481_SIGNAL_MASK   0xa835
420 #define MDIO_PMA_REG_8481_LINK_SIGNAL   0xa83b
421 #define MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK  0x800
422 #define MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT 11
423
424
425
426 #define MDIO_WIS_DEVAD                  0x2
427 /*bcm*/
428 #define MDIO_WIS_REG_LASI_CNTL          0x9002
429 #define MDIO_WIS_REG_LASI_STATUS        0x9005
430
431 #define MDIO_PCS_DEVAD                  0x3
432 #define MDIO_PCS_REG_STATUS             0x0020
433 #define MDIO_PCS_REG_LASI_STATUS        0x9005
434 #define MDIO_PCS_REG_7101_DSP_ACCESS    0xD000
435 #define MDIO_PCS_REG_7101_SPI_MUX       0xD008
436 #define MDIO_PCS_REG_7101_SPI_CTRL_ADDR 0xE12A
437         #define MDIO_PCS_REG_7101_SPI_RESET_BIT (5)
438 #define MDIO_PCS_REG_7101_SPI_FIFO_ADDR 0xE02A
439         #define MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD (6)
440         #define MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD   (0xC7)
441         #define MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD (2)
442 #define MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR 0xE028
443
444
445
446 #define MDIO_XS_DEVAD                   0x4
447 #define MDIO_XS_REG_STATUS              0x0001
448 #define MDIO_XS_PLL_SEQUENCER           0x8000
449 #define MDIO_XS_SFX7101_XGXS_TEST1      0xc00a
450
451 #define MDIO_XS_8706_REG_BANK_RX0       0x80bc
452 #define MDIO_XS_8706_REG_BANK_RX1       0x80cc
453 #define MDIO_XS_8706_REG_BANK_RX2       0x80dc
454 #define MDIO_XS_8706_REG_BANK_RX3       0x80ec
455 #define MDIO_XS_8706_REG_BANK_RXA       0x80fc
456
457 #define MDIO_XS_REG_8073_RX_CTRL_PCIE   0x80FA
458
459 #define MDIO_AN_DEVAD                   0x7
460 /*ieee*/
461 #define MDIO_AN_REG_CTRL                0x0000
462 #define MDIO_AN_REG_STATUS              0x0001
463         #define MDIO_AN_REG_STATUS_AN_COMPLETE          0x0020
464 #define MDIO_AN_REG_ADV_PAUSE           0x0010
465         #define MDIO_AN_REG_ADV_PAUSE_PAUSE             0x0400
466         #define MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC        0x0800
467         #define MDIO_AN_REG_ADV_PAUSE_BOTH              0x0C00
468         #define MDIO_AN_REG_ADV_PAUSE_MASK              0x0C00
469 #define MDIO_AN_REG_ADV                 0x0011
470 #define MDIO_AN_REG_ADV2                0x0012
471 #define MDIO_AN_REG_LP_AUTO_NEG         0x0013
472 #define MDIO_AN_REG_LP_AUTO_NEG2        0x0014
473 #define MDIO_AN_REG_MASTER_STATUS       0x0021
474 #define MDIO_AN_REG_EEE_ADV             0x003c
475 #define MDIO_AN_REG_LP_EEE_ADV          0x003d
476 /*bcm*/
477 #define MDIO_AN_REG_LINK_STATUS         0x8304
478 #define MDIO_AN_REG_CL37_CL73           0x8370
479 #define MDIO_AN_REG_CL37_AN             0xffe0
480 #define MDIO_AN_REG_CL37_FC_LD          0xffe4
481 #define         MDIO_AN_REG_CL37_FC_LP          0xffe5
482 #define         MDIO_AN_REG_1000T_STATUS        0xffea
483
484 #define MDIO_AN_REG_8073_2_5G           0x8329
485 #define MDIO_AN_REG_8073_BAM            0x8350
486
487 #define MDIO_AN_REG_8481_10GBASE_T_AN_CTRL      0x0020
488 #define MDIO_AN_REG_8481_LEGACY_MII_CTRL        0xffe0
489         #define MDIO_AN_REG_8481_MII_CTRL_FORCE_1G      0x40
490 #define MDIO_AN_REG_8481_LEGACY_MII_STATUS      0xffe1
491 #define MDIO_AN_REG_8481_LEGACY_AN_ADV          0xffe4
492 #define MDIO_AN_REG_8481_LEGACY_AN_EXPANSION    0xffe6
493 #define MDIO_AN_REG_8481_1000T_CTRL             0xffe9
494 #define MDIO_AN_REG_8481_1G_100T_EXT_CTRL       0xfff0
495         #define MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF        0x0008
496 #define MDIO_AN_REG_8481_EXPANSION_REG_RD_RW    0xfff5
497 #define MDIO_AN_REG_8481_EXPANSION_REG_ACCESS   0xfff7
498 #define MDIO_AN_REG_8481_AUX_CTRL               0xfff8
499 #define MDIO_AN_REG_8481_LEGACY_SHADOW          0xfffc
500
501 /* BCM84823 only */
502 #define MDIO_CTL_DEVAD                  0x1e
503 #define MDIO_CTL_REG_84823_MEDIA                0x401a
504         #define MDIO_CTL_REG_84823_MEDIA_MAC_MASK               0x0018
505         /* These pins configure the BCM84823 interface to MAC after reset. */
506                 #define MDIO_CTL_REG_84823_CTRL_MAC_XFI                 0x0008
507                 #define MDIO_CTL_REG_84823_MEDIA_MAC_XAUI_M             0x0010
508         /* These pins configure the BCM84823 interface to Line after reset. */
509         #define MDIO_CTL_REG_84823_MEDIA_LINE_MASK              0x0060
510                 #define MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L            0x0020
511                 #define MDIO_CTL_REG_84823_MEDIA_LINE_XFI               0x0040
512         /* When this pin is active high during reset, 10GBASE-T core is power
513          * down, When it is active low the 10GBASE-T is power up
514          */
515         #define MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN       0x0080
516         #define MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK          0x0100
517                 #define MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER        0x0000
518                 #define MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER         0x0100
519         #define MDIO_CTL_REG_84823_MEDIA_FIBER_1G                       0x1000
520 #define MDIO_CTL_REG_84823_USER_CTRL_REG                        0x4005
521         #define MDIO_CTL_REG_84823_USER_CTRL_CMS                        0x0080
522 #define MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH                0xa82b
523         #define MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ        0x2f
524 #define MDIO_PMA_REG_84823_CTL_LED_CTL_1                        0xa8e3
525 #define MDIO_PMA_REG_84833_CTL_LED_CTL_1                        0xa8ec
526         #define MDIO_PMA_REG_84823_LED3_STRETCH_EN                      0x0080
527
528 /* BCM84833 only */
529 #define MDIO_84833_TOP_CFG_FW_REV                       0x400f
530         #define MDIO_84833_TOP_CFG_FW_EEE               0x10b1
531         #define MDIO_84833_TOP_CFG_FW_NO_EEE            0x1f81
532 #define MDIO_84833_TOP_CFG_XGPHY_STRAP1                 0x401a
533         #define MDIO_84833_SUPER_ISOLATE                0x8000
534 /* These are mailbox register set used by 84833. */
535 #define MDIO_84833_TOP_CFG_SCRATCH_REG0                 0x4005
536 #define MDIO_84833_TOP_CFG_SCRATCH_REG1                 0x4006
537 #define MDIO_84833_TOP_CFG_SCRATCH_REG2                 0x4007
538 #define MDIO_84833_TOP_CFG_SCRATCH_REG3                 0x4008
539 #define MDIO_84833_TOP_CFG_SCRATCH_REG4                 0x4009
540 #define MDIO_84833_TOP_CFG_SCRATCH_REG26                0x4037
541 #define MDIO_84833_TOP_CFG_SCRATCH_REG27                0x4038
542 #define MDIO_84833_TOP_CFG_SCRATCH_REG28                0x4039
543 #define MDIO_84833_TOP_CFG_SCRATCH_REG29                0x403a
544 #define MDIO_84833_TOP_CFG_SCRATCH_REG30                0x403b
545 #define MDIO_84833_TOP_CFG_SCRATCH_REG31                0x403c
546 #define MDIO_84833_CMD_HDLR_COMMAND     MDIO_84833_TOP_CFG_SCRATCH_REG0
547 #define MDIO_84833_CMD_HDLR_STATUS      MDIO_84833_TOP_CFG_SCRATCH_REG26
548 #define MDIO_84833_CMD_HDLR_DATA1       MDIO_84833_TOP_CFG_SCRATCH_REG27
549 #define MDIO_84833_CMD_HDLR_DATA2       MDIO_84833_TOP_CFG_SCRATCH_REG28
550 #define MDIO_84833_CMD_HDLR_DATA3       MDIO_84833_TOP_CFG_SCRATCH_REG29
551 #define MDIO_84833_CMD_HDLR_DATA4       MDIO_84833_TOP_CFG_SCRATCH_REG30
552 #define MDIO_84833_CMD_HDLR_DATA5       MDIO_84833_TOP_CFG_SCRATCH_REG31
553
554 /* Mailbox command set used by 84833. */
555 #define PHY84833_CMD_SET_PAIR_SWAP                      0x8001
556 #define PHY84833_CMD_GET_EEE_MODE                       0x8008
557 #define PHY84833_CMD_SET_EEE_MODE                       0x8009
558 #define PHY84833_CMD_GET_CURRENT_TEMP                   0x8031
559 /* Mailbox status set used by 84833. */
560 #define PHY84833_STATUS_CMD_RECEIVED                    0x0001
561 #define PHY84833_STATUS_CMD_IN_PROGRESS                 0x0002
562 #define PHY84833_STATUS_CMD_COMPLETE_PASS               0x0004
563 #define PHY84833_STATUS_CMD_COMPLETE_ERROR              0x0008
564 #define PHY84833_STATUS_CMD_OPEN_FOR_CMDS               0x0010
565 #define PHY84833_STATUS_CMD_SYSTEM_BOOT                 0x0020
566 #define PHY84833_STATUS_CMD_NOT_OPEN_FOR_CMDS           0x0040
567 #define PHY84833_STATUS_CMD_CLEAR_COMPLETE              0x0080
568 #define PHY84833_STATUS_CMD_OPEN_OVERRIDE               0xa5a5
569
570
571 /* Warpcore clause 45 addressing */
572 #define MDIO_WC_DEVAD                                   0x3
573 #define MDIO_WC_REG_IEEE0BLK_MIICNTL                    0x0
574 #define MDIO_WC_REG_IEEE0BLK_AUTONEGNP                  0x7
575 #define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT0       0x10
576 #define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1       0x11
577 #define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2       0x12
578         #define MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY     0x4000
579         #define MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ         0x8000
580 #define MDIO_WC_REG_PCS_STATUS2                         0x0021
581 #define MDIO_WC_REG_PMD_KR_CONTROL                      0x0096
582 #define MDIO_WC_REG_XGXSBLK0_XGXSCONTROL                0x8000
583 #define MDIO_WC_REG_XGXSBLK0_MISCCONTROL1               0x800e
584 #define MDIO_WC_REG_XGXSBLK1_DESKEW                     0x8010
585 #define MDIO_WC_REG_XGXSBLK1_LANECTRL0                  0x8015
586 #define MDIO_WC_REG_XGXSBLK1_LANECTRL1                  0x8016
587 #define MDIO_WC_REG_XGXSBLK1_LANECTRL2                  0x8017
588 #define MDIO_WC_REG_XGXSBLK1_LANECTRL3                  0x8018
589 #define MDIO_WC_REG_XGXSBLK1_LANETEST0                  0x801a
590 #define MDIO_WC_REG_TX0_ANA_CTRL0                       0x8061
591 #define MDIO_WC_REG_TX1_ANA_CTRL0                       0x8071
592 #define MDIO_WC_REG_TX2_ANA_CTRL0                       0x8081
593 #define MDIO_WC_REG_TX3_ANA_CTRL0                       0x8091
594 #define MDIO_WC_REG_TX0_TX_DRIVER                       0x8067
595 #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET            0x04
596 #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_MASK                      0x00f0
597 #define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET                0x08
598 #define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_MASK                          0x0f00
599 #define MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET            0x0c
600 #define MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_MASK                      0x7000
601 #define MDIO_WC_REG_TX1_TX_DRIVER                       0x8077
602 #define MDIO_WC_REG_TX2_TX_DRIVER                       0x8087
603 #define MDIO_WC_REG_TX3_TX_DRIVER                       0x8097
604 #define MDIO_WC_REG_RX0_ANARXCONTROL1G                  0x80b9
605 #define MDIO_WC_REG_RX2_ANARXCONTROL1G                  0x80d9
606 #define MDIO_WC_REG_RX0_PCI_CTRL                        0x80ba
607 #define MDIO_WC_REG_RX1_PCI_CTRL                        0x80ca
608 #define MDIO_WC_REG_RX2_PCI_CTRL                        0x80da
609 #define MDIO_WC_REG_RX3_PCI_CTRL                        0x80ea
610 #define MDIO_WC_REG_RXB_ANA_RX_CONTROL_PCI              0x80fa
611 #define MDIO_WC_REG_XGXSBLK2_UNICORE_MODE_10G           0x8104
612 #define MDIO_WC_REG_XGXS_STATUS3                        0x8129
613 #define MDIO_WC_REG_PAR_DET_10G_STATUS                  0x8130
614 #define MDIO_WC_REG_PAR_DET_10G_CTRL                    0x8131
615 #define MDIO_WC_REG_XGXS_STATUS4                        0x813c
616 #define MDIO_WC_REG_XGXS_X2_CONTROL2                    0x8141
617 #define MDIO_WC_REG_XGXS_X2_CONTROL3                    0x8142
618 #define MDIO_WC_REG_XGXS_RX_LN_SWAP1                    0x816B
619 #define MDIO_WC_REG_XGXS_TX_LN_SWAP1                    0x8169
620 #define MDIO_WC_REG_GP2_STATUS_GP_2_0                   0x81d0
621 #define MDIO_WC_REG_GP2_STATUS_GP_2_1                   0x81d1
622 #define MDIO_WC_REG_GP2_STATUS_GP_2_2                   0x81d2
623 #define MDIO_WC_REG_GP2_STATUS_GP_2_3                   0x81d3
624 #define MDIO_WC_REG_GP2_STATUS_GP_2_4                   0x81d4
625         #define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL 0x1000
626         #define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_AN_CMPL 0x0100
627         #define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP 0x0010
628         #define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_AN_CAP 0x1
629 #define MDIO_WC_REG_UC_INFO_B0_DEAD_TRAP                0x81EE
630 #define MDIO_WC_REG_UC_INFO_B1_VERSION                  0x81F0
631 #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE            0x81F2
632         #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE0_OFFSET    0x0
633                 #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT        0x0
634                 #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_OPT_LR     0x1
635                 #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC        0x2
636                 #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_XLAUI      0x3
637                 #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_LONG_CH_6G     0x4
638         #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE1_OFFSET    0x4
639         #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE2_OFFSET    0x8
640         #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE3_OFFSET    0xc
641 #define MDIO_WC_REG_UC_INFO_B1_CRC                      0x81FE
642 #define MDIO_WC_REG_DSC1B0_UC_CTRL                              0x820e
643         #define MDIO_WC_REG_DSC1B0_UC_CTRL_RDY4CMD                      (1<<7)
644 #define MDIO_WC_REG_DSC_SMC                             0x8213
645 #define MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0               0x821e
646 #define MDIO_WC_REG_TX_FIR_TAP                          0x82e2
647         #define MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET           0x00
648         #define MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_MASK                     0x000f
649         #define MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET          0x04
650         #define MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_MASK            0x03f0
651         #define MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET          0x0a
652         #define MDIO_WC_REG_TX_FIR_TAP_POST_TAP_MASK            0x7c00
653         #define MDIO_WC_REG_TX_FIR_TAP_ENABLE           0x8000
654 #define MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP         0x82e2
655 #define MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL      0x82e3
656 #define MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL        0x82e6
657 #define MDIO_WC_REG_CL72_USERB0_CL72_BR_DEF_CTRL        0x82e7
658 #define MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL       0x82e8
659 #define MDIO_WC_REG_CL72_USERB0_CL72_MISC4_CONTROL      0x82ec
660 #define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1         0x8300
661 #define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2         0x8301
662 #define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3         0x8302
663 #define MDIO_WC_REG_SERDESDIGITAL_STATUS1000X1          0x8304
664 #define MDIO_WC_REG_SERDESDIGITAL_MISC1                 0x8308
665 #define MDIO_WC_REG_SERDESDIGITAL_MISC2                 0x8309
666 #define MDIO_WC_REG_DIGITAL3_UP1                        0x8329
667 #define MDIO_WC_REG_DIGITAL3_LP_UP1                     0x832c
668 #define MDIO_WC_REG_DIGITAL4_MISC3                      0x833c
669 #define MDIO_WC_REG_DIGITAL4_MISC5                      0x833e
670 #define MDIO_WC_REG_DIGITAL5_MISC6                      0x8345
671 #define MDIO_WC_REG_DIGITAL5_MISC7                      0x8349
672 #define MDIO_WC_REG_DIGITAL5_LINK_STATUS                0x834d
673 #define MDIO_WC_REG_DIGITAL5_ACTUAL_SPEED               0x834e
674 #define MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL           0x8350
675 #define MDIO_WC_REG_CL49_USERB0_CTRL                    0x8368
676 #define MDIO_WC_REG_CL73_USERB0_CTRL                    0x8370
677 #define MDIO_WC_REG_CL73_USERB0_USTAT                   0x8371
678 #define MDIO_WC_REG_CL73_BAM_CTRL1                      0x8372
679 #define MDIO_WC_REG_CL73_BAM_CTRL2                      0x8373
680 #define MDIO_WC_REG_CL73_BAM_CTRL3                      0x8374
681 #define MDIO_WC_REG_CL73_BAM_CODE_FIELD                 0x837b
682 #define MDIO_WC_REG_EEE_COMBO_CONTROL0                  0x8390
683 #define MDIO_WC_REG_TX66_CONTROL                        0x83b0
684 #define MDIO_WC_REG_RX66_CONTROL                        0x83c0
685 #define MDIO_WC_REG_RX66_SCW0                           0x83c2
686 #define MDIO_WC_REG_RX66_SCW1                           0x83c3
687 #define MDIO_WC_REG_RX66_SCW2                           0x83c4
688 #define MDIO_WC_REG_RX66_SCW3                           0x83c5
689 #define MDIO_WC_REG_RX66_SCW0_MASK                      0x83c6
690 #define MDIO_WC_REG_RX66_SCW1_MASK                      0x83c7
691 #define MDIO_WC_REG_RX66_SCW2_MASK                      0x83c8
692 #define MDIO_WC_REG_RX66_SCW3_MASK                      0x83c9
693 #define MDIO_WC_REG_FX100_CTRL1                         0x8400
694 #define MDIO_WC_REG_FX100_CTRL3                         0x8402
695 #define MDIO_WC_REG_CL82_USERB1_TX_CTRL5                0x8436
696 #define MDIO_WC_REG_CL82_USERB1_TX_CTRL6                0x8437
697 #define MDIO_WC_REG_CL82_USERB1_TX_CTRL7                0x8438
698 #define MDIO_WC_REG_CL82_USERB1_TX_CTRL9                0x8439
699 #define MDIO_WC_REG_CL82_USERB1_RX_CTRL10               0x843a
700 #define MDIO_WC_REG_CL82_USERB1_RX_CTRL11               0x843b
701 #define MDIO_WC_REG_ETA_CL73_OUI1                       0x8453
702 #define MDIO_WC_REG_ETA_CL73_OUI2                       0x8454
703 #define MDIO_WC_REG_ETA_CL73_OUI3                       0x8455
704 #define MDIO_WC_REG_ETA_CL73_LD_BAM_CODE                0x8456
705 #define MDIO_WC_REG_ETA_CL73_LD_UD_CODE                 0x8457
706 #define MDIO_WC_REG_MICROBLK_CMD                        0xffc2
707 #define MDIO_WC_REG_MICROBLK_DL_STATUS                  0xffc5
708 #define MDIO_WC_REG_MICROBLK_CMD3                       0xffcc
709
710 #define MDIO_WC_REG_AERBLK_AER                          0xffde
711 #define MDIO_WC_REG_COMBO_IEEE0_MIICTRL                 0xffe0
712 #define MDIO_WC_REG_COMBO_IEEE0_MIIISTAT                0xffe1
713
714 #define MDIO_WC0_XGXS_BLK2_LANE_RESET                   0x810A
715         #define MDIO_WC0_XGXS_BLK2_LANE_RESET_RX_BITSHIFT       0
716         #define MDIO_WC0_XGXS_BLK2_LANE_RESET_TX_BITSHIFT       4
717
718 #define MDIO_WC0_XGXS_BLK6_XGXS_X2_CONTROL2             0x8141
719
720 #define DIGITAL5_ACTUAL_SPEED_TX_MASK                   0x003f
721
722 /* 54618se */
723 #define MDIO_REG_GPHY_MII_STATUS                        0x1
724 #define MDIO_REG_GPHY_PHYID_LSB                         0x3
725 #define MDIO_REG_GPHY_CL45_ADDR_REG                     0xd
726         #define MDIO_REG_GPHY_CL45_REG_WRITE            0x4000
727         #define MDIO_REG_GPHY_CL45_REG_READ             0xc000
728 #define MDIO_REG_GPHY_CL45_DATA_REG                     0xe
729         #define MDIO_REG_GPHY_EEE_RESOLVED              0x803e
730 #define MDIO_REG_GPHY_EXP_ACCESS_GATE                   0x15
731 #define MDIO_REG_GPHY_EXP_ACCESS                        0x17
732         #define MDIO_REG_GPHY_EXP_ACCESS_TOP            0xd00
733         #define MDIO_REG_GPHY_EXP_TOP_2K_BUF            0x40
734 #define MDIO_REG_GPHY_AUX_STATUS                        0x19
735 #define MDIO_REG_INTR_STATUS                            0x1a
736 #define MDIO_REG_INTR_MASK                              0x1b
737         #define MDIO_REG_INTR_MASK_LINK_STATUS                  (0x1 << 1)
738 #define MDIO_REG_GPHY_SHADOW                            0x1c
739         #define MDIO_REG_GPHY_SHADOW_LED_SEL1                   (0x0d << 10)
740         #define MDIO_REG_GPHY_SHADOW_LED_SEL2                   (0x0e << 10)
741         #define MDIO_REG_GPHY_SHADOW_WR_ENA                     (0x1 << 15)
742         #define MDIO_REG_GPHY_SHADOW_AUTO_DET_MED               (0x1e << 10)
743         #define MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD              (0x1 << 8)
744
745
746 typedef elink_status_t (*read_sfp_module_eeprom_func_p)(struct elink_phy *phy,
747                                              struct elink_params *params,
748                                              uint8_t dev_addr, uint16_t addr, uint8_t byte_cnt,
749                                              uint8_t *o_buf, uint8_t);
750 /********************************************************/
751 #define ELINK_ETH_HLEN                  14
752 /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
753 #define ELINK_ETH_OVREHEAD                      (ELINK_ETH_HLEN + 8 + 8)
754 #define ELINK_ETH_MIN_PACKET_SIZE               60
755 #define ELINK_ETH_MAX_PACKET_SIZE               1500
756 #define ELINK_ETH_MAX_JUMBO_PACKET_SIZE 9600
757 #define ELINK_MDIO_ACCESS_TIMEOUT               1000
758 #define WC_LANE_MAX                     4
759 #define I2C_SWITCH_WIDTH                2
760 #define I2C_BSC0                        0
761 #define I2C_BSC1                        1
762 #define I2C_WA_RETRY_CNT                3
763 #define I2C_WA_PWR_ITER                 (I2C_WA_RETRY_CNT - 1)
764 #define MCPR_IMC_COMMAND_READ_OP        1
765 #define MCPR_IMC_COMMAND_WRITE_OP       2
766
767 /* LED Blink rate that will achieve ~15.9Hz */
768 #define LED_BLINK_RATE_VAL_E3           354
769 #define LED_BLINK_RATE_VAL_E1X_E2       480
770 /***********************************************************/
771 /*                      Shortcut definitions               */
772 /***********************************************************/
773
774 #define ELINK_NIG_LATCH_BC_ENABLE_MI_INT 0
775
776 #define ELINK_NIG_STATUS_EMAC0_MI_INT \
777                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
778 #define ELINK_NIG_STATUS_XGXS0_LINK10G \
779                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
780 #define ELINK_NIG_STATUS_XGXS0_LINK_STATUS \
781                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
782 #define ELINK_NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
783                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
784 #define ELINK_NIG_STATUS_SERDES0_LINK_STATUS \
785                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
786 #define ELINK_NIG_MASK_MI_INT \
787                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
788 #define ELINK_NIG_MASK_XGXS0_LINK10G \
789                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
790 #define ELINK_NIG_MASK_XGXS0_LINK_STATUS \
791                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
792 #define ELINK_NIG_MASK_SERDES0_LINK_STATUS \
793                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
794
795 #define ELINK_MDIO_AN_CL73_OR_37_COMPLETE \
796                 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
797                  MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
798
799 #define ELINK_XGXS_RESET_BITS \
800         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
801          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
802          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
803          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
804          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
805
806 #define ELINK_SERDES_RESET_BITS \
807         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
808          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
809          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
810          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
811
812 #define ELINK_AUTONEG_CL37              SHARED_HW_CFG_AN_ENABLE_CL37
813 #define ELINK_AUTONEG_CL73              SHARED_HW_CFG_AN_ENABLE_CL73
814 #define ELINK_AUTONEG_BAM               SHARED_HW_CFG_AN_ENABLE_BAM
815 #define ELINK_AUTONEG_PARALLEL \
816                                 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
817 #define ELINK_AUTONEG_SGMII_FIBER_AUTODET \
818                                 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
819 #define ELINK_AUTONEG_REMOTE_PHY        SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
820
821 #define ELINK_GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
822                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
823 #define ELINK_GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
824                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
825 #define ELINK_GP_STATUS_SPEED_MASK \
826                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
827 #define ELINK_GP_STATUS_10M     MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
828 #define ELINK_GP_STATUS_100M    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
829 #define ELINK_GP_STATUS_1G      MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
830 #define ELINK_GP_STATUS_2_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
831 #define ELINK_GP_STATUS_5G      MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
832 #define ELINK_GP_STATUS_6G      MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
833 #define ELINK_GP_STATUS_10G_HIG \
834                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
835 #define ELINK_GP_STATUS_10G_CX4 \
836                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
837 #define ELINK_GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
838 #define ELINK_GP_STATUS_10G_KX4 \
839                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
840 #define ELINK_GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR
841 #define ELINK_GP_STATUS_10G_XFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI
842 #define ELINK_GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS
843 #define ELINK_GP_STATUS_10G_SFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI
844 #define ELINK_GP_STATUS_20G_KR2 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_KR2
845 #define ELINK_LINK_10THD                LINK_STATUS_SPEED_AND_DUPLEX_10THD
846 #define ELINK_LINK_10TFD                LINK_STATUS_SPEED_AND_DUPLEX_10TFD
847 #define ELINK_LINK_100TXHD              LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
848 #define ELINK_LINK_100T4                LINK_STATUS_SPEED_AND_DUPLEX_100T4
849 #define ELINK_LINK_100TXFD              LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
850 #define ELINK_LINK_1000THD              LINK_STATUS_SPEED_AND_DUPLEX_1000THD
851 #define ELINK_LINK_1000TFD              LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
852 #define ELINK_LINK_1000XFD              LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
853 #define ELINK_LINK_2500THD              LINK_STATUS_SPEED_AND_DUPLEX_2500THD
854 #define ELINK_LINK_2500TFD              LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
855 #define ELINK_LINK_2500XFD              LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
856 #define ELINK_LINK_10GTFD               LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
857 #define ELINK_LINK_10GXFD               LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
858 #define ELINK_LINK_20GTFD               LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
859 #define ELINK_LINK_20GXFD               LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
860
861 #define ELINK_LINK_UPDATE_MASK \
862                         (LINK_STATUS_SPEED_AND_DUPLEX_MASK | \
863                          LINK_STATUS_LINK_UP | \
864                          LINK_STATUS_PHYSICAL_LINK_FLAG | \
865                          LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | \
866                          LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | \
867                          LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | \
868                          LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | \
869                          LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | \
870                          LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE)
871
872 #define ELINK_SFP_EEPROM_CON_TYPE_ADDR          0x2
873         #define ELINK_SFP_EEPROM_CON_TYPE_VAL_LC        0x7
874         #define ELINK_SFP_EEPROM_CON_TYPE_VAL_COPPER    0x21
875         #define ELINK_SFP_EEPROM_CON_TYPE_VAL_RJ45      0x22
876
877
878 #define ELINK_SFP_EEPROM_COMP_CODE_ADDR         0x3
879         #define ELINK_SFP_EEPROM_COMP_CODE_SR_MASK      (1<<4)
880         #define ELINK_SFP_EEPROM_COMP_CODE_LR_MASK      (1<<5)
881         #define ELINK_SFP_EEPROM_COMP_CODE_LRM_MASK     (1<<6)
882
883 #define ELINK_SFP_EEPROM_FC_TX_TECH_ADDR                0x8
884         #define ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
885         #define ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE  0x8
886
887 #define ELINK_SFP_EEPROM_OPTIONS_ADDR                   0x40
888         #define ELINK_SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
889 #define ELINK_SFP_EEPROM_OPTIONS_SIZE                   2
890
891 #define ELINK_EDC_MODE_LINEAR                           0x0022
892 #define ELINK_EDC_MODE_LIMITING                         0x0044
893 #define ELINK_EDC_MODE_PASSIVE_DAC                      0x0055
894 #define ELINK_EDC_MODE_ACTIVE_DAC                       0x0066
895
896 /* ETS defines*/
897 #define DCBX_INVALID_COS                                        (0xFF)
898
899 #define ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND           (0x5000)
900 #define ELINK_ETS_BW_LIMIT_CREDIT_WEIGHT                (0x5000)
901 #define ELINK_ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS               (1360)
902 #define ELINK_ETS_E3B0_NIG_MIN_W_VAL_20GBPS                     (2720)
903 #define ELINK_ETS_E3B0_PBF_MIN_W_VAL                            (10000)
904
905 #define ELINK_MAX_PACKET_SIZE                                   (9700)
906 #define MAX_KR_LINK_RETRY                               4
907
908 /**********************************************************/
909 /*                     INTERFACE                          */
910 /**********************************************************/
911
912 #define CL22_WR_OVER_CL45(_sc, _phy, _bank, _addr, _val) \
913         elink_cl45_write(_sc, _phy, \
914                 (_phy)->def_md_devad, \
915                 (_bank + (_addr & 0xf)), \
916                 _val)
917
918 #define CL22_RD_OVER_CL45(_sc, _phy, _bank, _addr, _val) \
919         elink_cl45_read(_sc, _phy, \
920                 (_phy)->def_md_devad, \
921                 (_bank + (_addr & 0xf)), \
922                 _val)
923
924 static uint32_t elink_bits_en(struct bxe_softc *sc, uint32_t reg, uint32_t bits)
925 {
926         uint32_t val = REG_RD(sc, reg);
927
928         val |= bits;
929         REG_WR(sc, reg, val);
930         return val;
931 }
932
933 static uint32_t elink_bits_dis(struct bxe_softc *sc, uint32_t reg, uint32_t bits)
934 {
935         uint32_t val = REG_RD(sc, reg);
936
937         val &= ~bits;
938         REG_WR(sc, reg, val);
939         return val;
940 }
941
942 /*
943  * elink_check_lfa - This function checks if link reinitialization is required,
944  *                   or link flap can be avoided.
945  *
946  * @params:     link parameters
947  * Returns 0 if Link Flap Avoidance conditions are met otherwise, the failed
948  *         condition code.
949  */
950 static int elink_check_lfa(struct elink_params *params)
951 {
952         uint32_t link_status, cfg_idx, lfa_mask, cfg_size;
953         uint32_t cur_speed_cap_mask, cur_req_fc_auto_adv, additional_config;
954         uint32_t saved_val, req_val, eee_status;
955         struct bxe_softc *sc = params->sc;
956
957         additional_config =
958                 REG_RD(sc, params->lfa_base +
959                            offsetof(struct shmem_lfa, additional_config));
960
961         /* NOTE: must be first condition checked -
962         * to verify DCC bit is cleared in any case!
963         */
964         if (additional_config & NO_LFA_DUE_TO_DCC_MASK) {
965                 ELINK_DEBUG_P0(sc, "No LFA due to DCC flap after clp exit\n");
966                 REG_WR(sc, params->lfa_base +
967                            offsetof(struct shmem_lfa, additional_config),
968                        additional_config & ~NO_LFA_DUE_TO_DCC_MASK);
969                 return LFA_DCC_LFA_DISABLED;
970         }
971
972         /* Verify that link is up */
973         link_status = REG_RD(sc, params->shmem_base +
974                              offsetof(struct shmem_region,
975                                       port_mb[params->port].link_status));
976         if (!(link_status & LINK_STATUS_LINK_UP))
977                 return LFA_LINK_DOWN;
978
979         /* if loaded after BOOT from SAN, don't flap the link in any case and
980          * rely on link set by preboot driver
981          */
982         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_BOOT_FROM_SAN)
983                 return 0;
984
985         /* Verify that loopback mode is not set */
986         if (params->loopback_mode)
987                 return LFA_LOOPBACK_ENABLED;
988
989         /* Verify that MFW supports LFA */
990         if (!params->lfa_base)
991                 return LFA_MFW_IS_TOO_OLD;
992
993         if (params->num_phys == 3) {
994                 cfg_size = 2;
995                 lfa_mask = 0xffffffff;
996         } else {
997                 cfg_size = 1;
998                 lfa_mask = 0xffff;
999         }
1000
1001         /* Compare Duplex */
1002         saved_val = REG_RD(sc, params->lfa_base +
1003                            offsetof(struct shmem_lfa, req_duplex));
1004         req_val = params->req_duplex[0] | (params->req_duplex[1] << 16);
1005         if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
1006                 ELINK_DEBUG_P2(sc, "Duplex mismatch %x vs. %x\n",
1007                                (saved_val & lfa_mask), (req_val & lfa_mask));
1008                 return LFA_DUPLEX_MISMATCH;
1009         }
1010         /* Compare Flow Control */
1011         saved_val = REG_RD(sc, params->lfa_base +
1012                            offsetof(struct shmem_lfa, req_flow_ctrl));
1013         req_val = params->req_flow_ctrl[0] | (params->req_flow_ctrl[1] << 16);
1014         if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
1015                 ELINK_DEBUG_P2(sc, "Flow control mismatch %x vs. %x\n",
1016                                (saved_val & lfa_mask), (req_val & lfa_mask));
1017                 return LFA_FLOW_CTRL_MISMATCH;
1018         }
1019         /* Compare Link Speed */
1020         saved_val = REG_RD(sc, params->lfa_base +
1021                            offsetof(struct shmem_lfa, req_line_speed));
1022         req_val = params->req_line_speed[0] | (params->req_line_speed[1] << 16);
1023         if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
1024                 ELINK_DEBUG_P2(sc, "Link speed mismatch %x vs. %x\n",
1025                                (saved_val & lfa_mask), (req_val & lfa_mask));
1026                 return LFA_LINK_SPEED_MISMATCH;
1027         }
1028
1029         for (cfg_idx = 0; cfg_idx < cfg_size; cfg_idx++) {
1030                 cur_speed_cap_mask = REG_RD(sc, params->lfa_base +
1031                                             offsetof(struct shmem_lfa,
1032                                                      speed_cap_mask[cfg_idx]));
1033
1034                 if (cur_speed_cap_mask != params->speed_cap_mask[cfg_idx]) {
1035                         ELINK_DEBUG_P2(sc, "Speed Cap mismatch %x vs. %x\n",
1036                                        cur_speed_cap_mask,
1037                                        params->speed_cap_mask[cfg_idx]);
1038                         return LFA_SPEED_CAP_MISMATCH;
1039                 }
1040         }
1041
1042         cur_req_fc_auto_adv =
1043                 REG_RD(sc, params->lfa_base +
1044                        offsetof(struct shmem_lfa, additional_config)) &
1045                 REQ_FC_AUTO_ADV_MASK;
1046
1047         if ((uint16_t)cur_req_fc_auto_adv != params->req_fc_auto_adv) {
1048                 ELINK_DEBUG_P2(sc, "Flow Ctrl AN mismatch %x vs. %x\n",
1049                                cur_req_fc_auto_adv, params->req_fc_auto_adv);
1050                 return LFA_FLOW_CTRL_MISMATCH;
1051         }
1052
1053         eee_status = REG_RD(sc, params->shmem2_base +
1054                             offsetof(struct shmem2_region,
1055                                      eee_status[params->port]));
1056
1057         if (((eee_status & SHMEM_EEE_LPI_REQUESTED_BIT) ^
1058              (params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI)) ||
1059             ((eee_status & SHMEM_EEE_REQUESTED_BIT) ^
1060              (params->eee_mode & ELINK_EEE_MODE_ADV_LPI))) {
1061                 ELINK_DEBUG_P2(sc, "EEE mismatch %x vs. %x\n", params->eee_mode,
1062                                eee_status);
1063                 return LFA_EEE_MISMATCH;
1064         }
1065
1066         /* LFA conditions are met */
1067         return 0;
1068 }
1069 /******************************************************************/
1070 /*                      EPIO/GPIO section                         */
1071 /******************************************************************/
1072 static void elink_get_epio(struct bxe_softc *sc, uint32_t epio_pin, uint32_t *en)
1073 {
1074         uint32_t epio_mask, gp_oenable;
1075         *en = 0;
1076         /* Sanity check */
1077         if (epio_pin > 31) {
1078                 ELINK_DEBUG_P1(sc, "Invalid EPIO pin %d to get\n", epio_pin);
1079                 return;
1080         }
1081
1082         epio_mask = 1 << epio_pin;
1083         /* Set this EPIO to output */
1084         gp_oenable = REG_RD(sc, MCP_REG_MCPR_GP_OENABLE);
1085         REG_WR(sc, MCP_REG_MCPR_GP_OENABLE, gp_oenable & ~epio_mask);
1086
1087         *en = (REG_RD(sc, MCP_REG_MCPR_GP_INPUTS) & epio_mask) >> epio_pin;
1088 }
1089 static void elink_set_epio(struct bxe_softc *sc, uint32_t epio_pin, uint32_t en)
1090 {
1091         uint32_t epio_mask, gp_output, gp_oenable;
1092
1093         /* Sanity check */
1094         if (epio_pin > 31) {
1095                 ELINK_DEBUG_P1(sc, "Invalid EPIO pin %d to set\n", epio_pin);
1096                 return;
1097         }
1098         ELINK_DEBUG_P2(sc, "Setting EPIO pin %d to %d\n", epio_pin, en);
1099         epio_mask = 1 << epio_pin;
1100         /* Set this EPIO to output */
1101         gp_output = REG_RD(sc, MCP_REG_MCPR_GP_OUTPUTS);
1102         if (en)
1103                 gp_output |= epio_mask;
1104         else
1105                 gp_output &= ~epio_mask;
1106
1107         REG_WR(sc, MCP_REG_MCPR_GP_OUTPUTS, gp_output);
1108
1109         /* Set the value for this EPIO */
1110         gp_oenable = REG_RD(sc, MCP_REG_MCPR_GP_OENABLE);
1111         REG_WR(sc, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask);
1112 }
1113
1114 static void elink_set_cfg_pin(struct bxe_softc *sc, uint32_t pin_cfg, uint32_t val)
1115 {
1116         if (pin_cfg == PIN_CFG_NA)
1117                 return;
1118         if (pin_cfg >= PIN_CFG_EPIO0) {
1119                 elink_set_epio(sc, pin_cfg - PIN_CFG_EPIO0, val);
1120         } else {
1121                 uint8_t gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
1122                 uint8_t gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
1123                 elink_cb_gpio_write(sc, gpio_num, (uint8_t)val, gpio_port);
1124         }
1125 }
1126
1127 static uint32_t elink_get_cfg_pin(struct bxe_softc *sc, uint32_t pin_cfg, uint32_t *val)
1128 {
1129         if (pin_cfg == PIN_CFG_NA)
1130                 return ELINK_STATUS_ERROR;
1131         if (pin_cfg >= PIN_CFG_EPIO0) {
1132                 elink_get_epio(sc, pin_cfg - PIN_CFG_EPIO0, val);
1133         } else {
1134                 uint8_t gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
1135                 uint8_t gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
1136                 *val = elink_cb_gpio_read(sc, gpio_num, gpio_port);
1137         }
1138         return ELINK_STATUS_OK;
1139
1140 }
1141 /******************************************************************/
1142 /*                              ETS section                       */
1143 /******************************************************************/
1144 static void elink_ets_e2e3a0_disabled(struct elink_params *params)
1145 {
1146         /* ETS disabled configuration*/
1147         struct bxe_softc *sc = params->sc;
1148
1149         ELINK_DEBUG_P0(sc, "ETS E2E3 disabled configuration\n");
1150
1151         /* mapping between entry  priority to client number (0,1,2 -debug and
1152          * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
1153          * 3bits client num.
1154          *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1155          * cos1-100     cos0-011     dbg1-010     dbg0-001     MCP-000
1156          */
1157
1158         REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
1159         /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1160          * as strict.  Bits 0,1,2 - debug and management entries, 3 -
1161          * COS0 entry, 4 - COS1 entry.
1162          * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
1163          * bit4   bit3    bit2   bit1     bit0
1164          * MCP and debug are strict
1165          */
1166
1167         REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
1168         /* defines which entries (clients) are subjected to WFQ arbitration */
1169         REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
1170         /* For strict priority entries defines the number of consecutive
1171          * slots for the highest priority.
1172          */
1173         REG_WR(sc, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
1174         /* mapping between the CREDIT_WEIGHT registers and actual client
1175          * numbers
1176          */
1177         REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
1178         REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
1179         REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
1180
1181         REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
1182         REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
1183         REG_WR(sc, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
1184         /* ETS mode disable */
1185         REG_WR(sc, PBF_REG_ETS_ENABLED, 0);
1186         /* If ETS mode is enabled (there is no strict priority) defines a WFQ
1187          * weight for COS0/COS1.
1188          */
1189         REG_WR(sc, PBF_REG_COS0_WEIGHT, 0x2710);
1190         REG_WR(sc, PBF_REG_COS1_WEIGHT, 0x2710);
1191         /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
1192         REG_WR(sc, PBF_REG_COS0_UPPER_BOUND, 0x989680);
1193         REG_WR(sc, PBF_REG_COS1_UPPER_BOUND, 0x989680);
1194         /* Defines the number of consecutive slots for the strict priority */
1195         REG_WR(sc, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
1196 }
1197 /******************************************************************************
1198 * Description:
1199 *       Getting min_w_val will be set according to line speed .
1200 *.
1201 ******************************************************************************/
1202 static uint32_t elink_ets_get_min_w_val_nig(const struct elink_vars *vars)
1203 {
1204         uint32_t min_w_val = 0;
1205         /* Calculate min_w_val.*/
1206         if (vars->link_up) {
1207                 if (vars->line_speed == ELINK_SPEED_20000)
1208                         min_w_val = ELINK_ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
1209                 else
1210                         min_w_val = ELINK_ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS;
1211         } else
1212                 min_w_val = ELINK_ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
1213         /* If the link isn't up (static configuration for example ) The
1214          * link will be according to 20GBPS.
1215          */
1216         return min_w_val;
1217 }
1218 /******************************************************************************
1219 * Description:
1220 *       Getting credit upper bound form min_w_val.
1221 *.
1222 ******************************************************************************/
1223 static uint32_t elink_ets_get_credit_upper_bound(const uint32_t min_w_val)
1224 {
1225         const uint32_t credit_upper_bound = (uint32_t)ELINK_MAXVAL((150 * min_w_val),
1226                                                 ELINK_MAX_PACKET_SIZE);
1227         return credit_upper_bound;
1228 }
1229 /******************************************************************************
1230 * Description:
1231 *       Set credit upper bound for NIG.
1232 *.
1233 ******************************************************************************/
1234 static void elink_ets_e3b0_set_credit_upper_bound_nig(
1235         const struct elink_params *params,
1236         const uint32_t min_w_val)
1237 {
1238         struct bxe_softc *sc = params->sc;
1239         const uint8_t port = params->port;
1240         const uint32_t credit_upper_bound =
1241             elink_ets_get_credit_upper_bound(min_w_val);
1242
1243         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_0 :
1244                 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, credit_upper_bound);
1245         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_1 :
1246                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, credit_upper_bound);
1247         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_2 :
1248                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_2, credit_upper_bound);
1249         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_3 :
1250                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_3, credit_upper_bound);
1251         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_4 :
1252                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_4, credit_upper_bound);
1253         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_5 :
1254                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_5, credit_upper_bound);
1255
1256         if (!port) {
1257                 REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_6,
1258                         credit_upper_bound);
1259                 REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_7,
1260                         credit_upper_bound);
1261                 REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_8,
1262                         credit_upper_bound);
1263         }
1264 }
1265 /******************************************************************************
1266 * Description:
1267 *       Will return the NIG ETS registers to init values.Except
1268 *       credit_upper_bound.
1269 *       That isn't used in this configuration (No WFQ is enabled) and will be
1270 *       configured acording to spec
1271 *.
1272 ******************************************************************************/
1273 static void elink_ets_e3b0_nig_disabled(const struct elink_params *params,
1274                                         const struct elink_vars *vars)
1275 {
1276         struct bxe_softc *sc = params->sc;
1277         const uint8_t port = params->port;
1278         const uint32_t min_w_val = elink_ets_get_min_w_val_nig(vars);
1279         /* Mapping between entry  priority to client number (0,1,2 -debug and
1280          * management clients, 3 - COS0 client, 4 - COS1, ... 8 -
1281          * COS5)(HIGHEST) 4bits client num.TODO_ETS - Should be done by
1282          * reset value or init tool
1283          */
1284         if (port) {
1285                 REG_WR(sc, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB, 0x543210);
1286                 REG_WR(sc, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB, 0x0);
1287         } else {
1288                 REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, 0x76543210);
1289                 REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, 0x8);
1290         }
1291         /* For strict priority entries defines the number of consecutive
1292          * slots for the highest priority.
1293          */
1294         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS :
1295                    NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
1296         /* Mapping between the CREDIT_WEIGHT registers and actual client
1297          * numbers
1298          */
1299         if (port) {
1300                 /*Port 1 has 6 COS*/
1301                 REG_WR(sc, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB, 0x210543);
1302                 REG_WR(sc, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x0);
1303         } else {
1304                 /*Port 0 has 9 COS*/
1305                 REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_LSB,
1306                        0x43210876);
1307                 REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x5);
1308         }
1309
1310         /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1311          * as strict.  Bits 0,1,2 - debug and management entries, 3 -
1312          * COS0 entry, 4 - COS1 entry.
1313          * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
1314          * bit4   bit3    bit2   bit1     bit0
1315          * MCP and debug are strict
1316          */
1317         if (port)
1318                 REG_WR(sc, NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT, 0x3f);
1319         else
1320                 REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1ff);
1321         /* defines which entries (clients) are subjected to WFQ arbitration */
1322         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
1323                    NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
1324
1325         /* Please notice the register address are note continuous and a
1326          * for here is note appropriate.In 2 port mode port0 only COS0-5
1327          * can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4
1328          * port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT
1329          * are never used for WFQ
1330          */
1331         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
1332                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0x0);
1333         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
1334                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0x0);
1335         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
1336                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2, 0x0);
1337         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_3 :
1338                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3, 0x0);
1339         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_4 :
1340                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4, 0x0);
1341         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_5 :
1342                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5, 0x0);
1343         if (!port) {
1344                 REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_6, 0x0);
1345                 REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_7, 0x0);
1346                 REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_8, 0x0);
1347         }
1348
1349         elink_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val);
1350 }
1351 /******************************************************************************
1352 * Description:
1353 *       Set credit upper bound for PBF.
1354 *.
1355 ******************************************************************************/
1356 static void elink_ets_e3b0_set_credit_upper_bound_pbf(
1357         const struct elink_params *params,
1358         const uint32_t min_w_val)
1359 {
1360         struct bxe_softc *sc = params->sc;
1361         const uint32_t credit_upper_bound =
1362             elink_ets_get_credit_upper_bound(min_w_val);
1363         const uint8_t port = params->port;
1364         uint32_t base_upper_bound = 0;
1365         uint8_t max_cos = 0;
1366         uint8_t i = 0;
1367         /* In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4
1368          * port mode port1 has COS0-2 that can be used for WFQ.
1369          */
1370         if (!port) {
1371                 base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P0;
1372                 max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1373         } else {
1374                 base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P1;
1375                 max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1;
1376         }
1377
1378         for (i = 0; i < max_cos; i++)
1379                 REG_WR(sc, base_upper_bound + (i << 2), credit_upper_bound);
1380 }
1381
1382 /******************************************************************************
1383 * Description:
1384 *       Will return the PBF ETS registers to init values.Except
1385 *       credit_upper_bound.
1386 *       That isn't used in this configuration (No WFQ is enabled) and will be
1387 *       configured acording to spec
1388 *.
1389 ******************************************************************************/
1390 static void elink_ets_e3b0_pbf_disabled(const struct elink_params *params)
1391 {
1392         struct bxe_softc *sc = params->sc;
1393         const uint8_t port = params->port;
1394         const uint32_t min_w_val_pbf = ELINK_ETS_E3B0_PBF_MIN_W_VAL;
1395         uint8_t i = 0;
1396         uint32_t base_weight = 0;
1397         uint8_t max_cos = 0;
1398
1399         /* Mapping between entry  priority to client number 0 - COS0
1400          * client, 2 - COS1, ... 5 - COS5)(HIGHEST) 4bits client num.
1401          * TODO_ETS - Should be done by reset value or init tool
1402          */
1403         if (port)
1404                 /*  0x688 (|011|0 10|00 1|000) */
1405                 REG_WR(sc, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , 0x688);
1406         else
1407                 /*  (10 1|100 |011|0 10|00 1|000) */
1408                 REG_WR(sc, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , 0x2C688);
1409
1410         /* TODO_ETS - Should be done by reset value or init tool */
1411         if (port)
1412                 /* 0x688 (|011|0 10|00 1|000)*/
1413                 REG_WR(sc, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P1, 0x688);
1414         else
1415         /* 0x2C688 (10 1|100 |011|0 10|00 1|000) */
1416         REG_WR(sc, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P0, 0x2C688);
1417
1418         REG_WR(sc, (port) ? PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P1 :
1419                    PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P0 , 0x100);
1420
1421
1422         REG_WR(sc, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
1423                    PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , 0);
1424
1425         REG_WR(sc, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
1426                    PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0 , 0);
1427         /* In 2 port mode port0 has COS0-5 that can be used for WFQ.
1428          * In 4 port mode port1 has COS0-2 that can be used for WFQ.
1429          */
1430         if (!port) {
1431                 base_weight = PBF_REG_COS0_WEIGHT_P0;
1432                 max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1433         } else {
1434                 base_weight = PBF_REG_COS0_WEIGHT_P1;
1435                 max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1;
1436         }
1437
1438         for (i = 0; i < max_cos; i++)
1439                 REG_WR(sc, base_weight + (0x4 * i), 0);
1440
1441         elink_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
1442 }
1443 /******************************************************************************
1444 * Description:
1445 *       E3B0 disable will return basicly the values to init values.
1446 *.
1447 ******************************************************************************/
1448 static elink_status_t elink_ets_e3b0_disabled(const struct elink_params *params,
1449                                    const struct elink_vars *vars)
1450 {
1451         struct bxe_softc *sc = params->sc;
1452
1453         if (!CHIP_IS_E3B0(sc)) {
1454                 ELINK_DEBUG_P0(sc,
1455                    "elink_ets_e3b0_disabled the chip isn't E3B0\n");
1456                 return ELINK_STATUS_ERROR;
1457         }
1458
1459         elink_ets_e3b0_nig_disabled(params, vars);
1460
1461         elink_ets_e3b0_pbf_disabled(params);
1462
1463         return ELINK_STATUS_OK;
1464 }
1465
1466 /******************************************************************************
1467 * Description:
1468 *       Disable will return basicly the values to init values.
1469 *
1470 ******************************************************************************/
1471 elink_status_t elink_ets_disabled(struct elink_params *params,
1472                       struct elink_vars *vars)
1473 {
1474         struct bxe_softc *sc = params->sc;
1475         elink_status_t elink_status = ELINK_STATUS_OK;
1476
1477         if ((CHIP_IS_E2(sc)) || (CHIP_IS_E3A0(sc)))
1478                 elink_ets_e2e3a0_disabled(params);
1479         else if (CHIP_IS_E3B0(sc))
1480                 elink_status = elink_ets_e3b0_disabled(params, vars);
1481         else {
1482                 ELINK_DEBUG_P0(sc, "elink_ets_disabled - chip not supported\n");
1483                 return ELINK_STATUS_ERROR;
1484         }
1485
1486         return elink_status;
1487 }
1488
1489 /******************************************************************************
1490 * Description
1491 *       Set the COS mappimg to SP and BW until this point all the COS are not
1492 *       set as SP or BW.
1493 ******************************************************************************/
1494 static elink_status_t elink_ets_e3b0_cli_map(const struct elink_params *params,
1495                                   const struct elink_ets_params *ets_params,
1496                                   const uint8_t cos_sp_bitmap,
1497                                   const uint8_t cos_bw_bitmap)
1498 {
1499         struct bxe_softc *sc = params->sc;
1500         const uint8_t port = params->port;
1501         const uint8_t nig_cli_sp_bitmap = 0x7 | (cos_sp_bitmap << 3);
1502         const uint8_t pbf_cli_sp_bitmap = cos_sp_bitmap;
1503         const uint8_t nig_cli_subject2wfq_bitmap = cos_bw_bitmap << 3;
1504         const uint8_t pbf_cli_subject2wfq_bitmap = cos_bw_bitmap;
1505
1506         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT :
1507                NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, nig_cli_sp_bitmap);
1508
1509         REG_WR(sc, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
1510                PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , pbf_cli_sp_bitmap);
1511
1512         REG_WR(sc, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
1513                NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ,
1514                nig_cli_subject2wfq_bitmap);
1515
1516         REG_WR(sc, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
1517                PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0,
1518                pbf_cli_subject2wfq_bitmap);
1519
1520         return ELINK_STATUS_OK;
1521 }
1522
1523 /******************************************************************************
1524 * Description:
1525 *       This function is needed because NIG ARB_CREDIT_WEIGHT_X are
1526 *       not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
1527 ******************************************************************************/
1528 static elink_status_t elink_ets_e3b0_set_cos_bw(struct bxe_softc *sc,
1529                                      const uint8_t cos_entry,
1530                                      const uint32_t min_w_val_nig,
1531                                      const uint32_t min_w_val_pbf,
1532                                      const uint16_t total_bw,
1533                                      const uint8_t bw,
1534                                      const uint8_t port)
1535 {
1536         uint32_t nig_reg_adress_crd_weight = 0;
1537         uint32_t pbf_reg_adress_crd_weight = 0;
1538         /* Calculate and set BW for this COS - use 1 instead of 0 for BW */
1539         const uint32_t cos_bw_nig = ((bw ? bw : 1) * min_w_val_nig) / total_bw;
1540         const uint32_t cos_bw_pbf = ((bw ? bw : 1) * min_w_val_pbf) / total_bw;
1541
1542         switch (cos_entry) {
1543         case 0:
1544             nig_reg_adress_crd_weight =
1545                  (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
1546                      NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0;
1547              pbf_reg_adress_crd_weight = (port) ?
1548                  PBF_REG_COS0_WEIGHT_P1 : PBF_REG_COS0_WEIGHT_P0;
1549              break;
1550         case 1:
1551              nig_reg_adress_crd_weight = (port) ?
1552                  NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
1553                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1;
1554              pbf_reg_adress_crd_weight = (port) ?
1555                  PBF_REG_COS1_WEIGHT_P1 : PBF_REG_COS1_WEIGHT_P0;
1556              break;
1557         case 2:
1558              nig_reg_adress_crd_weight = (port) ?
1559                  NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
1560                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2;
1561
1562                  pbf_reg_adress_crd_weight = (port) ?
1563                      PBF_REG_COS2_WEIGHT_P1 : PBF_REG_COS2_WEIGHT_P0;
1564              break;
1565         case 3:
1566             if (port)
1567                         return ELINK_STATUS_ERROR;
1568              nig_reg_adress_crd_weight =
1569                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3;
1570              pbf_reg_adress_crd_weight =
1571                  PBF_REG_COS3_WEIGHT_P0;
1572              break;
1573         case 4:
1574             if (port)
1575                 return ELINK_STATUS_ERROR;
1576              nig_reg_adress_crd_weight =
1577                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4;
1578              pbf_reg_adress_crd_weight = PBF_REG_COS4_WEIGHT_P0;
1579              break;
1580         case 5:
1581             if (port)
1582                 return ELINK_STATUS_ERROR;
1583              nig_reg_adress_crd_weight =
1584                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5;
1585              pbf_reg_adress_crd_weight = PBF_REG_COS5_WEIGHT_P0;
1586              break;
1587         }
1588
1589         REG_WR(sc, nig_reg_adress_crd_weight, cos_bw_nig);
1590
1591         REG_WR(sc, pbf_reg_adress_crd_weight, cos_bw_pbf);
1592
1593         return ELINK_STATUS_OK;
1594 }
1595 /******************************************************************************
1596 * Description:
1597 *       Calculate the total BW.A value of 0 isn't legal.
1598 *
1599 ******************************************************************************/
1600 static elink_status_t elink_ets_e3b0_get_total_bw(
1601         const struct elink_params *params,
1602         struct elink_ets_params *ets_params,
1603         uint16_t *total_bw)
1604 {
1605         struct bxe_softc *sc = params->sc;
1606         uint8_t cos_idx = 0;
1607         uint8_t is_bw_cos_exist = 0;
1608
1609         *total_bw = 0 ;
1610         /* Calculate total BW requested */
1611         for (cos_idx = 0; cos_idx < ets_params->num_of_cos; cos_idx++) {
1612                 if (ets_params->cos[cos_idx].state == elink_cos_state_bw) {
1613                         is_bw_cos_exist = 1;
1614                         if (!ets_params->cos[cos_idx].params.bw_params.bw) {
1615                                 ELINK_DEBUG_P0(sc, "elink_ets_E3B0_config BW"
1616                                                    "was set to 0\n");
1617                                 /* This is to prevent a state when ramrods
1618                                  * can't be sent
1619                                  */
1620                                 ets_params->cos[cos_idx].params.bw_params.bw
1621                                          = 1;
1622                         }
1623                         *total_bw +=
1624                                 ets_params->cos[cos_idx].params.bw_params.bw;
1625                 }
1626         }
1627
1628         /* Check total BW is valid */
1629         if ((is_bw_cos_exist == 1) && (*total_bw != 100)) {
1630                 if (*total_bw == 0) {
1631                         ELINK_DEBUG_P0(sc,
1632                            "elink_ets_E3B0_config total BW shouldn't be 0\n");
1633                         return ELINK_STATUS_ERROR;
1634                 }
1635                 ELINK_DEBUG_P0(sc,
1636                    "elink_ets_E3B0_config total BW should be 100\n");
1637                 /* We can handle a case whre the BW isn't 100 this can happen
1638                  * if the TC are joined.
1639                  */
1640         }
1641         return ELINK_STATUS_OK;
1642 }
1643
1644 /******************************************************************************
1645 * Description:
1646 *       Invalidate all the sp_pri_to_cos.
1647 *
1648 ******************************************************************************/
1649 static void elink_ets_e3b0_sp_pri_to_cos_init(uint8_t *sp_pri_to_cos)
1650 {
1651         uint8_t pri = 0;
1652         for (pri = 0; pri < ELINK_DCBX_MAX_NUM_COS; pri++)
1653                 sp_pri_to_cos[pri] = DCBX_INVALID_COS;
1654 }
1655 /******************************************************************************
1656 * Description:
1657 *       Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
1658 *       according to sp_pri_to_cos.
1659 *
1660 ******************************************************************************/
1661 static elink_status_t elink_ets_e3b0_sp_pri_to_cos_set(const struct elink_params *params,
1662                                             uint8_t *sp_pri_to_cos, const uint8_t pri,
1663                                             const uint8_t cos_entry)
1664 {
1665         struct bxe_softc *sc = params->sc;
1666         const uint8_t port = params->port;
1667         const uint8_t max_num_of_cos = (port) ? ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1 :
1668                 ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1669
1670         if (pri >= max_num_of_cos) {
1671                 ELINK_DEBUG_P0(sc, "elink_ets_e3b0_sp_pri_to_cos_set invalid "
1672                    "parameter Illegal strict priority\n");
1673             return ELINK_STATUS_ERROR;
1674         }
1675
1676         if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) {
1677                 ELINK_DEBUG_P0(sc, "elink_ets_e3b0_sp_pri_to_cos_set invalid "
1678                                    "parameter There can't be two COS's with "
1679                                    "the same strict pri\n");
1680                 return ELINK_STATUS_ERROR;
1681         }
1682
1683         sp_pri_to_cos[pri] = cos_entry;
1684         return ELINK_STATUS_OK;
1685
1686 }
1687
1688 /******************************************************************************
1689 * Description:
1690 *       Returns the correct value according to COS and priority in
1691 *       the sp_pri_cli register.
1692 *
1693 ******************************************************************************/
1694 static uint64_t elink_e3b0_sp_get_pri_cli_reg(const uint8_t cos, const uint8_t cos_offset,
1695                                          const uint8_t pri_set,
1696                                          const uint8_t pri_offset,
1697                                          const uint8_t entry_size)
1698 {
1699         uint64_t pri_cli_nig = 0;
1700         pri_cli_nig = ((uint64_t)(cos + cos_offset)) << (entry_size *
1701                                                     (pri_set + pri_offset));
1702
1703         return pri_cli_nig;
1704 }
1705 /******************************************************************************
1706 * Description:
1707 *       Returns the correct value according to COS and priority in the
1708 *       sp_pri_cli register for NIG.
1709 *
1710 ******************************************************************************/
1711 static uint64_t elink_e3b0_sp_get_pri_cli_reg_nig(const uint8_t cos, const uint8_t pri_set)
1712 {
1713         /* MCP Dbg0 and dbg1 are always with higher strict pri*/
1714         const uint8_t nig_cos_offset = 3;
1715         const uint8_t nig_pri_offset = 3;
1716
1717         return elink_e3b0_sp_get_pri_cli_reg(cos, nig_cos_offset, pri_set,
1718                 nig_pri_offset, 4);
1719
1720 }
1721 /******************************************************************************
1722 * Description:
1723 *       Returns the correct value according to COS and priority in the
1724 *       sp_pri_cli register for PBF.
1725 *
1726 ******************************************************************************/
1727 static uint64_t elink_e3b0_sp_get_pri_cli_reg_pbf(const uint8_t cos, const uint8_t pri_set)
1728 {
1729         const uint8_t pbf_cos_offset = 0;
1730         const uint8_t pbf_pri_offset = 0;
1731
1732         return elink_e3b0_sp_get_pri_cli_reg(cos, pbf_cos_offset, pri_set,
1733                 pbf_pri_offset, 3);
1734
1735 }
1736
1737 /******************************************************************************
1738 * Description:
1739 *       Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
1740 *       according to sp_pri_to_cos.(which COS has higher priority)
1741 *
1742 ******************************************************************************/
1743 static elink_status_t elink_ets_e3b0_sp_set_pri_cli_reg(const struct elink_params *params,
1744                                              uint8_t *sp_pri_to_cos)
1745 {
1746         struct bxe_softc *sc = params->sc;
1747         uint8_t i = 0;
1748         const uint8_t port = params->port;
1749         /* MCP Dbg0 and dbg1 are always with higher strict pri*/
1750         uint64_t pri_cli_nig = 0x210;
1751         uint32_t pri_cli_pbf = 0x0;
1752         uint8_t pri_set = 0;
1753         uint8_t pri_bitmask = 0;
1754         const uint8_t max_num_of_cos = (port) ? ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1 :
1755                 ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1756
1757         uint8_t cos_bit_to_set = (1 << max_num_of_cos) - 1;
1758
1759         /* Set all the strict priority first */
1760         for (i = 0; i < max_num_of_cos; i++) {
1761                 if (sp_pri_to_cos[i] != DCBX_INVALID_COS) {
1762                         if (sp_pri_to_cos[i] >= ELINK_DCBX_MAX_NUM_COS) {
1763                                 ELINK_DEBUG_P0(sc,
1764                                            "elink_ets_e3b0_sp_set_pri_cli_reg "
1765                                            "invalid cos entry\n");
1766                                 return ELINK_STATUS_ERROR;
1767                         }
1768
1769                         pri_cli_nig |= elink_e3b0_sp_get_pri_cli_reg_nig(
1770                             sp_pri_to_cos[i], pri_set);
1771
1772                         pri_cli_pbf |= elink_e3b0_sp_get_pri_cli_reg_pbf(
1773                             sp_pri_to_cos[i], pri_set);
1774                         pri_bitmask = 1 << sp_pri_to_cos[i];
1775                         /* COS is used remove it from bitmap.*/
1776                         if (!(pri_bitmask & cos_bit_to_set)) {
1777                                 ELINK_DEBUG_P0(sc,
1778                                         "elink_ets_e3b0_sp_set_pri_cli_reg "
1779                                         "invalid There can't be two COS's with"
1780                                         " the same strict pri\n");
1781                                 return ELINK_STATUS_ERROR;
1782                         }
1783                         cos_bit_to_set &= ~pri_bitmask;
1784                         pri_set++;
1785                 }
1786         }
1787
1788         /* Set all the Non strict priority i= COS*/
1789         for (i = 0; i < max_num_of_cos; i++) {
1790                 pri_bitmask = 1 << i;
1791                 /* Check if COS was already used for SP */
1792                 if (pri_bitmask & cos_bit_to_set) {
1793                         /* COS wasn't used for SP */
1794                         pri_cli_nig |= elink_e3b0_sp_get_pri_cli_reg_nig(
1795                             i, pri_set);
1796
1797                         pri_cli_pbf |= elink_e3b0_sp_get_pri_cli_reg_pbf(
1798                             i, pri_set);
1799                         /* COS is used remove it from bitmap.*/
1800                         cos_bit_to_set &= ~pri_bitmask;
1801                         pri_set++;
1802                 }
1803         }
1804
1805         if (pri_set != max_num_of_cos) {
1806                 ELINK_DEBUG_P0(sc, "elink_ets_e3b0_sp_set_pri_cli_reg not all "
1807                                    "entries were set\n");
1808                 return ELINK_STATUS_ERROR;
1809         }
1810
1811         if (port) {
1812                 /* Only 6 usable clients*/
1813                 REG_WR(sc, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB,
1814                        (uint32_t)pri_cli_nig);
1815
1816                 REG_WR(sc, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , pri_cli_pbf);
1817         } else {
1818                 /* Only 9 usable clients*/
1819                 const uint32_t pri_cli_nig_lsb = (uint32_t) (pri_cli_nig);
1820                 const uint32_t pri_cli_nig_msb = (uint32_t) ((pri_cli_nig >> 32) & 0xF);
1821
1822                 REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB,
1823                        pri_cli_nig_lsb);
1824                 REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB,
1825                        pri_cli_nig_msb);
1826
1827                 REG_WR(sc, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , pri_cli_pbf);
1828         }
1829         return ELINK_STATUS_OK;
1830 }
1831
1832 /******************************************************************************
1833 * Description:
1834 *       Configure the COS to ETS according to BW and SP settings.
1835 ******************************************************************************/
1836 elink_status_t elink_ets_e3b0_config(const struct elink_params *params,
1837                          const struct elink_vars *vars,
1838                          struct elink_ets_params *ets_params)
1839 {
1840         struct bxe_softc *sc = params->sc;
1841         elink_status_t elink_status = ELINK_STATUS_OK;
1842         const uint8_t port = params->port;
1843         uint16_t total_bw = 0;
1844         const uint32_t min_w_val_nig = elink_ets_get_min_w_val_nig(vars);
1845         const uint32_t min_w_val_pbf = ELINK_ETS_E3B0_PBF_MIN_W_VAL;
1846         uint8_t cos_bw_bitmap = 0;
1847         uint8_t cos_sp_bitmap = 0;
1848         uint8_t sp_pri_to_cos[ELINK_DCBX_MAX_NUM_COS] = {0};
1849         const uint8_t max_num_of_cos = (port) ? ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1 :
1850                 ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1851         uint8_t cos_entry = 0;
1852
1853         if (!CHIP_IS_E3B0(sc)) {
1854                 ELINK_DEBUG_P0(sc,
1855                    "elink_ets_e3b0_disabled the chip isn't E3B0\n");
1856                 return ELINK_STATUS_ERROR;
1857         }
1858
1859         if ((ets_params->num_of_cos > max_num_of_cos)) {
1860                 ELINK_DEBUG_P0(sc, "elink_ets_E3B0_config the number of COS "
1861                                    "isn't supported\n");
1862                 return ELINK_STATUS_ERROR;
1863         }
1864
1865         /* Prepare sp strict priority parameters*/
1866         elink_ets_e3b0_sp_pri_to_cos_init(sp_pri_to_cos);
1867
1868         /* Prepare BW parameters*/
1869         elink_status = elink_ets_e3b0_get_total_bw(params, ets_params,
1870                                                    &total_bw);
1871         if (elink_status != ELINK_STATUS_OK) {
1872                 ELINK_DEBUG_P0(sc,
1873                    "elink_ets_E3B0_config get_total_bw failed\n");
1874                 return ELINK_STATUS_ERROR;
1875         }
1876
1877         /* Upper bound is set according to current link speed (min_w_val
1878          * should be the same for upper bound and COS credit val).
1879          */
1880         elink_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val_nig);
1881         elink_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
1882
1883
1884         for (cos_entry = 0; cos_entry < ets_params->num_of_cos; cos_entry++) {
1885                 if (elink_cos_state_bw == ets_params->cos[cos_entry].state) {
1886                         cos_bw_bitmap |= (1 << cos_entry);
1887                         /* The function also sets the BW in HW(not the mappin
1888                          * yet)
1889                          */
1890                         elink_status = elink_ets_e3b0_set_cos_bw(
1891                                 sc, cos_entry, min_w_val_nig, min_w_val_pbf,
1892                                 total_bw,
1893                                 ets_params->cos[cos_entry].params.bw_params.bw,
1894                                  port);
1895                 } else if (elink_cos_state_strict ==
1896                         ets_params->cos[cos_entry].state){
1897                         cos_sp_bitmap |= (1 << cos_entry);
1898
1899                         elink_status = elink_ets_e3b0_sp_pri_to_cos_set(
1900                                 params,
1901                                 sp_pri_to_cos,
1902                                 ets_params->cos[cos_entry].params.sp_params.pri,
1903                                 cos_entry);
1904
1905                 } else {
1906                         ELINK_DEBUG_P0(sc,
1907                            "elink_ets_e3b0_config cos state not valid\n");
1908                         return ELINK_STATUS_ERROR;
1909                 }
1910                 if (elink_status != ELINK_STATUS_OK) {
1911                         ELINK_DEBUG_P0(sc,
1912                            "elink_ets_e3b0_config set cos bw failed\n");
1913                         return elink_status;
1914                 }
1915         }
1916
1917         /* Set SP register (which COS has higher priority) */
1918         elink_status = elink_ets_e3b0_sp_set_pri_cli_reg(params,
1919                                                          sp_pri_to_cos);
1920
1921         if (elink_status != ELINK_STATUS_OK) {
1922                 ELINK_DEBUG_P0(sc,
1923                    "elink_ets_E3B0_config set_pri_cli_reg failed\n");
1924                 return elink_status;
1925         }
1926
1927         /* Set client mapping of BW and strict */
1928         elink_status = elink_ets_e3b0_cli_map(params, ets_params,
1929                                               cos_sp_bitmap,
1930                                               cos_bw_bitmap);
1931
1932         if (elink_status != ELINK_STATUS_OK) {
1933                 ELINK_DEBUG_P0(sc, "elink_ets_E3B0_config SP failed\n");
1934                 return elink_status;
1935         }
1936         return ELINK_STATUS_OK;
1937 }
1938 static void elink_ets_bw_limit_common(const struct elink_params *params)
1939 {
1940         /* ETS disabled configuration */
1941         struct bxe_softc *sc = params->sc;
1942         ELINK_DEBUG_P0(sc, "ETS enabled BW limit configuration\n");
1943         /* Defines which entries (clients) are subjected to WFQ arbitration
1944          * COS0 0x8
1945          * COS1 0x10
1946          */
1947         REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
1948         /* Mapping between the ARB_CREDIT_WEIGHT registers and actual
1949          * client numbers (WEIGHT_0 does not actually have to represent
1950          * client 0)
1951          *    PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1952          *  cos1-001     cos0-000     dbg1-100     dbg0-011     MCP-010
1953          */
1954         REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
1955
1956         REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
1957                ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1958         REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
1959                ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1960
1961         /* ETS mode enabled*/
1962         REG_WR(sc, PBF_REG_ETS_ENABLED, 1);
1963
1964         /* Defines the number of consecutive slots for the strict priority */
1965         REG_WR(sc, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
1966         /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1967          * as strict.  Bits 0,1,2 - debug and management entries, 3 - COS0
1968          * entry, 4 - COS1 entry.
1969          * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1970          * bit4   bit3    bit2     bit1    bit0
1971          * MCP and debug are strict
1972          */
1973         REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
1974
1975         /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
1976         REG_WR(sc, PBF_REG_COS0_UPPER_BOUND,
1977                ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1978         REG_WR(sc, PBF_REG_COS1_UPPER_BOUND,
1979                ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1980 }
1981
1982 void elink_ets_bw_limit(const struct elink_params *params, const uint32_t cos0_bw,
1983                         const uint32_t cos1_bw)
1984 {
1985         /* ETS disabled configuration*/
1986         struct bxe_softc *sc = params->sc;
1987         const uint32_t total_bw = cos0_bw + cos1_bw;
1988         uint32_t cos0_credit_weight = 0;
1989         uint32_t cos1_credit_weight = 0;
1990
1991         ELINK_DEBUG_P0(sc, "ETS enabled BW limit configuration\n");
1992
1993         if ((!total_bw) ||
1994             (!cos0_bw) ||
1995             (!cos1_bw)) {
1996                 ELINK_DEBUG_P0(sc, "Total BW can't be zero\n");
1997                 return;
1998         }
1999
2000         cos0_credit_weight = (cos0_bw * ELINK_ETS_BW_LIMIT_CREDIT_WEIGHT)/
2001                 total_bw;
2002         cos1_credit_weight = (cos1_bw * ELINK_ETS_BW_LIMIT_CREDIT_WEIGHT)/
2003                 total_bw;
2004
2005         elink_ets_bw_limit_common(params);
2006
2007         REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
2008         REG_WR(sc, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
2009
2010         REG_WR(sc, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
2011         REG_WR(sc, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
2012 }
2013
2014 elink_status_t elink_ets_strict(const struct elink_params *params, const uint8_t strict_cos)
2015 {
2016         /* ETS disabled configuration*/
2017         struct bxe_softc *sc = params->sc;
2018         uint32_t val    = 0;
2019
2020         ELINK_DEBUG_P0(sc, "ETS enabled strict configuration\n");
2021         /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
2022          * as strict.  Bits 0,1,2 - debug and management entries,
2023          * 3 - COS0 entry, 4 - COS1 entry.
2024          *  COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
2025          *  bit4   bit3   bit2      bit1     bit0
2026          * MCP and debug are strict
2027          */
2028         REG_WR(sc, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
2029         /* For strict priority entries defines the number of consecutive slots
2030          * for the highest priority.
2031          */
2032         REG_WR(sc, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
2033         /* ETS mode disable */
2034         REG_WR(sc, PBF_REG_ETS_ENABLED, 0);
2035         /* Defines the number of consecutive slots for the strict priority */
2036         REG_WR(sc, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
2037
2038         /* Defines the number of consecutive slots for the strict priority */
2039         REG_WR(sc, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
2040
2041         /* Mapping between entry  priority to client number (0,1,2 -debug and
2042          * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
2043          * 3bits client num.
2044          *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
2045          * dbg0-010     dbg1-001     cos1-100     cos0-011     MCP-000
2046          * dbg0-010     dbg1-001     cos0-011     cos1-100     MCP-000
2047          */
2048         val = (!strict_cos) ? 0x2318 : 0x22E0;
2049         REG_WR(sc, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
2050
2051         return ELINK_STATUS_OK;
2052 }
2053
2054 /******************************************************************/
2055 /*                      PFC section                               */
2056 /******************************************************************/
2057 static void elink_update_pfc_xmac(struct elink_params *params,
2058                                   struct elink_vars *vars,
2059                                   uint8_t is_lb)
2060 {
2061         struct bxe_softc *sc = params->sc;
2062         uint32_t xmac_base;
2063         uint32_t pause_val, pfc0_val, pfc1_val;
2064
2065         /* XMAC base adrr */
2066         xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
2067
2068         /* Initialize pause and pfc registers */
2069         pause_val = 0x18000;
2070         pfc0_val = 0xFFFF8000;
2071         pfc1_val = 0x2;
2072
2073         /* No PFC support */
2074         if (!(params->feature_config_flags &
2075               ELINK_FEATURE_CONFIG_PFC_ENABLED)) {
2076
2077                 /* RX flow control - Process pause frame in receive direction
2078                  */
2079                 if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
2080                         pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN;
2081
2082                 /* TX flow control - Send pause packet when buffer is full */
2083                 if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
2084                         pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN;
2085         } else {/* PFC support */
2086                 pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN |
2087                         XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN |
2088                         XMAC_PFC_CTRL_HI_REG_RX_PFC_EN |
2089                         XMAC_PFC_CTRL_HI_REG_TX_PFC_EN |
2090                         XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
2091                 /* Write pause and PFC registers */
2092                 REG_WR(sc, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
2093                 REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
2094                 REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
2095                 pfc1_val &= ~XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
2096
2097         }
2098
2099         /* Write pause and PFC registers */
2100         REG_WR(sc, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
2101         REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
2102         REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
2103
2104
2105         /* Set MAC address for source TX Pause/PFC frames */
2106         REG_WR(sc, xmac_base + XMAC_REG_CTRL_SA_LO,
2107                ((params->mac_addr[2] << 24) |
2108                 (params->mac_addr[3] << 16) |
2109                 (params->mac_addr[4] << 8) |
2110                 (params->mac_addr[5])));
2111         REG_WR(sc, xmac_base + XMAC_REG_CTRL_SA_HI,
2112                ((params->mac_addr[0] << 8) |
2113                 (params->mac_addr[1])));
2114
2115         DELAY(30);
2116 }
2117
2118
2119 static void elink_emac_get_pfc_stat(struct elink_params *params,
2120                                     uint32_t pfc_frames_sent[2],
2121                                     uint32_t pfc_frames_received[2])
2122 {
2123         /* Read pfc statistic */
2124         struct bxe_softc *sc = params->sc;
2125         uint32_t emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2126         uint32_t val_xon = 0;
2127         uint32_t val_xoff = 0;
2128
2129         ELINK_DEBUG_P0(sc, "pfc statistic read from EMAC\n");
2130
2131         /* PFC received frames */
2132         val_xoff = REG_RD(sc, emac_base +
2133                                 EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
2134         val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
2135         val_xon = REG_RD(sc, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
2136         val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
2137
2138         pfc_frames_received[0] = val_xon + val_xoff;
2139
2140         /* PFC received sent */
2141         val_xoff = REG_RD(sc, emac_base +
2142                                 EMAC_REG_RX_PFC_STATS_XOFF_SENT);
2143         val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
2144         val_xon = REG_RD(sc, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
2145         val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
2146
2147         pfc_frames_sent[0] = val_xon + val_xoff;
2148 }
2149
2150 /* Read pfc statistic*/
2151 void elink_pfc_statistic(struct elink_params *params, struct elink_vars *vars,
2152                          uint32_t pfc_frames_sent[2],
2153                          uint32_t pfc_frames_received[2])
2154 {
2155         /* Read pfc statistic */
2156         struct bxe_softc *sc = params->sc;
2157
2158         ELINK_DEBUG_P0(sc, "pfc statistic\n");
2159
2160         if (!vars->link_up)
2161                 return;
2162
2163         if (vars->mac_type == ELINK_MAC_TYPE_EMAC) {
2164                 ELINK_DEBUG_P0(sc, "About to read PFC stats from EMAC\n");
2165                 elink_emac_get_pfc_stat(params, pfc_frames_sent,
2166                                         pfc_frames_received);
2167         }
2168 }
2169 /******************************************************************/
2170 /*                      MAC/PBF section                           */
2171 /******************************************************************/
2172 static void elink_set_mdio_clk(struct bxe_softc *sc, uint32_t chip_id,
2173                                uint32_t emac_base)
2174 {
2175         uint32_t new_mode, cur_mode;
2176         uint32_t clc_cnt;
2177         /* Set clause 45 mode, slow down the MDIO clock to 2.5MHz
2178          * (a value of 49==0x31) and make sure that the AUTO poll is off
2179          */
2180         cur_mode = REG_RD(sc, emac_base + EMAC_REG_EMAC_MDIO_MODE);
2181
2182         if (USES_WARPCORE(sc))
2183                 clc_cnt = 74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
2184         else
2185                 clc_cnt = 49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
2186
2187         if (((cur_mode & EMAC_MDIO_MODE_CLOCK_CNT) == clc_cnt) &&
2188             (cur_mode & (EMAC_MDIO_MODE_CLAUSE_45)))
2189                 return;
2190
2191         new_mode = cur_mode &
2192                 ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
2193         new_mode |= clc_cnt;
2194         new_mode |= (EMAC_MDIO_MODE_CLAUSE_45);
2195
2196         ELINK_DEBUG_P2(sc, "Changing emac_mode from 0x%x to 0x%x\n",
2197            cur_mode, new_mode);
2198         REG_WR(sc, emac_base + EMAC_REG_EMAC_MDIO_MODE, new_mode);
2199         DELAY(40);
2200 }
2201
2202 static void elink_set_mdio_emac_per_phy(struct bxe_softc *sc,
2203                                         struct elink_params *params)
2204 {
2205         uint8_t phy_index;
2206         /* Set mdio clock per phy */
2207         for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
2208               phy_index++)
2209                 elink_set_mdio_clk(sc, params->chip_id,
2210                                    params->phy[phy_index].mdio_ctrl);
2211 }
2212
2213 static uint8_t elink_is_4_port_mode(struct bxe_softc *sc)
2214 {
2215         uint32_t port4mode_ovwr_val;
2216         /* Check 4-port override enabled */
2217         port4mode_ovwr_val = REG_RD(sc, MISC_REG_PORT4MODE_EN_OVWR);
2218         if (port4mode_ovwr_val & (1<<0)) {
2219                 /* Return 4-port mode override value */
2220                 return ((port4mode_ovwr_val & (1<<1)) == (1<<1));
2221         }
2222         /* Return 4-port mode from input pin */
2223         return (uint8_t)REG_RD(sc, MISC_REG_PORT4MODE_EN);
2224 }
2225
2226 static void elink_emac_init(struct elink_params *params,
2227                             struct elink_vars *vars)
2228 {
2229         /* reset and unreset the emac core */
2230         struct bxe_softc *sc = params->sc;
2231         uint8_t port = params->port;
2232         uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2233         uint32_t val;
2234         uint16_t timeout;
2235
2236         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2237                (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
2238         DELAY(5);
2239         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2240                (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
2241
2242         /* init emac - use read-modify-write */
2243         /* self clear reset */
2244         val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
2245         elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
2246
2247         timeout = 200;
2248         do {
2249                 val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
2250                 ELINK_DEBUG_P1(sc, "EMAC reset reg is %u\n", val);
2251                 if (!timeout) {
2252                         ELINK_DEBUG_P0(sc, "EMAC timeout!\n");
2253                         return;
2254                 }
2255                 timeout--;
2256         } while (val & EMAC_MODE_RESET);
2257
2258         elink_set_mdio_emac_per_phy(sc, params);
2259         /* Set mac address */
2260         val = ((params->mac_addr[0] << 8) |
2261                 params->mac_addr[1]);
2262         elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MAC_MATCH, val);
2263
2264         val = ((params->mac_addr[2] << 24) |
2265                (params->mac_addr[3] << 16) |
2266                (params->mac_addr[4] << 8) |
2267                 params->mac_addr[5]);
2268         elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MAC_MATCH + 4, val);
2269 }
2270
2271 static void elink_set_xumac_nig(struct elink_params *params,
2272                                 uint16_t tx_pause_en,
2273                                 uint8_t enable)
2274 {
2275         struct bxe_softc *sc = params->sc;
2276
2277         REG_WR(sc, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN,
2278                enable);
2279         REG_WR(sc, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN,
2280                enable);
2281         REG_WR(sc, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN :
2282                NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
2283 }
2284
2285 static void elink_set_umac_rxtx(struct elink_params *params, uint8_t en)
2286 {
2287         uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
2288         uint32_t val;
2289         struct bxe_softc *sc = params->sc;
2290         if (!(REG_RD(sc, MISC_REG_RESET_REG_2) &
2291                    (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)))
2292                 return;
2293         val = REG_RD(sc, umac_base + UMAC_REG_COMMAND_CONFIG);
2294         if (en)
2295                 val |= (UMAC_COMMAND_CONFIG_REG_TX_ENA |
2296                         UMAC_COMMAND_CONFIG_REG_RX_ENA);
2297         else
2298                 val &= ~(UMAC_COMMAND_CONFIG_REG_TX_ENA |
2299                          UMAC_COMMAND_CONFIG_REG_RX_ENA);
2300         /* Disable RX and TX */
2301         REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
2302 }
2303
2304 static void elink_umac_enable(struct elink_params *params,
2305                             struct elink_vars *vars, uint8_t lb)
2306 {
2307         uint32_t val;
2308         uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
2309         struct bxe_softc *sc = params->sc;
2310         /* Reset UMAC */
2311         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2312                (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
2313         DELAY(1000 * 1);
2314
2315         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2316                (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
2317
2318         ELINK_DEBUG_P0(sc, "enabling UMAC\n");
2319
2320         /* This register opens the gate for the UMAC despite its name */
2321         REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
2322
2323         val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN |
2324                 UMAC_COMMAND_CONFIG_REG_PAD_EN |
2325                 UMAC_COMMAND_CONFIG_REG_SW_RESET |
2326                 UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK;
2327         switch (vars->line_speed) {
2328         case ELINK_SPEED_10:
2329                 val |= (0<<2);
2330                 break;
2331         case ELINK_SPEED_100:
2332                 val |= (1<<2);
2333                 break;
2334         case ELINK_SPEED_1000:
2335                 val |= (2<<2);
2336                 break;
2337         case ELINK_SPEED_2500:
2338                 val |= (3<<2);
2339                 break;
2340         default:
2341                 ELINK_DEBUG_P1(sc, "Invalid speed for UMAC %d\n",
2342                                vars->line_speed);
2343                 break;
2344         }
2345         if (!(vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2346                 val |= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE;
2347
2348         if (!(vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
2349                 val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE;
2350
2351         if (vars->duplex == DUPLEX_HALF)
2352                 val |= UMAC_COMMAND_CONFIG_REG_HD_ENA;
2353
2354         REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
2355         DELAY(50);
2356
2357         /* Configure UMAC for EEE */
2358         if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
2359                 ELINK_DEBUG_P0(sc, "configured UMAC for EEE\n");
2360                 REG_WR(sc, umac_base + UMAC_REG_UMAC_EEE_CTRL,
2361                        UMAC_UMAC_EEE_CTRL_REG_EEE_EN);
2362                 REG_WR(sc, umac_base + UMAC_REG_EEE_WAKE_TIMER, 0x11);
2363         } else {
2364                 REG_WR(sc, umac_base + UMAC_REG_UMAC_EEE_CTRL, 0x0);
2365         }
2366
2367         /* Set MAC address for source TX Pause/PFC frames (under SW reset) */
2368         REG_WR(sc, umac_base + UMAC_REG_MAC_ADDR0,
2369                ((params->mac_addr[2] << 24) |
2370                 (params->mac_addr[3] << 16) |
2371                 (params->mac_addr[4] << 8) |
2372                 (params->mac_addr[5])));
2373         REG_WR(sc, umac_base + UMAC_REG_MAC_ADDR1,
2374                ((params->mac_addr[0] << 8) |
2375                 (params->mac_addr[1])));
2376
2377         /* Enable RX and TX */
2378         val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN;
2379         val |= UMAC_COMMAND_CONFIG_REG_TX_ENA |
2380                 UMAC_COMMAND_CONFIG_REG_RX_ENA;
2381         REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
2382         DELAY(50);
2383
2384         /* Remove SW Reset */
2385         val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET;
2386
2387         /* Check loopback mode */
2388         if (lb)
2389                 val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA;
2390         REG_WR(sc, umac_base + UMAC_REG_COMMAND_CONFIG, val);
2391
2392         /* Maximum Frame Length (RW). Defines a 14-Bit maximum frame
2393          * length used by the MAC receive logic to check frames.
2394          */
2395         REG_WR(sc, umac_base + UMAC_REG_MAXFR, 0x2710);
2396         elink_set_xumac_nig(params,
2397                             ((vars->flow_ctrl & ELINK_FLOW_CTRL_TX) != 0), 1);
2398         vars->mac_type = ELINK_MAC_TYPE_UMAC;
2399
2400 }
2401
2402 /* Define the XMAC mode */
2403 static void elink_xmac_init(struct elink_params *params, uint32_t max_speed)
2404 {
2405         struct bxe_softc *sc = params->sc;
2406         uint32_t is_port4mode = elink_is_4_port_mode(sc);
2407
2408         /* In 4-port mode, need to set the mode only once, so if XMAC is
2409          * already out of reset, it means the mode has already been set,
2410          * and it must not* reset the XMAC again, since it controls both
2411          * ports of the path
2412          */
2413
2414         if (((CHIP_NUM(sc) == CHIP_NUM_57840_4_10) ||
2415              (CHIP_NUM(sc) == CHIP_NUM_57840_2_20) ||
2416              (CHIP_NUM(sc) == CHIP_NUM_57840_OBS)) &&
2417             is_port4mode &&
2418             (REG_RD(sc, MISC_REG_RESET_REG_2) &
2419              MISC_REGISTERS_RESET_REG_2_XMAC)) {
2420                 ELINK_DEBUG_P0(sc,
2421                    "XMAC already out of reset in 4-port mode\n");
2422                 return;
2423         }
2424
2425         /* Hard reset */
2426         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2427                MISC_REGISTERS_RESET_REG_2_XMAC);
2428         DELAY(1000 * 1);
2429
2430         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2431                MISC_REGISTERS_RESET_REG_2_XMAC);
2432         if (is_port4mode) {
2433                 ELINK_DEBUG_P0(sc, "Init XMAC to 2 ports x 10G per path\n");
2434
2435                 /* Set the number of ports on the system side to up to 2 */
2436                 REG_WR(sc, MISC_REG_XMAC_CORE_PORT_MODE, 1);
2437
2438                 /* Set the number of ports on the Warp Core to 10G */
2439                 REG_WR(sc, MISC_REG_XMAC_PHY_PORT_MODE, 3);
2440         } else {
2441                 /* Set the number of ports on the system side to 1 */
2442                 REG_WR(sc, MISC_REG_XMAC_CORE_PORT_MODE, 0);
2443                 if (max_speed == ELINK_SPEED_10000) {
2444                         ELINK_DEBUG_P0(sc,
2445                            "Init XMAC to 10G x 1 port per path\n");
2446                         /* Set the number of ports on the Warp Core to 10G */
2447                         REG_WR(sc, MISC_REG_XMAC_PHY_PORT_MODE, 3);
2448                 } else {
2449                         ELINK_DEBUG_P0(sc,
2450                            "Init XMAC to 20G x 2 ports per path\n");
2451                         /* Set the number of ports on the Warp Core to 20G */
2452                         REG_WR(sc, MISC_REG_XMAC_PHY_PORT_MODE, 1);
2453                 }
2454         }
2455         /* Soft reset */
2456         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2457                MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
2458         DELAY(1000 * 1);
2459
2460         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2461                MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
2462
2463 }
2464
2465 static void elink_set_xmac_rxtx(struct elink_params *params, uint8_t en)
2466 {
2467         uint8_t port = params->port;
2468         struct bxe_softc *sc = params->sc;
2469         uint32_t pfc_ctrl, xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
2470         uint32_t val;
2471
2472         if (REG_RD(sc, MISC_REG_RESET_REG_2) &
2473             MISC_REGISTERS_RESET_REG_2_XMAC) {
2474                 /* Send an indication to change the state in the NIG back to XON
2475                  * Clearing this bit enables the next set of this bit to get
2476                  * rising edge
2477                  */
2478                 pfc_ctrl = REG_RD(sc, xmac_base + XMAC_REG_PFC_CTRL_HI);
2479                 REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI,
2480                        (pfc_ctrl & ~(1<<1)));
2481                 REG_WR(sc, xmac_base + XMAC_REG_PFC_CTRL_HI,
2482                        (pfc_ctrl | (1<<1)));
2483                 ELINK_DEBUG_P1(sc, "Disable XMAC on port %x\n", port);
2484                 val = REG_RD(sc, xmac_base + XMAC_REG_CTRL);
2485                 if (en)
2486                         val |= (XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN);
2487                 else
2488                         val &= ~(XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN);
2489                 REG_WR(sc, xmac_base + XMAC_REG_CTRL, val);
2490         }
2491 }
2492
2493 static elink_status_t elink_xmac_enable(struct elink_params *params,
2494                              struct elink_vars *vars, uint8_t lb)
2495 {
2496         uint32_t val, xmac_base;
2497         struct bxe_softc *sc = params->sc;
2498         ELINK_DEBUG_P0(sc, "enabling XMAC\n");
2499
2500         xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
2501
2502         elink_xmac_init(params, vars->line_speed);
2503
2504         /* This register determines on which events the MAC will assert
2505          * error on the i/f to the NIG along w/ EOP.
2506          */
2507
2508         /* This register tells the NIG whether to send traffic to UMAC
2509          * or XMAC
2510          */
2511         REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0);
2512
2513         /* When XMAC is in XLGMII mode, disable sending idles for fault
2514          * detection.
2515          */
2516         if (!(params->phy[ELINK_INT_PHY].flags & ELINK_FLAGS_TX_ERROR_CHECK)) {
2517                 REG_WR(sc, xmac_base + XMAC_REG_RX_LSS_CTRL,
2518                        (XMAC_RX_LSS_CTRL_REG_LOCAL_FAULT_DISABLE |
2519                         XMAC_RX_LSS_CTRL_REG_REMOTE_FAULT_DISABLE));
2520                 REG_WR(sc, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
2521                 REG_WR(sc, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
2522                        XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
2523                        XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
2524         }
2525         /* Set Max packet size */
2526         REG_WR(sc, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710);
2527
2528         /* CRC append for Tx packets */
2529         REG_WR(sc, xmac_base + XMAC_REG_TX_CTRL, 0xC800);
2530
2531         /* update PFC */
2532         elink_update_pfc_xmac(params, vars, 0);
2533
2534         if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
2535                 ELINK_DEBUG_P0(sc, "Setting XMAC for EEE\n");
2536                 REG_WR(sc, xmac_base + XMAC_REG_EEE_TIMERS_HI, 0x1380008);
2537                 REG_WR(sc, xmac_base + XMAC_REG_EEE_CTRL, 0x1);
2538         } else {
2539                 REG_WR(sc, xmac_base + XMAC_REG_EEE_CTRL, 0x0);
2540         }
2541
2542         /* Enable TX and RX */
2543         val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
2544
2545         /* Set MAC in XLGMII mode for dual-mode */
2546         if ((vars->line_speed == ELINK_SPEED_20000) &&
2547             (params->phy[ELINK_INT_PHY].supported &
2548              ELINK_SUPPORTED_20000baseKR2_Full))
2549                 val |= XMAC_CTRL_REG_XLGMII_ALIGN_ENB;
2550
2551         /* Check loopback mode */
2552         if (lb)
2553                 val |= XMAC_CTRL_REG_LINE_LOCAL_LPBK;
2554         REG_WR(sc, xmac_base + XMAC_REG_CTRL, val);
2555         elink_set_xumac_nig(params,
2556                             ((vars->flow_ctrl & ELINK_FLOW_CTRL_TX) != 0), 1);
2557
2558         vars->mac_type = ELINK_MAC_TYPE_XMAC;
2559
2560         return ELINK_STATUS_OK;
2561 }
2562
2563 static elink_status_t elink_emac_enable(struct elink_params *params,
2564                              struct elink_vars *vars, uint8_t lb)
2565 {
2566         struct bxe_softc *sc = params->sc;
2567         uint8_t port = params->port;
2568         uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2569         uint32_t val;
2570
2571         ELINK_DEBUG_P0(sc, "enabling EMAC\n");
2572
2573         /* Disable BMAC */
2574         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2575                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2576
2577         /* enable emac and not bmac */
2578         REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
2579
2580 #ifdef ELINK_INCLUDE_EMUL
2581         /* for paladium */
2582         if (CHIP_REV_IS_EMUL(sc)) {
2583                 /* Use lane 1 (of lanes 0-3) */
2584                 REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
2585                 REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
2586         }
2587         /* for fpga */
2588         else
2589 #endif
2590 #ifdef ELINK_INCLUDE_FPGA
2591         if (CHIP_REV_IS_FPGA(sc)) {
2592                 /* Use lane 1 (of lanes 0-3) */
2593                 ELINK_DEBUG_P0(sc, "elink_emac_enable: Setting FPGA\n");
2594
2595                 REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
2596                 REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
2597         } else
2598 #endif
2599         /* ASIC */
2600         if (vars->phy_flags & PHY_XGXS_FLAG) {
2601                 uint32_t ser_lane = ((params->lane_config &
2602                                  PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
2603                                 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
2604
2605                 ELINK_DEBUG_P0(sc, "XGXS\n");
2606                 /* select the master lanes (out of 0-3) */
2607                 REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane);
2608                 /* select XGXS */
2609                 REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
2610
2611         } else { /* SerDes */
2612                 ELINK_DEBUG_P0(sc, "SerDes\n");
2613                 /* select SerDes */
2614                 REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
2615         }
2616
2617         elink_bits_en(sc, emac_base + EMAC_REG_EMAC_RX_MODE,
2618                       EMAC_RX_MODE_RESET);
2619         elink_bits_en(sc, emac_base + EMAC_REG_EMAC_TX_MODE,
2620                       EMAC_TX_MODE_RESET);
2621
2622 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
2623         if (CHIP_REV_IS_SLOW(sc)) {
2624                 /* config GMII mode */
2625                 val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
2626                 elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII));
2627         } else { /* ASIC */
2628 #endif
2629                 /* pause enable/disable */
2630                 elink_bits_dis(sc, emac_base + EMAC_REG_EMAC_RX_MODE,
2631                                EMAC_RX_MODE_FLOW_EN);
2632
2633                 elink_bits_dis(sc,  emac_base + EMAC_REG_EMAC_TX_MODE,
2634                                (EMAC_TX_MODE_EXT_PAUSE_EN |
2635                                 EMAC_TX_MODE_FLOW_EN));
2636                 if (!(params->feature_config_flags &
2637                       ELINK_FEATURE_CONFIG_PFC_ENABLED)) {
2638                         if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
2639                                 elink_bits_en(sc, emac_base +
2640                                               EMAC_REG_EMAC_RX_MODE,
2641                                               EMAC_RX_MODE_FLOW_EN);
2642
2643                         if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
2644                                 elink_bits_en(sc, emac_base +
2645                                               EMAC_REG_EMAC_TX_MODE,
2646                                               (EMAC_TX_MODE_EXT_PAUSE_EN |
2647                                                EMAC_TX_MODE_FLOW_EN));
2648                 } else
2649                         elink_bits_en(sc, emac_base + EMAC_REG_EMAC_TX_MODE,
2650                                       EMAC_TX_MODE_FLOW_EN);
2651 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
2652         }
2653 #endif
2654
2655         /* KEEP_VLAN_TAG, promiscuous */
2656         val = REG_RD(sc, emac_base + EMAC_REG_EMAC_RX_MODE);
2657         val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
2658
2659         /* Setting this bit causes MAC control frames (except for pause
2660          * frames) to be passed on for processing. This setting has no
2661          * affect on the operation of the pause frames. This bit effects
2662          * all packets regardless of RX Parser packet sorting logic.
2663          * Turn the PFC off to make sure we are in Xon state before
2664          * enabling it.
2665          */
2666         elink_cb_reg_write(sc, emac_base + EMAC_REG_RX_PFC_MODE, 0);
2667         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED) {
2668                 ELINK_DEBUG_P0(sc, "PFC is enabled\n");
2669                 /* Enable PFC again */
2670                 elink_cb_reg_write(sc, emac_base + EMAC_REG_RX_PFC_MODE,
2671                         EMAC_REG_RX_PFC_MODE_RX_EN |
2672                         EMAC_REG_RX_PFC_MODE_TX_EN |
2673                         EMAC_REG_RX_PFC_MODE_PRIORITIES);
2674
2675                 elink_cb_reg_write(sc, emac_base + EMAC_REG_RX_PFC_PARAM,
2676                         ((0x0101 <<
2677                           EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
2678                          (0x00ff <<
2679                           EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
2680                 val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
2681         }
2682         elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_RX_MODE, val);
2683
2684         /* Set Loopback */
2685         val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
2686         if (lb)
2687                 val |= 0x810;
2688         else
2689                 val &= ~0x810;
2690         elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MODE, val);
2691
2692         /* Enable emac */
2693         REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port*4, 1);
2694
2695         /* Enable emac for jumbo packets */
2696         elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_RX_MTU_SIZE,
2697                 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
2698                  (ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD)));
2699
2700         /* Strip CRC */
2701         REG_WR(sc, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
2702
2703         /* Disable the NIG in/out to the bmac */
2704         REG_WR(sc, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
2705         REG_WR(sc, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
2706         REG_WR(sc, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
2707
2708         /* Enable the NIG in/out to the emac */
2709         REG_WR(sc, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
2710         val = 0;
2711         if ((params->feature_config_flags &
2712               ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
2713             (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2714                 val = 1;
2715
2716         REG_WR(sc, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
2717         REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
2718
2719 #ifdef ELINK_INCLUDE_EMUL
2720         if (CHIP_REV_IS_EMUL(sc)) {
2721                 /* Take the BigMac out of reset */
2722                 REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2723                        (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2724
2725                 /* Enable access for bmac registers */
2726                 REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
2727         } else
2728 #endif
2729         REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
2730
2731         vars->mac_type = ELINK_MAC_TYPE_EMAC;
2732         return ELINK_STATUS_OK;
2733 }
2734
2735 static void elink_update_pfc_bmac1(struct elink_params *params,
2736                                    struct elink_vars *vars)
2737 {
2738         uint32_t wb_data[2];
2739         struct bxe_softc *sc = params->sc;
2740         uint32_t bmac_addr =  params->port ? NIG_REG_INGRESS_BMAC1_MEM :
2741                 NIG_REG_INGRESS_BMAC0_MEM;
2742
2743         uint32_t val = 0x14;
2744         if ((!(params->feature_config_flags &
2745               ELINK_FEATURE_CONFIG_PFC_ENABLED)) &&
2746                 (vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
2747                 /* Enable BigMAC to react on received Pause packets */
2748                 val |= (1<<5);
2749         wb_data[0] = val;
2750         wb_data[1] = 0;
2751         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
2752
2753         /* TX control */
2754         val = 0xc0;
2755         if (!(params->feature_config_flags &
2756               ELINK_FEATURE_CONFIG_PFC_ENABLED) &&
2757                 (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2758                 val |= 0x800000;
2759         wb_data[0] = val;
2760         wb_data[1] = 0;
2761         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
2762 }
2763
2764 static void elink_update_pfc_bmac2(struct elink_params *params,
2765                                    struct elink_vars *vars,
2766                                    uint8_t is_lb)
2767 {
2768         /* Set rx control: Strip CRC and enable BigMAC to relay
2769          * control packets to the system as well
2770          */
2771         uint32_t wb_data[2];
2772         struct bxe_softc *sc = params->sc;
2773         uint32_t bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
2774                 NIG_REG_INGRESS_BMAC0_MEM;
2775         uint32_t val = 0x14;
2776
2777         if ((!(params->feature_config_flags &
2778               ELINK_FEATURE_CONFIG_PFC_ENABLED)) &&
2779                 (vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
2780                 /* Enable BigMAC to react on received Pause packets */
2781                 val |= (1<<5);
2782         wb_data[0] = val;
2783         wb_data[1] = 0;
2784         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
2785         DELAY(30);
2786
2787         /* Tx control */
2788         val = 0xc0;
2789         if (!(params->feature_config_flags &
2790                                 ELINK_FEATURE_CONFIG_PFC_ENABLED) &&
2791             (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2792                 val |= 0x800000;
2793         wb_data[0] = val;
2794         wb_data[1] = 0;
2795         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
2796
2797         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED) {
2798                 ELINK_DEBUG_P0(sc, "PFC is enabled\n");
2799                 /* Enable PFC RX & TX & STATS and set 8 COS  */
2800                 wb_data[0] = 0x0;
2801                 wb_data[0] |= (1<<0);  /* RX */
2802                 wb_data[0] |= (1<<1);  /* TX */
2803                 wb_data[0] |= (1<<2);  /* Force initial Xon */
2804                 wb_data[0] |= (1<<3);  /* 8 cos */
2805                 wb_data[0] |= (1<<5);  /* STATS */
2806                 wb_data[1] = 0;
2807                 REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
2808                             wb_data, 2);
2809                 /* Clear the force Xon */
2810                 wb_data[0] &= ~(1<<2);
2811         } else {
2812                 ELINK_DEBUG_P0(sc, "PFC is disabled\n");
2813                 /* Disable PFC RX & TX & STATS and set 8 COS */
2814                 wb_data[0] = 0x8;
2815                 wb_data[1] = 0;
2816         }
2817
2818         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
2819
2820         /* Set Time (based unit is 512 bit time) between automatic
2821          * re-sending of PP packets amd enable automatic re-send of
2822          * Per-Priroity Packet as long as pp_gen is asserted and
2823          * pp_disable is low.
2824          */
2825         val = 0x8000;
2826         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
2827                 val |= (1<<16); /* enable automatic re-send */
2828
2829         wb_data[0] = val;
2830         wb_data[1] = 0;
2831         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
2832                     wb_data, 2);
2833
2834         /* mac control */
2835         val = 0x3; /* Enable RX and TX */
2836         if (is_lb) {
2837                 val |= 0x4; /* Local loopback */
2838                 ELINK_DEBUG_P0(sc, "enable bmac loopback\n");
2839         }
2840         /* When PFC enabled, Pass pause frames towards the NIG. */
2841         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
2842                 val |= ((1<<6)|(1<<5));
2843
2844         wb_data[0] = val;
2845         wb_data[1] = 0;
2846         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2847 }
2848
2849 /******************************************************************************
2850 * Description:
2851 *  This function is needed because NIG ARB_CREDIT_WEIGHT_X are
2852 *  not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
2853 ******************************************************************************/
2854 static elink_status_t elink_pfc_nig_rx_priority_mask(struct bxe_softc *sc,
2855                                            uint8_t cos_entry,
2856                                            uint32_t priority_mask, uint8_t port)
2857 {
2858         uint32_t nig_reg_rx_priority_mask_add = 0;
2859
2860         switch (cos_entry) {
2861         case 0:
2862              nig_reg_rx_priority_mask_add = (port) ?
2863                  NIG_REG_P1_RX_COS0_PRIORITY_MASK :
2864                  NIG_REG_P0_RX_COS0_PRIORITY_MASK;
2865              break;
2866         case 1:
2867             nig_reg_rx_priority_mask_add = (port) ?
2868                 NIG_REG_P1_RX_COS1_PRIORITY_MASK :
2869                 NIG_REG_P0_RX_COS1_PRIORITY_MASK;
2870             break;
2871         case 2:
2872             nig_reg_rx_priority_mask_add = (port) ?
2873                 NIG_REG_P1_RX_COS2_PRIORITY_MASK :
2874                 NIG_REG_P0_RX_COS2_PRIORITY_MASK;
2875             break;
2876         case 3:
2877             if (port)
2878                 return ELINK_STATUS_ERROR;
2879             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK;
2880             break;
2881         case 4:
2882             if (port)
2883                 return ELINK_STATUS_ERROR;
2884             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK;
2885             break;
2886         case 5:
2887             if (port)
2888                 return ELINK_STATUS_ERROR;
2889             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK;
2890             break;
2891         }
2892
2893         REG_WR(sc, nig_reg_rx_priority_mask_add, priority_mask);
2894
2895         return ELINK_STATUS_OK;
2896 }
2897 static void elink_update_mng(struct elink_params *params, uint32_t link_status)
2898 {
2899         struct bxe_softc *sc = params->sc;
2900
2901         REG_WR(sc, params->shmem_base +
2902                offsetof(struct shmem_region,
2903                         port_mb[params->port].link_status), link_status);
2904 }
2905
2906 static void elink_update_link_attr(struct elink_params *params, uint32_t link_attr)
2907 {
2908         struct bxe_softc *sc = params->sc;
2909
2910         if (SHMEM2_HAS(sc, link_attr_sync))
2911                 REG_WR(sc, params->shmem2_base +
2912                        offsetof(struct shmem2_region,
2913                                 link_attr_sync[params->port]), link_attr);
2914 }
2915
2916 static void elink_update_pfc_nig(struct elink_params *params,
2917                 struct elink_vars *vars,
2918                 struct elink_nig_brb_pfc_port_params *nig_params)
2919 {
2920         uint32_t xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
2921         uint32_t llfc_enable = 0, xcm_out_en = 0, hwpfc_enable = 0;
2922         uint32_t pkt_priority_to_cos = 0;
2923         struct bxe_softc *sc = params->sc;
2924         uint8_t port = params->port;
2925
2926         int set_pfc = params->feature_config_flags &
2927                 ELINK_FEATURE_CONFIG_PFC_ENABLED;
2928         ELINK_DEBUG_P0(sc, "updating pfc nig parameters\n");
2929
2930         /* When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
2931          * MAC control frames (that are not pause packets)
2932          * will be forwarded to the XCM.
2933          */
2934         xcm_mask = REG_RD(sc, port ? NIG_REG_LLH1_XCM_MASK :
2935                           NIG_REG_LLH0_XCM_MASK);
2936         /* NIG params will override non PFC params, since it's possible to
2937          * do transition from PFC to SAFC
2938          */
2939         if (set_pfc) {
2940                 pause_enable = 0;
2941                 llfc_out_en = 0;
2942                 llfc_enable = 0;
2943                 if (CHIP_IS_E3(sc))
2944                         ppp_enable = 0;
2945                 else
2946                         ppp_enable = 1;
2947                 xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2948                                      NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2949                 xcm_out_en = 0;
2950                 hwpfc_enable = 1;
2951         } else  {
2952                 if (nig_params) {
2953                         llfc_out_en = nig_params->llfc_out_en;
2954                         llfc_enable = nig_params->llfc_enable;
2955                         pause_enable = nig_params->pause_enable;
2956                 } else  /* Default non PFC mode - PAUSE */
2957                         pause_enable = 1;
2958
2959                 xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2960                         NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2961                 xcm_out_en = 1;
2962         }
2963
2964         if (CHIP_IS_E3(sc))
2965                 REG_WR(sc, port ? NIG_REG_BRB1_PAUSE_IN_EN :
2966                        NIG_REG_BRB0_PAUSE_IN_EN, pause_enable);
2967         REG_WR(sc, port ? NIG_REG_LLFC_OUT_EN_1 :
2968                NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
2969         REG_WR(sc, port ? NIG_REG_LLFC_ENABLE_1 :
2970                NIG_REG_LLFC_ENABLE_0, llfc_enable);
2971         REG_WR(sc, port ? NIG_REG_PAUSE_ENABLE_1 :
2972                NIG_REG_PAUSE_ENABLE_0, pause_enable);
2973
2974         REG_WR(sc, port ? NIG_REG_PPP_ENABLE_1 :
2975                NIG_REG_PPP_ENABLE_0, ppp_enable);
2976
2977         REG_WR(sc, port ? NIG_REG_LLH1_XCM_MASK :
2978                NIG_REG_LLH0_XCM_MASK, xcm_mask);
2979
2980         REG_WR(sc, port ? NIG_REG_LLFC_EGRESS_SRC_ENABLE_1 :
2981                NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
2982
2983         /* Output enable for RX_XCM # IF */
2984         REG_WR(sc, port ? NIG_REG_XCM1_OUT_EN :
2985                NIG_REG_XCM0_OUT_EN, xcm_out_en);
2986
2987         /* HW PFC TX enable */
2988         REG_WR(sc, port ? NIG_REG_P1_HWPFC_ENABLE :
2989                NIG_REG_P0_HWPFC_ENABLE, hwpfc_enable);
2990
2991         if (nig_params) {
2992                 uint8_t i = 0;
2993                 pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
2994
2995                 for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++)
2996                         elink_pfc_nig_rx_priority_mask(sc, i,
2997                 nig_params->rx_cos_priority_mask[i], port);
2998
2999                 REG_WR(sc, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
3000                        NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
3001                        nig_params->llfc_high_priority_classes);
3002
3003                 REG_WR(sc, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
3004                        NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
3005                        nig_params->llfc_low_priority_classes);
3006         }
3007         REG_WR(sc, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
3008                NIG_REG_P0_PKT_PRIORITY_TO_COS,
3009                pkt_priority_to_cos);
3010 }
3011
3012 elink_status_t elink_update_pfc(struct elink_params *params,
3013                       struct elink_vars *vars,
3014                       struct elink_nig_brb_pfc_port_params *pfc_params)
3015 {
3016         /* The PFC and pause are orthogonal to one another, meaning when
3017          * PFC is enabled, the pause are disabled, and when PFC is
3018          * disabled, pause are set according to the pause result.
3019          */
3020         uint32_t val;
3021         struct bxe_softc *sc = params->sc;
3022         elink_status_t elink_status = ELINK_STATUS_OK;
3023         uint8_t bmac_loopback = (params->loopback_mode == ELINK_LOOPBACK_BMAC);
3024
3025         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
3026                 vars->link_status |= LINK_STATUS_PFC_ENABLED;
3027         else
3028                 vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
3029
3030         elink_update_mng(params, vars->link_status);
3031
3032         /* Update NIG params */
3033         elink_update_pfc_nig(params, vars, pfc_params);
3034
3035         if (!vars->link_up)
3036                 return elink_status;
3037
3038         ELINK_DEBUG_P0(sc, "About to update PFC in BMAC\n");
3039
3040         if (CHIP_IS_E3(sc)) {
3041                 if (vars->mac_type == ELINK_MAC_TYPE_XMAC)
3042                         elink_update_pfc_xmac(params, vars, 0);
3043         } else {
3044                 val = REG_RD(sc, MISC_REG_RESET_REG_2);
3045                 if ((val &
3046                      (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
3047                     == 0) {
3048                         ELINK_DEBUG_P0(sc, "About to update PFC in EMAC\n");
3049                         elink_emac_enable(params, vars, 0);
3050                         return elink_status;
3051                 }
3052                 if (CHIP_IS_E2(sc))
3053                         elink_update_pfc_bmac2(params, vars, bmac_loopback);
3054                 else
3055                         elink_update_pfc_bmac1(params, vars);
3056
3057                 val = 0;
3058                 if ((params->feature_config_flags &
3059                      ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
3060                     (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
3061                         val = 1;
3062                 REG_WR(sc, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
3063         }
3064         return elink_status;
3065 }
3066
3067 static elink_status_t elink_bmac1_enable(struct elink_params *params,
3068                               struct elink_vars *vars,
3069                               uint8_t is_lb)
3070 {
3071         struct bxe_softc *sc = params->sc;
3072         uint8_t port = params->port;
3073         uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
3074                                NIG_REG_INGRESS_BMAC0_MEM;
3075         uint32_t wb_data[2];
3076         uint32_t val;
3077
3078         ELINK_DEBUG_P0(sc, "Enabling BigMAC1\n");
3079
3080         /* XGXS control */
3081         wb_data[0] = 0x3c;
3082         wb_data[1] = 0;
3083         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
3084                     wb_data, 2);
3085
3086         /* TX MAC SA */
3087         wb_data[0] = ((params->mac_addr[2] << 24) |
3088                        (params->mac_addr[3] << 16) |
3089                        (params->mac_addr[4] << 8) |
3090                         params->mac_addr[5]);
3091         wb_data[1] = ((params->mac_addr[0] << 8) |
3092                         params->mac_addr[1]);
3093         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
3094
3095         /* MAC control */
3096         val = 0x3;
3097         if (is_lb) {
3098                 val |= 0x4;
3099                 ELINK_DEBUG_P0(sc,  "enable bmac loopback\n");
3100         }
3101         wb_data[0] = val;
3102         wb_data[1] = 0;
3103         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
3104
3105         /* Set rx mtu */
3106         wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3107         wb_data[1] = 0;
3108         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
3109
3110         elink_update_pfc_bmac1(params, vars);
3111
3112         /* Set tx mtu */
3113         wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3114         wb_data[1] = 0;
3115         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
3116
3117         /* Set cnt max size */
3118         wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3119         wb_data[1] = 0;
3120         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
3121
3122         /* Configure SAFC */
3123         wb_data[0] = 0x1000200;
3124         wb_data[1] = 0;
3125         REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
3126                     wb_data, 2);
3127 #ifdef ELINK_INCLUDE_EMUL
3128         /* Fix for emulation */
3129         if (CHIP_REV_IS_EMUL(sc)) {
3130                 wb_data[0] = 0xf000;
3131                 wb_data[1] = 0;
3132                 REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
3133                             wb_data, 2);
3134         }
3135 #endif
3136
3137         return ELINK_STATUS_OK;
3138 }
3139
3140 static elink_status_t elink_bmac2_enable(struct elink_params *params,
3141                               struct elink_vars *vars,
3142                               uint8_t is_lb)
3143 {
3144         struct bxe_softc *sc = params->sc;
3145         uint8_t port = params->port;
3146         uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
3147                                NIG_REG_INGRESS_BMAC0_MEM;
3148         uint32_t wb_data[2];
3149
3150         ELINK_DEBUG_P0(sc, "Enabling BigMAC2\n");
3151
3152         wb_data[0] = 0;
3153         wb_data[1] = 0;
3154         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
3155         DELAY(30);
3156
3157         /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
3158         wb_data[0] = 0x3c;
3159         wb_data[1] = 0;
3160         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
3161                     wb_data, 2);
3162
3163         DELAY(30);
3164
3165         /* TX MAC SA */
3166         wb_data[0] = ((params->mac_addr[2] << 24) |
3167                        (params->mac_addr[3] << 16) |
3168                        (params->mac_addr[4] << 8) |
3169                         params->mac_addr[5]);
3170         wb_data[1] = ((params->mac_addr[0] << 8) |
3171                         params->mac_addr[1]);
3172         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
3173                     wb_data, 2);
3174
3175         DELAY(30);
3176
3177         /* Configure SAFC */
3178         wb_data[0] = 0x1000200;
3179         wb_data[1] = 0;
3180         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
3181                     wb_data, 2);
3182         DELAY(30);
3183
3184         /* Set RX MTU */
3185         wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3186         wb_data[1] = 0;
3187         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
3188         DELAY(30);
3189
3190         /* Set TX MTU */
3191         wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
3192         wb_data[1] = 0;
3193         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
3194         DELAY(30);
3195         /* Set cnt max size */
3196         wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD - 2;
3197         wb_data[1] = 0;
3198         REG_WR_DMAE(sc, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
3199         DELAY(30);
3200         elink_update_pfc_bmac2(params, vars, is_lb);
3201
3202         return ELINK_STATUS_OK;
3203 }
3204
3205 static elink_status_t elink_bmac_enable(struct elink_params *params,
3206                              struct elink_vars *vars,
3207                              uint8_t is_lb, uint8_t reset_bmac)
3208 {
3209         elink_status_t rc = ELINK_STATUS_OK;
3210         uint8_t port = params->port;
3211         struct bxe_softc *sc = params->sc;
3212         uint32_t val;
3213         /* Reset and unreset the BigMac */
3214         if (reset_bmac) {
3215                 REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
3216                        (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
3217                 DELAY(1000 * 1);
3218         }
3219
3220         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
3221                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
3222
3223         /* Enable access for bmac registers */
3224         REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
3225
3226         /* Enable BMAC according to BMAC type*/
3227         if (CHIP_IS_E2(sc))
3228                 rc = elink_bmac2_enable(params, vars, is_lb);
3229         else
3230                 rc = elink_bmac1_enable(params, vars, is_lb);
3231         REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
3232         REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
3233         REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
3234         val = 0;
3235         if ((params->feature_config_flags &
3236               ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
3237             (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
3238                 val = 1;
3239         REG_WR(sc, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
3240         REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
3241         REG_WR(sc, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
3242         REG_WR(sc, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
3243         REG_WR(sc, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
3244         REG_WR(sc, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
3245
3246         vars->mac_type = ELINK_MAC_TYPE_BMAC;
3247         return rc;
3248 }
3249
3250 static void elink_set_bmac_rx(struct bxe_softc *sc, uint32_t chip_id, uint8_t port, uint8_t en)
3251 {
3252         uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
3253                         NIG_REG_INGRESS_BMAC0_MEM;
3254         uint32_t wb_data[2];
3255         uint32_t nig_bmac_enable = REG_RD(sc, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
3256
3257         if (CHIP_IS_E2(sc))
3258                 bmac_addr += BIGMAC2_REGISTER_BMAC_CONTROL;
3259         else
3260                 bmac_addr += BIGMAC_REGISTER_BMAC_CONTROL;
3261         /* Only if the bmac is out of reset */
3262         if (REG_RD(sc, MISC_REG_RESET_REG_2) &
3263                         (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
3264             nig_bmac_enable) {
3265                 /* Clear Rx Enable bit in BMAC_CONTROL register */
3266                 REG_RD_DMAE(sc, bmac_addr, wb_data, 2);
3267                 if (en)
3268                         wb_data[0] |= ELINK_BMAC_CONTROL_RX_ENABLE;
3269                 else
3270                         wb_data[0] &= ~ELINK_BMAC_CONTROL_RX_ENABLE;
3271                 REG_WR_DMAE(sc, bmac_addr, wb_data, 2);
3272                 DELAY(1000 * 1);
3273         }
3274 }
3275
3276 static elink_status_t elink_pbf_update(struct elink_params *params, uint32_t flow_ctrl,
3277                             uint32_t line_speed)
3278 {
3279         struct bxe_softc *sc = params->sc;
3280         uint8_t port = params->port;
3281         uint32_t init_crd, crd;
3282         uint32_t count = 1000;
3283
3284         /* Disable port */
3285         REG_WR(sc, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
3286
3287         /* Wait for init credit */
3288         init_crd = REG_RD(sc, PBF_REG_P0_INIT_CRD + port*4);
3289         crd = REG_RD(sc, PBF_REG_P0_CREDIT + port*8);
3290         ELINK_DEBUG_P2(sc, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
3291
3292         while ((init_crd != crd) && count) {
3293                 DELAY(1000 * 5);
3294                 crd = REG_RD(sc, PBF_REG_P0_CREDIT + port*8);
3295                 count--;
3296         }
3297         crd = REG_RD(sc, PBF_REG_P0_CREDIT + port*8);
3298         if (init_crd != crd) {
3299                 ELINK_DEBUG_P2(sc, "BUG! init_crd 0x%x != crd 0x%x\n",
3300                           init_crd, crd);
3301                 return ELINK_STATUS_ERROR;
3302         }
3303
3304         if (flow_ctrl & ELINK_FLOW_CTRL_RX ||
3305             line_speed == ELINK_SPEED_10 ||
3306             line_speed == ELINK_SPEED_100 ||
3307             line_speed == ELINK_SPEED_1000 ||
3308             line_speed == ELINK_SPEED_2500) {
3309                 REG_WR(sc, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
3310                 /* Update threshold */
3311                 REG_WR(sc, PBF_REG_P0_ARB_THRSH + port*4, 0);
3312                 /* Update init credit */
3313                 init_crd = 778;         /* (800-18-4) */
3314
3315         } else {
3316                 uint32_t thresh = (ELINK_ETH_MAX_JUMBO_PACKET_SIZE +
3317                               ELINK_ETH_OVREHEAD)/16;
3318                 REG_WR(sc, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
3319                 /* Update threshold */
3320                 REG_WR(sc, PBF_REG_P0_ARB_THRSH + port*4, thresh);
3321                 /* Update init credit */
3322                 switch (line_speed) {
3323                 case ELINK_SPEED_10000:
3324                         init_crd = thresh + 553 - 22;
3325                         break;
3326                 default:
3327                         ELINK_DEBUG_P1(sc, "Invalid line_speed 0x%x\n",
3328                                   line_speed);
3329                         return ELINK_STATUS_ERROR;
3330                 }
3331         }
3332         REG_WR(sc, PBF_REG_P0_INIT_CRD + port*4, init_crd);
3333         ELINK_DEBUG_P2(sc, "PBF updated to speed %d credit %d\n",
3334                  line_speed, init_crd);
3335
3336         /* Probe the credit changes */
3337         REG_WR(sc, PBF_REG_INIT_P0 + port*4, 0x1);
3338         DELAY(1000 * 5);
3339         REG_WR(sc, PBF_REG_INIT_P0 + port*4, 0x0);
3340
3341         /* Enable port */
3342         REG_WR(sc, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
3343         return ELINK_STATUS_OK;
3344 }
3345
3346 /**
3347  * elink_get_emac_base - retrive emac base address
3348  *
3349  * @bp:                 driver handle
3350  * @mdc_mdio_access:    access type
3351  * @port:               port id
3352  *
3353  * This function selects the MDC/MDIO access (through emac0 or
3354  * emac1) depend on the mdc_mdio_access, port, port swapped. Each
3355  * phy has a default access mode, which could also be overridden
3356  * by nvram configuration. This parameter, whether this is the
3357  * default phy configuration, or the nvram overrun
3358  * configuration, is passed here as mdc_mdio_access and selects
3359  * the emac_base for the CL45 read/writes operations
3360  */
3361 static uint32_t elink_get_emac_base(struct bxe_softc *sc,
3362                                uint32_t mdc_mdio_access, uint8_t port)
3363 {
3364         uint32_t emac_base = 0;
3365         switch (mdc_mdio_access) {
3366         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
3367                 break;
3368         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
3369                 if (REG_RD(sc, NIG_REG_PORT_SWAP))
3370                         emac_base = GRCBASE_EMAC1;
3371                 else
3372                         emac_base = GRCBASE_EMAC0;
3373                 break;
3374         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
3375                 if (REG_RD(sc, NIG_REG_PORT_SWAP))
3376                         emac_base = GRCBASE_EMAC0;
3377                 else
3378                         emac_base = GRCBASE_EMAC1;
3379                 break;
3380         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
3381                 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3382                 break;
3383         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
3384                 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
3385                 break;
3386         default:
3387                 break;
3388         }
3389         return emac_base;
3390
3391 }
3392
3393 /******************************************************************/
3394 /*                      CL22 access functions                     */
3395 /******************************************************************/
3396 static elink_status_t elink_cl22_write(struct bxe_softc *sc,
3397                                        struct elink_phy *phy,
3398                                        uint16_t reg, uint16_t val)
3399 {
3400         uint32_t tmp, mode;
3401         uint8_t i;
3402         elink_status_t rc = ELINK_STATUS_OK;
3403         /* Switch to CL22 */
3404         mode = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
3405         REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
3406                mode & ~EMAC_MDIO_MODE_CLAUSE_45);
3407
3408         /* Address */
3409         tmp = ((phy->addr << 21) | (reg << 16) | val |
3410                EMAC_MDIO_COMM_COMMAND_WRITE_22 |
3411                EMAC_MDIO_COMM_START_BUSY);
3412         REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3413
3414         for (i = 0; i < 50; i++) {
3415                 DELAY(10);
3416
3417                 tmp = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3418                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3419                         DELAY(5);
3420                         break;
3421                 }
3422         }
3423         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3424                 ELINK_DEBUG_P0(sc, "write phy register failed\n");
3425                 rc = ELINK_STATUS_TIMEOUT;
3426         }
3427         REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
3428         return rc;
3429 }
3430
3431 static elink_status_t elink_cl22_read(struct bxe_softc *sc,
3432                                       struct elink_phy *phy,
3433                                       uint16_t reg, uint16_t *ret_val)
3434 {
3435         uint32_t val, mode;
3436         uint16_t i;
3437         elink_status_t rc = ELINK_STATUS_OK;
3438
3439         /* Switch to CL22 */
3440         mode = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
3441         REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
3442                mode & ~EMAC_MDIO_MODE_CLAUSE_45);
3443
3444         /* Address */
3445         val = ((phy->addr << 21) | (reg << 16) |
3446                EMAC_MDIO_COMM_COMMAND_READ_22 |
3447                EMAC_MDIO_COMM_START_BUSY);
3448         REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3449
3450         for (i = 0; i < 50; i++) {
3451                 DELAY(10);
3452
3453                 val = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3454                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3455                         *ret_val = (uint16_t)(val & EMAC_MDIO_COMM_DATA);
3456                         DELAY(5);
3457                         break;
3458                 }
3459         }
3460         if (val & EMAC_MDIO_COMM_START_BUSY) {
3461                 ELINK_DEBUG_P0(sc, "read phy register failed\n");
3462
3463                 *ret_val = 0;
3464                 rc = ELINK_STATUS_TIMEOUT;
3465         }
3466         REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
3467         return rc;
3468 }
3469
3470 /******************************************************************/
3471 /*                      CL45 access functions                     */
3472 /******************************************************************/
3473 static elink_status_t elink_cl45_read(struct bxe_softc *sc, struct elink_phy *phy,
3474                            uint8_t devad, uint16_t reg, uint16_t *ret_val)
3475 {
3476         uint32_t val;
3477         uint16_t i;
3478         elink_status_t rc = ELINK_STATUS_OK;
3479         uint32_t chip_id;
3480         if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_G) {
3481                 chip_id = (REG_RD(sc, MISC_REG_CHIP_NUM) << 16) |
3482                           ((REG_RD(sc, MISC_REG_CHIP_REV) & 0xf) << 12);
3483                 elink_set_mdio_clk(sc, chip_id, phy->mdio_ctrl);
3484         }
3485
3486         if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3487                 elink_bits_en(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3488                               EMAC_MDIO_STATUS_10MB);
3489         /* Address */
3490         val = ((phy->addr << 21) | (devad << 16) | reg |
3491                EMAC_MDIO_COMM_COMMAND_ADDRESS |
3492                EMAC_MDIO_COMM_START_BUSY);
3493         REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3494
3495         for (i = 0; i < 50; i++) {
3496                 DELAY(10);
3497
3498                 val = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3499                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3500                         DELAY(5);
3501                         break;
3502                 }
3503         }
3504         if (val & EMAC_MDIO_COMM_START_BUSY) {
3505                 ELINK_DEBUG_P0(sc, "read phy register failed\n");
3506                 elink_cb_event_log(sc, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT); // "MDC/MDIO access timeout\n"
3507
3508                 *ret_val = 0;
3509                 rc = ELINK_STATUS_TIMEOUT;
3510         } else {
3511                 /* Data */
3512                 val = ((phy->addr << 21) | (devad << 16) |
3513                        EMAC_MDIO_COMM_COMMAND_READ_45 |
3514                        EMAC_MDIO_COMM_START_BUSY);
3515                 REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3516
3517                 for (i = 0; i < 50; i++) {
3518                         DELAY(10);
3519
3520                         val = REG_RD(sc, phy->mdio_ctrl +
3521                                      EMAC_REG_EMAC_MDIO_COMM);
3522                         if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3523                                 *ret_val = (uint16_t)(val & EMAC_MDIO_COMM_DATA);
3524                                 break;
3525                         }
3526                 }
3527                 if (val & EMAC_MDIO_COMM_START_BUSY) {
3528                         ELINK_DEBUG_P0(sc, "read phy register failed\n");
3529                         elink_cb_event_log(sc, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT); // "MDC/MDIO access timeout\n"
3530
3531                         *ret_val = 0;
3532                         rc = ELINK_STATUS_TIMEOUT;
3533                 }
3534         }
3535         /* Work around for E3 A0 */
3536         if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA) {
3537                 phy->flags ^= ELINK_FLAGS_DUMMY_READ;
3538                 if (phy->flags & ELINK_FLAGS_DUMMY_READ) {
3539                         uint16_t temp_val;
3540                         elink_cl45_read(sc, phy, devad, 0xf, &temp_val);
3541                 }
3542         }
3543
3544         if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3545                 elink_bits_dis(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3546                                EMAC_MDIO_STATUS_10MB);
3547         return rc;
3548 }
3549
3550 static elink_status_t elink_cl45_write(struct bxe_softc *sc, struct elink_phy *phy,
3551                             uint8_t devad, uint16_t reg, uint16_t val)
3552 {
3553         uint32_t tmp;
3554         uint8_t i;
3555         elink_status_t rc = ELINK_STATUS_OK;
3556         uint32_t chip_id;
3557         if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_G) {
3558                 chip_id = (REG_RD(sc, MISC_REG_CHIP_NUM) << 16) |
3559                           ((REG_RD(sc, MISC_REG_CHIP_REV) & 0xf) << 12);
3560                 elink_set_mdio_clk(sc, chip_id, phy->mdio_ctrl);
3561         }
3562
3563         if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3564                 elink_bits_en(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3565                               EMAC_MDIO_STATUS_10MB);
3566
3567         /* Address */
3568         tmp = ((phy->addr << 21) | (devad << 16) | reg |
3569                EMAC_MDIO_COMM_COMMAND_ADDRESS |
3570                EMAC_MDIO_COMM_START_BUSY);
3571         REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3572
3573         for (i = 0; i < 50; i++) {
3574                 DELAY(10);
3575
3576                 tmp = REG_RD(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3577                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3578                         DELAY(5);
3579                         break;
3580                 }
3581         }
3582         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3583                 ELINK_DEBUG_P0(sc, "write phy register failed\n");
3584                 elink_cb_event_log(sc, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT); // "MDC/MDIO access timeout\n"
3585
3586                 rc = ELINK_STATUS_TIMEOUT;
3587         } else {
3588                 /* Data */
3589                 tmp = ((phy->addr << 21) | (devad << 16) | val |
3590                        EMAC_MDIO_COMM_COMMAND_WRITE_45 |
3591                        EMAC_MDIO_COMM_START_BUSY);
3592                 REG_WR(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3593
3594                 for (i = 0; i < 50; i++) {
3595                         DELAY(10);
3596
3597                         tmp = REG_RD(sc, phy->mdio_ctrl +
3598                                      EMAC_REG_EMAC_MDIO_COMM);
3599                         if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3600                                 DELAY(5);
3601                                 break;
3602                         }
3603                 }
3604                 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3605                         ELINK_DEBUG_P0(sc, "write phy register failed\n");
3606                         elink_cb_event_log(sc, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT); // "MDC/MDIO access timeout\n"
3607
3608                         rc = ELINK_STATUS_TIMEOUT;
3609                 }
3610         }
3611         /* Work around for E3 A0 */
3612         if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA) {
3613                 phy->flags ^= ELINK_FLAGS_DUMMY_READ;
3614                 if (phy->flags & ELINK_FLAGS_DUMMY_READ) {
3615                         uint16_t temp_val;
3616                         elink_cl45_read(sc, phy, devad, 0xf, &temp_val);
3617                 }
3618         }
3619         if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3620                 elink_bits_dis(sc, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3621                                EMAC_MDIO_STATUS_10MB);
3622         return rc;
3623 }
3624
3625 /******************************************************************/
3626 /*                      EEE section                                */
3627 /******************************************************************/
3628 static uint8_t elink_eee_has_cap(struct elink_params *params)
3629 {
3630         struct bxe_softc *sc = params->sc;
3631
3632         if (REG_RD(sc, params->shmem2_base) <=
3633                    offsetof(struct shmem2_region, eee_status[params->port]))
3634                 return 0;
3635
3636         return 1;
3637 }
3638
3639 static elink_status_t elink_eee_nvram_to_time(uint32_t nvram_mode, uint32_t *idle_timer)
3640 {
3641         switch (nvram_mode) {
3642         case PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED:
3643                 *idle_timer = ELINK_EEE_MODE_NVRAM_BALANCED_TIME;
3644                 break;
3645         case PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE:
3646                 *idle_timer = ELINK_EEE_MODE_NVRAM_AGGRESSIVE_TIME;
3647                 break;
3648         case PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY:
3649                 *idle_timer = ELINK_EEE_MODE_NVRAM_LATENCY_TIME;
3650                 break;
3651         default:
3652                 *idle_timer = 0;
3653                 break;
3654         }
3655
3656         return ELINK_STATUS_OK;
3657 }
3658
3659 static elink_status_t elink_eee_time_to_nvram(uint32_t idle_timer, uint32_t *nvram_mode)
3660 {
3661         switch (idle_timer) {
3662         case ELINK_EEE_MODE_NVRAM_BALANCED_TIME:
3663                 *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED;
3664                 break;
3665         case ELINK_EEE_MODE_NVRAM_AGGRESSIVE_TIME:
3666                 *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE;
3667                 break;
3668         case ELINK_EEE_MODE_NVRAM_LATENCY_TIME:
3669                 *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY;
3670                 break;
3671         default:
3672                 *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED;
3673                 break;
3674         }
3675
3676         return ELINK_STATUS_OK;
3677 }
3678
3679 static uint32_t elink_eee_calc_timer(struct elink_params *params)
3680 {
3681         uint32_t eee_mode, eee_idle;
3682         struct bxe_softc *sc = params->sc;
3683
3684         if (params->eee_mode & ELINK_EEE_MODE_OVERRIDE_NVRAM) {
3685                 if (params->eee_mode & ELINK_EEE_MODE_OUTPUT_TIME) {
3686                         /* time value in eee_mode --> used directly*/
3687                         eee_idle = params->eee_mode & ELINK_EEE_MODE_TIMER_MASK;
3688                 } else {
3689                         /* hsi value in eee_mode --> time */
3690                         if (elink_eee_nvram_to_time(params->eee_mode &
3691                                                     ELINK_EEE_MODE_NVRAM_MASK,
3692                                                     &eee_idle))
3693                                 return 0;
3694                 }
3695         } else {
3696                 /* hsi values in nvram --> time*/
3697                 eee_mode = ((REG_RD(sc, params->shmem_base +
3698                                     offsetof(struct shmem_region, dev_info.
3699                                     port_feature_config[params->port].
3700                                     eee_power_mode)) &
3701                              PORT_FEAT_CFG_EEE_POWER_MODE_MASK) >>
3702                             PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT);
3703
3704                 if (elink_eee_nvram_to_time(eee_mode, &eee_idle))
3705                         return 0;
3706         }
3707
3708         return eee_idle;
3709 }
3710
3711 static elink_status_t elink_eee_set_timers(struct elink_params *params,
3712                                    struct elink_vars *vars)
3713 {
3714         uint32_t eee_idle = 0, eee_mode;
3715         struct bxe_softc *sc = params->sc;
3716
3717         eee_idle = elink_eee_calc_timer(params);
3718
3719         if (eee_idle) {
3720                 REG_WR(sc, MISC_REG_CPMU_LP_IDLE_THR_P0 + (params->port << 2),
3721                        eee_idle);
3722         } else if ((params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI) &&
3723                    (params->eee_mode & ELINK_EEE_MODE_OVERRIDE_NVRAM) &&
3724                    (params->eee_mode & ELINK_EEE_MODE_OUTPUT_TIME)) {
3725                 ELINK_DEBUG_P0(sc, "Error: Tx LPI is enabled with timer 0\n");
3726                 return ELINK_STATUS_ERROR;
3727         }
3728
3729         vars->eee_status &= ~(SHMEM_EEE_TIMER_MASK | SHMEM_EEE_TIME_OUTPUT_BIT);
3730         if (params->eee_mode & ELINK_EEE_MODE_OUTPUT_TIME) {
3731                 /* eee_idle in 1u --> eee_status in 16u */
3732                 eee_idle >>= 4;
3733                 vars->eee_status |= (eee_idle & SHMEM_EEE_TIMER_MASK) |
3734                                     SHMEM_EEE_TIME_OUTPUT_BIT;
3735         } else {
3736                 if (elink_eee_time_to_nvram(eee_idle, &eee_mode))
3737                         return ELINK_STATUS_ERROR;
3738                 vars->eee_status |= eee_mode;
3739         }
3740
3741         return ELINK_STATUS_OK;
3742 }
3743
3744 static elink_status_t elink_eee_initial_config(struct elink_params *params,
3745                                      struct elink_vars *vars, uint8_t mode)
3746 {
3747         vars->eee_status |= ((uint32_t) mode) << SHMEM_EEE_SUPPORTED_SHIFT;
3748
3749         /* Propogate params' bits --> vars (for migration exposure) */
3750         if (params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI)
3751                 vars->eee_status |= SHMEM_EEE_LPI_REQUESTED_BIT;
3752         else
3753                 vars->eee_status &= ~SHMEM_EEE_LPI_REQUESTED_BIT;
3754
3755         if (params->eee_mode & ELINK_EEE_MODE_ADV_LPI)
3756                 vars->eee_status |= SHMEM_EEE_REQUESTED_BIT;
3757         else
3758                 vars->eee_status &= ~SHMEM_EEE_REQUESTED_BIT;
3759
3760         return elink_eee_set_timers(params, vars);
3761 }
3762
3763 static elink_status_t elink_eee_disable(struct elink_phy *phy,
3764                                 struct elink_params *params,
3765                                 struct elink_vars *vars)
3766 {
3767         struct bxe_softc *sc = params->sc;
3768
3769         /* Make Certain LPI is disabled */
3770         REG_WR(sc, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2), 0);
3771
3772         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, 0x0);
3773
3774         vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
3775
3776         return ELINK_STATUS_OK;
3777 }
3778
3779 static elink_status_t elink_eee_advertise(struct elink_phy *phy,
3780                                   struct elink_params *params,
3781                                   struct elink_vars *vars, uint8_t modes)
3782 {
3783         struct bxe_softc *sc = params->sc;
3784         uint16_t val = 0;
3785
3786         /* Mask events preventing LPI generation */
3787         REG_WR(sc, MISC_REG_CPMU_LP_MASK_EXT_P0 + (params->port << 2), 0xfc20);
3788
3789         if (modes & SHMEM_EEE_10G_ADV) {
3790                 ELINK_DEBUG_P0(sc, "Advertise 10GBase-T EEE\n");
3791                 val |= 0x8;
3792         }
3793         if (modes & SHMEM_EEE_1G_ADV) {
3794                 ELINK_DEBUG_P0(sc, "Advertise 1GBase-T EEE\n");
3795                 val |= 0x4;
3796         }
3797
3798         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, val);
3799
3800         vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
3801         vars->eee_status |= (modes << SHMEM_EEE_ADV_STATUS_SHIFT);
3802
3803         return ELINK_STATUS_OK;
3804 }
3805
3806 static void elink_update_mng_eee(struct elink_params *params, uint32_t eee_status)
3807 {
3808         struct bxe_softc *sc = params->sc;
3809
3810         if (elink_eee_has_cap(params))
3811                 REG_WR(sc, params->shmem2_base +
3812                        offsetof(struct shmem2_region,
3813                                 eee_status[params->port]), eee_status);
3814 }
3815
3816 static void elink_eee_an_resolve(struct elink_phy *phy,
3817                                   struct elink_params *params,
3818                                   struct elink_vars *vars)
3819 {
3820         struct bxe_softc *sc = params->sc;
3821         uint16_t adv = 0, lp = 0;
3822         uint32_t lp_adv = 0;
3823         uint8_t neg = 0;
3824
3825         elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, &adv);
3826         elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_LP_EEE_ADV, &lp);
3827
3828         if (lp & 0x2) {
3829                 lp_adv |= SHMEM_EEE_100M_ADV;
3830                 if (adv & 0x2) {
3831                         if (vars->line_speed == ELINK_SPEED_100)
3832                                 neg = 1;
3833                         ELINK_DEBUG_P0(sc, "EEE negotiated - 100M\n");
3834                 }
3835         }
3836         if (lp & 0x14) {
3837                 lp_adv |= SHMEM_EEE_1G_ADV;
3838                 if (adv & 0x14) {
3839                         if (vars->line_speed == ELINK_SPEED_1000)
3840                                 neg = 1;
3841                         ELINK_DEBUG_P0(sc, "EEE negotiated - 1G\n");
3842                 }
3843         }
3844         if (lp & 0x68) {
3845                 lp_adv |= SHMEM_EEE_10G_ADV;
3846                 if (adv & 0x68) {
3847                         if (vars->line_speed == ELINK_SPEED_10000)
3848                                 neg = 1;
3849                         ELINK_DEBUG_P0(sc, "EEE negotiated - 10G\n");
3850                 }
3851         }
3852
3853         vars->eee_status &= ~SHMEM_EEE_LP_ADV_STATUS_MASK;
3854         vars->eee_status |= (lp_adv << SHMEM_EEE_LP_ADV_STATUS_SHIFT);
3855
3856         if (neg) {
3857                 ELINK_DEBUG_P0(sc, "EEE is active\n");
3858                 vars->eee_status |= SHMEM_EEE_ACTIVE_BIT;
3859         }
3860 }
3861
3862 /******************************************************************/
3863 /*                      BSC access functions from E3              */
3864 /******************************************************************/
3865 static void elink_bsc_module_sel(struct elink_params *params)
3866 {
3867         int idx;
3868         uint32_t board_cfg, sfp_ctrl;
3869         uint32_t i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH];
3870         struct bxe_softc *sc = params->sc;
3871         uint8_t port = params->port;
3872         /* Read I2C output PINs */
3873         board_cfg = REG_RD(sc, params->shmem_base +
3874                            offsetof(struct shmem_region,
3875                                     dev_info.shared_hw_config.board));
3876         i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK;
3877         i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >>
3878                         SHARED_HW_CFG_E3_I2C_MUX1_SHIFT;
3879
3880         /* Read I2C output value */
3881         sfp_ctrl = REG_RD(sc, params->shmem_base +
3882                           offsetof(struct shmem_region,
3883                                  dev_info.port_hw_config[port].e3_cmn_pin_cfg));
3884         i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0;
3885         i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0;
3886         ELINK_DEBUG_P0(sc, "Setting BSC switch\n");
3887         for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++)
3888                 elink_set_cfg_pin(sc, i2c_pins[idx], i2c_val[idx]);
3889 }
3890
3891 static elink_status_t elink_bsc_read(struct elink_params *params,
3892                           struct bxe_softc *sc,
3893                           uint8_t sl_devid,
3894                           uint16_t sl_addr,
3895                           uint8_t lc_addr,
3896                           uint8_t xfer_cnt,
3897                           uint32_t *data_array)
3898 {
3899         uint32_t val, i;
3900         elink_status_t rc = ELINK_STATUS_OK;
3901
3902         if (xfer_cnt > 16) {
3903                 ELINK_DEBUG_P1(sc, "invalid xfer_cnt %d. Max is 16 bytes\n",
3904                                         xfer_cnt);
3905                 return ELINK_STATUS_ERROR;
3906         }
3907         if (params)
3908                 elink_bsc_module_sel(params);
3909
3910         xfer_cnt = 16 - lc_addr;
3911
3912         /* Enable the engine */
3913         val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3914         val |= MCPR_IMC_COMMAND_ENABLE;
3915         REG_WR(sc, MCP_REG_MCPR_IMC_COMMAND, val);
3916
3917         /* Program slave device ID */
3918         val = (sl_devid << 16) | sl_addr;
3919         REG_WR(sc, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val);
3920
3921         /* Start xfer with 0 byte to update the address pointer ???*/
3922         val = (MCPR_IMC_COMMAND_ENABLE) |
3923               (MCPR_IMC_COMMAND_WRITE_OP <<
3924                 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3925                 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0);
3926         REG_WR(sc, MCP_REG_MCPR_IMC_COMMAND, val);
3927
3928         /* Poll for completion */
3929         i = 0;
3930         val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3931         while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3932                 DELAY(10);
3933                 val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3934                 if (i++ > 1000) {
3935                         ELINK_DEBUG_P1(sc, "wr 0 byte timed out after %d try\n",
3936                                                                 i);
3937                         rc = ELINK_STATUS_TIMEOUT;
3938                         break;
3939                 }
3940         }
3941         if (rc == ELINK_STATUS_TIMEOUT)
3942                 return rc;
3943
3944         /* Start xfer with read op */
3945         val = (MCPR_IMC_COMMAND_ENABLE) |
3946                 (MCPR_IMC_COMMAND_READ_OP <<
3947                 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3948                 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) |
3949                   (xfer_cnt);
3950         REG_WR(sc, MCP_REG_MCPR_IMC_COMMAND, val);
3951
3952         /* Poll for completion */
3953         i = 0;
3954         val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3955         while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3956                 DELAY(10);
3957                 val = REG_RD(sc, MCP_REG_MCPR_IMC_COMMAND);
3958                 if (i++ > 1000) {
3959                         ELINK_DEBUG_P1(sc, "rd op timed out after %d try\n", i);
3960                         rc = ELINK_STATUS_TIMEOUT;
3961                         break;
3962                 }
3963         }
3964         if (rc == ELINK_STATUS_TIMEOUT)
3965                 return rc;
3966
3967         for (i = (lc_addr >> 2); i < 4; i++) {
3968                 data_array[i] = REG_RD(sc, (MCP_REG_MCPR_IMC_DATAREG0 + i*4));
3969 #ifdef __BIG_ENDIAN
3970                 data_array[i] = ((data_array[i] & 0x000000ff) << 24) |
3971                                 ((data_array[i] & 0x0000ff00) << 8) |
3972                                 ((data_array[i] & 0x00ff0000) >> 8) |
3973                                 ((data_array[i] & 0xff000000) >> 24);
3974 #endif
3975         }
3976         return rc;
3977 }
3978
3979 static void elink_cl45_read_or_write(struct bxe_softc *sc, struct elink_phy *phy,
3980                                      uint8_t devad, uint16_t reg, uint16_t or_val)
3981 {
3982         uint16_t val;
3983         elink_cl45_read(sc, phy, devad, reg, &val);
3984         elink_cl45_write(sc, phy, devad, reg, val | or_val);
3985 }
3986
3987 static void elink_cl45_read_and_write(struct bxe_softc *sc,
3988                                       struct elink_phy *phy,
3989                                       uint8_t devad, uint16_t reg, uint16_t and_val)
3990 {
3991         uint16_t val;
3992         elink_cl45_read(sc, phy, devad, reg, &val);
3993         elink_cl45_write(sc, phy, devad, reg, val & and_val);
3994 }
3995
3996 elink_status_t elink_phy_read(struct elink_params *params, uint8_t phy_addr,
3997                    uint8_t devad, uint16_t reg, uint16_t *ret_val)
3998 {
3999         uint8_t phy_index;
4000         /* Probe for the phy according to the given phy_addr, and execute
4001          * the read request on it
4002          */
4003         for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
4004                 if (params->phy[phy_index].addr == phy_addr) {
4005                         return elink_cl45_read(params->sc,
4006                                                &params->phy[phy_index], devad,
4007                                                reg, ret_val);
4008                 }
4009         }
4010         return ELINK_STATUS_ERROR;
4011 }
4012
4013 elink_status_t elink_phy_write(struct elink_params *params, uint8_t phy_addr,
4014                     uint8_t devad, uint16_t reg, uint16_t val)
4015 {
4016         uint8_t phy_index;
4017         /* Probe for the phy according to the given phy_addr, and execute
4018          * the write request on it
4019          */
4020         for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
4021                 if (params->phy[phy_index].addr == phy_addr) {
4022                         return elink_cl45_write(params->sc,
4023                                                 &params->phy[phy_index], devad,
4024                                                 reg, val);
4025                 }
4026         }
4027         return ELINK_STATUS_ERROR;
4028 }
4029 static uint8_t elink_get_warpcore_lane(struct elink_phy *phy,
4030                                   struct elink_params *params)
4031 {
4032         uint8_t lane = 0;
4033         struct bxe_softc *sc = params->sc;
4034         uint32_t path_swap, path_swap_ovr;
4035         uint8_t path, port;
4036
4037         path = SC_PATH(sc);
4038         port = params->port;
4039
4040         if (elink_is_4_port_mode(sc)) {
4041                 uint32_t port_swap, port_swap_ovr;
4042
4043                 /* Figure out path swap value */
4044                 path_swap_ovr = REG_RD(sc, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR);
4045                 if (path_swap_ovr & 0x1)
4046                         path_swap = (path_swap_ovr & 0x2);
4047                 else
4048                         path_swap = REG_RD(sc, MISC_REG_FOUR_PORT_PATH_SWAP);
4049
4050                 if (path_swap)
4051                         path = path ^ 1;
4052
4053                 /* Figure out port swap value */
4054                 port_swap_ovr = REG_RD(sc, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR);
4055                 if (port_swap_ovr & 0x1)
4056                         port_swap = (port_swap_ovr & 0x2);
4057                 else
4058                         port_swap = REG_RD(sc, MISC_REG_FOUR_PORT_PORT_SWAP);
4059
4060                 if (port_swap)
4061                         port = port ^ 1;
4062
4063                 lane = (port<<1) + path;
4064         } else { /* Two port mode - no port swap */
4065
4066                 /* Figure out path swap value */
4067                 path_swap_ovr =
4068                         REG_RD(sc, MISC_REG_TWO_PORT_PATH_SWAP_OVWR);
4069                 if (path_swap_ovr & 0x1) {
4070                         path_swap = (path_swap_ovr & 0x2);
4071                 } else {
4072                         path_swap =
4073                                 REG_RD(sc, MISC_REG_TWO_PORT_PATH_SWAP);
4074                 }
4075                 if (path_swap)
4076                         path = path ^ 1;
4077
4078                 lane = path << 1 ;
4079         }
4080         return lane;
4081 }
4082
4083 static void elink_set_aer_mmd(struct elink_params *params,
4084                               struct elink_phy *phy)
4085 {
4086         uint32_t ser_lane;
4087         uint16_t offset, aer_val;
4088         struct bxe_softc *sc = params->sc;
4089         ser_lane = ((params->lane_config &
4090                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4091                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4092
4093         offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
4094                 (phy->addr + ser_lane) : 0;
4095
4096         if (USES_WARPCORE(sc)) {
4097                 aer_val = elink_get_warpcore_lane(phy, params);
4098                 /* In Dual-lane mode, two lanes are joined together,
4099                  * so in order to configure them, the AER broadcast method is
4100                  * used here.
4101                  * 0x200 is the broadcast address for lanes 0,1
4102                  * 0x201 is the broadcast address for lanes 2,3
4103                  */
4104                 if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
4105                         aer_val = (aer_val >> 1) | 0x200;
4106         } else if (CHIP_IS_E2(sc))
4107                 aer_val = 0x3800 + offset - 1;
4108         else
4109                 aer_val = 0x3800 + offset;
4110
4111         CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4112                           MDIO_AER_BLOCK_AER_REG, aer_val);
4113
4114 }
4115
4116 /******************************************************************/
4117 /*                      Internal phy section                      */
4118 /******************************************************************/
4119
4120 static void elink_set_serdes_access(struct bxe_softc *sc, uint8_t port)
4121 {
4122         uint32_t emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4123
4124         /* Set Clause 22 */
4125         REG_WR(sc, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
4126         REG_WR(sc, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
4127         DELAY(500);
4128         REG_WR(sc, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
4129         DELAY(500);
4130          /* Set Clause 45 */
4131         REG_WR(sc, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
4132 }
4133
4134 static void elink_serdes_deassert(struct bxe_softc *sc, uint8_t port)
4135 {
4136         uint32_t val;
4137
4138         ELINK_DEBUG_P0(sc, "elink_serdes_deassert\n");
4139
4140         val = ELINK_SERDES_RESET_BITS << (port*16);
4141
4142         /* Reset and unreset the SerDes/XGXS */
4143         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
4144         DELAY(500);
4145         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
4146
4147         elink_set_serdes_access(sc, port);
4148
4149         REG_WR(sc, NIG_REG_SERDES0_CTRL_MD_DEVAD + port*0x10,
4150                ELINK_DEFAULT_PHY_DEV_ADDR);
4151 }
4152
4153 static void elink_xgxs_specific_func(struct elink_phy *phy,
4154                                      struct elink_params *params,
4155                                      uint32_t action)
4156 {
4157         struct bxe_softc *sc = params->sc;
4158         switch (action) {
4159         case ELINK_PHY_INIT:
4160                 /* Set correct devad */
4161                 REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_ST + params->port*0x18, 0);
4162                 REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
4163                        phy->def_md_devad);
4164                 break;
4165         }
4166 }
4167
4168 static void elink_xgxs_deassert(struct elink_params *params)
4169 {
4170         struct bxe_softc *sc = params->sc;
4171         uint8_t port;
4172         uint32_t val;
4173         ELINK_DEBUG_P0(sc, "elink_xgxs_deassert\n");
4174         port = params->port;
4175
4176         val = ELINK_XGXS_RESET_BITS << (port*16);
4177
4178         /* Reset and unreset the SerDes/XGXS */
4179         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
4180         DELAY(500);
4181         REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
4182         elink_xgxs_specific_func(&params->phy[ELINK_INT_PHY], params,
4183                                  ELINK_PHY_INIT);
4184 }
4185
4186 static void elink_calc_ieee_aneg_adv(struct elink_phy *phy,
4187                                      struct elink_params *params, uint16_t *ieee_fc)
4188 {
4189         struct bxe_softc *sc = params->sc;
4190         *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
4191         /* Resolve pause mode and advertisement Please refer to Table
4192          * 28B-3 of the 802.3ab-1999 spec
4193          */
4194
4195         switch (phy->req_flow_ctrl) {
4196         case ELINK_FLOW_CTRL_AUTO:
4197                 switch (params->req_fc_auto_adv) {
4198                 case ELINK_FLOW_CTRL_BOTH:
4199                         *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
4200                         break;
4201                 case ELINK_FLOW_CTRL_RX:
4202                 case ELINK_FLOW_CTRL_TX:
4203                         *ieee_fc |=
4204                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
4205                         break;
4206                 default:
4207                         break;
4208                 }
4209                 break;
4210         case ELINK_FLOW_CTRL_TX:
4211                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
4212                 break;
4213
4214         case ELINK_FLOW_CTRL_RX:
4215         case ELINK_FLOW_CTRL_BOTH:
4216                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
4217                 break;
4218
4219         case ELINK_FLOW_CTRL_NONE:
4220         default:
4221                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
4222                 break;
4223         }
4224         ELINK_DEBUG_P1(sc, "ieee_fc = 0x%x\n", *ieee_fc);
4225 }
4226
4227 static void set_phy_vars(struct elink_params *params,
4228                          struct elink_vars *vars)
4229 {
4230         struct bxe_softc *sc = params->sc;
4231         uint8_t actual_phy_idx, phy_index, link_cfg_idx;
4232         uint8_t phy_config_swapped = params->multi_phy_config &
4233                         PORT_HW_CFG_PHY_SWAPPED_ENABLED;
4234         for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
4235               phy_index++) {
4236                 link_cfg_idx = ELINK_LINK_CONFIG_IDX(phy_index);
4237                 actual_phy_idx = phy_index;
4238                 if (phy_config_swapped) {
4239                         if (phy_index == ELINK_EXT_PHY1)
4240                                 actual_phy_idx = ELINK_EXT_PHY2;
4241                         else if (phy_index == ELINK_EXT_PHY2)
4242                                 actual_phy_idx = ELINK_EXT_PHY1;
4243                 }
4244                 params->phy[actual_phy_idx].req_flow_ctrl =
4245                         params->req_flow_ctrl[link_cfg_idx];
4246
4247                 params->phy[actual_phy_idx].req_line_speed =
4248                         params->req_line_speed[link_cfg_idx];
4249
4250                 params->phy[actual_phy_idx].speed_cap_mask =
4251                         params->speed_cap_mask[link_cfg_idx];
4252
4253                 params->phy[actual_phy_idx].req_duplex =
4254                         params->req_duplex[link_cfg_idx];
4255
4256                 if (params->req_line_speed[link_cfg_idx] ==
4257                     ELINK_SPEED_AUTO_NEG)
4258                         vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
4259
4260                 ELINK_DEBUG_P3(sc, "req_flow_ctrl %x, req_line_speed %x,"
4261                            " speed_cap_mask %x\n",
4262                            params->phy[actual_phy_idx].req_flow_ctrl,
4263                            params->phy[actual_phy_idx].req_line_speed,
4264                            params->phy[actual_phy_idx].speed_cap_mask);
4265         }
4266 }
4267
4268 static void elink_ext_phy_set_pause(struct elink_params *params,
4269                                     struct elink_phy *phy,
4270                                     struct elink_vars *vars)
4271 {
4272         uint16_t val;
4273         struct bxe_softc *sc = params->sc;
4274         /* Read modify write pause advertizing */
4275         elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
4276
4277         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
4278
4279         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
4280         elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
4281         if ((vars->ieee_fc &
4282             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
4283             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
4284                 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
4285         }
4286         if ((vars->ieee_fc &
4287             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
4288             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
4289                 val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
4290         }
4291         ELINK_DEBUG_P1(sc, "Ext phy AN advertize 0x%x\n", val);
4292         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
4293 }
4294
4295 static void elink_pause_resolve(struct elink_vars *vars, uint32_t pause_result)
4296 {                                               /*  LD      LP   */
4297         switch (pause_result) {                 /* ASYM P ASYM P */
4298         case 0xb:                               /*   1  0   1  1 */
4299                 vars->flow_ctrl = ELINK_FLOW_CTRL_TX;
4300                 break;
4301
4302         case 0xe:                               /*   1  1   1  0 */
4303                 vars->flow_ctrl = ELINK_FLOW_CTRL_RX;
4304                 break;
4305
4306         case 0x5:                               /*   0  1   0  1 */
4307         case 0x7:                               /*   0  1   1  1 */
4308         case 0xd:                               /*   1  1   0  1 */
4309         case 0xf:                               /*   1  1   1  1 */
4310                 vars->flow_ctrl = ELINK_FLOW_CTRL_BOTH;
4311                 break;
4312
4313         default:
4314                 break;
4315         }
4316         if (pause_result & (1<<0))
4317                 vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
4318         if (pause_result & (1<<1))
4319                 vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
4320
4321 }
4322
4323 static void elink_ext_phy_update_adv_fc(struct elink_phy *phy,
4324                                         struct elink_params *params,
4325                                         struct elink_vars *vars)
4326 {
4327         uint16_t ld_pause;              /* local */
4328         uint16_t lp_pause;              /* link partner */
4329         uint16_t pause_result;
4330         struct bxe_softc *sc = params->sc;
4331         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) {
4332                 elink_cl22_read(sc, phy, 0x4, &ld_pause);
4333                 elink_cl22_read(sc, phy, 0x5, &lp_pause);
4334         } else if (CHIP_IS_E3(sc) &&
4335                 ELINK_SINGLE_MEDIA_DIRECT(params)) {
4336                 uint8_t lane = elink_get_warpcore_lane(phy, params);
4337                 uint16_t gp_status, gp_mask;
4338                 elink_cl45_read(sc, phy,
4339                                 MDIO_AN_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_4,
4340                                 &gp_status);
4341                 gp_mask = (MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL |
4342                            MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP) <<
4343                         lane;
4344                 if ((gp_status & gp_mask) == gp_mask) {
4345                         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
4346                                         MDIO_AN_REG_ADV_PAUSE, &ld_pause);
4347                         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
4348                                         MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
4349                 } else {
4350                         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
4351                                         MDIO_AN_REG_CL37_FC_LD, &ld_pause);
4352                         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
4353                                         MDIO_AN_REG_CL37_FC_LP, &lp_pause);
4354                         ld_pause = ((ld_pause &
4355                                      MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
4356                                     << 3);
4357                         lp_pause = ((lp_pause &
4358                                      MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
4359                                     << 3);
4360                 }
4361         } else {
4362                 elink_cl45_read(sc, phy,
4363                                 MDIO_AN_DEVAD,
4364                                 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
4365                 elink_cl45_read(sc, phy,
4366                                 MDIO_AN_DEVAD,
4367                                 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
4368         }
4369         pause_result = (ld_pause &
4370                         MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
4371         pause_result |= (lp_pause &
4372                          MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
4373         ELINK_DEBUG_P1(sc, "Ext PHY pause result 0x%x\n", pause_result);
4374         elink_pause_resolve(vars, pause_result);
4375
4376 }
4377
4378 static uint8_t elink_ext_phy_resolve_fc(struct elink_phy *phy,
4379                                    struct elink_params *params,
4380                                    struct elink_vars *vars)
4381 {
4382         uint8_t ret = 0;
4383         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
4384         if (phy->req_flow_ctrl != ELINK_FLOW_CTRL_AUTO) {
4385                 /* Update the advertised flow-controled of LD/LP in AN */
4386                 if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
4387                         elink_ext_phy_update_adv_fc(phy, params, vars);
4388                 /* But set the flow-control result as the requested one */
4389                 vars->flow_ctrl = phy->req_flow_ctrl;
4390         } else if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
4391                 vars->flow_ctrl = params->req_fc_auto_adv;
4392         else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
4393                 ret = 1;
4394                 elink_ext_phy_update_adv_fc(phy, params, vars);
4395         }
4396         return ret;
4397 }
4398 /******************************************************************/
4399 /*                      Warpcore section                          */
4400 /******************************************************************/
4401 /* The init_internal_warpcore should mirror the xgxs,
4402  * i.e. reset the lane (if needed), set aer for the
4403  * init configuration, and set/clear SGMII flag. Internal
4404  * phy init is done purely in phy_init stage.
4405  */
4406 #define WC_TX_DRIVER(post2, idriver, ipre) \
4407         ((post2 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | \
4408          (idriver << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | \
4409          (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))
4410
4411 #define WC_TX_FIR(post, main, pre) \
4412         ((post << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | \
4413          (main << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | \
4414          (pre << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET))
4415
4416 static void elink_warpcore_enable_AN_KR2(struct elink_phy *phy,
4417                                          struct elink_params *params,
4418                                          struct elink_vars *vars)
4419 {
4420         struct bxe_softc *sc = params->sc;
4421         uint16_t i;
4422         static struct elink_reg_set reg_set[] = {
4423                 /* Step 1 - Program the TX/RX alignment markers */
4424                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL5, 0xa157},
4425                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL7, 0xcbe2},
4426                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL6, 0x7537},
4427                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL9, 0xa157},
4428                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL11, 0xcbe2},
4429                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL10, 0x7537},
4430                 /* Step 2 - Configure the NP registers */
4431                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_USERB0_CTRL, 0x000a},
4432                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL1, 0x6400},
4433                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL3, 0x0620},
4434                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CODE_FIELD, 0x0157},
4435                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI1, 0x6464},
4436                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI2, 0x3150},
4437                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI3, 0x3150},
4438                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_BAM_CODE, 0x0157},
4439                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_UD_CODE, 0x0620}
4440         };
4441         ELINK_DEBUG_P0(sc, "Enabling 20G-KR2\n");
4442
4443         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4444                                  MDIO_WC_REG_CL49_USERB0_CTRL, (3<<6));
4445
4446         for (i = 0; i < ARRAY_SIZE(reg_set); i++)
4447                 elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
4448                                  reg_set[i].val);
4449
4450         /* Start KR2 work-around timer which handles BCM8073 link-parner */
4451         vars->link_attr_sync |= LINK_ATTR_SYNC_KR2_ENABLE;
4452         elink_update_link_attr(params, vars->link_attr_sync);
4453 }
4454
4455 static void elink_disable_kr2(struct elink_params *params,
4456                               struct elink_vars *vars,
4457                               struct elink_phy *phy)
4458 {
4459         struct bxe_softc *sc = params->sc;
4460         int i;
4461         static struct elink_reg_set reg_set[] = {
4462                 /* Step 1 - Program the TX/RX alignment markers */
4463                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL5, 0x7690},
4464                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL7, 0xe647},
4465                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL6, 0xc4f0},
4466                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL9, 0x7690},
4467                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL11, 0xe647},
4468                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL10, 0xc4f0},
4469                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_USERB0_CTRL, 0x000c},
4470                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL1, 0x6000},
4471                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL3, 0x0000},
4472                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CODE_FIELD, 0x0002},
4473                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI1, 0x0000},
4474                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI2, 0x0af7},
4475                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI3, 0x0af7},
4476                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_BAM_CODE, 0x0002},
4477                 {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_UD_CODE, 0x0000}
4478         };
4479         ELINK_DEBUG_P0(sc, "Disabling 20G-KR2\n");
4480
4481         for (i = 0; i < ARRAY_SIZE(reg_set); i++)
4482                 elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
4483                                  reg_set[i].val);
4484         vars->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE;
4485         elink_update_link_attr(params, vars->link_attr_sync);
4486
4487         vars->check_kr2_recovery_cnt = ELINK_CHECK_KR2_RECOVERY_CNT;
4488 }
4489
4490 static void elink_warpcore_set_lpi_passthrough(struct elink_phy *phy,
4491                                                struct elink_params *params)
4492 {
4493         struct bxe_softc *sc = params->sc;
4494
4495         ELINK_DEBUG_P0(sc, "Configure WC for LPI pass through\n");
4496         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4497                          MDIO_WC_REG_EEE_COMBO_CONTROL0, 0x7c);
4498         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4499                                  MDIO_WC_REG_DIGITAL4_MISC5, 0xc000);
4500 }
4501
4502 static void elink_warpcore_restart_AN_KR(struct elink_phy *phy,
4503                                          struct elink_params *params)
4504 {
4505         /* Restart autoneg on the leading lane only */
4506         struct bxe_softc *sc = params->sc;
4507         uint16_t lane = elink_get_warpcore_lane(phy, params);
4508         CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4509                           MDIO_AER_BLOCK_AER_REG, lane);
4510         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4511                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
4512
4513         /* Restore AER */
4514         elink_set_aer_mmd(params, phy);
4515 }
4516
4517 static void elink_warpcore_enable_AN_KR(struct elink_phy *phy,
4518                                         struct elink_params *params,
4519                                         struct elink_vars *vars) {
4520         uint16_t lane, i, cl72_ctrl, an_adv = 0;
4521         struct bxe_softc *sc = params->sc;
4522         static struct elink_reg_set reg_set[] = {
4523                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
4524                 {MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0},
4525                 {MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415},
4526                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190},
4527                 /* Disable Autoneg: re-enable it after adv is done. */
4528                 {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0},
4529                 {MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_KR_CONTROL, 0x2},
4530                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP, 0},
4531         };
4532         ELINK_DEBUG_P0(sc, "Enable Auto Negotiation for KR\n");
4533         /* Set to default registers that may be overriden by 10G force */
4534         for (i = 0; i < ARRAY_SIZE(reg_set); i++)
4535                 elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
4536                                  reg_set[i].val);
4537
4538         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4539                         MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &cl72_ctrl);
4540         cl72_ctrl &= 0x08ff;
4541         cl72_ctrl |= 0x3800;
4542         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4543                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, cl72_ctrl);
4544
4545         /* Check adding advertisement for 1G KX */
4546         if (((vars->line_speed == ELINK_SPEED_AUTO_NEG) &&
4547              (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
4548             (vars->line_speed == ELINK_SPEED_1000)) {
4549                 uint16_t addr = MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2;
4550                 an_adv |= (1<<5);
4551
4552                 /* Enable CL37 1G Parallel Detect */
4553                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD, addr, 0x1);
4554                 ELINK_DEBUG_P0(sc, "Advertize 1G\n");
4555         }
4556         if (((vars->line_speed == ELINK_SPEED_AUTO_NEG) &&
4557              (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
4558             (vars->line_speed ==  ELINK_SPEED_10000)) {
4559                 /* Check adding advertisement for 10G KR */
4560                 an_adv |= (1<<7);
4561                 /* Enable 10G Parallel Detect */
4562                 CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4563                                   MDIO_AER_BLOCK_AER_REG, 0);
4564
4565                 elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4566                                  MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
4567                 elink_set_aer_mmd(params, phy);
4568                 ELINK_DEBUG_P0(sc, "Advertize 10G\n");
4569         }
4570
4571         /* Set Transmit PMD settings */
4572         lane = elink_get_warpcore_lane(phy, params);
4573         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4574                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
4575                          WC_TX_DRIVER(0x02, 0x06, 0x09));
4576         /* Configure the next lane if dual mode */
4577         if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
4578                 elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4579                                  MDIO_WC_REG_TX0_TX_DRIVER + 0x10*(lane+1),
4580                                  WC_TX_DRIVER(0x02, 0x06, 0x09));
4581         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4582                          MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
4583                          0x03f0);
4584         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4585                          MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL,
4586                          0x03f0);
4587
4588         /* Advertised speeds */
4589         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4590                          MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, an_adv);
4591
4592         /* Advertised and set FEC (Forward Error Correction) */
4593         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4594                          MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2,
4595                          (MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY |
4596                           MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ));
4597
4598         /* Enable CL37 BAM */
4599         if (REG_RD(sc, params->shmem_base +
4600                    offsetof(struct shmem_region, dev_info.
4601                             port_hw_config[params->port].default_cfg)) &
4602             PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
4603                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4604                                          MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL,
4605                                          1);
4606                 ELINK_DEBUG_P0(sc, "Enable CL37 BAM on KR\n");
4607         }
4608
4609         /* Advertise pause */
4610         elink_ext_phy_set_pause(params, phy, vars);
4611         vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
4612         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4613                                  MDIO_WC_REG_DIGITAL5_MISC7, 0x100);
4614
4615         /* Over 1G - AN local device user page 1 */
4616         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4617                         MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
4618
4619         if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
4620              (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)) ||
4621             (phy->req_line_speed == ELINK_SPEED_20000)) {
4622
4623                 CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4624                                   MDIO_AER_BLOCK_AER_REG, lane);
4625
4626                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4627                                          MDIO_WC_REG_RX1_PCI_CTRL + (0x10*lane),
4628                                          (1<<11));
4629
4630                 elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4631                                  MDIO_WC_REG_XGXS_X2_CONTROL3, 0x7);
4632                 elink_set_aer_mmd(params, phy);
4633
4634                 elink_warpcore_enable_AN_KR2(phy, params, vars);
4635         } else {
4636                 /* Enable Auto-Detect to support 1G over CL37 as well */
4637                 elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4638                                  MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x10);
4639
4640                 /* Force cl48 sync_status LOW to avoid getting stuck in CL73
4641                  * parallel-detect loop when CL73 and CL37 are enabled.
4642                  */
4643                 CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4644                                   MDIO_AER_BLOCK_AER_REG, 0);
4645                 elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4646                                  MDIO_WC_REG_RXB_ANA_RX_CONTROL_PCI, 0x0800);
4647                 elink_set_aer_mmd(params, phy);
4648
4649                 elink_disable_kr2(params, vars, phy);
4650         }
4651
4652         /* Enable Autoneg: only on the main lane */
4653         elink_warpcore_restart_AN_KR(phy, params);
4654 }
4655
4656 static void elink_warpcore_set_10G_KR(struct elink_phy *phy,
4657                                       struct elink_params *params,
4658                                       struct elink_vars *vars)
4659 {
4660         struct bxe_softc *sc = params->sc;
4661         uint16_t val16, i, lane;
4662         static struct elink_reg_set reg_set[] = {
4663                 /* Disable Autoneg */
4664                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
4665                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
4666                         0x3f00},
4667                 {MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0},
4668                 {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0},
4669                 {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1},
4670                 {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa},
4671                 /* Leave cl72 training enable, needed for KR */
4672                 {MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_KR_CONTROL, 0x2}
4673         };
4674
4675         for (i = 0; i < ARRAY_SIZE(reg_set); i++)
4676                 elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
4677                                  reg_set[i].val);
4678
4679         lane = elink_get_warpcore_lane(phy, params);
4680         /* Global registers */
4681         CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4682                           MDIO_AER_BLOCK_AER_REG, 0);
4683         /* Disable CL36 PCS Tx */
4684         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4685                         MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
4686         val16 &= ~(0x0011 << lane);
4687         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4688                          MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
4689
4690         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4691                         MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
4692         val16 |= (0x0303 << (lane << 1));
4693         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4694                          MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
4695         /* Restore AER */
4696         elink_set_aer_mmd(params, phy);
4697         /* Set speed via PMA/PMD register */
4698         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD,
4699                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
4700
4701         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD,
4702                          MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
4703
4704         /* Enable encoded forced speed */
4705         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4706                          MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
4707
4708         /* Turn TX scramble payload only the 64/66 scrambler */
4709         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4710                          MDIO_WC_REG_TX66_CONTROL, 0x9);
4711
4712         /* Turn RX scramble payload only the 64/66 scrambler */
4713         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4714                                  MDIO_WC_REG_RX66_CONTROL, 0xF9);
4715
4716         /* Set and clear loopback to cause a reset to 64/66 decoder */
4717         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4718                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000);
4719         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4720                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
4721
4722 }
4723
4724 static void elink_warpcore_set_10G_XFI(struct elink_phy *phy,
4725                                        struct elink_params *params,
4726                                        uint8_t is_xfi)
4727 {
4728         struct bxe_softc *sc = params->sc;
4729         uint16_t misc1_val, tap_val, tx_driver_val, lane, val;
4730         uint32_t cfg_tap_val, tx_drv_brdct, tx_equal;
4731
4732         /* Hold rxSeqStart */
4733         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4734                                  MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x8000);
4735
4736         /* Hold tx_fifo_reset */
4737         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4738                                  MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x1);
4739
4740         /* Disable CL73 AN */
4741         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
4742
4743         /* Disable 100FX Enable and Auto-Detect */
4744         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4745                                   MDIO_WC_REG_FX100_CTRL1, 0xFFFA);
4746
4747         /* Disable 100FX Idle detect */
4748         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4749                                  MDIO_WC_REG_FX100_CTRL3, 0x0080);
4750
4751         /* Set Block address to Remote PHY & Clear forced_speed[5] */
4752         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4753                                   MDIO_WC_REG_DIGITAL4_MISC3, 0xFF7F);
4754
4755         /* Turn off auto-detect & fiber mode */
4756         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4757                                   MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4758                                   0xFFEE);
4759
4760         /* Set filter_force_link, disable_false_link and parallel_detect */
4761         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4762                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val);
4763         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4764                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4765                          ((val | 0x0006) & 0xFFFE));
4766
4767         /* Set XFI / SFI */
4768         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4769                         MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val);
4770
4771         misc1_val &= ~(0x1f);
4772
4773         if (is_xfi) {
4774                 misc1_val |= 0x5;
4775                 tap_val = WC_TX_FIR(0x08, 0x37, 0x00);
4776                 tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03);
4777         } else {
4778                 cfg_tap_val = REG_RD(sc, params->shmem_base +
4779                                      offsetof(struct shmem_region, dev_info.
4780                                               port_hw_config[params->port].
4781                                               sfi_tap_values));
4782
4783                 tx_equal = cfg_tap_val & PORT_HW_CFG_TX_EQUALIZATION_MASK;
4784
4785                 tx_drv_brdct = (cfg_tap_val &
4786                                 PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >>
4787                                PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT;
4788
4789                 misc1_val |= 0x9;
4790
4791                 /* TAP values are controlled by nvram, if value there isn't 0 */
4792                 if (tx_equal)
4793                         tap_val = (uint16_t)tx_equal;
4794                 else
4795                         tap_val = WC_TX_FIR(0x0f, 0x2b, 0x02);
4796
4797                 if (tx_drv_brdct)
4798                         tx_driver_val = WC_TX_DRIVER(0x03, (uint16_t)tx_drv_brdct,
4799                                                      0x06);
4800                 else
4801                         tx_driver_val = WC_TX_DRIVER(0x03, 0x02, 0x06);
4802         }
4803         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4804                          MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
4805
4806         /* Set Transmit PMD settings */
4807         lane = elink_get_warpcore_lane(phy, params);
4808         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4809                          MDIO_WC_REG_TX_FIR_TAP,
4810                          tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE);
4811         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4812                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
4813                          tx_driver_val);
4814
4815         /* Enable fiber mode, enable and invert sig_det */
4816         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4817                                  MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0xd);
4818
4819         /* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
4820         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4821                                  MDIO_WC_REG_DIGITAL4_MISC3, 0x8080);
4822
4823         elink_warpcore_set_lpi_passthrough(phy, params);
4824
4825         /* 10G XFI Full Duplex */
4826         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4827                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
4828
4829         /* Release tx_fifo_reset */
4830         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4831                                   MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3,
4832                                   0xFFFE);
4833         /* Release rxSeqStart */
4834         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4835                                   MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x7FFF);
4836 }
4837
4838 static void elink_warpcore_set_20G_force_KR2(struct elink_phy *phy,
4839                                              struct elink_params *params)
4840 {
4841         uint16_t val;
4842         struct bxe_softc *sc = params->sc;
4843         /* Set global registers, so set AER lane to 0 */
4844         CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4845                           MDIO_AER_BLOCK_AER_REG, 0);
4846
4847         /* Disable sequencer */
4848         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4849                                   MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, ~(1<<13));
4850
4851         elink_set_aer_mmd(params, phy);
4852
4853         elink_cl45_read_and_write(sc, phy, MDIO_PMA_DEVAD,
4854                                   MDIO_WC_REG_PMD_KR_CONTROL, ~(1<<1));
4855         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
4856                          MDIO_AN_REG_CTRL, 0);
4857         /* Turn off CL73 */
4858         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4859                         MDIO_WC_REG_CL73_USERB0_CTRL, &val);
4860         val &= ~(1<<5);
4861         val |= (1<<6);
4862         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4863                          MDIO_WC_REG_CL73_USERB0_CTRL, val);
4864
4865         /* Set 20G KR2 force speed */
4866         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4867                                  MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x1f);
4868
4869         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4870                                  MDIO_WC_REG_DIGITAL4_MISC3, (1<<7));
4871
4872         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4873                         MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &val);
4874         val &= ~(3<<14);
4875         val |= (1<<15);
4876         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4877                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, val);
4878         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4879                          MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP, 0x835A);
4880
4881         /* Enable sequencer (over lane 0) */
4882         CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
4883                           MDIO_AER_BLOCK_AER_REG, 0);
4884
4885         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4886                                  MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, (1<<13));
4887
4888         elink_set_aer_mmd(params, phy);
4889 }
4890
4891 static void elink_warpcore_set_20G_DXGXS(struct bxe_softc *sc,
4892                                          struct elink_phy *phy,
4893                                          uint16_t lane)
4894 {
4895         /* Rx0 anaRxControl1G */
4896         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4897                          MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90);
4898
4899         /* Rx2 anaRxControl1G */
4900         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4901                          MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90);
4902
4903         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4904                          MDIO_WC_REG_RX66_SCW0, 0xE070);
4905
4906         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4907                          MDIO_WC_REG_RX66_SCW1, 0xC0D0);
4908
4909         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4910                          MDIO_WC_REG_RX66_SCW2, 0xA0B0);
4911
4912         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4913                          MDIO_WC_REG_RX66_SCW3, 0x8090);
4914
4915         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4916                          MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0);
4917
4918         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4919                          MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0);
4920
4921         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4922                          MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0);
4923
4924         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4925                          MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0);
4926
4927         /* Serdes Digital Misc1 */
4928         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4929                          MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008);
4930
4931         /* Serdes Digital4 Misc3 */
4932         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4933                          MDIO_WC_REG_DIGITAL4_MISC3, 0x8088);
4934
4935         /* Set Transmit PMD settings */
4936         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4937                          MDIO_WC_REG_TX_FIR_TAP,
4938                          (WC_TX_FIR(0x12, 0x2d, 0x00) |
4939                           MDIO_WC_REG_TX_FIR_TAP_ENABLE));
4940         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4941                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
4942                          WC_TX_DRIVER(0x02, 0x02, 0x02));
4943 }
4944
4945 static void elink_warpcore_set_sgmii_speed(struct elink_phy *phy,
4946                                            struct elink_params *params,
4947                                            uint8_t fiber_mode,
4948                                            uint8_t always_autoneg)
4949 {
4950         struct bxe_softc *sc = params->sc;
4951         uint16_t val16, digctrl_kx1, digctrl_kx2;
4952
4953         /* Clear XFI clock comp in non-10G single lane mode. */
4954         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
4955                                   MDIO_WC_REG_RX66_CONTROL, ~(3<<13));
4956
4957         elink_warpcore_set_lpi_passthrough(phy, params);
4958
4959         if (always_autoneg || phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
4960                 /* SGMII Autoneg */
4961                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
4962                                          MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
4963                                          0x1000);
4964                 ELINK_DEBUG_P0(sc, "set SGMII AUTONEG\n");
4965         } else {
4966                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4967                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4968                 val16 &= 0xcebf;
4969                 switch (phy->req_line_speed) {
4970                 case ELINK_SPEED_10:
4971                         break;
4972                 case ELINK_SPEED_100:
4973                         val16 |= 0x2000;
4974                         break;
4975                 case ELINK_SPEED_1000:
4976                         val16 |= 0x0040;
4977                         break;
4978                 default:
4979                         ELINK_DEBUG_P1(sc,
4980                            "Speed not supported: 0x%x\n", phy->req_line_speed);
4981                         return;
4982                 }
4983
4984                 if (phy->req_duplex == DUPLEX_FULL)
4985                         val16 |= 0x0100;
4986
4987                 elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
4988                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16);
4989
4990                 ELINK_DEBUG_P1(sc, "set SGMII force speed %d\n",
4991                                phy->req_line_speed);
4992                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4993                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4994                 ELINK_DEBUG_P1(sc, "  (readback) %x\n", val16);
4995         }
4996
4997         /* SGMII Slave mode and disable signal detect */
4998         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
4999                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1);
5000         if (fiber_mode)
5001                 digctrl_kx1 = 1;
5002         else
5003                 digctrl_kx1 &= 0xff4a;
5004
5005         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5006                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
5007                         digctrl_kx1);
5008
5009         /* Turn off parallel detect */
5010         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5011                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2);
5012         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5013                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
5014                         (digctrl_kx2 & ~(1<<2)));
5015
5016         /* Re-enable parallel detect */
5017         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5018                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
5019                         (digctrl_kx2 | (1<<2)));
5020
5021         /* Enable autodet */
5022         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5023                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
5024                         (digctrl_kx1 | 0x10));
5025 }
5026
5027
5028 static void elink_warpcore_reset_lane(struct bxe_softc *sc,
5029                                       struct elink_phy *phy,
5030                                       uint8_t reset)
5031 {
5032         uint16_t val;
5033         /* Take lane out of reset after configuration is finished */
5034         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5035                         MDIO_WC_REG_DIGITAL5_MISC6, &val);
5036         if (reset)
5037                 val |= 0xC000;
5038         else
5039                 val &= 0x3FFF;
5040         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5041                          MDIO_WC_REG_DIGITAL5_MISC6, val);
5042         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5043                          MDIO_WC_REG_DIGITAL5_MISC6, &val);
5044 }
5045
5046 /* Clear SFI/XFI link settings registers */
5047 static void elink_warpcore_clear_regs(struct elink_phy *phy,
5048                                       struct elink_params *params,
5049                                       uint16_t lane)
5050 {
5051         struct bxe_softc *sc = params->sc;
5052         uint16_t i;
5053         static struct elink_reg_set wc_regs[] = {
5054                 {MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0},
5055                 {MDIO_WC_DEVAD, MDIO_WC_REG_FX100_CTRL1, 0x014a},
5056                 {MDIO_WC_DEVAD, MDIO_WC_REG_FX100_CTRL3, 0x0800},
5057                 {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL4_MISC3, 0x8008},
5058                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
5059                         0x0195},
5060                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
5061                         0x0007},
5062                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3,
5063                         0x0002},
5064                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000},
5065                 {MDIO_WC_DEVAD, MDIO_WC_REG_TX_FIR_TAP, 0x0000},
5066                 {MDIO_WC_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040},
5067                 {MDIO_WC_DEVAD, MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140}
5068         };
5069         /* Set XFI clock comp as default. */
5070         elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5071                                  MDIO_WC_REG_RX66_CONTROL, (3<<13));
5072
5073         for (i = 0; i < ARRAY_SIZE(wc_regs); i++)
5074                 elink_cl45_write(sc, phy, wc_regs[i].devad, wc_regs[i].reg,
5075                                  wc_regs[i].val);
5076
5077         lane = elink_get_warpcore_lane(phy, params);
5078         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5079                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990);
5080
5081 }
5082
5083 static elink_status_t elink_get_mod_abs_int_cfg(struct bxe_softc *sc,
5084                                                 uint32_t chip_id,
5085                                                 uint32_t shmem_base, uint8_t port,
5086                                                 uint8_t *gpio_num, uint8_t *gpio_port)
5087 {
5088         uint32_t cfg_pin;
5089         *gpio_num = 0;
5090         *gpio_port = 0;
5091         if (CHIP_IS_E3(sc)) {
5092                 cfg_pin = (REG_RD(sc, shmem_base +
5093                                 offsetof(struct shmem_region,
5094                                 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
5095                                 PORT_HW_CFG_E3_MOD_ABS_MASK) >>
5096                                 PORT_HW_CFG_E3_MOD_ABS_SHIFT;
5097
5098                 /* Should not happen. This function called upon interrupt
5099                  * triggered by GPIO ( since EPIO can only generate interrupts
5100                  * to MCP).
5101                  * So if this function was called and none of the GPIOs was set,
5102                  * it means the shit hit the fan.
5103                  */
5104                 if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
5105                     (cfg_pin > PIN_CFG_GPIO3_P1)) {
5106                         ELINK_DEBUG_P1(sc,
5107                            "No cfg pin %x for module detect indication\n",
5108                            cfg_pin);
5109                         return ELINK_STATUS_ERROR;
5110                 }
5111
5112                 *gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
5113                 *gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
5114         } else {
5115                 *gpio_num = MISC_REGISTERS_GPIO_3;
5116                 *gpio_port = port;
5117         }
5118
5119         return ELINK_STATUS_OK;
5120 }
5121
5122 static int elink_is_sfp_module_plugged(struct elink_phy *phy,
5123                                        struct elink_params *params)
5124 {
5125         struct bxe_softc *sc = params->sc;
5126         uint8_t gpio_num, gpio_port;
5127         uint32_t gpio_val;
5128         if (elink_get_mod_abs_int_cfg(sc, params->chip_id,
5129                                       params->shmem_base, params->port,
5130                                       &gpio_num, &gpio_port) != ELINK_STATUS_OK)
5131                 return 0;
5132         gpio_val = elink_cb_gpio_read(sc, gpio_num, gpio_port);
5133
5134         /* Call the handling function in case module is detected */
5135         if (gpio_val == 0)
5136                 return 1;
5137         else
5138                 return 0;
5139 }
5140 static int elink_warpcore_get_sigdet(struct elink_phy *phy,
5141                                      struct elink_params *params)
5142 {
5143         uint16_t gp2_status_reg0, lane;
5144         struct bxe_softc *sc = params->sc;
5145
5146         lane = elink_get_warpcore_lane(phy, params);
5147
5148         elink_cl45_read(sc, phy, MDIO_WC_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_0,
5149                                  &gp2_status_reg0);
5150
5151         return (gp2_status_reg0 >> (8+lane)) & 0x1;
5152 }
5153
5154 static void elink_warpcore_config_runtime(struct elink_phy *phy,
5155                                           struct elink_params *params,
5156                                           struct elink_vars *vars)
5157 {
5158         struct bxe_softc *sc = params->sc;
5159         uint32_t serdes_net_if;
5160         uint16_t gp_status1 = 0, lnkup = 0, lnkup_kr = 0;
5161
5162         vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1;
5163
5164         if (!vars->turn_to_run_wc_rt)
5165                 return;
5166
5167         if (vars->rx_tx_asic_rst) {
5168                 uint16_t lane = elink_get_warpcore_lane(phy, params);
5169                 serdes_net_if = (REG_RD(sc, params->shmem_base +
5170                                 offsetof(struct shmem_region, dev_info.
5171                                 port_hw_config[params->port].default_cfg)) &
5172                                 PORT_HW_CFG_NET_SERDES_IF_MASK);
5173
5174                 switch (serdes_net_if) {
5175                 case PORT_HW_CFG_NET_SERDES_IF_KR:
5176                         /* Do we get link yet? */
5177                         elink_cl45_read(sc, phy, MDIO_WC_DEVAD, 0x81d1,
5178                                         &gp_status1);
5179                         lnkup = (gp_status1 >> (8+lane)) & 0x1;/* 1G */
5180                                 /*10G KR*/
5181                         lnkup_kr = (gp_status1 >> (12+lane)) & 0x1;
5182
5183                         if (lnkup_kr || lnkup) {
5184                                 vars->rx_tx_asic_rst = 0;
5185                         } else {
5186                                 /* Reset the lane to see if link comes up.*/
5187                                 elink_warpcore_reset_lane(sc, phy, 1);
5188                                 elink_warpcore_reset_lane(sc, phy, 0);
5189
5190                                 /* Restart Autoneg */
5191                                 elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
5192                                         MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
5193
5194                                 vars->rx_tx_asic_rst--;
5195                                 ELINK_DEBUG_P1(sc, "0x%x retry left\n",
5196                                 vars->rx_tx_asic_rst);
5197                         }
5198                         break;
5199
5200                 default:
5201                         break;
5202                 }
5203
5204         } /*params->rx_tx_asic_rst*/
5205
5206 }
5207 static void elink_warpcore_config_sfi(struct elink_phy *phy,
5208                                       struct elink_params *params)
5209 {
5210         uint16_t lane = elink_get_warpcore_lane(phy, params);
5211         struct bxe_softc *sc = params->sc;
5212         elink_warpcore_clear_regs(phy, params, lane);
5213         if ((params->req_line_speed[ELINK_LINK_CONFIG_IDX(ELINK_INT_PHY)] ==
5214              ELINK_SPEED_10000) &&
5215             (phy->media_type != ELINK_ETH_PHY_SFP_1G_FIBER)) {
5216                 ELINK_DEBUG_P0(sc, "Setting 10G SFI\n");
5217                 elink_warpcore_set_10G_XFI(phy, params, 0);
5218         } else {
5219                 ELINK_DEBUG_P0(sc, "Setting 1G Fiber\n");
5220                 elink_warpcore_set_sgmii_speed(phy, params, 1, 0);
5221         }
5222 }
5223
5224 static void elink_sfp_e3_set_transmitter(struct elink_params *params,
5225                                          struct elink_phy *phy,
5226                                          uint8_t tx_en)
5227 {
5228         struct bxe_softc *sc = params->sc;
5229         uint32_t cfg_pin;
5230         uint8_t port = params->port;
5231
5232         cfg_pin = REG_RD(sc, params->shmem_base +
5233                          offsetof(struct shmem_region,
5234                                   dev_info.port_hw_config[port].e3_sfp_ctrl)) &
5235                 PORT_HW_CFG_E3_TX_LASER_MASK;
5236         /* Set the !tx_en since this pin is DISABLE_TX_LASER */
5237         ELINK_DEBUG_P1(sc, "Setting WC TX to %d\n", tx_en);
5238
5239         /* For 20G, the expected pin to be used is 3 pins after the current */
5240         elink_set_cfg_pin(sc, cfg_pin, tx_en ^ 1);
5241         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
5242                 elink_set_cfg_pin(sc, cfg_pin + 3, tx_en ^ 1);
5243 }
5244
5245 static void elink_warpcore_config_init(struct elink_phy *phy,
5246                                        struct elink_params *params,
5247                                        struct elink_vars *vars)
5248 {
5249         struct bxe_softc *sc = params->sc;
5250         uint32_t serdes_net_if;
5251         uint8_t fiber_mode;
5252         uint16_t lane = elink_get_warpcore_lane(phy, params);
5253         serdes_net_if = (REG_RD(sc, params->shmem_base +
5254                          offsetof(struct shmem_region, dev_info.
5255                                   port_hw_config[params->port].default_cfg)) &
5256                          PORT_HW_CFG_NET_SERDES_IF_MASK);
5257         ELINK_DEBUG_P2(sc, "Begin Warpcore init, link_speed %d, "
5258                            "serdes_net_if = 0x%x\n",
5259                        vars->line_speed, serdes_net_if);
5260         elink_set_aer_mmd(params, phy);
5261         elink_warpcore_reset_lane(sc, phy, 1);
5262         vars->phy_flags |= PHY_XGXS_FLAG;
5263         if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
5264             (phy->req_line_speed &&
5265              ((phy->req_line_speed == ELINK_SPEED_100) ||
5266               (phy->req_line_speed == ELINK_SPEED_10)))) {
5267                 vars->phy_flags |= PHY_SGMII_FLAG;
5268                 ELINK_DEBUG_P0(sc, "Setting SGMII mode\n");
5269                 elink_warpcore_clear_regs(phy, params, lane);
5270                 elink_warpcore_set_sgmii_speed(phy, params, 0, 1);
5271         } else {
5272                 switch (serdes_net_if) {
5273                 case PORT_HW_CFG_NET_SERDES_IF_KR:
5274                         /* Enable KR Auto Neg */
5275                         if (params->loopback_mode != ELINK_LOOPBACK_EXT)
5276                                 elink_warpcore_enable_AN_KR(phy, params, vars);
5277                         else {
5278                                 ELINK_DEBUG_P0(sc, "Setting KR 10G-Force\n");
5279                                 elink_warpcore_set_10G_KR(phy, params, vars);
5280                         }
5281                         break;
5282
5283                 case PORT_HW_CFG_NET_SERDES_IF_XFI:
5284                         elink_warpcore_clear_regs(phy, params, lane);
5285                         if (vars->line_speed == ELINK_SPEED_10000) {
5286                                 ELINK_DEBUG_P0(sc, "Setting 10G XFI\n");
5287                                 elink_warpcore_set_10G_XFI(phy, params, 1);
5288                         } else {
5289                                 if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
5290                                         ELINK_DEBUG_P0(sc, "1G Fiber\n");
5291                                         fiber_mode = 1;
5292                                 } else {
5293                                         ELINK_DEBUG_P0(sc, "10/100/1G SGMII\n");
5294                                         fiber_mode = 0;
5295                                 }
5296                                 elink_warpcore_set_sgmii_speed(phy,
5297                                                                 params,
5298                                                                 fiber_mode,
5299                                                                 0);
5300                         }
5301
5302                         break;
5303
5304                 case PORT_HW_CFG_NET_SERDES_IF_SFI:
5305                         /* Issue Module detection if module is plugged, or
5306                          * enabled transmitter to avoid current leakage in case
5307                          * no module is connected
5308                          */
5309                         if ((params->loopback_mode == ELINK_LOOPBACK_NONE) ||
5310                             (params->loopback_mode == ELINK_LOOPBACK_EXT)) {
5311                                 if (elink_is_sfp_module_plugged(phy, params))
5312                                         elink_sfp_module_detection(phy, params);
5313                                 else
5314                                         elink_sfp_e3_set_transmitter(params,
5315                                                                      phy, 1);
5316                         }
5317
5318                         elink_warpcore_config_sfi(phy, params);
5319                         break;
5320
5321                 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
5322                         if (vars->line_speed != ELINK_SPEED_20000) {
5323                                 ELINK_DEBUG_P0(sc, "Speed not supported yet\n");
5324                                 return;
5325                         }
5326                         ELINK_DEBUG_P0(sc, "Setting 20G DXGXS\n");
5327                         elink_warpcore_set_20G_DXGXS(sc, phy, lane);
5328                         /* Issue Module detection */
5329
5330                         elink_sfp_module_detection(phy, params);
5331                         break;
5332                 case PORT_HW_CFG_NET_SERDES_IF_KR2:
5333                         if (!params->loopback_mode) {
5334                                 elink_warpcore_enable_AN_KR(phy, params, vars);
5335                         } else {
5336                                 ELINK_DEBUG_P0(sc, "Setting KR 20G-Force\n");
5337                                 elink_warpcore_set_20G_force_KR2(phy, params);
5338                         }
5339                         break;
5340                 default:
5341                         ELINK_DEBUG_P1(sc,
5342                            "Unsupported Serdes Net Interface 0x%x\n",
5343                            serdes_net_if);
5344                         return;
5345                 }
5346         }
5347
5348         /* Take lane out of reset after configuration is finished */
5349         elink_warpcore_reset_lane(sc, phy, 0);
5350         ELINK_DEBUG_P0(sc, "Exit config init\n");
5351 }
5352
5353 static void elink_warpcore_link_reset(struct elink_phy *phy,
5354                                       struct elink_params *params)
5355 {
5356         struct bxe_softc *sc = params->sc;
5357         uint16_t val16, lane;
5358         elink_sfp_e3_set_transmitter(params, phy, 0);
5359         elink_set_mdio_emac_per_phy(sc, params);
5360         elink_set_aer_mmd(params, phy);
5361         /* Global register */
5362         elink_warpcore_reset_lane(sc, phy, 1);
5363
5364         /* Clear loopback settings (if any) */
5365         /* 10G & 20G */
5366         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5367                                   MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0xBFFF);
5368
5369         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5370                                   MDIO_WC_REG_IEEE0BLK_MIICNTL, 0xfffe);
5371
5372         /* Update those 1-copy registers */
5373         CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
5374                           MDIO_AER_BLOCK_AER_REG, 0);
5375         /* Enable 1G MDIO (1-copy) */
5376         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5377                                   MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
5378                                   ~0x10);
5379
5380         elink_cl45_read_and_write(sc, phy, MDIO_WC_DEVAD,
5381                                   MDIO_WC_REG_XGXSBLK1_LANECTRL2, 0xff00);
5382         lane = elink_get_warpcore_lane(phy, params);
5383         /* Disable CL36 PCS Tx */
5384         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5385                         MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
5386         val16 |= (0x11 << lane);
5387         if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
5388                 val16 |= (0x22 << lane);
5389         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5390                          MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
5391
5392         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5393                         MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
5394         val16 &= ~(0x0303 << (lane << 1));
5395         val16 |= (0x0101 << (lane << 1));
5396         if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE) {
5397                 val16 &= ~(0x0c0c << (lane << 1));
5398                 val16 |= (0x0404 << (lane << 1));
5399         }
5400
5401         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5402                          MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
5403         /* Restore AER */
5404         elink_set_aer_mmd(params, phy);
5405
5406 }
5407
5408 static void elink_set_warpcore_loopback(struct elink_phy *phy,
5409                                         struct elink_params *params)
5410 {
5411         struct bxe_softc *sc = params->sc;
5412         uint16_t val16;
5413         uint32_t lane;
5414         ELINK_DEBUG_P2(sc, "Setting Warpcore loopback type %x, speed %d\n",
5415                        params->loopback_mode, phy->req_line_speed);
5416
5417         if (phy->req_line_speed < ELINK_SPEED_10000 ||
5418             phy->supported & ELINK_SUPPORTED_20000baseKR2_Full) {
5419                 /* 10/100/1000/20G-KR2 */
5420
5421                 /* Update those 1-copy registers */
5422                 CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
5423                                   MDIO_AER_BLOCK_AER_REG, 0);
5424                 /* Enable 1G MDIO (1-copy) */
5425                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5426                                          MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
5427                                          0x10);
5428                 /* Set 1G loopback based on lane (1-copy) */
5429                 lane = elink_get_warpcore_lane(phy, params);
5430                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
5431                                 MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
5432                 val16 |= (1<<lane);
5433                 if (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)
5434                         val16 |= (2<<lane);
5435                 elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
5436                                  MDIO_WC_REG_XGXSBLK1_LANECTRL2,
5437                                  val16);
5438
5439                 /* Switch back to 4-copy registers */
5440                 elink_set_aer_mmd(params, phy);
5441         } else {
5442                 /* 10G / 20G-DXGXS */
5443                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5444                                          MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
5445                                          0x4000);
5446                 elink_cl45_read_or_write(sc, phy, MDIO_WC_DEVAD,
5447                                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1);
5448         }
5449 }
5450
5451
5452
5453 static void elink_sync_link(struct elink_params *params,
5454                              struct elink_vars *vars)
5455 {
5456         struct bxe_softc *sc = params->sc;
5457         uint8_t link_10g_plus;
5458         if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
5459                 vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
5460         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
5461         if (vars->link_up) {
5462                 ELINK_DEBUG_P0(sc, "phy link up\n");
5463
5464                 vars->phy_link_up = 1;
5465                 vars->duplex = DUPLEX_FULL;
5466                 switch (vars->link_status &
5467                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
5468                 case ELINK_LINK_10THD:
5469                         vars->duplex = DUPLEX_HALF;
5470                         /* Fall thru */
5471                 case ELINK_LINK_10TFD:
5472                         vars->line_speed = ELINK_SPEED_10;
5473                         break;
5474
5475                 case ELINK_LINK_100TXHD:
5476                         vars->duplex = DUPLEX_HALF;
5477                         /* Fall thru */
5478                 case ELINK_LINK_100T4:
5479                 case ELINK_LINK_100TXFD:
5480                         vars->line_speed = ELINK_SPEED_100;
5481                         break;
5482
5483                 case ELINK_LINK_1000THD:
5484                         vars->duplex = DUPLEX_HALF;
5485                         /* Fall thru */
5486                 case ELINK_LINK_1000TFD:
5487                         vars->line_speed = ELINK_SPEED_1000;
5488                         break;
5489
5490                 case ELINK_LINK_2500THD:
5491                         vars->duplex = DUPLEX_HALF;
5492                         /* Fall thru */
5493                 case ELINK_LINK_2500TFD:
5494                         vars->line_speed = ELINK_SPEED_2500;
5495                         break;
5496
5497                 case ELINK_LINK_10GTFD:
5498                         vars->line_speed = ELINK_SPEED_10000;
5499                         break;
5500                 case ELINK_LINK_20GTFD:
5501                         vars->line_speed = ELINK_SPEED_20000;
5502                         break;
5503                 default:
5504                         break;
5505                 }
5506                 vars->flow_ctrl = 0;
5507                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
5508                         vars->flow_ctrl |= ELINK_FLOW_CTRL_TX;
5509
5510                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
5511                         vars->flow_ctrl |= ELINK_FLOW_CTRL_RX;
5512
5513                 if (!vars->flow_ctrl)
5514                         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
5515
5516                 if (vars->line_speed &&
5517                     ((vars->line_speed == ELINK_SPEED_10) ||
5518                      (vars->line_speed == ELINK_SPEED_100))) {
5519                         vars->phy_flags |= PHY_SGMII_FLAG;
5520                 } else {
5521                         vars->phy_flags &= ~PHY_SGMII_FLAG;
5522                 }
5523                 if (vars->line_speed &&
5524                     USES_WARPCORE(sc) &&
5525                     (vars->line_speed == ELINK_SPEED_1000))
5526                         vars->phy_flags |= PHY_SGMII_FLAG;
5527                 /* Anything 10 and over uses the bmac */
5528                 link_10g_plus = (vars->line_speed >= ELINK_SPEED_10000);
5529
5530                 if (link_10g_plus) {
5531                         if (USES_WARPCORE(sc))
5532                                 vars->mac_type = ELINK_MAC_TYPE_XMAC;
5533                         else
5534                                 vars->mac_type = ELINK_MAC_TYPE_BMAC;
5535                 } else {
5536                         if (USES_WARPCORE(sc))
5537                                 vars->mac_type = ELINK_MAC_TYPE_UMAC;
5538                         else
5539                                 vars->mac_type = ELINK_MAC_TYPE_EMAC;
5540                 }
5541         } else { /* Link down */
5542                 ELINK_DEBUG_P0(sc, "phy link down\n");
5543
5544                 vars->phy_link_up = 0;
5545
5546                 vars->line_speed = 0;
5547                 vars->duplex = DUPLEX_FULL;
5548                 vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
5549
5550                 /* Indicate no mac active */
5551                 vars->mac_type = ELINK_MAC_TYPE_NONE;
5552                 if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
5553                         vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
5554                 if (vars->link_status & LINK_STATUS_SFP_TX_FAULT)
5555                         vars->phy_flags |= PHY_SFP_TX_FAULT_FLAG;
5556         }
5557 }
5558
5559 void elink_link_status_update(struct elink_params *params,
5560                               struct elink_vars *vars)
5561 {
5562         struct bxe_softc *sc = params->sc;
5563         uint8_t port = params->port;
5564         uint32_t sync_offset, media_types;
5565         /* Update PHY configuration */
5566         set_phy_vars(params, vars);
5567
5568         vars->link_status = REG_RD(sc, params->shmem_base +
5569                                    offsetof(struct shmem_region,
5570                                             port_mb[port].link_status));
5571
5572         /* Force link UP in non LOOPBACK_EXT loopback mode(s) */
5573         if (params->loopback_mode != ELINK_LOOPBACK_NONE &&
5574             params->loopback_mode != ELINK_LOOPBACK_EXT)
5575                 vars->link_status |= LINK_STATUS_LINK_UP;
5576
5577         if (elink_eee_has_cap(params))
5578                 vars->eee_status = REG_RD(sc, params->shmem2_base +
5579                                           offsetof(struct shmem2_region,
5580                                                    eee_status[params->port]));
5581
5582         vars->phy_flags = PHY_XGXS_FLAG;
5583         elink_sync_link(params, vars);
5584         /* Sync media type */
5585         sync_offset = params->shmem_base +
5586                         offsetof(struct shmem_region,
5587                                  dev_info.port_hw_config[port].media_type);
5588         media_types = REG_RD(sc, sync_offset);
5589
5590         params->phy[ELINK_INT_PHY].media_type =
5591                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
5592                 PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
5593         params->phy[ELINK_EXT_PHY1].media_type =
5594                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
5595                 PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
5596         params->phy[ELINK_EXT_PHY2].media_type =
5597                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
5598                 PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
5599         ELINK_DEBUG_P1(sc, "media_types = 0x%x\n", media_types);
5600
5601         /* Sync AEU offset */
5602         sync_offset = params->shmem_base +
5603                         offsetof(struct shmem_region,
5604                                  dev_info.port_hw_config[port].aeu_int_mask);
5605
5606         vars->aeu_int_mask = REG_RD(sc, sync_offset);
5607
5608         /* Sync PFC status */
5609         if (vars->link_status & LINK_STATUS_PFC_ENABLED)
5610                 params->feature_config_flags |=
5611                                         ELINK_FEATURE_CONFIG_PFC_ENABLED;
5612         else
5613                 params->feature_config_flags &=
5614                                         ~ELINK_FEATURE_CONFIG_PFC_ENABLED;
5615
5616         if (SHMEM2_HAS(sc, link_attr_sync))
5617                 vars->link_attr_sync = SHMEM2_RD(sc,
5618                                                  link_attr_sync[params->port]);
5619
5620         ELINK_DEBUG_P3(sc, "link_status 0x%x  phy_link_up %x int_mask 0x%x\n",
5621                  vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
5622         ELINK_DEBUG_P3(sc, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
5623                  vars->line_speed, vars->duplex, vars->flow_ctrl);
5624 }
5625
5626 static void elink_set_master_ln(struct elink_params *params,
5627                                 struct elink_phy *phy)
5628 {
5629         struct bxe_softc *sc = params->sc;
5630         uint16_t new_master_ln, ser_lane;
5631         ser_lane = ((params->lane_config &
5632                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
5633                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
5634
5635         /* Set the master_ln for AN */
5636         CL22_RD_OVER_CL45(sc, phy,
5637                           MDIO_REG_BANK_XGXS_BLOCK2,
5638                           MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
5639                           &new_master_ln);
5640
5641         CL22_WR_OVER_CL45(sc, phy,
5642                           MDIO_REG_BANK_XGXS_BLOCK2 ,
5643                           MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
5644                           (new_master_ln | ser_lane));
5645 }
5646
5647 static elink_status_t elink_reset_unicore(struct elink_params *params,
5648                                struct elink_phy *phy,
5649                                uint8_t set_serdes)
5650 {
5651         struct bxe_softc *sc = params->sc;
5652         uint16_t mii_control;
5653         uint16_t i;
5654         CL22_RD_OVER_CL45(sc, phy,
5655                           MDIO_REG_BANK_COMBO_IEEE0,
5656                           MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
5657
5658         /* Reset the unicore */
5659         CL22_WR_OVER_CL45(sc, phy,
5660                           MDIO_REG_BANK_COMBO_IEEE0,
5661                           MDIO_COMBO_IEEE0_MII_CONTROL,
5662                           (mii_control |
5663                            MDIO_COMBO_IEEO_MII_CONTROL_RESET));
5664         if (set_serdes)
5665                 elink_set_serdes_access(sc, params->port);
5666
5667         /* Wait for the reset to self clear */
5668         for (i = 0; i < ELINK_MDIO_ACCESS_TIMEOUT; i++) {
5669                 DELAY(5);
5670
5671                 /* The reset erased the previous bank value */
5672                 CL22_RD_OVER_CL45(sc, phy,
5673                                   MDIO_REG_BANK_COMBO_IEEE0,
5674                                   MDIO_COMBO_IEEE0_MII_CONTROL,
5675                                   &mii_control);
5676
5677                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
5678                         DELAY(5);
5679                         return ELINK_STATUS_OK;
5680                 }
5681         }
5682
5683         elink_cb_event_log(sc, ELINK_LOG_ID_PHY_UNINITIALIZED, params->port); // "Warning: PHY was not initialized,"
5684                              // " Port %d\n",
5685
5686         ELINK_DEBUG_P0(sc, "BUG! XGXS is still in reset!\n");
5687         return ELINK_STATUS_ERROR;
5688
5689 }
5690
5691 static void elink_set_swap_lanes(struct elink_params *params,
5692                                  struct elink_phy *phy)
5693 {
5694         struct bxe_softc *sc = params->sc;
5695         /* Each two bits represents a lane number:
5696          * No swap is 0123 => 0x1b no need to enable the swap
5697          */
5698         uint16_t rx_lane_swap, tx_lane_swap;
5699
5700         rx_lane_swap = ((params->lane_config &
5701                          PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
5702                         PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
5703         tx_lane_swap = ((params->lane_config &
5704                          PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
5705                         PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
5706
5707         if (rx_lane_swap != 0x1b) {
5708                 CL22_WR_OVER_CL45(sc, phy,
5709                                   MDIO_REG_BANK_XGXS_BLOCK2,
5710                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP,
5711                                   (rx_lane_swap |
5712                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
5713                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
5714         } else {
5715                 CL22_WR_OVER_CL45(sc, phy,
5716                                   MDIO_REG_BANK_XGXS_BLOCK2,
5717                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
5718         }
5719
5720         if (tx_lane_swap != 0x1b) {
5721                 CL22_WR_OVER_CL45(sc, phy,
5722                                   MDIO_REG_BANK_XGXS_BLOCK2,
5723                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP,
5724                                   (tx_lane_swap |
5725                                    MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
5726         } else {
5727                 CL22_WR_OVER_CL45(sc, phy,
5728                                   MDIO_REG_BANK_XGXS_BLOCK2,
5729                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
5730         }
5731 }
5732
5733 static void elink_set_parallel_detection(struct elink_phy *phy,
5734                                          struct elink_params *params)
5735 {
5736         struct bxe_softc *sc = params->sc;
5737         uint16_t control2;
5738         CL22_RD_OVER_CL45(sc, phy,
5739                           MDIO_REG_BANK_SERDES_DIGITAL,
5740                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
5741                           &control2);
5742         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
5743                 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
5744         else
5745                 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
5746         ELINK_DEBUG_P2(sc, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
5747                 phy->speed_cap_mask, control2);
5748         CL22_WR_OVER_CL45(sc, phy,
5749                           MDIO_REG_BANK_SERDES_DIGITAL,
5750                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
5751                           control2);
5752
5753         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
5754              (phy->speed_cap_mask &
5755                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
5756                 ELINK_DEBUG_P0(sc, "XGXS\n");
5757
5758                 CL22_WR_OVER_CL45(sc, phy,
5759                                  MDIO_REG_BANK_10G_PARALLEL_DETECT,
5760                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
5761                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
5762
5763                 CL22_RD_OVER_CL45(sc, phy,
5764                                   MDIO_REG_BANK_10G_PARALLEL_DETECT,
5765                                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
5766                                   &control2);
5767
5768
5769                 control2 |=
5770                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
5771
5772                 CL22_WR_OVER_CL45(sc, phy,
5773                                   MDIO_REG_BANK_10G_PARALLEL_DETECT,
5774                                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
5775                                   control2);
5776
5777                 /* Disable parallel detection of HiG */
5778                 CL22_WR_OVER_CL45(sc, phy,
5779                                   MDIO_REG_BANK_XGXS_BLOCK2,
5780                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
5781                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
5782                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
5783         }
5784 }
5785
5786 static void elink_set_autoneg(struct elink_phy *phy,
5787                               struct elink_params *params,
5788                               struct elink_vars *vars,
5789                               uint8_t enable_cl73)
5790 {
5791         struct bxe_softc *sc = params->sc;
5792         uint16_t reg_val;
5793
5794         /* CL37 Autoneg */
5795         CL22_RD_OVER_CL45(sc, phy,
5796                           MDIO_REG_BANK_COMBO_IEEE0,
5797                           MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
5798
5799         /* CL37 Autoneg Enabled */
5800         if (vars->line_speed == ELINK_SPEED_AUTO_NEG)
5801                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
5802         else /* CL37 Autoneg Disabled */
5803                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
5804                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
5805
5806         CL22_WR_OVER_CL45(sc, phy,
5807                           MDIO_REG_BANK_COMBO_IEEE0,
5808                           MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
5809
5810         /* Enable/Disable Autodetection */
5811
5812         CL22_RD_OVER_CL45(sc, phy,
5813                           MDIO_REG_BANK_SERDES_DIGITAL,
5814                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
5815         reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
5816                     MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
5817         reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
5818         if (vars->line_speed == ELINK_SPEED_AUTO_NEG)
5819                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
5820         else
5821                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
5822
5823         CL22_WR_OVER_CL45(sc, phy,
5824                           MDIO_REG_BANK_SERDES_DIGITAL,
5825                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
5826
5827         /* Enable TetonII and BAM autoneg */
5828         CL22_RD_OVER_CL45(sc, phy,
5829                           MDIO_REG_BANK_BAM_NEXT_PAGE,
5830                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
5831                           &reg_val);
5832         if (vars->line_speed == ELINK_SPEED_AUTO_NEG) {
5833                 /* Enable BAM aneg Mode and TetonII aneg Mode */
5834                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
5835                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
5836         } else {
5837                 /* TetonII and BAM Autoneg Disabled */
5838                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
5839                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
5840         }
5841         CL22_WR_OVER_CL45(sc, phy,
5842                           MDIO_REG_BANK_BAM_NEXT_PAGE,
5843                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
5844                           reg_val);
5845
5846         if (enable_cl73) {
5847                 /* Enable Cl73 FSM status bits */
5848                 CL22_WR_OVER_CL45(sc, phy,
5849                                   MDIO_REG_BANK_CL73_USERB0,
5850                                   MDIO_CL73_USERB0_CL73_UCTRL,
5851                                   0xe);
5852
5853                 /* Enable BAM Station Manager*/
5854                 CL22_WR_OVER_CL45(sc, phy,
5855                         MDIO_REG_BANK_CL73_USERB0,
5856                         MDIO_CL73_USERB0_CL73_BAM_CTRL1,
5857                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
5858                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
5859                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
5860
5861                 /* Advertise CL73 link speeds */
5862                 CL22_RD_OVER_CL45(sc, phy,
5863                                   MDIO_REG_BANK_CL73_IEEEB1,
5864                                   MDIO_CL73_IEEEB1_AN_ADV2,
5865                                   &reg_val);
5866                 if (phy->speed_cap_mask &
5867                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
5868                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
5869                 if (phy->speed_cap_mask &
5870                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
5871                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
5872
5873                 CL22_WR_OVER_CL45(sc, phy,
5874                                   MDIO_REG_BANK_CL73_IEEEB1,
5875                                   MDIO_CL73_IEEEB1_AN_ADV2,
5876                                   reg_val);
5877
5878                 /* CL73 Autoneg Enabled */
5879                 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
5880
5881         } else /* CL73 Autoneg Disabled */
5882                 reg_val = 0;
5883
5884         CL22_WR_OVER_CL45(sc, phy,
5885                           MDIO_REG_BANK_CL73_IEEEB0,
5886                           MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
5887 }
5888
5889 /* Program SerDes, forced speed */
5890 static void elink_program_serdes(struct elink_phy *phy,
5891                                  struct elink_params *params,
5892                                  struct elink_vars *vars)
5893 {
5894         struct bxe_softc *sc = params->sc;
5895         uint16_t reg_val;
5896
5897         /* Program duplex, disable autoneg and sgmii*/
5898         CL22_RD_OVER_CL45(sc, phy,
5899                           MDIO_REG_BANK_COMBO_IEEE0,
5900                           MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
5901         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
5902                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
5903                      MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
5904         if (phy->req_duplex == DUPLEX_FULL)
5905                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
5906         CL22_WR_OVER_CL45(sc, phy,
5907                           MDIO_REG_BANK_COMBO_IEEE0,
5908                           MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
5909
5910         /* Program speed
5911          *  - needed only if the speed is greater than 1G (2.5G or 10G)
5912          */
5913         CL22_RD_OVER_CL45(sc, phy,
5914                           MDIO_REG_BANK_SERDES_DIGITAL,
5915                           MDIO_SERDES_DIGITAL_MISC1, &reg_val);
5916         /* Clearing the speed value before setting the right speed */
5917         ELINK_DEBUG_P1(sc, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
5918
5919         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
5920                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
5921
5922         if (!((vars->line_speed == ELINK_SPEED_1000) ||
5923               (vars->line_speed == ELINK_SPEED_100) ||
5924               (vars->line_speed == ELINK_SPEED_10))) {
5925
5926                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
5927                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
5928                 if (vars->line_speed == ELINK_SPEED_10000)
5929                         reg_val |=
5930                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
5931         }
5932
5933         CL22_WR_OVER_CL45(sc, phy,
5934                           MDIO_REG_BANK_SERDES_DIGITAL,
5935                           MDIO_SERDES_DIGITAL_MISC1, reg_val);
5936
5937 }
5938
5939 static void elink_set_brcm_cl37_advertisement(struct elink_phy *phy,
5940                                               struct elink_params *params)
5941 {
5942         struct bxe_softc *sc = params->sc;
5943         uint16_t val = 0;
5944
5945         /* Set extended capabilities */
5946         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
5947                 val |= MDIO_OVER_1G_UP1_2_5G;
5948         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
5949                 val |= MDIO_OVER_1G_UP1_10G;
5950         CL22_WR_OVER_CL45(sc, phy,
5951                           MDIO_REG_BANK_OVER_1G,
5952                           MDIO_OVER_1G_UP1, val);
5953
5954         CL22_WR_OVER_CL45(sc, phy,
5955                           MDIO_REG_BANK_OVER_1G,
5956                           MDIO_OVER_1G_UP3, 0x400);
5957 }
5958
5959 static void elink_set_ieee_aneg_advertisement(struct elink_phy *phy,
5960                                               struct elink_params *params,
5961                                               uint16_t ieee_fc)
5962 {
5963         struct bxe_softc *sc = params->sc;
5964         uint16_t val;
5965         /* For AN, we are always publishing full duplex */
5966
5967         CL22_WR_OVER_CL45(sc, phy,
5968                           MDIO_REG_BANK_COMBO_IEEE0,
5969                           MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
5970         CL22_RD_OVER_CL45(sc, phy,
5971                           MDIO_REG_BANK_CL73_IEEEB1,
5972                           MDIO_CL73_IEEEB1_AN_ADV1, &val);
5973         val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
5974         val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
5975         CL22_WR_OVER_CL45(sc, phy,
5976                           MDIO_REG_BANK_CL73_IEEEB1,
5977                           MDIO_CL73_IEEEB1_AN_ADV1, val);
5978 }
5979
5980 static void elink_restart_autoneg(struct elink_phy *phy,
5981                                   struct elink_params *params,
5982                                   uint8_t enable_cl73)
5983 {
5984         struct bxe_softc *sc = params->sc;
5985         uint16_t mii_control;
5986
5987         ELINK_DEBUG_P0(sc, "elink_restart_autoneg\n");
5988         /* Enable and restart BAM/CL37 aneg */
5989
5990         if (enable_cl73) {
5991                 CL22_RD_OVER_CL45(sc, phy,
5992                                   MDIO_REG_BANK_CL73_IEEEB0,
5993                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5994                                   &mii_control);
5995
5996                 CL22_WR_OVER_CL45(sc, phy,
5997                                   MDIO_REG_BANK_CL73_IEEEB0,
5998                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5999                                   (mii_control |
6000                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
6001                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
6002         } else {
6003
6004                 CL22_RD_OVER_CL45(sc, phy,
6005                                   MDIO_REG_BANK_COMBO_IEEE0,
6006                                   MDIO_COMBO_IEEE0_MII_CONTROL,
6007                                   &mii_control);
6008                 ELINK_DEBUG_P1(sc,
6009                          "elink_restart_autoneg mii_control before = 0x%x\n",
6010                          mii_control);
6011                 CL22_WR_OVER_CL45(sc, phy,
6012                                   MDIO_REG_BANK_COMBO_IEEE0,
6013                                   MDIO_COMBO_IEEE0_MII_CONTROL,
6014                                   (mii_control |
6015                                    MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
6016                                    MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
6017         }
6018 }
6019
6020 static void elink_initialize_sgmii_process(struct elink_phy *phy,
6021                                            struct elink_params *params,
6022                                            struct elink_vars *vars)
6023 {
6024         struct bxe_softc *sc = params->sc;
6025         uint16_t control1;
6026
6027         /* In SGMII mode, the unicore is always slave */
6028
6029         CL22_RD_OVER_CL45(sc, phy,
6030                           MDIO_REG_BANK_SERDES_DIGITAL,
6031                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
6032                           &control1);
6033         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
6034         /* Set sgmii mode (and not fiber) */
6035         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
6036                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
6037                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
6038         CL22_WR_OVER_CL45(sc, phy,
6039                           MDIO_REG_BANK_SERDES_DIGITAL,
6040                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
6041                           control1);
6042
6043         /* If forced speed */
6044         if (!(vars->line_speed == ELINK_SPEED_AUTO_NEG)) {
6045                 /* Set speed, disable autoneg */
6046                 uint16_t mii_control;
6047
6048                 CL22_RD_OVER_CL45(sc, phy,
6049                                   MDIO_REG_BANK_COMBO_IEEE0,
6050                                   MDIO_COMBO_IEEE0_MII_CONTROL,
6051                                   &mii_control);
6052                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
6053                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
6054                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
6055
6056                 switch (vars->line_speed) {
6057                 case ELINK_SPEED_100:
6058                         mii_control |=
6059                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
6060                         break;
6061                 case ELINK_SPEED_1000:
6062                         mii_control |=
6063                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
6064                         break;
6065                 case ELINK_SPEED_10:
6066                         /* There is nothing to set for 10M */
6067                         break;
6068                 default:
6069                         /* Invalid speed for SGMII */
6070                         ELINK_DEBUG_P1(sc, "Invalid line_speed 0x%x\n",
6071                                   vars->line_speed);
6072                         break;
6073                 }
6074
6075                 /* Setting the full duplex */
6076                 if (phy->req_duplex == DUPLEX_FULL)
6077                         mii_control |=
6078                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
6079                 CL22_WR_OVER_CL45(sc, phy,
6080                                   MDIO_REG_BANK_COMBO_IEEE0,
6081                                   MDIO_COMBO_IEEE0_MII_CONTROL,
6082                                   mii_control);
6083
6084         } else { /* AN mode */
6085                 /* Enable and restart AN */
6086                 elink_restart_autoneg(phy, params, 0);
6087         }
6088 }
6089
6090 /* Link management
6091  */
6092 static elink_status_t elink_direct_parallel_detect_used(struct elink_phy *phy,
6093                                              struct elink_params *params)
6094 {
6095         struct bxe_softc *sc = params->sc;
6096         uint16_t pd_10g, status2_1000x;
6097         if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
6098                 return ELINK_STATUS_OK;
6099         CL22_RD_OVER_CL45(sc, phy,
6100                           MDIO_REG_BANK_SERDES_DIGITAL,
6101                           MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
6102                           &status2_1000x);
6103         CL22_RD_OVER_CL45(sc, phy,
6104                           MDIO_REG_BANK_SERDES_DIGITAL,
6105                           MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
6106                           &status2_1000x);
6107         if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
6108                 ELINK_DEBUG_P1(sc, "1G parallel detect link on port %d\n",
6109                          params->port);
6110                 return 1;
6111         }
6112
6113         CL22_RD_OVER_CL45(sc, phy,
6114                           MDIO_REG_BANK_10G_PARALLEL_DETECT,
6115                           MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
6116                           &pd_10g);
6117
6118         if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
6119                 ELINK_DEBUG_P1(sc, "10G parallel detect link on port %d\n",
6120                          params->port);
6121                 return 1;
6122         }
6123         return ELINK_STATUS_OK;
6124 }
6125
6126 static void elink_update_adv_fc(struct elink_phy *phy,
6127                                 struct elink_params *params,
6128                                 struct elink_vars *vars,
6129                                 uint32_t gp_status)
6130 {
6131         uint16_t ld_pause;   /* local driver */
6132         uint16_t lp_pause;   /* link partner */
6133         uint16_t pause_result;
6134         struct bxe_softc *sc = params->sc;
6135         if ((gp_status &
6136              (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
6137               MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
6138             (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
6139              MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
6140
6141                 CL22_RD_OVER_CL45(sc, phy,
6142                                   MDIO_REG_BANK_CL73_IEEEB1,
6143                                   MDIO_CL73_IEEEB1_AN_ADV1,
6144                                   &ld_pause);
6145                 CL22_RD_OVER_CL45(sc, phy,
6146                                   MDIO_REG_BANK_CL73_IEEEB1,
6147                                   MDIO_CL73_IEEEB1_AN_LP_ADV1,
6148                                   &lp_pause);
6149                 pause_result = (ld_pause &
6150                                 MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK) >> 8;
6151                 pause_result |= (lp_pause &
6152                                  MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK) >> 10;
6153                 ELINK_DEBUG_P1(sc, "pause_result CL73 0x%x\n", pause_result);
6154         } else {
6155                 CL22_RD_OVER_CL45(sc, phy,
6156                                   MDIO_REG_BANK_COMBO_IEEE0,
6157                                   MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
6158                                   &ld_pause);
6159                 CL22_RD_OVER_CL45(sc, phy,
6160                         MDIO_REG_BANK_COMBO_IEEE0,
6161                         MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
6162                         &lp_pause);
6163                 pause_result = (ld_pause &
6164                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
6165                 pause_result |= (lp_pause &
6166                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
6167                 ELINK_DEBUG_P1(sc, "pause_result CL37 0x%x\n", pause_result);
6168         }
6169         elink_pause_resolve(vars, pause_result);
6170
6171 }
6172
6173 static void elink_flow_ctrl_resolve(struct elink_phy *phy,
6174                                     struct elink_params *params,
6175                                     struct elink_vars *vars,
6176                                     uint32_t gp_status)
6177 {
6178         struct bxe_softc *sc = params->sc;
6179         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
6180
6181         /* Resolve from gp_status in case of AN complete and not sgmii */
6182         if (phy->req_flow_ctrl != ELINK_FLOW_CTRL_AUTO) {
6183                 /* Update the advertised flow-controled of LD/LP in AN */
6184                 if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
6185                         elink_update_adv_fc(phy, params, vars, gp_status);
6186                 /* But set the flow-control result as the requested one */
6187                 vars->flow_ctrl = phy->req_flow_ctrl;
6188         } else if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG)
6189                 vars->flow_ctrl = params->req_fc_auto_adv;
6190         else if ((gp_status & ELINK_MDIO_AN_CL73_OR_37_COMPLETE) &&
6191                  (!(vars->phy_flags & PHY_SGMII_FLAG))) {
6192                 if (elink_direct_parallel_detect_used(phy, params)) {
6193                         vars->flow_ctrl = params->req_fc_auto_adv;
6194                         return;
6195                 }
6196                 elink_update_adv_fc(phy, params, vars, gp_status);
6197         }
6198         ELINK_DEBUG_P1(sc, "flow_ctrl 0x%x\n", vars->flow_ctrl);
6199 }
6200
6201 static void elink_check_fallback_to_cl37(struct elink_phy *phy,
6202                                          struct elink_params *params)
6203 {
6204         struct bxe_softc *sc = params->sc;
6205         uint16_t rx_status, ustat_val, cl37_fsm_received;
6206         ELINK_DEBUG_P0(sc, "elink_check_fallback_to_cl37\n");
6207         /* Step 1: Make sure signal is detected */
6208         CL22_RD_OVER_CL45(sc, phy,
6209                           MDIO_REG_BANK_RX0,
6210                           MDIO_RX0_RX_STATUS,
6211                           &rx_status);
6212         if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
6213             (MDIO_RX0_RX_STATUS_SIGDET)) {
6214                 ELINK_DEBUG_P1(sc, "Signal is not detected. Restoring CL73."
6215                              "rx_status(0x80b0) = 0x%x\n", rx_status);
6216                 CL22_WR_OVER_CL45(sc, phy,
6217                                   MDIO_REG_BANK_CL73_IEEEB0,
6218                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6219                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
6220                 return;
6221         }
6222         /* Step 2: Check CL73 state machine */
6223         CL22_RD_OVER_CL45(sc, phy,
6224                           MDIO_REG_BANK_CL73_USERB0,
6225                           MDIO_CL73_USERB0_CL73_USTAT1,
6226                           &ustat_val);
6227         if ((ustat_val &
6228              (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
6229               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
6230             (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
6231               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
6232                 ELINK_DEBUG_P1(sc, "CL73 state-machine is not stable. "
6233                              "ustat_val(0x8371) = 0x%x\n", ustat_val);
6234                 return;
6235         }
6236         /* Step 3: Check CL37 Message Pages received to indicate LP
6237          * supports only CL37
6238          */
6239         CL22_RD_OVER_CL45(sc, phy,
6240                           MDIO_REG_BANK_REMOTE_PHY,
6241                           MDIO_REMOTE_PHY_MISC_RX_STATUS,
6242                           &cl37_fsm_received);
6243         if ((cl37_fsm_received &
6244              (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
6245              MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
6246             (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
6247               MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
6248                 ELINK_DEBUG_P1(sc, "No CL37 FSM were received. "
6249                              "misc_rx_status(0x8330) = 0x%x\n",
6250                          cl37_fsm_received);
6251                 return;
6252         }
6253         /* The combined cl37/cl73 fsm state information indicating that
6254          * we are connected to a device which does not support cl73, but
6255          * does support cl37 BAM. In this case we disable cl73 and
6256          * restart cl37 auto-neg
6257          */
6258
6259         /* Disable CL73 */
6260         CL22_WR_OVER_CL45(sc, phy,
6261                           MDIO_REG_BANK_CL73_IEEEB0,
6262                           MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
6263                           0);
6264         /* Restart CL37 autoneg */
6265         elink_restart_autoneg(phy, params, 0);
6266         ELINK_DEBUG_P0(sc, "Disabling CL73, and restarting CL37 autoneg\n");
6267 }
6268
6269 static void elink_xgxs_an_resolve(struct elink_phy *phy,
6270                                   struct elink_params *params,
6271                                   struct elink_vars *vars,
6272                                   uint32_t gp_status)
6273 {
6274         if (gp_status & ELINK_MDIO_AN_CL73_OR_37_COMPLETE)
6275                 vars->link_status |=
6276                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6277
6278         if (elink_direct_parallel_detect_used(phy, params))
6279                 vars->link_status |=
6280                         LINK_STATUS_PARALLEL_DETECTION_USED;
6281 }
6282 static elink_status_t elink_get_link_speed_duplex(struct elink_phy *phy,
6283                                      struct elink_params *params,
6284                                       struct elink_vars *vars,
6285                                       uint16_t is_link_up,
6286                                       uint16_t speed_mask,
6287                                       uint16_t is_duplex)
6288 {
6289         struct bxe_softc *sc = params->sc;
6290         if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
6291                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
6292         if (is_link_up) {
6293                 ELINK_DEBUG_P0(sc, "phy link up\n");
6294
6295                 vars->phy_link_up = 1;
6296                 vars->link_status |= LINK_STATUS_LINK_UP;
6297
6298                 switch (speed_mask) {
6299                 case ELINK_GP_STATUS_10M:
6300                         vars->line_speed = ELINK_SPEED_10;
6301                         if (is_duplex == DUPLEX_FULL)
6302                                 vars->link_status |= ELINK_LINK_10TFD;
6303                         else
6304                                 vars->link_status |= ELINK_LINK_10THD;
6305                         break;
6306
6307                 case ELINK_GP_STATUS_100M:
6308                         vars->line_speed = ELINK_SPEED_100;
6309                         if (is_duplex == DUPLEX_FULL)
6310                                 vars->link_status |= ELINK_LINK_100TXFD;
6311                         else
6312                                 vars->link_status |= ELINK_LINK_100TXHD;
6313                         break;
6314
6315                 case ELINK_GP_STATUS_1G:
6316                 case ELINK_GP_STATUS_1G_KX:
6317                         vars->line_speed = ELINK_SPEED_1000;
6318                         if (is_duplex == DUPLEX_FULL)
6319                                 vars->link_status |= ELINK_LINK_1000TFD;
6320                         else
6321                                 vars->link_status |= ELINK_LINK_1000THD;
6322                         break;
6323
6324                 case ELINK_GP_STATUS_2_5G:
6325                         vars->line_speed = ELINK_SPEED_2500;
6326                         if (is_duplex == DUPLEX_FULL)
6327                                 vars->link_status |= ELINK_LINK_2500TFD;
6328                         else
6329                                 vars->link_status |= ELINK_LINK_2500THD;
6330                         break;
6331
6332                 case ELINK_GP_STATUS_5G:
6333                 case ELINK_GP_STATUS_6G:
6334                         ELINK_DEBUG_P1(sc,
6335                                  "link speed unsupported  gp_status 0x%x\n",
6336                                   speed_mask);
6337                         return ELINK_STATUS_ERROR;
6338
6339                 case ELINK_GP_STATUS_10G_KX4:
6340                 case ELINK_GP_STATUS_10G_HIG:
6341                 case ELINK_GP_STATUS_10G_CX4:
6342                 case ELINK_GP_STATUS_10G_KR:
6343                 case ELINK_GP_STATUS_10G_SFI:
6344                 case ELINK_GP_STATUS_10G_XFI:
6345                         vars->line_speed = ELINK_SPEED_10000;
6346                         vars->link_status |= ELINK_LINK_10GTFD;
6347                         break;
6348                 case ELINK_GP_STATUS_20G_DXGXS:
6349                 case ELINK_GP_STATUS_20G_KR2:
6350                         vars->line_speed = ELINK_SPEED_20000;
6351                         vars->link_status |= ELINK_LINK_20GTFD;
6352                         break;
6353                 default:
6354                         ELINK_DEBUG_P1(sc,
6355                                   "link speed unsupported gp_status 0x%x\n",
6356                                   speed_mask);
6357                         return ELINK_STATUS_ERROR;
6358                 }
6359         } else { /* link_down */
6360                 ELINK_DEBUG_P0(sc, "phy link down\n");
6361
6362                 vars->phy_link_up = 0;
6363
6364                 vars->duplex = DUPLEX_FULL;
6365                 vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
6366                 vars->mac_type = ELINK_MAC_TYPE_NONE;
6367         }
6368         ELINK_DEBUG_P2(sc, " phy_link_up %x line_speed %d\n",
6369                     vars->phy_link_up, vars->line_speed);
6370         return ELINK_STATUS_OK;
6371 }
6372
6373 static elink_status_t elink_link_settings_status(struct elink_phy *phy,
6374                                       struct elink_params *params,
6375                                       struct elink_vars *vars)
6376 {
6377         struct bxe_softc *sc = params->sc;
6378
6379         uint16_t gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask;
6380         elink_status_t rc = ELINK_STATUS_OK;
6381
6382         /* Read gp_status */
6383         CL22_RD_OVER_CL45(sc, phy,
6384                           MDIO_REG_BANK_GP_STATUS,
6385                           MDIO_GP_STATUS_TOP_AN_STATUS1,
6386                           &gp_status);
6387         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
6388                 duplex = DUPLEX_FULL;
6389         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)
6390                 link_up = 1;
6391         speed_mask = gp_status & ELINK_GP_STATUS_SPEED_MASK;
6392         ELINK_DEBUG_P3(sc, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x\n",
6393                        gp_status, link_up, speed_mask);
6394         rc = elink_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
6395                                          duplex);
6396         if (rc == ELINK_STATUS_ERROR)
6397                 return rc;
6398
6399         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
6400                 if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
6401                         vars->duplex = duplex;
6402                         elink_flow_ctrl_resolve(phy, params, vars, gp_status);
6403                         if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)
6404                                 elink_xgxs_an_resolve(phy, params, vars,
6405                                                       gp_status);
6406                 }
6407         } else { /* Link_down */
6408                 if ((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
6409                     ELINK_SINGLE_MEDIA_DIRECT(params)) {
6410                         /* Check signal is detected */
6411                         elink_check_fallback_to_cl37(phy, params);
6412                 }
6413         }
6414
6415         /* Read LP advertised speeds*/
6416         if (ELINK_SINGLE_MEDIA_DIRECT(params) &&
6417             (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)) {
6418                 uint16_t val;
6419
6420                 CL22_RD_OVER_CL45(sc, phy, MDIO_REG_BANK_CL73_IEEEB1,
6421                                   MDIO_CL73_IEEEB1_AN_LP_ADV2, &val);
6422
6423                 if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
6424                         vars->link_status |=
6425                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
6426                 if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
6427                            MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
6428                         vars->link_status |=
6429                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6430
6431                 CL22_RD_OVER_CL45(sc, phy, MDIO_REG_BANK_OVER_1G,
6432                                   MDIO_OVER_1G_LP_UP1, &val);
6433
6434                 if (val & MDIO_OVER_1G_UP1_2_5G)
6435                         vars->link_status |=
6436                                 LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
6437                 if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
6438                         vars->link_status |=
6439                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6440         }
6441
6442         ELINK_DEBUG_P3(sc, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
6443                    vars->duplex, vars->flow_ctrl, vars->link_status);
6444         return rc;
6445 }
6446
6447 static elink_status_t elink_warpcore_read_status(struct elink_phy *phy,
6448                                      struct elink_params *params,
6449                                      struct elink_vars *vars)
6450 {
6451         struct bxe_softc *sc = params->sc;
6452         uint8_t lane;
6453         uint16_t gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL;
6454         elink_status_t rc = ELINK_STATUS_OK;
6455         lane = elink_get_warpcore_lane(phy, params);
6456         /* Read gp_status */
6457         if ((params->loopback_mode) &&
6458             (phy->flags & ELINK_FLAGS_WC_DUAL_MODE)) {
6459                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6460                                 MDIO_WC_REG_DIGITAL5_LINK_STATUS, &link_up);
6461                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6462                                 MDIO_WC_REG_DIGITAL5_LINK_STATUS, &link_up);
6463                 link_up &= 0x1;
6464         } else if ((phy->req_line_speed > ELINK_SPEED_10000) &&
6465                 (phy->supported & ELINK_SUPPORTED_20000baseMLD2_Full)) {
6466                 uint16_t temp_link_up;
6467                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6468                                 1, &temp_link_up);
6469                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6470                                 1, &link_up);
6471                 ELINK_DEBUG_P2(sc, "PCS RX link status = 0x%x-->0x%x\n",
6472                                temp_link_up, link_up);
6473                 link_up &= (1<<2);
6474                 if (link_up)
6475                         elink_ext_phy_resolve_fc(phy, params, vars);
6476         } else {
6477                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6478                                 MDIO_WC_REG_GP2_STATUS_GP_2_1,
6479                                 &gp_status1);
6480                 ELINK_DEBUG_P1(sc, "0x81d1 = 0x%x\n", gp_status1);
6481                 /* Check for either KR, 1G, or AN up. */
6482                 link_up = ((gp_status1 >> 8) |
6483                            (gp_status1 >> 12) |
6484                            (gp_status1)) &
6485                         (1 << lane);
6486                 if (phy->supported & ELINK_SUPPORTED_20000baseKR2_Full) {
6487                         uint16_t an_link;
6488                         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
6489                                         MDIO_AN_REG_STATUS, &an_link);
6490                         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
6491                                         MDIO_AN_REG_STATUS, &an_link);
6492                         link_up |= (an_link & (1<<2));
6493                 }
6494                 if (link_up && ELINK_SINGLE_MEDIA_DIRECT(params)) {
6495                         uint16_t pd, gp_status4;
6496                         if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
6497                                 /* Check Autoneg complete */
6498                                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6499                                                 MDIO_WC_REG_GP2_STATUS_GP_2_4,
6500                                                 &gp_status4);
6501                                 if (gp_status4 & ((1<<12)<<lane))
6502                                         vars->link_status |=
6503                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6504
6505                                 /* Check parallel detect used */
6506                                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6507                                                 MDIO_WC_REG_PAR_DET_10G_STATUS,
6508                                                 &pd);
6509                                 if (pd & (1<<15))
6510                                         vars->link_status |=
6511                                         LINK_STATUS_PARALLEL_DETECTION_USED;
6512                         }
6513                         elink_ext_phy_resolve_fc(phy, params, vars);
6514                         vars->duplex = duplex;
6515                 }
6516         }
6517
6518         if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) &&
6519             ELINK_SINGLE_MEDIA_DIRECT(params)) {
6520                 uint16_t val;
6521
6522                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
6523                                 MDIO_AN_REG_LP_AUTO_NEG2, &val);
6524
6525                 if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
6526                         vars->link_status |=
6527                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
6528                 if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
6529                            MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
6530                         vars->link_status |=
6531                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6532
6533                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6534                                 MDIO_WC_REG_DIGITAL3_LP_UP1, &val);
6535
6536                 if (val & MDIO_OVER_1G_UP1_2_5G)
6537                         vars->link_status |=
6538                                 LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
6539                 if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
6540                         vars->link_status |=
6541                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
6542
6543         }
6544
6545
6546         if (lane < 2) {
6547                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6548                                 MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed);
6549         } else {
6550                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
6551                                 MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed);
6552         }
6553         ELINK_DEBUG_P2(sc, "lane %d gp_speed 0x%x\n", lane, gp_speed);
6554
6555         if ((lane & 1) == 0)
6556                 gp_speed <<= 8;
6557         gp_speed &= 0x3f00;
6558         link_up = !!link_up;
6559
6560         /* Reset the TX FIFO to fix SGMII issue */
6561         rc = elink_get_link_speed_duplex(phy, params, vars, link_up, gp_speed,
6562                                          duplex);
6563
6564         /* In case of KR link down, start up the recovering procedure */
6565         if ((!link_up) && (phy->media_type == ELINK_ETH_PHY_KR) &&
6566             (!(phy->flags & ELINK_FLAGS_WC_DUAL_MODE)))
6567                 vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
6568
6569         ELINK_DEBUG_P3(sc, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
6570                    vars->duplex, vars->flow_ctrl, vars->link_status);
6571         return rc;
6572 }
6573 static void elink_set_gmii_tx_driver(struct elink_params *params)
6574 {
6575         struct bxe_softc *sc = params->sc;
6576         struct elink_phy *phy = &params->phy[ELINK_INT_PHY];
6577         uint16_t lp_up2;
6578         uint16_t tx_driver;
6579         uint16_t bank;
6580
6581         /* Read precomp */
6582         CL22_RD_OVER_CL45(sc, phy,
6583                           MDIO_REG_BANK_OVER_1G,
6584                           MDIO_OVER_1G_LP_UP2, &lp_up2);
6585
6586         /* Bits [10:7] at lp_up2, positioned at [15:12] */
6587         lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
6588                    MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
6589                   MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
6590
6591         if (lp_up2 == 0)
6592                 return;
6593
6594         for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
6595               bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
6596                 CL22_RD_OVER_CL45(sc, phy,
6597                                   bank,
6598                                   MDIO_TX0_TX_DRIVER, &tx_driver);
6599
6600                 /* Replace tx_driver bits [15:12] */
6601                 if (lp_up2 !=
6602                     (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
6603                         tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
6604                         tx_driver |= lp_up2;
6605                         CL22_WR_OVER_CL45(sc, phy,
6606                                           bank,
6607                                           MDIO_TX0_TX_DRIVER, tx_driver);
6608                 }
6609         }
6610 }
6611
6612 static elink_status_t elink_emac_program(struct elink_params *params,
6613                               struct elink_vars *vars)
6614 {
6615         struct bxe_softc *sc = params->sc;
6616         uint8_t port = params->port;
6617         uint16_t mode = 0;
6618
6619         ELINK_DEBUG_P0(sc, "setting link speed & duplex\n");
6620         elink_bits_dis(sc, GRCBASE_EMAC0 + port*0x400 +
6621                        EMAC_REG_EMAC_MODE,
6622                        (EMAC_MODE_25G_MODE |
6623                         EMAC_MODE_PORT_MII_10M |
6624                         EMAC_MODE_HALF_DUPLEX));
6625         switch (vars->line_speed) {
6626         case ELINK_SPEED_10:
6627                 mode |= EMAC_MODE_PORT_MII_10M;
6628                 break;
6629
6630         case ELINK_SPEED_100:
6631                 mode |= EMAC_MODE_PORT_MII;
6632                 break;
6633
6634         case ELINK_SPEED_1000:
6635                 mode |= EMAC_MODE_PORT_GMII;
6636                 break;
6637
6638         case ELINK_SPEED_2500:
6639                 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
6640                 break;
6641
6642         default:
6643                 /* 10G not valid for EMAC */
6644                 ELINK_DEBUG_P1(sc, "Invalid line_speed 0x%x\n",
6645                            vars->line_speed);
6646                 return ELINK_STATUS_ERROR;
6647         }
6648
6649         if (vars->duplex == DUPLEX_HALF)
6650                 mode |= EMAC_MODE_HALF_DUPLEX;
6651         elink_bits_en(sc,
6652                       GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
6653                       mode);
6654
6655         elink_set_led(params, vars, ELINK_LED_MODE_OPER, vars->line_speed);
6656         return ELINK_STATUS_OK;
6657 }
6658
6659 static void elink_set_preemphasis(struct elink_phy *phy,
6660                                   struct elink_params *params)
6661 {
6662
6663         uint16_t bank, i = 0;
6664         struct bxe_softc *sc = params->sc;
6665
6666         for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
6667               bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
6668                         CL22_WR_OVER_CL45(sc, phy,
6669                                           bank,
6670                                           MDIO_RX0_RX_EQ_BOOST,
6671                                           phy->rx_preemphasis[i]);
6672         }
6673
6674         for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
6675                       bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
6676                         CL22_WR_OVER_CL45(sc, phy,
6677                                           bank,
6678                                           MDIO_TX0_TX_DRIVER,
6679                                           phy->tx_preemphasis[i]);
6680         }
6681 }
6682
6683 static void elink_xgxs_config_init(struct elink_phy *phy,
6684                                    struct elink_params *params,
6685                                    struct elink_vars *vars)
6686 {
6687         struct bxe_softc *sc = params->sc;
6688         uint8_t enable_cl73 = (ELINK_SINGLE_MEDIA_DIRECT(params) ||
6689                           (params->loopback_mode == ELINK_LOOPBACK_XGXS));
6690         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
6691                 if (ELINK_SINGLE_MEDIA_DIRECT(params) &&
6692                     (params->feature_config_flags &
6693                      ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
6694                         elink_set_preemphasis(phy, params);
6695
6696                 /* Forced speed requested? */
6697                 if (vars->line_speed != ELINK_SPEED_AUTO_NEG ||
6698                     (ELINK_SINGLE_MEDIA_DIRECT(params) &&
6699                      params->loopback_mode == ELINK_LOOPBACK_EXT)) {
6700                         ELINK_DEBUG_P0(sc, "not SGMII, no AN\n");
6701
6702                         /* Disable autoneg */
6703                         elink_set_autoneg(phy, params, vars, 0);
6704
6705                         /* Program speed and duplex */
6706                         elink_program_serdes(phy, params, vars);
6707
6708                 } else { /* AN_mode */
6709                         ELINK_DEBUG_P0(sc, "not SGMII, AN\n");
6710
6711                         /* AN enabled */
6712                         elink_set_brcm_cl37_advertisement(phy, params);
6713
6714                         /* Program duplex & pause advertisement (for aneg) */
6715                         elink_set_ieee_aneg_advertisement(phy, params,
6716                                                           vars->ieee_fc);
6717
6718                         /* Enable autoneg */
6719                         elink_set_autoneg(phy, params, vars, enable_cl73);
6720
6721                         /* Enable and restart AN */
6722                         elink_restart_autoneg(phy, params, enable_cl73);
6723                 }
6724
6725         } else { /* SGMII mode */
6726                 ELINK_DEBUG_P0(sc, "SGMII\n");
6727
6728                 elink_initialize_sgmii_process(phy, params, vars);
6729         }
6730 }
6731
6732 static elink_status_t elink_prepare_xgxs(struct elink_phy *phy,
6733                           struct elink_params *params,
6734                           struct elink_vars *vars)
6735 {
6736         elink_status_t rc;
6737         vars->phy_flags |= PHY_XGXS_FLAG;
6738         if ((phy->req_line_speed &&
6739              ((phy->req_line_speed == ELINK_SPEED_100) ||
6740               (phy->req_line_speed == ELINK_SPEED_10))) ||
6741             (!phy->req_line_speed &&
6742              (phy->speed_cap_mask >=
6743               PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
6744              (phy->speed_cap_mask <
6745               PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
6746             (phy->type == PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD))
6747                 vars->phy_flags |= PHY_SGMII_FLAG;
6748         else
6749                 vars->phy_flags &= ~PHY_SGMII_FLAG;
6750
6751         elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
6752         elink_set_aer_mmd(params, phy);
6753         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
6754                 elink_set_master_ln(params, phy);
6755
6756         rc = elink_reset_unicore(params, phy, 0);
6757         /* Reset the SerDes and wait for reset bit return low */
6758         if (rc != ELINK_STATUS_OK)
6759                 return rc;
6760
6761         elink_set_aer_mmd(params, phy);
6762         /* Setting the masterLn_def again after the reset */
6763         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
6764                 elink_set_master_ln(params, phy);
6765                 elink_set_swap_lanes(params, phy);
6766         }
6767
6768         return rc;
6769 }
6770
6771 static uint16_t elink_wait_reset_complete(struct bxe_softc *sc,
6772                                      struct elink_phy *phy,
6773                                      struct elink_params *params)
6774 {
6775         uint16_t cnt, ctrl;
6776         /* Wait for soft reset to get cleared up to 1 sec */
6777         for (cnt = 0; cnt < 1000; cnt++) {
6778                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
6779                         elink_cl22_read(sc, phy,
6780                                 MDIO_PMA_REG_CTRL, &ctrl);
6781                 else
6782                         elink_cl45_read(sc, phy,
6783                                 MDIO_PMA_DEVAD,
6784                                 MDIO_PMA_REG_CTRL, &ctrl);
6785                 if (!(ctrl & (1<<15)))
6786                         break;
6787                 DELAY(1000 * 1);
6788         }
6789
6790         if (cnt == 1000)
6791                 elink_cb_event_log(sc, ELINK_LOG_ID_PHY_UNINITIALIZED, params->port); // "Warning: PHY was not initialized,"
6792                                      // " Port %d\n",
6793
6794         ELINK_DEBUG_P2(sc, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
6795         return cnt;
6796 }
6797
6798 static void elink_link_int_enable(struct elink_params *params)
6799 {
6800         uint8_t port = params->port;
6801         uint32_t mask;
6802         struct bxe_softc *sc = params->sc;
6803
6804         /* Setting the status to report on link up for either XGXS or SerDes */
6805         if (CHIP_IS_E3(sc)) {
6806                 mask = ELINK_NIG_MASK_XGXS0_LINK_STATUS;
6807                 if (!(ELINK_SINGLE_MEDIA_DIRECT(params)))
6808                         mask |= ELINK_NIG_MASK_MI_INT;
6809         } else if (params->switch_cfg == ELINK_SWITCH_CFG_10G) {
6810                 mask = (ELINK_NIG_MASK_XGXS0_LINK10G |
6811                         ELINK_NIG_MASK_XGXS0_LINK_STATUS);
6812                 ELINK_DEBUG_P0(sc, "enabled XGXS interrupt\n");
6813                 if (!(ELINK_SINGLE_MEDIA_DIRECT(params)) &&
6814                         params->phy[ELINK_INT_PHY].type !=
6815                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
6816                         mask |= ELINK_NIG_MASK_MI_INT;
6817                         ELINK_DEBUG_P0(sc, "enabled external phy int\n");
6818                 }
6819
6820         } else { /* SerDes */
6821                 mask = ELINK_NIG_MASK_SERDES0_LINK_STATUS;
6822                 ELINK_DEBUG_P0(sc, "enabled SerDes interrupt\n");
6823                 if (!(ELINK_SINGLE_MEDIA_DIRECT(params)) &&
6824                         params->phy[ELINK_INT_PHY].type !=
6825                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
6826                         mask |= ELINK_NIG_MASK_MI_INT;
6827                         ELINK_DEBUG_P0(sc, "enabled external phy int\n");
6828                 }
6829         }
6830         elink_bits_en(sc,
6831                       NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6832                       mask);
6833
6834         ELINK_DEBUG_P3(sc, "port %x, is_xgxs %x, int_status 0x%x\n", port,
6835                  (params->switch_cfg == ELINK_SWITCH_CFG_10G),
6836                  REG_RD(sc, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
6837         ELINK_DEBUG_P3(sc, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
6838                  REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
6839                  REG_RD(sc, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
6840                  REG_RD(sc, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
6841         ELINK_DEBUG_P2(sc, " 10G %x, XGXS_LINK %x\n",
6842            REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
6843            REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
6844 }
6845
6846 static void elink_rearm_latch_signal(struct bxe_softc *sc, uint8_t port,
6847                                      uint8_t exp_mi_int)
6848 {
6849         uint32_t latch_status = 0;
6850
6851         /* Disable the MI INT ( external phy int ) by writing 1 to the
6852          * status register. Link down indication is high-active-signal,
6853          * so in this case we need to write the status to clear the XOR
6854          */
6855         /* Read Latched signals */
6856         latch_status = REG_RD(sc,
6857                                     NIG_REG_LATCH_STATUS_0 + port*8);
6858         ELINK_DEBUG_P1(sc, "latch_status = 0x%x\n", latch_status);
6859         /* Handle only those with latched-signal=up.*/
6860         if (exp_mi_int)
6861                 elink_bits_en(sc,
6862                               NIG_REG_STATUS_INTERRUPT_PORT0
6863                               + port*4,
6864                               ELINK_NIG_STATUS_EMAC0_MI_INT);
6865         else
6866                 elink_bits_dis(sc,
6867                                NIG_REG_STATUS_INTERRUPT_PORT0
6868                                + port*4,
6869                                ELINK_NIG_STATUS_EMAC0_MI_INT);
6870
6871         if (latch_status & 1) {
6872
6873                 /* For all latched-signal=up : Re-Arm Latch signals */
6874                 REG_WR(sc, NIG_REG_LATCH_STATUS_0 + port*8,
6875                        (latch_status & 0xfffe) | (latch_status & 1));
6876         }
6877         /* For all latched-signal=up,Write original_signal to status */
6878 }
6879
6880 static void elink_link_int_ack(struct elink_params *params,
6881                                struct elink_vars *vars, uint8_t is_10g_plus)
6882 {
6883         struct bxe_softc *sc = params->sc;
6884         uint8_t port = params->port;
6885         uint32_t mask;
6886         /* First reset all status we assume only one line will be
6887          * change at a time
6888          */
6889         elink_bits_dis(sc, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
6890                        (ELINK_NIG_STATUS_XGXS0_LINK10G |
6891                         ELINK_NIG_STATUS_XGXS0_LINK_STATUS |
6892                         ELINK_NIG_STATUS_SERDES0_LINK_STATUS));
6893         if (vars->phy_link_up) {
6894                 if (USES_WARPCORE(sc))
6895                         mask = ELINK_NIG_STATUS_XGXS0_LINK_STATUS;
6896                 else {
6897                         if (is_10g_plus)
6898                                 mask = ELINK_NIG_STATUS_XGXS0_LINK10G;
6899                         else if (params->switch_cfg == ELINK_SWITCH_CFG_10G) {
6900                                 /* Disable the link interrupt by writing 1 to
6901                                  * the relevant lane in the status register
6902                                  */
6903                                 uint32_t ser_lane =
6904                                         ((params->lane_config &
6905                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
6906                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
6907                                 mask = ((1 << ser_lane) <<
6908                                        ELINK_NIG_STATUS_XGXS0_LINK_STATUS_SIZE);
6909                         } else
6910                                 mask = ELINK_NIG_STATUS_SERDES0_LINK_STATUS;
6911                 }
6912                 ELINK_DEBUG_P1(sc, "Ack link up interrupt with mask 0x%x\n",
6913                                mask);
6914                 elink_bits_en(sc,
6915                               NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
6916                               mask);
6917         }
6918 }
6919
6920 static elink_status_t elink_format_ver(uint32_t num, uint8_t *str, uint16_t *len)
6921 {
6922         uint8_t *str_ptr = str;
6923         uint32_t mask = 0xf0000000;
6924         uint8_t shift = 8*4;
6925         uint8_t digit;
6926         uint8_t remove_leading_zeros = 1;
6927         if (*len < 10) {
6928                 /* Need more than 10chars for this format */
6929                 *str_ptr = '\0';
6930                 (*len)--;
6931                 return ELINK_STATUS_ERROR;
6932         }
6933         while (shift > 0) {
6934
6935                 shift -= 4;
6936                 digit = ((num & mask) >> shift);
6937                 if (digit == 0 && remove_leading_zeros) {
6938                         mask = mask >> 4;
6939                         continue;
6940                 } else if (digit < 0xa)
6941                         *str_ptr = digit + '0';
6942                 else
6943                         *str_ptr = digit - 0xa + 'a';
6944                 remove_leading_zeros = 0;
6945                 str_ptr++;
6946                 (*len)--;
6947                 mask = mask >> 4;
6948                 if (shift == 4*4) {
6949                         *str_ptr = '.';
6950                         str_ptr++;
6951                         (*len)--;
6952                         remove_leading_zeros = 1;
6953                 }
6954         }
6955         return ELINK_STATUS_OK;
6956 }
6957
6958
6959 static elink_status_t elink_null_format_ver(uint32_t spirom_ver, uint8_t *str, uint16_t *len)
6960 {
6961         str[0] = '\0';
6962         (*len)--;
6963         return ELINK_STATUS_OK;
6964 }
6965
6966 elink_status_t elink_get_ext_phy_fw_version(struct elink_params *params, uint8_t *version,
6967                                  uint16_t len)
6968 {
6969         struct bxe_softc *sc;
6970         uint32_t spirom_ver = 0;
6971         elink_status_t status = ELINK_STATUS_OK;
6972         uint8_t *ver_p = version;
6973         uint16_t remain_len = len;
6974         if (version == NULL || params == NULL)
6975                 return ELINK_STATUS_ERROR;
6976         sc = params->sc;
6977
6978         /* Extract first external phy*/
6979         version[0] = '\0';
6980         spirom_ver = REG_RD(sc, params->phy[ELINK_EXT_PHY1].ver_addr);
6981
6982         if (params->phy[ELINK_EXT_PHY1].format_fw_ver) {
6983                 status |= params->phy[ELINK_EXT_PHY1].format_fw_ver(spirom_ver,
6984                                                               ver_p,
6985                                                               &remain_len);
6986                 ver_p += (len - remain_len);
6987         }
6988         if ((params->num_phys == ELINK_MAX_PHYS) &&
6989             (params->phy[ELINK_EXT_PHY2].ver_addr != 0)) {
6990                 spirom_ver = REG_RD(sc, params->phy[ELINK_EXT_PHY2].ver_addr);
6991                 if (params->phy[ELINK_EXT_PHY2].format_fw_ver) {
6992                         *ver_p = '/';
6993                         ver_p++;
6994                         remain_len--;
6995                         status |= params->phy[ELINK_EXT_PHY2].format_fw_ver(
6996                                 spirom_ver,
6997                                 ver_p,
6998                                 &remain_len);
6999                         ver_p = version + (len - remain_len);
7000                 }
7001         }
7002         *ver_p = '\0';
7003         return status;
7004 }
7005
7006 static void elink_set_xgxs_loopback(struct elink_phy *phy,
7007                                     struct elink_params *params)
7008 {
7009         uint8_t port = params->port;
7010         struct bxe_softc *sc = params->sc;
7011
7012         if (phy->req_line_speed != ELINK_SPEED_1000) {
7013                 uint32_t md_devad = 0;
7014
7015                 ELINK_DEBUG_P0(sc, "XGXS 10G loopback enable\n");
7016
7017                 if (!CHIP_IS_E3(sc)) {
7018                         /* Change the uni_phy_addr in the nig */
7019                         md_devad = REG_RD(sc, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
7020                                                port*0x18));
7021
7022                         REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
7023                                0x5);
7024                 }
7025
7026                 elink_cl45_write(sc, phy,
7027                                  5,
7028                                  (MDIO_REG_BANK_AER_BLOCK +
7029                                   (MDIO_AER_BLOCK_AER_REG & 0xf)),
7030                                  0x2800);
7031
7032                 elink_cl45_write(sc, phy,
7033                                  5,
7034                                  (MDIO_REG_BANK_CL73_IEEEB0 +
7035                                   (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
7036                                  0x6041);
7037                 DELAY(1000 * 200);
7038                 /* Set aer mmd back */
7039                 elink_set_aer_mmd(params, phy);
7040
7041                 if (!CHIP_IS_E3(sc)) {
7042                         /* And md_devad */
7043                         REG_WR(sc, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
7044                                md_devad);
7045                 }
7046         } else {
7047                 uint16_t mii_ctrl;
7048                 ELINK_DEBUG_P0(sc, "XGXS 1G loopback enable\n");
7049                 elink_cl45_read(sc, phy, 5,
7050                                 (MDIO_REG_BANK_COMBO_IEEE0 +
7051                                 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
7052                                 &mii_ctrl);
7053                 elink_cl45_write(sc, phy, 5,
7054                                  (MDIO_REG_BANK_COMBO_IEEE0 +
7055                                  (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
7056                                  mii_ctrl |
7057                                  MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
7058         }
7059 }
7060
7061 elink_status_t elink_set_led(struct elink_params *params,
7062                   struct elink_vars *vars, uint8_t mode, uint32_t speed)
7063 {
7064         uint8_t port = params->port;
7065         uint16_t hw_led_mode = params->hw_led_mode;
7066         elink_status_t rc = ELINK_STATUS_OK;
7067         uint8_t phy_idx;
7068         uint32_t tmp;
7069         uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
7070         struct bxe_softc *sc = params->sc;
7071         ELINK_DEBUG_P2(sc, "elink_set_led: port %x, mode %d\n", port, mode);
7072         ELINK_DEBUG_P2(sc, "speed 0x%x, hw_led_mode 0x%x\n",
7073                  speed, hw_led_mode);
7074         /* In case */
7075         for (phy_idx = ELINK_EXT_PHY1; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
7076                 if (params->phy[phy_idx].set_link_led) {
7077                         params->phy[phy_idx].set_link_led(
7078                                 &params->phy[phy_idx], params, mode);
7079                 }
7080         }
7081 #ifdef ELINK_INCLUDE_EMUL
7082         if (params->feature_config_flags &
7083             ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC)
7084                 return rc;
7085 #endif
7086
7087         switch (mode) {
7088         case ELINK_LED_MODE_FRONT_PANEL_OFF:
7089         case ELINK_LED_MODE_OFF:
7090                 REG_WR(sc, NIG_REG_LED_10G_P0 + port*4, 0);
7091                 REG_WR(sc, NIG_REG_LED_MODE_P0 + port*4,
7092                        SHARED_HW_CFG_LED_MAC1);
7093
7094                 tmp = elink_cb_reg_read(sc, emac_base + EMAC_REG_EMAC_LED);
7095                 if (params->phy[ELINK_EXT_PHY1].type ==
7096                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
7097                         tmp &= ~(EMAC_LED_1000MB_OVERRIDE |
7098                                 EMAC_LED_100MB_OVERRIDE |
7099                                 EMAC_LED_10MB_OVERRIDE);
7100                 else
7101                         tmp |= EMAC_LED_OVERRIDE;
7102
7103                 elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED, tmp);
7104                 break;
7105
7106         case ELINK_LED_MODE_OPER:
7107                 /* For all other phys, OPER mode is same as ON, so in case
7108                  * link is down, do nothing
7109                  */
7110                 if (!vars->link_up)
7111                         break;
7112         case ELINK_LED_MODE_ON:
7113                 if (((params->phy[ELINK_EXT_PHY1].type ==
7114                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) ||
7115                          (params->phy[ELINK_EXT_PHY1].type ==
7116                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722)) &&
7117                     CHIP_IS_E2(sc) && params->num_phys == 2) {
7118                         /* This is a work-around for E2+8727 Configurations */
7119                         if (mode == ELINK_LED_MODE_ON ||
7120                                 speed == ELINK_SPEED_10000){
7121                                 REG_WR(sc, NIG_REG_LED_MODE_P0 + port*4, 0);
7122                                 REG_WR(sc, NIG_REG_LED_10G_P0 + port*4, 1);
7123
7124                                 tmp = elink_cb_reg_read(sc, emac_base + EMAC_REG_EMAC_LED);
7125                                 elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED,
7126                                         (tmp | EMAC_LED_OVERRIDE));
7127                                 /* Return here without enabling traffic
7128                                  * LED blink and setting rate in ON mode.
7129                                  * In oper mode, enabling LED blink
7130                                  * and setting rate is needed.
7131                                  */
7132                                 if (mode == ELINK_LED_MODE_ON)
7133                                         return rc;
7134                         }
7135                 } else if (ELINK_SINGLE_MEDIA_DIRECT(params)) {
7136                         /* This is a work-around for HW issue found when link
7137                          * is up in CL73
7138                          */
7139                         if ((!CHIP_IS_E3(sc)) ||
7140                             (CHIP_IS_E3(sc) &&
7141                              mode == ELINK_LED_MODE_ON))
7142                                 REG_WR(sc, NIG_REG_LED_10G_P0 + port*4, 1);
7143
7144                         if (CHIP_IS_E1x(sc) ||
7145                             CHIP_IS_E2(sc) ||
7146                             (mode == ELINK_LED_MODE_ON))
7147                                 REG_WR(sc, NIG_REG_LED_MODE_P0 + port*4, 0);
7148                         else
7149                                 REG_WR(sc, NIG_REG_LED_MODE_P0 + port*4,
7150                                        hw_led_mode);
7151                 } else if ((params->phy[ELINK_EXT_PHY1].type ==
7152                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) &&
7153                            (mode == ELINK_LED_MODE_ON)) {
7154                         REG_WR(sc, NIG_REG_LED_MODE_P0 + port*4, 0);
7155                         tmp = elink_cb_reg_read(sc, emac_base + EMAC_REG_EMAC_LED);
7156                         elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED, tmp |
7157                                 EMAC_LED_OVERRIDE | EMAC_LED_1000MB_OVERRIDE);
7158                         /* Break here; otherwise, it'll disable the
7159                          * intended override.
7160                          */
7161                         break;
7162                 } else {
7163                         uint32_t nig_led_mode = ((params->hw_led_mode <<
7164                                              SHARED_HW_CFG_LED_MODE_SHIFT) ==
7165                                             SHARED_HW_CFG_LED_EXTPHY2) ?
7166                                 (SHARED_HW_CFG_LED_PHY1 >>
7167                                  SHARED_HW_CFG_LED_MODE_SHIFT) : hw_led_mode;
7168                         REG_WR(sc, NIG_REG_LED_MODE_P0 + port*4,
7169                                nig_led_mode);
7170                 }
7171
7172                 REG_WR(sc, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
7173                 /* Set blinking rate to ~15.9Hz */
7174                 if (CHIP_IS_E3(sc))
7175                         REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
7176                                LED_BLINK_RATE_VAL_E3);
7177                 else
7178                         REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
7179                                LED_BLINK_RATE_VAL_E1X_E2);
7180                 REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
7181                        port*4, 1);
7182                 tmp = elink_cb_reg_read(sc, emac_base + EMAC_REG_EMAC_LED);
7183                 elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_LED,
7184                         (tmp & (~EMAC_LED_OVERRIDE)));
7185
7186                 if (CHIP_IS_E1(sc) &&
7187                     ((speed == ELINK_SPEED_2500) ||
7188                      (speed == ELINK_SPEED_1000) ||
7189                      (speed == ELINK_SPEED_100) ||
7190                      (speed == ELINK_SPEED_10))) {
7191                         /* For speeds less than 10G LED scheme is different */
7192                         REG_WR(sc, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
7193                                + port*4, 1);
7194                         REG_WR(sc, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
7195                                port*4, 0);
7196                         REG_WR(sc, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
7197                                port*4, 1);
7198                 }
7199                 break;
7200
7201         default:
7202                 rc = ELINK_STATUS_ERROR;
7203                 ELINK_DEBUG_P1(sc, "elink_set_led: Invalid led mode %d\n",
7204                          mode);
7205                 break;
7206         }
7207         return rc;
7208
7209 }
7210
7211 /* This function comes to reflect the actual link state read DIRECTLY from the
7212  * HW
7213  */
7214 elink_status_t elink_test_link(struct elink_params *params, struct elink_vars *vars,
7215                     uint8_t is_serdes)
7216 {
7217         struct bxe_softc *sc = params->sc;
7218         uint16_t gp_status = 0, phy_index = 0;
7219         uint8_t ext_phy_link_up = 0, serdes_phy_type;
7220         struct elink_vars temp_vars;
7221         struct elink_phy *int_phy = &params->phy[ELINK_INT_PHY];
7222 #ifdef ELINK_INCLUDE_FPGA
7223         if (CHIP_REV_IS_FPGA(sc))
7224                 return ELINK_STATUS_OK;
7225 #endif
7226 #ifdef ELINK_INCLUDE_EMUL
7227         if (CHIP_REV_IS_EMUL(sc))
7228                 return ELINK_STATUS_OK;
7229 #endif
7230
7231         if (CHIP_IS_E3(sc)) {
7232                 uint16_t link_up;
7233                 if (params->req_line_speed[ELINK_LINK_CONFIG_IDX(ELINK_INT_PHY)]
7234                     > ELINK_SPEED_10000) {
7235                         /* Check 20G link */
7236                         elink_cl45_read(sc, int_phy, MDIO_WC_DEVAD,
7237                                         1, &link_up);
7238                         elink_cl45_read(sc, int_phy, MDIO_WC_DEVAD,
7239                                         1, &link_up);
7240                         link_up &= (1<<2);
7241                 } else {
7242                         /* Check 10G link and below*/
7243                         uint8_t lane = elink_get_warpcore_lane(int_phy, params);
7244                         elink_cl45_read(sc, int_phy, MDIO_WC_DEVAD,
7245                                         MDIO_WC_REG_GP2_STATUS_GP_2_1,
7246                                         &gp_status);
7247                         gp_status = ((gp_status >> 8) & 0xf) |
7248                                 ((gp_status >> 12) & 0xf);
7249                         link_up = gp_status & (1 << lane);
7250                 }
7251                 if (!link_up)
7252                         return ELINK_STATUS_NO_LINK;
7253         } else {
7254                 CL22_RD_OVER_CL45(sc, int_phy,
7255                           MDIO_REG_BANK_GP_STATUS,
7256                           MDIO_GP_STATUS_TOP_AN_STATUS1,
7257                           &gp_status);
7258         /* Link is up only if both local phy and external phy are up */
7259         if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
7260                 return ELINK_STATUS_NO_LINK;
7261         }
7262         /* In XGXS loopback mode, do not check external PHY */
7263         if (params->loopback_mode == ELINK_LOOPBACK_XGXS)
7264                 return ELINK_STATUS_OK;
7265
7266         switch (params->num_phys) {
7267         case 1:
7268                 /* No external PHY */
7269                 return ELINK_STATUS_OK;
7270         case 2:
7271                 ext_phy_link_up = params->phy[ELINK_EXT_PHY1].read_status(
7272                         &params->phy[ELINK_EXT_PHY1],
7273                         params, &temp_vars);
7274                 break;
7275         case 3: /* Dual Media */
7276                 for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7277                       phy_index++) {
7278                         serdes_phy_type = ((params->phy[phy_index].media_type ==
7279                                             ELINK_ETH_PHY_SFPP_10G_FIBER) ||
7280                                            (params->phy[phy_index].media_type ==
7281                                             ELINK_ETH_PHY_SFP_1G_FIBER) ||
7282                                            (params->phy[phy_index].media_type ==
7283                                             ELINK_ETH_PHY_XFP_FIBER) ||
7284                                            (params->phy[phy_index].media_type ==
7285                                             ELINK_ETH_PHY_DA_TWINAX));
7286
7287                         if (is_serdes != serdes_phy_type)
7288                                 continue;
7289                         if (params->phy[phy_index].read_status) {
7290                                 ext_phy_link_up |=
7291                                         params->phy[phy_index].read_status(
7292                                                 &params->phy[phy_index],
7293                                                 params, &temp_vars);
7294                         }
7295                 }
7296                 break;
7297         }
7298         if (ext_phy_link_up)
7299                 return ELINK_STATUS_OK;
7300         return ELINK_STATUS_NO_LINK;
7301 }
7302
7303 static elink_status_t elink_link_initialize(struct elink_params *params,
7304                                  struct elink_vars *vars)
7305 {
7306         elink_status_t rc = ELINK_STATUS_OK;
7307         uint8_t phy_index, non_ext_phy;
7308         struct bxe_softc *sc = params->sc;
7309         /* In case of external phy existence, the line speed would be the
7310          * line speed linked up by the external phy. In case it is direct
7311          * only, then the line_speed during initialization will be
7312          * equal to the req_line_speed
7313          */
7314         vars->line_speed = params->phy[ELINK_INT_PHY].req_line_speed;
7315
7316         /* Initialize the internal phy in case this is a direct board
7317          * (no external phys), or this board has external phy which requires
7318          * to first.
7319          */
7320         if (!USES_WARPCORE(sc))
7321                 elink_prepare_xgxs(&params->phy[ELINK_INT_PHY], params, vars);
7322         /* init ext phy and enable link state int */
7323         non_ext_phy = (ELINK_SINGLE_MEDIA_DIRECT(params) ||
7324                        (params->loopback_mode == ELINK_LOOPBACK_XGXS));
7325
7326         if (non_ext_phy ||
7327             (params->phy[ELINK_EXT_PHY1].flags & ELINK_FLAGS_INIT_XGXS_FIRST) ||
7328             (params->loopback_mode == ELINK_LOOPBACK_EXT_PHY)) {
7329                 struct elink_phy *phy = &params->phy[ELINK_INT_PHY];
7330                 if (vars->line_speed == ELINK_SPEED_AUTO_NEG &&
7331                     (CHIP_IS_E1x(sc) ||
7332                      CHIP_IS_E2(sc)))
7333                         elink_set_parallel_detection(phy, params);
7334                 if (params->phy[ELINK_INT_PHY].config_init)
7335                         params->phy[ELINK_INT_PHY].config_init(phy, params, vars);
7336         }
7337
7338         /* Re-read this value in case it was changed inside config_init due to
7339          * limitations of optic module
7340          */
7341         vars->line_speed = params->phy[ELINK_INT_PHY].req_line_speed;
7342
7343         /* Init external phy*/
7344         if (non_ext_phy) {
7345                 if (params->phy[ELINK_INT_PHY].supported &
7346                     ELINK_SUPPORTED_FIBRE)
7347                         vars->link_status |= LINK_STATUS_SERDES_LINK;
7348         } else {
7349                 for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7350                       phy_index++) {
7351                         /* No need to initialize second phy in case of first
7352                          * phy only selection. In case of second phy, we do
7353                          * need to initialize the first phy, since they are
7354                          * connected.
7355                          */
7356                         if (params->phy[phy_index].supported &
7357                             ELINK_SUPPORTED_FIBRE)
7358                                 vars->link_status |= LINK_STATUS_SERDES_LINK;
7359
7360                         if (phy_index == ELINK_EXT_PHY2 &&
7361                             (elink_phy_selection(params) ==
7362                              PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
7363                                 ELINK_DEBUG_P0(sc,
7364                                    "Not initializing second phy\n");
7365                                 continue;
7366                         }
7367                         params->phy[phy_index].config_init(
7368                                 &params->phy[phy_index],
7369                                 params, vars);
7370                 }
7371         }
7372         /* Reset the interrupt indication after phy was initialized */
7373         elink_bits_dis(sc, NIG_REG_STATUS_INTERRUPT_PORT0 +
7374                        params->port*4,
7375                        (ELINK_NIG_STATUS_XGXS0_LINK10G |
7376                         ELINK_NIG_STATUS_XGXS0_LINK_STATUS |
7377                         ELINK_NIG_STATUS_SERDES0_LINK_STATUS |
7378                         ELINK_NIG_MASK_MI_INT));
7379         return rc;
7380 }
7381
7382 static void elink_int_link_reset(struct elink_phy *phy,
7383                                  struct elink_params *params)
7384 {
7385         /* Reset the SerDes/XGXS */
7386         REG_WR(params->sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
7387                (0x1ff << (params->port*16)));
7388 }
7389
7390 static void elink_common_ext_link_reset(struct elink_phy *phy,
7391                                         struct elink_params *params)
7392 {
7393         struct bxe_softc *sc = params->sc;
7394         uint8_t gpio_port;
7395         /* HW reset */
7396         if (CHIP_IS_E2(sc))
7397                 gpio_port = SC_PATH(sc);
7398         else
7399                 gpio_port = params->port;
7400         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
7401                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
7402                        gpio_port);
7403         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
7404                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
7405                        gpio_port);
7406         ELINK_DEBUG_P0(sc, "reset external PHY\n");
7407 }
7408
7409 static elink_status_t elink_update_link_down(struct elink_params *params,
7410                                   struct elink_vars *vars)
7411 {
7412         struct bxe_softc *sc = params->sc;
7413         uint8_t port = params->port;
7414
7415         ELINK_DEBUG_P1(sc, "Port %x: Link is down\n", port);
7416         elink_set_led(params, vars, ELINK_LED_MODE_OFF, 0);
7417         vars->phy_flags &= ~PHY_PHYSICAL_LINK_FLAG;
7418         /* Indicate no mac active */
7419         vars->mac_type = ELINK_MAC_TYPE_NONE;
7420
7421         /* Update shared memory */
7422         vars->link_status &= ~ELINK_LINK_UPDATE_MASK;
7423         vars->line_speed = 0;
7424         elink_update_mng(params, vars->link_status);
7425
7426         /* Activate nig drain */
7427         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
7428
7429         /* Disable emac */
7430         if (!CHIP_IS_E3(sc))
7431                 REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port*4, 0);
7432
7433         DELAY(1000 * 10);
7434         /* Reset BigMac/Xmac */
7435         if (CHIP_IS_E1x(sc) ||
7436             CHIP_IS_E2(sc))
7437                 elink_set_bmac_rx(sc, params->chip_id, params->port, 0);
7438
7439         if (CHIP_IS_E3(sc)) {
7440                 /* Prevent LPI Generation by chip */
7441                 REG_WR(sc, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2),
7442                        0);
7443                 REG_WR(sc, MISC_REG_CPMU_LP_MASK_ENT_P0 + (params->port << 2),
7444                        0);
7445                 vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
7446                                       SHMEM_EEE_ACTIVE_BIT);
7447
7448                 elink_update_mng_eee(params, vars->eee_status);
7449                 elink_set_xmac_rxtx(params, 0);
7450                 elink_set_umac_rxtx(params, 0);
7451         }
7452
7453         return ELINK_STATUS_OK;
7454 }
7455
7456 static elink_status_t elink_update_link_up(struct elink_params *params,
7457                                 struct elink_vars *vars,
7458                                 uint8_t link_10g)
7459 {
7460         struct bxe_softc *sc = params->sc;
7461         uint8_t phy_idx, port = params->port;
7462         elink_status_t rc = ELINK_STATUS_OK;
7463
7464         vars->link_status |= (LINK_STATUS_LINK_UP |
7465                               LINK_STATUS_PHYSICAL_LINK_FLAG);
7466         vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
7467
7468         if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
7469                 vars->link_status |=
7470                         LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
7471
7472         if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
7473                 vars->link_status |=
7474                         LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
7475         if (USES_WARPCORE(sc)) {
7476                 if (link_10g) {
7477                         if (elink_xmac_enable(params, vars, 0) ==
7478                             ELINK_STATUS_NO_LINK) {
7479                                 ELINK_DEBUG_P0(sc, "Found errors on XMAC\n");
7480                                 vars->link_up = 0;
7481                                 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
7482                                 vars->link_status &= ~LINK_STATUS_LINK_UP;
7483                         }
7484                 } else
7485                         elink_umac_enable(params, vars, 0);
7486                 elink_set_led(params, vars,
7487                               ELINK_LED_MODE_OPER, vars->line_speed);
7488
7489                 if ((vars->eee_status & SHMEM_EEE_ACTIVE_BIT) &&
7490                     (vars->eee_status & SHMEM_EEE_LPI_REQUESTED_BIT)) {
7491                         ELINK_DEBUG_P0(sc, "Enabling LPI assertion\n");
7492                         REG_WR(sc, MISC_REG_CPMU_LP_FW_ENABLE_P0 +
7493                                (params->port << 2), 1);
7494                         REG_WR(sc, MISC_REG_CPMU_LP_DR_ENABLE, 1);
7495                         REG_WR(sc, MISC_REG_CPMU_LP_MASK_ENT_P0 +
7496                                (params->port << 2), 0xfc20);
7497                 }
7498         }
7499         if ((CHIP_IS_E1x(sc) ||
7500              CHIP_IS_E2(sc))) {
7501                 if (link_10g) {
7502                         if (elink_bmac_enable(params, vars, 0, 1) ==
7503                             ELINK_STATUS_NO_LINK) {
7504                                 ELINK_DEBUG_P0(sc, "Found errors on BMAC\n");
7505                                 vars->link_up = 0;
7506                                 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
7507                                 vars->link_status &= ~LINK_STATUS_LINK_UP;
7508                         }
7509
7510                         elink_set_led(params, vars,
7511                                       ELINK_LED_MODE_OPER, ELINK_SPEED_10000);
7512                 } else {
7513                         rc = elink_emac_program(params, vars);
7514                         elink_emac_enable(params, vars, 0);
7515
7516                         /* AN complete? */
7517                         if ((vars->link_status &
7518                              LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
7519                             && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
7520                             ELINK_SINGLE_MEDIA_DIRECT(params))
7521                                 elink_set_gmii_tx_driver(params);
7522                 }
7523         }
7524
7525         /* PBF - link up */
7526         if (CHIP_IS_E1x(sc))
7527                 rc |= elink_pbf_update(params, vars->flow_ctrl,
7528                                        vars->line_speed);
7529
7530         /* Disable drain */
7531         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
7532
7533         /* Update shared memory */
7534         elink_update_mng(params, vars->link_status);
7535         elink_update_mng_eee(params, vars->eee_status);
7536         /* Check remote fault */
7537         for (phy_idx = ELINK_INT_PHY; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
7538                 if (params->phy[phy_idx].flags & ELINK_FLAGS_TX_ERROR_CHECK) {
7539                         elink_check_half_open_conn(params, vars, 0);
7540                         break;
7541                 }
7542         }
7543         DELAY(1000 * 20);
7544         return rc;
7545 }
7546 /* The elink_link_update function should be called upon link
7547  * interrupt.
7548  * Link is considered up as follows:
7549  * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
7550  *   to be up
7551  * - SINGLE_MEDIA - The link between the 577xx and the external
7552  *   phy (XGXS) need to up as well as the external link of the
7553  *   phy (PHY_EXT1)
7554  * - DUAL_MEDIA - The link between the 577xx and the first
7555  *   external phy needs to be up, and at least one of the 2
7556  *   external phy link must be up.
7557  */
7558 elink_status_t elink_link_update(struct elink_params *params, struct elink_vars *vars)
7559 {
7560         struct bxe_softc *sc = params->sc;
7561         struct elink_vars phy_vars[ELINK_MAX_PHYS];
7562         uint8_t port = params->port;
7563         uint8_t link_10g_plus, phy_index;
7564         uint8_t ext_phy_link_up = 0, cur_link_up;
7565         elink_status_t rc = ELINK_STATUS_OK;
7566         uint8_t is_mi_int = 0;
7567         uint16_t ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
7568         uint8_t active_external_phy = ELINK_INT_PHY;
7569         vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
7570         vars->link_status &= ~ELINK_LINK_UPDATE_MASK;
7571         for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
7572               phy_index++) {
7573                 phy_vars[phy_index].flow_ctrl = 0;
7574                 phy_vars[phy_index].link_status = 0;
7575                 phy_vars[phy_index].line_speed = 0;
7576                 phy_vars[phy_index].duplex = DUPLEX_FULL;
7577                 phy_vars[phy_index].phy_link_up = 0;
7578                 phy_vars[phy_index].link_up = 0;
7579                 phy_vars[phy_index].fault_detected = 0;
7580                 /* different consideration, since vars holds inner state */
7581                 phy_vars[phy_index].eee_status = vars->eee_status;
7582         }
7583
7584         if (USES_WARPCORE(sc))
7585                 elink_set_aer_mmd(params, &params->phy[ELINK_INT_PHY]);
7586
7587         ELINK_DEBUG_P3(sc, "port %x, XGXS?%x, int_status 0x%x\n",
7588                  port, (vars->phy_flags & PHY_XGXS_FLAG),
7589                  REG_RD(sc, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
7590
7591         is_mi_int = (uint8_t)(REG_RD(sc, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
7592                                 port*0x18) > 0);
7593         ELINK_DEBUG_P3(sc, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
7594                  REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
7595                  is_mi_int,
7596                  REG_RD(sc, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
7597
7598         ELINK_DEBUG_P2(sc, " 10G %x, XGXS_LINK %x\n",
7599           REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
7600           REG_RD(sc, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
7601
7602         /* Disable emac */
7603         if (!CHIP_IS_E3(sc))
7604                 REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port*4, 0);
7605
7606         /* Step 1:
7607          * Check external link change only for external phys, and apply
7608          * priority selection between them in case the link on both phys
7609          * is up. Note that instead of the common vars, a temporary
7610          * vars argument is used since each phy may have different link/
7611          * speed/duplex result
7612          */
7613         for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7614               phy_index++) {
7615                 struct elink_phy *phy = &params->phy[phy_index];
7616                 if (!phy->read_status)
7617                         continue;
7618                 /* Read link status and params of this ext phy */
7619                 cur_link_up = phy->read_status(phy, params,
7620                                                &phy_vars[phy_index]);
7621                 if (cur_link_up) {
7622                         ELINK_DEBUG_P1(sc, "phy in index %d link is up\n",
7623                                    phy_index);
7624                 } else {
7625                         ELINK_DEBUG_P1(sc, "phy in index %d link is down\n",
7626                                    phy_index);
7627                         continue;
7628                 }
7629
7630                 if (!ext_phy_link_up) {
7631                         ext_phy_link_up = 1;
7632                         active_external_phy = phy_index;
7633                 } else {
7634                         switch (elink_phy_selection(params)) {
7635                         case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
7636                         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
7637                         /* In this option, the first PHY makes sure to pass the
7638                          * traffic through itself only.
7639                          * Its not clear how to reset the link on the second phy
7640                          */
7641                                 active_external_phy = ELINK_EXT_PHY1;
7642                                 break;
7643                         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
7644                         /* In this option, the first PHY makes sure to pass the
7645                          * traffic through the second PHY.
7646                          */
7647                                 active_external_phy = ELINK_EXT_PHY2;
7648                                 break;
7649                         default:
7650                         /* Link indication on both PHYs with the following cases
7651                          * is invalid:
7652                          * - FIRST_PHY means that second phy wasn't initialized,
7653                          * hence its link is expected to be down
7654                          * - SECOND_PHY means that first phy should not be able
7655                          * to link up by itself (using configuration)
7656                          * - DEFAULT should be overriden during initialiazation
7657                          */
7658                                 ELINK_DEBUG_P1(sc, "Invalid link indication"
7659                                            "mpc=0x%x. DISABLING LINK !!!\n",
7660                                            params->multi_phy_config);
7661                                 ext_phy_link_up = 0;
7662                                 break;
7663                         }
7664                 }
7665         }
7666         prev_line_speed = vars->line_speed;
7667         /* Step 2:
7668          * Read the status of the internal phy. In case of
7669          * DIRECT_SINGLE_MEDIA board, this link is the external link,
7670          * otherwise this is the link between the 577xx and the first
7671          * external phy
7672          */
7673         if (params->phy[ELINK_INT_PHY].read_status)
7674                 params->phy[ELINK_INT_PHY].read_status(
7675                         &params->phy[ELINK_INT_PHY],
7676                         params, vars);
7677         /* The INT_PHY flow control reside in the vars. This include the
7678          * case where the speed or flow control are not set to AUTO.
7679          * Otherwise, the active external phy flow control result is set
7680          * to the vars. The ext_phy_line_speed is needed to check if the
7681          * speed is different between the internal phy and external phy.
7682          * This case may be result of intermediate link speed change.
7683          */
7684         if (active_external_phy > ELINK_INT_PHY) {
7685                 vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
7686                 /* Link speed is taken from the XGXS. AN and FC result from
7687                  * the external phy.
7688                  */
7689                 vars->link_status |= phy_vars[active_external_phy].link_status;
7690
7691                 /* if active_external_phy is first PHY and link is up - disable
7692                  * disable TX on second external PHY
7693                  */
7694                 if (active_external_phy == ELINK_EXT_PHY1) {
7695                         if (params->phy[ELINK_EXT_PHY2].phy_specific_func) {
7696                                 ELINK_DEBUG_P0(sc,
7697                                    "Disabling TX on EXT_PHY2\n");
7698                                 params->phy[ELINK_EXT_PHY2].phy_specific_func(
7699                                         &params->phy[ELINK_EXT_PHY2],
7700                                         params, ELINK_DISABLE_TX);
7701                         }
7702                 }
7703
7704                 ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
7705                 vars->duplex = phy_vars[active_external_phy].duplex;
7706                 if (params->phy[active_external_phy].supported &
7707                     ELINK_SUPPORTED_FIBRE)
7708                         vars->link_status |= LINK_STATUS_SERDES_LINK;
7709                 else
7710                         vars->link_status &= ~LINK_STATUS_SERDES_LINK;
7711
7712                 vars->eee_status = phy_vars[active_external_phy].eee_status;
7713
7714                 ELINK_DEBUG_P1(sc, "Active external phy selected: %x\n",
7715                            active_external_phy);
7716         }
7717
7718         for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
7719               phy_index++) {
7720                 if (params->phy[phy_index].flags &
7721                     ELINK_FLAGS_REARM_LATCH_SIGNAL) {
7722                         elink_rearm_latch_signal(sc, port,
7723                                                  phy_index ==
7724                                                  active_external_phy);
7725                         break;
7726                 }
7727         }
7728         ELINK_DEBUG_P3(sc, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
7729                    " ext_phy_line_speed = %d\n", vars->flow_ctrl,
7730                    vars->link_status, ext_phy_line_speed);
7731         /* Upon link speed change set the NIG into drain mode. Comes to
7732          * deals with possible FIFO glitch due to clk change when speed
7733          * is decreased without link down indicator
7734          */
7735
7736         if (vars->phy_link_up) {
7737                 if (!(ELINK_SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
7738                     (ext_phy_line_speed != vars->line_speed)) {
7739                         ELINK_DEBUG_P2(sc, "Internal link speed %d is"
7740                                    " different than the external"
7741                                    " link speed %d\n", vars->line_speed,
7742                                    ext_phy_line_speed);
7743                         vars->phy_link_up = 0;
7744                 } else if (prev_line_speed != vars->line_speed) {
7745                         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4,
7746                                0);
7747                         DELAY(1000 * 1);
7748                 }
7749         }
7750
7751         /* Anything 10 and over uses the bmac */
7752         link_10g_plus = (vars->line_speed >= ELINK_SPEED_10000);
7753
7754         elink_link_int_ack(params, vars, link_10g_plus);
7755
7756         /* In case external phy link is up, and internal link is down
7757          * (not initialized yet probably after link initialization, it
7758          * needs to be initialized.
7759          * Note that after link down-up as result of cable plug, the xgxs
7760          * link would probably become up again without the need
7761          * initialize it
7762          */
7763         if (!(ELINK_SINGLE_MEDIA_DIRECT(params))) {
7764                 ELINK_DEBUG_P3(sc, "ext_phy_link_up = %d, int_link_up = %d,"
7765                            " init_preceding = %d\n", ext_phy_link_up,
7766                            vars->phy_link_up,
7767                            params->phy[ELINK_EXT_PHY1].flags &
7768                            ELINK_FLAGS_INIT_XGXS_FIRST);
7769                 if (!(params->phy[ELINK_EXT_PHY1].flags &
7770                       ELINK_FLAGS_INIT_XGXS_FIRST)
7771                     && ext_phy_link_up && !vars->phy_link_up) {
7772                         vars->line_speed = ext_phy_line_speed;
7773                         if (vars->line_speed < ELINK_SPEED_1000)
7774                                 vars->phy_flags |= PHY_SGMII_FLAG;
7775                         else
7776                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
7777
7778                         if (params->phy[ELINK_INT_PHY].config_init)
7779                                 params->phy[ELINK_INT_PHY].config_init(
7780                                         &params->phy[ELINK_INT_PHY], params,
7781                                                 vars);
7782                 }
7783         }
7784         /* Link is up only if both local phy and external phy (in case of
7785          * non-direct board) are up and no fault detected on active PHY.
7786          */
7787         vars->link_up = (vars->phy_link_up &&
7788                          (ext_phy_link_up ||
7789                           ELINK_SINGLE_MEDIA_DIRECT(params)) &&
7790                          (phy_vars[active_external_phy].fault_detected == 0));
7791
7792         /* Update the PFC configuration in case it was changed */
7793         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
7794                 vars->link_status |= LINK_STATUS_PFC_ENABLED;
7795         else
7796                 vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
7797
7798         if (vars->link_up)
7799                 rc = elink_update_link_up(params, vars, link_10g_plus);
7800         else
7801                 rc = elink_update_link_down(params, vars);
7802
7803         /* Update MCP link status was changed */
7804         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_BC_SUPPORTS_AFEX)
7805                 elink_cb_fw_command(sc, DRV_MSG_CODE_LINK_STATUS_CHANGED, 0);
7806
7807         return rc;
7808 }
7809
7810 /*****************************************************************************/
7811 /*                          External Phy section                             */
7812 /*****************************************************************************/
7813 void elink_ext_phy_hw_reset(struct bxe_softc *sc, uint8_t port)
7814 {
7815         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
7816                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
7817         DELAY(1000 * 1);
7818         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
7819                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
7820 }
7821
7822 static void elink_save_spirom_version(struct bxe_softc *sc, uint8_t port,
7823                                       uint32_t spirom_ver, uint32_t ver_addr)
7824 {
7825         ELINK_DEBUG_P3(sc, "FW version 0x%x:0x%x for port %d\n",
7826                  (uint16_t)(spirom_ver>>16), (uint16_t)spirom_ver, port);
7827
7828         if (ver_addr)
7829                 REG_WR(sc, ver_addr, spirom_ver);
7830 }
7831
7832 static void elink_save_bcm_spirom_ver(struct bxe_softc *sc,
7833                                       struct elink_phy *phy,
7834                                       uint8_t port)
7835 {
7836         uint16_t fw_ver1, fw_ver2;
7837
7838         elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
7839                         MDIO_PMA_REG_ROM_VER1, &fw_ver1);
7840         elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
7841                         MDIO_PMA_REG_ROM_VER2, &fw_ver2);
7842         elink_save_spirom_version(sc, port, (uint32_t)(fw_ver1<<16 | fw_ver2),
7843                                   phy->ver_addr);
7844 }
7845
7846 static void elink_ext_phy_10G_an_resolve(struct bxe_softc *sc,
7847                                        struct elink_phy *phy,
7848                                        struct elink_vars *vars)
7849 {
7850         uint16_t val;
7851         elink_cl45_read(sc, phy,
7852                         MDIO_AN_DEVAD,
7853                         MDIO_AN_REG_STATUS, &val);
7854         elink_cl45_read(sc, phy,
7855                         MDIO_AN_DEVAD,
7856                         MDIO_AN_REG_STATUS, &val);
7857         if (val & (1<<5))
7858                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
7859         if ((val & (1<<0)) == 0)
7860                 vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
7861 }
7862
7863 /******************************************************************/
7864 /*              common BCM8073/BCM8727 PHY SECTION                */
7865 /******************************************************************/
7866 static void elink_8073_resolve_fc(struct elink_phy *phy,
7867                                   struct elink_params *params,
7868                                   struct elink_vars *vars)
7869 {
7870         struct bxe_softc *sc = params->sc;
7871         if (phy->req_line_speed == ELINK_SPEED_10 ||
7872             phy->req_line_speed == ELINK_SPEED_100) {
7873                 vars->flow_ctrl = phy->req_flow_ctrl;
7874                 return;
7875         }
7876
7877         if (elink_ext_phy_resolve_fc(phy, params, vars) &&
7878             (vars->flow_ctrl == ELINK_FLOW_CTRL_NONE)) {
7879                 uint16_t pause_result;
7880                 uint16_t ld_pause;              /* local */
7881                 uint16_t lp_pause;              /* link partner */
7882                 elink_cl45_read(sc, phy,
7883                                 MDIO_AN_DEVAD,
7884                                 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
7885
7886                 elink_cl45_read(sc, phy,
7887                                 MDIO_AN_DEVAD,
7888                                 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
7889                 pause_result = (ld_pause &
7890                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
7891                 pause_result |= (lp_pause &
7892                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
7893
7894                 elink_pause_resolve(vars, pause_result);
7895                 ELINK_DEBUG_P1(sc, "Ext PHY CL37 pause result 0x%x\n",
7896                            pause_result);
7897         }
7898 }
7899 static elink_status_t elink_8073_8727_external_rom_boot(struct bxe_softc *sc,
7900                                              struct elink_phy *phy,
7901                                              uint8_t port)
7902 {
7903         uint32_t count = 0;
7904         uint16_t fw_ver1, fw_msgout;
7905         elink_status_t rc = ELINK_STATUS_OK;
7906
7907         /* Boot port from external ROM  */
7908         /* EDC grst */
7909         elink_cl45_write(sc, phy,
7910                          MDIO_PMA_DEVAD,
7911                          MDIO_PMA_REG_GEN_CTRL,
7912                          0x0001);
7913
7914         /* Ucode reboot and rst */
7915         elink_cl45_write(sc, phy,
7916                          MDIO_PMA_DEVAD,
7917                          MDIO_PMA_REG_GEN_CTRL,
7918                          0x008c);
7919
7920         elink_cl45_write(sc, phy,
7921                          MDIO_PMA_DEVAD,
7922                          MDIO_PMA_REG_MISC_CTRL1, 0x0001);
7923
7924         /* Reset internal microprocessor */
7925         elink_cl45_write(sc, phy,
7926                          MDIO_PMA_DEVAD,
7927                          MDIO_PMA_REG_GEN_CTRL,
7928                          MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
7929
7930         /* Release srst bit */
7931         elink_cl45_write(sc, phy,
7932                          MDIO_PMA_DEVAD,
7933                          MDIO_PMA_REG_GEN_CTRL,
7934                          MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
7935
7936         /* Delay 100ms per the PHY specifications */
7937         DELAY(1000 * 100);
7938
7939         /* 8073 sometimes taking longer to download */
7940         do {
7941                 count++;
7942                 if (count > 300) {
7943                         ELINK_DEBUG_P2(sc,
7944                                  "elink_8073_8727_external_rom_boot port %x:"
7945                                  "Download failed. fw version = 0x%x\n",
7946                                  port, fw_ver1);
7947                         rc = ELINK_STATUS_ERROR;
7948                         break;
7949                 }
7950
7951                 elink_cl45_read(sc, phy,
7952                                 MDIO_PMA_DEVAD,
7953                                 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
7954                 elink_cl45_read(sc, phy,
7955                                 MDIO_PMA_DEVAD,
7956                                 MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
7957
7958                 DELAY(1000 * 1);
7959         } while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
7960                         ((fw_msgout & 0xff) != 0x03 && (phy->type ==
7961                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)));
7962
7963         /* Clear ser_boot_ctl bit */
7964         elink_cl45_write(sc, phy,
7965                          MDIO_PMA_DEVAD,
7966                          MDIO_PMA_REG_MISC_CTRL1, 0x0000);
7967         elink_save_bcm_spirom_ver(sc, phy, port);
7968
7969         ELINK_DEBUG_P2(sc,
7970                  "elink_8073_8727_external_rom_boot port %x:"
7971                  "Download complete. fw version = 0x%x\n",
7972                  port, fw_ver1);
7973
7974         return rc;
7975 }
7976
7977 /******************************************************************/
7978 /*                      BCM8073 PHY SECTION                       */
7979 /******************************************************************/
7980 static elink_status_t elink_8073_is_snr_needed(struct bxe_softc *sc, struct elink_phy *phy)
7981 {
7982         /* This is only required for 8073A1, version 102 only */
7983         uint16_t val;
7984
7985         /* Read 8073 HW revision*/
7986         elink_cl45_read(sc, phy,
7987                         MDIO_PMA_DEVAD,
7988                         MDIO_PMA_REG_8073_CHIP_REV, &val);
7989
7990         if (val != 1) {
7991                 /* No need to workaround in 8073 A1 */
7992                 return ELINK_STATUS_OK;
7993         }
7994
7995         elink_cl45_read(sc, phy,
7996                         MDIO_PMA_DEVAD,
7997                         MDIO_PMA_REG_ROM_VER2, &val);
7998
7999         /* SNR should be applied only for version 0x102 */
8000         if (val != 0x102)
8001                 return ELINK_STATUS_OK;
8002
8003         return 1;
8004 }
8005
8006 static elink_status_t elink_8073_xaui_wa(struct bxe_softc *sc, struct elink_phy *phy)
8007 {
8008         uint16_t val, cnt, cnt1 ;
8009
8010         elink_cl45_read(sc, phy,
8011                         MDIO_PMA_DEVAD,
8012                         MDIO_PMA_REG_8073_CHIP_REV, &val);
8013
8014         if (val > 0) {
8015                 /* No need to workaround in 8073 A1 */
8016                 return ELINK_STATUS_OK;
8017         }
8018         /* XAUI workaround in 8073 A0: */
8019
8020         /* After loading the boot ROM and restarting Autoneg, poll
8021          * Dev1, Reg $C820:
8022          */
8023
8024         for (cnt = 0; cnt < 1000; cnt++) {
8025                 elink_cl45_read(sc, phy,
8026                                 MDIO_PMA_DEVAD,
8027                                 MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
8028                                 &val);
8029                   /* If bit [14] = 0 or bit [13] = 0, continue on with
8030                    * system initialization (XAUI work-around not required, as
8031                    * these bits indicate 2.5G or 1G link up).
8032                    */
8033                 if (!(val & (1<<14)) || !(val & (1<<13))) {
8034                         ELINK_DEBUG_P0(sc, "XAUI work-around not required\n");
8035                         return ELINK_STATUS_OK;
8036                 } else if (!(val & (1<<15))) {
8037                         ELINK_DEBUG_P0(sc, "bit 15 went off\n");
8038                         /* If bit 15 is 0, then poll Dev1, Reg $C841 until it's
8039                          * MSB (bit15) goes to 1 (indicating that the XAUI
8040                          * workaround has completed), then continue on with
8041                          * system initialization.
8042                          */
8043                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
8044                                 elink_cl45_read(sc, phy,
8045                                         MDIO_PMA_DEVAD,
8046                                         MDIO_PMA_REG_8073_XAUI_WA, &val);
8047                                 if (val & (1<<15)) {
8048                                         ELINK_DEBUG_P0(sc,
8049                                           "XAUI workaround has completed\n");
8050                                         return ELINK_STATUS_OK;
8051                                  }
8052                                  DELAY(1000 * 3);
8053                         }
8054                         break;
8055                 }
8056                 DELAY(1000 * 3);
8057         }
8058         ELINK_DEBUG_P0(sc, "Warning: XAUI work-around timeout !!!\n");
8059         return ELINK_STATUS_ERROR;
8060 }
8061
8062 static void elink_807x_force_10G(struct bxe_softc *sc, struct elink_phy *phy)
8063 {
8064         /* Force KR or KX */
8065         elink_cl45_write(sc, phy,
8066                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
8067         elink_cl45_write(sc, phy,
8068                          MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
8069         elink_cl45_write(sc, phy,
8070                          MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
8071         elink_cl45_write(sc, phy,
8072                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
8073 }
8074
8075 static void elink_8073_set_pause_cl37(struct elink_params *params,
8076                                       struct elink_phy *phy,
8077                                       struct elink_vars *vars)
8078 {
8079         uint16_t cl37_val;
8080         struct bxe_softc *sc = params->sc;
8081         elink_cl45_read(sc, phy,
8082                         MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
8083
8084         cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
8085         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
8086         elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
8087         if ((vars->ieee_fc &
8088             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
8089             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
8090                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
8091         }
8092         if ((vars->ieee_fc &
8093             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
8094             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
8095                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
8096         }
8097         if ((vars->ieee_fc &
8098             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
8099             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
8100                 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
8101         }
8102         ELINK_DEBUG_P1(sc,
8103                  "Ext phy AN advertize cl37 0x%x\n", cl37_val);
8104
8105         elink_cl45_write(sc, phy,
8106                          MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
8107         DELAY(1000 * 500);
8108 }
8109
8110 static void elink_8073_specific_func(struct elink_phy *phy,
8111                                      struct elink_params *params,
8112                                      uint32_t action)
8113 {
8114         struct bxe_softc *sc = params->sc;
8115         switch (action) {
8116         case ELINK_PHY_INIT:
8117                 /* Enable LASI */
8118                 elink_cl45_write(sc, phy,
8119                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, (1<<2));
8120                 elink_cl45_write(sc, phy,
8121                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,  0x0004);
8122                 break;
8123         }
8124 }
8125
8126 static elink_status_t elink_8073_config_init(struct elink_phy *phy,
8127                                   struct elink_params *params,
8128                                   struct elink_vars *vars)
8129 {
8130         struct bxe_softc *sc = params->sc;
8131         uint16_t val = 0, tmp1;
8132         uint8_t gpio_port;
8133         ELINK_DEBUG_P0(sc, "Init 8073\n");
8134
8135         if (CHIP_IS_E2(sc))
8136                 gpio_port = SC_PATH(sc);
8137         else
8138                 gpio_port = params->port;
8139         /* Restore normal power mode*/
8140         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
8141                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
8142
8143         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
8144                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
8145
8146         elink_8073_specific_func(phy, params, ELINK_PHY_INIT);
8147         elink_8073_set_pause_cl37(params, phy, vars);
8148
8149         elink_cl45_read(sc, phy,
8150                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
8151
8152         elink_cl45_read(sc, phy,
8153                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
8154
8155         ELINK_DEBUG_P1(sc, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
8156
8157         /* Swap polarity if required - Must be done only in non-1G mode */
8158         if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
8159                 /* Configure the 8073 to swap _P and _N of the KR lines */
8160                 ELINK_DEBUG_P0(sc, "Swapping polarity for the 8073\n");
8161                 /* 10G Rx/Tx and 1G Tx signal polarity swap */
8162                 elink_cl45_read(sc, phy,
8163                                 MDIO_PMA_DEVAD,
8164                                 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
8165                 elink_cl45_write(sc, phy,
8166                                  MDIO_PMA_DEVAD,
8167                                  MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
8168                                  (val | (3<<9)));
8169         }
8170
8171
8172         /* Enable CL37 BAM */
8173         if (REG_RD(sc, params->shmem_base +
8174                          offsetof(struct shmem_region, dev_info.
8175                                   port_hw_config[params->port].default_cfg)) &
8176             PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
8177
8178                 elink_cl45_read(sc, phy,
8179                                 MDIO_AN_DEVAD,
8180                                 MDIO_AN_REG_8073_BAM, &val);
8181                 elink_cl45_write(sc, phy,
8182                                  MDIO_AN_DEVAD,
8183                                  MDIO_AN_REG_8073_BAM, val | 1);
8184                 ELINK_DEBUG_P0(sc, "Enable CL37 BAM on KR\n");
8185         }
8186         if (params->loopback_mode == ELINK_LOOPBACK_EXT) {
8187                 elink_807x_force_10G(sc, phy);
8188                 ELINK_DEBUG_P0(sc, "Forced speed 10G on 807X\n");
8189                 return ELINK_STATUS_OK;
8190         } else {
8191                 elink_cl45_write(sc, phy,
8192                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
8193         }
8194         if (phy->req_line_speed != ELINK_SPEED_AUTO_NEG) {
8195                 if (phy->req_line_speed == ELINK_SPEED_10000) {
8196                         val = (1<<7);
8197                 } else if (phy->req_line_speed ==  ELINK_SPEED_2500) {
8198                         val = (1<<5);
8199                         /* Note that 2.5G works only when used with 1G
8200                          * advertisement
8201                          */
8202                 } else
8203                         val = (1<<5);
8204         } else {
8205                 val = 0;
8206                 if (phy->speed_cap_mask &
8207                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
8208                         val |= (1<<7);
8209
8210                 /* Note that 2.5G works only when used with 1G advertisement */
8211                 if (phy->speed_cap_mask &
8212                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
8213                          PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
8214                         val |= (1<<5);
8215                 ELINK_DEBUG_P1(sc, "807x autoneg val = 0x%x\n", val);
8216         }
8217
8218         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
8219         elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
8220
8221         if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
8222              (phy->req_line_speed == ELINK_SPEED_AUTO_NEG)) ||
8223             (phy->req_line_speed == ELINK_SPEED_2500)) {
8224                 uint16_t phy_ver;
8225                 /* Allow 2.5G for A1 and above */
8226                 elink_cl45_read(sc, phy,
8227                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
8228                                 &phy_ver);
8229                 ELINK_DEBUG_P0(sc, "Add 2.5G\n");
8230                 if (phy_ver > 0)
8231                         tmp1 |= 1;
8232                 else
8233                         tmp1 &= 0xfffe;
8234         } else {
8235                 ELINK_DEBUG_P0(sc, "Disable 2.5G\n");
8236                 tmp1 &= 0xfffe;
8237         }
8238
8239         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
8240         /* Add support for CL37 (passive mode) II */
8241
8242         elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
8243         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
8244                          (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
8245                                   0x20 : 0x40)));
8246
8247         /* Add support for CL37 (passive mode) III */
8248         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8249
8250         /* The SNR will improve about 2db by changing BW and FEE main
8251          * tap. Rest commands are executed after link is up
8252          * Change FFE main cursor to 5 in EDC register
8253          */
8254         if (elink_8073_is_snr_needed(sc, phy))
8255                 elink_cl45_write(sc, phy,
8256                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
8257                                  0xFB0C);
8258
8259         /* Enable FEC (Forware Error Correction) Request in the AN */
8260         elink_cl45_read(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
8261         tmp1 |= (1<<15);
8262         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
8263
8264         elink_ext_phy_set_pause(params, phy, vars);
8265
8266         /* Restart autoneg */
8267         DELAY(1000 * 500);
8268         elink_cl45_write(sc, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
8269         ELINK_DEBUG_P2(sc, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
8270                    ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
8271         return ELINK_STATUS_OK;
8272 }
8273
8274 static uint8_t elink_8073_read_status(struct elink_phy *phy,
8275                                  struct elink_params *params,
8276                                  struct elink_vars *vars)
8277 {
8278         struct bxe_softc *sc = params->sc;
8279         uint8_t link_up = 0;
8280         uint16_t val1, val2;
8281         uint16_t link_status = 0;
8282         uint16_t an1000_status = 0;
8283
8284         elink_cl45_read(sc, phy,
8285                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
8286
8287         ELINK_DEBUG_P1(sc, "8703 LASI status 0x%x\n", val1);
8288
8289         /* Clear the interrupt LASI status register */
8290         elink_cl45_read(sc, phy,
8291                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
8292         elink_cl45_read(sc, phy,
8293                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
8294         ELINK_DEBUG_P2(sc, "807x PCS status 0x%x->0x%x\n", val2, val1);
8295         /* Clear MSG-OUT */
8296         elink_cl45_read(sc, phy,
8297                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
8298
8299         /* Check the LASI */
8300         elink_cl45_read(sc, phy,
8301                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
8302
8303         ELINK_DEBUG_P1(sc, "KR 0x9003 0x%x\n", val2);
8304
8305         /* Check the link status */
8306         elink_cl45_read(sc, phy,
8307                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
8308         ELINK_DEBUG_P1(sc, "KR PCS status 0x%x\n", val2);
8309
8310         elink_cl45_read(sc, phy,
8311                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
8312         elink_cl45_read(sc, phy,
8313                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
8314         link_up = ((val1 & 4) == 4);
8315         ELINK_DEBUG_P1(sc, "PMA_REG_STATUS=0x%x\n", val1);
8316
8317         if (link_up &&
8318              ((phy->req_line_speed != ELINK_SPEED_10000))) {
8319                 if (elink_8073_xaui_wa(sc, phy) != 0)
8320                         return 0;
8321         }
8322         elink_cl45_read(sc, phy,
8323                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
8324         elink_cl45_read(sc, phy,
8325                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
8326
8327         /* Check the link status on 1.1.2 */
8328         elink_cl45_read(sc, phy,
8329                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
8330         elink_cl45_read(sc, phy,
8331                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
8332         ELINK_DEBUG_P3(sc, "KR PMA status 0x%x->0x%x,"
8333                    "an_link_status=0x%x\n", val2, val1, an1000_status);
8334
8335         link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
8336         if (link_up && elink_8073_is_snr_needed(sc, phy)) {
8337                 /* The SNR will improve about 2dbby changing the BW and FEE main
8338                  * tap. The 1st write to change FFE main tap is set before
8339                  * restart AN. Change PLL Bandwidth in EDC register
8340                  */
8341                 elink_cl45_write(sc, phy,
8342                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
8343                                  0x26BC);
8344
8345                 /* Change CDR Bandwidth in EDC register */
8346                 elink_cl45_write(sc, phy,
8347                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
8348                                  0x0333);
8349         }
8350         elink_cl45_read(sc, phy,
8351                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
8352                         &link_status);
8353
8354         /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
8355         if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
8356                 link_up = 1;
8357                 vars->line_speed = ELINK_SPEED_10000;
8358                 ELINK_DEBUG_P1(sc, "port %x: External link up in 10G\n",
8359                            params->port);
8360         } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
8361                 link_up = 1;
8362                 vars->line_speed = ELINK_SPEED_2500;
8363                 ELINK_DEBUG_P1(sc, "port %x: External link up in 2.5G\n",
8364                            params->port);
8365         } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
8366                 link_up = 1;
8367                 vars->line_speed = ELINK_SPEED_1000;
8368                 ELINK_DEBUG_P1(sc, "port %x: External link up in 1G\n",
8369                            params->port);
8370         } else {
8371                 link_up = 0;
8372                 ELINK_DEBUG_P1(sc, "port %x: External link is down\n",
8373                            params->port);
8374         }
8375
8376         if (link_up) {
8377                 /* Swap polarity if required */
8378                 if (params->lane_config &
8379                     PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
8380                         /* Configure the 8073 to swap P and N of the KR lines */
8381                         elink_cl45_read(sc, phy,
8382                                         MDIO_XS_DEVAD,
8383                                         MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
8384                         /* Set bit 3 to invert Rx in 1G mode and clear this bit
8385                          * when it`s in 10G mode.
8386                          */
8387                         if (vars->line_speed == ELINK_SPEED_1000) {
8388                                 ELINK_DEBUG_P0(sc, "Swapping 1G polarity for"
8389                                               "the 8073\n");
8390                                 val1 |= (1<<3);
8391                         } else
8392                                 val1 &= ~(1<<3);
8393
8394                         elink_cl45_write(sc, phy,
8395                                          MDIO_XS_DEVAD,
8396                                          MDIO_XS_REG_8073_RX_CTRL_PCIE,
8397                                          val1);
8398                 }
8399                 elink_ext_phy_10G_an_resolve(sc, phy, vars);
8400                 elink_8073_resolve_fc(phy, params, vars);
8401                 vars->duplex = DUPLEX_FULL;
8402         }
8403
8404         if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
8405                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
8406                                 MDIO_AN_REG_LP_AUTO_NEG2, &val1);
8407
8408                 if (val1 & (1<<5))
8409                         vars->link_status |=
8410                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
8411                 if (val1 & (1<<7))
8412                         vars->link_status |=
8413                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
8414         }
8415
8416         return link_up;
8417 }
8418
8419 static void elink_8073_link_reset(struct elink_phy *phy,
8420                                   struct elink_params *params)
8421 {
8422         struct bxe_softc *sc = params->sc;
8423         uint8_t gpio_port;
8424         if (CHIP_IS_E2(sc))
8425                 gpio_port = SC_PATH(sc);
8426         else
8427                 gpio_port = params->port;
8428         ELINK_DEBUG_P1(sc, "Setting 8073 port %d into low power mode\n",
8429            gpio_port);
8430         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
8431                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
8432                        gpio_port);
8433 }
8434
8435 /******************************************************************/
8436 /*                      BCM8705 PHY SECTION                       */
8437 /******************************************************************/
8438 static elink_status_t elink_8705_config_init(struct elink_phy *phy,
8439                                   struct elink_params *params,
8440                                   struct elink_vars *vars)
8441 {
8442         struct bxe_softc *sc = params->sc;
8443         ELINK_DEBUG_P0(sc, "init 8705\n");
8444         /* Restore normal power mode*/
8445         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
8446                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
8447         /* HW reset */
8448         elink_ext_phy_hw_reset(sc, params->port);
8449         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
8450         elink_wait_reset_complete(sc, phy, params);
8451
8452         elink_cl45_write(sc, phy,
8453                          MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
8454         elink_cl45_write(sc, phy,
8455                          MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
8456         elink_cl45_write(sc, phy,
8457                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
8458         elink_cl45_write(sc, phy,
8459                          MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
8460         /* BCM8705 doesn't have microcode, hence the 0 */
8461         elink_save_spirom_version(sc, params->port, params->shmem_base, 0);
8462         return ELINK_STATUS_OK;
8463 }
8464
8465 static uint8_t elink_8705_read_status(struct elink_phy *phy,
8466                                  struct elink_params *params,
8467                                  struct elink_vars *vars)
8468 {
8469         uint8_t link_up = 0;
8470         uint16_t val1, rx_sd;
8471         struct bxe_softc *sc = params->sc;
8472         ELINK_DEBUG_P0(sc, "read status 8705\n");
8473         elink_cl45_read(sc, phy,
8474                       MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
8475         ELINK_DEBUG_P1(sc, "8705 LASI status 0x%x\n", val1);
8476
8477         elink_cl45_read(sc, phy,
8478                       MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
8479         ELINK_DEBUG_P1(sc, "8705 LASI status 0x%x\n", val1);
8480
8481         elink_cl45_read(sc, phy,
8482                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
8483
8484         elink_cl45_read(sc, phy,
8485                       MDIO_PMA_DEVAD, 0xc809, &val1);
8486         elink_cl45_read(sc, phy,
8487                       MDIO_PMA_DEVAD, 0xc809, &val1);
8488
8489         ELINK_DEBUG_P1(sc, "8705 1.c809 val=0x%x\n", val1);
8490         link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
8491         if (link_up) {
8492                 vars->line_speed = ELINK_SPEED_10000;
8493                 elink_ext_phy_resolve_fc(phy, params, vars);
8494         }
8495         return link_up;
8496 }
8497
8498 /******************************************************************/
8499 /*                      SFP+ module Section                       */
8500 /******************************************************************/
8501 static void elink_set_disable_pmd_transmit(struct elink_params *params,
8502                                            struct elink_phy *phy,
8503                                            uint8_t pmd_dis)
8504 {
8505         struct bxe_softc *sc = params->sc;
8506         /* Disable transmitter only for bootcodes which can enable it afterwards
8507          * (for D3 link)
8508          */
8509         if (pmd_dis) {
8510                 if (params->feature_config_flags &
8511                      ELINK_FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED) {
8512                         ELINK_DEBUG_P0(sc, "Disabling PMD transmitter\n");
8513                 } else {
8514                         ELINK_DEBUG_P0(sc, "NOT disabling PMD transmitter\n");
8515                         return;
8516                 }
8517         } else
8518                 ELINK_DEBUG_P0(sc, "Enabling PMD transmitter\n");
8519         elink_cl45_write(sc, phy,
8520                          MDIO_PMA_DEVAD,
8521                          MDIO_PMA_REG_TX_DISABLE, pmd_dis);
8522 }
8523
8524 static uint8_t elink_get_gpio_port(struct elink_params *params)
8525 {
8526         uint8_t gpio_port;
8527         uint32_t swap_val, swap_override;
8528         struct bxe_softc *sc = params->sc;
8529         if (CHIP_IS_E2(sc))
8530                 gpio_port = SC_PATH(sc);
8531         else
8532                 gpio_port = params->port;
8533         swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
8534         swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
8535         return gpio_port ^ (swap_val && swap_override);
8536 }
8537
8538 static void elink_sfp_e1e2_set_transmitter(struct elink_params *params,
8539                                            struct elink_phy *phy,
8540                                            uint8_t tx_en)
8541 {
8542         uint16_t val;
8543         uint8_t port = params->port;
8544         struct bxe_softc *sc = params->sc;
8545         uint32_t tx_en_mode;
8546
8547         /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
8548         tx_en_mode = REG_RD(sc, params->shmem_base +
8549                             offsetof(struct shmem_region,
8550                                      dev_info.port_hw_config[port].sfp_ctrl)) &
8551                 PORT_HW_CFG_TX_LASER_MASK;
8552         ELINK_DEBUG_P3(sc, "Setting transmitter tx_en=%x for port %x "
8553                            "mode = %x\n", tx_en, port, tx_en_mode);
8554         switch (tx_en_mode) {
8555         case PORT_HW_CFG_TX_LASER_MDIO:
8556
8557                 elink_cl45_read(sc, phy,
8558                                 MDIO_PMA_DEVAD,
8559                                 MDIO_PMA_REG_PHY_IDENTIFIER,
8560                                 &val);
8561
8562                 if (tx_en)
8563                         val &= ~(1<<15);
8564                 else
8565                         val |= (1<<15);
8566
8567                 elink_cl45_write(sc, phy,
8568                                  MDIO_PMA_DEVAD,
8569                                  MDIO_PMA_REG_PHY_IDENTIFIER,
8570                                  val);
8571         break;
8572         case PORT_HW_CFG_TX_LASER_GPIO0:
8573         case PORT_HW_CFG_TX_LASER_GPIO1:
8574         case PORT_HW_CFG_TX_LASER_GPIO2:
8575         case PORT_HW_CFG_TX_LASER_GPIO3:
8576         {
8577                 uint16_t gpio_pin;
8578                 uint8_t gpio_port, gpio_mode;
8579                 if (tx_en)
8580                         gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH;
8581                 else
8582                         gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW;
8583
8584                 gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0;
8585                 gpio_port = elink_get_gpio_port(params);
8586                 elink_cb_gpio_write(sc, gpio_pin, gpio_mode, gpio_port);
8587                 break;
8588         }
8589         default:
8590                 ELINK_DEBUG_P1(sc, "Invalid TX_LASER_MDIO 0x%x\n", tx_en_mode);
8591                 break;
8592         }
8593 }
8594
8595 static void elink_sfp_set_transmitter(struct elink_params *params,
8596                                       struct elink_phy *phy,
8597                                       uint8_t tx_en)
8598 {
8599         struct bxe_softc *sc = params->sc;
8600         ELINK_DEBUG_P1(sc, "Setting SFP+ transmitter to %d\n", tx_en);
8601         if (CHIP_IS_E3(sc))
8602                 elink_sfp_e3_set_transmitter(params, phy, tx_en);
8603         else
8604                 elink_sfp_e1e2_set_transmitter(params, phy, tx_en);
8605 }
8606
8607 static elink_status_t elink_8726_read_sfp_module_eeprom(struct elink_phy *phy,
8608                                              struct elink_params *params,
8609                                              uint8_t dev_addr, uint16_t addr, uint8_t byte_cnt,
8610                                              uint8_t *o_buf, uint8_t is_init)
8611 {
8612         struct bxe_softc *sc = params->sc;
8613         uint16_t val = 0;
8614         uint16_t i;
8615         if (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) {
8616                 ELINK_DEBUG_P0(sc,
8617                    "Reading from eeprom is limited to 0xf\n");
8618                 return ELINK_STATUS_ERROR;
8619         }
8620         /* Set the read command byte count */
8621         elink_cl45_write(sc, phy,
8622                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
8623                          (byte_cnt | (dev_addr << 8)));
8624
8625         /* Set the read command address */
8626         elink_cl45_write(sc, phy,
8627                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
8628                          addr);
8629
8630         /* Activate read command */
8631         elink_cl45_write(sc, phy,
8632                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
8633                          0x2c0f);
8634
8635         /* Wait up to 500us for command complete status */
8636         for (i = 0; i < 100; i++) {
8637                 elink_cl45_read(sc, phy,
8638                                 MDIO_PMA_DEVAD,
8639                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
8640                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
8641                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
8642                         break;
8643                 DELAY(5);
8644         }
8645
8646         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
8647                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
8648                 ELINK_DEBUG_P1(sc,
8649                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
8650                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
8651                 return ELINK_STATUS_ERROR;
8652         }
8653
8654         /* Read the buffer */
8655         for (i = 0; i < byte_cnt; i++) {
8656                 elink_cl45_read(sc, phy,
8657                                 MDIO_PMA_DEVAD,
8658                                 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
8659                 o_buf[i] = (uint8_t)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
8660         }
8661
8662         for (i = 0; i < 100; i++) {
8663                 elink_cl45_read(sc, phy,
8664                                 MDIO_PMA_DEVAD,
8665                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
8666                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
8667                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
8668                         return ELINK_STATUS_OK;
8669                 DELAY(1000 * 1);
8670         }
8671         return ELINK_STATUS_ERROR;
8672 }
8673
8674 static void elink_warpcore_power_module(struct elink_params *params,
8675                                         uint8_t power)
8676 {
8677         uint32_t pin_cfg;
8678         struct bxe_softc *sc = params->sc;
8679
8680         pin_cfg = (REG_RD(sc, params->shmem_base +
8681                           offsetof(struct shmem_region,
8682                         dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
8683                         PORT_HW_CFG_E3_PWR_DIS_MASK) >>
8684                         PORT_HW_CFG_E3_PWR_DIS_SHIFT;
8685
8686         if (pin_cfg == PIN_CFG_NA)
8687                 return;
8688         ELINK_DEBUG_P2(sc, "Setting SFP+ module power to %d using pin cfg %d\n",
8689                        power, pin_cfg);
8690         /* Low ==> corresponding SFP+ module is powered
8691          * high ==> the SFP+ module is powered down
8692          */
8693         elink_set_cfg_pin(sc, pin_cfg, power ^ 1);
8694 }
8695 static elink_status_t elink_warpcore_read_sfp_module_eeprom(struct elink_phy *phy,
8696                                                  struct elink_params *params,
8697                                                  uint8_t dev_addr,
8698                                                  uint16_t addr, uint8_t byte_cnt,
8699                                                  uint8_t *o_buf, uint8_t is_init)
8700 {
8701         elink_status_t rc = ELINK_STATUS_OK;
8702         uint8_t i, j = 0, cnt = 0;
8703         uint32_t data_array[4];
8704         uint16_t addr32;
8705         struct bxe_softc *sc = params->sc;
8706
8707         if (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) {
8708                 ELINK_DEBUG_P0(sc,
8709                    "Reading from eeprom is limited to 16 bytes\n");
8710                 return ELINK_STATUS_ERROR;
8711         }
8712
8713         /* 4 byte aligned address */
8714         addr32 = addr & (~0x3);
8715         do {
8716                 if ((!is_init) && (cnt == I2C_WA_PWR_ITER)) {
8717                         elink_warpcore_power_module(params, 0);
8718                         /* Note that 100us are not enough here */
8719                         DELAY(1000 * 1);
8720                         elink_warpcore_power_module(params, 1);
8721                 }
8722                 rc = elink_bsc_read(params, sc, dev_addr, addr32, 0, byte_cnt,
8723                                     data_array);
8724         } while ((rc != ELINK_STATUS_OK) && (++cnt < I2C_WA_RETRY_CNT));
8725
8726         if (rc == ELINK_STATUS_OK) {
8727                 for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) {
8728                         o_buf[j] = *((uint8_t *)data_array + i);
8729                         j++;
8730                 }
8731         }
8732
8733         return rc;
8734 }
8735
8736 static elink_status_t elink_8727_read_sfp_module_eeprom(struct elink_phy *phy,
8737                                              struct elink_params *params,
8738                                              uint8_t dev_addr, uint16_t addr, uint8_t byte_cnt,
8739                                              uint8_t *o_buf, uint8_t is_init)
8740 {
8741         struct bxe_softc *sc = params->sc;
8742         uint16_t val, i;
8743
8744         if (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) {
8745                 ELINK_DEBUG_P0(sc,
8746                    "Reading from eeprom is limited to 0xf\n");
8747                 return ELINK_STATUS_ERROR;
8748         }
8749
8750         /* Set 2-wire transfer rate of SFP+ module EEPROM
8751          * to 100Khz since some DACs(direct attached cables) do
8752          * not work at 400Khz.
8753          */
8754         elink_cl45_write(sc, phy,
8755                          MDIO_PMA_DEVAD,
8756                          MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
8757                          ((dev_addr << 8) | 1));
8758
8759         /* Need to read from 1.8000 to clear it */
8760         elink_cl45_read(sc, phy,
8761                         MDIO_PMA_DEVAD,
8762                         MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
8763                         &val);
8764
8765         /* Set the read command byte count */
8766         elink_cl45_write(sc, phy,
8767                          MDIO_PMA_DEVAD,
8768                          MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
8769                          ((byte_cnt < 2) ? 2 : byte_cnt));
8770
8771         /* Set the read command address */
8772         elink_cl45_write(sc, phy,
8773                          MDIO_PMA_DEVAD,
8774                          MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
8775                          addr);
8776         /* Set the destination address */
8777         elink_cl45_write(sc, phy,
8778                          MDIO_PMA_DEVAD,
8779                          0x8004,
8780                          MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
8781
8782         /* Activate read command */
8783         elink_cl45_write(sc, phy,
8784                          MDIO_PMA_DEVAD,
8785                          MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
8786                          0x8002);
8787         /* Wait appropriate time for two-wire command to finish before
8788          * polling the status register
8789          */
8790         DELAY(1000 * 1);
8791
8792         /* Wait up to 500us for command complete status */
8793         for (i = 0; i < 100; i++) {
8794                 elink_cl45_read(sc, phy,
8795                                 MDIO_PMA_DEVAD,
8796                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
8797                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
8798                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
8799                         break;
8800                 DELAY(5);
8801         }
8802
8803         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
8804                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
8805                 ELINK_DEBUG_P1(sc,
8806                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
8807                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
8808                 return ELINK_STATUS_TIMEOUT;
8809         }
8810
8811         /* Read the buffer */
8812         for (i = 0; i < byte_cnt; i++) {
8813                 elink_cl45_read(sc, phy,
8814                                 MDIO_PMA_DEVAD,
8815                                 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
8816                 o_buf[i] = (uint8_t)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
8817         }
8818
8819         for (i = 0; i < 100; i++) {
8820                 elink_cl45_read(sc, phy,
8821                                 MDIO_PMA_DEVAD,
8822                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
8823                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
8824                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
8825                         return ELINK_STATUS_OK;
8826                 DELAY(1000 * 1);
8827         }
8828
8829         return ELINK_STATUS_ERROR;
8830 }
8831 elink_status_t elink_read_sfp_module_eeprom(struct elink_phy *phy,
8832                                  struct elink_params *params, uint8_t dev_addr,
8833                                  uint16_t addr, uint16_t byte_cnt, uint8_t *o_buf)
8834 {
8835         elink_status_t rc = 0;
8836         struct bxe_softc *sc = params->sc;
8837         uint8_t xfer_size;
8838         uint8_t *user_data = o_buf;
8839         read_sfp_module_eeprom_func_p read_func;
8840         if ((dev_addr != 0xa0) && (dev_addr != 0xa2)) {
8841                 ELINK_DEBUG_P1(sc, "invalid dev_addr 0x%x\n", dev_addr);
8842                 return ELINK_STATUS_ERROR;
8843         }
8844
8845         switch (phy->type) {
8846         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
8847                 read_func = elink_8726_read_sfp_module_eeprom;
8848                 break;
8849         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
8850         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
8851                 read_func = elink_8727_read_sfp_module_eeprom;
8852                 break;
8853         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
8854                 read_func = elink_warpcore_read_sfp_module_eeprom;
8855                 break;
8856         default:
8857                 return ELINK_OP_NOT_SUPPORTED;
8858         }
8859
8860         while (!rc && (byte_cnt > 0)) {
8861                 xfer_size = (byte_cnt > ELINK_SFP_EEPROM_PAGE_SIZE) ?
8862                         ELINK_SFP_EEPROM_PAGE_SIZE : byte_cnt;
8863                 rc = read_func(phy, params, dev_addr, addr, xfer_size,
8864                                user_data, 0);
8865                 byte_cnt -= xfer_size;
8866                 user_data += xfer_size;
8867                 addr += xfer_size;
8868         }
8869         return rc;
8870 }
8871
8872 static elink_status_t elink_get_edc_mode(struct elink_phy *phy,
8873                               struct elink_params *params,
8874                               uint16_t *edc_mode)
8875 {
8876         struct bxe_softc *sc = params->sc;
8877         uint32_t sync_offset = 0, phy_idx, media_types;
8878         uint8_t gport, val[2], check_limiting_mode = 0;
8879         *edc_mode = ELINK_EDC_MODE_LIMITING;
8880         phy->media_type = ELINK_ETH_PHY_UNSPECIFIED;
8881         /* First check for copper cable */
8882         if (elink_read_sfp_module_eeprom(phy,
8883                                          params,
8884                                          ELINK_I2C_DEV_ADDR_A0,
8885                                          ELINK_SFP_EEPROM_CON_TYPE_ADDR,
8886                                          2,
8887                                          (uint8_t *)val) != 0) {
8888                 ELINK_DEBUG_P0(sc, "Failed to read from SFP+ module EEPROM\n");
8889                 return ELINK_STATUS_ERROR;
8890         }
8891
8892         switch (val[0]) {
8893         case ELINK_SFP_EEPROM_CON_TYPE_VAL_COPPER:
8894         {
8895                 uint8_t copper_module_type;
8896                 phy->media_type = ELINK_ETH_PHY_DA_TWINAX;
8897                 /* Check if its active cable (includes SFP+ module)
8898                  * of passive cable
8899                  */
8900                 if (elink_read_sfp_module_eeprom(phy,
8901                                                params,
8902                                                ELINK_I2C_DEV_ADDR_A0,
8903                                                ELINK_SFP_EEPROM_FC_TX_TECH_ADDR,
8904                                                1,
8905                                                &copper_module_type) != 0) {
8906                         ELINK_DEBUG_P0(sc,
8907                                 "Failed to read copper-cable-type"
8908                                 " from SFP+ EEPROM\n");
8909                         return ELINK_STATUS_ERROR;
8910                 }
8911
8912                 if (copper_module_type &
8913                     ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
8914                         ELINK_DEBUG_P0(sc, "Active Copper cable detected\n");
8915                         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
8916                                 *edc_mode = ELINK_EDC_MODE_ACTIVE_DAC;
8917                         else
8918                                 check_limiting_mode = 1;
8919                 } else {
8920                         *edc_mode = ELINK_EDC_MODE_PASSIVE_DAC;
8921                         /* Even in case PASSIVE_DAC indication is not set,
8922                          * treat it as a passive DAC cable, since some cables
8923                          * don't have this indication.
8924                          */
8925                         if (copper_module_type &
8926                             ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
8927                                 ELINK_DEBUG_P0(sc,
8928                                                "Passive Copper cable detected\n");
8929                         } else {
8930                                 ELINK_DEBUG_P0(sc,
8931                                                "Unknown copper-cable-type\n");
8932                         }
8933                 }
8934                 break;
8935         }
8936         case ELINK_SFP_EEPROM_CON_TYPE_VAL_LC:
8937         case ELINK_SFP_EEPROM_CON_TYPE_VAL_RJ45:
8938                 check_limiting_mode = 1;
8939                 if ((val[1] & (ELINK_SFP_EEPROM_COMP_CODE_SR_MASK |
8940                                ELINK_SFP_EEPROM_COMP_CODE_LR_MASK |
8941                                ELINK_SFP_EEPROM_COMP_CODE_LRM_MASK)) == 0) {
8942                         ELINK_DEBUG_P0(sc, "1G SFP module detected\n");
8943                         gport = params->port;
8944                         phy->media_type = ELINK_ETH_PHY_SFP_1G_FIBER;
8945                         if (phy->req_line_speed != ELINK_SPEED_1000) {
8946                                 phy->req_line_speed = ELINK_SPEED_1000;
8947                                 if (!CHIP_IS_E1x(sc)) {
8948                                         gport = SC_PATH(sc) +
8949                                         (params->port << 1);
8950                                 }
8951                                 elink_cb_event_log(sc, ELINK_LOG_ID_NON_10G_MODULE, gport); //"Warning: Link speed was forced to 1000Mbps."
8952                                      // " Current SFP module in port %d is not"
8953                                      // " compliant with 10G Ethernet\n",
8954
8955                         }
8956                 } else {
8957                         int idx, cfg_idx = 0;
8958                         ELINK_DEBUG_P0(sc, "10G Optic module detected\n");
8959                         for (idx = ELINK_INT_PHY; idx < ELINK_MAX_PHYS; idx++) {
8960                                 if (params->phy[idx].type == phy->type) {
8961                                         cfg_idx = ELINK_LINK_CONFIG_IDX(idx);
8962                                         break;
8963                                 }
8964                         }
8965                         phy->media_type = ELINK_ETH_PHY_SFPP_10G_FIBER;
8966                         phy->req_line_speed = params->req_line_speed[cfg_idx];
8967                 }
8968                 break;
8969         default:
8970                 ELINK_DEBUG_P1(sc, "Unable to determine module type 0x%x !!!\n",
8971                          val[0]);
8972                 return ELINK_STATUS_ERROR;
8973         }
8974         sync_offset = params->shmem_base +
8975                 offsetof(struct shmem_region,
8976                          dev_info.port_hw_config[params->port].media_type);
8977         media_types = REG_RD(sc, sync_offset);
8978         /* Update media type for non-PMF sync */
8979         for (phy_idx = ELINK_INT_PHY; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
8980                 if (&(params->phy[phy_idx]) == phy) {
8981                         media_types &= ~(PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
8982                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
8983                         media_types |= ((phy->media_type &
8984                                         PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
8985                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
8986                         break;
8987                 }
8988         }
8989         REG_WR(sc, sync_offset, media_types);
8990         if (check_limiting_mode) {
8991                 uint8_t options[ELINK_SFP_EEPROM_OPTIONS_SIZE];
8992                 if (elink_read_sfp_module_eeprom(phy,
8993                                                  params,
8994                                                  ELINK_I2C_DEV_ADDR_A0,
8995                                                  ELINK_SFP_EEPROM_OPTIONS_ADDR,
8996                                                  ELINK_SFP_EEPROM_OPTIONS_SIZE,
8997                                                  options) != 0) {
8998                         ELINK_DEBUG_P0(sc,
8999                            "Failed to read Option field from module EEPROM\n");
9000                         return ELINK_STATUS_ERROR;
9001                 }
9002                 if ((options[0] & ELINK_SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
9003                         *edc_mode = ELINK_EDC_MODE_LINEAR;
9004                 else
9005                         *edc_mode = ELINK_EDC_MODE_LIMITING;
9006         }
9007         ELINK_DEBUG_P1(sc, "EDC mode is set to 0x%x\n", *edc_mode);
9008         return ELINK_STATUS_OK;
9009 }
9010 /* This function read the relevant field from the module (SFP+), and verify it
9011  * is compliant with this board
9012  */
9013 static elink_status_t elink_verify_sfp_module(struct elink_phy *phy,
9014                                    struct elink_params *params)
9015 {
9016         struct bxe_softc *sc = params->sc;
9017         uint32_t val, cmd;
9018         uint32_t fw_resp, fw_cmd_param;
9019         char vendor_name[ELINK_SFP_EEPROM_VENDOR_NAME_SIZE+1];
9020         char vendor_pn[ELINK_SFP_EEPROM_PART_NO_SIZE+1];
9021         phy->flags &= ~ELINK_FLAGS_SFP_NOT_APPROVED;
9022         val = REG_RD(sc, params->shmem_base +
9023                          offsetof(struct shmem_region, dev_info.
9024                                   port_feature_config[params->port].config));
9025         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9026             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
9027                 ELINK_DEBUG_P0(sc, "NOT enforcing module verification\n");
9028                 return ELINK_STATUS_OK;
9029         }
9030
9031         if (params->feature_config_flags &
9032             ELINK_FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
9033                 /* Use specific phy request */
9034                 cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
9035         } else if (params->feature_config_flags &
9036                    ELINK_FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
9037                 /* Use first phy request only in case of non-dual media*/
9038                 if (ELINK_DUAL_MEDIA(params)) {
9039                         ELINK_DEBUG_P0(sc,
9040                            "FW does not support OPT MDL verification\n");
9041                         return ELINK_STATUS_ERROR;
9042                 }
9043                 cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
9044         } else {
9045                 /* No support in OPT MDL detection */
9046                 ELINK_DEBUG_P0(sc,
9047                    "FW does not support OPT MDL verification\n");
9048                 return ELINK_STATUS_ERROR;
9049         }
9050
9051         fw_cmd_param = ELINK_FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
9052         fw_resp = elink_cb_fw_command(sc, cmd, fw_cmd_param);
9053         if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
9054                 ELINK_DEBUG_P0(sc, "Approved module\n");
9055                 return ELINK_STATUS_OK;
9056         }
9057
9058         /* Format the warning message */
9059         if (elink_read_sfp_module_eeprom(phy,
9060                                          params,
9061                                          ELINK_I2C_DEV_ADDR_A0,
9062                                          ELINK_SFP_EEPROM_VENDOR_NAME_ADDR,
9063                                          ELINK_SFP_EEPROM_VENDOR_NAME_SIZE,
9064                                          (uint8_t *)vendor_name))
9065                 vendor_name[0] = '\0';
9066         else
9067                 vendor_name[ELINK_SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
9068         if (elink_read_sfp_module_eeprom(phy,
9069                                          params,
9070                                          ELINK_I2C_DEV_ADDR_A0,
9071                                          ELINK_SFP_EEPROM_PART_NO_ADDR,
9072                                          ELINK_SFP_EEPROM_PART_NO_SIZE,
9073                                          (uint8_t *)vendor_pn))
9074                 vendor_pn[0] = '\0';
9075         else
9076                 vendor_pn[ELINK_SFP_EEPROM_PART_NO_SIZE] = '\0';
9077
9078         elink_cb_event_log(sc, ELINK_LOG_ID_UNQUAL_IO_MODULE, params->port, vendor_name, vendor_pn); // "Warning: Unqualified SFP+ module detected,"
9079                              // " Port %d from %s part number %s\n",
9080
9081         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
9082             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_WARNING_MSG)
9083                 phy->flags |= ELINK_FLAGS_SFP_NOT_APPROVED;
9084         return ELINK_STATUS_ERROR;
9085 }
9086
9087 static elink_status_t elink_wait_for_sfp_module_initialized(struct elink_phy *phy,
9088                                                  struct elink_params *params)
9089
9090 {
9091         uint8_t val;
9092         elink_status_t rc;
9093         struct bxe_softc *sc = params->sc;
9094         uint16_t timeout;
9095         /* Initialization time after hot-plug may take up to 300ms for
9096          * some phys type ( e.g. JDSU )
9097          */
9098
9099         for (timeout = 0; timeout < 60; timeout++) {
9100                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
9101                         rc = elink_warpcore_read_sfp_module_eeprom(
9102                                 phy, params, ELINK_I2C_DEV_ADDR_A0, 1, 1, &val,
9103                                 1);
9104                 else
9105                         rc = elink_read_sfp_module_eeprom(phy, params,
9106                                                           ELINK_I2C_DEV_ADDR_A0,
9107                                                           1, 1, &val);
9108                 if (rc == 0) {
9109                         ELINK_DEBUG_P1(sc,
9110                            "SFP+ module initialization took %d ms\n",
9111                            timeout * 5);
9112                         return ELINK_STATUS_OK;
9113                 }
9114                 DELAY(1000 * 5);
9115         }
9116         rc = elink_read_sfp_module_eeprom(phy, params, ELINK_I2C_DEV_ADDR_A0,
9117                                           1, 1, &val);
9118         return rc;
9119 }
9120
9121 static void elink_8727_power_module(struct bxe_softc *sc,
9122                                     struct elink_phy *phy,
9123                                     uint8_t is_power_up) {
9124         /* Make sure GPIOs are not using for LED mode */
9125         uint16_t val;
9126         /* In the GPIO register, bit 4 is use to determine if the GPIOs are
9127          * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
9128          * output
9129          * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0
9130          * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1
9131          * where the 1st bit is the over-current(only input), and 2nd bit is
9132          * for power( only output )
9133          *
9134          * In case of NOC feature is disabled and power is up, set GPIO control
9135          *  as input to enable listening of over-current indication
9136          */
9137         if (phy->flags & ELINK_FLAGS_NOC)
9138                 return;
9139         if (is_power_up)
9140                 val = (1<<4);
9141         else
9142                 /* Set GPIO control to OUTPUT, and set the power bit
9143                  * to according to the is_power_up
9144                  */
9145                 val = (1<<1);
9146
9147         elink_cl45_write(sc, phy,
9148                          MDIO_PMA_DEVAD,
9149                          MDIO_PMA_REG_8727_GPIO_CTRL,
9150                          val);
9151 }
9152
9153 static elink_status_t elink_8726_set_limiting_mode(struct bxe_softc *sc,
9154                                         struct elink_phy *phy,
9155                                         uint16_t edc_mode)
9156 {
9157         uint16_t cur_limiting_mode;
9158
9159         elink_cl45_read(sc, phy,
9160                         MDIO_PMA_DEVAD,
9161                         MDIO_PMA_REG_ROM_VER2,
9162                         &cur_limiting_mode);
9163         ELINK_DEBUG_P1(sc, "Current Limiting mode is 0x%x\n",
9164                  cur_limiting_mode);
9165
9166         if (edc_mode == ELINK_EDC_MODE_LIMITING) {
9167                 ELINK_DEBUG_P0(sc, "Setting LIMITING MODE\n");
9168                 elink_cl45_write(sc, phy,
9169                                  MDIO_PMA_DEVAD,
9170                                  MDIO_PMA_REG_ROM_VER2,
9171                                  ELINK_EDC_MODE_LIMITING);
9172         } else { /* LRM mode ( default )*/
9173
9174                 ELINK_DEBUG_P0(sc, "Setting LRM MODE\n");
9175
9176                 /* Changing to LRM mode takes quite few seconds. So do it only
9177                  * if current mode is limiting (default is LRM)
9178                  */
9179                 if (cur_limiting_mode != ELINK_EDC_MODE_LIMITING)
9180                         return ELINK_STATUS_OK;
9181
9182                 elink_cl45_write(sc, phy,
9183                                  MDIO_PMA_DEVAD,
9184                                  MDIO_PMA_REG_LRM_MODE,
9185                                  0);
9186                 elink_cl45_write(sc, phy,
9187                                  MDIO_PMA_DEVAD,
9188                                  MDIO_PMA_REG_ROM_VER2,
9189                                  0x128);
9190                 elink_cl45_write(sc, phy,
9191                                  MDIO_PMA_DEVAD,
9192                                  MDIO_PMA_REG_MISC_CTRL0,
9193                                  0x4008);
9194                 elink_cl45_write(sc, phy,
9195                                  MDIO_PMA_DEVAD,
9196                                  MDIO_PMA_REG_LRM_MODE,
9197                                  0xaaaa);
9198         }
9199         return ELINK_STATUS_OK;
9200 }
9201
9202 static elink_status_t elink_8727_set_limiting_mode(struct bxe_softc *sc,
9203                                         struct elink_phy *phy,
9204                                         uint16_t edc_mode)
9205 {
9206         uint16_t phy_identifier;
9207         uint16_t rom_ver2_val;
9208         elink_cl45_read(sc, phy,
9209                         MDIO_PMA_DEVAD,
9210                         MDIO_PMA_REG_PHY_IDENTIFIER,
9211                         &phy_identifier);
9212
9213         elink_cl45_write(sc, phy,
9214                          MDIO_PMA_DEVAD,
9215                          MDIO_PMA_REG_PHY_IDENTIFIER,
9216                          (phy_identifier & ~(1<<9)));
9217
9218         elink_cl45_read(sc, phy,
9219                         MDIO_PMA_DEVAD,
9220                         MDIO_PMA_REG_ROM_VER2,
9221                         &rom_ver2_val);
9222         /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
9223         elink_cl45_write(sc, phy,
9224                          MDIO_PMA_DEVAD,
9225                          MDIO_PMA_REG_ROM_VER2,
9226                          (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
9227
9228         elink_cl45_write(sc, phy,
9229                          MDIO_PMA_DEVAD,
9230                          MDIO_PMA_REG_PHY_IDENTIFIER,
9231                          (phy_identifier | (1<<9)));
9232
9233         return ELINK_STATUS_OK;
9234 }
9235
9236 static void elink_8727_specific_func(struct elink_phy *phy,
9237                                      struct elink_params *params,
9238                                      uint32_t action)
9239 {
9240         struct bxe_softc *sc = params->sc;
9241         uint16_t val;
9242         switch (action) {
9243         case ELINK_DISABLE_TX:
9244                 elink_sfp_set_transmitter(params, phy, 0);
9245                 break;
9246         case ELINK_ENABLE_TX:
9247                 if (!(phy->flags & ELINK_FLAGS_SFP_NOT_APPROVED))
9248                         elink_sfp_set_transmitter(params, phy, 1);
9249                 break;
9250         case ELINK_PHY_INIT:
9251                 elink_cl45_write(sc, phy,
9252                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9253                                  (1<<2) | (1<<5));
9254                 elink_cl45_write(sc, phy,
9255                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
9256                                  0);
9257                 elink_cl45_write(sc, phy,
9258                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x0006);
9259                 /* Make MOD_ABS give interrupt on change */
9260                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
9261                                 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
9262                                 &val);
9263                 val |= (1<<12);
9264                 if (phy->flags & ELINK_FLAGS_NOC)
9265                         val |= (3<<5);
9266                 /* Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
9267                  * status which reflect SFP+ module over-current
9268                  */
9269                 if (!(phy->flags & ELINK_FLAGS_NOC))
9270                         val &= 0xff8f; /* Reset bits 4-6 */
9271                 elink_cl45_write(sc, phy,
9272                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
9273                                  val);
9274                 break;
9275         default:
9276                 ELINK_DEBUG_P1(sc, "Function 0x%x not supported by 8727\n",
9277                    action);
9278                 return;
9279         }
9280 }
9281
9282 static void elink_set_e1e2_module_fault_led(struct elink_params *params,
9283                                            uint8_t gpio_mode)
9284 {
9285         struct bxe_softc *sc = params->sc;
9286
9287         uint32_t fault_led_gpio = REG_RD(sc, params->shmem_base +
9288                             offsetof(struct shmem_region,
9289                         dev_info.port_hw_config[params->port].sfp_ctrl)) &
9290                 PORT_HW_CFG_FAULT_MODULE_LED_MASK;
9291         switch (fault_led_gpio) {
9292         case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED:
9293                 return;
9294         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0:
9295         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1:
9296         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2:
9297         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3:
9298         {
9299                 uint8_t gpio_port = elink_get_gpio_port(params);
9300                 uint16_t gpio_pin = fault_led_gpio -
9301                         PORT_HW_CFG_FAULT_MODULE_LED_GPIO0;
9302                 ELINK_DEBUG_P3(sc, "Set fault module-detected led "
9303                                    "pin %x port %x mode %x\n",
9304                                gpio_pin, gpio_port, gpio_mode);
9305                 elink_cb_gpio_write(sc, gpio_pin, gpio_mode, gpio_port);
9306         }
9307         break;
9308         default:
9309                 ELINK_DEBUG_P1(sc, "Error: Invalid fault led mode 0x%x\n",
9310                                fault_led_gpio);
9311         }
9312 }
9313
9314 static void elink_set_e3_module_fault_led(struct elink_params *params,
9315                                           uint8_t gpio_mode)
9316 {
9317         uint32_t pin_cfg;
9318         uint8_t port = params->port;
9319         struct bxe_softc *sc = params->sc;
9320         pin_cfg = (REG_RD(sc, params->shmem_base +
9321                          offsetof(struct shmem_region,
9322                                   dev_info.port_hw_config[port].e3_sfp_ctrl)) &
9323                 PORT_HW_CFG_E3_FAULT_MDL_LED_MASK) >>
9324                 PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT;
9325         ELINK_DEBUG_P2(sc, "Setting Fault LED to %d using pin cfg %d\n",
9326                        gpio_mode, pin_cfg);
9327         elink_set_cfg_pin(sc, pin_cfg, gpio_mode);
9328 }
9329
9330 static void elink_set_sfp_module_fault_led(struct elink_params *params,
9331                                            uint8_t gpio_mode)
9332 {
9333         struct bxe_softc *sc = params->sc;
9334         ELINK_DEBUG_P1(sc, "Setting SFP+ module fault LED to %d\n", gpio_mode);
9335         if (CHIP_IS_E3(sc)) {
9336                 /* Low ==> if SFP+ module is supported otherwise
9337                  * High ==> if SFP+ module is not on the approved vendor list
9338                  */
9339                 elink_set_e3_module_fault_led(params, gpio_mode);
9340         } else
9341                 elink_set_e1e2_module_fault_led(params, gpio_mode);
9342 }
9343
9344 static void elink_warpcore_hw_reset(struct elink_phy *phy,
9345                                     struct elink_params *params)
9346 {
9347         struct bxe_softc *sc = params->sc;
9348         elink_warpcore_power_module(params, 0);
9349         /* Put Warpcore in low power mode */
9350         REG_WR(sc, MISC_REG_WC0_RESET, 0x0c0e);
9351
9352         /* Put LCPLL in low power mode */
9353         REG_WR(sc, MISC_REG_LCPLL_E40_PWRDWN, 1);
9354         REG_WR(sc, MISC_REG_LCPLL_E40_RESETB_ANA, 0);
9355         REG_WR(sc, MISC_REG_LCPLL_E40_RESETB_DIG, 0);
9356 }
9357
9358 static void elink_power_sfp_module(struct elink_params *params,
9359                                    struct elink_phy *phy,
9360                                    uint8_t power)
9361 {
9362         struct bxe_softc *sc = params->sc;
9363         ELINK_DEBUG_P1(sc, "Setting SFP+ power to %x\n", power);
9364
9365         switch (phy->type) {
9366         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
9367         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
9368                 elink_8727_power_module(params->sc, phy, power);
9369                 break;
9370         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
9371                 elink_warpcore_power_module(params, power);
9372                 break;
9373         default:
9374                 break;
9375         }
9376 }
9377 static void elink_warpcore_set_limiting_mode(struct elink_params *params,
9378                                              struct elink_phy *phy,
9379                                              uint16_t edc_mode)
9380 {
9381         uint16_t val = 0;
9382         uint16_t mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
9383         struct bxe_softc *sc = params->sc;
9384
9385         uint8_t lane = elink_get_warpcore_lane(phy, params);
9386         /* This is a global register which controls all lanes */
9387         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
9388                         MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
9389         val &= ~(0xf << (lane << 2));
9390
9391         switch (edc_mode) {
9392         case ELINK_EDC_MODE_LINEAR:
9393         case ELINK_EDC_MODE_LIMITING:
9394                 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
9395                 break;
9396         case ELINK_EDC_MODE_PASSIVE_DAC:
9397         case ELINK_EDC_MODE_ACTIVE_DAC:
9398                 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC;
9399                 break;
9400         default:
9401                 break;
9402         }
9403
9404         val |= (mode << (lane << 2));
9405         elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
9406                          MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, val);
9407         /* A must read */
9408         elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
9409                         MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
9410
9411         /* Restart microcode to re-read the new mode */
9412         elink_warpcore_reset_lane(sc, phy, 1);
9413         elink_warpcore_reset_lane(sc, phy, 0);
9414
9415 }
9416
9417 static void elink_set_limiting_mode(struct elink_params *params,
9418                                     struct elink_phy *phy,
9419                                     uint16_t edc_mode)
9420 {
9421         switch (phy->type) {
9422         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
9423                 elink_8726_set_limiting_mode(params->sc, phy, edc_mode);
9424                 break;
9425         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
9426         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
9427                 elink_8727_set_limiting_mode(params->sc, phy, edc_mode);
9428                 break;
9429         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
9430                 elink_warpcore_set_limiting_mode(params, phy, edc_mode);
9431                 break;
9432         }
9433 }
9434
9435 elink_status_t elink_sfp_module_detection(struct elink_phy *phy,
9436                                struct elink_params *params)
9437 {
9438         struct bxe_softc *sc = params->sc;
9439         uint16_t edc_mode;
9440         elink_status_t rc = ELINK_STATUS_OK;
9441
9442         uint32_t val = REG_RD(sc, params->shmem_base +
9443                              offsetof(struct shmem_region, dev_info.
9444                                      port_feature_config[params->port].config));
9445         /* Enabled transmitter by default */
9446         elink_sfp_set_transmitter(params, phy, 1);
9447         ELINK_DEBUG_P1(sc, "SFP+ module plugged in/out detected on port %d\n",
9448                  params->port);
9449         /* Power up module */
9450         elink_power_sfp_module(params, phy, 1);
9451         if (elink_get_edc_mode(phy, params, &edc_mode) != 0) {
9452                 ELINK_DEBUG_P0(sc, "Failed to get valid module type\n");
9453                 return ELINK_STATUS_ERROR;
9454         } else if (elink_verify_sfp_module(phy, params) != 0) {
9455                 /* Check SFP+ module compatibility */
9456                 ELINK_DEBUG_P0(sc, "Module verification failed!!\n");
9457                 rc = ELINK_STATUS_ERROR;
9458                 /* Turn on fault module-detected led */
9459                 elink_set_sfp_module_fault_led(params,
9460                                                MISC_REGISTERS_GPIO_HIGH);
9461
9462                 /* Check if need to power down the SFP+ module */
9463                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9464                      PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN) {
9465                         ELINK_DEBUG_P0(sc, "Shutdown SFP+ module!!\n");
9466                         elink_power_sfp_module(params, phy, 0);
9467                         return rc;
9468                 }
9469         } else {
9470                 /* Turn off fault module-detected led */
9471                 elink_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
9472         }
9473
9474         /* Check and set limiting mode / LRM mode on 8726. On 8727 it
9475          * is done automatically
9476          */
9477         elink_set_limiting_mode(params, phy, edc_mode);
9478
9479         /* Disable transmit for this module if the module is not approved, and
9480          * laser needs to be disabled.
9481          */
9482         if ((rc != 0) &&
9483             ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9484              PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER))
9485                 elink_sfp_set_transmitter(params, phy, 0);
9486
9487         return rc;
9488 }
9489
9490 void elink_handle_module_detect_int(struct elink_params *params)
9491 {
9492         struct bxe_softc *sc = params->sc;
9493         struct elink_phy *phy;
9494         uint32_t gpio_val;
9495         uint8_t gpio_num, gpio_port;
9496         if (CHIP_IS_E3(sc)) {
9497                 phy = &params->phy[ELINK_INT_PHY];
9498                 /* Always enable TX laser,will be disabled in case of fault */
9499                 elink_sfp_set_transmitter(params, phy, 1);
9500         } else {
9501                 phy = &params->phy[ELINK_EXT_PHY1];
9502         }
9503         if (elink_get_mod_abs_int_cfg(sc, params->chip_id, params->shmem_base,
9504                                       params->port, &gpio_num, &gpio_port) ==
9505             ELINK_STATUS_ERROR) {
9506                 ELINK_DEBUG_P0(sc, "Failed to get MOD_ABS interrupt config\n");
9507                 return;
9508         }
9509
9510         /* Set valid module led off */
9511         elink_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH);
9512
9513         /* Get current gpio val reflecting module plugged in / out*/
9514         gpio_val = elink_cb_gpio_read(sc, gpio_num, gpio_port);
9515
9516         /* Call the handling function in case module is detected */
9517         if (gpio_val == 0) {
9518                 elink_set_mdio_emac_per_phy(sc, params);
9519                 elink_set_aer_mmd(params, phy);
9520
9521                 elink_power_sfp_module(params, phy, 1);
9522                 elink_cb_gpio_int_write(sc, gpio_num,
9523                                    MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
9524                                    gpio_port);
9525                 if (elink_wait_for_sfp_module_initialized(phy, params) == 0) {
9526                         elink_sfp_module_detection(phy, params);
9527                         if (CHIP_IS_E3(sc)) {
9528                                 uint16_t rx_tx_in_reset;
9529                                 /* In case WC is out of reset, reconfigure the
9530                                  * link speed while taking into account 1G
9531                                  * module limitation.
9532                                  */
9533                                 elink_cl45_read(sc, phy,
9534                                                 MDIO_WC_DEVAD,
9535                                                 MDIO_WC_REG_DIGITAL5_MISC6,
9536                                                 &rx_tx_in_reset);
9537                                 if ((!rx_tx_in_reset) &&
9538                                     (params->link_flags &
9539                                      ELINK_PHY_INITIALIZED)) {
9540                                         elink_warpcore_reset_lane(sc, phy, 1);
9541                                         elink_warpcore_config_sfi(phy, params);
9542                                         elink_warpcore_reset_lane(sc, phy, 0);
9543                                 }
9544                         }
9545                 } else {
9546                         ELINK_DEBUG_P0(sc, "SFP+ module is not initialized\n");
9547                 }
9548         } else {
9549                 elink_cb_gpio_int_write(sc, gpio_num,
9550                                    MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
9551                                    gpio_port);
9552                 /* Module was plugged out.
9553                  * Disable transmit for this module
9554                  */
9555                 phy->media_type = ELINK_ETH_PHY_NOT_PRESENT;
9556         }
9557 }
9558
9559 /******************************************************************/
9560 /*              Used by 8706 and 8727                             */
9561 /******************************************************************/
9562 static void elink_sfp_mask_fault(struct bxe_softc *sc,
9563                                  struct elink_phy *phy,
9564                                  uint16_t alarm_status_offset,
9565                                  uint16_t alarm_ctrl_offset)
9566 {
9567         uint16_t alarm_status, val;
9568         elink_cl45_read(sc, phy,
9569                         MDIO_PMA_DEVAD, alarm_status_offset,
9570                         &alarm_status);
9571         elink_cl45_read(sc, phy,
9572                         MDIO_PMA_DEVAD, alarm_status_offset,
9573                         &alarm_status);
9574         /* Mask or enable the fault event. */
9575         elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, &val);
9576         if (alarm_status & (1<<0))
9577                 val &= ~(1<<0);
9578         else
9579                 val |= (1<<0);
9580         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, val);
9581 }
9582 /******************************************************************/
9583 /*              common BCM8706/BCM8726 PHY SECTION                */
9584 /******************************************************************/
9585 static uint8_t elink_8706_8726_read_status(struct elink_phy *phy,
9586                                       struct elink_params *params,
9587                                       struct elink_vars *vars)
9588 {
9589         uint8_t link_up = 0;
9590         uint16_t val1, val2, rx_sd, pcs_status;
9591         struct bxe_softc *sc = params->sc;
9592         ELINK_DEBUG_P0(sc, "XGXS 8706/8726\n");
9593         /* Clear RX Alarm*/
9594         elink_cl45_read(sc, phy,
9595                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
9596
9597         elink_sfp_mask_fault(sc, phy, MDIO_PMA_LASI_TXSTAT,
9598                              MDIO_PMA_LASI_TXCTRL);
9599
9600         /* Clear LASI indication*/
9601         elink_cl45_read(sc, phy,
9602                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
9603         elink_cl45_read(sc, phy,
9604                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
9605         ELINK_DEBUG_P2(sc, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
9606
9607         elink_cl45_read(sc, phy,
9608                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
9609         elink_cl45_read(sc, phy,
9610                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
9611         elink_cl45_read(sc, phy,
9612                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
9613         elink_cl45_read(sc, phy,
9614                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
9615
9616         ELINK_DEBUG_P3(sc, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
9617                         " link_status 0x%x\n", rx_sd, pcs_status, val2);
9618         /* Link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
9619          * are set, or if the autoneg bit 1 is set
9620          */
9621         link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
9622         if (link_up) {
9623                 if (val2 & (1<<1))
9624                         vars->line_speed = ELINK_SPEED_1000;
9625                 else
9626                         vars->line_speed = ELINK_SPEED_10000;
9627                 elink_ext_phy_resolve_fc(phy, params, vars);
9628                 vars->duplex = DUPLEX_FULL;
9629         }
9630
9631         /* Capture 10G link fault. Read twice to clear stale value. */
9632         if (vars->line_speed == ELINK_SPEED_10000) {
9633                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
9634                             MDIO_PMA_LASI_TXSTAT, &val1);
9635                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
9636                             MDIO_PMA_LASI_TXSTAT, &val1);
9637                 if (val1 & (1<<0))
9638                         vars->fault_detected = 1;
9639         }
9640
9641         return link_up;
9642 }
9643
9644 /******************************************************************/
9645 /*                      BCM8706 PHY SECTION                       */
9646 /******************************************************************/
9647 static uint8_t elink_8706_config_init(struct elink_phy *phy,
9648                                  struct elink_params *params,
9649                                  struct elink_vars *vars)
9650 {
9651         uint32_t tx_en_mode;
9652         uint16_t cnt, val, tmp1;
9653         struct bxe_softc *sc = params->sc;
9654
9655         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
9656                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
9657         /* HW reset */
9658         elink_ext_phy_hw_reset(sc, params->port);
9659         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
9660         elink_wait_reset_complete(sc, phy, params);
9661
9662         /* Wait until fw is loaded */
9663         for (cnt = 0; cnt < 100; cnt++) {
9664                 elink_cl45_read(sc, phy,
9665                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
9666                 if (val)
9667                         break;
9668                 DELAY(1000 * 10);
9669         }
9670         ELINK_DEBUG_P1(sc, "XGXS 8706 is initialized after %d ms\n", cnt);
9671         if ((params->feature_config_flags &
9672              ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
9673                 uint8_t i;
9674                 uint16_t reg;
9675                 for (i = 0; i < 4; i++) {
9676                         reg = MDIO_XS_8706_REG_BANK_RX0 +
9677                                 i*(MDIO_XS_8706_REG_BANK_RX1 -
9678                                    MDIO_XS_8706_REG_BANK_RX0);
9679                         elink_cl45_read(sc, phy, MDIO_XS_DEVAD, reg, &val);
9680                         /* Clear first 3 bits of the control */
9681                         val &= ~0x7;
9682                         /* Set control bits according to configuration */
9683                         val |= (phy->rx_preemphasis[i] & 0x7);
9684                         ELINK_DEBUG_P2(sc, "Setting RX Equalizer to BCM8706"
9685                                    " reg 0x%x <-- val 0x%x\n", reg, val);
9686                         elink_cl45_write(sc, phy, MDIO_XS_DEVAD, reg, val);
9687                 }
9688         }
9689         /* Force speed */
9690         if (phy->req_line_speed == ELINK_SPEED_10000) {
9691                 ELINK_DEBUG_P0(sc, "XGXS 8706 force 10Gbps\n");
9692
9693                 elink_cl45_write(sc, phy,
9694                                  MDIO_PMA_DEVAD,
9695                                  MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
9696                 elink_cl45_write(sc, phy,
9697                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
9698                                  0);
9699                 /* Arm LASI for link and Tx fault. */
9700                 elink_cl45_write(sc, phy,
9701                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 3);
9702         } else {
9703                 /* Force 1Gbps using autoneg with 1G advertisement */
9704
9705                 /* Allow CL37 through CL73 */
9706                 ELINK_DEBUG_P0(sc, "XGXS 8706 AutoNeg\n");
9707                 elink_cl45_write(sc, phy,
9708                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
9709
9710                 /* Enable Full-Duplex advertisement on CL37 */
9711                 elink_cl45_write(sc, phy,
9712                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
9713                 /* Enable CL37 AN */
9714                 elink_cl45_write(sc, phy,
9715                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
9716                 /* 1G support */
9717                 elink_cl45_write(sc, phy,
9718                                  MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
9719
9720                 /* Enable clause 73 AN */
9721                 elink_cl45_write(sc, phy,
9722                                  MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
9723                 elink_cl45_write(sc, phy,
9724                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9725                                  0x0400);
9726                 elink_cl45_write(sc, phy,
9727                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
9728                                  0x0004);
9729         }
9730         elink_save_bcm_spirom_ver(sc, phy, params->port);
9731
9732         /* If TX Laser is controlled by GPIO_0, do not let PHY go into low
9733          * power mode, if TX Laser is disabled
9734          */
9735
9736         tx_en_mode = REG_RD(sc, params->shmem_base +
9737                             offsetof(struct shmem_region,
9738                                 dev_info.port_hw_config[params->port].sfp_ctrl))
9739                         & PORT_HW_CFG_TX_LASER_MASK;
9740
9741         if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
9742                 ELINK_DEBUG_P0(sc, "Enabling TXONOFF_PWRDN_DIS\n");
9743                 elink_cl45_read(sc, phy,
9744                         MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1);
9745                 tmp1 |= 0x1;
9746                 elink_cl45_write(sc, phy,
9747                         MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1);
9748         }
9749
9750         return ELINK_STATUS_OK;
9751 }
9752
9753 static elink_status_t elink_8706_read_status(struct elink_phy *phy,
9754                                   struct elink_params *params,
9755                                   struct elink_vars *vars)
9756 {
9757         return elink_8706_8726_read_status(phy, params, vars);
9758 }
9759
9760 /******************************************************************/
9761 /*                      BCM8726 PHY SECTION                       */
9762 /******************************************************************/
9763 static void elink_8726_config_loopback(struct elink_phy *phy,
9764                                        struct elink_params *params)
9765 {
9766         struct bxe_softc *sc = params->sc;
9767         ELINK_DEBUG_P0(sc, "PMA/PMD ext_phy_loopback: 8726\n");
9768         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
9769 }
9770
9771 static void elink_8726_external_rom_boot(struct elink_phy *phy,
9772                                          struct elink_params *params)
9773 {
9774         struct bxe_softc *sc = params->sc;
9775         /* Need to wait 100ms after reset */
9776         DELAY(1000 * 100);
9777
9778         /* Micro controller re-boot */
9779         elink_cl45_write(sc, phy,
9780                          MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
9781
9782         /* Set soft reset */
9783         elink_cl45_write(sc, phy,
9784                          MDIO_PMA_DEVAD,
9785                          MDIO_PMA_REG_GEN_CTRL,
9786                          MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
9787
9788         elink_cl45_write(sc, phy,
9789                          MDIO_PMA_DEVAD,
9790                          MDIO_PMA_REG_MISC_CTRL1, 0x0001);
9791
9792         elink_cl45_write(sc, phy,
9793                          MDIO_PMA_DEVAD,
9794                          MDIO_PMA_REG_GEN_CTRL,
9795                          MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
9796
9797         /* Wait for 150ms for microcode load */
9798         DELAY(1000 * 150);
9799
9800         /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
9801         elink_cl45_write(sc, phy,
9802                          MDIO_PMA_DEVAD,
9803                          MDIO_PMA_REG_MISC_CTRL1, 0x0000);
9804
9805         DELAY(1000 * 200);
9806         elink_save_bcm_spirom_ver(sc, phy, params->port);
9807 }
9808
9809 static uint8_t elink_8726_read_status(struct elink_phy *phy,
9810                                  struct elink_params *params,
9811                                  struct elink_vars *vars)
9812 {
9813         struct bxe_softc *sc = params->sc;
9814         uint16_t val1;
9815         uint8_t link_up = elink_8706_8726_read_status(phy, params, vars);
9816         if (link_up) {
9817                 elink_cl45_read(sc, phy,
9818                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
9819                                 &val1);
9820                 if (val1 & (1<<15)) {
9821                         ELINK_DEBUG_P0(sc, "Tx is disabled\n");
9822                         link_up = 0;
9823                         vars->line_speed = 0;
9824                 }
9825         }
9826         return link_up;
9827 }
9828
9829
9830 static elink_status_t elink_8726_config_init(struct elink_phy *phy,
9831                                   struct elink_params *params,
9832                                   struct elink_vars *vars)
9833 {
9834         struct bxe_softc *sc = params->sc;
9835         ELINK_DEBUG_P0(sc, "Initializing BCM8726\n");
9836
9837         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
9838         elink_wait_reset_complete(sc, phy, params);
9839
9840         elink_8726_external_rom_boot(phy, params);
9841
9842         /* Need to call module detected on initialization since the module
9843          * detection triggered by actual module insertion might occur before
9844          * driver is loaded, and when driver is loaded, it reset all
9845          * registers, including the transmitter
9846          */
9847         elink_sfp_module_detection(phy, params);
9848
9849         if (phy->req_line_speed == ELINK_SPEED_1000) {
9850                 ELINK_DEBUG_P0(sc, "Setting 1G force\n");
9851                 elink_cl45_write(sc, phy,
9852                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
9853                 elink_cl45_write(sc, phy,
9854                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
9855                 elink_cl45_write(sc, phy,
9856                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x5);
9857                 elink_cl45_write(sc, phy,
9858                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9859                                  0x400);
9860         } else if ((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
9861                    (phy->speed_cap_mask &
9862                       PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
9863                    ((phy->speed_cap_mask &
9864                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
9865                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
9866                 ELINK_DEBUG_P0(sc, "Setting 1G clause37\n");
9867                 /* Set Flow control */
9868                 elink_ext_phy_set_pause(params, phy, vars);
9869                 elink_cl45_write(sc, phy,
9870                                  MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
9871                 elink_cl45_write(sc, phy,
9872                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
9873                 elink_cl45_write(sc, phy,
9874                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
9875                 elink_cl45_write(sc, phy,
9876                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
9877                 elink_cl45_write(sc, phy,
9878                                 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
9879                 /* Enable RX-ALARM control to receive interrupt for 1G speed
9880                  * change
9881                  */
9882                 elink_cl45_write(sc, phy,
9883                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x4);
9884                 elink_cl45_write(sc, phy,
9885                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9886                                  0x400);
9887
9888         } else { /* Default 10G. Set only LASI control */
9889                 elink_cl45_write(sc, phy,
9890                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 1);
9891         }
9892
9893         /* Set TX PreEmphasis if needed */
9894         if ((params->feature_config_flags &
9895              ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
9896                 ELINK_DEBUG_P2(sc,
9897                    "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
9898                          phy->tx_preemphasis[0],
9899                          phy->tx_preemphasis[1]);
9900                 elink_cl45_write(sc, phy,
9901                                  MDIO_PMA_DEVAD,
9902                                  MDIO_PMA_REG_8726_TX_CTRL1,
9903                                  phy->tx_preemphasis[0]);
9904
9905                 elink_cl45_write(sc, phy,
9906                                  MDIO_PMA_DEVAD,
9907                                  MDIO_PMA_REG_8726_TX_CTRL2,
9908                                  phy->tx_preemphasis[1]);
9909         }
9910
9911         return ELINK_STATUS_OK;
9912
9913 }
9914
9915 static void elink_8726_link_reset(struct elink_phy *phy,
9916                                   struct elink_params *params)
9917 {
9918         struct bxe_softc *sc = params->sc;
9919         ELINK_DEBUG_P1(sc, "elink_8726_link_reset port %d\n", params->port);
9920         /* Set serial boot control for external load */
9921         elink_cl45_write(sc, phy,
9922                          MDIO_PMA_DEVAD,
9923                          MDIO_PMA_REG_GEN_CTRL, 0x0001);
9924 }
9925
9926 /******************************************************************/
9927 /*                      BCM8727 PHY SECTION                       */
9928 /******************************************************************/
9929
9930 static void elink_8727_set_link_led(struct elink_phy *phy,
9931                                     struct elink_params *params, uint8_t mode)
9932 {
9933         struct bxe_softc *sc = params->sc;
9934         uint16_t led_mode_bitmask = 0;
9935         uint16_t gpio_pins_bitmask = 0;
9936         uint16_t val;
9937         /* Only NOC flavor requires to set the LED specifically */
9938         if (!(phy->flags & ELINK_FLAGS_NOC))
9939                 return;
9940         switch (mode) {
9941         case ELINK_LED_MODE_FRONT_PANEL_OFF:
9942         case ELINK_LED_MODE_OFF:
9943                 led_mode_bitmask = 0;
9944                 gpio_pins_bitmask = 0x03;
9945                 break;
9946         case ELINK_LED_MODE_ON:
9947                 led_mode_bitmask = 0;
9948                 gpio_pins_bitmask = 0x02;
9949                 break;
9950         case ELINK_LED_MODE_OPER:
9951                 led_mode_bitmask = 0x60;
9952                 gpio_pins_bitmask = 0x11;
9953                 break;
9954         }
9955         elink_cl45_read(sc, phy,
9956                         MDIO_PMA_DEVAD,
9957                         MDIO_PMA_REG_8727_PCS_OPT_CTRL,
9958                         &val);
9959         val &= 0xff8f;
9960         val |= led_mode_bitmask;
9961         elink_cl45_write(sc, phy,
9962                          MDIO_PMA_DEVAD,
9963                          MDIO_PMA_REG_8727_PCS_OPT_CTRL,
9964                          val);
9965         elink_cl45_read(sc, phy,
9966                         MDIO_PMA_DEVAD,
9967                         MDIO_PMA_REG_8727_GPIO_CTRL,
9968                         &val);
9969         val &= 0xffe0;
9970         val |= gpio_pins_bitmask;
9971         elink_cl45_write(sc, phy,
9972                          MDIO_PMA_DEVAD,
9973                          MDIO_PMA_REG_8727_GPIO_CTRL,
9974                          val);
9975 }
9976 static void elink_8727_hw_reset(struct elink_phy *phy,
9977                                 struct elink_params *params) {
9978         uint32_t swap_val, swap_override;
9979         uint8_t port;
9980         /* The PHY reset is controlled by GPIO 1. Fake the port number
9981          * to cancel the swap done in set_gpio()
9982          */
9983         struct bxe_softc *sc = params->sc;
9984         swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
9985         swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
9986         port = (swap_val && swap_override) ^ 1;
9987         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_1,
9988                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
9989 }
9990
9991 static void elink_8727_config_speed(struct elink_phy *phy,
9992                                     struct elink_params *params)
9993 {
9994         struct bxe_softc *sc = params->sc;
9995         uint16_t tmp1, val;
9996         /* Set option 1G speed */
9997         if ((phy->req_line_speed == ELINK_SPEED_1000) ||
9998             (phy->media_type == ELINK_ETH_PHY_SFP_1G_FIBER)) {
9999                 ELINK_DEBUG_P0(sc, "Setting 1G force\n");
10000                 elink_cl45_write(sc, phy,
10001                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
10002                 elink_cl45_write(sc, phy,
10003                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
10004                 elink_cl45_read(sc, phy,
10005                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
10006                 ELINK_DEBUG_P1(sc, "1.7 = 0x%x\n", tmp1);
10007                 /* Power down the XAUI until link is up in case of dual-media
10008                  * and 1G
10009                  */
10010                 if (ELINK_DUAL_MEDIA(params)) {
10011                         elink_cl45_read(sc, phy,
10012                                         MDIO_PMA_DEVAD,
10013                                         MDIO_PMA_REG_8727_PCS_GP, &val);
10014                         val |= (3<<10);
10015                         elink_cl45_write(sc, phy,
10016                                          MDIO_PMA_DEVAD,
10017                                          MDIO_PMA_REG_8727_PCS_GP, val);
10018                 }
10019         } else if ((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10020                    ((phy->speed_cap_mask &
10021                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
10022                    ((phy->speed_cap_mask &
10023                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
10024                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
10025
10026                 ELINK_DEBUG_P0(sc, "Setting 1G clause37\n");
10027                 elink_cl45_write(sc, phy,
10028                                  MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
10029                 elink_cl45_write(sc, phy,
10030                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
10031         } else {
10032                 /* Since the 8727 has only single reset pin, need to set the 10G
10033                  * registers although it is default
10034                  */
10035                 elink_cl45_write(sc, phy,
10036                                  MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
10037                                  0x0020);
10038                 elink_cl45_write(sc, phy,
10039                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
10040                 elink_cl45_write(sc, phy,
10041                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
10042                 elink_cl45_write(sc, phy,
10043                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
10044                                  0x0008);
10045         }
10046 }
10047
10048 static elink_status_t elink_8727_config_init(struct elink_phy *phy,
10049                                   struct elink_params *params,
10050                                   struct elink_vars *vars)
10051 {
10052         uint32_t tx_en_mode;
10053         uint16_t tmp1, mod_abs, tmp2;
10054         struct bxe_softc *sc = params->sc;
10055         /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
10056
10057         elink_wait_reset_complete(sc, phy, params);
10058
10059         ELINK_DEBUG_P0(sc, "Initializing BCM8727\n");
10060
10061         elink_8727_specific_func(phy, params, ELINK_PHY_INIT);
10062         /* Initially configure MOD_ABS to interrupt when module is
10063          * presence( bit 8)
10064          */
10065         elink_cl45_read(sc, phy,
10066                         MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
10067         /* Set EDC off by setting OPTXLOS signal input to low (bit 9).
10068          * When the EDC is off it locks onto a reference clock and avoids
10069          * becoming 'lost'
10070          */
10071         mod_abs &= ~(1<<8);
10072         if (!(phy->flags & ELINK_FLAGS_NOC))
10073                 mod_abs &= ~(1<<9);
10074         elink_cl45_write(sc, phy,
10075                          MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
10076
10077         /* Enable/Disable PHY transmitter output */
10078         elink_set_disable_pmd_transmit(params, phy, 0);
10079
10080         elink_8727_power_module(sc, phy, 1);
10081
10082         elink_cl45_read(sc, phy,
10083                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
10084
10085         elink_cl45_read(sc, phy,
10086                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
10087
10088         elink_8727_config_speed(phy, params);
10089
10090
10091         /* Set TX PreEmphasis if needed */
10092         if ((params->feature_config_flags &
10093              ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
10094                 ELINK_DEBUG_P2(sc, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
10095                            phy->tx_preemphasis[0],
10096                            phy->tx_preemphasis[1]);
10097                 elink_cl45_write(sc, phy,
10098                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
10099                                  phy->tx_preemphasis[0]);
10100
10101                 elink_cl45_write(sc, phy,
10102                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
10103                                  phy->tx_preemphasis[1]);
10104         }
10105
10106         /* If TX Laser is controlled by GPIO_0, do not let PHY go into low
10107          * power mode, if TX Laser is disabled
10108          */
10109         tx_en_mode = REG_RD(sc, params->shmem_base +
10110                             offsetof(struct shmem_region,
10111                                 dev_info.port_hw_config[params->port].sfp_ctrl))
10112                         & PORT_HW_CFG_TX_LASER_MASK;
10113
10114         if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
10115
10116                 ELINK_DEBUG_P0(sc, "Enabling TXONOFF_PWRDN_DIS\n");
10117                 elink_cl45_read(sc, phy,
10118                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2);
10119                 tmp2 |= 0x1000;
10120                 tmp2 &= 0xFFEF;
10121                 elink_cl45_write(sc, phy,
10122                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
10123                 elink_cl45_read(sc, phy,
10124                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
10125                                 &tmp2);
10126                 elink_cl45_write(sc, phy,
10127                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
10128                                  (tmp2 & 0x7fff));
10129         }
10130
10131         return ELINK_STATUS_OK;
10132 }
10133
10134 static void elink_8727_handle_mod_abs(struct elink_phy *phy,
10135                                       struct elink_params *params)
10136 {
10137         struct bxe_softc *sc = params->sc;
10138         uint16_t mod_abs, rx_alarm_status;
10139         uint32_t val = REG_RD(sc, params->shmem_base +
10140                              offsetof(struct shmem_region, dev_info.
10141                                       port_feature_config[params->port].
10142                                       config));
10143         elink_cl45_read(sc, phy,
10144                         MDIO_PMA_DEVAD,
10145                         MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
10146         if (mod_abs & (1<<8)) {
10147
10148                 /* Module is absent */
10149                 ELINK_DEBUG_P0(sc,
10150                    "MOD_ABS indication show module is absent\n");
10151                 phy->media_type = ELINK_ETH_PHY_NOT_PRESENT;
10152                 /* 1. Set mod_abs to detect next module
10153                  *    presence event
10154                  * 2. Set EDC off by setting OPTXLOS signal input to low
10155                  *    (bit 9).
10156                  *    When the EDC is off it locks onto a reference clock and
10157                  *    avoids becoming 'lost'.
10158                  */
10159                 mod_abs &= ~(1<<8);
10160                 if (!(phy->flags & ELINK_FLAGS_NOC))
10161                         mod_abs &= ~(1<<9);
10162                 elink_cl45_write(sc, phy,
10163                                  MDIO_PMA_DEVAD,
10164                                  MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
10165
10166                 /* Clear RX alarm since it stays up as long as
10167                  * the mod_abs wasn't changed
10168                  */
10169                 elink_cl45_read(sc, phy,
10170                                 MDIO_PMA_DEVAD,
10171                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
10172
10173         } else {
10174                 /* Module is present */
10175                 ELINK_DEBUG_P0(sc,
10176                    "MOD_ABS indication show module is present\n");
10177                 /* First disable transmitter, and if the module is ok, the
10178                  * module_detection will enable it
10179                  * 1. Set mod_abs to detect next module absent event ( bit 8)
10180                  * 2. Restore the default polarity of the OPRXLOS signal and
10181                  * this signal will then correctly indicate the presence or
10182                  * absence of the Rx signal. (bit 9)
10183                  */
10184                 mod_abs |= (1<<8);
10185                 if (!(phy->flags & ELINK_FLAGS_NOC))
10186                         mod_abs |= (1<<9);
10187                 elink_cl45_write(sc, phy,
10188                                  MDIO_PMA_DEVAD,
10189                                  MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
10190
10191                 /* Clear RX alarm since it stays up as long as the mod_abs
10192                  * wasn't changed. This is need to be done before calling the
10193                  * module detection, otherwise it will clear* the link update
10194                  * alarm
10195                  */
10196                 elink_cl45_read(sc, phy,
10197                                 MDIO_PMA_DEVAD,
10198                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
10199
10200
10201                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
10202                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
10203                         elink_sfp_set_transmitter(params, phy, 0);
10204
10205                 if (elink_wait_for_sfp_module_initialized(phy, params) == 0)
10206                         elink_sfp_module_detection(phy, params);
10207                 else
10208                         ELINK_DEBUG_P0(sc, "SFP+ module is not initialized\n");
10209
10210                 /* Reconfigure link speed based on module type limitations */
10211                 elink_8727_config_speed(phy, params);
10212         }
10213
10214         ELINK_DEBUG_P1(sc, "8727 RX_ALARM_STATUS 0x%x\n",
10215                    rx_alarm_status);
10216         /* No need to check link status in case of module plugged in/out */
10217 }
10218
10219 static uint8_t elink_8727_read_status(struct elink_phy *phy,
10220                                  struct elink_params *params,
10221                                  struct elink_vars *vars)
10222
10223 {
10224         struct bxe_softc *sc = params->sc;
10225         uint8_t link_up = 0, oc_port = params->port;
10226         uint16_t link_status = 0;
10227         uint16_t rx_alarm_status, lasi_ctrl, val1;
10228
10229         /* If PHY is not initialized, do not check link status */
10230         elink_cl45_read(sc, phy,
10231                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
10232                         &lasi_ctrl);
10233         if (!lasi_ctrl)
10234                 return 0;
10235
10236         /* Check the LASI on Rx */
10237         elink_cl45_read(sc, phy,
10238                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT,
10239                         &rx_alarm_status);
10240         vars->line_speed = 0;
10241         ELINK_DEBUG_P1(sc, "8727 RX_ALARM_STATUS  0x%x\n", rx_alarm_status);
10242
10243         elink_sfp_mask_fault(sc, phy, MDIO_PMA_LASI_TXSTAT,
10244                              MDIO_PMA_LASI_TXCTRL);
10245
10246         elink_cl45_read(sc, phy,
10247                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
10248
10249         ELINK_DEBUG_P1(sc, "8727 LASI status 0x%x\n", val1);
10250
10251         /* Clear MSG-OUT */
10252         elink_cl45_read(sc, phy,
10253                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
10254
10255         /* If a module is present and there is need to check
10256          * for over current
10257          */
10258         if (!(phy->flags & ELINK_FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
10259                 /* Check over-current using 8727 GPIO0 input*/
10260                 elink_cl45_read(sc, phy,
10261                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
10262                                 &val1);
10263
10264                 if ((val1 & (1<<8)) == 0) {
10265                         if (!CHIP_IS_E1x(sc))
10266                                 oc_port = SC_PATH(sc) + (params->port << 1);
10267                         ELINK_DEBUG_P1(sc,
10268                            "8727 Power fault has been detected on port %d\n",
10269                            oc_port);
10270                         elink_cb_event_log(sc, ELINK_LOG_ID_OVER_CURRENT, oc_port); //"Error: Power fault on Port %d has "
10271                                           //  "been detected and the power to "
10272                                           //  "that SFP+ module has been removed "
10273                                           //  "to prevent failure of the card. "
10274                                           //  "Please remove the SFP+ module and "
10275                                           //  "restart the system to clear this "
10276                                           //  "error.\n",
10277                         /* Disable all RX_ALARMs except for mod_abs */
10278                         elink_cl45_write(sc, phy,
10279                                          MDIO_PMA_DEVAD,
10280                                          MDIO_PMA_LASI_RXCTRL, (1<<5));
10281
10282                         elink_cl45_read(sc, phy,
10283                                         MDIO_PMA_DEVAD,
10284                                         MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
10285                         /* Wait for module_absent_event */
10286                         val1 |= (1<<8);
10287                         elink_cl45_write(sc, phy,
10288                                          MDIO_PMA_DEVAD,
10289                                          MDIO_PMA_REG_PHY_IDENTIFIER, val1);
10290                         /* Clear RX alarm */
10291                         elink_cl45_read(sc, phy,
10292                                 MDIO_PMA_DEVAD,
10293                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
10294                         elink_8727_power_module(params->sc, phy, 0);
10295                         return 0;
10296                 }
10297         } /* Over current check */
10298
10299         /* When module absent bit is set, check module */
10300         if (rx_alarm_status & (1<<5)) {
10301                 elink_8727_handle_mod_abs(phy, params);
10302                 /* Enable all mod_abs and link detection bits */
10303                 elink_cl45_write(sc, phy,
10304                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
10305                                  ((1<<5) | (1<<2)));
10306         }
10307
10308         if (!(phy->flags & ELINK_FLAGS_SFP_NOT_APPROVED)) {
10309                 ELINK_DEBUG_P0(sc, "Enabling 8727 TX laser\n");
10310                 elink_sfp_set_transmitter(params, phy, 1);
10311         } else {
10312                 ELINK_DEBUG_P0(sc, "Tx is disabled\n");
10313                 return 0;
10314         }
10315
10316         elink_cl45_read(sc, phy,
10317                         MDIO_PMA_DEVAD,
10318                         MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
10319
10320         /* Bits 0..2 --> speed detected,
10321          * Bits 13..15--> link is down
10322          */
10323         if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
10324                 link_up = 1;
10325                 vars->line_speed = ELINK_SPEED_10000;
10326                 ELINK_DEBUG_P1(sc, "port %x: External link up in 10G\n",
10327                            params->port);
10328         } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
10329                 link_up = 1;
10330                 vars->line_speed = ELINK_SPEED_1000;
10331                 ELINK_DEBUG_P1(sc, "port %x: External link up in 1G\n",
10332                            params->port);
10333         } else {
10334                 link_up = 0;
10335                 ELINK_DEBUG_P1(sc, "port %x: External link is down\n",
10336                            params->port);
10337         }
10338
10339         /* Capture 10G link fault. */
10340         if (vars->line_speed == ELINK_SPEED_10000) {
10341                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
10342                             MDIO_PMA_LASI_TXSTAT, &val1);
10343
10344                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD,
10345                             MDIO_PMA_LASI_TXSTAT, &val1);
10346
10347                 if (val1 & (1<<0)) {
10348                         vars->fault_detected = 1;
10349                 }
10350         }
10351
10352         if (link_up) {
10353                 elink_ext_phy_resolve_fc(phy, params, vars);
10354                 vars->duplex = DUPLEX_FULL;
10355                 ELINK_DEBUG_P1(sc, "duplex = 0x%x\n", vars->duplex);
10356         }
10357
10358         if ((ELINK_DUAL_MEDIA(params)) &&
10359             (phy->req_line_speed == ELINK_SPEED_1000)) {
10360                 elink_cl45_read(sc, phy,
10361                                 MDIO_PMA_DEVAD,
10362                                 MDIO_PMA_REG_8727_PCS_GP, &val1);
10363                 /* In case of dual-media board and 1G, power up the XAUI side,
10364                  * otherwise power it down. For 10G it is done automatically
10365                  */
10366                 if (link_up)
10367                         val1 &= ~(3<<10);
10368                 else
10369                         val1 |= (3<<10);
10370                 elink_cl45_write(sc, phy,
10371                                  MDIO_PMA_DEVAD,
10372                                  MDIO_PMA_REG_8727_PCS_GP, val1);
10373         }
10374         return link_up;
10375 }
10376
10377 static void elink_8727_link_reset(struct elink_phy *phy,
10378                                   struct elink_params *params)
10379 {
10380         struct bxe_softc *sc = params->sc;
10381
10382         /* Enable/Disable PHY transmitter output */
10383         elink_set_disable_pmd_transmit(params, phy, 1);
10384
10385         /* Disable Transmitter */
10386         elink_sfp_set_transmitter(params, phy, 0);
10387         /* Clear LASI */
10388         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0);
10389
10390 }
10391
10392 /******************************************************************/
10393 /*              BCM8481/BCM84823/BCM84833 PHY SECTION             */
10394 /******************************************************************/
10395 static void elink_save_848xx_spirom_version(struct elink_phy *phy,
10396                                             struct bxe_softc *sc,
10397                                             uint8_t port)
10398 {
10399         uint16_t val, fw_ver2, cnt, i;
10400         static struct elink_reg_set reg_set[] = {
10401                 {MDIO_PMA_DEVAD, 0xA819, 0x0014},
10402                 {MDIO_PMA_DEVAD, 0xA81A, 0xc200},
10403                 {MDIO_PMA_DEVAD, 0xA81B, 0x0000},
10404                 {MDIO_PMA_DEVAD, 0xA81C, 0x0300},
10405                 {MDIO_PMA_DEVAD, 0xA817, 0x0009}
10406         };
10407         uint16_t fw_ver1;
10408
10409         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
10410             (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834)) {
10411                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD, 0x400f, &fw_ver1);
10412                 elink_save_spirom_version(sc, port, fw_ver1 & 0xfff,
10413                                 phy->ver_addr);
10414         } else {
10415                 /* For 32-bit registers in 848xx, access via MDIO2ARM i/f. */
10416                 /* (1) set reg 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
10417                 for (i = 0; i < ARRAY_SIZE(reg_set); i++)
10418                         elink_cl45_write(sc, phy, reg_set[i].devad,
10419                                          reg_set[i].reg, reg_set[i].val);
10420
10421                 for (cnt = 0; cnt < 100; cnt++) {
10422                         elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA818, &val);
10423                         if (val & 1)
10424                                 break;
10425                         DELAY(5);
10426                 }
10427                 if (cnt == 100) {
10428                         ELINK_DEBUG_P0(sc, "Unable to read 848xx "
10429                                         "phy fw version(1)\n");
10430                         elink_save_spirom_version(sc, port, 0,
10431                                                   phy->ver_addr);
10432                         return;
10433                 }
10434
10435
10436                 /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
10437                 elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
10438                 elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
10439                 elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
10440                 for (cnt = 0; cnt < 100; cnt++) {
10441                         elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA818, &val);
10442                         if (val & 1)
10443                                 break;
10444                         DELAY(5);
10445                 }
10446                 if (cnt == 100) {
10447                         ELINK_DEBUG_P0(sc, "Unable to read 848xx phy fw "
10448                                         "version(2)\n");
10449                         elink_save_spirom_version(sc, port, 0,
10450                                                   phy->ver_addr);
10451                         return;
10452                 }
10453
10454                 /* lower 16 bits of the register SPI_FW_STATUS */
10455                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
10456                 /* upper 16 bits of register SPI_FW_STATUS */
10457                 elink_cl45_read(sc, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
10458
10459                 elink_save_spirom_version(sc, port, (fw_ver2<<16) | fw_ver1,
10460                                           phy->ver_addr);
10461         }
10462
10463 }
10464 static void elink_848xx_set_led(struct bxe_softc *sc,
10465                                 struct elink_phy *phy)
10466 {
10467         uint16_t val, offset, i;
10468         static struct elink_reg_set reg_set[] = {
10469                 {MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED1_MASK, 0x0080},
10470                 {MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED2_MASK, 0x0018},
10471                 {MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED3_MASK, 0x0006},
10472                 {MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED3_BLINK, 0x0000},
10473                 {MDIO_PMA_DEVAD, MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH,
10474                         MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ},
10475                 {MDIO_AN_DEVAD, 0xFFFB, 0xFFFD}
10476         };
10477         /* PHYC_CTL_LED_CTL */
10478         elink_cl45_read(sc, phy,
10479                         MDIO_PMA_DEVAD,
10480                         MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
10481         val &= 0xFE00;
10482         val |= 0x0092;
10483
10484         elink_cl45_write(sc, phy,
10485                          MDIO_PMA_DEVAD,
10486                          MDIO_PMA_REG_8481_LINK_SIGNAL, val);
10487
10488         for (i = 0; i < ARRAY_SIZE(reg_set); i++)
10489                 elink_cl45_write(sc, phy, reg_set[i].devad, reg_set[i].reg,
10490                                  reg_set[i].val);
10491
10492         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
10493             (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834))
10494                 offset = MDIO_PMA_REG_84833_CTL_LED_CTL_1;
10495         else
10496                 offset = MDIO_PMA_REG_84823_CTL_LED_CTL_1;
10497
10498         /* stretch_en for LED3*/
10499         elink_cl45_read_or_write(sc, phy,
10500                                  MDIO_PMA_DEVAD, offset,
10501                                  MDIO_PMA_REG_84823_LED3_STRETCH_EN);
10502 }
10503
10504 static void elink_848xx_specific_func(struct elink_phy *phy,
10505                                       struct elink_params *params,
10506                                       uint32_t action)
10507 {
10508         struct bxe_softc *sc = params->sc;
10509         switch (action) {
10510         case ELINK_PHY_INIT:
10511                 if ((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) &&
10512                     (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834)) {
10513                         /* Save spirom version */
10514                         elink_save_848xx_spirom_version(phy, sc, params->port);
10515                 }
10516                 /* This phy uses the NIG latch mechanism since link indication
10517                  * arrives through its LED4 and not via its LASI signal, so we
10518                  * get steady signal instead of clear on read
10519                  */
10520                 elink_bits_en(sc, NIG_REG_LATCH_BC_0 + params->port*4,
10521                               1 << ELINK_NIG_LATCH_BC_ENABLE_MI_INT);
10522
10523                 elink_848xx_set_led(sc, phy);
10524                 break;
10525         }
10526 }
10527
10528 static elink_status_t elink_848xx_cmn_config_init(struct elink_phy *phy,
10529                                        struct elink_params *params,
10530                                        struct elink_vars *vars)
10531 {
10532         struct bxe_softc *sc = params->sc;
10533         uint16_t autoneg_val, an_1000_val, an_10_100_val;
10534
10535         elink_848xx_specific_func(phy, params, ELINK_PHY_INIT);
10536         elink_cl45_write(sc, phy,
10537                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
10538
10539         /* set 1000 speed advertisement */
10540         elink_cl45_read(sc, phy,
10541                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
10542                         &an_1000_val);
10543
10544         elink_ext_phy_set_pause(params, phy, vars);
10545         elink_cl45_read(sc, phy,
10546                         MDIO_AN_DEVAD,
10547                         MDIO_AN_REG_8481_LEGACY_AN_ADV,
10548                         &an_10_100_val);
10549         elink_cl45_read(sc, phy,
10550                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
10551                         &autoneg_val);
10552         /* Disable forced speed */
10553         autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
10554         an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
10555
10556         if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10557              (phy->speed_cap_mask &
10558              PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
10559             (phy->req_line_speed == ELINK_SPEED_1000)) {
10560                 an_1000_val |= (1<<8);
10561                 autoneg_val |= (1<<9 | 1<<12);
10562                 if (phy->req_duplex == DUPLEX_FULL)
10563                         an_1000_val |= (1<<9);
10564                 ELINK_DEBUG_P0(sc, "Advertising 1G\n");
10565         } else
10566                 an_1000_val &= ~((1<<8) | (1<<9));
10567
10568         elink_cl45_write(sc, phy,
10569                          MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
10570                          an_1000_val);
10571
10572         /* Set 10/100 speed advertisement */
10573         if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
10574                 if (phy->speed_cap_mask &
10575                     PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) {
10576                         /* Enable autoneg and restart autoneg for legacy speeds
10577                          */
10578                         autoneg_val |= (1<<9 | 1<<12);
10579                         an_10_100_val |= (1<<8);
10580                         ELINK_DEBUG_P0(sc, "Advertising 100M-FD\n");
10581                 }
10582
10583                 if (phy->speed_cap_mask &
10584                     PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) {
10585                         /* Enable autoneg and restart autoneg for legacy speeds
10586                          */
10587                         autoneg_val |= (1<<9 | 1<<12);
10588                         an_10_100_val |= (1<<7);
10589                         ELINK_DEBUG_P0(sc, "Advertising 100M-HD\n");
10590                 }
10591
10592                 if ((phy->speed_cap_mask &
10593                      PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
10594                     (phy->supported & ELINK_SUPPORTED_10baseT_Full)) {
10595                         an_10_100_val |= (1<<6);
10596                         autoneg_val |= (1<<9 | 1<<12);
10597                         ELINK_DEBUG_P0(sc, "Advertising 10M-FD\n");
10598                 }
10599
10600                 if ((phy->speed_cap_mask &
10601                      PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) &&
10602                     (phy->supported & ELINK_SUPPORTED_10baseT_Half)) {
10603                         an_10_100_val |= (1<<5);
10604                         autoneg_val |= (1<<9 | 1<<12);
10605                         ELINK_DEBUG_P0(sc, "Advertising 10M-HD\n");
10606                 }
10607         }
10608
10609         /* Only 10/100 are allowed to work in FORCE mode */
10610         if ((phy->req_line_speed == ELINK_SPEED_100) &&
10611             (phy->supported &
10612              (ELINK_SUPPORTED_100baseT_Half |
10613               ELINK_SUPPORTED_100baseT_Full))) {
10614                 autoneg_val |= (1<<13);
10615                 /* Enabled AUTO-MDIX when autoneg is disabled */
10616                 elink_cl45_write(sc, phy,
10617                                  MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
10618                                  (1<<15 | 1<<9 | 7<<0));
10619                 /* The PHY needs this set even for forced link. */
10620                 an_10_100_val |= (1<<8) | (1<<7);
10621                 ELINK_DEBUG_P0(sc, "Setting 100M force\n");
10622         }
10623         if ((phy->req_line_speed == ELINK_SPEED_10) &&
10624             (phy->supported &
10625              (ELINK_SUPPORTED_10baseT_Half |
10626               ELINK_SUPPORTED_10baseT_Full))) {
10627                 /* Enabled AUTO-MDIX when autoneg is disabled */
10628                 elink_cl45_write(sc, phy,
10629                                  MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
10630                                  (1<<15 | 1<<9 | 7<<0));
10631                 ELINK_DEBUG_P0(sc, "Setting 10M force\n");
10632         }
10633
10634         elink_cl45_write(sc, phy,
10635                          MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
10636                          an_10_100_val);
10637
10638         if (phy->req_duplex == DUPLEX_FULL)
10639                 autoneg_val |= (1<<8);
10640
10641         /* Always write this if this is not 84833/4.
10642          * For 84833/4, write it only when it's a forced speed.
10643          */
10644         if (((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) &&
10645              (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834)) ||
10646             ((autoneg_val & (1<<12)) == 0))
10647                 elink_cl45_write(sc, phy,
10648                          MDIO_AN_DEVAD,
10649                          MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
10650
10651         if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
10652             (phy->speed_cap_mask &
10653              PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
10654                 (phy->req_line_speed == ELINK_SPEED_10000)) {
10655                         ELINK_DEBUG_P0(sc, "Advertising 10G\n");
10656                         /* Restart autoneg for 10G*/
10657
10658                         elink_cl45_read_or_write(
10659                                 sc, phy,
10660                                 MDIO_AN_DEVAD,
10661                                 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
10662                                 0x1000);
10663                         elink_cl45_write(sc, phy,
10664                                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
10665                                          0x3200);
10666         } else
10667                 elink_cl45_write(sc, phy,
10668                                  MDIO_AN_DEVAD,
10669                                  MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
10670                                  1);
10671
10672         return ELINK_STATUS_OK;
10673 }
10674
10675 static elink_status_t elink_8481_config_init(struct elink_phy *phy,
10676                                   struct elink_params *params,
10677                                   struct elink_vars *vars)
10678 {
10679         struct bxe_softc *sc = params->sc;
10680         /* Restore normal power mode*/
10681         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
10682                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
10683
10684         /* HW reset */
10685         elink_ext_phy_hw_reset(sc, params->port);
10686         elink_wait_reset_complete(sc, phy, params);
10687
10688         elink_cl45_write(sc, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
10689         return elink_848xx_cmn_config_init(phy, params, vars);
10690 }
10691
10692 #define PHY84833_CMDHDLR_WAIT 300
10693 #define PHY84833_CMDHDLR_MAX_ARGS 5
10694 static elink_status_t elink_84833_cmd_hdlr(struct elink_phy *phy,
10695                                 struct elink_params *params, uint16_t fw_cmd,
10696                                 uint16_t cmd_args[], int argc)
10697 {
10698         int idx;
10699         uint16_t val;
10700         struct bxe_softc *sc = params->sc;
10701         /* Write CMD_OPEN_OVERRIDE to STATUS reg */
10702         elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10703                         MDIO_84833_CMD_HDLR_STATUS,
10704                         PHY84833_STATUS_CMD_OPEN_OVERRIDE);
10705         for (idx = 0; idx < PHY84833_CMDHDLR_WAIT; idx++) {
10706                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
10707                                 MDIO_84833_CMD_HDLR_STATUS, &val);
10708                 if (val == PHY84833_STATUS_CMD_OPEN_FOR_CMDS)
10709                         break;
10710                 DELAY(1000 * 1);
10711         }
10712         if (idx >= PHY84833_CMDHDLR_WAIT) {
10713                 ELINK_DEBUG_P0(sc, "FW cmd: FW not ready.\n");
10714                 return ELINK_STATUS_ERROR;
10715         }
10716
10717         /* Prepare argument(s) and issue command */
10718         for (idx = 0; idx < argc; idx++) {
10719                 elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10720                                 MDIO_84833_CMD_HDLR_DATA1 + idx,
10721                                 cmd_args[idx]);
10722         }
10723         elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10724                         MDIO_84833_CMD_HDLR_COMMAND, fw_cmd);
10725         for (idx = 0; idx < PHY84833_CMDHDLR_WAIT; idx++) {
10726                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
10727                                 MDIO_84833_CMD_HDLR_STATUS, &val);
10728                 if ((val == PHY84833_STATUS_CMD_COMPLETE_PASS) ||
10729                         (val == PHY84833_STATUS_CMD_COMPLETE_ERROR))
10730                         break;
10731                 DELAY(1000 * 1);
10732         }
10733         if ((idx >= PHY84833_CMDHDLR_WAIT) ||
10734                 (val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) {
10735                 ELINK_DEBUG_P0(sc, "FW cmd failed.\n");
10736                 return ELINK_STATUS_ERROR;
10737         }
10738         /* Gather returning data */
10739         for (idx = 0; idx < argc; idx++) {
10740                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
10741                                 MDIO_84833_CMD_HDLR_DATA1 + idx,
10742                                 &cmd_args[idx]);
10743         }
10744         elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10745                         MDIO_84833_CMD_HDLR_STATUS,
10746                         PHY84833_STATUS_CMD_CLEAR_COMPLETE);
10747         return ELINK_STATUS_OK;
10748 }
10749
10750 static elink_status_t elink_84833_pair_swap_cfg(struct elink_phy *phy,
10751                                    struct elink_params *params,
10752                                    struct elink_vars *vars)
10753 {
10754         uint32_t pair_swap;
10755         uint16_t data[PHY84833_CMDHDLR_MAX_ARGS];
10756         elink_status_t status;
10757         struct bxe_softc *sc = params->sc;
10758
10759         /* Check for configuration. */
10760         pair_swap = REG_RD(sc, params->shmem_base +
10761                            offsetof(struct shmem_region,
10762                         dev_info.port_hw_config[params->port].xgbt_phy_cfg)) &
10763                 PORT_HW_CFG_RJ45_PAIR_SWAP_MASK;
10764
10765         if (pair_swap == 0)
10766                 return ELINK_STATUS_OK;
10767
10768         /* Only the second argument is used for this command */
10769         data[1] = (uint16_t)pair_swap;
10770
10771         status = elink_84833_cmd_hdlr(phy, params,
10772                 PHY84833_CMD_SET_PAIR_SWAP, data, PHY84833_CMDHDLR_MAX_ARGS);
10773         if (status == ELINK_STATUS_OK)
10774                 ELINK_DEBUG_P1(sc, "Pairswap OK, val=0x%x\n", data[1]);
10775
10776         return status;
10777 }
10778
10779 static uint8_t elink_84833_get_reset_gpios(struct bxe_softc *sc,
10780                                       uint32_t shmem_base_path[],
10781                                       uint32_t chip_id)
10782 {
10783         uint32_t reset_pin[2];
10784         uint32_t idx;
10785         uint8_t reset_gpios;
10786         if (CHIP_IS_E3(sc)) {
10787                 /* Assume that these will be GPIOs, not EPIOs. */
10788                 for (idx = 0; idx < 2; idx++) {
10789                         /* Map config param to register bit. */
10790                         reset_pin[idx] = REG_RD(sc, shmem_base_path[idx] +
10791                                 offsetof(struct shmem_region,
10792                                 dev_info.port_hw_config[0].e3_cmn_pin_cfg));
10793                         reset_pin[idx] = (reset_pin[idx] &
10794                                 PORT_HW_CFG_E3_PHY_RESET_MASK) >>
10795                                 PORT_HW_CFG_E3_PHY_RESET_SHIFT;
10796                         reset_pin[idx] -= PIN_CFG_GPIO0_P0;
10797                         reset_pin[idx] = (1 << reset_pin[idx]);
10798                 }
10799                 reset_gpios = (uint8_t)(reset_pin[0] | reset_pin[1]);
10800         } else {
10801                 /* E2, look from diff place of shmem. */
10802                 for (idx = 0; idx < 2; idx++) {
10803                         reset_pin[idx] = REG_RD(sc, shmem_base_path[idx] +
10804                                 offsetof(struct shmem_region,
10805                                 dev_info.port_hw_config[0].default_cfg));
10806                         reset_pin[idx] &= PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK;
10807                         reset_pin[idx] -= PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0;
10808                         reset_pin[idx] >>= PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT;
10809                         reset_pin[idx] = (1 << reset_pin[idx]);
10810                 }
10811                 reset_gpios = (uint8_t)(reset_pin[0] | reset_pin[1]);
10812         }
10813
10814         return reset_gpios;
10815 }
10816
10817 static elink_status_t elink_84833_hw_reset_phy(struct elink_phy *phy,
10818                                 struct elink_params *params)
10819 {
10820         struct bxe_softc *sc = params->sc;
10821         uint8_t reset_gpios;
10822         uint32_t other_shmem_base_addr = REG_RD(sc, params->shmem2_base +
10823                                 offsetof(struct shmem2_region,
10824                                 other_shmem_base_addr));
10825
10826         uint32_t shmem_base_path[2];
10827
10828         /* Work around for 84833 LED failure inside RESET status */
10829         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
10830                 MDIO_AN_REG_8481_LEGACY_MII_CTRL,
10831                 MDIO_AN_REG_8481_MII_CTRL_FORCE_1G);
10832         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
10833                 MDIO_AN_REG_8481_1G_100T_EXT_CTRL,
10834                 MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF);
10835
10836         shmem_base_path[0] = params->shmem_base;
10837         shmem_base_path[1] = other_shmem_base_addr;
10838
10839         reset_gpios = elink_84833_get_reset_gpios(sc, shmem_base_path,
10840                                                   params->chip_id);
10841
10842         elink_cb_gpio_mult_write(sc, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
10843         DELAY(10);
10844         ELINK_DEBUG_P1(sc, "84833 hw reset on pin values 0x%x\n",
10845                 reset_gpios);
10846
10847         return ELINK_STATUS_OK;
10848 }
10849
10850 static elink_status_t elink_8483x_disable_eee(struct elink_phy *phy,
10851                                    struct elink_params *params,
10852                                    struct elink_vars *vars)
10853 {
10854         elink_status_t rc;
10855         struct bxe_softc *sc = params->sc;
10856         uint16_t cmd_args = 0;
10857
10858         ELINK_DEBUG_P0(sc, "Don't Advertise 10GBase-T EEE\n");
10859
10860         /* Prevent Phy from working in EEE and advertising it */
10861         rc = elink_84833_cmd_hdlr(phy, params,
10862                 PHY84833_CMD_SET_EEE_MODE, &cmd_args, 1);
10863         if (rc != ELINK_STATUS_OK) {
10864                 ELINK_DEBUG_P0(sc, "EEE disable failed.\n");
10865                 return rc;
10866         }
10867
10868         return elink_eee_disable(phy, params, vars);
10869 }
10870
10871 static elink_status_t elink_8483x_enable_eee(struct elink_phy *phy,
10872                                    struct elink_params *params,
10873                                    struct elink_vars *vars)
10874 {
10875         elink_status_t rc;
10876         struct bxe_softc *sc = params->sc;
10877         uint16_t cmd_args = 1;
10878
10879         rc = elink_84833_cmd_hdlr(phy, params,
10880                 PHY84833_CMD_SET_EEE_MODE, &cmd_args, 1);
10881         if (rc != ELINK_STATUS_OK) {
10882                 ELINK_DEBUG_P0(sc, "EEE enable failed.\n");
10883                 return rc;
10884         }
10885
10886         return elink_eee_advertise(phy, params, vars, SHMEM_EEE_10G_ADV);
10887 }
10888
10889 #define PHY84833_CONSTANT_LATENCY 1193
10890 static elink_status_t elink_848x3_config_init(struct elink_phy *phy,
10891                                    struct elink_params *params,
10892                                    struct elink_vars *vars)
10893 {
10894         struct bxe_softc *sc = params->sc;
10895         uint8_t port, initialize = 1;
10896         uint16_t val;
10897         uint32_t actual_phy_selection;
10898         uint16_t cmd_args[PHY84833_CMDHDLR_MAX_ARGS];
10899         elink_status_t rc = ELINK_STATUS_OK;
10900
10901         DELAY(1000 * 1);
10902
10903         if (!(CHIP_IS_E1x(sc)))
10904                 port = SC_PATH(sc);
10905         else
10906                 port = params->port;
10907
10908         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
10909                 elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_3,
10910                                MISC_REGISTERS_GPIO_OUTPUT_HIGH,
10911                                port);
10912         } else {
10913                 /* MDIO reset */
10914                 elink_cl45_write(sc, phy,
10915                                 MDIO_PMA_DEVAD,
10916                                 MDIO_PMA_REG_CTRL, 0x8000);
10917         }
10918
10919         elink_wait_reset_complete(sc, phy, params);
10920
10921         /* Wait for GPHY to come out of reset */
10922         DELAY(1000 * 50);
10923         if ((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) &&
10924             (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834)) {
10925                 /* BCM84823 requires that XGXS links up first @ 10G for normal
10926                  * behavior.
10927                  */
10928                 uint16_t temp;
10929                 temp = vars->line_speed;
10930                 vars->line_speed = ELINK_SPEED_10000;
10931                 elink_set_autoneg(&params->phy[ELINK_INT_PHY], params, vars, 0);
10932                 elink_program_serdes(&params->phy[ELINK_INT_PHY], params, vars);
10933                 vars->line_speed = temp;
10934         }
10935
10936         elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
10937                         MDIO_CTL_REG_84823_MEDIA, &val);
10938         val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
10939                  MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
10940                  MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
10941                  MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
10942                  MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
10943
10944         if (CHIP_IS_E3(sc)) {
10945                 val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
10946                          MDIO_CTL_REG_84823_MEDIA_LINE_MASK);
10947         } else {
10948                 val |= (MDIO_CTL_REG_84823_CTRL_MAC_XFI |
10949                         MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L);
10950         }
10951
10952         actual_phy_selection = elink_phy_selection(params);
10953
10954         switch (actual_phy_selection) {
10955         case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
10956                 /* Do nothing. Essentially this is like the priority copper */
10957                 break;
10958         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
10959                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
10960                 break;
10961         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
10962                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
10963                 break;
10964         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
10965                 /* Do nothing here. The first PHY won't be initialized at all */
10966                 break;
10967         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
10968                 val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
10969                 initialize = 0;
10970                 break;
10971         }
10972         if (params->phy[ELINK_EXT_PHY2].req_line_speed == ELINK_SPEED_1000)
10973                 val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
10974
10975         elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
10976                          MDIO_CTL_REG_84823_MEDIA, val);
10977         ELINK_DEBUG_P2(sc, "Multi_phy config = 0x%x, Media control = 0x%x\n",
10978                    params->multi_phy_config, val);
10979
10980         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
10981             (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834)) {
10982                 elink_84833_pair_swap_cfg(phy, params, vars);
10983
10984                 /* Keep AutogrEEEn disabled. */
10985                 cmd_args[0] = 0x0;
10986                 cmd_args[1] = 0x0;
10987                 cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1;
10988                 cmd_args[3] = PHY84833_CONSTANT_LATENCY;
10989                 rc = elink_84833_cmd_hdlr(phy, params,
10990                         PHY84833_CMD_SET_EEE_MODE, cmd_args,
10991                         PHY84833_CMDHDLR_MAX_ARGS);
10992                 if (rc != ELINK_STATUS_OK)
10993                         ELINK_DEBUG_P0(sc, "Cfg AutogrEEEn failed.\n");
10994         }
10995         if (initialize)
10996                 rc = elink_848xx_cmn_config_init(phy, params, vars);
10997         else
10998                 elink_save_848xx_spirom_version(phy, sc, params->port);
10999         /* 84833 PHY has a better feature and doesn't need to support this. */
11000         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
11001                 uint32_t cms_enable = REG_RD(sc, params->shmem_base +
11002                         offsetof(struct shmem_region,
11003                         dev_info.port_hw_config[params->port].default_cfg)) &
11004                         PORT_HW_CFG_ENABLE_CMS_MASK;
11005
11006                 elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11007                                 MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
11008                 if (cms_enable)
11009                         val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
11010                 else
11011                         val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
11012                 elink_cl45_write(sc, phy, MDIO_CTL_DEVAD,
11013                                  MDIO_CTL_REG_84823_USER_CTRL_REG, val);
11014         }
11015
11016         elink_cl45_read(sc, phy, MDIO_CTL_DEVAD,
11017                         MDIO_84833_TOP_CFG_FW_REV, &val);
11018
11019         /* Configure EEE support */
11020         if ((val >= MDIO_84833_TOP_CFG_FW_EEE) &&
11021             (val != MDIO_84833_TOP_CFG_FW_NO_EEE) &&
11022             elink_eee_has_cap(params)) {
11023                 rc = elink_eee_initial_config(params, vars, SHMEM_EEE_10G_ADV);
11024                 if (rc != ELINK_STATUS_OK) {
11025                         ELINK_DEBUG_P0(sc, "Failed to configure EEE timers\n");
11026                         elink_8483x_disable_eee(phy, params, vars);
11027                         return rc;
11028                 }
11029
11030                 if ((phy->req_duplex == DUPLEX_FULL) &&
11031                     (params->eee_mode & ELINK_EEE_MODE_ADV_LPI) &&
11032                     (elink_eee_calc_timer(params) ||
11033                      !(params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI)))
11034                         rc = elink_8483x_enable_eee(phy, params, vars);
11035                 else
11036                         rc = elink_8483x_disable_eee(phy, params, vars);
11037                 if (rc != ELINK_STATUS_OK) {
11038                         ELINK_DEBUG_P0(sc, "Failed to set EEE advertisement\n");
11039                         return rc;
11040                 }
11041         } else {
11042                 vars->eee_status &= ~SHMEM_EEE_SUPPORTED_MASK;
11043         }
11044
11045         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
11046             (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834)) {
11047                 /* Bring PHY out of super isolate mode as the final step. */
11048                 elink_cl45_read_and_write(sc, phy,
11049                                           MDIO_CTL_DEVAD,
11050                                           MDIO_84833_TOP_CFG_XGPHY_STRAP1,
11051                                           (uint16_t)~MDIO_84833_SUPER_ISOLATE);
11052         }
11053         return rc;
11054 }
11055
11056 static uint8_t elink_848xx_read_status(struct elink_phy *phy,
11057                                   struct elink_params *params,
11058                                   struct elink_vars *vars)
11059 {
11060         struct bxe_softc *sc = params->sc;
11061         uint16_t val, val1, val2;
11062         uint8_t link_up = 0;
11063
11064
11065         /* Check 10G-BaseT link status */
11066         /* Check PMD signal ok */
11067         elink_cl45_read(sc, phy,
11068                         MDIO_AN_DEVAD, 0xFFFA, &val1);
11069         elink_cl45_read(sc, phy,
11070                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
11071                         &val2);
11072         ELINK_DEBUG_P1(sc, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
11073
11074         /* Check link 10G */
11075         if (val2 & (1<<11)) {
11076                 vars->line_speed = ELINK_SPEED_10000;
11077                 vars->duplex = DUPLEX_FULL;
11078                 link_up = 1;
11079                 elink_ext_phy_10G_an_resolve(sc, phy, vars);
11080         } else { /* Check Legacy speed link */
11081                 uint16_t legacy_status, legacy_speed, mii_ctrl;
11082
11083                 /* Enable expansion register 0x42 (Operation mode status) */
11084                 elink_cl45_write(sc, phy,
11085                                  MDIO_AN_DEVAD,
11086                                  MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
11087
11088                 /* Get legacy speed operation status */
11089                 elink_cl45_read(sc, phy,
11090                                 MDIO_AN_DEVAD,
11091                                 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
11092                                 &legacy_status);
11093
11094                 ELINK_DEBUG_P1(sc, "Legacy speed status = 0x%x\n",
11095                    legacy_status);
11096                 link_up = ((legacy_status & (1<<11)) == (1<<11));
11097                 legacy_speed = (legacy_status & (3<<9));
11098                 if (legacy_speed == (0<<9))
11099                         vars->line_speed = ELINK_SPEED_10;
11100                 else if (legacy_speed == (1<<9))
11101                         vars->line_speed = ELINK_SPEED_100;
11102                 else if (legacy_speed == (2<<9))
11103                         vars->line_speed = ELINK_SPEED_1000;
11104                 else { /* Should not happen: Treat as link down */
11105                         vars->line_speed = 0;
11106                         link_up = 0;
11107                 }
11108
11109                 if (params->feature_config_flags &
11110                         ELINK_FEATURE_CONFIG_IEEE_PHY_TEST) {
11111                         elink_cl45_read(sc, phy,
11112                                         MDIO_AN_DEVAD,
11113                                         MDIO_AN_REG_8481_LEGACY_MII_CTRL,
11114                                         &mii_ctrl);
11115                         /* For IEEE testing, check for a fake link. */
11116                         link_up |= ((mii_ctrl & 0x3040) == 0x40);
11117                 }
11118
11119                 if (link_up) {
11120                         if (legacy_status & (1<<8))
11121                                 vars->duplex = DUPLEX_FULL;
11122                         else
11123                                 vars->duplex = DUPLEX_HALF;
11124
11125                         ELINK_DEBUG_P2(sc,
11126                            "Link is up in %dMbps, is_duplex_full= %d\n",
11127                            vars->line_speed,
11128                            (vars->duplex == DUPLEX_FULL));
11129                         /* Check legacy speed AN resolution */
11130                         elink_cl45_read(sc, phy,
11131                                         MDIO_AN_DEVAD,
11132                                         MDIO_AN_REG_8481_LEGACY_MII_STATUS,
11133                                         &val);
11134                         if (val & (1<<5))
11135                                 vars->link_status |=
11136                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
11137                         elink_cl45_read(sc, phy,
11138                                         MDIO_AN_DEVAD,
11139                                         MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
11140                                         &val);
11141                         if ((val & (1<<0)) == 0)
11142                                 vars->link_status |=
11143                                         LINK_STATUS_PARALLEL_DETECTION_USED;
11144                 }
11145         }
11146         if (link_up) {
11147                 ELINK_DEBUG_P1(sc, "BCM848x3: link speed is %d\n",
11148                            vars->line_speed);
11149                 elink_ext_phy_resolve_fc(phy, params, vars);
11150
11151                 /* Read LP advertised speeds */
11152                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11153                                 MDIO_AN_REG_CL37_FC_LP, &val);
11154                 if (val & (1<<5))
11155                         vars->link_status |=
11156                                 LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
11157                 if (val & (1<<6))
11158                         vars->link_status |=
11159                                 LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
11160                 if (val & (1<<7))
11161                         vars->link_status |=
11162                                 LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
11163                 if (val & (1<<8))
11164                         vars->link_status |=
11165                                 LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
11166                 if (val & (1<<9))
11167                         vars->link_status |=
11168                                 LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
11169
11170                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11171                                 MDIO_AN_REG_1000T_STATUS, &val);
11172
11173                 if (val & (1<<10))
11174                         vars->link_status |=
11175                                 LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
11176                 if (val & (1<<11))
11177                         vars->link_status |=
11178                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
11179
11180                 elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
11181                                 MDIO_AN_REG_MASTER_STATUS, &val);
11182
11183                 if (val & (1<<11))
11184                         vars->link_status |=
11185                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
11186
11187                 /* Determine if EEE was negotiated */
11188                 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
11189                     (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834))
11190                         elink_eee_an_resolve(phy, params, vars);
11191         }
11192
11193         return link_up;
11194 }
11195
11196 static elink_status_t elink_848xx_format_ver(uint32_t raw_ver, uint8_t *str, uint16_t *len)
11197 {
11198         elink_status_t status = ELINK_STATUS_OK;
11199         uint32_t spirom_ver;
11200         spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
11201         status = elink_format_ver(spirom_ver, str, len);
11202         return status;
11203 }
11204
11205 static void elink_8481_hw_reset(struct elink_phy *phy,
11206                                 struct elink_params *params)
11207 {
11208         elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_1,
11209                        MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
11210         elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_1,
11211                        MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
11212 }
11213
11214 static void elink_8481_link_reset(struct elink_phy *phy,
11215                                         struct elink_params *params)
11216 {
11217         elink_cl45_write(params->sc, phy,
11218                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
11219         elink_cl45_write(params->sc, phy,
11220                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
11221 }
11222
11223 static void elink_848x3_link_reset(struct elink_phy *phy,
11224                                    struct elink_params *params)
11225 {
11226         struct bxe_softc *sc = params->sc;
11227         uint8_t port;
11228         uint16_t val16;
11229
11230         if (!(CHIP_IS_E1x(sc)))
11231                 port = SC_PATH(sc);
11232         else
11233                 port = params->port;
11234
11235         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
11236                 elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_3,
11237                                MISC_REGISTERS_GPIO_OUTPUT_LOW,
11238                                port);
11239         } else {
11240                 elink_cl45_read(sc, phy,
11241                                 MDIO_CTL_DEVAD,
11242                                 MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val16);
11243                 val16 |= MDIO_84833_SUPER_ISOLATE;
11244                 elink_cl45_write(sc, phy,
11245                                  MDIO_CTL_DEVAD,
11246                                  MDIO_84833_TOP_CFG_XGPHY_STRAP1, val16);
11247         }
11248 }
11249
11250 static void elink_848xx_set_link_led(struct elink_phy *phy,
11251                                      struct elink_params *params, uint8_t mode)
11252 {
11253         struct bxe_softc *sc = params->sc;
11254         uint16_t val;
11255         uint8_t port;
11256
11257         if (!(CHIP_IS_E1x(sc)))
11258                 port = SC_PATH(sc);
11259         else
11260                 port = params->port;
11261
11262         switch (mode) {
11263         case ELINK_LED_MODE_OFF:
11264
11265                 ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE OFF\n", port);
11266
11267                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11268                     SHARED_HW_CFG_LED_EXTPHY1) {
11269
11270                         /* Set LED masks */
11271                         elink_cl45_write(sc, phy,
11272                                         MDIO_PMA_DEVAD,
11273                                         MDIO_PMA_REG_8481_LED1_MASK,
11274                                         0x0);
11275
11276                         elink_cl45_write(sc, phy,
11277                                         MDIO_PMA_DEVAD,
11278                                         MDIO_PMA_REG_8481_LED2_MASK,
11279                                         0x0);
11280
11281                         elink_cl45_write(sc, phy,
11282                                         MDIO_PMA_DEVAD,
11283                                         MDIO_PMA_REG_8481_LED3_MASK,
11284                                         0x0);
11285
11286                         elink_cl45_write(sc, phy,
11287                                         MDIO_PMA_DEVAD,
11288                                         MDIO_PMA_REG_8481_LED5_MASK,
11289                                         0x0);
11290
11291                 } else {
11292                         elink_cl45_write(sc, phy,
11293                                          MDIO_PMA_DEVAD,
11294                                          MDIO_PMA_REG_8481_LED1_MASK,
11295                                          0x0);
11296                 }
11297                 break;
11298         case ELINK_LED_MODE_FRONT_PANEL_OFF:
11299
11300                 ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
11301                    port);
11302
11303                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11304                     SHARED_HW_CFG_LED_EXTPHY1) {
11305
11306                         /* Set LED masks */
11307                         elink_cl45_write(sc, phy,
11308                                          MDIO_PMA_DEVAD,
11309                                          MDIO_PMA_REG_8481_LED1_MASK,
11310                                          0x0);
11311
11312                         elink_cl45_write(sc, phy,
11313                                          MDIO_PMA_DEVAD,
11314                                          MDIO_PMA_REG_8481_LED2_MASK,
11315                                          0x0);
11316
11317                         elink_cl45_write(sc, phy,
11318                                          MDIO_PMA_DEVAD,
11319                                          MDIO_PMA_REG_8481_LED3_MASK,
11320                                          0x0);
11321
11322                         elink_cl45_write(sc, phy,
11323                                          MDIO_PMA_DEVAD,
11324                                          MDIO_PMA_REG_8481_LED5_MASK,
11325                                          0x20);
11326
11327                 } else {
11328                         elink_cl45_write(sc, phy,
11329                                          MDIO_PMA_DEVAD,
11330                                          MDIO_PMA_REG_8481_LED1_MASK,
11331                                          0x0);
11332                         if (phy->type ==
11333                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) {
11334                                 /* Disable MI_INT interrupt before setting LED4
11335                                  * source to constant off.
11336                                  */
11337                                 if (REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
11338                                            params->port*4) &
11339                                     ELINK_NIG_MASK_MI_INT) {
11340                                         params->link_flags |=
11341                                         ELINK_LINK_FLAGS_INT_DISABLED;
11342
11343                                         elink_bits_dis(
11344                                                 sc,
11345                                                 NIG_REG_MASK_INTERRUPT_PORT0 +
11346                                                 params->port*4,
11347                                                 ELINK_NIG_MASK_MI_INT);
11348                                 }
11349                                 elink_cl45_write(sc, phy,
11350                                                  MDIO_PMA_DEVAD,
11351                                                  MDIO_PMA_REG_8481_SIGNAL_MASK,
11352                                                  0x0);
11353                         }
11354                 }
11355                 break;
11356         case ELINK_LED_MODE_ON:
11357
11358                 ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE ON\n", port);
11359
11360                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11361                     SHARED_HW_CFG_LED_EXTPHY1) {
11362                         /* Set control reg */
11363                         elink_cl45_read(sc, phy,
11364                                         MDIO_PMA_DEVAD,
11365                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
11366                                         &val);
11367                         val &= 0x8000;
11368                         val |= 0x2492;
11369
11370                         elink_cl45_write(sc, phy,
11371                                          MDIO_PMA_DEVAD,
11372                                          MDIO_PMA_REG_8481_LINK_SIGNAL,
11373                                          val);
11374
11375                         /* Set LED masks */
11376                         elink_cl45_write(sc, phy,
11377                                          MDIO_PMA_DEVAD,
11378                                          MDIO_PMA_REG_8481_LED1_MASK,
11379                                          0x0);
11380
11381                         elink_cl45_write(sc, phy,
11382                                          MDIO_PMA_DEVAD,
11383                                          MDIO_PMA_REG_8481_LED2_MASK,
11384                                          0x20);
11385
11386                         elink_cl45_write(sc, phy,
11387                                          MDIO_PMA_DEVAD,
11388                                          MDIO_PMA_REG_8481_LED3_MASK,
11389                                          0x20);
11390
11391                         elink_cl45_write(sc, phy,
11392                                          MDIO_PMA_DEVAD,
11393                                          MDIO_PMA_REG_8481_LED5_MASK,
11394                                          0x0);
11395                 } else {
11396                         elink_cl45_write(sc, phy,
11397                                          MDIO_PMA_DEVAD,
11398                                          MDIO_PMA_REG_8481_LED1_MASK,
11399                                          0x20);
11400                         if (phy->type ==
11401                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) {
11402                                 /* Disable MI_INT interrupt before setting LED4
11403                                  * source to constant on.
11404                                  */
11405                                 if (REG_RD(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
11406                                            params->port*4) &
11407                                     ELINK_NIG_MASK_MI_INT) {
11408                                         params->link_flags |=
11409                                         ELINK_LINK_FLAGS_INT_DISABLED;
11410
11411                                         elink_bits_dis(
11412                                                 sc,
11413                                                 NIG_REG_MASK_INTERRUPT_PORT0 +
11414                                                 params->port*4,
11415                                                 ELINK_NIG_MASK_MI_INT);
11416                                 }
11417                                 elink_cl45_write(sc, phy,
11418                                                  MDIO_PMA_DEVAD,
11419                                                  MDIO_PMA_REG_8481_SIGNAL_MASK,
11420                                                  0x20);
11421                         }
11422                 }
11423                 break;
11424
11425         case ELINK_LED_MODE_OPER:
11426
11427                 ELINK_DEBUG_P1(sc, "Port 0x%x: LED MODE OPER\n", port);
11428
11429                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
11430                     SHARED_HW_CFG_LED_EXTPHY1) {
11431
11432                         /* Set control reg */
11433                         elink_cl45_read(sc, phy,
11434                                         MDIO_PMA_DEVAD,
11435                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
11436                                         &val);
11437
11438                         if (!((val &
11439                                MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
11440                           >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) {
11441                                 ELINK_DEBUG_P0(sc, "Setting LINK_SIGNAL\n");
11442                                 elink_cl45_write(sc, phy,
11443                                                  MDIO_PMA_DEVAD,
11444                                                  MDIO_PMA_REG_8481_LINK_SIGNAL,
11445                                                  0xa492);
11446                         }
11447
11448                         /* Set LED masks */
11449                         elink_cl45_write(sc, phy,
11450                                          MDIO_PMA_DEVAD,
11451                                          MDIO_PMA_REG_8481_LED1_MASK,
11452                                          0x10);
11453
11454                         elink_cl45_write(sc, phy,
11455                                          MDIO_PMA_DEVAD,
11456                                          MDIO_PMA_REG_8481_LED2_MASK,
11457                                          0x80);
11458
11459                         elink_cl45_write(sc, phy,
11460                                          MDIO_PMA_DEVAD,
11461                                          MDIO_PMA_REG_8481_LED3_MASK,
11462                                          0x98);
11463
11464                         elink_cl45_write(sc, phy,
11465                                          MDIO_PMA_DEVAD,
11466                                          MDIO_PMA_REG_8481_LED5_MASK,
11467                                          0x40);
11468
11469                 } else {
11470                         /* EXTPHY2 LED mode indicate that the 100M/1G/10G LED
11471                          * sources are all wired through LED1, rather than only
11472                          * 10G in other modes.
11473                          */
11474                         val = ((params->hw_led_mode <<
11475                                 SHARED_HW_CFG_LED_MODE_SHIFT) ==
11476                                SHARED_HW_CFG_LED_EXTPHY2) ? 0x98 : 0x80;
11477
11478                         elink_cl45_write(sc, phy,
11479                                          MDIO_PMA_DEVAD,
11480                                          MDIO_PMA_REG_8481_LED1_MASK,
11481                                          val);
11482
11483                         /* Tell LED3 to blink on source */
11484                         elink_cl45_read(sc, phy,
11485                                         MDIO_PMA_DEVAD,
11486                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
11487                                         &val);
11488                         val &= ~(7<<6);
11489                         val |= (1<<6); /* A83B[8:6]= 1 */
11490                         elink_cl45_write(sc, phy,
11491                                          MDIO_PMA_DEVAD,
11492                                          MDIO_PMA_REG_8481_LINK_SIGNAL,
11493                                          val);
11494                         if (phy->type ==
11495                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) {
11496                                 /* Restore LED4 source to external link,
11497                                  * and re-enable interrupts.
11498                                  */
11499                                 elink_cl45_write(sc, phy,
11500                                                  MDIO_PMA_DEVAD,
11501                                                  MDIO_PMA_REG_8481_SIGNAL_MASK,
11502                                                  0x40);
11503                                 if (params->link_flags &
11504                                     ELINK_LINK_FLAGS_INT_DISABLED) {
11505                                         elink_link_int_enable(params);
11506                                         params->link_flags &=
11507                                                 ~ELINK_LINK_FLAGS_INT_DISABLED;
11508                                 }
11509                         }
11510                 }
11511                 break;
11512         }
11513
11514         /* This is a workaround for E3+84833 until autoneg
11515          * restart is fixed in f/w
11516          */
11517         if (CHIP_IS_E3(sc)) {
11518                 elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
11519                                 MDIO_WC_REG_GP2_STATUS_GP_2_1, &val);
11520         }
11521 }
11522
11523 /******************************************************************/
11524 /*                      54618SE PHY SECTION                       */
11525 /******************************************************************/
11526 static void elink_54618se_specific_func(struct elink_phy *phy,
11527                                         struct elink_params *params,
11528                                         uint32_t action)
11529 {
11530         struct bxe_softc *sc = params->sc;
11531         uint16_t temp;
11532         switch (action) {
11533         case ELINK_PHY_INIT:
11534                 /* Configure LED4: set to INTR (0x6). */
11535                 /* Accessing shadow register 0xe. */
11536                 elink_cl22_write(sc, phy,
11537                                  MDIO_REG_GPHY_SHADOW,
11538                                  MDIO_REG_GPHY_SHADOW_LED_SEL2);
11539                 elink_cl22_read(sc, phy,
11540                                 MDIO_REG_GPHY_SHADOW,
11541                                 &temp);
11542                 temp &= ~(0xf << 4);
11543                 temp |= (0x6 << 4);
11544                 elink_cl22_write(sc, phy,
11545                                  MDIO_REG_GPHY_SHADOW,
11546                                  MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
11547                 /* Configure INTR based on link status change. */
11548                 elink_cl22_write(sc, phy,
11549                                  MDIO_REG_INTR_MASK,
11550                                  ~MDIO_REG_INTR_MASK_LINK_STATUS);
11551                 break;
11552         }
11553 }
11554
11555 static elink_status_t elink_54618se_config_init(struct elink_phy *phy,
11556                                                struct elink_params *params,
11557                                                struct elink_vars *vars)
11558 {
11559         struct bxe_softc *sc = params->sc;
11560         uint8_t port;
11561         uint16_t autoneg_val, an_1000_val, an_10_100_val, fc_val, temp;
11562         uint32_t cfg_pin;
11563
11564         ELINK_DEBUG_P0(sc, "54618SE cfg init\n");
11565         DELAY(1000 * 1);
11566
11567         /* This works with E3 only, no need to check the chip
11568          * before determining the port.
11569          */
11570         port = params->port;
11571
11572         cfg_pin = (REG_RD(sc, params->shmem_base +
11573                         offsetof(struct shmem_region,
11574                         dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
11575                         PORT_HW_CFG_E3_PHY_RESET_MASK) >>
11576                         PORT_HW_CFG_E3_PHY_RESET_SHIFT;
11577
11578         /* Drive pin high to bring the GPHY out of reset. */
11579         elink_set_cfg_pin(sc, cfg_pin, 1);
11580
11581         /* wait for GPHY to reset */
11582         DELAY(1000 * 50);
11583
11584         /* reset phy */
11585         elink_cl22_write(sc, phy,
11586                          MDIO_PMA_REG_CTRL, 0x8000);
11587         elink_wait_reset_complete(sc, phy, params);
11588
11589         /* Wait for GPHY to reset */
11590         DELAY(1000 * 50);
11591
11592
11593         elink_54618se_specific_func(phy, params, ELINK_PHY_INIT);
11594         /* Flip the signal detect polarity (set 0x1c.0x1e[8]). */
11595         elink_cl22_write(sc, phy,
11596                         MDIO_REG_GPHY_SHADOW,
11597                         MDIO_REG_GPHY_SHADOW_AUTO_DET_MED);
11598         elink_cl22_read(sc, phy,
11599                         MDIO_REG_GPHY_SHADOW,
11600                         &temp);
11601         temp |= MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD;
11602         elink_cl22_write(sc, phy,
11603                         MDIO_REG_GPHY_SHADOW,
11604                         MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
11605
11606         /* Set up fc */
11607         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
11608         elink_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
11609         fc_val = 0;
11610         if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
11611                         MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC)
11612                 fc_val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
11613
11614         if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
11615                         MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
11616                 fc_val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
11617
11618         /* Read all advertisement */
11619         elink_cl22_read(sc, phy,
11620                         0x09,
11621                         &an_1000_val);
11622
11623         elink_cl22_read(sc, phy,
11624                         0x04,
11625                         &an_10_100_val);
11626
11627         elink_cl22_read(sc, phy,
11628                         MDIO_PMA_REG_CTRL,
11629                         &autoneg_val);
11630
11631         /* Disable forced speed */
11632         autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
11633         an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8) | (1<<10) |
11634                            (1<<11));
11635
11636         if (((phy->req_line_speed == ELINK_SPEED_AUTO_NEG) &&
11637                         (phy->speed_cap_mask &
11638                         PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
11639                         (phy->req_line_speed == ELINK_SPEED_1000)) {
11640                 an_1000_val |= (1<<8);
11641                 autoneg_val |= (1<<9 | 1<<12);
11642                 if (phy->req_duplex == DUPLEX_FULL)
11643                         an_1000_val |= (1<<9);
11644                 ELINK_DEBUG_P0(sc, "Advertising 1G\n");
11645         } else
11646                 an_1000_val &= ~((1<<8) | (1<<9));
11647
11648         elink_cl22_write(sc, phy,
11649                         0x09,
11650                         an_1000_val);
11651         elink_cl22_read(sc, phy,
11652                         0x09,
11653                         &an_1000_val);
11654
11655         /* Advertise 10/100 link speed */
11656         if (phy->req_line_speed == ELINK_SPEED_AUTO_NEG) {
11657                 if (phy->speed_cap_mask &
11658                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) {
11659                         an_10_100_val |= (1<<5);
11660                         autoneg_val |= (1<<9 | 1<<12);
11661                         ELINK_DEBUG_P0(sc, "Advertising 10M-HD\n");
11662                 }
11663                 if (phy->speed_cap_mask &
11664                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) {
11665                         an_10_100_val |= (1<<6);
11666                         autoneg_val |= (1<<9 | 1<<12);
11667                         ELINK_DEBUG_P0(sc, "Advertising 10M-FD\n");
11668                 }
11669                 if (phy->speed_cap_mask &
11670                     PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) {
11671                         an_10_100_val |= (1<<7);
11672                         autoneg_val |= (1<<9 | 1<<12);
11673                         ELINK_DEBUG_P0(sc, "Advertising 100M-HD\n");
11674                 }
11675                 if (phy->speed_cap_mask &
11676                     PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) {
11677                         an_10_100_val |= (1<<8);
11678                         autoneg_val |= (1<<9 | 1<<12);
11679                         ELINK_DEBUG_P0(sc, "Advertising 100M-FD\n");
11680                 }
11681         }
11682
11683         /* Only 10/100 are allowed to work in FORCE mode */
11684         if (phy->req_line_speed == ELINK_SPEED_100) {
11685                 autoneg_val |= (1<<13);
11686                 /* Enabled AUTO-MDIX when autoneg is disabled */
11687                 elink_cl22_write(sc, phy,
11688                                 0x18,
11689                                 (1<<15 | 1<<9 | 7<<0));
11690                 ELINK_DEBUG_P0(sc, "Setting 100M force\n");
11691         }
11692         if (phy->req_line_speed == ELINK_SPEED_10) {
11693                 /* Enabled AUTO-MDIX when autoneg is disabled */
11694                 elink_cl22_write(sc, phy,
11695                                 0x18,
11696                                 (1<<15 | 1<<9 | 7<<0));
11697                 ELINK_DEBUG_P0(sc, "Setting 10M force\n");
11698         }
11699
11700         if ((phy->flags & ELINK_FLAGS_EEE) && elink_eee_has_cap(params)) {
11701                 elink_status_t rc;
11702
11703                 elink_cl22_write(sc, phy, MDIO_REG_GPHY_EXP_ACCESS,
11704                                  MDIO_REG_GPHY_EXP_ACCESS_TOP |
11705                                  MDIO_REG_GPHY_EXP_TOP_2K_BUF);
11706                 elink_cl22_read(sc, phy, MDIO_REG_GPHY_EXP_ACCESS_GATE, &temp);
11707                 temp &= 0xfffe;
11708                 elink_cl22_write(sc, phy, MDIO_REG_GPHY_EXP_ACCESS_GATE, temp);
11709
11710                 rc = elink_eee_initial_config(params, vars, SHMEM_EEE_1G_ADV);
11711                 if (rc != ELINK_STATUS_OK) {
11712                         ELINK_DEBUG_P0(sc, "Failed to configure EEE timers\n");
11713                         elink_eee_disable(phy, params, vars);
11714                 } else if ((params->eee_mode & ELINK_EEE_MODE_ADV_LPI) &&
11715                            (phy->req_duplex == DUPLEX_FULL) &&
11716                            (elink_eee_calc_timer(params) ||
11717                             !(params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI))) {
11718                         /* Need to advertise EEE only when requested,
11719                          * and either no LPI assertion was requested,
11720                          * or it was requested and a valid timer was set.
11721                          * Also notice full duplex is required for EEE.
11722                          */
11723                         elink_eee_advertise(phy, params, vars,
11724                                             SHMEM_EEE_1G_ADV);
11725                 } else {
11726                         ELINK_DEBUG_P0(sc, "Don't Advertise 1GBase-T EEE\n");
11727                         elink_eee_disable(phy, params, vars);
11728                 }
11729         } else {
11730                 vars->eee_status &= ~SHMEM_EEE_1G_ADV <<
11731                                     SHMEM_EEE_SUPPORTED_SHIFT;
11732
11733                 if (phy->flags & ELINK_FLAGS_EEE) {
11734                         /* Handle legacy auto-grEEEn */
11735                         if (params->feature_config_flags &
11736                             ELINK_FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
11737                                 temp = 6;
11738                                 ELINK_DEBUG_P0(sc, "Enabling Auto-GrEEEn\n");
11739                         } else {
11740                                 temp = 0;
11741                                 ELINK_DEBUG_P0(sc, "Don't Adv. EEE\n");
11742                         }
11743                         elink_cl45_write(sc, phy, MDIO_AN_DEVAD,
11744                                          MDIO_AN_REG_EEE_ADV, temp);
11745                 }
11746         }
11747
11748         elink_cl22_write(sc, phy,
11749                         0x04,
11750                         an_10_100_val | fc_val);
11751
11752         if (phy->req_duplex == DUPLEX_FULL)
11753                 autoneg_val |= (1<<8);
11754
11755         elink_cl22_write(sc, phy,
11756                         MDIO_PMA_REG_CTRL, autoneg_val);
11757
11758         return ELINK_STATUS_OK;
11759 }
11760
11761
11762 static void elink_5461x_set_link_led(struct elink_phy *phy,
11763                                        struct elink_params *params, uint8_t mode)
11764 {
11765         struct bxe_softc *sc = params->sc;
11766         uint16_t temp;
11767
11768         elink_cl22_write(sc, phy,
11769                 MDIO_REG_GPHY_SHADOW,
11770                 MDIO_REG_GPHY_SHADOW_LED_SEL1);
11771         elink_cl22_read(sc, phy,
11772                 MDIO_REG_GPHY_SHADOW,
11773                 &temp);
11774         temp &= 0xff00;
11775
11776         ELINK_DEBUG_P1(sc, "54618x set link led (mode=%x)\n", mode);
11777         switch (mode) {
11778         case ELINK_LED_MODE_FRONT_PANEL_OFF:
11779         case ELINK_LED_MODE_OFF:
11780                 temp |= 0x00ee;
11781                 break;
11782         case ELINK_LED_MODE_OPER:
11783                 temp |= 0x0001;
11784                 break;
11785         case ELINK_LED_MODE_ON:
11786                 temp |= 0x00ff;
11787                 break;
11788         default:
11789                 break;
11790         }
11791         elink_cl22_write(sc, phy,
11792                 MDIO_REG_GPHY_SHADOW,
11793                 MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
11794         return;
11795 }
11796
11797
11798 static void elink_54618se_link_reset(struct elink_phy *phy,
11799                                      struct elink_params *params)
11800 {
11801         struct bxe_softc *sc = params->sc;
11802         uint32_t cfg_pin;
11803         uint8_t port;
11804
11805         /* In case of no EPIO routed to reset the GPHY, put it
11806          * in low power mode.
11807          */
11808         elink_cl22_write(sc, phy, MDIO_PMA_REG_CTRL, 0x800);
11809         /* This works with E3 only, no need to check the chip
11810          * before determining the port.
11811          */
11812         port = params->port;
11813         cfg_pin = (REG_RD(sc, params->shmem_base +
11814                         offsetof(struct shmem_region,
11815                         dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
11816                         PORT_HW_CFG_E3_PHY_RESET_MASK) >>
11817                         PORT_HW_CFG_E3_PHY_RESET_SHIFT;
11818
11819         /* Drive pin low to put GPHY in reset. */
11820         elink_set_cfg_pin(sc, cfg_pin, 0);
11821 }
11822
11823 static uint8_t elink_54618se_read_status(struct elink_phy *phy,
11824                                     struct elink_params *params,
11825                                     struct elink_vars *vars)
11826 {
11827         struct bxe_softc *sc = params->sc;
11828         uint16_t val;
11829         uint8_t link_up = 0;
11830         uint16_t legacy_status, legacy_speed;
11831
11832         /* Get speed operation status */
11833         elink_cl22_read(sc, phy,
11834                         MDIO_REG_GPHY_AUX_STATUS,
11835                         &legacy_status);
11836         ELINK_DEBUG_P1(sc, "54618SE read_status: 0x%x\n", legacy_status);
11837
11838         /* Read status to clear the PHY interrupt. */
11839         elink_cl22_read(sc, phy,
11840                         MDIO_REG_INTR_STATUS,
11841                         &val);
11842
11843         link_up = ((legacy_status & (1<<2)) == (1<<2));
11844
11845         if (link_up) {
11846                 legacy_speed = (legacy_status & (7<<8));
11847                 if (legacy_speed == (7<<8)) {
11848                         vars->line_speed = ELINK_SPEED_1000;
11849                         vars->duplex = DUPLEX_FULL;
11850                 } else if (legacy_speed == (6<<8)) {
11851                         vars->line_speed = ELINK_SPEED_1000;
11852                         vars->duplex = DUPLEX_HALF;
11853                 } else if (legacy_speed == (5<<8)) {
11854                         vars->line_speed = ELINK_SPEED_100;
11855                         vars->duplex = DUPLEX_FULL;
11856                 }
11857                 /* Omitting 100Base-T4 for now */
11858                 else if (legacy_speed == (3<<8)) {
11859                         vars->line_speed = ELINK_SPEED_100;
11860                         vars->duplex = DUPLEX_HALF;
11861                 } else if (legacy_speed == (2<<8)) {
11862                         vars->line_speed = ELINK_SPEED_10;
11863                         vars->duplex = DUPLEX_FULL;
11864                 } else if (legacy_speed == (1<<8)) {
11865                         vars->line_speed = ELINK_SPEED_10;
11866                         vars->duplex = DUPLEX_HALF;
11867                 } else /* Should not happen */
11868                         vars->line_speed = 0;
11869
11870                 ELINK_DEBUG_P2(sc,
11871                    "Link is up in %dMbps, is_duplex_full= %d\n",
11872                    vars->line_speed,
11873                    (vars->duplex == DUPLEX_FULL));
11874
11875                 /* Check legacy speed AN resolution */
11876                 elink_cl22_read(sc, phy,
11877                                 0x01,
11878                                 &val);
11879                 if (val & (1<<5))
11880                         vars->link_status |=
11881                                 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
11882                 elink_cl22_read(sc, phy,
11883                                 0x06,
11884                                 &val);
11885                 if ((val & (1<<0)) == 0)
11886                         vars->link_status |=
11887                                 LINK_STATUS_PARALLEL_DETECTION_USED;
11888
11889                 ELINK_DEBUG_P1(sc, "BCM54618SE: link speed is %d\n",
11890                            vars->line_speed);
11891
11892                 elink_ext_phy_resolve_fc(phy, params, vars);
11893
11894                 if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
11895                         /* Report LP advertised speeds */
11896                         elink_cl22_read(sc, phy, 0x5, &val);
11897
11898                         if (val & (1<<5))
11899                                 vars->link_status |=
11900                                   LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
11901                         if (val & (1<<6))
11902                                 vars->link_status |=
11903                                   LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
11904                         if (val & (1<<7))
11905                                 vars->link_status |=
11906                                   LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
11907                         if (val & (1<<8))
11908                                 vars->link_status |=
11909                                   LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
11910                         if (val & (1<<9))
11911                                 vars->link_status |=
11912                                   LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
11913
11914                         elink_cl22_read(sc, phy, 0xa, &val);
11915                         if (val & (1<<10))
11916                                 vars->link_status |=
11917                                   LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
11918                         if (val & (1<<11))
11919                                 vars->link_status |=
11920                                   LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
11921
11922                         if ((phy->flags & ELINK_FLAGS_EEE) &&
11923                             elink_eee_has_cap(params))
11924                                 elink_eee_an_resolve(phy, params, vars);
11925                 }
11926         }
11927         return link_up;
11928 }
11929
11930 static void elink_54618se_config_loopback(struct elink_phy *phy,
11931                                           struct elink_params *params)
11932 {
11933         struct bxe_softc *sc = params->sc;
11934         uint16_t val;
11935         uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
11936
11937         ELINK_DEBUG_P0(sc, "2PMA/PMD ext_phy_loopback: 54618se\n");
11938
11939         /* Enable master/slave manual mmode and set to master */
11940         /* mii write 9 [bits set 11 12] */
11941         elink_cl22_write(sc, phy, 0x09, 3<<11);
11942
11943         /* forced 1G and disable autoneg */
11944         /* set val [mii read 0] */
11945         /* set val [expr $val & [bits clear 6 12 13]] */
11946         /* set val [expr $val | [bits set 6 8]] */
11947         /* mii write 0 $val */
11948         elink_cl22_read(sc, phy, 0x00, &val);
11949         val &= ~((1<<6) | (1<<12) | (1<<13));
11950         val |= (1<<6) | (1<<8);
11951         elink_cl22_write(sc, phy, 0x00, val);
11952
11953         /* Set external loopback and Tx using 6dB coding */
11954         /* mii write 0x18 7 */
11955         /* set val [mii read 0x18] */
11956         /* mii write 0x18 [expr $val | [bits set 10 15]] */
11957         elink_cl22_write(sc, phy, 0x18, 7);
11958         elink_cl22_read(sc, phy, 0x18, &val);
11959         elink_cl22_write(sc, phy, 0x18, val | (1<<10) | (1<<15));
11960
11961         /* This register opens the gate for the UMAC despite its name */
11962         REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
11963
11964         /* Maximum Frame Length (RW). Defines a 14-Bit maximum frame
11965          * length used by the MAC receive logic to check frames.
11966          */
11967         REG_WR(sc, umac_base + UMAC_REG_MAXFR, 0x2710);
11968 }
11969
11970 /******************************************************************/
11971 /*                      SFX7101 PHY SECTION                       */
11972 /******************************************************************/
11973 static void elink_7101_config_loopback(struct elink_phy *phy,
11974                                        struct elink_params *params)
11975 {
11976         struct bxe_softc *sc = params->sc;
11977         /* SFX7101_XGXS_TEST1 */
11978         elink_cl45_write(sc, phy,
11979                          MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
11980 }
11981
11982 static elink_status_t elink_7101_config_init(struct elink_phy *phy,
11983                                   struct elink_params *params,
11984                                   struct elink_vars *vars)
11985 {
11986         uint16_t fw_ver1, fw_ver2, val;
11987         struct bxe_softc *sc = params->sc;
11988         ELINK_DEBUG_P0(sc, "Setting the SFX7101 LASI indication\n");
11989
11990         /* Restore normal power mode*/
11991         elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
11992                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
11993         /* HW reset */
11994         elink_ext_phy_hw_reset(sc, params->port);
11995         elink_wait_reset_complete(sc, phy, params);
11996
11997         elink_cl45_write(sc, phy,
11998                          MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x1);
11999         ELINK_DEBUG_P0(sc, "Setting the SFX7101 LED to blink on traffic\n");
12000         elink_cl45_write(sc, phy,
12001                          MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
12002
12003         elink_ext_phy_set_pause(params, phy, vars);
12004         /* Restart autoneg */
12005         elink_cl45_read(sc, phy,
12006                         MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
12007         val |= 0x200;
12008         elink_cl45_write(sc, phy,
12009                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
12010
12011         /* Save spirom version */
12012         elink_cl45_read(sc, phy,
12013                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
12014
12015         elink_cl45_read(sc, phy,
12016                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
12017         elink_save_spirom_version(sc, params->port,
12018                                   (uint32_t)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
12019         return ELINK_STATUS_OK;
12020 }
12021
12022 static uint8_t elink_7101_read_status(struct elink_phy *phy,
12023                                  struct elink_params *params,
12024                                  struct elink_vars *vars)
12025 {
12026         struct bxe_softc *sc = params->sc;
12027         uint8_t link_up;
12028         uint16_t val1, val2;
12029         elink_cl45_read(sc, phy,
12030                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
12031         elink_cl45_read(sc, phy,
12032                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
12033         ELINK_DEBUG_P2(sc, "10G-base-T LASI status 0x%x->0x%x\n",
12034                    val2, val1);
12035         elink_cl45_read(sc, phy,
12036                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
12037         elink_cl45_read(sc, phy,
12038                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
12039         ELINK_DEBUG_P2(sc, "10G-base-T PMA status 0x%x->0x%x\n",
12040                    val2, val1);
12041         link_up = ((val1 & 4) == 4);
12042         /* If link is up print the AN outcome of the SFX7101 PHY */
12043         if (link_up) {
12044                 elink_cl45_read(sc, phy,
12045                                 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
12046                                 &val2);
12047                 vars->line_speed = ELINK_SPEED_10000;
12048                 vars->duplex = DUPLEX_FULL;
12049                 ELINK_DEBUG_P2(sc, "SFX7101 AN status 0x%x->Master=%x\n",
12050                            val2, (val2 & (1<<14)));
12051                 elink_ext_phy_10G_an_resolve(sc, phy, vars);
12052                 elink_ext_phy_resolve_fc(phy, params, vars);
12053
12054                 /* Read LP advertised speeds */
12055                 if (val2 & (1<<11))
12056                         vars->link_status |=
12057                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
12058         }
12059         return link_up;
12060 }
12061
12062 static elink_status_t elink_7101_format_ver(uint32_t spirom_ver, uint8_t *str, uint16_t *len)
12063 {
12064         if (*len < 5)
12065                 return ELINK_STATUS_ERROR;
12066         str[0] = (spirom_ver & 0xFF);
12067         str[1] = (spirom_ver & 0xFF00) >> 8;
12068         str[2] = (spirom_ver & 0xFF0000) >> 16;
12069         str[3] = (spirom_ver & 0xFF000000) >> 24;
12070         str[4] = '\0';
12071         *len -= 5;
12072         return ELINK_STATUS_OK;
12073 }
12074
12075 void elink_sfx7101_sp_sw_reset(struct bxe_softc *sc, struct elink_phy *phy)
12076 {
12077         uint16_t val, cnt;
12078
12079         elink_cl45_read(sc, phy,
12080                         MDIO_PMA_DEVAD,
12081                         MDIO_PMA_REG_7101_RESET, &val);
12082
12083         for (cnt = 0; cnt < 10; cnt++) {
12084                 DELAY(1000 * 50);
12085                 /* Writes a self-clearing reset */
12086                 elink_cl45_write(sc, phy,
12087                                  MDIO_PMA_DEVAD,
12088                                  MDIO_PMA_REG_7101_RESET,
12089                                  (val | (1<<15)));
12090                 /* Wait for clear */
12091                 elink_cl45_read(sc, phy,
12092                                 MDIO_PMA_DEVAD,
12093                                 MDIO_PMA_REG_7101_RESET, &val);
12094
12095                 if ((val & (1<<15)) == 0)
12096                         break;
12097         }
12098 }
12099
12100 static void elink_7101_hw_reset(struct elink_phy *phy,
12101                                 struct elink_params *params) {
12102         /* Low power mode is controlled by GPIO 2 */
12103         elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_2,
12104                        MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
12105         /* The PHY reset is controlled by GPIO 1 */
12106         elink_cb_gpio_write(params->sc, MISC_REGISTERS_GPIO_1,
12107                        MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
12108 }
12109
12110 static void elink_7101_set_link_led(struct elink_phy *phy,
12111                                     struct elink_params *params, uint8_t mode)
12112 {
12113         uint16_t val = 0;
12114         struct bxe_softc *sc = params->sc;
12115         switch (mode) {
12116         case ELINK_LED_MODE_FRONT_PANEL_OFF:
12117         case ELINK_LED_MODE_OFF:
12118                 val = 2;
12119                 break;
12120         case ELINK_LED_MODE_ON:
12121                 val = 1;
12122                 break;
12123         case ELINK_LED_MODE_OPER:
12124                 val = 0;
12125                 break;
12126         }
12127         elink_cl45_write(sc, phy,
12128                          MDIO_PMA_DEVAD,
12129                          MDIO_PMA_REG_7107_LINK_LED_CNTL,
12130                          val);
12131 }
12132
12133 /******************************************************************/
12134 /*                      STATIC PHY DECLARATION                    */
12135 /******************************************************************/
12136
12137 static const struct elink_phy phy_null = {
12138         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
12139         .addr           = 0,
12140         .def_md_devad   = 0,
12141         .flags          = ELINK_FLAGS_INIT_XGXS_FIRST,
12142         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12143         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12144         .mdio_ctrl      = 0,
12145         .supported      = 0,
12146         .media_type     = ELINK_ETH_PHY_NOT_PRESENT,
12147         .ver_addr       = 0,
12148         .req_flow_ctrl  = 0,
12149         .req_line_speed = 0,
12150         .speed_cap_mask = 0,
12151         .req_duplex     = 0,
12152         .rsrv           = 0,
12153         .config_init    = (config_init_t)NULL,
12154         .read_status    = (read_status_t)NULL,
12155         .link_reset     = (link_reset_t)NULL,
12156         .config_loopback = (config_loopback_t)NULL,
12157         .format_fw_ver  = (format_fw_ver_t)NULL,
12158         .hw_reset       = (hw_reset_t)NULL,
12159         .set_link_led   = (set_link_led_t)NULL,
12160         .phy_specific_func = (phy_specific_func_t)NULL
12161 };
12162
12163 static const struct elink_phy phy_serdes = {
12164         .type           = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
12165         .addr           = 0xff,
12166         .def_md_devad   = 0,
12167         .flags          = 0,
12168         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12169         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12170         .mdio_ctrl      = 0,
12171         .supported      = (ELINK_SUPPORTED_10baseT_Half |
12172                            ELINK_SUPPORTED_10baseT_Full |
12173                            ELINK_SUPPORTED_100baseT_Half |
12174                            ELINK_SUPPORTED_100baseT_Full |
12175                            ELINK_SUPPORTED_1000baseT_Full |
12176                            ELINK_SUPPORTED_2500baseX_Full |
12177                            ELINK_SUPPORTED_TP |
12178                            ELINK_SUPPORTED_Autoneg |
12179                            ELINK_SUPPORTED_Pause |
12180                            ELINK_SUPPORTED_Asym_Pause),
12181         .media_type     = ELINK_ETH_PHY_BASE_T,
12182         .ver_addr       = 0,
12183         .req_flow_ctrl  = 0,
12184         .req_line_speed = 0,
12185         .speed_cap_mask = 0,
12186         .req_duplex     = 0,
12187         .rsrv           = 0,
12188         .config_init    = (config_init_t)elink_xgxs_config_init,
12189         .read_status    = (read_status_t)elink_link_settings_status,
12190         .link_reset     = (link_reset_t)elink_int_link_reset,
12191         .config_loopback = (config_loopback_t)NULL,
12192         .format_fw_ver  = (format_fw_ver_t)NULL,
12193         .hw_reset       = (hw_reset_t)NULL,
12194         .set_link_led   = (set_link_led_t)NULL,
12195         .phy_specific_func = (phy_specific_func_t)NULL
12196 };
12197
12198 static const struct elink_phy phy_xgxs = {
12199         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
12200         .addr           = 0xff,
12201         .def_md_devad   = 0,
12202         .flags          = 0,
12203         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12204         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12205         .mdio_ctrl      = 0,
12206         .supported      = (ELINK_SUPPORTED_10baseT_Half |
12207                            ELINK_SUPPORTED_10baseT_Full |
12208                            ELINK_SUPPORTED_100baseT_Half |
12209                            ELINK_SUPPORTED_100baseT_Full |
12210                            ELINK_SUPPORTED_1000baseT_Full |
12211                            ELINK_SUPPORTED_2500baseX_Full |
12212                            ELINK_SUPPORTED_10000baseT_Full |
12213                            ELINK_SUPPORTED_FIBRE |
12214                            ELINK_SUPPORTED_Autoneg |
12215                            ELINK_SUPPORTED_Pause |
12216                            ELINK_SUPPORTED_Asym_Pause),
12217         .media_type     = ELINK_ETH_PHY_CX4,
12218         .ver_addr       = 0,
12219         .req_flow_ctrl  = 0,
12220         .req_line_speed = 0,
12221         .speed_cap_mask = 0,
12222         .req_duplex     = 0,
12223         .rsrv           = 0,
12224         .config_init    = (config_init_t)elink_xgxs_config_init,
12225         .read_status    = (read_status_t)elink_link_settings_status,
12226         .link_reset     = (link_reset_t)elink_int_link_reset,
12227         .config_loopback = (config_loopback_t)elink_set_xgxs_loopback,
12228         .format_fw_ver  = (format_fw_ver_t)NULL,
12229         .hw_reset       = (hw_reset_t)NULL,
12230         .set_link_led   = (set_link_led_t)NULL,
12231         .phy_specific_func = (phy_specific_func_t)elink_xgxs_specific_func
12232 };
12233 static const struct elink_phy phy_warpcore = {
12234         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
12235         .addr           = 0xff,
12236         .def_md_devad   = 0,
12237         .flags          = ELINK_FLAGS_TX_ERROR_CHECK,
12238         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12239         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12240         .mdio_ctrl      = 0,
12241         .supported      = (ELINK_SUPPORTED_10baseT_Half |
12242                            ELINK_SUPPORTED_10baseT_Full |
12243                            ELINK_SUPPORTED_100baseT_Half |
12244                            ELINK_SUPPORTED_100baseT_Full |
12245                            ELINK_SUPPORTED_1000baseT_Full |
12246                            ELINK_SUPPORTED_10000baseT_Full |
12247                            ELINK_SUPPORTED_20000baseKR2_Full |
12248                            ELINK_SUPPORTED_20000baseMLD2_Full |
12249                            ELINK_SUPPORTED_FIBRE |
12250                            ELINK_SUPPORTED_Autoneg |
12251                            ELINK_SUPPORTED_Pause |
12252                            ELINK_SUPPORTED_Asym_Pause),
12253         .media_type     = ELINK_ETH_PHY_UNSPECIFIED,
12254         .ver_addr       = 0,
12255         .req_flow_ctrl  = 0,
12256         .req_line_speed = 0,
12257         .speed_cap_mask = 0,
12258         /* req_duplex = */0,
12259         /* rsrv = */0,
12260         .config_init    = (config_init_t)elink_warpcore_config_init,
12261         .read_status    = (read_status_t)elink_warpcore_read_status,
12262         .link_reset     = (link_reset_t)elink_warpcore_link_reset,
12263         .config_loopback = (config_loopback_t)elink_set_warpcore_loopback,
12264         .format_fw_ver  = (format_fw_ver_t)NULL,
12265         .hw_reset       = (hw_reset_t)elink_warpcore_hw_reset,
12266         .set_link_led   = (set_link_led_t)NULL,
12267         .phy_specific_func = (phy_specific_func_t)NULL
12268 };
12269
12270
12271 static const struct elink_phy phy_7101 = {
12272         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
12273         .addr           = 0xff,
12274         .def_md_devad   = 0,
12275         .flags          = ELINK_FLAGS_FAN_FAILURE_DET_REQ,
12276         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12277         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12278         .mdio_ctrl      = 0,
12279         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12280                            ELINK_SUPPORTED_TP |
12281                            ELINK_SUPPORTED_Autoneg |
12282                            ELINK_SUPPORTED_Pause |
12283                            ELINK_SUPPORTED_Asym_Pause),
12284         .media_type     = ELINK_ETH_PHY_BASE_T,
12285         .ver_addr       = 0,
12286         .req_flow_ctrl  = 0,
12287         .req_line_speed = 0,
12288         .speed_cap_mask = 0,
12289         .req_duplex     = 0,
12290         .rsrv           = 0,
12291         .config_init    = (config_init_t)elink_7101_config_init,
12292         .read_status    = (read_status_t)elink_7101_read_status,
12293         .link_reset     = (link_reset_t)elink_common_ext_link_reset,
12294         .config_loopback = (config_loopback_t)elink_7101_config_loopback,
12295         .format_fw_ver  = (format_fw_ver_t)elink_7101_format_ver,
12296         .hw_reset       = (hw_reset_t)elink_7101_hw_reset,
12297         .set_link_led   = (set_link_led_t)elink_7101_set_link_led,
12298         .phy_specific_func = (phy_specific_func_t)NULL
12299 };
12300 static const struct elink_phy phy_8073 = {
12301         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
12302         .addr           = 0xff,
12303         .def_md_devad   = 0,
12304         .flags          = 0,
12305         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12306         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12307         .mdio_ctrl      = 0,
12308         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12309                            ELINK_SUPPORTED_2500baseX_Full |
12310                            ELINK_SUPPORTED_1000baseT_Full |
12311                            ELINK_SUPPORTED_FIBRE |
12312                            ELINK_SUPPORTED_Autoneg |
12313                            ELINK_SUPPORTED_Pause |
12314                            ELINK_SUPPORTED_Asym_Pause),
12315         .media_type     = ELINK_ETH_PHY_KR,
12316         .ver_addr       = 0,
12317         .req_flow_ctrl  = 0,
12318         .req_line_speed = 0,
12319         .speed_cap_mask = 0,
12320         .req_duplex     = 0,
12321         .rsrv           = 0,
12322         .config_init    = (config_init_t)elink_8073_config_init,
12323         .read_status    = (read_status_t)elink_8073_read_status,
12324         .link_reset     = (link_reset_t)elink_8073_link_reset,
12325         .config_loopback = (config_loopback_t)NULL,
12326         .format_fw_ver  = (format_fw_ver_t)elink_format_ver,
12327         .hw_reset       = (hw_reset_t)NULL,
12328         .set_link_led   = (set_link_led_t)NULL,
12329         .phy_specific_func = (phy_specific_func_t)elink_8073_specific_func
12330 };
12331 static const struct elink_phy phy_8705 = {
12332         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
12333         .addr           = 0xff,
12334         .def_md_devad   = 0,
12335         .flags          = ELINK_FLAGS_INIT_XGXS_FIRST,
12336         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12337         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12338         .mdio_ctrl      = 0,
12339         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12340                            ELINK_SUPPORTED_FIBRE |
12341                            ELINK_SUPPORTED_Pause |
12342                            ELINK_SUPPORTED_Asym_Pause),
12343         .media_type     = ELINK_ETH_PHY_XFP_FIBER,
12344         .ver_addr       = 0,
12345         .req_flow_ctrl  = 0,
12346         .req_line_speed = 0,
12347         .speed_cap_mask = 0,
12348         .req_duplex     = 0,
12349         .rsrv           = 0,
12350         .config_init    = (config_init_t)elink_8705_config_init,
12351         .read_status    = (read_status_t)elink_8705_read_status,
12352         .link_reset     = (link_reset_t)elink_common_ext_link_reset,
12353         .config_loopback = (config_loopback_t)NULL,
12354         .format_fw_ver  = (format_fw_ver_t)elink_null_format_ver,
12355         .hw_reset       = (hw_reset_t)NULL,
12356         .set_link_led   = (set_link_led_t)NULL,
12357         .phy_specific_func = (phy_specific_func_t)NULL
12358 };
12359 static const struct elink_phy phy_8706 = {
12360         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
12361         .addr           = 0xff,
12362         .def_md_devad   = 0,
12363         .flags          = ELINK_FLAGS_INIT_XGXS_FIRST,
12364         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12365         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12366         .mdio_ctrl      = 0,
12367         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12368                            ELINK_SUPPORTED_1000baseT_Full |
12369                            ELINK_SUPPORTED_FIBRE |
12370                            ELINK_SUPPORTED_Pause |
12371                            ELINK_SUPPORTED_Asym_Pause),
12372         .media_type     = ELINK_ETH_PHY_SFPP_10G_FIBER,
12373         .ver_addr       = 0,
12374         .req_flow_ctrl  = 0,
12375         .req_line_speed = 0,
12376         .speed_cap_mask = 0,
12377         .req_duplex     = 0,
12378         .rsrv           = 0,
12379         .config_init    = (config_init_t)elink_8706_config_init,
12380         .read_status    = (read_status_t)elink_8706_read_status,
12381         .link_reset     = (link_reset_t)elink_common_ext_link_reset,
12382         .config_loopback = (config_loopback_t)NULL,
12383         .format_fw_ver  = (format_fw_ver_t)elink_format_ver,
12384         .hw_reset       = (hw_reset_t)NULL,
12385         .set_link_led   = (set_link_led_t)NULL,
12386         .phy_specific_func = (phy_specific_func_t)NULL
12387 };
12388
12389 static const struct elink_phy phy_8726 = {
12390         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
12391         .addr           = 0xff,
12392         .def_md_devad   = 0,
12393         .flags          = (ELINK_FLAGS_INIT_XGXS_FIRST |
12394                            ELINK_FLAGS_TX_ERROR_CHECK),
12395         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12396         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12397         .mdio_ctrl      = 0,
12398         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12399                            ELINK_SUPPORTED_1000baseT_Full |
12400                            ELINK_SUPPORTED_Autoneg |
12401                            ELINK_SUPPORTED_FIBRE |
12402                            ELINK_SUPPORTED_Pause |
12403                            ELINK_SUPPORTED_Asym_Pause),
12404         .media_type     = ELINK_ETH_PHY_NOT_PRESENT,
12405         .ver_addr       = 0,
12406         .req_flow_ctrl  = 0,
12407         .req_line_speed = 0,
12408         .speed_cap_mask = 0,
12409         .req_duplex     = 0,
12410         .rsrv           = 0,
12411         .config_init    = (config_init_t)elink_8726_config_init,
12412         .read_status    = (read_status_t)elink_8726_read_status,
12413         .link_reset     = (link_reset_t)elink_8726_link_reset,
12414         .config_loopback = (config_loopback_t)elink_8726_config_loopback,
12415         .format_fw_ver  = (format_fw_ver_t)elink_format_ver,
12416         .hw_reset       = (hw_reset_t)NULL,
12417         .set_link_led   = (set_link_led_t)NULL,
12418         .phy_specific_func = (phy_specific_func_t)NULL
12419 };
12420
12421 static const struct elink_phy phy_8727 = {
12422         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
12423         .addr           = 0xff,
12424         .def_md_devad   = 0,
12425         .flags          = (ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12426                            ELINK_FLAGS_TX_ERROR_CHECK),
12427         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12428         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12429         .mdio_ctrl      = 0,
12430         .supported      = (ELINK_SUPPORTED_10000baseT_Full |
12431                            ELINK_SUPPORTED_1000baseT_Full |
12432                            ELINK_SUPPORTED_FIBRE |
12433                            ELINK_SUPPORTED_Pause |
12434                            ELINK_SUPPORTED_Asym_Pause),
12435         .media_type     = ELINK_ETH_PHY_NOT_PRESENT,
12436         .ver_addr       = 0,
12437         .req_flow_ctrl  = 0,
12438         .req_line_speed = 0,
12439         .speed_cap_mask = 0,
12440         .req_duplex     = 0,
12441         .rsrv           = 0,
12442         .config_init    = (config_init_t)elink_8727_config_init,
12443         .read_status    = (read_status_t)elink_8727_read_status,
12444         .link_reset     = (link_reset_t)elink_8727_link_reset,
12445         .config_loopback = (config_loopback_t)NULL,
12446         .format_fw_ver  = (format_fw_ver_t)elink_format_ver,
12447         .hw_reset       = (hw_reset_t)elink_8727_hw_reset,
12448         .set_link_led   = (set_link_led_t)elink_8727_set_link_led,
12449         .phy_specific_func = (phy_specific_func_t)elink_8727_specific_func
12450 };
12451 static const struct elink_phy phy_8481 = {
12452         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
12453         .addr           = 0xff,
12454         .def_md_devad   = 0,
12455         .flags          = ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12456                           ELINK_FLAGS_REARM_LATCH_SIGNAL,
12457         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12458         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12459         .mdio_ctrl      = 0,
12460         .supported      = (ELINK_SUPPORTED_10baseT_Half |
12461                            ELINK_SUPPORTED_10baseT_Full |
12462                            ELINK_SUPPORTED_100baseT_Half |
12463                            ELINK_SUPPORTED_100baseT_Full |
12464                            ELINK_SUPPORTED_1000baseT_Full |
12465                            ELINK_SUPPORTED_10000baseT_Full |
12466                            ELINK_SUPPORTED_TP |
12467                            ELINK_SUPPORTED_Autoneg |
12468                            ELINK_SUPPORTED_Pause |
12469                            ELINK_SUPPORTED_Asym_Pause),
12470         .media_type     = ELINK_ETH_PHY_BASE_T,
12471         .ver_addr       = 0,
12472         .req_flow_ctrl  = 0,
12473         .req_line_speed = 0,
12474         .speed_cap_mask = 0,
12475         .req_duplex     = 0,
12476         .rsrv           = 0,
12477         .config_init    = (config_init_t)elink_8481_config_init,
12478         .read_status    = (read_status_t)elink_848xx_read_status,
12479         .link_reset     = (link_reset_t)elink_8481_link_reset,
12480         .config_loopback = (config_loopback_t)NULL,
12481         .format_fw_ver  = (format_fw_ver_t)elink_848xx_format_ver,
12482         .hw_reset       = (hw_reset_t)elink_8481_hw_reset,
12483         .set_link_led   = (set_link_led_t)elink_848xx_set_link_led,
12484         .phy_specific_func = (phy_specific_func_t)NULL
12485 };
12486
12487 static const struct elink_phy phy_84823 = {
12488         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
12489         .addr           = 0xff,
12490         .def_md_devad   = 0,
12491         .flags          = (ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12492                            ELINK_FLAGS_REARM_LATCH_SIGNAL |
12493                            ELINK_FLAGS_TX_ERROR_CHECK),
12494         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12495         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12496         .mdio_ctrl      = 0,
12497         .supported      = (ELINK_SUPPORTED_10baseT_Half |
12498                            ELINK_SUPPORTED_10baseT_Full |
12499                            ELINK_SUPPORTED_100baseT_Half |
12500                            ELINK_SUPPORTED_100baseT_Full |
12501                            ELINK_SUPPORTED_1000baseT_Full |
12502                            ELINK_SUPPORTED_10000baseT_Full |
12503                            ELINK_SUPPORTED_TP |
12504                            ELINK_SUPPORTED_Autoneg |
12505                            ELINK_SUPPORTED_Pause |
12506                            ELINK_SUPPORTED_Asym_Pause),
12507         .media_type     = ELINK_ETH_PHY_BASE_T,
12508         .ver_addr       = 0,
12509         .req_flow_ctrl  = 0,
12510         .req_line_speed = 0,
12511         .speed_cap_mask = 0,
12512         .req_duplex     = 0,
12513         .rsrv           = 0,
12514         .config_init    = (config_init_t)elink_848x3_config_init,
12515         .read_status    = (read_status_t)elink_848xx_read_status,
12516         .link_reset     = (link_reset_t)elink_848x3_link_reset,
12517         .config_loopback = (config_loopback_t)NULL,
12518         .format_fw_ver  = (format_fw_ver_t)elink_848xx_format_ver,
12519         .hw_reset       = (hw_reset_t)NULL,
12520         .set_link_led   = (set_link_led_t)elink_848xx_set_link_led,
12521         .phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12522 };
12523
12524 static const struct elink_phy phy_84833 = {
12525         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833,
12526         .addr           = 0xff,
12527         .def_md_devad   = 0,
12528         .flags          = (ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12529                            ELINK_FLAGS_REARM_LATCH_SIGNAL |
12530                            ELINK_FLAGS_TX_ERROR_CHECK |
12531                            ELINK_FLAGS_TEMPERATURE),
12532         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12533         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12534         .mdio_ctrl      = 0,
12535         .supported      = (ELINK_SUPPORTED_100baseT_Half |
12536                            ELINK_SUPPORTED_100baseT_Full |
12537                            ELINK_SUPPORTED_1000baseT_Full |
12538                            ELINK_SUPPORTED_10000baseT_Full |
12539                            ELINK_SUPPORTED_TP |
12540                            ELINK_SUPPORTED_Autoneg |
12541                            ELINK_SUPPORTED_Pause |
12542                            ELINK_SUPPORTED_Asym_Pause),
12543         .media_type     = ELINK_ETH_PHY_BASE_T,
12544         .ver_addr       = 0,
12545         .req_flow_ctrl  = 0,
12546         .req_line_speed = 0,
12547         .speed_cap_mask = 0,
12548         .req_duplex     = 0,
12549         .rsrv           = 0,
12550         .config_init    = (config_init_t)elink_848x3_config_init,
12551         .read_status    = (read_status_t)elink_848xx_read_status,
12552         .link_reset     = (link_reset_t)elink_848x3_link_reset,
12553         .config_loopback = (config_loopback_t)NULL,
12554         .format_fw_ver  = (format_fw_ver_t)elink_848xx_format_ver,
12555         .hw_reset       = (hw_reset_t)elink_84833_hw_reset_phy,
12556         .set_link_led   = (set_link_led_t)elink_848xx_set_link_led,
12557         .phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12558 };
12559
12560 static const struct elink_phy phy_84834 = {
12561         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834,
12562         .addr           = 0xff,
12563         .def_md_devad   = 0,
12564         .flags          = ELINK_FLAGS_FAN_FAILURE_DET_REQ |
12565                             ELINK_FLAGS_REARM_LATCH_SIGNAL,
12566         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12567         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12568         .mdio_ctrl      = 0,
12569         .supported      = (ELINK_SUPPORTED_100baseT_Half |
12570                            ELINK_SUPPORTED_100baseT_Full |
12571                            ELINK_SUPPORTED_1000baseT_Full |
12572                            ELINK_SUPPORTED_10000baseT_Full |
12573                            ELINK_SUPPORTED_TP |
12574                            ELINK_SUPPORTED_Autoneg |
12575                            ELINK_SUPPORTED_Pause |
12576                            ELINK_SUPPORTED_Asym_Pause),
12577         .media_type     = ELINK_ETH_PHY_BASE_T,
12578         .ver_addr       = 0,
12579         .req_flow_ctrl  = 0,
12580         .req_line_speed = 0,
12581         .speed_cap_mask = 0,
12582         .req_duplex     = 0,
12583         .rsrv           = 0,
12584         .config_init    = (config_init_t)elink_848x3_config_init,
12585         .read_status    = (read_status_t)elink_848xx_read_status,
12586         .link_reset     = (link_reset_t)elink_848x3_link_reset,
12587         .config_loopback = (config_loopback_t)NULL,
12588         .format_fw_ver  = (format_fw_ver_t)elink_848xx_format_ver,
12589         .hw_reset       = (hw_reset_t)elink_84833_hw_reset_phy,
12590         .set_link_led   = (set_link_led_t)elink_848xx_set_link_led,
12591         .phy_specific_func = (phy_specific_func_t)elink_848xx_specific_func
12592 };
12593
12594 static const struct elink_phy phy_54618se = {
12595         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE,
12596         .addr           = 0xff,
12597         .def_md_devad   = 0,
12598         .flags          = ELINK_FLAGS_INIT_XGXS_FIRST,
12599         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12600         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
12601         .mdio_ctrl      = 0,
12602         .supported      = (ELINK_SUPPORTED_10baseT_Half |
12603                            ELINK_SUPPORTED_10baseT_Full |
12604                            ELINK_SUPPORTED_100baseT_Half |
12605                            ELINK_SUPPORTED_100baseT_Full |
12606                            ELINK_SUPPORTED_1000baseT_Full |
12607                            ELINK_SUPPORTED_TP |
12608                            ELINK_SUPPORTED_Autoneg |
12609                            ELINK_SUPPORTED_Pause |
12610                            ELINK_SUPPORTED_Asym_Pause),
12611         .media_type     = ELINK_ETH_PHY_BASE_T,
12612         .ver_addr       = 0,
12613         .req_flow_ctrl  = 0,
12614         .req_line_speed = 0,
12615         .speed_cap_mask = 0,
12616         /* req_duplex = */0,
12617         /* rsrv = */0,
12618         .config_init    = (config_init_t)elink_54618se_config_init,
12619         .read_status    = (read_status_t)elink_54618se_read_status,
12620         .link_reset     = (link_reset_t)elink_54618se_link_reset,
12621         .config_loopback = (config_loopback_t)elink_54618se_config_loopback,
12622         .format_fw_ver  = (format_fw_ver_t)NULL,
12623         .hw_reset       = (hw_reset_t)NULL,
12624         .set_link_led   = (set_link_led_t)elink_5461x_set_link_led,
12625         .phy_specific_func = (phy_specific_func_t)elink_54618se_specific_func
12626 };
12627 /*****************************************************************/
12628 /*                                                               */
12629 /* Populate the phy according. Main function: elink_populate_phy   */
12630 /*                                                               */
12631 /*****************************************************************/
12632
12633 static void elink_populate_preemphasis(struct bxe_softc *sc, uint32_t shmem_base,
12634                                      struct elink_phy *phy, uint8_t port,
12635                                      uint8_t phy_index)
12636 {
12637         /* Get the 4 lanes xgxs config rx and tx */
12638         uint32_t rx = 0, tx = 0, i;
12639         for (i = 0; i < 2; i++) {
12640                 /* INT_PHY and ELINK_EXT_PHY1 share the same value location in
12641                  * the shmem. When num_phys is greater than 1, than this value
12642                  * applies only to ELINK_EXT_PHY1
12643                  */
12644                 if (phy_index == ELINK_INT_PHY || phy_index == ELINK_EXT_PHY1) {
12645                         rx = REG_RD(sc, shmem_base +
12646                                     offsetof(struct shmem_region,
12647                           dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
12648
12649                         tx = REG_RD(sc, shmem_base +
12650                                     offsetof(struct shmem_region,
12651                           dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
12652                 } else {
12653                         rx = REG_RD(sc, shmem_base +
12654                                     offsetof(struct shmem_region,
12655                          dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
12656
12657                         tx = REG_RD(sc, shmem_base +
12658                                     offsetof(struct shmem_region,
12659                          dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
12660                 }
12661
12662                 phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
12663                 phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
12664
12665                 phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
12666                 phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
12667         }
12668 }
12669
12670 static uint32_t elink_get_ext_phy_config(struct bxe_softc *sc, uint32_t shmem_base,
12671                                     uint8_t phy_index, uint8_t port)
12672 {
12673         uint32_t ext_phy_config = 0;
12674         switch (phy_index) {
12675         case ELINK_EXT_PHY1:
12676                 ext_phy_config = REG_RD(sc, shmem_base +
12677                                               offsetof(struct shmem_region,
12678                         dev_info.port_hw_config[port].external_phy_config));
12679                 break;
12680         case ELINK_EXT_PHY2:
12681                 ext_phy_config = REG_RD(sc, shmem_base +
12682                                               offsetof(struct shmem_region,
12683                         dev_info.port_hw_config[port].external_phy_config2));
12684                 break;
12685         default:
12686                 ELINK_DEBUG_P1(sc, "Invalid phy_index %d\n", phy_index);
12687                 return ELINK_STATUS_ERROR;
12688         }
12689
12690         return ext_phy_config;
12691 }
12692 static elink_status_t elink_populate_int_phy(struct bxe_softc *sc, uint32_t shmem_base, uint8_t port,
12693                                   struct elink_phy *phy)
12694 {
12695         uint32_t phy_addr;
12696         uint32_t chip_id;
12697         uint32_t switch_cfg = (REG_RD(sc, shmem_base +
12698                                        offsetof(struct shmem_region,
12699                         dev_info.port_feature_config[port].link_config)) &
12700                           PORT_FEATURE_CONNECTED_SWITCH_MASK);
12701         chip_id = (REG_RD(sc, MISC_REG_CHIP_NUM) << 16) |
12702                 ((REG_RD(sc, MISC_REG_CHIP_REV) & 0xf) << 12);
12703
12704         ELINK_DEBUG_P1(sc, ":chip_id = 0x%x\n", chip_id);
12705         if (USES_WARPCORE(sc)) {
12706                 uint32_t serdes_net_if;
12707                 phy_addr = REG_RD(sc,
12708                                   MISC_REG_WC0_CTRL_PHY_ADDR);
12709                 *phy = phy_warpcore;
12710                 if (REG_RD(sc, MISC_REG_PORT4MODE_EN_OVWR) == 0x3)
12711                         phy->flags |= ELINK_FLAGS_4_PORT_MODE;
12712                 else
12713                         phy->flags &= ~ELINK_FLAGS_4_PORT_MODE;
12714                         /* Check Dual mode */
12715                 serdes_net_if = (REG_RD(sc, shmem_base +
12716                                         offsetof(struct shmem_region, dev_info.
12717                                         port_hw_config[port].default_cfg)) &
12718                                  PORT_HW_CFG_NET_SERDES_IF_MASK);
12719                 /* Set the appropriate supported and flags indications per
12720                  * interface type of the chip
12721                  */
12722                 switch (serdes_net_if) {
12723                 case PORT_HW_CFG_NET_SERDES_IF_SGMII:
12724                         phy->supported &= (ELINK_SUPPORTED_10baseT_Half |
12725                                            ELINK_SUPPORTED_10baseT_Full |
12726                                            ELINK_SUPPORTED_100baseT_Half |
12727                                            ELINK_SUPPORTED_100baseT_Full |
12728                                            ELINK_SUPPORTED_1000baseT_Full |
12729                                            ELINK_SUPPORTED_FIBRE |
12730                                            ELINK_SUPPORTED_Autoneg |
12731                                            ELINK_SUPPORTED_Pause |
12732                                            ELINK_SUPPORTED_Asym_Pause);
12733                         phy->media_type = ELINK_ETH_PHY_BASE_T;
12734                         break;
12735                 case PORT_HW_CFG_NET_SERDES_IF_XFI:
12736                         phy->supported &= (ELINK_SUPPORTED_1000baseT_Full |
12737                                            ELINK_SUPPORTED_10000baseT_Full |
12738                                            ELINK_SUPPORTED_FIBRE |
12739                                            ELINK_SUPPORTED_Pause |
12740                                            ELINK_SUPPORTED_Asym_Pause);
12741                         phy->media_type = ELINK_ETH_PHY_XFP_FIBER;
12742                         break;
12743                 case PORT_HW_CFG_NET_SERDES_IF_SFI:
12744                         phy->supported &= (ELINK_SUPPORTED_1000baseT_Full |
12745                                            ELINK_SUPPORTED_10000baseT_Full |
12746                                            ELINK_SUPPORTED_FIBRE |
12747                                            ELINK_SUPPORTED_Pause |
12748                                            ELINK_SUPPORTED_Asym_Pause);
12749                         phy->media_type = ELINK_ETH_PHY_SFPP_10G_FIBER;
12750                         break;
12751                 case PORT_HW_CFG_NET_SERDES_IF_KR:
12752                         phy->media_type = ELINK_ETH_PHY_KR;
12753                         phy->supported &= (ELINK_SUPPORTED_1000baseT_Full |
12754                                            ELINK_SUPPORTED_10000baseT_Full |
12755                                            ELINK_SUPPORTED_FIBRE |
12756                                            ELINK_SUPPORTED_Autoneg |
12757                                            ELINK_SUPPORTED_Pause |
12758                                            ELINK_SUPPORTED_Asym_Pause);
12759                         break;
12760                 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
12761                         phy->media_type = ELINK_ETH_PHY_KR;
12762                         phy->flags |= ELINK_FLAGS_WC_DUAL_MODE;
12763                         phy->supported &= (ELINK_SUPPORTED_20000baseMLD2_Full |
12764                                            ELINK_SUPPORTED_FIBRE |
12765                                            ELINK_SUPPORTED_Pause |
12766                                            ELINK_SUPPORTED_Asym_Pause);
12767                         break;
12768                 case PORT_HW_CFG_NET_SERDES_IF_KR2:
12769                         phy->media_type = ELINK_ETH_PHY_KR;
12770                         phy->flags |= ELINK_FLAGS_WC_DUAL_MODE;
12771                         phy->supported &= (ELINK_SUPPORTED_20000baseKR2_Full |
12772                                            ELINK_SUPPORTED_10000baseT_Full |
12773                                            ELINK_SUPPORTED_1000baseT_Full |
12774                                            ELINK_SUPPORTED_Autoneg |
12775                                            ELINK_SUPPORTED_FIBRE |
12776                                            ELINK_SUPPORTED_Pause |
12777                                            ELINK_SUPPORTED_Asym_Pause);
12778                         phy->flags &= ~ELINK_FLAGS_TX_ERROR_CHECK;
12779                         break;
12780                 default:
12781                         ELINK_DEBUG_P1(sc, "Unknown WC interface type 0x%x\n",
12782                                        serdes_net_if);
12783                         break;
12784                 }
12785
12786                 /* Enable MDC/MDIO work-around for E3 A0 since free running MDC
12787                  * was not set as expected. For B0, ECO will be enabled so there
12788                  * won't be an issue there
12789                  */
12790                 if (CHIP_REV(sc) == CHIP_REV_Ax)
12791                         phy->flags |= ELINK_FLAGS_MDC_MDIO_WA;
12792                 else
12793                         phy->flags |= ELINK_FLAGS_MDC_MDIO_WA_B0;
12794         } else
12795         {
12796                 switch (switch_cfg) {
12797                 case ELINK_SWITCH_CFG_1G:
12798                         phy_addr = REG_RD(sc,
12799                                           NIG_REG_SERDES0_CTRL_PHY_ADDR +
12800                                           port * 0x10);
12801                         *phy = phy_serdes;
12802                         break;
12803                 case ELINK_SWITCH_CFG_10G:
12804                         phy_addr = REG_RD(sc,
12805                                           NIG_REG_XGXS0_CTRL_PHY_ADDR +
12806                                           port * 0x18);
12807                         *phy = phy_xgxs;
12808                         break;
12809                 default:
12810                         ELINK_DEBUG_P0(sc, "Invalid switch_cfg\n");
12811                         return ELINK_STATUS_ERROR;
12812                 }
12813         }
12814         phy->addr = (uint8_t)phy_addr;
12815         phy->mdio_ctrl = elink_get_emac_base(sc,
12816                                             SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
12817                                             port);
12818         if (CHIP_IS_E2(sc))
12819                 phy->def_md_devad = ELINK_E2_DEFAULT_PHY_DEV_ADDR;
12820         else
12821                 phy->def_md_devad = ELINK_DEFAULT_PHY_DEV_ADDR;
12822
12823         ELINK_DEBUG_P3(sc, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
12824                    port, phy->addr, phy->mdio_ctrl);
12825
12826         elink_populate_preemphasis(sc, shmem_base, phy, port, ELINK_INT_PHY);
12827         return ELINK_STATUS_OK;
12828 }
12829
12830 static elink_status_t elink_populate_ext_phy(struct bxe_softc *sc,
12831                                   uint8_t phy_index,
12832                                   uint32_t shmem_base,
12833                                   uint32_t shmem2_base,
12834                                   uint8_t port,
12835                                   struct elink_phy *phy)
12836 {
12837         uint32_t ext_phy_config, phy_type, config2;
12838         uint32_t mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
12839         ext_phy_config = elink_get_ext_phy_config(sc, shmem_base,
12840                                                   phy_index, port);
12841         phy_type = ELINK_XGXS_EXT_PHY_TYPE(ext_phy_config);
12842         /* Select the phy type */
12843         switch (phy_type) {
12844         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
12845                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
12846                 *phy = phy_8073;
12847                 break;
12848         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
12849                 *phy = phy_8705;
12850                 break;
12851         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
12852                 *phy = phy_8706;
12853                 break;
12854         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
12855                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
12856                 *phy = phy_8726;
12857                 break;
12858         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
12859                 /* BCM8727_NOC => BCM8727 no over current */
12860                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
12861                 *phy = phy_8727;
12862                 phy->flags |= ELINK_FLAGS_NOC;
12863                 break;
12864         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
12865         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
12866                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
12867                 *phy = phy_8727;
12868                 break;
12869         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
12870                 *phy = phy_8481;
12871                 break;
12872         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
12873                 *phy = phy_84823;
12874                 break;
12875         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
12876                 *phy = phy_84833;
12877                 break;
12878         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834:
12879                 *phy = phy_84834;
12880                 break;
12881         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616:
12882         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE:
12883                 *phy = phy_54618se;
12884                 if (phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
12885                         phy->flags |= ELINK_FLAGS_EEE;
12886                 break;
12887         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
12888                 *phy = phy_7101;
12889                 break;
12890         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
12891                 *phy = phy_null;
12892                 return ELINK_STATUS_ERROR;
12893         default:
12894                 *phy = phy_null;
12895                 /* In case external PHY wasn't found */
12896                 if ((phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
12897                     (phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN))
12898                         return ELINK_STATUS_ERROR;
12899                 return ELINK_STATUS_OK;
12900         }
12901
12902         phy->addr = ELINK_XGXS_EXT_PHY_ADDR(ext_phy_config);
12903         elink_populate_preemphasis(sc, shmem_base, phy, port, phy_index);
12904
12905         /* The shmem address of the phy version is located on different
12906          * structures. In case this structure is too old, do not set
12907          * the address
12908          */
12909         config2 = REG_RD(sc, shmem_base + offsetof(struct shmem_region,
12910                                         dev_info.shared_hw_config.config2));
12911         if (phy_index == ELINK_EXT_PHY1) {
12912                 phy->ver_addr = shmem_base + offsetof(struct shmem_region,
12913                                 port_mb[port].ext_phy_fw_version);
12914
12915                 /* Check specific mdc mdio settings */
12916                 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
12917                         mdc_mdio_access = config2 &
12918                         SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
12919         } else {
12920                 uint32_t size = REG_RD(sc, shmem2_base);
12921
12922                 if (size >
12923                     offsetof(struct shmem2_region, ext_phy_fw_version2)) {
12924                         phy->ver_addr = shmem2_base +
12925                             offsetof(struct shmem2_region,
12926                                      ext_phy_fw_version2[port]);
12927                 }
12928                 /* Check specific mdc mdio settings */
12929                 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
12930                         mdc_mdio_access = (config2 &
12931                         SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
12932                         (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
12933                          SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
12934         }
12935         phy->mdio_ctrl = elink_get_emac_base(sc, mdc_mdio_access, port);
12936
12937         if (((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
12938              (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834)) &&
12939             (phy->ver_addr)) {
12940                 /* Remove 100Mb link supported for BCM84833/4 when phy fw
12941                  * version lower than or equal to 1.39
12942                  */
12943                 uint32_t raw_ver = REG_RD(sc, phy->ver_addr);
12944                 if (((raw_ver & 0x7F) <= 39) &&
12945                     (((raw_ver & 0xF80) >> 7) <= 1))
12946                         phy->supported &= ~(ELINK_SUPPORTED_100baseT_Half |
12947                                             ELINK_SUPPORTED_100baseT_Full);
12948         }
12949
12950         ELINK_DEBUG_P3(sc, "phy_type 0x%x port %d found in index %d\n",
12951                    phy_type, port, phy_index);
12952         ELINK_DEBUG_P2(sc, "             addr=0x%x, mdio_ctl=0x%x\n",
12953                    phy->addr, phy->mdio_ctrl);
12954         return ELINK_STATUS_OK;
12955 }
12956
12957 static elink_status_t elink_populate_phy(struct bxe_softc *sc, uint8_t phy_index, uint32_t shmem_base,
12958                               uint32_t shmem2_base, uint8_t port, struct elink_phy *phy)
12959 {
12960         elink_status_t status = ELINK_STATUS_OK;
12961         phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
12962         if (phy_index == ELINK_INT_PHY)
12963                 return elink_populate_int_phy(sc, shmem_base, port, phy);
12964         status = elink_populate_ext_phy(sc, phy_index, shmem_base, shmem2_base,
12965                                         port, phy);
12966         return status;
12967 }
12968
12969 static void elink_phy_def_cfg(struct elink_params *params,
12970                               struct elink_phy *phy,
12971                               uint8_t phy_index)
12972 {
12973         struct bxe_softc *sc = params->sc;
12974         uint32_t link_config;
12975         /* Populate the default phy configuration for MF mode */
12976         if (phy_index == ELINK_EXT_PHY2) {
12977                 link_config = REG_RD(sc, params->shmem_base +
12978                                      offsetof(struct shmem_region, dev_info.
12979                         port_feature_config[params->port].link_config2));
12980                 phy->speed_cap_mask = REG_RD(sc, params->shmem_base +
12981                                              offsetof(struct shmem_region,
12982                                                       dev_info.
12983                         port_hw_config[params->port].speed_capability_mask2));
12984         } else {
12985                 link_config = REG_RD(sc, params->shmem_base +
12986                                      offsetof(struct shmem_region, dev_info.
12987                                 port_feature_config[params->port].link_config));
12988                 phy->speed_cap_mask = REG_RD(sc, params->shmem_base +
12989                                              offsetof(struct shmem_region,
12990                                                       dev_info.
12991                         port_hw_config[params->port].speed_capability_mask));
12992         }
12993         ELINK_DEBUG_P3(sc,
12994            "Default config phy idx %x cfg 0x%x speed_cap_mask 0x%x\n",
12995            phy_index, link_config, phy->speed_cap_mask);
12996
12997         phy->req_duplex = DUPLEX_FULL;
12998         switch (link_config  & PORT_FEATURE_LINK_SPEED_MASK) {
12999         case PORT_FEATURE_LINK_SPEED_10M_HALF:
13000                 phy->req_duplex = DUPLEX_HALF;
13001         case PORT_FEATURE_LINK_SPEED_10M_FULL:
13002                 phy->req_line_speed = ELINK_SPEED_10;
13003                 break;
13004         case PORT_FEATURE_LINK_SPEED_100M_HALF:
13005                 phy->req_duplex = DUPLEX_HALF;
13006         case PORT_FEATURE_LINK_SPEED_100M_FULL:
13007                 phy->req_line_speed = ELINK_SPEED_100;
13008                 break;
13009         case PORT_FEATURE_LINK_SPEED_1G:
13010                 phy->req_line_speed = ELINK_SPEED_1000;
13011                 break;
13012         case PORT_FEATURE_LINK_SPEED_2_5G:
13013                 phy->req_line_speed = ELINK_SPEED_2500;
13014                 break;
13015         case PORT_FEATURE_LINK_SPEED_10G_CX4:
13016                 phy->req_line_speed = ELINK_SPEED_10000;
13017                 break;
13018         default:
13019                 phy->req_line_speed = ELINK_SPEED_AUTO_NEG;
13020                 break;
13021         }
13022
13023         switch (link_config  & PORT_FEATURE_FLOW_CONTROL_MASK) {
13024         case PORT_FEATURE_FLOW_CONTROL_AUTO:
13025                 phy->req_flow_ctrl = ELINK_FLOW_CTRL_AUTO;
13026                 break;
13027         case PORT_FEATURE_FLOW_CONTROL_TX:
13028                 phy->req_flow_ctrl = ELINK_FLOW_CTRL_TX;
13029                 break;
13030         case PORT_FEATURE_FLOW_CONTROL_RX:
13031                 phy->req_flow_ctrl = ELINK_FLOW_CTRL_RX;
13032                 break;
13033         case PORT_FEATURE_FLOW_CONTROL_BOTH:
13034                 phy->req_flow_ctrl = ELINK_FLOW_CTRL_BOTH;
13035                 break;
13036         default:
13037                 phy->req_flow_ctrl = ELINK_FLOW_CTRL_NONE;
13038                 break;
13039         }
13040 }
13041
13042 uint32_t elink_phy_selection(struct elink_params *params)
13043 {
13044         uint32_t phy_config_swapped, prio_cfg;
13045         uint32_t return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
13046
13047         phy_config_swapped = params->multi_phy_config &
13048                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
13049
13050         prio_cfg = params->multi_phy_config &
13051                         PORT_HW_CFG_PHY_SELECTION_MASK;
13052
13053         if (phy_config_swapped) {
13054                 switch (prio_cfg) {
13055                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
13056                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
13057                      break;
13058                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
13059                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
13060                      break;
13061                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
13062                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
13063                      break;
13064                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
13065                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
13066                      break;
13067                 }
13068         } else
13069                 return_cfg = prio_cfg;
13070
13071         return return_cfg;
13072 }
13073
13074 elink_status_t elink_phy_probe(struct elink_params *params)
13075 {
13076         uint8_t phy_index, actual_phy_idx;
13077         uint32_t phy_config_swapped, sync_offset, media_types;
13078         struct bxe_softc *sc = params->sc;
13079         struct elink_phy *phy;
13080         params->num_phys = 0;
13081         ELINK_DEBUG_P0(sc, "Begin phy probe\n");
13082 #ifdef ELINK_INCLUDE_EMUL
13083         if (CHIP_REV_IS_EMUL(sc))
13084                 return ELINK_STATUS_OK;
13085 #endif
13086         phy_config_swapped = params->multi_phy_config &
13087                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
13088
13089         for (phy_index = ELINK_INT_PHY; phy_index < ELINK_MAX_PHYS;
13090               phy_index++) {
13091                 actual_phy_idx = phy_index;
13092                 if (phy_config_swapped) {
13093                         if (phy_index == ELINK_EXT_PHY1)
13094                                 actual_phy_idx = ELINK_EXT_PHY2;
13095                         else if (phy_index == ELINK_EXT_PHY2)
13096                                 actual_phy_idx = ELINK_EXT_PHY1;
13097                 }
13098                 ELINK_DEBUG_P3(sc, "phy_config_swapped %x, phy_index %x,"
13099                                " actual_phy_idx %x\n", phy_config_swapped,
13100                            phy_index, actual_phy_idx);
13101                 phy = &params->phy[actual_phy_idx];
13102                 if (elink_populate_phy(sc, phy_index, params->shmem_base,
13103                                        params->shmem2_base, params->port,
13104                                        phy) != ELINK_STATUS_OK) {
13105                         params->num_phys = 0;
13106                         ELINK_DEBUG_P1(sc, "phy probe failed in phy index %d\n",
13107                                    phy_index);
13108                         for (phy_index = ELINK_INT_PHY;
13109                               phy_index < ELINK_MAX_PHYS;
13110                               phy_index++)
13111                                 *phy = phy_null;
13112                         return ELINK_STATUS_ERROR;
13113                 }
13114                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
13115                         break;
13116
13117                 if (params->feature_config_flags &
13118                     ELINK_FEATURE_CONFIG_DISABLE_REMOTE_FAULT_DET)
13119                         phy->flags &= ~ELINK_FLAGS_TX_ERROR_CHECK;
13120
13121                 if (!(params->feature_config_flags &
13122                       ELINK_FEATURE_CONFIG_MT_SUPPORT))
13123                         phy->flags |= ELINK_FLAGS_MDC_MDIO_WA_G;
13124
13125                 sync_offset = params->shmem_base +
13126                         offsetof(struct shmem_region,
13127                         dev_info.port_hw_config[params->port].media_type);
13128                 media_types = REG_RD(sc, sync_offset);
13129
13130                 /* Update media type for non-PMF sync only for the first time
13131                  * In case the media type changes afterwards, it will be updated
13132                  * using the update_status function
13133                  */
13134                 if ((media_types & (PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
13135                                     (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
13136                                      actual_phy_idx))) == 0) {
13137                         media_types |= ((phy->media_type &
13138                                         PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
13139                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
13140                                  actual_phy_idx));
13141                 }
13142                 REG_WR(sc, sync_offset, media_types);
13143
13144                 elink_phy_def_cfg(params, phy, phy_index);
13145                 params->num_phys++;
13146         }
13147
13148         ELINK_DEBUG_P1(sc, "End phy probe. #phys found %x\n", params->num_phys);
13149         return ELINK_STATUS_OK;
13150 }
13151
13152 #ifdef ELINK_INCLUDE_EMUL
13153 static elink_status_t elink_init_e3_emul_mac(struct elink_params *params,
13154                                              struct elink_vars *vars)
13155 {
13156         struct bxe_softc *sc = params->sc;
13157         vars->line_speed = params->req_line_speed[0];
13158         /* In case link speed is auto, set speed the highest as possible */
13159         if (params->req_line_speed[0] == ELINK_SPEED_AUTO_NEG) {
13160                 if (params->feature_config_flags &
13161                     ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC)
13162                         vars->line_speed = ELINK_SPEED_2500;
13163                 else if (elink_is_4_port_mode(sc))
13164                         vars->line_speed = ELINK_SPEED_10000;
13165                 else
13166                         vars->line_speed = ELINK_SPEED_20000;
13167         }
13168         if (vars->line_speed < ELINK_SPEED_10000) {
13169                 if ((params->feature_config_flags &
13170                      ELINK_FEATURE_CONFIG_EMUL_DISABLE_UMAC)) {
13171                         ELINK_DEBUG_P1(sc, "Invalid line speed %d while UMAC is"
13172                                    " disabled!\n", params->req_line_speed[0]);
13173                         return ELINK_STATUS_ERROR;
13174                 }
13175                 switch (vars->line_speed) {
13176                 case ELINK_SPEED_10:
13177                         vars->link_status = ELINK_LINK_10TFD;
13178                         break;
13179                 case ELINK_SPEED_100:
13180                         vars->link_status = ELINK_LINK_100TXFD;
13181                         break;
13182                 case ELINK_SPEED_1000:
13183                         vars->link_status = ELINK_LINK_1000TFD;
13184                         break;
13185                 case ELINK_SPEED_2500:
13186                         vars->link_status = ELINK_LINK_2500TFD;
13187                         break;
13188                 default:
13189                         ELINK_DEBUG_P1(sc, "Invalid line speed %d for UMAC\n",
13190                                    vars->line_speed);
13191                         return ELINK_STATUS_ERROR;
13192                 }
13193                 vars->link_status |= LINK_STATUS_LINK_UP;
13194
13195                 if (params->loopback_mode == ELINK_LOOPBACK_UMAC)
13196                         elink_umac_enable(params, vars, 1);
13197                 else
13198                         elink_umac_enable(params, vars, 0);
13199         } else {
13200                 /* Link speed >= 10000 requires XMAC enabled */
13201                 if (params->feature_config_flags &
13202                     ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC) {
13203                         ELINK_DEBUG_P1(sc, "Invalid line speed %d while XMAC is"
13204                                    " disabled!\n", params->req_line_speed[0]);
13205                 return ELINK_STATUS_ERROR;
13206         }
13207                 /* Check link speed */
13208                 switch (vars->line_speed) {
13209                 case ELINK_SPEED_10000:
13210                         vars->link_status = ELINK_LINK_10GTFD;
13211                         break;
13212                 case ELINK_SPEED_20000:
13213                         vars->link_status = ELINK_LINK_20GTFD;
13214                         break;
13215                 default:
13216                         ELINK_DEBUG_P1(sc, "Invalid line speed %d for XMAC\n",
13217                                    vars->line_speed);
13218                         return ELINK_STATUS_ERROR;
13219                 }
13220                 vars->link_status |= LINK_STATUS_LINK_UP;
13221                 if (params->loopback_mode == ELINK_LOOPBACK_XMAC)
13222                         elink_xmac_enable(params, vars, 1);
13223                 else
13224                         elink_xmac_enable(params, vars, 0);
13225         }
13226                 return ELINK_STATUS_OK;
13227 }
13228
13229 static elink_status_t elink_init_emul(struct elink_params *params,
13230                             struct elink_vars *vars)
13231 {
13232         struct bxe_softc *sc = params->sc;
13233         if (CHIP_IS_E3(sc)) {
13234                 if (elink_init_e3_emul_mac(params, vars) !=
13235                     ELINK_STATUS_OK)
13236                         return ELINK_STATUS_ERROR;
13237         } else {
13238                 if (params->feature_config_flags &
13239                     ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC) {
13240                         vars->line_speed = ELINK_SPEED_1000;
13241                         vars->link_status = (LINK_STATUS_LINK_UP |
13242                                              ELINK_LINK_1000XFD);
13243                         if (params->loopback_mode ==
13244                             ELINK_LOOPBACK_EMAC)
13245                                 elink_emac_enable(params, vars, 1);
13246                         else
13247                                 elink_emac_enable(params, vars, 0);
13248                 } else {
13249                         vars->line_speed = ELINK_SPEED_10000;
13250                         vars->link_status = (LINK_STATUS_LINK_UP |
13251                                              ELINK_LINK_10GTFD);
13252                         if (params->loopback_mode ==
13253                             ELINK_LOOPBACK_BMAC)
13254                                 elink_bmac_enable(params, vars, 1, 1);
13255                         else
13256                                 elink_bmac_enable(params, vars, 0, 1);
13257                 }
13258         }
13259         vars->link_up = 1;
13260         vars->duplex = DUPLEX_FULL;
13261         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13262
13263                 if (CHIP_IS_E1x(sc))
13264                         elink_pbf_update(params, vars->flow_ctrl,
13265                                          vars->line_speed);
13266                 /* Disable drain */
13267                 REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13268
13269                 /* update shared memory */
13270                 elink_update_mng(params, vars->link_status);
13271         return ELINK_STATUS_OK;
13272 }
13273 #endif
13274 #ifdef ELINK_INCLUDE_FPGA
13275 static elink_status_t elink_init_fpga(struct elink_params *params,
13276                             struct elink_vars *vars)
13277 {
13278         /* Enable on E1.5 FPGA */
13279         struct bxe_softc *sc = params->sc;
13280         vars->duplex = DUPLEX_FULL;
13281         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13282         if (!(CHIP_IS_E1(sc))) {
13283                 vars->flow_ctrl = (ELINK_FLOW_CTRL_TX |
13284                                    ELINK_FLOW_CTRL_RX);
13285                 vars->link_status |= (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
13286                                       LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
13287         }
13288         if (CHIP_IS_E3(sc)) {
13289                 vars->line_speed = params->req_line_speed[0];
13290                 switch (vars->line_speed) {
13291                 case ELINK_SPEED_AUTO_NEG:
13292                         vars->line_speed = ELINK_SPEED_2500;
13293                 case ELINK_SPEED_2500:
13294                         vars->link_status = ELINK_LINK_2500TFD;
13295                         break;
13296                 case ELINK_SPEED_1000:
13297                         vars->link_status = ELINK_LINK_1000XFD;
13298                         break;
13299                 case ELINK_SPEED_100:
13300                         vars->link_status = ELINK_LINK_100TXFD;
13301                         break;
13302                 case ELINK_SPEED_10:
13303                         vars->link_status = ELINK_LINK_10TFD;
13304                         break;
13305                 default:
13306                         ELINK_DEBUG_P1(sc, "Invalid link speed %d\n",
13307                                    params->req_line_speed[0]);
13308                         return ELINK_STATUS_ERROR;
13309                 }
13310                 vars->link_status |= LINK_STATUS_LINK_UP;
13311                 if (params->loopback_mode == ELINK_LOOPBACK_UMAC)
13312                         elink_umac_enable(params, vars, 1);
13313                 else
13314                         elink_umac_enable(params, vars, 0);
13315         } else {
13316                 vars->line_speed = ELINK_SPEED_10000;
13317                 vars->link_status = (LINK_STATUS_LINK_UP | ELINK_LINK_10GTFD);
13318                 if (params->loopback_mode == ELINK_LOOPBACK_EMAC)
13319                         elink_emac_enable(params, vars, 1);
13320                 else
13321                         elink_emac_enable(params, vars, 0);
13322         }
13323         vars->link_up = 1;
13324
13325         if (CHIP_IS_E1x(sc))
13326                 elink_pbf_update(params, vars->flow_ctrl,
13327                                  vars->line_speed);
13328         /* Disable drain */
13329         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13330
13331         /* Update shared memory */
13332         elink_update_mng(params, vars->link_status);
13333                 return ELINK_STATUS_OK;
13334 }
13335 #endif
13336 static void elink_init_bmac_loopback(struct elink_params *params,
13337                                      struct elink_vars *vars)
13338 {
13339         struct bxe_softc *sc = params->sc;
13340                 vars->link_up = 1;
13341                 vars->line_speed = ELINK_SPEED_10000;
13342                 vars->duplex = DUPLEX_FULL;
13343                 vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13344                 vars->mac_type = ELINK_MAC_TYPE_BMAC;
13345
13346                 vars->phy_flags = PHY_XGXS_FLAG;
13347
13348                 elink_xgxs_deassert(params);
13349
13350                 /* Set bmac loopback */
13351                 elink_bmac_enable(params, vars, 1, 1);
13352
13353                 REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13354 }
13355
13356 static void elink_init_emac_loopback(struct elink_params *params,
13357                                      struct elink_vars *vars)
13358 {
13359         struct bxe_softc *sc = params->sc;
13360                 vars->link_up = 1;
13361                 vars->line_speed = ELINK_SPEED_1000;
13362                 vars->duplex = DUPLEX_FULL;
13363                 vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13364                 vars->mac_type = ELINK_MAC_TYPE_EMAC;
13365
13366                 vars->phy_flags = PHY_XGXS_FLAG;
13367
13368                 elink_xgxs_deassert(params);
13369                 /* Set bmac loopback */
13370                 elink_emac_enable(params, vars, 1);
13371                 elink_emac_program(params, vars);
13372                 REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13373 }
13374
13375 static void elink_init_xmac_loopback(struct elink_params *params,
13376                                      struct elink_vars *vars)
13377 {
13378         struct bxe_softc *sc = params->sc;
13379         vars->link_up = 1;
13380         if (!params->req_line_speed[0])
13381                 vars->line_speed = ELINK_SPEED_10000;
13382         else
13383                 vars->line_speed = params->req_line_speed[0];
13384         vars->duplex = DUPLEX_FULL;
13385         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13386         vars->mac_type = ELINK_MAC_TYPE_XMAC;
13387         vars->phy_flags = PHY_XGXS_FLAG;
13388         /* Set WC to loopback mode since link is required to provide clock
13389          * to the XMAC in 20G mode
13390          */
13391         elink_set_aer_mmd(params, &params->phy[0]);
13392         elink_warpcore_reset_lane(sc, &params->phy[0], 0);
13393         params->phy[ELINK_INT_PHY].config_loopback(
13394                         &params->phy[ELINK_INT_PHY],
13395                         params);
13396
13397         elink_xmac_enable(params, vars, 1);
13398         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13399 }
13400
13401 static void elink_init_umac_loopback(struct elink_params *params,
13402                                      struct elink_vars *vars)
13403 {
13404         struct bxe_softc *sc = params->sc;
13405         vars->link_up = 1;
13406         vars->line_speed = ELINK_SPEED_1000;
13407         vars->duplex = DUPLEX_FULL;
13408         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13409         vars->mac_type = ELINK_MAC_TYPE_UMAC;
13410         vars->phy_flags = PHY_XGXS_FLAG;
13411         elink_umac_enable(params, vars, 1);
13412
13413         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13414 }
13415
13416 static void elink_init_xgxs_loopback(struct elink_params *params,
13417                                      struct elink_vars *vars)
13418 {
13419         struct bxe_softc *sc = params->sc;
13420         struct elink_phy *int_phy = &params->phy[ELINK_INT_PHY];
13421         vars->link_up = 1;
13422         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13423         vars->duplex = DUPLEX_FULL;
13424         if (params->req_line_speed[0] == ELINK_SPEED_1000)
13425                 vars->line_speed = ELINK_SPEED_1000;
13426         else if ((params->req_line_speed[0] == ELINK_SPEED_20000) ||
13427                  (int_phy->flags & ELINK_FLAGS_WC_DUAL_MODE))
13428                 vars->line_speed = ELINK_SPEED_20000;
13429         else
13430                 vars->line_speed = ELINK_SPEED_10000;
13431
13432         if (!USES_WARPCORE(sc))
13433                 elink_xgxs_deassert(params);
13434         elink_link_initialize(params, vars);
13435
13436         if (params->req_line_speed[0] == ELINK_SPEED_1000) {
13437                 if (USES_WARPCORE(sc))
13438                         elink_umac_enable(params, vars, 0);
13439                 else {
13440                         elink_emac_program(params, vars);
13441                         elink_emac_enable(params, vars, 0);
13442                 }
13443         } else {
13444                 if (USES_WARPCORE(sc))
13445                         elink_xmac_enable(params, vars, 0);
13446                 else
13447                         elink_bmac_enable(params, vars, 0, 1);
13448         }
13449
13450         if (params->loopback_mode == ELINK_LOOPBACK_XGXS) {
13451                 /* Set 10G XGXS loopback */
13452                 int_phy->config_loopback(int_phy, params);
13453         } else {
13454                 /* Set external phy loopback */
13455                 uint8_t phy_index;
13456                 for (phy_index = ELINK_EXT_PHY1;
13457                       phy_index < params->num_phys; phy_index++)
13458                         if (params->phy[phy_index].config_loopback)
13459                                 params->phy[phy_index].config_loopback(
13460                                         &params->phy[phy_index],
13461                                         params);
13462         }
13463         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13464
13465         elink_set_led(params, vars, ELINK_LED_MODE_OPER, vars->line_speed);
13466 }
13467
13468 void elink_set_rx_filter(struct elink_params *params, uint8_t en)
13469 {
13470         struct bxe_softc *sc = params->sc;
13471         uint8_t val = en * 0x1F;
13472
13473         /* Open / close the gate between the NIG and the BRB */
13474         if (!CHIP_IS_E1x(sc))
13475                 val |= en * 0x20;
13476         REG_WR(sc, NIG_REG_LLH0_BRB1_DRV_MASK + params->port*4, val);
13477
13478         if (!CHIP_IS_E1(sc)) {
13479                 REG_WR(sc, NIG_REG_LLH0_BRB1_DRV_MASK_MF + params->port*4,
13480                        en*0x3);
13481         }
13482
13483         REG_WR(sc, (params->port ? NIG_REG_LLH1_BRB1_NOT_MCP :
13484                     NIG_REG_LLH0_BRB1_NOT_MCP), en);
13485 }
13486 static elink_status_t elink_avoid_link_flap(struct elink_params *params,
13487                                             struct elink_vars *vars)
13488 {
13489         uint32_t phy_idx;
13490         uint32_t dont_clear_stat, lfa_sts;
13491         struct bxe_softc *sc = params->sc;
13492
13493         /* Sync the link parameters */
13494         elink_link_status_update(params, vars);
13495
13496         /*
13497          * The module verification was already done by previous link owner,
13498          * so this call is meant only to get warning message
13499          */
13500
13501         for (phy_idx = ELINK_INT_PHY; phy_idx < params->num_phys; phy_idx++) {
13502                 struct elink_phy *phy = &params->phy[phy_idx];
13503                 if (phy->phy_specific_func) {
13504                         ELINK_DEBUG_P0(sc, "Calling PHY specific func\n");
13505                         phy->phy_specific_func(phy, params, ELINK_PHY_INIT);
13506                 }
13507                 if ((phy->media_type == ELINK_ETH_PHY_SFPP_10G_FIBER) ||
13508                     (phy->media_type == ELINK_ETH_PHY_SFP_1G_FIBER) ||
13509                     (phy->media_type == ELINK_ETH_PHY_DA_TWINAX))
13510                         elink_verify_sfp_module(phy, params);
13511         }
13512         lfa_sts = REG_RD(sc, params->lfa_base +
13513                          offsetof(struct shmem_lfa,
13514                                   lfa_sts));
13515
13516         dont_clear_stat = lfa_sts & SHMEM_LFA_DONT_CLEAR_STAT;
13517
13518         /* Re-enable the NIG/MAC */
13519         if (CHIP_IS_E3(sc)) {
13520                 if (!dont_clear_stat) {
13521                         REG_WR(sc, GRCBASE_MISC +
13522                                MISC_REGISTERS_RESET_REG_2_CLEAR,
13523                                (MISC_REGISTERS_RESET_REG_2_MSTAT0 <<
13524                                 params->port));
13525                         REG_WR(sc, GRCBASE_MISC +
13526                                MISC_REGISTERS_RESET_REG_2_SET,
13527                                (MISC_REGISTERS_RESET_REG_2_MSTAT0 <<
13528                                 params->port));
13529                 }
13530                 if (vars->line_speed < ELINK_SPEED_10000)
13531                         elink_umac_enable(params, vars, 0);
13532                 else
13533                         elink_xmac_enable(params, vars, 0);
13534         } else {
13535                 if (vars->line_speed < ELINK_SPEED_10000)
13536                         elink_emac_enable(params, vars, 0);
13537                 else
13538                         elink_bmac_enable(params, vars, 0, !dont_clear_stat);
13539         }
13540
13541         /* Increment LFA count */
13542         lfa_sts = ((lfa_sts & ~LINK_FLAP_AVOIDANCE_COUNT_MASK) |
13543                    (((((lfa_sts & LINK_FLAP_AVOIDANCE_COUNT_MASK) >>
13544                        LINK_FLAP_AVOIDANCE_COUNT_OFFSET) + 1) & 0xff)
13545                     << LINK_FLAP_AVOIDANCE_COUNT_OFFSET));
13546         /* Clear link flap reason */
13547         lfa_sts &= ~LFA_LINK_FLAP_REASON_MASK;
13548
13549         REG_WR(sc, params->lfa_base +
13550                offsetof(struct shmem_lfa, lfa_sts), lfa_sts);
13551
13552         /* Disable NIG DRAIN */
13553         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13554
13555         /* Enable interrupts */
13556         elink_link_int_enable(params);
13557         return ELINK_STATUS_OK;
13558 }
13559
13560 static void elink_cannot_avoid_link_flap(struct elink_params *params,
13561                                          struct elink_vars *vars,
13562                                          int lfa_status)
13563 {
13564         uint32_t lfa_sts, cfg_idx, tmp_val;
13565         struct bxe_softc *sc = params->sc;
13566
13567         elink_link_reset(params, vars, 1);
13568
13569         if (!params->lfa_base)
13570                 return;
13571         /* Store the new link parameters */
13572         REG_WR(sc, params->lfa_base +
13573                offsetof(struct shmem_lfa, req_duplex),
13574                params->req_duplex[0] | (params->req_duplex[1] << 16));
13575
13576         REG_WR(sc, params->lfa_base +
13577                offsetof(struct shmem_lfa, req_flow_ctrl),
13578                params->req_flow_ctrl[0] | (params->req_flow_ctrl[1] << 16));
13579
13580         REG_WR(sc, params->lfa_base +
13581                offsetof(struct shmem_lfa, req_line_speed),
13582                params->req_line_speed[0] | (params->req_line_speed[1] << 16));
13583
13584         for (cfg_idx = 0; cfg_idx < SHMEM_LINK_CONFIG_SIZE; cfg_idx++) {
13585                 REG_WR(sc, params->lfa_base +
13586                        offsetof(struct shmem_lfa,
13587                                 speed_cap_mask[cfg_idx]),
13588                        params->speed_cap_mask[cfg_idx]);
13589         }
13590
13591         tmp_val = REG_RD(sc, params->lfa_base +
13592                          offsetof(struct shmem_lfa, additional_config));
13593         tmp_val &= ~REQ_FC_AUTO_ADV_MASK;
13594         tmp_val |= params->req_fc_auto_adv;
13595
13596         REG_WR(sc, params->lfa_base +
13597                offsetof(struct shmem_lfa, additional_config), tmp_val);
13598
13599         lfa_sts = REG_RD(sc, params->lfa_base +
13600                          offsetof(struct shmem_lfa, lfa_sts));
13601
13602         /* Clear the "Don't Clear Statistics" bit, and set reason */
13603         lfa_sts &= ~SHMEM_LFA_DONT_CLEAR_STAT;
13604
13605         /* Set link flap reason */
13606         lfa_sts &= ~LFA_LINK_FLAP_REASON_MASK;
13607         lfa_sts |= ((lfa_status & LFA_LINK_FLAP_REASON_MASK) <<
13608                     LFA_LINK_FLAP_REASON_OFFSET);
13609
13610         /* Increment link flap counter */
13611         lfa_sts = ((lfa_sts & ~LINK_FLAP_COUNT_MASK) |
13612                    (((((lfa_sts & LINK_FLAP_COUNT_MASK) >>
13613                        LINK_FLAP_COUNT_OFFSET) + 1) & 0xff)
13614                     << LINK_FLAP_COUNT_OFFSET));
13615         REG_WR(sc, params->lfa_base +
13616                offsetof(struct shmem_lfa, lfa_sts), lfa_sts);
13617         /* Proceed with regular link initialization */
13618 }
13619
13620 elink_status_t elink_phy_init(struct elink_params *params, struct elink_vars *vars)
13621 {
13622         int lfa_status;
13623         struct bxe_softc *sc = params->sc;
13624         ELINK_DEBUG_P0(sc, "Phy Initialization started\n");
13625         ELINK_DEBUG_P2(sc, "(1) req_speed %d, req_flowctrl %d\n",
13626                    params->req_line_speed[0], params->req_flow_ctrl[0]);
13627         ELINK_DEBUG_P2(sc, "(2) req_speed %d, req_flowctrl %d\n",
13628                    params->req_line_speed[1], params->req_flow_ctrl[1]);
13629         ELINK_DEBUG_P1(sc, "req_adv_flow_ctrl 0x%x\n", params->req_fc_auto_adv);
13630         vars->link_status = 0;
13631         vars->phy_link_up = 0;
13632         vars->link_up = 0;
13633         vars->line_speed = 0;
13634         vars->duplex = DUPLEX_FULL;
13635         vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
13636         vars->mac_type = ELINK_MAC_TYPE_NONE;
13637         vars->phy_flags = 0;
13638         vars->check_kr2_recovery_cnt = 0;
13639         params->link_flags = ELINK_PHY_INITIALIZED;
13640         /* Driver opens NIG-BRB filters */
13641         elink_set_rx_filter(params, 1);
13642         /* Check if link flap can be avoided */
13643         lfa_status = elink_check_lfa(params);
13644
13645         if (lfa_status == 0) {
13646                 ELINK_DEBUG_P0(sc, "Link Flap Avoidance in progress\n");
13647                 return elink_avoid_link_flap(params, vars);
13648         }
13649
13650         ELINK_DEBUG_P1(sc, "Cannot avoid link flap lfa_sta=0x%x\n",
13651                        lfa_status);
13652         elink_cannot_avoid_link_flap(params, vars, lfa_status);
13653
13654         /* Disable attentions */
13655         elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
13656                        (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
13657                         ELINK_NIG_MASK_XGXS0_LINK10G |
13658                         ELINK_NIG_MASK_SERDES0_LINK_STATUS |
13659                         ELINK_NIG_MASK_MI_INT));
13660 #ifdef ELINK_INCLUDE_EMUL
13661         if (!(params->feature_config_flags &
13662               ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC))
13663 #endif
13664
13665         elink_emac_init(params, vars);
13666
13667         if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
13668                 vars->link_status |= LINK_STATUS_PFC_ENABLED;
13669
13670         if ((params->num_phys == 0) &&
13671             !CHIP_REV_IS_SLOW(sc)) {
13672                 ELINK_DEBUG_P0(sc, "No phy found for initialization !!\n");
13673                 return ELINK_STATUS_ERROR;
13674         }
13675         set_phy_vars(params, vars);
13676
13677         ELINK_DEBUG_P1(sc, "Num of phys on board: %d\n", params->num_phys);
13678 #ifdef ELINK_INCLUDE_FPGA
13679         if (CHIP_REV_IS_FPGA(sc)) {
13680                 return elink_init_fpga(params, vars);
13681         } else
13682 #endif
13683 #ifdef ELINK_INCLUDE_EMUL
13684         if (CHIP_REV_IS_EMUL(sc)) {
13685                 return elink_init_emul(params, vars);
13686         } else
13687 #endif
13688         switch (params->loopback_mode) {
13689         case ELINK_LOOPBACK_BMAC:
13690                 elink_init_bmac_loopback(params, vars);
13691                 break;
13692         case ELINK_LOOPBACK_EMAC:
13693                 elink_init_emac_loopback(params, vars);
13694                 break;
13695         case ELINK_LOOPBACK_XMAC:
13696                 elink_init_xmac_loopback(params, vars);
13697                 break;
13698         case ELINK_LOOPBACK_UMAC:
13699                 elink_init_umac_loopback(params, vars);
13700                 break;
13701         case ELINK_LOOPBACK_XGXS:
13702         case ELINK_LOOPBACK_EXT_PHY:
13703                 elink_init_xgxs_loopback(params, vars);
13704                 break;
13705         default:
13706                 if (!CHIP_IS_E3(sc)) {
13707                         if (params->switch_cfg == ELINK_SWITCH_CFG_10G)
13708                                 elink_xgxs_deassert(params);
13709                         else
13710                                 elink_serdes_deassert(sc, params->port);
13711                 }
13712                 elink_link_initialize(params, vars);
13713                 DELAY(1000 * 30);
13714                 elink_link_int_enable(params);
13715                 break;
13716         }
13717         elink_update_mng(params, vars->link_status);
13718
13719         elink_update_mng_eee(params, vars->eee_status);
13720         return ELINK_STATUS_OK;
13721 }
13722
13723 elink_status_t elink_link_reset(struct elink_params *params, struct elink_vars *vars,
13724                      uint8_t reset_ext_phy)
13725 {
13726         struct bxe_softc *sc = params->sc;
13727         uint8_t phy_index, port = params->port, clear_latch_ind = 0;
13728         ELINK_DEBUG_P1(sc, "Resetting the link of port %d\n", port);
13729         /* Disable attentions */
13730         vars->link_status = 0;
13731         elink_update_mng(params, vars->link_status);
13732         vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
13733                               SHMEM_EEE_ACTIVE_BIT);
13734         elink_update_mng_eee(params, vars->eee_status);
13735         elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
13736                        (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
13737                         ELINK_NIG_MASK_XGXS0_LINK10G |
13738                         ELINK_NIG_MASK_SERDES0_LINK_STATUS |
13739                         ELINK_NIG_MASK_MI_INT));
13740
13741         /* Activate nig drain */
13742         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
13743
13744         /* Disable nig egress interface */
13745         if (!CHIP_IS_E3(sc)) {
13746                 REG_WR(sc, NIG_REG_BMAC0_OUT_EN + port*4, 0);
13747                 REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
13748         }
13749
13750 #ifdef ELINK_INCLUDE_EMUL
13751         /* Stop BigMac rx */
13752         if (!(params->feature_config_flags &
13753               ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC))
13754 #endif
13755                 if (!CHIP_IS_E3(sc))
13756                         elink_set_bmac_rx(sc, params->chip_id, port, 0);
13757 #ifdef ELINK_INCLUDE_EMUL
13758         /* Stop XMAC/UMAC rx */
13759         if (!(params->feature_config_flags &
13760               ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC))
13761 #endif
13762                 if (CHIP_IS_E3(sc) &&
13763                 !CHIP_REV_IS_FPGA(sc)) {
13764                         elink_set_xmac_rxtx(params, 0);
13765                         elink_set_umac_rxtx(params, 0);
13766                 }
13767         /* Disable emac */
13768         if (!CHIP_IS_E3(sc))
13769                 REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port*4, 0);
13770
13771         DELAY(1000 * 10);
13772         /* The PHY reset is controlled by GPIO 1
13773          * Hold it as vars low
13774          */
13775          /* Clear link led */
13776         elink_set_mdio_emac_per_phy(sc, params);
13777         elink_set_led(params, vars, ELINK_LED_MODE_OFF, 0);
13778
13779         if (reset_ext_phy && (!CHIP_REV_IS_SLOW(sc))) {
13780                 for (phy_index = ELINK_EXT_PHY1; phy_index < params->num_phys;
13781                       phy_index++) {
13782                         if (params->phy[phy_index].link_reset) {
13783                                 elink_set_aer_mmd(params,
13784                                                   &params->phy[phy_index]);
13785                                 params->phy[phy_index].link_reset(
13786                                         &params->phy[phy_index],
13787                                         params);
13788                         }
13789                         if (params->phy[phy_index].flags &
13790                             ELINK_FLAGS_REARM_LATCH_SIGNAL)
13791                                 clear_latch_ind = 1;
13792                 }
13793         }
13794
13795         if (clear_latch_ind) {
13796                 /* Clear latching indication */
13797                 elink_rearm_latch_signal(sc, port, 0);
13798                 elink_bits_dis(sc, NIG_REG_LATCH_BC_0 + port*4,
13799                                1 << ELINK_NIG_LATCH_BC_ENABLE_MI_INT);
13800         }
13801 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
13802         if (!CHIP_REV_IS_SLOW(sc))
13803 #endif
13804         if (params->phy[ELINK_INT_PHY].link_reset)
13805                 params->phy[ELINK_INT_PHY].link_reset(
13806                         &params->phy[ELINK_INT_PHY], params);
13807
13808         /* Disable nig ingress interface */
13809         if (!CHIP_IS_E3(sc)) {
13810                 /* Reset BigMac */
13811                 REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
13812                        (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
13813                 REG_WR(sc, NIG_REG_BMAC0_IN_EN + port*4, 0);
13814                 REG_WR(sc, NIG_REG_EMAC0_IN_EN + port*4, 0);
13815         } else {
13816                 uint32_t xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
13817                 elink_set_xumac_nig(params, 0, 0);
13818                 if (REG_RD(sc, MISC_REG_RESET_REG_2) &
13819                     MISC_REGISTERS_RESET_REG_2_XMAC)
13820                         REG_WR(sc, xmac_base + XMAC_REG_CTRL,
13821                                XMAC_CTRL_REG_SOFT_RESET);
13822         }
13823         vars->link_up = 0;
13824         vars->phy_flags = 0;
13825         return ELINK_STATUS_OK;
13826 }
13827 elink_status_t elink_lfa_reset(struct elink_params *params,
13828                                struct elink_vars *vars)
13829 {
13830         struct bxe_softc *sc = params->sc;
13831         vars->link_up = 0;
13832         vars->phy_flags = 0;
13833         params->link_flags &= ~ELINK_PHY_INITIALIZED;
13834         if (!params->lfa_base)
13835                 return elink_link_reset(params, vars, 1);
13836         /*
13837          * Activate NIG drain so that during this time the device won't send
13838          * anything while it is unable to response.
13839          */
13840         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 1);
13841
13842         /*
13843          * Close gracefully the gate from BMAC to NIG such that no half packets
13844          * are passed.
13845          */
13846         if (!CHIP_IS_E3(sc))
13847                 elink_set_bmac_rx(sc, params->chip_id, params->port, 0);
13848
13849         if (CHIP_IS_E3(sc)) {
13850                 elink_set_xmac_rxtx(params, 0);
13851                 elink_set_umac_rxtx(params, 0);
13852         }
13853         /* Wait 10ms for the pipe to clean up*/
13854         DELAY(1000 * 10);
13855
13856         /* Clean the NIG-BRB using the network filters in a way that will
13857          * not cut a packet in the middle.
13858          */
13859         elink_set_rx_filter(params, 0);
13860
13861         /*
13862          * Re-open the gate between the BMAC and the NIG, after verifying the
13863          * gate to the BRB is closed, otherwise packets may arrive to the
13864          * firmware before driver had initialized it. The target is to achieve
13865          * minimum management protocol down time.
13866          */
13867         if (!CHIP_IS_E3(sc))
13868                 elink_set_bmac_rx(sc, params->chip_id, params->port, 1);
13869
13870         if (CHIP_IS_E3(sc)) {
13871                 elink_set_xmac_rxtx(params, 1);
13872                 elink_set_umac_rxtx(params, 1);
13873         }
13874         /* Disable NIG drain */
13875         REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
13876         return ELINK_STATUS_OK;
13877 }
13878
13879 /****************************************************************************/
13880 /*                              Common function                             */
13881 /****************************************************************************/
13882 static elink_status_t elink_8073_common_init_phy(struct bxe_softc *sc,
13883                                       uint32_t shmem_base_path[],
13884                                       uint32_t shmem2_base_path[], uint8_t phy_index,
13885                                       uint32_t chip_id)
13886 {
13887         struct elink_phy phy[PORT_MAX];
13888         struct elink_phy *phy_blk[PORT_MAX];
13889         uint16_t val;
13890         int8_t port = 0;
13891         int8_t port_of_path = 0;
13892         uint32_t swap_val, swap_override;
13893         swap_val = REG_RD(sc,  NIG_REG_PORT_SWAP);
13894         swap_override = REG_RD(sc,  NIG_REG_STRAP_OVERRIDE);
13895         port ^= (swap_val && swap_override);
13896         elink_ext_phy_hw_reset(sc, port);
13897         /* PART1 - Reset both phys */
13898         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
13899                 uint32_t shmem_base, shmem2_base;
13900                 /* In E2, same phy is using for port0 of the two paths */
13901                 if (CHIP_IS_E1x(sc)) {
13902                         shmem_base = shmem_base_path[0];
13903                         shmem2_base = shmem2_base_path[0];
13904                         port_of_path = port;
13905                 } else {
13906                         shmem_base = shmem_base_path[port];
13907                         shmem2_base = shmem2_base_path[port];
13908                         port_of_path = 0;
13909                 }
13910
13911                 /* Extract the ext phy address for the port */
13912                 if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
13913                                        port_of_path, &phy[port]) !=
13914                     ELINK_STATUS_OK) {
13915                         ELINK_DEBUG_P0(sc, "populate_phy failed\n");
13916                         return ELINK_STATUS_ERROR;
13917                 }
13918                 /* Disable attentions */
13919                 elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
13920                                port_of_path*4,
13921                                (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
13922                                 ELINK_NIG_MASK_XGXS0_LINK10G |
13923                                 ELINK_NIG_MASK_SERDES0_LINK_STATUS |
13924                                 ELINK_NIG_MASK_MI_INT));
13925
13926                 /* Need to take the phy out of low power mode in order
13927                  * to write to access its registers
13928                  */
13929                 elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
13930                                MISC_REGISTERS_GPIO_OUTPUT_HIGH,
13931                                port);
13932
13933                 /* Reset the phy */
13934                 elink_cl45_write(sc, &phy[port],
13935                                  MDIO_PMA_DEVAD,
13936                                  MDIO_PMA_REG_CTRL,
13937                                  1<<15);
13938         }
13939
13940         /* Add delay of 150ms after reset */
13941         DELAY(1000 * 150);
13942
13943         if (phy[PORT_0].addr & 0x1) {
13944                 phy_blk[PORT_0] = &(phy[PORT_1]);
13945                 phy_blk[PORT_1] = &(phy[PORT_0]);
13946         } else {
13947                 phy_blk[PORT_0] = &(phy[PORT_0]);
13948                 phy_blk[PORT_1] = &(phy[PORT_1]);
13949         }
13950
13951         /* PART2 - Download firmware to both phys */
13952         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
13953                 if (CHIP_IS_E1x(sc))
13954                         port_of_path = port;
13955                 else
13956                         port_of_path = 0;
13957
13958                 ELINK_DEBUG_P1(sc, "Loading spirom for phy address 0x%x\n",
13959                            phy_blk[port]->addr);
13960                 if (elink_8073_8727_external_rom_boot(sc, phy_blk[port],
13961                                                       port_of_path))
13962                         return ELINK_STATUS_ERROR;
13963
13964                 /* Only set bit 10 = 1 (Tx power down) */
13965                 elink_cl45_read(sc, phy_blk[port],
13966                                 MDIO_PMA_DEVAD,
13967                                 MDIO_PMA_REG_TX_POWER_DOWN, &val);
13968
13969                 /* Phase1 of TX_POWER_DOWN reset */
13970                 elink_cl45_write(sc, phy_blk[port],
13971                                  MDIO_PMA_DEVAD,
13972                                  MDIO_PMA_REG_TX_POWER_DOWN,
13973                                  (val | 1<<10));
13974         }
13975
13976         /* Toggle Transmitter: Power down and then up with 600ms delay
13977          * between
13978          */
13979         DELAY(1000 * 600);
13980
13981         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
13982         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
13983                 /* Phase2 of POWER_DOWN_RESET */
13984                 /* Release bit 10 (Release Tx power down) */
13985                 elink_cl45_read(sc, phy_blk[port],
13986                                 MDIO_PMA_DEVAD,
13987                                 MDIO_PMA_REG_TX_POWER_DOWN, &val);
13988
13989                 elink_cl45_write(sc, phy_blk[port],
13990                                 MDIO_PMA_DEVAD,
13991                                 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
13992                 DELAY(1000 * 15);
13993
13994                 /* Read modify write the SPI-ROM version select register */
13995                 elink_cl45_read(sc, phy_blk[port],
13996                                 MDIO_PMA_DEVAD,
13997                                 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
13998                 elink_cl45_write(sc, phy_blk[port],
13999                                  MDIO_PMA_DEVAD,
14000                                  MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
14001
14002                 /* set GPIO2 back to LOW */
14003                 elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_2,
14004                                MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
14005         }
14006         return ELINK_STATUS_OK;
14007 }
14008 static elink_status_t elink_8726_common_init_phy(struct bxe_softc *sc,
14009                                       uint32_t shmem_base_path[],
14010                                       uint32_t shmem2_base_path[], uint8_t phy_index,
14011                                       uint32_t chip_id)
14012 {
14013         uint32_t val;
14014         int8_t port;
14015         struct elink_phy phy;
14016         /* Use port1 because of the static port-swap */
14017         /* Enable the module detection interrupt */
14018         val = REG_RD(sc, MISC_REG_GPIO_EVENT_EN);
14019         val |= ((1<<MISC_REGISTERS_GPIO_3)|
14020                 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
14021         REG_WR(sc, MISC_REG_GPIO_EVENT_EN, val);
14022
14023         elink_ext_phy_hw_reset(sc, 0);
14024         DELAY(1000 * 5);
14025         for (port = 0; port < PORT_MAX; port++) {
14026                 uint32_t shmem_base, shmem2_base;
14027
14028                 /* In E2, same phy is using for port0 of the two paths */
14029                 if (CHIP_IS_E1x(sc)) {
14030                         shmem_base = shmem_base_path[0];
14031                         shmem2_base = shmem2_base_path[0];
14032                 } else {
14033                         shmem_base = shmem_base_path[port];
14034                         shmem2_base = shmem2_base_path[port];
14035                 }
14036                 /* Extract the ext phy address for the port */
14037                 if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
14038                                        port, &phy) !=
14039                     ELINK_STATUS_OK) {
14040                         ELINK_DEBUG_P0(sc, "populate phy failed\n");
14041                         return ELINK_STATUS_ERROR;
14042                 }
14043
14044                 /* Reset phy*/
14045                 elink_cl45_write(sc, &phy,
14046                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
14047
14048
14049                 /* Set fault module detected LED on */
14050                 elink_cb_gpio_write(sc, MISC_REGISTERS_GPIO_0,
14051                                MISC_REGISTERS_GPIO_HIGH,
14052                                port);
14053         }
14054
14055         return ELINK_STATUS_OK;
14056 }
14057 static void elink_get_ext_phy_reset_gpio(struct bxe_softc *sc, uint32_t shmem_base,
14058                                          uint8_t *io_gpio, uint8_t *io_port)
14059 {
14060
14061         uint32_t phy_gpio_reset = REG_RD(sc, shmem_base +
14062                                           offsetof(struct shmem_region,
14063                                 dev_info.port_hw_config[PORT_0].default_cfg));
14064         switch (phy_gpio_reset) {
14065         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0:
14066                 *io_gpio = 0;
14067                 *io_port = 0;
14068                 break;
14069         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0:
14070                 *io_gpio = 1;
14071                 *io_port = 0;
14072                 break;
14073         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0:
14074                 *io_gpio = 2;
14075                 *io_port = 0;
14076                 break;
14077         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0:
14078                 *io_gpio = 3;
14079                 *io_port = 0;
14080                 break;
14081         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1:
14082                 *io_gpio = 0;
14083                 *io_port = 1;
14084                 break;
14085         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1:
14086                 *io_gpio = 1;
14087                 *io_port = 1;
14088                 break;
14089         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1:
14090                 *io_gpio = 2;
14091                 *io_port = 1;
14092                 break;
14093         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1:
14094                 *io_gpio = 3;
14095                 *io_port = 1;
14096                 break;
14097         default:
14098                 /* Don't override the io_gpio and io_port */
14099                 break;
14100         }
14101 }
14102
14103 static elink_status_t elink_8727_common_init_phy(struct bxe_softc *sc,
14104                                       uint32_t shmem_base_path[],
14105                                       uint32_t shmem2_base_path[], uint8_t phy_index,
14106                                       uint32_t chip_id)
14107 {
14108         int8_t port, reset_gpio;
14109         uint32_t swap_val, swap_override;
14110         struct elink_phy phy[PORT_MAX];
14111         struct elink_phy *phy_blk[PORT_MAX];
14112         int8_t port_of_path;
14113         swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
14114         swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
14115
14116         reset_gpio = MISC_REGISTERS_GPIO_1;
14117         port = 1;
14118
14119         /* Retrieve the reset gpio/port which control the reset.
14120          * Default is GPIO1, PORT1
14121          */
14122         elink_get_ext_phy_reset_gpio(sc, shmem_base_path[0],
14123                                      (uint8_t *)&reset_gpio, (uint8_t *)&port);
14124
14125         /* Calculate the port based on port swap */
14126         port ^= (swap_val && swap_override);
14127
14128         /* Initiate PHY reset*/
14129         elink_cb_gpio_write(sc, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW,
14130                        port);
14131         DELAY(1000 * 1);
14132         elink_cb_gpio_write(sc, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH,
14133                        port);
14134
14135         DELAY(1000 * 5);
14136
14137         /* PART1 - Reset both phys */
14138         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14139                 uint32_t shmem_base, shmem2_base;
14140
14141                 /* In E2, same phy is using for port0 of the two paths */
14142                 if (CHIP_IS_E1x(sc)) {
14143                         shmem_base = shmem_base_path[0];
14144                         shmem2_base = shmem2_base_path[0];
14145                         port_of_path = port;
14146                 } else {
14147                         shmem_base = shmem_base_path[port];
14148                         shmem2_base = shmem2_base_path[port];
14149                         port_of_path = 0;
14150                 }
14151
14152                 /* Extract the ext phy address for the port */
14153                 if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
14154                                        port_of_path, &phy[port]) !=
14155                                        ELINK_STATUS_OK) {
14156                         ELINK_DEBUG_P0(sc, "populate phy failed\n");
14157                         return ELINK_STATUS_ERROR;
14158                 }
14159                 /* disable attentions */
14160                 elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 +
14161                                port_of_path*4,
14162                                (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14163                                 ELINK_NIG_MASK_XGXS0_LINK10G |
14164                                 ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14165                                 ELINK_NIG_MASK_MI_INT));
14166
14167
14168                 /* Reset the phy */
14169                 elink_cl45_write(sc, &phy[port],
14170                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
14171         }
14172
14173         /* Add delay of 150ms after reset */
14174         DELAY(1000 * 150);
14175         if (phy[PORT_0].addr & 0x1) {
14176                 phy_blk[PORT_0] = &(phy[PORT_1]);
14177                 phy_blk[PORT_1] = &(phy[PORT_0]);
14178         } else {
14179                 phy_blk[PORT_0] = &(phy[PORT_0]);
14180                 phy_blk[PORT_1] = &(phy[PORT_1]);
14181         }
14182         /* PART2 - Download firmware to both phys */
14183         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
14184                 if (CHIP_IS_E1x(sc))
14185                         port_of_path = port;
14186                 else
14187                         port_of_path = 0;
14188                 ELINK_DEBUG_P1(sc, "Loading spirom for phy address 0x%x\n",
14189                            phy_blk[port]->addr);
14190                 if (elink_8073_8727_external_rom_boot(sc, phy_blk[port],
14191                                                       port_of_path))
14192                         return ELINK_STATUS_ERROR;
14193                 /* Disable PHY transmitter output */
14194                 elink_cl45_write(sc, phy_blk[port],
14195                                  MDIO_PMA_DEVAD,
14196                                  MDIO_PMA_REG_TX_DISABLE, 1);
14197
14198         }
14199         return ELINK_STATUS_OK;
14200 }
14201
14202 static elink_status_t elink_84833_common_init_phy(struct bxe_softc *sc,
14203                                                 uint32_t shmem_base_path[],
14204                                                 uint32_t shmem2_base_path[],
14205                                                 uint8_t phy_index,
14206                                                 uint32_t chip_id)
14207 {
14208         uint8_t reset_gpios;
14209         reset_gpios = elink_84833_get_reset_gpios(sc, shmem_base_path, chip_id);
14210         elink_cb_gpio_mult_write(sc, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
14211         DELAY(10);
14212         elink_cb_gpio_mult_write(sc, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH);
14213         ELINK_DEBUG_P1(sc, "84833 reset pulse on pin values 0x%x\n",
14214                 reset_gpios);
14215         return ELINK_STATUS_OK;
14216 }
14217 static elink_status_t elink_ext_phy_common_init(struct bxe_softc *sc, uint32_t shmem_base_path[],
14218                                      uint32_t shmem2_base_path[], uint8_t phy_index,
14219                                      uint32_t ext_phy_type, uint32_t chip_id)
14220 {
14221         elink_status_t rc = ELINK_STATUS_OK;
14222
14223         switch (ext_phy_type) {
14224         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
14225                 rc = elink_8073_common_init_phy(sc, shmem_base_path,
14226                                                 shmem2_base_path,
14227                                                 phy_index, chip_id);
14228                 break;
14229         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
14230         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
14231         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
14232                 rc = elink_8727_common_init_phy(sc, shmem_base_path,
14233                                                 shmem2_base_path,
14234                                                 phy_index, chip_id);
14235                 break;
14236
14237         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
14238                 /* GPIO1 affects both ports, so there's need to pull
14239                  * it for single port alone
14240                  */
14241                 rc = elink_8726_common_init_phy(sc, shmem_base_path,
14242                                                 shmem2_base_path,
14243                                                 phy_index, chip_id);
14244                 break;
14245         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
14246         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834:
14247                 /* GPIO3's are linked, and so both need to be toggled
14248                  * to obtain required 2us pulse.
14249                  */
14250                 rc = elink_84833_common_init_phy(sc, shmem_base_path,
14251                                                 shmem2_base_path,
14252                                                 phy_index, chip_id);
14253                 break;
14254         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
14255                 rc = ELINK_STATUS_ERROR;
14256                 break;
14257         default:
14258                 ELINK_DEBUG_P1(sc,
14259                            "ext_phy 0x%x common init not required\n",
14260                            ext_phy_type);
14261                 break;
14262         }
14263
14264         if (rc != ELINK_STATUS_OK)
14265                 elink_cb_event_log(sc, ELINK_LOG_ID_PHY_UNINITIALIZED, 0); // "Warning: PHY was not initialized,"
14266                                      // " Port %d\n",
14267
14268         return rc;
14269 }
14270
14271 elink_status_t elink_common_init_phy(struct bxe_softc *sc, uint32_t shmem_base_path[],
14272                           uint32_t shmem2_base_path[], uint32_t chip_id,
14273                           uint8_t one_port_enabled)
14274 {
14275         elink_status_t rc = ELINK_STATUS_OK;
14276         uint32_t phy_ver, val;
14277         uint8_t phy_index = 0;
14278         uint32_t ext_phy_type, ext_phy_config;
14279 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
14280         if (CHIP_REV_IS_EMUL(sc) || CHIP_REV_IS_FPGA(sc))
14281                 return ELINK_STATUS_OK;
14282 #endif
14283
14284         elink_set_mdio_clk(sc, chip_id, GRCBASE_EMAC0);
14285         elink_set_mdio_clk(sc, chip_id, GRCBASE_EMAC1);
14286         ELINK_DEBUG_P0(sc, "Begin common phy init\n");
14287         if (CHIP_IS_E3(sc)) {
14288                 /* Enable EPIO */
14289                 val = REG_RD(sc, MISC_REG_GEN_PURP_HWG);
14290                 REG_WR(sc, MISC_REG_GEN_PURP_HWG, val | 1);
14291         }
14292         /* Check if common init was already done */
14293         phy_ver = REG_RD(sc, shmem_base_path[0] +
14294                          offsetof(struct shmem_region,
14295                                   port_mb[PORT_0].ext_phy_fw_version));
14296         if (phy_ver) {
14297                 ELINK_DEBUG_P1(sc, "Not doing common init; phy ver is 0x%x\n",
14298                                phy_ver);
14299                 return ELINK_STATUS_OK;
14300         }
14301
14302         /* Read the ext_phy_type for arbitrary port(0) */
14303         for (phy_index = ELINK_EXT_PHY1; phy_index < ELINK_MAX_PHYS;
14304               phy_index++) {
14305                 ext_phy_config = elink_get_ext_phy_config(sc,
14306                                                           shmem_base_path[0],
14307                                                           phy_index, 0);
14308                 ext_phy_type = ELINK_XGXS_EXT_PHY_TYPE(ext_phy_config);
14309                 rc |= elink_ext_phy_common_init(sc, shmem_base_path,
14310                                                 shmem2_base_path,
14311                                                 phy_index, ext_phy_type,
14312                                                 chip_id);
14313         }
14314         return rc;
14315 }
14316
14317 static void elink_check_over_curr(struct elink_params *params,
14318                                   struct elink_vars *vars)
14319 {
14320         struct bxe_softc *sc = params->sc;
14321         uint32_t cfg_pin;
14322         uint8_t port = params->port;
14323         uint32_t pin_val;
14324
14325         cfg_pin = (REG_RD(sc, params->shmem_base +
14326                           offsetof(struct shmem_region,
14327                                dev_info.port_hw_config[port].e3_cmn_pin_cfg1)) &
14328                    PORT_HW_CFG_E3_OVER_CURRENT_MASK) >>
14329                 PORT_HW_CFG_E3_OVER_CURRENT_SHIFT;
14330
14331         /* Ignore check if no external input PIN available */
14332         if (elink_get_cfg_pin(sc, cfg_pin, &pin_val) != ELINK_STATUS_OK)
14333                 return;
14334
14335         if (!pin_val) {
14336                 if ((vars->phy_flags & PHY_OVER_CURRENT_FLAG) == 0) {
14337                         elink_cb_event_log(sc, ELINK_LOG_ID_OVER_CURRENT, params->port); //"Error:  Power fault on Port %d has"
14338                                           //  " been detected and the power to "
14339                                           //  "that SFP+ module has been removed"
14340                                           //  " to prevent failure of the card."
14341                                           //  " Please remove the SFP+ module and"
14342                                           //  " restart the system to clear this"
14343                                           //  " error.\n",
14344                         vars->phy_flags |= PHY_OVER_CURRENT_FLAG;
14345                         elink_warpcore_power_module(params, 0);
14346                 }
14347         } else
14348                 vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG;
14349 }
14350
14351 /* Returns 0 if no change occured since last check; 1 otherwise. */
14352 static uint8_t elink_analyze_link_error(struct elink_params *params,
14353                                     struct elink_vars *vars, uint32_t status,
14354                                     uint32_t phy_flag, uint32_t link_flag, uint8_t notify)
14355 {
14356         struct bxe_softc *sc = params->sc;
14357         /* Compare new value with previous value */
14358         uint8_t led_mode;
14359         uint32_t old_status = (vars->phy_flags & phy_flag) ? 1 : 0;
14360
14361         if ((status ^ old_status) == 0)
14362                 return 0;
14363
14364         /* If values differ */
14365         switch (phy_flag) {
14366         case PHY_HALF_OPEN_CONN_FLAG:
14367                 ELINK_DEBUG_P0(sc, "Analyze Remote Fault\n");
14368                 break;
14369         case PHY_SFP_TX_FAULT_FLAG:
14370                 ELINK_DEBUG_P0(sc, "Analyze TX Fault\n");
14371                 break;
14372         default:
14373                 ELINK_DEBUG_P0(sc, "Analyze UNKNOWN\n");
14374         }
14375         ELINK_DEBUG_P3(sc, "Link changed:[%x %x]->%x\n", vars->link_up,
14376            old_status, status);
14377
14378         /* Do not touch the link in case physical link down */
14379         if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0)
14380                 return 1;
14381
14382         /* a. Update shmem->link_status accordingly
14383          * b. Update elink_vars->link_up
14384          */
14385         if (status) {
14386                 vars->link_status &= ~LINK_STATUS_LINK_UP;
14387                 vars->link_status |= link_flag;
14388                 vars->link_up = 0;
14389                 vars->phy_flags |= phy_flag;
14390
14391                 /* activate nig drain */
14392                 REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 1);
14393                 /* Set LED mode to off since the PHY doesn't know about these
14394                  * errors
14395                  */
14396                 led_mode = ELINK_LED_MODE_OFF;
14397         } else {
14398                 vars->link_status |= LINK_STATUS_LINK_UP;
14399                 vars->link_status &= ~link_flag;
14400                 vars->link_up = 1;
14401                 vars->phy_flags &= ~phy_flag;
14402                 led_mode = ELINK_LED_MODE_OPER;
14403
14404                 /* Clear nig drain */
14405                 REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
14406         }
14407         elink_sync_link(params, vars);
14408         /* Update the LED according to the link state */
14409         elink_set_led(params, vars, led_mode, ELINK_SPEED_10000);
14410
14411         /* Update link status in the shared memory */
14412         elink_update_mng(params, vars->link_status);
14413
14414         /* C. Trigger General Attention */
14415         vars->periodic_flags |= ELINK_PERIODIC_FLAGS_LINK_EVENT;
14416         if (notify)
14417                 elink_cb_notify_link_changed(sc);
14418
14419         return 1;
14420 }
14421
14422 /******************************************************************************
14423 * Description:
14424 *       This function checks for half opened connection change indication.
14425 *       When such change occurs, it calls the elink_analyze_link_error
14426 *       to check if Remote Fault is set or cleared. Reception of remote fault
14427 *       status message in the MAC indicates that the peer's MAC has detected
14428 *       a fault, for example, due to break in the TX side of fiber.
14429 *
14430 ******************************************************************************/
14431 elink_status_t elink_check_half_open_conn(struct elink_params *params,
14432                                 struct elink_vars *vars,
14433                                 uint8_t notify)
14434 {
14435         struct bxe_softc *sc = params->sc;
14436         uint32_t lss_status = 0;
14437         uint32_t mac_base;
14438         /* In case link status is physically up @ 10G do */
14439         if (((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0) ||
14440             (REG_RD(sc, NIG_REG_EGRESS_EMAC0_PORT + params->port*4)))
14441                 return ELINK_STATUS_OK;
14442
14443         if (CHIP_IS_E3(sc) &&
14444             (REG_RD(sc, MISC_REG_RESET_REG_2) &
14445               (MISC_REGISTERS_RESET_REG_2_XMAC))) {
14446                 /* Check E3 XMAC */
14447                 /* Note that link speed cannot be queried here, since it may be
14448                  * zero while link is down. In case UMAC is active, LSS will
14449                  * simply not be set
14450                  */
14451                 mac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
14452
14453                 /* Clear stick bits (Requires rising edge) */
14454                 REG_WR(sc, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
14455                 REG_WR(sc, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
14456                        XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
14457                        XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
14458                 if (REG_RD(sc, mac_base + XMAC_REG_RX_LSS_STATUS))
14459                         lss_status = 1;
14460
14461                 elink_analyze_link_error(params, vars, lss_status,
14462                                          PHY_HALF_OPEN_CONN_FLAG,
14463                                          LINK_STATUS_NONE, notify);
14464         } else if (REG_RD(sc, MISC_REG_RESET_REG_2) &
14465                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) {
14466                 /* Check E1X / E2 BMAC */
14467                 uint32_t lss_status_reg;
14468                 uint32_t wb_data[2];
14469                 mac_base = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
14470                         NIG_REG_INGRESS_BMAC0_MEM;
14471                 /*  Read BIGMAC_REGISTER_RX_LSS_STATUS */
14472                 if (CHIP_IS_E2(sc))
14473                         lss_status_reg = BIGMAC2_REGISTER_RX_LSS_STAT;
14474                 else
14475                         lss_status_reg = BIGMAC_REGISTER_RX_LSS_STATUS;
14476
14477                 REG_RD_DMAE(sc, mac_base + lss_status_reg, wb_data, 2);
14478                 lss_status = (wb_data[0] > 0);
14479
14480                 elink_analyze_link_error(params, vars, lss_status,
14481                                          PHY_HALF_OPEN_CONN_FLAG,
14482                                          LINK_STATUS_NONE, notify);
14483         }
14484         return ELINK_STATUS_OK;
14485 }
14486 static void elink_sfp_tx_fault_detection(struct elink_phy *phy,
14487                                          struct elink_params *params,
14488                                          struct elink_vars *vars)
14489 {
14490         struct bxe_softc *sc = params->sc;
14491         uint32_t cfg_pin, value = 0;
14492         uint8_t led_change, port = params->port;
14493
14494         /* Get The SFP+ TX_Fault controlling pin ([eg]pio) */
14495         cfg_pin = (REG_RD(sc, params->shmem_base + offsetof(struct shmem_region,
14496                           dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
14497                    PORT_HW_CFG_E3_TX_FAULT_MASK) >>
14498                   PORT_HW_CFG_E3_TX_FAULT_SHIFT;
14499
14500         if (elink_get_cfg_pin(sc, cfg_pin, &value)) {
14501                 ELINK_DEBUG_P1(sc, "Failed to read pin 0x%02x\n", cfg_pin);
14502                 return;
14503         }
14504
14505         led_change = elink_analyze_link_error(params, vars, value,
14506                                               PHY_SFP_TX_FAULT_FLAG,
14507                                               LINK_STATUS_SFP_TX_FAULT, 1);
14508
14509         if (led_change) {
14510                 /* Change TX_Fault led, set link status for further syncs */
14511                 uint8_t led_mode;
14512
14513                 if (vars->phy_flags & PHY_SFP_TX_FAULT_FLAG) {
14514                         led_mode = MISC_REGISTERS_GPIO_HIGH;
14515                         vars->link_status |= LINK_STATUS_SFP_TX_FAULT;
14516                 } else {
14517                         led_mode = MISC_REGISTERS_GPIO_LOW;
14518                         vars->link_status &= ~LINK_STATUS_SFP_TX_FAULT;
14519                 }
14520
14521                 /* If module is unapproved, led should be on regardless */
14522                 if (!(phy->flags & ELINK_FLAGS_SFP_NOT_APPROVED)) {
14523                         ELINK_DEBUG_P1(sc, "Change TX_Fault LED: ->%x\n",
14524                            led_mode);
14525                         elink_set_e3_module_fault_led(params, led_mode);
14526                 }
14527         }
14528 }
14529 static void elink_kr2_recovery(struct elink_params *params,
14530                                struct elink_vars *vars,
14531                                struct elink_phy *phy)
14532 {
14533         struct bxe_softc *sc = params->sc;
14534         ELINK_DEBUG_P0(sc, "KR2 recovery\n");
14535         elink_warpcore_enable_AN_KR2(phy, params, vars);
14536         elink_warpcore_restart_AN_KR(phy, params);
14537 }
14538
14539 static void elink_check_kr2_wa(struct elink_params *params,
14540                                struct elink_vars *vars,
14541                                struct elink_phy *phy)
14542 {
14543         struct bxe_softc *sc = params->sc;
14544         uint16_t base_page, next_page, not_kr2_device, lane;
14545         int sigdet;
14546
14547         /* Once KR2 was disabled, wait 5 seconds before checking KR2 recovery
14548          * Since some switches tend to reinit the AN process and clear the
14549          * the advertised BP/NP after ~2 seconds causing the KR2 to be disabled
14550          * and recovered many times
14551          */
14552         if (vars->check_kr2_recovery_cnt > 0) {
14553                 vars->check_kr2_recovery_cnt--;
14554                 return;
14555         }
14556
14557         sigdet = elink_warpcore_get_sigdet(phy, params);
14558         if (!sigdet) {
14559                 if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
14560                         elink_kr2_recovery(params, vars, phy);
14561                         ELINK_DEBUG_P0(sc, "No sigdet\n");
14562                 }
14563                 return;
14564         }
14565
14566         lane = elink_get_warpcore_lane(phy, params);
14567         CL22_WR_OVER_CL45(sc, phy, MDIO_REG_BANK_AER_BLOCK,
14568                           MDIO_AER_BLOCK_AER_REG, lane);
14569         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
14570                         MDIO_AN_REG_LP_AUTO_NEG, &base_page);
14571         elink_cl45_read(sc, phy, MDIO_AN_DEVAD,
14572                         MDIO_AN_REG_LP_AUTO_NEG2, &next_page);
14573         elink_set_aer_mmd(params, phy);
14574
14575         /* CL73 has not begun yet */
14576         if (base_page == 0) {
14577                 if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
14578                         elink_kr2_recovery(params, vars, phy);
14579                         ELINK_DEBUG_P0(sc, "No BP\n");
14580                 }
14581                 return;
14582         }
14583
14584         /* In case NP bit is not set in the BasePage, or it is set,
14585          * but only KX is advertised, declare this link partner as non-KR2
14586          * device.
14587          */
14588         not_kr2_device = (((base_page & 0x8000) == 0) ||
14589                           (((base_page & 0x8000) &&
14590                             ((next_page & 0xe0) == 0x2))));
14591
14592         /* In case KR2 is already disabled, check if we need to re-enable it */
14593         if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
14594                 if (!not_kr2_device) {
14595                         ELINK_DEBUG_P2(sc, "BP=0x%x, NP=0x%x\n", base_page,
14596                            next_page);
14597                         elink_kr2_recovery(params, vars, phy);
14598                 }
14599                 return;
14600         }
14601         /* KR2 is enabled, but not KR2 device */
14602         if (not_kr2_device) {
14603                 /* Disable KR2 on both lanes */
14604                 ELINK_DEBUG_P2(sc, "BP=0x%x, NP=0x%x\n", base_page, next_page);
14605                 elink_disable_kr2(params, vars, phy);
14606                 /* Restart AN on leading lane */
14607                 elink_warpcore_restart_AN_KR(phy, params);
14608                 return;
14609         }
14610 }
14611
14612 void elink_period_func(struct elink_params *params, struct elink_vars *vars)
14613 {
14614         uint16_t phy_idx;
14615         struct bxe_softc *sc = params->sc;
14616         for (phy_idx = ELINK_INT_PHY; phy_idx < ELINK_MAX_PHYS; phy_idx++) {
14617                 if (params->phy[phy_idx].flags & ELINK_FLAGS_TX_ERROR_CHECK) {
14618                         elink_set_aer_mmd(params, &params->phy[phy_idx]);
14619                         if (elink_check_half_open_conn(params, vars, 1) !=
14620                             ELINK_STATUS_OK)
14621                                 ELINK_DEBUG_P0(sc, "Fault detection failed\n");
14622                         break;
14623                 }
14624         }
14625
14626         if (CHIP_IS_E3(sc)) {
14627                 struct elink_phy *phy = &params->phy[ELINK_INT_PHY];
14628                 elink_set_aer_mmd(params, phy);
14629                 if ((phy->supported & ELINK_SUPPORTED_20000baseKR2_Full) &&
14630                     (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G))
14631                         elink_check_kr2_wa(params, vars, phy);
14632                 elink_check_over_curr(params, vars);
14633                 if (vars->rx_tx_asic_rst)
14634                         elink_warpcore_config_runtime(phy, params, vars);
14635
14636                 if ((REG_RD(sc, params->shmem_base +
14637                             offsetof(struct shmem_region, dev_info.
14638                                 port_hw_config[params->port].default_cfg))
14639                     & PORT_HW_CFG_NET_SERDES_IF_MASK) ==
14640                     PORT_HW_CFG_NET_SERDES_IF_SFI) {
14641                         if (elink_is_sfp_module_plugged(phy, params)) {
14642                                 elink_sfp_tx_fault_detection(phy, params, vars);
14643                         } else if (vars->link_status &
14644                                 LINK_STATUS_SFP_TX_FAULT) {
14645                                 /* Clean trail, interrupt corrects the leds */
14646                                 vars->link_status &= ~LINK_STATUS_SFP_TX_FAULT;
14647                                 vars->phy_flags &= ~PHY_SFP_TX_FAULT_FLAG;
14648                                 /* Update link status in the shared memory */
14649                                 elink_update_mng(params, vars->link_status);
14650                         }
14651                 }
14652         }
14653 }
14654
14655 uint8_t elink_fan_failure_det_req(struct bxe_softc *sc,
14656                              uint32_t shmem_base,
14657                              uint32_t shmem2_base,
14658                              uint8_t port)
14659 {
14660         uint8_t phy_index, fan_failure_det_req = 0;
14661         struct elink_phy phy;
14662         for (phy_index = ELINK_EXT_PHY1; phy_index < ELINK_MAX_PHYS;
14663               phy_index++) {
14664                 if (elink_populate_phy(sc, phy_index, shmem_base, shmem2_base,
14665                                        port, &phy)
14666                     != ELINK_STATUS_OK) {
14667                         ELINK_DEBUG_P0(sc, "populate phy failed\n");
14668                         return 0;
14669                 }
14670                 fan_failure_det_req |= (phy.flags &
14671                                         ELINK_FLAGS_FAN_FAILURE_DET_REQ);
14672         }
14673         return fan_failure_det_req;
14674 }
14675
14676 void elink_hw_reset_phy(struct elink_params *params)
14677 {
14678         uint8_t phy_index;
14679         struct bxe_softc *sc = params->sc;
14680         elink_update_mng(params, 0);
14681         elink_bits_dis(sc, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
14682                        (ELINK_NIG_MASK_XGXS0_LINK_STATUS |
14683                         ELINK_NIG_MASK_XGXS0_LINK10G |
14684                         ELINK_NIG_MASK_SERDES0_LINK_STATUS |
14685                         ELINK_NIG_MASK_MI_INT));
14686
14687         for (phy_index = ELINK_INT_PHY; phy_index < ELINK_MAX_PHYS;
14688               phy_index++) {
14689                 if (params->phy[phy_index].hw_reset) {
14690                         params->phy[phy_index].hw_reset(
14691                                 &params->phy[phy_index],
14692                                 params);
14693                         params->phy[phy_index] = phy_null;
14694                 }
14695         }
14696 }
14697
14698 void elink_init_mod_abs_int(struct bxe_softc *sc, struct elink_vars *vars,
14699                             uint32_t chip_id, uint32_t shmem_base, uint32_t shmem2_base,
14700                             uint8_t port)
14701 {
14702         uint8_t gpio_num = 0xff, gpio_port = 0xff, phy_index;
14703         uint32_t val;
14704         uint32_t offset, aeu_mask, swap_val, swap_override, sync_offset;
14705         if (CHIP_IS_E3(sc)) {
14706                 if (elink_get_mod_abs_int_cfg(sc, chip_id,
14707                                               shmem_base,
14708                                               port,
14709                                               &gpio_num,
14710                                               &gpio_port) != ELINK_STATUS_OK)
14711                         return;
14712         } else {
14713                 struct elink_phy phy;
14714                 for (phy_index = ELINK_EXT_PHY1; phy_index < ELINK_MAX_PHYS;
14715                       phy_index++) {
14716                         if (elink_populate_phy(sc, phy_index, shmem_base,
14717                                                shmem2_base, port, &phy)
14718                             != ELINK_STATUS_OK) {
14719                                 ELINK_DEBUG_P0(sc, "populate phy failed\n");
14720                                 return;
14721                         }
14722                         if (phy.type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
14723                                 gpio_num = MISC_REGISTERS_GPIO_3;
14724                                 gpio_port = port;
14725                                 break;
14726                         }
14727                 }
14728         }
14729
14730         if (gpio_num == 0xff)
14731                 return;
14732
14733         /* Set GPIO3 to trigger SFP+ module insertion/removal */
14734         elink_cb_gpio_write(sc, gpio_num, MISC_REGISTERS_GPIO_INPUT_HI_Z, gpio_port);
14735
14736         swap_val = REG_RD(sc, NIG_REG_PORT_SWAP);
14737         swap_override = REG_RD(sc, NIG_REG_STRAP_OVERRIDE);
14738         gpio_port ^= (swap_val && swap_override);
14739
14740         vars->aeu_int_mask = AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 <<
14741                 (gpio_num + (gpio_port << 2));
14742
14743         sync_offset = shmem_base +
14744                 offsetof(struct shmem_region,
14745                          dev_info.port_hw_config[port].aeu_int_mask);
14746         REG_WR(sc, sync_offset, vars->aeu_int_mask);
14747
14748         ELINK_DEBUG_P3(sc, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x\n",
14749                        gpio_num, gpio_port, vars->aeu_int_mask);
14750
14751         if (port == 0)
14752                 offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
14753         else
14754                 offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
14755
14756         /* Open appropriate AEU for interrupts */
14757         aeu_mask = REG_RD(sc, offset);
14758         aeu_mask |= vars->aeu_int_mask;
14759         REG_WR(sc, offset, aeu_mask);
14760
14761         /* Enable the GPIO to trigger interrupt */
14762         val = REG_RD(sc, MISC_REG_GPIO_EVENT_EN);
14763         val |= 1 << (gpio_num + (gpio_port << 2));
14764         REG_WR(sc, MISC_REG_GPIO_EVENT_EN, val);
14765 }
14766