1 /* Copyright 2008-2009 Broadcom Corporation
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").
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
13 * Written by Yaniv Rosner
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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>
29 /********************************************************/
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
38 /***********************************************************/
39 /* Shortcut definitions */
40 /***********************************************************/
42 #define NIG_LATCH_BC_ENABLE_MI_INT 0
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
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)
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)
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)
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
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
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
139 #define PHY_XGXS_FLAG 0x1
140 #define PHY_SGMII_FLAG 0x2
141 #define PHY_SERDES_FLAG 0x4
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
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)
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
158 #define SFP_EEPROM_OPTIONS_ADDR 0x40
159 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
160 #define SFP_EEPROM_OPTIONS_SIZE 2
162 #define EDC_MODE_LINEAR 0x0022
163 #define EDC_MODE_LIMITING 0x0044
164 #define EDC_MODE_PASSIVE_DAC 0x0055
167 #define ETS_BW_LIMIT_CREDIT_UPPER_BOUND (0x5000)
168 #define ETS_BW_LIMIT_CREDIT_WEIGHT (0x5000)
169 /**********************************************************/
171 /**********************************************************/
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)), \
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)), \
185 static u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
186 u8 devad, u16 reg, u16 *ret_val);
188 static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
189 u8 devad, u16 reg, u16 val);
191 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
193 u32 val = REG_RD(bp, reg);
196 REG_WR(bp, reg, val);
200 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
202 u32 val = REG_RD(bp, reg);
205 REG_WR(bp, reg, val);
209 /******************************************************************/
211 /******************************************************************/
212 void bnx2x_ets_disabled(struct link_params *params)
214 /* ETS disabled configuration*/
215 struct bnx2x *bp = params->bp;
217 DP(NETIF_MSG_LINK, "ETS disabled configuration\n");
220 * mapping between entry priority to client number (0,1,2 -debug and
221 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
223 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
224 * cos1-100 cos0-011 dbg1-010 dbg0-001 MCP-000
227 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
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
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);
241 * For strict priority entries defines the number of consecutive
242 * slots for the highest priority.
244 REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
246 * mapping between the CREDIT_WEIGHT registers and actual client
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);
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);
259 * If ETS mode is enabled (there is no strict priority) defines a WFQ
260 * weight for COS0/COS1.
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);
271 void bnx2x_ets_bw_limit_common(const struct link_params *params)
273 /* ETS disabled configuration */
274 struct bnx2x *bp = params->bp;
275 DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
277 * defines which entries (clients) are subjected to WFQ arbitration
281 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
283 * mapping between the ARB_CREDIT_WEIGHT registers and actual
284 * client numbers (WEIGHT_0 does not actually have to represent
286 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
287 * cos1-001 cos0-000 dbg1-100 dbg0-011 MCP-010
289 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
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);
296 /* ETS mode enabled*/
297 REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
299 /* Defines the number of consecutive slots for the strict priority */
300 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
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
309 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
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);
318 void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
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;
327 DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
329 if ((0 == total_bw) ||
333 "bnx2x_ets_bw_limit: Total BW can't be zero\n");
337 cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
339 cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
342 bnx2x_ets_bw_limit_common(params);
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);
347 REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
348 REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
351 u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
353 /* ETS disabled configuration*/
354 struct bnx2x *bp = params->bp;
357 DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
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
366 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
368 * For strict priority entries defines the number of consecutive slots
369 * for the highest priority.
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);
377 /* Defines the number of consecutive slots for the strict priority */
378 REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
381 * mapping between entry priority to client number (0,1,2 -debug and
382 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
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
388 val = (0 == strict_cos) ? 0x2318 : 0x22E0;
389 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
393 /******************************************************************/
395 /******************************************************************/
397 static void bnx2x_bmac2_get_pfc_stat(struct link_params *params,
398 u32 pfc_frames_sent[2],
399 u32 pfc_frames_received[2])
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;
406 DP(NETIF_MSG_LINK, "pfc statistic read from BMAC\n");
408 REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_STAT_GTPP,
411 REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_STAT_GRPP,
412 pfc_frames_received, 2);
415 static void bnx2x_emac_get_pfc_stat(struct link_params *params,
416 u32 pfc_frames_sent[2],
417 u32 pfc_frames_received[2])
419 /* Read pfc statistic */
420 struct bnx2x *bp = params->bp;
421 u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
425 DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n");
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;
434 pfc_frames_received[0] = val_xon + val_xoff;
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;
443 pfc_frames_sent[0] = val_xon + val_xoff;
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])
450 /* Read pfc statistic */
451 struct bnx2x *bp = params->bp;
453 DP(NETIF_MSG_LINK, "pfc statistic\n");
458 val = REG_RD(bp, MISC_REG_RESET_REG_2);
459 if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
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);
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);
470 /******************************************************************/
471 /* MAC/PBF section */
472 /******************************************************************/
473 static void bnx2x_emac_init(struct link_params *params,
474 struct link_vars *vars)
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;
483 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
484 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
486 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
487 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
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));
496 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
497 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
499 DP(NETIF_MSG_LINK, "EMAC timeout!\n");
503 } while (val & EMAC_MODE_RESET);
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);
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);
517 static u8 bnx2x_emac_enable(struct link_params *params,
518 struct link_vars *vars, u8 lb)
520 struct bnx2x *bp = params->bp;
521 u8 port = params->port;
522 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
525 DP(NETIF_MSG_LINK, "enabling EMAC\n");
527 /* enable emac and not bmac */
528 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
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 +
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");
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,
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);
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 +
559 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
562 } else { /* SerDes */
563 DP(NETIF_MSG_LINK, "SerDes\n");
565 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
569 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
571 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
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));
580 /* pause enable/disable */
581 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
582 EMAC_RX_MODE_FLOW_EN);
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);
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));
600 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
601 EMAC_TX_MODE_FLOW_EN);
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;
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
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);
625 EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
627 EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
629 EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
630 val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
632 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
635 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
640 EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
643 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
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)));
651 REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
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);
658 /* enable the NIG in/out to the emac */
659 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
661 if ((params->feature_config_flags &
662 FEATURE_CONFIG_PFC_ENABLED) ||
663 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
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);
669 if (CHIP_REV_IS_EMUL(bp)) {
670 /* take the BigMac out of reset */
672 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
673 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
675 /* enable access for bmac registers */
676 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
678 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
680 vars->mac_type = MAC_TYPE_EMAC;
684 static void bnx2x_update_pfc_bmac1(struct link_params *params,
685 struct link_vars *vars)
688 struct bnx2x *bp = params->bp;
689 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
690 NIG_REG_INGRESS_BMAC0_MEM;
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 */
700 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
704 if (!(params->feature_config_flags &
705 FEATURE_CONFIG_PFC_ENABLED) &&
706 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
710 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
713 static void bnx2x_update_pfc_bmac2(struct link_params *params,
714 struct link_vars *vars,
718 * Set rx control: Strip CRC and enable BigMAC to relay
719 * control packets to the system as well
722 struct bnx2x *bp = params->bp;
723 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
724 NIG_REG_INGRESS_BMAC0_MEM;
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 */
734 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL,
740 if (!(params->feature_config_flags &
741 FEATURE_CONFIG_PFC_ENABLED) &&
742 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
746 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
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 */
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 */
758 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
760 /* Clear the force Xon */
761 wb_data[0] &= ~(1<<2);
763 DP(NETIF_MSG_LINK, "PFC is disabled\n");
764 /* disable PFC RX & TX & STATS and set 8 COS */
769 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
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
778 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
779 val |= (1<<16); /* enable automatic re-send */
783 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
787 val = 0x3; /* Enable RX and TX */
789 val |= 0x4; /* Local loopback */
790 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
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));
798 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL,
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)
806 struct bnx2x *bp = params->bp;
807 int set_pfc = params->feature_config_flags &
808 FEATURE_CONFIG_PFC_ENABLED;
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;
816 if (set_pfc && pfc_params)
818 if (!pfc_params->cos0_pauseable) {
820 PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE;
822 PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE;
824 PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE;
826 PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE;
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);
841 if (set_pfc && pfc_params) {
843 if (pfc_params->cos1_pauseable) {
845 PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE;
847 PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE;
849 PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE;
851 PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE;
854 PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE;
856 PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE;
858 PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE;
860 PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE;
863 * The number of free blocks below which the pause signal to
864 * class 1 of MAC #n is asserted. n=0,1
866 REG_WR(bp, BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0, pause_xoff_th);
868 * The number of free blocks above which the pause signal to
869 * class 1 of MAC #n is de-asserted. n=0,1
871 REG_WR(bp, BRB1_REG_PAUSE_1_XON_THRESHOLD_0, pause_xon_th);
873 * The number of free blocks below which the full signal to
874 * class 1 of MAC #n is asserted. n=0,1
876 REG_WR(bp, BRB1_REG_FULL_1_XOFF_THRESHOLD_0, full_xoff_th);
878 * The number of free blocks above which the full signal to
879 * class 1 of MAC #n is de-asserted. n=0,1
881 REG_WR(bp, BRB1_REG_FULL_1_XON_THRESHOLD_0, full_xon_th);
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)
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;
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");
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.
904 xcm_mask = REG_RD(bp,
905 port ? NIG_REG_LLH1_XCM_MASK :
906 NIG_REG_LLH0_XCM_MASK);
908 * nig params will override non PFC params, since it's possible to
909 * do transition from PFC to SAFC
916 xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
917 NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
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 */
928 xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
929 NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
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);
940 REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
941 NIG_REG_PPP_ENABLE_0, ppp_enable);
943 REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
944 NIG_REG_LLH0_XCM_MASK, xcm_mask);
946 REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
948 /* output enable for RX_XCM # IF */
949 REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en);
951 /* HW PFC TX enable */
952 REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable);
954 /* 0x2 = BMAC, 0x1= EMAC */
955 switch (vars->mac_type) {
966 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT, val);
969 pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
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);
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);
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);
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);
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);
993 void bnx2x_update_pfc(struct link_params *params,
994 struct link_vars *vars,
995 struct bnx2x_nig_brb_pfc_port_params *pfc_params)
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.
1003 struct bnx2x *bp = params->bp;
1005 /* update NIG params */
1006 bnx2x_update_pfc_nig(params, vars, pfc_params);
1008 /* update BRB params */
1009 bnx2x_update_pfc_brb(params, vars, pfc_params);
1014 val = REG_RD(bp, MISC_REG_RESET_REG_2);
1015 if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
1017 DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
1018 bnx2x_emac_enable(params, vars, 0);
1022 DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
1024 bnx2x_update_pfc_bmac2(params, vars, 0);
1026 bnx2x_update_pfc_bmac1(params, vars);
1029 if ((params->feature_config_flags &
1030 FEATURE_CONFIG_PFC_ENABLED) ||
1031 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1033 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
1036 static u8 bnx2x_bmac1_enable(struct link_params *params,
1037 struct link_vars *vars,
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;
1047 DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
1052 REG_WR_DMAE(bp, bmac_addr +
1053 BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
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,
1070 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
1074 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
1078 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1080 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
1083 bnx2x_update_pfc_bmac1(params, vars);
1086 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1088 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
1091 /* set cnt max size */
1092 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1094 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
1097 /* configure safc */
1098 wb_data[0] = 0x1000200;
1100 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
1102 /* fix for emulation */
1103 if (CHIP_REV_IS_EMUL(bp)) {
1104 wb_data[0] = 0xf000;
1107 bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
1115 static u8 bnx2x_bmac2_enable(struct link_params *params,
1116 struct link_vars *vars,
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;
1125 DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
1129 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL,
1133 /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
1136 REG_WR_DMAE(bp, bmac_addr +
1137 BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
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,
1154 /* Configure SAFC */
1155 wb_data[0] = 0x1000200;
1157 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
1162 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1164 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE,
1169 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1171 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE,
1174 /* set cnt max size */
1175 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
1177 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE,
1180 bnx2x_update_pfc_bmac2(params, vars, is_lb);
1185 static u8 bnx2x_bmac_enable(struct link_params *params,
1186 struct link_vars *vars,
1189 u8 rc, port = params->port;
1190 struct bnx2x *bp = params->bp;
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));
1197 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1198 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1200 /* enable access for bmac registers */
1201 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
1203 /* Enable BMAC according to BMAC type*/
1205 rc = bnx2x_bmac2_enable(params, vars, is_lb);
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);
1212 if ((params->feature_config_flags &
1213 FEATURE_CONFIG_PFC_ENABLED) ||
1214 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
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);
1223 vars->mac_type = MAC_TYPE_BMAC;
1228 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
1230 struct bnx2x *bp = params->bp;
1232 REG_WR(bp, params->shmem_base +
1233 offsetof(struct shmem_region,
1234 port_mb[params->port].link_status),
1238 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
1240 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1241 NIG_REG_INGRESS_BMAC0_MEM;
1243 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
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) &&
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,
1255 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
1256 REG_WR_DMAE(bp, bmac_addr +
1257 BIGMAC2_REGISTER_BMAC_CONTROL,
1260 /* Clear Rx Enable bit in BMAC_CONTROL register */
1261 REG_RD_DMAE(bp, bmac_addr +
1262 BIGMAC_REGISTER_BMAC_CONTROL,
1264 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
1265 REG_WR_DMAE(bp, bmac_addr +
1266 BIGMAC_REGISTER_BMAC_CONTROL,
1273 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
1276 struct bnx2x *bp = params->bp;
1277 u8 port = params->port;
1282 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
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);
1289 while ((init_crd != crd) && count) {
1292 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
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",
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) */
1314 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
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) {
1322 init_crd = thresh + 553 - 22;
1326 init_crd = thresh + 664 - 22;
1330 init_crd = thresh + 742 - 22;
1334 init_crd = thresh + 778 - 22;
1337 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
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);
1346 /* probe the credit changes */
1347 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
1349 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
1352 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
1356 static u32 bnx2x_get_emac_base(struct bnx2x *bp,
1357 u32 mdc_mdio_access, u8 port)
1360 switch (mdc_mdio_access) {
1361 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
1363 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
1364 if (REG_RD(bp, NIG_REG_PORT_SWAP))
1365 emac_base = GRCBASE_EMAC1;
1367 emac_base = GRCBASE_EMAC0;
1369 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
1370 if (REG_RD(bp, NIG_REG_PORT_SWAP))
1371 emac_base = GRCBASE_EMAC0;
1373 emac_base = GRCBASE_EMAC1;
1375 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
1376 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1378 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
1379 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
1388 u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
1389 u8 devad, u16 reg, u16 val)
1391 u32 tmp, saved_mode;
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
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);
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);
1414 for (i = 0; i < 50; i++) {
1417 tmp = REG_RD(bp, phy->mdio_ctrl +
1418 EMAC_REG_EMAC_MDIO_COMM);
1419 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
1424 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
1425 DP(NETIF_MSG_LINK, "write phy register failed\n");
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);
1434 for (i = 0; i < 50; i++) {
1437 tmp = REG_RD(bp, phy->mdio_ctrl +
1438 EMAC_REG_EMAC_MDIO_COMM);
1439 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
1444 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
1445 DP(NETIF_MSG_LINK, "write phy register failed\n");
1450 /* Restore the saved mode */
1451 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
1456 u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
1457 u8 devad, u16 reg, u16 *ret_val)
1459 u32 val, saved_mode;
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
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);
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);
1482 for (i = 0; i < 50; i++) {
1485 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
1486 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
1491 if (val & EMAC_MDIO_COMM_START_BUSY) {
1492 DP(NETIF_MSG_LINK, "read phy register failed\n");
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);
1504 for (i = 0; i < 50; i++) {
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);
1514 if (val & EMAC_MDIO_COMM_START_BUSY) {
1515 DP(NETIF_MSG_LINK, "read phy register failed\n");
1522 /* Restore the saved mode */
1523 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
1528 u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr,
1529 u8 devad, u16 reg, u16 *ret_val)
1533 * Probe for the phy according to the given phy_addr, and execute
1534 * the read request on it
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 ¶ms->phy[phy_index], devad,
1546 u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr,
1547 u8 devad, u16 reg, u16 val)
1551 * Probe for the phy according to the given phy_addr, and execute
1552 * the write request on it
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 ¶ms->phy[phy_index], devad,
1564 static void bnx2x_set_aer_mmd_xgxs(struct link_params *params,
1565 struct bnx2x_phy *phy)
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);
1574 offset = phy->addr + ser_lane;
1576 aer_val = 0x2800 + offset - 1;
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);
1583 static void bnx2x_set_aer_mmd_serdes(struct bnx2x *bp,
1584 struct bnx2x_phy *phy)
1586 CL45_WR_OVER_CL22(bp, phy,
1587 MDIO_REG_BANK_AER_BLOCK,
1588 MDIO_AER_BLOCK_AER_REG, 0x3800);
1591 /******************************************************************/
1592 /* Internal phy section */
1593 /******************************************************************/
1595 static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
1597 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
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);
1603 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
1606 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
1609 static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
1613 DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
1615 val = SERDES_RESET_BITS << (port*16);
1617 /* reset and unreset the SerDes/XGXS */
1618 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
1620 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
1622 bnx2x_set_serdes_access(bp, port);
1624 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
1626 DEFAULT_PHY_DEV_ADDR);
1629 static void bnx2x_xgxs_deassert(struct link_params *params)
1631 struct bnx2x *bp = params->bp;
1634 DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
1635 port = params->port;
1637 val = XGXS_RESET_BITS << (port*16);
1639 /* reset and unreset the SerDes/XGXS */
1640 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
1642 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
1644 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
1646 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
1647 params->phy[INT_PHY].def_md_devad);
1651 void bnx2x_link_status_update(struct link_params *params,
1652 struct link_vars *vars)
1654 struct bnx2x *bp = params->bp;
1656 u8 port = params->port;
1658 vars->link_status = REG_RD(bp, params->shmem_base +
1659 offsetof(struct shmem_region,
1660 port_mb[port].link_status));
1662 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
1664 if (vars->link_up) {
1665 DP(NETIF_MSG_LINK, "phy link up\n");
1667 vars->phy_link_up = 1;
1668 vars->duplex = DUPLEX_FULL;
1669 switch (vars->link_status &
1670 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
1672 vars->duplex = DUPLEX_HALF;
1675 vars->line_speed = SPEED_10;
1679 vars->duplex = DUPLEX_HALF;
1683 vars->line_speed = SPEED_100;
1687 vars->duplex = DUPLEX_HALF;
1690 vars->line_speed = SPEED_1000;
1694 vars->duplex = DUPLEX_HALF;
1697 vars->line_speed = SPEED_2500;
1701 vars->line_speed = SPEED_10000;
1705 vars->line_speed = SPEED_12000;
1709 vars->line_speed = SPEED_12500;
1713 vars->line_speed = SPEED_13000;
1717 vars->line_speed = SPEED_15000;
1721 vars->line_speed = SPEED_16000;
1727 vars->flow_ctrl = 0;
1728 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
1729 vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
1731 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
1732 vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
1734 if (!vars->flow_ctrl)
1735 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1737 if (vars->line_speed &&
1738 ((vars->line_speed == SPEED_10) ||
1739 (vars->line_speed == SPEED_100))) {
1740 vars->phy_flags |= PHY_SGMII_FLAG;
1742 vars->phy_flags &= ~PHY_SGMII_FLAG;
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));
1753 vars->mac_type = MAC_TYPE_BMAC;
1755 vars->mac_type = MAC_TYPE_EMAC;
1757 } else { /* link down */
1758 DP(NETIF_MSG_LINK, "phy link down\n");
1760 vars->phy_link_up = 0;
1762 vars->line_speed = 0;
1763 vars->duplex = DUPLEX_FULL;
1764 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1766 /* indicate no mac active */
1767 vars->mac_type = MAC_TYPE_NONE;
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);
1777 static void bnx2x_set_master_ln(struct link_params *params,
1778 struct bnx2x_phy *phy)
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);
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,
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));
1798 static u8 bnx2x_reset_unicore(struct link_params *params,
1799 struct bnx2x_phy *phy,
1802 struct bnx2x *bp = params->bp;
1806 CL45_RD_OVER_CL22(bp, phy,
1807 MDIO_REG_BANK_COMBO_IEEE0,
1808 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
1810 /* reset the unicore */
1811 CL45_WR_OVER_CL22(bp, phy,
1812 MDIO_REG_BANK_COMBO_IEEE0,
1813 MDIO_COMBO_IEEE0_MII_CONTROL,
1815 MDIO_COMBO_IEEO_MII_CONTROL_RESET));
1817 bnx2x_set_serdes_access(bp, params->port);
1819 /* wait for the reset to self clear */
1820 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
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,
1829 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1835 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1840 static void bnx2x_set_swap_lanes(struct link_params *params,
1841 struct bnx2x_phy *phy)
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;
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);
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,
1863 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1864 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1866 CL45_WR_OVER_CL22(bp, phy,
1867 MDIO_REG_BANK_XGXS_BLOCK2,
1868 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
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,
1876 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1878 CL45_WR_OVER_CL22(bp, phy,
1879 MDIO_REG_BANK_XGXS_BLOCK2,
1880 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1884 static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
1885 struct link_params *params)
1887 struct bnx2x *bp = params->bp;
1889 CL45_RD_OVER_CL22(bp, phy,
1890 MDIO_REG_BANK_SERDES_DIGITAL,
1891 MDIO_SERDES_DIGITAL_A_1000X_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;
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,
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");
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);
1914 CL45_RD_OVER_CL22(bp, phy,
1915 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1916 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1921 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1923 CL45_WR_OVER_CL22(bp, phy,
1924 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1925 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
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);
1937 static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
1938 struct link_params *params,
1939 struct link_vars *vars,
1942 struct bnx2x *bp = params->bp;
1946 CL45_RD_OVER_CL22(bp, phy,
1947 MDIO_REG_BANK_COMBO_IEEE0,
1948 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
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);
1957 CL45_WR_OVER_CL22(bp, phy,
1958 MDIO_REG_BANK_COMBO_IEEE0,
1959 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1961 /* Enable/Disable Autodetection */
1963 CL45_RD_OVER_CL22(bp, phy,
1964 MDIO_REG_BANK_SERDES_DIGITAL,
1965 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_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;
1972 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1974 CL45_WR_OVER_CL22(bp, phy,
1975 MDIO_REG_BANK_SERDES_DIGITAL,
1976 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
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,
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);
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);
1992 CL45_WR_OVER_CL22(bp, phy,
1993 MDIO_REG_BANK_BAM_NEXT_PAGE,
1994 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
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,
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);
2012 /* Advertise CL73 link speeds */
2013 CL45_RD_OVER_CL22(bp, phy,
2014 MDIO_REG_BANK_CL73_IEEEB1,
2015 MDIO_CL73_IEEEB1_AN_ADV2,
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;
2024 CL45_WR_OVER_CL22(bp, phy,
2025 MDIO_REG_BANK_CL73_IEEEB1,
2026 MDIO_CL73_IEEEB1_AN_ADV2,
2029 /* CL73 Autoneg Enabled */
2030 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
2032 } else /* CL73 Autoneg Disabled */
2035 CL45_WR_OVER_CL22(bp, phy,
2036 MDIO_REG_BANK_CL73_IEEEB0,
2037 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
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)
2045 struct bnx2x *bp = params->bp;
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, ®_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);
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, ®_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);
2069 reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
2070 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
2072 if (!((vars->line_speed == SPEED_1000) ||
2073 (vars->line_speed == SPEED_100) ||
2074 (vars->line_speed == SPEED_10))) {
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)
2080 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
2081 if (vars->line_speed == SPEED_13000)
2083 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
2086 CL45_WR_OVER_CL22(bp, phy,
2087 MDIO_REG_BANK_SERDES_DIGITAL,
2088 MDIO_SERDES_DIGITAL_MISC1, reg_val);
2092 static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x_phy *phy,
2093 struct link_params *params)
2095 struct bnx2x *bp = params->bp;
2098 /* configure the 48 bits for BAM AN */
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);
2109 CL45_WR_OVER_CL22(bp, phy,
2110 MDIO_REG_BANK_OVER_1G,
2111 MDIO_OVER_1G_UP3, 0x400);
2114 static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
2115 struct link_params *params, u16 *ieee_fc)
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 */
2122 switch (phy->req_flow_ctrl) {
2123 case BNX2X_FLOW_CTRL_AUTO:
2124 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
2126 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2129 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2132 case BNX2X_FLOW_CTRL_TX:
2134 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2137 case BNX2X_FLOW_CTRL_RX:
2138 case BNX2X_FLOW_CTRL_BOTH:
2139 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2142 case BNX2X_FLOW_CTRL_NONE:
2144 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
2147 DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
2150 static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x_phy *phy,
2151 struct link_params *params,
2154 struct bnx2x *bp = params->bp;
2156 /* for AN, we are always publishing full duplex */
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);
2171 static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
2172 struct link_params *params,
2175 struct bnx2x *bp = params->bp;
2178 DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
2179 /* Enable and restart BAM/CL37 aneg */
2182 CL45_RD_OVER_CL22(bp, phy,
2183 MDIO_REG_BANK_CL73_IEEEB0,
2184 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2187 CL45_WR_OVER_CL22(bp, phy,
2188 MDIO_REG_BANK_CL73_IEEEB0,
2189 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2191 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
2192 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
2195 CL45_RD_OVER_CL22(bp, phy,
2196 MDIO_REG_BANK_COMBO_IEEE0,
2197 MDIO_COMBO_IEEE0_MII_CONTROL,
2200 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
2202 CL45_WR_OVER_CL22(bp, phy,
2203 MDIO_REG_BANK_COMBO_IEEE0,
2204 MDIO_COMBO_IEEE0_MII_CONTROL,
2206 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
2207 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
2211 static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
2212 struct link_params *params,
2213 struct link_vars *vars)
2215 struct bnx2x *bp = params->bp;
2218 /* in SGMII mode, the unicore is always slave */
2220 CL45_RD_OVER_CL22(bp, phy,
2221 MDIO_REG_BANK_SERDES_DIGITAL,
2222 MDIO_SERDES_DIGITAL_A_1000X_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,
2234 /* if forced speed */
2235 if (!(vars->line_speed == SPEED_AUTO_NEG)) {
2236 /* set speed, disable autoneg */
2239 CL45_RD_OVER_CL22(bp, phy,
2240 MDIO_REG_BANK_COMBO_IEEE0,
2241 MDIO_COMBO_IEEE0_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);
2247 switch (vars->line_speed) {
2250 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
2254 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
2257 /* there is nothing to set for 10M */
2260 /* invalid speed for SGMII */
2261 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2266 /* setting the full duplex */
2267 if (phy->req_duplex == DUPLEX_FULL)
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,
2275 } else { /* AN mode */
2276 /* enable and restart AN */
2277 bnx2x_restart_autoneg(phy, params, 0);
2286 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
2288 switch (pause_result) { /* ASYM P ASYM P */
2289 case 0xb: /* 1 0 1 1 */
2290 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
2293 case 0xe: /* 1 1 1 0 */
2294 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
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;
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;
2313 static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
2314 struct link_params *params)
2316 struct bnx2x *bp = params->bp;
2317 u16 pd_10g, status2_1000x;
2318 if (phy->req_line_speed != SPEED_AUTO_NEG)
2320 CL45_RD_OVER_CL22(bp, phy,
2321 MDIO_REG_BANK_SERDES_DIGITAL,
2322 MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
2324 CL45_RD_OVER_CL22(bp, phy,
2325 MDIO_REG_BANK_SERDES_DIGITAL,
2326 MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
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",
2334 CL45_RD_OVER_CL22(bp, phy,
2335 MDIO_REG_BANK_10G_PARALLEL_DETECT,
2336 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
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",
2347 static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
2348 struct link_params *params,
2349 struct link_vars *vars,
2352 struct bnx2x *bp = params->bp;
2353 u16 ld_pause; /* local driver */
2354 u16 lp_pause; /* link partner */
2357 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
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;
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)) {
2376 CL45_RD_OVER_CL22(bp, phy,
2377 MDIO_REG_BANK_CL73_IEEEB1,
2378 MDIO_CL73_IEEEB1_AN_ADV1,
2380 CL45_RD_OVER_CL22(bp, phy,
2381 MDIO_REG_BANK_CL73_IEEEB1,
2382 MDIO_CL73_IEEEB1_AN_LP_ADV1,
2384 pause_result = (ld_pause &
2385 MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
2387 pause_result |= (lp_pause &
2388 MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
2390 DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
2393 CL45_RD_OVER_CL22(bp, phy,
2394 MDIO_REG_BANK_COMBO_IEEE0,
2395 MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
2397 CL45_RD_OVER_CL22(bp, phy,
2398 MDIO_REG_BANK_COMBO_IEEE0,
2399 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
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",
2408 bnx2x_pause_resolve(vars, pause_result);
2410 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
2413 static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
2414 struct link_params *params)
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,
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);
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,
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);
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",
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 */
2468 CL45_WR_OVER_CL22(bp, phy,
2469 MDIO_REG_BANK_CL73_IEEEB0,
2470 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2472 /* Restart CL37 autoneg */
2473 bnx2x_restart_autoneg(phy, params, 0);
2474 DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
2477 static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
2478 struct link_params *params,
2479 struct link_vars *vars,
2482 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
2483 vars->link_status |=
2484 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
2486 if (bnx2x_direct_parallel_detect_used(phy, params))
2487 vars->link_status |=
2488 LINK_STATUS_PARALLEL_DETECTION_USED;
2491 static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy,
2492 struct link_params *params,
2493 struct link_vars *vars)
2495 struct bnx2x *bp = params->bp;
2496 u16 new_line_speed , gp_status;
2499 /* Read gp_status */
2500 CL45_RD_OVER_CL22(bp, phy,
2501 MDIO_REG_BANK_GP_STATUS,
2502 MDIO_GP_STATUS_TOP_AN_STATUS1,
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",
2511 vars->phy_link_up = 1;
2512 vars->link_status |= LINK_STATUS_LINK_UP;
2514 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
2515 vars->duplex = DUPLEX_FULL;
2517 vars->duplex = DUPLEX_HALF;
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,
2526 switch (gp_status & GP_STATUS_SPEED_MASK) {
2528 new_line_speed = SPEED_10;
2529 if (vars->duplex == DUPLEX_FULL)
2530 vars->link_status |= LINK_10TFD;
2532 vars->link_status |= LINK_10THD;
2535 case GP_STATUS_100M:
2536 new_line_speed = SPEED_100;
2537 if (vars->duplex == DUPLEX_FULL)
2538 vars->link_status |= LINK_100TXFD;
2540 vars->link_status |= LINK_100TXHD;
2544 case GP_STATUS_1G_KX:
2545 new_line_speed = SPEED_1000;
2546 if (vars->duplex == DUPLEX_FULL)
2547 vars->link_status |= LINK_1000TFD;
2549 vars->link_status |= LINK_1000THD;
2552 case GP_STATUS_2_5G:
2553 new_line_speed = SPEED_2500;
2554 if (vars->duplex == DUPLEX_FULL)
2555 vars->link_status |= LINK_2500TFD;
2557 vars->link_status |= LINK_2500THD;
2563 "link speed unsupported gp_status 0x%x\n",
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;
2574 case GP_STATUS_12G_HIG:
2575 new_line_speed = SPEED_12000;
2576 vars->link_status |= LINK_12GTFD;
2579 case GP_STATUS_12_5G:
2580 new_line_speed = SPEED_12500;
2581 vars->link_status |= LINK_12_5GTFD;
2585 new_line_speed = SPEED_13000;
2586 vars->link_status |= LINK_13GTFD;
2590 new_line_speed = SPEED_15000;
2591 vars->link_status |= LINK_15GTFD;
2595 new_line_speed = SPEED_16000;
2596 vars->link_status |= LINK_16GTFD;
2601 "link speed unsupported gp_status 0x%x\n",
2606 vars->line_speed = new_line_speed;
2608 } else { /* link_down */
2609 DP(NETIF_MSG_LINK, "phy link down\n");
2611 vars->phy_link_up = 0;
2613 vars->duplex = DUPLEX_FULL;
2614 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
2615 vars->mac_type = MAC_TYPE_NONE;
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);
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);
2631 static void bnx2x_set_gmii_tx_driver(struct link_params *params)
2633 struct bnx2x *bp = params->bp;
2634 struct bnx2x_phy *phy = ¶ms->phy[INT_PHY];
2640 CL45_RD_OVER_CL22(bp, phy,
2641 MDIO_REG_BANK_OVER_1G,
2642 MDIO_OVER_1G_LP_UP2, &lp_up2);
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);
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,
2656 MDIO_TX0_TX_DRIVER, &tx_driver);
2658 /* replace tx_driver bits [15:12] */
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,
2665 MDIO_TX0_TX_DRIVER, tx_driver);
2670 static u8 bnx2x_emac_program(struct link_params *params,
2671 struct link_vars *vars)
2673 struct bnx2x *bp = params->bp;
2674 u8 port = params->port;
2677 DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
2678 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
2680 (EMAC_MODE_25G_MODE |
2681 EMAC_MODE_PORT_MII_10M |
2682 EMAC_MODE_HALF_DUPLEX));
2683 switch (vars->line_speed) {
2685 mode |= EMAC_MODE_PORT_MII_10M;
2689 mode |= EMAC_MODE_PORT_MII;
2693 mode |= EMAC_MODE_PORT_GMII;
2697 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
2701 /* 10G not valid for EMAC */
2702 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2707 if (vars->duplex == DUPLEX_HALF)
2708 mode |= EMAC_MODE_HALF_DUPLEX;
2710 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
2713 bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
2717 static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
2718 struct link_params *params)
2722 struct bnx2x *bp = params->bp;
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,
2728 MDIO_RX0_RX_EQ_BOOST,
2729 phy->rx_preemphasis[i]);
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,
2737 phy->tx_preemphasis[i]);
2741 static void bnx2x_init_internal_phy(struct bnx2x_phy *phy,
2742 struct link_params *params,
2743 struct link_vars *vars)
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);
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");
2760 /* disable autoneg */
2761 bnx2x_set_autoneg(phy, params, vars, 0);
2763 /* program speed and duplex */
2764 bnx2x_program_serdes(phy, params, vars);
2766 } else { /* AN_mode */
2767 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2770 bnx2x_set_brcm_cl37_advertisment(phy, params);
2772 /* program duplex & pause advertisement (for aneg) */
2773 bnx2x_set_ieee_aneg_advertisment(phy, params,
2776 /* enable autoneg */
2777 bnx2x_set_autoneg(phy, params, vars, enable_cl73);
2779 /* enable and restart AN */
2780 bnx2x_restart_autoneg(phy, params, enable_cl73);
2783 } else { /* SGMII mode */
2784 DP(NETIF_MSG_LINK, "SGMII\n");
2786 bnx2x_initialize_sgmii_process(phy, params, vars);
2790 static u8 bnx2x_init_serdes(struct bnx2x_phy *phy,
2791 struct link_params *params,
2792 struct link_vars *vars)
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 */
2802 bnx2x_set_aer_mmd_serdes(params->bp, phy);
2807 static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy,
2808 struct link_params *params,
2809 struct link_vars *vars)
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)
2822 vars->phy_flags |= PHY_SGMII_FLAG;
2824 vars->phy_flags &= ~PHY_SGMII_FLAG;
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);
2830 rc = bnx2x_reset_unicore(params, phy, 0);
2831 /* reset the SerDes and wait for reset bit return low */
2835 bnx2x_set_aer_mmd_xgxs(params, phy);
2837 /* setting the masterLn_def again after the reset */
2838 bnx2x_set_master_ln(params, phy);
2839 bnx2x_set_swap_lanes(params, phy);
2844 static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
2845 struct bnx2x_phy *phy)
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)))
2856 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
2860 static void bnx2x_link_int_enable(struct link_params *params)
2862 u8 port = params->port;
2864 struct bnx2x *bp = params->bp;
2866 /* setting the status to report on link up
2867 for either XGXS or SerDes */
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");
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");
2891 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
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));
2906 static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port,
2909 u32 latch_status = 0;
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
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.*/
2923 NIG_REG_STATUS_INTERRUPT_PORT0
2925 NIG_STATUS_EMAC0_MI_INT);
2928 NIG_REG_STATUS_INTERRUPT_PORT0
2930 NIG_STATUS_EMAC0_MI_INT);
2932 if (latch_status & 1) {
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));
2938 /* For all latched-signal=up,Write original_signal to status */
2941 static void bnx2x_link_int_ack(struct link_params *params,
2942 struct link_vars *vars, u8 is_10g)
2944 struct bnx2x *bp = params->bp;
2945 u8 port = params->port;
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) {
2955 /* Disable the 10G link interrupt
2956 * by writing 1 to the status register
2958 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
2960 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2961 NIG_STATUS_XGXS0_LINK10G);
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
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);
2972 DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
2975 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2977 NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
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
2985 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2986 NIG_STATUS_SERDES0_LINK_STATUS);
2992 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len)
2995 u32 mask = 0xf0000000;
2998 u8 remove_leading_zeros = 1;
3000 /* Need more than 10chars for this format */
3008 digit = ((num & mask) >> shift);
3009 if (digit == 0 && remove_leading_zeros) {
3012 } else if (digit < 0xa)
3013 *str_ptr = digit + '0';
3015 *str_ptr = digit - 0xa + 'a';
3016 remove_leading_zeros = 0;
3024 remove_leading_zeros = 1;