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