Merge tag 'soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / net / ethernet / broadcom / bnx2x / bnx2x_link.c
1 /* Copyright 2008-2012 Broadcom Corporation
2  *
3  * Unless you and Broadcom execute a separate written software license
4  * agreement governing use of this software, this software is licensed to you
5  * under the terms of the GNU General Public License version 2, available
6  * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
7  *
8  * Notwithstanding the above, under no circumstances may you combine this
9  * software in any way with any other Broadcom software provided under a
10  * license other than the GPL, without Broadcom's express prior written
11  * consent.
12  *
13  * Written by Yaniv Rosner
14  *
15  */
16
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/pci.h>
22 #include <linux/netdevice.h>
23 #include <linux/delay.h>
24 #include <linux/ethtool.h>
25 #include <linux/mutex.h>
26
27 #include "bnx2x.h"
28 #include "bnx2x_cmn.h"
29
30 /********************************************************/
31 #define ETH_HLEN                        14
32 /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
33 #define ETH_OVREHEAD                    (ETH_HLEN + 8 + 8)
34 #define ETH_MIN_PACKET_SIZE             60
35 #define ETH_MAX_PACKET_SIZE             1500
36 #define ETH_MAX_JUMBO_PACKET_SIZE       9600
37 #define MDIO_ACCESS_TIMEOUT             1000
38 #define BMAC_CONTROL_RX_ENABLE          2
39 #define WC_LANE_MAX                     4
40 #define I2C_SWITCH_WIDTH                2
41 #define I2C_BSC0                        0
42 #define I2C_BSC1                        1
43 #define I2C_WA_RETRY_CNT                3
44 #define MCPR_IMC_COMMAND_READ_OP        1
45 #define MCPR_IMC_COMMAND_WRITE_OP       2
46
47 /* LED Blink rate that will achieve ~15.9Hz */
48 #define LED_BLINK_RATE_VAL_E3           354
49 #define LED_BLINK_RATE_VAL_E1X_E2       480
50 /***********************************************************/
51 /*                      Shortcut definitions               */
52 /***********************************************************/
53
54 #define NIG_LATCH_BC_ENABLE_MI_INT 0
55
56 #define NIG_STATUS_EMAC0_MI_INT \
57                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
58 #define NIG_STATUS_XGXS0_LINK10G \
59                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
60 #define NIG_STATUS_XGXS0_LINK_STATUS \
61                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
62 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
63                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
64 #define NIG_STATUS_SERDES0_LINK_STATUS \
65                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
66 #define NIG_MASK_MI_INT \
67                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
68 #define NIG_MASK_XGXS0_LINK10G \
69                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
70 #define NIG_MASK_XGXS0_LINK_STATUS \
71                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
72 #define NIG_MASK_SERDES0_LINK_STATUS \
73                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
74
75 #define MDIO_AN_CL73_OR_37_COMPLETE \
76                 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
77                  MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
78
79 #define XGXS_RESET_BITS \
80         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
81          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
82          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
83          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
84          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
85
86 #define SERDES_RESET_BITS \
87         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
88          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
89          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
90          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
91
92 #define AUTONEG_CL37            SHARED_HW_CFG_AN_ENABLE_CL37
93 #define AUTONEG_CL73            SHARED_HW_CFG_AN_ENABLE_CL73
94 #define AUTONEG_BAM             SHARED_HW_CFG_AN_ENABLE_BAM
95 #define AUTONEG_PARALLEL \
96                                 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
97 #define AUTONEG_SGMII_FIBER_AUTODET \
98                                 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
99 #define AUTONEG_REMOTE_PHY      SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
100
101 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
102                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
103 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
104                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
105 #define GP_STATUS_SPEED_MASK \
106                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
107 #define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
108 #define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
109 #define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
110 #define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
111 #define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
112 #define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
113 #define GP_STATUS_10G_HIG \
114                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
115 #define GP_STATUS_10G_CX4 \
116                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
117 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
118 #define GP_STATUS_10G_KX4 \
119                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
120 #define GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR
121 #define GP_STATUS_10G_XFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI
122 #define GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS
123 #define GP_STATUS_10G_SFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI
124 #define LINK_10THD              LINK_STATUS_SPEED_AND_DUPLEX_10THD
125 #define LINK_10TFD              LINK_STATUS_SPEED_AND_DUPLEX_10TFD
126 #define LINK_100TXHD            LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
127 #define LINK_100T4              LINK_STATUS_SPEED_AND_DUPLEX_100T4
128 #define LINK_100TXFD            LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
129 #define LINK_1000THD            LINK_STATUS_SPEED_AND_DUPLEX_1000THD
130 #define LINK_1000TFD            LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
131 #define LINK_1000XFD            LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
132 #define LINK_2500THD            LINK_STATUS_SPEED_AND_DUPLEX_2500THD
133 #define LINK_2500TFD            LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
134 #define LINK_2500XFD            LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
135 #define LINK_10GTFD             LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
136 #define LINK_10GXFD             LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
137 #define LINK_20GTFD             LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
138 #define LINK_20GXFD             LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
139
140
141
142 /* */
143 #define SFP_EEPROM_CON_TYPE_ADDR                0x2
144         #define SFP_EEPROM_CON_TYPE_VAL_LC      0x7
145         #define SFP_EEPROM_CON_TYPE_VAL_COPPER  0x21
146
147
148 #define SFP_EEPROM_COMP_CODE_ADDR               0x3
149         #define SFP_EEPROM_COMP_CODE_SR_MASK    (1<<4)
150         #define SFP_EEPROM_COMP_CODE_LR_MASK    (1<<5)
151         #define SFP_EEPROM_COMP_CODE_LRM_MASK   (1<<6)
152
153 #define SFP_EEPROM_FC_TX_TECH_ADDR              0x8
154         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
155         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE  0x8
156
157 #define SFP_EEPROM_OPTIONS_ADDR                 0x40
158         #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
159 #define SFP_EEPROM_OPTIONS_SIZE                 2
160
161 #define EDC_MODE_LINEAR                         0x0022
162 #define EDC_MODE_LIMITING                               0x0044
163 #define EDC_MODE_PASSIVE_DAC                    0x0055
164
165 /* BRB default for class 0 E2 */
166 #define DEFAULT0_E2_BRB_MAC_PAUSE_XOFF_THR      170
167 #define DEFAULT0_E2_BRB_MAC_PAUSE_XON_THR               250
168 #define DEFAULT0_E2_BRB_MAC_FULL_XOFF_THR               10
169 #define DEFAULT0_E2_BRB_MAC_FULL_XON_THR                50
170
171 /* BRB thresholds for E2*/
172 #define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE             170
173 #define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE         0
174
175 #define PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE              250
176 #define PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE          0
177
178 #define PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE              10
179 #define PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE          90
180
181 #define PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE                       50
182 #define PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE           250
183
184 /* BRB default for class 0 E3A0 */
185 #define DEFAULT0_E3A0_BRB_MAC_PAUSE_XOFF_THR    290
186 #define DEFAULT0_E3A0_BRB_MAC_PAUSE_XON_THR     410
187 #define DEFAULT0_E3A0_BRB_MAC_FULL_XOFF_THR     10
188 #define DEFAULT0_E3A0_BRB_MAC_FULL_XON_THR      50
189
190 /* BRB thresholds for E3A0 */
191 #define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE           290
192 #define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE               0
193
194 #define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE            410
195 #define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE                0
196
197 #define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE            10
198 #define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE                170
199
200 #define PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE             50
201 #define PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE         410
202
203 /* BRB default for E3B0 */
204 #define DEFAULT0_E3B0_BRB_MAC_PAUSE_XOFF_THR    330
205 #define DEFAULT0_E3B0_BRB_MAC_PAUSE_XON_THR     490
206 #define DEFAULT0_E3B0_BRB_MAC_FULL_XOFF_THR     15
207 #define DEFAULT0_E3B0_BRB_MAC_FULL_XON_THR      55
208
209 /* BRB thresholds for E3B0 2 port mode*/
210 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE                1025
211 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE    0
212
213 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE         1025
214 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE     0
215
216 #define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE         10
217 #define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE     1025
218
219 #define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE          50
220 #define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE      1025
221
222 /* only for E3B0*/
223 #define PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR                        1025
224 #define PFC_E3B0_2P_BRB_FULL_LB_XON_THR                 1025
225
226 /* Lossy +Lossless GUARANTIED == GUART */
227 #define PFC_E3B0_2P_MIX_PAUSE_LB_GUART                  284
228 /* Lossless +Lossless*/
229 #define PFC_E3B0_2P_PAUSE_LB_GUART                      236
230 /* Lossy +Lossy*/
231 #define PFC_E3B0_2P_NON_PAUSE_LB_GUART                  342
232
233 /* Lossy +Lossless*/
234 #define PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART               284
235 /* Lossless +Lossless*/
236 #define PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART           236
237 /* Lossy +Lossy*/
238 #define PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART               336
239 #define PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST                80
240
241 #define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART             0
242 #define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST                0
243
244 /* BRB thresholds for E3B0 4 port mode */
245 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE                304
246 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE    0
247
248 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE         384
249 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE     0
250
251 #define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE         10
252 #define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE     304
253
254 #define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE          50
255 #define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE      384
256
257 /* only for E3B0*/
258 #define PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR                        304
259 #define PFC_E3B0_4P_BRB_FULL_LB_XON_THR                 384
260 #define PFC_E3B0_4P_LB_GUART            120
261
262 #define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART             120
263 #define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST        80
264
265 #define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART             80
266 #define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST        120
267
268 /* Pause defines*/
269 #define DEFAULT_E3B0_BRB_FULL_LB_XOFF_THR                       330
270 #define DEFAULT_E3B0_BRB_FULL_LB_XON_THR                        490
271 #define DEFAULT_E3B0_LB_GUART           40
272
273 #define DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART            40
274 #define DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART_HYST       0
275
276 #define DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART            40
277 #define DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART_HYST       0
278
279 /* ETS defines*/
280 #define DCBX_INVALID_COS                                        (0xFF)
281
282 #define ETS_BW_LIMIT_CREDIT_UPPER_BOUND         (0x5000)
283 #define ETS_BW_LIMIT_CREDIT_WEIGHT              (0x5000)
284 #define ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS             (1360)
285 #define ETS_E3B0_NIG_MIN_W_VAL_20GBPS                   (2720)
286 #define ETS_E3B0_PBF_MIN_W_VAL                          (10000)
287
288 #define MAX_PACKET_SIZE                                 (9700)
289 #define WC_UC_TIMEOUT                                   100
290 #define MAX_KR_LINK_RETRY                               4
291
292 /**********************************************************/
293 /*                     INTERFACE                          */
294 /**********************************************************/
295
296 #define CL22_WR_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
297         bnx2x_cl45_write(_bp, _phy, \
298                 (_phy)->def_md_devad, \
299                 (_bank + (_addr & 0xf)), \
300                 _val)
301
302 #define CL22_RD_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
303         bnx2x_cl45_read(_bp, _phy, \
304                 (_phy)->def_md_devad, \
305                 (_bank + (_addr & 0xf)), \
306                 _val)
307
308 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
309 {
310         u32 val = REG_RD(bp, reg);
311
312         val |= bits;
313         REG_WR(bp, reg, val);
314         return val;
315 }
316
317 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
318 {
319         u32 val = REG_RD(bp, reg);
320
321         val &= ~bits;
322         REG_WR(bp, reg, val);
323         return val;
324 }
325
326 /******************************************************************/
327 /*                      EPIO/GPIO section                         */
328 /******************************************************************/
329 static void bnx2x_get_epio(struct bnx2x *bp, u32 epio_pin, u32 *en)
330 {
331         u32 epio_mask, gp_oenable;
332         *en = 0;
333         /* Sanity check */
334         if (epio_pin > 31) {
335                 DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to get\n", epio_pin);
336                 return;
337         }
338
339         epio_mask = 1 << epio_pin;
340         /* Set this EPIO to output */
341         gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE);
342         REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable & ~epio_mask);
343
344         *en = (REG_RD(bp, MCP_REG_MCPR_GP_INPUTS) & epio_mask) >> epio_pin;
345 }
346 static void bnx2x_set_epio(struct bnx2x *bp, u32 epio_pin, u32 en)
347 {
348         u32 epio_mask, gp_output, gp_oenable;
349
350         /* Sanity check */
351         if (epio_pin > 31) {
352                 DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to set\n", epio_pin);
353                 return;
354         }
355         DP(NETIF_MSG_LINK, "Setting EPIO pin %d to %d\n", epio_pin, en);
356         epio_mask = 1 << epio_pin;
357         /* Set this EPIO to output */
358         gp_output = REG_RD(bp, MCP_REG_MCPR_GP_OUTPUTS);
359         if (en)
360                 gp_output |= epio_mask;
361         else
362                 gp_output &= ~epio_mask;
363
364         REG_WR(bp, MCP_REG_MCPR_GP_OUTPUTS, gp_output);
365
366         /* Set the value for this EPIO */
367         gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE);
368         REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask);
369 }
370
371 static void bnx2x_set_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 val)
372 {
373         if (pin_cfg == PIN_CFG_NA)
374                 return;
375         if (pin_cfg >= PIN_CFG_EPIO0) {
376                 bnx2x_set_epio(bp, pin_cfg - PIN_CFG_EPIO0, val);
377         } else {
378                 u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
379                 u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
380                 bnx2x_set_gpio(bp, gpio_num, (u8)val, gpio_port);
381         }
382 }
383
384 static u32 bnx2x_get_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 *val)
385 {
386         if (pin_cfg == PIN_CFG_NA)
387                 return -EINVAL;
388         if (pin_cfg >= PIN_CFG_EPIO0) {
389                 bnx2x_get_epio(bp, pin_cfg - PIN_CFG_EPIO0, val);
390         } else {
391                 u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
392                 u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
393                 *val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
394         }
395         return 0;
396
397 }
398 /******************************************************************/
399 /*                              ETS section                       */
400 /******************************************************************/
401 static void bnx2x_ets_e2e3a0_disabled(struct link_params *params)
402 {
403         /* ETS disabled configuration*/
404         struct bnx2x *bp = params->bp;
405
406         DP(NETIF_MSG_LINK, "ETS E2E3 disabled configuration\n");
407
408         /*
409          * mapping between entry  priority to client number (0,1,2 -debug and
410          * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
411          * 3bits client num.
412          *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
413          * cos1-100     cos0-011     dbg1-010     dbg0-001     MCP-000
414          */
415
416         REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
417         /*
418          * Bitmap of 5bits length. Each bit specifies whether the entry behaves
419          * as strict.  Bits 0,1,2 - debug and management entries, 3 -
420          * COS0 entry, 4 - COS1 entry.
421          * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
422          * bit4   bit3    bit2   bit1     bit0
423          * MCP and debug are strict
424          */
425
426         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
427         /* defines which entries (clients) are subjected to WFQ arbitration */
428         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
429         /*
430          * For strict priority entries defines the number of consecutive
431          * slots for the highest priority.
432          */
433         REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
434         /*
435          * mapping between the CREDIT_WEIGHT registers and actual client
436          * numbers
437          */
438         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
439         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
440         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
441
442         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
443         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
444         REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
445         /* ETS mode disable */
446         REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
447         /*
448          * If ETS mode is enabled (there is no strict priority) defines a WFQ
449          * weight for COS0/COS1.
450          */
451         REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
452         REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710);
453         /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
454         REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680);
455         REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680);
456         /* Defines the number of consecutive slots for the strict priority */
457         REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
458 }
459 /******************************************************************************
460 * Description:
461 *       Getting min_w_val will be set according to line speed .
462 *.
463 ******************************************************************************/
464 static u32 bnx2x_ets_get_min_w_val_nig(const struct link_vars *vars)
465 {
466         u32 min_w_val = 0;
467         /* Calculate min_w_val.*/
468         if (vars->link_up) {
469                 if (vars->line_speed == SPEED_20000)
470                         min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
471                 else
472                         min_w_val = ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS;
473         } else
474                 min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
475         /**
476          *  If the link isn't up (static configuration for example ) The
477          *  link will be according to 20GBPS.
478         */
479         return min_w_val;
480 }
481 /******************************************************************************
482 * Description:
483 *       Getting credit upper bound form min_w_val.
484 *.
485 ******************************************************************************/
486 static u32 bnx2x_ets_get_credit_upper_bound(const u32 min_w_val)
487 {
488         const u32 credit_upper_bound = (u32)MAXVAL((150 * min_w_val),
489                                                 MAX_PACKET_SIZE);
490         return credit_upper_bound;
491 }
492 /******************************************************************************
493 * Description:
494 *       Set credit upper bound for NIG.
495 *.
496 ******************************************************************************/
497 static void bnx2x_ets_e3b0_set_credit_upper_bound_nig(
498         const struct link_params *params,
499         const u32 min_w_val)
500 {
501         struct bnx2x *bp = params->bp;
502         const u8 port = params->port;
503         const u32 credit_upper_bound =
504             bnx2x_ets_get_credit_upper_bound(min_w_val);
505
506         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_0 :
507                 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, credit_upper_bound);
508         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_1 :
509                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, credit_upper_bound);
510         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_2 :
511                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_2, credit_upper_bound);
512         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_3 :
513                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_3, credit_upper_bound);
514         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_4 :
515                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_4, credit_upper_bound);
516         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_5 :
517                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_5, credit_upper_bound);
518
519         if (!port) {
520                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_6,
521                         credit_upper_bound);
522                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_7,
523                         credit_upper_bound);
524                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_8,
525                         credit_upper_bound);
526         }
527 }
528 /******************************************************************************
529 * Description:
530 *       Will return the NIG ETS registers to init values.Except
531 *       credit_upper_bound.
532 *       That isn't used in this configuration (No WFQ is enabled) and will be
533 *       configured acording to spec
534 *.
535 ******************************************************************************/
536 static void bnx2x_ets_e3b0_nig_disabled(const struct link_params *params,
537                                         const struct link_vars *vars)
538 {
539         struct bnx2x *bp = params->bp;
540         const u8 port = params->port;
541         const u32 min_w_val = bnx2x_ets_get_min_w_val_nig(vars);
542         /**
543          * mapping between entry  priority to client number (0,1,2 -debug and
544          * management clients, 3 - COS0 client, 4 - COS1, ... 8 -
545          * COS5)(HIGHEST) 4bits client num.TODO_ETS - Should be done by
546          * reset value or init tool
547          */
548         if (port) {
549                 REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB, 0x543210);
550                 REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB, 0x0);
551         } else {
552                 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, 0x76543210);
553                 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, 0x8);
554         }
555         /**
556         * For strict priority entries defines the number of consecutive
557         * slots for the highest priority.
558         */
559         /* TODO_ETS - Should be done by reset value or init tool */
560         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS :
561                    NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
562         /**
563          * mapping between the CREDIT_WEIGHT registers and actual client
564          * numbers
565          */
566         /* TODO_ETS - Should be done by reset value or init tool */
567         if (port) {
568                 /*Port 1 has 6 COS*/
569                 REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB, 0x210543);
570                 REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x0);
571         } else {
572                 /*Port 0 has 9 COS*/
573                 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_LSB,
574                        0x43210876);
575                 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x5);
576         }
577
578         /**
579          * Bitmap of 5bits length. Each bit specifies whether the entry behaves
580          * as strict.  Bits 0,1,2 - debug and management entries, 3 -
581          * COS0 entry, 4 - COS1 entry.
582          * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
583          * bit4   bit3    bit2   bit1     bit0
584          * MCP and debug are strict
585          */
586         if (port)
587                 REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT, 0x3f);
588         else
589                 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1ff);
590         /* defines which entries (clients) are subjected to WFQ arbitration */
591         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
592                    NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
593
594         /**
595         * Please notice the register address are note continuous and a
596         * for here is note appropriate.In 2 port mode port0 only COS0-5
597         * can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4
598         * port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT
599         * are never used for WFQ
600         */
601         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
602                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0x0);
603         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
604                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0x0);
605         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
606                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2, 0x0);
607         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_3 :
608                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3, 0x0);
609         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_4 :
610                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4, 0x0);
611         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_5 :
612                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5, 0x0);
613         if (!port) {
614                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_6, 0x0);
615                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_7, 0x0);
616                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_8, 0x0);
617         }
618
619         bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val);
620 }
621 /******************************************************************************
622 * Description:
623 *       Set credit upper bound for PBF.
624 *.
625 ******************************************************************************/
626 static void bnx2x_ets_e3b0_set_credit_upper_bound_pbf(
627         const struct link_params *params,
628         const u32 min_w_val)
629 {
630         struct bnx2x *bp = params->bp;
631         const u32 credit_upper_bound =
632             bnx2x_ets_get_credit_upper_bound(min_w_val);
633         const u8 port = params->port;
634         u32 base_upper_bound = 0;
635         u8 max_cos = 0;
636         u8 i = 0;
637         /**
638         * In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4
639         * port mode port1 has COS0-2 that can be used for WFQ.
640         */
641         if (!port) {
642                 base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P0;
643                 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0;
644         } else {
645                 base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P1;
646                 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1;
647         }
648
649         for (i = 0; i < max_cos; i++)
650                 REG_WR(bp, base_upper_bound + (i << 2), credit_upper_bound);
651 }
652
653 /******************************************************************************
654 * Description:
655 *       Will return the PBF ETS registers to init values.Except
656 *       credit_upper_bound.
657 *       That isn't used in this configuration (No WFQ is enabled) and will be
658 *       configured acording to spec
659 *.
660 ******************************************************************************/
661 static void bnx2x_ets_e3b0_pbf_disabled(const struct link_params *params)
662 {
663         struct bnx2x *bp = params->bp;
664         const u8 port = params->port;
665         const u32 min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL;
666         u8 i = 0;
667         u32 base_weight = 0;
668         u8 max_cos = 0;
669
670         /**
671          * mapping between entry  priority to client number 0 - COS0
672          * client, 2 - COS1, ... 5 - COS5)(HIGHEST) 4bits client num.
673          * TODO_ETS - Should be done by reset value or init tool
674          */
675         if (port)
676                 /*  0x688 (|011|0 10|00 1|000) */
677                 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , 0x688);
678         else
679                 /*  (10 1|100 |011|0 10|00 1|000) */
680                 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , 0x2C688);
681
682         /* TODO_ETS - Should be done by reset value or init tool */
683         if (port)
684                 /* 0x688 (|011|0 10|00 1|000)*/
685                 REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P1, 0x688);
686         else
687         /* 0x2C688 (10 1|100 |011|0 10|00 1|000) */
688         REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P0, 0x2C688);
689
690         REG_WR(bp, (port) ? PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P1 :
691                    PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P0 , 0x100);
692
693
694         REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
695                    PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , 0);
696
697         REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
698                    PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0 , 0);
699         /**
700         * In 2 port mode port0 has COS0-5 that can be used for WFQ.
701         * In 4 port mode port1 has COS0-2 that can be used for WFQ.
702         */
703         if (!port) {
704                 base_weight = PBF_REG_COS0_WEIGHT_P0;
705                 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0;
706         } else {
707                 base_weight = PBF_REG_COS0_WEIGHT_P1;
708                 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1;
709         }
710
711         for (i = 0; i < max_cos; i++)
712                 REG_WR(bp, base_weight + (0x4 * i), 0);
713
714         bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
715 }
716 /******************************************************************************
717 * Description:
718 *       E3B0 disable will return basicly the values to init values.
719 *.
720 ******************************************************************************/
721 static int bnx2x_ets_e3b0_disabled(const struct link_params *params,
722                                    const struct link_vars *vars)
723 {
724         struct bnx2x *bp = params->bp;
725
726         if (!CHIP_IS_E3B0(bp)) {
727                 DP(NETIF_MSG_LINK,
728                    "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
729                 return -EINVAL;
730         }
731
732         bnx2x_ets_e3b0_nig_disabled(params, vars);
733
734         bnx2x_ets_e3b0_pbf_disabled(params);
735
736         return 0;
737 }
738
739 /******************************************************************************
740 * Description:
741 *       Disable will return basicly the values to init values.
742 *.
743 ******************************************************************************/
744 int bnx2x_ets_disabled(struct link_params *params,
745                       struct link_vars *vars)
746 {
747         struct bnx2x *bp = params->bp;
748         int bnx2x_status = 0;
749
750         if ((CHIP_IS_E2(bp)) || (CHIP_IS_E3A0(bp)))
751                 bnx2x_ets_e2e3a0_disabled(params);
752         else if (CHIP_IS_E3B0(bp))
753                 bnx2x_status = bnx2x_ets_e3b0_disabled(params, vars);
754         else {
755                 DP(NETIF_MSG_LINK, "bnx2x_ets_disabled - chip not supported\n");
756                 return -EINVAL;
757         }
758
759         return bnx2x_status;
760 }
761
762 /******************************************************************************
763 * Description
764 *       Set the COS mappimg to SP and BW until this point all the COS are not
765 *       set as SP or BW.
766 ******************************************************************************/
767 static int bnx2x_ets_e3b0_cli_map(const struct link_params *params,
768                                   const struct bnx2x_ets_params *ets_params,
769                                   const u8 cos_sp_bitmap,
770                                   const u8 cos_bw_bitmap)
771 {
772         struct bnx2x *bp = params->bp;
773         const u8 port = params->port;
774         const u8 nig_cli_sp_bitmap = 0x7 | (cos_sp_bitmap << 3);
775         const u8 pbf_cli_sp_bitmap = cos_sp_bitmap;
776         const u8 nig_cli_subject2wfq_bitmap = cos_bw_bitmap << 3;
777         const u8 pbf_cli_subject2wfq_bitmap = cos_bw_bitmap;
778
779         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT :
780                NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, nig_cli_sp_bitmap);
781
782         REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
783                PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , pbf_cli_sp_bitmap);
784
785         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
786                NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ,
787                nig_cli_subject2wfq_bitmap);
788
789         REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
790                PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0,
791                pbf_cli_subject2wfq_bitmap);
792
793         return 0;
794 }
795
796 /******************************************************************************
797 * Description:
798 *       This function is needed because NIG ARB_CREDIT_WEIGHT_X are
799 *       not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
800 ******************************************************************************/
801 static int bnx2x_ets_e3b0_set_cos_bw(struct bnx2x *bp,
802                                      const u8 cos_entry,
803                                      const u32 min_w_val_nig,
804                                      const u32 min_w_val_pbf,
805                                      const u16 total_bw,
806                                      const u8 bw,
807                                      const u8 port)
808 {
809         u32 nig_reg_adress_crd_weight = 0;
810         u32 pbf_reg_adress_crd_weight = 0;
811         /* Calculate and set BW for this COS - use 1 instead of 0 for BW */
812         const u32 cos_bw_nig = ((bw ? bw : 1) * min_w_val_nig) / total_bw;
813         const u32 cos_bw_pbf = ((bw ? bw : 1) * min_w_val_pbf) / total_bw;
814
815         switch (cos_entry) {
816         case 0:
817             nig_reg_adress_crd_weight =
818                  (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
819                      NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0;
820              pbf_reg_adress_crd_weight = (port) ?
821                  PBF_REG_COS0_WEIGHT_P1 : PBF_REG_COS0_WEIGHT_P0;
822              break;
823         case 1:
824              nig_reg_adress_crd_weight = (port) ?
825                  NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
826                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1;
827              pbf_reg_adress_crd_weight = (port) ?
828                  PBF_REG_COS1_WEIGHT_P1 : PBF_REG_COS1_WEIGHT_P0;
829              break;
830         case 2:
831              nig_reg_adress_crd_weight = (port) ?
832                  NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
833                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2;
834
835                  pbf_reg_adress_crd_weight = (port) ?
836                      PBF_REG_COS2_WEIGHT_P1 : PBF_REG_COS2_WEIGHT_P0;
837              break;
838         case 3:
839             if (port)
840                         return -EINVAL;
841              nig_reg_adress_crd_weight =
842                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3;
843              pbf_reg_adress_crd_weight =
844                  PBF_REG_COS3_WEIGHT_P0;
845              break;
846         case 4:
847             if (port)
848                 return -EINVAL;
849              nig_reg_adress_crd_weight =
850                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4;
851              pbf_reg_adress_crd_weight = PBF_REG_COS4_WEIGHT_P0;
852              break;
853         case 5:
854             if (port)
855                 return -EINVAL;
856              nig_reg_adress_crd_weight =
857                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5;
858              pbf_reg_adress_crd_weight = PBF_REG_COS5_WEIGHT_P0;
859              break;
860         }
861
862         REG_WR(bp, nig_reg_adress_crd_weight, cos_bw_nig);
863
864         REG_WR(bp, pbf_reg_adress_crd_weight, cos_bw_pbf);
865
866         return 0;
867 }
868 /******************************************************************************
869 * Description:
870 *       Calculate the total BW.A value of 0 isn't legal.
871 *.
872 ******************************************************************************/
873 static int bnx2x_ets_e3b0_get_total_bw(
874         const struct link_params *params,
875         struct bnx2x_ets_params *ets_params,
876         u16 *total_bw)
877 {
878         struct bnx2x *bp = params->bp;
879         u8 cos_idx = 0;
880         u8 is_bw_cos_exist = 0;
881
882         *total_bw = 0 ;
883
884         /* Calculate total BW requested */
885         for (cos_idx = 0; cos_idx < ets_params->num_of_cos; cos_idx++) {
886                 if (ets_params->cos[cos_idx].state == bnx2x_cos_state_bw) {
887                         is_bw_cos_exist = 1;
888                         if (!ets_params->cos[cos_idx].params.bw_params.bw) {
889                                 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config BW"
890                                                    "was set to 0\n");
891                                 /*
892                                  * This is to prevent a state when ramrods
893                                  * can't be sent
894                                 */
895                                 ets_params->cos[cos_idx].params.bw_params.bw
896                                          = 1;
897                         }
898                         *total_bw +=
899                                 ets_params->cos[cos_idx].params.bw_params.bw;
900                 }
901         }
902
903         /* Check total BW is valid */
904         if ((is_bw_cos_exist == 1) && (*total_bw != 100)) {
905                 if (*total_bw == 0) {
906                         DP(NETIF_MSG_LINK,
907                            "bnx2x_ets_E3B0_config total BW shouldn't be 0\n");
908                         return -EINVAL;
909                 }
910                 DP(NETIF_MSG_LINK,
911                    "bnx2x_ets_E3B0_config total BW should be 100\n");
912                 /*
913                  * We can handle a case whre the BW isn't 100 this can happen
914                  * if the TC are joined.
915                  */
916         }
917         return 0;
918 }
919
920 /******************************************************************************
921 * Description:
922 *       Invalidate all the sp_pri_to_cos.
923 *.
924 ******************************************************************************/
925 static void bnx2x_ets_e3b0_sp_pri_to_cos_init(u8 *sp_pri_to_cos)
926 {
927         u8 pri = 0;
928         for (pri = 0; pri < DCBX_MAX_NUM_COS; pri++)
929                 sp_pri_to_cos[pri] = DCBX_INVALID_COS;
930 }
931 /******************************************************************************
932 * Description:
933 *       Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
934 *       according to sp_pri_to_cos.
935 *.
936 ******************************************************************************/
937 static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,
938                                             u8 *sp_pri_to_cos, const u8 pri,
939                                             const u8 cos_entry)
940 {
941         struct bnx2x *bp = params->bp;
942         const u8 port = params->port;
943         const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
944                 DCBX_E3B0_MAX_NUM_COS_PORT0;
945
946         if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) {
947                 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
948                                    "parameter There can't be two COS's with "
949                                    "the same strict pri\n");
950                 return -EINVAL;
951         }
952
953         if (pri > max_num_of_cos) {
954                 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
955                    "parameter Illegal strict priority\n");
956             return -EINVAL;
957         }
958
959         sp_pri_to_cos[pri] = cos_entry;
960         return 0;
961
962 }
963
964 /******************************************************************************
965 * Description:
966 *       Returns the correct value according to COS and priority in
967 *       the sp_pri_cli register.
968 *.
969 ******************************************************************************/
970 static u64 bnx2x_e3b0_sp_get_pri_cli_reg(const u8 cos, const u8 cos_offset,
971                                          const u8 pri_set,
972                                          const u8 pri_offset,
973                                          const u8 entry_size)
974 {
975         u64 pri_cli_nig = 0;
976         pri_cli_nig = ((u64)(cos + cos_offset)) << (entry_size *
977                                                     (pri_set + pri_offset));
978
979         return pri_cli_nig;
980 }
981 /******************************************************************************
982 * Description:
983 *       Returns the correct value according to COS and priority in the
984 *       sp_pri_cli register for NIG.
985 *.
986 ******************************************************************************/
987 static u64 bnx2x_e3b0_sp_get_pri_cli_reg_nig(const u8 cos, const u8 pri_set)
988 {
989         /* MCP Dbg0 and dbg1 are always with higher strict pri*/
990         const u8 nig_cos_offset = 3;
991         const u8 nig_pri_offset = 3;
992
993         return bnx2x_e3b0_sp_get_pri_cli_reg(cos, nig_cos_offset, pri_set,
994                 nig_pri_offset, 4);
995
996 }
997 /******************************************************************************
998 * Description:
999 *       Returns the correct value according to COS and priority in the
1000 *       sp_pri_cli register for PBF.
1001 *.
1002 ******************************************************************************/
1003 static u64 bnx2x_e3b0_sp_get_pri_cli_reg_pbf(const u8 cos, const u8 pri_set)
1004 {
1005         const u8 pbf_cos_offset = 0;
1006         const u8 pbf_pri_offset = 0;
1007
1008         return bnx2x_e3b0_sp_get_pri_cli_reg(cos, pbf_cos_offset, pri_set,
1009                 pbf_pri_offset, 3);
1010
1011 }
1012
1013 /******************************************************************************
1014 * Description:
1015 *       Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
1016 *       according to sp_pri_to_cos.(which COS has higher priority)
1017 *.
1018 ******************************************************************************/
1019 static int bnx2x_ets_e3b0_sp_set_pri_cli_reg(const struct link_params *params,
1020                                              u8 *sp_pri_to_cos)
1021 {
1022         struct bnx2x *bp = params->bp;
1023         u8 i = 0;
1024         const u8 port = params->port;
1025         /* MCP Dbg0 and dbg1 are always with higher strict pri*/
1026         u64 pri_cli_nig = 0x210;
1027         u32 pri_cli_pbf = 0x0;
1028         u8 pri_set = 0;
1029         u8 pri_bitmask = 0;
1030         const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
1031                 DCBX_E3B0_MAX_NUM_COS_PORT0;
1032
1033         u8 cos_bit_to_set = (1 << max_num_of_cos) - 1;
1034
1035         /* Set all the strict priority first */
1036         for (i = 0; i < max_num_of_cos; i++) {
1037                 if (sp_pri_to_cos[i] != DCBX_INVALID_COS) {
1038                         if (sp_pri_to_cos[i] >= DCBX_MAX_NUM_COS) {
1039                                 DP(NETIF_MSG_LINK,
1040                                            "bnx2x_ets_e3b0_sp_set_pri_cli_reg "
1041                                            "invalid cos entry\n");
1042                                 return -EINVAL;
1043                         }
1044
1045                         pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
1046                             sp_pri_to_cos[i], pri_set);
1047
1048                         pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
1049                             sp_pri_to_cos[i], pri_set);
1050                         pri_bitmask = 1 << sp_pri_to_cos[i];
1051                         /* COS is used remove it from bitmap.*/
1052                         if (!(pri_bitmask & cos_bit_to_set)) {
1053                                 DP(NETIF_MSG_LINK,
1054                                         "bnx2x_ets_e3b0_sp_set_pri_cli_reg "
1055                                         "invalid There can't be two COS's with"
1056                                         " the same strict pri\n");
1057                                 return -EINVAL;
1058                         }
1059                         cos_bit_to_set &= ~pri_bitmask;
1060                         pri_set++;
1061                 }
1062         }
1063
1064         /* Set all the Non strict priority i= COS*/
1065         for (i = 0; i < max_num_of_cos; i++) {
1066                 pri_bitmask = 1 << i;
1067                 /* Check if COS was already used for SP */
1068                 if (pri_bitmask & cos_bit_to_set) {
1069                         /* COS wasn't used for SP */
1070                         pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
1071                             i, pri_set);
1072
1073                         pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
1074                             i, pri_set);
1075                         /* COS is used remove it from bitmap.*/
1076                         cos_bit_to_set &= ~pri_bitmask;
1077                         pri_set++;
1078                 }
1079         }
1080
1081         if (pri_set != max_num_of_cos) {
1082                 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_set_pri_cli_reg not all "
1083                                    "entries were set\n");
1084                 return -EINVAL;
1085         }
1086
1087         if (port) {
1088                 /* Only 6 usable clients*/
1089                 REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB,
1090                        (u32)pri_cli_nig);
1091
1092                 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , pri_cli_pbf);
1093         } else {
1094                 /* Only 9 usable clients*/
1095                 const u32 pri_cli_nig_lsb = (u32) (pri_cli_nig);
1096                 const u32 pri_cli_nig_msb = (u32) ((pri_cli_nig >> 32) & 0xF);
1097
1098                 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB,
1099                        pri_cli_nig_lsb);
1100                 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB,
1101                        pri_cli_nig_msb);
1102
1103                 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , pri_cli_pbf);
1104         }
1105         return 0;
1106 }
1107
1108 /******************************************************************************
1109 * Description:
1110 *       Configure the COS to ETS according to BW and SP settings.
1111 ******************************************************************************/
1112 int bnx2x_ets_e3b0_config(const struct link_params *params,
1113                          const struct link_vars *vars,
1114                          struct bnx2x_ets_params *ets_params)
1115 {
1116         struct bnx2x *bp = params->bp;
1117         int bnx2x_status = 0;
1118         const u8 port = params->port;
1119         u16 total_bw = 0;
1120         const u32 min_w_val_nig = bnx2x_ets_get_min_w_val_nig(vars);
1121         const u32 min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL;
1122         u8 cos_bw_bitmap = 0;
1123         u8 cos_sp_bitmap = 0;
1124         u8 sp_pri_to_cos[DCBX_MAX_NUM_COS] = {0};
1125         const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
1126                 DCBX_E3B0_MAX_NUM_COS_PORT0;
1127         u8 cos_entry = 0;
1128
1129         if (!CHIP_IS_E3B0(bp)) {
1130                 DP(NETIF_MSG_LINK,
1131                    "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
1132                 return -EINVAL;
1133         }
1134
1135         if ((ets_params->num_of_cos > max_num_of_cos)) {
1136                 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config the number of COS "
1137                                    "isn't supported\n");
1138                 return -EINVAL;
1139         }
1140
1141         /* Prepare sp strict priority parameters*/
1142         bnx2x_ets_e3b0_sp_pri_to_cos_init(sp_pri_to_cos);
1143
1144         /* Prepare BW parameters*/
1145         bnx2x_status = bnx2x_ets_e3b0_get_total_bw(params, ets_params,
1146                                                    &total_bw);
1147         if (bnx2x_status) {
1148                 DP(NETIF_MSG_LINK,
1149                    "bnx2x_ets_E3B0_config get_total_bw failed\n");
1150                 return -EINVAL;
1151         }
1152
1153         /*
1154          * Upper bound is set according to current link speed (min_w_val
1155          * should be the same for upper bound and COS credit val).
1156          */
1157         bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val_nig);
1158         bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
1159
1160
1161         for (cos_entry = 0; cos_entry < ets_params->num_of_cos; cos_entry++) {
1162                 if (bnx2x_cos_state_bw == ets_params->cos[cos_entry].state) {
1163                         cos_bw_bitmap |= (1 << cos_entry);
1164                         /*
1165                          * The function also sets the BW in HW(not the mappin
1166                          * yet)
1167                          */
1168                         bnx2x_status = bnx2x_ets_e3b0_set_cos_bw(
1169                                 bp, cos_entry, min_w_val_nig, min_w_val_pbf,
1170                                 total_bw,
1171                                 ets_params->cos[cos_entry].params.bw_params.bw,
1172                                  port);
1173                 } else if (bnx2x_cos_state_strict ==
1174                         ets_params->cos[cos_entry].state){
1175                         cos_sp_bitmap |= (1 << cos_entry);
1176
1177                         bnx2x_status = bnx2x_ets_e3b0_sp_pri_to_cos_set(
1178                                 params,
1179                                 sp_pri_to_cos,
1180                                 ets_params->cos[cos_entry].params.sp_params.pri,
1181                                 cos_entry);
1182
1183                 } else {
1184                         DP(NETIF_MSG_LINK,
1185                            "bnx2x_ets_e3b0_config cos state not valid\n");
1186                         return -EINVAL;
1187                 }
1188                 if (bnx2x_status) {
1189                         DP(NETIF_MSG_LINK,
1190                            "bnx2x_ets_e3b0_config set cos bw failed\n");
1191                         return bnx2x_status;
1192                 }
1193         }
1194
1195         /* Set SP register (which COS has higher priority) */
1196         bnx2x_status = bnx2x_ets_e3b0_sp_set_pri_cli_reg(params,
1197                                                          sp_pri_to_cos);
1198
1199         if (bnx2x_status) {
1200                 DP(NETIF_MSG_LINK,
1201                    "bnx2x_ets_E3B0_config set_pri_cli_reg failed\n");
1202                 return bnx2x_status;
1203         }
1204
1205         /* Set client mapping of BW and strict */
1206         bnx2x_status = bnx2x_ets_e3b0_cli_map(params, ets_params,
1207                                               cos_sp_bitmap,
1208                                               cos_bw_bitmap);
1209
1210         if (bnx2x_status) {
1211                 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config SP failed\n");
1212                 return bnx2x_status;
1213         }
1214         return 0;
1215 }
1216 static void bnx2x_ets_bw_limit_common(const struct link_params *params)
1217 {
1218         /* ETS disabled configuration */
1219         struct bnx2x *bp = params->bp;
1220         DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
1221         /*
1222          * defines which entries (clients) are subjected to WFQ arbitration
1223          * COS0 0x8
1224          * COS1 0x10
1225          */
1226         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
1227         /*
1228          * mapping between the ARB_CREDIT_WEIGHT registers and actual
1229          * client numbers (WEIGHT_0 does not actually have to represent
1230          * client 0)
1231          *    PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1232          *  cos1-001     cos0-000     dbg1-100     dbg0-011     MCP-010
1233          */
1234         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
1235
1236         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
1237                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1238         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
1239                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1240
1241         /* ETS mode enabled*/
1242         REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
1243
1244         /* Defines the number of consecutive slots for the strict priority */
1245         REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
1246         /*
1247          * Bitmap of 5bits length. Each bit specifies whether the entry behaves
1248          * as strict.  Bits 0,1,2 - debug and management entries, 3 - COS0
1249          * entry, 4 - COS1 entry.
1250          * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1251          * bit4   bit3    bit2     bit1    bit0
1252          * MCP and debug are strict
1253          */
1254         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
1255
1256         /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
1257         REG_WR(bp, PBF_REG_COS0_UPPER_BOUND,
1258                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1259         REG_WR(bp, PBF_REG_COS1_UPPER_BOUND,
1260                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1261 }
1262
1263 void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
1264                         const u32 cos1_bw)
1265 {
1266         /* ETS disabled configuration*/
1267         struct bnx2x *bp = params->bp;
1268         const u32 total_bw = cos0_bw + cos1_bw;
1269         u32 cos0_credit_weight = 0;
1270         u32 cos1_credit_weight = 0;
1271
1272         DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
1273
1274         if ((!total_bw) ||
1275             (!cos0_bw) ||
1276             (!cos1_bw)) {
1277                 DP(NETIF_MSG_LINK, "Total BW can't be zero\n");
1278                 return;
1279         }
1280
1281         cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
1282                 total_bw;
1283         cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
1284                 total_bw;
1285
1286         bnx2x_ets_bw_limit_common(params);
1287
1288         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
1289         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
1290
1291         REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
1292         REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
1293 }
1294
1295 int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
1296 {
1297         /* ETS disabled configuration*/
1298         struct bnx2x *bp = params->bp;
1299         u32 val = 0;
1300
1301         DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
1302         /*
1303          * Bitmap of 5bits length. Each bit specifies whether the entry behaves
1304          * as strict.  Bits 0,1,2 - debug and management entries,
1305          * 3 - COS0 entry, 4 - COS1 entry.
1306          *  COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1307          *  bit4   bit3   bit2      bit1     bit0
1308          * MCP and debug are strict
1309          */
1310         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
1311         /*
1312          * For strict priority entries defines the number of consecutive slots
1313          * for the highest priority.
1314          */
1315         REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
1316         /* ETS mode disable */
1317         REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
1318         /* Defines the number of consecutive slots for the strict priority */
1319         REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
1320
1321         /* Defines the number of consecutive slots for the strict priority */
1322         REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
1323
1324         /*
1325          * mapping between entry  priority to client number (0,1,2 -debug and
1326          * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
1327          * 3bits client num.
1328          *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1329          * dbg0-010     dbg1-001     cos1-100     cos0-011     MCP-000
1330          * dbg0-010     dbg1-001     cos0-011     cos1-100     MCP-000
1331          */
1332         val = (!strict_cos) ? 0x2318 : 0x22E0;
1333         REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
1334
1335         return 0;
1336 }
1337 /******************************************************************/
1338 /*                      PFC section                               */
1339 /******************************************************************/
1340 static void bnx2x_update_pfc_xmac(struct link_params *params,
1341                                   struct link_vars *vars,
1342                                   u8 is_lb)
1343 {
1344         struct bnx2x *bp = params->bp;
1345         u32 xmac_base;
1346         u32 pause_val, pfc0_val, pfc1_val;
1347
1348         /* XMAC base adrr */
1349         xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1350
1351         /* Initialize pause and pfc registers */
1352         pause_val = 0x18000;
1353         pfc0_val = 0xFFFF8000;
1354         pfc1_val = 0x2;
1355
1356         /* No PFC support */
1357         if (!(params->feature_config_flags &
1358               FEATURE_CONFIG_PFC_ENABLED)) {
1359
1360                 /*
1361                  * RX flow control - Process pause frame in receive direction
1362                  */
1363                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1364                         pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN;
1365
1366                 /*
1367                  * TX flow control - Send pause packet when buffer is full
1368                  */
1369                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1370                         pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN;
1371         } else {/* PFC support */
1372                 pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN |
1373                         XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN |
1374                         XMAC_PFC_CTRL_HI_REG_RX_PFC_EN |
1375                         XMAC_PFC_CTRL_HI_REG_TX_PFC_EN;
1376         }
1377
1378         /* Write pause and PFC registers */
1379         REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
1380         REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
1381         REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
1382
1383
1384         /* Set MAC address for source TX Pause/PFC frames */
1385         REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_LO,
1386                ((params->mac_addr[2] << 24) |
1387                 (params->mac_addr[3] << 16) |
1388                 (params->mac_addr[4] << 8) |
1389                 (params->mac_addr[5])));
1390         REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_HI,
1391                ((params->mac_addr[0] << 8) |
1392                 (params->mac_addr[1])));
1393
1394         udelay(30);
1395 }
1396
1397
1398 static void bnx2x_emac_get_pfc_stat(struct link_params *params,
1399                                     u32 pfc_frames_sent[2],
1400                                     u32 pfc_frames_received[2])
1401 {
1402         /* Read pfc statistic */
1403         struct bnx2x *bp = params->bp;
1404         u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1405         u32 val_xon = 0;
1406         u32 val_xoff = 0;
1407
1408         DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n");
1409
1410         /* PFC received frames */
1411         val_xoff = REG_RD(bp, emac_base +
1412                                 EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
1413         val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
1414         val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
1415         val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
1416
1417         pfc_frames_received[0] = val_xon + val_xoff;
1418
1419         /* PFC received sent */
1420         val_xoff = REG_RD(bp, emac_base +
1421                                 EMAC_REG_RX_PFC_STATS_XOFF_SENT);
1422         val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
1423         val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
1424         val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
1425
1426         pfc_frames_sent[0] = val_xon + val_xoff;
1427 }
1428
1429 /* Read pfc statistic*/
1430 void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
1431                          u32 pfc_frames_sent[2],
1432                          u32 pfc_frames_received[2])
1433 {
1434         /* Read pfc statistic */
1435         struct bnx2x *bp = params->bp;
1436
1437         DP(NETIF_MSG_LINK, "pfc statistic\n");
1438
1439         if (!vars->link_up)
1440                 return;
1441
1442         if (vars->mac_type == MAC_TYPE_EMAC) {
1443                 DP(NETIF_MSG_LINK, "About to read PFC stats from EMAC\n");
1444                 bnx2x_emac_get_pfc_stat(params, pfc_frames_sent,
1445                                         pfc_frames_received);
1446         }
1447 }
1448 /******************************************************************/
1449 /*                      MAC/PBF section                           */
1450 /******************************************************************/
1451 static void bnx2x_set_mdio_clk(struct bnx2x *bp, u32 chip_id, u8 port)
1452 {
1453         u32 mode, emac_base;
1454         /**
1455          * Set clause 45 mode, slow down the MDIO clock to 2.5MHz
1456          * (a value of 49==0x31) and make sure that the AUTO poll is off
1457          */
1458
1459         if (CHIP_IS_E2(bp))
1460                 emac_base = GRCBASE_EMAC0;
1461         else
1462                 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1463         mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
1464         mode &= ~(EMAC_MDIO_MODE_AUTO_POLL |
1465                   EMAC_MDIO_MODE_CLOCK_CNT);
1466         if (USES_WARPCORE(bp))
1467                 mode |= (74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
1468         else
1469                 mode |= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
1470
1471         mode |= (EMAC_MDIO_MODE_CLAUSE_45);
1472         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, mode);
1473
1474         udelay(40);
1475 }
1476 static u8 bnx2x_is_4_port_mode(struct bnx2x *bp)
1477 {
1478         u32 port4mode_ovwr_val;
1479         /* Check 4-port override enabled */
1480         port4mode_ovwr_val = REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR);
1481         if (port4mode_ovwr_val & (1<<0)) {
1482                 /* Return 4-port mode override value */
1483                 return ((port4mode_ovwr_val & (1<<1)) == (1<<1));
1484         }
1485         /* Return 4-port mode from input pin */
1486         return (u8)REG_RD(bp, MISC_REG_PORT4MODE_EN);
1487 }
1488
1489 static void bnx2x_emac_init(struct link_params *params,
1490                             struct link_vars *vars)
1491 {
1492         /* reset and unreset the emac core */
1493         struct bnx2x *bp = params->bp;
1494         u8 port = params->port;
1495         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1496         u32 val;
1497         u16 timeout;
1498
1499         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1500                (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1501         udelay(5);
1502         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1503                (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1504
1505         /* init emac - use read-modify-write */
1506         /* self clear reset */
1507         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1508         EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
1509
1510         timeout = 200;
1511         do {
1512                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1513                 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
1514                 if (!timeout) {
1515                         DP(NETIF_MSG_LINK, "EMAC timeout!\n");
1516                         return;
1517                 }
1518                 timeout--;
1519         } while (val & EMAC_MODE_RESET);
1520         bnx2x_set_mdio_clk(bp, params->chip_id, port);
1521         /* Set mac address */
1522         val = ((params->mac_addr[0] << 8) |
1523                 params->mac_addr[1]);
1524         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
1525
1526         val = ((params->mac_addr[2] << 24) |
1527                (params->mac_addr[3] << 16) |
1528                (params->mac_addr[4] << 8) |
1529                 params->mac_addr[5]);
1530         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
1531 }
1532
1533 static void bnx2x_set_xumac_nig(struct link_params *params,
1534                                 u16 tx_pause_en,
1535                                 u8 enable)
1536 {
1537         struct bnx2x *bp = params->bp;
1538
1539         REG_WR(bp, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN,
1540                enable);
1541         REG_WR(bp, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN,
1542                enable);
1543         REG_WR(bp, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN :
1544                NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
1545 }
1546
1547 static void bnx2x_umac_disable(struct link_params *params)
1548 {
1549         u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
1550         struct bnx2x *bp = params->bp;
1551         if (!(REG_RD(bp, MISC_REG_RESET_REG_2) &
1552                    (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)))
1553                 return;
1554
1555         /* Disable RX and TX */
1556         REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, 0);
1557 }
1558
1559 static void bnx2x_umac_enable(struct link_params *params,
1560                             struct link_vars *vars, u8 lb)
1561 {
1562         u32 val;
1563         u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
1564         struct bnx2x *bp = params->bp;
1565         /* Reset UMAC */
1566         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1567                (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
1568         usleep_range(1000, 1000);
1569
1570         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1571                (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
1572
1573         DP(NETIF_MSG_LINK, "enabling UMAC\n");
1574
1575         /**
1576          * This register determines on which events the MAC will assert
1577          * error on the i/f to the NIG along w/ EOP.
1578          */
1579
1580         /**
1581          * BD REG_WR(bp, NIG_REG_P0_MAC_RSV_ERR_MASK +
1582          * params->port*0x14,      0xfffff.
1583          */
1584         /* This register opens the gate for the UMAC despite its name */
1585         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
1586
1587         val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN |
1588                 UMAC_COMMAND_CONFIG_REG_PAD_EN |
1589                 UMAC_COMMAND_CONFIG_REG_SW_RESET |
1590                 UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK;
1591         switch (vars->line_speed) {
1592         case SPEED_10:
1593                 val |= (0<<2);
1594                 break;
1595         case SPEED_100:
1596                 val |= (1<<2);
1597                 break;
1598         case SPEED_1000:
1599                 val |= (2<<2);
1600                 break;
1601         case SPEED_2500:
1602                 val |= (3<<2);
1603                 break;
1604         default:
1605                 DP(NETIF_MSG_LINK, "Invalid speed for UMAC %d\n",
1606                                vars->line_speed);
1607                 break;
1608         }
1609         if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1610                 val |= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE;
1611
1612         if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1613                 val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE;
1614
1615         if (vars->duplex == DUPLEX_HALF)
1616                 val |= UMAC_COMMAND_CONFIG_REG_HD_ENA;
1617
1618         REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1619         udelay(50);
1620
1621         /* Set MAC address for source TX Pause/PFC frames (under SW reset) */
1622         REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR0,
1623                ((params->mac_addr[2] << 24) |
1624                 (params->mac_addr[3] << 16) |
1625                 (params->mac_addr[4] << 8) |
1626                 (params->mac_addr[5])));
1627         REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR1,
1628                ((params->mac_addr[0] << 8) |
1629                 (params->mac_addr[1])));
1630
1631         /* Enable RX and TX */
1632         val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN;
1633         val |= UMAC_COMMAND_CONFIG_REG_TX_ENA |
1634                 UMAC_COMMAND_CONFIG_REG_RX_ENA;
1635         REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1636         udelay(50);
1637
1638         /* Remove SW Reset */
1639         val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET;
1640
1641         /* Check loopback mode */
1642         if (lb)
1643                 val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA;
1644         REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1645
1646         /*
1647          * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
1648          * length used by the MAC receive logic to check frames.
1649          */
1650         REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
1651         bnx2x_set_xumac_nig(params,
1652                             ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
1653         vars->mac_type = MAC_TYPE_UMAC;
1654
1655 }
1656
1657 /* Define the XMAC mode */
1658 static void bnx2x_xmac_init(struct link_params *params, u32 max_speed)
1659 {
1660         struct bnx2x *bp = params->bp;
1661         u32 is_port4mode = bnx2x_is_4_port_mode(bp);
1662
1663         /*
1664          * In 4-port mode, need to set the mode only once, so if XMAC is
1665          * already out of reset, it means the mode has already been set,
1666          * and it must not* reset the XMAC again, since it controls both
1667          * ports of the path
1668          */
1669
1670         if ((CHIP_NUM(bp) == CHIP_NUM_57840) &&
1671             (REG_RD(bp, MISC_REG_RESET_REG_2) &
1672              MISC_REGISTERS_RESET_REG_2_XMAC)) {
1673                 DP(NETIF_MSG_LINK,
1674                    "XMAC already out of reset in 4-port mode\n");
1675                 return;
1676         }
1677
1678         /* Hard reset */
1679         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1680                MISC_REGISTERS_RESET_REG_2_XMAC);
1681         usleep_range(1000, 1000);
1682
1683         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1684                MISC_REGISTERS_RESET_REG_2_XMAC);
1685         if (is_port4mode) {
1686                 DP(NETIF_MSG_LINK, "Init XMAC to 2 ports x 10G per path\n");
1687
1688                 /*  Set the number of ports on the system side to up to 2 */
1689                 REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 1);
1690
1691                 /* Set the number of ports on the Warp Core to 10G */
1692                 REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
1693         } else {
1694                 /*  Set the number of ports on the system side to 1 */
1695                 REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 0);
1696                 if (max_speed == SPEED_10000) {
1697                         DP(NETIF_MSG_LINK,
1698                            "Init XMAC to 10G x 1 port per path\n");
1699                         /* Set the number of ports on the Warp Core to 10G */
1700                         REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
1701                 } else {
1702                         DP(NETIF_MSG_LINK,
1703                            "Init XMAC to 20G x 2 ports per path\n");
1704                         /* Set the number of ports on the Warp Core to 20G */
1705                         REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 1);
1706                 }
1707         }
1708         /* Soft reset */
1709         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1710                MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
1711         usleep_range(1000, 1000);
1712
1713         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1714                MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
1715
1716 }
1717
1718 static void bnx2x_xmac_disable(struct link_params *params)
1719 {
1720         u8 port = params->port;
1721         struct bnx2x *bp = params->bp;
1722         u32 pfc_ctrl, xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1723
1724         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
1725             MISC_REGISTERS_RESET_REG_2_XMAC) {
1726                 /*
1727                  * Send an indication to change the state in the NIG back to XON
1728                  * Clearing this bit enables the next set of this bit to get
1729                  * rising edge
1730                  */
1731                 pfc_ctrl = REG_RD(bp, xmac_base + XMAC_REG_PFC_CTRL_HI);
1732                 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI,
1733                        (pfc_ctrl & ~(1<<1)));
1734                 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI,
1735                        (pfc_ctrl | (1<<1)));
1736                 DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port);
1737                 REG_WR(bp, xmac_base + XMAC_REG_CTRL, 0);
1738         }
1739 }
1740
1741 static int bnx2x_xmac_enable(struct link_params *params,
1742                              struct link_vars *vars, u8 lb)
1743 {
1744         u32 val, xmac_base;
1745         struct bnx2x *bp = params->bp;
1746         DP(NETIF_MSG_LINK, "enabling XMAC\n");
1747
1748         xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1749
1750         bnx2x_xmac_init(params, vars->line_speed);
1751
1752         /*
1753          * This register determines on which events the MAC will assert
1754          * error on the i/f to the NIG along w/ EOP.
1755          */
1756
1757         /*
1758          * This register tells the NIG whether to send traffic to UMAC
1759          * or XMAC
1760          */
1761         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0);
1762
1763         /* Set Max packet size */
1764         REG_WR(bp, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710);
1765
1766         /* CRC append for Tx packets */
1767         REG_WR(bp, xmac_base + XMAC_REG_TX_CTRL, 0xC800);
1768
1769         /* update PFC */
1770         bnx2x_update_pfc_xmac(params, vars, 0);
1771
1772         /* Enable TX and RX */
1773         val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
1774
1775         /* Check loopback mode */
1776         if (lb)
1777                 val |= XMAC_CTRL_REG_LINE_LOCAL_LPBK;
1778         REG_WR(bp, xmac_base + XMAC_REG_CTRL, val);
1779         bnx2x_set_xumac_nig(params,
1780                             ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
1781
1782         vars->mac_type = MAC_TYPE_XMAC;
1783
1784         return 0;
1785 }
1786
1787 static int bnx2x_emac_enable(struct link_params *params,
1788                              struct link_vars *vars, u8 lb)
1789 {
1790         struct bnx2x *bp = params->bp;
1791         u8 port = params->port;
1792         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1793         u32 val;
1794
1795         DP(NETIF_MSG_LINK, "enabling EMAC\n");
1796
1797         /* Disable BMAC */
1798         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1799                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1800
1801         /* enable emac and not bmac */
1802         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
1803
1804         /* ASIC */
1805         if (vars->phy_flags & PHY_XGXS_FLAG) {
1806                 u32 ser_lane = ((params->lane_config &
1807                                  PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1808                                 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1809
1810                 DP(NETIF_MSG_LINK, "XGXS\n");
1811                 /* select the master lanes (out of 0-3) */
1812                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane);
1813                 /* select XGXS */
1814                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
1815
1816         } else { /* SerDes */
1817                 DP(NETIF_MSG_LINK, "SerDes\n");
1818                 /* select SerDes */
1819                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
1820         }
1821
1822         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
1823                       EMAC_RX_MODE_RESET);
1824         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1825                       EMAC_TX_MODE_RESET);
1826
1827         if (CHIP_REV_IS_SLOW(bp)) {
1828                 /* config GMII mode */
1829                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1830                 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII));
1831         } else { /* ASIC */
1832                 /* pause enable/disable */
1833                 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
1834                                EMAC_RX_MODE_FLOW_EN);
1835
1836                 bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
1837                                (EMAC_TX_MODE_EXT_PAUSE_EN |
1838                                 EMAC_TX_MODE_FLOW_EN));
1839                 if (!(params->feature_config_flags &
1840                       FEATURE_CONFIG_PFC_ENABLED)) {
1841                         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1842                                 bnx2x_bits_en(bp, emac_base +
1843                                               EMAC_REG_EMAC_RX_MODE,
1844                                               EMAC_RX_MODE_FLOW_EN);
1845
1846                         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1847                                 bnx2x_bits_en(bp, emac_base +
1848                                               EMAC_REG_EMAC_TX_MODE,
1849                                               (EMAC_TX_MODE_EXT_PAUSE_EN |
1850                                                EMAC_TX_MODE_FLOW_EN));
1851                 } else
1852                         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1853                                       EMAC_TX_MODE_FLOW_EN);
1854         }
1855
1856         /* KEEP_VLAN_TAG, promiscuous */
1857         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
1858         val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
1859
1860         /*
1861          * Setting this bit causes MAC control frames (except for pause
1862          * frames) to be passed on for processing. This setting has no
1863          * affect on the operation of the pause frames. This bit effects
1864          * all packets regardless of RX Parser packet sorting logic.
1865          * Turn the PFC off to make sure we are in Xon state before
1866          * enabling it.
1867          */
1868         EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
1869         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
1870                 DP(NETIF_MSG_LINK, "PFC is enabled\n");
1871                 /* Enable PFC again */
1872                 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
1873                         EMAC_REG_RX_PFC_MODE_RX_EN |
1874                         EMAC_REG_RX_PFC_MODE_TX_EN |
1875                         EMAC_REG_RX_PFC_MODE_PRIORITIES);
1876
1877                 EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
1878                         ((0x0101 <<
1879                           EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
1880                          (0x00ff <<
1881                           EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
1882                 val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
1883         }
1884         EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
1885
1886         /* Set Loopback */
1887         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1888         if (lb)
1889                 val |= 0x810;
1890         else
1891                 val &= ~0x810;
1892         EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
1893
1894         /* enable emac */
1895         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
1896
1897         /* enable emac for jumbo packets */
1898         EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
1899                 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
1900                  (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
1901
1902         /* strip CRC */
1903         REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
1904
1905         /* disable the NIG in/out to the bmac */
1906         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
1907         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
1908         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
1909
1910         /* enable the NIG in/out to the emac */
1911         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
1912         val = 0;
1913         if ((params->feature_config_flags &
1914               FEATURE_CONFIG_PFC_ENABLED) ||
1915             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1916                 val = 1;
1917
1918         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
1919         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
1920
1921         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
1922
1923         vars->mac_type = MAC_TYPE_EMAC;
1924         return 0;
1925 }
1926
1927 static void bnx2x_update_pfc_bmac1(struct link_params *params,
1928                                    struct link_vars *vars)
1929 {
1930         u32 wb_data[2];
1931         struct bnx2x *bp = params->bp;
1932         u32 bmac_addr =  params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1933                 NIG_REG_INGRESS_BMAC0_MEM;
1934
1935         u32 val = 0x14;
1936         if ((!(params->feature_config_flags &
1937               FEATURE_CONFIG_PFC_ENABLED)) &&
1938                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1939                 /* Enable BigMAC to react on received Pause packets */
1940                 val |= (1<<5);
1941         wb_data[0] = val;
1942         wb_data[1] = 0;
1943         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
1944
1945         /* tx control */
1946         val = 0xc0;
1947         if (!(params->feature_config_flags &
1948               FEATURE_CONFIG_PFC_ENABLED) &&
1949                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1950                 val |= 0x800000;
1951         wb_data[0] = val;
1952         wb_data[1] = 0;
1953         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
1954 }
1955
1956 static void bnx2x_update_pfc_bmac2(struct link_params *params,
1957                                    struct link_vars *vars,
1958                                    u8 is_lb)
1959 {
1960         /*
1961          * Set rx control: Strip CRC and enable BigMAC to relay
1962          * control packets to the system as well
1963          */
1964         u32 wb_data[2];
1965         struct bnx2x *bp = params->bp;
1966         u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1967                 NIG_REG_INGRESS_BMAC0_MEM;
1968         u32 val = 0x14;
1969
1970         if ((!(params->feature_config_flags &
1971               FEATURE_CONFIG_PFC_ENABLED)) &&
1972                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1973                 /* Enable BigMAC to react on received Pause packets */
1974                 val |= (1<<5);
1975         wb_data[0] = val;
1976         wb_data[1] = 0;
1977         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
1978         udelay(30);
1979
1980         /* Tx control */
1981         val = 0xc0;
1982         if (!(params->feature_config_flags &
1983                                 FEATURE_CONFIG_PFC_ENABLED) &&
1984             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1985                 val |= 0x800000;
1986         wb_data[0] = val;
1987         wb_data[1] = 0;
1988         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
1989
1990         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
1991                 DP(NETIF_MSG_LINK, "PFC is enabled\n");
1992                 /* Enable PFC RX & TX & STATS and set 8 COS  */
1993                 wb_data[0] = 0x0;
1994                 wb_data[0] |= (1<<0);  /* RX */
1995                 wb_data[0] |= (1<<1);  /* TX */
1996                 wb_data[0] |= (1<<2);  /* Force initial Xon */
1997                 wb_data[0] |= (1<<3);  /* 8 cos */
1998                 wb_data[0] |= (1<<5);  /* STATS */
1999                 wb_data[1] = 0;
2000                 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
2001                             wb_data, 2);
2002                 /* Clear the force Xon */
2003                 wb_data[0] &= ~(1<<2);
2004         } else {
2005                 DP(NETIF_MSG_LINK, "PFC is disabled\n");
2006                 /* disable PFC RX & TX & STATS and set 8 COS */
2007                 wb_data[0] = 0x8;
2008                 wb_data[1] = 0;
2009         }
2010
2011         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
2012
2013         /*
2014          * Set Time (based unit is 512 bit time) between automatic
2015          * re-sending of PP packets amd enable automatic re-send of
2016          * Per-Priroity Packet as long as pp_gen is asserted and
2017          * pp_disable is low.
2018          */
2019         val = 0x8000;
2020         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2021                 val |= (1<<16); /* enable automatic re-send */
2022
2023         wb_data[0] = val;
2024         wb_data[1] = 0;
2025         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
2026                     wb_data, 2);
2027
2028         /* mac control */
2029         val = 0x3; /* Enable RX and TX */
2030         if (is_lb) {
2031                 val |= 0x4; /* Local loopback */
2032                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
2033         }
2034         /* When PFC enabled, Pass pause frames towards the NIG. */
2035         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2036                 val |= ((1<<6)|(1<<5));
2037
2038         wb_data[0] = val;
2039         wb_data[1] = 0;
2040         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2041 }
2042
2043 /* PFC BRB internal port configuration params */
2044 struct bnx2x_pfc_brb_threshold_val {
2045         u32 pause_xoff;
2046         u32 pause_xon;
2047         u32 full_xoff;
2048         u32 full_xon;
2049 };
2050
2051 struct bnx2x_pfc_brb_e3b0_val {
2052         u32 per_class_guaranty_mode;
2053         u32 lb_guarantied_hyst;
2054         u32 full_lb_xoff_th;
2055         u32 full_lb_xon_threshold;
2056         u32 lb_guarantied;
2057         u32 mac_0_class_t_guarantied;
2058         u32 mac_0_class_t_guarantied_hyst;
2059         u32 mac_1_class_t_guarantied;
2060         u32 mac_1_class_t_guarantied_hyst;
2061 };
2062
2063 struct bnx2x_pfc_brb_th_val {
2064         struct bnx2x_pfc_brb_threshold_val pauseable_th;
2065         struct bnx2x_pfc_brb_threshold_val non_pauseable_th;
2066         struct bnx2x_pfc_brb_threshold_val default_class0;
2067         struct bnx2x_pfc_brb_threshold_val default_class1;
2068
2069 };
2070 static int bnx2x_pfc_brb_get_config_params(
2071                                 struct link_params *params,
2072                                 struct bnx2x_pfc_brb_th_val *config_val)
2073 {
2074         struct bnx2x *bp = params->bp;
2075         DP(NETIF_MSG_LINK, "Setting PFC BRB configuration\n");
2076
2077         config_val->default_class1.pause_xoff = 0;
2078         config_val->default_class1.pause_xon = 0;
2079         config_val->default_class1.full_xoff = 0;
2080         config_val->default_class1.full_xon = 0;
2081
2082         if (CHIP_IS_E2(bp)) {
2083                 /*  class0 defaults */
2084                 config_val->default_class0.pause_xoff =
2085                         DEFAULT0_E2_BRB_MAC_PAUSE_XOFF_THR;
2086                 config_val->default_class0.pause_xon =
2087                         DEFAULT0_E2_BRB_MAC_PAUSE_XON_THR;
2088                 config_val->default_class0.full_xoff =
2089                         DEFAULT0_E2_BRB_MAC_FULL_XOFF_THR;
2090                 config_val->default_class0.full_xon =
2091                         DEFAULT0_E2_BRB_MAC_FULL_XON_THR;
2092                 /*  pause able*/
2093                 config_val->pauseable_th.pause_xoff =
2094                         PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2095                 config_val->pauseable_th.pause_xon =
2096                         PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE;
2097                 config_val->pauseable_th.full_xoff =
2098                         PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE;
2099                 config_val->pauseable_th.full_xon =
2100                         PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE;
2101                 /* non pause able*/
2102                 config_val->non_pauseable_th.pause_xoff =
2103                         PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2104                 config_val->non_pauseable_th.pause_xon =
2105                         PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2106                 config_val->non_pauseable_th.full_xoff =
2107                         PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2108                 config_val->non_pauseable_th.full_xon =
2109                         PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2110         } else if (CHIP_IS_E3A0(bp)) {
2111                 /*  class0 defaults */
2112                 config_val->default_class0.pause_xoff =
2113                         DEFAULT0_E3A0_BRB_MAC_PAUSE_XOFF_THR;
2114                 config_val->default_class0.pause_xon =
2115                         DEFAULT0_E3A0_BRB_MAC_PAUSE_XON_THR;
2116                 config_val->default_class0.full_xoff =
2117                         DEFAULT0_E3A0_BRB_MAC_FULL_XOFF_THR;
2118                 config_val->default_class0.full_xon =
2119                         DEFAULT0_E3A0_BRB_MAC_FULL_XON_THR;
2120                 /*  pause able */
2121                 config_val->pauseable_th.pause_xoff =
2122                         PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2123                 config_val->pauseable_th.pause_xon =
2124                         PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE;
2125                 config_val->pauseable_th.full_xoff =
2126                         PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE;
2127                 config_val->pauseable_th.full_xon =
2128                         PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE;
2129                 /* non pause able*/
2130                 config_val->non_pauseable_th.pause_xoff =
2131                         PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2132                 config_val->non_pauseable_th.pause_xon =
2133                         PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2134                 config_val->non_pauseable_th.full_xoff =
2135                         PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2136                 config_val->non_pauseable_th.full_xon =
2137                         PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2138         } else if (CHIP_IS_E3B0(bp)) {
2139                 /*  class0 defaults */
2140                 config_val->default_class0.pause_xoff =
2141                         DEFAULT0_E3B0_BRB_MAC_PAUSE_XOFF_THR;
2142                 config_val->default_class0.pause_xon =
2143                     DEFAULT0_E3B0_BRB_MAC_PAUSE_XON_THR;
2144                 config_val->default_class0.full_xoff =
2145                     DEFAULT0_E3B0_BRB_MAC_FULL_XOFF_THR;
2146                 config_val->default_class0.full_xon =
2147                     DEFAULT0_E3B0_BRB_MAC_FULL_XON_THR;
2148
2149                 if (params->phy[INT_PHY].flags &
2150                     FLAGS_4_PORT_MODE) {
2151                         config_val->pauseable_th.pause_xoff =
2152                                 PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2153                         config_val->pauseable_th.pause_xon =
2154                                 PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE;
2155                         config_val->pauseable_th.full_xoff =
2156                                 PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE;
2157                         config_val->pauseable_th.full_xon =
2158                                 PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE;
2159                         /* non pause able*/
2160                         config_val->non_pauseable_th.pause_xoff =
2161                         PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2162                         config_val->non_pauseable_th.pause_xon =
2163                         PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2164                         config_val->non_pauseable_th.full_xoff =
2165                         PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2166                         config_val->non_pauseable_th.full_xon =
2167                         PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2168                 } else {
2169                         config_val->pauseable_th.pause_xoff =
2170                                 PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2171                         config_val->pauseable_th.pause_xon =
2172                                 PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE;
2173                         config_val->pauseable_th.full_xoff =
2174                                 PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE;
2175                         config_val->pauseable_th.full_xon =
2176                                 PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE;
2177                         /* non pause able*/
2178                         config_val->non_pauseable_th.pause_xoff =
2179                                 PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2180                         config_val->non_pauseable_th.pause_xon =
2181                                 PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2182                         config_val->non_pauseable_th.full_xoff =
2183                                 PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2184                         config_val->non_pauseable_th.full_xon =
2185                                 PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2186                 }
2187         } else
2188             return -EINVAL;
2189
2190         return 0;
2191 }
2192
2193 static void bnx2x_pfc_brb_get_e3b0_config_params(
2194                 struct link_params *params,
2195                 struct bnx2x_pfc_brb_e3b0_val
2196                 *e3b0_val,
2197                 struct bnx2x_nig_brb_pfc_port_params *pfc_params,
2198                 const u8 pfc_enabled)
2199 {
2200         if (pfc_enabled && pfc_params) {
2201                 e3b0_val->per_class_guaranty_mode = 1;
2202                 e3b0_val->lb_guarantied_hyst = 80;
2203
2204                 if (params->phy[INT_PHY].flags &
2205                     FLAGS_4_PORT_MODE) {
2206                         e3b0_val->full_lb_xoff_th =
2207                                 PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR;
2208                         e3b0_val->full_lb_xon_threshold =
2209                                 PFC_E3B0_4P_BRB_FULL_LB_XON_THR;
2210                         e3b0_val->lb_guarantied =
2211                                 PFC_E3B0_4P_LB_GUART;
2212                         e3b0_val->mac_0_class_t_guarantied =
2213                                 PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART;
2214                         e3b0_val->mac_0_class_t_guarantied_hyst =
2215                                 PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST;
2216                         e3b0_val->mac_1_class_t_guarantied =
2217                                 PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART;
2218                         e3b0_val->mac_1_class_t_guarantied_hyst =
2219                                 PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST;
2220                 } else {
2221                         e3b0_val->full_lb_xoff_th =
2222                                 PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR;
2223                         e3b0_val->full_lb_xon_threshold =
2224                                 PFC_E3B0_2P_BRB_FULL_LB_XON_THR;
2225                         e3b0_val->mac_0_class_t_guarantied_hyst =
2226                                 PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST;
2227                         e3b0_val->mac_1_class_t_guarantied =
2228                                 PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART;
2229                         e3b0_val->mac_1_class_t_guarantied_hyst =
2230                                 PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST;
2231
2232                         if (pfc_params->cos0_pauseable !=
2233                                 pfc_params->cos1_pauseable) {
2234                                 /* nonpauseable= Lossy + pauseable = Lossless*/
2235                                 e3b0_val->lb_guarantied =
2236                                         PFC_E3B0_2P_MIX_PAUSE_LB_GUART;
2237                                 e3b0_val->mac_0_class_t_guarantied =
2238                                PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART;
2239                         } else if (pfc_params->cos0_pauseable) {
2240                                 /* Lossless +Lossless*/
2241                                 e3b0_val->lb_guarantied =
2242                                         PFC_E3B0_2P_PAUSE_LB_GUART;
2243                                 e3b0_val->mac_0_class_t_guarantied =
2244                                    PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART;
2245                         } else {
2246                                 /* Lossy +Lossy*/
2247                                 e3b0_val->lb_guarantied =
2248                                         PFC_E3B0_2P_NON_PAUSE_LB_GUART;
2249                                 e3b0_val->mac_0_class_t_guarantied =
2250                                PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART;
2251                         }
2252                 }
2253         } else {
2254                 e3b0_val->per_class_guaranty_mode = 0;
2255                 e3b0_val->lb_guarantied_hyst = 0;
2256                 e3b0_val->full_lb_xoff_th =
2257                         DEFAULT_E3B0_BRB_FULL_LB_XOFF_THR;
2258                 e3b0_val->full_lb_xon_threshold =
2259                         DEFAULT_E3B0_BRB_FULL_LB_XON_THR;
2260                 e3b0_val->lb_guarantied =
2261                         DEFAULT_E3B0_LB_GUART;
2262                 e3b0_val->mac_0_class_t_guarantied =
2263                         DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART;
2264                 e3b0_val->mac_0_class_t_guarantied_hyst =
2265                         DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART_HYST;
2266                 e3b0_val->mac_1_class_t_guarantied =
2267                         DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART;
2268                 e3b0_val->mac_1_class_t_guarantied_hyst =
2269                         DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART_HYST;
2270         }
2271 }
2272 static int bnx2x_update_pfc_brb(struct link_params *params,
2273                                 struct link_vars *vars,
2274                                 struct bnx2x_nig_brb_pfc_port_params
2275                                 *pfc_params)
2276 {
2277         struct bnx2x *bp = params->bp;
2278         struct bnx2x_pfc_brb_th_val config_val = { {0} };
2279         struct bnx2x_pfc_brb_threshold_val *reg_th_config =
2280                 &config_val.pauseable_th;
2281         struct bnx2x_pfc_brb_e3b0_val e3b0_val = {0};
2282         const int set_pfc = params->feature_config_flags &
2283                 FEATURE_CONFIG_PFC_ENABLED;
2284         const u8 pfc_enabled = (set_pfc && pfc_params);
2285         int bnx2x_status = 0;
2286         u8 port = params->port;
2287
2288         /* default - pause configuration */
2289         reg_th_config = &config_val.pauseable_th;
2290         bnx2x_status = bnx2x_pfc_brb_get_config_params(params, &config_val);
2291         if (bnx2x_status)
2292                 return bnx2x_status;
2293
2294         if (pfc_enabled) {
2295                 /* First COS */
2296                 if (pfc_params->cos0_pauseable)
2297                         reg_th_config = &config_val.pauseable_th;
2298                 else
2299                         reg_th_config = &config_val.non_pauseable_th;
2300         } else
2301                 reg_th_config = &config_val.default_class0;
2302         /*
2303          * The number of free blocks below which the pause signal to class 0
2304          * of MAC #n is asserted. n=0,1
2305          */
2306         REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XOFF_THRESHOLD_1 :
2307                BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 ,
2308                reg_th_config->pause_xoff);
2309         /*
2310          * The number of free blocks above which the pause signal to class 0
2311          * of MAC #n is de-asserted. n=0,1
2312          */
2313         REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XON_THRESHOLD_1 :
2314                BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , reg_th_config->pause_xon);
2315         /*
2316          * The number of free blocks below which the full signal to class 0
2317          * of MAC #n is asserted. n=0,1
2318          */
2319         REG_WR(bp, (port) ? BRB1_REG_FULL_0_XOFF_THRESHOLD_1 :
2320                BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , reg_th_config->full_xoff);
2321         /*
2322          * The number of free blocks above which the full signal to class 0
2323          * of MAC #n is de-asserted. n=0,1
2324          */
2325         REG_WR(bp, (port) ? BRB1_REG_FULL_0_XON_THRESHOLD_1 :
2326                BRB1_REG_FULL_0_XON_THRESHOLD_0 , reg_th_config->full_xon);
2327
2328         if (pfc_enabled) {
2329                 /* Second COS */
2330                 if (pfc_params->cos1_pauseable)
2331                         reg_th_config = &config_val.pauseable_th;
2332                 else
2333                         reg_th_config = &config_val.non_pauseable_th;
2334         } else
2335                 reg_th_config = &config_val.default_class1;
2336         /*
2337          * The number of free blocks below which the pause signal to
2338          * class 1 of MAC #n is asserted. n=0,1
2339          */
2340         REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XOFF_THRESHOLD_1 :
2341                BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0,
2342                reg_th_config->pause_xoff);
2343
2344         /*
2345          * The number of free blocks above which the pause signal to
2346          * class 1 of MAC #n is de-asserted. n=0,1
2347          */
2348         REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XON_THRESHOLD_1 :
2349                BRB1_REG_PAUSE_1_XON_THRESHOLD_0,
2350                reg_th_config->pause_xon);
2351         /*
2352          * The number of free blocks below which the full signal to
2353          * class 1 of MAC #n is asserted. n=0,1
2354          */
2355         REG_WR(bp, (port) ? BRB1_REG_FULL_1_XOFF_THRESHOLD_1 :
2356                BRB1_REG_FULL_1_XOFF_THRESHOLD_0,
2357                reg_th_config->full_xoff);
2358         /*
2359          * The number of free blocks above which the full signal to
2360          * class 1 of MAC #n is de-asserted. n=0,1
2361          */
2362         REG_WR(bp, (port) ? BRB1_REG_FULL_1_XON_THRESHOLD_1 :
2363                BRB1_REG_FULL_1_XON_THRESHOLD_0,
2364                reg_th_config->full_xon);
2365
2366         if (CHIP_IS_E3B0(bp)) {
2367                 bnx2x_pfc_brb_get_e3b0_config_params(
2368                         params,
2369                         &e3b0_val,
2370                         pfc_params,
2371                         pfc_enabled);
2372
2373                 REG_WR(bp, BRB1_REG_PER_CLASS_GUARANTY_MODE,
2374                            e3b0_val.per_class_guaranty_mode);
2375
2376                 /*
2377                  * The hysteresis on the guarantied buffer space for the Lb
2378                  * port before signaling XON.
2379                  */
2380                 REG_WR(bp, BRB1_REG_LB_GUARANTIED_HYST,
2381                            e3b0_val.lb_guarantied_hyst);
2382
2383                 /*
2384                  * The number of free blocks below which the full signal to the
2385                  * LB port is asserted.
2386                  */
2387                 REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD,
2388                        e3b0_val.full_lb_xoff_th);
2389                 /*
2390                  * The number of free blocks above which the full signal to the
2391                  * LB port is de-asserted.
2392                  */
2393                 REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD,
2394                        e3b0_val.full_lb_xon_threshold);
2395                 /*
2396                  * The number of blocks guarantied for the MAC #n port. n=0,1
2397                  */
2398
2399                 /* The number of blocks guarantied for the LB port.*/
2400                 REG_WR(bp, BRB1_REG_LB_GUARANTIED,
2401                        e3b0_val.lb_guarantied);
2402
2403                 /*
2404                  * The number of blocks guarantied for the MAC #n port.
2405                  */
2406                 REG_WR(bp, BRB1_REG_MAC_GUARANTIED_0,
2407                        2 * e3b0_val.mac_0_class_t_guarantied);
2408                 REG_WR(bp, BRB1_REG_MAC_GUARANTIED_1,
2409                        2 * e3b0_val.mac_1_class_t_guarantied);
2410                 /*
2411                  * The number of blocks guarantied for class #t in MAC0. t=0,1
2412                  */
2413                 REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED,
2414                        e3b0_val.mac_0_class_t_guarantied);
2415                 REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED,
2416                        e3b0_val.mac_0_class_t_guarantied);
2417                 /*
2418                  * The hysteresis on the guarantied buffer space for class in
2419                  * MAC0.  t=0,1
2420                  */
2421                 REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED_HYST,
2422                        e3b0_val.mac_0_class_t_guarantied_hyst);
2423                 REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED_HYST,
2424                        e3b0_val.mac_0_class_t_guarantied_hyst);
2425
2426                 /*
2427                  * The number of blocks guarantied for class #t in MAC1.t=0,1
2428                  */
2429                 REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED,
2430                        e3b0_val.mac_1_class_t_guarantied);
2431                 REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED,
2432                        e3b0_val.mac_1_class_t_guarantied);
2433                 /*
2434                  * The hysteresis on the guarantied buffer space for class #t
2435                  * in MAC1.  t=0,1
2436                  */
2437                 REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED_HYST,
2438                        e3b0_val.mac_1_class_t_guarantied_hyst);
2439                 REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED_HYST,
2440                        e3b0_val.mac_1_class_t_guarantied_hyst);
2441         }
2442
2443         return bnx2x_status;
2444 }
2445
2446 /******************************************************************************
2447 * Description:
2448 *  This function is needed because NIG ARB_CREDIT_WEIGHT_X are
2449 *  not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
2450 ******************************************************************************/
2451 int bnx2x_pfc_nig_rx_priority_mask(struct bnx2x *bp,
2452                                               u8 cos_entry,
2453                                               u32 priority_mask, u8 port)
2454 {
2455         u32 nig_reg_rx_priority_mask_add = 0;
2456
2457         switch (cos_entry) {
2458         case 0:
2459              nig_reg_rx_priority_mask_add = (port) ?
2460                  NIG_REG_P1_RX_COS0_PRIORITY_MASK :
2461                  NIG_REG_P0_RX_COS0_PRIORITY_MASK;
2462              break;
2463         case 1:
2464             nig_reg_rx_priority_mask_add = (port) ?
2465                 NIG_REG_P1_RX_COS1_PRIORITY_MASK :
2466                 NIG_REG_P0_RX_COS1_PRIORITY_MASK;
2467             break;
2468         case 2:
2469             nig_reg_rx_priority_mask_add = (port) ?
2470                 NIG_REG_P1_RX_COS2_PRIORITY_MASK :
2471                 NIG_REG_P0_RX_COS2_PRIORITY_MASK;
2472             break;
2473         case 3:
2474             if (port)
2475                 return -EINVAL;
2476             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK;
2477             break;
2478         case 4:
2479             if (port)
2480                 return -EINVAL;
2481             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK;
2482             break;
2483         case 5:
2484             if (port)
2485                 return -EINVAL;
2486             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK;
2487             break;
2488         }
2489
2490         REG_WR(bp, nig_reg_rx_priority_mask_add, priority_mask);
2491
2492         return 0;
2493 }
2494 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
2495 {
2496         struct bnx2x *bp = params->bp;
2497
2498         REG_WR(bp, params->shmem_base +
2499                offsetof(struct shmem_region,
2500                         port_mb[params->port].link_status), link_status);
2501 }
2502
2503 static void bnx2x_update_pfc_nig(struct link_params *params,
2504                 struct link_vars *vars,
2505                 struct bnx2x_nig_brb_pfc_port_params *nig_params)
2506 {
2507         u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
2508         u32 llfc_enable = 0, xcm_out_en = 0, hwpfc_enable = 0;
2509         u32 pkt_priority_to_cos = 0;
2510         struct bnx2x *bp = params->bp;
2511         u8 port = params->port;
2512
2513         int set_pfc = params->feature_config_flags &
2514                 FEATURE_CONFIG_PFC_ENABLED;
2515         DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
2516
2517         /*
2518          * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
2519          * MAC control frames (that are not pause packets)
2520          * will be forwarded to the XCM.
2521          */
2522         xcm_mask = REG_RD(bp, port ? NIG_REG_LLH1_XCM_MASK :
2523                           NIG_REG_LLH0_XCM_MASK);
2524         /*
2525          * nig params will override non PFC params, since it's possible to
2526          * do transition from PFC to SAFC
2527          */
2528         if (set_pfc) {
2529                 pause_enable = 0;
2530                 llfc_out_en = 0;
2531                 llfc_enable = 0;
2532                 if (CHIP_IS_E3(bp))
2533                         ppp_enable = 0;
2534                 else
2535                 ppp_enable = 1;
2536                 xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2537                                      NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2538                 xcm_out_en = 0;
2539                 hwpfc_enable = 1;
2540         } else  {
2541                 if (nig_params) {
2542                         llfc_out_en = nig_params->llfc_out_en;
2543                         llfc_enable = nig_params->llfc_enable;
2544                         pause_enable = nig_params->pause_enable;
2545                 } else  /*defaul non PFC mode - PAUSE */
2546                         pause_enable = 1;
2547
2548                 xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2549                         NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2550                 xcm_out_en = 1;
2551         }
2552
2553         if (CHIP_IS_E3(bp))
2554                 REG_WR(bp, port ? NIG_REG_BRB1_PAUSE_IN_EN :
2555                        NIG_REG_BRB0_PAUSE_IN_EN, pause_enable);
2556         REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
2557                NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
2558         REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
2559                NIG_REG_LLFC_ENABLE_0, llfc_enable);
2560         REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
2561                NIG_REG_PAUSE_ENABLE_0, pause_enable);
2562
2563         REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
2564                NIG_REG_PPP_ENABLE_0, ppp_enable);
2565
2566         REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
2567                NIG_REG_LLH0_XCM_MASK, xcm_mask);
2568
2569         REG_WR(bp, port ? NIG_REG_LLFC_EGRESS_SRC_ENABLE_1 :
2570                NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
2571
2572         /* output enable for RX_XCM # IF */
2573         REG_WR(bp, port ? NIG_REG_XCM1_OUT_EN :
2574                NIG_REG_XCM0_OUT_EN, xcm_out_en);
2575
2576         /* HW PFC TX enable */
2577         REG_WR(bp, port ? NIG_REG_P1_HWPFC_ENABLE :
2578                NIG_REG_P0_HWPFC_ENABLE, hwpfc_enable);
2579
2580         if (nig_params) {
2581                 u8 i = 0;
2582                 pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
2583
2584                 for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++)
2585                         bnx2x_pfc_nig_rx_priority_mask(bp, i,
2586                 nig_params->rx_cos_priority_mask[i], port);
2587
2588                 REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
2589                        NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
2590                        nig_params->llfc_high_priority_classes);
2591
2592                 REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
2593                        NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
2594                        nig_params->llfc_low_priority_classes);
2595         }
2596         REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
2597                NIG_REG_P0_PKT_PRIORITY_TO_COS,
2598                pkt_priority_to_cos);
2599 }
2600
2601 int bnx2x_update_pfc(struct link_params *params,
2602                       struct link_vars *vars,
2603                       struct bnx2x_nig_brb_pfc_port_params *pfc_params)
2604 {
2605         /*
2606          * The PFC and pause are orthogonal to one another, meaning when
2607          * PFC is enabled, the pause are disabled, and when PFC is
2608          * disabled, pause are set according to the pause result.
2609          */
2610         u32 val;
2611         struct bnx2x *bp = params->bp;
2612         int bnx2x_status = 0;
2613         u8 bmac_loopback = (params->loopback_mode == LOOPBACK_BMAC);
2614
2615         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2616                 vars->link_status |= LINK_STATUS_PFC_ENABLED;
2617         else
2618                 vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
2619
2620         bnx2x_update_mng(params, vars->link_status);
2621
2622         /* update NIG params */
2623         bnx2x_update_pfc_nig(params, vars, pfc_params);
2624
2625         /* update BRB params */
2626         bnx2x_status = bnx2x_update_pfc_brb(params, vars, pfc_params);
2627         if (bnx2x_status)
2628                 return bnx2x_status;
2629
2630         if (!vars->link_up)
2631                 return bnx2x_status;
2632
2633         DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
2634         if (CHIP_IS_E3(bp))
2635                 bnx2x_update_pfc_xmac(params, vars, 0);
2636         else {
2637                 val = REG_RD(bp, MISC_REG_RESET_REG_2);
2638                 if ((val &
2639                      (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
2640                     == 0) {
2641                         DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
2642                         bnx2x_emac_enable(params, vars, 0);
2643                         return bnx2x_status;
2644                 }
2645                 if (CHIP_IS_E2(bp))
2646                         bnx2x_update_pfc_bmac2(params, vars, bmac_loopback);
2647                 else
2648                         bnx2x_update_pfc_bmac1(params, vars);
2649
2650                 val = 0;
2651                 if ((params->feature_config_flags &
2652                      FEATURE_CONFIG_PFC_ENABLED) ||
2653                     (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
2654                         val = 1;
2655                 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
2656         }
2657         return bnx2x_status;
2658 }
2659
2660
2661 static int bnx2x_bmac1_enable(struct link_params *params,
2662                               struct link_vars *vars,
2663                               u8 is_lb)
2664 {
2665         struct bnx2x *bp = params->bp;
2666         u8 port = params->port;
2667         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2668                                NIG_REG_INGRESS_BMAC0_MEM;
2669         u32 wb_data[2];
2670         u32 val;
2671
2672         DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
2673
2674         /* XGXS control */
2675         wb_data[0] = 0x3c;
2676         wb_data[1] = 0;
2677         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
2678                     wb_data, 2);
2679
2680         /* tx MAC SA */
2681         wb_data[0] = ((params->mac_addr[2] << 24) |
2682                        (params->mac_addr[3] << 16) |
2683                        (params->mac_addr[4] << 8) |
2684                         params->mac_addr[5]);
2685         wb_data[1] = ((params->mac_addr[0] << 8) |
2686                         params->mac_addr[1]);
2687         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
2688
2689         /* mac control */
2690         val = 0x3;
2691         if (is_lb) {
2692                 val |= 0x4;
2693                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
2694         }
2695         wb_data[0] = val;
2696         wb_data[1] = 0;
2697         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
2698
2699         /* set rx mtu */
2700         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2701         wb_data[1] = 0;
2702         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
2703
2704         bnx2x_update_pfc_bmac1(params, vars);
2705
2706         /* set tx mtu */
2707         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2708         wb_data[1] = 0;
2709         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
2710
2711         /* set cnt max size */
2712         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2713         wb_data[1] = 0;
2714         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2715
2716         /* configure safc */
2717         wb_data[0] = 0x1000200;
2718         wb_data[1] = 0;
2719         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
2720                     wb_data, 2);
2721
2722         return 0;
2723 }
2724
2725 static int bnx2x_bmac2_enable(struct link_params *params,
2726                               struct link_vars *vars,
2727                               u8 is_lb)
2728 {
2729         struct bnx2x *bp = params->bp;
2730         u8 port = params->port;
2731         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2732                                NIG_REG_INGRESS_BMAC0_MEM;
2733         u32 wb_data[2];
2734
2735         DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
2736
2737         wb_data[0] = 0;
2738         wb_data[1] = 0;
2739         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2740         udelay(30);
2741
2742         /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
2743         wb_data[0] = 0x3c;
2744         wb_data[1] = 0;
2745         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
2746                     wb_data, 2);
2747
2748         udelay(30);
2749
2750         /* tx MAC SA */
2751         wb_data[0] = ((params->mac_addr[2] << 24) |
2752                        (params->mac_addr[3] << 16) |
2753                        (params->mac_addr[4] << 8) |
2754                         params->mac_addr[5]);
2755         wb_data[1] = ((params->mac_addr[0] << 8) |
2756                         params->mac_addr[1]);
2757         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
2758                     wb_data, 2);
2759
2760         udelay(30);
2761
2762         /* Configure SAFC */
2763         wb_data[0] = 0x1000200;
2764         wb_data[1] = 0;
2765         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
2766                     wb_data, 2);
2767         udelay(30);
2768
2769         /* set rx mtu */
2770         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2771         wb_data[1] = 0;
2772         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
2773         udelay(30);
2774
2775         /* set tx mtu */
2776         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2777         wb_data[1] = 0;
2778         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
2779         udelay(30);
2780         /* set cnt max size */
2781         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
2782         wb_data[1] = 0;
2783         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2784         udelay(30);
2785         bnx2x_update_pfc_bmac2(params, vars, is_lb);
2786
2787         return 0;
2788 }
2789
2790 static int bnx2x_bmac_enable(struct link_params *params,
2791                              struct link_vars *vars,
2792                              u8 is_lb)
2793 {
2794         int rc = 0;
2795         u8 port = params->port;
2796         struct bnx2x *bp = params->bp;
2797         u32 val;
2798         /* reset and unreset the BigMac */
2799         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2800                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2801         msleep(1);
2802
2803         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2804                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2805
2806         /* enable access for bmac registers */
2807         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
2808
2809         /* Enable BMAC according to BMAC type*/
2810         if (CHIP_IS_E2(bp))
2811                 rc = bnx2x_bmac2_enable(params, vars, is_lb);
2812         else
2813                 rc = bnx2x_bmac1_enable(params, vars, is_lb);
2814         REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
2815         REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
2816         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
2817         val = 0;
2818         if ((params->feature_config_flags &
2819               FEATURE_CONFIG_PFC_ENABLED) ||
2820             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
2821                 val = 1;
2822         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
2823         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
2824         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
2825         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
2826         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
2827         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
2828
2829         vars->mac_type = MAC_TYPE_BMAC;
2830         return rc;
2831 }
2832
2833 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
2834 {
2835         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2836                         NIG_REG_INGRESS_BMAC0_MEM;
2837         u32 wb_data[2];
2838         u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
2839
2840         /* Only if the bmac is out of reset */
2841         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
2842                         (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
2843             nig_bmac_enable) {
2844
2845                 if (CHIP_IS_E2(bp)) {
2846                         /* Clear Rx Enable bit in BMAC_CONTROL register */
2847                         REG_RD_DMAE(bp, bmac_addr +
2848                                     BIGMAC2_REGISTER_BMAC_CONTROL,
2849                                     wb_data, 2);
2850                         wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
2851                         REG_WR_DMAE(bp, bmac_addr +
2852                                     BIGMAC2_REGISTER_BMAC_CONTROL,
2853                                     wb_data, 2);
2854                 } else {
2855                         /* Clear Rx Enable bit in BMAC_CONTROL register */
2856                         REG_RD_DMAE(bp, bmac_addr +
2857                                         BIGMAC_REGISTER_BMAC_CONTROL,
2858                                         wb_data, 2);
2859                         wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
2860                         REG_WR_DMAE(bp, bmac_addr +
2861                                         BIGMAC_REGISTER_BMAC_CONTROL,
2862                                         wb_data, 2);
2863                 }
2864                 msleep(1);
2865         }
2866 }
2867
2868 static int bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
2869                             u32 line_speed)
2870 {
2871         struct bnx2x *bp = params->bp;
2872         u8 port = params->port;
2873         u32 init_crd, crd;
2874         u32 count = 1000;
2875
2876         /* disable port */
2877         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
2878
2879         /* wait for init credit */
2880         init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
2881         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2882         DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
2883
2884         while ((init_crd != crd) && count) {
2885                 msleep(5);
2886
2887                 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2888                 count--;
2889         }
2890         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2891         if (init_crd != crd) {
2892                 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
2893                           init_crd, crd);
2894                 return -EINVAL;
2895         }
2896
2897         if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
2898             line_speed == SPEED_10 ||
2899             line_speed == SPEED_100 ||
2900             line_speed == SPEED_1000 ||
2901             line_speed == SPEED_2500) {
2902                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
2903                 /* update threshold */
2904                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
2905                 /* update init credit */
2906                 init_crd = 778;         /* (800-18-4) */
2907
2908         } else {
2909                 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
2910                               ETH_OVREHEAD)/16;
2911                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
2912                 /* update threshold */
2913                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
2914                 /* update init credit */
2915                 switch (line_speed) {
2916                 case SPEED_10000:
2917                         init_crd = thresh + 553 - 22;
2918                         break;
2919                 default:
2920                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2921                                   line_speed);
2922                         return -EINVAL;
2923                 }
2924         }
2925         REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
2926         DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
2927                  line_speed, init_crd);
2928
2929         /* probe the credit changes */
2930         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
2931         msleep(5);
2932         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
2933
2934         /* enable port */
2935         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
2936         return 0;
2937 }
2938
2939 /**
2940  * bnx2x_get_emac_base - retrive emac base address
2941  *
2942  * @bp:                 driver handle
2943  * @mdc_mdio_access:    access type
2944  * @port:               port id
2945  *
2946  * This function selects the MDC/MDIO access (through emac0 or
2947  * emac1) depend on the mdc_mdio_access, port, port swapped. Each
2948  * phy has a default access mode, which could also be overridden
2949  * by nvram configuration. This parameter, whether this is the
2950  * default phy configuration, or the nvram overrun
2951  * configuration, is passed here as mdc_mdio_access and selects
2952  * the emac_base for the CL45 read/writes operations
2953  */
2954 static u32 bnx2x_get_emac_base(struct bnx2x *bp,
2955                                u32 mdc_mdio_access, u8 port)
2956 {
2957         u32 emac_base = 0;
2958         switch (mdc_mdio_access) {
2959         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
2960                 break;
2961         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
2962                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
2963                         emac_base = GRCBASE_EMAC1;
2964                 else
2965                         emac_base = GRCBASE_EMAC0;
2966                 break;
2967         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
2968                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
2969                         emac_base = GRCBASE_EMAC0;
2970                 else
2971                         emac_base = GRCBASE_EMAC1;
2972                 break;
2973         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
2974                 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2975                 break;
2976         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
2977                 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
2978                 break;
2979         default:
2980                 break;
2981         }
2982         return emac_base;
2983
2984 }
2985
2986 /******************************************************************/
2987 /*                      CL22 access functions                     */
2988 /******************************************************************/
2989 static int bnx2x_cl22_write(struct bnx2x *bp,
2990                                        struct bnx2x_phy *phy,
2991                                        u16 reg, u16 val)
2992 {
2993         u32 tmp, mode;
2994         u8 i;
2995         int rc = 0;
2996         /* Switch to CL22 */
2997         mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
2998         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
2999                mode & ~EMAC_MDIO_MODE_CLAUSE_45);
3000
3001         /* address */
3002         tmp = ((phy->addr << 21) | (reg << 16) | val |
3003                EMAC_MDIO_COMM_COMMAND_WRITE_22 |
3004                EMAC_MDIO_COMM_START_BUSY);
3005         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3006
3007         for (i = 0; i < 50; i++) {
3008                 udelay(10);
3009
3010                 tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3011                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3012                         udelay(5);
3013                         break;
3014                 }
3015         }
3016         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3017                 DP(NETIF_MSG_LINK, "write phy register failed\n");
3018                 rc = -EFAULT;
3019         }
3020         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
3021         return rc;
3022 }
3023
3024 static int bnx2x_cl22_read(struct bnx2x *bp,
3025                                       struct bnx2x_phy *phy,
3026                                       u16 reg, u16 *ret_val)
3027 {
3028         u32 val, mode;
3029         u16 i;
3030         int rc = 0;
3031
3032         /* Switch to CL22 */
3033         mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
3034         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
3035                mode & ~EMAC_MDIO_MODE_CLAUSE_45);
3036
3037         /* address */
3038         val = ((phy->addr << 21) | (reg << 16) |
3039                EMAC_MDIO_COMM_COMMAND_READ_22 |
3040                EMAC_MDIO_COMM_START_BUSY);
3041         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3042
3043         for (i = 0; i < 50; i++) {
3044                 udelay(10);
3045
3046                 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3047                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3048                         *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
3049                         udelay(5);
3050                         break;
3051                 }
3052         }
3053         if (val & EMAC_MDIO_COMM_START_BUSY) {
3054                 DP(NETIF_MSG_LINK, "read phy register failed\n");
3055
3056                 *ret_val = 0;
3057                 rc = -EFAULT;
3058         }
3059         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
3060         return rc;
3061 }
3062
3063 /******************************************************************/
3064 /*                      CL45 access functions                     */
3065 /******************************************************************/
3066 static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
3067                            u8 devad, u16 reg, u16 *ret_val)
3068 {
3069         u32 val;
3070         u16 i;
3071         int rc = 0;
3072         if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3073                 bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3074                               EMAC_MDIO_STATUS_10MB);
3075         /* address */
3076         val = ((phy->addr << 21) | (devad << 16) | reg |
3077                EMAC_MDIO_COMM_COMMAND_ADDRESS |
3078                EMAC_MDIO_COMM_START_BUSY);
3079         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3080
3081         for (i = 0; i < 50; i++) {
3082                 udelay(10);
3083
3084                 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3085                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3086                         udelay(5);
3087                         break;
3088                 }
3089         }
3090         if (val & EMAC_MDIO_COMM_START_BUSY) {
3091                 DP(NETIF_MSG_LINK, "read phy register failed\n");
3092                 netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3093                 *ret_val = 0;
3094                 rc = -EFAULT;
3095         } else {
3096                 /* data */
3097                 val = ((phy->addr << 21) | (devad << 16) |
3098                        EMAC_MDIO_COMM_COMMAND_READ_45 |
3099                        EMAC_MDIO_COMM_START_BUSY);
3100                 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3101
3102                 for (i = 0; i < 50; i++) {
3103                         udelay(10);
3104
3105                         val = REG_RD(bp, phy->mdio_ctrl +
3106                                      EMAC_REG_EMAC_MDIO_COMM);
3107                         if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3108                                 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
3109                                 break;
3110                         }
3111                 }
3112                 if (val & EMAC_MDIO_COMM_START_BUSY) {
3113                         DP(NETIF_MSG_LINK, "read phy register failed\n");
3114                         netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3115                         *ret_val = 0;
3116                         rc = -EFAULT;
3117                 }
3118         }
3119         /* Work around for E3 A0 */
3120         if (phy->flags & FLAGS_MDC_MDIO_WA) {
3121                 phy->flags ^= FLAGS_DUMMY_READ;
3122                 if (phy->flags & FLAGS_DUMMY_READ) {
3123                         u16 temp_val;
3124                         bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
3125                 }
3126         }
3127
3128         if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3129                 bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3130                                EMAC_MDIO_STATUS_10MB);
3131         return rc;
3132 }
3133
3134 static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
3135                             u8 devad, u16 reg, u16 val)
3136 {
3137         u32 tmp;
3138         u8 i;
3139         int rc = 0;
3140         if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3141                 bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3142                               EMAC_MDIO_STATUS_10MB);
3143
3144         /* address */
3145
3146         tmp = ((phy->addr << 21) | (devad << 16) | reg |
3147                EMAC_MDIO_COMM_COMMAND_ADDRESS |
3148                EMAC_MDIO_COMM_START_BUSY);
3149         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3150
3151         for (i = 0; i < 50; i++) {
3152                 udelay(10);
3153
3154                 tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3155                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3156                         udelay(5);
3157                         break;
3158                 }
3159         }
3160         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3161                 DP(NETIF_MSG_LINK, "write phy register failed\n");
3162                 netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3163                 rc = -EFAULT;
3164         } else {
3165                 /* data */
3166                 tmp = ((phy->addr << 21) | (devad << 16) | val |
3167                        EMAC_MDIO_COMM_COMMAND_WRITE_45 |
3168                        EMAC_MDIO_COMM_START_BUSY);
3169                 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3170
3171                 for (i = 0; i < 50; i++) {
3172                         udelay(10);
3173
3174                         tmp = REG_RD(bp, phy->mdio_ctrl +
3175                                      EMAC_REG_EMAC_MDIO_COMM);
3176                         if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3177                                 udelay(5);
3178                                 break;
3179                         }
3180                 }
3181                 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3182                         DP(NETIF_MSG_LINK, "write phy register failed\n");
3183                         netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3184                         rc = -EFAULT;
3185                 }
3186         }
3187         /* Work around for E3 A0 */
3188         if (phy->flags & FLAGS_MDC_MDIO_WA) {
3189                 phy->flags ^= FLAGS_DUMMY_READ;
3190                 if (phy->flags & FLAGS_DUMMY_READ) {
3191                         u16 temp_val;
3192                         bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
3193                 }
3194         }
3195         if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3196                 bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3197                                EMAC_MDIO_STATUS_10MB);
3198         return rc;
3199 }
3200 /******************************************************************/
3201 /*                      BSC access functions from E3              */
3202 /******************************************************************/
3203 static void bnx2x_bsc_module_sel(struct link_params *params)
3204 {
3205         int idx;
3206         u32 board_cfg, sfp_ctrl;
3207         u32 i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH];
3208         struct bnx2x *bp = params->bp;
3209         u8 port = params->port;
3210         /* Read I2C output PINs */
3211         board_cfg = REG_RD(bp, params->shmem_base +
3212                            offsetof(struct shmem_region,
3213                                     dev_info.shared_hw_config.board));
3214         i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK;
3215         i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >>
3216                         SHARED_HW_CFG_E3_I2C_MUX1_SHIFT;
3217
3218         /* Read I2C output value */
3219         sfp_ctrl = REG_RD(bp, params->shmem_base +
3220                           offsetof(struct shmem_region,
3221                                  dev_info.port_hw_config[port].e3_cmn_pin_cfg));
3222         i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0;
3223         i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0;
3224         DP(NETIF_MSG_LINK, "Setting BSC switch\n");
3225         for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++)
3226                 bnx2x_set_cfg_pin(bp, i2c_pins[idx], i2c_val[idx]);
3227 }
3228
3229 static int bnx2x_bsc_read(struct link_params *params,
3230                           struct bnx2x_phy *phy,
3231                           u8 sl_devid,
3232                           u16 sl_addr,
3233                           u8 lc_addr,
3234                           u8 xfer_cnt,
3235                           u32 *data_array)
3236 {
3237         u32 val, i;
3238         int rc = 0;
3239         struct bnx2x *bp = params->bp;
3240
3241         if ((sl_devid != 0xa0) && (sl_devid != 0xa2)) {
3242                 DP(NETIF_MSG_LINK, "invalid sl_devid 0x%x\n", sl_devid);
3243                 return -EINVAL;
3244         }
3245
3246         if (xfer_cnt > 16) {
3247                 DP(NETIF_MSG_LINK, "invalid xfer_cnt %d. Max is 16 bytes\n",
3248                                         xfer_cnt);
3249                 return -EINVAL;
3250         }
3251         bnx2x_bsc_module_sel(params);
3252
3253         xfer_cnt = 16 - lc_addr;
3254
3255         /* enable the engine */
3256         val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3257         val |= MCPR_IMC_COMMAND_ENABLE;
3258         REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3259
3260         /* program slave device ID */
3261         val = (sl_devid << 16) | sl_addr;
3262         REG_WR(bp, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val);
3263
3264         /* start xfer with 0 byte to update the address pointer ???*/
3265         val = (MCPR_IMC_COMMAND_ENABLE) |
3266               (MCPR_IMC_COMMAND_WRITE_OP <<
3267                 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3268                 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0);
3269         REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3270
3271         /* poll for completion */
3272         i = 0;
3273         val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3274         while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3275                 udelay(10);
3276                 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3277                 if (i++ > 1000) {
3278                         DP(NETIF_MSG_LINK, "wr 0 byte timed out after %d try\n",
3279                                                                 i);
3280                         rc = -EFAULT;
3281                         break;
3282                 }
3283         }
3284         if (rc == -EFAULT)
3285                 return rc;
3286
3287         /* start xfer with read op */
3288         val = (MCPR_IMC_COMMAND_ENABLE) |
3289                 (MCPR_IMC_COMMAND_READ_OP <<
3290                 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3291                 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) |
3292                   (xfer_cnt);
3293         REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3294
3295         /* poll for completion */
3296         i = 0;
3297         val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3298         while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3299                 udelay(10);
3300                 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3301                 if (i++ > 1000) {
3302                         DP(NETIF_MSG_LINK, "rd op timed out after %d try\n", i);
3303                         rc = -EFAULT;
3304                         break;
3305                 }
3306         }
3307         if (rc == -EFAULT)
3308                 return rc;
3309
3310         for (i = (lc_addr >> 2); i < 4; i++) {
3311                 data_array[i] = REG_RD(bp, (MCP_REG_MCPR_IMC_DATAREG0 + i*4));
3312 #ifdef __BIG_ENDIAN
3313                 data_array[i] = ((data_array[i] & 0x000000ff) << 24) |
3314                                 ((data_array[i] & 0x0000ff00) << 8) |
3315                                 ((data_array[i] & 0x00ff0000) >> 8) |
3316                                 ((data_array[i] & 0xff000000) >> 24);
3317 #endif
3318         }
3319         return rc;
3320 }
3321
3322 static void bnx2x_cl45_read_or_write(struct bnx2x *bp, struct bnx2x_phy *phy,
3323                                      u8 devad, u16 reg, u16 or_val)
3324 {
3325         u16 val;
3326         bnx2x_cl45_read(bp, phy, devad, reg, &val);
3327         bnx2x_cl45_write(bp, phy, devad, reg, val | or_val);
3328 }
3329
3330 int bnx2x_phy_read(struct link_params *params, u8 phy_addr,
3331                    u8 devad, u16 reg, u16 *ret_val)
3332 {
3333         u8 phy_index;
3334         /*
3335          * Probe for the phy according to the given phy_addr, and execute
3336          * the read request on it
3337          */
3338         for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
3339                 if (params->phy[phy_index].addr == phy_addr) {
3340                         return bnx2x_cl45_read(params->bp,
3341                                                &params->phy[phy_index], devad,
3342                                                reg, ret_val);
3343                 }
3344         }
3345         return -EINVAL;
3346 }
3347
3348 int bnx2x_phy_write(struct link_params *params, u8 phy_addr,
3349                     u8 devad, u16 reg, u16 val)
3350 {
3351         u8 phy_index;
3352         /*
3353          * Probe for the phy according to the given phy_addr, and execute
3354          * the write request on it
3355          */
3356         for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
3357                 if (params->phy[phy_index].addr == phy_addr) {
3358                         return bnx2x_cl45_write(params->bp,
3359                                                 &params->phy[phy_index], devad,
3360                                                 reg, val);
3361                 }
3362         }
3363         return -EINVAL;
3364 }
3365 static u8 bnx2x_get_warpcore_lane(struct bnx2x_phy *phy,
3366                                   struct link_params *params)
3367 {
3368         u8 lane = 0;
3369         struct bnx2x *bp = params->bp;
3370         u32 path_swap, path_swap_ovr;
3371         u8 path, port;
3372
3373         path = BP_PATH(bp);
3374         port = params->port;
3375
3376         if (bnx2x_is_4_port_mode(bp)) {
3377                 u32 port_swap, port_swap_ovr;
3378
3379                 /*figure out path swap value */
3380                 path_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR);
3381                 if (path_swap_ovr & 0x1)
3382                         path_swap = (path_swap_ovr & 0x2);
3383                 else
3384                         path_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP);
3385
3386                 if (path_swap)
3387                         path = path ^ 1;
3388
3389                 /*figure out port swap value */
3390                 port_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR);
3391                 if (port_swap_ovr & 0x1)
3392                         port_swap = (port_swap_ovr & 0x2);
3393                 else
3394                         port_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP);
3395
3396                 if (port_swap)
3397                         port = port ^ 1;
3398
3399                 lane = (port<<1) + path;
3400         } else { /* two port mode - no port swap */
3401
3402                 /*figure out path swap value */
3403                 path_swap_ovr =
3404                         REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP_OVWR);
3405                 if (path_swap_ovr & 0x1) {
3406                         path_swap = (path_swap_ovr & 0x2);
3407                 } else {
3408                         path_swap =
3409                                 REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP);
3410                 }
3411                 if (path_swap)
3412                         path = path ^ 1;
3413
3414                 lane = path << 1 ;
3415         }
3416         return lane;
3417 }
3418
3419 static void bnx2x_set_aer_mmd(struct link_params *params,
3420                               struct bnx2x_phy *phy)
3421 {
3422         u32 ser_lane;
3423         u16 offset, aer_val;
3424         struct bnx2x *bp = params->bp;
3425         ser_lane = ((params->lane_config &
3426                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3427                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3428
3429         offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
3430                 (phy->addr + ser_lane) : 0;
3431
3432         if (USES_WARPCORE(bp)) {
3433                 aer_val = bnx2x_get_warpcore_lane(phy, params);
3434                 /*
3435                  * In Dual-lane mode, two lanes are joined together,
3436                  * so in order to configure them, the AER broadcast method is
3437                  * used here.
3438                  * 0x200 is the broadcast address for lanes 0,1
3439                  * 0x201 is the broadcast address for lanes 2,3
3440                  */
3441                 if (phy->flags & FLAGS_WC_DUAL_MODE)
3442                         aer_val = (aer_val >> 1) | 0x200;
3443         } else if (CHIP_IS_E2(bp))
3444                 aer_val = 0x3800 + offset - 1;
3445         else
3446                 aer_val = 0x3800 + offset;
3447
3448         CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
3449                           MDIO_AER_BLOCK_AER_REG, aer_val);
3450
3451 }
3452
3453 /******************************************************************/
3454 /*                      Internal phy section                      */
3455 /******************************************************************/
3456
3457 static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
3458 {
3459         u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3460
3461         /* Set Clause 22 */
3462         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
3463         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
3464         udelay(500);
3465         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
3466         udelay(500);
3467          /* Set Clause 45 */
3468         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
3469 }
3470
3471 static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
3472 {
3473         u32 val;
3474
3475         DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
3476
3477         val = SERDES_RESET_BITS << (port*16);
3478
3479         /* reset and unreset the SerDes/XGXS */
3480         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3481         udelay(500);
3482         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3483
3484         bnx2x_set_serdes_access(bp, port);
3485
3486         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + port*0x10,
3487                DEFAULT_PHY_DEV_ADDR);
3488 }
3489
3490 static void bnx2x_xgxs_deassert(struct link_params *params)
3491 {
3492         struct bnx2x *bp = params->bp;
3493         u8 port;
3494         u32 val;
3495         DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
3496         port = params->port;
3497
3498         val = XGXS_RESET_BITS << (port*16);
3499
3500         /* reset and unreset the SerDes/XGXS */
3501         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3502         udelay(500);
3503         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3504
3505         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0);
3506         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
3507                params->phy[INT_PHY].def_md_devad);
3508 }
3509
3510 static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
3511                                      struct link_params *params, u16 *ieee_fc)
3512 {
3513         struct bnx2x *bp = params->bp;
3514         *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
3515         /**
3516          * resolve pause mode and advertisement Please refer to Table
3517          * 28B-3 of the 802.3ab-1999 spec
3518          */
3519
3520         switch (phy->req_flow_ctrl) {
3521         case BNX2X_FLOW_CTRL_AUTO:
3522                 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH)
3523                         *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3524                 else
3525                         *ieee_fc |=
3526                         MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3527                 break;
3528
3529         case BNX2X_FLOW_CTRL_TX:
3530                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3531                 break;
3532
3533         case BNX2X_FLOW_CTRL_RX:
3534         case BNX2X_FLOW_CTRL_BOTH:
3535                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3536                 break;
3537
3538         case BNX2X_FLOW_CTRL_NONE:
3539         default:
3540                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
3541                 break;
3542         }
3543         DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
3544 }
3545
3546 static void set_phy_vars(struct link_params *params,
3547                          struct link_vars *vars)
3548 {
3549         struct bnx2x *bp = params->bp;
3550         u8 actual_phy_idx, phy_index, link_cfg_idx;
3551         u8 phy_config_swapped = params->multi_phy_config &
3552                         PORT_HW_CFG_PHY_SWAPPED_ENABLED;
3553         for (phy_index = INT_PHY; phy_index < params->num_phys;
3554               phy_index++) {
3555                 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
3556                 actual_phy_idx = phy_index;
3557                 if (phy_config_swapped) {
3558                         if (phy_index == EXT_PHY1)
3559                                 actual_phy_idx = EXT_PHY2;
3560                         else if (phy_index == EXT_PHY2)
3561                                 actual_phy_idx = EXT_PHY1;
3562                 }
3563                 params->phy[actual_phy_idx].req_flow_ctrl =
3564                         params->req_flow_ctrl[link_cfg_idx];
3565
3566                 params->phy[actual_phy_idx].req_line_speed =
3567                         params->req_line_speed[link_cfg_idx];
3568
3569                 params->phy[actual_phy_idx].speed_cap_mask =
3570                         params->speed_cap_mask[link_cfg_idx];
3571
3572                 params->phy[actual_phy_idx].req_duplex =
3573                         params->req_duplex[link_cfg_idx];
3574
3575                 if (params->req_line_speed[link_cfg_idx] ==
3576                     SPEED_AUTO_NEG)
3577                         vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
3578
3579                 DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
3580                            " speed_cap_mask %x\n",
3581                            params->phy[actual_phy_idx].req_flow_ctrl,
3582                            params->phy[actual_phy_idx].req_line_speed,
3583                            params->phy[actual_phy_idx].speed_cap_mask);
3584         }
3585 }
3586
3587 static void bnx2x_ext_phy_set_pause(struct link_params *params,
3588                                     struct bnx2x_phy *phy,
3589                                     struct link_vars *vars)
3590 {
3591         u16 val;
3592         struct bnx2x *bp = params->bp;
3593         /* read modify write pause advertizing */
3594         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
3595
3596         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3597
3598         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3599         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
3600         if ((vars->ieee_fc &
3601             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3602             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3603                 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3604         }
3605         if ((vars->ieee_fc &
3606             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3607             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3608                 val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
3609         }
3610         DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
3611         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
3612 }
3613
3614 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
3615 {                                               /*  LD      LP   */
3616         switch (pause_result) {                 /* ASYM P ASYM P */
3617         case 0xb:                               /*   1  0   1  1 */
3618                 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
3619                 break;
3620
3621         case 0xe:                               /*   1  1   1  0 */
3622                 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
3623                 break;
3624
3625         case 0x5:                               /*   0  1   0  1 */
3626         case 0x7:                               /*   0  1   1  1 */
3627         case 0xd:                               /*   1  1   0  1 */
3628         case 0xf:                               /*   1  1   1  1 */
3629                 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
3630                 break;
3631
3632         default:
3633                 break;
3634         }
3635         if (pause_result & (1<<0))
3636                 vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
3637         if (pause_result & (1<<1))
3638                 vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
3639 }
3640
3641 static void bnx2x_ext_phy_update_adv_fc(struct bnx2x_phy *phy,
3642                                         struct link_params *params,
3643                                         struct link_vars *vars)
3644 {
3645         u16 ld_pause;           /* local */
3646         u16 lp_pause;           /* link partner */
3647         u16 pause_result;
3648         struct bnx2x *bp = params->bp;
3649         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) {
3650                 bnx2x_cl22_read(bp, phy, 0x4, &ld_pause);
3651                 bnx2x_cl22_read(bp, phy, 0x5, &lp_pause);
3652         } else {
3653                 bnx2x_cl45_read(bp, phy,
3654                                 MDIO_AN_DEVAD,
3655                                 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3656                 bnx2x_cl45_read(bp, phy,
3657                                 MDIO_AN_DEVAD,
3658                                 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3659         }
3660         pause_result = (ld_pause &
3661                         MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
3662         pause_result |= (lp_pause &
3663                          MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
3664         DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n", pause_result);
3665         bnx2x_pause_resolve(vars, pause_result);
3666
3667 }
3668 static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
3669                                    struct link_params *params,
3670                                    struct link_vars *vars)
3671 {
3672         u8 ret = 0;
3673         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3674         if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) {
3675                 /* Update the advertised flow-controled of LD/LP in AN */
3676                 if (phy->req_line_speed == SPEED_AUTO_NEG)
3677                         bnx2x_ext_phy_update_adv_fc(phy, params, vars);
3678                 /* But set the flow-control result as the requested one */
3679                 vars->flow_ctrl = phy->req_flow_ctrl;
3680         } else if (phy->req_line_speed != SPEED_AUTO_NEG)
3681                 vars->flow_ctrl = params->req_fc_auto_adv;
3682         else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
3683                 ret = 1;
3684                 bnx2x_ext_phy_update_adv_fc(phy, params, vars);
3685         }
3686         return ret;
3687 }
3688 /******************************************************************/
3689 /*                      Warpcore section                          */
3690 /******************************************************************/
3691 /* The init_internal_warpcore should mirror the xgxs,
3692  * i.e. reset the lane (if needed), set aer for the
3693  * init configuration, and set/clear SGMII flag. Internal
3694  * phy init is done purely in phy_init stage.
3695  */
3696 static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
3697                                         struct link_params *params,
3698                                         struct link_vars *vars) {
3699         u16 val16 = 0, lane, bam37 = 0;
3700         struct bnx2x *bp = params->bp;
3701         DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n");
3702
3703         /* Disable Autoneg: re-enable it after adv is done. */
3704         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3705                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0);
3706
3707         /* Check adding advertisement for 1G KX */
3708         if (((vars->line_speed == SPEED_AUTO_NEG) &&
3709              (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
3710             (vars->line_speed == SPEED_1000)) {
3711                 u16 sd_digital;
3712                 val16 |= (1<<5);
3713
3714                 /* Enable CL37 1G Parallel Detect */
3715                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3716                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &sd_digital);
3717                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3718                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3719                                  (sd_digital | 0x1));
3720
3721                 DP(NETIF_MSG_LINK, "Advertize 1G\n");
3722         }
3723         if (((vars->line_speed == SPEED_AUTO_NEG) &&
3724              (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
3725             (vars->line_speed ==  SPEED_10000)) {
3726                 /* Check adding advertisement for 10G KR */
3727                 val16 |= (1<<7);
3728                 /* Enable 10G Parallel Detect */
3729                 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3730                                 MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
3731
3732                 DP(NETIF_MSG_LINK, "Advertize 10G\n");
3733         }
3734
3735         /* Set Transmit PMD settings */
3736         lane = bnx2x_get_warpcore_lane(phy, params);
3737         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3738                       MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3739                      ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3740                       (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3741                       (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
3742         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3743                          MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
3744                          0x03f0);
3745         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3746                          MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL,
3747                          0x03f0);
3748
3749         /* Advertised speeds */
3750         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3751                          MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16);
3752
3753         /* Advertised and set FEC (Forward Error Correction) */
3754         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3755                          MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2,
3756                          (MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY |
3757                           MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ));
3758
3759         /* Enable CL37 BAM */
3760         if (REG_RD(bp, params->shmem_base +
3761                    offsetof(struct shmem_region, dev_info.
3762                             port_hw_config[params->port].default_cfg)) &
3763             PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
3764                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3765                                 MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, &bam37);
3766                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3767                         MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, bam37 | 1);
3768                 DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
3769         }
3770
3771         /* Advertise pause */
3772         bnx2x_ext_phy_set_pause(params, phy, vars);
3773
3774         /*
3775          * Set KR Autoneg Work-Around flag for Warpcore version older than D108
3776          */
3777         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3778                         MDIO_WC_REG_UC_INFO_B1_VERSION, &val16);
3779         if (val16 < 0xd108) {
3780                 DP(NETIF_MSG_LINK, "Enable AN KR work-around\n");
3781                 vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
3782         }
3783
3784         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3785                         MDIO_WC_REG_DIGITAL5_MISC7, &val16);
3786
3787         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3788                          MDIO_WC_REG_DIGITAL5_MISC7, val16 | 0x100);
3789
3790         /* Over 1G - AN local device user page 1 */
3791         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3792                         MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
3793
3794         /* Enable Autoneg */
3795         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3796                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
3797
3798 }
3799
3800 static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy,
3801                                       struct link_params *params,
3802                                       struct link_vars *vars)
3803 {
3804         struct bnx2x *bp = params->bp;
3805         u16 val;
3806
3807         /* Disable Autoneg */
3808         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3809                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7);
3810
3811         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3812                          MDIO_WC_REG_PAR_DET_10G_CTRL, 0);
3813
3814         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3815                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0x3f00);
3816
3817         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3818                          MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0);
3819
3820         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3821                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
3822
3823         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3824                         MDIO_WC_REG_DIGITAL3_UP1, 0x1);
3825
3826         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3827                          MDIO_WC_REG_DIGITAL5_MISC7, 0xa);
3828
3829         /* Disable CL36 PCS Tx */
3830         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3831                         MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0);
3832
3833         /* Double Wide Single Data Rate @ pll rate */
3834         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3835                         MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF);
3836
3837         /* Leave cl72 training enable, needed for KR */
3838         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3839                 MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150,
3840                 0x2);
3841
3842         /* Leave CL72 enabled */
3843         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3844                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3845                          &val);
3846         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3847                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3848                          val | 0x3800);
3849
3850         /* Set speed via PMA/PMD register */
3851         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3852                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
3853
3854         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3855                          MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
3856
3857         /*Enable encoded forced speed */
3858         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3859                          MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
3860
3861         /* Turn TX scramble payload only the 64/66 scrambler */
3862         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3863                          MDIO_WC_REG_TX66_CONTROL, 0x9);
3864
3865         /* Turn RX scramble payload only the 64/66 scrambler */
3866         bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3867                                  MDIO_WC_REG_RX66_CONTROL, 0xF9);
3868
3869         /* set and clear loopback to cause a reset to 64/66 decoder */
3870         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3871                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000);
3872         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3873                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
3874
3875 }
3876
3877 static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
3878                                        struct link_params *params,
3879                                        u8 is_xfi)
3880 {
3881         struct bnx2x *bp = params->bp;
3882         u16 misc1_val, tap_val, tx_driver_val, lane, val;
3883         /* Hold rxSeqStart */
3884         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3885                         MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
3886         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3887                          MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val | 0x8000));
3888
3889         /* Hold tx_fifo_reset */
3890         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3891                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
3892         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3893                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, (val | 0x1));
3894
3895         /* Disable CL73 AN */
3896         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
3897
3898         /* Disable 100FX Enable and Auto-Detect */
3899         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3900                         MDIO_WC_REG_FX100_CTRL1, &val);
3901         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3902                          MDIO_WC_REG_FX100_CTRL1, (val & 0xFFFA));
3903
3904         /* Disable 100FX Idle detect */
3905         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3906                         MDIO_WC_REG_FX100_CTRL3, &val);
3907         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3908                          MDIO_WC_REG_FX100_CTRL3, (val | 0x0080));
3909
3910         /* Set Block address to Remote PHY & Clear forced_speed[5] */
3911         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3912                         MDIO_WC_REG_DIGITAL4_MISC3, &val);
3913         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3914                          MDIO_WC_REG_DIGITAL4_MISC3, (val & 0xFF7F));
3915
3916         /* Turn off auto-detect & fiber mode */
3917         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3918                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
3919         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3920                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3921                          (val & 0xFFEE));
3922
3923         /* Set filter_force_link, disable_false_link and parallel_detect */
3924         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3925                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val);
3926         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3927                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3928                          ((val | 0x0006) & 0xFFFE));
3929
3930         /* Set XFI / SFI */
3931         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3932                         MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val);
3933
3934         misc1_val &= ~(0x1f);
3935
3936         if (is_xfi) {
3937                 misc1_val |= 0x5;
3938                 tap_val = ((0x08 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3939                            (0x37 << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3940                            (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
3941                 tx_driver_val =
3942                       ((0x00 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3943                        (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3944                        (0x03 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
3945
3946         } else {
3947                 misc1_val |= 0x9;
3948                 tap_val = ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3949                            (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3950                            (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
3951                 tx_driver_val =
3952                       ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3953                        (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3954                        (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
3955         }
3956         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3957                          MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
3958
3959         /* Set Transmit PMD settings */
3960         lane = bnx2x_get_warpcore_lane(phy, params);
3961         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3962                          MDIO_WC_REG_TX_FIR_TAP,
3963                          tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE);
3964         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3965                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3966                          tx_driver_val);
3967
3968         /* Enable fiber mode, enable and invert sig_det */
3969         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3970                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
3971         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3972                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, val | 0xd);
3973
3974         /* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
3975         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3976                         MDIO_WC_REG_DIGITAL4_MISC3, &val);
3977         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3978                          MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080);
3979
3980         /* 10G XFI Full Duplex */
3981         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3982                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
3983
3984         /* Release tx_fifo_reset */
3985         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3986                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
3987         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3988                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, val & 0xFFFE);
3989
3990         /* Release rxSeqStart */
3991         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3992                         MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
3993         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3994                          MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val & 0x7FFF));
3995 }
3996
3997 static void bnx2x_warpcore_set_20G_KR2(struct bnx2x *bp,
3998                                        struct bnx2x_phy *phy)
3999 {
4000         DP(NETIF_MSG_LINK, "KR2 still not supported !!!\n");
4001 }
4002
4003 static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp,
4004                                          struct bnx2x_phy *phy,
4005                                          u16 lane)
4006 {
4007         /* Rx0 anaRxControl1G */
4008         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4009                          MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90);
4010
4011         /* Rx2 anaRxControl1G */
4012         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4013                          MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90);
4014
4015         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4016                          MDIO_WC_REG_RX66_SCW0, 0xE070);
4017
4018         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4019                          MDIO_WC_REG_RX66_SCW1, 0xC0D0);
4020
4021         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4022                          MDIO_WC_REG_RX66_SCW2, 0xA0B0);
4023
4024         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4025                          MDIO_WC_REG_RX66_SCW3, 0x8090);
4026
4027         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4028                          MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0);
4029
4030         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4031                          MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0);
4032
4033         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4034                          MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0);
4035
4036         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4037                          MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0);
4038
4039         /* Serdes Digital Misc1 */
4040         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4041                          MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008);
4042
4043         /* Serdes Digital4 Misc3 */
4044         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4045                          MDIO_WC_REG_DIGITAL4_MISC3, 0x8088);
4046
4047         /* Set Transmit PMD settings */
4048         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4049                          MDIO_WC_REG_TX_FIR_TAP,
4050                         ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
4051                          (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
4052                          (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET) |
4053                          MDIO_WC_REG_TX_FIR_TAP_ENABLE));
4054         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4055                       MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
4056                      ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
4057                       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
4058                       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
4059 }
4060
4061 static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
4062                                            struct link_params *params,
4063                                            u8 fiber_mode,
4064                                            u8 always_autoneg)
4065 {
4066         struct bnx2x *bp = params->bp;
4067         u16 val16, digctrl_kx1, digctrl_kx2;
4068
4069         /* Clear XFI clock comp in non-10G single lane mode. */
4070         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4071                         MDIO_WC_REG_RX66_CONTROL, &val16);
4072         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4073                          MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13));
4074
4075         if (always_autoneg || phy->req_line_speed == SPEED_AUTO_NEG) {
4076                 /* SGMII Autoneg */
4077                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4078                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4079                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4080                                  MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
4081                                  val16 | 0x1000);
4082                 DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n");
4083         } else {
4084                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4085                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4086                 val16 &= 0xcebf;
4087                 switch (phy->req_line_speed) {
4088                 case SPEED_10:
4089                         break;
4090                 case SPEED_100:
4091                         val16 |= 0x2000;
4092                         break;
4093                 case SPEED_1000:
4094                         val16 |= 0x0040;
4095                         break;
4096                 default:
4097                         DP(NETIF_MSG_LINK,
4098                            "Speed not supported: 0x%x\n", phy->req_line_speed);
4099                         return;
4100                 }
4101
4102                 if (phy->req_duplex == DUPLEX_FULL)
4103                         val16 |= 0x0100;
4104
4105                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4106                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16);
4107
4108                 DP(NETIF_MSG_LINK, "set SGMII force speed %d\n",
4109                                phy->req_line_speed);
4110                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4111                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4112                 DP(NETIF_MSG_LINK, "  (readback) %x\n", val16);
4113         }
4114
4115         /* SGMII Slave mode and disable signal detect */
4116         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4117                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1);
4118         if (fiber_mode)
4119                 digctrl_kx1 = 1;
4120         else
4121                 digctrl_kx1 &= 0xff4a;
4122
4123         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4124                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4125                         digctrl_kx1);
4126
4127         /* Turn off parallel detect */
4128         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4129                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2);
4130         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4131                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4132                         (digctrl_kx2 & ~(1<<2)));
4133
4134         /* Re-enable parallel detect */
4135         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4136                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4137                         (digctrl_kx2 | (1<<2)));
4138
4139         /* Enable autodet */
4140         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4141                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4142                         (digctrl_kx1 | 0x10));
4143 }
4144
4145 static void bnx2x_warpcore_reset_lane(struct bnx2x *bp,
4146                                       struct bnx2x_phy *phy,
4147                                       u8 reset)
4148 {
4149         u16 val;
4150         /* Take lane out of reset after configuration is finished */
4151         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4152                         MDIO_WC_REG_DIGITAL5_MISC6, &val);
4153         if (reset)
4154                 val |= 0xC000;
4155         else
4156                 val &= 0x3FFF;
4157         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4158                          MDIO_WC_REG_DIGITAL5_MISC6, val);
4159         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4160                          MDIO_WC_REG_DIGITAL5_MISC6, &val);
4161 }
4162 /* Clear SFI/XFI link settings registers */
4163 static void bnx2x_warpcore_clear_regs(struct bnx2x_phy *phy,
4164                                       struct link_params *params,
4165                                       u16 lane)
4166 {
4167         struct bnx2x *bp = params->bp;
4168         u16 val16;
4169
4170         /* Set XFI clock comp as default. */
4171         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4172                         MDIO_WC_REG_RX66_CONTROL, &val16);
4173         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4174                          MDIO_WC_REG_RX66_CONTROL, val16 | (3<<13));
4175
4176         bnx2x_warpcore_reset_lane(bp, phy, 1);
4177         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
4178         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4179                          MDIO_WC_REG_FX100_CTRL1, 0x014a);
4180         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4181                          MDIO_WC_REG_FX100_CTRL3, 0x0800);
4182         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4183                          MDIO_WC_REG_DIGITAL4_MISC3, 0x8008);
4184         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4185                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x0195);
4186         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4187                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x0007);
4188         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4189                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x0002);
4190         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4191                          MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000);
4192         lane = bnx2x_get_warpcore_lane(phy, params);
4193         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4194                          MDIO_WC_REG_TX_FIR_TAP, 0x0000);
4195         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4196                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990);
4197         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4198                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
4199         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4200                          MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140);
4201         bnx2x_warpcore_reset_lane(bp, phy, 0);
4202 }
4203
4204 static int bnx2x_get_mod_abs_int_cfg(struct bnx2x *bp,
4205                                                 u32 chip_id,
4206                                                 u32 shmem_base, u8 port,
4207                                                 u8 *gpio_num, u8 *gpio_port)
4208 {
4209         u32 cfg_pin;
4210         *gpio_num = 0;
4211         *gpio_port = 0;
4212         if (CHIP_IS_E3(bp)) {
4213                 cfg_pin = (REG_RD(bp, shmem_base +
4214                                 offsetof(struct shmem_region,
4215                                 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4216                                 PORT_HW_CFG_E3_MOD_ABS_MASK) >>
4217                                 PORT_HW_CFG_E3_MOD_ABS_SHIFT;
4218
4219                 /*
4220                  * Should not happen. This function called upon interrupt
4221                  * triggered by GPIO ( since EPIO can only generate interrupts
4222                  * to MCP).
4223                  * So if this function was called and none of the GPIOs was set,
4224                  * it means the shit hit the fan.
4225                  */
4226                 if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
4227                     (cfg_pin > PIN_CFG_GPIO3_P1)) {
4228                         DP(NETIF_MSG_LINK,
4229                            "ERROR: Invalid cfg pin %x for module detect indication\n",
4230                            cfg_pin);
4231                         return -EINVAL;
4232                 }
4233
4234                 *gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
4235                 *gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
4236         } else {
4237                 *gpio_num = MISC_REGISTERS_GPIO_3;
4238                 *gpio_port = port;
4239         }
4240         DP(NETIF_MSG_LINK, "MOD_ABS int GPIO%d_P%d\n", *gpio_num, *gpio_port);
4241         return 0;
4242 }
4243
4244 static int bnx2x_is_sfp_module_plugged(struct bnx2x_phy *phy,
4245                                        struct link_params *params)
4246 {
4247         struct bnx2x *bp = params->bp;
4248         u8 gpio_num, gpio_port;
4249         u32 gpio_val;
4250         if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id,
4251                                       params->shmem_base, params->port,
4252                                       &gpio_num, &gpio_port) != 0)
4253                 return 0;
4254         gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
4255
4256         /* Call the handling function in case module is detected */
4257         if (gpio_val == 0)
4258                 return 1;
4259         else
4260                 return 0;
4261 }
4262 static int bnx2x_warpcore_get_sigdet(struct bnx2x_phy *phy,
4263                                         struct link_params *params)
4264 {
4265         u16 gp2_status_reg0, lane;
4266         struct bnx2x *bp = params->bp;
4267
4268         lane = bnx2x_get_warpcore_lane(phy, params);
4269
4270         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_0,
4271                                  &gp2_status_reg0);
4272
4273         return (gp2_status_reg0 >> (8+lane)) & 0x1;
4274 }
4275
4276 static void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy,
4277                                        struct link_params *params,
4278                                        struct link_vars *vars)
4279 {
4280         struct bnx2x *bp = params->bp;
4281         u32 serdes_net_if;
4282         u16 gp_status1 = 0, lnkup = 0, lnkup_kr = 0;
4283         u16 lane = bnx2x_get_warpcore_lane(phy, params);
4284
4285         vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1;
4286
4287         if (!vars->turn_to_run_wc_rt)
4288                 return;
4289
4290         /* return if there is no link partner */
4291         if (!(bnx2x_warpcore_get_sigdet(phy, params))) {
4292                 DP(NETIF_MSG_LINK, "bnx2x_warpcore_get_sigdet false\n");
4293                 return;
4294         }
4295
4296         if (vars->rx_tx_asic_rst) {
4297                 serdes_net_if = (REG_RD(bp, params->shmem_base +
4298                                 offsetof(struct shmem_region, dev_info.
4299                                 port_hw_config[params->port].default_cfg)) &
4300                                 PORT_HW_CFG_NET_SERDES_IF_MASK);
4301
4302                 switch (serdes_net_if) {
4303                 case PORT_HW_CFG_NET_SERDES_IF_KR:
4304                         /* Do we get link yet? */
4305                         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 0x81d1,
4306                                                                 &gp_status1);
4307                         lnkup = (gp_status1 >> (8+lane)) & 0x1;/* 1G */
4308                                 /*10G KR*/
4309                         lnkup_kr = (gp_status1 >> (12+lane)) & 0x1;
4310
4311                         DP(NETIF_MSG_LINK,
4312                                 "gp_status1 0x%x\n", gp_status1);
4313
4314                         if (lnkup_kr || lnkup) {
4315                                         vars->rx_tx_asic_rst = 0;
4316                                         DP(NETIF_MSG_LINK,
4317                                         "link up, rx_tx_asic_rst 0x%x\n",
4318                                         vars->rx_tx_asic_rst);
4319                         } else {
4320                                 /*reset the lane to see if link comes up.*/
4321                                 bnx2x_warpcore_reset_lane(bp, phy, 1);
4322                                 bnx2x_warpcore_reset_lane(bp, phy, 0);
4323
4324                                 /* restart Autoneg */
4325                                 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
4326                                         MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
4327
4328                                 vars->rx_tx_asic_rst--;
4329                                 DP(NETIF_MSG_LINK, "0x%x retry left\n",
4330                                 vars->rx_tx_asic_rst);
4331                         }
4332                         break;
4333
4334                 default:
4335                         break;
4336                 }
4337
4338         } /*params->rx_tx_asic_rst*/
4339
4340 }
4341
4342 static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
4343                                        struct link_params *params,
4344                                        struct link_vars *vars)
4345 {
4346         struct bnx2x *bp = params->bp;
4347         u32 serdes_net_if;
4348         u8 fiber_mode;
4349         u16 lane = bnx2x_get_warpcore_lane(phy, params);
4350         serdes_net_if = (REG_RD(bp, params->shmem_base +
4351                          offsetof(struct shmem_region, dev_info.
4352                                   port_hw_config[params->port].default_cfg)) &
4353                          PORT_HW_CFG_NET_SERDES_IF_MASK);
4354         DP(NETIF_MSG_LINK, "Begin Warpcore init, link_speed %d, "
4355                            "serdes_net_if = 0x%x\n",
4356                        vars->line_speed, serdes_net_if);
4357         bnx2x_set_aer_mmd(params, phy);
4358
4359         vars->phy_flags |= PHY_XGXS_FLAG;
4360         if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
4361             (phy->req_line_speed &&
4362              ((phy->req_line_speed == SPEED_100) ||
4363               (phy->req_line_speed == SPEED_10)))) {
4364                 vars->phy_flags |= PHY_SGMII_FLAG;
4365                 DP(NETIF_MSG_LINK, "Setting SGMII mode\n");
4366                 bnx2x_warpcore_clear_regs(phy, params, lane);
4367                 bnx2x_warpcore_set_sgmii_speed(phy, params, 0, 1);
4368         } else {
4369                 switch (serdes_net_if) {
4370                 case PORT_HW_CFG_NET_SERDES_IF_KR:
4371                         /* Enable KR Auto Neg */
4372                         if (params->loopback_mode == LOOPBACK_NONE)
4373                                 bnx2x_warpcore_enable_AN_KR(phy, params, vars);
4374                         else {
4375                                 DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n");
4376                                 bnx2x_warpcore_set_10G_KR(phy, params, vars);
4377                         }
4378                         break;
4379
4380                 case PORT_HW_CFG_NET_SERDES_IF_XFI:
4381                         bnx2x_warpcore_clear_regs(phy, params, lane);
4382                         if (vars->line_speed == SPEED_10000) {
4383                                 DP(NETIF_MSG_LINK, "Setting 10G XFI\n");
4384                                 bnx2x_warpcore_set_10G_XFI(phy, params, 1);
4385                         } else {
4386                                 if (SINGLE_MEDIA_DIRECT(params)) {
4387                                         DP(NETIF_MSG_LINK, "1G Fiber\n");
4388                                         fiber_mode = 1;
4389                                 } else {
4390                                         DP(NETIF_MSG_LINK, "10/100/1G SGMII\n");
4391                                         fiber_mode = 0;
4392                                 }
4393                                 bnx2x_warpcore_set_sgmii_speed(phy,
4394                                                                 params,
4395                                                                 fiber_mode,
4396                                                                 0);
4397                         }
4398
4399                         break;
4400
4401                 case PORT_HW_CFG_NET_SERDES_IF_SFI:
4402
4403                         bnx2x_warpcore_clear_regs(phy, params, lane);
4404                         if (vars->line_speed == SPEED_10000) {
4405                                 DP(NETIF_MSG_LINK, "Setting 10G SFI\n");
4406                                 bnx2x_warpcore_set_10G_XFI(phy, params, 0);
4407                         } else if (vars->line_speed == SPEED_1000) {
4408                                 DP(NETIF_MSG_LINK, "Setting 1G Fiber\n");
4409                                 bnx2x_warpcore_set_sgmii_speed(
4410                                                 phy, params, 1, 0);
4411                         }
4412                         /* Issue Module detection */
4413                         if (bnx2x_is_sfp_module_plugged(phy, params))
4414                                 bnx2x_sfp_module_detection(phy, params);
4415                         break;
4416
4417                 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
4418                         if (vars->line_speed != SPEED_20000) {
4419                                 DP(NETIF_MSG_LINK, "Speed not supported yet\n");
4420                                 return;
4421                         }
4422                         DP(NETIF_MSG_LINK, "Setting 20G DXGXS\n");
4423                         bnx2x_warpcore_set_20G_DXGXS(bp, phy, lane);
4424                         /* Issue Module detection */
4425
4426                         bnx2x_sfp_module_detection(phy, params);
4427                         break;
4428
4429                 case PORT_HW_CFG_NET_SERDES_IF_KR2:
4430                         if (vars->line_speed != SPEED_20000) {
4431                                 DP(NETIF_MSG_LINK, "Speed not supported yet\n");
4432                                 return;
4433                         }
4434                         DP(NETIF_MSG_LINK, "Setting 20G KR2\n");
4435                         bnx2x_warpcore_set_20G_KR2(bp, phy);
4436                         break;
4437
4438                 default:
4439                         DP(NETIF_MSG_LINK,
4440                            "Unsupported Serdes Net Interface 0x%x\n",
4441                            serdes_net_if);
4442                         return;
4443                 }
4444         }
4445
4446         /* Take lane out of reset after configuration is finished */
4447         bnx2x_warpcore_reset_lane(bp, phy, 0);
4448         DP(NETIF_MSG_LINK, "Exit config init\n");
4449 }
4450
4451 static void bnx2x_sfp_e3_set_transmitter(struct link_params *params,
4452                                          struct bnx2x_phy *phy,
4453                                          u8 tx_en)
4454 {
4455         struct bnx2x *bp = params->bp;
4456         u32 cfg_pin;
4457         u8 port = params->port;
4458
4459         cfg_pin = REG_RD(bp, params->shmem_base +
4460                                 offsetof(struct shmem_region,
4461                                 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4462                                 PORT_HW_CFG_TX_LASER_MASK;
4463         /* Set the !tx_en since this pin is DISABLE_TX_LASER */
4464         DP(NETIF_MSG_LINK, "Setting WC TX to %d\n", tx_en);
4465         /* For 20G, the expected pin to be used is 3 pins after the current */
4466
4467         bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1);
4468         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
4469                 bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1);
4470 }
4471
4472 static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy,
4473                                       struct link_params *params)
4474 {
4475         struct bnx2x *bp = params->bp;
4476         u16 val16;
4477         bnx2x_sfp_e3_set_transmitter(params, phy, 0);
4478         bnx2x_set_mdio_clk(bp, params->chip_id, params->port);
4479         bnx2x_set_aer_mmd(params, phy);
4480         /* Global register */
4481         bnx2x_warpcore_reset_lane(bp, phy, 1);
4482
4483         /* Clear loopback settings (if any) */
4484         /* 10G & 20G */
4485         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4486                         MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4487         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4488                          MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 &
4489                          0xBFFF);
4490
4491         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4492                         MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
4493         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4494                         MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 & 0xfffe);
4495
4496         /* Update those 1-copy registers */
4497         CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4498                           MDIO_AER_BLOCK_AER_REG, 0);
4499                 /* Enable 1G MDIO (1-copy) */
4500         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4501                         MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4502                         &val16);
4503         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4504                          MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4505                          val16 & ~0x10);
4506
4507         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4508                         MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
4509         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4510                          MDIO_WC_REG_XGXSBLK1_LANECTRL2,
4511                          val16 & 0xff00);
4512
4513 }
4514
4515 static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy,
4516                                         struct link_params *params)
4517 {
4518         struct bnx2x *bp = params->bp;
4519         u16 val16;
4520         u32 lane;
4521         DP(NETIF_MSG_LINK, "Setting Warpcore loopback type %x, speed %d\n",
4522                        params->loopback_mode, phy->req_line_speed);
4523
4524         if (phy->req_line_speed < SPEED_10000) {
4525                 /* 10/100/1000 */
4526
4527                 /* Update those 1-copy registers */
4528                 CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4529                                   MDIO_AER_BLOCK_AER_REG, 0);
4530                 /* Enable 1G MDIO (1-copy) */
4531                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4532                                 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4533                                 &val16);
4534                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4535                                 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4536                                 val16 | 0x10);
4537                 /* Set 1G loopback based on lane (1-copy) */
4538                 lane = bnx2x_get_warpcore_lane(phy, params);
4539                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4540                                 MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
4541                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4542                                 MDIO_WC_REG_XGXSBLK1_LANECTRL2,
4543                                 val16 | (1<<lane));
4544
4545                 /* Switch back to 4-copy registers */
4546                 bnx2x_set_aer_mmd(params, phy);
4547         } else {
4548                 /* 10G & 20G */
4549                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4550                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4551                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4552                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 |
4553                                  0x4000);
4554
4555                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4556                                 MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
4557                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4558                                 MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 | 0x1);
4559         }
4560 }
4561
4562
4563 void bnx2x_sync_link(struct link_params *params,
4564                            struct link_vars *vars)
4565 {
4566         struct bnx2x *bp = params->bp;
4567         u8 link_10g_plus;
4568         if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4569                 vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
4570         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
4571         if (vars->link_up) {
4572                 DP(NETIF_MSG_LINK, "phy link up\n");
4573
4574                 vars->phy_link_up = 1;
4575                 vars->duplex = DUPLEX_FULL;
4576                 switch (vars->link_status &
4577                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
4578                         case LINK_10THD:
4579                                 vars->duplex = DUPLEX_HALF;
4580                                 /* fall thru */
4581                         case LINK_10TFD:
4582                                 vars->line_speed = SPEED_10;
4583                                 break;
4584
4585                         case LINK_100TXHD:
4586                                 vars->duplex = DUPLEX_HALF;
4587                                 /* fall thru */
4588                         case LINK_100T4:
4589                         case LINK_100TXFD:
4590                                 vars->line_speed = SPEED_100;
4591                                 break;
4592
4593                         case LINK_1000THD:
4594                                 vars->duplex = DUPLEX_HALF;
4595                                 /* fall thru */
4596                         case LINK_1000TFD:
4597                                 vars->line_speed = SPEED_1000;
4598                                 break;
4599
4600                         case LINK_2500THD:
4601                                 vars->duplex = DUPLEX_HALF;
4602                                 /* fall thru */
4603                         case LINK_2500TFD:
4604                                 vars->line_speed = SPEED_2500;
4605                                 break;
4606
4607                         case LINK_10GTFD:
4608                                 vars->line_speed = SPEED_10000;
4609                                 break;
4610                         case LINK_20GTFD:
4611                                 vars->line_speed = SPEED_20000;
4612                                 break;
4613                         default:
4614                                 break;
4615                 }
4616                 vars->flow_ctrl = 0;
4617                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
4618                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
4619
4620                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
4621                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
4622
4623                 if (!vars->flow_ctrl)
4624                         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4625
4626                 if (vars->line_speed &&
4627                     ((vars->line_speed == SPEED_10) ||
4628                      (vars->line_speed == SPEED_100))) {
4629                         vars->phy_flags |= PHY_SGMII_FLAG;
4630                 } else {
4631                         vars->phy_flags &= ~PHY_SGMII_FLAG;
4632                 }
4633                 if (vars->line_speed &&
4634                     USES_WARPCORE(bp) &&
4635                     (vars->line_speed == SPEED_1000))
4636                         vars->phy_flags |= PHY_SGMII_FLAG;
4637                 /* anything 10 and over uses the bmac */
4638                 link_10g_plus = (vars->line_speed >= SPEED_10000);
4639
4640                 if (link_10g_plus) {
4641                         if (USES_WARPCORE(bp))
4642                                 vars->mac_type = MAC_TYPE_XMAC;
4643                         else
4644                                 vars->mac_type = MAC_TYPE_BMAC;
4645                 } else {
4646                         if (USES_WARPCORE(bp))
4647                                 vars->mac_type = MAC_TYPE_UMAC;
4648                         else
4649                                 vars->mac_type = MAC_TYPE_EMAC;
4650                 }
4651         } else { /* link down */
4652                 DP(NETIF_MSG_LINK, "phy link down\n");
4653
4654                 vars->phy_link_up = 0;
4655
4656                 vars->line_speed = 0;
4657                 vars->duplex = DUPLEX_FULL;
4658                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4659
4660                 /* indicate no mac active */
4661                 vars->mac_type = MAC_TYPE_NONE;
4662                 if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4663                         vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
4664         }
4665 }
4666
4667 void bnx2x_link_status_update(struct link_params *params,
4668                               struct link_vars *vars)
4669 {
4670         struct bnx2x *bp = params->bp;
4671         u8 port = params->port;
4672         u32 sync_offset, media_types;
4673         /* Update PHY configuration */
4674         set_phy_vars(params, vars);
4675
4676         vars->link_status = REG_RD(bp, params->shmem_base +
4677                                    offsetof(struct shmem_region,
4678                                             port_mb[port].link_status));
4679
4680         vars->phy_flags = PHY_XGXS_FLAG;
4681         bnx2x_sync_link(params, vars);
4682         /* Sync media type */
4683         sync_offset = params->shmem_base +
4684                         offsetof(struct shmem_region,
4685                                  dev_info.port_hw_config[port].media_type);
4686         media_types = REG_RD(bp, sync_offset);
4687
4688         params->phy[INT_PHY].media_type =
4689                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
4690                 PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
4691         params->phy[EXT_PHY1].media_type =
4692                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
4693                 PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
4694         params->phy[EXT_PHY2].media_type =
4695                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
4696                 PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
4697         DP(NETIF_MSG_LINK, "media_types = 0x%x\n", media_types);
4698
4699         /* Sync AEU offset */
4700         sync_offset = params->shmem_base +
4701                         offsetof(struct shmem_region,
4702                                  dev_info.port_hw_config[port].aeu_int_mask);
4703
4704         vars->aeu_int_mask = REG_RD(bp, sync_offset);
4705
4706         /* Sync PFC status */
4707         if (vars->link_status & LINK_STATUS_PFC_ENABLED)
4708                 params->feature_config_flags |=
4709                                         FEATURE_CONFIG_PFC_ENABLED;
4710         else
4711                 params->feature_config_flags &=
4712                                         ~FEATURE_CONFIG_PFC_ENABLED;
4713
4714         DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x int_mask 0x%x\n",
4715                  vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
4716         DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
4717                  vars->line_speed, vars->duplex, vars->flow_ctrl);
4718 }
4719
4720 static void bnx2x_set_master_ln(struct link_params *params,
4721                                 struct bnx2x_phy *phy)
4722 {
4723         struct bnx2x *bp = params->bp;
4724         u16 new_master_ln, ser_lane;
4725         ser_lane = ((params->lane_config &
4726                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4727                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4728
4729         /* set the master_ln for AN */
4730         CL22_RD_OVER_CL45(bp, phy,
4731                           MDIO_REG_BANK_XGXS_BLOCK2,
4732                           MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4733                           &new_master_ln);
4734
4735         CL22_WR_OVER_CL45(bp, phy,
4736                           MDIO_REG_BANK_XGXS_BLOCK2 ,
4737                           MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4738                           (new_master_ln | ser_lane));
4739 }
4740
4741 static int bnx2x_reset_unicore(struct link_params *params,
4742                                struct bnx2x_phy *phy,
4743                                u8 set_serdes)
4744 {
4745         struct bnx2x *bp = params->bp;
4746         u16 mii_control;
4747         u16 i;
4748         CL22_RD_OVER_CL45(bp, phy,
4749                           MDIO_REG_BANK_COMBO_IEEE0,
4750                           MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
4751
4752         /* reset the unicore */
4753         CL22_WR_OVER_CL45(bp, phy,
4754                           MDIO_REG_BANK_COMBO_IEEE0,
4755                           MDIO_COMBO_IEEE0_MII_CONTROL,
4756                           (mii_control |
4757                            MDIO_COMBO_IEEO_MII_CONTROL_RESET));
4758         if (set_serdes)
4759                 bnx2x_set_serdes_access(bp, params->port);
4760
4761         /* wait for the reset to self clear */
4762         for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
4763                 udelay(5);
4764
4765                 /* the reset erased the previous bank value */
4766                 CL22_RD_OVER_CL45(bp, phy,
4767                                   MDIO_REG_BANK_COMBO_IEEE0,
4768                                   MDIO_COMBO_IEEE0_MII_CONTROL,
4769                                   &mii_control);
4770
4771                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
4772                         udelay(5);
4773                         return 0;
4774                 }
4775         }
4776
4777         netdev_err(bp->dev,  "Warning: PHY was not initialized,"
4778                               " Port %d\n",
4779                          params->port);
4780         DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
4781         return -EINVAL;
4782
4783 }
4784
4785 static void bnx2x_set_swap_lanes(struct link_params *params,
4786                                  struct bnx2x_phy *phy)
4787 {
4788         struct bnx2x *bp = params->bp;
4789         /*
4790          *  Each two bits represents a lane number:
4791          *  No swap is 0123 => 0x1b no need to enable the swap
4792          */
4793         u16 rx_lane_swap, tx_lane_swap;
4794
4795         rx_lane_swap = ((params->lane_config &
4796                          PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
4797                         PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
4798         tx_lane_swap = ((params->lane_config &
4799                          PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
4800                         PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
4801
4802         if (rx_lane_swap != 0x1b) {
4803                 CL22_WR_OVER_CL45(bp, phy,
4804                                   MDIO_REG_BANK_XGXS_BLOCK2,
4805                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP,
4806                                   (rx_lane_swap |
4807                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
4808                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
4809         } else {
4810                 CL22_WR_OVER_CL45(bp, phy,
4811                                   MDIO_REG_BANK_XGXS_BLOCK2,
4812                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
4813         }
4814
4815         if (tx_lane_swap != 0x1b) {
4816                 CL22_WR_OVER_CL45(bp, phy,
4817                                   MDIO_REG_BANK_XGXS_BLOCK2,
4818                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP,
4819                                   (tx_lane_swap |
4820                                    MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
4821         } else {
4822                 CL22_WR_OVER_CL45(bp, phy,
4823                                   MDIO_REG_BANK_XGXS_BLOCK2,
4824                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
4825         }
4826 }
4827
4828 static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
4829                                          struct link_params *params)
4830 {
4831         struct bnx2x *bp = params->bp;
4832         u16 control2;
4833         CL22_RD_OVER_CL45(bp, phy,
4834                           MDIO_REG_BANK_SERDES_DIGITAL,
4835                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
4836                           &control2);
4837         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4838                 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
4839         else
4840                 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
4841         DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
4842                 phy->speed_cap_mask, control2);
4843         CL22_WR_OVER_CL45(bp, phy,
4844                           MDIO_REG_BANK_SERDES_DIGITAL,
4845                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
4846                           control2);
4847
4848         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
4849              (phy->speed_cap_mask &
4850                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
4851                 DP(NETIF_MSG_LINK, "XGXS\n");
4852
4853                 CL22_WR_OVER_CL45(bp, phy,
4854                                  MDIO_REG_BANK_10G_PARALLEL_DETECT,
4855                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
4856                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
4857
4858                 CL22_RD_OVER_CL45(bp, phy,
4859                                   MDIO_REG_BANK_10G_PARALLEL_DETECT,
4860                                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4861                                   &control2);
4862
4863
4864                 control2 |=
4865                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
4866
4867                 CL22_WR_OVER_CL45(bp, phy,
4868                                   MDIO_REG_BANK_10G_PARALLEL_DETECT,
4869                                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4870                                   control2);
4871
4872                 /* Disable parallel detection of HiG */
4873                 CL22_WR_OVER_CL45(bp, phy,
4874                                   MDIO_REG_BANK_XGXS_BLOCK2,
4875                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
4876                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
4877                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
4878         }
4879 }
4880
4881 static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
4882                               struct link_params *params,
4883                               struct link_vars *vars,
4884                               u8 enable_cl73)
4885 {
4886         struct bnx2x *bp = params->bp;
4887         u16 reg_val;
4888
4889         /* CL37 Autoneg */
4890         CL22_RD_OVER_CL45(bp, phy,
4891                           MDIO_REG_BANK_COMBO_IEEE0,
4892                           MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
4893
4894         /* CL37 Autoneg Enabled */
4895         if (vars->line_speed == SPEED_AUTO_NEG)
4896                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
4897         else /* CL37 Autoneg Disabled */
4898                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4899                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
4900
4901         CL22_WR_OVER_CL45(bp, phy,
4902                           MDIO_REG_BANK_COMBO_IEEE0,
4903                           MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
4904
4905         /* Enable/Disable Autodetection */
4906
4907         CL22_RD_OVER_CL45(bp, phy,
4908                           MDIO_REG_BANK_SERDES_DIGITAL,
4909                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
4910         reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
4911                     MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
4912         reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
4913         if (vars->line_speed == SPEED_AUTO_NEG)
4914                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4915         else
4916                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4917
4918         CL22_WR_OVER_CL45(bp, phy,
4919                           MDIO_REG_BANK_SERDES_DIGITAL,
4920                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
4921
4922         /* Enable TetonII and BAM autoneg */
4923         CL22_RD_OVER_CL45(bp, phy,
4924                           MDIO_REG_BANK_BAM_NEXT_PAGE,
4925                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
4926                           &reg_val);
4927         if (vars->line_speed == SPEED_AUTO_NEG) {
4928                 /* Enable BAM aneg Mode and TetonII aneg Mode */
4929                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4930                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4931         } else {
4932                 /* TetonII and BAM Autoneg Disabled */
4933                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4934                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4935         }
4936         CL22_WR_OVER_CL45(bp, phy,
4937                           MDIO_REG_BANK_BAM_NEXT_PAGE,
4938                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
4939                           reg_val);
4940
4941         if (enable_cl73) {
4942                 /* Enable Cl73 FSM status bits */
4943                 CL22_WR_OVER_CL45(bp, phy,
4944                                   MDIO_REG_BANK_CL73_USERB0,
4945                                   MDIO_CL73_USERB0_CL73_UCTRL,
4946                                   0xe);
4947
4948                 /* Enable BAM Station Manager*/
4949                 CL22_WR_OVER_CL45(bp, phy,
4950                         MDIO_REG_BANK_CL73_USERB0,
4951                         MDIO_CL73_USERB0_CL73_BAM_CTRL1,
4952                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
4953                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
4954                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
4955
4956                 /* Advertise CL73 link speeds */
4957                 CL22_RD_OVER_CL45(bp, phy,
4958                                   MDIO_REG_BANK_CL73_IEEEB1,
4959                                   MDIO_CL73_IEEEB1_AN_ADV2,
4960                                   &reg_val);
4961                 if (phy->speed_cap_mask &
4962                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4963                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
4964                 if (phy->speed_cap_mask &
4965                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4966                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
4967
4968                 CL22_WR_OVER_CL45(bp, phy,
4969                                   MDIO_REG_BANK_CL73_IEEEB1,
4970                                   MDIO_CL73_IEEEB1_AN_ADV2,
4971                                   reg_val);
4972
4973                 /* CL73 Autoneg Enabled */
4974                 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
4975
4976         } else /* CL73 Autoneg Disabled */
4977                 reg_val = 0;
4978
4979         CL22_WR_OVER_CL45(bp, phy,
4980                           MDIO_REG_BANK_CL73_IEEEB0,
4981                           MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
4982 }
4983
4984 /* program SerDes, forced speed */
4985 static void bnx2x_program_serdes(struct bnx2x_phy *phy,
4986                                  struct link_params *params,
4987                                  struct link_vars *vars)
4988 {
4989         struct bnx2x *bp = params->bp;
4990         u16 reg_val;
4991
4992         /* program duplex, disable autoneg and sgmii*/
4993         CL22_RD_OVER_CL45(bp, phy,
4994                           MDIO_REG_BANK_COMBO_IEEE0,
4995                           MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
4996         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
4997                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4998                      MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
4999         if (phy->req_duplex == DUPLEX_FULL)
5000                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
5001         CL22_WR_OVER_CL45(bp, phy,
5002                           MDIO_REG_BANK_COMBO_IEEE0,
5003                           MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
5004
5005         /*
5006          * program speed
5007          *  - needed only if the speed is greater than 1G (2.5G or 10G)
5008          */
5009         CL22_RD_OVER_CL45(bp, phy,
5010                           MDIO_REG_BANK_SERDES_DIGITAL,
5011                           MDIO_SERDES_DIGITAL_MISC1, &reg_val);
5012         /* clearing the speed value before setting the right speed */
5013         DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
5014
5015         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
5016                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
5017
5018         if (!((vars->line_speed == SPEED_1000) ||
5019               (vars->line_speed == SPEED_100) ||
5020               (vars->line_speed == SPEED_10))) {
5021
5022                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
5023                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
5024                 if (vars->line_speed == SPEED_10000)
5025                         reg_val |=
5026                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
5027         }
5028
5029         CL22_WR_OVER_CL45(bp, phy,
5030                           MDIO_REG_BANK_SERDES_DIGITAL,
5031                           MDIO_SERDES_DIGITAL_MISC1, reg_val);
5032
5033 }
5034
5035 static void bnx2x_set_brcm_cl37_advertisement(struct bnx2x_phy *phy,
5036                                               struct link_params *params)
5037 {
5038         struct bnx2x *bp = params->bp;
5039         u16 val = 0;
5040
5041         /* configure the 48 bits for BAM AN */
5042
5043         /* set extended capabilities */
5044         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
5045                 val |= MDIO_OVER_1G_UP1_2_5G;
5046         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
5047                 val |= MDIO_OVER_1G_UP1_10G;
5048         CL22_WR_OVER_CL45(bp, phy,
5049                           MDIO_REG_BANK_OVER_1G,
5050                           MDIO_OVER_1G_UP1, val);
5051
5052         CL22_WR_OVER_CL45(bp, phy,
5053                           MDIO_REG_BANK_OVER_1G,
5054                           MDIO_OVER_1G_UP3, 0x400);
5055 }
5056
5057 static void bnx2x_set_ieee_aneg_advertisement(struct bnx2x_phy *phy,
5058                                               struct link_params *params,
5059                                               u16 ieee_fc)
5060 {
5061         struct bnx2x *bp = params->bp;
5062         u16 val;
5063         /* for AN, we are always publishing full duplex */
5064
5065         CL22_WR_OVER_CL45(bp, phy,
5066                           MDIO_REG_BANK_COMBO_IEEE0,
5067                           MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
5068         CL22_RD_OVER_CL45(bp, phy,
5069                           MDIO_REG_BANK_CL73_IEEEB1,
5070                           MDIO_CL73_IEEEB1_AN_ADV1, &val);
5071         val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
5072         val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
5073         CL22_WR_OVER_CL45(bp, phy,
5074                           MDIO_REG_BANK_CL73_IEEEB1,
5075                           MDIO_CL73_IEEEB1_AN_ADV1, val);
5076 }
5077
5078 static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
5079                                   struct link_params *params,
5080                                   u8 enable_cl73)
5081 {
5082         struct bnx2x *bp = params->bp;
5083         u16 mii_control;
5084
5085         DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
5086         /* Enable and restart BAM/CL37 aneg */
5087
5088         if (enable_cl73) {
5089                 CL22_RD_OVER_CL45(bp, phy,
5090                                   MDIO_REG_BANK_CL73_IEEEB0,
5091                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5092                                   &mii_control);
5093
5094                 CL22_WR_OVER_CL45(bp, phy,
5095                                   MDIO_REG_BANK_CL73_IEEEB0,
5096                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5097                                   (mii_control |
5098                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
5099                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
5100         } else {
5101
5102                 CL22_RD_OVER_CL45(bp, phy,
5103                                   MDIO_REG_BANK_COMBO_IEEE0,
5104                                   MDIO_COMBO_IEEE0_MII_CONTROL,
5105                                   &mii_control);
5106                 DP(NETIF_MSG_LINK,
5107                          "bnx2x_restart_autoneg mii_control before = 0x%x\n",
5108                          mii_control);
5109                 CL22_WR_OVER_CL45(bp, phy,
5110                                   MDIO_REG_BANK_COMBO_IEEE0,
5111                                   MDIO_COMBO_IEEE0_MII_CONTROL,
5112                                   (mii_control |
5113                                    MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
5114                                    MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
5115         }
5116 }
5117
5118 static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
5119                                            struct link_params *params,
5120                                            struct link_vars *vars)
5121 {
5122         struct bnx2x *bp = params->bp;
5123         u16 control1;
5124
5125         /* in SGMII mode, the unicore is always slave */
5126
5127         CL22_RD_OVER_CL45(bp, phy,
5128                           MDIO_REG_BANK_SERDES_DIGITAL,
5129                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
5130                           &control1);
5131         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
5132         /* set sgmii mode (and not fiber) */
5133         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
5134                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
5135                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
5136         CL22_WR_OVER_CL45(bp, phy,
5137                           MDIO_REG_BANK_SERDES_DIGITAL,
5138                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
5139                           control1);
5140
5141         /* if forced speed */
5142         if (!(vars->line_speed == SPEED_AUTO_NEG)) {
5143                 /* set speed, disable autoneg */
5144                 u16 mii_control;
5145
5146                 CL22_RD_OVER_CL45(bp, phy,
5147                                   MDIO_REG_BANK_COMBO_IEEE0,
5148                                   MDIO_COMBO_IEEE0_MII_CONTROL,
5149                                   &mii_control);
5150                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
5151                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
5152                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
5153
5154                 switch (vars->line_speed) {
5155                 case SPEED_100:
5156                         mii_control |=
5157                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
5158                         break;
5159                 case SPEED_1000:
5160                         mii_control |=
5161                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
5162                         break;
5163                 case SPEED_10:
5164                         /* there is nothing to set for 10M */
5165                         break;
5166                 default:
5167                         /* invalid speed for SGMII */
5168                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
5169                                   vars->line_speed);
5170                         break;
5171                 }
5172
5173                 /* setting the full duplex */
5174                 if (phy->req_duplex == DUPLEX_FULL)
5175                         mii_control |=
5176                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
5177                 CL22_WR_OVER_CL45(bp, phy,
5178                                   MDIO_REG_BANK_COMBO_IEEE0,
5179                                   MDIO_COMBO_IEEE0_MII_CONTROL,
5180                                   mii_control);
5181
5182         } else { /* AN mode */
5183                 /* enable and restart AN */
5184                 bnx2x_restart_autoneg(phy, params, 0);
5185         }
5186 }
5187
5188
5189 /*
5190  * link management
5191  */
5192
5193 static int bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
5194                                              struct link_params *params)
5195 {
5196         struct bnx2x *bp = params->bp;
5197         u16 pd_10g, status2_1000x;
5198         if (phy->req_line_speed != SPEED_AUTO_NEG)
5199                 return 0;
5200         CL22_RD_OVER_CL45(bp, phy,
5201                           MDIO_REG_BANK_SERDES_DIGITAL,
5202                           MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
5203                           &status2_1000x);
5204         CL22_RD_OVER_CL45(bp, phy,
5205                           MDIO_REG_BANK_SERDES_DIGITAL,
5206                           MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
5207                           &status2_1000x);
5208         if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
5209                 DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
5210                          params->port);
5211                 return 1;
5212         }
5213
5214         CL22_RD_OVER_CL45(bp, phy,
5215                           MDIO_REG_BANK_10G_PARALLEL_DETECT,
5216                           MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
5217                           &pd_10g);
5218
5219         if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
5220                 DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
5221                          params->port);
5222                 return 1;
5223         }
5224         return 0;
5225 }
5226
5227 static void bnx2x_update_adv_fc(struct bnx2x_phy *phy,
5228                                 struct link_params *params,
5229                                 struct link_vars *vars,
5230                                 u32 gp_status)
5231 {
5232         u16 ld_pause;   /* local driver */
5233         u16 lp_pause;   /* link partner */
5234         u16 pause_result;
5235         struct bnx2x *bp = params->bp;
5236         if ((gp_status &
5237              (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
5238               MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
5239             (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
5240              MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
5241
5242                 CL22_RD_OVER_CL45(bp, phy,
5243                                   MDIO_REG_BANK_CL73_IEEEB1,
5244                                   MDIO_CL73_IEEEB1_AN_ADV1,
5245                                   &ld_pause);
5246                 CL22_RD_OVER_CL45(bp, phy,
5247                                   MDIO_REG_BANK_CL73_IEEEB1,
5248                                   MDIO_CL73_IEEEB1_AN_LP_ADV1,
5249                                   &lp_pause);
5250                 pause_result = (ld_pause &
5251                                 MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK) >> 8;
5252                 pause_result |= (lp_pause &
5253                                  MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK) >> 10;
5254                 DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n", pause_result);
5255         } else {
5256                 CL22_RD_OVER_CL45(bp, phy,
5257                                   MDIO_REG_BANK_COMBO_IEEE0,
5258                                   MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
5259                                   &ld_pause);
5260                 CL22_RD_OVER_CL45(bp, phy,
5261                         MDIO_REG_BANK_COMBO_IEEE0,
5262                         MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
5263                         &lp_pause);
5264                 pause_result = (ld_pause &
5265                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
5266                 pause_result |= (lp_pause &
5267                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
5268                 DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n", pause_result);
5269         }
5270         bnx2x_pause_resolve(vars, pause_result);
5271
5272 }
5273
5274 static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
5275                                     struct link_params *params,
5276                                     struct link_vars *vars,
5277                                     u32 gp_status)
5278 {
5279         struct bnx2x *bp = params->bp;
5280         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5281
5282         /* resolve from gp_status in case of AN complete and not sgmii */
5283         if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) {
5284                 /* Update the advertised flow-controled of LD/LP in AN */
5285                 if (phy->req_line_speed == SPEED_AUTO_NEG)
5286                         bnx2x_update_adv_fc(phy, params, vars, gp_status);
5287                 /* But set the flow-control result as the requested one */
5288                 vars->flow_ctrl = phy->req_flow_ctrl;
5289         } else if (phy->req_line_speed != SPEED_AUTO_NEG)
5290                 vars->flow_ctrl = params->req_fc_auto_adv;
5291         else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
5292                  (!(vars->phy_flags & PHY_SGMII_FLAG))) {
5293                 if (bnx2x_direct_parallel_detect_used(phy, params)) {
5294                         vars->flow_ctrl = params->req_fc_auto_adv;
5295                         return;
5296                 }
5297                 bnx2x_update_adv_fc(phy, params, vars, gp_status);
5298         }
5299         DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
5300 }
5301
5302 static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
5303                                          struct link_params *params)
5304 {
5305         struct bnx2x *bp = params->bp;
5306         u16 rx_status, ustat_val, cl37_fsm_received;
5307         DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
5308         /* Step 1: Make sure signal is detected */
5309         CL22_RD_OVER_CL45(bp, phy,
5310                           MDIO_REG_BANK_RX0,
5311                           MDIO_RX0_RX_STATUS,
5312                           &rx_status);
5313         if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
5314             (MDIO_RX0_RX_STATUS_SIGDET)) {
5315                 DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
5316                              "rx_status(0x80b0) = 0x%x\n", rx_status);
5317                 CL22_WR_OVER_CL45(bp, phy,
5318                                   MDIO_REG_BANK_CL73_IEEEB0,
5319                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5320                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
5321                 return;
5322         }
5323         /* Step 2: Check CL73 state machine */
5324         CL22_RD_OVER_CL45(bp, phy,
5325                           MDIO_REG_BANK_CL73_USERB0,
5326                           MDIO_CL73_USERB0_CL73_USTAT1,
5327                           &ustat_val);
5328         if ((ustat_val &
5329              (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5330               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
5331             (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5332               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
5333                 DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
5334                              "ustat_val(0x8371) = 0x%x\n", ustat_val);
5335                 return;
5336         }
5337         /*
5338          * Step 3: Check CL37 Message Pages received to indicate LP
5339          * supports only CL37
5340          */
5341         CL22_RD_OVER_CL45(bp, phy,
5342                           MDIO_REG_BANK_REMOTE_PHY,
5343                           MDIO_REMOTE_PHY_MISC_RX_STATUS,
5344                           &cl37_fsm_received);
5345         if ((cl37_fsm_received &
5346              (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5347              MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
5348             (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5349               MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
5350                 DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
5351                              "misc_rx_status(0x8330) = 0x%x\n",
5352                          cl37_fsm_received);
5353                 return;
5354         }
5355         /*
5356          * The combined cl37/cl73 fsm state information indicating that
5357          * we are connected to a device which does not support cl73, but
5358          * does support cl37 BAM. In this case we disable cl73 and
5359          * restart cl37 auto-neg
5360          */
5361
5362         /* Disable CL73 */
5363         CL22_WR_OVER_CL45(bp, phy,
5364                           MDIO_REG_BANK_CL73_IEEEB0,
5365                           MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5366                           0);
5367         /* Restart CL37 autoneg */
5368         bnx2x_restart_autoneg(phy, params, 0);
5369         DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
5370 }
5371
5372 static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
5373                                   struct link_params *params,
5374                                   struct link_vars *vars,
5375                                   u32 gp_status)
5376 {
5377         if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
5378                 vars->link_status |=
5379                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5380
5381         if (bnx2x_direct_parallel_detect_used(phy, params))
5382                 vars->link_status |=
5383                         LINK_STATUS_PARALLEL_DETECTION_USED;
5384 }
5385 static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,
5386                                      struct link_params *params,
5387                                       struct link_vars *vars,
5388                                       u16 is_link_up,
5389                                       u16 speed_mask,
5390                                       u16 is_duplex)
5391 {
5392         struct bnx2x *bp = params->bp;
5393         if (phy->req_line_speed == SPEED_AUTO_NEG)
5394                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
5395         if (is_link_up) {
5396                 DP(NETIF_MSG_LINK, "phy link up\n");
5397
5398                 vars->phy_link_up = 1;
5399                 vars->link_status |= LINK_STATUS_LINK_UP;
5400
5401                 switch (speed_mask) {
5402                 case GP_STATUS_10M:
5403                         vars->line_speed = SPEED_10;
5404                         if (vars->duplex == DUPLEX_FULL)
5405                                 vars->link_status |= LINK_10TFD;
5406                         else
5407                                 vars->link_status |= LINK_10THD;
5408                         break;
5409
5410                 case GP_STATUS_100M:
5411                         vars->line_speed = SPEED_100;
5412                         if (vars->duplex == DUPLEX_FULL)
5413                                 vars->link_status |= LINK_100TXFD;
5414                         else
5415                                 vars->link_status |= LINK_100TXHD;
5416                         break;
5417
5418                 case GP_STATUS_1G:
5419                 case GP_STATUS_1G_KX:
5420                         vars->line_speed = SPEED_1000;
5421                         if (vars->duplex == DUPLEX_FULL)
5422                                 vars->link_status |= LINK_1000TFD;
5423                         else
5424                                 vars->link_status |= LINK_1000THD;
5425                         break;
5426
5427                 case GP_STATUS_2_5G:
5428                         vars->line_speed = SPEED_2500;
5429                         if (vars->duplex == DUPLEX_FULL)
5430                                 vars->link_status |= LINK_2500TFD;
5431                         else
5432                                 vars->link_status |= LINK_2500THD;
5433                         break;
5434
5435                 case GP_STATUS_5G:
5436                 case GP_STATUS_6G:
5437                         DP(NETIF_MSG_LINK,
5438                                  "link speed unsupported  gp_status 0x%x\n",
5439                                   speed_mask);
5440                         return -EINVAL;
5441
5442                 case GP_STATUS_10G_KX4:
5443                 case GP_STATUS_10G_HIG:
5444                 case GP_STATUS_10G_CX4:
5445                 case GP_STATUS_10G_KR:
5446                 case GP_STATUS_10G_SFI:
5447                 case GP_STATUS_10G_XFI:
5448                         vars->line_speed = SPEED_10000;
5449                         vars->link_status |= LINK_10GTFD;
5450                         break;
5451                 case GP_STATUS_20G_DXGXS:
5452                         vars->line_speed = SPEED_20000;
5453                         vars->link_status |= LINK_20GTFD;
5454                         break;
5455                 default:
5456                         DP(NETIF_MSG_LINK,
5457                                   "link speed unsupported gp_status 0x%x\n",
5458                                   speed_mask);
5459                         return -EINVAL;
5460                 }
5461         } else { /* link_down */
5462                 DP(NETIF_MSG_LINK, "phy link down\n");
5463
5464                 vars->phy_link_up = 0;
5465
5466                 vars->duplex = DUPLEX_FULL;
5467                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5468                 vars->mac_type = MAC_TYPE_NONE;
5469         }
5470         DP(NETIF_MSG_LINK, " phy_link_up %x line_speed %d\n",
5471                     vars->phy_link_up, vars->line_speed);
5472         return 0;
5473 }
5474
5475 static int bnx2x_link_settings_status(struct bnx2x_phy *phy,
5476                                       struct link_params *params,
5477                                       struct link_vars *vars)
5478 {
5479         struct bnx2x *bp = params->bp;
5480
5481         u16 gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask;
5482         int rc = 0;
5483
5484         /* Read gp_status */
5485         CL22_RD_OVER_CL45(bp, phy,
5486                           MDIO_REG_BANK_GP_STATUS,
5487                           MDIO_GP_STATUS_TOP_AN_STATUS1,
5488                           &gp_status);
5489         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
5490                 duplex = DUPLEX_FULL;
5491         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)
5492                 link_up = 1;
5493         speed_mask = gp_status & GP_STATUS_SPEED_MASK;
5494         DP(NETIF_MSG_LINK, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x\n",
5495                        gp_status, link_up, speed_mask);
5496         rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
5497                                          duplex);
5498         if (rc == -EINVAL)
5499                 return rc;
5500
5501         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
5502                 if (SINGLE_MEDIA_DIRECT(params)) {
5503                         bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
5504                         if (phy->req_line_speed == SPEED_AUTO_NEG)
5505                                 bnx2x_xgxs_an_resolve(phy, params, vars,
5506                                                       gp_status);
5507                 }
5508         } else { /* link_down */
5509                 if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
5510                     SINGLE_MEDIA_DIRECT(params)) {
5511                         /* Check signal is detected */
5512                         bnx2x_check_fallback_to_cl37(phy, params);
5513                 }
5514         }
5515
5516         /* Read LP advertised speeds*/
5517         if (SINGLE_MEDIA_DIRECT(params) &&
5518             (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)) {
5519                 u16 val;
5520
5521                 CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_IEEEB1,
5522                                   MDIO_CL73_IEEEB1_AN_LP_ADV2, &val);
5523
5524                 if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
5525                         vars->link_status |=
5526                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
5527                 if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
5528                            MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
5529                         vars->link_status |=
5530                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
5531
5532                 CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_OVER_1G,
5533                                   MDIO_OVER_1G_LP_UP1, &val);
5534
5535                 if (val & MDIO_OVER_1G_UP1_2_5G)
5536                         vars->link_status |=
5537                                 LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
5538                 if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
5539                         vars->link_status |=
5540                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
5541         }
5542
5543         DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
5544                    vars->duplex, vars->flow_ctrl, vars->link_status);
5545         return rc;
5546 }
5547
5548 static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy,
5549                                      struct link_params *params,
5550                                      struct link_vars *vars)
5551 {
5552         struct bnx2x *bp = params->bp;
5553         u8 lane;
5554         u16 gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL;
5555         int rc = 0;
5556         lane = bnx2x_get_warpcore_lane(phy, params);
5557         /* Read gp_status */
5558         if (phy->req_line_speed > SPEED_10000) {
5559                 u16 temp_link_up;
5560                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5561                                 1, &temp_link_up);
5562                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5563                                 1, &link_up);
5564                 DP(NETIF_MSG_LINK, "PCS RX link status = 0x%x-->0x%x\n",
5565                                temp_link_up, link_up);
5566                 link_up &= (1<<2);
5567                 if (link_up)
5568                         bnx2x_ext_phy_resolve_fc(phy, params, vars);
5569         } else {
5570                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5571                                 MDIO_WC_REG_GP2_STATUS_GP_2_1, &gp_status1);
5572                 DP(NETIF_MSG_LINK, "0x81d1 = 0x%x\n", gp_status1);
5573                 /* Check for either KR or generic link up. */
5574                 gp_status1 = ((gp_status1 >> 8) & 0xf) |
5575                         ((gp_status1 >> 12) & 0xf);
5576                 link_up = gp_status1 & (1 << lane);
5577                 if (link_up && SINGLE_MEDIA_DIRECT(params)) {
5578                         u16 pd, gp_status4;
5579                         if (phy->req_line_speed == SPEED_AUTO_NEG) {
5580                                 /* Check Autoneg complete */
5581                                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5582                                                 MDIO_WC_REG_GP2_STATUS_GP_2_4,
5583                                                 &gp_status4);
5584                                 if (gp_status4 & ((1<<12)<<lane))
5585                                         vars->link_status |=
5586                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5587
5588                                 /* Check parallel detect used */
5589                                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5590                                                 MDIO_WC_REG_PAR_DET_10G_STATUS,
5591                                                 &pd);
5592                                 if (pd & (1<<15))
5593                                         vars->link_status |=
5594                                         LINK_STATUS_PARALLEL_DETECTION_USED;
5595                         }
5596                         bnx2x_ext_phy_resolve_fc(phy, params, vars);
5597                 }
5598         }
5599
5600         if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) &&
5601             SINGLE_MEDIA_DIRECT(params)) {
5602                 u16 val;
5603
5604                 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
5605                                 MDIO_AN_REG_LP_AUTO_NEG2, &val);
5606
5607                 if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
5608                         vars->link_status |=
5609                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
5610                 if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
5611                            MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
5612                         vars->link_status |=
5613                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
5614
5615                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5616                                 MDIO_WC_REG_DIGITAL3_LP_UP1, &val);
5617
5618                 if (val & MDIO_OVER_1G_UP1_2_5G)
5619                         vars->link_status |=
5620                                 LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
5621                 if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
5622                         vars->link_status |=
5623                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
5624
5625         }
5626
5627
5628         if (lane < 2) {
5629                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5630                                 MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed);
5631         } else {
5632                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5633                                 MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed);
5634         }
5635         DP(NETIF_MSG_LINK, "lane %d gp_speed 0x%x\n", lane, gp_speed);
5636
5637         if ((lane & 1) == 0)
5638                 gp_speed <<= 8;
5639         gp_speed &= 0x3f00;
5640
5641
5642         rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed,
5643                                          duplex);
5644
5645         DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
5646                    vars->duplex, vars->flow_ctrl, vars->link_status);
5647         return rc;
5648 }
5649 static void bnx2x_set_gmii_tx_driver(struct link_params *params)
5650 {
5651         struct bnx2x *bp = params->bp;
5652         struct bnx2x_phy *phy = &params->phy[INT_PHY];
5653         u16 lp_up2;
5654         u16 tx_driver;
5655         u16 bank;
5656
5657         /* read precomp */
5658         CL22_RD_OVER_CL45(bp, phy,
5659                           MDIO_REG_BANK_OVER_1G,
5660                           MDIO_OVER_1G_LP_UP2, &lp_up2);
5661
5662         /* bits [10:7] at lp_up2, positioned at [15:12] */
5663         lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
5664                    MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
5665                   MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
5666
5667         if (lp_up2 == 0)
5668                 return;
5669
5670         for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
5671               bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
5672                 CL22_RD_OVER_CL45(bp, phy,
5673                                   bank,
5674                                   MDIO_TX0_TX_DRIVER, &tx_driver);
5675
5676                 /* replace tx_driver bits [15:12] */
5677                 if (lp_up2 !=
5678                     (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
5679                         tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
5680                         tx_driver |= lp_up2;
5681                         CL22_WR_OVER_CL45(bp, phy,
5682                                           bank,
5683                                           MDIO_TX0_TX_DRIVER, tx_driver);
5684                 }
5685         }
5686 }
5687
5688 static int bnx2x_emac_program(struct link_params *params,
5689                               struct link_vars *vars)
5690 {
5691         struct bnx2x *bp = params->bp;
5692         u8 port = params->port;
5693         u16 mode = 0;
5694
5695         DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
5696         bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
5697                        EMAC_REG_EMAC_MODE,
5698                        (EMAC_MODE_25G_MODE |
5699                         EMAC_MODE_PORT_MII_10M |
5700                         EMAC_MODE_HALF_DUPLEX));
5701         switch (vars->line_speed) {
5702         case SPEED_10:
5703                 mode |= EMAC_MODE_PORT_MII_10M;
5704                 break;
5705
5706         case SPEED_100:
5707                 mode |= EMAC_MODE_PORT_MII;
5708                 break;
5709
5710         case SPEED_1000:
5711                 mode |= EMAC_MODE_PORT_GMII;
5712                 break;
5713
5714         case SPEED_2500:
5715                 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
5716                 break;
5717
5718         default:
5719                 /* 10G not valid for EMAC */
5720                 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
5721                            vars->line_speed);
5722                 return -EINVAL;
5723         }
5724
5725         if (vars->duplex == DUPLEX_HALF)
5726                 mode |= EMAC_MODE_HALF_DUPLEX;
5727         bnx2x_bits_en(bp,
5728                       GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
5729                       mode);
5730
5731         bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
5732         return 0;
5733 }
5734
5735 static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
5736                                   struct link_params *params)
5737 {
5738
5739         u16 bank, i = 0;
5740         struct bnx2x *bp = params->bp;
5741
5742         for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
5743               bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
5744                         CL22_WR_OVER_CL45(bp, phy,
5745                                           bank,
5746                                           MDIO_RX0_RX_EQ_BOOST,
5747                                           phy->rx_preemphasis[i]);
5748         }
5749
5750         for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
5751                       bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
5752                         CL22_WR_OVER_CL45(bp, phy,
5753                                           bank,
5754                                           MDIO_TX0_TX_DRIVER,
5755                                           phy->tx_preemphasis[i]);
5756         }
5757 }
5758
5759 static void bnx2x_xgxs_config_init(struct bnx2x_phy *phy,
5760                                    struct link_params *params,
5761                                    struct link_vars *vars)
5762 {
5763         struct bnx2x *bp = params->bp;
5764         u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
5765                           (params->loopback_mode == LOOPBACK_XGXS));
5766         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
5767                 if (SINGLE_MEDIA_DIRECT(params) &&
5768                     (params->feature_config_flags &
5769                      FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
5770                         bnx2x_set_preemphasis(phy, params);
5771
5772                 /* forced speed requested? */
5773                 if (vars->line_speed != SPEED_AUTO_NEG ||
5774                     (SINGLE_MEDIA_DIRECT(params) &&
5775                      params->loopback_mode == LOOPBACK_EXT)) {
5776                         DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
5777
5778                         /* disable autoneg */
5779                         bnx2x_set_autoneg(phy, params, vars, 0);
5780
5781                         /* program speed and duplex */
5782                         bnx2x_program_serdes(phy, params, vars);
5783
5784                 } else { /* AN_mode */
5785                         DP(NETIF_MSG_LINK, "not SGMII, AN\n");
5786
5787                         /* AN enabled */
5788                         bnx2x_set_brcm_cl37_advertisement(phy, params);
5789
5790                         /* program duplex & pause advertisement (for aneg) */
5791                         bnx2x_set_ieee_aneg_advertisement(phy, params,
5792                                                           vars->ieee_fc);
5793
5794                         /* enable autoneg */
5795                         bnx2x_set_autoneg(phy, params, vars, enable_cl73);
5796
5797                         /* enable and restart AN */
5798                         bnx2x_restart_autoneg(phy, params, enable_cl73);
5799                 }
5800
5801         } else { /* SGMII mode */
5802                 DP(NETIF_MSG_LINK, "SGMII\n");
5803
5804                 bnx2x_initialize_sgmii_process(phy, params, vars);
5805         }
5806 }
5807
5808 static int bnx2x_prepare_xgxs(struct bnx2x_phy *phy,
5809                           struct link_params *params,
5810                           struct link_vars *vars)
5811 {
5812         int rc;
5813         vars->phy_flags |= PHY_XGXS_FLAG;
5814         if ((phy->req_line_speed &&
5815              ((phy->req_line_speed == SPEED_100) ||
5816               (phy->req_line_speed == SPEED_10))) ||
5817             (!phy->req_line_speed &&
5818              (phy->speed_cap_mask >=
5819               PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
5820              (phy->speed_cap_mask <
5821               PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
5822             (phy->type == PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD))
5823                 vars->phy_flags |= PHY_SGMII_FLAG;
5824         else
5825                 vars->phy_flags &= ~PHY_SGMII_FLAG;
5826
5827         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
5828         bnx2x_set_aer_mmd(params, phy);
5829         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
5830                 bnx2x_set_master_ln(params, phy);
5831
5832         rc = bnx2x_reset_unicore(params, phy, 0);
5833         /* reset the SerDes and wait for reset bit return low */
5834         if (rc != 0)
5835                 return rc;
5836
5837         bnx2x_set_aer_mmd(params, phy);
5838         /* setting the masterLn_def again after the reset */
5839         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
5840                 bnx2x_set_master_ln(params, phy);
5841                 bnx2x_set_swap_lanes(params, phy);
5842         }
5843
5844         return rc;
5845 }
5846
5847 static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
5848                                      struct bnx2x_phy *phy,
5849                                      struct link_params *params)
5850 {
5851         u16 cnt, ctrl;
5852         /* Wait for soft reset to get cleared up to 1 sec */
5853         for (cnt = 0; cnt < 1000; cnt++) {
5854                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
5855                         bnx2x_cl22_read(bp, phy,
5856                                 MDIO_PMA_REG_CTRL, &ctrl);
5857                 else
5858                         bnx2x_cl45_read(bp, phy,
5859                                 MDIO_PMA_DEVAD,
5860                                 MDIO_PMA_REG_CTRL, &ctrl);
5861                 if (!(ctrl & (1<<15)))
5862                         break;
5863                 msleep(1);
5864         }
5865
5866         if (cnt == 1000)
5867                 netdev_err(bp->dev,  "Warning: PHY was not initialized,"
5868                                       " Port %d\n",
5869                          params->port);
5870         DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
5871         return cnt;
5872 }
5873
5874 static void bnx2x_link_int_enable(struct link_params *params)
5875 {
5876         u8 port = params->port;
5877         u32 mask;
5878         struct bnx2x *bp = params->bp;
5879
5880         /* Setting the status to report on link up for either XGXS or SerDes */
5881         if (CHIP_IS_E3(bp)) {
5882                 mask = NIG_MASK_XGXS0_LINK_STATUS;
5883                 if (!(SINGLE_MEDIA_DIRECT(params)))
5884                         mask |= NIG_MASK_MI_INT;
5885         } else if (params->switch_cfg == SWITCH_CFG_10G) {
5886                 mask = (NIG_MASK_XGXS0_LINK10G |
5887                         NIG_MASK_XGXS0_LINK_STATUS);
5888                 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
5889                 if (!(SINGLE_MEDIA_DIRECT(params)) &&
5890                         params->phy[INT_PHY].type !=
5891                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
5892                         mask |= NIG_MASK_MI_INT;
5893                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
5894                 }
5895
5896         } else { /* SerDes */
5897                 mask = NIG_MASK_SERDES0_LINK_STATUS;
5898                 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
5899                 if (!(SINGLE_MEDIA_DIRECT(params)) &&
5900                         params->phy[INT_PHY].type !=
5901                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
5902                         mask |= NIG_MASK_MI_INT;
5903                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
5904                 }
5905         }
5906         bnx2x_bits_en(bp,
5907                       NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5908                       mask);
5909
5910         DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
5911                  (params->switch_cfg == SWITCH_CFG_10G),
5912                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5913         DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
5914                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5915                  REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5916                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
5917         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5918            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5919            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5920 }
5921
5922 static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port,
5923                                      u8 exp_mi_int)
5924 {
5925         u32 latch_status = 0;
5926
5927         /*
5928          * Disable the MI INT ( external phy int ) by writing 1 to the
5929          * status register. Link down indication is high-active-signal,
5930          * so in this case we need to write the status to clear the XOR
5931          */
5932         /* Read Latched signals */
5933         latch_status = REG_RD(bp,
5934                                     NIG_REG_LATCH_STATUS_0 + port*8);
5935         DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status);
5936         /* Handle only those with latched-signal=up.*/
5937         if (exp_mi_int)
5938                 bnx2x_bits_en(bp,
5939                               NIG_REG_STATUS_INTERRUPT_PORT0
5940                               + port*4,
5941                               NIG_STATUS_EMAC0_MI_INT);
5942         else
5943                 bnx2x_bits_dis(bp,
5944                                NIG_REG_STATUS_INTERRUPT_PORT0
5945                                + port*4,
5946                                NIG_STATUS_EMAC0_MI_INT);
5947
5948         if (latch_status & 1) {
5949
5950                 /* For all latched-signal=up : Re-Arm Latch signals */
5951                 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
5952                        (latch_status & 0xfffe) | (latch_status & 1));
5953         }
5954         /* For all latched-signal=up,Write original_signal to status */
5955 }
5956
5957 static void bnx2x_link_int_ack(struct link_params *params,
5958                                struct link_vars *vars, u8 is_10g_plus)
5959 {
5960         struct bnx2x *bp = params->bp;
5961         u8 port = params->port;
5962         u32 mask;
5963         /*
5964          * First reset all status we assume only one line will be
5965          * change at a time
5966          */
5967         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5968                        (NIG_STATUS_XGXS0_LINK10G |
5969                         NIG_STATUS_XGXS0_LINK_STATUS |
5970                         NIG_STATUS_SERDES0_LINK_STATUS));
5971         if (vars->phy_link_up) {
5972                 if (USES_WARPCORE(bp))
5973                         mask = NIG_STATUS_XGXS0_LINK_STATUS;
5974                 else {
5975                         if (is_10g_plus)
5976                                 mask = NIG_STATUS_XGXS0_LINK10G;
5977                         else if (params->switch_cfg == SWITCH_CFG_10G) {
5978                                 /*
5979                                  * Disable the link interrupt by writing 1 to
5980                                  * the relevant lane in the status register
5981                                  */
5982                                 u32 ser_lane =
5983                                         ((params->lane_config &
5984                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
5985                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
5986                                 mask = ((1 << ser_lane) <<
5987                                        NIG_STATUS_XGXS0_LINK_STATUS_SIZE);
5988                         } else
5989                                 mask = NIG_STATUS_SERDES0_LINK_STATUS;
5990                 }
5991                 DP(NETIF_MSG_LINK, "Ack link up interrupt with mask 0x%x\n",
5992                                mask);
5993                 bnx2x_bits_en(bp,
5994                               NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5995                               mask);
5996         }
5997 }
5998
5999 static int bnx2x_format_ver(u32 num, u8 *str, u16 *len)
6000 {
6001         u8 *str_ptr = str;
6002         u32 mask = 0xf0000000;
6003         u8 shift = 8*4;
6004         u8 digit;
6005         u8 remove_leading_zeros = 1;
6006         if (*len < 10) {
6007                 /* Need more than 10chars for this format */
6008                 *str_ptr = '\0';
6009                 (*len)--;
6010                 return -EINVAL;
6011         }
6012         while (shift > 0) {
6013
6014                 shift -= 4;
6015                 digit = ((num & mask) >> shift);
6016                 if (digit == 0 && remove_leading_zeros) {
6017                         mask = mask >> 4;
6018                         continue;
6019                 } else if (digit < 0xa)
6020                         *str_ptr = digit + '0';
6021                 else
6022                         *str_ptr = digit - 0xa + 'a';
6023                 remove_leading_zeros = 0;
6024                 str_ptr++;
6025                 (*len)--;
6026                 mask = mask >> 4;
6027                 if (shift == 4*4) {
6028                         *str_ptr = '.';
6029                         str_ptr++;
6030                         (*len)--;
6031                         remove_leading_zeros = 1;
6032                 }
6033         }
6034         return 0;
6035 }
6036
6037
6038 static int bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
6039 {
6040         str[0] = '\0';
6041         (*len)--;
6042         return 0;
6043 }
6044
6045 int bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 *version,
6046                                  u16 len)
6047 {
6048         struct bnx2x *bp;
6049         u32 spirom_ver = 0;
6050         int status = 0;
6051         u8 *ver_p = version;
6052         u16 remain_len = len;
6053         if (version == NULL || params == NULL)
6054                 return -EINVAL;
6055         bp = params->bp;
6056
6057         /* Extract first external phy*/
6058         version[0] = '\0';
6059         spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
6060
6061         if (params->phy[EXT_PHY1].format_fw_ver) {
6062                 status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
6063                                                               ver_p,
6064                                                               &remain_len);
6065                 ver_p += (len - remain_len);
6066         }
6067         if ((params->num_phys == MAX_PHYS) &&
6068             (params->phy[EXT_PHY2].ver_addr != 0)) {
6069                 spirom_ver = REG_RD(bp, params->phy[EXT_PHY2].ver_addr);
6070                 if (params->phy[EXT_PHY2].format_fw_ver) {
6071                         *ver_p = '/';
6072                         ver_p++;
6073                         remain_len--;
6074                         status |= params->phy[EXT_PHY2].format_fw_ver(
6075                                 spirom_ver,
6076                                 ver_p,
6077                                 &remain_len);
6078                         ver_p = version + (len - remain_len);
6079                 }
6080         }
6081         *ver_p = '\0';
6082         return status;
6083 }
6084
6085 static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
6086                                     struct link_params *params)
6087 {
6088         u8 port = params->port;
6089         struct bnx2x *bp = params->bp;
6090
6091         if (phy->req_line_speed != SPEED_1000) {
6092                 u32 md_devad = 0;
6093
6094                 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
6095
6096                 if (!CHIP_IS_E3(bp)) {
6097                         /* change the uni_phy_addr in the nig */
6098                         md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
6099                                                port*0x18));
6100
6101                         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
6102                                0x5);
6103                 }
6104
6105                 bnx2x_cl45_write(bp, phy,
6106                                  5,
6107                                  (MDIO_REG_BANK_AER_BLOCK +
6108                                   (MDIO_AER_BLOCK_AER_REG & 0xf)),
6109                                  0x2800);
6110
6111                 bnx2x_cl45_write(bp, phy,
6112                                  5,
6113                                  (MDIO_REG_BANK_CL73_IEEEB0 +
6114                                   (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
6115                                  0x6041);
6116                 msleep(200);
6117                 /* set aer mmd back */
6118                 bnx2x_set_aer_mmd(params, phy);
6119
6120                 if (!CHIP_IS_E3(bp)) {
6121                         /* and md_devad */
6122                         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
6123                                md_devad);
6124                 }
6125         } else {
6126                 u16 mii_ctrl;
6127                 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
6128                 bnx2x_cl45_read(bp, phy, 5,
6129                                 (MDIO_REG_BANK_COMBO_IEEE0 +
6130                                 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
6131                                 &mii_ctrl);
6132                 bnx2x_cl45_write(bp, phy, 5,
6133                                  (MDIO_REG_BANK_COMBO_IEEE0 +
6134                                  (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
6135                                  mii_ctrl |
6136                                  MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
6137         }
6138 }
6139
6140 int bnx2x_set_led(struct link_params *params,
6141                   struct link_vars *vars, u8 mode, u32 speed)
6142 {
6143         u8 port = params->port;
6144         u16 hw_led_mode = params->hw_led_mode;
6145         int rc = 0;
6146         u8 phy_idx;
6147         u32 tmp;
6148         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
6149         struct bnx2x *bp = params->bp;
6150         DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
6151         DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
6152                  speed, hw_led_mode);
6153         /* In case */
6154         for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) {
6155                 if (params->phy[phy_idx].set_link_led) {
6156                         params->phy[phy_idx].set_link_led(
6157                                 &params->phy[phy_idx], params, mode);
6158                 }
6159         }
6160
6161         switch (mode) {
6162         case LED_MODE_FRONT_PANEL_OFF:
6163         case LED_MODE_OFF:
6164                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
6165                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
6166                        SHARED_HW_CFG_LED_MAC1);
6167
6168                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
6169                 if (params->phy[EXT_PHY1].type ==
6170                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
6171                         EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp & 0xfff1);
6172                 else {
6173                         EMAC_WR(bp, EMAC_REG_EMAC_LED,
6174                                 (tmp | EMAC_LED_OVERRIDE));
6175                 }
6176                 break;
6177
6178         case LED_MODE_OPER:
6179                 /*
6180                  * For all other phys, OPER mode is same as ON, so in case
6181                  * link is down, do nothing
6182                  */
6183                 if (!vars->link_up)
6184                         break;
6185         case LED_MODE_ON:
6186                 if (((params->phy[EXT_PHY1].type ==
6187                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) ||
6188                          (params->phy[EXT_PHY1].type ==
6189                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722)) &&
6190                     CHIP_IS_E2(bp) && params->num_phys == 2) {
6191                         /*
6192                          * This is a work-around for E2+8727 Configurations
6193                          */
6194                         if (mode == LED_MODE_ON ||
6195                                 speed == SPEED_10000){
6196                                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
6197                                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
6198
6199                                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
6200                                 EMAC_WR(bp, EMAC_REG_EMAC_LED,
6201                                         (tmp | EMAC_LED_OVERRIDE));
6202                                 /*
6203                                  * return here without enabling traffic
6204                                  * LED blink and setting rate in ON mode.
6205                                  * In oper mode, enabling LED blink
6206                                  * and setting rate is needed.
6207                                  */
6208                                 if (mode == LED_MODE_ON)
6209                                         return rc;
6210                         }
6211                 } else if (SINGLE_MEDIA_DIRECT(params)) {
6212                         /*
6213                          * This is a work-around for HW issue found when link
6214                          * is up in CL73
6215                          */
6216                         if ((!CHIP_IS_E3(bp)) ||
6217                             (CHIP_IS_E3(bp) &&
6218                              mode == LED_MODE_ON))
6219                                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
6220
6221                         if (CHIP_IS_E1x(bp) ||
6222                             CHIP_IS_E2(bp) ||
6223                             (mode == LED_MODE_ON))
6224                                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
6225                         else
6226                                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
6227                                        hw_led_mode);
6228                 } else if ((params->phy[EXT_PHY1].type ==
6229                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) &&
6230                            (mode != LED_MODE_OPER)) {
6231                         REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
6232                         tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
6233                         EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp | 0x3);
6234                 } else
6235                         REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
6236                                hw_led_mode);
6237
6238                 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
6239                 /* Set blinking rate to ~15.9Hz */
6240                 if (CHIP_IS_E3(bp))
6241                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
6242                                LED_BLINK_RATE_VAL_E3);
6243                 else
6244                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
6245                                LED_BLINK_RATE_VAL_E1X_E2);
6246                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
6247                        port*4, 1);
6248                 if ((params->phy[EXT_PHY1].type !=
6249                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) &&
6250                     (mode != LED_MODE_OPER)) {
6251                         tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
6252                         EMAC_WR(bp, EMAC_REG_EMAC_LED,
6253                                 (tmp & (~EMAC_LED_OVERRIDE)));
6254                 }
6255
6256                 if (CHIP_IS_E1(bp) &&
6257                     ((speed == SPEED_2500) ||
6258                      (speed == SPEED_1000) ||
6259                      (speed == SPEED_100) ||
6260                      (speed == SPEED_10))) {
6261                         /*
6262                          * On Everest 1 Ax chip versions for speeds less than
6263                          * 10G LED scheme is different
6264                          */
6265                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
6266                                + port*4, 1);
6267                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
6268                                port*4, 0);
6269                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
6270                                port*4, 1);
6271                 }
6272                 break;
6273
6274         default:
6275                 rc = -EINVAL;
6276                 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
6277                          mode);
6278                 break;
6279         }
6280         return rc;
6281
6282 }
6283
6284 /*
6285  * This function comes to reflect the actual link state read DIRECTLY from the
6286  * HW
6287  */
6288 int bnx2x_test_link(struct link_params *params, struct link_vars *vars,
6289                     u8 is_serdes)
6290 {
6291         struct bnx2x *bp = params->bp;
6292         u16 gp_status = 0, phy_index = 0;
6293         u8 ext_phy_link_up = 0, serdes_phy_type;
6294         struct link_vars temp_vars;
6295         struct bnx2x_phy *int_phy = &params->phy[INT_PHY];
6296
6297         if (CHIP_IS_E3(bp)) {
6298                 u16 link_up;
6299                 if (params->req_line_speed[LINK_CONFIG_IDX(INT_PHY)]
6300                     > SPEED_10000) {
6301                         /* Check 20G link */
6302                         bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
6303                                         1, &link_up);
6304                         bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
6305                                         1, &link_up);
6306                         link_up &= (1<<2);
6307                 } else {
6308                         /* Check 10G link and below*/
6309                         u8 lane = bnx2x_get_warpcore_lane(int_phy, params);
6310                         bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
6311                                         MDIO_WC_REG_GP2_STATUS_GP_2_1,
6312                                         &gp_status);
6313                         gp_status = ((gp_status >> 8) & 0xf) |
6314                                 ((gp_status >> 12) & 0xf);
6315                         link_up = gp_status & (1 << lane);
6316                 }
6317                 if (!link_up)
6318                         return -ESRCH;
6319         } else {
6320                 CL22_RD_OVER_CL45(bp, int_phy,
6321                           MDIO_REG_BANK_GP_STATUS,
6322                           MDIO_GP_STATUS_TOP_AN_STATUS1,
6323                           &gp_status);
6324         /* link is up only if both local phy and external phy are up */
6325         if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
6326                 return -ESRCH;
6327         }
6328         /* In XGXS loopback mode, do not check external PHY */
6329         if (params->loopback_mode == LOOPBACK_XGXS)
6330                 return 0;
6331
6332         switch (params->num_phys) {
6333         case 1:
6334                 /* No external PHY */
6335                 return 0;
6336         case 2:
6337                 ext_phy_link_up = params->phy[EXT_PHY1].read_status(
6338                         &params->phy[EXT_PHY1],
6339                         params, &temp_vars);
6340                 break;
6341         case 3: /* Dual Media */
6342                 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6343                       phy_index++) {
6344                         serdes_phy_type = ((params->phy[phy_index].media_type ==
6345                                             ETH_PHY_SFP_FIBER) ||
6346                                            (params->phy[phy_index].media_type ==
6347                                             ETH_PHY_XFP_FIBER) ||
6348                                            (params->phy[phy_index].media_type ==
6349                                             ETH_PHY_DA_TWINAX));
6350
6351                         if (is_serdes != serdes_phy_type)
6352                                 continue;
6353                         if (params->phy[phy_index].read_status) {
6354                                 ext_phy_link_up |=
6355                                         params->phy[phy_index].read_status(
6356                                                 &params->phy[phy_index],
6357                                                 params, &temp_vars);
6358                         }
6359                 }
6360                 break;
6361         }
6362         if (ext_phy_link_up)
6363                 return 0;
6364         return -ESRCH;
6365 }
6366
6367 static int bnx2x_link_initialize(struct link_params *params,
6368                                  struct link_vars *vars)
6369 {
6370         int rc = 0;
6371         u8 phy_index, non_ext_phy;
6372         struct bnx2x *bp = params->bp;
6373         /*
6374          * In case of external phy existence, the line speed would be the
6375          * line speed linked up by the external phy. In case it is direct
6376          * only, then the line_speed during initialization will be
6377          * equal to the req_line_speed
6378          */
6379         vars->line_speed = params->phy[INT_PHY].req_line_speed;
6380
6381         /*
6382          * Initialize the internal phy in case this is a direct board
6383          * (no external phys), or this board has external phy which requires
6384          * to first.
6385          */
6386         if (!USES_WARPCORE(bp))
6387                 bnx2x_prepare_xgxs(&params->phy[INT_PHY], params, vars);
6388         /* init ext phy and enable link state int */
6389         non_ext_phy = (SINGLE_MEDIA_DIRECT(params) ||
6390                        (params->loopback_mode == LOOPBACK_XGXS));
6391
6392         if (non_ext_phy ||
6393             (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) ||
6394             (params->loopback_mode == LOOPBACK_EXT_PHY)) {
6395                 struct bnx2x_phy *phy = &params->phy[INT_PHY];
6396                 if (vars->line_speed == SPEED_AUTO_NEG &&
6397                     (CHIP_IS_E1x(bp) ||
6398                      CHIP_IS_E2(bp)))
6399                         bnx2x_set_parallel_detection(phy, params);
6400                         if (params->phy[INT_PHY].config_init)
6401                                 params->phy[INT_PHY].config_init(phy,
6402                                                                  params,
6403                                                                  vars);
6404         }
6405
6406         /* Init external phy*/
6407         if (non_ext_phy) {
6408                 if (params->phy[INT_PHY].supported &
6409                     SUPPORTED_FIBRE)
6410                         vars->link_status |= LINK_STATUS_SERDES_LINK;
6411         } else {
6412                 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6413                       phy_index++) {
6414                         /*
6415                          * No need to initialize second phy in case of first
6416                          * phy only selection. In case of second phy, we do
6417                          * need to initialize the first phy, since they are
6418                          * connected.
6419                          */
6420                         if (params->phy[phy_index].supported &
6421                             SUPPORTED_FIBRE)
6422                                 vars->link_status |= LINK_STATUS_SERDES_LINK;
6423
6424                         if (phy_index == EXT_PHY2 &&
6425                             (bnx2x_phy_selection(params) ==
6426                              PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
6427                                 DP(NETIF_MSG_LINK,
6428                                    "Not initializing second phy\n");
6429                                 continue;
6430                         }
6431                         params->phy[phy_index].config_init(
6432                                 &params->phy[phy_index],
6433                                 params, vars);
6434                 }
6435         }
6436         /* Reset the interrupt indication after phy was initialized */
6437         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
6438                        params->port*4,
6439                        (NIG_STATUS_XGXS0_LINK10G |
6440                         NIG_STATUS_XGXS0_LINK_STATUS |
6441                         NIG_STATUS_SERDES0_LINK_STATUS |
6442                         NIG_MASK_MI_INT));
6443         bnx2x_update_mng(params, vars->link_status);
6444         return rc;
6445 }
6446
6447 static void bnx2x_int_link_reset(struct bnx2x_phy *phy,
6448                                  struct link_params *params)
6449 {
6450         /* reset the SerDes/XGXS */
6451         REG_WR(params->bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
6452                (0x1ff << (params->port*16)));
6453 }
6454
6455 static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
6456                                         struct link_params *params)
6457 {
6458         struct bnx2x *bp = params->bp;
6459         u8 gpio_port;
6460         /* HW reset */
6461         if (CHIP_IS_E2(bp))
6462                 gpio_port = BP_PATH(bp);
6463         else
6464                 gpio_port = params->port;
6465         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6466                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
6467                        gpio_port);
6468         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6469                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
6470                        gpio_port);
6471         DP(NETIF_MSG_LINK, "reset external PHY\n");
6472 }
6473
6474 static int bnx2x_update_link_down(struct link_params *params,
6475                                   struct link_vars *vars)
6476 {
6477         struct bnx2x *bp = params->bp;
6478         u8 port = params->port;
6479
6480         DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
6481         bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
6482         vars->phy_flags &= ~PHY_PHYSICAL_LINK_FLAG;
6483         /* indicate no mac active */
6484         vars->mac_type = MAC_TYPE_NONE;
6485
6486         /* update shared memory */
6487         vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK |
6488                                LINK_STATUS_LINK_UP |
6489                                LINK_STATUS_PHYSICAL_LINK_FLAG |
6490                                LINK_STATUS_AUTO_NEGOTIATE_COMPLETE |
6491                                LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK |
6492                                LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK |
6493                                LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK |
6494                                LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE |
6495                                LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE);
6496         vars->line_speed = 0;
6497         bnx2x_update_mng(params, vars->link_status);
6498
6499         /* activate nig drain */
6500         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6501
6502         /* disable emac */
6503         if (!CHIP_IS_E3(bp))
6504                 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6505
6506         msleep(10);
6507         /* reset BigMac/Xmac */
6508         if (CHIP_IS_E1x(bp) ||
6509             CHIP_IS_E2(bp)) {
6510                 bnx2x_bmac_rx_disable(bp, params->port);
6511                 REG_WR(bp, GRCBASE_MISC +
6512                        MISC_REGISTERS_RESET_REG_2_CLEAR,
6513                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6514         }
6515         if (CHIP_IS_E3(bp)) {
6516                 bnx2x_xmac_disable(params);
6517                 bnx2x_umac_disable(params);
6518         }
6519
6520         return 0;
6521 }
6522
6523 static int bnx2x_update_link_up(struct link_params *params,
6524                                 struct link_vars *vars,
6525                                 u8 link_10g)
6526 {
6527         struct bnx2x *bp = params->bp;
6528         u8 port = params->port;
6529         int rc = 0;
6530
6531         vars->link_status |= (LINK_STATUS_LINK_UP |
6532                               LINK_STATUS_PHYSICAL_LINK_FLAG);
6533         vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
6534
6535         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
6536                 vars->link_status |=
6537                         LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
6538
6539         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
6540                 vars->link_status |=
6541                         LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
6542         if (USES_WARPCORE(bp)) {
6543                 if (link_10g) {
6544                         if (bnx2x_xmac_enable(params, vars, 0) ==
6545                             -ESRCH) {
6546                                 DP(NETIF_MSG_LINK, "Found errors on XMAC\n");
6547                                 vars->link_up = 0;
6548                                 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
6549                                 vars->link_status &= ~LINK_STATUS_LINK_UP;
6550                         }
6551                 } else
6552                         bnx2x_umac_enable(params, vars, 0);
6553                 bnx2x_set_led(params, vars,
6554                               LED_MODE_OPER, vars->line_speed);
6555         }
6556         if ((CHIP_IS_E1x(bp) ||
6557              CHIP_IS_E2(bp))) {
6558                 if (link_10g) {
6559                         if (bnx2x_bmac_enable(params, vars, 0) ==
6560                             -ESRCH) {
6561                                 DP(NETIF_MSG_LINK, "Found errors on BMAC\n");
6562                                 vars->link_up = 0;
6563                                 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
6564                                 vars->link_status &= ~LINK_STATUS_LINK_UP;
6565                         }
6566
6567                         bnx2x_set_led(params, vars,
6568                                       LED_MODE_OPER, SPEED_10000);
6569                 } else {
6570                         rc = bnx2x_emac_program(params, vars);
6571                         bnx2x_emac_enable(params, vars, 0);
6572
6573                         /* AN complete? */
6574                         if ((vars->link_status &
6575                              LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
6576                             && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
6577                             SINGLE_MEDIA_DIRECT(params))
6578                                 bnx2x_set_gmii_tx_driver(params);
6579                 }
6580         }
6581
6582         /* PBF - link up */
6583         if (CHIP_IS_E1x(bp))
6584                 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
6585                                        vars->line_speed);
6586
6587         /* disable drain */
6588         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
6589
6590         /* update shared memory */
6591         bnx2x_update_mng(params, vars->link_status);
6592         msleep(20);
6593         return rc;
6594 }
6595 /*
6596  * The bnx2x_link_update function should be called upon link
6597  * interrupt.
6598  * Link is considered up as follows:
6599  * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
6600  *   to be up
6601  * - SINGLE_MEDIA - The link between the 577xx and the external
6602  *   phy (XGXS) need to up as well as the external link of the
6603  *   phy (PHY_EXT1)
6604  * - DUAL_MEDIA - The link between the 577xx and the first
6605  *   external phy needs to be up, and at least one of the 2
6606  *   external phy link must be up.
6607  */
6608 int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
6609 {
6610         struct bnx2x *bp = params->bp;
6611         struct link_vars phy_vars[MAX_PHYS];
6612         u8 port = params->port;
6613         u8 link_10g_plus, phy_index;
6614         u8 ext_phy_link_up = 0, cur_link_up;
6615         int rc = 0;
6616         u8 is_mi_int = 0;
6617         u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
6618         u8 active_external_phy = INT_PHY;
6619         vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
6620         for (phy_index = INT_PHY; phy_index < params->num_phys;
6621               phy_index++) {
6622                 phy_vars[phy_index].flow_ctrl = 0;
6623                 phy_vars[phy_index].link_status = 0;
6624                 phy_vars[phy_index].line_speed = 0;
6625                 phy_vars[phy_index].duplex = DUPLEX_FULL;
6626                 phy_vars[phy_index].phy_link_up = 0;
6627                 phy_vars[phy_index].link_up = 0;
6628                 phy_vars[phy_index].fault_detected = 0;
6629         }
6630
6631         if (USES_WARPCORE(bp))
6632                 bnx2x_set_aer_mmd(params, &params->phy[INT_PHY]);
6633
6634         DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
6635                  port, (vars->phy_flags & PHY_XGXS_FLAG),
6636                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
6637
6638         is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
6639                                 port*0x18) > 0);
6640         DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
6641                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
6642                  is_mi_int,
6643                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
6644
6645         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
6646           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
6647           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
6648
6649         /* disable emac */
6650         if (!CHIP_IS_E3(bp))
6651                 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6652
6653         /*
6654          * Step 1:
6655          * Check external link change only for external phys, and apply
6656          * priority selection between them in case the link on both phys
6657          * is up. Note that instead of the common vars, a temporary
6658          * vars argument is used since each phy may have different link/
6659          * speed/duplex result
6660          */
6661         for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6662               phy_index++) {
6663                 struct bnx2x_phy *phy = &params->phy[phy_index];
6664                 if (!phy->read_status)
6665                         continue;
6666                 /* Read link status and params of this ext phy */
6667                 cur_link_up = phy->read_status(phy, params,
6668                                                &phy_vars[phy_index]);
6669                 if (cur_link_up) {
6670                         DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
6671                                    phy_index);
6672                 } else {
6673                         DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
6674                                    phy_index);
6675                         continue;
6676                 }
6677
6678                 if (!ext_phy_link_up) {
6679                         ext_phy_link_up = 1;
6680                         active_external_phy = phy_index;
6681                 } else {
6682                         switch (bnx2x_phy_selection(params)) {
6683                         case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
6684                         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
6685                         /*
6686                          * In this option, the first PHY makes sure to pass the
6687                          * traffic through itself only.
6688                          * Its not clear how to reset the link on the second phy
6689                          */
6690                                 active_external_phy = EXT_PHY1;
6691                                 break;
6692                         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
6693                         /*
6694                          * In this option, the first PHY makes sure to pass the
6695                          * traffic through the second PHY.
6696                          */
6697                                 active_external_phy = EXT_PHY2;
6698                                 break;
6699                         default:
6700                         /*
6701                          * Link indication on both PHYs with the following cases
6702                          * is invalid:
6703                          * - FIRST_PHY means that second phy wasn't initialized,
6704                          * hence its link is expected to be down
6705                          * - SECOND_PHY means that first phy should not be able
6706                          * to link up by itself (using configuration)
6707                          * - DEFAULT should be overriden during initialiazation
6708                          */
6709                                 DP(NETIF_MSG_LINK, "Invalid link indication"
6710                                            "mpc=0x%x. DISABLING LINK !!!\n",
6711                                            params->multi_phy_config);
6712                                 ext_phy_link_up = 0;
6713                                 break;
6714                         }
6715                 }
6716         }
6717         prev_line_speed = vars->line_speed;
6718         /*
6719          * Step 2:
6720          * Read the status of the internal phy. In case of
6721          * DIRECT_SINGLE_MEDIA board, this link is the external link,
6722          * otherwise this is the link between the 577xx and the first
6723          * external phy
6724          */
6725         if (params->phy[INT_PHY].read_status)
6726                 params->phy[INT_PHY].read_status(
6727                         &params->phy[INT_PHY],
6728                         params, vars);
6729         /*
6730          * The INT_PHY flow control reside in the vars. This include the
6731          * case where the speed or flow control are not set to AUTO.
6732          * Otherwise, the active external phy flow control result is set
6733          * to the vars. The ext_phy_line_speed is needed to check if the
6734          * speed is different between the internal phy and external phy.
6735          * This case may be result of intermediate link speed change.
6736          */
6737         if (active_external_phy > INT_PHY) {
6738                 vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
6739                 /*
6740                  * Link speed is taken from the XGXS. AN and FC result from
6741                  * the external phy.
6742                  */
6743                 vars->link_status |= phy_vars[active_external_phy].link_status;
6744
6745                 /*
6746                  * if active_external_phy is first PHY and link is up - disable
6747                  * disable TX on second external PHY
6748                  */
6749                 if (active_external_phy == EXT_PHY1) {
6750                         if (params->phy[EXT_PHY2].phy_specific_func) {
6751                                 DP(NETIF_MSG_LINK,
6752                                    "Disabling TX on EXT_PHY2\n");
6753                                 params->phy[EXT_PHY2].phy_specific_func(
6754                                         &params->phy[EXT_PHY2],
6755                                         params, DISABLE_TX);
6756                         }
6757                 }
6758
6759                 ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
6760                 vars->duplex = phy_vars[active_external_phy].duplex;
6761                 if (params->phy[active_external_phy].supported &
6762                     SUPPORTED_FIBRE)
6763                         vars->link_status |= LINK_STATUS_SERDES_LINK;
6764                 else
6765                         vars->link_status &= ~LINK_STATUS_SERDES_LINK;
6766                 DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
6767                            active_external_phy);
6768         }
6769
6770         for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6771               phy_index++) {
6772                 if (params->phy[phy_index].flags &
6773                     FLAGS_REARM_LATCH_SIGNAL) {
6774                         bnx2x_rearm_latch_signal(bp, port,
6775                                                  phy_index ==
6776                                                  active_external_phy);
6777                         break;
6778                 }
6779         }
6780         DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
6781                    " ext_phy_line_speed = %d\n", vars->flow_ctrl,
6782                    vars->link_status, ext_phy_line_speed);
6783         /*
6784          * Upon link speed change set the NIG into drain mode. Comes to
6785          * deals with possible FIFO glitch due to clk change when speed
6786          * is decreased without link down indicator
6787          */
6788
6789         if (vars->phy_link_up) {
6790                 if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
6791                     (ext_phy_line_speed != vars->line_speed)) {
6792                         DP(NETIF_MSG_LINK, "Internal link speed %d is"
6793                                    " different than the external"
6794                                    " link speed %d\n", vars->line_speed,
6795                                    ext_phy_line_speed);
6796                         vars->phy_link_up = 0;
6797                 } else if (prev_line_speed != vars->line_speed) {
6798                         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4,
6799                                0);
6800                         msleep(1);
6801                 }
6802         }
6803
6804         /* anything 10 and over uses the bmac */
6805         link_10g_plus = (vars->line_speed >= SPEED_10000);
6806
6807         bnx2x_link_int_ack(params, vars, link_10g_plus);
6808
6809         /*
6810          * In case external phy link is up, and internal link is down
6811          * (not initialized yet probably after link initialization, it
6812          * needs to be initialized.
6813          * Note that after link down-up as result of cable plug, the xgxs
6814          * link would probably become up again without the need
6815          * initialize it
6816          */
6817         if (!(SINGLE_MEDIA_DIRECT(params))) {
6818                 DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
6819                            " init_preceding = %d\n", ext_phy_link_up,
6820                            vars->phy_link_up,
6821                            params->phy[EXT_PHY1].flags &
6822                            FLAGS_INIT_XGXS_FIRST);
6823                 if (!(params->phy[EXT_PHY1].flags &
6824                       FLAGS_INIT_XGXS_FIRST)
6825                     && ext_phy_link_up && !vars->phy_link_up) {
6826                         vars->line_speed = ext_phy_line_speed;
6827                         if (vars->line_speed < SPEED_1000)
6828                                 vars->phy_flags |= PHY_SGMII_FLAG;
6829                         else
6830                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
6831
6832                         if (params->phy[INT_PHY].config_init)
6833                                 params->phy[INT_PHY].config_init(
6834                                         &params->phy[INT_PHY], params,
6835                                                 vars);
6836                 }
6837         }
6838         /*
6839          * Link is up only if both local phy and external phy (in case of
6840          * non-direct board) are up and no fault detected on active PHY.
6841          */
6842         vars->link_up = (vars->phy_link_up &&
6843                          (ext_phy_link_up ||
6844                           SINGLE_MEDIA_DIRECT(params)) &&
6845                          (phy_vars[active_external_phy].fault_detected == 0));
6846
6847         if (vars->link_up)
6848                 rc = bnx2x_update_link_up(params, vars, link_10g_plus);
6849         else
6850                 rc = bnx2x_update_link_down(params, vars);
6851
6852         return rc;
6853 }
6854
6855 /*****************************************************************************/
6856 /*                          External Phy section                             */
6857 /*****************************************************************************/
6858 void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
6859 {
6860         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6861                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
6862         msleep(1);
6863         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6864                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
6865 }
6866
6867 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
6868                                       u32 spirom_ver, u32 ver_addr)
6869 {
6870         DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
6871                  (u16)(spirom_ver>>16), (u16)spirom_ver, port);
6872
6873         if (ver_addr)
6874                 REG_WR(bp, ver_addr, spirom_ver);
6875 }
6876
6877 static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp,
6878                                       struct bnx2x_phy *phy,
6879                                       u8 port)
6880 {
6881         u16 fw_ver1, fw_ver2;
6882
6883         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
6884                         MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6885         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
6886                         MDIO_PMA_REG_ROM_VER2, &fw_ver2);
6887         bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2),
6888                                   phy->ver_addr);
6889 }
6890
6891 static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp,
6892                                        struct bnx2x_phy *phy,
6893                                        struct link_vars *vars)
6894 {
6895         u16 val;
6896         bnx2x_cl45_read(bp, phy,
6897                         MDIO_AN_DEVAD,
6898                         MDIO_AN_REG_STATUS, &val);
6899         bnx2x_cl45_read(bp, phy,
6900                         MDIO_AN_DEVAD,
6901                         MDIO_AN_REG_STATUS, &val);
6902         if (val & (1<<5))
6903                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6904         if ((val & (1<<0)) == 0)
6905                 vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
6906 }
6907
6908 /******************************************************************/
6909 /*              common BCM8073/BCM8727 PHY SECTION                */
6910 /******************************************************************/
6911 static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
6912                                   struct link_params *params,
6913                                   struct link_vars *vars)
6914 {
6915         struct bnx2x *bp = params->bp;
6916         if (phy->req_line_speed == SPEED_10 ||
6917             phy->req_line_speed == SPEED_100) {
6918                 vars->flow_ctrl = phy->req_flow_ctrl;
6919                 return;
6920         }
6921
6922         if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
6923             (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) {
6924                 u16 pause_result;
6925                 u16 ld_pause;           /* local */
6926                 u16 lp_pause;           /* link partner */
6927                 bnx2x_cl45_read(bp, phy,
6928                                 MDIO_AN_DEVAD,
6929                                 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
6930
6931                 bnx2x_cl45_read(bp, phy,
6932                                 MDIO_AN_DEVAD,
6933                                 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
6934                 pause_result = (ld_pause &
6935                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
6936                 pause_result |= (lp_pause &
6937                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
6938
6939                 bnx2x_pause_resolve(vars, pause_result);
6940                 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
6941                            pause_result);
6942         }
6943 }
6944 static int bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
6945                                              struct bnx2x_phy *phy,
6946                                              u8 port)
6947 {
6948         u32 count = 0;
6949         u16 fw_ver1, fw_msgout;
6950         int rc = 0;
6951
6952         /* Boot port from external ROM  */
6953         /* EDC grst */
6954         bnx2x_cl45_write(bp, phy,
6955                          MDIO_PMA_DEVAD,
6956                          MDIO_PMA_REG_GEN_CTRL,
6957                          0x0001);
6958
6959         /* ucode reboot and rst */
6960         bnx2x_cl45_write(bp, phy,
6961                          MDIO_PMA_DEVAD,
6962                          MDIO_PMA_REG_GEN_CTRL,
6963                          0x008c);
6964
6965         bnx2x_cl45_write(bp, phy,
6966                          MDIO_PMA_DEVAD,
6967                          MDIO_PMA_REG_MISC_CTRL1, 0x0001);
6968
6969         /* Reset internal microprocessor */
6970         bnx2x_cl45_write(bp, phy,
6971                          MDIO_PMA_DEVAD,
6972                          MDIO_PMA_REG_GEN_CTRL,
6973                          MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
6974
6975         /* Release srst bit */
6976         bnx2x_cl45_write(bp, phy,
6977                          MDIO_PMA_DEVAD,
6978                          MDIO_PMA_REG_GEN_CTRL,
6979                          MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
6980
6981         /* Delay 100ms per the PHY specifications */
6982         msleep(100);
6983
6984         /* 8073 sometimes taking longer to download */
6985         do {
6986                 count++;
6987                 if (count > 300) {
6988                         DP(NETIF_MSG_LINK,
6989                                  "bnx2x_8073_8727_external_rom_boot port %x:"
6990                                  "Download failed. fw version = 0x%x\n",
6991                                  port, fw_ver1);
6992                         rc = -EINVAL;
6993                         break;
6994                 }
6995
6996                 bnx2x_cl45_read(bp, phy,
6997                                 MDIO_PMA_DEVAD,
6998                                 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6999                 bnx2x_cl45_read(bp, phy,
7000                                 MDIO_PMA_DEVAD,
7001                                 MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
7002
7003                 msleep(1);
7004         } while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
7005                         ((fw_msgout & 0xff) != 0x03 && (phy->type ==
7006                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)));
7007
7008         /* Clear ser_boot_ctl bit */
7009         bnx2x_cl45_write(bp, phy,
7010                          MDIO_PMA_DEVAD,
7011                          MDIO_PMA_REG_MISC_CTRL1, 0x0000);
7012         bnx2x_save_bcm_spirom_ver(bp, phy, port);
7013
7014         DP(NETIF_MSG_LINK,
7015                  "bnx2x_8073_8727_external_rom_boot port %x:"
7016                  "Download complete. fw version = 0x%x\n",
7017                  port, fw_ver1);
7018
7019         return rc;
7020 }
7021
7022 /******************************************************************/
7023 /*                      BCM8073 PHY SECTION                       */
7024 /******************************************************************/
7025 static int bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
7026 {
7027         /* This is only required for 8073A1, version 102 only */
7028         u16 val;
7029
7030         /* Read 8073 HW revision*/
7031         bnx2x_cl45_read(bp, phy,
7032                         MDIO_PMA_DEVAD,
7033                         MDIO_PMA_REG_8073_CHIP_REV, &val);
7034
7035         if (val != 1) {
7036                 /* No need to workaround in 8073 A1 */
7037                 return 0;
7038         }
7039
7040         bnx2x_cl45_read(bp, phy,
7041                         MDIO_PMA_DEVAD,
7042                         MDIO_PMA_REG_ROM_VER2, &val);
7043
7044         /* SNR should be applied only for version 0x102 */
7045         if (val != 0x102)
7046                 return 0;
7047
7048         return 1;
7049 }
7050
7051 static int bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
7052 {
7053         u16 val, cnt, cnt1 ;
7054
7055         bnx2x_cl45_read(bp, phy,
7056                         MDIO_PMA_DEVAD,
7057                         MDIO_PMA_REG_8073_CHIP_REV, &val);
7058
7059         if (val > 0) {
7060                 /* No need to workaround in 8073 A1 */
7061                 return 0;
7062         }
7063         /* XAUI workaround in 8073 A0: */
7064
7065         /*
7066          * After loading the boot ROM and restarting Autoneg, poll
7067          * Dev1, Reg $C820:
7068          */
7069
7070         for (cnt = 0; cnt < 1000; cnt++) {
7071                 bnx2x_cl45_read(bp, phy,
7072                                 MDIO_PMA_DEVAD,
7073                                 MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
7074                                 &val);
7075                   /*
7076                    * If bit [14] = 0 or bit [13] = 0, continue on with
7077                    * system initialization (XAUI work-around not required, as
7078                    * these bits indicate 2.5G or 1G link up).
7079                    */
7080                 if (!(val & (1<<14)) || !(val & (1<<13))) {
7081                         DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
7082                         return 0;
7083                 } else if (!(val & (1<<15))) {
7084                         DP(NETIF_MSG_LINK, "bit 15 went off\n");
7085                         /*
7086                          * If bit 15 is 0, then poll Dev1, Reg $C841 until it's
7087                          * MSB (bit15) goes to 1 (indicating that the XAUI
7088                          * workaround has completed), then continue on with
7089                          * system initialization.
7090                          */
7091                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
7092                                 bnx2x_cl45_read(bp, phy,
7093                                         MDIO_PMA_DEVAD,
7094                                         MDIO_PMA_REG_8073_XAUI_WA, &val);
7095                                 if (val & (1<<15)) {
7096                                         DP(NETIF_MSG_LINK,
7097                                           "XAUI workaround has completed\n");
7098                                         return 0;
7099                                  }
7100                                  msleep(3);
7101                         }
7102                         break;
7103                 }
7104                 msleep(3);
7105         }
7106         DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
7107         return -EINVAL;
7108 }
7109
7110 static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy)
7111 {
7112         /* Force KR or KX */
7113         bnx2x_cl45_write(bp, phy,
7114                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
7115         bnx2x_cl45_write(bp, phy,
7116                          MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
7117         bnx2x_cl45_write(bp, phy,
7118                          MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
7119         bnx2x_cl45_write(bp, phy,
7120                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
7121 }
7122
7123 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
7124                                       struct bnx2x_phy *phy,
7125                                       struct link_vars *vars)
7126 {
7127         u16 cl37_val;
7128         struct bnx2x *bp = params->bp;
7129         bnx2x_cl45_read(bp, phy,
7130                         MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
7131
7132         cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
7133         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
7134         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
7135         if ((vars->ieee_fc &
7136             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
7137             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
7138                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
7139         }
7140         if ((vars->ieee_fc &
7141             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
7142             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
7143                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
7144         }
7145         if ((vars->ieee_fc &
7146             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
7147             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
7148                 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
7149         }
7150         DP(NETIF_MSG_LINK,
7151                  "Ext phy AN advertize cl37 0x%x\n", cl37_val);
7152
7153         bnx2x_cl45_write(bp, phy,
7154                          MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
7155         msleep(500);
7156 }
7157
7158 static int bnx2x_8073_config_init(struct bnx2x_phy *phy,
7159                                   struct link_params *params,
7160                                   struct link_vars *vars)
7161 {
7162         struct bnx2x *bp = params->bp;
7163         u16 val = 0, tmp1;
7164         u8 gpio_port;
7165         DP(NETIF_MSG_LINK, "Init 8073\n");
7166
7167         if (CHIP_IS_E2(bp))
7168                 gpio_port = BP_PATH(bp);
7169         else
7170                 gpio_port = params->port;
7171         /* Restore normal power mode*/
7172         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7173                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
7174
7175         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
7176                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
7177
7178         /* enable LASI */
7179         bnx2x_cl45_write(bp, phy,
7180                          MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, (1<<2));
7181         bnx2x_cl45_write(bp, phy,
7182                          MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,  0x0004);
7183
7184         bnx2x_8073_set_pause_cl37(params, phy, vars);
7185
7186         bnx2x_cl45_read(bp, phy,
7187                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
7188
7189         bnx2x_cl45_read(bp, phy,
7190                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
7191
7192         DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
7193
7194         /* Swap polarity if required - Must be done only in non-1G mode */
7195         if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
7196                 /* Configure the 8073 to swap _P and _N of the KR lines */
7197                 DP(NETIF_MSG_LINK, "Swapping polarity for the 8073\n");
7198                 /* 10G Rx/Tx and 1G Tx signal polarity swap */
7199                 bnx2x_cl45_read(bp, phy,
7200                                 MDIO_PMA_DEVAD,
7201                                 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
7202                 bnx2x_cl45_write(bp, phy,
7203                                  MDIO_PMA_DEVAD,
7204                                  MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
7205                                  (val | (3<<9)));
7206         }
7207
7208
7209         /* Enable CL37 BAM */
7210         if (REG_RD(bp, params->shmem_base +
7211                          offsetof(struct shmem_region, dev_info.
7212                                   port_hw_config[params->port].default_cfg)) &
7213             PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
7214
7215                 bnx2x_cl45_read(bp, phy,
7216                                 MDIO_AN_DEVAD,
7217                                 MDIO_AN_REG_8073_BAM, &val);
7218                 bnx2x_cl45_write(bp, phy,
7219                                  MDIO_AN_DEVAD,
7220                                  MDIO_AN_REG_8073_BAM, val | 1);
7221                 DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
7222         }
7223         if (params->loopback_mode == LOOPBACK_EXT) {
7224                 bnx2x_807x_force_10G(bp, phy);
7225                 DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
7226                 return 0;
7227         } else {
7228                 bnx2x_cl45_write(bp, phy,
7229                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
7230         }
7231         if (phy->req_line_speed != SPEED_AUTO_NEG) {
7232                 if (phy->req_line_speed == SPEED_10000) {
7233                         val = (1<<7);
7234                 } else if (phy->req_line_speed ==  SPEED_2500) {
7235                         val = (1<<5);
7236                         /*
7237                          * Note that 2.5G works only when used with 1G
7238                          * advertisement
7239                          */
7240                 } else
7241                         val = (1<<5);
7242         } else {
7243                 val = 0;
7244                 if (phy->speed_cap_mask &
7245                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
7246                         val |= (1<<7);
7247
7248                 /* Note that 2.5G works only when used with 1G advertisement */
7249                 if (phy->speed_cap_mask &
7250                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
7251                          PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
7252                         val |= (1<<5);
7253                 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
7254         }
7255
7256         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
7257         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
7258
7259         if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
7260              (phy->req_line_speed == SPEED_AUTO_NEG)) ||
7261             (phy->req_line_speed == SPEED_2500)) {
7262                 u16 phy_ver;
7263                 /* Allow 2.5G for A1 and above */
7264                 bnx2x_cl45_read(bp, phy,
7265                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
7266                                 &phy_ver);
7267                 DP(NETIF_MSG_LINK, "Add 2.5G\n");
7268                 if (phy_ver > 0)
7269                         tmp1 |= 1;
7270                 else
7271                         tmp1 &= 0xfffe;
7272         } else {
7273                 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
7274                 tmp1 &= 0xfffe;
7275         }
7276
7277         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
7278         /* Add support for CL37 (passive mode) II */
7279
7280         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
7281         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
7282                          (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
7283                                   0x20 : 0x40)));
7284
7285         /* Add support for CL37 (passive mode) III */
7286         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
7287
7288         /*
7289          * The SNR will improve about 2db by changing BW and FEE main
7290          * tap. Rest commands are executed after link is up
7291          * Change FFE main cursor to 5 in EDC register
7292          */
7293         if (bnx2x_8073_is_snr_needed(bp, phy))
7294                 bnx2x_cl45_write(bp, phy,
7295                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
7296                                  0xFB0C);
7297
7298         /* Enable FEC (Forware Error Correction) Request in the AN */
7299         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
7300         tmp1 |= (1<<15);
7301         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
7302
7303         bnx2x_ext_phy_set_pause(params, phy, vars);
7304
7305         /* Restart autoneg */
7306         msleep(500);
7307         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
7308         DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
7309                    ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
7310         return 0;
7311 }
7312
7313 static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
7314                                  struct link_params *params,
7315                                  struct link_vars *vars)
7316 {
7317         struct bnx2x *bp = params->bp;
7318         u8 link_up = 0;
7319         u16 val1, val2;
7320         u16 link_status = 0;
7321         u16 an1000_status = 0;
7322
7323         bnx2x_cl45_read(bp, phy,
7324                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
7325
7326         DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
7327
7328         /* clear the interrupt LASI status register */
7329         bnx2x_cl45_read(bp, phy,
7330                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
7331         bnx2x_cl45_read(bp, phy,
7332                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
7333         DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
7334         /* Clear MSG-OUT */
7335         bnx2x_cl45_read(bp, phy,
7336                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
7337
7338         /* Check the LASI */
7339         bnx2x_cl45_read(bp, phy,
7340                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
7341
7342         DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
7343
7344         /* Check the link status */
7345         bnx2x_cl45_read(bp, phy,
7346                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
7347         DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
7348
7349         bnx2x_cl45_read(bp, phy,
7350                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
7351         bnx2x_cl45_read(bp, phy,
7352                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
7353         link_up = ((val1 & 4) == 4);
7354         DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
7355
7356         if (link_up &&
7357              ((phy->req_line_speed != SPEED_10000))) {
7358                 if (bnx2x_8073_xaui_wa(bp, phy) != 0)
7359                         return 0;
7360         }
7361         bnx2x_cl45_read(bp, phy,
7362                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
7363         bnx2x_cl45_read(bp, phy,
7364                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
7365
7366         /* Check the link status on 1.1.2 */
7367         bnx2x_cl45_read(bp, phy,
7368                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
7369         bnx2x_cl45_read(bp, phy,
7370                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
7371         DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
7372                    "an_link_status=0x%x\n", val2, val1, an1000_status);
7373
7374         link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
7375         if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
7376                 /*
7377                  * The SNR will improve about 2dbby changing the BW and FEE main
7378                  * tap. The 1st write to change FFE main tap is set before
7379                  * restart AN. Change PLL Bandwidth in EDC register
7380                  */
7381                 bnx2x_cl45_write(bp, phy,
7382                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
7383                                  0x26BC);
7384
7385                 /* Change CDR Bandwidth in EDC register */
7386                 bnx2x_cl45_write(bp, phy,
7387                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
7388                                  0x0333);
7389         }
7390         bnx2x_cl45_read(bp, phy,
7391                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
7392                         &link_status);
7393
7394         /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
7395         if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
7396                 link_up = 1;
7397                 vars->line_speed = SPEED_10000;
7398                 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
7399                            params->port);
7400         } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
7401                 link_up = 1;
7402                 vars->line_speed = SPEED_2500;
7403                 DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
7404                            params->port);
7405         } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
7406                 link_up = 1;
7407                 vars->line_speed = SPEED_1000;
7408                 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
7409                            params->port);
7410         } else {
7411                 link_up = 0;
7412                 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
7413                            params->port);
7414         }
7415
7416         if (link_up) {
7417                 /* Swap polarity if required */
7418                 if (params->lane_config &
7419                     PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
7420                         /* Configure the 8073 to swap P and N of the KR lines */
7421                         bnx2x_cl45_read(bp, phy,
7422                                         MDIO_XS_DEVAD,
7423                                         MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
7424                         /*
7425                          * Set bit 3 to invert Rx in 1G mode and clear this bit
7426                          * when it`s in 10G mode.
7427                          */
7428                         if (vars->line_speed == SPEED_1000) {
7429                                 DP(NETIF_MSG_LINK, "Swapping 1G polarity for"
7430                                               "the 8073\n");
7431                                 val1 |= (1<<3);
7432                         } else
7433                                 val1 &= ~(1<<3);
7434
7435                         bnx2x_cl45_write(bp, phy,
7436                                          MDIO_XS_DEVAD,
7437                                          MDIO_XS_REG_8073_RX_CTRL_PCIE,
7438                                          val1);
7439                 }
7440                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
7441                 bnx2x_8073_resolve_fc(phy, params, vars);
7442                 vars->duplex = DUPLEX_FULL;
7443         }
7444
7445         if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
7446                 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
7447                                 MDIO_AN_REG_LP_AUTO_NEG2, &val1);
7448
7449                 if (val1 & (1<<5))
7450                         vars->link_status |=
7451                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
7452                 if (val1 & (1<<7))
7453                         vars->link_status |=
7454                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
7455         }
7456
7457         return link_up;
7458 }
7459
7460 static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
7461                                   struct link_params *params)
7462 {
7463         struct bnx2x *bp = params->bp;
7464         u8 gpio_port;
7465         if (CHIP_IS_E2(bp))
7466                 gpio_port = BP_PATH(bp);
7467         else
7468                 gpio_port = params->port;
7469         DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
7470            gpio_port);
7471         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7472                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
7473                        gpio_port);
7474 }
7475
7476 /******************************************************************/
7477 /*                      BCM8705 PHY SECTION                       */
7478 /******************************************************************/
7479 static int bnx2x_8705_config_init(struct bnx2x_phy *phy,
7480                                   struct link_params *params,
7481                                   struct link_vars *vars)
7482 {
7483         struct bnx2x *bp = params->bp;
7484         DP(NETIF_MSG_LINK, "init 8705\n");
7485         /* Restore normal power mode*/
7486         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7487                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
7488         /* HW reset */
7489         bnx2x_ext_phy_hw_reset(bp, params->port);
7490         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
7491         bnx2x_wait_reset_complete(bp, phy, params);
7492
7493         bnx2x_cl45_write(bp, phy,
7494                          MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
7495         bnx2x_cl45_write(bp, phy,
7496                          MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
7497         bnx2x_cl45_write(bp, phy,
7498                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
7499         bnx2x_cl45_write(bp, phy,
7500                          MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
7501         /* BCM8705 doesn't have microcode, hence the 0 */
7502         bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
7503         return 0;
7504 }
7505
7506 static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
7507                                  struct link_params *params,
7508                                  struct link_vars *vars)
7509 {
7510         u8 link_up = 0;
7511         u16 val1, rx_sd;
7512         struct bnx2x *bp = params->bp;
7513         DP(NETIF_MSG_LINK, "read status 8705\n");
7514         bnx2x_cl45_read(bp, phy,
7515                       MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
7516         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
7517
7518         bnx2x_cl45_read(bp, phy,
7519                       MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
7520         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
7521
7522         bnx2x_cl45_read(bp, phy,
7523                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
7524
7525         bnx2x_cl45_read(bp, phy,
7526                       MDIO_PMA_DEVAD, 0xc809, &val1);
7527         bnx2x_cl45_read(bp, phy,
7528                       MDIO_PMA_DEVAD, 0xc809, &val1);
7529
7530         DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
7531         link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
7532         if (link_up) {
7533                 vars->line_speed = SPEED_10000;
7534                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
7535         }
7536         return link_up;
7537 }
7538
7539 /******************************************************************/
7540 /*                      SFP+ module Section                       */
7541 /******************************************************************/
7542 static void bnx2x_set_disable_pmd_transmit(struct link_params *params,
7543                                            struct bnx2x_phy *phy,
7544                                            u8 pmd_dis)
7545 {
7546         struct bnx2x *bp = params->bp;
7547         /*
7548          * Disable transmitter only for bootcodes which can enable it afterwards
7549          * (for D3 link)
7550          */
7551         if (pmd_dis) {
7552                 if (params->feature_config_flags &
7553                      FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED)
7554                         DP(NETIF_MSG_LINK, "Disabling PMD transmitter\n");
7555                 else {
7556                         DP(NETIF_MSG_LINK, "NOT disabling PMD transmitter\n");
7557                         return;
7558                 }
7559         } else
7560                 DP(NETIF_MSG_LINK, "Enabling PMD transmitter\n");
7561         bnx2x_cl45_write(bp, phy,
7562                          MDIO_PMA_DEVAD,
7563                          MDIO_PMA_REG_TX_DISABLE, pmd_dis);
7564 }
7565
7566 static u8 bnx2x_get_gpio_port(struct link_params *params)
7567 {
7568         u8 gpio_port;
7569         u32 swap_val, swap_override;
7570         struct bnx2x *bp = params->bp;
7571         if (CHIP_IS_E2(bp))
7572                 gpio_port = BP_PATH(bp);
7573         else
7574                 gpio_port = params->port;
7575         swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
7576         swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
7577         return gpio_port ^ (swap_val && swap_override);
7578 }
7579
7580 static void bnx2x_sfp_e1e2_set_transmitter(struct link_params *params,
7581                                            struct bnx2x_phy *phy,
7582                                            u8 tx_en)
7583 {
7584         u16 val;
7585         u8 port = params->port;
7586         struct bnx2x *bp = params->bp;
7587         u32 tx_en_mode;
7588
7589         /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
7590         tx_en_mode = REG_RD(bp, params->shmem_base +
7591                             offsetof(struct shmem_region,
7592                                      dev_info.port_hw_config[port].sfp_ctrl)) &
7593                 PORT_HW_CFG_TX_LASER_MASK;
7594         DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x "
7595                            "mode = %x\n", tx_en, port, tx_en_mode);
7596         switch (tx_en_mode) {
7597         case PORT_HW_CFG_TX_LASER_MDIO:
7598
7599                 bnx2x_cl45_read(bp, phy,
7600                                 MDIO_PMA_DEVAD,
7601                                 MDIO_PMA_REG_PHY_IDENTIFIER,
7602                                 &val);
7603
7604                 if (tx_en)
7605                         val &= ~(1<<15);
7606                 else
7607                         val |= (1<<15);
7608
7609                 bnx2x_cl45_write(bp, phy,
7610                                  MDIO_PMA_DEVAD,
7611                                  MDIO_PMA_REG_PHY_IDENTIFIER,
7612                                  val);
7613         break;
7614         case PORT_HW_CFG_TX_LASER_GPIO0:
7615         case PORT_HW_CFG_TX_LASER_GPIO1:
7616         case PORT_HW_CFG_TX_LASER_GPIO2:
7617         case PORT_HW_CFG_TX_LASER_GPIO3:
7618         {
7619                 u16 gpio_pin;
7620                 u8 gpio_port, gpio_mode;
7621                 if (tx_en)
7622                         gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH;
7623                 else
7624                         gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW;
7625
7626                 gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0;
7627                 gpio_port = bnx2x_get_gpio_port(params);
7628                 bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
7629                 break;
7630         }
7631         default:
7632                 DP(NETIF_MSG_LINK, "Invalid TX_LASER_MDIO 0x%x\n", tx_en_mode);
7633                 break;
7634         }
7635 }
7636
7637 static void bnx2x_sfp_set_transmitter(struct link_params *params,
7638                                       struct bnx2x_phy *phy,
7639                                       u8 tx_en)
7640 {
7641         struct bnx2x *bp = params->bp;
7642         DP(NETIF_MSG_LINK, "Setting SFP+ transmitter to %d\n", tx_en);
7643         if (CHIP_IS_E3(bp))
7644                 bnx2x_sfp_e3_set_transmitter(params, phy, tx_en);
7645         else
7646                 bnx2x_sfp_e1e2_set_transmitter(params, phy, tx_en);
7647 }
7648
7649 static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7650                                              struct link_params *params,
7651                                              u16 addr, u8 byte_cnt, u8 *o_buf)
7652 {
7653         struct bnx2x *bp = params->bp;
7654         u16 val = 0;
7655         u16 i;
7656         if (byte_cnt > 16) {
7657                 DP(NETIF_MSG_LINK,
7658                    "Reading from eeprom is limited to 0xf\n");
7659                 return -EINVAL;
7660         }
7661         /* Set the read command byte count */
7662         bnx2x_cl45_write(bp, phy,
7663                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
7664                          (byte_cnt | 0xa000));
7665
7666         /* Set the read command address */
7667         bnx2x_cl45_write(bp, phy,
7668                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
7669                          addr);
7670
7671         /* Activate read command */
7672         bnx2x_cl45_write(bp, phy,
7673                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7674                          0x2c0f);
7675
7676         /* Wait up to 500us for command complete status */
7677         for (i = 0; i < 100; i++) {
7678                 bnx2x_cl45_read(bp, phy,
7679                                 MDIO_PMA_DEVAD,
7680                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7681                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7682                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
7683                         break;
7684                 udelay(5);
7685         }
7686
7687         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
7688                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
7689                 DP(NETIF_MSG_LINK,
7690                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
7691                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
7692                 return -EINVAL;
7693         }
7694
7695         /* Read the buffer */
7696         for (i = 0; i < byte_cnt; i++) {
7697                 bnx2x_cl45_read(bp, phy,
7698                                 MDIO_PMA_DEVAD,
7699                                 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
7700                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
7701         }
7702
7703         for (i = 0; i < 100; i++) {
7704                 bnx2x_cl45_read(bp, phy,
7705                                 MDIO_PMA_DEVAD,
7706                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7707                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7708                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
7709                         return 0;
7710                 msleep(1);
7711         }
7712         return -EINVAL;
7713 }
7714
7715 static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7716                                                  struct link_params *params,
7717                                                  u16 addr, u8 byte_cnt,
7718                                                  u8 *o_buf)
7719 {
7720         int rc = 0;
7721         u8 i, j = 0, cnt = 0;
7722         u32 data_array[4];
7723         u16 addr32;
7724         struct bnx2x *bp = params->bp;
7725         /*DP(NETIF_MSG_LINK, "bnx2x_direct_read_sfp_module_eeprom:"
7726                                         " addr %d, cnt %d\n",
7727                                         addr, byte_cnt);*/
7728         if (byte_cnt > 16) {
7729                 DP(NETIF_MSG_LINK,
7730                    "Reading from eeprom is limited to 16 bytes\n");
7731                 return -EINVAL;
7732         }
7733
7734         /* 4 byte aligned address */
7735         addr32 = addr & (~0x3);
7736         do {
7737                 rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt,
7738                                     data_array);
7739         } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT));
7740
7741         if (rc == 0) {
7742                 for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) {
7743                         o_buf[j] = *((u8 *)data_array + i);
7744                         j++;
7745                 }
7746         }
7747
7748         return rc;
7749 }
7750
7751 static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7752                                              struct link_params *params,
7753                                              u16 addr, u8 byte_cnt, u8 *o_buf)
7754 {
7755         struct bnx2x *bp = params->bp;
7756         u16 val, i;
7757
7758         if (byte_cnt > 16) {
7759                 DP(NETIF_MSG_LINK,
7760                    "Reading from eeprom is limited to 0xf\n");
7761                 return -EINVAL;
7762         }
7763
7764         /* Need to read from 1.8000 to clear it */
7765         bnx2x_cl45_read(bp, phy,
7766                         MDIO_PMA_DEVAD,
7767                         MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7768                         &val);
7769
7770         /* Set the read command byte count */
7771         bnx2x_cl45_write(bp, phy,
7772                          MDIO_PMA_DEVAD,
7773                          MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
7774                          ((byte_cnt < 2) ? 2 : byte_cnt));
7775
7776         /* Set the read command address */
7777         bnx2x_cl45_write(bp, phy,
7778                          MDIO_PMA_DEVAD,
7779                          MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
7780                          addr);
7781         /* Set the destination address */
7782         bnx2x_cl45_write(bp, phy,
7783                          MDIO_PMA_DEVAD,
7784                          0x8004,
7785                          MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
7786
7787         /* Activate read command */
7788         bnx2x_cl45_write(bp, phy,
7789                          MDIO_PMA_DEVAD,
7790                          MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7791                          0x8002);
7792         /*
7793          * Wait appropriate time for two-wire command to finish before
7794          * polling the status register
7795          */
7796         msleep(1);
7797
7798         /* Wait up to 500us for command complete status */
7799         for (i = 0; i < 100; i++) {
7800                 bnx2x_cl45_read(bp, phy,
7801                                 MDIO_PMA_DEVAD,
7802                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7803                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7804                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
7805                         break;
7806                 udelay(5);
7807         }
7808
7809         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
7810                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
7811                 DP(NETIF_MSG_LINK,
7812                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
7813                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
7814                 return -EFAULT;
7815         }
7816
7817         /* Read the buffer */
7818         for (i = 0; i < byte_cnt; i++) {
7819                 bnx2x_cl45_read(bp, phy,
7820                                 MDIO_PMA_DEVAD,
7821                                 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
7822                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
7823         }
7824
7825         for (i = 0; i < 100; i++) {
7826                 bnx2x_cl45_read(bp, phy,
7827                                 MDIO_PMA_DEVAD,
7828                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7829                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7830                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
7831                         return 0;
7832                 msleep(1);
7833         }
7834
7835         return -EINVAL;
7836 }
7837
7838 int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7839                                  struct link_params *params, u16 addr,
7840                                  u8 byte_cnt, u8 *o_buf)
7841 {
7842         int rc = -EINVAL;
7843         switch (phy->type) {
7844         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7845                 rc = bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
7846                                                        byte_cnt, o_buf);
7847         break;
7848         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7849         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
7850                 rc = bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
7851                                                        byte_cnt, o_buf);
7852         break;
7853         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
7854                 rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr,
7855                                                            byte_cnt, o_buf);
7856         break;
7857         }
7858         return rc;
7859 }
7860
7861 static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
7862                               struct link_params *params,
7863                               u16 *edc_mode)
7864 {
7865         struct bnx2x *bp = params->bp;
7866         u32 sync_offset = 0, phy_idx, media_types;
7867         u8 val, check_limiting_mode = 0;
7868         *edc_mode = EDC_MODE_LIMITING;
7869
7870         phy->media_type = ETH_PHY_UNSPECIFIED;
7871         /* First check for copper cable */
7872         if (bnx2x_read_sfp_module_eeprom(phy,
7873                                          params,
7874                                          SFP_EEPROM_CON_TYPE_ADDR,
7875                                          1,
7876                                          &val) != 0) {
7877                 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
7878                 return -EINVAL;
7879         }
7880
7881         switch (val) {
7882         case SFP_EEPROM_CON_TYPE_VAL_COPPER:
7883         {
7884                 u8 copper_module_type;
7885                 phy->media_type = ETH_PHY_DA_TWINAX;
7886                 /*
7887                  * Check if its active cable (includes SFP+ module)
7888                  * of passive cable
7889                  */
7890                 if (bnx2x_read_sfp_module_eeprom(phy,
7891                                                params,
7892                                                SFP_EEPROM_FC_TX_TECH_ADDR,
7893                                                1,
7894                                                &copper_module_type) != 0) {
7895                         DP(NETIF_MSG_LINK,
7896                                 "Failed to read copper-cable-type"
7897                                 " from SFP+ EEPROM\n");
7898                         return -EINVAL;
7899                 }
7900
7901                 if (copper_module_type &
7902                     SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
7903                         DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
7904                         check_limiting_mode = 1;
7905                 } else if (copper_module_type &
7906                         SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
7907                                 DP(NETIF_MSG_LINK,
7908                                    "Passive Copper cable detected\n");
7909                                 *edc_mode =
7910                                       EDC_MODE_PASSIVE_DAC;
7911                 } else {
7912                         DP(NETIF_MSG_LINK,
7913                            "Unknown copper-cable-type 0x%x !!!\n",
7914                            copper_module_type);
7915                         return -EINVAL;
7916                 }
7917                 break;
7918         }
7919         case SFP_EEPROM_CON_TYPE_VAL_LC:
7920                 phy->media_type = ETH_PHY_SFP_FIBER;
7921                 DP(NETIF_MSG_LINK, "Optic module detected\n");
7922                 check_limiting_mode = 1;
7923                 break;
7924         default:
7925                 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
7926                          val);
7927                 return -EINVAL;
7928         }
7929         sync_offset = params->shmem_base +
7930                 offsetof(struct shmem_region,
7931                          dev_info.port_hw_config[params->port].media_type);
7932         media_types = REG_RD(bp, sync_offset);
7933         /* Update media type for non-PMF sync */
7934         for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
7935                 if (&(params->phy[phy_idx]) == phy) {
7936                         media_types &= ~(PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
7937                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
7938                         media_types |= ((phy->media_type &
7939                                         PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
7940                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
7941                         break;
7942                 }
7943         }
7944         REG_WR(bp, sync_offset, media_types);
7945         if (check_limiting_mode) {
7946                 u8 options[SFP_EEPROM_OPTIONS_SIZE];
7947                 if (bnx2x_read_sfp_module_eeprom(phy,
7948                                                  params,
7949                                                  SFP_EEPROM_OPTIONS_ADDR,
7950                                                  SFP_EEPROM_OPTIONS_SIZE,
7951                                                  options) != 0) {
7952                         DP(NETIF_MSG_LINK,
7953                            "Failed to read Option field from module EEPROM\n");
7954                         return -EINVAL;
7955                 }
7956                 if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
7957                         *edc_mode = EDC_MODE_LINEAR;
7958                 else
7959                         *edc_mode = EDC_MODE_LIMITING;
7960         }
7961         DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
7962         return 0;
7963 }
7964 /*
7965  * This function read the relevant field from the module (SFP+), and verify it
7966  * is compliant with this board
7967  */
7968 static int bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
7969                                    struct link_params *params)
7970 {
7971         struct bnx2x *bp = params->bp;
7972         u32 val, cmd;
7973         u32 fw_resp, fw_cmd_param;
7974         char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
7975         char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
7976         phy->flags &= ~FLAGS_SFP_NOT_APPROVED;
7977         val = REG_RD(bp, params->shmem_base +
7978                          offsetof(struct shmem_region, dev_info.
7979                                   port_feature_config[params->port].config));
7980         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
7981             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
7982                 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
7983                 return 0;
7984         }
7985
7986         if (params->feature_config_flags &
7987             FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
7988                 /* Use specific phy request */
7989                 cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
7990         } else if (params->feature_config_flags &
7991                    FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
7992                 /* Use first phy request only in case of non-dual media*/
7993                 if (DUAL_MEDIA(params)) {
7994                         DP(NETIF_MSG_LINK,
7995                            "FW does not support OPT MDL verification\n");
7996                         return -EINVAL;
7997                 }
7998                 cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
7999         } else {
8000                 /* No support in OPT MDL detection */
8001                 DP(NETIF_MSG_LINK,
8002                    "FW does not support OPT MDL verification\n");
8003                 return -EINVAL;
8004         }
8005
8006         fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
8007         fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param);
8008         if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
8009                 DP(NETIF_MSG_LINK, "Approved module\n");
8010                 return 0;
8011         }
8012
8013         /* format the warning message */
8014         if (bnx2x_read_sfp_module_eeprom(phy,
8015                                          params,
8016                                          SFP_EEPROM_VENDOR_NAME_ADDR,
8017                                          SFP_EEPROM_VENDOR_NAME_SIZE,
8018                                          (u8 *)vendor_name))
8019                 vendor_name[0] = '\0';
8020         else
8021                 vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
8022         if (bnx2x_read_sfp_module_eeprom(phy,
8023                                          params,
8024                                          SFP_EEPROM_PART_NO_ADDR,
8025                                          SFP_EEPROM_PART_NO_SIZE,
8026                                          (u8 *)vendor_pn))
8027                 vendor_pn[0] = '\0';
8028         else
8029                 vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
8030
8031         netdev_err(bp->dev,  "Warning: Unqualified SFP+ module detected,"
8032                               " Port %d from %s part number %s\n",
8033                          params->port, vendor_name, vendor_pn);
8034         phy->flags |= FLAGS_SFP_NOT_APPROVED;
8035         return -EINVAL;
8036 }
8037
8038 static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
8039                                                  struct link_params *params)
8040
8041 {
8042         u8 val;
8043         struct bnx2x *bp = params->bp;
8044         u16 timeout;
8045         /*
8046          * Initialization time after hot-plug may take up to 300ms for
8047          * some phys type ( e.g. JDSU )
8048          */
8049
8050         for (timeout = 0; timeout < 60; timeout++) {
8051                 if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
8052                     == 0) {
8053                         DP(NETIF_MSG_LINK,
8054                            "SFP+ module initialization took %d ms\n",
8055                            timeout * 5);
8056                         return 0;
8057                 }
8058                 msleep(5);
8059         }
8060         return -EINVAL;
8061 }
8062
8063 static void bnx2x_8727_power_module(struct bnx2x *bp,
8064                                     struct bnx2x_phy *phy,
8065                                     u8 is_power_up) {
8066         /* Make sure GPIOs are not using for LED mode */
8067         u16 val;
8068         /*
8069          * In the GPIO register, bit 4 is use to determine if the GPIOs are
8070          * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
8071          * output
8072          * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0
8073          * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1
8074          * where the 1st bit is the over-current(only input), and 2nd bit is
8075          * for power( only output )
8076          *
8077          * In case of NOC feature is disabled and power is up, set GPIO control
8078          *  as input to enable listening of over-current indication
8079          */
8080         if (phy->flags & FLAGS_NOC)
8081                 return;
8082         if (is_power_up)
8083                 val = (1<<4);
8084         else
8085                 /*
8086                  * Set GPIO control to OUTPUT, and set the power bit
8087                  * to according to the is_power_up
8088                  */
8089                 val = (1<<1);
8090
8091         bnx2x_cl45_write(bp, phy,
8092                          MDIO_PMA_DEVAD,
8093                          MDIO_PMA_REG_8727_GPIO_CTRL,
8094                          val);
8095 }
8096
8097 static int bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
8098                                         struct bnx2x_phy *phy,
8099                                         u16 edc_mode)
8100 {
8101         u16 cur_limiting_mode;
8102
8103         bnx2x_cl45_read(bp, phy,
8104                         MDIO_PMA_DEVAD,
8105                         MDIO_PMA_REG_ROM_VER2,
8106                         &cur_limiting_mode);
8107         DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
8108                  cur_limiting_mode);
8109
8110         if (edc_mode == EDC_MODE_LIMITING) {
8111                 DP(NETIF_MSG_LINK, "Setting LIMITING MODE\n");
8112                 bnx2x_cl45_write(bp, phy,
8113                                  MDIO_PMA_DEVAD,
8114                                  MDIO_PMA_REG_ROM_VER2,
8115                                  EDC_MODE_LIMITING);
8116         } else { /* LRM mode ( default )*/
8117
8118                 DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
8119
8120                 /*
8121                  * Changing to LRM mode takes quite few seconds. So do it only
8122                  * if current mode is limiting (default is LRM)
8123                  */
8124                 if (cur_limiting_mode != EDC_MODE_LIMITING)
8125                         return 0;
8126
8127                 bnx2x_cl45_write(bp, phy,
8128                                  MDIO_PMA_DEVAD,
8129                                  MDIO_PMA_REG_LRM_MODE,
8130                                  0);
8131                 bnx2x_cl45_write(bp, phy,
8132                                  MDIO_PMA_DEVAD,
8133                                  MDIO_PMA_REG_ROM_VER2,
8134                                  0x128);
8135                 bnx2x_cl45_write(bp, phy,
8136                                  MDIO_PMA_DEVAD,
8137                                  MDIO_PMA_REG_MISC_CTRL0,
8138                                  0x4008);
8139                 bnx2x_cl45_write(bp, phy,
8140                                  MDIO_PMA_DEVAD,
8141                                  MDIO_PMA_REG_LRM_MODE,
8142                                  0xaaaa);
8143         }
8144         return 0;
8145 }
8146
8147 static int bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
8148                                         struct bnx2x_phy *phy,
8149                                         u16 edc_mode)
8150 {
8151         u16 phy_identifier;
8152         u16 rom_ver2_val;
8153         bnx2x_cl45_read(bp, phy,
8154                         MDIO_PMA_DEVAD,
8155                         MDIO_PMA_REG_PHY_IDENTIFIER,
8156                         &phy_identifier);
8157
8158         bnx2x_cl45_write(bp, phy,
8159                          MDIO_PMA_DEVAD,
8160                          MDIO_PMA_REG_PHY_IDENTIFIER,
8161                          (phy_identifier & ~(1<<9)));
8162
8163         bnx2x_cl45_read(bp, phy,
8164                         MDIO_PMA_DEVAD,
8165                         MDIO_PMA_REG_ROM_VER2,
8166                         &rom_ver2_val);
8167         /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
8168         bnx2x_cl45_write(bp, phy,
8169                          MDIO_PMA_DEVAD,
8170                          MDIO_PMA_REG_ROM_VER2,
8171                          (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
8172
8173         bnx2x_cl45_write(bp, phy,
8174                          MDIO_PMA_DEVAD,
8175                          MDIO_PMA_REG_PHY_IDENTIFIER,
8176                          (phy_identifier | (1<<9)));
8177
8178         return 0;
8179 }
8180
8181 static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
8182                                      struct link_params *params,
8183                                      u32 action)
8184 {
8185         struct bnx2x *bp = params->bp;
8186
8187         switch (action) {
8188         case DISABLE_TX:
8189                 bnx2x_sfp_set_transmitter(params, phy, 0);
8190                 break;
8191         case ENABLE_TX:
8192                 if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
8193                         bnx2x_sfp_set_transmitter(params, phy, 1);
8194                 break;
8195         default:
8196                 DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
8197                    action);
8198                 return;
8199         }
8200 }
8201
8202 static void bnx2x_set_e1e2_module_fault_led(struct link_params *params,
8203                                            u8 gpio_mode)
8204 {
8205         struct bnx2x *bp = params->bp;
8206
8207         u32 fault_led_gpio = REG_RD(bp, params->shmem_base +
8208                             offsetof(struct shmem_region,
8209                         dev_info.port_hw_config[params->port].sfp_ctrl)) &
8210                 PORT_HW_CFG_FAULT_MODULE_LED_MASK;
8211         switch (fault_led_gpio) {
8212         case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED:
8213                 return;
8214         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0:
8215         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1:
8216         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2:
8217         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3:
8218         {
8219                 u8 gpio_port = bnx2x_get_gpio_port(params);
8220                 u16 gpio_pin = fault_led_gpio -
8221                         PORT_HW_CFG_FAULT_MODULE_LED_GPIO0;
8222                 DP(NETIF_MSG_LINK, "Set fault module-detected led "
8223                                    "pin %x port %x mode %x\n",
8224                                gpio_pin, gpio_port, gpio_mode);
8225                 bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
8226         }
8227         break;
8228         default:
8229                 DP(NETIF_MSG_LINK, "Error: Invalid fault led mode 0x%x\n",
8230                                fault_led_gpio);
8231         }
8232 }
8233
8234 static void bnx2x_set_e3_module_fault_led(struct link_params *params,
8235                                           u8 gpio_mode)
8236 {
8237         u32 pin_cfg;
8238         u8 port = params->port;
8239         struct bnx2x *bp = params->bp;
8240         pin_cfg = (REG_RD(bp, params->shmem_base +
8241                          offsetof(struct shmem_region,
8242                                   dev_info.port_hw_config[port].e3_sfp_ctrl)) &
8243                 PORT_HW_CFG_E3_FAULT_MDL_LED_MASK) >>
8244                 PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT;
8245         DP(NETIF_MSG_LINK, "Setting Fault LED to %d using pin cfg %d\n",
8246                        gpio_mode, pin_cfg);
8247         bnx2x_set_cfg_pin(bp, pin_cfg, gpio_mode);
8248 }
8249
8250 static void bnx2x_set_sfp_module_fault_led(struct link_params *params,
8251                                            u8 gpio_mode)
8252 {
8253         struct bnx2x *bp = params->bp;
8254         DP(NETIF_MSG_LINK, "Setting SFP+ module fault LED to %d\n", gpio_mode);
8255         if (CHIP_IS_E3(bp)) {
8256                 /*
8257                  * Low ==> if SFP+ module is supported otherwise
8258                  * High ==> if SFP+ module is not on the approved vendor list
8259                  */
8260                 bnx2x_set_e3_module_fault_led(params, gpio_mode);
8261         } else
8262                 bnx2x_set_e1e2_module_fault_led(params, gpio_mode);
8263 }
8264
8265 static void bnx2x_warpcore_power_module(struct link_params *params,
8266                                         struct bnx2x_phy *phy,
8267                                         u8 power)
8268 {
8269         u32 pin_cfg;
8270         struct bnx2x *bp = params->bp;
8271
8272         pin_cfg = (REG_RD(bp, params->shmem_base +
8273                           offsetof(struct shmem_region,
8274                         dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
8275                         PORT_HW_CFG_E3_PWR_DIS_MASK) >>
8276                         PORT_HW_CFG_E3_PWR_DIS_SHIFT;
8277
8278         if (pin_cfg == PIN_CFG_NA)
8279                 return;
8280         DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n",
8281                        power, pin_cfg);
8282         /*
8283          * Low ==> corresponding SFP+ module is powered
8284          * high ==> the SFP+ module is powered down
8285          */
8286         bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1);
8287 }
8288
8289 static void bnx2x_warpcore_hw_reset(struct bnx2x_phy *phy,
8290                                     struct link_params *params)
8291 {
8292         struct bnx2x *bp = params->bp;
8293         bnx2x_warpcore_power_module(params, phy, 0);
8294         /* Put Warpcore in low power mode */
8295         REG_WR(bp, MISC_REG_WC0_RESET, 0x0c0e);
8296
8297         /* Put LCPLL in low power mode */
8298         REG_WR(bp, MISC_REG_LCPLL_E40_PWRDWN, 1);
8299         REG_WR(bp, MISC_REG_LCPLL_E40_RESETB_ANA, 0);
8300         REG_WR(bp, MISC_REG_LCPLL_E40_RESETB_DIG, 0);
8301 }
8302
8303 static void bnx2x_power_sfp_module(struct link_params *params,
8304                                    struct bnx2x_phy *phy,
8305                                    u8 power)
8306 {
8307         struct bnx2x *bp = params->bp;
8308         DP(NETIF_MSG_LINK, "Setting SFP+ power to %x\n", power);
8309
8310         switch (phy->type) {
8311         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
8312         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
8313                 bnx2x_8727_power_module(params->bp, phy, power);
8314                 break;
8315         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
8316                 bnx2x_warpcore_power_module(params, phy, power);
8317                 break;
8318         default:
8319                 break;
8320         }
8321 }
8322 static void bnx2x_warpcore_set_limiting_mode(struct link_params *params,
8323                                              struct bnx2x_phy *phy,
8324                                              u16 edc_mode)
8325 {
8326         u16 val = 0;
8327         u16 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
8328         struct bnx2x *bp = params->bp;
8329
8330         u8 lane = bnx2x_get_warpcore_lane(phy, params);
8331         /* This is a global register which controls all lanes */
8332         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
8333                         MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
8334         val &= ~(0xf << (lane << 2));
8335
8336         switch (edc_mode) {
8337         case EDC_MODE_LINEAR:
8338         case EDC_MODE_LIMITING:
8339                 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
8340                 break;
8341         case EDC_MODE_PASSIVE_DAC:
8342                 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC;
8343                 break;
8344         default:
8345                 break;
8346         }
8347
8348         val |= (mode << (lane << 2));
8349         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
8350                          MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, val);
8351         /* A must read */
8352         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
8353                         MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
8354
8355         /* Restart microcode to re-read the new mode */
8356         bnx2x_warpcore_reset_lane(bp, phy, 1);
8357         bnx2x_warpcore_reset_lane(bp, phy, 0);
8358
8359 }
8360
8361 static void bnx2x_set_limiting_mode(struct link_params *params,
8362                                     struct bnx2x_phy *phy,
8363                                     u16 edc_mode)
8364 {
8365         switch (phy->type) {
8366         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
8367                 bnx2x_8726_set_limiting_mode(params->bp, phy, edc_mode);
8368                 break;
8369         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
8370         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
8371                 bnx2x_8727_set_limiting_mode(params->bp, phy, edc_mode);
8372                 break;
8373         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
8374                 bnx2x_warpcore_set_limiting_mode(params, phy, edc_mode);
8375                 break;
8376         }
8377 }
8378
8379 int bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
8380                                struct link_params *params)
8381 {
8382         struct bnx2x *bp = params->bp;
8383         u16 edc_mode;
8384         int rc = 0;
8385
8386         u32 val = REG_RD(bp, params->shmem_base +
8387                              offsetof(struct shmem_region, dev_info.
8388                                      port_feature_config[params->port].config));
8389
8390         DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
8391                  params->port);
8392         /* Power up module */
8393         bnx2x_power_sfp_module(params, phy, 1);
8394         if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
8395                 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
8396                 return -EINVAL;
8397         } else if (bnx2x_verify_sfp_module(phy, params) != 0) {
8398                 /* check SFP+ module compatibility */
8399                 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
8400                 rc = -EINVAL;
8401                 /* Turn on fault module-detected led */
8402                 bnx2x_set_sfp_module_fault_led(params,
8403                                                MISC_REGISTERS_GPIO_HIGH);
8404
8405                 /* Check if need to power down the SFP+ module */
8406                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8407                      PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN) {
8408                         DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
8409                         bnx2x_power_sfp_module(params, phy, 0);
8410                         return rc;
8411                 }
8412         } else {
8413                 /* Turn off fault module-detected led */
8414                 bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
8415         }
8416
8417         /*
8418          * Check and set limiting mode / LRM mode on 8726. On 8727 it
8419          * is done automatically
8420          */
8421         bnx2x_set_limiting_mode(params, phy, edc_mode);
8422
8423         /*
8424          * Enable transmit for this module if the module is approved, or
8425          * if unapproved modules should also enable the Tx laser
8426          */
8427         if (rc == 0 ||
8428             (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
8429             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
8430                 bnx2x_sfp_set_transmitter(params, phy, 1);
8431         else
8432                 bnx2x_sfp_set_transmitter(params, phy, 0);
8433
8434         return rc;
8435 }
8436
8437 void bnx2x_handle_module_detect_int(struct link_params *params)
8438 {
8439         struct bnx2x *bp = params->bp;
8440         struct bnx2x_phy *phy;
8441         u32 gpio_val;
8442         u8 gpio_num, gpio_port;
8443         if (CHIP_IS_E3(bp))
8444                 phy = &params->phy[INT_PHY];
8445         else
8446                 phy = &params->phy[EXT_PHY1];
8447
8448         if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id, params->shmem_base,
8449                                       params->port, &gpio_num, &gpio_port) ==
8450             -EINVAL) {
8451                 DP(NETIF_MSG_LINK, "Failed to get MOD_ABS interrupt config\n");
8452                 return;
8453         }
8454
8455         /* Set valid module led off */
8456         bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH);
8457
8458         /* Get current gpio val reflecting module plugged in / out*/
8459         gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
8460
8461         /* Call the handling function in case module is detected */
8462         if (gpio_val == 0) {
8463                 bnx2x_power_sfp_module(params, phy, 1);
8464                 bnx2x_set_gpio_int(bp, gpio_num,
8465                                    MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
8466                                    gpio_port);
8467                 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
8468                         bnx2x_sfp_module_detection(phy, params);
8469                 else
8470                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
8471         } else {
8472                 u32 val = REG_RD(bp, params->shmem_base +
8473                                  offsetof(struct shmem_region, dev_info.
8474                                           port_feature_config[params->port].
8475                                           config));
8476                 bnx2x_set_gpio_int(bp, gpio_num,
8477                                    MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
8478                                    gpio_port);
8479                 /*
8480                  * Module was plugged out.
8481                  * Disable transmit for this module
8482                  */
8483                 phy->media_type = ETH_PHY_NOT_PRESENT;
8484                 if (((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8485                      PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) ||
8486                     CHIP_IS_E3(bp))
8487                         bnx2x_sfp_set_transmitter(params, phy, 0);
8488         }
8489 }
8490
8491 /******************************************************************/
8492 /*              Used by 8706 and 8727                             */
8493 /******************************************************************/
8494 static void bnx2x_sfp_mask_fault(struct bnx2x *bp,
8495                                  struct bnx2x_phy *phy,
8496                                  u16 alarm_status_offset,
8497                                  u16 alarm_ctrl_offset)
8498 {
8499         u16 alarm_status, val;
8500         bnx2x_cl45_read(bp, phy,
8501                         MDIO_PMA_DEVAD, alarm_status_offset,
8502                         &alarm_status);
8503         bnx2x_cl45_read(bp, phy,
8504                         MDIO_PMA_DEVAD, alarm_status_offset,
8505                         &alarm_status);
8506         /* Mask or enable the fault event. */
8507         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, &val);
8508         if (alarm_status & (1<<0))
8509                 val &= ~(1<<0);
8510         else
8511                 val |= (1<<0);
8512         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, val);
8513 }
8514 /******************************************************************/
8515 /*              common BCM8706/BCM8726 PHY SECTION                */
8516 /******************************************************************/
8517 static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
8518                                       struct link_params *params,
8519                                       struct link_vars *vars)
8520 {
8521         u8 link_up = 0;
8522         u16 val1, val2, rx_sd, pcs_status;
8523         struct bnx2x *bp = params->bp;
8524         DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
8525         /* Clear RX Alarm*/
8526         bnx2x_cl45_read(bp, phy,
8527                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
8528
8529         bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT,
8530                              MDIO_PMA_LASI_TXCTRL);
8531
8532         /* clear LASI indication*/
8533         bnx2x_cl45_read(bp, phy,
8534                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
8535         bnx2x_cl45_read(bp, phy,
8536                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
8537         DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
8538
8539         bnx2x_cl45_read(bp, phy,
8540                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
8541         bnx2x_cl45_read(bp, phy,
8542                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
8543         bnx2x_cl45_read(bp, phy,
8544                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
8545         bnx2x_cl45_read(bp, phy,
8546                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
8547
8548         DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
8549                         " link_status 0x%x\n", rx_sd, pcs_status, val2);
8550         /*
8551          * link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
8552          * are set, or if the autoneg bit 1 is set
8553          */
8554         link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
8555         if (link_up) {
8556                 if (val2 & (1<<1))
8557                         vars->line_speed = SPEED_1000;
8558                 else
8559                         vars->line_speed = SPEED_10000;
8560                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
8561                 vars->duplex = DUPLEX_FULL;
8562         }
8563
8564         /* Capture 10G link fault. Read twice to clear stale value. */
8565         if (vars->line_speed == SPEED_10000) {
8566                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
8567                             MDIO_PMA_LASI_TXSTAT, &val1);
8568                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
8569                             MDIO_PMA_LASI_TXSTAT, &val1);
8570                 if (val1 & (1<<0))
8571                         vars->fault_detected = 1;
8572         }
8573
8574         return link_up;
8575 }
8576
8577 /******************************************************************/
8578 /*                      BCM8706 PHY SECTION                       */
8579 /******************************************************************/
8580 static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
8581                                  struct link_params *params,
8582                                  struct link_vars *vars)
8583 {
8584         u32 tx_en_mode;
8585         u16 cnt, val, tmp1;
8586         struct bnx2x *bp = params->bp;
8587
8588         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
8589                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
8590         /* HW reset */
8591         bnx2x_ext_phy_hw_reset(bp, params->port);
8592         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
8593         bnx2x_wait_reset_complete(bp, phy, params);
8594
8595         /* Wait until fw is loaded */
8596         for (cnt = 0; cnt < 100; cnt++) {
8597                 bnx2x_cl45_read(bp, phy,
8598                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
8599                 if (val)
8600                         break;
8601                 msleep(10);
8602         }
8603         DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt);
8604         if ((params->feature_config_flags &
8605              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
8606                 u8 i;
8607                 u16 reg;
8608                 for (i = 0; i < 4; i++) {
8609                         reg = MDIO_XS_8706_REG_BANK_RX0 +
8610                                 i*(MDIO_XS_8706_REG_BANK_RX1 -
8611                                    MDIO_XS_8706_REG_BANK_RX0);
8612                         bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val);
8613                         /* Clear first 3 bits of the control */
8614                         val &= ~0x7;
8615                         /* Set control bits according to configuration */
8616                         val |= (phy->rx_preemphasis[i] & 0x7);
8617                         DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706"
8618                                    " reg 0x%x <-- val 0x%x\n", reg, val);
8619                         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val);
8620                 }
8621         }
8622         /* Force speed */
8623         if (phy->req_line_speed == SPEED_10000) {
8624                 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
8625
8626                 bnx2x_cl45_write(bp, phy,
8627                                  MDIO_PMA_DEVAD,
8628                                  MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
8629                 bnx2x_cl45_write(bp, phy,
8630                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
8631                                  0);
8632                 /* Arm LASI for link and Tx fault. */
8633                 bnx2x_cl45_write(bp, phy,
8634                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 3);
8635         } else {
8636                 /* Force 1Gbps using autoneg with 1G advertisement */
8637
8638                 /* Allow CL37 through CL73 */
8639                 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
8640                 bnx2x_cl45_write(bp, phy,
8641                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
8642
8643                 /* Enable Full-Duplex advertisement on CL37 */
8644                 bnx2x_cl45_write(bp, phy,
8645                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
8646                 /* Enable CL37 AN */
8647                 bnx2x_cl45_write(bp, phy,
8648                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8649                 /* 1G support */
8650                 bnx2x_cl45_write(bp, phy,
8651                                  MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
8652
8653                 /* Enable clause 73 AN */
8654                 bnx2x_cl45_write(bp, phy,
8655                                  MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
8656                 bnx2x_cl45_write(bp, phy,
8657                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8658                                  0x0400);
8659                 bnx2x_cl45_write(bp, phy,
8660                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
8661                                  0x0004);
8662         }
8663         bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
8664
8665         /*
8666          * If TX Laser is controlled by GPIO_0, do not let PHY go into low
8667          * power mode, if TX Laser is disabled
8668          */
8669
8670         tx_en_mode = REG_RD(bp, params->shmem_base +
8671                             offsetof(struct shmem_region,
8672                                 dev_info.port_hw_config[params->port].sfp_ctrl))
8673                         & PORT_HW_CFG_TX_LASER_MASK;
8674
8675         if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
8676                 DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
8677                 bnx2x_cl45_read(bp, phy,
8678                         MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1);
8679                 tmp1 |= 0x1;
8680                 bnx2x_cl45_write(bp, phy,
8681                         MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1);
8682         }
8683
8684         return 0;
8685 }
8686
8687 static int bnx2x_8706_read_status(struct bnx2x_phy *phy,
8688                                   struct link_params *params,
8689                                   struct link_vars *vars)
8690 {
8691         return bnx2x_8706_8726_read_status(phy, params, vars);
8692 }
8693
8694 /******************************************************************/
8695 /*                      BCM8726 PHY SECTION                       */
8696 /******************************************************************/
8697 static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
8698                                        struct link_params *params)
8699 {
8700         struct bnx2x *bp = params->bp;
8701         DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
8702         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
8703 }
8704
8705 static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
8706                                          struct link_params *params)
8707 {
8708         struct bnx2x *bp = params->bp;
8709         /* Need to wait 100ms after reset */
8710         msleep(100);
8711
8712         /* Micro controller re-boot */
8713         bnx2x_cl45_write(bp, phy,
8714                          MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
8715
8716         /* Set soft reset */
8717         bnx2x_cl45_write(bp, phy,
8718                          MDIO_PMA_DEVAD,
8719                          MDIO_PMA_REG_GEN_CTRL,
8720                          MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
8721
8722         bnx2x_cl45_write(bp, phy,
8723                          MDIO_PMA_DEVAD,
8724                          MDIO_PMA_REG_MISC_CTRL1, 0x0001);
8725
8726         bnx2x_cl45_write(bp, phy,
8727                          MDIO_PMA_DEVAD,
8728                          MDIO_PMA_REG_GEN_CTRL,
8729                          MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
8730
8731         /* wait for 150ms for microcode load */
8732         msleep(150);
8733
8734         /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
8735         bnx2x_cl45_write(bp, phy,
8736                          MDIO_PMA_DEVAD,
8737                          MDIO_PMA_REG_MISC_CTRL1, 0x0000);
8738
8739         msleep(200);
8740         bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
8741 }
8742
8743 static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
8744                                  struct link_params *params,
8745                                  struct link_vars *vars)
8746 {
8747         struct bnx2x *bp = params->bp;
8748         u16 val1;
8749         u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
8750         if (link_up) {
8751                 bnx2x_cl45_read(bp, phy,
8752                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
8753                                 &val1);
8754                 if (val1 & (1<<15)) {
8755                         DP(NETIF_MSG_LINK, "Tx is disabled\n");
8756                         link_up = 0;
8757                         vars->line_speed = 0;
8758                 }
8759         }
8760         return link_up;
8761 }
8762
8763
8764 static int bnx2x_8726_config_init(struct bnx2x_phy *phy,
8765                                   struct link_params *params,
8766                                   struct link_vars *vars)
8767 {
8768         struct bnx2x *bp = params->bp;
8769         DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
8770
8771         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
8772         bnx2x_wait_reset_complete(bp, phy, params);
8773
8774         bnx2x_8726_external_rom_boot(phy, params);
8775
8776         /*
8777          * Need to call module detected on initialization since the module
8778          * detection triggered by actual module insertion might occur before
8779          * driver is loaded, and when driver is loaded, it reset all
8780          * registers, including the transmitter
8781          */
8782         bnx2x_sfp_module_detection(phy, params);
8783
8784         if (phy->req_line_speed == SPEED_1000) {
8785                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
8786                 bnx2x_cl45_write(bp, phy,
8787                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
8788                 bnx2x_cl45_write(bp, phy,
8789                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
8790                 bnx2x_cl45_write(bp, phy,
8791                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x5);
8792                 bnx2x_cl45_write(bp, phy,
8793                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8794                                  0x400);
8795         } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
8796                    (phy->speed_cap_mask &
8797                       PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
8798                    ((phy->speed_cap_mask &
8799                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
8800                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
8801                 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
8802                 /* Set Flow control */
8803                 bnx2x_ext_phy_set_pause(params, phy, vars);
8804                 bnx2x_cl45_write(bp, phy,
8805                                  MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
8806                 bnx2x_cl45_write(bp, phy,
8807                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
8808                 bnx2x_cl45_write(bp, phy,
8809                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
8810                 bnx2x_cl45_write(bp, phy,
8811                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8812                 bnx2x_cl45_write(bp, phy,
8813                                 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
8814                 /*
8815                  * Enable RX-ALARM control to receive interrupt for 1G speed
8816                  * change
8817                  */
8818                 bnx2x_cl45_write(bp, phy,
8819                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x4);
8820                 bnx2x_cl45_write(bp, phy,
8821                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8822                                  0x400);
8823
8824         } else { /* Default 10G. Set only LASI control */
8825                 bnx2x_cl45_write(bp, phy,
8826                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 1);
8827         }
8828
8829         /* Set TX PreEmphasis if needed */
8830         if ((params->feature_config_flags &
8831              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
8832                 DP(NETIF_MSG_LINK,
8833                    "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
8834                          phy->tx_preemphasis[0],
8835                          phy->tx_preemphasis[1]);
8836                 bnx2x_cl45_write(bp, phy,
8837                                  MDIO_PMA_DEVAD,
8838                                  MDIO_PMA_REG_8726_TX_CTRL1,
8839                                  phy->tx_preemphasis[0]);
8840
8841                 bnx2x_cl45_write(bp, phy,
8842                                  MDIO_PMA_DEVAD,
8843                                  MDIO_PMA_REG_8726_TX_CTRL2,
8844                                  phy->tx_preemphasis[1]);
8845         }
8846
8847         return 0;
8848
8849 }
8850
8851 static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
8852                                   struct link_params *params)
8853 {
8854         struct bnx2x *bp = params->bp;
8855         DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
8856         /* Set serial boot control for external load */
8857         bnx2x_cl45_write(bp, phy,
8858                          MDIO_PMA_DEVAD,
8859                          MDIO_PMA_REG_GEN_CTRL, 0x0001);
8860 }
8861
8862 /******************************************************************/
8863 /*                      BCM8727 PHY SECTION                       */
8864 /******************************************************************/
8865
8866 static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy,
8867                                     struct link_params *params, u8 mode)
8868 {
8869         struct bnx2x *bp = params->bp;
8870         u16 led_mode_bitmask = 0;
8871         u16 gpio_pins_bitmask = 0;
8872         u16 val;
8873         /* Only NOC flavor requires to set the LED specifically */
8874         if (!(phy->flags & FLAGS_NOC))
8875                 return;
8876         switch (mode) {
8877         case LED_MODE_FRONT_PANEL_OFF:
8878         case LED_MODE_OFF:
8879                 led_mode_bitmask = 0;
8880                 gpio_pins_bitmask = 0x03;
8881                 break;
8882         case LED_MODE_ON:
8883                 led_mode_bitmask = 0;
8884                 gpio_pins_bitmask = 0x02;
8885                 break;
8886         case LED_MODE_OPER:
8887                 led_mode_bitmask = 0x60;
8888                 gpio_pins_bitmask = 0x11;
8889                 break;
8890         }
8891         bnx2x_cl45_read(bp, phy,
8892                         MDIO_PMA_DEVAD,
8893                         MDIO_PMA_REG_8727_PCS_OPT_CTRL,
8894                         &val);
8895         val &= 0xff8f;
8896         val |= led_mode_bitmask;
8897         bnx2x_cl45_write(bp, phy,
8898                          MDIO_PMA_DEVAD,
8899                          MDIO_PMA_REG_8727_PCS_OPT_CTRL,
8900                          val);
8901         bnx2x_cl45_read(bp, phy,
8902                         MDIO_PMA_DEVAD,
8903                         MDIO_PMA_REG_8727_GPIO_CTRL,
8904                         &val);
8905         val &= 0xffe0;
8906         val |= gpio_pins_bitmask;
8907         bnx2x_cl45_write(bp, phy,
8908                          MDIO_PMA_DEVAD,
8909                          MDIO_PMA_REG_8727_GPIO_CTRL,
8910                          val);
8911 }
8912 static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
8913                                 struct link_params *params) {
8914         u32 swap_val, swap_override;
8915         u8 port;
8916         /*
8917          * The PHY reset is controlled by GPIO 1. Fake the port number
8918          * to cancel the swap done in set_gpio()
8919          */
8920         struct bnx2x *bp = params->bp;
8921         swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
8922         swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
8923         port = (swap_val && swap_override) ^ 1;
8924         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
8925                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
8926 }
8927
8928 static int bnx2x_8727_config_init(struct bnx2x_phy *phy,
8929                                   struct link_params *params,
8930                                   struct link_vars *vars)
8931 {
8932         u32 tx_en_mode;
8933         u16 tmp1, val, mod_abs, tmp2;
8934         u16 rx_alarm_ctrl_val;
8935         u16 lasi_ctrl_val;
8936         struct bnx2x *bp = params->bp;
8937         /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
8938
8939         bnx2x_wait_reset_complete(bp, phy, params);
8940         rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
8941         /* Should be 0x6 to enable XS on Tx side. */
8942         lasi_ctrl_val = 0x0006;
8943
8944         DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
8945         /* enable LASI */
8946         bnx2x_cl45_write(bp, phy,
8947                          MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8948                          rx_alarm_ctrl_val);
8949         bnx2x_cl45_write(bp, phy,
8950                          MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
8951                          0);
8952         bnx2x_cl45_write(bp, phy,
8953                          MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, lasi_ctrl_val);
8954
8955         /*
8956          * Initially configure MOD_ABS to interrupt when module is
8957          * presence( bit 8)
8958          */
8959         bnx2x_cl45_read(bp, phy,
8960                         MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
8961         /*
8962          * Set EDC off by setting OPTXLOS signal input to low (bit 9).
8963          * When the EDC is off it locks onto a reference clock and avoids
8964          * becoming 'lost'
8965          */
8966         mod_abs &= ~(1<<8);
8967         if (!(phy->flags & FLAGS_NOC))
8968                 mod_abs &= ~(1<<9);
8969         bnx2x_cl45_write(bp, phy,
8970                          MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
8971
8972
8973         /* Enable/Disable PHY transmitter output */
8974         bnx2x_set_disable_pmd_transmit(params, phy, 0);
8975
8976         /* Make MOD_ABS give interrupt on change */
8977         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
8978                         &val);
8979         val |= (1<<12);
8980         if (phy->flags & FLAGS_NOC)
8981                 val |= (3<<5);
8982
8983         /*
8984          * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
8985          * status which reflect SFP+ module over-current
8986          */
8987         if (!(phy->flags & FLAGS_NOC))
8988                 val &= 0xff8f; /* Reset bits 4-6 */
8989         bnx2x_cl45_write(bp, phy,
8990                          MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val);
8991
8992         bnx2x_8727_power_module(bp, phy, 1);
8993
8994         bnx2x_cl45_read(bp, phy,
8995                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
8996
8997         bnx2x_cl45_read(bp, phy,
8998                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
8999
9000         /* Set option 1G speed */
9001         if (phy->req_line_speed == SPEED_1000) {
9002                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
9003                 bnx2x_cl45_write(bp, phy,
9004                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
9005                 bnx2x_cl45_write(bp, phy,
9006                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
9007                 bnx2x_cl45_read(bp, phy,
9008                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
9009                 DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
9010                 /*
9011                  * Power down the XAUI until link is up in case of dual-media
9012                  * and 1G
9013                  */
9014                 if (DUAL_MEDIA(params)) {
9015                         bnx2x_cl45_read(bp, phy,
9016                                         MDIO_PMA_DEVAD,
9017                                         MDIO_PMA_REG_8727_PCS_GP, &val);
9018                         val |= (3<<10);
9019                         bnx2x_cl45_write(bp, phy,
9020                                          MDIO_PMA_DEVAD,
9021                                          MDIO_PMA_REG_8727_PCS_GP, val);
9022                 }
9023         } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
9024                    ((phy->speed_cap_mask &
9025                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
9026                    ((phy->speed_cap_mask &
9027                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
9028                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
9029
9030                 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
9031                 bnx2x_cl45_write(bp, phy,
9032                                  MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
9033                 bnx2x_cl45_write(bp, phy,
9034                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
9035         } else {
9036                 /*
9037                  * Since the 8727 has only single reset pin, need to set the 10G
9038                  * registers although it is default
9039                  */
9040                 bnx2x_cl45_write(bp, phy,
9041                                  MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
9042                                  0x0020);
9043                 bnx2x_cl45_write(bp, phy,
9044                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
9045                 bnx2x_cl45_write(bp, phy,
9046                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
9047                 bnx2x_cl45_write(bp, phy,
9048                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
9049                                  0x0008);
9050         }
9051
9052         /*
9053          * Set 2-wire transfer rate of SFP+ module EEPROM
9054          * to 100Khz since some DACs(direct attached cables) do
9055          * not work at 400Khz.
9056          */
9057         bnx2x_cl45_write(bp, phy,
9058                          MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
9059                          0xa001);
9060
9061         /* Set TX PreEmphasis if needed */
9062         if ((params->feature_config_flags &
9063              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
9064                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
9065                            phy->tx_preemphasis[0],
9066                            phy->tx_preemphasis[1]);
9067                 bnx2x_cl45_write(bp, phy,
9068                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
9069                                  phy->tx_preemphasis[0]);
9070
9071                 bnx2x_cl45_write(bp, phy,
9072                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
9073                                  phy->tx_preemphasis[1]);
9074         }
9075
9076         /*
9077          * If TX Laser is controlled by GPIO_0, do not let PHY go into low
9078          * power mode, if TX Laser is disabled
9079          */
9080         tx_en_mode = REG_RD(bp, params->shmem_base +
9081                             offsetof(struct shmem_region,
9082                                 dev_info.port_hw_config[params->port].sfp_ctrl))
9083                         & PORT_HW_CFG_TX_LASER_MASK;
9084
9085         if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
9086
9087                 DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
9088                 bnx2x_cl45_read(bp, phy,
9089                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2);
9090                 tmp2 |= 0x1000;
9091                 tmp2 &= 0xFFEF;
9092                 bnx2x_cl45_write(bp, phy,
9093                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
9094         }
9095
9096         return 0;
9097 }
9098
9099 static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
9100                                       struct link_params *params)
9101 {
9102         struct bnx2x *bp = params->bp;
9103         u16 mod_abs, rx_alarm_status;
9104         u32 val = REG_RD(bp, params->shmem_base +
9105                              offsetof(struct shmem_region, dev_info.
9106                                       port_feature_config[params->port].
9107                                       config));
9108         bnx2x_cl45_read(bp, phy,
9109                         MDIO_PMA_DEVAD,
9110                         MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
9111         if (mod_abs & (1<<8)) {
9112
9113                 /* Module is absent */
9114                 DP(NETIF_MSG_LINK,
9115                    "MOD_ABS indication show module is absent\n");
9116                 phy->media_type = ETH_PHY_NOT_PRESENT;
9117                 /*
9118                  * 1. Set mod_abs to detect next module
9119                  *    presence event
9120                  * 2. Set EDC off by setting OPTXLOS signal input to low
9121                  *    (bit 9).
9122                  *    When the EDC is off it locks onto a reference clock and
9123                  *    avoids becoming 'lost'.
9124                  */
9125                 mod_abs &= ~(1<<8);
9126                 if (!(phy->flags & FLAGS_NOC))
9127                         mod_abs &= ~(1<<9);
9128                 bnx2x_cl45_write(bp, phy,
9129                                  MDIO_PMA_DEVAD,
9130                                  MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
9131
9132                 /*
9133                  * Clear RX alarm since it stays up as long as
9134                  * the mod_abs wasn't changed
9135                  */
9136                 bnx2x_cl45_read(bp, phy,
9137                                 MDIO_PMA_DEVAD,
9138                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
9139
9140         } else {
9141                 /* Module is present */
9142                 DP(NETIF_MSG_LINK,
9143                    "MOD_ABS indication show module is present\n");
9144                 /*
9145                  * First disable transmitter, and if the module is ok, the
9146                  * module_detection will enable it
9147                  * 1. Set mod_abs to detect next module absent event ( bit 8)
9148                  * 2. Restore the default polarity of the OPRXLOS signal and
9149                  * this signal will then correctly indicate the presence or
9150                  * absence of the Rx signal. (bit 9)
9151                  */
9152                 mod_abs |= (1<<8);
9153                 if (!(phy->flags & FLAGS_NOC))
9154                         mod_abs |= (1<<9);
9155                 bnx2x_cl45_write(bp, phy,
9156                                  MDIO_PMA_DEVAD,
9157                                  MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
9158
9159                 /*
9160                  * Clear RX alarm since it stays up as long as the mod_abs
9161                  * wasn't changed. This is need to be done before calling the
9162                  * module detection, otherwise it will clear* the link update
9163                  * alarm
9164                  */
9165                 bnx2x_cl45_read(bp, phy,
9166                                 MDIO_PMA_DEVAD,
9167                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
9168
9169
9170                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9171                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
9172                         bnx2x_sfp_set_transmitter(params, phy, 0);
9173
9174                 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
9175                         bnx2x_sfp_module_detection(phy, params);
9176                 else
9177                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
9178         }
9179
9180         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
9181                    rx_alarm_status);
9182         /* No need to check link status in case of module plugged in/out */
9183 }
9184
9185 static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
9186                                  struct link_params *params,
9187                                  struct link_vars *vars)
9188
9189 {
9190         struct bnx2x *bp = params->bp;
9191         u8 link_up = 0, oc_port = params->port;
9192         u16 link_status = 0;
9193         u16 rx_alarm_status, lasi_ctrl, val1;
9194
9195         /* If PHY is not initialized, do not check link status */
9196         bnx2x_cl45_read(bp, phy,
9197                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
9198                         &lasi_ctrl);
9199         if (!lasi_ctrl)
9200                 return 0;
9201
9202         /* Check the LASI on Rx */
9203         bnx2x_cl45_read(bp, phy,
9204                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT,
9205                         &rx_alarm_status);
9206         vars->line_speed = 0;
9207         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS  0x%x\n", rx_alarm_status);
9208
9209         bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT,
9210                              MDIO_PMA_LASI_TXCTRL);
9211
9212         bnx2x_cl45_read(bp, phy,
9213                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
9214
9215         DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
9216
9217         /* Clear MSG-OUT */
9218         bnx2x_cl45_read(bp, phy,
9219                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
9220
9221         /*
9222          * If a module is present and there is need to check
9223          * for over current
9224          */
9225         if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
9226                 /* Check over-current using 8727 GPIO0 input*/
9227                 bnx2x_cl45_read(bp, phy,
9228                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
9229                                 &val1);
9230
9231                 if ((val1 & (1<<8)) == 0) {
9232                         if (!CHIP_IS_E1x(bp))
9233                                 oc_port = BP_PATH(bp) + (params->port << 1);
9234                         DP(NETIF_MSG_LINK,
9235                            "8727 Power fault has been detected on port %d\n",
9236                            oc_port);
9237                         netdev_err(bp->dev, "Error: Power fault on Port %d has "
9238                                             "been detected and the power to "
9239                                             "that SFP+ module has been removed "
9240                                             "to prevent failure of the card. "
9241                                             "Please remove the SFP+ module and "
9242                                             "restart the system to clear this "
9243                                             "error.\n",
9244                          oc_port);
9245                         /* Disable all RX_ALARMs except for mod_abs */
9246                         bnx2x_cl45_write(bp, phy,
9247                                          MDIO_PMA_DEVAD,
9248                                          MDIO_PMA_LASI_RXCTRL, (1<<5));
9249
9250                         bnx2x_cl45_read(bp, phy,
9251                                         MDIO_PMA_DEVAD,
9252                                         MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
9253                         /* Wait for module_absent_event */
9254                         val1 |= (1<<8);
9255                         bnx2x_cl45_write(bp, phy,
9256                                          MDIO_PMA_DEVAD,
9257                                          MDIO_PMA_REG_PHY_IDENTIFIER, val1);
9258                         /* Clear RX alarm */
9259                         bnx2x_cl45_read(bp, phy,
9260                                 MDIO_PMA_DEVAD,
9261                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
9262                         return 0;
9263                 }
9264         } /* Over current check */
9265
9266         /* When module absent bit is set, check module */
9267         if (rx_alarm_status & (1<<5)) {
9268                 bnx2x_8727_handle_mod_abs(phy, params);
9269                 /* Enable all mod_abs and link detection bits */
9270                 bnx2x_cl45_write(bp, phy,
9271                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9272                                  ((1<<5) | (1<<2)));
9273         }
9274         DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n");
9275         bnx2x_8727_specific_func(phy, params, ENABLE_TX);
9276         /* If transmitter is disabled, ignore false link up indication */
9277         bnx2x_cl45_read(bp, phy,
9278                         MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
9279         if (val1 & (1<<15)) {
9280                 DP(NETIF_MSG_LINK, "Tx is disabled\n");
9281                 return 0;
9282         }
9283
9284         bnx2x_cl45_read(bp, phy,
9285                         MDIO_PMA_DEVAD,
9286                         MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
9287
9288         /*
9289          * Bits 0..2 --> speed detected,
9290          * Bits 13..15--> link is down
9291          */
9292         if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
9293                 link_up = 1;
9294                 vars->line_speed = SPEED_10000;
9295                 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
9296                            params->port);
9297         } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
9298                 link_up = 1;
9299                 vars->line_speed = SPEED_1000;
9300                 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
9301                            params->port);
9302         } else {
9303                 link_up = 0;
9304                 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
9305                            params->port);
9306         }
9307
9308         /* Capture 10G link fault. */
9309         if (vars->line_speed == SPEED_10000) {
9310                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
9311                             MDIO_PMA_LASI_TXSTAT, &val1);
9312
9313                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
9314                             MDIO_PMA_LASI_TXSTAT, &val1);
9315
9316                 if (val1 & (1<<0)) {
9317                         vars->fault_detected = 1;
9318                 }
9319         }
9320
9321         if (link_up) {
9322                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
9323                 vars->duplex = DUPLEX_FULL;
9324                 DP(NETIF_MSG_LINK, "duplex = 0x%x\n", vars->duplex);
9325         }
9326
9327         if ((DUAL_MEDIA(params)) &&
9328             (phy->req_line_speed == SPEED_1000)) {
9329                 bnx2x_cl45_read(bp, phy,
9330                                 MDIO_PMA_DEVAD,
9331                                 MDIO_PMA_REG_8727_PCS_GP, &val1);
9332                 /*
9333                  * In case of dual-media board and 1G, power up the XAUI side,
9334                  * otherwise power it down. For 10G it is done automatically
9335                  */
9336                 if (link_up)
9337                         val1 &= ~(3<<10);
9338                 else
9339                         val1 |= (3<<10);
9340                 bnx2x_cl45_write(bp, phy,
9341                                  MDIO_PMA_DEVAD,
9342                                  MDIO_PMA_REG_8727_PCS_GP, val1);
9343         }
9344         return link_up;
9345 }
9346
9347 static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
9348                                   struct link_params *params)
9349 {
9350         struct bnx2x *bp = params->bp;
9351
9352         /* Enable/Disable PHY transmitter output */
9353         bnx2x_set_disable_pmd_transmit(params, phy, 1);
9354
9355         /* Disable Transmitter */
9356         bnx2x_sfp_set_transmitter(params, phy, 0);
9357         /* Clear LASI */
9358         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0);
9359
9360 }
9361
9362 /******************************************************************/
9363 /*              BCM8481/BCM84823/BCM84833 PHY SECTION             */
9364 /******************************************************************/
9365 static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
9366                                             struct bnx2x *bp,
9367                                             u8 port)
9368 {
9369         u16 val, fw_ver1, fw_ver2, cnt;
9370
9371         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
9372                 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 0x400f, &fw_ver1);
9373                 bnx2x_save_spirom_version(bp, port,
9374                                 ((fw_ver1 & 0xf000)>>5) | (fw_ver1 & 0x7f),
9375                                 phy->ver_addr);
9376         } else {
9377                 /* For 32-bit registers in 848xx, access via MDIO2ARM i/f. */
9378                 /* (1) set reg 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
9379                 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
9380                 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
9381                 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
9382                 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
9383                 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
9384
9385                 for (cnt = 0; cnt < 100; cnt++) {
9386                         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
9387                         if (val & 1)
9388                                 break;
9389                         udelay(5);
9390                 }
9391                 if (cnt == 100) {
9392                         DP(NETIF_MSG_LINK, "Unable to read 848xx "
9393                                         "phy fw version(1)\n");
9394                         bnx2x_save_spirom_version(bp, port, 0,
9395                                                   phy->ver_addr);
9396                         return;
9397                 }
9398
9399
9400                 /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
9401                 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
9402                 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
9403                 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
9404                 for (cnt = 0; cnt < 100; cnt++) {
9405                         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
9406                         if (val & 1)
9407                                 break;
9408                         udelay(5);
9409                 }
9410                 if (cnt == 100) {
9411                         DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw "
9412                                         "version(2)\n");
9413                         bnx2x_save_spirom_version(bp, port, 0,
9414                                                   phy->ver_addr);
9415                         return;
9416                 }
9417
9418                 /* lower 16 bits of the register SPI_FW_STATUS */
9419                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
9420                 /* upper 16 bits of register SPI_FW_STATUS */
9421                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
9422
9423                 bnx2x_save_spirom_version(bp, port, (fw_ver2<<16) | fw_ver1,
9424                                           phy->ver_addr);
9425         }
9426
9427 }
9428 static void bnx2x_848xx_set_led(struct bnx2x *bp,
9429                                 struct bnx2x_phy *phy)
9430 {
9431         u16 val, offset;
9432
9433         /* PHYC_CTL_LED_CTL */
9434         bnx2x_cl45_read(bp, phy,
9435                         MDIO_PMA_DEVAD,
9436                         MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
9437         val &= 0xFE00;
9438         val |= 0x0092;
9439
9440         bnx2x_cl45_write(bp, phy,
9441                          MDIO_PMA_DEVAD,
9442                          MDIO_PMA_REG_8481_LINK_SIGNAL, val);
9443
9444         bnx2x_cl45_write(bp, phy,
9445                          MDIO_PMA_DEVAD,
9446                          MDIO_PMA_REG_8481_LED1_MASK,
9447                          0x80);
9448
9449         bnx2x_cl45_write(bp, phy,
9450                          MDIO_PMA_DEVAD,
9451                          MDIO_PMA_REG_8481_LED2_MASK,
9452                          0x18);
9453
9454         /* Select activity source by Tx and Rx, as suggested by PHY AE */
9455         bnx2x_cl45_write(bp, phy,
9456                          MDIO_PMA_DEVAD,
9457                          MDIO_PMA_REG_8481_LED3_MASK,
9458                          0x0006);
9459
9460         /* Select the closest activity blink rate to that in 10/100/1000 */
9461         bnx2x_cl45_write(bp, phy,
9462                         MDIO_PMA_DEVAD,
9463                         MDIO_PMA_REG_8481_LED3_BLINK,
9464                         0);
9465
9466         /* Configure the blink rate to ~15.9 Hz */
9467         bnx2x_cl45_write(bp, phy,
9468                         MDIO_PMA_DEVAD,
9469                         MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH,
9470                         MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ);
9471
9472         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
9473                 offset = MDIO_PMA_REG_84833_CTL_LED_CTL_1;
9474         else
9475                 offset = MDIO_PMA_REG_84823_CTL_LED_CTL_1;
9476
9477         bnx2x_cl45_read(bp, phy,
9478                         MDIO_PMA_DEVAD, offset, &val);
9479         val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/
9480         bnx2x_cl45_write(bp, phy,
9481                          MDIO_PMA_DEVAD, offset, val);
9482
9483         /* 'Interrupt Mask' */
9484         bnx2x_cl45_write(bp, phy,
9485                          MDIO_AN_DEVAD,
9486                          0xFFFB, 0xFFFD);
9487 }
9488
9489 static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
9490                                        struct link_params *params,
9491                                        struct link_vars *vars)
9492 {
9493         struct bnx2x *bp = params->bp;
9494         u16 autoneg_val, an_1000_val, an_10_100_val, an_10g_val;
9495
9496         if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
9497                 /* Save spirom version */
9498                 bnx2x_save_848xx_spirom_version(phy, bp, params->port);
9499         }
9500         /*
9501          * This phy uses the NIG latch mechanism since link indication
9502          * arrives through its LED4 and not via its LASI signal, so we
9503          * get steady signal instead of clear on read
9504          */
9505         bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
9506                       1 << NIG_LATCH_BC_ENABLE_MI_INT);
9507
9508         bnx2x_cl45_write(bp, phy,
9509                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
9510
9511         bnx2x_848xx_set_led(bp, phy);
9512
9513         /* set 1000 speed advertisement */
9514         bnx2x_cl45_read(bp, phy,
9515                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
9516                         &an_1000_val);
9517
9518         bnx2x_ext_phy_set_pause(params, phy, vars);
9519         bnx2x_cl45_read(bp, phy,
9520                         MDIO_AN_DEVAD,
9521                         MDIO_AN_REG_8481_LEGACY_AN_ADV,
9522                         &an_10_100_val);
9523         bnx2x_cl45_read(bp, phy,
9524                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
9525                         &autoneg_val);
9526         /* Disable forced speed */
9527         autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
9528         an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
9529
9530         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9531              (phy->speed_cap_mask &
9532              PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
9533             (phy->req_line_speed == SPEED_1000)) {
9534                 an_1000_val |= (1<<8);
9535                 autoneg_val |= (1<<9 | 1<<12);
9536                 if (phy->req_duplex == DUPLEX_FULL)
9537                         an_1000_val |= (1<<9);
9538                 DP(NETIF_MSG_LINK, "Advertising 1G\n");
9539         } else
9540                 an_1000_val &= ~((1<<8) | (1<<9));
9541
9542         bnx2x_cl45_write(bp, phy,
9543                          MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
9544                          an_1000_val);
9545
9546         /* set 100 speed advertisement */
9547         if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
9548              (phy->speed_cap_mask &
9549               (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
9550                PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF))) {
9551                 an_10_100_val |= (1<<7);
9552                 /* Enable autoneg and restart autoneg for legacy speeds */
9553                 autoneg_val |= (1<<9 | 1<<12);
9554
9555                 if (phy->req_duplex == DUPLEX_FULL)
9556                         an_10_100_val |= (1<<8);
9557                 DP(NETIF_MSG_LINK, "Advertising 100M\n");
9558         }
9559         /* set 10 speed advertisement */
9560         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9561              (phy->speed_cap_mask &
9562               (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
9563                PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) &&
9564              (phy->supported &
9565               (SUPPORTED_10baseT_Half |
9566                SUPPORTED_10baseT_Full)))) {
9567                 an_10_100_val |= (1<<5);
9568                 autoneg_val |= (1<<9 | 1<<12);
9569                 if (phy->req_duplex == DUPLEX_FULL)
9570                         an_10_100_val |= (1<<6);
9571                 DP(NETIF_MSG_LINK, "Advertising 10M\n");
9572         }
9573
9574         /* Only 10/100 are allowed to work in FORCE mode */
9575         if ((phy->req_line_speed == SPEED_100) &&
9576             (phy->supported &
9577              (SUPPORTED_100baseT_Half |
9578               SUPPORTED_100baseT_Full))) {
9579                 autoneg_val |= (1<<13);
9580                 /* Enabled AUTO-MDIX when autoneg is disabled */
9581                 bnx2x_cl45_write(bp, phy,
9582                                  MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
9583                                  (1<<15 | 1<<9 | 7<<0));
9584                 /* The PHY needs this set even for forced link. */
9585                 an_10_100_val |= (1<<8) | (1<<7);
9586                 DP(NETIF_MSG_LINK, "Setting 100M force\n");
9587         }
9588         if ((phy->req_line_speed == SPEED_10) &&
9589             (phy->supported &
9590              (SUPPORTED_10baseT_Half |
9591               SUPPORTED_10baseT_Full))) {
9592                 /* Enabled AUTO-MDIX when autoneg is disabled */
9593                 bnx2x_cl45_write(bp, phy,
9594                                  MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
9595                                  (1<<15 | 1<<9 | 7<<0));
9596                 DP(NETIF_MSG_LINK, "Setting 10M force\n");
9597         }
9598
9599         bnx2x_cl45_write(bp, phy,
9600                          MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
9601                          an_10_100_val);
9602
9603         if (phy->req_duplex == DUPLEX_FULL)
9604                 autoneg_val |= (1<<8);
9605
9606         /*
9607          * Always write this if this is not 84833.
9608          * For 84833, write it only when it's a forced speed.
9609          */
9610         if ((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
9611                 ((autoneg_val & (1<<12)) == 0))
9612                 bnx2x_cl45_write(bp, phy,
9613                          MDIO_AN_DEVAD,
9614                          MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
9615
9616         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9617             (phy->speed_cap_mask &
9618              PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
9619                 (phy->req_line_speed == SPEED_10000)) {
9620                         DP(NETIF_MSG_LINK, "Advertising 10G\n");
9621                         /* Restart autoneg for 10G*/
9622
9623                         bnx2x_cl45_read(bp, phy,
9624                                         MDIO_AN_DEVAD,
9625                                         MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
9626                                         &an_10g_val);
9627                         bnx2x_cl45_write(bp, phy,
9628                                          MDIO_AN_DEVAD,
9629                                          MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
9630                                          an_10g_val | 0x1000);
9631                         bnx2x_cl45_write(bp, phy,
9632                                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
9633                                          0x3200);
9634         } else
9635                 bnx2x_cl45_write(bp, phy,
9636                                  MDIO_AN_DEVAD,
9637                                  MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
9638                                  1);
9639
9640         return 0;
9641 }
9642
9643 static int bnx2x_8481_config_init(struct bnx2x_phy *phy,
9644                                   struct link_params *params,
9645                                   struct link_vars *vars)
9646 {
9647         struct bnx2x *bp = params->bp;
9648         /* Restore normal power mode*/
9649         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
9650                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
9651
9652         /* HW reset */
9653         bnx2x_ext_phy_hw_reset(bp, params->port);
9654         bnx2x_wait_reset_complete(bp, phy, params);
9655
9656         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
9657         return bnx2x_848xx_cmn_config_init(phy, params, vars);
9658 }
9659
9660 #define PHY84833_CMDHDLR_WAIT 300
9661 #define PHY84833_CMDHDLR_MAX_ARGS 5
9662 static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy,
9663                                    struct link_params *params,
9664                    u16 fw_cmd,
9665                    u16 cmd_args[])
9666 {
9667         u32 idx;
9668         u16 val;
9669         struct bnx2x *bp = params->bp;
9670         /* Write CMD_OPEN_OVERRIDE to STATUS reg */
9671         bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9672                         MDIO_84833_CMD_HDLR_STATUS,
9673                         PHY84833_STATUS_CMD_OPEN_OVERRIDE);
9674         for (idx = 0; idx < PHY84833_CMDHDLR_WAIT; idx++) {
9675                 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9676                                 MDIO_84833_CMD_HDLR_STATUS, &val);
9677                 if (val == PHY84833_STATUS_CMD_OPEN_FOR_CMDS)
9678                         break;
9679                 msleep(1);
9680         }
9681         if (idx >= PHY84833_CMDHDLR_WAIT) {
9682                 DP(NETIF_MSG_LINK, "FW cmd: FW not ready.\n");
9683                 return -EINVAL;
9684         }
9685
9686         /* Prepare argument(s) and issue command */
9687         for (idx = 0; idx < PHY84833_CMDHDLR_MAX_ARGS; idx++) {
9688                 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9689                                 MDIO_84833_CMD_HDLR_DATA1 + idx,
9690                                 cmd_args[idx]);
9691         }
9692         bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9693                         MDIO_84833_CMD_HDLR_COMMAND, fw_cmd);
9694         for (idx = 0; idx < PHY84833_CMDHDLR_WAIT; idx++) {
9695                 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9696                                 MDIO_84833_CMD_HDLR_STATUS, &val);
9697                 if ((val == PHY84833_STATUS_CMD_COMPLETE_PASS) ||
9698                         (val == PHY84833_STATUS_CMD_COMPLETE_ERROR))
9699                         break;
9700                 msleep(1);
9701         }
9702         if ((idx >= PHY84833_CMDHDLR_WAIT) ||
9703                 (val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) {
9704                 DP(NETIF_MSG_LINK, "FW cmd failed.\n");
9705                 return -EINVAL;
9706         }
9707         /* Gather returning data */
9708         for (idx = 0; idx < PHY84833_CMDHDLR_MAX_ARGS; idx++) {
9709                 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9710                                 MDIO_84833_CMD_HDLR_DATA1 + idx,
9711                                 &cmd_args[idx]);
9712         }
9713         bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9714                         MDIO_84833_CMD_HDLR_STATUS,
9715                         PHY84833_STATUS_CMD_CLEAR_COMPLETE);
9716         return 0;
9717 }
9718
9719
9720 static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy,
9721                                    struct link_params *params,
9722                                    struct link_vars *vars)
9723 {
9724         u32 pair_swap;
9725         u16 data[PHY84833_CMDHDLR_MAX_ARGS];
9726         int status;
9727         struct bnx2x *bp = params->bp;
9728
9729         /* Check for configuration. */
9730         pair_swap = REG_RD(bp, params->shmem_base +
9731                            offsetof(struct shmem_region,
9732                         dev_info.port_hw_config[params->port].xgbt_phy_cfg)) &
9733                 PORT_HW_CFG_RJ45_PAIR_SWAP_MASK;
9734
9735         if (pair_swap == 0)
9736                 return 0;
9737
9738         /* Only the second argument is used for this command */
9739         data[1] = (u16)pair_swap;
9740
9741         status = bnx2x_84833_cmd_hdlr(phy, params,
9742                 PHY84833_CMD_SET_PAIR_SWAP, data);
9743         if (status == 0)
9744                 DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data[1]);
9745
9746         return status;
9747 }
9748
9749 static u8 bnx2x_84833_get_reset_gpios(struct bnx2x *bp,
9750                                       u32 shmem_base_path[],
9751                                       u32 chip_id)
9752 {
9753         u32 reset_pin[2];
9754         u32 idx;
9755         u8 reset_gpios;
9756         if (CHIP_IS_E3(bp)) {
9757                 /* Assume that these will be GPIOs, not EPIOs. */
9758                 for (idx = 0; idx < 2; idx++) {
9759                         /* Map config param to register bit. */
9760                         reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] +
9761                                 offsetof(struct shmem_region,
9762                                 dev_info.port_hw_config[0].e3_cmn_pin_cfg));
9763                         reset_pin[idx] = (reset_pin[idx] &
9764                                 PORT_HW_CFG_E3_PHY_RESET_MASK) >>
9765                                 PORT_HW_CFG_E3_PHY_RESET_SHIFT;
9766                         reset_pin[idx] -= PIN_CFG_GPIO0_P0;
9767                         reset_pin[idx] = (1 << reset_pin[idx]);
9768                 }
9769                 reset_gpios = (u8)(reset_pin[0] | reset_pin[1]);
9770         } else {
9771                 /* E2, look from diff place of shmem. */
9772                 for (idx = 0; idx < 2; idx++) {
9773                         reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] +
9774                                 offsetof(struct shmem_region,
9775                                 dev_info.port_hw_config[0].default_cfg));
9776                         reset_pin[idx] &= PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK;
9777                         reset_pin[idx] -= PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0;
9778                         reset_pin[idx] >>= PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT;
9779                         reset_pin[idx] = (1 << reset_pin[idx]);
9780                 }
9781                 reset_gpios = (u8)(reset_pin[0] | reset_pin[1]);
9782         }
9783
9784         return reset_gpios;
9785 }
9786
9787 static int bnx2x_84833_hw_reset_phy(struct bnx2x_phy *phy,
9788                                 struct link_params *params)
9789 {
9790         struct bnx2x *bp = params->bp;
9791         u8 reset_gpios;
9792         u32 other_shmem_base_addr = REG_RD(bp, params->shmem2_base +
9793                                 offsetof(struct shmem2_region,
9794                                 other_shmem_base_addr));
9795
9796         u32 shmem_base_path[2];
9797         shmem_base_path[0] = params->shmem_base;
9798         shmem_base_path[1] = other_shmem_base_addr;
9799
9800         reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path,
9801                                                   params->chip_id);
9802
9803         bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
9804         udelay(10);
9805         DP(NETIF_MSG_LINK, "84833 hw reset on pin values 0x%x\n",
9806                 reset_gpios);
9807
9808         return 0;
9809 }
9810
9811 #define PHY84833_CONSTANT_LATENCY 1193
9812 static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
9813                                    struct link_params *params,
9814                                    struct link_vars *vars)
9815 {
9816         struct bnx2x *bp = params->bp;
9817         u8 port, initialize = 1;
9818         u16 val;
9819         u32 actual_phy_selection, cms_enable;
9820         u16 cmd_args[PHY84833_CMDHDLR_MAX_ARGS];
9821         int rc = 0;
9822
9823         msleep(1);
9824
9825         if (!(CHIP_IS_E1(bp)))
9826                 port = BP_PATH(bp);
9827         else
9828                 port = params->port;
9829
9830         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
9831                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
9832                                MISC_REGISTERS_GPIO_OUTPUT_HIGH,
9833                                port);
9834         } else {
9835                 /* MDIO reset */
9836                 bnx2x_cl45_write(bp, phy,
9837                                 MDIO_PMA_DEVAD,
9838                                 MDIO_PMA_REG_CTRL, 0x8000);
9839         }
9840
9841         bnx2x_wait_reset_complete(bp, phy, params);
9842
9843         /* Wait for GPHY to come out of reset */
9844         msleep(50);
9845         if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
9846                 /*
9847                  * BCM84823 requires that XGXS links up first @ 10G for normal
9848                  * behavior.
9849                  */
9850                 u16 temp;
9851                 temp = vars->line_speed;
9852                 vars->line_speed = SPEED_10000;
9853                 bnx2x_set_autoneg(&params->phy[INT_PHY], params, vars, 0);
9854                 bnx2x_program_serdes(&params->phy[INT_PHY], params, vars);
9855                 vars->line_speed = temp;
9856         }
9857
9858         bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9859                         MDIO_CTL_REG_84823_MEDIA, &val);
9860         val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
9861                  MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
9862                  MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
9863                  MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
9864                  MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
9865
9866         if (CHIP_IS_E3(bp)) {
9867                 val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
9868                          MDIO_CTL_REG_84823_MEDIA_LINE_MASK);
9869         } else {
9870                 val |= (MDIO_CTL_REG_84823_CTRL_MAC_XFI |
9871                         MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L);
9872         }
9873
9874         actual_phy_selection = bnx2x_phy_selection(params);
9875
9876         switch (actual_phy_selection) {
9877         case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
9878                 /* Do nothing. Essentially this is like the priority copper */
9879                 break;
9880         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
9881                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
9882                 break;
9883         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
9884                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
9885                 break;
9886         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
9887                 /* Do nothing here. The first PHY won't be initialized at all */
9888                 break;
9889         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
9890                 val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
9891                 initialize = 0;
9892                 break;
9893         }
9894         if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000)
9895                 val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
9896
9897         bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9898                          MDIO_CTL_REG_84823_MEDIA, val);
9899         DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
9900                    params->multi_phy_config, val);
9901
9902         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
9903                 bnx2x_84833_pair_swap_cfg(phy, params, vars);
9904
9905                 /* Keep AutogrEEEn disabled. */
9906                 cmd_args[0] = 0x0;
9907                 cmd_args[1] = 0x0;
9908                 cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1;
9909                 cmd_args[3] = PHY84833_CONSTANT_LATENCY;
9910                 rc = bnx2x_84833_cmd_hdlr(phy, params,
9911                         PHY84833_CMD_SET_EEE_MODE, cmd_args);
9912                 if (rc != 0)
9913                         DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n");
9914         }
9915         if (initialize)
9916                 rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
9917         else
9918                 bnx2x_save_848xx_spirom_version(phy, bp, params->port);
9919         /* 84833 PHY has a better feature and doesn't need to support this. */
9920         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
9921                 cms_enable = REG_RD(bp, params->shmem_base +
9922                         offsetof(struct shmem_region,
9923                         dev_info.port_hw_config[params->port].default_cfg)) &
9924                         PORT_HW_CFG_ENABLE_CMS_MASK;
9925
9926                 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9927                                 MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
9928                 if (cms_enable)
9929                         val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
9930                 else
9931                         val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
9932                 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9933                                  MDIO_CTL_REG_84823_USER_CTRL_REG, val);
9934         }
9935
9936         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
9937                 /* Bring PHY out of super isolate mode as the final step. */
9938                 bnx2x_cl45_read(bp, phy,
9939                                 MDIO_CTL_DEVAD,
9940                                 MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
9941                 val &= ~MDIO_84833_SUPER_ISOLATE;
9942                 bnx2x_cl45_write(bp, phy,
9943                                 MDIO_CTL_DEVAD,
9944                                 MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
9945         }
9946         return rc;
9947 }
9948
9949 static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
9950                                   struct link_params *params,
9951                                   struct link_vars *vars)
9952 {
9953         struct bnx2x *bp = params->bp;
9954         u16 val, val1, val2;
9955         u8 link_up = 0;
9956
9957
9958         /* Check 10G-BaseT link status */
9959         /* Check PMD signal ok */
9960         bnx2x_cl45_read(bp, phy,
9961                         MDIO_AN_DEVAD, 0xFFFA, &val1);
9962         bnx2x_cl45_read(bp, phy,
9963                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
9964                         &val2);
9965         DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
9966
9967         /* Check link 10G */
9968         if (val2 & (1<<11)) {
9969                 vars->line_speed = SPEED_10000;
9970                 vars->duplex = DUPLEX_FULL;
9971                 link_up = 1;
9972                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
9973         } else { /* Check Legacy speed link */
9974                 u16 legacy_status, legacy_speed;
9975
9976                 /* Enable expansion register 0x42 (Operation mode status) */
9977                 bnx2x_cl45_write(bp, phy,
9978                                  MDIO_AN_DEVAD,
9979                                  MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
9980
9981                 /* Get legacy speed operation status */
9982                 bnx2x_cl45_read(bp, phy,
9983                                 MDIO_AN_DEVAD,
9984                                 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
9985                                 &legacy_status);
9986
9987                 DP(NETIF_MSG_LINK, "Legacy speed status = 0x%x\n",
9988                    legacy_status);
9989                 link_up = ((legacy_status & (1<<11)) == (1<<11));
9990                 if (link_up) {
9991                         legacy_speed = (legacy_status & (3<<9));
9992                         if (legacy_speed == (0<<9))
9993                                 vars->line_speed = SPEED_10;
9994                         else if (legacy_speed == (1<<9))
9995                                 vars->line_speed = SPEED_100;
9996                         else if (legacy_speed == (2<<9))
9997                                 vars->line_speed = SPEED_1000;
9998                         else /* Should not happen */
9999                                 vars->line_speed = 0;
10000
10001                         if (legacy_status & (1<<8))
10002                                 vars->duplex = DUPLEX_FULL;
10003                         else
10004                                 vars->duplex = DUPLEX_HALF;
10005
10006                         DP(NETIF_MSG_LINK,
10007                            "Link is up in %dMbps, is_duplex_full= %d\n",
10008                            vars->line_speed,
10009                            (vars->duplex == DUPLEX_FULL));
10010                         /* Check legacy speed AN resolution */
10011                         bnx2x_cl45_read(bp, phy,
10012                                         MDIO_AN_DEVAD,
10013                                         MDIO_AN_REG_8481_LEGACY_MII_STATUS,
10014                                         &val);
10015                         if (val & (1<<5))
10016                                 vars->link_status |=
10017                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
10018                         bnx2x_cl45_read(bp, phy,
10019                                         MDIO_AN_DEVAD,
10020                                         MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
10021                                         &val);
10022                         if ((val & (1<<0)) == 0)
10023                                 vars->link_status |=
10024                                         LINK_STATUS_PARALLEL_DETECTION_USED;
10025                 }
10026         }
10027         if (link_up) {
10028                 DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n",
10029                            vars->line_speed);
10030                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
10031
10032                 /* Read LP advertised speeds */
10033                 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
10034                                 MDIO_AN_REG_CL37_FC_LP, &val);
10035                 if (val & (1<<5))
10036                         vars->link_status |=
10037                                 LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
10038                 if (val & (1<<6))
10039                         vars->link_status |=
10040                                 LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
10041                 if (val & (1<<7))
10042                         vars->link_status |=
10043                                 LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
10044                 if (val & (1<<8))
10045                         vars->link_status |=
10046                                 LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
10047                 if (val & (1<<9))
10048                         vars->link_status |=
10049                                 LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
10050
10051                 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
10052                                 MDIO_AN_REG_1000T_STATUS, &val);
10053
10054                 if (val & (1<<10))
10055                         vars->link_status |=
10056                                 LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
10057                 if (val & (1<<11))
10058                         vars->link_status |=
10059                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
10060
10061                 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
10062                                 MDIO_AN_REG_MASTER_STATUS, &val);
10063
10064                 if (val & (1<<11))
10065                         vars->link_status |=
10066                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
10067         }
10068
10069         return link_up;
10070 }
10071
10072
10073 static int bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
10074 {
10075         int status = 0;
10076         u32 spirom_ver;
10077         spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
10078         status = bnx2x_format_ver(spirom_ver, str, len);
10079         return status;
10080 }
10081
10082 static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
10083                                 struct link_params *params)
10084 {
10085         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
10086                        MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
10087         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
10088                        MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
10089 }
10090
10091 static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
10092                                         struct link_params *params)
10093 {
10094         bnx2x_cl45_write(params->bp, phy,
10095                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
10096         bnx2x_cl45_write(params->bp, phy,
10097                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
10098 }
10099
10100 static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
10101                                    struct link_params *params)
10102 {
10103         struct bnx2x *bp = params->bp;
10104         u8 port;
10105         u16 val16;
10106
10107         if (!(CHIP_IS_E1(bp)))
10108                 port = BP_PATH(bp);
10109         else
10110                 port = params->port;
10111
10112         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
10113                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
10114                                MISC_REGISTERS_GPIO_OUTPUT_LOW,
10115                                port);
10116         } else {
10117                 bnx2x_cl45_read(bp, phy,
10118                                 MDIO_CTL_DEVAD,
10119                                 MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val16);
10120                 val16 |= MDIO_84833_SUPER_ISOLATE;
10121                 bnx2x_cl45_write(bp, phy,
10122                                  MDIO_CTL_DEVAD,
10123                                  MDIO_84833_TOP_CFG_XGPHY_STRAP1, val16);
10124         }
10125 }
10126
10127 static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
10128                                      struct link_params *params, u8 mode)
10129 {
10130         struct bnx2x *bp = params->bp;
10131         u16 val;
10132         u8 port;
10133
10134         if (!(CHIP_IS_E1(bp)))
10135                 port = BP_PATH(bp);
10136         else
10137                 port = params->port;
10138
10139         switch (mode) {
10140         case LED_MODE_OFF:
10141
10142                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", port);
10143
10144                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
10145                     SHARED_HW_CFG_LED_EXTPHY1) {
10146
10147                         /* Set LED masks */
10148                         bnx2x_cl45_write(bp, phy,
10149                                         MDIO_PMA_DEVAD,
10150                                         MDIO_PMA_REG_8481_LED1_MASK,
10151                                         0x0);
10152
10153                         bnx2x_cl45_write(bp, phy,
10154                                         MDIO_PMA_DEVAD,
10155                                         MDIO_PMA_REG_8481_LED2_MASK,
10156                                         0x0);
10157
10158                         bnx2x_cl45_write(bp, phy,
10159                                         MDIO_PMA_DEVAD,
10160                                         MDIO_PMA_REG_8481_LED3_MASK,
10161                                         0x0);
10162
10163                         bnx2x_cl45_write(bp, phy,
10164                                         MDIO_PMA_DEVAD,
10165                                         MDIO_PMA_REG_8481_LED5_MASK,
10166                                         0x0);
10167
10168                 } else {
10169                         bnx2x_cl45_write(bp, phy,
10170                                          MDIO_PMA_DEVAD,
10171                                          MDIO_PMA_REG_8481_LED1_MASK,
10172                                          0x0);
10173                 }
10174                 break;
10175         case LED_MODE_FRONT_PANEL_OFF:
10176
10177                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
10178                    port);
10179
10180                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
10181                     SHARED_HW_CFG_LED_EXTPHY1) {
10182
10183                         /* Set LED masks */
10184                         bnx2x_cl45_write(bp, phy,
10185                                          MDIO_PMA_DEVAD,
10186                                          MDIO_PMA_REG_8481_LED1_MASK,
10187                                          0x0);
10188
10189                         bnx2x_cl45_write(bp, phy,
10190                                          MDIO_PMA_DEVAD,
10191                                          MDIO_PMA_REG_8481_LED2_MASK,
10192                                          0x0);
10193
10194                         bnx2x_cl45_write(bp, phy,
10195                                          MDIO_PMA_DEVAD,
10196                                          MDIO_PMA_REG_8481_LED3_MASK,
10197                                          0x0);
10198
10199                         bnx2x_cl45_write(bp, phy,
10200                                          MDIO_PMA_DEVAD,
10201                                          MDIO_PMA_REG_8481_LED5_MASK,
10202                                          0x20);
10203
10204                 } else {
10205                         bnx2x_cl45_write(bp, phy,
10206                                          MDIO_PMA_DEVAD,
10207                                          MDIO_PMA_REG_8481_LED1_MASK,
10208                                          0x0);
10209                 }
10210                 break;
10211         case LED_MODE_ON:
10212
10213                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", port);
10214
10215                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
10216                     SHARED_HW_CFG_LED_EXTPHY1) {
10217                         /* Set control reg */
10218                         bnx2x_cl45_read(bp, phy,
10219                                         MDIO_PMA_DEVAD,
10220                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
10221                                         &val);
10222                         val &= 0x8000;
10223                         val |= 0x2492;
10224
10225                         bnx2x_cl45_write(bp, phy,
10226                                          MDIO_PMA_DEVAD,
10227                                          MDIO_PMA_REG_8481_LINK_SIGNAL,
10228                                          val);
10229
10230                         /* Set LED masks */
10231                         bnx2x_cl45_write(bp, phy,
10232                                          MDIO_PMA_DEVAD,
10233                                          MDIO_PMA_REG_8481_LED1_MASK,
10234                                          0x0);
10235
10236                         bnx2x_cl45_write(bp, phy,
10237                                          MDIO_PMA_DEVAD,
10238                                          MDIO_PMA_REG_8481_LED2_MASK,
10239                                          0x20);
10240
10241                         bnx2x_cl45_write(bp, phy,
10242                                          MDIO_PMA_DEVAD,
10243                                          MDIO_PMA_REG_8481_LED3_MASK,
10244                                          0x20);
10245
10246                         bnx2x_cl45_write(bp, phy,
10247                                          MDIO_PMA_DEVAD,
10248                                          MDIO_PMA_REG_8481_LED5_MASK,
10249                                          0x0);
10250                 } else {
10251                         bnx2x_cl45_write(bp, phy,
10252                                          MDIO_PMA_DEVAD,
10253                                          MDIO_PMA_REG_8481_LED1_MASK,
10254                                          0x20);
10255                 }
10256                 break;
10257
10258         case LED_MODE_OPER:
10259
10260                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", port);
10261
10262                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
10263                     SHARED_HW_CFG_LED_EXTPHY1) {
10264
10265                         /* Set control reg */
10266                         bnx2x_cl45_read(bp, phy,
10267                                         MDIO_PMA_DEVAD,
10268                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
10269                                         &val);
10270
10271                         if (!((val &
10272                                MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
10273                           >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) {
10274                                 DP(NETIF_MSG_LINK, "Setting LINK_SIGNAL\n");
10275                                 bnx2x_cl45_write(bp, phy,
10276                                                  MDIO_PMA_DEVAD,
10277                                                  MDIO_PMA_REG_8481_LINK_SIGNAL,
10278                                                  0xa492);
10279                         }
10280
10281                         /* Set LED masks */
10282                         bnx2x_cl45_write(bp, phy,
10283                                          MDIO_PMA_DEVAD,
10284                                          MDIO_PMA_REG_8481_LED1_MASK,
10285                                          0x10);
10286
10287                         bnx2x_cl45_write(bp, phy,
10288                                          MDIO_PMA_DEVAD,
10289                                          MDIO_PMA_REG_8481_LED2_MASK,
10290                                          0x80);
10291
10292                         bnx2x_cl45_write(bp, phy,
10293                                          MDIO_PMA_DEVAD,
10294                                          MDIO_PMA_REG_8481_LED3_MASK,
10295                                          0x98);
10296
10297                         bnx2x_cl45_write(bp, phy,
10298                                          MDIO_PMA_DEVAD,
10299                                          MDIO_PMA_REG_8481_LED5_MASK,
10300                                          0x40);
10301
10302                 } else {
10303                         bnx2x_cl45_write(bp, phy,
10304                                          MDIO_PMA_DEVAD,
10305                                          MDIO_PMA_REG_8481_LED1_MASK,
10306                                          0x80);
10307
10308                         /* Tell LED3 to blink on source */
10309                         bnx2x_cl45_read(bp, phy,
10310                                         MDIO_PMA_DEVAD,
10311                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
10312                                         &val);
10313                         val &= ~(7<<6);
10314                         val |= (1<<6); /* A83B[8:6]= 1 */
10315                         bnx2x_cl45_write(bp, phy,
10316                                          MDIO_PMA_DEVAD,
10317                                          MDIO_PMA_REG_8481_LINK_SIGNAL,
10318                                          val);
10319                 }
10320                 break;
10321         }
10322
10323         /*
10324          * This is a workaround for E3+84833 until autoneg
10325          * restart is fixed in f/w
10326          */
10327         if (CHIP_IS_E3(bp)) {
10328                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
10329                                 MDIO_WC_REG_GP2_STATUS_GP_2_1, &val);
10330         }
10331 }
10332
10333 /******************************************************************/
10334 /*                      54618SE PHY SECTION                       */
10335 /******************************************************************/
10336 static int bnx2x_54618se_config_init(struct bnx2x_phy *phy,
10337                                                struct link_params *params,
10338                                                struct link_vars *vars)
10339 {
10340         struct bnx2x *bp = params->bp;
10341         u8 port;
10342         u16 autoneg_val, an_1000_val, an_10_100_val, fc_val, temp;
10343         u32 cfg_pin;
10344
10345         DP(NETIF_MSG_LINK, "54618SE cfg init\n");
10346         usleep_range(1000, 1000);
10347
10348         /*
10349          * This works with E3 only, no need to check the chip
10350          * before determining the port.
10351          */
10352         port = params->port;
10353
10354         cfg_pin = (REG_RD(bp, params->shmem_base +
10355                         offsetof(struct shmem_region,
10356                         dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
10357                         PORT_HW_CFG_E3_PHY_RESET_MASK) >>
10358                         PORT_HW_CFG_E3_PHY_RESET_SHIFT;
10359
10360         /* Drive pin high to bring the GPHY out of reset. */
10361         bnx2x_set_cfg_pin(bp, cfg_pin, 1);
10362
10363         /* wait for GPHY to reset */
10364         msleep(50);
10365
10366         /* reset phy */
10367         bnx2x_cl22_write(bp, phy,
10368                          MDIO_PMA_REG_CTRL, 0x8000);
10369         bnx2x_wait_reset_complete(bp, phy, params);
10370
10371         /*wait for GPHY to reset */
10372         msleep(50);
10373
10374         /* Configure LED4: set to INTR (0x6). */
10375         /* Accessing shadow register 0xe. */
10376         bnx2x_cl22_write(bp, phy,
10377                         MDIO_REG_GPHY_SHADOW,
10378                         MDIO_REG_GPHY_SHADOW_LED_SEL2);
10379         bnx2x_cl22_read(bp, phy,
10380                         MDIO_REG_GPHY_SHADOW,
10381                         &temp);
10382         temp &= ~(0xf << 4);
10383         temp |= (0x6 << 4);
10384         bnx2x_cl22_write(bp, phy,
10385                         MDIO_REG_GPHY_SHADOW,
10386                         MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
10387         /* Configure INTR based on link status change. */
10388         bnx2x_cl22_write(bp, phy,
10389                         MDIO_REG_INTR_MASK,
10390                         ~MDIO_REG_INTR_MASK_LINK_STATUS);
10391
10392         /* Flip the signal detect polarity (set 0x1c.0x1e[8]). */
10393         bnx2x_cl22_write(bp, phy,
10394                         MDIO_REG_GPHY_SHADOW,
10395                         MDIO_REG_GPHY_SHADOW_AUTO_DET_MED);
10396         bnx2x_cl22_read(bp, phy,
10397                         MDIO_REG_GPHY_SHADOW,
10398                         &temp);
10399         temp |= MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD;
10400         bnx2x_cl22_write(bp, phy,
10401                         MDIO_REG_GPHY_SHADOW,
10402                         MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
10403
10404         /* Set up fc */
10405         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
10406         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
10407         fc_val = 0;
10408         if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
10409                         MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC)
10410                 fc_val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
10411
10412         if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
10413                         MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
10414                 fc_val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
10415
10416         /* read all advertisement */
10417         bnx2x_cl22_read(bp, phy,
10418                         0x09,
10419                         &an_1000_val);
10420
10421         bnx2x_cl22_read(bp, phy,
10422                         0x04,
10423                         &an_10_100_val);
10424
10425         bnx2x_cl22_read(bp, phy,
10426                         MDIO_PMA_REG_CTRL,
10427                         &autoneg_val);
10428
10429         /* Disable forced speed */
10430         autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
10431         an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8) | (1<<10) |
10432                            (1<<11));
10433
10434         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
10435                         (phy->speed_cap_mask &
10436                         PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
10437                         (phy->req_line_speed == SPEED_1000)) {
10438                 an_1000_val |= (1<<8);
10439                 autoneg_val |= (1<<9 | 1<<12);
10440                 if (phy->req_duplex == DUPLEX_FULL)
10441                         an_1000_val |= (1<<9);
10442                 DP(NETIF_MSG_LINK, "Advertising 1G\n");
10443         } else
10444                 an_1000_val &= ~((1<<8) | (1<<9));
10445
10446         bnx2x_cl22_write(bp, phy,
10447                         0x09,
10448                         an_1000_val);
10449         bnx2x_cl22_read(bp, phy,
10450                         0x09,
10451                         &an_1000_val);
10452
10453         /* set 100 speed advertisement */
10454         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
10455                         (phy->speed_cap_mask &
10456                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
10457                         PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
10458                 an_10_100_val |= (1<<7);
10459                 /* Enable autoneg and restart autoneg for legacy speeds */
10460                 autoneg_val |= (1<<9 | 1<<12);
10461
10462                 if (phy->req_duplex == DUPLEX_FULL)
10463                         an_10_100_val |= (1<<8);
10464                 DP(NETIF_MSG_LINK, "Advertising 100M\n");
10465         }
10466
10467         /* set 10 speed advertisement */
10468         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
10469                         (phy->speed_cap_mask &
10470                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
10471                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
10472                 an_10_100_val |= (1<<5);
10473                 autoneg_val |= (1<<9 | 1<<12);
10474                 if (phy->req_duplex == DUPLEX_FULL)
10475                         an_10_100_val |= (1<<6);
10476                 DP(NETIF_MSG_LINK, "Advertising 10M\n");
10477         }
10478
10479         /* Only 10/100 are allowed to work in FORCE mode */
10480         if (phy->req_line_speed == SPEED_100) {
10481                 autoneg_val |= (1<<13);
10482                 /* Enabled AUTO-MDIX when autoneg is disabled */
10483                 bnx2x_cl22_write(bp, phy,
10484                                 0x18,
10485                                 (1<<15 | 1<<9 | 7<<0));
10486                 DP(NETIF_MSG_LINK, "Setting 100M force\n");
10487         }
10488         if (phy->req_line_speed == SPEED_10) {
10489                 /* Enabled AUTO-MDIX when autoneg is disabled */
10490                 bnx2x_cl22_write(bp, phy,
10491                                 0x18,
10492                                 (1<<15 | 1<<9 | 7<<0));
10493                 DP(NETIF_MSG_LINK, "Setting 10M force\n");
10494         }
10495
10496         /* Check if we should turn on Auto-GrEEEn */
10497         bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &temp);
10498         if (temp == MDIO_REG_GPHY_ID_54618SE) {
10499                 if (params->feature_config_flags &
10500                     FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
10501                         temp = 6;
10502                         DP(NETIF_MSG_LINK, "Enabling Auto-GrEEEn\n");
10503                 } else {
10504                         temp = 0;
10505                         DP(NETIF_MSG_LINK, "Disabling Auto-GrEEEn\n");
10506                 }
10507                 bnx2x_cl22_write(bp, phy,
10508                                  MDIO_REG_GPHY_CL45_ADDR_REG, MDIO_AN_DEVAD);
10509                 bnx2x_cl22_write(bp, phy,
10510                                  MDIO_REG_GPHY_CL45_DATA_REG,
10511                                  MDIO_REG_GPHY_EEE_ADV);
10512                 bnx2x_cl22_write(bp, phy,
10513                                  MDIO_REG_GPHY_CL45_ADDR_REG,
10514                                  (0x1 << 14) | MDIO_AN_DEVAD);
10515                 bnx2x_cl22_write(bp, phy,
10516                                  MDIO_REG_GPHY_CL45_DATA_REG,
10517                                  temp);
10518         }
10519
10520         bnx2x_cl22_write(bp, phy,
10521                         0x04,
10522                         an_10_100_val | fc_val);
10523
10524         if (phy->req_duplex == DUPLEX_FULL)
10525                 autoneg_val |= (1<<8);
10526
10527         bnx2x_cl22_write(bp, phy,
10528                         MDIO_PMA_REG_CTRL, autoneg_val);
10529
10530         return 0;
10531 }
10532
10533
10534 static void bnx2x_5461x_set_link_led(struct bnx2x_phy *phy,
10535                                        struct link_params *params, u8 mode)
10536 {
10537         struct bnx2x *bp = params->bp;
10538         u16 temp;
10539
10540         bnx2x_cl22_write(bp, phy,
10541                 MDIO_REG_GPHY_SHADOW,
10542                 MDIO_REG_GPHY_SHADOW_LED_SEL1);
10543         bnx2x_cl22_read(bp, phy,
10544                 MDIO_REG_GPHY_SHADOW,
10545                 &temp);
10546         temp &= 0xff00;
10547
10548         DP(NETIF_MSG_LINK, "54618x set link led (mode=%x)\n", mode);
10549         switch (mode) {
10550         case LED_MODE_FRONT_PANEL_OFF:
10551         case LED_MODE_OFF:
10552                 temp |= 0x00ee;
10553                 break;
10554         case LED_MODE_OPER:
10555                 temp |= 0x0001;
10556                 break;
10557         case LED_MODE_ON:
10558                 temp |= 0x00ff;
10559                 break;
10560         default:
10561                 break;
10562         }
10563         bnx2x_cl22_write(bp, phy,
10564                 MDIO_REG_GPHY_SHADOW,
10565                 MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
10566         return;
10567 }
10568
10569
10570 static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy,
10571                                      struct link_params *params)
10572 {
10573         struct bnx2x *bp = params->bp;
10574         u32 cfg_pin;
10575         u8 port;
10576
10577         /*
10578          * In case of no EPIO routed to reset the GPHY, put it
10579          * in low power mode.
10580          */
10581         bnx2x_cl22_write(bp, phy, MDIO_PMA_REG_CTRL, 0x800);
10582         /*
10583          * This works with E3 only, no need to check the chip
10584          * before determining the port.
10585          */
10586         port = params->port;
10587         cfg_pin = (REG_RD(bp, params->shmem_base +
10588                         offsetof(struct shmem_region,
10589                         dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
10590                         PORT_HW_CFG_E3_PHY_RESET_MASK) >>
10591                         PORT_HW_CFG_E3_PHY_RESET_SHIFT;
10592
10593         /* Drive pin low to put GPHY in reset. */
10594         bnx2x_set_cfg_pin(bp, cfg_pin, 0);
10595 }
10596
10597 static u8 bnx2x_54618se_read_status(struct bnx2x_phy *phy,
10598                                     struct link_params *params,
10599                                     struct link_vars *vars)
10600 {
10601         struct bnx2x *bp = params->bp;
10602         u16 val;
10603         u8 link_up = 0;
10604         u16 legacy_status, legacy_speed;
10605
10606         /* Get speed operation status */
10607         bnx2x_cl22_read(bp, phy,
10608                         0x19,
10609                         &legacy_status);
10610         DP(NETIF_MSG_LINK, "54618SE read_status: 0x%x\n", legacy_status);
10611
10612         /* Read status to clear the PHY interrupt. */
10613         bnx2x_cl22_read(bp, phy,
10614                         MDIO_REG_INTR_STATUS,
10615                         &val);
10616
10617         link_up = ((legacy_status & (1<<2)) == (1<<2));
10618
10619         if (link_up) {
10620                 legacy_speed = (legacy_status & (7<<8));
10621                 if (legacy_speed == (7<<8)) {
10622                         vars->line_speed = SPEED_1000;
10623                         vars->duplex = DUPLEX_FULL;
10624                 } else if (legacy_speed == (6<<8)) {
10625                         vars->line_speed = SPEED_1000;
10626                         vars->duplex = DUPLEX_HALF;
10627                 } else if (legacy_speed == (5<<8)) {
10628                         vars->line_speed = SPEED_100;
10629                         vars->duplex = DUPLEX_FULL;
10630                 }
10631                 /* Omitting 100Base-T4 for now */
10632                 else if (legacy_speed == (3<<8)) {
10633                         vars->line_speed = SPEED_100;
10634                         vars->duplex = DUPLEX_HALF;
10635                 } else if (legacy_speed == (2<<8)) {
10636                         vars->line_speed = SPEED_10;
10637                         vars->duplex = DUPLEX_FULL;
10638                 } else if (legacy_speed == (1<<8)) {
10639                         vars->line_speed = SPEED_10;
10640                         vars->duplex = DUPLEX_HALF;
10641                 } else /* Should not happen */
10642                         vars->line_speed = 0;
10643
10644                 DP(NETIF_MSG_LINK,
10645                    "Link is up in %dMbps, is_duplex_full= %d\n",
10646                    vars->line_speed,
10647                    (vars->duplex == DUPLEX_FULL));
10648
10649                 /* Check legacy speed AN resolution */
10650                 bnx2x_cl22_read(bp, phy,
10651                                 0x01,
10652                                 &val);
10653                 if (val & (1<<5))
10654                         vars->link_status |=
10655                                 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
10656                 bnx2x_cl22_read(bp, phy,
10657                                 0x06,
10658                                 &val);
10659                 if ((val & (1<<0)) == 0)
10660                         vars->link_status |=
10661                                 LINK_STATUS_PARALLEL_DETECTION_USED;
10662
10663                 DP(NETIF_MSG_LINK, "BCM54618SE: link speed is %d\n",
10664                            vars->line_speed);
10665
10666                 /* Report whether EEE is resolved. */
10667                 bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &val);
10668                 if (val == MDIO_REG_GPHY_ID_54618SE) {
10669                         if (vars->link_status &
10670                             LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
10671                                 val = 0;
10672                         else {
10673                                 bnx2x_cl22_write(bp, phy,
10674                                         MDIO_REG_GPHY_CL45_ADDR_REG,
10675                                         MDIO_AN_DEVAD);
10676                                 bnx2x_cl22_write(bp, phy,
10677                                         MDIO_REG_GPHY_CL45_DATA_REG,
10678                                         MDIO_REG_GPHY_EEE_RESOLVED);
10679                                 bnx2x_cl22_write(bp, phy,
10680                                         MDIO_REG_GPHY_CL45_ADDR_REG,
10681                                         (0x1 << 14) | MDIO_AN_DEVAD);
10682                                 bnx2x_cl22_read(bp, phy,
10683                                         MDIO_REG_GPHY_CL45_DATA_REG,
10684                                         &val);
10685                         }
10686                         DP(NETIF_MSG_LINK, "EEE resolution: 0x%x\n", val);
10687                 }
10688
10689                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
10690
10691                 if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
10692                         /* report LP advertised speeds */
10693                         bnx2x_cl22_read(bp, phy, 0x5, &val);
10694
10695                         if (val & (1<<5))
10696                                 vars->link_status |=
10697                                   LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
10698                         if (val & (1<<6))
10699                                 vars->link_status |=
10700                                   LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
10701                         if (val & (1<<7))
10702                                 vars->link_status |=
10703                                   LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
10704                         if (val & (1<<8))
10705                                 vars->link_status |=
10706                                   LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
10707                         if (val & (1<<9))
10708                                 vars->link_status |=
10709                                   LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
10710
10711                         bnx2x_cl22_read(bp, phy, 0xa, &val);
10712                         if (val & (1<<10))
10713                                 vars->link_status |=
10714                                   LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
10715                         if (val & (1<<11))
10716                                 vars->link_status |=
10717                                   LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
10718                 }
10719         }
10720         return link_up;
10721 }
10722
10723 static void bnx2x_54618se_config_loopback(struct bnx2x_phy *phy,
10724                                           struct link_params *params)
10725 {
10726         struct bnx2x *bp = params->bp;
10727         u16 val;
10728         u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
10729
10730         DP(NETIF_MSG_LINK, "2PMA/PMD ext_phy_loopback: 54618se\n");
10731
10732         /* Enable master/slave manual mmode and set to master */
10733         /* mii write 9 [bits set 11 12] */
10734         bnx2x_cl22_write(bp, phy, 0x09, 3<<11);
10735
10736         /* forced 1G and disable autoneg */
10737         /* set val [mii read 0] */
10738         /* set val [expr $val & [bits clear 6 12 13]] */
10739         /* set val [expr $val | [bits set 6 8]] */
10740         /* mii write 0 $val */
10741         bnx2x_cl22_read(bp, phy, 0x00, &val);
10742         val &= ~((1<<6) | (1<<12) | (1<<13));
10743         val |= (1<<6) | (1<<8);
10744         bnx2x_cl22_write(bp, phy, 0x00, val);
10745
10746         /* Set external loopback and Tx using 6dB coding */
10747         /* mii write 0x18 7 */
10748         /* set val [mii read 0x18] */
10749         /* mii write 0x18 [expr $val | [bits set 10 15]] */
10750         bnx2x_cl22_write(bp, phy, 0x18, 7);
10751         bnx2x_cl22_read(bp, phy, 0x18, &val);
10752         bnx2x_cl22_write(bp, phy, 0x18, val | (1<<10) | (1<<15));
10753
10754         /* This register opens the gate for the UMAC despite its name */
10755         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
10756
10757         /*
10758          * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
10759          * length used by the MAC receive logic to check frames.
10760          */
10761         REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
10762 }
10763
10764 /******************************************************************/
10765 /*                      SFX7101 PHY SECTION                       */
10766 /******************************************************************/
10767 static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
10768                                        struct link_params *params)
10769 {
10770         struct bnx2x *bp = params->bp;
10771         /* SFX7101_XGXS_TEST1 */
10772         bnx2x_cl45_write(bp, phy,
10773                          MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
10774 }
10775
10776 static int bnx2x_7101_config_init(struct bnx2x_phy *phy,
10777                                   struct link_params *params,
10778                                   struct link_vars *vars)
10779 {
10780         u16 fw_ver1, fw_ver2, val;
10781         struct bnx2x *bp = params->bp;
10782         DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
10783
10784         /* Restore normal power mode*/
10785         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
10786                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
10787         /* HW reset */
10788         bnx2x_ext_phy_hw_reset(bp, params->port);
10789         bnx2x_wait_reset_complete(bp, phy, params);
10790
10791         bnx2x_cl45_write(bp, phy,
10792                          MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x1);
10793         DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
10794         bnx2x_cl45_write(bp, phy,
10795                          MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
10796
10797         bnx2x_ext_phy_set_pause(params, phy, vars);
10798         /* Restart autoneg */
10799         bnx2x_cl45_read(bp, phy,
10800                         MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
10801         val |= 0x200;
10802         bnx2x_cl45_write(bp, phy,
10803                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
10804
10805         /* Save spirom version */
10806         bnx2x_cl45_read(bp, phy,
10807                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
10808
10809         bnx2x_cl45_read(bp, phy,
10810                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
10811         bnx2x_save_spirom_version(bp, params->port,
10812                                   (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
10813         return 0;
10814 }
10815
10816 static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
10817                                  struct link_params *params,
10818                                  struct link_vars *vars)
10819 {
10820         struct bnx2x *bp = params->bp;
10821         u8 link_up;
10822         u16 val1, val2;
10823         bnx2x_cl45_read(bp, phy,
10824                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
10825         bnx2x_cl45_read(bp, phy,
10826                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
10827         DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
10828                    val2, val1);
10829         bnx2x_cl45_read(bp, phy,
10830                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
10831         bnx2x_cl45_read(bp, phy,
10832                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
10833         DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
10834                    val2, val1);
10835         link_up = ((val1 & 4) == 4);
10836         /* if link is up print the AN outcome of the SFX7101 PHY */
10837         if (link_up) {
10838                 bnx2x_cl45_read(bp, phy,
10839                                 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
10840                                 &val2);
10841                 vars->line_speed = SPEED_10000;
10842                 vars->duplex = DUPLEX_FULL;
10843                 DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
10844                            val2, (val2 & (1<<14)));
10845                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
10846                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
10847
10848                 /* read LP advertised speeds */
10849                 if (val2 & (1<<11))
10850                         vars->link_status |=
10851                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
10852         }
10853         return link_up;
10854 }
10855
10856 static int bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
10857 {
10858         if (*len < 5)
10859                 return -EINVAL;
10860         str[0] = (spirom_ver & 0xFF);
10861         str[1] = (spirom_ver & 0xFF00) >> 8;
10862         str[2] = (spirom_ver & 0xFF0000) >> 16;
10863         str[3] = (spirom_ver & 0xFF000000) >> 24;
10864         str[4] = '\0';
10865         *len -= 5;
10866         return 0;
10867 }
10868
10869 void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
10870 {
10871         u16 val, cnt;
10872
10873         bnx2x_cl45_read(bp, phy,
10874                         MDIO_PMA_DEVAD,
10875                         MDIO_PMA_REG_7101_RESET, &val);
10876
10877         for (cnt = 0; cnt < 10; cnt++) {
10878                 msleep(50);
10879                 /* Writes a self-clearing reset */
10880                 bnx2x_cl45_write(bp, phy,
10881                                  MDIO_PMA_DEVAD,
10882                                  MDIO_PMA_REG_7101_RESET,
10883                                  (val | (1<<15)));
10884                 /* Wait for clear */
10885                 bnx2x_cl45_read(bp, phy,
10886                                 MDIO_PMA_DEVAD,
10887                                 MDIO_PMA_REG_7101_RESET, &val);
10888
10889                 if ((val & (1<<15)) == 0)
10890                         break;
10891         }
10892 }
10893
10894 static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
10895                                 struct link_params *params) {
10896         /* Low power mode is controlled by GPIO 2 */
10897         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
10898                        MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
10899         /* The PHY reset is controlled by GPIO 1 */
10900         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
10901                        MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
10902 }
10903
10904 static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy,
10905                                     struct link_params *params, u8 mode)
10906 {
10907         u16 val = 0;
10908         struct bnx2x *bp = params->bp;
10909         switch (mode) {
10910         case LED_MODE_FRONT_PANEL_OFF:
10911         case LED_MODE_OFF:
10912                 val = 2;
10913                 break;
10914         case LED_MODE_ON:
10915                 val = 1;
10916                 break;
10917         case LED_MODE_OPER:
10918                 val = 0;
10919                 break;
10920         }
10921         bnx2x_cl45_write(bp, phy,
10922                          MDIO_PMA_DEVAD,
10923                          MDIO_PMA_REG_7107_LINK_LED_CNTL,
10924                          val);
10925 }
10926
10927 /******************************************************************/
10928 /*                      STATIC PHY DECLARATION                    */
10929 /******************************************************************/
10930
10931 static struct bnx2x_phy phy_null = {
10932         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
10933         .addr           = 0,
10934         .def_md_devad   = 0,
10935         .flags          = FLAGS_INIT_XGXS_FIRST,
10936         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10937         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10938         .mdio_ctrl      = 0,
10939         .supported      = 0,
10940         .media_type     = ETH_PHY_NOT_PRESENT,
10941         .ver_addr       = 0,
10942         .req_flow_ctrl  = 0,
10943         .req_line_speed = 0,
10944         .speed_cap_mask = 0,
10945         .req_duplex     = 0,
10946         .rsrv           = 0,
10947         .config_init    = (config_init_t)NULL,
10948         .read_status    = (read_status_t)NULL,
10949         .link_reset     = (link_reset_t)NULL,
10950         .config_loopback = (config_loopback_t)NULL,
10951         .format_fw_ver  = (format_fw_ver_t)NULL,
10952         .hw_reset       = (hw_reset_t)NULL,
10953         .set_link_led   = (set_link_led_t)NULL,
10954         .phy_specific_func = (phy_specific_func_t)NULL
10955 };
10956
10957 static struct bnx2x_phy phy_serdes = {
10958         .type           = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
10959         .addr           = 0xff,
10960         .def_md_devad   = 0,
10961         .flags          = 0,
10962         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10963         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10964         .mdio_ctrl      = 0,
10965         .supported      = (SUPPORTED_10baseT_Half |
10966                            SUPPORTED_10baseT_Full |
10967                            SUPPORTED_100baseT_Half |
10968                            SUPPORTED_100baseT_Full |
10969                            SUPPORTED_1000baseT_Full |
10970                            SUPPORTED_2500baseX_Full |
10971                            SUPPORTED_TP |
10972                            SUPPORTED_Autoneg |
10973                            SUPPORTED_Pause |
10974                            SUPPORTED_Asym_Pause),
10975         .media_type     = ETH_PHY_BASE_T,
10976         .ver_addr       = 0,
10977         .req_flow_ctrl  = 0,
10978         .req_line_speed = 0,
10979         .speed_cap_mask = 0,
10980         .req_duplex     = 0,
10981         .rsrv           = 0,
10982         .config_init    = (config_init_t)bnx2x_xgxs_config_init,
10983         .read_status    = (read_status_t)bnx2x_link_settings_status,
10984         .link_reset     = (link_reset_t)bnx2x_int_link_reset,
10985         .config_loopback = (config_loopback_t)NULL,
10986         .format_fw_ver  = (format_fw_ver_t)NULL,
10987         .hw_reset       = (hw_reset_t)NULL,
10988         .set_link_led   = (set_link_led_t)NULL,
10989         .phy_specific_func = (phy_specific_func_t)NULL
10990 };
10991
10992 static struct bnx2x_phy phy_xgxs = {
10993         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
10994         .addr           = 0xff,
10995         .def_md_devad   = 0,
10996         .flags          = 0,
10997         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10998         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10999         .mdio_ctrl      = 0,
11000         .supported      = (SUPPORTED_10baseT_Half |
11001                            SUPPORTED_10baseT_Full |
11002                            SUPPORTED_100baseT_Half |
11003                            SUPPORTED_100baseT_Full |
11004                            SUPPORTED_1000baseT_Full |
11005                            SUPPORTED_2500baseX_Full |
11006                            SUPPORTED_10000baseT_Full |
11007                            SUPPORTED_FIBRE |
11008                            SUPPORTED_Autoneg |
11009                            SUPPORTED_Pause |
11010                            SUPPORTED_Asym_Pause),
11011         .media_type     = ETH_PHY_CX4,
11012         .ver_addr       = 0,
11013         .req_flow_ctrl  = 0,
11014         .req_line_speed = 0,
11015         .speed_cap_mask = 0,
11016         .req_duplex     = 0,
11017         .rsrv           = 0,
11018         .config_init    = (config_init_t)bnx2x_xgxs_config_init,
11019         .read_status    = (read_status_t)bnx2x_link_settings_status,
11020         .link_reset     = (link_reset_t)bnx2x_int_link_reset,
11021         .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
11022         .format_fw_ver  = (format_fw_ver_t)NULL,
11023         .hw_reset       = (hw_reset_t)NULL,
11024         .set_link_led   = (set_link_led_t)NULL,
11025         .phy_specific_func = (phy_specific_func_t)NULL
11026 };
11027 static struct bnx2x_phy phy_warpcore = {
11028         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
11029         .addr           = 0xff,
11030         .def_md_devad   = 0,
11031         .flags          = FLAGS_HW_LOCK_REQUIRED,
11032         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11033         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11034         .mdio_ctrl      = 0,
11035         .supported      = (SUPPORTED_10baseT_Half |
11036                              SUPPORTED_10baseT_Full |
11037                              SUPPORTED_100baseT_Half |
11038                              SUPPORTED_100baseT_Full |
11039                              SUPPORTED_1000baseT_Full |
11040                              SUPPORTED_10000baseT_Full |
11041                              SUPPORTED_20000baseKR2_Full |
11042                              SUPPORTED_20000baseMLD2_Full |
11043                              SUPPORTED_FIBRE |
11044                              SUPPORTED_Autoneg |
11045                              SUPPORTED_Pause |
11046                              SUPPORTED_Asym_Pause),
11047         .media_type     = ETH_PHY_UNSPECIFIED,
11048         .ver_addr       = 0,
11049         .req_flow_ctrl  = 0,
11050         .req_line_speed = 0,
11051         .speed_cap_mask = 0,
11052         /* req_duplex = */0,
11053         /* rsrv = */0,
11054         .config_init    = (config_init_t)bnx2x_warpcore_config_init,
11055         .read_status    = (read_status_t)bnx2x_warpcore_read_status,
11056         .link_reset     = (link_reset_t)bnx2x_warpcore_link_reset,
11057         .config_loopback = (config_loopback_t)bnx2x_set_warpcore_loopback,
11058         .format_fw_ver  = (format_fw_ver_t)NULL,
11059         .hw_reset       = (hw_reset_t)bnx2x_warpcore_hw_reset,
11060         .set_link_led   = (set_link_led_t)NULL,
11061         .phy_specific_func = (phy_specific_func_t)NULL
11062 };
11063
11064
11065 static struct bnx2x_phy phy_7101 = {
11066         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
11067         .addr           = 0xff,
11068         .def_md_devad   = 0,
11069         .flags          = FLAGS_FAN_FAILURE_DET_REQ,
11070         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11071         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11072         .mdio_ctrl      = 0,
11073         .supported      = (SUPPORTED_10000baseT_Full |
11074                            SUPPORTED_TP |
11075                            SUPPORTED_Autoneg |
11076                            SUPPORTED_Pause |
11077                            SUPPORTED_Asym_Pause),
11078         .media_type     = ETH_PHY_BASE_T,
11079         .ver_addr       = 0,
11080         .req_flow_ctrl  = 0,
11081         .req_line_speed = 0,
11082         .speed_cap_mask = 0,
11083         .req_duplex     = 0,
11084         .rsrv           = 0,
11085         .config_init    = (config_init_t)bnx2x_7101_config_init,
11086         .read_status    = (read_status_t)bnx2x_7101_read_status,
11087         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
11088         .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
11089         .format_fw_ver  = (format_fw_ver_t)bnx2x_7101_format_ver,
11090         .hw_reset       = (hw_reset_t)bnx2x_7101_hw_reset,
11091         .set_link_led   = (set_link_led_t)bnx2x_7101_set_link_led,
11092         .phy_specific_func = (phy_specific_func_t)NULL
11093 };
11094 static struct bnx2x_phy phy_8073 = {
11095         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
11096         .addr           = 0xff,
11097         .def_md_devad   = 0,
11098         .flags          = FLAGS_HW_LOCK_REQUIRED,
11099         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11100         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11101         .mdio_ctrl      = 0,
11102         .supported      = (SUPPORTED_10000baseT_Full |
11103                            SUPPORTED_2500baseX_Full |
11104                            SUPPORTED_1000baseT_Full |
11105                            SUPPORTED_FIBRE |
11106                            SUPPORTED_Autoneg |
11107                            SUPPORTED_Pause |
11108                            SUPPORTED_Asym_Pause),
11109         .media_type     = ETH_PHY_KR,
11110         .ver_addr       = 0,
11111         .req_flow_ctrl  = 0,
11112         .req_line_speed = 0,
11113         .speed_cap_mask = 0,
11114         .req_duplex     = 0,
11115         .rsrv           = 0,
11116         .config_init    = (config_init_t)bnx2x_8073_config_init,
11117         .read_status    = (read_status_t)bnx2x_8073_read_status,
11118         .link_reset     = (link_reset_t)bnx2x_8073_link_reset,
11119         .config_loopback = (config_loopback_t)NULL,
11120         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
11121         .hw_reset       = (hw_reset_t)NULL,
11122         .set_link_led   = (set_link_led_t)NULL,
11123         .phy_specific_func = (phy_specific_func_t)NULL
11124 };
11125 static struct bnx2x_phy phy_8705 = {
11126         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
11127         .addr           = 0xff,
11128         .def_md_devad   = 0,
11129         .flags          = FLAGS_INIT_XGXS_FIRST,
11130         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11131         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11132         .mdio_ctrl      = 0,
11133         .supported      = (SUPPORTED_10000baseT_Full |
11134                            SUPPORTED_FIBRE |
11135                            SUPPORTED_Pause |
11136                            SUPPORTED_Asym_Pause),
11137         .media_type     = ETH_PHY_XFP_FIBER,
11138         .ver_addr       = 0,
11139         .req_flow_ctrl  = 0,
11140         .req_line_speed = 0,
11141         .speed_cap_mask = 0,
11142         .req_duplex     = 0,
11143         .rsrv           = 0,
11144         .config_init    = (config_init_t)bnx2x_8705_config_init,
11145         .read_status    = (read_status_t)bnx2x_8705_read_status,
11146         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
11147         .config_loopback = (config_loopback_t)NULL,
11148         .format_fw_ver  = (format_fw_ver_t)bnx2x_null_format_ver,
11149         .hw_reset       = (hw_reset_t)NULL,
11150         .set_link_led   = (set_link_led_t)NULL,
11151         .phy_specific_func = (phy_specific_func_t)NULL
11152 };
11153 static struct bnx2x_phy phy_8706 = {
11154         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
11155         .addr           = 0xff,
11156         .def_md_devad   = 0,
11157         .flags          = FLAGS_INIT_XGXS_FIRST,
11158         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11159         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11160         .mdio_ctrl      = 0,
11161         .supported      = (SUPPORTED_10000baseT_Full |
11162                            SUPPORTED_1000baseT_Full |
11163                            SUPPORTED_FIBRE |
11164                            SUPPORTED_Pause |
11165                            SUPPORTED_Asym_Pause),
11166         .media_type     = ETH_PHY_SFP_FIBER,
11167         .ver_addr       = 0,
11168         .req_flow_ctrl  = 0,
11169         .req_line_speed = 0,
11170         .speed_cap_mask = 0,
11171         .req_duplex     = 0,
11172         .rsrv           = 0,
11173         .config_init    = (config_init_t)bnx2x_8706_config_init,
11174         .read_status    = (read_status_t)bnx2x_8706_read_status,
11175         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
11176         .config_loopback = (config_loopback_t)NULL,
11177         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
11178         .hw_reset       = (hw_reset_t)NULL,
11179         .set_link_led   = (set_link_led_t)NULL,
11180         .phy_specific_func = (phy_specific_func_t)NULL
11181 };
11182
11183 static struct bnx2x_phy phy_8726 = {
11184         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
11185         .addr           = 0xff,
11186         .def_md_devad   = 0,
11187         .flags          = (FLAGS_HW_LOCK_REQUIRED |
11188                            FLAGS_INIT_XGXS_FIRST),
11189         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11190         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11191         .mdio_ctrl      = 0,
11192         .supported      = (SUPPORTED_10000baseT_Full |
11193                            SUPPORTED_1000baseT_Full |
11194                            SUPPORTED_Autoneg |
11195                            SUPPORTED_FIBRE |
11196                            SUPPORTED_Pause |
11197                            SUPPORTED_Asym_Pause),
11198         .media_type     = ETH_PHY_NOT_PRESENT,
11199         .ver_addr       = 0,
11200         .req_flow_ctrl  = 0,
11201         .req_line_speed = 0,
11202         .speed_cap_mask = 0,
11203         .req_duplex     = 0,
11204         .rsrv           = 0,
11205         .config_init    = (config_init_t)bnx2x_8726_config_init,
11206         .read_status    = (read_status_t)bnx2x_8726_read_status,
11207         .link_reset     = (link_reset_t)bnx2x_8726_link_reset,
11208         .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
11209         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
11210         .hw_reset       = (hw_reset_t)NULL,
11211         .set_link_led   = (set_link_led_t)NULL,
11212         .phy_specific_func = (phy_specific_func_t)NULL
11213 };
11214
11215 static struct bnx2x_phy phy_8727 = {
11216         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
11217         .addr           = 0xff,
11218         .def_md_devad   = 0,
11219         .flags          = FLAGS_FAN_FAILURE_DET_REQ,
11220         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11221         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11222         .mdio_ctrl      = 0,
11223         .supported      = (SUPPORTED_10000baseT_Full |
11224                            SUPPORTED_1000baseT_Full |
11225                            SUPPORTED_FIBRE |
11226                            SUPPORTED_Pause |
11227                            SUPPORTED_Asym_Pause),
11228         .media_type     = ETH_PHY_NOT_PRESENT,
11229         .ver_addr       = 0,
11230         .req_flow_ctrl  = 0,
11231         .req_line_speed = 0,
11232         .speed_cap_mask = 0,
11233         .req_duplex     = 0,
11234         .rsrv           = 0,
11235         .config_init    = (config_init_t)bnx2x_8727_config_init,
11236         .read_status    = (read_status_t)bnx2x_8727_read_status,
11237         .link_reset     = (link_reset_t)bnx2x_8727_link_reset,
11238         .config_loopback = (config_loopback_t)NULL,
11239         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
11240         .hw_reset       = (hw_reset_t)bnx2x_8727_hw_reset,
11241         .set_link_led   = (set_link_led_t)bnx2x_8727_set_link_led,
11242         .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func
11243 };
11244 static struct bnx2x_phy phy_8481 = {
11245         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
11246         .addr           = 0xff,
11247         .def_md_devad   = 0,
11248         .flags          = FLAGS_FAN_FAILURE_DET_REQ |
11249                           FLAGS_REARM_LATCH_SIGNAL,
11250         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11251         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11252         .mdio_ctrl      = 0,
11253         .supported      = (SUPPORTED_10baseT_Half |
11254                            SUPPORTED_10baseT_Full |
11255                            SUPPORTED_100baseT_Half |
11256                            SUPPORTED_100baseT_Full |
11257                            SUPPORTED_1000baseT_Full |
11258                            SUPPORTED_10000baseT_Full |
11259                            SUPPORTED_TP |
11260                            SUPPORTED_Autoneg |
11261                            SUPPORTED_Pause |
11262                            SUPPORTED_Asym_Pause),
11263         .media_type     = ETH_PHY_BASE_T,
11264         .ver_addr       = 0,
11265         .req_flow_ctrl  = 0,
11266         .req_line_speed = 0,
11267         .speed_cap_mask = 0,
11268         .req_duplex     = 0,
11269         .rsrv           = 0,
11270         .config_init    = (config_init_t)bnx2x_8481_config_init,
11271         .read_status    = (read_status_t)bnx2x_848xx_read_status,
11272         .link_reset     = (link_reset_t)bnx2x_8481_link_reset,
11273         .config_loopback = (config_loopback_t)NULL,
11274         .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
11275         .hw_reset       = (hw_reset_t)bnx2x_8481_hw_reset,
11276         .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
11277         .phy_specific_func = (phy_specific_func_t)NULL
11278 };
11279
11280 static struct bnx2x_phy phy_84823 = {
11281         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
11282         .addr           = 0xff,
11283         .def_md_devad   = 0,
11284         .flags          = FLAGS_FAN_FAILURE_DET_REQ |
11285                           FLAGS_REARM_LATCH_SIGNAL,
11286         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11287         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11288         .mdio_ctrl      = 0,
11289         .supported      = (SUPPORTED_10baseT_Half |
11290                            SUPPORTED_10baseT_Full |
11291                            SUPPORTED_100baseT_Half |
11292                            SUPPORTED_100baseT_Full |
11293                            SUPPORTED_1000baseT_Full |
11294                            SUPPORTED_10000baseT_Full |
11295                            SUPPORTED_TP |
11296                            SUPPORTED_Autoneg |
11297                            SUPPORTED_Pause |
11298                            SUPPORTED_Asym_Pause),
11299         .media_type     = ETH_PHY_BASE_T,
11300         .ver_addr       = 0,
11301         .req_flow_ctrl  = 0,
11302         .req_line_speed = 0,
11303         .speed_cap_mask = 0,
11304         .req_duplex     = 0,
11305         .rsrv           = 0,
11306         .config_init    = (config_init_t)bnx2x_848x3_config_init,
11307         .read_status    = (read_status_t)bnx2x_848xx_read_status,
11308         .link_reset     = (link_reset_t)bnx2x_848x3_link_reset,
11309         .config_loopback = (config_loopback_t)NULL,
11310         .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
11311         .hw_reset       = (hw_reset_t)NULL,
11312         .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
11313         .phy_specific_func = (phy_specific_func_t)NULL
11314 };
11315
11316 static struct bnx2x_phy phy_84833 = {
11317         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833,
11318         .addr           = 0xff,
11319         .def_md_devad   = 0,
11320         .flags          = FLAGS_FAN_FAILURE_DET_REQ |
11321                             FLAGS_REARM_LATCH_SIGNAL,
11322         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11323         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11324         .mdio_ctrl      = 0,
11325         .supported      = (SUPPORTED_100baseT_Half |
11326                            SUPPORTED_100baseT_Full |
11327                            SUPPORTED_1000baseT_Full |
11328                            SUPPORTED_10000baseT_Full |
11329                            SUPPORTED_TP |
11330                            SUPPORTED_Autoneg |
11331                            SUPPORTED_Pause |
11332                            SUPPORTED_Asym_Pause),
11333         .media_type     = ETH_PHY_BASE_T,
11334         .ver_addr       = 0,
11335         .req_flow_ctrl  = 0,
11336         .req_line_speed = 0,
11337         .speed_cap_mask = 0,
11338         .req_duplex     = 0,
11339         .rsrv           = 0,
11340         .config_init    = (config_init_t)bnx2x_848x3_config_init,
11341         .read_status    = (read_status_t)bnx2x_848xx_read_status,
11342         .link_reset     = (link_reset_t)bnx2x_848x3_link_reset,
11343         .config_loopback = (config_loopback_t)NULL,
11344         .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
11345         .hw_reset       = (hw_reset_t)bnx2x_84833_hw_reset_phy,
11346         .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
11347         .phy_specific_func = (phy_specific_func_t)NULL
11348 };
11349
11350 static struct bnx2x_phy phy_54618se = {
11351         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE,
11352         .addr           = 0xff,
11353         .def_md_devad   = 0,
11354         .flags          = FLAGS_INIT_XGXS_FIRST,
11355         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11356         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11357         .mdio_ctrl      = 0,
11358         .supported      = (SUPPORTED_10baseT_Half |
11359                            SUPPORTED_10baseT_Full |
11360                            SUPPORTED_100baseT_Half |
11361                            SUPPORTED_100baseT_Full |
11362                            SUPPORTED_1000baseT_Full |
11363                            SUPPORTED_TP |
11364                            SUPPORTED_Autoneg |
11365                            SUPPORTED_Pause |
11366                            SUPPORTED_Asym_Pause),
11367         .media_type     = ETH_PHY_BASE_T,
11368         .ver_addr       = 0,
11369         .req_flow_ctrl  = 0,
11370         .req_line_speed = 0,
11371         .speed_cap_mask = 0,
11372         /* req_duplex = */0,
11373         /* rsrv = */0,
11374         .config_init    = (config_init_t)bnx2x_54618se_config_init,
11375         .read_status    = (read_status_t)bnx2x_54618se_read_status,
11376         .link_reset     = (link_reset_t)bnx2x_54618se_link_reset,
11377         .config_loopback = (config_loopback_t)bnx2x_54618se_config_loopback,
11378         .format_fw_ver  = (format_fw_ver_t)NULL,
11379         .hw_reset       = (hw_reset_t)NULL,
11380         .set_link_led   = (set_link_led_t)bnx2x_5461x_set_link_led,
11381         .phy_specific_func = (phy_specific_func_t)NULL
11382 };
11383 /*****************************************************************/
11384 /*                                                               */
11385 /* Populate the phy according. Main function: bnx2x_populate_phy   */
11386 /*                                                               */
11387 /*****************************************************************/
11388
11389 static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
11390                                      struct bnx2x_phy *phy, u8 port,
11391                                      u8 phy_index)
11392 {
11393         /* Get the 4 lanes xgxs config rx and tx */
11394         u32 rx = 0, tx = 0, i;
11395         for (i = 0; i < 2; i++) {
11396                 /*
11397                  * INT_PHY and EXT_PHY1 share the same value location in the
11398                  * shmem. When num_phys is greater than 1, than this value
11399                  * applies only to EXT_PHY1
11400                  */
11401                 if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
11402                         rx = REG_RD(bp, shmem_base +
11403                                     offsetof(struct shmem_region,
11404                           dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
11405
11406                         tx = REG_RD(bp, shmem_base +
11407                                     offsetof(struct shmem_region,
11408                           dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
11409                 } else {
11410                         rx = REG_RD(bp, shmem_base +
11411                                     offsetof(struct shmem_region,
11412                          dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
11413
11414                         tx = REG_RD(bp, shmem_base +
11415                                     offsetof(struct shmem_region,
11416                          dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
11417                 }
11418
11419                 phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
11420                 phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
11421
11422                 phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
11423                 phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
11424         }
11425 }
11426
11427 static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
11428                                     u8 phy_index, u8 port)
11429 {
11430         u32 ext_phy_config = 0;
11431         switch (phy_index) {
11432         case EXT_PHY1:
11433                 ext_phy_config = REG_RD(bp, shmem_base +
11434                                               offsetof(struct shmem_region,
11435                         dev_info.port_hw_config[port].external_phy_config));
11436                 break;
11437         case EXT_PHY2:
11438                 ext_phy_config = REG_RD(bp, shmem_base +
11439                                               offsetof(struct shmem_region,
11440                         dev_info.port_hw_config[port].external_phy_config2));
11441                 break;
11442         default:
11443                 DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
11444                 return -EINVAL;
11445         }
11446
11447         return ext_phy_config;
11448 }
11449 static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
11450                                   struct bnx2x_phy *phy)
11451 {
11452         u32 phy_addr;
11453         u32 chip_id;
11454         u32 switch_cfg = (REG_RD(bp, shmem_base +
11455                                        offsetof(struct shmem_region,
11456                         dev_info.port_feature_config[port].link_config)) &
11457                           PORT_FEATURE_CONNECTED_SWITCH_MASK);
11458         chip_id = (REG_RD(bp, MISC_REG_CHIP_NUM) << 16) |
11459                 ((REG_RD(bp, MISC_REG_CHIP_REV) & 0xf) << 12);
11460
11461         DP(NETIF_MSG_LINK, ":chip_id = 0x%x\n", chip_id);
11462         if (USES_WARPCORE(bp)) {
11463                 u32 serdes_net_if;
11464                 phy_addr = REG_RD(bp,
11465                                   MISC_REG_WC0_CTRL_PHY_ADDR);
11466                 *phy = phy_warpcore;
11467                 if (REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR) == 0x3)
11468                         phy->flags |= FLAGS_4_PORT_MODE;
11469                 else
11470                         phy->flags &= ~FLAGS_4_PORT_MODE;
11471                         /* Check Dual mode */
11472                 serdes_net_if = (REG_RD(bp, shmem_base +
11473                                         offsetof(struct shmem_region, dev_info.
11474                                         port_hw_config[port].default_cfg)) &
11475                                  PORT_HW_CFG_NET_SERDES_IF_MASK);
11476                 /*
11477                  * Set the appropriate supported and flags indications per
11478                  * interface type of the chip
11479                  */
11480                 switch (serdes_net_if) {
11481                 case PORT_HW_CFG_NET_SERDES_IF_SGMII:
11482                         phy->supported &= (SUPPORTED_10baseT_Half |
11483                                            SUPPORTED_10baseT_Full |
11484                                            SUPPORTED_100baseT_Half |
11485                                            SUPPORTED_100baseT_Full |
11486                                            SUPPORTED_1000baseT_Full |
11487                                            SUPPORTED_FIBRE |
11488                                            SUPPORTED_Autoneg |
11489                                            SUPPORTED_Pause |
11490                                            SUPPORTED_Asym_Pause);
11491                         phy->media_type = ETH_PHY_BASE_T;
11492                         break;
11493                 case PORT_HW_CFG_NET_SERDES_IF_XFI:
11494                         phy->media_type = ETH_PHY_XFP_FIBER;
11495                         break;
11496                 case PORT_HW_CFG_NET_SERDES_IF_SFI:
11497                         phy->supported &= (SUPPORTED_1000baseT_Full |
11498                                            SUPPORTED_10000baseT_Full |
11499                                            SUPPORTED_FIBRE |
11500                                            SUPPORTED_Pause |
11501                                            SUPPORTED_Asym_Pause);
11502                         phy->media_type = ETH_PHY_SFP_FIBER;
11503                         break;
11504                 case PORT_HW_CFG_NET_SERDES_IF_KR:
11505                         phy->media_type = ETH_PHY_KR;
11506                         phy->supported &= (SUPPORTED_1000baseT_Full |
11507                                            SUPPORTED_10000baseT_Full |
11508                                            SUPPORTED_FIBRE |
11509                                            SUPPORTED_Autoneg |
11510                                            SUPPORTED_Pause |
11511                                            SUPPORTED_Asym_Pause);
11512                         break;
11513                 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
11514                         phy->media_type = ETH_PHY_KR;
11515                         phy->flags |= FLAGS_WC_DUAL_MODE;
11516                         phy->supported &= (SUPPORTED_20000baseMLD2_Full |
11517                                            SUPPORTED_FIBRE |
11518                                            SUPPORTED_Pause |
11519                                            SUPPORTED_Asym_Pause);
11520                         break;
11521                 case PORT_HW_CFG_NET_SERDES_IF_KR2:
11522                         phy->media_type = ETH_PHY_KR;
11523                         phy->flags |= FLAGS_WC_DUAL_MODE;
11524                         phy->supported &= (SUPPORTED_20000baseKR2_Full |
11525                                            SUPPORTED_FIBRE |
11526                                            SUPPORTED_Pause |
11527                                            SUPPORTED_Asym_Pause);
11528                         break;
11529                 default:
11530                         DP(NETIF_MSG_LINK, "Unknown WC interface type 0x%x\n",
11531                                        serdes_net_if);
11532                         break;
11533                 }
11534
11535                 /*
11536                  * Enable MDC/MDIO work-around for E3 A0 since free running MDC
11537                  * was not set as expected. For B0, ECO will be enabled so there
11538                  * won't be an issue there
11539                  */
11540                 if (CHIP_REV(bp) == CHIP_REV_Ax)
11541                         phy->flags |= FLAGS_MDC_MDIO_WA;
11542                 else
11543                         phy->flags |= FLAGS_MDC_MDIO_WA_B0;
11544         } else {
11545                 switch (switch_cfg) {
11546                 case SWITCH_CFG_1G:
11547                         phy_addr = REG_RD(bp,
11548                                           NIG_REG_SERDES0_CTRL_PHY_ADDR +
11549                                           port * 0x10);
11550                         *phy = phy_serdes;
11551                         break;
11552                 case SWITCH_CFG_10G:
11553                         phy_addr = REG_RD(bp,
11554                                           NIG_REG_XGXS0_CTRL_PHY_ADDR +
11555                                           port * 0x18);
11556                         *phy = phy_xgxs;
11557                         break;
11558                 default:
11559                         DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
11560                         return -EINVAL;
11561                 }
11562         }
11563         phy->addr = (u8)phy_addr;
11564         phy->mdio_ctrl = bnx2x_get_emac_base(bp,
11565                                             SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
11566                                             port);
11567         if (CHIP_IS_E2(bp))
11568                 phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
11569         else
11570                 phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
11571
11572         DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
11573                    port, phy->addr, phy->mdio_ctrl);
11574
11575         bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
11576         return 0;
11577 }
11578
11579 static int bnx2x_populate_ext_phy(struct bnx2x *bp,
11580                                   u8 phy_index,
11581                                   u32 shmem_base,
11582                                   u32 shmem2_base,
11583                                   u8 port,
11584                                   struct bnx2x_phy *phy)
11585 {
11586         u32 ext_phy_config, phy_type, config2;
11587         u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
11588         ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
11589                                                   phy_index, port);
11590         phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
11591         /* Select the phy type */
11592         switch (phy_type) {
11593         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
11594                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
11595                 *phy = phy_8073;
11596                 break;
11597         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
11598                 *phy = phy_8705;
11599                 break;
11600         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
11601                 *phy = phy_8706;
11602                 break;
11603         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
11604                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
11605                 *phy = phy_8726;
11606                 break;
11607         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
11608                 /* BCM8727_NOC => BCM8727 no over current */
11609                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
11610                 *phy = phy_8727;
11611                 phy->flags |= FLAGS_NOC;
11612                 break;
11613         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
11614         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
11615                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
11616                 *phy = phy_8727;
11617                 break;
11618         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
11619                 *phy = phy_8481;
11620                 break;
11621         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
11622                 *phy = phy_84823;
11623                 break;
11624         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
11625                 *phy = phy_84833;
11626                 break;
11627         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616:
11628         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE:
11629                 *phy = phy_54618se;
11630                 break;
11631         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
11632                 *phy = phy_7101;
11633                 break;
11634         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
11635                 *phy = phy_null;
11636                 return -EINVAL;
11637         default:
11638                 *phy = phy_null;
11639                 /* In case external PHY wasn't found */
11640                 if ((phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
11641                     (phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN))
11642                         return -EINVAL;
11643                 return 0;
11644         }
11645
11646         phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
11647         bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
11648
11649         /*
11650          * The shmem address of the phy version is located on different
11651          * structures. In case this structure is too old, do not set
11652          * the address
11653          */
11654         config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region,
11655                                         dev_info.shared_hw_config.config2));
11656         if (phy_index == EXT_PHY1) {
11657                 phy->ver_addr = shmem_base + offsetof(struct shmem_region,
11658                                 port_mb[port].ext_phy_fw_version);
11659
11660                 /* Check specific mdc mdio settings */
11661                 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
11662                         mdc_mdio_access = config2 &
11663                         SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
11664         } else {
11665                 u32 size = REG_RD(bp, shmem2_base);
11666
11667                 if (size >
11668                     offsetof(struct shmem2_region, ext_phy_fw_version2)) {
11669                         phy->ver_addr = shmem2_base +
11670                             offsetof(struct shmem2_region,
11671                                      ext_phy_fw_version2[port]);
11672                 }
11673                 /* Check specific mdc mdio settings */
11674                 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
11675                         mdc_mdio_access = (config2 &
11676                         SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
11677                         (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
11678                          SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
11679         }
11680         phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
11681
11682         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) &&
11683             (phy->ver_addr)) {
11684                 /*
11685                  * Remove 100Mb link supported for BCM84833 when phy fw
11686                  * version lower than or equal to 1.39
11687                  */
11688                 u32 raw_ver = REG_RD(bp, phy->ver_addr);
11689                 if (((raw_ver & 0x7F) <= 39) &&
11690                     (((raw_ver & 0xF80) >> 7) <= 1))
11691                         phy->supported &= ~(SUPPORTED_100baseT_Half |
11692                                             SUPPORTED_100baseT_Full);
11693         }
11694
11695         /*
11696          * In case mdc/mdio_access of the external phy is different than the
11697          * mdc/mdio access of the XGXS, a HW lock must be taken in each access
11698          * to prevent one port interfere with another port's CL45 operations.
11699          */
11700         if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH)
11701                 phy->flags |= FLAGS_HW_LOCK_REQUIRED;
11702         DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n",
11703                    phy_type, port, phy_index);
11704         DP(NETIF_MSG_LINK, "             addr=0x%x, mdio_ctl=0x%x\n",
11705                    phy->addr, phy->mdio_ctrl);
11706         return 0;
11707 }
11708
11709 static int bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
11710                               u32 shmem2_base, u8 port, struct bnx2x_phy *phy)
11711 {
11712         int status = 0;
11713         phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
11714         if (phy_index == INT_PHY)
11715                 return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
11716         status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
11717                                         port, phy);
11718         return status;
11719 }
11720
11721 static void bnx2x_phy_def_cfg(struct link_params *params,
11722                               struct bnx2x_phy *phy,
11723                               u8 phy_index)
11724 {
11725         struct bnx2x *bp = params->bp;
11726         u32 link_config;
11727         /* Populate the default phy configuration for MF mode */
11728         if (phy_index == EXT_PHY2) {
11729                 link_config = REG_RD(bp, params->shmem_base +
11730                                      offsetof(struct shmem_region, dev_info.
11731                         port_feature_config[params->port].link_config2));
11732                 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
11733                                              offsetof(struct shmem_region,
11734                                                       dev_info.
11735                         port_hw_config[params->port].speed_capability_mask2));
11736         } else {
11737                 link_config = REG_RD(bp, params->shmem_base +
11738                                      offsetof(struct shmem_region, dev_info.
11739                                 port_feature_config[params->port].link_config));
11740                 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
11741                                              offsetof(struct shmem_region,
11742                                                       dev_info.
11743                         port_hw_config[params->port].speed_capability_mask));
11744         }
11745         DP(NETIF_MSG_LINK,
11746            "Default config phy idx %x cfg 0x%x speed_cap_mask 0x%x\n",
11747            phy_index, link_config, phy->speed_cap_mask);
11748
11749         phy->req_duplex = DUPLEX_FULL;
11750         switch (link_config  & PORT_FEATURE_LINK_SPEED_MASK) {
11751         case PORT_FEATURE_LINK_SPEED_10M_HALF:
11752                 phy->req_duplex = DUPLEX_HALF;
11753         case PORT_FEATURE_LINK_SPEED_10M_FULL:
11754                 phy->req_line_speed = SPEED_10;
11755                 break;
11756         case PORT_FEATURE_LINK_SPEED_100M_HALF:
11757                 phy->req_duplex = DUPLEX_HALF;
11758         case PORT_FEATURE_LINK_SPEED_100M_FULL:
11759                 phy->req_line_speed = SPEED_100;
11760                 break;
11761         case PORT_FEATURE_LINK_SPEED_1G:
11762                 phy->req_line_speed = SPEED_1000;
11763                 break;
11764         case PORT_FEATURE_LINK_SPEED_2_5G:
11765                 phy->req_line_speed = SPEED_2500;
11766                 break;
11767         case PORT_FEATURE_LINK_SPEED_10G_CX4:
11768                 phy->req_line_speed = SPEED_10000;
11769                 break;
11770         default:
11771                 phy->req_line_speed = SPEED_AUTO_NEG;
11772                 break;
11773         }
11774
11775         switch (link_config  & PORT_FEATURE_FLOW_CONTROL_MASK) {
11776         case PORT_FEATURE_FLOW_CONTROL_AUTO:
11777                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
11778                 break;
11779         case PORT_FEATURE_FLOW_CONTROL_TX:
11780                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
11781                 break;
11782         case PORT_FEATURE_FLOW_CONTROL_RX:
11783                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
11784                 break;
11785         case PORT_FEATURE_FLOW_CONTROL_BOTH:
11786                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
11787                 break;
11788         default:
11789                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11790                 break;
11791         }
11792 }
11793
11794 u32 bnx2x_phy_selection(struct link_params *params)
11795 {
11796         u32 phy_config_swapped, prio_cfg;
11797         u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
11798
11799         phy_config_swapped = params->multi_phy_config &
11800                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
11801
11802         prio_cfg = params->multi_phy_config &
11803                         PORT_HW_CFG_PHY_SELECTION_MASK;
11804
11805         if (phy_config_swapped) {
11806                 switch (prio_cfg) {
11807                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
11808                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
11809                      break;
11810                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
11811                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
11812                      break;
11813                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
11814                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
11815                      break;
11816                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
11817                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
11818                      break;
11819                 }
11820         } else
11821                 return_cfg = prio_cfg;
11822
11823         return return_cfg;
11824 }
11825
11826
11827 int bnx2x_phy_probe(struct link_params *params)
11828 {
11829         u8 phy_index, actual_phy_idx;
11830         u32 phy_config_swapped, sync_offset, media_types;
11831         struct bnx2x *bp = params->bp;
11832         struct bnx2x_phy *phy;
11833         params->num_phys = 0;
11834         DP(NETIF_MSG_LINK, "Begin phy probe\n");
11835         phy_config_swapped = params->multi_phy_config &
11836                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
11837
11838         for (phy_index = INT_PHY; phy_index < MAX_PHYS;
11839               phy_index++) {
11840                 actual_phy_idx = phy_index;
11841                 if (phy_config_swapped) {
11842                         if (phy_index == EXT_PHY1)
11843                                 actual_phy_idx = EXT_PHY2;
11844                         else if (phy_index == EXT_PHY2)
11845                                 actual_phy_idx = EXT_PHY1;
11846                 }
11847                 DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x,"
11848                                " actual_phy_idx %x\n", phy_config_swapped,
11849                            phy_index, actual_phy_idx);
11850                 phy = &params->phy[actual_phy_idx];
11851                 if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
11852                                        params->shmem2_base, params->port,
11853                                        phy) != 0) {
11854                         params->num_phys = 0;
11855                         DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
11856                                    phy_index);
11857                         for (phy_index = INT_PHY;
11858                               phy_index < MAX_PHYS;
11859                               phy_index++)
11860                                 *phy = phy_null;
11861                         return -EINVAL;
11862                 }
11863                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
11864                         break;
11865
11866                 sync_offset = params->shmem_base +
11867                         offsetof(struct shmem_region,
11868                         dev_info.port_hw_config[params->port].media_type);
11869                 media_types = REG_RD(bp, sync_offset);
11870
11871                 /*
11872                  * Update media type for non-PMF sync only for the first time
11873                  * In case the media type changes afterwards, it will be updated
11874                  * using the update_status function
11875                  */
11876                 if ((media_types & (PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
11877                                     (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
11878                                      actual_phy_idx))) == 0) {
11879                         media_types |= ((phy->media_type &
11880                                         PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
11881                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
11882                                  actual_phy_idx));
11883                 }
11884                 REG_WR(bp, sync_offset, media_types);
11885
11886                 bnx2x_phy_def_cfg(params, phy, phy_index);
11887                 params->num_phys++;
11888         }
11889
11890         DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
11891         return 0;
11892 }
11893
11894 void bnx2x_init_bmac_loopback(struct link_params *params,
11895                               struct link_vars *vars)
11896 {
11897         struct bnx2x *bp = params->bp;
11898                 vars->link_up = 1;
11899                 vars->line_speed = SPEED_10000;
11900                 vars->duplex = DUPLEX_FULL;
11901                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11902                 vars->mac_type = MAC_TYPE_BMAC;
11903
11904                 vars->phy_flags = PHY_XGXS_FLAG;
11905
11906                 bnx2x_xgxs_deassert(params);
11907
11908                 /* set bmac loopback */
11909                 bnx2x_bmac_enable(params, vars, 1);
11910
11911                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11912 }
11913
11914 void bnx2x_init_emac_loopback(struct link_params *params,
11915                               struct link_vars *vars)
11916 {
11917         struct bnx2x *bp = params->bp;
11918                 vars->link_up = 1;
11919                 vars->line_speed = SPEED_1000;
11920                 vars->duplex = DUPLEX_FULL;
11921                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11922                 vars->mac_type = MAC_TYPE_EMAC;
11923
11924                 vars->phy_flags = PHY_XGXS_FLAG;
11925
11926                 bnx2x_xgxs_deassert(params);
11927                 /* set bmac loopback */
11928                 bnx2x_emac_enable(params, vars, 1);
11929                 bnx2x_emac_program(params, vars);
11930                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11931 }
11932
11933 void bnx2x_init_xmac_loopback(struct link_params *params,
11934                               struct link_vars *vars)
11935 {
11936         struct bnx2x *bp = params->bp;
11937         vars->link_up = 1;
11938         if (!params->req_line_speed[0])
11939                 vars->line_speed = SPEED_10000;
11940         else
11941                 vars->line_speed = params->req_line_speed[0];
11942         vars->duplex = DUPLEX_FULL;
11943         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11944         vars->mac_type = MAC_TYPE_XMAC;
11945         vars->phy_flags = PHY_XGXS_FLAG;
11946         /*
11947          * Set WC to loopback mode since link is required to provide clock
11948          * to the XMAC in 20G mode
11949          */
11950         bnx2x_set_aer_mmd(params, &params->phy[0]);
11951         bnx2x_warpcore_reset_lane(bp, &params->phy[0], 0);
11952         params->phy[INT_PHY].config_loopback(
11953                         &params->phy[INT_PHY],
11954                         params);
11955
11956         bnx2x_xmac_enable(params, vars, 1);
11957         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11958 }
11959
11960 void bnx2x_init_umac_loopback(struct link_params *params,
11961                               struct link_vars *vars)
11962 {
11963         struct bnx2x *bp = params->bp;
11964         vars->link_up = 1;
11965         vars->line_speed = SPEED_1000;
11966         vars->duplex = DUPLEX_FULL;
11967         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11968         vars->mac_type = MAC_TYPE_UMAC;
11969         vars->phy_flags = PHY_XGXS_FLAG;
11970         bnx2x_umac_enable(params, vars, 1);
11971
11972         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11973 }
11974
11975 void bnx2x_init_xgxs_loopback(struct link_params *params,
11976                               struct link_vars *vars)
11977 {
11978         struct bnx2x *bp = params->bp;
11979                 vars->link_up = 1;
11980                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11981                 vars->duplex = DUPLEX_FULL;
11982         if (params->req_line_speed[0] == SPEED_1000)
11983                         vars->line_speed = SPEED_1000;
11984         else
11985                         vars->line_speed = SPEED_10000;
11986
11987         if (!USES_WARPCORE(bp))
11988                 bnx2x_xgxs_deassert(params);
11989         bnx2x_link_initialize(params, vars);
11990
11991         if (params->req_line_speed[0] == SPEED_1000) {
11992                 if (USES_WARPCORE(bp))
11993                         bnx2x_umac_enable(params, vars, 0);
11994                 else {
11995                         bnx2x_emac_program(params, vars);
11996                         bnx2x_emac_enable(params, vars, 0);
11997                 }
11998         } else {
11999                 if (USES_WARPCORE(bp))
12000                         bnx2x_xmac_enable(params, vars, 0);
12001                 else
12002                         bnx2x_bmac_enable(params, vars, 0);
12003         }
12004
12005                 if (params->loopback_mode == LOOPBACK_XGXS) {
12006                         /* set 10G XGXS loopback */
12007                         params->phy[INT_PHY].config_loopback(
12008                                 &params->phy[INT_PHY],
12009                                 params);
12010
12011                 } else {
12012                         /* set external phy loopback */
12013                         u8 phy_index;
12014                         for (phy_index = EXT_PHY1;
12015                               phy_index < params->num_phys; phy_index++) {
12016                                 if (params->phy[phy_index].config_loopback)
12017                                         params->phy[phy_index].config_loopback(
12018                                                 &params->phy[phy_index],
12019                                                 params);
12020                         }
12021                 }
12022                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
12023
12024         bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
12025 }
12026
12027 int bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
12028 {
12029         struct bnx2x *bp = params->bp;
12030         DP(NETIF_MSG_LINK, "Phy Initialization started\n");
12031         DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n",
12032                    params->req_line_speed[0], params->req_flow_ctrl[0]);
12033         DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n",
12034                    params->req_line_speed[1], params->req_flow_ctrl[1]);
12035         vars->link_status = 0;
12036         vars->phy_link_up = 0;
12037         vars->link_up = 0;
12038         vars->line_speed = 0;
12039         vars->duplex = DUPLEX_FULL;
12040         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
12041         vars->mac_type = MAC_TYPE_NONE;
12042         vars->phy_flags = 0;
12043
12044         /* disable attentions */
12045         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
12046                        (NIG_MASK_XGXS0_LINK_STATUS |
12047                         NIG_MASK_XGXS0_LINK10G |
12048                         NIG_MASK_SERDES0_LINK_STATUS |
12049                         NIG_MASK_MI_INT));
12050
12051         bnx2x_emac_init(params, vars);
12052
12053         if (params->num_phys == 0) {
12054                 DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
12055                 return -EINVAL;
12056         }
12057         set_phy_vars(params, vars);
12058
12059         DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
12060         switch (params->loopback_mode) {
12061         case LOOPBACK_BMAC:
12062                 bnx2x_init_bmac_loopback(params, vars);
12063                 break;
12064         case LOOPBACK_EMAC:
12065                 bnx2x_init_emac_loopback(params, vars);
12066                 break;
12067         case LOOPBACK_XMAC:
12068                 bnx2x_init_xmac_loopback(params, vars);
12069                 break;
12070         case LOOPBACK_UMAC:
12071                 bnx2x_init_umac_loopback(params, vars);
12072                 break;
12073         case LOOPBACK_XGXS:
12074         case LOOPBACK_EXT_PHY:
12075                 bnx2x_init_xgxs_loopback(params, vars);
12076                 break;
12077         default:
12078                 if (!CHIP_IS_E3(bp)) {
12079                         if (params->switch_cfg == SWITCH_CFG_10G)
12080                                 bnx2x_xgxs_deassert(params);
12081                         else
12082                                 bnx2x_serdes_deassert(bp, params->port);
12083                 }
12084                 bnx2x_link_initialize(params, vars);
12085                 msleep(30);
12086                 bnx2x_link_int_enable(params);
12087                 break;
12088         }
12089         return 0;
12090 }
12091
12092 int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
12093                      u8 reset_ext_phy)
12094 {
12095         struct bnx2x *bp = params->bp;
12096         u8 phy_index, port = params->port, clear_latch_ind = 0;
12097         DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
12098         /* disable attentions */
12099         vars->link_status = 0;
12100         bnx2x_update_mng(params, vars->link_status);
12101         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
12102                        (NIG_MASK_XGXS0_LINK_STATUS |
12103                         NIG_MASK_XGXS0_LINK10G |
12104                         NIG_MASK_SERDES0_LINK_STATUS |
12105                         NIG_MASK_MI_INT));
12106
12107         /* activate nig drain */
12108         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
12109
12110         /* disable nig egress interface */
12111         if (!CHIP_IS_E3(bp)) {
12112                 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
12113                 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
12114         }
12115
12116         /* Stop BigMac rx */
12117         if (!CHIP_IS_E3(bp))
12118                 bnx2x_bmac_rx_disable(bp, port);
12119         else {
12120                 bnx2x_xmac_disable(params);
12121                 bnx2x_umac_disable(params);
12122         }
12123         /* disable emac */
12124         if (!CHIP_IS_E3(bp))
12125                 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
12126
12127         msleep(10);
12128         /* The PHY reset is controlled by GPIO 1
12129          * Hold it as vars low
12130          */
12131          /* clear link led */
12132         bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
12133
12134         if (reset_ext_phy) {
12135                 bnx2x_set_mdio_clk(bp, params->chip_id, port);
12136                 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
12137                       phy_index++) {
12138                         if (params->phy[phy_index].link_reset) {
12139                                 bnx2x_set_aer_mmd(params,
12140                                                   &params->phy[phy_index]);
12141                                 params->phy[phy_index].link_reset(
12142                                         &params->phy[phy_index],
12143                                         params);
12144                         }
12145                         if (params->phy[phy_index].flags &
12146                             FLAGS_REARM_LATCH_SIGNAL)
12147                                 clear_latch_ind = 1;
12148                 }
12149         }
12150
12151         if (clear_latch_ind) {
12152                 /* Clear latching indication */
12153                 bnx2x_rearm_latch_signal(bp, port, 0);
12154                 bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4,
12155                                1 << NIG_LATCH_BC_ENABLE_MI_INT);
12156         }
12157         if (params->phy[INT_PHY].link_reset)
12158                 params->phy[INT_PHY].link_reset(
12159                         &params->phy[INT_PHY], params);
12160
12161         /* disable nig ingress interface */
12162         if (!CHIP_IS_E3(bp)) {
12163                 /* reset BigMac */
12164                 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
12165                        (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
12166                 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
12167                 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
12168         } else {
12169                 u32 xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
12170                 bnx2x_set_xumac_nig(params, 0, 0);
12171                 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
12172                     MISC_REGISTERS_RESET_REG_2_XMAC)
12173                         REG_WR(bp, xmac_base + XMAC_REG_CTRL,
12174                                XMAC_CTRL_REG_SOFT_RESET);
12175         }
12176         vars->link_up = 0;
12177         vars->phy_flags = 0;
12178         return 0;
12179 }
12180
12181 /****************************************************************************/
12182 /*                              Common function                             */
12183 /****************************************************************************/
12184 static int bnx2x_8073_common_init_phy(struct bnx2x *bp,
12185                                       u32 shmem_base_path[],
12186                                       u32 shmem2_base_path[], u8 phy_index,
12187                                       u32 chip_id)
12188 {
12189         struct bnx2x_phy phy[PORT_MAX];
12190         struct bnx2x_phy *phy_blk[PORT_MAX];
12191         u16 val;
12192         s8 port = 0;
12193         s8 port_of_path = 0;
12194         u32 swap_val, swap_override;
12195         swap_val = REG_RD(bp,  NIG_REG_PORT_SWAP);
12196         swap_override = REG_RD(bp,  NIG_REG_STRAP_OVERRIDE);
12197         port ^= (swap_val && swap_override);
12198         bnx2x_ext_phy_hw_reset(bp, port);
12199         /* PART1 - Reset both phys */
12200         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
12201                 u32 shmem_base, shmem2_base;
12202                 /* In E2, same phy is using for port0 of the two paths */
12203                 if (CHIP_IS_E1x(bp)) {
12204                         shmem_base = shmem_base_path[0];
12205                         shmem2_base = shmem2_base_path[0];
12206                         port_of_path = port;
12207                 } else {
12208                         shmem_base = shmem_base_path[port];
12209                         shmem2_base = shmem2_base_path[port];
12210                         port_of_path = 0;
12211                 }
12212
12213                 /* Extract the ext phy address for the port */
12214                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12215                                        port_of_path, &phy[port]) !=
12216                     0) {
12217                         DP(NETIF_MSG_LINK, "populate_phy failed\n");
12218                         return -EINVAL;
12219                 }
12220                 /* disable attentions */
12221                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
12222                                port_of_path*4,
12223                                (NIG_MASK_XGXS0_LINK_STATUS |
12224                                 NIG_MASK_XGXS0_LINK10G |
12225                                 NIG_MASK_SERDES0_LINK_STATUS |
12226                                 NIG_MASK_MI_INT));
12227
12228                 /* Need to take the phy out of low power mode in order
12229                         to write to access its registers */
12230                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
12231                                MISC_REGISTERS_GPIO_OUTPUT_HIGH,
12232                                port);
12233
12234                 /* Reset the phy */
12235                 bnx2x_cl45_write(bp, &phy[port],
12236                                  MDIO_PMA_DEVAD,
12237                                  MDIO_PMA_REG_CTRL,
12238                                  1<<15);
12239         }
12240
12241         /* Add delay of 150ms after reset */
12242         msleep(150);
12243
12244         if (phy[PORT_0].addr & 0x1) {
12245                 phy_blk[PORT_0] = &(phy[PORT_1]);
12246                 phy_blk[PORT_1] = &(phy[PORT_0]);
12247         } else {
12248                 phy_blk[PORT_0] = &(phy[PORT_0]);
12249                 phy_blk[PORT_1] = &(phy[PORT_1]);
12250         }
12251
12252         /* PART2 - Download firmware to both phys */
12253         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
12254                 if (CHIP_IS_E1x(bp))
12255                         port_of_path = port;
12256                 else
12257                         port_of_path = 0;
12258
12259                 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
12260                            phy_blk[port]->addr);
12261                 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
12262                                                       port_of_path))
12263                         return -EINVAL;
12264
12265                 /* Only set bit 10 = 1 (Tx power down) */
12266                 bnx2x_cl45_read(bp, phy_blk[port],
12267                                 MDIO_PMA_DEVAD,
12268                                 MDIO_PMA_REG_TX_POWER_DOWN, &val);
12269
12270                 /* Phase1 of TX_POWER_DOWN reset */
12271                 bnx2x_cl45_write(bp, phy_blk[port],
12272                                  MDIO_PMA_DEVAD,
12273                                  MDIO_PMA_REG_TX_POWER_DOWN,
12274                                  (val | 1<<10));
12275         }
12276
12277         /*
12278          * Toggle Transmitter: Power down and then up with 600ms delay
12279          * between
12280          */
12281         msleep(600);
12282
12283         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
12284         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
12285                 /* Phase2 of POWER_DOWN_RESET */
12286                 /* Release bit 10 (Release Tx power down) */
12287                 bnx2x_cl45_read(bp, phy_blk[port],
12288                                 MDIO_PMA_DEVAD,
12289                                 MDIO_PMA_REG_TX_POWER_DOWN, &val);
12290
12291                 bnx2x_cl45_write(bp, phy_blk[port],
12292                                 MDIO_PMA_DEVAD,
12293                                 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
12294                 msleep(15);
12295
12296                 /* Read modify write the SPI-ROM version select register */
12297                 bnx2x_cl45_read(bp, phy_blk[port],
12298                                 MDIO_PMA_DEVAD,
12299                                 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
12300                 bnx2x_cl45_write(bp, phy_blk[port],
12301                                  MDIO_PMA_DEVAD,
12302                                  MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
12303
12304                 /* set GPIO2 back to LOW */
12305                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
12306                                MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
12307         }
12308         return 0;
12309 }
12310 static int bnx2x_8726_common_init_phy(struct bnx2x *bp,
12311                                       u32 shmem_base_path[],
12312                                       u32 shmem2_base_path[], u8 phy_index,
12313                                       u32 chip_id)
12314 {
12315         u32 val;
12316         s8 port;
12317         struct bnx2x_phy phy;
12318         /* Use port1 because of the static port-swap */
12319         /* Enable the module detection interrupt */
12320         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
12321         val |= ((1<<MISC_REGISTERS_GPIO_3)|
12322                 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
12323         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
12324
12325         bnx2x_ext_phy_hw_reset(bp, 0);
12326         msleep(5);
12327         for (port = 0; port < PORT_MAX; port++) {
12328                 u32 shmem_base, shmem2_base;
12329
12330                 /* In E2, same phy is using for port0 of the two paths */
12331                 if (CHIP_IS_E1x(bp)) {
12332                         shmem_base = shmem_base_path[0];
12333                         shmem2_base = shmem2_base_path[0];
12334                 } else {
12335                         shmem_base = shmem_base_path[port];
12336                         shmem2_base = shmem2_base_path[port];
12337                 }
12338                 /* Extract the ext phy address for the port */
12339                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12340                                        port, &phy) !=
12341                     0) {
12342                         DP(NETIF_MSG_LINK, "populate phy failed\n");
12343                         return -EINVAL;
12344                 }
12345
12346                 /* Reset phy*/
12347                 bnx2x_cl45_write(bp, &phy,
12348                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
12349
12350
12351                 /* Set fault module detected LED on */
12352                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
12353                                MISC_REGISTERS_GPIO_HIGH,
12354                                port);
12355         }
12356
12357         return 0;
12358 }
12359 static void bnx2x_get_ext_phy_reset_gpio(struct bnx2x *bp, u32 shmem_base,
12360                                          u8 *io_gpio, u8 *io_port)
12361 {
12362
12363         u32 phy_gpio_reset = REG_RD(bp, shmem_base +
12364                                           offsetof(struct shmem_region,
12365                                 dev_info.port_hw_config[PORT_0].default_cfg));
12366         switch (phy_gpio_reset) {
12367         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0:
12368                 *io_gpio = 0;
12369                 *io_port = 0;
12370                 break;
12371         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0:
12372                 *io_gpio = 1;
12373                 *io_port = 0;
12374                 break;
12375         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0:
12376                 *io_gpio = 2;
12377                 *io_port = 0;
12378                 break;
12379         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0:
12380                 *io_gpio = 3;
12381                 *io_port = 0;
12382                 break;
12383         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1:
12384                 *io_gpio = 0;
12385                 *io_port = 1;
12386                 break;
12387         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1:
12388                 *io_gpio = 1;
12389                 *io_port = 1;
12390                 break;
12391         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1:
12392                 *io_gpio = 2;
12393                 *io_port = 1;
12394                 break;
12395         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1:
12396                 *io_gpio = 3;
12397                 *io_port = 1;
12398                 break;
12399         default:
12400                 /* Don't override the io_gpio and io_port */
12401                 break;
12402         }
12403 }
12404
12405 static int bnx2x_8727_common_init_phy(struct bnx2x *bp,
12406                                       u32 shmem_base_path[],
12407                                       u32 shmem2_base_path[], u8 phy_index,
12408                                       u32 chip_id)
12409 {
12410         s8 port, reset_gpio;
12411         u32 swap_val, swap_override;
12412         struct bnx2x_phy phy[PORT_MAX];
12413         struct bnx2x_phy *phy_blk[PORT_MAX];
12414         s8 port_of_path;
12415         swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
12416         swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
12417
12418         reset_gpio = MISC_REGISTERS_GPIO_1;
12419         port = 1;
12420
12421         /*
12422          * Retrieve the reset gpio/port which control the reset.
12423          * Default is GPIO1, PORT1
12424          */
12425         bnx2x_get_ext_phy_reset_gpio(bp, shmem_base_path[0],
12426                                      (u8 *)&reset_gpio, (u8 *)&port);
12427
12428         /* Calculate the port based on port swap */
12429         port ^= (swap_val && swap_override);
12430
12431         /* Initiate PHY reset*/
12432         bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW,
12433                        port);
12434         msleep(1);
12435         bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH,
12436                        port);
12437
12438         msleep(5);
12439
12440         /* PART1 - Reset both phys */
12441         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
12442                 u32 shmem_base, shmem2_base;
12443
12444                 /* In E2, same phy is using for port0 of the two paths */
12445                 if (CHIP_IS_E1x(bp)) {
12446                         shmem_base = shmem_base_path[0];
12447                         shmem2_base = shmem2_base_path[0];
12448                         port_of_path = port;
12449                 } else {
12450                         shmem_base = shmem_base_path[port];
12451                         shmem2_base = shmem2_base_path[port];
12452                         port_of_path = 0;
12453                 }
12454
12455                 /* Extract the ext phy address for the port */
12456                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12457                                        port_of_path, &phy[port]) !=
12458                                        0) {
12459                         DP(NETIF_MSG_LINK, "populate phy failed\n");
12460                         return -EINVAL;
12461                 }
12462                 /* disable attentions */
12463                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
12464                                port_of_path*4,
12465                                (NIG_MASK_XGXS0_LINK_STATUS |
12466                                 NIG_MASK_XGXS0_LINK10G |
12467                                 NIG_MASK_SERDES0_LINK_STATUS |
12468                                 NIG_MASK_MI_INT));
12469
12470
12471                 /* Reset the phy */
12472                 bnx2x_cl45_write(bp, &phy[port],
12473                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
12474         }
12475
12476         /* Add delay of 150ms after reset */
12477         msleep(150);
12478         if (phy[PORT_0].addr & 0x1) {
12479                 phy_blk[PORT_0] = &(phy[PORT_1]);
12480                 phy_blk[PORT_1] = &(phy[PORT_0]);
12481         } else {
12482                 phy_blk[PORT_0] = &(phy[PORT_0]);
12483                 phy_blk[PORT_1] = &(phy[PORT_1]);
12484         }
12485         /* PART2 - Download firmware to both phys */
12486         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
12487                 if (CHIP_IS_E1x(bp))
12488                         port_of_path = port;
12489                 else
12490                         port_of_path = 0;
12491                 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
12492                            phy_blk[port]->addr);
12493                 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
12494                                                       port_of_path))
12495                         return -EINVAL;
12496                 /* Disable PHY transmitter output */
12497                 bnx2x_cl45_write(bp, phy_blk[port],
12498                                  MDIO_PMA_DEVAD,
12499                                  MDIO_PMA_REG_TX_DISABLE, 1);
12500
12501         }
12502         return 0;
12503 }
12504
12505 static int bnx2x_84833_common_init_phy(struct bnx2x *bp,
12506                                                 u32 shmem_base_path[],
12507                                                 u32 shmem2_base_path[],
12508                                                 u8 phy_index,
12509                                                 u32 chip_id)
12510 {
12511         u8 reset_gpios;
12512         reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path, chip_id);
12513         bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
12514         udelay(10);
12515         bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH);
12516         DP(NETIF_MSG_LINK, "84833 reset pulse on pin values 0x%x\n",
12517                 reset_gpios);
12518         return 0;
12519 }
12520
12521 static int bnx2x_84833_pre_init_phy(struct bnx2x *bp,
12522                                                struct bnx2x_phy *phy)
12523 {
12524         u16 val, cnt;
12525         /* Wait for FW completing its initialization. */
12526         for (cnt = 0; cnt < 1500; cnt++) {
12527                 bnx2x_cl45_read(bp, phy,
12528                                 MDIO_PMA_DEVAD,
12529                                 MDIO_PMA_REG_CTRL, &val);
12530                 if (!(val & (1<<15)))
12531                         break;
12532                 msleep(1);
12533         }
12534         if (cnt >= 1500) {
12535                 DP(NETIF_MSG_LINK, "84833 reset timeout\n");
12536                 return -EINVAL;
12537         }
12538
12539         /* Put the port in super isolate mode. */
12540         bnx2x_cl45_read(bp, phy,
12541                         MDIO_CTL_DEVAD,
12542                         MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
12543         val |= MDIO_84833_SUPER_ISOLATE;
12544         bnx2x_cl45_write(bp, phy,
12545                          MDIO_CTL_DEVAD,
12546                          MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
12547
12548         /* Save spirom version */
12549         bnx2x_save_848xx_spirom_version(phy, bp, PORT_0);
12550         return 0;
12551 }
12552
12553 int bnx2x_pre_init_phy(struct bnx2x *bp,
12554                                   u32 shmem_base,
12555                                   u32 shmem2_base,
12556                                   u32 chip_id)
12557 {
12558         int rc = 0;
12559         struct bnx2x_phy phy;
12560         bnx2x_set_mdio_clk(bp, chip_id, PORT_0);
12561         if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, shmem2_base,
12562                                PORT_0, &phy)) {
12563                 DP(NETIF_MSG_LINK, "populate_phy failed\n");
12564                 return -EINVAL;
12565         }
12566         switch (phy.type) {
12567         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
12568                 rc = bnx2x_84833_pre_init_phy(bp, &phy);
12569                 break;
12570         default:
12571                 break;
12572         }
12573         return rc;
12574 }
12575
12576 static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
12577                                      u32 shmem2_base_path[], u8 phy_index,
12578                                      u32 ext_phy_type, u32 chip_id)
12579 {
12580         int rc = 0;
12581
12582         switch (ext_phy_type) {
12583         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
12584                 rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
12585                                                 shmem2_base_path,
12586                                                 phy_index, chip_id);
12587                 break;
12588         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
12589         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
12590         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
12591                 rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
12592                                                 shmem2_base_path,
12593                                                 phy_index, chip_id);
12594                 break;
12595
12596         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
12597                 /*
12598                  * GPIO1 affects both ports, so there's need to pull
12599                  * it for single port alone
12600                  */
12601                 rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
12602                                                 shmem2_base_path,
12603                                                 phy_index, chip_id);
12604                 break;
12605         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
12606                 /*
12607                  * GPIO3's are linked, and so both need to be toggled
12608                  * to obtain required 2us pulse.
12609                  */
12610                 rc = bnx2x_84833_common_init_phy(bp, shmem_base_path,
12611                                                 shmem2_base_path,
12612                                                 phy_index, chip_id);
12613                 break;
12614         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
12615                 rc = -EINVAL;
12616                 break;
12617         default:
12618                 DP(NETIF_MSG_LINK,
12619                            "ext_phy 0x%x common init not required\n",
12620                            ext_phy_type);
12621                 break;
12622         }
12623
12624         if (rc != 0)
12625                 netdev_err(bp->dev,  "Warning: PHY was not initialized,"
12626                                       " Port %d\n",
12627                          0);
12628         return rc;
12629 }
12630
12631 int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
12632                           u32 shmem2_base_path[], u32 chip_id)
12633 {
12634         int rc = 0;
12635         u32 phy_ver, val;
12636         u8 phy_index = 0;
12637         u32 ext_phy_type, ext_phy_config;
12638         bnx2x_set_mdio_clk(bp, chip_id, PORT_0);
12639         bnx2x_set_mdio_clk(bp, chip_id, PORT_1);
12640         DP(NETIF_MSG_LINK, "Begin common phy init\n");
12641         if (CHIP_IS_E3(bp)) {
12642                 /* Enable EPIO */
12643                 val = REG_RD(bp, MISC_REG_GEN_PURP_HWG);
12644                 REG_WR(bp, MISC_REG_GEN_PURP_HWG, val | 1);
12645         }
12646         /* Check if common init was already done */
12647         phy_ver = REG_RD(bp, shmem_base_path[0] +
12648                          offsetof(struct shmem_region,
12649                                   port_mb[PORT_0].ext_phy_fw_version));
12650         if (phy_ver) {
12651                 DP(NETIF_MSG_LINK, "Not doing common init; phy ver is 0x%x\n",
12652                                phy_ver);
12653                 return 0;
12654         }
12655
12656         /* Read the ext_phy_type for arbitrary port(0) */
12657         for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
12658               phy_index++) {
12659                 ext_phy_config = bnx2x_get_ext_phy_config(bp,
12660                                                           shmem_base_path[0],
12661                                                           phy_index, 0);
12662                 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
12663                 rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
12664                                                 shmem2_base_path,
12665                                                 phy_index, ext_phy_type,
12666                                                 chip_id);
12667         }
12668         return rc;
12669 }
12670
12671 static void bnx2x_check_over_curr(struct link_params *params,
12672                                   struct link_vars *vars)
12673 {
12674         struct bnx2x *bp = params->bp;
12675         u32 cfg_pin;
12676         u8 port = params->port;
12677         u32 pin_val;
12678
12679         cfg_pin = (REG_RD(bp, params->shmem_base +
12680                           offsetof(struct shmem_region,
12681                                dev_info.port_hw_config[port].e3_cmn_pin_cfg1)) &
12682                    PORT_HW_CFG_E3_OVER_CURRENT_MASK) >>
12683                 PORT_HW_CFG_E3_OVER_CURRENT_SHIFT;
12684
12685         /* Ignore check if no external input PIN available */
12686         if (bnx2x_get_cfg_pin(bp, cfg_pin, &pin_val) != 0)
12687                 return;
12688
12689         if (!pin_val) {
12690                 if ((vars->phy_flags & PHY_OVER_CURRENT_FLAG) == 0) {
12691                         netdev_err(bp->dev, "Error:  Power fault on Port %d has"
12692                                             " been detected and the power to "
12693                                             "that SFP+ module has been removed"
12694                                             " to prevent failure of the card."
12695                                             " Please remove the SFP+ module and"
12696                                             " restart the system to clear this"
12697                                             " error.\n",
12698                          params->port);
12699                         vars->phy_flags |= PHY_OVER_CURRENT_FLAG;
12700                 }
12701         } else
12702                 vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG;
12703 }
12704
12705 static void bnx2x_analyze_link_error(struct link_params *params,
12706                                      struct link_vars *vars, u32 lss_status)
12707 {
12708         struct bnx2x *bp = params->bp;
12709         /* Compare new value with previous value */
12710         u8 led_mode;
12711         u32 half_open_conn = (vars->phy_flags & PHY_HALF_OPEN_CONN_FLAG) > 0;
12712
12713         if ((lss_status ^ half_open_conn) == 0)
12714                 return;
12715
12716         /* If values differ */
12717         DP(NETIF_MSG_LINK, "Link changed:%x %x->%x\n", vars->link_up,
12718                        half_open_conn, lss_status);
12719
12720         /*
12721          * a. Update shmem->link_status accordingly
12722          * b. Update link_vars->link_up
12723          */
12724         if (lss_status) {
12725                 DP(NETIF_MSG_LINK, "Remote Fault detected !!!\n");
12726                 vars->link_status &= ~LINK_STATUS_LINK_UP;
12727                 vars->link_up = 0;
12728                 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
12729                 /*
12730                  * Set LED mode to off since the PHY doesn't know about these
12731                  * errors
12732                  */
12733                 led_mode = LED_MODE_OFF;
12734         } else {
12735                 DP(NETIF_MSG_LINK, "Remote Fault cleared\n");
12736                 vars->link_status |= LINK_STATUS_LINK_UP;
12737                 vars->link_up = 1;
12738                 vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
12739                 led_mode = LED_MODE_OPER;
12740         }
12741         /* Update the LED according to the link state */
12742         bnx2x_set_led(params, vars, led_mode, SPEED_10000);
12743
12744         /* Update link status in the shared memory */
12745         bnx2x_update_mng(params, vars->link_status);
12746
12747         /* C. Trigger General Attention */
12748         vars->periodic_flags |= PERIODIC_FLAGS_LINK_EVENT;
12749         bnx2x_notify_link_changed(bp);
12750 }
12751
12752 /******************************************************************************
12753 * Description:
12754 *       This function checks for half opened connection change indication.
12755 *       When such change occurs, it calls the bnx2x_analyze_link_error
12756 *       to check if Remote Fault is set or cleared. Reception of remote fault
12757 *       status message in the MAC indicates that the peer's MAC has detected
12758 *       a fault, for example, due to break in the TX side of fiber.
12759 *
12760 ******************************************************************************/
12761 static void bnx2x_check_half_open_conn(struct link_params *params,
12762                                        struct link_vars *vars)
12763 {
12764         struct bnx2x *bp = params->bp;
12765         u32 lss_status = 0;
12766         u32 mac_base;
12767         /* In case link status is physically up @ 10G do */
12768         if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0)
12769                 return;
12770
12771         if (CHIP_IS_E3(bp) &&
12772             (REG_RD(bp, MISC_REG_RESET_REG_2) &
12773               (MISC_REGISTERS_RESET_REG_2_XMAC))) {
12774                 /* Check E3 XMAC */
12775                 /*
12776                  * Note that link speed cannot be queried here, since it may be
12777                  * zero while link is down. In case UMAC is active, LSS will
12778                  * simply not be set
12779                  */
12780                 mac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
12781
12782                 /* Clear stick bits (Requires rising edge) */
12783                 REG_WR(bp, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
12784                 REG_WR(bp, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
12785                        XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
12786                        XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
12787                 if (REG_RD(bp, mac_base + XMAC_REG_RX_LSS_STATUS))
12788                         lss_status = 1;
12789
12790                 bnx2x_analyze_link_error(params, vars, lss_status);
12791         } else if (REG_RD(bp, MISC_REG_RESET_REG_2) &
12792                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) {
12793                 /* Check E1X / E2 BMAC */
12794                 u32 lss_status_reg;
12795                 u32 wb_data[2];
12796                 mac_base = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
12797                         NIG_REG_INGRESS_BMAC0_MEM;
12798                 /*  Read BIGMAC_REGISTER_RX_LSS_STATUS */
12799                 if (CHIP_IS_E2(bp))
12800                         lss_status_reg = BIGMAC2_REGISTER_RX_LSS_STAT;
12801                 else
12802                         lss_status_reg = BIGMAC_REGISTER_RX_LSS_STATUS;
12803
12804                 REG_RD_DMAE(bp, mac_base + lss_status_reg, wb_data, 2);
12805                 lss_status = (wb_data[0] > 0);
12806
12807                 bnx2x_analyze_link_error(params, vars, lss_status);
12808         }
12809 }
12810
12811 void bnx2x_period_func(struct link_params *params, struct link_vars *vars)
12812 {
12813         struct bnx2x *bp = params->bp;
12814         u16 phy_idx;
12815         for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
12816                 if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) {
12817                         bnx2x_set_aer_mmd(params, &params->phy[phy_idx]);
12818                         bnx2x_check_half_open_conn(params, vars);
12819                         break;
12820                 }
12821         }
12822
12823         if (CHIP_IS_E3(bp)) {
12824                 struct bnx2x_phy *phy = &params->phy[INT_PHY];
12825                 bnx2x_set_aer_mmd(params, phy);
12826                 bnx2x_check_over_curr(params, vars);
12827                 bnx2x_warpcore_config_runtime(phy, params, vars);
12828         }
12829
12830 }
12831
12832 u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
12833 {
12834         u8 phy_index;
12835         struct bnx2x_phy phy;
12836         for (phy_index = INT_PHY; phy_index < MAX_PHYS;
12837               phy_index++) {
12838                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12839                                        0, &phy) != 0) {
12840                         DP(NETIF_MSG_LINK, "populate phy failed\n");
12841                         return 0;
12842                 }
12843
12844                 if (phy.flags & FLAGS_HW_LOCK_REQUIRED)
12845                         return 1;
12846         }
12847         return 0;
12848 }
12849
12850 u8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
12851                              u32 shmem_base,
12852                              u32 shmem2_base,
12853                              u8 port)
12854 {
12855         u8 phy_index, fan_failure_det_req = 0;
12856         struct bnx2x_phy phy;
12857         for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
12858               phy_index++) {
12859                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12860                                        port, &phy)
12861                     != 0) {
12862                         DP(NETIF_MSG_LINK, "populate phy failed\n");
12863                         return 0;
12864                 }
12865                 fan_failure_det_req |= (phy.flags &
12866                                         FLAGS_FAN_FAILURE_DET_REQ);
12867         }
12868         return fan_failure_det_req;
12869 }
12870
12871 void bnx2x_hw_reset_phy(struct link_params *params)
12872 {
12873         u8 phy_index;
12874         struct bnx2x *bp = params->bp;
12875         bnx2x_update_mng(params, 0);
12876         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
12877                        (NIG_MASK_XGXS0_LINK_STATUS |
12878                         NIG_MASK_XGXS0_LINK10G |
12879                         NIG_MASK_SERDES0_LINK_STATUS |
12880                         NIG_MASK_MI_INT));
12881
12882         for (phy_index = INT_PHY; phy_index < MAX_PHYS;
12883               phy_index++) {
12884                 if (params->phy[phy_index].hw_reset) {
12885                         params->phy[phy_index].hw_reset(
12886                                 &params->phy[phy_index],
12887                                 params);
12888                         params->phy[phy_index] = phy_null;
12889                 }
12890         }
12891 }
12892
12893 void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars,
12894                             u32 chip_id, u32 shmem_base, u32 shmem2_base,
12895                             u8 port)
12896 {
12897         u8 gpio_num = 0xff, gpio_port = 0xff, phy_index;
12898         u32 val;
12899         u32 offset, aeu_mask, swap_val, swap_override, sync_offset;
12900         if (CHIP_IS_E3(bp)) {
12901                 if (bnx2x_get_mod_abs_int_cfg(bp, chip_id,
12902                                               shmem_base,
12903                                               port,
12904                                               &gpio_num,
12905                                               &gpio_port) != 0)
12906                         return;
12907         } else {
12908                 struct bnx2x_phy phy;
12909                 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
12910                       phy_index++) {
12911                         if (bnx2x_populate_phy(bp, phy_index, shmem_base,
12912                                                shmem2_base, port, &phy)
12913                             != 0) {
12914                                 DP(NETIF_MSG_LINK, "populate phy failed\n");
12915                                 return;
12916                         }
12917                         if (phy.type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
12918                                 gpio_num = MISC_REGISTERS_GPIO_3;
12919                                 gpio_port = port;
12920                                 break;
12921                         }
12922                 }
12923         }
12924
12925         if (gpio_num == 0xff)
12926                 return;
12927
12928         /* Set GPIO3 to trigger SFP+ module insertion/removal */
12929         bnx2x_set_gpio(bp, gpio_num, MISC_REGISTERS_GPIO_INPUT_HI_Z, gpio_port);
12930
12931         swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
12932         swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
12933         gpio_port ^= (swap_val && swap_override);
12934
12935         vars->aeu_int_mask = AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 <<
12936                 (gpio_num + (gpio_port << 2));
12937
12938         sync_offset = shmem_base +
12939                 offsetof(struct shmem_region,
12940                          dev_info.port_hw_config[port].aeu_int_mask);
12941         REG_WR(bp, sync_offset, vars->aeu_int_mask);
12942
12943         DP(NETIF_MSG_LINK, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x\n",
12944                        gpio_num, gpio_port, vars->aeu_int_mask);
12945
12946         if (port == 0)
12947                 offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
12948         else
12949                 offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
12950
12951         /* Open appropriate AEU for interrupts */
12952         aeu_mask = REG_RD(bp, offset);
12953         aeu_mask |= vars->aeu_int_mask;
12954         REG_WR(bp, offset, aeu_mask);
12955
12956         /* Enable the GPIO to trigger interrupt */
12957         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
12958         val |= 1 << (gpio_num + (gpio_port << 2));
12959         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
12960 }