]> nv-tegra.nvidia Code Review - linux-3.10.git/blob - drivers/net/bnx2x/bnx2x_link.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-3.10.git] / drivers / net / bnx2x / bnx2x_link.c
1 /* Copyright 2008-2009 Broadcom Corporation
2  *
3  * Unless you and Broadcom execute a separate written software license
4  * agreement governing use of this software, this software is licensed to you
5  * under the terms of the GNU General Public License version 2, available
6  * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
7  *
8  * Notwithstanding the above, under no circumstances may you combine this
9  * software in any way with any other Broadcom software provided under a
10  * license other than the GPL, without Broadcom's express prior written
11  * consent.
12  *
13  * Written by Yaniv Rosner
14  *
15  */
16
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/pci.h>
22 #include <linux/netdevice.h>
23 #include <linux/delay.h>
24 #include <linux/ethtool.h>
25 #include <linux/mutex.h>
26
27 #include "bnx2x.h"
28
29 /********************************************************/
30 #define ETH_HLEN                        14
31 #define ETH_OVREHEAD            (ETH_HLEN + 8 + 8)/* 16 for CRC + VLAN + LLC */
32 #define ETH_MIN_PACKET_SIZE             60
33 #define ETH_MAX_PACKET_SIZE             1500
34 #define ETH_MAX_JUMBO_PACKET_SIZE       9600
35 #define MDIO_ACCESS_TIMEOUT             1000
36 #define BMAC_CONTROL_RX_ENABLE  2
37
38 /***********************************************************/
39 /*                      Shortcut definitions               */
40 /***********************************************************/
41
42 #define NIG_LATCH_BC_ENABLE_MI_INT 0
43
44 #define NIG_STATUS_EMAC0_MI_INT \
45                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
46 #define NIG_STATUS_XGXS0_LINK10G \
47                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
48 #define NIG_STATUS_XGXS0_LINK_STATUS \
49                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
50 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
51                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
52 #define NIG_STATUS_SERDES0_LINK_STATUS \
53                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
54 #define NIG_MASK_MI_INT \
55                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
56 #define NIG_MASK_XGXS0_LINK10G \
57                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
58 #define NIG_MASK_XGXS0_LINK_STATUS \
59                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
60 #define NIG_MASK_SERDES0_LINK_STATUS \
61                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
62
63 #define MDIO_AN_CL73_OR_37_COMPLETE \
64                 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
65                  MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
66
67 #define XGXS_RESET_BITS \
68         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
69          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
70          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
71          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
72          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
73
74 #define SERDES_RESET_BITS \
75         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
76          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
77          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
78          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
79
80 #define AUTONEG_CL37            SHARED_HW_CFG_AN_ENABLE_CL37
81 #define AUTONEG_CL73            SHARED_HW_CFG_AN_ENABLE_CL73
82 #define AUTONEG_BAM             SHARED_HW_CFG_AN_ENABLE_BAM
83 #define AUTONEG_PARALLEL \
84                                 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
85 #define AUTONEG_SGMII_FIBER_AUTODET \
86                                 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
87 #define AUTONEG_REMOTE_PHY      SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
88
89 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
90                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
91 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
92                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
93 #define GP_STATUS_SPEED_MASK \
94                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
95 #define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
96 #define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
97 #define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
98 #define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
99 #define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
100 #define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
101 #define GP_STATUS_10G_HIG \
102                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
103 #define GP_STATUS_10G_CX4 \
104                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
105 #define GP_STATUS_12G_HIG \
106                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
107 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
108 #define GP_STATUS_13G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
109 #define GP_STATUS_15G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
110 #define GP_STATUS_16G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
111 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
112 #define GP_STATUS_10G_KX4 \
113                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
114
115 #define LINK_10THD                      LINK_STATUS_SPEED_AND_DUPLEX_10THD
116 #define LINK_10TFD                      LINK_STATUS_SPEED_AND_DUPLEX_10TFD
117 #define LINK_100TXHD            LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
118 #define LINK_100T4                      LINK_STATUS_SPEED_AND_DUPLEX_100T4
119 #define LINK_100TXFD            LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
120 #define LINK_1000THD            LINK_STATUS_SPEED_AND_DUPLEX_1000THD
121 #define LINK_1000TFD            LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
122 #define LINK_1000XFD            LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
123 #define LINK_2500THD            LINK_STATUS_SPEED_AND_DUPLEX_2500THD
124 #define LINK_2500TFD            LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
125 #define LINK_2500XFD            LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
126 #define LINK_10GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
127 #define LINK_10GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
128 #define LINK_12GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
129 #define LINK_12GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
130 #define LINK_12_5GTFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
131 #define LINK_12_5GXFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
132 #define LINK_13GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
133 #define LINK_13GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
134 #define LINK_15GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
135 #define LINK_15GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
136 #define LINK_16GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
137 #define LINK_16GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
138
139 #define PHY_XGXS_FLAG                   0x1
140 #define PHY_SGMII_FLAG                  0x2
141 #define PHY_SERDES_FLAG                 0x4
142
143 /* */
144 #define SFP_EEPROM_CON_TYPE_ADDR                0x2
145         #define SFP_EEPROM_CON_TYPE_VAL_LC              0x7
146         #define SFP_EEPROM_CON_TYPE_VAL_COPPER  0x21
147
148
149 #define SFP_EEPROM_COMP_CODE_ADDR               0x3
150         #define SFP_EEPROM_COMP_CODE_SR_MASK    (1<<4)
151         #define SFP_EEPROM_COMP_CODE_LR_MASK    (1<<5)
152         #define SFP_EEPROM_COMP_CODE_LRM_MASK   (1<<6)
153
154 #define SFP_EEPROM_FC_TX_TECH_ADDR              0x8
155         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
156         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE      0x8
157
158 #define SFP_EEPROM_OPTIONS_ADDR                 0x40
159         #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
160 #define SFP_EEPROM_OPTIONS_SIZE                 2
161
162 #define EDC_MODE_LINEAR                         0x0022
163 #define EDC_MODE_LIMITING                               0x0044
164 #define EDC_MODE_PASSIVE_DAC                    0x0055
165
166
167 #define ETS_BW_LIMIT_CREDIT_UPPER_BOUND         (0x5000)
168 #define ETS_BW_LIMIT_CREDIT_WEIGHT              (0x5000)
169 /**********************************************************/
170 /*                     INTERFACE                          */
171 /**********************************************************/
172
173 #define CL45_WR_OVER_CL22(_bp, _phy, _bank, _addr, _val) \
174         bnx2x_cl45_write(_bp, _phy, \
175                 (_phy)->def_md_devad, \
176                 (_bank + (_addr & 0xf)), \
177                 _val)
178
179 #define CL45_RD_OVER_CL22(_bp, _phy, _bank, _addr, _val) \
180         bnx2x_cl45_read(_bp, _phy, \
181                 (_phy)->def_md_devad, \
182                 (_bank + (_addr & 0xf)), \
183                 _val)
184
185 static u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
186                           u8 devad, u16 reg, u16 *ret_val);
187
188 static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
189                            u8 devad, u16 reg, u16 val);
190
191 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
192 {
193         u32 val = REG_RD(bp, reg);
194
195         val |= bits;
196         REG_WR(bp, reg, val);
197         return val;
198 }
199
200 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
201 {
202         u32 val = REG_RD(bp, reg);
203
204         val &= ~bits;
205         REG_WR(bp, reg, val);
206         return val;
207 }
208
209 /******************************************************************/
210 /*                              ETS section                       */
211 /******************************************************************/
212 void bnx2x_ets_disabled(struct link_params *params)
213 {
214         /* ETS disabled configuration*/
215         struct bnx2x *bp = params->bp;
216
217         DP(NETIF_MSG_LINK, "ETS disabled configuration\n");
218
219         /**
220          * mapping between entry  priority to client number (0,1,2 -debug and
221          * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
222          * 3bits client num.
223          *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
224          * cos1-100     cos0-011     dbg1-010     dbg0-001     MCP-000
225          */
226
227         REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
228         /**
229          * Bitmap of 5bits length. Each bit specifies whether the entry behaves
230          * as strict.  Bits 0,1,2 - debug and management entries, 3 -
231          * COS0 entry, 4 - COS1 entry.
232          * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
233          * bit4   bit3    bit2   bit1     bit0
234          * MCP and debug are strict
235          */
236
237         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
238         /* defines which entries (clients) are subjected to WFQ arbitration */
239         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
240         /**
241         * For strict priority entries defines the number of consecutive
242         * slots for the highest priority.
243         */
244         REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
245         /**
246          * mapping between the CREDIT_WEIGHT registers and actual client
247          * numbers
248          */
249         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
250         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
251         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
252
253         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
254         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
255         REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
256         /* ETS mode disable */
257         REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
258         /**
259          * If ETS mode is enabled (there is no strict priority) defines a WFQ
260          * weight for COS0/COS1.
261          */
262         REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
263         REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710);
264         /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
265         REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680);
266         REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680);
267         /* Defines the number of consecutive slots for the strict priority */
268         REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
269 }
270
271 void bnx2x_ets_bw_limit_common(const struct link_params *params)
272 {
273         /* ETS disabled configuration */
274         struct bnx2x *bp = params->bp;
275         DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
276         /**
277         * defines which entries (clients) are subjected to WFQ arbitration
278         * COS0 0x8
279         * COS1 0x10
280         */
281         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
282         /**
283         * mapping between the ARB_CREDIT_WEIGHT registers and actual
284         * client numbers (WEIGHT_0 does not actually have to represent
285         * client 0)
286         *    PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
287         *  cos1-001     cos0-000     dbg1-100     dbg0-011     MCP-010
288         */
289         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
290
291         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
292                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
293         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
294                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
295
296         /* ETS mode enabled*/
297         REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
298
299         /* Defines the number of consecutive slots for the strict priority */
300         REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
301         /**
302         * Bitmap of 5bits length. Each bit specifies whether the entry behaves
303         * as strict.  Bits 0,1,2 - debug and management entries, 3 - COS0
304         * entry, 4 - COS1 entry.
305         * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
306         * bit4   bit3     bit2     bit1    bit0
307         * MCP and debug are strict
308         */
309         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
310
311         /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
312         REG_WR(bp, PBF_REG_COS0_UPPER_BOUND,
313                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
314         REG_WR(bp, PBF_REG_COS1_UPPER_BOUND,
315                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
316 }
317
318 void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
319                         const u32 cos1_bw)
320 {
321         /* ETS disabled configuration*/
322         struct bnx2x *bp = params->bp;
323         const u32 total_bw = cos0_bw + cos1_bw;
324         u32 cos0_credit_weight = 0;
325         u32 cos1_credit_weight = 0;
326
327         DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
328
329         if ((0 == total_bw) ||
330             (0 == cos0_bw) ||
331             (0 == cos1_bw)) {
332                 DP(NETIF_MSG_LINK,
333                    "bnx2x_ets_bw_limit: Total BW can't be zero\n");
334                 return;
335         }
336
337         cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
338                 total_bw;
339         cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
340                 total_bw;
341
342         bnx2x_ets_bw_limit_common(params);
343
344         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
345         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
346
347         REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
348         REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
349 }
350
351 u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
352 {
353         /* ETS disabled configuration*/
354         struct bnx2x *bp = params->bp;
355         u32 val = 0;
356
357         DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
358         /**
359          * Bitmap of 5bits length. Each bit specifies whether the entry behaves
360          * as strict.  Bits 0,1,2 - debug and management entries,
361          * 3 - COS0 entry, 4 - COS1 entry.
362          *  COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
363          *  bit4   bit3   bit2      bit1     bit0
364          * MCP and debug are strict
365          */
366         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
367         /**
368          * For strict priority entries defines the number of consecutive slots
369          * for the highest priority.
370          */
371         REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
372         /* ETS mode disable */
373         REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
374         /* Defines the number of consecutive slots for the strict priority */
375         REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
376
377         /* Defines the number of consecutive slots for the strict priority */
378         REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
379
380         /**
381         * mapping between entry  priority to client number (0,1,2 -debug and
382         * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
383         * 3bits client num.
384         *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
385         * dbg0-010     dbg1-001     cos1-100     cos0-011     MCP-000
386         * dbg0-010     dbg1-001     cos0-011     cos1-100     MCP-000
387         */
388         val = (0 == strict_cos) ? 0x2318 : 0x22E0;
389         REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
390
391         return 0;
392 }
393 /******************************************************************/
394 /*                      ETS section                               */
395 /******************************************************************/
396
397 static void bnx2x_bmac2_get_pfc_stat(struct link_params *params,
398                                      u32 pfc_frames_sent[2],
399                                      u32 pfc_frames_received[2])
400 {
401         /* Read pfc statistic */
402         struct bnx2x *bp = params->bp;
403         u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
404                 NIG_REG_INGRESS_BMAC0_MEM;
405
406         DP(NETIF_MSG_LINK, "pfc statistic read from BMAC\n");
407
408         REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_STAT_GTPP,
409                                         pfc_frames_sent, 2);
410
411         REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_STAT_GRPP,
412                                         pfc_frames_received, 2);
413
414 }
415 static void bnx2x_emac_get_pfc_stat(struct link_params *params,
416                                     u32 pfc_frames_sent[2],
417                                     u32 pfc_frames_received[2])
418 {
419         /* Read pfc statistic */
420         struct bnx2x *bp = params->bp;
421         u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
422         u32 val_xon = 0;
423         u32 val_xoff = 0;
424
425         DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n");
426
427         /* PFC received frames */
428         val_xoff = REG_RD(bp, emac_base +
429                                 EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
430         val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
431         val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
432         val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
433
434         pfc_frames_received[0] = val_xon + val_xoff;
435
436         /* PFC received sent */
437         val_xoff = REG_RD(bp, emac_base +
438                                 EMAC_REG_RX_PFC_STATS_XOFF_SENT);
439         val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
440         val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
441         val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
442
443         pfc_frames_sent[0] = val_xon + val_xoff;
444 }
445
446 void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
447                          u32 pfc_frames_sent[2],
448                          u32 pfc_frames_received[2])
449 {
450         /* Read pfc statistic */
451         struct bnx2x *bp = params->bp;
452         u32 val = 0;
453         DP(NETIF_MSG_LINK, "pfc statistic\n");
454
455         if (!vars->link_up)
456                 return;
457
458         val = REG_RD(bp, MISC_REG_RESET_REG_2);
459         if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
460             == 0) {
461                 DP(NETIF_MSG_LINK, "About to read stats from EMAC\n");
462                 bnx2x_emac_get_pfc_stat(params, pfc_frames_sent,
463                                         pfc_frames_received);
464         } else {
465                 DP(NETIF_MSG_LINK, "About to read stats from BMAC\n");
466                 bnx2x_bmac2_get_pfc_stat(params, pfc_frames_sent,
467                                          pfc_frames_received);
468         }
469 }
470 /******************************************************************/
471 /*                      MAC/PBF section                           */
472 /******************************************************************/
473 static void bnx2x_emac_init(struct link_params *params,
474                            struct link_vars *vars)
475 {
476         /* reset and unreset the emac core */
477         struct bnx2x *bp = params->bp;
478         u8 port = params->port;
479         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
480         u32 val;
481         u16 timeout;
482
483         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
484                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
485         udelay(5);
486         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
487                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
488
489         /* init emac - use read-modify-write */
490         /* self clear reset */
491         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
492         EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
493
494         timeout = 200;
495         do {
496                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
497                 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
498                 if (!timeout) {
499                         DP(NETIF_MSG_LINK, "EMAC timeout!\n");
500                         return;
501                 }
502                 timeout--;
503         } while (val & EMAC_MODE_RESET);
504
505         /* Set mac address */
506         val = ((params->mac_addr[0] << 8) |
507                 params->mac_addr[1]);
508         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
509
510         val = ((params->mac_addr[2] << 24) |
511                (params->mac_addr[3] << 16) |
512                (params->mac_addr[4] << 8) |
513                 params->mac_addr[5]);
514         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
515 }
516
517 static u8 bnx2x_emac_enable(struct link_params *params,
518                           struct link_vars *vars, u8 lb)
519 {
520         struct bnx2x *bp = params->bp;
521         u8 port = params->port;
522         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
523         u32 val;
524
525         DP(NETIF_MSG_LINK, "enabling EMAC\n");
526
527         /* enable emac and not bmac */
528         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
529
530         /* for paladium */
531         if (CHIP_REV_IS_EMUL(bp)) {
532                 /* Use lane 1 (of lanes 0-3) */
533                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
534                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
535                             port*4, 1);
536         }
537         /* for fpga */
538         else
539
540         if (CHIP_REV_IS_FPGA(bp)) {
541                 /* Use lane 1 (of lanes 0-3) */
542                 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
543
544                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
545                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
546                             0);
547         } else
548         /* ASIC */
549         if (vars->phy_flags & PHY_XGXS_FLAG) {
550                 u32 ser_lane = ((params->lane_config &
551                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
552                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
553
554                 DP(NETIF_MSG_LINK, "XGXS\n");
555                 /* select the master lanes (out of 0-3) */
556                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
557                            port*4, ser_lane);
558                 /* select XGXS */
559                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
560                            port*4, 1);
561
562         } else { /* SerDes */
563                 DP(NETIF_MSG_LINK, "SerDes\n");
564                 /* select SerDes */
565                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
566                            port*4, 0);
567         }
568
569         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
570                     EMAC_RX_MODE_RESET);
571         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
572                     EMAC_TX_MODE_RESET);
573
574         if (CHIP_REV_IS_SLOW(bp)) {
575                 /* config GMII mode */
576                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
577                 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
578                             (val | EMAC_MODE_PORT_GMII));
579         } else { /* ASIC */
580                 /* pause enable/disable */
581                 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
582                                EMAC_RX_MODE_FLOW_EN);
583
584                 bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
585                                (EMAC_TX_MODE_EXT_PAUSE_EN |
586                                 EMAC_TX_MODE_FLOW_EN));
587                 if (!(params->feature_config_flags &
588                       FEATURE_CONFIG_PFC_ENABLED)) {
589                         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
590                                 bnx2x_bits_en(bp, emac_base +
591                                               EMAC_REG_EMAC_RX_MODE,
592                                               EMAC_RX_MODE_FLOW_EN);
593
594                         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
595                                 bnx2x_bits_en(bp, emac_base +
596                                               EMAC_REG_EMAC_TX_MODE,
597                                               (EMAC_TX_MODE_EXT_PAUSE_EN |
598                                                EMAC_TX_MODE_FLOW_EN));
599                 } else
600                         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
601                                       EMAC_TX_MODE_FLOW_EN);
602         }
603
604         /* KEEP_VLAN_TAG, promiscuous */
605         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
606         val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
607
608         /**
609         * Setting this bit causes MAC control frames (except for pause
610         * frames) to be passed on for processing. This setting has no
611         * affect on the operation of the pause frames. This bit effects
612         * all packets regardless of RX Parser packet sorting logic.
613         * Turn the PFC off to make sure we are in Xon state before
614         * enabling it.
615         */
616         EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
617         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
618                 DP(NETIF_MSG_LINK, "PFC is enabled\n");
619                 /* Enable PFC again */
620                 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
621                         EMAC_REG_RX_PFC_MODE_RX_EN |
622                         EMAC_REG_RX_PFC_MODE_TX_EN |
623                         EMAC_REG_RX_PFC_MODE_PRIORITIES);
624
625                 EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
626                         ((0x0101 <<
627                           EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
628                          (0x00ff <<
629                           EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
630                 val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
631         }
632         EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
633
634         /* Set Loopback */
635         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
636         if (lb)
637                 val |= 0x810;
638         else
639                 val &= ~0x810;
640         EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
641
642         /* enable emac */
643         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
644
645         /* enable emac for jumbo packets */
646         EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
647                 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
648                  (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
649
650         /* strip CRC */
651         REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
652
653         /* disable the NIG in/out to the bmac */
654         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
655         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
656         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
657
658         /* enable the NIG in/out to the emac */
659         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
660         val = 0;
661         if ((params->feature_config_flags &
662               FEATURE_CONFIG_PFC_ENABLED) ||
663             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
664                 val = 1;
665
666         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
667         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
668
669         if (CHIP_REV_IS_EMUL(bp)) {
670                 /* take the BigMac out of reset */
671                 REG_WR(bp,
672                            GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
673                            (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
674
675                 /* enable access for bmac registers */
676                 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
677         } else
678                 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
679
680         vars->mac_type = MAC_TYPE_EMAC;
681         return 0;
682 }
683
684 static void bnx2x_update_pfc_bmac1(struct link_params *params,
685                                    struct link_vars *vars)
686 {
687         u32 wb_data[2];
688         struct bnx2x *bp = params->bp;
689         u32 bmac_addr =  params->port ? NIG_REG_INGRESS_BMAC1_MEM :
690                 NIG_REG_INGRESS_BMAC0_MEM;
691
692         u32 val = 0x14;
693         if ((!(params->feature_config_flags &
694               FEATURE_CONFIG_PFC_ENABLED)) &&
695                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
696                 /* Enable BigMAC to react on received Pause packets */
697                 val |= (1<<5);
698         wb_data[0] = val;
699         wb_data[1] = 0;
700         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
701
702         /* tx control */
703         val = 0xc0;
704         if (!(params->feature_config_flags &
705               FEATURE_CONFIG_PFC_ENABLED) &&
706                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
707                 val |= 0x800000;
708         wb_data[0] = val;
709         wb_data[1] = 0;
710         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
711 }
712
713 static void bnx2x_update_pfc_bmac2(struct link_params *params,
714                                    struct link_vars *vars,
715                                    u8 is_lb)
716 {
717         /*
718          * Set rx control: Strip CRC and enable BigMAC to relay
719          * control packets to the system as well
720          */
721         u32 wb_data[2];
722         struct bnx2x *bp = params->bp;
723         u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
724                 NIG_REG_INGRESS_BMAC0_MEM;
725         u32 val = 0x14;
726
727         if ((!(params->feature_config_flags &
728               FEATURE_CONFIG_PFC_ENABLED)) &&
729                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
730                 /* Enable BigMAC to react on received Pause packets */
731                 val |= (1<<5);
732         wb_data[0] = val;
733         wb_data[1] = 0;
734         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL,
735                         wb_data, 2);
736         udelay(30);
737
738         /* Tx control */
739         val = 0xc0;
740         if (!(params->feature_config_flags &
741                                 FEATURE_CONFIG_PFC_ENABLED) &&
742             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
743                 val |= 0x800000;
744         wb_data[0] = val;
745         wb_data[1] = 0;
746         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
747
748         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
749                 DP(NETIF_MSG_LINK, "PFC is enabled\n");
750                 /* Enable PFC RX & TX & STATS and set 8 COS  */
751                 wb_data[0] = 0x0;
752                 wb_data[0] |= (1<<0);  /* RX */
753                 wb_data[0] |= (1<<1);  /* TX */
754                 wb_data[0] |= (1<<2);  /* Force initial Xon */
755                 wb_data[0] |= (1<<3);  /* 8 cos */
756                 wb_data[0] |= (1<<5);  /* STATS */
757                 wb_data[1] = 0;
758                 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
759                             wb_data, 2);
760                 /* Clear the force Xon */
761                 wb_data[0] &= ~(1<<2);
762         } else {
763                 DP(NETIF_MSG_LINK, "PFC is disabled\n");
764                 /* disable PFC RX & TX & STATS and set 8 COS */
765                 wb_data[0] = 0x8;
766                 wb_data[1] = 0;
767         }
768
769         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
770
771         /**
772         * Set Time (based unit is 512 bit time) between automatic
773         * re-sending of PP packets amd enable automatic re-send of
774         * Per-Priroity Packet as long as pp_gen is asserted and
775         * pp_disable is low.
776         */
777         val = 0x8000;
778         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
779                 val |= (1<<16); /* enable automatic re-send */
780
781         wb_data[0] = val;
782         wb_data[1] = 0;
783         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
784                         wb_data, 2);
785
786         /* mac control */
787         val = 0x3; /* Enable RX and TX */
788         if (is_lb) {
789                 val |= 0x4; /* Local loopback */
790                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
791         }
792         /* When PFC enabled, Pass pause frames towards the NIG. */
793         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
794                 val |= ((1<<6)|(1<<5));
795
796         wb_data[0] = val;
797         wb_data[1] = 0;
798         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL,
799                         wb_data, 2);
800 }
801
802 static void bnx2x_update_pfc_brb(struct link_params *params,
803                 struct link_vars *vars,
804                 struct bnx2x_nig_brb_pfc_port_params *pfc_params)
805 {
806         struct bnx2x *bp = params->bp;
807         int set_pfc = params->feature_config_flags &
808                 FEATURE_CONFIG_PFC_ENABLED;
809
810         /* default - pause configuration */
811         u32 pause_xoff_th = PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE;
812         u32 pause_xon_th = PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE;
813         u32 full_xoff_th = PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE;
814         u32 full_xon_th = PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE;
815
816         if (set_pfc && pfc_params)
817                 /* First COS */
818                 if (!pfc_params->cos0_pauseable) {
819                         pause_xoff_th =
820                           PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE;
821                         pause_xon_th =
822                           PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE;
823                         full_xoff_th =
824                           PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE;
825                         full_xon_th =
826                           PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE;
827                 }
828         /* The number of free blocks below which the pause signal to class 0
829            of MAC #n is asserted. n=0,1 */
830         REG_WR(bp, BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 , pause_xoff_th);
831         /* The number of free blocks above which the pause signal to class 0
832            of MAC #n is de-asserted. n=0,1 */
833         REG_WR(bp, BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , pause_xon_th);
834         /* The number of free blocks below which the full signal to class 0
835            of MAC #n is asserted. n=0,1 */
836         REG_WR(bp, BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , full_xoff_th);
837         /* The number of free blocks above which the full signal to class 0
838            of MAC #n is de-asserted. n=0,1 */
839         REG_WR(bp, BRB1_REG_FULL_0_XON_THRESHOLD_0 , full_xon_th);
840
841         if (set_pfc && pfc_params) {
842                 /* Second COS */
843                 if (pfc_params->cos1_pauseable) {
844                         pause_xoff_th =
845                           PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE;
846                         pause_xon_th =
847                           PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE;
848                         full_xoff_th =
849                           PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE;
850                         full_xon_th =
851                           PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE;
852                 } else {
853                         pause_xoff_th =
854                           PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE;
855                         pause_xon_th =
856                           PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE;
857                         full_xoff_th =
858                           PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE;
859                         full_xon_th =
860                           PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE;
861                 }
862                 /**
863                  * The number of free blocks below which the pause signal to
864                  * class 1 of MAC #n is asserted. n=0,1
865                  **/
866                 REG_WR(bp, BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0, pause_xoff_th);
867                 /**
868                  * The number of free blocks above which the pause signal to
869                  * class 1 of MAC #n is de-asserted. n=0,1
870                  **/
871                 REG_WR(bp, BRB1_REG_PAUSE_1_XON_THRESHOLD_0, pause_xon_th);
872                 /**
873                  * The number of free blocks below which the full signal to
874                  * class 1 of MAC #n is asserted. n=0,1
875                  **/
876                 REG_WR(bp, BRB1_REG_FULL_1_XOFF_THRESHOLD_0, full_xoff_th);
877                 /**
878                  * The number of free blocks above which the full signal to
879                  * class 1 of MAC #n is de-asserted. n=0,1
880                  **/
881                 REG_WR(bp, BRB1_REG_FULL_1_XON_THRESHOLD_0, full_xon_th);
882         }
883 }
884
885 static void bnx2x_update_pfc_nig(struct link_params *params,
886                 struct link_vars *vars,
887                 struct bnx2x_nig_brb_pfc_port_params *nig_params)
888 {
889         u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
890         u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0;
891         u32 pkt_priority_to_cos = 0;
892         u32 val;
893         struct bnx2x *bp = params->bp;
894         int port = params->port;
895         int set_pfc = params->feature_config_flags &
896                 FEATURE_CONFIG_PFC_ENABLED;
897         DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
898
899         /**
900          * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
901          * MAC control frames (that are not pause packets)
902          * will be forwarded to the XCM.
903          */
904         xcm_mask = REG_RD(bp,
905                                 port ? NIG_REG_LLH1_XCM_MASK :
906                                 NIG_REG_LLH0_XCM_MASK);
907         /**
908          * nig params will override non PFC params, since it's possible to
909          * do transition from PFC to SAFC
910          */
911         if (set_pfc) {
912                 pause_enable = 0;
913                 llfc_out_en = 0;
914                 llfc_enable = 0;
915                 ppp_enable = 1;
916                 xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
917                                      NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
918                 xcm0_out_en = 0;
919                 p0_hwpfc_enable = 1;
920         } else  {
921                 if (nig_params) {
922                         llfc_out_en = nig_params->llfc_out_en;
923                         llfc_enable = nig_params->llfc_enable;
924                         pause_enable = nig_params->pause_enable;
925                 } else  /*defaul non PFC mode - PAUSE */
926                         pause_enable = 1;
927
928                 xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
929                         NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
930                 xcm0_out_en = 1;
931         }
932
933         REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
934                NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
935         REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
936                NIG_REG_LLFC_ENABLE_0, llfc_enable);
937         REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
938                NIG_REG_PAUSE_ENABLE_0, pause_enable);
939
940         REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
941                NIG_REG_PPP_ENABLE_0, ppp_enable);
942
943         REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
944                NIG_REG_LLH0_XCM_MASK, xcm_mask);
945
946         REG_WR(bp,  NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
947
948         /* output enable for RX_XCM # IF */
949         REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en);
950
951         /* HW PFC TX enable */
952         REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable);
953
954         /* 0x2 = BMAC, 0x1= EMAC */
955         switch (vars->mac_type) {
956         case MAC_TYPE_EMAC:
957                 val = 1;
958                 break;
959         case MAC_TYPE_BMAC:
960                 val = 0;
961                 break;
962         default:
963                 val = 0;
964                 break;
965         }
966         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT, val);
967
968         if (nig_params) {
969                 pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
970
971                 REG_WR(bp, port ? NIG_REG_P1_RX_COS0_PRIORITY_MASK :
972                        NIG_REG_P0_RX_COS0_PRIORITY_MASK,
973                        nig_params->rx_cos0_priority_mask);
974
975                 REG_WR(bp, port ? NIG_REG_P1_RX_COS1_PRIORITY_MASK :
976                        NIG_REG_P0_RX_COS1_PRIORITY_MASK,
977                        nig_params->rx_cos1_priority_mask);
978
979                 REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
980                        NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
981                        nig_params->llfc_high_priority_classes);
982
983                 REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
984                        NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
985                        nig_params->llfc_low_priority_classes);
986         }
987         REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
988                NIG_REG_P0_PKT_PRIORITY_TO_COS,
989                pkt_priority_to_cos);
990 }
991
992
993 void bnx2x_update_pfc(struct link_params *params,
994                       struct link_vars *vars,
995                       struct bnx2x_nig_brb_pfc_port_params *pfc_params)
996 {
997         /**
998          * The PFC and pause are orthogonal to one another, meaning when
999          * PFC is enabled, the pause are disabled, and when PFC is
1000          * disabled, pause are set according to the pause result.
1001          */
1002         u32 val;
1003         struct bnx2x *bp = params->bp;
1004
1005         /* update NIG params */
1006         bnx2x_update_pfc_nig(params, vars, pfc_params);
1007
1008         /* update BRB params */
1009         bnx2x_update_pfc_brb(params, vars, pfc_params);
1010
1011         if (!vars->link_up)
1012                 return;
1013
1014         val = REG_RD(bp, MISC_REG_RESET_REG_2);
1015         if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
1016             == 0) {
1017                 DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
1018                 bnx2x_emac_enable(params, vars, 0);
1019                 return;
1020         }
1021
1022         DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
1023         if (CHIP_IS_E2(bp))
1024                 bnx2x_update_pfc_bmac2(params, vars, 0);
1025         else
1026                 bnx2x_update_pfc_bmac1(params, vars);
1027
1028         val = 0;
1029         if ((params->feature_config_flags &
1030               FEATURE_CONFIG_PFC_ENABLED) ||
1031             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1032                 val = 1;
1033         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
1034 }
1035
1036 static u8 bnx2x_bmac1_enable(struct link_params *params,
1037                              struct link_vars *vars,
1038                           u8 is_lb)
1039 {
1040         struct bnx2x *bp = params->bp;
1041         u8 port = params->port;
1042         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1043                                NIG_REG_INGRESS_BMAC0_MEM;
1044         u32 wb_data[2];
1045         u32 val;
1046
1047         DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
1048
1049         /* XGXS control */
1050         wb_data[0] = 0x3c;
1051         wb_data[1] = 0;
1052         REG_WR_DMAE(bp, bmac_addr +
1053                       BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
1054                       wb_data, 2);
1055
1056         /* tx MAC SA */
1057         wb_data[0] = ((params->mac_addr[2] << 24) |
1058                        (params->mac_addr[3] << 16) |
1059                        (params->mac_addr[4] << 8) |
1060                         params->mac_addr[5]);
1061         wb_data[1] = ((params->mac_addr[0] << 8) |
1062                         params->mac_addr[1]);
1063         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
1064                     wb_data, 2);
1065
1066         /* mac control */
1067         val = 0x3;
1068         if (is_lb) {
1069                 val |= 0x4;
1070                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
1071         }
1072         wb_data[0] = val;
1073         wb_data[1] = 0;
1074         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
1075                     wb_data, 2);
1076
1077         /* set rx mtu */
1078         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1079         wb_data[1] = 0;
1080         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
1081                         wb_data, 2);
1082
1083         bnx2x_update_pfc_bmac1(params, vars);
1084
1085         /* set tx mtu */
1086         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1087         wb_data[1] = 0;
1088         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
1089                         wb_data, 2);
1090
1091         /* set cnt max size */
1092         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1093         wb_data[1] = 0;
1094         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
1095                     wb_data, 2);
1096
1097         /* configure safc */
1098         wb_data[0] = 0x1000200;
1099         wb_data[1] = 0;
1100         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
1101                     wb_data, 2);
1102         /* fix for emulation */
1103         if (CHIP_REV_IS_EMUL(bp)) {
1104                 wb_data[0] = 0xf000;
1105                 wb_data[1] = 0;
1106                 REG_WR_DMAE(bp,
1107                             bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
1108                             wb_data, 2);
1109         }
1110
1111
1112         return 0;
1113 }
1114
1115 static u8 bnx2x_bmac2_enable(struct link_params *params,
1116                              struct link_vars *vars,
1117                              u8 is_lb)
1118 {
1119         struct bnx2x *bp = params->bp;
1120         u8 port = params->port;
1121         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1122                                NIG_REG_INGRESS_BMAC0_MEM;
1123         u32 wb_data[2];
1124
1125         DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
1126
1127         wb_data[0] = 0;
1128         wb_data[1] = 0;
1129         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL,
1130                         wb_data, 2);
1131         udelay(30);
1132
1133         /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
1134         wb_data[0] = 0x3c;
1135         wb_data[1] = 0;
1136         REG_WR_DMAE(bp, bmac_addr +
1137                         BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
1138                         wb_data, 2);
1139
1140         udelay(30);
1141
1142         /* tx MAC SA */
1143         wb_data[0] = ((params->mac_addr[2] << 24) |
1144                        (params->mac_addr[3] << 16) |
1145                        (params->mac_addr[4] << 8) |
1146                         params->mac_addr[5]);
1147         wb_data[1] = ((params->mac_addr[0] << 8) |
1148                         params->mac_addr[1]);
1149         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
1150                         wb_data, 2);
1151
1152         udelay(30);
1153
1154         /* Configure SAFC */
1155         wb_data[0] = 0x1000200;
1156         wb_data[1] = 0;
1157         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
1158                         wb_data, 2);
1159         udelay(30);
1160
1161         /* set rx mtu */
1162         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1163         wb_data[1] = 0;
1164         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE,
1165                         wb_data, 2);
1166         udelay(30);
1167
1168         /* set tx mtu */
1169         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1170         wb_data[1] = 0;
1171         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE,
1172                         wb_data, 2);
1173         udelay(30);
1174         /* set cnt max size */
1175         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
1176         wb_data[1] = 0;
1177         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE,
1178                         wb_data, 2);
1179         udelay(30);
1180         bnx2x_update_pfc_bmac2(params, vars, is_lb);
1181
1182         return 0;
1183 }
1184
1185 static u8 bnx2x_bmac_enable(struct link_params *params,
1186                             struct link_vars *vars,
1187                             u8 is_lb)
1188 {
1189         u8 rc, port = params->port;
1190         struct bnx2x *bp = params->bp;
1191         u32 val;
1192         /* reset and unreset the BigMac */
1193         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1194                      (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1195         msleep(1);
1196
1197         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1198                      (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1199
1200         /* enable access for bmac registers */
1201         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
1202
1203         /* Enable BMAC according to BMAC type*/
1204         if (CHIP_IS_E2(bp))
1205                 rc = bnx2x_bmac2_enable(params, vars, is_lb);
1206         else
1207                 rc = bnx2x_bmac1_enable(params, vars, is_lb);
1208         REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
1209         REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
1210         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
1211         val = 0;
1212         if ((params->feature_config_flags &
1213               FEATURE_CONFIG_PFC_ENABLED) ||
1214             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1215                 val = 1;
1216         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
1217         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
1218         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
1219         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
1220         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
1221         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
1222
1223         vars->mac_type = MAC_TYPE_BMAC;
1224         return rc;
1225 }
1226
1227
1228 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
1229 {
1230         struct bnx2x *bp = params->bp;
1231
1232         REG_WR(bp, params->shmem_base +
1233                    offsetof(struct shmem_region,
1234                             port_mb[params->port].link_status),
1235                         link_status);
1236 }
1237
1238 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
1239 {
1240         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1241                 NIG_REG_INGRESS_BMAC0_MEM;
1242         u32 wb_data[2];
1243         u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
1244
1245         /* Only if the bmac is out of reset */
1246         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
1247                         (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
1248             nig_bmac_enable) {
1249
1250                 if (CHIP_IS_E2(bp)) {
1251                         /* Clear Rx Enable bit in BMAC_CONTROL register */
1252                         REG_RD_DMAE(bp, bmac_addr +
1253                                         BIGMAC2_REGISTER_BMAC_CONTROL,
1254                                         wb_data, 2);
1255                         wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
1256                         REG_WR_DMAE(bp, bmac_addr +
1257                                         BIGMAC2_REGISTER_BMAC_CONTROL,
1258                                         wb_data, 2);
1259                 } else {
1260                         /* Clear Rx Enable bit in BMAC_CONTROL register */
1261                         REG_RD_DMAE(bp, bmac_addr +
1262                                         BIGMAC_REGISTER_BMAC_CONTROL,
1263                                         wb_data, 2);
1264                         wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
1265                         REG_WR_DMAE(bp, bmac_addr +
1266                                         BIGMAC_REGISTER_BMAC_CONTROL,
1267                                         wb_data, 2);
1268                 }
1269                 msleep(1);
1270         }
1271 }
1272
1273 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
1274                          u32 line_speed)
1275 {
1276         struct bnx2x *bp = params->bp;
1277         u8 port = params->port;
1278         u32 init_crd, crd;
1279         u32 count = 1000;
1280
1281         /* disable port */
1282         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
1283
1284         /* wait for init credit */
1285         init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
1286         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
1287         DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
1288
1289         while ((init_crd != crd) && count) {
1290                 msleep(5);
1291
1292                 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
1293                 count--;
1294         }
1295         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
1296         if (init_crd != crd) {
1297                 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
1298                           init_crd, crd);
1299                 return -EINVAL;
1300         }
1301
1302         if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
1303             line_speed == SPEED_10 ||
1304             line_speed == SPEED_100 ||
1305             line_speed == SPEED_1000 ||
1306             line_speed == SPEED_2500) {
1307                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
1308                 /* update threshold */
1309                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
1310                 /* update init credit */
1311                 init_crd = 778;         /* (800-18-4) */
1312
1313         } else {
1314                 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
1315                               ETH_OVREHEAD)/16;
1316                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
1317                 /* update threshold */
1318                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
1319                 /* update init credit */
1320                 switch (line_speed) {
1321                 case SPEED_10000:
1322                         init_crd = thresh + 553 - 22;
1323                         break;
1324
1325                 case SPEED_12000:
1326                         init_crd = thresh + 664 - 22;
1327                         break;
1328
1329                 case SPEED_13000:
1330                         init_crd = thresh + 742 - 22;
1331                         break;
1332
1333                 case SPEED_16000:
1334                         init_crd = thresh + 778 - 22;
1335                         break;
1336                 default:
1337                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1338                                   line_speed);
1339                         return -EINVAL;
1340                 }
1341         }
1342         REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
1343         DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
1344                  line_speed, init_crd);
1345
1346         /* probe the credit changes */
1347         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
1348         msleep(5);
1349         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
1350
1351         /* enable port */
1352         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
1353         return 0;
1354 }
1355
1356 static u32 bnx2x_get_emac_base(struct bnx2x *bp,
1357                                u32 mdc_mdio_access, u8 port)
1358 {
1359         u32 emac_base = 0;
1360         switch (mdc_mdio_access) {
1361         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
1362                 break;
1363         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
1364                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
1365                         emac_base = GRCBASE_EMAC1;
1366                 else
1367                         emac_base = GRCBASE_EMAC0;
1368                 break;
1369         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
1370                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
1371                         emac_base = GRCBASE_EMAC0;
1372                 else
1373                         emac_base = GRCBASE_EMAC1;
1374                 break;
1375         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
1376                 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1377                 break;
1378         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
1379                 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
1380                 break;
1381         default:
1382                 break;
1383         }
1384         return emac_base;
1385
1386 }
1387
1388 u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
1389                     u8 devad, u16 reg, u16 val)
1390 {
1391         u32 tmp, saved_mode;
1392         u8 i, rc = 0;
1393
1394         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
1395          * (a value of 49==0x31) and make sure that the AUTO poll is off
1396          */
1397
1398         saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
1399         tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
1400                              EMAC_MDIO_MODE_CLOCK_CNT);
1401         tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
1402                 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
1403         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
1404         REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
1405         udelay(40);
1406
1407         /* address */
1408
1409         tmp = ((phy->addr << 21) | (devad << 16) | reg |
1410                EMAC_MDIO_COMM_COMMAND_ADDRESS |
1411                EMAC_MDIO_COMM_START_BUSY);
1412         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
1413
1414         for (i = 0; i < 50; i++) {
1415                 udelay(10);
1416
1417                 tmp = REG_RD(bp, phy->mdio_ctrl +
1418                                    EMAC_REG_EMAC_MDIO_COMM);
1419                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
1420                         udelay(5);
1421                         break;
1422                 }
1423         }
1424         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
1425                 DP(NETIF_MSG_LINK, "write phy register failed\n");
1426                 rc = -EFAULT;
1427         } else {
1428                 /* data */
1429                 tmp = ((phy->addr << 21) | (devad << 16) | val |
1430                        EMAC_MDIO_COMM_COMMAND_WRITE_45 |
1431                        EMAC_MDIO_COMM_START_BUSY);
1432                 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
1433
1434                 for (i = 0; i < 50; i++) {
1435                         udelay(10);
1436
1437                         tmp = REG_RD(bp, phy->mdio_ctrl +
1438                                          EMAC_REG_EMAC_MDIO_COMM);
1439                         if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
1440                                 udelay(5);
1441                                 break;
1442                         }
1443                 }
1444                 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
1445                         DP(NETIF_MSG_LINK, "write phy register failed\n");
1446                         rc = -EFAULT;
1447                 }
1448         }
1449
1450         /* Restore the saved mode */
1451         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
1452
1453         return rc;
1454 }
1455
1456 u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
1457                    u8 devad, u16 reg, u16 *ret_val)
1458 {
1459         u32 val, saved_mode;
1460         u16 i;
1461         u8 rc = 0;
1462
1463         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
1464          * (a value of 49==0x31) and make sure that the AUTO poll is off
1465          */
1466
1467         saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
1468         val = saved_mode & ~((EMAC_MDIO_MODE_AUTO_POLL |
1469                              EMAC_MDIO_MODE_CLOCK_CNT));
1470         val |= (EMAC_MDIO_MODE_CLAUSE_45 |
1471                 (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
1472         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
1473         REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
1474         udelay(40);
1475
1476         /* address */
1477         val = ((phy->addr << 21) | (devad << 16) | reg |
1478                EMAC_MDIO_COMM_COMMAND_ADDRESS |
1479                EMAC_MDIO_COMM_START_BUSY);
1480         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
1481
1482         for (i = 0; i < 50; i++) {
1483                 udelay(10);
1484
1485                 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
1486                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
1487                         udelay(5);
1488                         break;
1489                 }
1490         }
1491         if (val & EMAC_MDIO_COMM_START_BUSY) {
1492                 DP(NETIF_MSG_LINK, "read phy register failed\n");
1493
1494                 *ret_val = 0;
1495                 rc = -EFAULT;
1496
1497         } else {
1498                 /* data */
1499                 val = ((phy->addr << 21) | (devad << 16) |
1500                        EMAC_MDIO_COMM_COMMAND_READ_45 |
1501                        EMAC_MDIO_COMM_START_BUSY);
1502                 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
1503
1504                 for (i = 0; i < 50; i++) {
1505                         udelay(10);
1506
1507                         val = REG_RD(bp, phy->mdio_ctrl +
1508                                           EMAC_REG_EMAC_MDIO_COMM);
1509                         if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
1510                                 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
1511                                 break;
1512                         }
1513                 }
1514                 if (val & EMAC_MDIO_COMM_START_BUSY) {
1515                         DP(NETIF_MSG_LINK, "read phy register failed\n");
1516
1517                         *ret_val = 0;
1518                         rc = -EFAULT;
1519                 }
1520         }
1521
1522         /* Restore the saved mode */
1523         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
1524
1525         return rc;
1526 }
1527
1528 u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr,
1529                   u8 devad, u16 reg, u16 *ret_val)
1530 {
1531         u8 phy_index;
1532         /**
1533          * Probe for the phy according to the given phy_addr, and execute
1534          * the read request on it
1535          */
1536         for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
1537                 if (params->phy[phy_index].addr == phy_addr) {
1538                         return bnx2x_cl45_read(params->bp,
1539                                                &params->phy[phy_index], devad,
1540                                                reg, ret_val);
1541                 }
1542         }
1543         return -EINVAL;
1544 }
1545
1546 u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr,
1547                    u8 devad, u16 reg, u16 val)
1548 {
1549         u8 phy_index;
1550         /**
1551          * Probe for the phy according to the given phy_addr, and execute
1552          * the write request on it
1553          */
1554         for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
1555                 if (params->phy[phy_index].addr == phy_addr) {
1556                         return bnx2x_cl45_write(params->bp,
1557                                                 &params->phy[phy_index], devad,
1558                                                 reg, val);
1559                 }
1560         }
1561         return -EINVAL;
1562 }
1563
1564 static void bnx2x_set_aer_mmd_xgxs(struct link_params *params,
1565                                    struct bnx2x_phy *phy)
1566 {
1567         u32 ser_lane;
1568         u16 offset, aer_val;
1569         struct bnx2x *bp = params->bp;
1570         ser_lane = ((params->lane_config &
1571                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1572                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1573
1574         offset = phy->addr + ser_lane;
1575         if (CHIP_IS_E2(bp))
1576                 aer_val = 0x3800 + offset - 1;
1577         else
1578                 aer_val = 0x3800 + offset;
1579         CL45_WR_OVER_CL22(bp, phy,
1580                                 MDIO_REG_BANK_AER_BLOCK,
1581                                 MDIO_AER_BLOCK_AER_REG, aer_val);
1582 }
1583 static void bnx2x_set_aer_mmd_serdes(struct bnx2x *bp,
1584                                      struct bnx2x_phy *phy)
1585 {
1586         CL45_WR_OVER_CL22(bp, phy,
1587                                 MDIO_REG_BANK_AER_BLOCK,
1588                                 MDIO_AER_BLOCK_AER_REG, 0x3800);
1589 }
1590
1591 /******************************************************************/
1592 /*                      Internal phy section                      */
1593 /******************************************************************/
1594
1595 static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
1596 {
1597         u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1598
1599         /* Set Clause 22 */
1600         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
1601         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
1602         udelay(500);
1603         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
1604         udelay(500);
1605          /* Set Clause 45 */
1606         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
1607 }
1608
1609 static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
1610 {
1611         u32 val;
1612
1613         DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
1614
1615         val = SERDES_RESET_BITS << (port*16);
1616
1617         /* reset and unreset the SerDes/XGXS */
1618         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
1619         udelay(500);
1620         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
1621
1622         bnx2x_set_serdes_access(bp, port);
1623
1624         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
1625                      port*0x10,
1626                      DEFAULT_PHY_DEV_ADDR);
1627 }
1628
1629 static void bnx2x_xgxs_deassert(struct link_params *params)
1630 {
1631         struct bnx2x *bp = params->bp;
1632         u8 port;
1633         u32 val;
1634         DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
1635         port = params->port;
1636
1637         val = XGXS_RESET_BITS << (port*16);
1638
1639         /* reset and unreset the SerDes/XGXS */
1640         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
1641         udelay(500);
1642         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
1643
1644         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
1645                      port*0x18, 0);
1646         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
1647                      params->phy[INT_PHY].def_md_devad);
1648 }
1649
1650
1651 void bnx2x_link_status_update(struct link_params *params,
1652                             struct link_vars   *vars)
1653 {
1654         struct bnx2x *bp = params->bp;
1655         u8 link_10g;
1656         u8 port = params->port;
1657
1658         vars->link_status = REG_RD(bp, params->shmem_base +
1659                                           offsetof(struct shmem_region,
1660                                            port_mb[port].link_status));
1661
1662         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
1663
1664         if (vars->link_up) {
1665                 DP(NETIF_MSG_LINK, "phy link up\n");
1666
1667                 vars->phy_link_up = 1;
1668                 vars->duplex = DUPLEX_FULL;
1669                 switch (vars->link_status &
1670                                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
1671                         case LINK_10THD:
1672                                 vars->duplex = DUPLEX_HALF;
1673                                 /* fall thru */
1674                         case LINK_10TFD:
1675                                 vars->line_speed = SPEED_10;
1676                                 break;
1677
1678                         case LINK_100TXHD:
1679                                 vars->duplex = DUPLEX_HALF;
1680                                 /* fall thru */
1681                         case LINK_100T4:
1682                         case LINK_100TXFD:
1683                                 vars->line_speed = SPEED_100;
1684                                 break;
1685
1686                         case LINK_1000THD:
1687                                 vars->duplex = DUPLEX_HALF;
1688                                 /* fall thru */
1689                         case LINK_1000TFD:
1690                                 vars->line_speed = SPEED_1000;
1691                                 break;
1692
1693                         case LINK_2500THD:
1694                                 vars->duplex = DUPLEX_HALF;
1695                                 /* fall thru */
1696                         case LINK_2500TFD:
1697                                 vars->line_speed = SPEED_2500;
1698                                 break;
1699
1700                         case LINK_10GTFD:
1701                                 vars->line_speed = SPEED_10000;
1702                                 break;
1703
1704                         case LINK_12GTFD:
1705                                 vars->line_speed = SPEED_12000;
1706                                 break;
1707
1708                         case LINK_12_5GTFD:
1709                                 vars->line_speed = SPEED_12500;
1710                                 break;
1711
1712                         case LINK_13GTFD:
1713                                 vars->line_speed = SPEED_13000;
1714                                 break;
1715
1716                         case LINK_15GTFD:
1717                                 vars->line_speed = SPEED_15000;
1718                                 break;
1719
1720                         case LINK_16GTFD:
1721                                 vars->line_speed = SPEED_16000;
1722                                 break;
1723
1724                         default:
1725                                 break;
1726                 }
1727                 vars->flow_ctrl = 0;
1728                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
1729                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
1730
1731                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
1732                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
1733
1734                 if (!vars->flow_ctrl)
1735                         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1736
1737                 if (vars->line_speed &&
1738                     ((vars->line_speed == SPEED_10) ||
1739                      (vars->line_speed == SPEED_100))) {
1740                         vars->phy_flags |= PHY_SGMII_FLAG;
1741                 } else {
1742                         vars->phy_flags &= ~PHY_SGMII_FLAG;
1743                 }
1744
1745                 /* anything 10 and over uses the bmac */
1746                 link_10g = ((vars->line_speed == SPEED_10000) ||
1747                             (vars->line_speed == SPEED_12000) ||
1748                             (vars->line_speed == SPEED_12500) ||
1749                             (vars->line_speed == SPEED_13000) ||
1750                             (vars->line_speed == SPEED_15000) ||
1751                             (vars->line_speed == SPEED_16000));
1752                 if (link_10g)
1753                         vars->mac_type = MAC_TYPE_BMAC;
1754                 else
1755                         vars->mac_type = MAC_TYPE_EMAC;
1756
1757         } else { /* link down */
1758                 DP(NETIF_MSG_LINK, "phy link down\n");
1759
1760                 vars->phy_link_up = 0;
1761
1762                 vars->line_speed = 0;
1763                 vars->duplex = DUPLEX_FULL;
1764                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1765
1766                 /* indicate no mac active */
1767                 vars->mac_type = MAC_TYPE_NONE;
1768         }
1769
1770         DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x\n",
1771                  vars->link_status, vars->phy_link_up);
1772         DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
1773                  vars->line_speed, vars->duplex, vars->flow_ctrl);
1774 }
1775
1776
1777 static void bnx2x_set_master_ln(struct link_params *params,
1778                                 struct bnx2x_phy *phy)
1779 {
1780         struct bnx2x *bp = params->bp;
1781         u16 new_master_ln, ser_lane;
1782         ser_lane =  ((params->lane_config &
1783                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1784                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1785
1786         /* set the master_ln for AN */
1787         CL45_RD_OVER_CL22(bp, phy,
1788                               MDIO_REG_BANK_XGXS_BLOCK2,
1789                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1790                               &new_master_ln);
1791
1792         CL45_WR_OVER_CL22(bp, phy,
1793                               MDIO_REG_BANK_XGXS_BLOCK2 ,
1794                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1795                               (new_master_ln | ser_lane));
1796 }
1797
1798 static u8 bnx2x_reset_unicore(struct link_params *params,
1799                               struct bnx2x_phy *phy,
1800                               u8 set_serdes)
1801 {
1802         struct bnx2x *bp = params->bp;
1803         u16 mii_control;
1804         u16 i;
1805
1806         CL45_RD_OVER_CL22(bp, phy,
1807                               MDIO_REG_BANK_COMBO_IEEE0,
1808                               MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
1809
1810         /* reset the unicore */
1811         CL45_WR_OVER_CL22(bp, phy,
1812                               MDIO_REG_BANK_COMBO_IEEE0,
1813                               MDIO_COMBO_IEEE0_MII_CONTROL,
1814                               (mii_control |
1815                                MDIO_COMBO_IEEO_MII_CONTROL_RESET));
1816         if (set_serdes)
1817                 bnx2x_set_serdes_access(bp, params->port);
1818
1819         /* wait for the reset to self clear */
1820         for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
1821                 udelay(5);
1822
1823                 /* the reset erased the previous bank value */
1824                 CL45_RD_OVER_CL22(bp, phy,
1825                               MDIO_REG_BANK_COMBO_IEEE0,
1826                               MDIO_COMBO_IEEE0_MII_CONTROL,
1827                               &mii_control);
1828
1829                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1830                         udelay(5);
1831                         return 0;
1832                 }
1833         }
1834
1835         DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1836         return -EINVAL;
1837
1838 }
1839
1840 static void bnx2x_set_swap_lanes(struct link_params *params,
1841                                  struct bnx2x_phy *phy)
1842 {
1843         struct bnx2x *bp = params->bp;
1844         /* Each two bits represents a lane number:
1845            No swap is 0123 => 0x1b no need to enable the swap */
1846         u16 ser_lane, rx_lane_swap, tx_lane_swap;
1847
1848         ser_lane = ((params->lane_config &
1849                          PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1850                         PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1851         rx_lane_swap = ((params->lane_config &
1852                              PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1853                             PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1854         tx_lane_swap = ((params->lane_config &
1855                              PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1856                             PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1857
1858         if (rx_lane_swap != 0x1b) {
1859                 CL45_WR_OVER_CL22(bp, phy,
1860                                     MDIO_REG_BANK_XGXS_BLOCK2,
1861                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1862                                     (rx_lane_swap |
1863                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1864                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1865         } else {
1866                 CL45_WR_OVER_CL22(bp, phy,
1867                                       MDIO_REG_BANK_XGXS_BLOCK2,
1868                                       MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1869         }
1870
1871         if (tx_lane_swap != 0x1b) {
1872                 CL45_WR_OVER_CL22(bp, phy,
1873                                       MDIO_REG_BANK_XGXS_BLOCK2,
1874                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1875                                       (tx_lane_swap |
1876                                        MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1877         } else {
1878                 CL45_WR_OVER_CL22(bp, phy,
1879                                       MDIO_REG_BANK_XGXS_BLOCK2,
1880                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1881         }
1882 }
1883
1884 static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
1885                                          struct link_params *params)
1886 {
1887         struct bnx2x *bp = params->bp;
1888         u16 control2;
1889         CL45_RD_OVER_CL22(bp, phy,
1890                               MDIO_REG_BANK_SERDES_DIGITAL,
1891                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1892                               &control2);
1893         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
1894                 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1895         else
1896                 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1897         DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
1898                 phy->speed_cap_mask, control2);
1899         CL45_WR_OVER_CL22(bp, phy,
1900                               MDIO_REG_BANK_SERDES_DIGITAL,
1901                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1902                               control2);
1903
1904         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
1905              (phy->speed_cap_mask &
1906                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
1907                 DP(NETIF_MSG_LINK, "XGXS\n");
1908
1909                 CL45_WR_OVER_CL22(bp, phy,
1910                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1911                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1912                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1913
1914                 CL45_RD_OVER_CL22(bp, phy,
1915                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1916                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1917                                 &control2);
1918
1919
1920                 control2 |=
1921                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1922
1923                 CL45_WR_OVER_CL22(bp, phy,
1924                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1925                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1926                                 control2);
1927
1928                 /* Disable parallel detection of HiG */
1929                 CL45_WR_OVER_CL22(bp, phy,
1930                                 MDIO_REG_BANK_XGXS_BLOCK2,
1931                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1932                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1933                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1934         }
1935 }
1936
1937 static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
1938                               struct link_params *params,
1939                             struct link_vars *vars,
1940                             u8 enable_cl73)
1941 {
1942         struct bnx2x *bp = params->bp;
1943         u16 reg_val;
1944
1945         /* CL37 Autoneg */
1946         CL45_RD_OVER_CL22(bp, phy,
1947                               MDIO_REG_BANK_COMBO_IEEE0,
1948                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1949
1950         /* CL37 Autoneg Enabled */
1951         if (vars->line_speed == SPEED_AUTO_NEG)
1952                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1953         else /* CL37 Autoneg Disabled */
1954                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1955                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1956
1957         CL45_WR_OVER_CL22(bp, phy,
1958                               MDIO_REG_BANK_COMBO_IEEE0,
1959                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1960
1961         /* Enable/Disable Autodetection */
1962
1963         CL45_RD_OVER_CL22(bp, phy,
1964                               MDIO_REG_BANK_SERDES_DIGITAL,
1965                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1966         reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
1967                     MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
1968         reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
1969         if (vars->line_speed == SPEED_AUTO_NEG)
1970                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1971         else
1972                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1973
1974         CL45_WR_OVER_CL22(bp, phy,
1975                               MDIO_REG_BANK_SERDES_DIGITAL,
1976                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1977
1978         /* Enable TetonII and BAM autoneg */
1979         CL45_RD_OVER_CL22(bp, phy,
1980                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1981                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1982                           &reg_val);
1983         if (vars->line_speed == SPEED_AUTO_NEG) {
1984                 /* Enable BAM aneg Mode and TetonII aneg Mode */
1985                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1986                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1987         } else {
1988                 /* TetonII and BAM Autoneg Disabled */
1989                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1990                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1991         }
1992         CL45_WR_OVER_CL22(bp, phy,
1993                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1994                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1995                               reg_val);
1996
1997         if (enable_cl73) {
1998                 /* Enable Cl73 FSM status bits */
1999                 CL45_WR_OVER_CL22(bp, phy,
2000                                       MDIO_REG_BANK_CL73_USERB0,
2001                                     MDIO_CL73_USERB0_CL73_UCTRL,
2002                                       0xe);
2003
2004                 /* Enable BAM Station Manager*/
2005                 CL45_WR_OVER_CL22(bp, phy,
2006                         MDIO_REG_BANK_CL73_USERB0,
2007                         MDIO_CL73_USERB0_CL73_BAM_CTRL1,
2008                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
2009                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
2010                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
2011
2012                 /* Advertise CL73 link speeds */
2013                 CL45_RD_OVER_CL22(bp, phy,
2014                                               MDIO_REG_BANK_CL73_IEEEB1,
2015                                               MDIO_CL73_IEEEB1_AN_ADV2,
2016                                               &reg_val);
2017                 if (phy->speed_cap_mask &
2018                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2019                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
2020                 if (phy->speed_cap_mask &
2021                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
2022                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
2023
2024                 CL45_WR_OVER_CL22(bp, phy,
2025                                               MDIO_REG_BANK_CL73_IEEEB1,
2026                                               MDIO_CL73_IEEEB1_AN_ADV2,
2027                                       reg_val);
2028
2029                 /* CL73 Autoneg Enabled */
2030                 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
2031
2032         } else /* CL73 Autoneg Disabled */
2033                 reg_val = 0;
2034
2035         CL45_WR_OVER_CL22(bp, phy,
2036                               MDIO_REG_BANK_CL73_IEEEB0,
2037                               MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
2038 }
2039
2040 /* program SerDes, forced speed */
2041 static void bnx2x_program_serdes(struct bnx2x_phy *phy,
2042                                  struct link_params *params,
2043                                struct link_vars *vars)
2044 {
2045         struct bnx2x *bp = params->bp;
2046         u16 reg_val;
2047
2048         /* program duplex, disable autoneg and sgmii*/
2049         CL45_RD_OVER_CL22(bp, phy,
2050                               MDIO_REG_BANK_COMBO_IEEE0,
2051                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
2052         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
2053                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
2054                      MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
2055         if (phy->req_duplex == DUPLEX_FULL)
2056                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
2057         CL45_WR_OVER_CL22(bp, phy,
2058                               MDIO_REG_BANK_COMBO_IEEE0,
2059                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
2060
2061         /* program speed
2062            - needed only if the speed is greater than 1G (2.5G or 10G) */
2063         CL45_RD_OVER_CL22(bp, phy,
2064                                       MDIO_REG_BANK_SERDES_DIGITAL,
2065                                       MDIO_SERDES_DIGITAL_MISC1, &reg_val);
2066         /* clearing the speed value before setting the right speed */
2067         DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
2068
2069         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
2070                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
2071
2072         if (!((vars->line_speed == SPEED_1000) ||
2073               (vars->line_speed == SPEED_100) ||
2074               (vars->line_speed == SPEED_10))) {
2075
2076                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
2077                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
2078                 if (vars->line_speed == SPEED_10000)
2079                         reg_val |=
2080                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
2081                 if (vars->line_speed == SPEED_13000)
2082                         reg_val |=
2083                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
2084         }
2085
2086         CL45_WR_OVER_CL22(bp, phy,
2087                                       MDIO_REG_BANK_SERDES_DIGITAL,
2088                                       MDIO_SERDES_DIGITAL_MISC1, reg_val);
2089
2090 }
2091
2092 static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x_phy *phy,
2093                                              struct link_params *params)
2094 {
2095         struct bnx2x *bp = params->bp;
2096         u16 val = 0;
2097
2098         /* configure the 48 bits for BAM AN */
2099
2100         /* set extended capabilities */
2101         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
2102                 val |= MDIO_OVER_1G_UP1_2_5G;
2103         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2104                 val |= MDIO_OVER_1G_UP1_10G;
2105         CL45_WR_OVER_CL22(bp, phy,
2106                               MDIO_REG_BANK_OVER_1G,
2107                               MDIO_OVER_1G_UP1, val);
2108
2109         CL45_WR_OVER_CL22(bp, phy,
2110                               MDIO_REG_BANK_OVER_1G,
2111                               MDIO_OVER_1G_UP3, 0x400);
2112 }
2113
2114 static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
2115                                      struct link_params *params, u16 *ieee_fc)
2116 {
2117         struct bnx2x *bp = params->bp;
2118         *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
2119         /* resolve pause mode and advertisement
2120          * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
2121
2122         switch (phy->req_flow_ctrl) {
2123         case BNX2X_FLOW_CTRL_AUTO:
2124                 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
2125                         *ieee_fc |=
2126                              MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2127                 } else {
2128                         *ieee_fc |=
2129                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2130                 }
2131                 break;
2132         case BNX2X_FLOW_CTRL_TX:
2133                 *ieee_fc |=
2134                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2135                 break;
2136
2137         case BNX2X_FLOW_CTRL_RX:
2138         case BNX2X_FLOW_CTRL_BOTH:
2139                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2140                 break;
2141
2142         case BNX2X_FLOW_CTRL_NONE:
2143         default:
2144                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
2145                 break;
2146         }
2147         DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
2148 }
2149
2150 static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x_phy *phy,
2151                                              struct link_params *params,
2152                                            u16 ieee_fc)
2153 {
2154         struct bnx2x *bp = params->bp;
2155         u16 val;
2156         /* for AN, we are always publishing full duplex */
2157
2158         CL45_WR_OVER_CL22(bp, phy,
2159                               MDIO_REG_BANK_COMBO_IEEE0,
2160                               MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
2161         CL45_RD_OVER_CL22(bp, phy,
2162                               MDIO_REG_BANK_CL73_IEEEB1,
2163                               MDIO_CL73_IEEEB1_AN_ADV1, &val);
2164         val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
2165         val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
2166         CL45_WR_OVER_CL22(bp, phy,
2167                               MDIO_REG_BANK_CL73_IEEEB1,
2168                               MDIO_CL73_IEEEB1_AN_ADV1, val);
2169 }
2170
2171 static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
2172                                   struct link_params *params,
2173                                   u8 enable_cl73)
2174 {
2175         struct bnx2x *bp = params->bp;
2176         u16 mii_control;
2177
2178         DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
2179         /* Enable and restart BAM/CL37 aneg */
2180
2181         if (enable_cl73) {
2182                 CL45_RD_OVER_CL22(bp, phy,
2183                                       MDIO_REG_BANK_CL73_IEEEB0,
2184                                       MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2185                                       &mii_control);
2186
2187                 CL45_WR_OVER_CL22(bp, phy,
2188                                 MDIO_REG_BANK_CL73_IEEEB0,
2189                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2190                                 (mii_control |
2191                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
2192                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
2193         } else {
2194
2195                 CL45_RD_OVER_CL22(bp, phy,
2196                                       MDIO_REG_BANK_COMBO_IEEE0,
2197                                       MDIO_COMBO_IEEE0_MII_CONTROL,
2198                                       &mii_control);
2199                 DP(NETIF_MSG_LINK,
2200                          "bnx2x_restart_autoneg mii_control before = 0x%x\n",
2201                          mii_control);
2202                 CL45_WR_OVER_CL22(bp, phy,
2203                                       MDIO_REG_BANK_COMBO_IEEE0,
2204                                       MDIO_COMBO_IEEE0_MII_CONTROL,
2205                                       (mii_control |
2206                                        MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
2207                                        MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
2208         }
2209 }
2210
2211 static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
2212                                            struct link_params *params,
2213                                          struct link_vars *vars)
2214 {
2215         struct bnx2x *bp = params->bp;
2216         u16 control1;
2217
2218         /* in SGMII mode, the unicore is always slave */
2219
2220         CL45_RD_OVER_CL22(bp, phy,
2221                               MDIO_REG_BANK_SERDES_DIGITAL,
2222                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
2223                       &control1);
2224         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
2225         /* set sgmii mode (and not fiber) */
2226         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
2227                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
2228                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
2229         CL45_WR_OVER_CL22(bp, phy,
2230                               MDIO_REG_BANK_SERDES_DIGITAL,
2231                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
2232                               control1);
2233
2234         /* if forced speed */
2235         if (!(vars->line_speed == SPEED_AUTO_NEG)) {
2236                 /* set speed, disable autoneg */
2237                 u16 mii_control;
2238
2239                 CL45_RD_OVER_CL22(bp, phy,
2240                                       MDIO_REG_BANK_COMBO_IEEE0,
2241                                       MDIO_COMBO_IEEE0_MII_CONTROL,
2242                                       &mii_control);
2243                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
2244                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
2245                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
2246
2247                 switch (vars->line_speed) {
2248                 case SPEED_100:
2249                         mii_control |=
2250                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
2251                         break;
2252                 case SPEED_1000:
2253                         mii_control |=
2254                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
2255                         break;
2256                 case SPEED_10:
2257                         /* there is nothing to set for 10M */
2258                         break;
2259                 default:
2260                         /* invalid speed for SGMII */
2261                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2262                                   vars->line_speed);
2263                         break;
2264                 }
2265
2266                 /* setting the full duplex */
2267                 if (phy->req_duplex == DUPLEX_FULL)
2268                         mii_control |=
2269                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
2270                 CL45_WR_OVER_CL22(bp, phy,
2271                                       MDIO_REG_BANK_COMBO_IEEE0,
2272                                       MDIO_COMBO_IEEE0_MII_CONTROL,
2273                                       mii_control);
2274
2275         } else { /* AN mode */
2276                 /* enable and restart AN */
2277                 bnx2x_restart_autoneg(phy, params, 0);
2278         }
2279 }
2280
2281
2282 /*
2283  * link management
2284  */
2285
2286 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
2287 {                                               /*  LD      LP   */
2288         switch (pause_result) {                 /* ASYM P ASYM P */
2289         case 0xb:                               /*   1  0   1  1 */
2290                 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
2291                 break;
2292
2293         case 0xe:                               /*   1  1   1  0 */
2294                 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
2295                 break;
2296
2297         case 0x5:                               /*   0  1   0  1 */
2298         case 0x7:                               /*   0  1   1  1 */
2299         case 0xd:                               /*   1  1   0  1 */
2300         case 0xf:                               /*   1  1   1  1 */
2301                 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
2302                 break;
2303
2304         default:
2305                 break;
2306         }
2307         if (pause_result & (1<<0))
2308                 vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
2309         if (pause_result & (1<<1))
2310                 vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
2311 }
2312
2313 static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
2314                                             struct link_params *params)
2315 {
2316         struct bnx2x *bp = params->bp;
2317         u16 pd_10g, status2_1000x;
2318         if (phy->req_line_speed != SPEED_AUTO_NEG)
2319                 return 0;
2320         CL45_RD_OVER_CL22(bp, phy,
2321                               MDIO_REG_BANK_SERDES_DIGITAL,
2322                               MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
2323                               &status2_1000x);
2324         CL45_RD_OVER_CL22(bp, phy,
2325                               MDIO_REG_BANK_SERDES_DIGITAL,
2326                               MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
2327                               &status2_1000x);
2328         if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
2329                 DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
2330                          params->port);
2331                 return 1;
2332         }
2333
2334         CL45_RD_OVER_CL22(bp, phy,
2335                               MDIO_REG_BANK_10G_PARALLEL_DETECT,
2336                               MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
2337                               &pd_10g);
2338
2339         if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
2340                 DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
2341                          params->port);
2342                 return 1;
2343         }
2344         return 0;
2345 }
2346
2347 static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
2348                                     struct link_params *params,
2349                                     struct link_vars *vars,
2350                                     u32 gp_status)
2351 {
2352         struct bnx2x *bp = params->bp;
2353         u16 ld_pause;   /* local driver */
2354         u16 lp_pause;   /* link partner */
2355         u16 pause_result;
2356
2357         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
2358
2359         /* resolve from gp_status in case of AN complete and not sgmii */
2360         if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
2361                 vars->flow_ctrl = phy->req_flow_ctrl;
2362         else if (phy->req_line_speed != SPEED_AUTO_NEG)
2363                 vars->flow_ctrl = params->req_fc_auto_adv;
2364         else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
2365                  (!(vars->phy_flags & PHY_SGMII_FLAG))) {
2366                 if (bnx2x_direct_parallel_detect_used(phy, params)) {
2367                         vars->flow_ctrl = params->req_fc_auto_adv;
2368                         return;
2369                 }
2370                 if ((gp_status &
2371                     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
2372                      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
2373                     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
2374                      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
2375
2376                         CL45_RD_OVER_CL22(bp, phy,
2377                                               MDIO_REG_BANK_CL73_IEEEB1,
2378                                               MDIO_CL73_IEEEB1_AN_ADV1,
2379                                               &ld_pause);
2380                         CL45_RD_OVER_CL22(bp, phy,
2381                                              MDIO_REG_BANK_CL73_IEEEB1,
2382                                              MDIO_CL73_IEEEB1_AN_LP_ADV1,
2383                                              &lp_pause);
2384                         pause_result = (ld_pause &
2385                                         MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
2386                                         >> 8;
2387                         pause_result |= (lp_pause &
2388                                         MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
2389                                         >> 10;
2390                         DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
2391                                  pause_result);
2392                 } else {
2393                         CL45_RD_OVER_CL22(bp, phy,
2394                                               MDIO_REG_BANK_COMBO_IEEE0,
2395                                               MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
2396                                               &ld_pause);
2397                         CL45_RD_OVER_CL22(bp, phy,
2398                                MDIO_REG_BANK_COMBO_IEEE0,
2399                                MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
2400                                &lp_pause);
2401                         pause_result = (ld_pause &
2402                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
2403                         pause_result |= (lp_pause &
2404                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
2405                         DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
2406                                  pause_result);
2407                 }
2408                 bnx2x_pause_resolve(vars, pause_result);
2409         }
2410         DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
2411 }
2412
2413 static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
2414                                          struct link_params *params)
2415 {
2416         struct bnx2x *bp = params->bp;
2417         u16 rx_status, ustat_val, cl37_fsm_recieved;
2418         DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
2419         /* Step 1: Make sure signal is detected */
2420         CL45_RD_OVER_CL22(bp, phy,
2421                               MDIO_REG_BANK_RX0,
2422                               MDIO_RX0_RX_STATUS,
2423                               &rx_status);
2424         if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
2425             (MDIO_RX0_RX_STATUS_SIGDET)) {
2426                 DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
2427                              "rx_status(0x80b0) = 0x%x\n", rx_status);
2428                 CL45_WR_OVER_CL22(bp, phy,
2429                                       MDIO_REG_BANK_CL73_IEEEB0,
2430                                       MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2431                                       MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
2432                 return;
2433         }
2434         /* Step 2: Check CL73 state machine */
2435         CL45_RD_OVER_CL22(bp, phy,
2436                               MDIO_REG_BANK_CL73_USERB0,
2437                               MDIO_CL73_USERB0_CL73_USTAT1,
2438                               &ustat_val);
2439         if ((ustat_val &
2440              (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
2441               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
2442             (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
2443               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
2444                 DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
2445                              "ustat_val(0x8371) = 0x%x\n", ustat_val);
2446                 return;
2447         }
2448         /* Step 3: Check CL37 Message Pages received to indicate LP
2449         supports only CL37 */
2450         CL45_RD_OVER_CL22(bp, phy,
2451                               MDIO_REG_BANK_REMOTE_PHY,
2452                               MDIO_REMOTE_PHY_MISC_RX_STATUS,
2453                               &cl37_fsm_recieved);
2454         if ((cl37_fsm_recieved &
2455              (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
2456              MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
2457             (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
2458               MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
2459                 DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
2460                              "misc_rx_status(0x8330) = 0x%x\n",
2461                          cl37_fsm_recieved);
2462                 return;
2463         }
2464         /* The combined cl37/cl73 fsm state information indicating that we are
2465         connected to a device which does not support cl73, but does support
2466         cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */
2467         /* Disable CL73 */
2468         CL45_WR_OVER_CL22(bp, phy,
2469                               MDIO_REG_BANK_CL73_IEEEB0,
2470                               MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2471                               0);
2472         /* Restart CL37 autoneg */
2473         bnx2x_restart_autoneg(phy, params, 0);
2474         DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
2475 }
2476
2477 static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
2478                                   struct link_params *params,
2479                                   struct link_vars *vars,
2480                                   u32 gp_status)
2481 {
2482         if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
2483                 vars->link_status |=
2484                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
2485
2486         if (bnx2x_direct_parallel_detect_used(phy, params))
2487                 vars->link_status |=
2488                         LINK_STATUS_PARALLEL_DETECTION_USED;
2489 }
2490
2491 static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy,
2492                                      struct link_params *params,
2493                                      struct link_vars *vars)
2494 {
2495         struct bnx2x *bp = params->bp;
2496         u16 new_line_speed , gp_status;
2497         u8 rc = 0;
2498
2499         /* Read gp_status */
2500         CL45_RD_OVER_CL22(bp, phy,
2501                                 MDIO_REG_BANK_GP_STATUS,
2502                                 MDIO_GP_STATUS_TOP_AN_STATUS1,
2503                                 &gp_status);
2504
2505         if (phy->req_line_speed == SPEED_AUTO_NEG)
2506                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
2507         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
2508                 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
2509                          gp_status);
2510
2511                 vars->phy_link_up = 1;
2512                 vars->link_status |= LINK_STATUS_LINK_UP;
2513
2514                 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
2515                         vars->duplex = DUPLEX_FULL;
2516                 else
2517                         vars->duplex = DUPLEX_HALF;
2518
2519                 if (SINGLE_MEDIA_DIRECT(params)) {
2520                         bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
2521                         if (phy->req_line_speed == SPEED_AUTO_NEG)
2522                                 bnx2x_xgxs_an_resolve(phy, params, vars,
2523                                                       gp_status);
2524                 }
2525
2526                 switch (gp_status & GP_STATUS_SPEED_MASK) {
2527                 case GP_STATUS_10M:
2528                         new_line_speed = SPEED_10;
2529                         if (vars->duplex == DUPLEX_FULL)
2530                                 vars->link_status |= LINK_10TFD;
2531                         else
2532                                 vars->link_status |= LINK_10THD;
2533                         break;
2534
2535                 case GP_STATUS_100M:
2536                         new_line_speed = SPEED_100;
2537                         if (vars->duplex == DUPLEX_FULL)
2538                                 vars->link_status |= LINK_100TXFD;
2539                         else
2540                                 vars->link_status |= LINK_100TXHD;
2541                         break;
2542
2543                 case GP_STATUS_1G:
2544                 case GP_STATUS_1G_KX:
2545                         new_line_speed = SPEED_1000;
2546                         if (vars->duplex == DUPLEX_FULL)
2547                                 vars->link_status |= LINK_1000TFD;
2548                         else
2549                                 vars->link_status |= LINK_1000THD;
2550                         break;
2551
2552                 case GP_STATUS_2_5G:
2553                         new_line_speed = SPEED_2500;
2554                         if (vars->duplex == DUPLEX_FULL)
2555                                 vars->link_status |= LINK_2500TFD;
2556                         else
2557                                 vars->link_status |= LINK_2500THD;
2558                         break;
2559
2560                 case GP_STATUS_5G:
2561                 case GP_STATUS_6G:
2562                         DP(NETIF_MSG_LINK,
2563                                  "link speed unsupported  gp_status 0x%x\n",
2564                                   gp_status);
2565                         return -EINVAL;
2566
2567                 case GP_STATUS_10G_KX4:
2568                 case GP_STATUS_10G_HIG:
2569                 case GP_STATUS_10G_CX4:
2570                         new_line_speed = SPEED_10000;
2571                         vars->link_status |= LINK_10GTFD;
2572                         break;
2573
2574                 case GP_STATUS_12G_HIG:
2575                         new_line_speed = SPEED_12000;
2576                         vars->link_status |= LINK_12GTFD;
2577                         break;
2578
2579                 case GP_STATUS_12_5G:
2580                         new_line_speed = SPEED_12500;
2581                         vars->link_status |= LINK_12_5GTFD;
2582                         break;
2583
2584                 case GP_STATUS_13G:
2585                         new_line_speed = SPEED_13000;
2586                         vars->link_status |= LINK_13GTFD;
2587                         break;
2588
2589                 case GP_STATUS_15G:
2590                         new_line_speed = SPEED_15000;
2591                         vars->link_status |= LINK_15GTFD;
2592                         break;
2593
2594                 case GP_STATUS_16G:
2595                         new_line_speed = SPEED_16000;
2596                         vars->link_status |= LINK_16GTFD;
2597                         break;
2598
2599                 default:
2600                         DP(NETIF_MSG_LINK,
2601                                   "link speed unsupported gp_status 0x%x\n",
2602                                   gp_status);
2603                         return -EINVAL;
2604                 }
2605
2606                 vars->line_speed = new_line_speed;
2607
2608         } else { /* link_down */
2609                 DP(NETIF_MSG_LINK, "phy link down\n");
2610
2611                 vars->phy_link_up = 0;
2612
2613                 vars->duplex = DUPLEX_FULL;
2614                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
2615                 vars->mac_type = MAC_TYPE_NONE;
2616
2617                 if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
2618                     SINGLE_MEDIA_DIRECT(params)) {
2619                         /* Check signal is detected */
2620                         bnx2x_check_fallback_to_cl37(phy, params);
2621                 }
2622         }
2623
2624         DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %x line_speed %x\n",
2625                  gp_status, vars->phy_link_up, vars->line_speed);
2626         DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
2627                    vars->duplex, vars->flow_ctrl, vars->link_status);
2628         return rc;
2629 }
2630
2631 static void bnx2x_set_gmii_tx_driver(struct link_params *params)
2632 {
2633         struct bnx2x *bp = params->bp;
2634         struct bnx2x_phy *phy = &params->phy[INT_PHY];
2635         u16 lp_up2;
2636         u16 tx_driver;
2637         u16 bank;
2638
2639         /* read precomp */
2640         CL45_RD_OVER_CL22(bp, phy,
2641                               MDIO_REG_BANK_OVER_1G,
2642                               MDIO_OVER_1G_LP_UP2, &lp_up2);
2643
2644         /* bits [10:7] at lp_up2, positioned at [15:12] */
2645         lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
2646                    MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
2647                   MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
2648
2649         if (lp_up2 == 0)
2650                 return;
2651
2652         for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
2653               bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
2654                 CL45_RD_OVER_CL22(bp, phy,
2655                                       bank,
2656                                       MDIO_TX0_TX_DRIVER, &tx_driver);
2657
2658                 /* replace tx_driver bits [15:12] */
2659                 if (lp_up2 !=
2660                     (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
2661                         tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
2662                         tx_driver |= lp_up2;
2663                         CL45_WR_OVER_CL22(bp, phy,
2664                                               bank,
2665                                               MDIO_TX0_TX_DRIVER, tx_driver);
2666                 }
2667         }
2668 }
2669
2670 static u8 bnx2x_emac_program(struct link_params *params,
2671                              struct link_vars *vars)
2672 {
2673         struct bnx2x *bp = params->bp;
2674         u8 port = params->port;
2675         u16 mode = 0;
2676
2677         DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
2678         bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
2679                      EMAC_REG_EMAC_MODE,
2680                      (EMAC_MODE_25G_MODE |
2681                      EMAC_MODE_PORT_MII_10M |
2682                      EMAC_MODE_HALF_DUPLEX));
2683         switch (vars->line_speed) {
2684         case SPEED_10:
2685                 mode |= EMAC_MODE_PORT_MII_10M;
2686                 break;
2687
2688         case SPEED_100:
2689                 mode |= EMAC_MODE_PORT_MII;
2690                 break;
2691
2692         case SPEED_1000:
2693                 mode |= EMAC_MODE_PORT_GMII;
2694                 break;
2695
2696         case SPEED_2500:
2697                 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
2698                 break;
2699
2700         default:
2701                 /* 10G not valid for EMAC */
2702                 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2703                            vars->line_speed);
2704                 return -EINVAL;
2705         }
2706
2707         if (vars->duplex == DUPLEX_HALF)
2708                 mode |= EMAC_MODE_HALF_DUPLEX;
2709         bnx2x_bits_en(bp,
2710                     GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
2711                     mode);
2712
2713         bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
2714         return 0;
2715 }
2716
2717 static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
2718                                   struct link_params *params)
2719 {
2720
2721         u16 bank, i = 0;
2722         struct bnx2x *bp = params->bp;
2723
2724         for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
2725               bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
2726                         CL45_WR_OVER_CL22(bp, phy,
2727                                           bank,
2728                                           MDIO_RX0_RX_EQ_BOOST,
2729                                           phy->rx_preemphasis[i]);
2730         }
2731
2732         for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
2733                       bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
2734                         CL45_WR_OVER_CL22(bp, phy,
2735                                           bank,
2736                                           MDIO_TX0_TX_DRIVER,
2737                                           phy->tx_preemphasis[i]);
2738         }
2739 }
2740
2741 static void bnx2x_init_internal_phy(struct bnx2x_phy *phy,
2742                                     struct link_params *params,
2743                                     struct link_vars *vars)
2744 {
2745         struct bnx2x *bp = params->bp;
2746         u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
2747                           (params->loopback_mode == LOOPBACK_XGXS));
2748         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2749                 if (SINGLE_MEDIA_DIRECT(params) &&
2750                     (params->feature_config_flags &
2751                      FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
2752                         bnx2x_set_preemphasis(phy, params);
2753
2754                 /* forced speed requested? */
2755                 if (vars->line_speed != SPEED_AUTO_NEG ||
2756                     (SINGLE_MEDIA_DIRECT(params) &&
2757                           params->loopback_mode == LOOPBACK_EXT)) {
2758                         DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2759
2760                         /* disable autoneg */
2761                         bnx2x_set_autoneg(phy, params, vars, 0);
2762
2763                         /* program speed and duplex */
2764                         bnx2x_program_serdes(phy, params, vars);
2765
2766                 } else { /* AN_mode */
2767                         DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2768
2769                         /* AN enabled */
2770                         bnx2x_set_brcm_cl37_advertisment(phy, params);
2771
2772                         /* program duplex & pause advertisement (for aneg) */
2773                         bnx2x_set_ieee_aneg_advertisment(phy, params,
2774                                                        vars->ieee_fc);
2775
2776                         /* enable autoneg */
2777                         bnx2x_set_autoneg(phy, params, vars, enable_cl73);
2778
2779                         /* enable and restart AN */
2780                         bnx2x_restart_autoneg(phy, params, enable_cl73);
2781                 }
2782
2783         } else { /* SGMII mode */
2784                 DP(NETIF_MSG_LINK, "SGMII\n");
2785
2786                 bnx2x_initialize_sgmii_process(phy, params, vars);
2787         }
2788 }
2789
2790 static u8 bnx2x_init_serdes(struct bnx2x_phy *phy,
2791                             struct link_params *params,
2792                             struct link_vars *vars)
2793 {
2794         u8 rc;
2795         vars->phy_flags |= PHY_SGMII_FLAG;
2796         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2797         bnx2x_set_aer_mmd_serdes(params->bp, phy);
2798         rc = bnx2x_reset_unicore(params, phy, 1);
2799         /* reset the SerDes and wait for reset bit return low */
2800         if (rc != 0)
2801                 return rc;
2802         bnx2x_set_aer_mmd_serdes(params->bp, phy);
2803
2804         return rc;
2805 }
2806
2807 static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy,
2808                           struct link_params *params,
2809                           struct link_vars *vars)
2810 {
2811         u8 rc;
2812         vars->phy_flags = PHY_XGXS_FLAG;
2813         if ((phy->req_line_speed &&
2814              ((phy->req_line_speed == SPEED_100) ||
2815               (phy->req_line_speed == SPEED_10))) ||
2816             (!phy->req_line_speed &&
2817              (phy->speed_cap_mask >=
2818               PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
2819              (phy->speed_cap_mask <
2820               PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
2821              ))
2822                 vars->phy_flags |= PHY_SGMII_FLAG;
2823         else
2824                 vars->phy_flags &= ~PHY_SGMII_FLAG;
2825
2826         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2827         bnx2x_set_aer_mmd_xgxs(params, phy);
2828         bnx2x_set_master_ln(params, phy);
2829
2830         rc = bnx2x_reset_unicore(params, phy, 0);
2831         /* reset the SerDes and wait for reset bit return low */
2832         if (rc != 0)
2833                 return rc;
2834
2835         bnx2x_set_aer_mmd_xgxs(params, phy);
2836
2837         /* setting the masterLn_def again after the reset */
2838         bnx2x_set_master_ln(params, phy);
2839         bnx2x_set_swap_lanes(params, phy);
2840
2841         return rc;
2842 }
2843
2844 static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
2845                                      struct bnx2x_phy *phy)
2846 {
2847         u16 cnt, ctrl;
2848         /* Wait for soft reset to get cleared upto 1 sec */
2849         for (cnt = 0; cnt < 1000; cnt++) {
2850                 bnx2x_cl45_read(bp, phy,
2851                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl);
2852                 if (!(ctrl & (1<<15)))
2853                         break;
2854                 msleep(1);
2855         }
2856         DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
2857         return cnt;
2858 }
2859
2860 static void bnx2x_link_int_enable(struct link_params *params)
2861 {
2862         u8 port = params->port;
2863         u32 mask;
2864         struct bnx2x *bp = params->bp;
2865
2866         /* setting the status to report on link up
2867            for either XGXS or SerDes */
2868
2869         if (params->switch_cfg == SWITCH_CFG_10G) {
2870                 mask = (NIG_MASK_XGXS0_LINK10G |
2871                         NIG_MASK_XGXS0_LINK_STATUS);
2872                 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
2873                 if (!(SINGLE_MEDIA_DIRECT(params)) &&
2874                         params->phy[INT_PHY].type !=
2875                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
2876                         mask |= NIG_MASK_MI_INT;
2877                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
2878                 }
2879
2880         } else { /* SerDes */
2881                 mask = NIG_MASK_SERDES0_LINK_STATUS;
2882                 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
2883                 if (!(SINGLE_MEDIA_DIRECT(params)) &&
2884                         params->phy[INT_PHY].type !=
2885                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
2886                         mask |= NIG_MASK_MI_INT;
2887                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
2888                 }
2889         }
2890         bnx2x_bits_en(bp,
2891                       NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
2892                       mask);
2893
2894         DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
2895                  (params->switch_cfg == SWITCH_CFG_10G),
2896                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
2897         DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
2898                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
2899                  REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
2900                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
2901         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
2902            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
2903            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
2904 }
2905
2906 static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port,
2907                                      u8 exp_mi_int)
2908 {
2909         u32 latch_status = 0;
2910
2911         /**
2912          * Disable the MI INT ( external phy int ) by writing 1 to the
2913          * status register. Link down indication is high-active-signal,
2914          * so in this case we need to write the status to clear the XOR
2915          */
2916         /* Read Latched signals */
2917         latch_status = REG_RD(bp,
2918                                     NIG_REG_LATCH_STATUS_0 + port*8);
2919         DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status);
2920         /* Handle only those with latched-signal=up.*/
2921         if (exp_mi_int)
2922                 bnx2x_bits_en(bp,
2923                               NIG_REG_STATUS_INTERRUPT_PORT0
2924                               + port*4,
2925                               NIG_STATUS_EMAC0_MI_INT);
2926         else
2927                 bnx2x_bits_dis(bp,
2928                                NIG_REG_STATUS_INTERRUPT_PORT0
2929                                + port*4,
2930                                NIG_STATUS_EMAC0_MI_INT);
2931
2932         if (latch_status & 1) {
2933
2934                 /* For all latched-signal=up : Re-Arm Latch signals */
2935                 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
2936                              (latch_status & 0xfffe) | (latch_status & 1));
2937         }
2938         /* For all latched-signal=up,Write original_signal to status */
2939 }
2940
2941 static void bnx2x_link_int_ack(struct link_params *params,
2942                              struct link_vars *vars, u8 is_10g)
2943 {
2944         struct bnx2x *bp = params->bp;
2945         u8 port = params->port;
2946
2947         /* first reset all status
2948          * we assume only one line will be change at a time */
2949         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2950                      (NIG_STATUS_XGXS0_LINK10G |
2951                       NIG_STATUS_XGXS0_LINK_STATUS |
2952                       NIG_STATUS_SERDES0_LINK_STATUS));
2953         if (vars->phy_link_up) {
2954                 if (is_10g) {
2955                         /* Disable the 10G link interrupt
2956                          * by writing 1 to the status register
2957                          */
2958                         DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
2959                         bnx2x_bits_en(bp,
2960                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2961                                       NIG_STATUS_XGXS0_LINK10G);
2962
2963                 } else if (params->switch_cfg == SWITCH_CFG_10G) {
2964                         /* Disable the link interrupt
2965                          * by writing 1 to the relevant lane
2966                          * in the status register
2967                          */
2968                         u32 ser_lane = ((params->lane_config &
2969                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
2970                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
2971
2972                         DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
2973                                  vars->line_speed);
2974                         bnx2x_bits_en(bp,
2975                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2976                                       ((1 << ser_lane) <<
2977                                        NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
2978
2979                 } else { /* SerDes */
2980                         DP(NETIF_MSG_LINK, "SerDes phy link up\n");
2981                         /* Disable the link interrupt
2982                          * by writing 1 to the status register
2983                          */
2984                         bnx2x_bits_en(bp,
2985                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2986                                       NIG_STATUS_SERDES0_LINK_STATUS);
2987                 }
2988
2989         }
2990 }
2991
2992 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len)
2993 {
2994         u8 *str_ptr = str;
2995         u32 mask = 0xf0000000;
2996         u8 shift = 8*4;
2997         u8 digit;
2998         u8 remove_leading_zeros = 1;
2999         if (*len < 10) {
3000                 /* Need more than 10chars for this format */
3001                 *str_ptr = '\0';
3002                 (*len)--;
3003                 return -EINVAL;
3004         }
3005         while (shift > 0) {
3006
3007                 shift -= 4;
3008                 digit = ((num & mask) >> shift);
3009                 if (digit == 0 && remove_leading_zeros) {
3010                         mask = mask >> 4;
3011                         continue;
3012                 } else if (digit < 0xa)
3013                         *str_ptr = digit + '0';
3014                 else
3015                         *str_ptr = digit - 0xa + 'a';
3016                 remove_leading_zeros = 0;
3017                 str_ptr++;
3018                 (*len)--;
3019                 mask = mask >> 4;
3020                 if (shift == 4*4) {
3021                         *str_ptr = '.';
3022                         str_ptr++;
3023                         (*len)--;
3024                         remove_leading_zeros = 1;
3025                 }
3026         }
3027         return 0;
3028 }
3029