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