36a88448b245dfa0dbe8b45d1a5d86cc6b1534f9
[cascardo/linux.git] / drivers / net / bnx2x / bnx2x_link.c
1 /* Copyright 2008-2009 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
29 /********************************************************/
30 #define ETH_HLEN                        14
31 #define ETH_OVREHEAD            (ETH_HLEN + 8 + 8)/* 16 for CRC + VLAN + LLC */
32 #define ETH_MIN_PACKET_SIZE             60
33 #define ETH_MAX_PACKET_SIZE             1500
34 #define ETH_MAX_JUMBO_PACKET_SIZE       9600
35 #define MDIO_ACCESS_TIMEOUT             1000
36 #define BMAC_CONTROL_RX_ENABLE  2
37
38 /***********************************************************/
39 /*                      Shortcut definitions               */
40 /***********************************************************/
41
42 #define NIG_LATCH_BC_ENABLE_MI_INT 0
43
44 #define NIG_STATUS_EMAC0_MI_INT \
45                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
46 #define NIG_STATUS_XGXS0_LINK10G \
47                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
48 #define NIG_STATUS_XGXS0_LINK_STATUS \
49                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
50 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
51                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
52 #define NIG_STATUS_SERDES0_LINK_STATUS \
53                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
54 #define NIG_MASK_MI_INT \
55                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
56 #define NIG_MASK_XGXS0_LINK10G \
57                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
58 #define NIG_MASK_XGXS0_LINK_STATUS \
59                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
60 #define NIG_MASK_SERDES0_LINK_STATUS \
61                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
62
63 #define MDIO_AN_CL73_OR_37_COMPLETE \
64                 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
65                  MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
66
67 #define XGXS_RESET_BITS \
68         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
69          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
70          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
71          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
72          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
73
74 #define SERDES_RESET_BITS \
75         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
76          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
77          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
78          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
79
80 #define AUTONEG_CL37            SHARED_HW_CFG_AN_ENABLE_CL37
81 #define AUTONEG_CL73            SHARED_HW_CFG_AN_ENABLE_CL73
82 #define AUTONEG_BAM             SHARED_HW_CFG_AN_ENABLE_BAM
83 #define AUTONEG_PARALLEL \
84                                 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
85 #define AUTONEG_SGMII_FIBER_AUTODET \
86                                 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
87 #define AUTONEG_REMOTE_PHY      SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
88
89 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
90                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
91 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
92                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
93 #define GP_STATUS_SPEED_MASK \
94                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
95 #define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
96 #define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
97 #define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
98 #define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
99 #define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
100 #define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
101 #define GP_STATUS_10G_HIG \
102                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
103 #define GP_STATUS_10G_CX4 \
104                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
105 #define GP_STATUS_12G_HIG \
106                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
107 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
108 #define GP_STATUS_13G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
109 #define GP_STATUS_15G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
110 #define GP_STATUS_16G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
111 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
112 #define GP_STATUS_10G_KX4 \
113                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
114
115 #define LINK_10THD                      LINK_STATUS_SPEED_AND_DUPLEX_10THD
116 #define LINK_10TFD                      LINK_STATUS_SPEED_AND_DUPLEX_10TFD
117 #define LINK_100TXHD            LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
118 #define LINK_100T4                      LINK_STATUS_SPEED_AND_DUPLEX_100T4
119 #define LINK_100TXFD            LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
120 #define LINK_1000THD            LINK_STATUS_SPEED_AND_DUPLEX_1000THD
121 #define LINK_1000TFD            LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
122 #define LINK_1000XFD            LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
123 #define LINK_2500THD            LINK_STATUS_SPEED_AND_DUPLEX_2500THD
124 #define LINK_2500TFD            LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
125 #define LINK_2500XFD            LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
126 #define LINK_10GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
127 #define LINK_10GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
128 #define LINK_12GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
129 #define LINK_12GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
130 #define LINK_12_5GTFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
131 #define LINK_12_5GXFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
132 #define LINK_13GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
133 #define LINK_13GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
134 #define LINK_15GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
135 #define LINK_15GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
136 #define LINK_16GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
137 #define LINK_16GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
138
139 #define PHY_XGXS_FLAG                   0x1
140 #define PHY_SGMII_FLAG                  0x2
141 #define PHY_SERDES_FLAG                 0x4
142
143 /* */
144 #define SFP_EEPROM_CON_TYPE_ADDR                0x2
145         #define SFP_EEPROM_CON_TYPE_VAL_LC              0x7
146         #define SFP_EEPROM_CON_TYPE_VAL_COPPER  0x21
147
148
149 #define SFP_EEPROM_COMP_CODE_ADDR               0x3
150         #define SFP_EEPROM_COMP_CODE_SR_MASK    (1<<4)
151         #define SFP_EEPROM_COMP_CODE_LR_MASK    (1<<5)
152         #define SFP_EEPROM_COMP_CODE_LRM_MASK   (1<<6)
153
154 #define SFP_EEPROM_FC_TX_TECH_ADDR              0x8
155         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
156         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE      0x8
157
158 #define SFP_EEPROM_OPTIONS_ADDR                 0x40
159         #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
160 #define SFP_EEPROM_OPTIONS_SIZE                 2
161
162 #define EDC_MODE_LINEAR                         0x0022
163 #define EDC_MODE_LIMITING                               0x0044
164 #define EDC_MODE_PASSIVE_DAC                    0x0055
165
166
167 #define ETS_BW_LIMIT_CREDIT_UPPER_BOUND         (0x5000)
168 #define ETS_BW_LIMIT_CREDIT_WEIGHT              (0x5000)
169 /**********************************************************/
170 /*                     INTERFACE                          */
171 /**********************************************************/
172
173 #define CL45_WR_OVER_CL22(_bp, _phy, _bank, _addr, _val) \
174         bnx2x_cl45_write(_bp, _phy, \
175                 (_phy)->def_md_devad, \
176                 (_bank + (_addr & 0xf)), \
177                 _val)
178
179 #define CL45_RD_OVER_CL22(_bp, _phy, _bank, _addr, _val) \
180         bnx2x_cl45_read(_bp, _phy, \
181                 (_phy)->def_md_devad, \
182                 (_bank + (_addr & 0xf)), \
183                 _val)
184
185 static u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
186                           u8 devad, u16 reg, u16 *ret_val);
187
188 static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
189                            u8 devad, u16 reg, u16 val);
190
191 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
192 {
193         u32 val = REG_RD(bp, reg);
194
195         val |= bits;
196         REG_WR(bp, reg, val);
197         return val;
198 }
199
200 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
201 {
202         u32 val = REG_RD(bp, reg);
203
204         val &= ~bits;
205         REG_WR(bp, reg, val);
206         return val;
207 }
208
209 /******************************************************************/
210 /*                              ETS section                       */
211 /******************************************************************/
212 void bnx2x_ets_disabled(struct link_params *params)
213 {
214         /* ETS disabled configuration*/
215         struct bnx2x *bp = params->bp;
216
217         DP(NETIF_MSG_LINK, "ETS disabled configuration\n");
218
219         /**
220          * mapping between entry  priority to client number (0,1,2 -debug and
221          * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
222          * 3bits client num.
223          *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
224          * cos1-100     cos0-011     dbg1-010     dbg0-001     MCP-000
225          */
226
227         REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
228         /**
229          * Bitmap of 5bits length. Each bit specifies whether the entry behaves
230          * as strict.  Bits 0,1,2 - debug and management entries, 3 -
231          * COS0 entry, 4 - COS1 entry.
232          * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
233          * bit4   bit3    bit2   bit1     bit0
234          * MCP and debug are strict
235          */
236
237         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
238         /* defines which entries (clients) are subjected to WFQ arbitration */
239         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
240         /**
241         * For strict priority entries defines the number of consecutive
242         * slots for the highest priority.
243         */
244         REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
245         /**
246          * mapping between the CREDIT_WEIGHT registers and actual client
247          * numbers
248          */
249         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
250         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
251         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
252
253         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
254         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
255         REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
256         /* ETS mode disable */
257         REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
258         /**
259          * If ETS mode is enabled (there is no strict priority) defines a WFQ
260          * weight for COS0/COS1.
261          */
262         REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
263         REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710);
264         /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
265         REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680);
266         REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680);
267         /* Defines the number of consecutive slots for the strict priority */
268         REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
269 }
270
271 void bnx2x_ets_bw_limit_common(const struct link_params *params)
272 {
273         /* ETS disabled configuration */
274         struct bnx2x *bp = params->bp;
275         DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
276         /**
277         * defines which entries (clients) are subjected to WFQ arbitration
278         * COS0 0x8
279         * COS1 0x10
280         */
281         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
282         /**
283         * mapping between the ARB_CREDIT_WEIGHT registers and actual
284         * client numbers (WEIGHT_0 does not actually have to represent
285         * client 0)
286         *    PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
287         *  cos1-001     cos0-000     dbg1-100     dbg0-011     MCP-010
288         */
289         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
290
291         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
292                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
293         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
294                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
295
296         /* ETS mode enabled*/
297         REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
298
299         /* Defines the number of consecutive slots for the strict priority */
300         REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
301         /**
302         * Bitmap of 5bits length. Each bit specifies whether the entry behaves
303         * as strict.  Bits 0,1,2 - debug and management entries, 3 - COS0
304         * entry, 4 - COS1 entry.
305         * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
306         * bit4   bit3     bit2     bit1    bit0
307         * MCP and debug are strict
308         */
309         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
310
311         /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
312         REG_WR(bp, PBF_REG_COS0_UPPER_BOUND,
313                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
314         REG_WR(bp, PBF_REG_COS1_UPPER_BOUND,
315                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
316 }
317
318 void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
319                         const u32 cos1_bw)
320 {
321         /* ETS disabled configuration*/
322         struct bnx2x *bp = params->bp;
323         const u32 total_bw = cos0_bw + cos1_bw;
324         u32 cos0_credit_weight = 0;
325         u32 cos1_credit_weight = 0;
326
327         DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
328
329         if ((0 == total_bw) ||
330             (0 == cos0_bw) ||
331             (0 == cos1_bw)) {
332                 DP(NETIF_MSG_LINK,
333                    "bnx2x_ets_bw_limit: Total BW can't be zero\n");
334                 return;
335         }
336
337         cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
338                 total_bw;
339         cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
340                 total_bw;
341
342         bnx2x_ets_bw_limit_common(params);
343
344         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
345         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
346
347         REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
348         REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
349 }
350
351 u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
352 {
353         /* ETS disabled configuration*/
354         struct bnx2x *bp = params->bp;
355         u32 val = 0;
356
357         DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
358         /**
359          * Bitmap of 5bits length. Each bit specifies whether the entry behaves
360          * as strict.  Bits 0,1,2 - debug and management entries,
361          * 3 - COS0 entry, 4 - COS1 entry.
362          *  COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
363          *  bit4   bit3   bit2      bit1     bit0
364          * MCP and debug are strict
365          */
366         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
367         /**
368          * For strict priority entries defines the number of consecutive slots
369          * for the highest priority.
370          */
371         REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
372         /* ETS mode disable */
373         REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
374         /* Defines the number of consecutive slots for the strict priority */
375         REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
376
377         /* Defines the number of consecutive slots for the strict priority */
378         REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
379
380         /**
381         * mapping between entry  priority to client number (0,1,2 -debug and
382         * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
383         * 3bits client num.
384         *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
385         * dbg0-010     dbg1-001     cos1-100     cos0-011     MCP-000
386         * dbg0-010     dbg1-001     cos0-011     cos1-100     MCP-000
387         */
388         val = (0 == strict_cos) ? 0x2318 : 0x22E0;
389         REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
390
391         return 0;
392 }
393 /******************************************************************/
394 /*                      ETS section                               */
395 /******************************************************************/
396
397 static void bnx2x_bmac2_get_pfc_stat(struct link_params *params,
398                                      u32 pfc_frames_sent[2],
399                                      u32 pfc_frames_received[2])
400 {
401         /* Read pfc statistic */
402         struct bnx2x *bp = params->bp;
403         u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
404                 NIG_REG_INGRESS_BMAC0_MEM;
405
406         DP(NETIF_MSG_LINK, "pfc statistic read from BMAC\n");
407
408         REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_STAT_GTPP,
409                                         pfc_frames_sent, 2);
410
411         REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_STAT_GRPP,
412                                         pfc_frames_received, 2);
413
414 }
415 static void bnx2x_emac_get_pfc_stat(struct link_params *params,
416                                     u32 pfc_frames_sent[2],
417                                     u32 pfc_frames_received[2])
418 {
419         /* Read pfc statistic */
420         struct bnx2x *bp = params->bp;
421         u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
422         u32 val_xon = 0;
423         u32 val_xoff = 0;
424
425         DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n");
426
427         /* PFC received frames */
428         val_xoff = REG_RD(bp, emac_base +
429                                 EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
430         val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
431         val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
432         val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
433
434         pfc_frames_received[0] = val_xon + val_xoff;
435
436         /* PFC received sent */
437         val_xoff = REG_RD(bp, emac_base +
438                                 EMAC_REG_RX_PFC_STATS_XOFF_SENT);
439         val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
440         val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
441         val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
442
443         pfc_frames_sent[0] = val_xon + val_xoff;
444 }
445
446 void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
447                          u32 pfc_frames_sent[2],
448                          u32 pfc_frames_received[2])
449 {
450         /* Read pfc statistic */
451         struct bnx2x *bp = params->bp;
452         u32 val = 0;
453         DP(NETIF_MSG_LINK, "pfc statistic\n");
454
455         if (!vars->link_up)
456                 return;
457
458         val = REG_RD(bp, MISC_REG_RESET_REG_2);
459         if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
460             == 0) {
461                 DP(NETIF_MSG_LINK, "About to read stats from EMAC\n");
462                 bnx2x_emac_get_pfc_stat(params, pfc_frames_sent,
463                                         pfc_frames_received);
464         } else {
465                 DP(NETIF_MSG_LINK, "About to read stats from BMAC\n");
466                 bnx2x_bmac2_get_pfc_stat(params, pfc_frames_sent,
467                                          pfc_frames_received);
468         }
469 }
470 /******************************************************************/
471 /*                      MAC/PBF section                           */
472 /******************************************************************/
473 static void bnx2x_emac_init(struct link_params *params,
474                            struct link_vars *vars)
475 {
476         /* reset and unreset the emac core */
477         struct bnx2x *bp = params->bp;
478         u8 port = params->port;
479         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
480         u32 val;
481         u16 timeout;
482
483         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
484                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
485         udelay(5);
486         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
487                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
488
489         /* init emac - use read-modify-write */
490         /* self clear reset */
491         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
492         EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
493
494         timeout = 200;
495         do {
496                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
497                 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
498                 if (!timeout) {
499                         DP(NETIF_MSG_LINK, "EMAC timeout!\n");
500                         return;
501                 }
502                 timeout--;
503         } while (val & EMAC_MODE_RESET);
504
505         /* Set mac address */
506         val = ((params->mac_addr[0] << 8) |
507                 params->mac_addr[1]);
508         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
509
510         val = ((params->mac_addr[2] << 24) |
511                (params->mac_addr[3] << 16) |
512                (params->mac_addr[4] << 8) |
513                 params->mac_addr[5]);
514         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
515 }
516
517 static u8 bnx2x_emac_enable(struct link_params *params,
518                           struct link_vars *vars, u8 lb)
519 {
520         struct bnx2x *bp = params->bp;
521         u8 port = params->port;
522         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
523         u32 val;
524
525         DP(NETIF_MSG_LINK, "enabling EMAC\n");
526
527         /* enable emac and not bmac */
528         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
529
530         /* for paladium */
531         if (CHIP_REV_IS_EMUL(bp)) {
532                 /* Use lane 1 (of lanes 0-3) */
533                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
534                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
535                             port*4, 1);
536         }
537         /* for fpga */
538         else
539
540         if (CHIP_REV_IS_FPGA(bp)) {
541                 /* Use lane 1 (of lanes 0-3) */
542                 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
543
544                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
545                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
546                             0);
547         } else
548         /* ASIC */
549         if (vars->phy_flags & PHY_XGXS_FLAG) {
550                 u32 ser_lane = ((params->lane_config &
551                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
552                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
553
554                 DP(NETIF_MSG_LINK, "XGXS\n");
555                 /* select the master lanes (out of 0-3) */
556                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
557                            port*4, ser_lane);
558                 /* select XGXS */
559                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
560                            port*4, 1);
561
562         } else { /* SerDes */
563                 DP(NETIF_MSG_LINK, "SerDes\n");
564                 /* select SerDes */
565                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
566                            port*4, 0);
567         }
568
569         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
570                     EMAC_RX_MODE_RESET);
571         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
572                     EMAC_TX_MODE_RESET);
573
574         if (CHIP_REV_IS_SLOW(bp)) {
575                 /* config GMII mode */
576                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
577                 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
578                             (val | EMAC_MODE_PORT_GMII));
579         } else { /* ASIC */
580                 /* pause enable/disable */
581                 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
582                                EMAC_RX_MODE_FLOW_EN);
583
584                 bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
585                                (EMAC_TX_MODE_EXT_PAUSE_EN |
586                                 EMAC_TX_MODE_FLOW_EN));
587                 if (!(params->feature_config_flags &
588                       FEATURE_CONFIG_PFC_ENABLED)) {
589                         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
590                                 bnx2x_bits_en(bp, emac_base +
591                                               EMAC_REG_EMAC_RX_MODE,
592                                               EMAC_RX_MODE_FLOW_EN);
593
594                         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
595                                 bnx2x_bits_en(bp, emac_base +
596                                               EMAC_REG_EMAC_TX_MODE,
597                                               (EMAC_TX_MODE_EXT_PAUSE_EN |
598                                                EMAC_TX_MODE_FLOW_EN));
599                 } else
600                         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
601                                       EMAC_TX_MODE_FLOW_EN);
602         }
603
604         /* KEEP_VLAN_TAG, promiscuous */
605         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
606         val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
607
608         /**
609         * Setting this bit causes MAC control frames (except for pause
610         * frames) to be passed on for processing. This setting has no
611         * affect on the operation of the pause frames. This bit effects
612         * all packets regardless of RX Parser packet sorting logic.
613         * Turn the PFC off to make sure we are in Xon state before
614         * enabling it.
615         */
616         EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
617         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
618                 DP(NETIF_MSG_LINK, "PFC is enabled\n");
619                 /* Enable PFC again */
620                 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
621                         EMAC_REG_RX_PFC_MODE_RX_EN |
622                         EMAC_REG_RX_PFC_MODE_TX_EN |
623                         EMAC_REG_RX_PFC_MODE_PRIORITIES);
624
625                 EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
626                         ((0x0101 <<
627                           EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
628                          (0x00ff <<
629                           EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
630                 val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
631         }
632         EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
633
634         /* Set Loopback */
635         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
636         if (lb)
637                 val |= 0x810;
638         else
639                 val &= ~0x810;
640         EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
641
642         /* enable emac */
643         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
644
645         /* enable emac for jumbo packets */
646         EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
647                 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
648                  (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
649
650         /* strip CRC */
651         REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
652
653         /* disable the NIG in/out to the bmac */
654         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
655         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
656         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
657
658         /* enable the NIG in/out to the emac */
659         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
660         val = 0;
661         if ((params->feature_config_flags &
662               FEATURE_CONFIG_PFC_ENABLED) ||
663             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
664                 val = 1;
665
666         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
667         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
668
669         if (CHIP_REV_IS_EMUL(bp)) {
670                 /* take the BigMac out of reset */
671                 REG_WR(bp,
672                            GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
673                            (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
674
675                 /* enable access for bmac registers */
676                 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
677         } else
678                 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
679
680         vars->mac_type = MAC_TYPE_EMAC;
681         return 0;
682 }
683
684 static void bnx2x_update_pfc_bmac1(struct link_params *params,
685                                    struct link_vars *vars)
686 {
687         u32 wb_data[2];
688         struct bnx2x *bp = params->bp;
689         u32 bmac_addr =  params->port ? NIG_REG_INGRESS_BMAC1_MEM :
690                 NIG_REG_INGRESS_BMAC0_MEM;
691
692         u32 val = 0x14;
693         if ((!(params->feature_config_flags &
694               FEATURE_CONFIG_PFC_ENABLED)) &&
695                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
696                 /* Enable BigMAC to react on received Pause packets */
697                 val |= (1<<5);
698         wb_data[0] = val;
699         wb_data[1] = 0;
700         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
701
702         /* tx control */
703         val = 0xc0;
704         if (!(params->feature_config_flags &
705               FEATURE_CONFIG_PFC_ENABLED) &&
706                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
707                 val |= 0x800000;
708         wb_data[0] = val;
709         wb_data[1] = 0;
710         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
711 }
712
713 static void bnx2x_update_pfc_bmac2(struct link_params *params,
714                                    struct link_vars *vars,
715                                    u8 is_lb)
716 {
717         /*
718          * Set rx control: Strip CRC and enable BigMAC to relay
719          * control packets to the system as well
720          */
721         u32 wb_data[2];
722         struct bnx2x *bp = params->bp;
723         u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
724                 NIG_REG_INGRESS_BMAC0_MEM;
725         u32 val = 0x14;
726
727         if ((!(params->feature_config_flags &
728               FEATURE_CONFIG_PFC_ENABLED)) &&
729                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
730                 /* Enable BigMAC to react on received Pause packets */
731                 val |= (1<<5);
732         wb_data[0] = val;
733         wb_data[1] = 0;
734         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL,
735                         wb_data, 2);
736         udelay(30);
737
738         /* Tx control */
739         val = 0xc0;
740         if (!(params->feature_config_flags &
741                                 FEATURE_CONFIG_PFC_ENABLED) &&
742             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
743                 val |= 0x800000;
744         wb_data[0] = val;
745         wb_data[1] = 0;
746         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
747
748         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
749                 DP(NETIF_MSG_LINK, "PFC is enabled\n");
750                 /* Enable PFC RX & TX & STATS and set 8 COS  */
751                 wb_data[0] = 0x0;
752                 wb_data[0] |= (1<<0);  /* RX */
753                 wb_data[0] |= (1<<1);  /* TX */
754                 wb_data[0] |= (1<<2);  /* Force initial Xon */
755                 wb_data[0] |= (1<<3);  /* 8 cos */
756                 wb_data[0] |= (1<<5);  /* STATS */
757                 wb_data[1] = 0;
758                 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
759                             wb_data, 2);
760                 /* Clear the force Xon */
761                 wb_data[0] &= ~(1<<2);
762         } else {
763                 DP(NETIF_MSG_LINK, "PFC is disabled\n");
764                 /* disable PFC RX & TX & STATS and set 8 COS */
765                 wb_data[0] = 0x8;
766                 wb_data[1] = 0;
767         }
768
769         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
770
771         /**
772         * Set Time (based unit is 512 bit time) between automatic
773         * re-sending of PP packets amd enable automatic re-send of
774         * Per-Priroity Packet as long as pp_gen is asserted and
775         * pp_disable is low.
776         */
777         val = 0x8000;
778         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
779                 val |= (1<<16); /* enable automatic re-send */
780
781         wb_data[0] = val;
782         wb_data[1] = 0;
783         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
784                         wb_data, 2);
785
786         /* mac control */
787         val = 0x3; /* Enable RX and TX */
788         if (is_lb) {
789                 val |= 0x4; /* Local loopback */
790                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
791         }
792         /* When PFC enabled, Pass pause frames towards the NIG. */
793         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
794                 val |= ((1<<6)|(1<<5));
795
796         wb_data[0] = val;
797         wb_data[1] = 0;
798         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL,
799                         wb_data, 2);
800 }
801
802 static void bnx2x_update_pfc_brb(struct link_params *params,
803                 struct link_vars *vars,
804                 struct bnx2x_nig_brb_pfc_port_params *pfc_params)
805 {
806         struct bnx2x *bp = params->bp;
807         int set_pfc = params->feature_config_flags &
808                 FEATURE_CONFIG_PFC_ENABLED;
809
810         /* default - pause configuration */
811         u32 pause_xoff_th = PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE;
812         u32 pause_xon_th = PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE;
813         u32 full_xoff_th = PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE;
814         u32 full_xon_th = PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE;
815
816         if (set_pfc && pfc_params)
817                 /* First COS */
818                 if (!pfc_params->cos0_pauseable) {
819                         pause_xoff_th =
820                           PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE;
821                         pause_xon_th =
822                           PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE;
823                         full_xoff_th =
824                           PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE;
825                         full_xon_th =
826                           PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE;
827                 }
828         /* The number of free blocks below which the pause signal to class 0
829            of MAC #n is asserted. n=0,1 */
830         REG_WR(bp, BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 , pause_xoff_th);
831         /* The number of free blocks above which the pause signal to class 0
832            of MAC #n is de-asserted. n=0,1 */
833         REG_WR(bp, BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , pause_xon_th);
834         /* The number of free blocks below which the full signal to class 0
835            of MAC #n is asserted. n=0,1 */
836         REG_WR(bp, BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , full_xoff_th);
837         /* The number of free blocks above which the full signal to class 0
838            of MAC #n is de-asserted. n=0,1 */
839         REG_WR(bp, BRB1_REG_FULL_0_XON_THRESHOLD_0 , full_xon_th);
840
841         if (set_pfc && pfc_params) {
842                 /* Second COS */
843                 if (pfc_params->cos1_pauseable) {
844                         pause_xoff_th =
845                           PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE;
846                         pause_xon_th =
847                           PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE;
848                         full_xoff_th =
849                           PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE;
850                         full_xon_th =
851                           PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE;
852                 } else {
853                         pause_xoff_th =
854                           PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE;
855                         pause_xon_th =
856                           PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE;
857                         full_xoff_th =
858                           PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE;
859                         full_xon_th =
860                           PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE;
861                 }
862                 /**
863                  * The number of free blocks below which the pause signal to
864                  * class 1 of MAC #n is asserted. n=0,1
865                  **/
866                 REG_WR(bp, BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0, pause_xoff_th);
867                 /**
868                  * The number of free blocks above which the pause signal to
869                  * class 1 of MAC #n is de-asserted. n=0,1
870                  **/
871                 REG_WR(bp, BRB1_REG_PAUSE_1_XON_THRESHOLD_0, pause_xon_th);
872                 /**
873                  * The number of free blocks below which the full signal to
874                  * class 1 of MAC #n is asserted. n=0,1
875                  **/
876                 REG_WR(bp, BRB1_REG_FULL_1_XOFF_THRESHOLD_0, full_xoff_th);
877                 /**
878                  * The number of free blocks above which the full signal to
879                  * class 1 of MAC #n is de-asserted. n=0,1
880                  **/
881                 REG_WR(bp, BRB1_REG_FULL_1_XON_THRESHOLD_0, full_xon_th);
882         }
883 }
884
885 static void bnx2x_update_pfc_nig(struct link_params *params,
886                 struct link_vars *vars,
887                 struct bnx2x_nig_brb_pfc_port_params *nig_params)
888 {
889         u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
890         u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0;
891         u32 pkt_priority_to_cos = 0;
892         u32 val;
893         struct bnx2x *bp = params->bp;
894         int port = params->port;
895         int set_pfc = params->feature_config_flags &
896                 FEATURE_CONFIG_PFC_ENABLED;
897         DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
898
899         /**
900          * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
901          * MAC control frames (that are not pause packets)
902          * will be forwarded to the XCM.
903          */
904         xcm_mask = REG_RD(bp,
905                                 port ? NIG_REG_LLH1_XCM_MASK :
906                                 NIG_REG_LLH0_XCM_MASK);
907         /**
908          * nig params will override non PFC params, since it's possible to
909          * do transition from PFC to SAFC
910          */
911         if (set_pfc) {
912                 pause_enable = 0;
913                 llfc_out_en = 0;
914                 llfc_enable = 0;
915                 ppp_enable = 1;
916                 xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
917                                      NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
918                 xcm0_out_en = 0;
919                 p0_hwpfc_enable = 1;
920         } else  {
921                 if (nig_params) {
922                         llfc_out_en = nig_params->llfc_out_en;
923                         llfc_enable = nig_params->llfc_enable;
924                         pause_enable = nig_params->pause_enable;
925                 } else  /*defaul non PFC mode - PAUSE */
926                         pause_enable = 1;
927
928                 xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
929                         NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
930                 xcm0_out_en = 1;
931         }
932
933         REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
934                NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
935         REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
936                NIG_REG_LLFC_ENABLE_0, llfc_enable);
937         REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
938                NIG_REG_PAUSE_ENABLE_0, pause_enable);
939
940         REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
941                NIG_REG_PPP_ENABLE_0, ppp_enable);
942
943         REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
944                NIG_REG_LLH0_XCM_MASK, xcm_mask);
945
946         REG_WR(bp,  NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
947
948         /* output enable for RX_XCM # IF */
949         REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en);
950
951         /* HW PFC TX enable */
952         REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable);
953
954         /* 0x2 = BMAC, 0x1= EMAC */
955         switch (vars->mac_type) {
956         case MAC_TYPE_EMAC:
957                 val = 1;
958                 break;
959         case MAC_TYPE_BMAC:
960                 val = 0;
961                 break;
962         default:
963                 val = 0;
964                 break;
965         }
966         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT, val);
967
968         if (nig_params) {
969                 pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
970
971                 REG_WR(bp, port ? NIG_REG_P1_RX_COS0_PRIORITY_MASK :
972                        NIG_REG_P0_RX_COS0_PRIORITY_MASK,
973                        nig_params->rx_cos0_priority_mask);
974
975                 REG_WR(bp, port ? NIG_REG_P1_RX_COS1_PRIORITY_MASK :
976                        NIG_REG_P0_RX_COS1_PRIORITY_MASK,
977                        nig_params->rx_cos1_priority_mask);
978
979                 REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
980                        NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
981                        nig_params->llfc_high_priority_classes);
982
983                 REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
984                        NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
985                        nig_params->llfc_low_priority_classes);
986         }
987         REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
988                NIG_REG_P0_PKT_PRIORITY_TO_COS,
989                pkt_priority_to_cos);
990 }
991
992
993 void bnx2x_update_pfc(struct link_params *params,
994                       struct link_vars *vars,
995                       struct bnx2x_nig_brb_pfc_port_params *pfc_params)
996 {
997         /**
998          * The PFC and pause are orthogonal to one another, meaning when
999          * PFC is enabled, the pause are disabled, and when PFC is
1000          * disabled, pause are set according to the pause result.
1001          */
1002         u32 val;
1003         struct bnx2x *bp = params->bp;
1004
1005         /* update NIG params */
1006         bnx2x_update_pfc_nig(params, vars, pfc_params);
1007
1008         /* update BRB params */
1009         bnx2x_update_pfc_brb(params, vars, pfc_params);
1010
1011         if (!vars->link_up)
1012                 return;
1013
1014         val = REG_RD(bp, MISC_REG_RESET_REG_2);
1015         if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
1016             == 0) {
1017                 DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
1018                 bnx2x_emac_enable(params, vars, 0);
1019                 return;
1020         }
1021
1022         DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
1023         if (CHIP_IS_E2(bp))
1024                 bnx2x_update_pfc_bmac2(params, vars, 0);
1025         else
1026                 bnx2x_update_pfc_bmac1(params, vars);
1027
1028         val = 0;
1029         if ((params->feature_config_flags &
1030               FEATURE_CONFIG_PFC_ENABLED) ||
1031             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1032                 val = 1;
1033         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
1034 }
1035
1036 static u8 bnx2x_bmac1_enable(struct link_params *params,
1037                              struct link_vars *vars,
1038                           u8 is_lb)
1039 {
1040         struct bnx2x *bp = params->bp;
1041         u8 port = params->port;
1042         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1043                                NIG_REG_INGRESS_BMAC0_MEM;
1044         u32 wb_data[2];
1045         u32 val;
1046
1047         DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
1048
1049         /* XGXS control */
1050         wb_data[0] = 0x3c;
1051         wb_data[1] = 0;
1052         REG_WR_DMAE(bp, bmac_addr +
1053                       BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
1054                       wb_data, 2);
1055
1056         /* tx MAC SA */
1057         wb_data[0] = ((params->mac_addr[2] << 24) |
1058                        (params->mac_addr[3] << 16) |
1059                        (params->mac_addr[4] << 8) |
1060                         params->mac_addr[5]);
1061         wb_data[1] = ((params->mac_addr[0] << 8) |
1062                         params->mac_addr[1]);
1063         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
1064                     wb_data, 2);
1065
1066         /* mac control */
1067         val = 0x3;
1068         if (is_lb) {
1069                 val |= 0x4;
1070                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
1071         }
1072         wb_data[0] = val;
1073         wb_data[1] = 0;
1074         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
1075                     wb_data, 2);
1076
1077         /* set rx mtu */
1078         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1079         wb_data[1] = 0;
1080         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
1081                         wb_data, 2);
1082
1083         bnx2x_update_pfc_bmac1(params, vars);
1084
1085         /* set tx mtu */
1086         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1087         wb_data[1] = 0;
1088         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
1089                         wb_data, 2);
1090
1091         /* set cnt max size */
1092         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1093         wb_data[1] = 0;
1094         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
1095                     wb_data, 2);
1096
1097         /* configure safc */
1098         wb_data[0] = 0x1000200;
1099         wb_data[1] = 0;
1100         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
1101                     wb_data, 2);
1102         /* fix for emulation */
1103         if (CHIP_REV_IS_EMUL(bp)) {
1104                 wb_data[0] = 0xf000;
1105                 wb_data[1] = 0;
1106                 REG_WR_DMAE(bp,
1107                             bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
1108                             wb_data, 2);
1109         }
1110
1111
1112         return 0;
1113 }
1114
1115 static u8 bnx2x_bmac2_enable(struct link_params *params,
1116                              struct link_vars *vars,
1117                              u8 is_lb)
1118 {
1119         struct bnx2x *bp = params->bp;
1120         u8 port = params->port;
1121         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1122                                NIG_REG_INGRESS_BMAC0_MEM;
1123         u32 wb_data[2];
1124
1125         DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
1126
1127         wb_data[0] = 0;
1128         wb_data[1] = 0;
1129         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL,
1130                         wb_data, 2);
1131         udelay(30);
1132
1133         /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
1134         wb_data[0] = 0x3c;
1135         wb_data[1] = 0;
1136         REG_WR_DMAE(bp, bmac_addr +
1137                         BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
1138                         wb_data, 2);
1139
1140         udelay(30);
1141
1142         /* tx MAC SA */
1143         wb_data[0] = ((params->mac_addr[2] << 24) |
1144                        (params->mac_addr[3] << 16) |
1145                        (params->mac_addr[4] << 8) |
1146                         params->mac_addr[5]);
1147         wb_data[1] = ((params->mac_addr[0] << 8) |
1148                         params->mac_addr[1]);
1149         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
1150                         wb_data, 2);
1151
1152         udelay(30);
1153
1154         /* Configure SAFC */
1155         wb_data[0] = 0x1000200;
1156         wb_data[1] = 0;
1157         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
1158                         wb_data, 2);
1159         udelay(30);
1160
1161         /* set rx mtu */
1162         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1163         wb_data[1] = 0;
1164         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE,
1165                         wb_data, 2);
1166         udelay(30);
1167
1168         /* set tx mtu */
1169         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1170         wb_data[1] = 0;
1171         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE,
1172                         wb_data, 2);
1173         udelay(30);
1174         /* set cnt max size */
1175         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
1176         wb_data[1] = 0;
1177         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE,
1178                         wb_data, 2);
1179         udelay(30);
1180         bnx2x_update_pfc_bmac2(params, vars, is_lb);
1181
1182         return 0;
1183 }
1184
1185 static u8 bnx2x_bmac_enable(struct link_params *params,
1186                             struct link_vars *vars,
1187                             u8 is_lb)
1188 {
1189         u8 rc, port = params->port;
1190         struct bnx2x *bp = params->bp;
1191         u32 val;
1192         /* reset and unreset the BigMac */
1193         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1194                      (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1195         msleep(1);
1196
1197         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1198                      (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1199
1200         /* enable access for bmac registers */
1201         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
1202
1203         /* Enable BMAC according to BMAC type*/
1204         if (CHIP_IS_E2(bp))
1205                 rc = bnx2x_bmac2_enable(params, vars, is_lb);
1206         else
1207                 rc = bnx2x_bmac1_enable(params, vars, is_lb);
1208         REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
1209         REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
1210         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
1211         val = 0;
1212         if ((params->feature_config_flags &
1213               FEATURE_CONFIG_PFC_ENABLED) ||
1214             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1215                 val = 1;
1216         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
1217         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
1218         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
1219         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
1220         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
1221         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
1222
1223         vars->mac_type = MAC_TYPE_BMAC;
1224         return rc;
1225 }
1226
1227
1228 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
1229 {
1230         struct bnx2x *bp = params->bp;
1231
1232         REG_WR(bp, params->shmem_base +
1233                    offsetof(struct shmem_region,
1234                             port_mb[params->port].link_status),
1235                         link_status);
1236 }
1237
1238 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
1239 {
1240         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1241                 NIG_REG_INGRESS_BMAC0_MEM;
1242         u32 wb_data[2];
1243         u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
1244
1245         /* Only if the bmac is out of reset */
1246         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
1247                         (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
1248             nig_bmac_enable) {
1249
1250                 if (CHIP_IS_E2(bp)) {
1251                         /* Clear Rx Enable bit in BMAC_CONTROL register */
1252                         REG_RD_DMAE(bp, bmac_addr +
1253                                         BIGMAC2_REGISTER_BMAC_CONTROL,
1254                                         wb_data, 2);
1255                         wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
1256                         REG_WR_DMAE(bp, bmac_addr +
1257                                         BIGMAC2_REGISTER_BMAC_CONTROL,
1258                                         wb_data, 2);
1259                 } else {
1260                         /* Clear Rx Enable bit in BMAC_CONTROL register */
1261                         REG_RD_DMAE(bp, bmac_addr +
1262                                         BIGMAC_REGISTER_BMAC_CONTROL,
1263                                         wb_data, 2);
1264                         wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
1265                         REG_WR_DMAE(bp, bmac_addr +
1266                                         BIGMAC_REGISTER_BMAC_CONTROL,
1267                                         wb_data, 2);
1268                 }
1269                 msleep(1);
1270         }
1271 }
1272
1273 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
1274                          u32 line_speed)
1275 {
1276         struct bnx2x *bp = params->bp;
1277         u8 port = params->port;
1278         u32 init_crd, crd;
1279         u32 count = 1000;
1280
1281         /* disable port */
1282         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
1283
1284         /* wait for init credit */
1285         init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
1286         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
1287         DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
1288
1289         while ((init_crd != crd) && count) {
1290                 msleep(5);
1291
1292                 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
1293                 count--;
1294         }
1295         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
1296         if (init_crd != crd) {
1297                 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
1298                           init_crd, crd);
1299                 return -EINVAL;
1300         }
1301
1302         if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
1303             line_speed == SPEED_10 ||
1304             line_speed == SPEED_100 ||
1305             line_speed == SPEED_1000 ||
1306             line_speed == SPEED_2500) {
1307                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
1308                 /* update threshold */
1309                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
1310                 /* update init credit */
1311                 init_crd = 778;         /* (800-18-4) */
1312
1313         } else {
1314                 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
1315                               ETH_OVREHEAD)/16;
1316                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
1317                 /* update threshold */
1318                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
1319                 /* update init credit */
1320                 switch (line_speed) {
1321                 case SPEED_10000:
1322                         init_crd = thresh + 553 - 22;
1323                         break;
1324
1325                 case SPEED_12000:
1326                         init_crd = thresh + 664 - 22;
1327                         break;
1328
1329                 case SPEED_13000:
1330                         init_crd = thresh + 742 - 22;
1331                         break;
1332
1333                 case SPEED_16000:
1334                         init_crd = thresh + 778 - 22;
1335                         break;
1336                 default:
1337                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1338                                   line_speed);
1339                         return -EINVAL;
1340                 }
1341         }
1342         REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
1343         DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
1344                  line_speed, init_crd);
1345
1346         /* probe the credit changes */
1347         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
1348         msleep(5);
1349         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
1350
1351         /* enable port */
1352         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
1353         return 0;
1354 }
1355
1356 static u32 bnx2x_get_emac_base(struct bnx2x *bp,
1357                                u32 mdc_mdio_access, u8 port)
1358 {
1359         u32 emac_base = 0;
1360         switch (mdc_mdio_access) {
1361         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
1362                 break;
1363         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
1364                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
1365                         emac_base = GRCBASE_EMAC1;
1366                 else
1367                         emac_base = GRCBASE_EMAC0;
1368                 break;
1369         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
1370                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
1371                         emac_base = GRCBASE_EMAC0;
1372                 else
1373                         emac_base = GRCBASE_EMAC1;
1374                 break;
1375         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
1376                 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1377                 break;
1378         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
1379                 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
1380                 break;
1381         default:
1382                 break;
1383         }
1384         return emac_base;
1385
1386 }
1387
1388 u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
1389                     u8 devad, u16 reg, u16 val)
1390 {
1391         u32 tmp, saved_mode;
1392         u8 i, rc = 0;
1393
1394         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
1395          * (a value of 49==0x31) and make sure that the AUTO poll is off
1396          */
1397
1398         saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
1399         tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
1400                              EMAC_MDIO_MODE_CLOCK_CNT);
1401         tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
1402                 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
1403         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
1404         REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
1405         udelay(40);
1406
1407         /* address */
1408
1409         tmp = ((phy->addr << 21) | (devad << 16) | reg |
1410                EMAC_MDIO_COMM_COMMAND_ADDRESS |
1411                EMAC_MDIO_COMM_START_BUSY);
1412         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
1413
1414         for (i = 0; i < 50; i++) {
1415                 udelay(10);
1416
1417                 tmp = REG_RD(bp, phy->mdio_ctrl +
1418                                    EMAC_REG_EMAC_MDIO_COMM);
1419                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
1420                         udelay(5);
1421                         break;
1422                 }
1423         }
1424         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
1425                 DP(NETIF_MSG_LINK, "write phy register failed\n");
1426                 rc = -EFAULT;
1427         } else {
1428                 /* data */
1429                 tmp = ((phy->addr << 21) | (devad << 16) | val |
1430                        EMAC_MDIO_COMM_COMMAND_WRITE_45 |
1431                        EMAC_MDIO_COMM_START_BUSY);
1432                 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
1433
1434                 for (i = 0; i < 50; i++) {
1435                         udelay(10);
1436
1437                         tmp = REG_RD(bp, phy->mdio_ctrl +
1438                                          EMAC_REG_EMAC_MDIO_COMM);
1439                         if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
1440                                 udelay(5);
1441                                 break;
1442                         }
1443                 }
1444                 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
1445                         DP(NETIF_MSG_LINK, "write phy register failed\n");
1446                         rc = -EFAULT;
1447                 }
1448         }
1449
1450         /* Restore the saved mode */
1451         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
1452
1453         return rc;
1454 }
1455
1456 u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
1457                    u8 devad, u16 reg, u16 *ret_val)
1458 {
1459         u32 val, saved_mode;
1460         u16 i;
1461         u8 rc = 0;
1462
1463         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
1464          * (a value of 49==0x31) and make sure that the AUTO poll is off
1465          */
1466
1467         saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
1468         val = saved_mode & ~((EMAC_MDIO_MODE_AUTO_POLL |
1469                              EMAC_MDIO_MODE_CLOCK_CNT));
1470         val |= (EMAC_MDIO_MODE_CLAUSE_45 |
1471                 (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
1472         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
1473         REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
1474         udelay(40);
1475
1476         /* address */
1477         val = ((phy->addr << 21) | (devad << 16) | reg |
1478                EMAC_MDIO_COMM_COMMAND_ADDRESS |
1479                EMAC_MDIO_COMM_START_BUSY);
1480         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
1481
1482         for (i = 0; i < 50; i++) {
1483                 udelay(10);
1484
1485                 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
1486                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
1487                         udelay(5);
1488                         break;
1489                 }
1490         }
1491         if (val & EMAC_MDIO_COMM_START_BUSY) {
1492                 DP(NETIF_MSG_LINK, "read phy register failed\n");
1493
1494                 *ret_val = 0;
1495                 rc = -EFAULT;
1496
1497         } else {
1498                 /* data */
1499                 val = ((phy->addr << 21) | (devad << 16) |
1500                        EMAC_MDIO_COMM_COMMAND_READ_45 |
1501                        EMAC_MDIO_COMM_START_BUSY);
1502                 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
1503
1504                 for (i = 0; i < 50; i++) {
1505                         udelay(10);
1506
1507                         val = REG_RD(bp, phy->mdio_ctrl +
1508                                           EMAC_REG_EMAC_MDIO_COMM);
1509                         if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
1510                                 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
1511                                 break;
1512                         }
1513                 }
1514                 if (val & EMAC_MDIO_COMM_START_BUSY) {
1515                         DP(NETIF_MSG_LINK, "read phy register failed\n");
1516
1517                         *ret_val = 0;
1518                         rc = -EFAULT;
1519                 }
1520         }
1521
1522         /* Restore the saved mode */
1523         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
1524
1525         return rc;
1526 }
1527
1528 u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr,
1529                   u8 devad, u16 reg, u16 *ret_val)
1530 {
1531         u8 phy_index;
1532         /**
1533          * Probe for the phy according to the given phy_addr, and execute
1534          * the read request on it
1535          */
1536         for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
1537                 if (params->phy[phy_index].addr == phy_addr) {
1538                         return bnx2x_cl45_read(params->bp,
1539                                                &params->phy[phy_index], devad,
1540                                                reg, ret_val);
1541                 }
1542         }
1543         return -EINVAL;
1544 }
1545
1546 u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr,
1547                    u8 devad, u16 reg, u16 val)
1548 {
1549         u8 phy_index;
1550         /**
1551          * Probe for the phy according to the given phy_addr, and execute
1552          * the write request on it
1553          */
1554         for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
1555                 if (params->phy[phy_index].addr == phy_addr) {
1556                         return bnx2x_cl45_write(params->bp,
1557                                                 &params->phy[phy_index], devad,
1558                                                 reg, val);
1559                 }
1560         }
1561         return -EINVAL;
1562 }
1563
1564 static void bnx2x_set_aer_mmd_xgxs(struct link_params *params,
1565                                    struct bnx2x_phy *phy)
1566 {
1567         u32 ser_lane;
1568         u16 offset, aer_val;
1569         struct bnx2x *bp = params->bp;
1570         ser_lane = ((params->lane_config &
1571                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1572                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1573
1574         offset = phy->addr + ser_lane;
1575         if (CHIP_IS_E2(bp))
1576                 aer_val = 0x2800 + offset - 1;
1577         else
1578                 aer_val = 0x3800 + offset;
1579         CL45_WR_OVER_CL22(bp, phy,
1580                                 MDIO_REG_BANK_AER_BLOCK,
1581                                 MDIO_AER_BLOCK_AER_REG, aer_val);
1582 }
1583 static void bnx2x_set_aer_mmd_serdes(struct bnx2x *bp,
1584                                      struct bnx2x_phy *phy)
1585 {
1586         CL45_WR_OVER_CL22(bp, phy,
1587                                 MDIO_REG_BANK_AER_BLOCK,
1588                                 MDIO_AER_BLOCK_AER_REG, 0x3800);
1589 }
1590
1591 /******************************************************************/
1592 /*                      Internal phy section                      */
1593 /******************************************************************/
1594
1595 static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
1596 {
1597         u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1598
1599         /* Set Clause 22 */
1600         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
1601         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
1602         udelay(500);
1603         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
1604         udelay(500);
1605          /* Set Clause 45 */
1606         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
1607 }
1608
1609 static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
1610 {
1611         u32 val;
1612
1613         DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
1614
1615         val = SERDES_RESET_BITS << (port*16);
1616
1617         /* reset and unreset the SerDes/XGXS */
1618         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
1619         udelay(500);
1620         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
1621
1622         bnx2x_set_serdes_access(bp, port);
1623
1624         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
1625                      port*0x10,
1626                      DEFAULT_PHY_DEV_ADDR);
1627 }
1628
1629 static void bnx2x_xgxs_deassert(struct link_params *params)
1630 {
1631         struct bnx2x *bp = params->bp;
1632         u8 port;
1633         u32 val;
1634         DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
1635         port = params->port;
1636
1637         val = XGXS_RESET_BITS << (port*16);
1638
1639         /* reset and unreset the SerDes/XGXS */
1640         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
1641         udelay(500);
1642         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
1643
1644         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
1645                      port*0x18, 0);
1646         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
1647                      params->phy[INT_PHY].def_md_devad);
1648 }
1649
1650
1651 void bnx2x_link_status_update(struct link_params *params,
1652                             struct link_vars   *vars)
1653 {
1654         struct bnx2x *bp = params->bp;
1655         u8 link_10g;
1656         u8 port = params->port;
1657
1658         vars->link_status = REG_RD(bp, params->shmem_base +
1659                                           offsetof(struct shmem_region,
1660                                            port_mb[port].link_status));
1661
1662         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
1663
1664         if (vars->link_up) {
1665                 DP(NETIF_MSG_LINK, "phy link up\n");
1666
1667                 vars->phy_link_up = 1;
1668                 vars->duplex = DUPLEX_FULL;
1669                 switch (vars->link_status &
1670                                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
1671                         case LINK_10THD:
1672                                 vars->duplex = DUPLEX_HALF;
1673                                 /* fall thru */
1674                         case LINK_10TFD:
1675                                 vars->line_speed = SPEED_10;
1676                                 break;
1677
1678                         case LINK_100TXHD:
1679                                 vars->duplex = DUPLEX_HALF;
1680                                 /* fall thru */
1681                         case LINK_100T4:
1682                         case LINK_100TXFD:
1683                                 vars->line_speed = SPEED_100;
1684                                 break;
1685
1686                         case LINK_1000THD:
1687                                 vars->duplex = DUPLEX_HALF;
1688                                 /* fall thru */
1689                         case LINK_1000TFD:
1690                                 vars->line_speed = SPEED_1000;
1691                                 break;
1692
1693                         case LINK_2500THD:
1694                                 vars->duplex = DUPLEX_HALF;
1695                                 /* fall thru */
1696                         case LINK_2500TFD:
1697                                 vars->line_speed = SPEED_2500;
1698                                 break;
1699
1700                         case LINK_10GTFD:
1701                                 vars->line_speed = SPEED_10000;
1702                                 break;
1703
1704                         case LINK_12GTFD:
1705                                 vars->line_speed = SPEED_12000;
1706                                 break;
1707
1708                         case LINK_12_5GTFD:
1709                                 vars->line_speed = SPEED_12500;
1710                                 break;
1711
1712                         case LINK_13GTFD:
1713                                 vars->line_speed = SPEED_13000;
1714                                 break;
1715
1716                         case LINK_15GTFD:
1717                                 vars->line_speed = SPEED_15000;
1718                                 break;
1719
1720                         case LINK_16GTFD:
1721                                 vars->line_speed = SPEED_16000;
1722                                 break;
1723
1724                         default:
1725                                 break;
1726                 }
1727                 vars->flow_ctrl = 0;
1728                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
1729                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
1730
1731                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
1732                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
1733
1734                 if (!vars->flow_ctrl)
1735                         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1736
1737                 if (vars->line_speed &&
1738                     ((vars->line_speed == SPEED_10) ||
1739                      (vars->line_speed == SPEED_100))) {
1740                         vars->phy_flags |= PHY_SGMII_FLAG;
1741                 } else {
1742                         vars->phy_flags &= ~PHY_SGMII_FLAG;
1743                 }
1744
1745                 /* anything 10 and over uses the bmac */
1746                 link_10g = ((vars->line_speed == SPEED_10000) ||
1747                             (vars->line_speed == SPEED_12000) ||
1748                             (vars->line_speed == SPEED_12500) ||
1749                             (vars->line_speed == SPEED_13000) ||
1750                             (vars->line_speed == SPEED_15000) ||
1751                             (vars->line_speed == SPEED_16000));
1752                 if (link_10g)
1753                         vars->mac_type = MAC_TYPE_BMAC;
1754                 else
1755                         vars->mac_type = MAC_TYPE_EMAC;
1756
1757         } else { /* link down */
1758                 DP(NETIF_MSG_LINK, "phy link down\n");
1759
1760                 vars->phy_link_up = 0;
1761
1762                 vars->line_speed = 0;
1763                 vars->duplex = DUPLEX_FULL;
1764                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1765
1766                 /* indicate no mac active */
1767                 vars->mac_type = MAC_TYPE_NONE;
1768         }
1769
1770         DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x\n",
1771                  vars->link_status, vars->phy_link_up);
1772         DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
1773                  vars->line_speed, vars->duplex, vars->flow_ctrl);
1774 }
1775
1776
1777 static void bnx2x_set_master_ln(struct link_params *params,
1778                                 struct bnx2x_phy *phy)
1779 {
1780         struct bnx2x *bp = params->bp;
1781         u16 new_master_ln, ser_lane;
1782         ser_lane =  ((params->lane_config &
1783                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1784                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1785
1786         /* set the master_ln for AN */
1787         CL45_RD_OVER_CL22(bp, phy,
1788                               MDIO_REG_BANK_XGXS_BLOCK2,
1789                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1790                               &new_master_ln);
1791
1792         CL45_WR_OVER_CL22(bp, phy,
1793                               MDIO_REG_BANK_XGXS_BLOCK2 ,
1794                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1795                               (new_master_ln | ser_lane));
1796 }
1797
1798 static u8 bnx2x_reset_unicore(struct link_params *params,
1799                               struct bnx2x_phy *phy,
1800                               u8 set_serdes)
1801 {
1802         struct bnx2x *bp = params->bp;
1803         u16 mii_control;
1804         u16 i;
1805
1806         CL45_RD_OVER_CL22(bp, phy,
1807                               MDIO_REG_BANK_COMBO_IEEE0,
1808                               MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
1809
1810         /* reset the unicore */
1811         CL45_WR_OVER_CL22(bp, phy,
1812                               MDIO_REG_BANK_COMBO_IEEE0,
1813                               MDIO_COMBO_IEEE0_MII_CONTROL,
1814                               (mii_control |
1815                                MDIO_COMBO_IEEO_MII_CONTROL_RESET));
1816         if (set_serdes)
1817                 bnx2x_set_serdes_access(bp, params->port);
1818
1819         /* wait for the reset to self clear */
1820         for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
1821                 udelay(5);
1822
1823                 /* the reset erased the previous bank value */
1824                 CL45_RD_OVER_CL22(bp, phy,
1825                               MDIO_REG_BANK_COMBO_IEEE0,
1826                               MDIO_COMBO_IEEE0_MII_CONTROL,
1827                               &mii_control);
1828
1829                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1830                         udelay(5);
1831                         return 0;
1832                 }
1833         }
1834
1835         DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1836         return -EINVAL;
1837
1838 }
1839
1840 static void bnx2x_set_swap_lanes(struct link_params *params,
1841                                  struct bnx2x_phy *phy)
1842 {
1843         struct bnx2x *bp = params->bp;
1844         /* Each two bits represents a lane number:
1845            No swap is 0123 => 0x1b no need to enable the swap */
1846         u16 ser_lane, rx_lane_swap, tx_lane_swap;
1847
1848         ser_lane = ((params->lane_config &
1849                          PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1850                         PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1851         rx_lane_swap = ((params->lane_config &
1852                              PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1853                             PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1854         tx_lane_swap = ((params->lane_config &
1855                              PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1856                             PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1857
1858         if (rx_lane_swap != 0x1b) {
1859                 CL45_WR_OVER_CL22(bp, phy,
1860                                     MDIO_REG_BANK_XGXS_BLOCK2,
1861                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1862                                     (rx_lane_swap |
1863                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1864                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1865         } else {
1866                 CL45_WR_OVER_CL22(bp, phy,
1867                                       MDIO_REG_BANK_XGXS_BLOCK2,
1868                                       MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1869         }
1870
1871         if (tx_lane_swap != 0x1b) {
1872                 CL45_WR_OVER_CL22(bp, phy,
1873                                       MDIO_REG_BANK_XGXS_BLOCK2,
1874                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1875                                       (tx_lane_swap |
1876                                        MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1877         } else {
1878                 CL45_WR_OVER_CL22(bp, phy,
1879                                       MDIO_REG_BANK_XGXS_BLOCK2,
1880                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1881         }
1882 }
1883
1884 static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
1885                                          struct link_params *params)
1886 {
1887         struct bnx2x *bp = params->bp;
1888         u16 control2;
1889         CL45_RD_OVER_CL22(bp, phy,
1890                               MDIO_REG_BANK_SERDES_DIGITAL,
1891                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1892                               &control2);
1893         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
1894                 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1895         else
1896                 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1897         DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
1898                 phy->speed_cap_mask, control2);
1899         CL45_WR_OVER_CL22(bp, phy,
1900                               MDIO_REG_BANK_SERDES_DIGITAL,
1901                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1902                               control2);
1903
1904         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
1905              (phy->speed_cap_mask &
1906                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
1907                 DP(NETIF_MSG_LINK, "XGXS\n");
1908
1909                 CL45_WR_OVER_CL22(bp, phy,
1910                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1911                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1912                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1913
1914                 CL45_RD_OVER_CL22(bp, phy,
1915                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1916                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1917                                 &control2);
1918
1919
1920                 control2 |=
1921                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1922
1923                 CL45_WR_OVER_CL22(bp, phy,
1924                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1925                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1926                                 control2);
1927
1928                 /* Disable parallel detection of HiG */
1929                 CL45_WR_OVER_CL22(bp, phy,
1930                                 MDIO_REG_BANK_XGXS_BLOCK2,
1931                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1932                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1933                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1934         }
1935 }
1936
1937 static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
1938                               struct link_params *params,
1939                             struct link_vars *vars,
1940                             u8 enable_cl73)
1941 {
1942         struct bnx2x *bp = params->bp;
1943         u16 reg_val;
1944
1945         /* CL37 Autoneg */
1946         CL45_RD_OVER_CL22(bp, phy,
1947                               MDIO_REG_BANK_COMBO_IEEE0,
1948                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1949
1950         /* CL37 Autoneg Enabled */
1951         if (vars->line_speed == SPEED_AUTO_NEG)
1952                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1953         else /* CL37 Autoneg Disabled */
1954                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1955                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1956
1957         CL45_WR_OVER_CL22(bp, phy,
1958                               MDIO_REG_BANK_COMBO_IEEE0,
1959                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1960
1961         /* Enable/Disable Autodetection */
1962
1963         CL45_RD_OVER_CL22(bp, phy,
1964                               MDIO_REG_BANK_SERDES_DIGITAL,
1965                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1966         reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
1967                     MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
1968         reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
1969         if (vars->line_speed == SPEED_AUTO_NEG)
1970                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1971         else
1972                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1973
1974         CL45_WR_OVER_CL22(bp, phy,
1975                               MDIO_REG_BANK_SERDES_DIGITAL,
1976                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1977
1978         /* Enable TetonII and BAM autoneg */
1979         CL45_RD_OVER_CL22(bp, phy,
1980                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1981                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1982                           &reg_val);
1983         if (vars->line_speed == SPEED_AUTO_NEG) {
1984                 /* Enable BAM aneg Mode and TetonII aneg Mode */
1985                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1986                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1987         } else {
1988                 /* TetonII and BAM Autoneg Disabled */
1989                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1990                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1991         }
1992         CL45_WR_OVER_CL22(bp, phy,
1993                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1994                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1995                               reg_val);
1996
1997         if (enable_cl73) {
1998                 /* Enable Cl73 FSM status bits */
1999                 CL45_WR_OVER_CL22(bp, phy,
2000                                       MDIO_REG_BANK_CL73_USERB0,
2001                                     MDIO_CL73_USERB0_CL73_UCTRL,
2002                                       0xe);
2003
2004                 /* Enable BAM Station Manager*/
2005                 CL45_WR_OVER_CL22(bp, phy,
2006                         MDIO_REG_BANK_CL73_USERB0,
2007                         MDIO_CL73_USERB0_CL73_BAM_CTRL1,
2008                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
2009                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
2010                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
2011
2012                 /* Advertise CL73 link speeds */
2013                 CL45_RD_OVER_CL22(bp, phy,
2014                                               MDIO_REG_BANK_CL73_IEEEB1,
2015                                               MDIO_CL73_IEEEB1_AN_ADV2,
2016                                               &reg_val);
2017                 if (phy->speed_cap_mask &
2018                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2019                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
2020                 if (phy->speed_cap_mask &
2021                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
2022                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
2023
2024                 CL45_WR_OVER_CL22(bp, phy,
2025                                               MDIO_REG_BANK_CL73_IEEEB1,
2026                                               MDIO_CL73_IEEEB1_AN_ADV2,
2027                                       reg_val);
2028
2029                 /* CL73 Autoneg Enabled */
2030                 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
2031
2032         } else /* CL73 Autoneg Disabled */
2033                 reg_val = 0;
2034
2035         CL45_WR_OVER_CL22(bp, phy,
2036                               MDIO_REG_BANK_CL73_IEEEB0,
2037                               MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
2038 }
2039
2040 /* program SerDes, forced speed */
2041 static void bnx2x_program_serdes(struct bnx2x_phy *phy,
2042                                  struct link_params *params,
2043                                struct link_vars *vars)
2044 {
2045         struct bnx2x *bp = params->bp;
2046         u16 reg_val;
2047
2048         /* program duplex, disable autoneg and sgmii*/
2049         CL45_RD_OVER_CL22(bp, phy,
2050                               MDIO_REG_BANK_COMBO_IEEE0,
2051                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
2052         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
2053                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
2054                      MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
2055         if (phy->req_duplex == DUPLEX_FULL)
2056                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
2057         CL45_WR_OVER_CL22(bp, phy,
2058                               MDIO_REG_BANK_COMBO_IEEE0,
2059                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
2060
2061         /* program speed
2062            - needed only if the speed is greater than 1G (2.5G or 10G) */
2063         CL45_RD_OVER_CL22(bp, phy,
2064                                       MDIO_REG_BANK_SERDES_DIGITAL,
2065                                       MDIO_SERDES_DIGITAL_MISC1, &reg_val);
2066         /* clearing the speed value before setting the right speed */
2067         DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
2068
2069         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
2070                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
2071
2072         if (!((vars->line_speed == SPEED_1000) ||
2073               (vars->line_speed == SPEED_100) ||
2074               (vars->line_speed == SPEED_10))) {
2075
2076                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
2077                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
2078                 if (vars->line_speed == SPEED_10000)
2079                         reg_val |=
2080                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
2081                 if (vars->line_speed == SPEED_13000)
2082                         reg_val |=
2083                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
2084         }
2085
2086         CL45_WR_OVER_CL22(bp, phy,
2087                                       MDIO_REG_BANK_SERDES_DIGITAL,
2088                                       MDIO_SERDES_DIGITAL_MISC1, reg_val);
2089
2090 }
2091
2092 static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x_phy *phy,
2093                                              struct link_params *params)
2094 {
2095         struct bnx2x *bp = params->bp;
2096         u16 val = 0;
2097
2098         /* configure the 48 bits for BAM AN */
2099
2100         /* set extended capabilities */
2101         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
2102                 val |= MDIO_OVER_1G_UP1_2_5G;
2103         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2104                 val |= MDIO_OVER_1G_UP1_10G;
2105         CL45_WR_OVER_CL22(bp, phy,
2106                               MDIO_REG_BANK_OVER_1G,
2107                               MDIO_OVER_1G_UP1, val);
2108
2109         CL45_WR_OVER_CL22(bp, phy,
2110                               MDIO_REG_BANK_OVER_1G,
2111                               MDIO_OVER_1G_UP3, 0x400);
2112 }
2113
2114 static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
2115                                      struct link_params *params, u16 *ieee_fc)
2116 {
2117         struct bnx2x *bp = params->bp;
2118         *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
2119         /* resolve pause mode and advertisement
2120          * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
2121
2122         switch (phy->req_flow_ctrl) {
2123         case BNX2X_FLOW_CTRL_AUTO:
2124                 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
2125                         *ieee_fc |=
2126                              MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2127                 } else {
2128                         *ieee_fc |=
2129                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2130                 }
2131                 break;
2132         case BNX2X_FLOW_CTRL_TX:
2133                 *ieee_fc |=
2134                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2135                 break;
2136
2137         case BNX2X_FLOW_CTRL_RX:
2138         case BNX2X_FLOW_CTRL_BOTH:
2139                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2140                 break;
2141
2142         case BNX2X_FLOW_CTRL_NONE:
2143         default:
2144                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
2145                 break;
2146         }
2147         DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
2148 }
2149
2150 static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x_phy *phy,
2151                                              struct link_params *params,
2152                                            u16 ieee_fc)
2153 {
2154         struct bnx2x *bp = params->bp;
2155         u16 val;
2156         /* for AN, we are always publishing full duplex */
2157
2158         CL45_WR_OVER_CL22(bp, phy,
2159                               MDIO_REG_BANK_COMBO_IEEE0,
2160                               MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
2161         CL45_RD_OVER_CL22(bp, phy,
2162                               MDIO_REG_BANK_CL73_IEEEB1,
2163                               MDIO_CL73_IEEEB1_AN_ADV1, &val);
2164         val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
2165         val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
2166         CL45_WR_OVER_CL22(bp, phy,
2167                               MDIO_REG_BANK_CL73_IEEEB1,
2168                               MDIO_CL73_IEEEB1_AN_ADV1, val);
2169 }
2170
2171 static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
2172                                   struct link_params *params,
2173                                   u8 enable_cl73)
2174 {
2175         struct bnx2x *bp = params->bp;
2176         u16 mii_control;
2177
2178         DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
2179         /* Enable and restart BAM/CL37 aneg */
2180
2181         if (enable_cl73) {
2182                 CL45_RD_OVER_CL22(bp, phy,
2183                                       MDIO_REG_BANK_CL73_IEEEB0,
2184                                       MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2185                                       &mii_control);
2186
2187                 CL45_WR_OVER_CL22(bp, phy,
2188                                 MDIO_REG_BANK_CL73_IEEEB0,
2189                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2190                                 (mii_control |
2191                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
2192                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
2193         } else {
2194
2195                 CL45_RD_OVER_CL22(bp, phy,
2196                                       MDIO_REG_BANK_COMBO_IEEE0,
2197                                       MDIO_COMBO_IEEE0_MII_CONTROL,
2198                                       &mii_control);
2199                 DP(NETIF_MSG_LINK,
2200                          "bnx2x_restart_autoneg mii_control before = 0x%x\n",
2201                          mii_control);
2202                 CL45_WR_OVER_CL22(bp, phy,
2203                                       MDIO_REG_BANK_COMBO_IEEE0,
2204                                       MDIO_COMBO_IEEE0_MII_CONTROL,
2205                                       (mii_control |
2206                                        MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
2207                                        MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
2208         }
2209 }
2210
2211 static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
2212                                            struct link_params *params,
2213                                          struct link_vars *vars)
2214 {
2215         struct bnx2x *bp = params->bp;
2216         u16 control1;
2217
2218         /* in SGMII mode, the unicore is always slave */
2219
2220         CL45_RD_OVER_CL22(bp, phy,
2221                               MDIO_REG_BANK_SERDES_DIGITAL,
2222                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
2223                       &control1);
2224         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
2225         /* set sgmii mode (and not fiber) */
2226         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
2227                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
2228                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
2229         CL45_WR_OVER_CL22(bp, phy,
2230                               MDIO_REG_BANK_SERDES_DIGITAL,
2231                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
2232                               control1);
2233
2234         /* if forced speed */
2235         if (!(vars->line_speed == SPEED_AUTO_NEG)) {
2236                 /* set speed, disable autoneg */
2237                 u16 mii_control;
2238
2239                 CL45_RD_OVER_CL22(bp, phy,
2240                                       MDIO_REG_BANK_COMBO_IEEE0,
2241                                       MDIO_COMBO_IEEE0_MII_CONTROL,
2242                                       &mii_control);
2243                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
2244                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
2245                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
2246
2247                 switch (vars->line_speed) {
2248                 case SPEED_100:
2249                         mii_control |=
2250                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
2251                         break;
2252                 case SPEED_1000:
2253                         mii_control |=
2254                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
2255                         break;
2256                 case SPEED_10:
2257                         /* there is nothing to set for 10M */
2258                         break;
2259                 default:
2260                         /* invalid speed for SGMII */
2261                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2262                                   vars->line_speed);
2263                         break;
2264                 }
2265
2266                 /* setting the full duplex */
2267                 if (phy->req_duplex == DUPLEX_FULL)
2268                         mii_control |=
2269                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
2270                 CL45_WR_OVER_CL22(bp, phy,
2271                                       MDIO_REG_BANK_COMBO_IEEE0,
2272                                       MDIO_COMBO_IEEE0_MII_CONTROL,
2273                                       mii_control);
2274
2275         } else { /* AN mode */
2276                 /* enable and restart AN */
2277                 bnx2x_restart_autoneg(phy, params, 0);
2278         }
2279 }
2280
2281
2282 /*
2283  * link management
2284  */
2285
2286 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
2287 {                                               /*  LD      LP   */
2288         switch (pause_result) {                 /* ASYM P ASYM P */
2289         case 0xb:                               /*   1  0   1  1 */
2290                 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
2291                 break;
2292
2293         case 0xe:                               /*   1  1   1  0 */
2294                 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
2295                 break;
2296
2297         case 0x5:                               /*   0  1   0  1 */
2298         case 0x7:                               /*   0  1   1  1 */
2299         case 0xd:                               /*   1  1   0  1 */
2300         case 0xf:                               /*   1  1   1  1 */
2301                 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
2302                 break;
2303
2304         default:
2305                 break;
2306         }
2307         if (pause_result & (1<<0))
2308                 vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
2309         if (pause_result & (1<<1))
2310                 vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
2311 }
2312
2313 static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
2314                                             struct link_params *params)
2315 {
2316         struct bnx2x *bp = params->bp;
2317         u16 pd_10g, status2_1000x;
2318         if (phy->req_line_speed != SPEED_AUTO_NEG)
2319                 return 0;
2320         CL45_RD_OVER_CL22(bp, phy,
2321                               MDIO_REG_BANK_SERDES_DIGITAL,
2322                               MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
2323                               &status2_1000x);
2324         CL45_RD_OVER_CL22(bp, phy,
2325                               MDIO_REG_BANK_SERDES_DIGITAL,
2326                               MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
2327                               &status2_1000x);
2328         if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
2329                 DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
2330                          params->port);
2331                 return 1;
2332         }
2333
2334         CL45_RD_OVER_CL22(bp, phy,
2335                               MDIO_REG_BANK_10G_PARALLEL_DETECT,
2336                               MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
2337                               &pd_10g);
2338
2339         if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
2340                 DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
2341                          params->port);
2342                 return 1;
2343         }
2344         return 0;
2345 }
2346
2347 static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
2348                                     struct link_params *params,
2349                                     struct link_vars *vars,
2350                                     u32 gp_status)
2351 {
2352         struct bnx2x *bp = params->bp;
2353         u16 ld_pause;   /* local driver */
2354         u16 lp_pause;   /* link partner */
2355         u16 pause_result;
2356
2357         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
2358
2359         /* resolve from gp_status in case of AN complete and not sgmii */
2360         if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
2361                 vars->flow_ctrl = phy->req_flow_ctrl;
2362         else if (phy->req_line_speed != SPEED_AUTO_NEG)
2363                 vars->flow_ctrl = params->req_fc_auto_adv;
2364         else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
2365                  (!(vars->phy_flags & PHY_SGMII_FLAG))) {
2366                 if (bnx2x_direct_parallel_detect_used(phy, params)) {
2367                         vars->flow_ctrl = params->req_fc_auto_adv;
2368                         return;
2369                 }
2370                 if ((gp_status &
2371                     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
2372                      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
2373                     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
2374                      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
2375
2376                         CL45_RD_OVER_CL22(bp, phy,
2377                                               MDIO_REG_BANK_CL73_IEEEB1,
2378                                               MDIO_CL73_IEEEB1_AN_ADV1,
2379                                               &ld_pause);
2380                         CL45_RD_OVER_CL22(bp, phy,
2381                                              MDIO_REG_BANK_CL73_IEEEB1,
2382                                              MDIO_CL73_IEEEB1_AN_LP_ADV1,
2383                                              &lp_pause);
2384                         pause_result = (ld_pause &
2385                                         MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
2386                                         >> 8;
2387                         pause_result |= (lp_pause &
2388                                         MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
2389                                         >> 10;
2390                         DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
2391                                  pause_result);
2392                 } else {
2393                         CL45_RD_OVER_CL22(bp, phy,
2394                                               MDIO_REG_BANK_COMBO_IEEE0,
2395                                               MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
2396                                               &ld_pause);
2397                         CL45_RD_OVER_CL22(bp, phy,
2398                                MDIO_REG_BANK_COMBO_IEEE0,
2399                                MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
2400                                &lp_pause);
2401                         pause_result = (ld_pause &
2402                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
2403                         pause_result |= (lp_pause &
2404                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
2405                         DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
2406                                  pause_result);
2407                 }
2408                 bnx2x_pause_resolve(vars, pause_result);
2409         }
2410         DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
2411 }
2412
2413 static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
2414                                          struct link_params *params)
2415 {
2416         struct bnx2x *bp = params->bp;
2417         u16 rx_status, ustat_val, cl37_fsm_recieved;
2418         DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
2419         /* Step 1: Make sure signal is detected */
2420         CL45_RD_OVER_CL22(bp, phy,
2421                               MDIO_REG_BANK_RX0,
2422                               MDIO_RX0_RX_STATUS,
2423                               &rx_status);
2424         if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
2425             (MDIO_RX0_RX_STATUS_SIGDET)) {
2426                 DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
2427                              "rx_status(0x80b0) = 0x%x\n", rx_status);
2428                 CL45_WR_OVER_CL22(bp, phy,
2429                                       MDIO_REG_BANK_CL73_IEEEB0,
2430                                       MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2431                                       MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
2432                 return;
2433         }
2434         /* Step 2: Check CL73 state machine */
2435         CL45_RD_OVER_CL22(bp, phy,
2436                               MDIO_REG_BANK_CL73_USERB0,
2437                               MDIO_CL73_USERB0_CL73_USTAT1,
2438                               &ustat_val);
2439         if ((ustat_val &
2440              (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
2441               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
2442             (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
2443               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
2444                 DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
2445                              "ustat_val(0x8371) = 0x%x\n", ustat_val);
2446                 return;
2447         }
2448         /* Step 3: Check CL37 Message Pages received to indicate LP
2449         supports only CL37 */
2450         CL45_RD_OVER_CL22(bp, phy,
2451                               MDIO_REG_BANK_REMOTE_PHY,
2452                               MDIO_REMOTE_PHY_MISC_RX_STATUS,
2453                               &cl37_fsm_recieved);
2454         if ((cl37_fsm_recieved &
2455              (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
2456              MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
2457             (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
2458               MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
2459                 DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
2460                              "misc_rx_status(0x8330) = 0x%x\n",
2461                          cl37_fsm_recieved);
2462                 return;
2463         }
2464         /* The combined cl37/cl73 fsm state information indicating that we are
2465         connected to a device which does not support cl73, but does support
2466         cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */
2467         /* Disable CL73 */
2468         CL45_WR_OVER_CL22(bp, phy,
2469                               MDIO_REG_BANK_CL73_IEEEB0,
2470                               MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2471                               0);
2472         /* Restart CL37 autoneg */
2473         bnx2x_restart_autoneg(phy, params, 0);
2474         DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
2475 }
2476
2477 static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
2478                                   struct link_params *params,
2479                                   struct link_vars *vars,
2480                                   u32 gp_status)
2481 {
2482         if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
2483                 vars->link_status |=
2484                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
2485
2486         if (bnx2x_direct_parallel_detect_used(phy, params))
2487                 vars->link_status |=
2488                         LINK_STATUS_PARALLEL_DETECTION_USED;
2489 }
2490
2491 static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy,
2492                                      struct link_params *params,
2493                                      struct link_vars *vars)
2494 {
2495         struct bnx2x *bp = params->bp;
2496         u16 new_line_speed , gp_status;
2497         u8 rc = 0;
2498
2499         /* Read gp_status */
2500         CL45_RD_OVER_CL22(bp, phy,
2501                                 MDIO_REG_BANK_GP_STATUS,
2502                                 MDIO_GP_STATUS_TOP_AN_STATUS1,
2503                                 &gp_status);
2504
2505         if (phy->req_line_speed == SPEED_AUTO_NEG)
2506                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
2507         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
2508                 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
2509                          gp_status);
2510
2511                 vars->phy_link_up = 1;
2512                 vars->link_status |= LINK_STATUS_LINK_UP;
2513
2514                 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
2515                         vars->duplex = DUPLEX_FULL;
2516                 else
2517                         vars->duplex = DUPLEX_HALF;
2518
2519                 if (SINGLE_MEDIA_DIRECT(params)) {
2520                         bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
2521                         if (phy->req_line_speed == SPEED_AUTO_NEG)
2522                                 bnx2x_xgxs_an_resolve(phy, params, vars,
2523                                                       gp_status);
2524                 }
2525
2526                 switch (gp_status & GP_STATUS_SPEED_MASK) {
2527                 case GP_STATUS_10M:
2528                         new_line_speed = SPEED_10;
2529                         if (vars->duplex == DUPLEX_FULL)
2530                                 vars->link_status |= LINK_10TFD;
2531                         else
2532                                 vars->link_status |= LINK_10THD;
2533                         break;
2534
2535                 case GP_STATUS_100M:
2536                         new_line_speed = SPEED_100;
2537                         if (vars->duplex == DUPLEX_FULL)
2538                                 vars->link_status |= LINK_100TXFD;
2539                         else
2540                                 vars->link_status |= LINK_100TXHD;
2541                         break;
2542
2543                 case GP_STATUS_1G:
2544                 case GP_STATUS_1G_KX:
2545                         new_line_speed = SPEED_1000;
2546                         if (vars->duplex == DUPLEX_FULL)
2547                                 vars->link_status |= LINK_1000TFD;
2548                         else
2549                                 vars->link_status |= LINK_1000THD;
2550                         break;
2551
2552                 case GP_STATUS_2_5G:
2553                         new_line_speed = SPEED_2500;
2554                         if (vars->duplex == DUPLEX_FULL)
2555                                 vars->link_status |= LINK_2500TFD;
2556                         else
2557                                 vars->link_status |= LINK_2500THD;
2558                         break;
2559
2560                 case GP_STATUS_5G:
2561                 case GP_STATUS_6G:
2562                         DP(NETIF_MSG_LINK,
2563                                  "link speed unsupported  gp_status 0x%x\n",
2564                                   gp_status);
2565                         return -EINVAL;
2566
2567                 case GP_STATUS_10G_KX4:
2568                 case GP_STATUS_10G_HIG:
2569                 case GP_STATUS_10G_CX4:
2570                         new_line_speed = SPEED_10000;
2571                         vars->link_status |= LINK_10GTFD;
2572                         break;
2573
2574                 case GP_STATUS_12G_HIG:
2575                         new_line_speed = SPEED_12000;
2576                         vars->link_status |= LINK_12GTFD;
2577                         break;
2578
2579                 case GP_STATUS_12_5G:
2580                         new_line_speed = SPEED_12500;
2581                         vars->link_status |= LINK_12_5GTFD;
2582                         break;
2583
2584                 case GP_STATUS_13G:
2585                         new_line_speed = SPEED_13000;
2586                         vars->link_status |= LINK_13GTFD;
2587                         break;
2588
2589                 case GP_STATUS_15G:
2590                         new_line_speed = SPEED_15000;
2591                         vars->link_status |= LINK_15GTFD;
2592                         break;
2593
2594                 case GP_STATUS_16G:
2595                         new_line_speed = SPEED_16000;
2596                         vars->link_status |= LINK_16GTFD;
2597                         break;
2598
2599                 default:
2600                         DP(NETIF_MSG_LINK,
2601                                   "link speed unsupported gp_status 0x%x\n",
2602                                   gp_status);
2603                         return -EINVAL;
2604                 }
2605
2606                 vars->line_speed = new_line_speed;
2607
2608         } else { /* link_down */
2609                 DP(NETIF_MSG_LINK, "phy link down\n");
2610
2611                 vars->phy_link_up = 0;
2612
2613                 vars->duplex = DUPLEX_FULL;
2614                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
2615                 vars->mac_type = MAC_TYPE_NONE;
2616
2617                 if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
2618                     SINGLE_MEDIA_DIRECT(params)) {
2619                         /* Check signal is detected */
2620                         bnx2x_check_fallback_to_cl37(phy, params);
2621                 }
2622         }
2623
2624         DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %x line_speed %x\n",
2625                  gp_status, vars->phy_link_up, vars->line_speed);
2626         DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
2627                    vars->duplex, vars->flow_ctrl, vars->link_status);
2628         return rc;
2629 }
2630
2631 static void bnx2x_set_gmii_tx_driver(struct link_params *params)
2632 {
2633         struct bnx2x *bp = params->bp;
2634         struct bnx2x_phy *phy = &params->phy[INT_PHY];
2635         u16 lp_up2;
2636         u16 tx_driver;
2637         u16 bank;
2638
2639         /* read precomp */
2640         CL45_RD_OVER_CL22(bp, phy,
2641                               MDIO_REG_BANK_OVER_1G,
2642                               MDIO_OVER_1G_LP_UP2, &lp_up2);
2643
2644         /* bits [10:7] at lp_up2, positioned at [15:12] */
2645         lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
2646                    MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
2647                   MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
2648
2649         if (lp_up2 == 0)
2650                 return;
2651
2652         for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
2653               bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
2654                 CL45_RD_OVER_CL22(bp, phy,
2655                                       bank,
2656                                       MDIO_TX0_TX_DRIVER, &tx_driver);
2657
2658                 /* replace tx_driver bits [15:12] */
2659                 if (lp_up2 !=
2660                     (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
2661                         tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
2662                         tx_driver |= lp_up2;
2663                         CL45_WR_OVER_CL22(bp, phy,
2664                                               bank,
2665                                               MDIO_TX0_TX_DRIVER, tx_driver);
2666                 }
2667         }
2668 }
2669
2670 static u8 bnx2x_emac_program(struct link_params *params,
2671                              struct link_vars *vars)
2672 {
2673         struct bnx2x *bp = params->bp;
2674         u8 port = params->port;
2675         u16 mode = 0;
2676
2677         DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
2678         bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
2679                      EMAC_REG_EMAC_MODE,
2680                      (EMAC_MODE_25G_MODE |
2681                      EMAC_MODE_PORT_MII_10M |
2682                      EMAC_MODE_HALF_DUPLEX));
2683         switch (vars->line_speed) {
2684         case SPEED_10:
2685                 mode |= EMAC_MODE_PORT_MII_10M;
2686                 break;
2687
2688         case SPEED_100:
2689                 mode |= EMAC_MODE_PORT_MII;
2690                 break;
2691
2692         case SPEED_1000:
2693                 mode |= EMAC_MODE_PORT_GMII;
2694                 break;
2695
2696         case SPEED_2500:
2697                 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
2698                 break;
2699
2700         default:
2701                 /* 10G not valid for EMAC */
2702                 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2703                            vars->line_speed);
2704                 return -EINVAL;
2705         }
2706
2707         if (vars->duplex == DUPLEX_HALF)
2708                 mode |= EMAC_MODE_HALF_DUPLEX;
2709         bnx2x_bits_en(bp,
2710                     GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
2711                     mode);
2712
2713         bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
2714         return 0;
2715 }
2716
2717 static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
2718                                   struct link_params *params)
2719 {
2720
2721         u16 bank, i = 0;
2722         struct bnx2x *bp = params->bp;
2723
2724         for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
2725               bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
2726                         CL45_WR_OVER_CL22(bp, phy,
2727                                           bank,
2728                                           MDIO_RX0_RX_EQ_BOOST,
2729                                           phy->rx_preemphasis[i]);
2730         }
2731
2732         for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
2733                       bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
2734                         CL45_WR_OVER_CL22(bp, phy,
2735                                           bank,
2736                                           MDIO_TX0_TX_DRIVER,
2737                                           phy->tx_preemphasis[i]);
2738         }
2739 }
2740
2741 static void bnx2x_init_internal_phy(struct bnx2x_phy *phy,
2742                                     struct link_params *params,
2743                                     struct link_vars *vars)
2744 {
2745         struct bnx2x *bp = params->bp;
2746         u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
2747                           (params->loopback_mode == LOOPBACK_XGXS));
2748         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2749                 if (SINGLE_MEDIA_DIRECT(params) &&
2750                     (params->feature_config_flags &
2751                      FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
2752                         bnx2x_set_preemphasis(phy, params);
2753
2754                 /* forced speed requested? */
2755                 if (vars->line_speed != SPEED_AUTO_NEG ||
2756                     (SINGLE_MEDIA_DIRECT(params) &&
2757                           params->loopback_mode == LOOPBACK_EXT)) {
2758                         DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2759
2760                         /* disable autoneg */
2761                         bnx2x_set_autoneg(phy, params, vars, 0);
2762
2763                         /* program speed and duplex */
2764                         bnx2x_program_serdes(phy, params, vars);
2765
2766                 } else { /* AN_mode */
2767                         DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2768
2769                         /* AN enabled */
2770                         bnx2x_set_brcm_cl37_advertisment(phy, params);
2771
2772                         /* program duplex & pause advertisement (for aneg) */
2773                         bnx2x_set_ieee_aneg_advertisment(phy, params,
2774                                                        vars->ieee_fc);
2775
2776                         /* enable autoneg */
2777                         bnx2x_set_autoneg(phy, params, vars, enable_cl73);
2778
2779                         /* enable and restart AN */
2780                         bnx2x_restart_autoneg(phy, params, enable_cl73);
2781                 }
2782
2783         } else { /* SGMII mode */
2784                 DP(NETIF_MSG_LINK, "SGMII\n");
2785
2786                 bnx2x_initialize_sgmii_process(phy, params, vars);
2787         }
2788 }
2789
2790 static u8 bnx2x_init_serdes(struct bnx2x_phy *phy,
2791                             struct link_params *params,
2792                             struct link_vars *vars)
2793 {
2794         u8 rc;
2795         vars->phy_flags |= PHY_SGMII_FLAG;
2796         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2797         bnx2x_set_aer_mmd_serdes(params->bp, phy);
2798         rc = bnx2x_reset_unicore(params, phy, 1);
2799         /* reset the SerDes and wait for reset bit return low */
2800         if (rc != 0)
2801                 return rc;
2802         bnx2x_set_aer_mmd_serdes(params->bp, phy);
2803
2804         return rc;
2805 }
2806
2807 static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy,
2808                           struct link_params *params,
2809                           struct link_vars *vars)
2810 {
2811         u8 rc;
2812         vars->phy_flags = PHY_XGXS_FLAG;
2813         if ((phy->req_line_speed &&
2814              ((phy->req_line_speed == SPEED_100) ||
2815               (phy->req_line_speed == SPEED_10))) ||
2816             (!phy->req_line_speed &&
2817              (phy->speed_cap_mask >=
2818               PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
2819              (phy->speed_cap_mask <
2820               PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
2821              ))
2822                 vars->phy_flags |= PHY_SGMII_FLAG;
2823         else
2824                 vars->phy_flags &= ~PHY_SGMII_FLAG;
2825
2826         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2827         bnx2x_set_aer_mmd_xgxs(params, phy);
2828         bnx2x_set_master_ln(params, phy);
2829
2830         rc = bnx2x_reset_unicore(params, phy, 0);
2831         /* reset the SerDes and wait for reset bit return low */
2832         if (rc != 0)
2833                 return rc;
2834
2835         bnx2x_set_aer_mmd_xgxs(params, phy);
2836
2837         /* setting the masterLn_def again after the reset */
2838         bnx2x_set_master_ln(params, phy);
2839         bnx2x_set_swap_lanes(params, phy);
2840
2841         return rc;
2842 }
2843
2844 static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
2845                                      struct bnx2x_phy *phy)
2846 {
2847         u16 cnt, ctrl;
2848         /* Wait for soft reset to get cleared upto 1 sec */
2849         for (cnt = 0; cnt < 1000; cnt++) {
2850                 bnx2x_cl45_read(bp, phy,
2851                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl);
2852                 if (!(ctrl & (1<<15)))
2853                         break;
2854                 msleep(1);
2855         }
2856         DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
2857         return cnt;
2858 }
2859
2860 static void bnx2x_link_int_enable(struct link_params *params)
2861 {
2862         u8 port = params->port;
2863         u32 mask;
2864         struct bnx2x *bp = params->bp;
2865
2866         /* setting the status to report on link up
2867            for either XGXS or SerDes */
2868
2869         if (params->switch_cfg == SWITCH_CFG_10G) {
2870                 mask = (NIG_MASK_XGXS0_LINK10G |
2871                         NIG_MASK_XGXS0_LINK_STATUS);
2872                 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
2873                 if (!(SINGLE_MEDIA_DIRECT(params)) &&
2874                         params->phy[INT_PHY].type !=
2875                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
2876                         mask |= NIG_MASK_MI_INT;
2877                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
2878                 }
2879
2880         } else { /* SerDes */
2881                 mask = NIG_MASK_SERDES0_LINK_STATUS;
2882                 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
2883                 if (!(SINGLE_MEDIA_DIRECT(params)) &&
2884                         params->phy[INT_PHY].type !=
2885                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
2886                         mask |= NIG_MASK_MI_INT;
2887                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
2888                 }
2889         }
2890         bnx2x_bits_en(bp,
2891                       NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
2892                       mask);
2893
2894         DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
2895                  (params->switch_cfg == SWITCH_CFG_10G),
2896                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
2897         DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
2898                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
2899                  REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
2900                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
2901         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
2902            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
2903            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
2904 }
2905
2906 static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port,
2907                                      u8 exp_mi_int)
2908 {
2909         u32 latch_status = 0;
2910
2911         /**
2912          * Disable the MI INT ( external phy int ) by writing 1 to the
2913          * status register. Link down indication is high-active-signal,
2914          * so in this case we need to write the status to clear the XOR
2915          */
2916         /* Read Latched signals */
2917         latch_status = REG_RD(bp,
2918                                     NIG_REG_LATCH_STATUS_0 + port*8);
2919         DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status);
2920         /* Handle only those with latched-signal=up.*/
2921         if (exp_mi_int)
2922                 bnx2x_bits_en(bp,
2923                               NIG_REG_STATUS_INTERRUPT_PORT0
2924                               + port*4,
2925                               NIG_STATUS_EMAC0_MI_INT);
2926         else
2927                 bnx2x_bits_dis(bp,
2928                                NIG_REG_STATUS_INTERRUPT_PORT0
2929                                + port*4,
2930                                NIG_STATUS_EMAC0_MI_INT);
2931
2932         if (latch_status & 1) {
2933
2934                 /* For all latched-signal=up : Re-Arm Latch signals */
2935                 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
2936                              (latch_status & 0xfffe) | (latch_status & 1));
2937         }
2938         /* For all latched-signal=up,Write original_signal to status */
2939 }
2940
2941 static void bnx2x_link_int_ack(struct link_params *params,
2942                              struct link_vars *vars, u8 is_10g)
2943 {
2944         struct bnx2x *bp = params->bp;
2945         u8 port = params->port;
2946
2947         /* first reset all status
2948          * we assume only one line will be change at a time */
2949         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2950                      (NIG_STATUS_XGXS0_LINK10G |
2951                       NIG_STATUS_XGXS0_LINK_STATUS |
2952                       NIG_STATUS_SERDES0_LINK_STATUS));
2953         if (vars->phy_link_up) {
2954                 if (is_10g) {
2955                         /* Disable the 10G link interrupt
2956                          * by writing 1 to the status register
2957                          */
2958                         DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
2959                         bnx2x_bits_en(bp,
2960                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2961                                       NIG_STATUS_XGXS0_LINK10G);
2962
2963                 } else if (params->switch_cfg == SWITCH_CFG_10G) {
2964                         /* Disable the link interrupt
2965                          * by writing 1 to the relevant lane
2966                          * in the status register
2967                          */
2968                         u32 ser_lane = ((params->lane_config &
2969                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
2970                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
2971
2972                         DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
2973                                  vars->line_speed);
2974                         bnx2x_bits_en(bp,
2975                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2976                                       ((1 << ser_lane) <<
2977                                        NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
2978
2979                 } else { /* SerDes */
2980                         DP(NETIF_MSG_LINK, "SerDes phy link up\n");
2981                         /* Disable the link interrupt
2982                          * by writing 1 to the status register
2983                          */
2984                         bnx2x_bits_en(bp,
2985                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2986                                       NIG_STATUS_SERDES0_LINK_STATUS);
2987                 }
2988
2989         }
2990 }
2991
2992 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len)
2993 {
2994         u8 *str_ptr = str;
2995         u32 mask = 0xf0000000;
2996         u8 shift = 8*4;
2997         u8 digit;
2998         u8 remove_leading_zeros = 1;
2999         if (*len < 10) {
3000                 /* Need more than 10chars for this format */
3001                 *str_ptr = '\0';
3002                 (*len)--;
3003                 return -EINVAL;
3004         }
3005         while (shift > 0) {
3006
3007                 shift -= 4;
3008                 digit = ((num & mask) >> shift);
3009                 if (digit == 0 && remove_leading_zeros) {
3010                         mask = mask >> 4;
3011                         continue;
3012                 } else if (digit < 0xa)
3013                         *str_ptr = digit + '0';
3014                 else
3015                         *str_ptr = digit - 0xa + 'a';
3016                 remove_leading_zeros = 0;
3017                 str_ptr++;
3018                 (*len)--;
3019                 mask = mask >> 4;
3020                 if (shift == 4*4) {
3021                         *str_ptr = '.';
3022                         str_ptr++;
3023                         (*len)--;
3024                         remove_leading_zeros = 1;
3025                 }
3026         }
3027         return 0;
3028 }
3029
3030
3031 static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
3032 {
3033         str[0] = '\0';
3034         (*len)--;
3035         return 0;
3036 }
3037
3038 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3039                               u8 *version, u16 len)
3040 {
3041         struct bnx2x *bp;
3042         u32 spirom_ver = 0;
3043         u8 status = 0;
3044         u8 *ver_p = version;
3045         u16 remain_len = len;
3046         if (version == NULL || params == NULL)
3047                 return -EINVAL;
3048         bp = params->bp;
3049
3050         /* Extract first external phy*/
3051         version[0] = '\0';
3052         spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
3053
3054         if (params->phy[EXT_PHY1].format_fw_ver) {
3055                 status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
3056                                                               ver_p,
3057                                                               &remain_len);
3058                 ver_p += (len - remain_len);
3059         }
3060         if ((params->num_phys == MAX_PHYS) &&
3061             (params->phy[EXT_PHY2].ver_addr != 0)) {
3062                 spirom_ver = REG_RD(bp,
3063                                           params->phy[EXT_PHY2].ver_addr);
3064                 if (params->phy[EXT_PHY2].format_fw_ver) {
3065                         *ver_p = '/';
3066                         ver_p++;
3067                         remain_len--;
3068                         status |= params->phy[EXT_PHY2].format_fw_ver(
3069                                 spirom_ver,
3070                                 ver_p,
3071                                 &remain_len);
3072                         ver_p = version + (len - remain_len);
3073                 }
3074         }
3075         *ver_p = '\0';
3076         return status;
3077 }
3078
3079 static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
3080                                     struct link_params *params)
3081 {
3082         u8 port = params->port;
3083         struct bnx2x *bp = params->bp;
3084
3085         if (phy->req_line_speed != SPEED_1000) {
3086                 u32 md_devad;
3087
3088                 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
3089
3090                 /* change the uni_phy_addr in the nig */
3091                 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
3092                                           port*0x18));
3093
3094                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
3095
3096                 bnx2x_cl45_write(bp, phy,
3097                                5,
3098                                (MDIO_REG_BANK_AER_BLOCK +
3099                                 (MDIO_AER_BLOCK_AER_REG & 0xf)),
3100                                0x2800);
3101
3102                 bnx2x_cl45_write(bp, phy,
3103                                5,
3104                                (MDIO_REG_BANK_CL73_IEEEB0 +
3105                                 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
3106                                0x6041);
3107                 msleep(200);
3108                 /* set aer mmd back */
3109                 bnx2x_set_aer_mmd_xgxs(params, phy);
3110
3111                 /* and md_devad */
3112                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
3113                             md_devad);
3114
3115         } else {
3116                 u16 mii_ctrl;
3117                 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
3118                 bnx2x_cl45_read(bp, phy, 5,
3119                                 (MDIO_REG_BANK_COMBO_IEEE0 +
3120                                 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
3121                                 &mii_ctrl);
3122                 bnx2x_cl45_write(bp, phy, 5,
3123                                  (MDIO_REG_BANK_COMBO_IEEE0 +
3124                                  (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
3125                                  mii_ctrl |
3126                                  MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
3127         }
3128 }
3129
3130 u8 bnx2x_set_led(struct link_params *params,
3131                  struct link_vars *vars, u8 mode, u32 speed)
3132 {
3133         u8 port = params->port;
3134         u16 hw_led_mode = params->hw_led_mode;
3135         u8 rc = 0, phy_idx;
3136         u32 tmp;
3137         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3138         struct bnx2x *bp = params->bp;
3139         DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
3140         DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
3141                  speed, hw_led_mode);
3142         /* In case */
3143         for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) {
3144                 if (params->phy[phy_idx].set_link_led) {
3145                         params->phy[phy_idx].set_link_led(
3146                                 &params->phy[phy_idx], params, mode);
3147                 }
3148         }
3149
3150         switch (mode) {
3151         case LED_MODE_FRONT_PANEL_OFF:
3152         case LED_MODE_OFF:
3153                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
3154                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
3155                            SHARED_HW_CFG_LED_MAC1);
3156
3157                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3158                 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
3159                 break;
3160
3161         case LED_MODE_OPER:
3162                 /**
3163                  * For all other phys, OPER mode is same as ON, so in case
3164                  * link is down, do nothing
3165                  **/
3166                 if (!vars->link_up)
3167                         break;
3168         case LED_MODE_ON:
3169                 if (params->phy[EXT_PHY1].type ==
3170                     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727 &&
3171                     CHIP_IS_E2(bp) && params->num_phys == 2) {
3172                         /**
3173                         * This is a work-around for E2+8727 Configurations
3174                         */
3175                         if (mode == LED_MODE_ON ||
3176                                 speed == SPEED_10000){
3177                                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
3178                                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
3179
3180                                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3181                                 EMAC_WR(bp, EMAC_REG_EMAC_LED,
3182                                         (tmp | EMAC_LED_OVERRIDE));
3183                                 return rc;
3184                         }
3185                 } else if (SINGLE_MEDIA_DIRECT(params)) {
3186                         /**
3187                         * This is a work-around for HW issue found when link
3188                         * is up in CL73
3189                         */
3190                         REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
3191                         REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
3192                 } else {
3193                         REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
3194                                    hw_led_mode);
3195                 }
3196
3197                 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
3198                            port*4, 0);
3199                 /* Set blinking rate to ~15.9Hz */
3200                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
3201                            LED_BLINK_RATE_VAL);
3202                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
3203                            port*4, 1);
3204                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3205                 EMAC_WR(bp, EMAC_REG_EMAC_LED,
3206                             (tmp & (~EMAC_LED_OVERRIDE)));
3207
3208                 if (CHIP_IS_E1(bp) &&
3209                     ((speed == SPEED_2500) ||
3210                      (speed == SPEED_1000) ||
3211                      (speed == SPEED_100) ||
3212                      (speed == SPEED_10))) {
3213                         /* On Everest 1 Ax chip versions for speeds less than
3214                         10G LED scheme is different */
3215                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3216                                    + port*4, 1);
3217                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
3218                                    port*4, 0);
3219                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
3220                                    port*4, 1);
3221                 }
3222                 break;
3223
3224         default:
3225                 rc = -EINVAL;
3226                 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
3227                          mode);
3228                 break;
3229         }
3230         return rc;
3231
3232 }
3233
3234 /**
3235  * This function comes to reflect the actual link state read DIRECTLY from the
3236  * HW
3237  */
3238 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars,
3239                    u8 is_serdes)
3240 {
3241         struct bnx2x *bp = params->bp;
3242         u16 gp_status = 0, phy_index = 0;
3243         u8 ext_phy_link_up = 0, serdes_phy_type;
3244         struct link_vars temp_vars;
3245
3246         CL45_RD_OVER_CL22(bp, &params->phy[INT_PHY],
3247                               MDIO_REG_BANK_GP_STATUS,
3248                               MDIO_GP_STATUS_TOP_AN_STATUS1,
3249                               &gp_status);
3250         /* link is up only if both local phy and external phy are up */
3251         if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
3252                 return -ESRCH;
3253
3254         switch (params->num_phys) {
3255         case 1:
3256                 /* No external PHY */
3257                 return 0;
3258         case 2:
3259                 ext_phy_link_up = params->phy[EXT_PHY1].read_status(
3260                         &params->phy[EXT_PHY1],
3261                         params, &temp_vars);
3262                 break;
3263         case 3: /* Dual Media */
3264                 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3265                       phy_index++) {
3266                         serdes_phy_type = ((params->phy[phy_index].media_type ==
3267                                             ETH_PHY_SFP_FIBER) ||
3268                                            (params->phy[phy_index].media_type ==
3269                                             ETH_PHY_XFP_FIBER));
3270
3271                         if (is_serdes != serdes_phy_type)
3272                                 continue;
3273                         if (params->phy[phy_index].read_status) {
3274                                 ext_phy_link_up |=
3275                                         params->phy[phy_index].read_status(
3276                                                 &params->phy[phy_index],
3277                                                 params, &temp_vars);
3278                         }
3279                 }
3280                 break;
3281         }
3282         if (ext_phy_link_up)
3283                 return 0;
3284         return -ESRCH;
3285 }
3286
3287 static u8 bnx2x_link_initialize(struct link_params *params,
3288                                 struct link_vars *vars)
3289 {
3290         u8 rc = 0;
3291         u8 phy_index, non_ext_phy;
3292         struct bnx2x *bp = params->bp;
3293         /**
3294         * In case of external phy existence, the line speed would be the
3295         * line speed linked up by the external phy. In case it is direct
3296         * only, then the line_speed during initialization will be
3297         * equal to the req_line_speed
3298         */
3299         vars->line_speed = params->phy[INT_PHY].req_line_speed;
3300
3301         /**
3302          * Initialize the internal phy in case this is a direct board
3303          * (no external phys), or this board has external phy which requires
3304          * to first.
3305          */
3306
3307         if (params->phy[INT_PHY].config_init)
3308                 params->phy[INT_PHY].config_init(
3309                         &params->phy[INT_PHY],
3310                         params, vars);
3311
3312         /* init ext phy and enable link state int */
3313         non_ext_phy = (SINGLE_MEDIA_DIRECT(params) ||
3314                        (params->loopback_mode == LOOPBACK_XGXS));
3315
3316         if (non_ext_phy ||
3317             (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) ||
3318             (params->loopback_mode == LOOPBACK_EXT_PHY)) {
3319                 struct bnx2x_phy *phy = &params->phy[INT_PHY];
3320                 if (vars->line_speed == SPEED_AUTO_NEG)
3321                         bnx2x_set_parallel_detection(phy, params);
3322                 bnx2x_init_internal_phy(phy, params, vars);
3323         }
3324
3325         /* Init external phy*/
3326         if (!non_ext_phy)
3327                 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3328                       phy_index++) {
3329                         /**
3330                          * No need to initialize second phy in case of first
3331                          * phy only selection. In case of second phy, we do
3332                          * need to initialize the first phy, since they are
3333                          * connected.
3334                          **/
3335                         if (phy_index == EXT_PHY2 &&
3336                             (bnx2x_phy_selection(params) ==
3337                              PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
3338                                 DP(NETIF_MSG_LINK, "Not initializing"
3339                                                    "second phy\n");
3340                                 continue;
3341                         }
3342                         params->phy[phy_index].config_init(
3343                                 &params->phy[phy_index],
3344                                 params, vars);
3345                 }
3346
3347         /* Reset the interrupt indication after phy was initialized */
3348         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
3349                        params->port*4,
3350                        (NIG_STATUS_XGXS0_LINK10G |
3351                         NIG_STATUS_XGXS0_LINK_STATUS |
3352                         NIG_STATUS_SERDES0_LINK_STATUS |
3353                         NIG_MASK_MI_INT));
3354         return rc;
3355 }
3356
3357 static void bnx2x_int_link_reset(struct bnx2x_phy *phy,
3358                                  struct link_params *params)
3359 {
3360         /* reset the SerDes/XGXS */
3361         REG_WR(params->bp, GRCBASE_MISC +
3362                      MISC_REGISTERS_RESET_REG_3_CLEAR,
3363                      (0x1ff << (params->port*16)));
3364 }
3365
3366 static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
3367                                         struct link_params *params)
3368 {
3369         struct bnx2x *bp = params->bp;
3370         u8 gpio_port;
3371         /* HW reset */
3372         if (CHIP_IS_E2(bp))
3373                 gpio_port = BP_PATH(bp);
3374         else
3375                 gpio_port = params->port;
3376         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3377                             MISC_REGISTERS_GPIO_OUTPUT_LOW,
3378                             gpio_port);
3379         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3380                             MISC_REGISTERS_GPIO_OUTPUT_LOW,
3381                             gpio_port);
3382         DP(NETIF_MSG_LINK, "reset external PHY\n");
3383 }
3384
3385 static u8 bnx2x_update_link_down(struct link_params *params,
3386                                struct link_vars *vars)
3387 {
3388         struct bnx2x *bp = params->bp;
3389         u8 port = params->port;
3390
3391         DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
3392         bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
3393
3394         /* indicate no mac active */
3395         vars->mac_type = MAC_TYPE_NONE;
3396
3397         /* update shared memory */
3398         vars->link_status = 0;
3399         vars->line_speed = 0;
3400         bnx2x_update_mng(params, vars->link_status);
3401
3402         /* activate nig drain */
3403         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
3404
3405         /* disable emac */
3406         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
3407
3408         msleep(10);
3409
3410         /* reset BigMac */
3411         bnx2x_bmac_rx_disable(bp, params->port);
3412         REG_WR(bp, GRCBASE_MISC +
3413                    MISC_REGISTERS_RESET_REG_2_CLEAR,
3414                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
3415         return 0;
3416 }
3417
3418 static u8 bnx2x_update_link_up(struct link_params *params,
3419                              struct link_vars *vars,
3420                              u8 link_10g)
3421 {
3422         struct bnx2x *bp = params->bp;
3423         u8 port = params->port;
3424         u8 rc = 0;
3425
3426         vars->link_status |= LINK_STATUS_LINK_UP;
3427
3428         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
3429                 vars->link_status |=
3430                         LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
3431
3432         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
3433                 vars->link_status |=
3434                         LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
3435
3436         if (link_10g) {
3437                 bnx2x_bmac_enable(params, vars, 0);
3438                 bnx2x_set_led(params, vars,
3439                               LED_MODE_OPER, SPEED_10000);
3440         } else {
3441                 rc = bnx2x_emac_program(params, vars);
3442
3443                 bnx2x_emac_enable(params, vars, 0);
3444
3445                 /* AN complete? */
3446                 if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
3447                     && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
3448                     SINGLE_MEDIA_DIRECT(params))
3449                         bnx2x_set_gmii_tx_driver(params);
3450         }
3451
3452         /* PBF - link up */
3453         if (!(CHIP_IS_E2(bp)))
3454                 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
3455                                        vars->line_speed);
3456
3457         /* disable drain */
3458         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
3459
3460         /* update shared memory */
3461         bnx2x_update_mng(params, vars->link_status);
3462         msleep(20);
3463         return rc;
3464 }
3465 /**
3466  * The bnx2x_link_update function should be called upon link
3467  * interrupt.
3468  * Link is considered up as follows:
3469  * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
3470  *   to be up
3471  * - SINGLE_MEDIA - The link between the 577xx and the external
3472  *   phy (XGXS) need to up as well as the external link of the
3473  *   phy (PHY_EXT1)
3474  * - DUAL_MEDIA - The link between the 577xx and the first
3475  *   external phy needs to be up, and at least one of the 2
3476  *   external phy link must be up.
3477  */
3478 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
3479 {
3480         struct bnx2x *bp = params->bp;
3481         struct link_vars phy_vars[MAX_PHYS];
3482         u8 port = params->port;
3483         u8 link_10g, phy_index;
3484         u8 ext_phy_link_up = 0, cur_link_up, rc = 0;
3485         u8 is_mi_int = 0;
3486         u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
3487         u8 active_external_phy = INT_PHY;
3488         vars->link_status = 0;
3489         for (phy_index = INT_PHY; phy_index < params->num_phys;
3490               phy_index++) {
3491                 phy_vars[phy_index].flow_ctrl = 0;
3492                 phy_vars[phy_index].link_status = 0;
3493                 phy_vars[phy_index].line_speed = 0;
3494                 phy_vars[phy_index].duplex = DUPLEX_FULL;
3495                 phy_vars[phy_index].phy_link_up = 0;
3496                 phy_vars[phy_index].link_up = 0;
3497         }
3498
3499         DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
3500                  port, (vars->phy_flags & PHY_XGXS_FLAG),
3501                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
3502
3503         is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
3504                                     port*0x18) > 0);
3505         DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
3506                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
3507                  is_mi_int,
3508                  REG_RD(bp,
3509                             NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
3510
3511         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
3512           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
3513           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
3514
3515         /* disable emac */
3516         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
3517
3518         /**
3519         * Step 1:
3520         * Check external link change only for external phys, and apply
3521         * priority selection between them in case the link on both phys
3522         * is up. Note that the instead of the common vars, a temporary
3523         * vars argument is used since each phy may have different link/
3524         * speed/duplex result
3525         */
3526         for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3527               phy_index++) {
3528                 struct bnx2x_phy *phy = &params->phy[phy_index];
3529                 if (!phy->read_status)
3530                         continue;
3531                 /* Read link status and params of this ext phy */
3532                 cur_link_up = phy->read_status(phy, params,
3533                                                &phy_vars[phy_index]);
3534                 if (cur_link_up) {
3535                         DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
3536                                    phy_index);
3537                 } else {
3538                         DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
3539                                    phy_index);
3540                         continue;
3541                 }
3542
3543                 if (!ext_phy_link_up) {
3544                         ext_phy_link_up = 1;
3545                         active_external_phy = phy_index;
3546                 } else {
3547                         switch (bnx2x_phy_selection(params)) {
3548                         case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
3549                         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
3550                         /**
3551                          * In this option, the first PHY makes sure to pass the
3552                          * traffic through itself only.
3553                          * Its not clear how to reset the link on the second phy
3554                          **/
3555                                 active_external_phy = EXT_PHY1;
3556                                 break;
3557                         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
3558                         /**
3559                          * In this option, the first PHY makes sure to pass the
3560                          * traffic through the second PHY.
3561                          **/
3562                                 active_external_phy = EXT_PHY2;
3563                                 break;
3564                         default:
3565                         /**
3566                          * Link indication on both PHYs with the following cases
3567                          * is invalid:
3568                          * - FIRST_PHY means that second phy wasn't initialized,
3569                          * hence its link is expected to be down
3570                          * - SECOND_PHY means that first phy should not be able
3571                          * to link up by itself (using configuration)
3572                          * - DEFAULT should be overriden during initialiazation
3573                          **/
3574                                 DP(NETIF_MSG_LINK, "Invalid link indication"
3575                                            "mpc=0x%x. DISABLING LINK !!!\n",
3576                                            params->multi_phy_config);
3577                                 ext_phy_link_up = 0;
3578                                 break;
3579                         }
3580                 }
3581         }
3582         prev_line_speed = vars->line_speed;
3583         /**
3584         * Step 2:
3585         * Read the status of the internal phy. In case of
3586         * DIRECT_SINGLE_MEDIA board, this link is the external link,
3587         * otherwise this is the link between the 577xx and the first
3588         * external phy
3589         */
3590         if (params->phy[INT_PHY].read_status)
3591                 params->phy[INT_PHY].read_status(
3592                         &params->phy[INT_PHY],
3593                         params, vars);
3594         /**
3595          * The INT_PHY flow control reside in the vars. This include the
3596          * case where the speed or flow control are not set to AUTO.
3597          * Otherwise, the active external phy flow control result is set
3598          * to the vars. The ext_phy_line_speed is needed to check if the
3599          * speed is different between the internal phy and external phy.
3600          * This case may be result of intermediate link speed change.
3601          */
3602         if (active_external_phy > INT_PHY) {
3603                 vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
3604                 /**
3605                  * Link speed is taken from the XGXS. AN and FC result from
3606                  * the external phy.
3607                  */
3608                 vars->link_status |= phy_vars[active_external_phy].link_status;
3609
3610                 /**
3611                  * if active_external_phy is first PHY and link is up - disable
3612                  * disable TX on second external PHY
3613                  */
3614                 if (active_external_phy == EXT_PHY1) {
3615                         if (params->phy[EXT_PHY2].phy_specific_func) {
3616                                 DP(NETIF_MSG_LINK, "Disabling TX on"
3617                                                    " EXT_PHY2\n");
3618                                 params->phy[EXT_PHY2].phy_specific_func(
3619                                         &params->phy[EXT_PHY2],
3620                                         params, DISABLE_TX);
3621                         }
3622                 }
3623
3624                 ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
3625                 vars->duplex = phy_vars[active_external_phy].duplex;
3626                 if (params->phy[active_external_phy].supported &
3627                     SUPPORTED_FIBRE)
3628                         vars->link_status |= LINK_STATUS_SERDES_LINK;
3629                 DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
3630                            active_external_phy);
3631         }
3632
3633         for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3634               phy_index++) {
3635                 if (params->phy[phy_index].flags &
3636                     FLAGS_REARM_LATCH_SIGNAL) {
3637                         bnx2x_rearm_latch_signal(bp, port,
3638                                                  phy_index ==
3639                                                  active_external_phy);
3640                         break;
3641                 }
3642         }
3643         DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
3644                    " ext_phy_line_speed = %d\n", vars->flow_ctrl,
3645                    vars->link_status, ext_phy_line_speed);
3646         /**
3647          * Upon link speed change set the NIG into drain mode. Comes to
3648          * deals with possible FIFO glitch due to clk change when speed
3649          * is decreased without link down indicator
3650          */
3651
3652         if (vars->phy_link_up) {
3653                 if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
3654                     (ext_phy_line_speed != vars->line_speed)) {
3655                         DP(NETIF_MSG_LINK, "Internal link speed %d is"
3656                                    " different than the external"
3657                                    " link speed %d\n", vars->line_speed,
3658                                    ext_phy_line_speed);
3659                         vars->phy_link_up = 0;
3660                 } else if (prev_line_speed != vars->line_speed) {
3661                         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3662                                      + params->port*4, 0);
3663                         msleep(1);
3664                 }
3665         }
3666
3667         /* anything 10 and over uses the bmac */
3668         link_10g = ((vars->line_speed == SPEED_10000) ||
3669                     (vars->line_speed == SPEED_12000) ||
3670                     (vars->line_speed == SPEED_12500) ||
3671                     (vars->line_speed == SPEED_13000) ||
3672                     (vars->line_speed == SPEED_15000) ||
3673                     (vars->line_speed == SPEED_16000));
3674
3675         bnx2x_link_int_ack(params, vars, link_10g);
3676
3677         /**
3678         * In case external phy link is up, and internal link is down
3679         * (not initialized yet probably after link initialization, it
3680         * needs to be initialized.
3681         * Note that after link down-up as result of cable plug, the xgxs
3682         * link would probably become up again without the need
3683         * initialize it
3684         */
3685         if (!(SINGLE_MEDIA_DIRECT(params))) {
3686                 DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
3687                            " init_preceding = %d\n", ext_phy_link_up,
3688                            vars->phy_link_up,
3689                            params->phy[EXT_PHY1].flags &
3690                            FLAGS_INIT_XGXS_FIRST);
3691                 if (!(params->phy[EXT_PHY1].flags &
3692                       FLAGS_INIT_XGXS_FIRST)
3693                     && ext_phy_link_up && !vars->phy_link_up) {
3694                         vars->line_speed = ext_phy_line_speed;
3695                         if (vars->line_speed < SPEED_1000)
3696                                 vars->phy_flags |= PHY_SGMII_FLAG;
3697                         else
3698                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
3699                         bnx2x_init_internal_phy(&params->phy[INT_PHY],
3700                                                 params,
3701                                                 vars);
3702                 }
3703         }
3704         /**
3705          *  Link is up only if both local phy and external phy (in case of
3706          *  non-direct board) are up
3707          */
3708         vars->link_up = (vars->phy_link_up &&
3709                          (ext_phy_link_up ||
3710                           SINGLE_MEDIA_DIRECT(params)));
3711
3712         if (vars->link_up)
3713                 rc = bnx2x_update_link_up(params, vars, link_10g);
3714         else
3715                 rc = bnx2x_update_link_down(params, vars);
3716
3717         return rc;
3718 }
3719
3720
3721 /*****************************************************************************/
3722 /*                          External Phy section                             */
3723 /*****************************************************************************/
3724 void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
3725 {
3726         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3727                             MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
3728         msleep(1);
3729         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3730                             MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
3731 }
3732
3733 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
3734                                       u32 spirom_ver, u32 ver_addr)
3735 {
3736         DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
3737                  (u16)(spirom_ver>>16), (u16)spirom_ver, port);
3738
3739         if (ver_addr)
3740                 REG_WR(bp, ver_addr, spirom_ver);
3741 }
3742
3743 static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp,
3744                                       struct bnx2x_phy *phy,
3745                                       u8 port)
3746 {
3747         u16 fw_ver1, fw_ver2;
3748
3749         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
3750                       MDIO_PMA_REG_ROM_VER1, &fw_ver1);
3751         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
3752                       MDIO_PMA_REG_ROM_VER2, &fw_ver2);
3753         bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2),
3754                                   phy->ver_addr);
3755 }
3756
3757 static void bnx2x_ext_phy_set_pause(struct link_params *params,
3758                                     struct bnx2x_phy *phy,
3759                                     struct link_vars *vars)
3760 {
3761         u16 val;
3762         struct bnx2x *bp = params->bp;
3763         /* read modify write pause advertizing */
3764         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
3765
3766         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3767
3768         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3769         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
3770         if ((vars->ieee_fc &
3771             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3772             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3773                 val |=  MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3774         }
3775         if ((vars->ieee_fc &
3776             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3777             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3778                 val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
3779         }
3780         DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
3781         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
3782 }
3783
3784 static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
3785                                    struct link_params *params,
3786                                    struct link_vars *vars)
3787 {
3788         struct bnx2x *bp = params->bp;
3789         u16 ld_pause;           /* local */
3790         u16 lp_pause;           /* link partner */
3791         u16 pause_result;
3792         u8 ret = 0;
3793         /* read twice */
3794
3795         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3796
3797         if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
3798                 vars->flow_ctrl = phy->req_flow_ctrl;
3799         else if (phy->req_line_speed != SPEED_AUTO_NEG)
3800                 vars->flow_ctrl = params->req_fc_auto_adv;
3801         else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
3802                 ret = 1;
3803                 bnx2x_cl45_read(bp, phy,
3804                               MDIO_AN_DEVAD,
3805                               MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3806                 bnx2x_cl45_read(bp, phy,
3807                               MDIO_AN_DEVAD,
3808                               MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3809                 pause_result = (ld_pause &
3810                                 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
3811                 pause_result |= (lp_pause &
3812                                  MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
3813                 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
3814                    pause_result);
3815                 bnx2x_pause_resolve(vars, pause_result);
3816         }
3817         return ret;
3818 }
3819
3820 static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp,
3821                                        struct bnx2x_phy *phy,
3822                                        struct link_vars *vars)
3823 {
3824         u16 val;
3825         bnx2x_cl45_read(bp, phy,
3826                         MDIO_AN_DEVAD,
3827                         MDIO_AN_REG_STATUS, &val);
3828         bnx2x_cl45_read(bp, phy,
3829                         MDIO_AN_DEVAD,
3830                         MDIO_AN_REG_STATUS, &val);
3831         if (val & (1<<5))
3832                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
3833         if ((val & (1<<0)) == 0)
3834                 vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
3835 }
3836
3837 /******************************************************************/
3838 /*              common BCM8073/BCM8727 PHY SECTION                */
3839 /******************************************************************/
3840 static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
3841                                   struct link_params *params,
3842                                   struct link_vars *vars)
3843 {
3844         struct bnx2x *bp = params->bp;
3845         if (phy->req_line_speed == SPEED_10 ||
3846             phy->req_line_speed == SPEED_100) {
3847                 vars->flow_ctrl = phy->req_flow_ctrl;
3848                 return;
3849         }
3850
3851         if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
3852             (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) {
3853                 u16 pause_result;
3854                 u16 ld_pause;           /* local */
3855                 u16 lp_pause;           /* link partner */
3856                 bnx2x_cl45_read(bp, phy,
3857                                 MDIO_AN_DEVAD,
3858                                 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
3859
3860                 bnx2x_cl45_read(bp, phy,
3861                                 MDIO_AN_DEVAD,
3862                                 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
3863                 pause_result = (ld_pause &
3864                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
3865                 pause_result |= (lp_pause &
3866                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
3867
3868                 bnx2x_pause_resolve(vars, pause_result);
3869                 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
3870                            pause_result);
3871         }
3872 }
3873
3874 static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
3875                                               struct bnx2x_phy *phy,
3876                                               u8 port)
3877 {
3878         /* Boot port from external ROM  */
3879         /* EDC grst */
3880         bnx2x_cl45_write(bp, phy,
3881                        MDIO_PMA_DEVAD,
3882                        MDIO_PMA_REG_GEN_CTRL,
3883                        0x0001);
3884
3885         /* ucode reboot and rst */
3886         bnx2x_cl45_write(bp, phy,
3887                        MDIO_PMA_DEVAD,
3888                        MDIO_PMA_REG_GEN_CTRL,
3889                        0x008c);
3890
3891         bnx2x_cl45_write(bp, phy,
3892                        MDIO_PMA_DEVAD,
3893                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
3894
3895         /* Reset internal microprocessor */
3896         bnx2x_cl45_write(bp, phy,
3897                        MDIO_PMA_DEVAD,
3898                        MDIO_PMA_REG_GEN_CTRL,
3899                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
3900
3901         /* Release srst bit */
3902         bnx2x_cl45_write(bp, phy,
3903                        MDIO_PMA_DEVAD,
3904                        MDIO_PMA_REG_GEN_CTRL,
3905                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
3906
3907         /* wait for 120ms for code download via SPI port */
3908         msleep(120);
3909
3910         /* Clear ser_boot_ctl bit */
3911         bnx2x_cl45_write(bp, phy,
3912                        MDIO_PMA_DEVAD,
3913                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
3914         bnx2x_save_bcm_spirom_ver(bp, phy, port);
3915 }
3916
3917 static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp,
3918                                                struct bnx2x_phy *phy)
3919 {
3920         u16 val;
3921         bnx2x_cl45_read(bp, phy,
3922                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val);
3923
3924         if (val == 0) {
3925                 /* Mustn't set low power mode in 8073 A0 */
3926                 return;
3927         }
3928
3929         /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
3930         bnx2x_cl45_read(bp, phy,
3931                         MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val);
3932         val &= ~(1<<13);
3933         bnx2x_cl45_write(bp, phy,
3934                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
3935
3936         /* PLL controls */
3937         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805E, 0x1077);
3938         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805D, 0x0000);
3939         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805C, 0x030B);
3940         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805B, 0x1240);
3941         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805A, 0x2490);
3942
3943         /* Tx Controls */
3944         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A7, 0x0C74);
3945         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A6, 0x9041);
3946         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A5, 0x4640);
3947
3948         /* Rx Controls */
3949         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FE, 0x01C4);
3950         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FD, 0x9249);
3951         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FC, 0x2015);
3952
3953         /* Enable PLL sequencer  (use read-modify-write to set bit 13) */
3954         bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val);
3955         val |= (1<<13);
3956         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
3957 }
3958
3959 /******************************************************************/
3960 /*                      BCM8073 PHY SECTION                       */
3961 /******************************************************************/
3962 static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
3963 {
3964         /* This is only required for 8073A1, version 102 only */
3965         u16 val;
3966
3967         /* Read 8073 HW revision*/
3968         bnx2x_cl45_read(bp, phy,
3969                       MDIO_PMA_DEVAD,
3970                       MDIO_PMA_REG_8073_CHIP_REV, &val);
3971
3972         if (val != 1) {
3973                 /* No need to workaround in 8073 A1 */
3974                 return 0;
3975         }
3976
3977         bnx2x_cl45_read(bp, phy,
3978                       MDIO_PMA_DEVAD,
3979                       MDIO_PMA_REG_ROM_VER2, &val);
3980
3981         /* SNR should be applied only for version 0x102 */
3982         if (val != 0x102)
3983                 return 0;
3984
3985         return 1;
3986 }
3987
3988 static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
3989 {
3990         u16 val, cnt, cnt1 ;
3991
3992         bnx2x_cl45_read(bp, phy,
3993                       MDIO_PMA_DEVAD,
3994                       MDIO_PMA_REG_8073_CHIP_REV, &val);
3995
3996         if (val > 0) {
3997                 /* No need to workaround in 8073 A1 */
3998                 return 0;
3999         }
4000         /* XAUI workaround in 8073 A0: */
4001
4002         /* After loading the boot ROM and restarting Autoneg,
4003         poll Dev1, Reg $C820: */
4004
4005         for (cnt = 0; cnt < 1000; cnt++) {
4006                 bnx2x_cl45_read(bp, phy,
4007                               MDIO_PMA_DEVAD,
4008                               MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
4009                               &val);
4010                   /* If bit [14] = 0 or bit [13] = 0, continue on with
4011                    system initialization (XAUI work-around not required,
4012                     as these bits indicate 2.5G or 1G link up). */
4013                 if (!(val & (1<<14)) || !(val & (1<<13))) {
4014                         DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
4015                         return 0;
4016                 } else if (!(val & (1<<15))) {
4017                         DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
4018                          /* If bit 15 is 0, then poll Dev1, Reg $C841 until
4019                           it's MSB (bit 15) goes to 1 (indicating that the
4020                           XAUI workaround has completed),
4021                           then continue on with system initialization.*/
4022                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
4023                                 bnx2x_cl45_read(bp, phy,
4024                                         MDIO_PMA_DEVAD,
4025                                         MDIO_PMA_REG_8073_XAUI_WA, &val);
4026                                 if (val & (1<<15)) {
4027                                         DP(NETIF_MSG_LINK,
4028                                           "XAUI workaround has completed\n");
4029                                         return 0;
4030                                  }
4031                                  msleep(3);
4032                         }
4033                         break;
4034                 }
4035                 msleep(3);
4036         }
4037         DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
4038         return -EINVAL;
4039 }
4040
4041 static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy)
4042 {
4043         /* Force KR or KX */
4044         bnx2x_cl45_write(bp, phy,
4045                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
4046         bnx2x_cl45_write(bp, phy,
4047                          MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
4048         bnx2x_cl45_write(bp, phy,
4049                          MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
4050         bnx2x_cl45_write(bp, phy,
4051                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
4052 }
4053
4054 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
4055                                       struct bnx2x_phy *phy,
4056                                       struct link_vars *vars)
4057 {
4058         u16 cl37_val;
4059         struct bnx2x *bp = params->bp;
4060         bnx2x_cl45_read(bp, phy,
4061                         MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
4062
4063         cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
4064         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
4065         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
4066         if ((vars->ieee_fc &
4067             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
4068             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
4069                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
4070         }
4071         if ((vars->ieee_fc &
4072             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
4073             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
4074                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
4075         }
4076         if ((vars->ieee_fc &
4077             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
4078             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
4079                 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
4080         }
4081         DP(NETIF_MSG_LINK,
4082                  "Ext phy AN advertize cl37 0x%x\n", cl37_val);
4083
4084         bnx2x_cl45_write(bp, phy,
4085                          MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
4086         msleep(500);
4087 }
4088
4089 static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy,
4090                                  struct link_params *params,
4091                                  struct link_vars *vars)
4092 {
4093         struct bnx2x *bp = params->bp;
4094         u16 val = 0, tmp1;
4095         u8 gpio_port;
4096         DP(NETIF_MSG_LINK, "Init 8073\n");
4097
4098         if (CHIP_IS_E2(bp))
4099                 gpio_port = BP_PATH(bp);
4100         else
4101                 gpio_port = params->port;
4102         /* Restore normal power mode*/
4103         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4104                             MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
4105
4106         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4107                             MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
4108
4109         /* enable LASI */
4110         bnx2x_cl45_write(bp, phy,
4111                          MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2));
4112         bnx2x_cl45_write(bp, phy,
4113                          MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,  0x0004);
4114
4115         bnx2x_8073_set_pause_cl37(params, phy, vars);
4116
4117         bnx2x_8073_set_xaui_low_power_mode(bp, phy);
4118
4119         bnx2x_cl45_read(bp, phy,
4120                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
4121
4122         bnx2x_cl45_read(bp, phy,
4123                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
4124
4125         DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
4126
4127         /**
4128          * If this is forced speed, set to KR or KX (all other are not
4129          * supported)
4130          */
4131         /* Swap polarity if required - Must be done only in non-1G mode */
4132         if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
4133                 /* Configure the 8073 to swap _P and _N of the KR lines */
4134                 DP(NETIF_MSG_LINK, "Swapping polarity for the 8073\n");
4135                 /* 10G Rx/Tx and 1G Tx signal polarity swap */
4136                 bnx2x_cl45_read(bp, phy,
4137                                 MDIO_PMA_DEVAD,
4138                                 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
4139                 bnx2x_cl45_write(bp, phy,
4140                                  MDIO_PMA_DEVAD,
4141                                  MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
4142                                  (val | (3<<9)));
4143         }
4144
4145
4146         /* Enable CL37 BAM */
4147         if (REG_RD(bp, params->shmem_base +
4148                          offsetof(struct shmem_region, dev_info.
4149                                   port_hw_config[params->port].default_cfg)) &
4150             PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
4151
4152                 bnx2x_cl45_read(bp, phy,
4153                                 MDIO_AN_DEVAD,
4154                                 MDIO_AN_REG_8073_BAM, &val);
4155                 bnx2x_cl45_write(bp, phy,
4156                                  MDIO_AN_DEVAD,
4157                                  MDIO_AN_REG_8073_BAM, val | 1);
4158                 DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
4159         }
4160         if (params->loopback_mode == LOOPBACK_EXT) {
4161                 bnx2x_807x_force_10G(bp, phy);
4162                 DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
4163                 return 0;
4164         } else {
4165                 bnx2x_cl45_write(bp, phy,
4166                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
4167         }
4168         if (phy->req_line_speed != SPEED_AUTO_NEG) {
4169                 if (phy->req_line_speed == SPEED_10000) {
4170                         val = (1<<7);
4171                 } else if (phy->req_line_speed ==  SPEED_2500) {
4172                         val = (1<<5);
4173                         /* Note that 2.5G works only
4174                         when used with 1G advertisment */
4175                 } else
4176                         val = (1<<5);
4177         } else {
4178                 val = 0;
4179                 if (phy->speed_cap_mask &
4180                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4181                         val |= (1<<7);
4182
4183                 /* Note that 2.5G works only when
4184                 used with 1G advertisment */
4185                 if (phy->speed_cap_mask &
4186                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
4187                          PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
4188                         val |= (1<<5);
4189                 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
4190         }
4191
4192         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
4193         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
4194
4195         if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
4196              (phy->req_line_speed == SPEED_AUTO_NEG)) ||
4197             (phy->req_line_speed == SPEED_2500)) {
4198                 u16 phy_ver;
4199                 /* Allow 2.5G for A1 and above */
4200                 bnx2x_cl45_read(bp, phy,
4201                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
4202                                 &phy_ver);
4203                 DP(NETIF_MSG_LINK, "Add 2.5G\n");
4204                 if (phy_ver > 0)
4205                         tmp1 |= 1;
4206                 else
4207                         tmp1 &= 0xfffe;
4208         } else {
4209                 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
4210                 tmp1 &= 0xfffe;
4211         }
4212
4213         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
4214         /* Add support for CL37 (passive mode) II */
4215
4216         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
4217         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
4218                          (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
4219                                   0x20 : 0x40)));
4220
4221         /* Add support for CL37 (passive mode) III */
4222         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
4223
4224         /* The SNR will improve about 2db by changing
4225         BW and FEE main tap. Rest commands are executed
4226         after link is up*/
4227         if (bnx2x_8073_is_snr_needed(bp, phy))
4228                 bnx2x_cl45_write(bp, phy,
4229                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
4230                                  0xFB0C);
4231
4232         /* Enable FEC (Forware Error Correction) Request in the AN */
4233         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
4234         tmp1 |= (1<<15);
4235         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
4236
4237         bnx2x_ext_phy_set_pause(params, phy, vars);
4238
4239         /* Restart autoneg */
4240         msleep(500);
4241         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
4242         DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
4243                    ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
4244         return 0;
4245 }
4246
4247 static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
4248                                  struct link_params *params,
4249                                  struct link_vars *vars)
4250 {
4251         struct bnx2x *bp = params->bp;
4252         u8 link_up = 0;
4253         u16 val1, val2;
4254         u16 link_status = 0;
4255         u16 an1000_status = 0;
4256
4257         bnx2x_cl45_read(bp, phy,
4258                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
4259
4260         DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
4261
4262         /* clear the interrupt LASI status register */
4263         bnx2x_cl45_read(bp, phy,
4264                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
4265         bnx2x_cl45_read(bp, phy,
4266                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
4267         DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
4268         /* Clear MSG-OUT */
4269         bnx2x_cl45_read(bp, phy,
4270                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
4271
4272         /* Check the LASI */
4273         bnx2x_cl45_read(bp, phy,
4274                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
4275
4276         DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
4277
4278         /* Check the link status */
4279         bnx2x_cl45_read(bp, phy,
4280                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
4281         DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
4282
4283         bnx2x_cl45_read(bp, phy,
4284                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
4285         bnx2x_cl45_read(bp, phy,
4286                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
4287         link_up = ((val1 & 4) == 4);
4288         DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
4289
4290         if (link_up &&
4291              ((phy->req_line_speed != SPEED_10000))) {
4292                 if (bnx2x_8073_xaui_wa(bp, phy) != 0)
4293                         return 0;
4294         }
4295         bnx2x_cl45_read(bp, phy,
4296                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
4297         bnx2x_cl45_read(bp, phy,
4298                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
4299
4300         /* Check the link status on 1.1.2 */
4301         bnx2x_cl45_read(bp, phy,
4302                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
4303         bnx2x_cl45_read(bp, phy,
4304                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
4305         DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
4306                    "an_link_status=0x%x\n", val2, val1, an1000_status);
4307
4308         link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
4309         if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
4310                 /* The SNR will improve about 2dbby
4311                 changing the BW and FEE main tap.*/
4312                 /* The 1st write to change FFE main
4313                 tap is set before restart AN */
4314                 /* Change PLL Bandwidth in EDC
4315                 register */
4316                 bnx2x_cl45_write(bp, phy,
4317                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
4318                                  0x26BC);
4319
4320                 /* Change CDR Bandwidth in EDC register */
4321                 bnx2x_cl45_write(bp, phy,
4322                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
4323                                  0x0333);
4324         }
4325         bnx2x_cl45_read(bp, phy,
4326                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
4327                         &link_status);
4328
4329         /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
4330         if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
4331                 link_up = 1;
4332                 vars->line_speed = SPEED_10000;
4333                 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
4334                            params->port);
4335         } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
4336                 link_up = 1;
4337                 vars->line_speed = SPEED_2500;
4338                 DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
4339                            params->port);
4340         } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
4341                 link_up = 1;
4342                 vars->line_speed = SPEED_1000;
4343                 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
4344                            params->port);
4345         } else {
4346                 link_up = 0;
4347                 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
4348                            params->port);
4349         }
4350
4351         if (link_up) {
4352                 /* Swap polarity if required */
4353                 if (params->lane_config &
4354                     PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
4355                         /* Configure the 8073 to swap P and N of the KR lines */
4356                         bnx2x_cl45_read(bp, phy,
4357                                         MDIO_XS_DEVAD,
4358                                         MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
4359                         /**
4360                         * Set bit 3 to invert Rx in 1G mode and clear this bit
4361                         * when it`s in 10G mode.
4362                         */
4363                         if (vars->line_speed == SPEED_1000) {
4364                                 DP(NETIF_MSG_LINK, "Swapping 1G polarity for"
4365                                               "the 8073\n");
4366                                 val1 |= (1<<3);
4367                         } else
4368                                 val1 &= ~(1<<3);
4369
4370                         bnx2x_cl45_write(bp, phy,
4371                                          MDIO_XS_DEVAD,
4372                                          MDIO_XS_REG_8073_RX_CTRL_PCIE,
4373                                          val1);
4374                 }
4375                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
4376                 bnx2x_8073_resolve_fc(phy, params, vars);
4377         }
4378         return link_up;
4379 }
4380
4381 static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
4382                                   struct link_params *params)
4383 {
4384         struct bnx2x *bp = params->bp;
4385         u8 gpio_port;
4386         if (CHIP_IS_E2(bp))
4387                 gpio_port = BP_PATH(bp);
4388         else
4389                 gpio_port = params->port;
4390         DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
4391            gpio_port);
4392         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4393                             MISC_REGISTERS_GPIO_OUTPUT_LOW,
4394                             gpio_port);
4395 }
4396
4397 /******************************************************************/
4398 /*                      BCM8705 PHY SECTION                       */
4399 /******************************************************************/
4400 static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy,
4401                                  struct link_params *params,
4402                                  struct link_vars *vars)
4403 {
4404         struct bnx2x *bp = params->bp;
4405         DP(NETIF_MSG_LINK, "init 8705\n");
4406         /* Restore normal power mode*/
4407         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4408                             MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
4409         /* HW reset */
4410         bnx2x_ext_phy_hw_reset(bp, params->port);
4411         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
4412         bnx2x_wait_reset_complete(bp, phy);
4413
4414         bnx2x_cl45_write(bp, phy,
4415                          MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
4416         bnx2x_cl45_write(bp, phy,
4417                          MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
4418         bnx2x_cl45_write(bp, phy,
4419                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
4420         bnx2x_cl45_write(bp, phy,
4421                          MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
4422         /* BCM8705 doesn't have microcode, hence the 0 */
4423         bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
4424         return 0;
4425 }
4426
4427 static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
4428                                  struct link_params *params,
4429                                  struct link_vars *vars)
4430 {
4431         u8 link_up = 0;
4432         u16 val1, rx_sd;
4433         struct bnx2x *bp = params->bp;
4434         DP(NETIF_MSG_LINK, "read status 8705\n");
4435         bnx2x_cl45_read(bp, phy,
4436                       MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
4437         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4438
4439         bnx2x_cl45_read(bp, phy,
4440                       MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
4441         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4442
4443         bnx2x_cl45_read(bp, phy,
4444                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
4445
4446         bnx2x_cl45_read(bp, phy,
4447                       MDIO_PMA_DEVAD, 0xc809, &val1);
4448         bnx2x_cl45_read(bp, phy,
4449                       MDIO_PMA_DEVAD, 0xc809, &val1);
4450
4451         DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
4452         link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
4453         if (link_up) {
4454                 vars->line_speed = SPEED_10000;
4455                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
4456         }
4457         return link_up;
4458 }
4459
4460 /******************************************************************/
4461 /*                      SFP+ module Section                       */
4462 /******************************************************************/
4463 static void bnx2x_sfp_set_transmitter(struct bnx2x *bp,
4464                                       struct bnx2x_phy *phy,
4465                                       u8 port,
4466                                       u8 tx_en)
4467 {
4468         u16 val;
4469
4470         DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
4471                  tx_en, port);
4472         /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
4473         bnx2x_cl45_read(bp, phy,
4474                       MDIO_PMA_DEVAD,
4475                       MDIO_PMA_REG_PHY_IDENTIFIER,
4476                       &val);
4477
4478         if (tx_en)
4479                 val &= ~(1<<15);
4480         else
4481                 val |= (1<<15);
4482
4483         bnx2x_cl45_write(bp, phy,
4484                        MDIO_PMA_DEVAD,
4485                        MDIO_PMA_REG_PHY_IDENTIFIER,
4486                        val);
4487 }
4488
4489 static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
4490                                             struct link_params *params,
4491                                           u16 addr, u8 byte_cnt, u8 *o_buf)
4492 {
4493         struct bnx2x *bp = params->bp;
4494         u16 val = 0;
4495         u16 i;
4496         if (byte_cnt > 16) {
4497                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
4498                             " is limited to 0xf\n");
4499                 return -EINVAL;
4500         }
4501         /* Set the read command byte count */
4502         bnx2x_cl45_write(bp, phy,
4503                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
4504                        (byte_cnt | 0xa000));
4505
4506         /* Set the read command address */
4507         bnx2x_cl45_write(bp, phy,
4508                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
4509                        addr);
4510
4511         /* Activate read command */
4512         bnx2x_cl45_write(bp, phy,
4513                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
4514                        0x2c0f);
4515
4516         /* Wait up to 500us for command complete status */
4517         for (i = 0; i < 100; i++) {
4518                 bnx2x_cl45_read(bp, phy,
4519                               MDIO_PMA_DEVAD,
4520                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
4521                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
4522                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
4523                         break;
4524                 udelay(5);
4525         }
4526
4527         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
4528                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
4529                 DP(NETIF_MSG_LINK,
4530                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
4531                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
4532                 return -EINVAL;
4533         }
4534
4535         /* Read the buffer */
4536         for (i = 0; i < byte_cnt; i++) {
4537                 bnx2x_cl45_read(bp, phy,
4538                               MDIO_PMA_DEVAD,
4539                               MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
4540                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
4541         }
4542
4543         for (i = 0; i < 100; i++) {
4544                 bnx2x_cl45_read(bp, phy,
4545                               MDIO_PMA_DEVAD,
4546                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
4547                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
4548                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
4549                         return 0;
4550                 msleep(1);
4551         }
4552         return -EINVAL;
4553 }
4554
4555 static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
4556                                             struct link_params *params,
4557                                           u16 addr, u8 byte_cnt, u8 *o_buf)
4558 {
4559         struct bnx2x *bp = params->bp;
4560         u16 val, i;
4561
4562         if (byte_cnt > 16) {
4563                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
4564                             " is limited to 0xf\n");
4565                 return -EINVAL;
4566         }
4567
4568         /* Need to read from 1.8000 to clear it */
4569         bnx2x_cl45_read(bp, phy,
4570                       MDIO_PMA_DEVAD,
4571                       MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
4572                       &val);
4573
4574         /* Set the read command byte count */
4575         bnx2x_cl45_write(bp, phy,
4576                        MDIO_PMA_DEVAD,
4577                        MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
4578                        ((byte_cnt < 2) ? 2 : byte_cnt));
4579
4580         /* Set the read command address */
4581         bnx2x_cl45_write(bp, phy,
4582                        MDIO_PMA_DEVAD,
4583                        MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
4584                        addr);
4585         /* Set the destination address */
4586         bnx2x_cl45_write(bp, phy,
4587                        MDIO_PMA_DEVAD,
4588                        0x8004,
4589                        MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
4590
4591         /* Activate read command */
4592         bnx2x_cl45_write(bp, phy,
4593                        MDIO_PMA_DEVAD,
4594                        MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
4595                        0x8002);
4596         /* Wait appropriate time for two-wire command to finish before
4597         polling the status register */
4598         msleep(1);
4599
4600         /* Wait up to 500us for command complete status */
4601         for (i = 0; i < 100; i++) {
4602                 bnx2x_cl45_read(bp, phy,
4603                               MDIO_PMA_DEVAD,
4604                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
4605                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
4606                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
4607                         break;
4608                 udelay(5);
4609         }
4610
4611         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
4612                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
4613                 DP(NETIF_MSG_LINK,
4614                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
4615                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
4616                 return -EINVAL;
4617         }
4618
4619         /* Read the buffer */
4620         for (i = 0; i < byte_cnt; i++) {
4621                 bnx2x_cl45_read(bp, phy,
4622                               MDIO_PMA_DEVAD,
4623                               MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
4624                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
4625         }
4626
4627         for (i = 0; i < 100; i++) {
4628                 bnx2x_cl45_read(bp, phy,
4629                               MDIO_PMA_DEVAD,
4630                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
4631                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
4632                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
4633                         return 0;
4634                 msleep(1);
4635         }
4636
4637         return -EINVAL;
4638 }
4639
4640 static u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
4641                                        struct link_params *params, u16 addr,
4642                                        u8 byte_cnt, u8 *o_buf)
4643 {
4644         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
4645                 return bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
4646                                                        byte_cnt, o_buf);
4647         else if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
4648                 return bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
4649                                                        byte_cnt, o_buf);
4650         return -EINVAL;
4651 }
4652
4653 static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy,
4654                              struct link_params *params,
4655                                   u16 *edc_mode)
4656 {
4657         struct bnx2x *bp = params->bp;
4658         u8 val, check_limiting_mode = 0;
4659         *edc_mode = EDC_MODE_LIMITING;
4660
4661         /* First check for copper cable */
4662         if (bnx2x_read_sfp_module_eeprom(phy,
4663                                          params,
4664                                          SFP_EEPROM_CON_TYPE_ADDR,
4665                                          1,
4666                                          &val) != 0) {
4667                 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
4668                 return -EINVAL;
4669         }
4670
4671         switch (val) {
4672         case SFP_EEPROM_CON_TYPE_VAL_COPPER:
4673         {
4674                 u8 copper_module_type;
4675
4676                 /* Check if its active cable( includes SFP+ module)
4677                 of passive cable*/
4678                 if (bnx2x_read_sfp_module_eeprom(phy,
4679                                                params,
4680                                                SFP_EEPROM_FC_TX_TECH_ADDR,
4681                                                1,
4682                                                &copper_module_type) !=
4683                     0) {
4684                         DP(NETIF_MSG_LINK,
4685                                 "Failed to read copper-cable-type"
4686                                 " from SFP+ EEPROM\n");
4687                         return -EINVAL;
4688                 }
4689
4690                 if (copper_module_type &
4691                     SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
4692                         DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
4693                         check_limiting_mode = 1;
4694                 } else if (copper_module_type &
4695                         SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
4696                                 DP(NETIF_MSG_LINK, "Passive Copper"
4697                                             " cable detected\n");
4698                                 *edc_mode =
4699                                       EDC_MODE_PASSIVE_DAC;
4700                 } else {
4701                         DP(NETIF_MSG_LINK, "Unknown copper-cable-"
4702                                      "type 0x%x !!!\n", copper_module_type);
4703                         return -EINVAL;
4704                 }
4705                 break;
4706         }
4707         case SFP_EEPROM_CON_TYPE_VAL_LC:
4708                 DP(NETIF_MSG_LINK, "Optic module detected\n");
4709                 check_limiting_mode = 1;
4710                 break;
4711         default:
4712                 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
4713                          val);
4714                 return -EINVAL;
4715         }
4716
4717         if (check_limiting_mode) {
4718                 u8 options[SFP_EEPROM_OPTIONS_SIZE];
4719                 if (bnx2x_read_sfp_module_eeprom(phy,
4720                                                  params,
4721                                                  SFP_EEPROM_OPTIONS_ADDR,
4722                                                  SFP_EEPROM_OPTIONS_SIZE,
4723                                                  options) != 0) {
4724                         DP(NETIF_MSG_LINK, "Failed to read Option"
4725                                 " field from module EEPROM\n");
4726                         return -EINVAL;
4727                 }
4728                 if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
4729                         *edc_mode = EDC_MODE_LINEAR;
4730                 else
4731                         *edc_mode = EDC_MODE_LIMITING;
4732         }
4733         DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
4734         return 0;
4735 }
4736 /* This function read the relevant field from the module ( SFP+ ),
4737         and verify it is compliant with this board */
4738 static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
4739                                   struct link_params *params)
4740 {
4741         struct bnx2x *bp = params->bp;
4742         u32 val, cmd;
4743         u32 fw_resp, fw_cmd_param;
4744         char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
4745         char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
4746         phy->flags &= ~FLAGS_SFP_NOT_APPROVED;
4747         val = REG_RD(bp, params->shmem_base +
4748                          offsetof(struct shmem_region, dev_info.
4749                                   port_feature_config[params->port].config));
4750         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
4751             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
4752                 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
4753                 return 0;
4754         }
4755
4756         if (params->feature_config_flags &
4757             FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
4758                 /* Use specific phy request */
4759                 cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
4760         } else if (params->feature_config_flags &
4761                    FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
4762                 /* Use first phy request only in case of non-dual media*/
4763                 if (DUAL_MEDIA(params)) {
4764                         DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
4765                            "verification\n");
4766                         return -EINVAL;
4767                 }
4768                 cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
4769         } else {
4770                 /* No support in OPT MDL detection */
4771                 DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
4772                           "verification\n");
4773                 return -EINVAL;
4774         }
4775
4776         fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
4777         fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param);
4778         if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
4779                 DP(NETIF_MSG_LINK, "Approved module\n");
4780                 return 0;
4781         }
4782
4783         /* format the warning message */
4784         if (bnx2x_read_sfp_module_eeprom(phy,
4785                                          params,
4786                                        SFP_EEPROM_VENDOR_NAME_ADDR,
4787                                        SFP_EEPROM_VENDOR_NAME_SIZE,
4788                                        (u8 *)vendor_name))
4789                 vendor_name[0] = '\0';
4790         else
4791                 vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
4792         if (bnx2x_read_sfp_module_eeprom(phy,
4793                                          params,
4794                                        SFP_EEPROM_PART_NO_ADDR,
4795                                        SFP_EEPROM_PART_NO_SIZE,
4796                                        (u8 *)vendor_pn))
4797                 vendor_pn[0] = '\0';
4798         else
4799                 vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
4800
4801         netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected,"
4802                              " Port %d from %s part number %s\n",
4803                     params->port, vendor_name, vendor_pn);
4804         phy->flags |= FLAGS_SFP_NOT_APPROVED;
4805         return -EINVAL;
4806 }
4807
4808 static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
4809                                                 struct link_params *params)
4810
4811 {
4812         u8 val;
4813         struct bnx2x *bp = params->bp;
4814         u16 timeout;
4815         /* Initialization time after hot-plug may take up to 300ms for some
4816         phys type ( e.g. JDSU ) */
4817         for (timeout = 0; timeout < 60; timeout++) {
4818                 if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
4819                     == 0) {
4820                         DP(NETIF_MSG_LINK, "SFP+ module initialization "
4821                                      "took %d ms\n", timeout * 5);
4822                         return 0;
4823                 }
4824                 msleep(5);
4825         }
4826         return -EINVAL;
4827 }
4828
4829 static void bnx2x_8727_power_module(struct bnx2x *bp,
4830                                     struct bnx2x_phy *phy,
4831                                     u8 is_power_up) {
4832         /* Make sure GPIOs are not using for LED mode */
4833         u16 val;
4834         /*
4835          * In the GPIO register, bit 4 is use to detemine if the GPIOs are
4836          * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
4837          * output
4838          * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
4839          * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
4840          * where the 1st bit is the over-current(only input), and 2nd bit is
4841          * for power( only output )
4842         */
4843
4844         /*
4845          * In case of NOC feature is disabled and power is up, set GPIO control
4846          *  as input to enable listening of over-current indication
4847          */
4848         if (phy->flags & FLAGS_NOC)
4849                 return;
4850         if (!(phy->flags &
4851               FLAGS_NOC) && is_power_up)
4852                 val = (1<<4);
4853         else
4854                 /*
4855                  * Set GPIO control to OUTPUT, and set the power bit
4856                  * to according to the is_power_up
4857                  */
4858                 val = ((!(is_power_up)) << 1);
4859
4860         bnx2x_cl45_write(bp, phy,
4861                          MDIO_PMA_DEVAD,
4862                          MDIO_PMA_REG_8727_GPIO_CTRL,
4863                          val);
4864 }
4865
4866 static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
4867                                        struct bnx2x_phy *phy,
4868                                        u16 edc_mode)
4869 {
4870         u16 cur_limiting_mode;
4871
4872         bnx2x_cl45_read(bp, phy,
4873                       MDIO_PMA_DEVAD,
4874                       MDIO_PMA_REG_ROM_VER2,
4875                       &cur_limiting_mode);
4876         DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
4877                  cur_limiting_mode);
4878
4879         if (edc_mode == EDC_MODE_LIMITING) {
4880                 DP(NETIF_MSG_LINK,
4881                          "Setting LIMITING MODE\n");
4882                 bnx2x_cl45_write(bp, phy,
4883                                  MDIO_PMA_DEVAD,
4884                                  MDIO_PMA_REG_ROM_VER2,
4885                                  EDC_MODE_LIMITING);
4886         } else { /* LRM mode ( default )*/
4887
4888                 DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
4889
4890                 /* Changing to LRM mode takes quite few seconds.
4891                 So do it only if current mode is limiting
4892                 ( default is LRM )*/
4893                 if (cur_limiting_mode != EDC_MODE_LIMITING)
4894                         return 0;
4895
4896                 bnx2x_cl45_write(bp, phy,
4897                                MDIO_PMA_DEVAD,
4898                                MDIO_PMA_REG_LRM_MODE,
4899                                0);
4900                 bnx2x_cl45_write(bp, phy,
4901                                MDIO_PMA_DEVAD,
4902                                MDIO_PMA_REG_ROM_VER2,
4903                                0x128);
4904                 bnx2x_cl45_write(bp, phy,
4905                                MDIO_PMA_DEVAD,
4906                                MDIO_PMA_REG_MISC_CTRL0,
4907                                0x4008);
4908                 bnx2x_cl45_write(bp, phy,
4909                                MDIO_PMA_DEVAD,
4910                                MDIO_PMA_REG_LRM_MODE,
4911                                0xaaaa);
4912         }
4913         return 0;
4914 }
4915
4916 static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
4917                                        struct bnx2x_phy *phy,
4918                                         u16 edc_mode)
4919 {
4920         u16 phy_identifier;
4921         u16 rom_ver2_val;
4922         bnx2x_cl45_read(bp, phy,
4923                        MDIO_PMA_DEVAD,
4924                        MDIO_PMA_REG_PHY_IDENTIFIER,
4925                        &phy_identifier);
4926
4927         bnx2x_cl45_write(bp, phy,
4928                        MDIO_PMA_DEVAD,
4929                        MDIO_PMA_REG_PHY_IDENTIFIER,
4930                        (phy_identifier & ~(1<<9)));
4931
4932         bnx2x_cl45_read(bp, phy,
4933                       MDIO_PMA_DEVAD,
4934                       MDIO_PMA_REG_ROM_VER2,
4935                       &rom_ver2_val);
4936         /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
4937         bnx2x_cl45_write(bp, phy,
4938                        MDIO_PMA_DEVAD,
4939                        MDIO_PMA_REG_ROM_VER2,
4940                        (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
4941
4942         bnx2x_cl45_write(bp, phy,
4943                        MDIO_PMA_DEVAD,
4944                        MDIO_PMA_REG_PHY_IDENTIFIER,
4945                        (phy_identifier | (1<<9)));
4946
4947         return 0;
4948 }
4949
4950 static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
4951                                      struct link_params *params,
4952                                      u32 action)
4953 {
4954         struct bnx2x *bp = params->bp;
4955
4956         switch (action) {
4957         case DISABLE_TX:
4958                 bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
4959                 break;
4960         case ENABLE_TX:
4961                 if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
4962                         bnx2x_sfp_set_transmitter(bp, phy, params->port, 1);
4963                 break;
4964         default:
4965                 DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
4966                    action);
4967                 return;
4968         }
4969 }
4970
4971 static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
4972                                      struct link_params *params)
4973 {
4974         struct bnx2x *bp = params->bp;
4975         u16 edc_mode;
4976         u8 rc = 0;
4977
4978         u32 val = REG_RD(bp, params->shmem_base +
4979                              offsetof(struct shmem_region, dev_info.
4980                                      port_feature_config[params->port].config));
4981
4982         DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
4983                  params->port);
4984
4985         if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
4986                 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
4987                 return -EINVAL;
4988         } else if (bnx2x_verify_sfp_module(phy, params) !=
4989                    0) {
4990                 /* check SFP+ module compatibility */
4991                 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
4992                 rc = -EINVAL;
4993                 /* Turn on fault module-detected led */
4994                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4995                                   MISC_REGISTERS_GPIO_HIGH,
4996                                   params->port);
4997                 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
4998                     ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
4999                      PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) {
5000                         /* Shutdown SFP+ module */
5001                         DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
5002                         bnx2x_8727_power_module(bp, phy, 0);
5003                         return rc;
5004                 }
5005         } else {
5006                 /* Turn off fault module-detected led */
5007                 DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n");
5008                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5009                                           MISC_REGISTERS_GPIO_LOW,
5010                                           params->port);
5011         }
5012
5013         /* power up the SFP module */
5014         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
5015                 bnx2x_8727_power_module(bp, phy, 1);
5016
5017         /* Check and set limiting mode / LRM mode on 8726.
5018         On 8727 it is done automatically */
5019         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
5020                 bnx2x_8726_set_limiting_mode(bp, phy, edc_mode);
5021         else
5022                 bnx2x_8727_set_limiting_mode(bp, phy, edc_mode);
5023         /*
5024          * Enable transmit for this module if the module is approved, or
5025          * if unapproved modules should also enable the Tx laser
5026          */
5027         if (rc == 0 ||
5028             (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
5029             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
5030                 bnx2x_sfp_set_transmitter(bp, phy, params->port, 1);
5031         else
5032                 bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
5033
5034         return rc;
5035 }
5036
5037 void bnx2x_handle_module_detect_int(struct link_params *params)
5038 {
5039         struct bnx2x *bp = params->bp;
5040         struct bnx2x_phy *phy = &params->phy[EXT_PHY1];
5041         u32 gpio_val;
5042         u8 port = params->port;
5043
5044         /* Set valid module led off */
5045         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5046                           MISC_REGISTERS_GPIO_HIGH,
5047                           params->port);
5048
5049         /* Get current gpio val refelecting module plugged in / out*/
5050         gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
5051
5052         /* Call the handling function in case module is detected */
5053         if (gpio_val == 0) {
5054
5055                 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
5056                                    MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
5057                                    port);
5058
5059                 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
5060                         bnx2x_sfp_module_detection(phy, params);
5061                 else
5062                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
5063         } else {
5064                 u32 val = REG_RD(bp, params->shmem_base +
5065                                      offsetof(struct shmem_region, dev_info.
5066                                               port_feature_config[params->port].
5067                                               config));
5068
5069                 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
5070                                    MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
5071                                    port);
5072                 /* Module was plugged out. */
5073                 /* Disable transmit for this module */
5074                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
5075                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
5076                         bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
5077         }
5078 }
5079
5080 /******************************************************************/
5081 /*              common BCM8706/BCM8726 PHY SECTION                */
5082 /******************************************************************/
5083 static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
5084                                       struct link_params *params,
5085                                       struct link_vars *vars)
5086 {
5087         u8 link_up = 0;
5088         u16 val1, val2, rx_sd, pcs_status;
5089         struct bnx2x *bp = params->bp;
5090         DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
5091         /* Clear RX Alarm*/
5092         bnx2x_cl45_read(bp, phy,
5093                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
5094         /* clear LASI indication*/
5095         bnx2x_cl45_read(bp, phy,
5096                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
5097         bnx2x_cl45_read(bp, phy,
5098                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
5099         DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
5100
5101         bnx2x_cl45_read(bp, phy,
5102                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
5103         bnx2x_cl45_read(bp, phy,
5104                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
5105         bnx2x_cl45_read(bp, phy,
5106                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
5107         bnx2x_cl45_read(bp, phy,
5108                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
5109
5110         DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
5111                         " link_status 0x%x\n", rx_sd, pcs_status, val2);
5112         /* link is up if both bit 0 of pmd_rx_sd and
5113          * bit 0 of pcs_status are set, or if the autoneg bit
5114          * 1 is set
5115          */
5116         link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
5117         if (link_up) {
5118                 if (val2 & (1<<1))
5119                         vars->line_speed = SPEED_1000;
5120                 else
5121                         vars->line_speed = SPEED_10000;
5122                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5123         }
5124         return link_up;
5125 }
5126
5127 /******************************************************************/
5128 /*                      BCM8706 PHY SECTION                       */
5129 /******************************************************************/
5130 static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
5131                                  struct link_params *params,
5132                                  struct link_vars *vars)
5133 {
5134         u16 cnt, val;
5135         struct bnx2x *bp = params->bp;
5136         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5137                             MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
5138         /* HW reset */
5139         bnx2x_ext_phy_hw_reset(bp, params->port);
5140         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
5141         bnx2x_wait_reset_complete(bp, phy);
5142
5143         /* Wait until fw is loaded */
5144         for (cnt = 0; cnt < 100; cnt++) {
5145                 bnx2x_cl45_read(bp, phy,
5146                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
5147                 if (val)
5148                         break;
5149                 msleep(10);
5150         }
5151         DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt);
5152         if ((params->feature_config_flags &
5153              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
5154                 u8 i;
5155                 u16 reg;
5156                 for (i = 0; i < 4; i++) {
5157                         reg = MDIO_XS_8706_REG_BANK_RX0 +
5158                                 i*(MDIO_XS_8706_REG_BANK_RX1 -
5159                                    MDIO_XS_8706_REG_BANK_RX0);
5160                         bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val);
5161                         /* Clear first 3 bits of the control */
5162                         val &= ~0x7;
5163                         /* Set control bits according to configuration */
5164                         val |= (phy->rx_preemphasis[i] & 0x7);
5165                         DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706"
5166                                    " reg 0x%x <-- val 0x%x\n", reg, val);
5167                         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val);
5168                 }
5169         }
5170         /* Force speed */
5171         if (phy->req_line_speed == SPEED_10000) {
5172                 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
5173
5174                 bnx2x_cl45_write(bp, phy,
5175                                  MDIO_PMA_DEVAD,
5176                                  MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
5177                 bnx2x_cl45_write(bp, phy,
5178                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
5179         } else {
5180                 /* Force 1Gbps using autoneg with 1G advertisment */
5181
5182                 /* Allow CL37 through CL73 */
5183                 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
5184                 bnx2x_cl45_write(bp, phy,
5185                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
5186
5187                 /* Enable Full-Duplex advertisment on CL37 */
5188                 bnx2x_cl45_write(bp, phy,
5189                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
5190                 /* Enable CL37 AN */
5191                 bnx2x_cl45_write(bp, phy,
5192                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
5193                 /* 1G support */
5194                 bnx2x_cl45_write(bp, phy,
5195                                  MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
5196
5197                 /* Enable clause 73 AN */
5198                 bnx2x_cl45_write(bp, phy,
5199                                  MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
5200                 bnx2x_cl45_write(bp, phy,
5201                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5202                                  0x0400);
5203                 bnx2x_cl45_write(bp, phy,
5204                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
5205                                  0x0004);
5206         }
5207         bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
5208         return 0;
5209 }
5210
5211 static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy,
5212                                  struct link_params *params,
5213                                  struct link_vars *vars)
5214 {
5215         return bnx2x_8706_8726_read_status(phy, params, vars);
5216 }
5217
5218 /******************************************************************/
5219 /*                      BCM8726 PHY SECTION                       */
5220 /******************************************************************/
5221 static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
5222                                        struct link_params *params)
5223 {
5224         struct bnx2x *bp = params->bp;
5225         DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
5226         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
5227 }
5228
5229 static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
5230                                          struct link_params *params)
5231 {
5232         struct bnx2x *bp = params->bp;
5233         /* Need to wait 100ms after reset */
5234         msleep(100);
5235
5236         /* Micro controller re-boot */
5237         bnx2x_cl45_write(bp, phy,
5238                          MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
5239
5240         /* Set soft reset */
5241         bnx2x_cl45_write(bp, phy,
5242                        MDIO_PMA_DEVAD,
5243                        MDIO_PMA_REG_GEN_CTRL,
5244                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
5245
5246         bnx2x_cl45_write(bp, phy,
5247                        MDIO_PMA_DEVAD,
5248                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
5249
5250         bnx2x_cl45_write(bp, phy,
5251                        MDIO_PMA_DEVAD,
5252                        MDIO_PMA_REG_GEN_CTRL,
5253                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
5254
5255         /* wait for 150ms for microcode load */
5256         msleep(150);
5257
5258         /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
5259         bnx2x_cl45_write(bp, phy,
5260                        MDIO_PMA_DEVAD,
5261                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
5262
5263         msleep(200);
5264         bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
5265 }
5266
5267 static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
5268                                  struct link_params *params,
5269                                  struct link_vars *vars)
5270 {
5271         struct bnx2x *bp = params->bp;
5272         u16 val1;
5273         u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
5274         if (link_up) {
5275                 bnx2x_cl45_read(bp, phy,
5276                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
5277                                 &val1);
5278                 if (val1 & (1<<15)) {
5279                         DP(NETIF_MSG_LINK, "Tx is disabled\n");
5280                         link_up = 0;
5281                         vars->line_speed = 0;
5282                 }
5283         }
5284         return link_up;
5285 }
5286
5287
5288 static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy,
5289                                  struct link_params *params,
5290                                  struct link_vars *vars)
5291 {
5292         struct bnx2x *bp = params->bp;
5293         u32 val;
5294         u32 swap_val, swap_override, aeu_gpio_mask, offset;
5295         DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
5296         /* Restore normal power mode*/
5297         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5298                             MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
5299
5300         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
5301                             MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
5302
5303         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
5304         bnx2x_wait_reset_complete(bp, phy);
5305
5306         bnx2x_8726_external_rom_boot(phy, params);
5307
5308         /* Need to call module detected on initialization since
5309         the module detection triggered by actual module
5310         insertion might occur before driver is loaded, and when
5311         driver is loaded, it reset all registers, including the
5312         transmitter */
5313         bnx2x_sfp_module_detection(phy, params);
5314
5315         if (phy->req_line_speed == SPEED_1000) {
5316                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
5317                 bnx2x_cl45_write(bp, phy,
5318                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
5319                 bnx2x_cl45_write(bp, phy,
5320                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
5321                 bnx2x_cl45_write(bp, phy,
5322                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5);
5323                 bnx2x_cl45_write(bp, phy,
5324                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5325                                  0x400);
5326         } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
5327                    (phy->speed_cap_mask &
5328                       PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
5329                    ((phy->speed_cap_mask &
5330                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
5331                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
5332                 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
5333                 /* Set Flow control */
5334                 bnx2x_ext_phy_set_pause(params, phy, vars);
5335                 bnx2x_cl45_write(bp, phy,
5336                                  MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
5337                 bnx2x_cl45_write(bp, phy,
5338                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
5339                 bnx2x_cl45_write(bp, phy,
5340                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
5341                 bnx2x_cl45_write(bp, phy,
5342                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
5343                 bnx2x_cl45_write(bp, phy,
5344                                 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
5345                 /* Enable RX-ALARM control to receive
5346                 interrupt for 1G speed change */
5347                 bnx2x_cl45_write(bp, phy,
5348                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4);
5349                 bnx2x_cl45_write(bp, phy,
5350                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5351                                  0x400);
5352
5353         } else { /* Default 10G. Set only LASI control */
5354                 bnx2x_cl45_write(bp, phy,
5355                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
5356         }
5357
5358         /* Set TX PreEmphasis if needed */
5359         if ((params->feature_config_flags &
5360              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
5361                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
5362                          "TX_CTRL2 0x%x\n",
5363                          phy->tx_preemphasis[0],
5364                          phy->tx_preemphasis[1]);
5365                 bnx2x_cl45_write(bp, phy,
5366                                  MDIO_PMA_DEVAD,
5367                                  MDIO_PMA_REG_8726_TX_CTRL1,
5368                                  phy->tx_preemphasis[0]);
5369
5370                 bnx2x_cl45_write(bp, phy,
5371                                  MDIO_PMA_DEVAD,
5372                                  MDIO_PMA_REG_8726_TX_CTRL2,
5373                                  phy->tx_preemphasis[1]);
5374         }
5375
5376         /* Set GPIO3 to trigger SFP+ module insertion/removal */
5377         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
5378                             MISC_REGISTERS_GPIO_INPUT_HI_Z, params->port);
5379
5380         /* The GPIO should be swapped if the swap register is set and active */
5381         swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
5382         swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
5383
5384         /* Select function upon port-swap configuration */
5385         if (params->port == 0) {
5386                 offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
5387                 aeu_gpio_mask = (swap_val && swap_override) ?
5388                         AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 :
5389                         AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0;
5390         } else {
5391                 offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
5392                 aeu_gpio_mask = (swap_val && swap_override) ?
5393                         AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 :
5394                         AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1;
5395         }
5396         val = REG_RD(bp, offset);
5397         /* add GPIO3 to group */
5398         val |= aeu_gpio_mask;
5399         REG_WR(bp, offset, val);
5400         return 0;
5401
5402 }
5403
5404 static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
5405                                   struct link_params *params)
5406 {
5407         struct bnx2x *bp = params->bp;
5408         DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
5409         /* Set serial boot control for external load */
5410         bnx2x_cl45_write(bp, phy,
5411                          MDIO_PMA_DEVAD,
5412                          MDIO_PMA_REG_GEN_CTRL, 0x0001);
5413 }
5414
5415 /******************************************************************/
5416 /*                      BCM8727 PHY SECTION                       */
5417 /******************************************************************/
5418
5419 static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy,
5420                                     struct link_params *params, u8 mode)
5421 {
5422         struct bnx2x *bp = params->bp;
5423         u16 led_mode_bitmask = 0;
5424         u16 gpio_pins_bitmask = 0;
5425         u16 val;
5426         /* Only NOC flavor requires to set the LED specifically */
5427         if (!(phy->flags & FLAGS_NOC))
5428                 return;
5429         switch (mode) {
5430         case LED_MODE_FRONT_PANEL_OFF:
5431         case LED_MODE_OFF:
5432                 led_mode_bitmask = 0;
5433                 gpio_pins_bitmask = 0x03;
5434                 break;
5435         case LED_MODE_ON:
5436                 led_mode_bitmask = 0;
5437                 gpio_pins_bitmask = 0x02;
5438                 break;
5439         case LED_MODE_OPER:
5440                 led_mode_bitmask = 0x60;
5441                 gpio_pins_bitmask = 0x11;
5442                 break;
5443         }
5444         bnx2x_cl45_read(bp, phy,
5445                         MDIO_PMA_DEVAD,
5446                         MDIO_PMA_REG_8727_PCS_OPT_CTRL,
5447                         &val);
5448         val &= 0xff8f;
5449         val |= led_mode_bitmask;
5450         bnx2x_cl45_write(bp, phy,
5451                          MDIO_PMA_DEVAD,
5452                          MDIO_PMA_REG_8727_PCS_OPT_CTRL,
5453                          val);
5454         bnx2x_cl45_read(bp, phy,
5455                         MDIO_PMA_DEVAD,
5456                         MDIO_PMA_REG_8727_GPIO_CTRL,
5457                         &val);
5458         val &= 0xffe0;
5459         val |= gpio_pins_bitmask;
5460         bnx2x_cl45_write(bp, phy,
5461                          MDIO_PMA_DEVAD,
5462                          MDIO_PMA_REG_8727_GPIO_CTRL,
5463                          val);
5464 }
5465 static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
5466                                 struct link_params *params) {
5467         u32 swap_val, swap_override;
5468         u8 port;
5469         /**
5470          * The PHY reset is controlled by GPIO 1. Fake the port number
5471          * to cancel the swap done in set_gpio()
5472          */
5473         struct bnx2x *bp = params->bp;
5474         swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
5475         swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
5476         port = (swap_val && swap_override) ^ 1;
5477         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
5478                             MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
5479 }
5480
5481 static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy,
5482                                  struct link_params *params,
5483                                  struct link_vars *vars)
5484 {
5485         u16 tmp1, val, mod_abs;
5486         u16 rx_alarm_ctrl_val;
5487         u16 lasi_ctrl_val;
5488         struct bnx2x *bp = params->bp;
5489         /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
5490
5491         bnx2x_wait_reset_complete(bp, phy);
5492         rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
5493         lasi_ctrl_val = 0x0004;
5494
5495         DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
5496         /* enable LASI */
5497         bnx2x_cl45_write(bp, phy,
5498                          MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5499                          rx_alarm_ctrl_val);
5500
5501         bnx2x_cl45_write(bp, phy,
5502                          MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val);
5503
5504         /* Initially configure  MOD_ABS to interrupt when
5505         module is presence( bit 8) */
5506         bnx2x_cl45_read(bp, phy,
5507                         MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
5508         /* Set EDC off by setting OPTXLOS signal input to low
5509         (bit 9).
5510         When the EDC is off it locks onto a reference clock and
5511         avoids becoming 'lost'.*/
5512         mod_abs &= ~(1<<8);
5513         if (!(phy->flags & FLAGS_NOC))
5514                 mod_abs &= ~(1<<9);
5515         bnx2x_cl45_write(bp, phy,
5516                          MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
5517
5518
5519         /* Make MOD_ABS give interrupt on change */
5520         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
5521                         &val);
5522         val |= (1<<12);
5523         if (phy->flags & FLAGS_NOC)
5524                 val |= (3<<5);
5525
5526         /**
5527          * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
5528          * status which reflect SFP+ module over-current
5529          */
5530         if (!(phy->flags & FLAGS_NOC))
5531                 val &= 0xff8f; /* Reset bits 4-6 */
5532         bnx2x_cl45_write(bp, phy,
5533                          MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val);
5534
5535         bnx2x_8727_power_module(bp, phy, 1);
5536
5537         bnx2x_cl45_read(bp, phy,
5538                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
5539
5540         bnx2x_cl45_read(bp, phy,
5541                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
5542
5543         /* Set option 1G speed */
5544         if (phy->req_line_speed == SPEED_1000) {
5545                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
5546                 bnx2x_cl45_write(bp, phy,
5547                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
5548                 bnx2x_cl45_write(bp, phy,
5549                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
5550                 bnx2x_cl45_read(bp, phy,
5551                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
5552                 DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
5553                 /**
5554                  * Power down the XAUI until link is up in case of dual-media
5555                  * and 1G
5556                  */
5557                 if (DUAL_MEDIA(params)) {
5558                         bnx2x_cl45_read(bp, phy,
5559                                         MDIO_PMA_DEVAD,
5560                                         MDIO_PMA_REG_8727_PCS_GP, &val);
5561                         val |= (3<<10);
5562                         bnx2x_cl45_write(bp, phy,
5563                                          MDIO_PMA_DEVAD,
5564                                          MDIO_PMA_REG_8727_PCS_GP, val);
5565                 }
5566         } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
5567                    ((phy->speed_cap_mask &
5568                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
5569                    ((phy->speed_cap_mask &
5570                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
5571                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
5572
5573                 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
5574                 bnx2x_cl45_write(bp, phy,
5575                                  MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
5576                 bnx2x_cl45_write(bp, phy,
5577                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
5578         } else {
5579                 /**
5580                  * Since the 8727 has only single reset pin, need to set the 10G
5581                  * registers although it is default
5582                  */
5583                 bnx2x_cl45_write(bp, phy,
5584                                  MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
5585                                  0x0020);
5586                 bnx2x_cl45_write(bp, phy,
5587                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
5588                 bnx2x_cl45_write(bp, phy,
5589                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
5590                 bnx2x_cl45_write(bp, phy,
5591                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
5592                                  0x0008);
5593         }
5594
5595         /* Set 2-wire transfer rate of SFP+ module EEPROM
5596          * to 100Khz since some DACs(direct attached cables) do
5597          * not work at 400Khz.
5598          */
5599         bnx2x_cl45_write(bp, phy,
5600                          MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
5601                          0xa001);
5602
5603         /* Set TX PreEmphasis if needed */
5604         if ((params->feature_config_flags &
5605              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
5606                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
5607                            phy->tx_preemphasis[0],
5608                            phy->tx_preemphasis[1]);
5609                 bnx2x_cl45_write(bp, phy,
5610                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
5611                                  phy->tx_preemphasis[0]);
5612
5613                 bnx2x_cl45_write(bp, phy,
5614                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
5615                                  phy->tx_preemphasis[1]);
5616         }
5617
5618         return 0;
5619 }
5620
5621 static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
5622                                       struct link_params *params)
5623 {
5624         struct bnx2x *bp = params->bp;
5625         u16 mod_abs, rx_alarm_status;
5626         u32 val = REG_RD(bp, params->shmem_base +
5627                              offsetof(struct shmem_region, dev_info.
5628                                       port_feature_config[params->port].
5629                                       config));
5630         bnx2x_cl45_read(bp, phy,
5631                       MDIO_PMA_DEVAD,
5632                       MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
5633         if (mod_abs & (1<<8)) {
5634
5635                 /* Module is absent */
5636                 DP(NETIF_MSG_LINK, "MOD_ABS indication "
5637                             "show module is absent\n");
5638
5639                 /* 1. Set mod_abs to detect next module
5640                 presence event
5641                    2. Set EDC off by setting OPTXLOS signal input to low
5642                         (bit 9).
5643                         When the EDC is off it locks onto a reference clock and
5644                         avoids becoming 'lost'.*/
5645                 mod_abs &= ~(1<<8);
5646                 if (!(phy->flags & FLAGS_NOC))
5647                         mod_abs &= ~(1<<9);
5648                 bnx2x_cl45_write(bp, phy,
5649                                MDIO_PMA_DEVAD,
5650                                MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
5651
5652                 /* Clear RX alarm since it stays up as long as
5653                 the mod_abs wasn't changed */
5654                 bnx2x_cl45_read(bp, phy,
5655                               MDIO_PMA_DEVAD,
5656                               MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
5657
5658         } else {
5659                 /* Module is present */
5660                 DP(NETIF_MSG_LINK, "MOD_ABS indication "
5661                             "show module is present\n");
5662                 /* First thing, disable transmitter,
5663                 and if the module is ok, the
5664                 module_detection will enable it*/
5665
5666                 /* 1. Set mod_abs to detect next module
5667                 absent event ( bit 8)
5668                    2. Restore the default polarity of the OPRXLOS signal and
5669                 this signal will then correctly indicate the presence or
5670                 absence of the Rx signal. (bit 9) */
5671                 mod_abs |= (1<<8);
5672                 if (!(phy->flags & FLAGS_NOC))
5673                         mod_abs |= (1<<9);
5674                 bnx2x_cl45_write(bp, phy,
5675                                  MDIO_PMA_DEVAD,
5676                                  MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
5677
5678                 /* Clear RX alarm since it stays up as long as
5679                 the mod_abs wasn't changed. This is need to be done
5680                 before calling the module detection, otherwise it will clear
5681                 the link update alarm */
5682                 bnx2x_cl45_read(bp, phy,
5683                                 MDIO_PMA_DEVAD,
5684                                 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
5685
5686
5687                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
5688                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
5689                         bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
5690
5691                 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
5692                         bnx2x_sfp_module_detection(phy, params);
5693                 else
5694                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
5695         }
5696
5697         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
5698                  rx_alarm_status);
5699         /* No need to check link status in case of
5700         module plugged in/out */
5701 }
5702
5703 static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
5704                                  struct link_params *params,
5705                                  struct link_vars *vars)
5706
5707 {
5708         struct bnx2x *bp = params->bp;
5709         u8 link_up = 0;
5710         u16 link_status = 0;
5711         u16 rx_alarm_status, lasi_ctrl, val1;
5712
5713         /* If PHY is not initialized, do not check link status */
5714         bnx2x_cl45_read(bp, phy,
5715                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
5716                         &lasi_ctrl);
5717         if (!lasi_ctrl)
5718                 return 0;
5719
5720         /* Check the LASI */
5721         bnx2x_cl45_read(bp, phy,
5722                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
5723                         &rx_alarm_status);
5724         vars->line_speed = 0;
5725         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS  0x%x\n", rx_alarm_status);
5726
5727         bnx2x_cl45_read(bp, phy,
5728                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
5729
5730         DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
5731
5732         /* Clear MSG-OUT */
5733         bnx2x_cl45_read(bp, phy,
5734                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
5735
5736         /**
5737          * If a module is present and there is need to check
5738          * for over current
5739          */
5740         if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
5741                 /* Check over-current using 8727 GPIO0 input*/
5742                 bnx2x_cl45_read(bp, phy,
5743                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
5744                                 &val1);
5745
5746                 if ((val1 & (1<<8)) == 0) {
5747                         DP(NETIF_MSG_LINK, "8727 Power fault has been detected"
5748                                        " on port %d\n", params->port);
5749                         netdev_err(bp->dev, "Error:  Power fault on Port %d has"
5750                                             " been detected and the power to "
5751                                             "that SFP+ module has been removed"
5752                                             " to prevent failure of the card."
5753                                             " Please remove the SFP+ module and"
5754                                             " restart the system to clear this"
5755                                             " error.\n",
5756                                    params->port);
5757
5758                         /*
5759                          * Disable all RX_ALARMs except for
5760                          * mod_abs
5761                          */
5762                         bnx2x_cl45_write(bp, phy,
5763                                          MDIO_PMA_DEVAD,
5764                                          MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5));
5765
5766                         bnx2x_cl45_read(bp, phy,
5767                                         MDIO_PMA_DEVAD,
5768                                         MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
5769                         /* Wait for module_absent_event */
5770                         val1 |= (1<<8);
5771                         bnx2x_cl45_write(bp, phy,
5772                                          MDIO_PMA_DEVAD,
5773                                          MDIO_PMA_REG_PHY_IDENTIFIER, val1);
5774                         /* Clear RX alarm */
5775                         bnx2x_cl45_read(bp, phy,
5776                                 MDIO_PMA_DEVAD,
5777                                 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
5778                         return 0;
5779                 }
5780         } /* Over current check */
5781
5782         /* When module absent bit is set, check module */
5783         if (rx_alarm_status & (1<<5)) {
5784                 bnx2x_8727_handle_mod_abs(phy, params);
5785                 /* Enable all mod_abs and link detection bits */
5786                 bnx2x_cl45_write(bp, phy,
5787                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5788                                  ((1<<5) | (1<<2)));
5789         }
5790         DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n");
5791         bnx2x_8727_specific_func(phy, params, ENABLE_TX);
5792         /* If transmitter is disabled, ignore false link up indication */
5793         bnx2x_cl45_read(bp, phy,
5794                         MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
5795         if (val1 & (1<<15)) {
5796                 DP(NETIF_MSG_LINK, "Tx is disabled\n");
5797                 return 0;
5798         }
5799
5800         bnx2x_cl45_read(bp, phy,
5801                         MDIO_PMA_DEVAD,
5802                         MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
5803
5804         /* Bits 0..2 --> speed detected,
5805            bits 13..15--> link is down */
5806         if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
5807                 link_up = 1;
5808                 vars->line_speed = SPEED_10000;
5809         } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
5810                 link_up = 1;
5811                 vars->line_speed = SPEED_1000;
5812                 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
5813                            params->port);
5814         } else {
5815                 link_up = 0;
5816                 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
5817                            params->port);
5818         }
5819         if (link_up)
5820                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5821
5822         if ((DUAL_MEDIA(params)) &&
5823             (phy->req_line_speed == SPEED_1000)) {
5824                 bnx2x_cl45_read(bp, phy,
5825                                 MDIO_PMA_DEVAD,
5826                                 MDIO_PMA_REG_8727_PCS_GP, &val1);
5827                 /**
5828                  * In case of dual-media board and 1G, power up the XAUI side,
5829                  * otherwise power it down. For 10G it is done automatically
5830                  */
5831                 if (link_up)
5832                         val1 &= ~(3<<10);
5833                 else
5834                         val1 |= (3<<10);
5835                 bnx2x_cl45_write(bp, phy,
5836                                  MDIO_PMA_DEVAD,
5837                                  MDIO_PMA_REG_8727_PCS_GP, val1);
5838         }
5839         return link_up;
5840 }
5841
5842 static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
5843                                   struct link_params *params)
5844 {
5845         struct bnx2x *bp = params->bp;
5846         /* Disable Transmitter */
5847         bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
5848         /* Clear LASI */
5849         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0);
5850
5851 }
5852
5853 /******************************************************************/
5854 /*              BCM8481/BCM84823/BCM84833 PHY SECTION             */
5855 /******************************************************************/
5856 static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
5857                                            struct link_params *params)
5858 {
5859         u16 val, fw_ver1, fw_ver2, cnt;
5860         struct bnx2x *bp = params->bp;
5861
5862         /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
5863         /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
5864         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
5865         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
5866         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
5867         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
5868         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
5869
5870         for (cnt = 0; cnt < 100; cnt++) {
5871                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
5872                 if (val & 1)
5873                         break;
5874                 udelay(5);
5875         }
5876         if (cnt == 100) {
5877                 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n");
5878                 bnx2x_save_spirom_version(bp, params->port, 0,
5879                                           phy->ver_addr);
5880                 return;
5881         }
5882
5883
5884         /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
5885         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
5886         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
5887         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
5888         for (cnt = 0; cnt < 100; cnt++) {
5889                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
5890                 if (val & 1)
5891                         break;
5892                 udelay(5);
5893         }
5894         if (cnt == 100) {
5895                 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n");
5896                 bnx2x_save_spirom_version(bp, params->port, 0,
5897                                           phy->ver_addr);
5898                 return;
5899         }
5900
5901         /* lower 16 bits of the register SPI_FW_STATUS */
5902         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
5903         /* upper 16 bits of register SPI_FW_STATUS */
5904         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
5905
5906         bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1,
5907                                   phy->ver_addr);
5908 }
5909
5910 static void bnx2x_848xx_set_led(struct bnx2x *bp,
5911                                 struct bnx2x_phy *phy)
5912 {
5913         u16 val;
5914
5915         /* PHYC_CTL_LED_CTL */
5916         bnx2x_cl45_read(bp, phy,
5917                         MDIO_PMA_DEVAD,
5918                         MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
5919         val &= 0xFE00;
5920         val |= 0x0092;
5921
5922         bnx2x_cl45_write(bp, phy,
5923                          MDIO_PMA_DEVAD,
5924                          MDIO_PMA_REG_8481_LINK_SIGNAL, val);
5925
5926         bnx2x_cl45_write(bp, phy,
5927                          MDIO_PMA_DEVAD,
5928                          MDIO_PMA_REG_8481_LED1_MASK,
5929                          0x80);
5930
5931         bnx2x_cl45_write(bp, phy,
5932                          MDIO_PMA_DEVAD,
5933                          MDIO_PMA_REG_8481_LED2_MASK,
5934                          0x18);
5935
5936         bnx2x_cl45_write(bp, phy,
5937                          MDIO_PMA_DEVAD,
5938                          MDIO_PMA_REG_8481_LED3_MASK,
5939                          0x0040);
5940
5941         /* 'Interrupt Mask' */
5942         bnx2x_cl45_write(bp, phy,
5943                          MDIO_AN_DEVAD,
5944                          0xFFFB, 0xFFFD);
5945 }
5946
5947 static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
5948                                       struct link_params *params,
5949                                       struct link_vars *vars)
5950 {
5951         struct bnx2x *bp = params->bp;
5952         u16 autoneg_val, an_1000_val, an_10_100_val;
5953
5954         bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
5955                       1 << NIG_LATCH_BC_ENABLE_MI_INT);
5956
5957         bnx2x_cl45_write(bp, phy,
5958                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
5959
5960         bnx2x_848xx_set_led(bp, phy);
5961
5962         /* set 1000 speed advertisement */
5963         bnx2x_cl45_read(bp, phy,
5964                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
5965                         &an_1000_val);
5966
5967         bnx2x_ext_phy_set_pause(params, phy, vars);
5968         bnx2x_cl45_read(bp, phy,
5969                         MDIO_AN_DEVAD,
5970                         MDIO_AN_REG_8481_LEGACY_AN_ADV,
5971                         &an_10_100_val);
5972         bnx2x_cl45_read(bp, phy,
5973                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
5974                         &autoneg_val);
5975         /* Disable forced speed */
5976         autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
5977         an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
5978
5979         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
5980              (phy->speed_cap_mask &
5981              PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
5982             (phy->req_line_speed == SPEED_1000)) {
5983                 an_1000_val |= (1<<8);
5984                 autoneg_val |= (1<<9 | 1<<12);
5985                 if (phy->req_duplex == DUPLEX_FULL)
5986                         an_1000_val |= (1<<9);
5987                 DP(NETIF_MSG_LINK, "Advertising 1G\n");
5988         } else
5989                 an_1000_val &= ~((1<<8) | (1<<9));
5990
5991         bnx2x_cl45_write(bp, phy,
5992                          MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
5993                          an_1000_val);
5994
5995         /* set 10 speed advertisement */
5996         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
5997              (phy->speed_cap_mask &
5998              (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
5999               PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
6000                 an_10_100_val |= (1<<7);
6001                 /* Enable autoneg and restart autoneg for legacy speeds */
6002                 autoneg_val |= (1<<9 | 1<<12);
6003
6004                 if (phy->req_duplex == DUPLEX_FULL)
6005                         an_10_100_val |= (1<<8);
6006                 DP(NETIF_MSG_LINK, "Advertising 100M\n");
6007         }
6008         /* set 10 speed advertisement */
6009         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
6010             (phy->speed_cap_mask &
6011           (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
6012            PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
6013                 an_10_100_val |= (1<<5);
6014                 autoneg_val |= (1<<9 | 1<<12);
6015                 if (phy->req_duplex == DUPLEX_FULL)
6016                         an_10_100_val |= (1<<6);
6017                 DP(NETIF_MSG_LINK, "Advertising 10M\n");
6018         }
6019
6020         /* Only 10/100 are allowed to work in FORCE mode */
6021         if (phy->req_line_speed == SPEED_100) {
6022                 autoneg_val |= (1<<13);
6023                 /* Enabled AUTO-MDIX when autoneg is disabled */
6024                 bnx2x_cl45_write(bp, phy,
6025                                  MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
6026                                  (1<<15 | 1<<9 | 7<<0));
6027                 DP(NETIF_MSG_LINK, "Setting 100M force\n");
6028         }
6029         if (phy->req_line_speed == SPEED_10) {
6030                 /* Enabled AUTO-MDIX when autoneg is disabled */
6031                 bnx2x_cl45_write(bp, phy,
6032                                  MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
6033                                  (1<<15 | 1<<9 | 7<<0));
6034                 DP(NETIF_MSG_LINK, "Setting 10M force\n");
6035         }
6036
6037         bnx2x_cl45_write(bp, phy,
6038                          MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
6039                          an_10_100_val);
6040
6041         if (phy->req_duplex == DUPLEX_FULL)
6042                 autoneg_val |= (1<<8);
6043
6044         bnx2x_cl45_write(bp, phy,
6045                          MDIO_AN_DEVAD,
6046                          MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
6047
6048         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
6049             (phy->speed_cap_mask &
6050              PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
6051                 (phy->req_line_speed == SPEED_10000)) {
6052                 DP(NETIF_MSG_LINK, "Advertising 10G\n");
6053                 /* Restart autoneg for 10G*/
6054
6055                 bnx2x_cl45_write(bp, phy,
6056                                  MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
6057                                  0x3200);
6058         } else if (phy->req_line_speed != SPEED_10 &&
6059                    phy->req_line_speed != SPEED_100) {
6060                 bnx2x_cl45_write(bp, phy,
6061                                  MDIO_AN_DEVAD,
6062                                  MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
6063                                  1);
6064         }
6065         /* Save spirom version */
6066         bnx2x_save_848xx_spirom_version(phy, params);
6067
6068         return 0;
6069 }
6070
6071 static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy,
6072                                  struct link_params *params,
6073                                  struct link_vars *vars)
6074 {
6075         struct bnx2x *bp = params->bp;
6076         /* Restore normal power mode*/
6077         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6078                             MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
6079
6080         /* HW reset */
6081         bnx2x_ext_phy_hw_reset(bp, params->port);
6082         bnx2x_wait_reset_complete(bp, phy);
6083
6084         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
6085         return bnx2x_848xx_cmn_config_init(phy, params, vars);
6086 }
6087
6088 static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
6089                                   struct link_params *params,
6090                                   struct link_vars *vars)
6091 {
6092         struct bnx2x *bp = params->bp;
6093         u8 port, initialize = 1;
6094         u16 val;
6095         u16 temp;
6096         u32 actual_phy_selection;
6097         u8 rc = 0;
6098
6099         /* This is just for MDIO_CTL_REG_84823_MEDIA register. */
6100
6101         msleep(1);
6102         if (CHIP_IS_E2(bp))
6103                 port = BP_PATH(bp);
6104         else
6105                 port = params->port;
6106         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
6107                        MISC_REGISTERS_GPIO_OUTPUT_HIGH,
6108                        port);
6109         bnx2x_wait_reset_complete(bp, phy);
6110         /* Wait for GPHY to come out of reset */
6111         msleep(50);
6112         /* BCM84823 requires that XGXS links up first @ 10G for normal
6113         behavior */
6114         temp = vars->line_speed;
6115         vars->line_speed = SPEED_10000;
6116         bnx2x_set_autoneg(&params->phy[INT_PHY], params, vars, 0);
6117         bnx2x_program_serdes(&params->phy[INT_PHY], params, vars);
6118         vars->line_speed = temp;
6119
6120         /* Set dual-media configuration according to configuration */
6121
6122         bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
6123                         MDIO_CTL_REG_84823_MEDIA, &val);
6124         val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
6125                  MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
6126                  MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
6127                  MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
6128                  MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
6129         val |= MDIO_CTL_REG_84823_CTRL_MAC_XFI |
6130                 MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L;
6131
6132         actual_phy_selection = bnx2x_phy_selection(params);
6133
6134         switch (actual_phy_selection) {
6135         case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
6136                 /* Do nothing. Essentialy this is like the priority copper */
6137                 break;
6138         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
6139                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
6140                 break;
6141         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
6142                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
6143                 break;
6144         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
6145                 /* Do nothing here. The first PHY won't be initialized at all */
6146                 break;
6147         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
6148                 val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
6149                 initialize = 0;
6150                 break;
6151         }
6152         if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000)
6153                 val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
6154
6155         bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
6156                          MDIO_CTL_REG_84823_MEDIA, val);
6157         DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
6158                    params->multi_phy_config, val);
6159
6160         if (initialize)
6161                 rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
6162         else
6163                 bnx2x_save_848xx_spirom_version(phy, params);
6164         return rc;
6165 }
6166
6167 static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
6168                                        struct link_params *params,
6169                                        struct link_vars *vars)
6170 {
6171         struct bnx2x *bp = params->bp;
6172         u16 val, val1, val2;
6173         u8 link_up = 0;
6174
6175         /* Check 10G-BaseT link status */
6176         /* Check PMD signal ok */
6177         bnx2x_cl45_read(bp, phy,
6178                         MDIO_AN_DEVAD, 0xFFFA, &val1);
6179         bnx2x_cl45_read(bp, phy,
6180                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
6181                         &val2);
6182         DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
6183
6184         /* Check link 10G */
6185         if (val2 & (1<<11)) {
6186                 vars->line_speed = SPEED_10000;
6187                 link_up = 1;
6188                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
6189         } else { /* Check Legacy speed link */
6190                 u16 legacy_status, legacy_speed;
6191
6192                 /* Enable expansion register 0x42 (Operation mode status) */
6193                 bnx2x_cl45_write(bp, phy,
6194                                  MDIO_AN_DEVAD,
6195                                  MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
6196
6197                 /* Get legacy speed operation status */
6198                 bnx2x_cl45_read(bp, phy,
6199                                 MDIO_AN_DEVAD,
6200                                 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
6201                                 &legacy_status);
6202
6203                 DP(NETIF_MSG_LINK, "Legacy speed status"
6204                              " = 0x%x\n", legacy_status);
6205                 link_up = ((legacy_status & (1<<11)) == (1<<11));
6206                 if (link_up) {
6207                         legacy_speed = (legacy_status & (3<<9));
6208                         if (legacy_speed == (0<<9))
6209                                 vars->line_speed = SPEED_10;
6210                         else if (legacy_speed == (1<<9))
6211                                 vars->line_speed = SPEED_100;
6212                         else if (legacy_speed == (2<<9))
6213                                 vars->line_speed = SPEED_1000;
6214                         else /* Should not happen */
6215                                 vars->line_speed = 0;
6216
6217                         if (legacy_status & (1<<8))
6218                                 vars->duplex = DUPLEX_FULL;
6219                         else
6220                                 vars->duplex = DUPLEX_HALF;
6221
6222                         DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
6223                                    " is_duplex_full= %d\n", vars->line_speed,
6224                                    (vars->duplex == DUPLEX_FULL));
6225                         /* Check legacy speed AN resolution */
6226                         bnx2x_cl45_read(bp, phy,
6227                                         MDIO_AN_DEVAD,
6228                                         MDIO_AN_REG_8481_LEGACY_MII_STATUS,
6229                                         &val);
6230                         if (val & (1<<5))
6231                                 vars->link_status |=
6232                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6233                         bnx2x_cl45_read(bp, phy,
6234                                         MDIO_AN_DEVAD,
6235                                         MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
6236                                         &val);
6237                         if ((val & (1<<0)) == 0)
6238                                 vars->link_status |=
6239                                         LINK_STATUS_PARALLEL_DETECTION_USED;
6240                 }
6241         }
6242         if (link_up) {
6243                 DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n",
6244                            vars->line_speed);
6245                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
6246         }
6247
6248         return link_up;
6249 }
6250
6251 static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
6252 {
6253         u8 status = 0;
6254         u32 spirom_ver;
6255         spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
6256         status = bnx2x_format_ver(spirom_ver, str, len);
6257         return status;
6258 }
6259
6260 static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
6261                                 struct link_params *params)
6262 {
6263         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
6264                             MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
6265         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
6266                             MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
6267 }
6268
6269 static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
6270                                         struct link_params *params)
6271 {
6272         bnx2x_cl45_write(params->bp, phy,
6273                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
6274         bnx2x_cl45_write(params->bp, phy,
6275                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
6276 }
6277
6278 static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
6279                                    struct link_params *params)
6280 {
6281         struct bnx2x *bp = params->bp;
6282         u8 port;
6283         if (CHIP_IS_E2(bp))
6284                 port = BP_PATH(bp);
6285         else
6286                 port = params->port;
6287         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
6288                             MISC_REGISTERS_GPIO_OUTPUT_LOW,
6289                             port);
6290 }
6291
6292 static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
6293                                      struct link_params *params, u8 mode)
6294 {
6295         struct bnx2x *bp = params->bp;
6296         u16 val;
6297
6298         switch (mode) {
6299         case LED_MODE_OFF:
6300
6301                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", params->port);
6302
6303                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
6304                     SHARED_HW_CFG_LED_EXTPHY1) {
6305
6306                         /* Set LED masks */
6307                         bnx2x_cl45_write(bp, phy,
6308                                         MDIO_PMA_DEVAD,
6309                                         MDIO_PMA_REG_8481_LED1_MASK,
6310                                         0x0);
6311
6312                         bnx2x_cl45_write(bp, phy,
6313                                         MDIO_PMA_DEVAD,
6314                                         MDIO_PMA_REG_8481_LED2_MASK,
6315                                         0x0);
6316
6317                         bnx2x_cl45_write(bp, phy,
6318                                         MDIO_PMA_DEVAD,
6319                                         MDIO_PMA_REG_8481_LED3_MASK,
6320                                         0x0);
6321
6322                         bnx2x_cl45_write(bp, phy,
6323                                         MDIO_PMA_DEVAD,
6324                                         MDIO_PMA_REG_8481_LED5_MASK,
6325                                         0x0);
6326
6327                 } else {
6328                         bnx2x_cl45_write(bp, phy,
6329                                          MDIO_PMA_DEVAD,
6330                                          MDIO_PMA_REG_8481_LED1_MASK,
6331                                          0x0);
6332                 }
6333                 break;
6334         case LED_MODE_FRONT_PANEL_OFF:
6335
6336                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
6337                    params->port);
6338
6339                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
6340                     SHARED_HW_CFG_LED_EXTPHY1) {
6341
6342                         /* Set LED masks */
6343                         bnx2x_cl45_write(bp, phy,
6344                                         MDIO_PMA_DEVAD,
6345                                         MDIO_PMA_REG_8481_LED1_MASK,
6346                                         0x0);
6347
6348                         bnx2x_cl45_write(bp, phy,
6349                                         MDIO_PMA_DEVAD,
6350                                         MDIO_PMA_REG_8481_LED2_MASK,
6351                                         0x0);
6352
6353                         bnx2x_cl45_write(bp, phy,
6354                                         MDIO_PMA_DEVAD,
6355                                         MDIO_PMA_REG_8481_LED3_MASK,
6356                                         0x0);
6357
6358                         bnx2x_cl45_write(bp, phy,
6359                                         MDIO_PMA_DEVAD,
6360                                         MDIO_PMA_REG_8481_LED5_MASK,
6361                                         0x20);
6362
6363                 } else {
6364                         bnx2x_cl45_write(bp, phy,
6365                                          MDIO_PMA_DEVAD,
6366                                          MDIO_PMA_REG_8481_LED1_MASK,
6367                                          0x0);
6368                 }
6369                 break;
6370         case LED_MODE_ON:
6371
6372                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", params->port);
6373
6374                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
6375                     SHARED_HW_CFG_LED_EXTPHY1) {
6376                         /* Set control reg */
6377                         bnx2x_cl45_read(bp, phy,
6378                                         MDIO_PMA_DEVAD,
6379                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
6380                                         &val);
6381                         val &= 0x8000;
6382                         val |= 0x2492;
6383
6384                         bnx2x_cl45_write(bp, phy,
6385                                         MDIO_PMA_DEVAD,
6386                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
6387                                         val);
6388
6389                         /* Set LED masks */
6390                         bnx2x_cl45_write(bp, phy,
6391                                         MDIO_PMA_DEVAD,
6392                                         MDIO_PMA_REG_8481_LED1_MASK,
6393                                         0x0);
6394
6395                         bnx2x_cl45_write(bp, phy,
6396                                         MDIO_PMA_DEVAD,
6397                                         MDIO_PMA_REG_8481_LED2_MASK,
6398                                         0x20);
6399
6400                         bnx2x_cl45_write(bp, phy,
6401                                         MDIO_PMA_DEVAD,
6402                                         MDIO_PMA_REG_8481_LED3_MASK,
6403                                         0x20);
6404
6405                         bnx2x_cl45_write(bp, phy,
6406                                         MDIO_PMA_DEVAD,
6407                                         MDIO_PMA_REG_8481_LED5_MASK,
6408                                         0x0);
6409                 } else {
6410                         bnx2x_cl45_write(bp, phy,
6411                                         MDIO_PMA_DEVAD,
6412                                         MDIO_PMA_REG_8481_LED1_MASK,
6413                                         0x20);
6414                 }
6415                 break;
6416
6417         case LED_MODE_OPER:
6418
6419                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", params->port);
6420
6421                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
6422                     SHARED_HW_CFG_LED_EXTPHY1) {
6423
6424                         /* Set control reg */
6425                         bnx2x_cl45_read(bp, phy,
6426                                         MDIO_PMA_DEVAD,
6427                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
6428                                         &val);
6429
6430                         if (!((val &
6431                               MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
6432                            >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)){
6433                                 DP(NETIF_MSG_LINK, "Seting LINK_SIGNAL\n");
6434                                 bnx2x_cl45_write(bp, phy,
6435                                                  MDIO_PMA_DEVAD,
6436                                                  MDIO_PMA_REG_8481_LINK_SIGNAL,
6437                                                  0xa492);
6438                         }
6439
6440                         /* Set LED masks */
6441                         bnx2x_cl45_write(bp, phy,
6442                                         MDIO_PMA_DEVAD,
6443                                         MDIO_PMA_REG_8481_LED1_MASK,
6444                                         0x10);
6445
6446                         bnx2x_cl45_write(bp, phy,
6447                                         MDIO_PMA_DEVAD,
6448                                         MDIO_PMA_REG_8481_LED2_MASK,
6449                                         0x80);
6450
6451                         bnx2x_cl45_write(bp, phy,
6452                                         MDIO_PMA_DEVAD,
6453                                         MDIO_PMA_REG_8481_LED3_MASK,
6454                                         0x98);
6455
6456                         bnx2x_cl45_write(bp, phy,
6457                                         MDIO_PMA_DEVAD,
6458                                         MDIO_PMA_REG_8481_LED5_MASK,
6459                                         0x40);
6460
6461                 } else {
6462                         bnx2x_cl45_write(bp, phy,
6463                                          MDIO_PMA_DEVAD,
6464                                          MDIO_PMA_REG_8481_LED1_MASK,
6465                                          0x80);
6466                 }
6467                 break;
6468         }
6469 }
6470 /******************************************************************/
6471 /*                      SFX7101 PHY SECTION                       */
6472 /******************************************************************/
6473 static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
6474                                        struct link_params *params)
6475 {
6476         struct bnx2x *bp = params->bp;
6477         /* SFX7101_XGXS_TEST1 */
6478         bnx2x_cl45_write(bp, phy,
6479                          MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
6480 }
6481
6482 static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy,
6483                                  struct link_params *params,
6484                                  struct link_vars *vars)
6485 {
6486         u16 fw_ver1, fw_ver2, val;
6487         struct bnx2x *bp = params->bp;
6488         DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
6489
6490         /* Restore normal power mode*/
6491         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6492                             MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
6493         /* HW reset */
6494         bnx2x_ext_phy_hw_reset(bp, params->port);
6495         bnx2x_wait_reset_complete(bp, phy);
6496
6497         bnx2x_cl45_write(bp, phy,
6498                          MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1);
6499         DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
6500         bnx2x_cl45_write(bp, phy,
6501                          MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
6502
6503         bnx2x_ext_phy_set_pause(params, phy, vars);
6504         /* Restart autoneg */
6505         bnx2x_cl45_read(bp, phy,
6506                         MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
6507         val |= 0x200;
6508         bnx2x_cl45_write(bp, phy,
6509                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
6510
6511         /* Save spirom version */
6512         bnx2x_cl45_read(bp, phy,
6513                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
6514
6515         bnx2x_cl45_read(bp, phy,
6516                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
6517         bnx2x_save_spirom_version(bp, params->port,
6518                                   (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
6519         return 0;
6520 }
6521
6522 static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
6523                                  struct link_params *params,
6524                                  struct link_vars *vars)
6525 {
6526         struct bnx2x *bp = params->bp;
6527         u8 link_up;
6528         u16 val1, val2;
6529         bnx2x_cl45_read(bp, phy,
6530                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
6531         bnx2x_cl45_read(bp, phy,
6532                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
6533         DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
6534                    val2, val1);
6535         bnx2x_cl45_read(bp, phy,
6536                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
6537         bnx2x_cl45_read(bp, phy,
6538                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
6539         DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
6540                    val2, val1);
6541         link_up = ((val1 & 4) == 4);
6542         /* if link is up
6543          * print the AN outcome of the SFX7101 PHY
6544          */
6545         if (link_up) {
6546                 bnx2x_cl45_read(bp, phy,
6547                                 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
6548                                 &val2);
6549                 vars->line_speed = SPEED_10000;
6550                 DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
6551                            val2, (val2 & (1<<14)));
6552                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
6553                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
6554         }
6555         return link_up;
6556 }
6557
6558
6559 static u8 bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
6560 {
6561         if (*len < 5)
6562                 return -EINVAL;
6563         str[0] = (spirom_ver & 0xFF);
6564         str[1] = (spirom_ver & 0xFF00) >> 8;
6565         str[2] = (spirom_ver & 0xFF0000) >> 16;
6566         str[3] = (spirom_ver & 0xFF000000) >> 24;
6567         str[4] = '\0';
6568         *len -= 5;
6569         return 0;
6570 }
6571
6572 void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
6573 {
6574         u16 val, cnt;
6575
6576         bnx2x_cl45_read(bp, phy,
6577                       MDIO_PMA_DEVAD,
6578                       MDIO_PMA_REG_7101_RESET, &val);
6579
6580         for (cnt = 0; cnt < 10; cnt++) {
6581                 msleep(50);
6582                 /* Writes a self-clearing reset */
6583                 bnx2x_cl45_write(bp, phy,
6584                                MDIO_PMA_DEVAD,
6585                                MDIO_PMA_REG_7101_RESET,
6586                                (val | (1<<15)));
6587                 /* Wait for clear */
6588                 bnx2x_cl45_read(bp, phy,
6589                               MDIO_PMA_DEVAD,
6590                               MDIO_PMA_REG_7101_RESET, &val);
6591
6592                 if ((val & (1<<15)) == 0)
6593                         break;
6594         }
6595 }
6596
6597 static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
6598                                 struct link_params *params) {
6599         /* Low power mode is controlled by GPIO 2 */
6600         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
6601                             MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
6602         /* The PHY reset is controlled by GPIO 1 */
6603         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
6604                             MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
6605 }
6606
6607 static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy,
6608                                     struct link_params *params, u8 mode)
6609 {
6610         u16 val = 0;
6611         struct bnx2x *bp = params->bp;
6612         switch (mode) {
6613         case LED_MODE_FRONT_PANEL_OFF:
6614         case LED_MODE_OFF:
6615                 val = 2;
6616                 break;
6617         case LED_MODE_ON:
6618                 val = 1;
6619                 break;
6620         case LED_MODE_OPER:
6621                 val = 0;
6622                 break;
6623         }
6624         bnx2x_cl45_write(bp, phy,
6625                          MDIO_PMA_DEVAD,
6626                          MDIO_PMA_REG_7107_LINK_LED_CNTL,
6627                          val);
6628 }
6629
6630 /******************************************************************/
6631 /*                      STATIC PHY DECLARATION                    */
6632 /******************************************************************/
6633
6634 static struct bnx2x_phy phy_null = {
6635         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
6636         .addr           = 0,
6637         .flags          = FLAGS_INIT_XGXS_FIRST,
6638         .def_md_devad   = 0,
6639         .reserved       = 0,
6640         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6641         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6642         .mdio_ctrl      = 0,
6643         .supported      = 0,
6644         .media_type     = ETH_PHY_NOT_PRESENT,
6645         .ver_addr       = 0,
6646         .req_flow_ctrl  = 0,
6647         .req_line_speed = 0,
6648         .speed_cap_mask = 0,
6649         .req_duplex     = 0,
6650         .rsrv           = 0,
6651         .config_init    = (config_init_t)NULL,
6652         .read_status    = (read_status_t)NULL,
6653         .link_reset     = (link_reset_t)NULL,
6654         .config_loopback = (config_loopback_t)NULL,
6655         .format_fw_ver  = (format_fw_ver_t)NULL,
6656         .hw_reset       = (hw_reset_t)NULL,
6657         .set_link_led   = (set_link_led_t)NULL,
6658         .phy_specific_func = (phy_specific_func_t)NULL
6659 };
6660
6661 static struct bnx2x_phy phy_serdes = {
6662         .type           = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
6663         .addr           = 0xff,
6664         .flags          = 0,
6665         .def_md_devad   = 0,
6666         .reserved       = 0,
6667         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6668         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6669         .mdio_ctrl      = 0,
6670         .supported      = (SUPPORTED_10baseT_Half |
6671                            SUPPORTED_10baseT_Full |
6672                            SUPPORTED_100baseT_Half |
6673                            SUPPORTED_100baseT_Full |
6674                            SUPPORTED_1000baseT_Full |
6675                            SUPPORTED_2500baseX_Full |
6676                            SUPPORTED_TP |
6677                            SUPPORTED_Autoneg |
6678                            SUPPORTED_Pause |
6679                            SUPPORTED_Asym_Pause),
6680         .media_type     = ETH_PHY_UNSPECIFIED,
6681         .ver_addr       = 0,
6682         .req_flow_ctrl  = 0,
6683         .req_line_speed = 0,
6684         .speed_cap_mask = 0,
6685         .req_duplex     = 0,
6686         .rsrv           = 0,
6687         .config_init    = (config_init_t)bnx2x_init_serdes,
6688         .read_status    = (read_status_t)bnx2x_link_settings_status,
6689         .link_reset     = (link_reset_t)bnx2x_int_link_reset,
6690         .config_loopback = (config_loopback_t)NULL,
6691         .format_fw_ver  = (format_fw_ver_t)NULL,
6692         .hw_reset       = (hw_reset_t)NULL,
6693         .set_link_led   = (set_link_led_t)NULL,
6694         .phy_specific_func = (phy_specific_func_t)NULL
6695 };
6696
6697 static struct bnx2x_phy phy_xgxs = {
6698         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
6699         .addr           = 0xff,
6700         .flags          = 0,
6701         .def_md_devad   = 0,
6702         .reserved       = 0,
6703         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6704         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6705         .mdio_ctrl      = 0,
6706         .supported      = (SUPPORTED_10baseT_Half |
6707                            SUPPORTED_10baseT_Full |
6708                            SUPPORTED_100baseT_Half |
6709                            SUPPORTED_100baseT_Full |
6710                            SUPPORTED_1000baseT_Full |
6711                            SUPPORTED_2500baseX_Full |
6712                            SUPPORTED_10000baseT_Full |
6713                            SUPPORTED_FIBRE |
6714                            SUPPORTED_Autoneg |
6715                            SUPPORTED_Pause |
6716                            SUPPORTED_Asym_Pause),
6717         .media_type     = ETH_PHY_UNSPECIFIED,
6718         .ver_addr       = 0,
6719         .req_flow_ctrl  = 0,
6720         .req_line_speed = 0,
6721         .speed_cap_mask = 0,
6722         .req_duplex     = 0,
6723         .rsrv           = 0,
6724         .config_init    = (config_init_t)bnx2x_init_xgxs,
6725         .read_status    = (read_status_t)bnx2x_link_settings_status,
6726         .link_reset     = (link_reset_t)bnx2x_int_link_reset,
6727         .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
6728         .format_fw_ver  = (format_fw_ver_t)NULL,
6729         .hw_reset       = (hw_reset_t)NULL,
6730         .set_link_led   = (set_link_led_t)NULL,
6731         .phy_specific_func = (phy_specific_func_t)NULL
6732 };
6733
6734 static struct bnx2x_phy phy_7101 = {
6735         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6736         .addr           = 0xff,
6737         .flags          = FLAGS_FAN_FAILURE_DET_REQ,
6738         .def_md_devad   = 0,
6739         .reserved       = 0,
6740         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6741         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6742         .mdio_ctrl      = 0,
6743         .supported      = (SUPPORTED_10000baseT_Full |
6744                            SUPPORTED_TP |
6745                            SUPPORTED_Autoneg |
6746                            SUPPORTED_Pause |
6747                            SUPPORTED_Asym_Pause),
6748         .media_type     = ETH_PHY_BASE_T,
6749         .ver_addr       = 0,
6750         .req_flow_ctrl  = 0,
6751         .req_line_speed = 0,
6752         .speed_cap_mask = 0,
6753         .req_duplex     = 0,
6754         .rsrv           = 0,
6755         .config_init    = (config_init_t)bnx2x_7101_config_init,
6756         .read_status    = (read_status_t)bnx2x_7101_read_status,
6757         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
6758         .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
6759         .format_fw_ver  = (format_fw_ver_t)bnx2x_7101_format_ver,
6760         .hw_reset       = (hw_reset_t)bnx2x_7101_hw_reset,
6761         .set_link_led   = (set_link_led_t)bnx2x_7101_set_link_led,
6762         .phy_specific_func = (phy_specific_func_t)NULL
6763 };
6764 static struct bnx2x_phy phy_8073 = {
6765         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6766         .addr           = 0xff,
6767         .flags          = FLAGS_HW_LOCK_REQUIRED,
6768         .def_md_devad   = 0,
6769         .reserved       = 0,
6770         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6771         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6772         .mdio_ctrl      = 0,
6773         .supported      = (SUPPORTED_10000baseT_Full |
6774                            SUPPORTED_2500baseX_Full |
6775                            SUPPORTED_1000baseT_Full |
6776                            SUPPORTED_FIBRE |
6777                            SUPPORTED_Autoneg |
6778                            SUPPORTED_Pause |
6779                            SUPPORTED_Asym_Pause),
6780         .media_type     = ETH_PHY_UNSPECIFIED,
6781         .ver_addr       = 0,
6782         .req_flow_ctrl  = 0,
6783         .req_line_speed = 0,
6784         .speed_cap_mask = 0,
6785         .req_duplex     = 0,
6786         .rsrv           = 0,
6787         .config_init    = (config_init_t)bnx2x_8073_config_init,
6788         .read_status    = (read_status_t)bnx2x_8073_read_status,
6789         .link_reset     = (link_reset_t)bnx2x_8073_link_reset,
6790         .config_loopback = (config_loopback_t)NULL,
6791         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
6792         .hw_reset       = (hw_reset_t)NULL,
6793         .set_link_led   = (set_link_led_t)NULL,
6794         .phy_specific_func = (phy_specific_func_t)NULL
6795 };
6796 static struct bnx2x_phy phy_8705 = {
6797         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
6798         .addr           = 0xff,
6799         .flags          = FLAGS_INIT_XGXS_FIRST,
6800         .def_md_devad   = 0,
6801         .reserved       = 0,
6802         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6803         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6804         .mdio_ctrl      = 0,
6805         .supported      = (SUPPORTED_10000baseT_Full |
6806                            SUPPORTED_FIBRE |
6807                            SUPPORTED_Pause |
6808                            SUPPORTED_Asym_Pause),
6809         .media_type     = ETH_PHY_XFP_FIBER,
6810         .ver_addr       = 0,
6811         .req_flow_ctrl  = 0,
6812         .req_line_speed = 0,
6813         .speed_cap_mask = 0,
6814         .req_duplex     = 0,
6815         .rsrv           = 0,
6816         .config_init    = (config_init_t)bnx2x_8705_config_init,
6817         .read_status    = (read_status_t)bnx2x_8705_read_status,
6818         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
6819         .config_loopback = (config_loopback_t)NULL,
6820         .format_fw_ver  = (format_fw_ver_t)bnx2x_null_format_ver,
6821         .hw_reset       = (hw_reset_t)NULL,
6822         .set_link_led   = (set_link_led_t)NULL,
6823         .phy_specific_func = (phy_specific_func_t)NULL
6824 };
6825 static struct bnx2x_phy phy_8706 = {
6826         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
6827         .addr           = 0xff,
6828         .flags          = FLAGS_INIT_XGXS_FIRST,
6829         .def_md_devad   = 0,
6830         .reserved       = 0,
6831         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6832         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6833         .mdio_ctrl      = 0,
6834         .supported      = (SUPPORTED_10000baseT_Full |
6835                            SUPPORTED_1000baseT_Full |
6836                            SUPPORTED_FIBRE |
6837                            SUPPORTED_Pause |
6838                            SUPPORTED_Asym_Pause),
6839         .media_type     = ETH_PHY_SFP_FIBER,
6840         .ver_addr       = 0,
6841         .req_flow_ctrl  = 0,
6842         .req_line_speed = 0,
6843         .speed_cap_mask = 0,
6844         .req_duplex     = 0,
6845         .rsrv           = 0,
6846         .config_init    = (config_init_t)bnx2x_8706_config_init,
6847         .read_status    = (read_status_t)bnx2x_8706_read_status,
6848         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
6849         .config_loopback = (config_loopback_t)NULL,
6850         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
6851         .hw_reset       = (hw_reset_t)NULL,
6852         .set_link_led   = (set_link_led_t)NULL,
6853         .phy_specific_func = (phy_specific_func_t)NULL
6854 };
6855
6856 static struct bnx2x_phy phy_8726 = {
6857         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
6858         .addr           = 0xff,
6859         .flags          = (FLAGS_HW_LOCK_REQUIRED |
6860                            FLAGS_INIT_XGXS_FIRST),
6861         .def_md_devad   = 0,
6862         .reserved       = 0,
6863         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6864         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6865         .mdio_ctrl      = 0,
6866         .supported      = (SUPPORTED_10000baseT_Full |
6867                            SUPPORTED_1000baseT_Full |
6868                            SUPPORTED_Autoneg |
6869                            SUPPORTED_FIBRE |
6870                            SUPPORTED_Pause |
6871                            SUPPORTED_Asym_Pause),
6872         .media_type     = ETH_PHY_SFP_FIBER,
6873         .ver_addr       = 0,
6874         .req_flow_ctrl  = 0,
6875         .req_line_speed = 0,
6876         .speed_cap_mask = 0,
6877         .req_duplex     = 0,
6878         .rsrv           = 0,
6879         .config_init    = (config_init_t)bnx2x_8726_config_init,
6880         .read_status    = (read_status_t)bnx2x_8726_read_status,
6881         .link_reset     = (link_reset_t)bnx2x_8726_link_reset,
6882         .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
6883         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
6884         .hw_reset       = (hw_reset_t)NULL,
6885         .set_link_led   = (set_link_led_t)NULL,
6886         .phy_specific_func = (phy_specific_func_t)NULL
6887 };
6888
6889 static struct bnx2x_phy phy_8727 = {
6890         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6891         .addr           = 0xff,
6892         .flags          = FLAGS_FAN_FAILURE_DET_REQ,
6893         .def_md_devad   = 0,
6894         .reserved       = 0,
6895         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6896         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6897         .mdio_ctrl      = 0,
6898         .supported      = (SUPPORTED_10000baseT_Full |
6899                            SUPPORTED_1000baseT_Full |
6900                            SUPPORTED_FIBRE |
6901                            SUPPORTED_Pause |
6902                            SUPPORTED_Asym_Pause),
6903         .media_type     = ETH_PHY_SFP_FIBER,
6904         .ver_addr       = 0,
6905         .req_flow_ctrl  = 0,
6906         .req_line_speed = 0,
6907         .speed_cap_mask = 0,
6908         .req_duplex     = 0,
6909         .rsrv           = 0,
6910         .config_init    = (config_init_t)bnx2x_8727_config_init,
6911         .read_status    = (read_status_t)bnx2x_8727_read_status,
6912         .link_reset     = (link_reset_t)bnx2x_8727_link_reset,
6913         .config_loopback = (config_loopback_t)NULL,
6914         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
6915         .hw_reset       = (hw_reset_t)bnx2x_8727_hw_reset,
6916         .set_link_led   = (set_link_led_t)bnx2x_8727_set_link_led,
6917         .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func
6918 };
6919 static struct bnx2x_phy phy_8481 = {
6920         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
6921         .addr           = 0xff,
6922         .flags          = FLAGS_FAN_FAILURE_DET_REQ |
6923                           FLAGS_REARM_LATCH_SIGNAL,
6924         .def_md_devad   = 0,
6925         .reserved       = 0,
6926         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6927         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6928         .mdio_ctrl      = 0,
6929         .supported      = (SUPPORTED_10baseT_Half |
6930                            SUPPORTED_10baseT_Full |
6931                            SUPPORTED_100baseT_Half |
6932                            SUPPORTED_100baseT_Full |
6933                            SUPPORTED_1000baseT_Full |
6934                            SUPPORTED_10000baseT_Full |
6935                            SUPPORTED_TP |
6936                            SUPPORTED_Autoneg |
6937                            SUPPORTED_Pause |
6938                            SUPPORTED_Asym_Pause),
6939         .media_type     = ETH_PHY_BASE_T,
6940         .ver_addr       = 0,
6941         .req_flow_ctrl  = 0,
6942         .req_line_speed = 0,
6943         .speed_cap_mask = 0,
6944         .req_duplex     = 0,
6945         .rsrv           = 0,
6946         .config_init    = (config_init_t)bnx2x_8481_config_init,
6947         .read_status    = (read_status_t)bnx2x_848xx_read_status,
6948         .link_reset     = (link_reset_t)bnx2x_8481_link_reset,
6949         .config_loopback = (config_loopback_t)NULL,
6950         .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
6951         .hw_reset       = (hw_reset_t)bnx2x_8481_hw_reset,
6952         .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
6953         .phy_specific_func = (phy_specific_func_t)NULL
6954 };
6955
6956 static struct bnx2x_phy phy_84823 = {
6957         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
6958         .addr           = 0xff,
6959         .flags          = FLAGS_FAN_FAILURE_DET_REQ |
6960                           FLAGS_REARM_LATCH_SIGNAL,
6961         .def_md_devad   = 0,
6962         .reserved       = 0,
6963         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6964         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6965         .mdio_ctrl      = 0,
6966         .supported      = (SUPPORTED_10baseT_Half |
6967                            SUPPORTED_10baseT_Full |
6968                            SUPPORTED_100baseT_Half |
6969                            SUPPORTED_100baseT_Full |
6970                            SUPPORTED_1000baseT_Full |
6971                            SUPPORTED_10000baseT_Full |
6972                            SUPPORTED_TP |
6973                            SUPPORTED_Autoneg |
6974                            SUPPORTED_Pause |
6975                            SUPPORTED_Asym_Pause),
6976         .media_type     = ETH_PHY_BASE_T,
6977         .ver_addr       = 0,
6978         .req_flow_ctrl  = 0,
6979         .req_line_speed = 0,
6980         .speed_cap_mask = 0,
6981         .req_duplex     = 0,
6982         .rsrv           = 0,
6983         .config_init    = (config_init_t)bnx2x_848x3_config_init,
6984         .read_status    = (read_status_t)bnx2x_848xx_read_status,
6985         .link_reset     = (link_reset_t)bnx2x_848x3_link_reset,
6986         .config_loopback = (config_loopback_t)NULL,
6987         .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
6988         .hw_reset       = (hw_reset_t)NULL,
6989         .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
6990         .phy_specific_func = (phy_specific_func_t)NULL
6991 };
6992
6993 /*****************************************************************/
6994 /*                                                               */
6995 /* Populate the phy according. Main function: bnx2x_populate_phy   */
6996 /*                                                               */
6997 /*****************************************************************/
6998
6999 static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
7000                                      struct bnx2x_phy *phy, u8 port,
7001                                      u8 phy_index)
7002 {
7003         /* Get the 4 lanes xgxs config rx and tx */
7004         u32 rx = 0, tx = 0, i;
7005         for (i = 0; i < 2; i++) {
7006                 /**
7007                  * INT_PHY and EXT_PHY1 share the same value location in the
7008                  * shmem. When num_phys is greater than 1, than this value
7009                  * applies only to EXT_PHY1
7010                  */
7011                 if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
7012                         rx = REG_RD(bp, shmem_base +
7013                                     offsetof(struct shmem_region,
7014                            dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
7015
7016                         tx = REG_RD(bp, shmem_base +
7017                                     offsetof(struct shmem_region,
7018                            dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
7019                 } else {
7020                         rx = REG_RD(bp, shmem_base +
7021                                     offsetof(struct shmem_region,
7022                           dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
7023
7024                         tx = REG_RD(bp, shmem_base +
7025                                     offsetof(struct shmem_region,
7026                           dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
7027                 }
7028
7029                 phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
7030                 phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
7031
7032                 phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
7033                 phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
7034         }
7035 }
7036
7037 static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
7038                                     u8 phy_index, u8 port)
7039 {
7040         u32 ext_phy_config = 0;
7041         switch (phy_index) {
7042         case EXT_PHY1:
7043                 ext_phy_config = REG_RD(bp, shmem_base +
7044                                               offsetof(struct shmem_region,
7045                         dev_info.port_hw_config[port].external_phy_config));
7046                 break;
7047         case EXT_PHY2:
7048                 ext_phy_config = REG_RD(bp, shmem_base +
7049                                               offsetof(struct shmem_region,
7050                         dev_info.port_hw_config[port].external_phy_config2));
7051                 break;
7052         default:
7053                 DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
7054                 return -EINVAL;
7055         }
7056
7057         return ext_phy_config;
7058 }
7059 static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
7060                                  struct bnx2x_phy *phy)
7061 {
7062         u32 phy_addr;
7063         u32 chip_id;
7064         u32 switch_cfg = (REG_RD(bp, shmem_base +
7065                                        offsetof(struct shmem_region,
7066                         dev_info.port_feature_config[port].link_config)) &
7067                           PORT_FEATURE_CONNECTED_SWITCH_MASK);
7068         chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16;
7069         switch (switch_cfg) {
7070         case SWITCH_CFG_1G:
7071                 phy_addr = REG_RD(bp,
7072                                         NIG_REG_SERDES0_CTRL_PHY_ADDR +
7073                                         port * 0x10);
7074                 *phy = phy_serdes;
7075                 break;
7076         case SWITCH_CFG_10G:
7077                 phy_addr = REG_RD(bp,
7078                                         NIG_REG_XGXS0_CTRL_PHY_ADDR +
7079                                         port * 0x18);
7080                 *phy = phy_xgxs;
7081                 break;
7082         default:
7083                 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
7084                 return -EINVAL;
7085         }
7086         phy->addr = (u8)phy_addr;
7087         phy->mdio_ctrl = bnx2x_get_emac_base(bp,
7088                                             SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
7089                                             port);
7090         if (CHIP_IS_E2(bp))
7091                 phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
7092         else
7093                 phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
7094
7095         DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
7096                    port, phy->addr, phy->mdio_ctrl);
7097
7098         bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
7099         return 0;
7100 }
7101
7102 static u8 bnx2x_populate_ext_phy(struct bnx2x *bp,
7103                                  u8 phy_index,
7104                                  u32 shmem_base,
7105                                  u32 shmem2_base,
7106                                  u8 port,
7107                                  struct bnx2x_phy *phy)
7108 {
7109         u32 ext_phy_config, phy_type, config2;
7110         u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
7111         ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
7112                                                   phy_index, port);
7113         phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
7114         /* Select the phy type */
7115         switch (phy_type) {
7116         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
7117                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
7118                 *phy = phy_8073;
7119                 break;
7120         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
7121                 *phy = phy_8705;
7122                 break;
7123         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
7124                 *phy = phy_8706;
7125                 break;
7126         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7127                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
7128                 *phy = phy_8726;
7129                 break;
7130         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
7131                 /* BCM8727_NOC => BCM8727 no over current */
7132                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
7133                 *phy = phy_8727;
7134                 phy->flags |= FLAGS_NOC;
7135                 break;
7136         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7137                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
7138                 *phy = phy_8727;
7139                 break;
7140         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
7141                 *phy = phy_8481;
7142                 break;
7143         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
7144                 *phy = phy_84823;
7145                 break;
7146         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
7147                 *phy = phy_7101;
7148                 break;
7149         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
7150                 *phy = phy_null;
7151                 return -EINVAL;
7152         default:
7153                 *phy = phy_null;
7154                 return 0;
7155         }
7156
7157         phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
7158         bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
7159
7160         /**
7161         * The shmem address of the phy version is located on different
7162         * structures. In case this structure is too old, do not set
7163         * the address
7164         */
7165         config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region,
7166                                         dev_info.shared_hw_config.config2));
7167         if (phy_index == EXT_PHY1) {
7168                 phy->ver_addr = shmem_base + offsetof(struct shmem_region,
7169                                 port_mb[port].ext_phy_fw_version);
7170
7171         /* Check specific mdc mdio settings */
7172         if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
7173                 mdc_mdio_access = config2 &
7174                 SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
7175         } else {
7176                 u32 size = REG_RD(bp, shmem2_base);
7177
7178                 if (size >
7179                     offsetof(struct shmem2_region, ext_phy_fw_version2)) {
7180                         phy->ver_addr = shmem2_base +
7181                             offsetof(struct shmem2_region,
7182                                      ext_phy_fw_version2[port]);
7183                 }
7184                 /* Check specific mdc mdio settings */
7185                 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
7186                         mdc_mdio_access = (config2 &
7187                         SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
7188                         (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
7189                          SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
7190         }
7191         phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
7192
7193         /**
7194          * In case mdc/mdio_access of the external phy is different than the
7195          * mdc/mdio access of the XGXS, a HW lock must be taken in each access
7196          * to prevent one port interfere with another port's CL45 operations.
7197          */
7198         if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH)
7199                 phy->flags |= FLAGS_HW_LOCK_REQUIRED;
7200         DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n",
7201                    phy_type, port, phy_index);
7202         DP(NETIF_MSG_LINK, "             addr=0x%x, mdio_ctl=0x%x\n",
7203                    phy->addr, phy->mdio_ctrl);
7204         return 0;
7205 }
7206
7207 static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
7208                              u32 shmem2_base, u8 port, struct bnx2x_phy *phy)
7209 {
7210         u8 status = 0;
7211         phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
7212         if (phy_index == INT_PHY)
7213                 return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
7214         status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
7215                                         port, phy);
7216         return status;
7217 }
7218
7219 static void bnx2x_phy_def_cfg(struct link_params *params,
7220                               struct bnx2x_phy *phy,
7221                               u8 phy_index)
7222 {
7223         struct bnx2x *bp = params->bp;
7224         u32 link_config;
7225         /* Populate the default phy configuration for MF mode */
7226         if (phy_index == EXT_PHY2) {
7227                 link_config = REG_RD(bp, params->shmem_base +
7228                                          offsetof(struct shmem_region, dev_info.
7229                         port_feature_config[params->port].link_config2));
7230                 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
7231                                         offsetof(struct shmem_region, dev_info.
7232                         port_hw_config[params->port].speed_capability_mask2));
7233         } else {
7234                 link_config = REG_RD(bp, params->shmem_base +
7235                                 offsetof(struct shmem_region, dev_info.
7236                                 port_feature_config[params->port].link_config));
7237                 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
7238                                 offsetof(struct shmem_region, dev_info.
7239                            port_hw_config[params->port].speed_capability_mask));
7240         }
7241         DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask"
7242                        " 0x%x\n", phy_index, link_config, phy->speed_cap_mask);
7243
7244         phy->req_duplex = DUPLEX_FULL;
7245         switch (link_config  & PORT_FEATURE_LINK_SPEED_MASK) {
7246         case PORT_FEATURE_LINK_SPEED_10M_HALF:
7247                 phy->req_duplex = DUPLEX_HALF;
7248         case PORT_FEATURE_LINK_SPEED_10M_FULL:
7249                 phy->req_line_speed = SPEED_10;
7250                 break;
7251         case PORT_FEATURE_LINK_SPEED_100M_HALF:
7252                 phy->req_duplex = DUPLEX_HALF;
7253         case PORT_FEATURE_LINK_SPEED_100M_FULL:
7254                 phy->req_line_speed = SPEED_100;
7255                 break;
7256         case PORT_FEATURE_LINK_SPEED_1G:
7257                 phy->req_line_speed = SPEED_1000;
7258                 break;
7259         case PORT_FEATURE_LINK_SPEED_2_5G:
7260                 phy->req_line_speed = SPEED_2500;
7261                 break;
7262         case PORT_FEATURE_LINK_SPEED_10G_CX4:
7263                 phy->req_line_speed = SPEED_10000;
7264                 break;
7265         default:
7266                 phy->req_line_speed = SPEED_AUTO_NEG;
7267                 break;
7268         }
7269
7270         switch (link_config  & PORT_FEATURE_FLOW_CONTROL_MASK) {
7271         case PORT_FEATURE_FLOW_CONTROL_AUTO:
7272                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
7273                 break;
7274         case PORT_FEATURE_FLOW_CONTROL_TX:
7275                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
7276                 break;
7277         case PORT_FEATURE_FLOW_CONTROL_RX:
7278                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
7279                 break;
7280         case PORT_FEATURE_FLOW_CONTROL_BOTH:
7281                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
7282                 break;
7283         default:
7284                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7285                 break;
7286         }
7287 }
7288
7289 u32 bnx2x_phy_selection(struct link_params *params)
7290 {
7291         u32 phy_config_swapped, prio_cfg;
7292         u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
7293
7294         phy_config_swapped = params->multi_phy_config &
7295                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
7296
7297         prio_cfg = params->multi_phy_config &
7298                         PORT_HW_CFG_PHY_SELECTION_MASK;
7299
7300         if (phy_config_swapped) {
7301                 switch (prio_cfg) {
7302                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
7303                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
7304                      break;
7305                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
7306                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
7307                      break;
7308                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
7309                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
7310                      break;
7311                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
7312                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
7313                      break;
7314                 }
7315         } else
7316                 return_cfg = prio_cfg;
7317
7318         return return_cfg;
7319 }
7320
7321
7322 u8 bnx2x_phy_probe(struct link_params *params)
7323 {
7324         u8 phy_index, actual_phy_idx, link_cfg_idx;
7325         u32 phy_config_swapped;
7326         struct bnx2x *bp = params->bp;
7327         struct bnx2x_phy *phy;
7328         params->num_phys = 0;
7329         DP(NETIF_MSG_LINK, "Begin phy probe\n");
7330         phy_config_swapped = params->multi_phy_config &
7331                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
7332
7333         for (phy_index = INT_PHY; phy_index < MAX_PHYS;
7334               phy_index++) {
7335                 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
7336                 actual_phy_idx = phy_index;
7337                 if (phy_config_swapped) {
7338                         if (phy_index == EXT_PHY1)
7339                                 actual_phy_idx = EXT_PHY2;
7340                         else if (phy_index == EXT_PHY2)
7341                                 actual_phy_idx = EXT_PHY1;
7342                 }
7343                 DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x,"
7344                                " actual_phy_idx %x\n", phy_config_swapped,
7345                            phy_index, actual_phy_idx);
7346                 phy = &params->phy[actual_phy_idx];
7347                 if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
7348                                        params->shmem2_base, params->port,
7349                                        phy) != 0) {
7350                         params->num_phys = 0;
7351                         DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
7352                                    phy_index);
7353                         for (phy_index = INT_PHY;
7354                               phy_index < MAX_PHYS;
7355                               phy_index++)
7356                                 *phy = phy_null;
7357                         return -EINVAL;
7358                 }
7359                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
7360                         break;
7361
7362                 bnx2x_phy_def_cfg(params, phy, phy_index);
7363                 params->num_phys++;
7364         }
7365
7366         DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
7367         return 0;
7368 }
7369
7370 static void set_phy_vars(struct link_params *params)
7371 {
7372         struct bnx2x *bp = params->bp;
7373         u8 actual_phy_idx, phy_index, link_cfg_idx;
7374         u8 phy_config_swapped = params->multi_phy_config &
7375                         PORT_HW_CFG_PHY_SWAPPED_ENABLED;
7376         for (phy_index = INT_PHY; phy_index < params->num_phys;
7377               phy_index++) {
7378                 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
7379                 actual_phy_idx = phy_index;
7380                 if (phy_config_swapped) {
7381                         if (phy_index == EXT_PHY1)
7382                                 actual_phy_idx = EXT_PHY2;
7383                         else if (phy_index == EXT_PHY2)
7384                                 actual_phy_idx = EXT_PHY1;
7385                 }
7386                 params->phy[actual_phy_idx].req_flow_ctrl  =
7387                         params->req_flow_ctrl[link_cfg_idx];
7388
7389                 params->phy[actual_phy_idx].req_line_speed =
7390                         params->req_line_speed[link_cfg_idx];
7391
7392                 params->phy[actual_phy_idx].speed_cap_mask =
7393                         params->speed_cap_mask[link_cfg_idx];
7394
7395                 params->phy[actual_phy_idx].req_duplex =
7396                         params->req_duplex[link_cfg_idx];
7397
7398                 DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
7399                            " speed_cap_mask %x\n",
7400                            params->phy[actual_phy_idx].req_flow_ctrl,
7401                            params->phy[actual_phy_idx].req_line_speed,
7402                            params->phy[actual_phy_idx].speed_cap_mask);
7403         }
7404 }
7405
7406 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
7407 {
7408         struct bnx2x *bp = params->bp;
7409         DP(NETIF_MSG_LINK, "Phy Initialization started\n");
7410         DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n",
7411                    params->req_line_speed[0], params->req_flow_ctrl[0]);
7412         DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n",
7413                    params->req_line_speed[1], params->req_flow_ctrl[1]);
7414         vars->link_status = 0;
7415         vars->phy_link_up = 0;
7416         vars->link_up = 0;
7417         vars->line_speed = 0;
7418         vars->duplex = DUPLEX_FULL;
7419         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7420         vars->mac_type = MAC_TYPE_NONE;
7421         vars->phy_flags = 0;
7422
7423         /* disable attentions */
7424         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
7425                        (NIG_MASK_XGXS0_LINK_STATUS |
7426                         NIG_MASK_XGXS0_LINK10G |
7427                         NIG_MASK_SERDES0_LINK_STATUS |
7428                         NIG_MASK_MI_INT));
7429
7430         bnx2x_emac_init(params, vars);
7431
7432         if (params->num_phys == 0) {
7433                 DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
7434                 return -EINVAL;
7435         }
7436         set_phy_vars(params);
7437
7438         DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
7439         if (CHIP_REV_IS_FPGA(bp)) {
7440
7441                 vars->link_up = 1;
7442                 vars->line_speed = SPEED_10000;
7443                 vars->duplex = DUPLEX_FULL;
7444                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7445                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
7446                 /* enable on E1.5 FPGA */
7447                 if (CHIP_IS_E1H(bp)) {
7448                         vars->flow_ctrl |=
7449                                         (BNX2X_FLOW_CTRL_TX |
7450                                          BNX2X_FLOW_CTRL_RX);
7451                         vars->link_status |=
7452                                         (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
7453                                          LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
7454                 }
7455
7456                 bnx2x_emac_enable(params, vars, 0);
7457                 if (!(CHIP_IS_E2(bp)))
7458                         bnx2x_pbf_update(params, vars->flow_ctrl,
7459                                          vars->line_speed);
7460                 /* disable drain */
7461                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
7462
7463                 /* update shared memory */
7464                 bnx2x_update_mng(params, vars->link_status);
7465
7466                 return 0;
7467
7468         } else
7469         if (CHIP_REV_IS_EMUL(bp)) {
7470
7471                 vars->link_up = 1;
7472                 vars->line_speed = SPEED_10000;
7473                 vars->duplex = DUPLEX_FULL;
7474                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7475                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
7476
7477                 bnx2x_bmac_enable(params, vars, 0);
7478
7479                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
7480                 /* Disable drain */
7481                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
7482                                     + params->port*4, 0);
7483
7484                 /* update shared memory */
7485                 bnx2x_update_mng(params, vars->link_status);
7486
7487                 return 0;
7488
7489         } else
7490         if (params->loopback_mode == LOOPBACK_BMAC) {
7491
7492                 vars->link_up = 1;
7493                 vars->line_speed = SPEED_10000;
7494                 vars->duplex = DUPLEX_FULL;
7495                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7496                 vars->mac_type = MAC_TYPE_BMAC;
7497
7498                 vars->phy_flags = PHY_XGXS_FLAG;
7499
7500                 bnx2x_xgxs_deassert(params);
7501
7502                 /* set bmac loopback */
7503                 bnx2x_bmac_enable(params, vars, 1);
7504
7505                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
7506                     params->port*4, 0);
7507
7508         } else if (params->loopback_mode == LOOPBACK_EMAC) {
7509
7510                 vars->link_up = 1;
7511                 vars->line_speed = SPEED_1000;
7512                 vars->duplex = DUPLEX_FULL;
7513                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7514                 vars->mac_type = MAC_TYPE_EMAC;
7515
7516                 vars->phy_flags = PHY_XGXS_FLAG;
7517
7518                 bnx2x_xgxs_deassert(params);
7519                 /* set bmac loopback */
7520                 bnx2x_emac_enable(params, vars, 1);
7521                 bnx2x_emac_program(params, vars);
7522                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
7523                     params->port*4, 0);
7524
7525         } else if ((params->loopback_mode == LOOPBACK_XGXS) ||
7526                    (params->loopback_mode == LOOPBACK_EXT_PHY)) {
7527
7528                 vars->link_up = 1;
7529                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7530                 vars->duplex = DUPLEX_FULL;
7531                 if (params->req_line_speed[0] == SPEED_1000) {
7532                         vars->line_speed = SPEED_1000;
7533                         vars->mac_type = MAC_TYPE_EMAC;
7534                 } else {
7535                         vars->line_speed = SPEED_10000;
7536                         vars->mac_type = MAC_TYPE_BMAC;
7537                 }
7538
7539                 bnx2x_xgxs_deassert(params);
7540                 bnx2x_link_initialize(params, vars);
7541
7542                 if (params->req_line_speed[0] == SPEED_1000) {
7543                         bnx2x_emac_program(params, vars);
7544                         bnx2x_emac_enable(params, vars, 0);
7545                 } else
7546                 bnx2x_bmac_enable(params, vars, 0);
7547
7548                 if (params->loopback_mode == LOOPBACK_XGXS) {
7549                         /* set 10G XGXS loopback */
7550                         params->phy[INT_PHY].config_loopback(
7551                                 &params->phy[INT_PHY],
7552                                 params);
7553
7554                 } else {
7555                         /* set external phy loopback */
7556                         u8 phy_index;
7557                         for (phy_index = EXT_PHY1;
7558                               phy_index < params->num_phys; phy_index++) {
7559                                 if (params->phy[phy_index].config_loopback)
7560                                         params->phy[phy_index].config_loopback(
7561                                                 &params->phy[phy_index],
7562                                                 params);
7563                         }
7564                 }
7565
7566                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
7567                             params->port*4, 0);
7568
7569                 bnx2x_set_led(params, vars,
7570                               LED_MODE_OPER, vars->line_speed);
7571         } else
7572         /* No loopback */
7573         {
7574                 if (params->switch_cfg == SWITCH_CFG_10G)
7575                         bnx2x_xgxs_deassert(params);
7576                 else
7577                         bnx2x_serdes_deassert(bp, params->port);
7578
7579                 bnx2x_link_initialize(params, vars);
7580                 msleep(30);
7581                 bnx2x_link_int_enable(params);
7582         }
7583         return 0;
7584 }
7585 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
7586                   u8 reset_ext_phy)
7587 {
7588         struct bnx2x *bp = params->bp;
7589         u8 phy_index, port = params->port, clear_latch_ind = 0;
7590         DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
7591         /* disable attentions */
7592         vars->link_status = 0;
7593         bnx2x_update_mng(params, vars->link_status);
7594         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
7595                      (NIG_MASK_XGXS0_LINK_STATUS |
7596                       NIG_MASK_XGXS0_LINK10G |
7597                       NIG_MASK_SERDES0_LINK_STATUS |
7598                       NIG_MASK_MI_INT));
7599
7600         /* activate nig drain */
7601         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
7602
7603         /* disable nig egress interface */
7604         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
7605         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
7606
7607         /* Stop BigMac rx */
7608         bnx2x_bmac_rx_disable(bp, port);
7609
7610         /* disable emac */
7611         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
7612
7613         msleep(10);
7614         /* The PHY reset is controled by GPIO 1
7615          * Hold it as vars low
7616          */
7617          /* clear link led */
7618         bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
7619
7620         if (reset_ext_phy) {
7621                 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
7622                       phy_index++) {
7623                         if (params->phy[phy_index].link_reset)
7624                                 params->phy[phy_index].link_reset(
7625                                         &params->phy[phy_index],
7626                                         params);
7627                         if (params->phy[phy_index].flags &
7628                             FLAGS_REARM_LATCH_SIGNAL)
7629                                 clear_latch_ind = 1;
7630                 }
7631         }
7632
7633         if (clear_latch_ind) {
7634                 /* Clear latching indication */
7635                 bnx2x_rearm_latch_signal(bp, port, 0);
7636                 bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4,
7637                                1 << NIG_LATCH_BC_ENABLE_MI_INT);
7638         }
7639         if (params->phy[INT_PHY].link_reset)
7640                 params->phy[INT_PHY].link_reset(
7641                         &params->phy[INT_PHY], params);
7642         /* reset BigMac */
7643         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
7644                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
7645
7646         /* disable nig ingress interface */
7647         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
7648         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
7649         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
7650         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
7651         vars->link_up = 0;
7652         return 0;
7653 }
7654
7655 /****************************************************************************/
7656 /*                              Common function                             */
7657 /****************************************************************************/
7658 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp,
7659                                      u32 shmem_base_path[],
7660                                      u32 shmem2_base_path[], u8 phy_index,
7661                                      u32 chip_id)
7662 {
7663         struct bnx2x_phy phy[PORT_MAX];
7664         struct bnx2x_phy *phy_blk[PORT_MAX];
7665         u16 val;
7666         s8 port;
7667         s8 port_of_path = 0;
7668
7669         bnx2x_ext_phy_hw_reset(bp, 0);
7670         /* PART1 - Reset both phys */
7671         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7672                 u32 shmem_base, shmem2_base;
7673                 /* In E2, same phy is using for port0 of the two paths */
7674                 if (CHIP_IS_E2(bp)) {
7675                         shmem_base = shmem_base_path[port];
7676                         shmem2_base = shmem2_base_path[port];
7677                         port_of_path = 0;
7678                 } else {
7679                         shmem_base = shmem_base_path[0];
7680                         shmem2_base = shmem2_base_path[0];
7681                         port_of_path = port;
7682                 }
7683
7684                 /* Extract the ext phy address for the port */
7685                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7686                                        port_of_path, &phy[port]) !=
7687                     0) {
7688                         DP(NETIF_MSG_LINK, "populate_phy failed\n");
7689                         return -EINVAL;
7690                 }
7691                 /* disable attentions */
7692                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
7693                                port_of_path*4,
7694                              (NIG_MASK_XGXS0_LINK_STATUS |
7695                               NIG_MASK_XGXS0_LINK10G |
7696                               NIG_MASK_SERDES0_LINK_STATUS |
7697                               NIG_MASK_MI_INT));
7698
7699                 /* Need to take the phy out of low power mode in order
7700                         to write to access its registers */
7701                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7702                                   MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
7703
7704                 /* Reset the phy */
7705                 bnx2x_cl45_write(bp, &phy[port],
7706                                MDIO_PMA_DEVAD,
7707                                MDIO_PMA_REG_CTRL,
7708                                1<<15);
7709         }
7710
7711         /* Add delay of 150ms after reset */
7712         msleep(150);
7713
7714         if (phy[PORT_0].addr & 0x1) {
7715                 phy_blk[PORT_0] = &(phy[PORT_1]);
7716                 phy_blk[PORT_1] = &(phy[PORT_0]);
7717         } else {
7718                 phy_blk[PORT_0] = &(phy[PORT_0]);
7719                 phy_blk[PORT_1] = &(phy[PORT_1]);
7720         }
7721
7722         /* PART2 - Download firmware to both phys */
7723         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7724                 u16 fw_ver1;
7725                 if (CHIP_IS_E2(bp))
7726                         port_of_path = 0;
7727                 else
7728                         port_of_path = port;
7729
7730                 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
7731                            phy_blk[port]->addr);
7732                 bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
7733                                                   port_of_path);
7734
7735                 bnx2x_cl45_read(bp, phy_blk[port],
7736                               MDIO_PMA_DEVAD,
7737                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
7738                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
7739                         DP(NETIF_MSG_LINK,
7740                                  "bnx2x_8073_common_init_phy port %x:"
7741                                  "Download failed. fw version = 0x%x\n",
7742                                  port, fw_ver1);
7743                         return -EINVAL;
7744                 }
7745
7746                 /* Only set bit 10 = 1 (Tx power down) */
7747                 bnx2x_cl45_read(bp, phy_blk[port],
7748                               MDIO_PMA_DEVAD,
7749                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
7750
7751                 /* Phase1 of TX_POWER_DOWN reset */
7752                 bnx2x_cl45_write(bp, phy_blk[port],
7753                                MDIO_PMA_DEVAD,
7754                                MDIO_PMA_REG_TX_POWER_DOWN,
7755                                (val | 1<<10));
7756         }
7757
7758         /* Toggle Transmitter: Power down and then up with 600ms
7759            delay between */
7760         msleep(600);
7761
7762         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
7763         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7764                 /* Phase2 of POWER_DOWN_RESET */
7765                 /* Release bit 10 (Release Tx power down) */
7766                 bnx2x_cl45_read(bp, phy_blk[port],
7767                               MDIO_PMA_DEVAD,
7768                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
7769
7770                 bnx2x_cl45_write(bp, phy_blk[port],
7771                                MDIO_PMA_DEVAD,
7772                                MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
7773                 msleep(15);
7774
7775                 /* Read modify write the SPI-ROM version select register */
7776                 bnx2x_cl45_read(bp, phy_blk[port],
7777                               MDIO_PMA_DEVAD,
7778                               MDIO_PMA_REG_EDC_FFE_MAIN, &val);
7779                 bnx2x_cl45_write(bp, phy_blk[port],
7780                               MDIO_PMA_DEVAD,
7781                               MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
7782
7783                 /* set GPIO2 back to LOW */
7784                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7785                                   MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
7786         }
7787         return 0;
7788 }
7789 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp,
7790                                      u32 shmem_base_path[],
7791                                      u32 shmem2_base_path[], u8 phy_index,
7792                                      u32 chip_id)
7793 {
7794         u32 val;
7795         s8 port;
7796         struct bnx2x_phy phy;
7797         /* Use port1 because of the static port-swap */
7798         /* Enable the module detection interrupt */
7799         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
7800         val |= ((1<<MISC_REGISTERS_GPIO_3)|
7801                 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
7802         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
7803
7804         bnx2x_ext_phy_hw_reset(bp, 0);
7805         msleep(5);
7806         for (port = 0; port < PORT_MAX; port++) {
7807                 u32 shmem_base, shmem2_base;
7808
7809                 /* In E2, same phy is using for port0 of the two paths */
7810                 if (CHIP_IS_E2(bp)) {
7811                         shmem_base = shmem_base_path[port];
7812                         shmem2_base = shmem2_base_path[port];
7813                 } else {
7814                         shmem_base = shmem_base_path[0];
7815                         shmem2_base = shmem2_base_path[0];
7816                 }
7817                 /* Extract the ext phy address for the port */
7818                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7819                                        port, &phy) !=
7820                     0) {
7821                         DP(NETIF_MSG_LINK, "populate phy failed\n");
7822                         return -EINVAL;
7823                 }
7824
7825                 /* Reset phy*/
7826                 bnx2x_cl45_write(bp, &phy,
7827                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
7828
7829
7830                 /* Set fault module detected LED on */
7831                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
7832                                   MISC_REGISTERS_GPIO_HIGH,
7833                                   port);
7834         }
7835
7836         return 0;
7837 }
7838 static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp,
7839                                      u32 shmem_base_path[],
7840                                      u32 shmem2_base_path[], u8 phy_index,
7841                                      u32 chip_id)
7842 {
7843         s8 port;
7844         u32 swap_val, swap_override;
7845         struct bnx2x_phy phy[PORT_MAX];
7846         struct bnx2x_phy *phy_blk[PORT_MAX];
7847         s8 port_of_path;
7848         swap_val = REG_RD(bp,  NIG_REG_PORT_SWAP);
7849         swap_override = REG_RD(bp,  NIG_REG_STRAP_OVERRIDE);
7850
7851         port = 1;
7852
7853         bnx2x_ext_phy_hw_reset(bp, port ^ (swap_val && swap_override));
7854
7855         /* Calculate the port based on port swap */
7856         port ^= (swap_val && swap_override);
7857
7858         msleep(5);
7859
7860         /* PART1 - Reset both phys */
7861         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7862                 u32 shmem_base, shmem2_base;
7863
7864                 /* In E2, same phy is using for port0 of the two paths */
7865                 if (CHIP_IS_E2(bp)) {
7866                         shmem_base = shmem_base_path[port];
7867                         shmem2_base = shmem2_base_path[port];
7868                         port_of_path = 0;
7869                 } else {
7870                         shmem_base = shmem_base_path[0];
7871                         shmem2_base = shmem2_base_path[0];
7872                         port_of_path = port;
7873                 }
7874
7875                 /* Extract the ext phy address for the port */
7876                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7877                                        port_of_path, &phy[port]) !=
7878                                        0) {
7879                         DP(NETIF_MSG_LINK, "populate phy failed\n");
7880                         return -EINVAL;
7881                 }
7882                 /* disable attentions */
7883                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
7884                                port_of_path*4,
7885                                (NIG_MASK_XGXS0_LINK_STATUS |
7886                                 NIG_MASK_XGXS0_LINK10G |
7887                                 NIG_MASK_SERDES0_LINK_STATUS |
7888                                 NIG_MASK_MI_INT));
7889
7890
7891                 /* Reset the phy */
7892                 bnx2x_cl45_write(bp, &phy[port],
7893                                MDIO_PMA_DEVAD,
7894                                MDIO_PMA_REG_CTRL,
7895                                1<<15);
7896         }
7897
7898         /* Add delay of 150ms after reset */
7899         msleep(150);
7900         if (phy[PORT_0].addr & 0x1) {
7901                 phy_blk[PORT_0] = &(phy[PORT_1]);
7902                 phy_blk[PORT_1] = &(phy[PORT_0]);
7903         } else {
7904                 phy_blk[PORT_0] = &(phy[PORT_0]);
7905                 phy_blk[PORT_1] = &(phy[PORT_1]);
7906         }
7907         /* PART2 - Download firmware to both phys */
7908         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7909                 u16 fw_ver1;
7910                  if (CHIP_IS_E2(bp))
7911                         port_of_path = 0;
7912                 else
7913                         port_of_path = port;
7914                 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
7915                            phy_blk[port]->addr);
7916                 bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
7917                                                   port_of_path);
7918                 bnx2x_cl45_read(bp, phy_blk[port],
7919                               MDIO_PMA_DEVAD,
7920                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
7921                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
7922                         DP(NETIF_MSG_LINK,
7923                                  "bnx2x_8727_common_init_phy port %x:"
7924                                  "Download failed. fw version = 0x%x\n",
7925                                  port, fw_ver1);
7926                         return -EINVAL;
7927                 }
7928         }
7929
7930         return 0;
7931 }
7932
7933 static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
7934                                     u32 shmem2_base_path[], u8 phy_index,
7935                                     u32 ext_phy_type, u32 chip_id)
7936 {
7937         u8 rc = 0;
7938
7939         switch (ext_phy_type) {
7940         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
7941                 rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
7942                                                 shmem2_base_path,
7943                                                 phy_index, chip_id);
7944                 break;
7945
7946         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7947         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
7948                 rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
7949                                                 shmem2_base_path,
7950                                                 phy_index, chip_id);
7951                 break;
7952
7953         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7954                 /* GPIO1 affects both ports, so there's need to pull
7955                 it for single port alone */
7956                 rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
7957                                                 shmem2_base_path,
7958                                                 phy_index, chip_id);
7959                 break;
7960         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
7961                 rc = -EINVAL;
7962                 break;
7963         default:
7964                 DP(NETIF_MSG_LINK,
7965                          "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
7966                          ext_phy_type);
7967                 break;
7968         }
7969
7970         return rc;
7971 }
7972
7973 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
7974                          u32 shmem2_base_path[], u32 chip_id)
7975 {
7976         u8 rc = 0;
7977         u32 phy_ver;
7978         u8 phy_index;
7979         u32 ext_phy_type, ext_phy_config;
7980         DP(NETIF_MSG_LINK, "Begin common phy init\n");
7981
7982         if (CHIP_REV_IS_EMUL(bp))
7983                 return 0;
7984
7985         /* Check if common init was already done */
7986         phy_ver = REG_RD(bp, shmem_base_path[0] +
7987                          offsetof(struct shmem_region,
7988                                   port_mb[PORT_0].ext_phy_fw_version));
7989         if (phy_ver) {
7990                 DP(NETIF_MSG_LINK, "Not doing common init; phy ver is 0x%x\n",
7991                                phy_ver);
7992                 return 0;
7993         }
7994
7995         /* Read the ext_phy_type for arbitrary port(0) */
7996         for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
7997               phy_index++) {
7998                 ext_phy_config = bnx2x_get_ext_phy_config(bp,
7999                                                           shmem_base_path[0],
8000                                                           phy_index, 0);
8001                 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
8002                 rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
8003                                                 shmem2_base_path,
8004                                                 phy_index, ext_phy_type,
8005                                                 chip_id);
8006         }
8007         return rc;
8008 }
8009
8010 u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
8011 {
8012         u8 phy_index;
8013         struct bnx2x_phy phy;
8014         for (phy_index = INT_PHY; phy_index < MAX_PHYS;
8015               phy_index++) {
8016                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
8017                                        0, &phy) != 0) {
8018                         DP(NETIF_MSG_LINK, "populate phy failed\n");
8019                         return 0;
8020                 }
8021
8022                 if (phy.flags & FLAGS_HW_LOCK_REQUIRED)
8023                         return 1;
8024         }
8025         return 0;
8026 }
8027
8028 u8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
8029                              u32 shmem_base,
8030                              u32 shmem2_base,
8031                              u8 port)
8032 {
8033         u8 phy_index, fan_failure_det_req = 0;
8034         struct bnx2x_phy phy;
8035         for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
8036               phy_index++) {
8037                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
8038                                        port, &phy)
8039                     != 0) {
8040                         DP(NETIF_MSG_LINK, "populate phy failed\n");
8041                         return 0;
8042                 }
8043                 fan_failure_det_req |= (phy.flags &
8044                                         FLAGS_FAN_FAILURE_DET_REQ);
8045         }
8046         return fan_failure_det_req;
8047 }
8048
8049 void bnx2x_hw_reset_phy(struct link_params *params)
8050 {
8051         u8 phy_index;
8052         for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
8053               phy_index++) {
8054                 if (params->phy[phy_index].hw_reset) {
8055                         params->phy[phy_index].hw_reset(
8056                                 &params->phy[phy_index],
8057                                 params);
8058                         params->phy[phy_index] = phy_null;
8059                 }
8060         }
8061 }