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