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