1 /* Copyright 2008-2011 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 /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
32 #define ETH_OVREHEAD (ETH_HLEN + 8 + 8)
33 #define ETH_MIN_PACKET_SIZE 60
34 #define ETH_MAX_PACKET_SIZE 1500
35 #define ETH_MAX_JUMBO_PACKET_SIZE 9600
36 #define MDIO_ACCESS_TIMEOUT 1000
37 #define BMAC_CONTROL_RX_ENABLE 2
39 /***********************************************************/
40 /* Shortcut definitions */
41 /***********************************************************/
43 #define NIG_LATCH_BC_ENABLE_MI_INT 0
45 #define NIG_STATUS_EMAC0_MI_INT \
46 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
47 #define NIG_STATUS_XGXS0_LINK10G \
48 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
49 #define NIG_STATUS_XGXS0_LINK_STATUS \
50 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
51 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
52 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
53 #define NIG_STATUS_SERDES0_LINK_STATUS \
54 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
55 #define NIG_MASK_MI_INT \
56 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
57 #define NIG_MASK_XGXS0_LINK10G \
58 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
59 #define NIG_MASK_XGXS0_LINK_STATUS \
60 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
61 #define NIG_MASK_SERDES0_LINK_STATUS \
62 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
64 #define MDIO_AN_CL73_OR_37_COMPLETE \
65 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
66 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
68 #define XGXS_RESET_BITS \
69 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
70 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
71 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
72 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
73 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
75 #define SERDES_RESET_BITS \
76 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
77 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
78 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
79 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
81 #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
82 #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
83 #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
84 #define AUTONEG_PARALLEL \
85 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
86 #define AUTONEG_SGMII_FIBER_AUTODET \
87 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
88 #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
90 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
91 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
92 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
93 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
94 #define GP_STATUS_SPEED_MASK \
95 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
96 #define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
97 #define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
98 #define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
99 #define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
100 #define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
101 #define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
102 #define GP_STATUS_10G_HIG \
103 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
104 #define GP_STATUS_10G_CX4 \
105 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
106 #define GP_STATUS_12G_HIG \
107 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
108 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
109 #define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
110 #define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
111 #define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
112 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
113 #define GP_STATUS_10G_KX4 \
114 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
116 #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
117 #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
118 #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
119 #define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
120 #define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
121 #define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
122 #define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
123 #define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
124 #define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
125 #define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
126 #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
127 #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
128 #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
129 #define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
130 #define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
131 #define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
132 #define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
133 #define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
134 #define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
135 #define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
136 #define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
137 #define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
138 #define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
140 #define PHY_XGXS_FLAG 0x1
141 #define PHY_SGMII_FLAG 0x2
142 #define PHY_SERDES_FLAG 0x4
145 #define SFP_EEPROM_CON_TYPE_ADDR 0x2
146 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
147 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
150 #define SFP_EEPROM_COMP_CODE_ADDR 0x3
151 #define SFP_EEPROM_COMP_CODE_SR_MASK (1<<4)
152 #define SFP_EEPROM_COMP_CODE_LR_MASK (1<<5)
153 #define SFP_EEPROM_COMP_CODE_LRM_MASK (1<<6)
155 #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
156 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
157 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
159 #define SFP_EEPROM_OPTIONS_ADDR 0x40
160 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
161 #define SFP_EEPROM_OPTIONS_SIZE 2
163 #define EDC_MODE_LINEAR 0x0022
164 #define EDC_MODE_LIMITING 0x0044
165 #define EDC_MODE_PASSIVE_DAC 0x0055
168 #define ETS_BW_LIMIT_CREDIT_UPPER_BOUND (0x5000)
169 #define ETS_BW_LIMIT_CREDIT_WEIGHT (0x5000)
170 /**********************************************************/
172 /**********************************************************/
174 #define CL22_WR_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
175 bnx2x_cl45_write(_bp, _phy, \
176 (_phy)->def_md_devad, \
177 (_bank + (_addr & 0xf)), \
180 #define CL22_RD_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
181 bnx2x_cl45_read(_bp, _phy, \
182 (_phy)->def_md_devad, \
183 (_bank + (_addr & 0xf)), \
186 static u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
187 u8 devad, u16 reg, u16 *ret_val);
189 static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
190 u8 devad, u16 reg, u16 val);
192 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
194 u32 val = REG_RD(bp, reg);
197 REG_WR(bp, reg, val);
201 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
203 u32 val = REG_RD(bp, reg);
206 REG_WR(bp, reg, val);
210 /******************************************************************/
212 /******************************************************************/
213 void bnx2x_ets_disabled(struct link_params *params)
215 /* ETS disabled configuration*/
216 struct bnx2x *bp = params->bp;
218 DP(NETIF_MSG_LINK, "ETS disabled configuration\n");
221 * mapping between entry priority to client number (0,1,2 -debug and
222 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
224 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
225 * cos1-100 cos0-011 dbg1-010 dbg0-001 MCP-000
228 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
230 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
231 * as strict. Bits 0,1,2 - debug and management entries, 3 -
232 * COS0 entry, 4 - COS1 entry.
233 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
234 * bit4 bit3 bit2 bit1 bit0
235 * MCP and debug are strict
238 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
239 /* defines which entries (clients) are subjected to WFQ arbitration */
240 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
242 * For strict priority entries defines the number of consecutive
243 * slots for the highest priority.
245 REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
247 * mapping between the CREDIT_WEIGHT registers and actual client
250 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
251 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
252 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
254 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
255 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
256 REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
257 /* ETS mode disable */
258 REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
260 * If ETS mode is enabled (there is no strict priority) defines a WFQ
261 * weight for COS0/COS1.
263 REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
264 REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710);
265 /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
266 REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680);
267 REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680);
268 /* Defines the number of consecutive slots for the strict priority */
269 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
272 void bnx2x_ets_bw_limit_common(const struct link_params *params)
274 /* ETS disabled configuration */
275 struct bnx2x *bp = params->bp;
276 DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
278 * defines which entries (clients) are subjected to WFQ arbitration
282 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
284 * mapping between the ARB_CREDIT_WEIGHT registers and actual
285 * client numbers (WEIGHT_0 does not actually have to represent
287 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
288 * cos1-001 cos0-000 dbg1-100 dbg0-011 MCP-010
290 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
292 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
293 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
294 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
295 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
297 /* ETS mode enabled*/
298 REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
300 /* Defines the number of consecutive slots for the strict priority */
301 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
303 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
304 * as strict. Bits 0,1,2 - debug and management entries, 3 - COS0
305 * entry, 4 - COS1 entry.
306 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
307 * bit4 bit3 bit2 bit1 bit0
308 * MCP and debug are strict
310 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
312 /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
313 REG_WR(bp, PBF_REG_COS0_UPPER_BOUND,
314 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
315 REG_WR(bp, PBF_REG_COS1_UPPER_BOUND,
316 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
319 void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
322 /* ETS disabled configuration*/
323 struct bnx2x *bp = params->bp;
324 const u32 total_bw = cos0_bw + cos1_bw;
325 u32 cos0_credit_weight = 0;
326 u32 cos1_credit_weight = 0;
328 DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
330 if ((0 == total_bw) ||
333 DP(NETIF_MSG_LINK, "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 + port*4, 1);
539 if (CHIP_REV_IS_FPGA(bp)) {
540 /* Use lane 1 (of lanes 0-3) */
541 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
543 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
544 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
547 if (vars->phy_flags & PHY_XGXS_FLAG) {
548 u32 ser_lane = ((params->lane_config &
549 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
550 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
552 DP(NETIF_MSG_LINK, "XGXS\n");
553 /* select the master lanes (out of 0-3) */
554 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane);
556 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
558 } else { /* SerDes */
559 DP(NETIF_MSG_LINK, "SerDes\n");
561 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
564 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
566 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
569 if (CHIP_REV_IS_SLOW(bp)) {
570 /* config GMII mode */
571 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
572 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII));
574 /* pause enable/disable */
575 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
576 EMAC_RX_MODE_FLOW_EN);
578 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
579 (EMAC_TX_MODE_EXT_PAUSE_EN |
580 EMAC_TX_MODE_FLOW_EN));
581 if (!(params->feature_config_flags &
582 FEATURE_CONFIG_PFC_ENABLED)) {
583 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
584 bnx2x_bits_en(bp, emac_base +
585 EMAC_REG_EMAC_RX_MODE,
586 EMAC_RX_MODE_FLOW_EN);
588 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
589 bnx2x_bits_en(bp, emac_base +
590 EMAC_REG_EMAC_TX_MODE,
591 (EMAC_TX_MODE_EXT_PAUSE_EN |
592 EMAC_TX_MODE_FLOW_EN));
594 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
595 EMAC_TX_MODE_FLOW_EN);
598 /* KEEP_VLAN_TAG, promiscuous */
599 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
600 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
603 * Setting this bit causes MAC control frames (except for pause
604 * frames) to be passed on for processing. This setting has no
605 * affect on the operation of the pause frames. This bit effects
606 * all packets regardless of RX Parser packet sorting logic.
607 * Turn the PFC off to make sure we are in Xon state before
610 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
611 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
612 DP(NETIF_MSG_LINK, "PFC is enabled\n");
613 /* Enable PFC again */
614 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
615 EMAC_REG_RX_PFC_MODE_RX_EN |
616 EMAC_REG_RX_PFC_MODE_TX_EN |
617 EMAC_REG_RX_PFC_MODE_PRIORITIES);
619 EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
621 EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
623 EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
624 val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
626 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
629 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
634 EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
637 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
639 /* enable emac for jumbo packets */
640 EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
641 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
642 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
645 REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
647 /* disable the NIG in/out to the bmac */
648 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
649 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
650 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
652 /* enable the NIG in/out to the emac */
653 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
655 if ((params->feature_config_flags &
656 FEATURE_CONFIG_PFC_ENABLED) ||
657 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
660 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
661 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
663 if (CHIP_REV_IS_EMUL(bp)) {
664 /* take the BigMac out of reset */
665 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
666 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
668 /* enable access for bmac registers */
669 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
671 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
673 vars->mac_type = MAC_TYPE_EMAC;
677 static void bnx2x_update_pfc_bmac1(struct link_params *params,
678 struct link_vars *vars)
681 struct bnx2x *bp = params->bp;
682 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
683 NIG_REG_INGRESS_BMAC0_MEM;
686 if ((!(params->feature_config_flags &
687 FEATURE_CONFIG_PFC_ENABLED)) &&
688 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
689 /* Enable BigMAC to react on received Pause packets */
693 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
697 if (!(params->feature_config_flags &
698 FEATURE_CONFIG_PFC_ENABLED) &&
699 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
703 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
706 static void bnx2x_update_pfc_bmac2(struct link_params *params,
707 struct link_vars *vars,
711 * Set rx control: Strip CRC and enable BigMAC to relay
712 * control packets to the system as well
715 struct bnx2x *bp = params->bp;
716 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
717 NIG_REG_INGRESS_BMAC0_MEM;
720 if ((!(params->feature_config_flags &
721 FEATURE_CONFIG_PFC_ENABLED)) &&
722 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
723 /* Enable BigMAC to react on received Pause packets */
727 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
732 if (!(params->feature_config_flags &
733 FEATURE_CONFIG_PFC_ENABLED) &&
734 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
738 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
740 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
741 DP(NETIF_MSG_LINK, "PFC is enabled\n");
742 /* Enable PFC RX & TX & STATS and set 8 COS */
744 wb_data[0] |= (1<<0); /* RX */
745 wb_data[0] |= (1<<1); /* TX */
746 wb_data[0] |= (1<<2); /* Force initial Xon */
747 wb_data[0] |= (1<<3); /* 8 cos */
748 wb_data[0] |= (1<<5); /* STATS */
750 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
752 /* Clear the force Xon */
753 wb_data[0] &= ~(1<<2);
755 DP(NETIF_MSG_LINK, "PFC is disabled\n");
756 /* disable PFC RX & TX & STATS and set 8 COS */
761 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
764 * Set Time (based unit is 512 bit time) between automatic
765 * re-sending of PP packets amd enable automatic re-send of
766 * Per-Priroity Packet as long as pp_gen is asserted and
770 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
771 val |= (1<<16); /* enable automatic re-send */
775 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
779 val = 0x3; /* Enable RX and TX */
781 val |= 0x4; /* Local loopback */
782 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
784 /* When PFC enabled, Pass pause frames towards the NIG. */
785 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
786 val |= ((1<<6)|(1<<5));
790 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
793 static void bnx2x_update_pfc_brb(struct link_params *params,
794 struct link_vars *vars,
795 struct bnx2x_nig_brb_pfc_port_params *pfc_params)
797 struct bnx2x *bp = params->bp;
798 int set_pfc = params->feature_config_flags &
799 FEATURE_CONFIG_PFC_ENABLED;
801 /* default - pause configuration */
802 u32 pause_xoff_th = PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE;
803 u32 pause_xon_th = PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE;
804 u32 full_xoff_th = PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE;
805 u32 full_xon_th = PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE;
807 if (set_pfc && pfc_params)
809 if (!pfc_params->cos0_pauseable) {
811 PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE;
813 PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE;
815 PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE;
817 PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE;
819 /* The number of free blocks below which the pause signal to class 0
820 of MAC #n is asserted. n=0,1 */
821 REG_WR(bp, BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 , pause_xoff_th);
822 /* The number of free blocks above which the pause signal to class 0
823 of MAC #n is de-asserted. n=0,1 */
824 REG_WR(bp, BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , pause_xon_th);
825 /* The number of free blocks below which the full signal to class 0
826 of MAC #n is asserted. n=0,1 */
827 REG_WR(bp, BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , full_xoff_th);
828 /* The number of free blocks above which the full signal to class 0
829 of MAC #n is de-asserted. n=0,1 */
830 REG_WR(bp, BRB1_REG_FULL_0_XON_THRESHOLD_0 , full_xon_th);
832 if (set_pfc && pfc_params) {
834 if (pfc_params->cos1_pauseable) {
836 PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE;
838 PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE;
840 PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE;
842 PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE;
845 PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE;
847 PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE;
849 PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE;
851 PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE;
854 * The number of free blocks below which the pause signal to
855 * class 1 of MAC #n is asserted. n=0,1
857 REG_WR(bp, BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0, pause_xoff_th);
859 * The number of free blocks above which the pause signal to
860 * class 1 of MAC #n is de-asserted. n=0,1
862 REG_WR(bp, BRB1_REG_PAUSE_1_XON_THRESHOLD_0, pause_xon_th);
864 * The number of free blocks below which the full signal to
865 * class 1 of MAC #n is asserted. n=0,1
867 REG_WR(bp, BRB1_REG_FULL_1_XOFF_THRESHOLD_0, full_xoff_th);
869 * The number of free blocks above which the full signal to
870 * class 1 of MAC #n is de-asserted. n=0,1
872 REG_WR(bp, BRB1_REG_FULL_1_XON_THRESHOLD_0, full_xon_th);
876 static void bnx2x_update_pfc_nig(struct link_params *params,
877 struct link_vars *vars,
878 struct bnx2x_nig_brb_pfc_port_params *nig_params)
880 u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
881 u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0;
882 u32 pkt_priority_to_cos = 0;
884 struct bnx2x *bp = params->bp;
885 int port = params->port;
886 int set_pfc = params->feature_config_flags &
887 FEATURE_CONFIG_PFC_ENABLED;
888 DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
891 * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
892 * MAC control frames (that are not pause packets)
893 * will be forwarded to the XCM.
895 xcm_mask = REG_RD(bp,
896 port ? NIG_REG_LLH1_XCM_MASK :
897 NIG_REG_LLH0_XCM_MASK);
899 * nig params will override non PFC params, since it's possible to
900 * do transition from PFC to SAFC
907 xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
908 NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
913 llfc_out_en = nig_params->llfc_out_en;
914 llfc_enable = nig_params->llfc_enable;
915 pause_enable = nig_params->pause_enable;
916 } else /*defaul non PFC mode - PAUSE */
919 xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
920 NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
924 REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
925 NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
926 REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
927 NIG_REG_LLFC_ENABLE_0, llfc_enable);
928 REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
929 NIG_REG_PAUSE_ENABLE_0, pause_enable);
931 REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
932 NIG_REG_PPP_ENABLE_0, ppp_enable);
934 REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
935 NIG_REG_LLH0_XCM_MASK, xcm_mask);
937 REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
939 /* output enable for RX_XCM # IF */
940 REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en);
942 /* HW PFC TX enable */
943 REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable);
945 /* 0x2 = BMAC, 0x1= EMAC */
946 switch (vars->mac_type) {
957 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT, val);
960 pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
962 REG_WR(bp, port ? NIG_REG_P1_RX_COS0_PRIORITY_MASK :
963 NIG_REG_P0_RX_COS0_PRIORITY_MASK,
964 nig_params->rx_cos0_priority_mask);
966 REG_WR(bp, port ? NIG_REG_P1_RX_COS1_PRIORITY_MASK :
967 NIG_REG_P0_RX_COS1_PRIORITY_MASK,
968 nig_params->rx_cos1_priority_mask);
970 REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
971 NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
972 nig_params->llfc_high_priority_classes);
974 REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
975 NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
976 nig_params->llfc_low_priority_classes);
978 REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
979 NIG_REG_P0_PKT_PRIORITY_TO_COS,
980 pkt_priority_to_cos);
984 void bnx2x_update_pfc(struct link_params *params,
985 struct link_vars *vars,
986 struct bnx2x_nig_brb_pfc_port_params *pfc_params)
989 * The PFC and pause are orthogonal to one another, meaning when
990 * PFC is enabled, the pause are disabled, and when PFC is
991 * disabled, pause are set according to the pause result.
994 struct bnx2x *bp = params->bp;
996 /* update NIG params */
997 bnx2x_update_pfc_nig(params, vars, pfc_params);
999 /* update BRB params */
1000 bnx2x_update_pfc_brb(params, vars, pfc_params);
1005 val = REG_RD(bp, MISC_REG_RESET_REG_2);
1006 if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
1008 DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
1009 bnx2x_emac_enable(params, vars, 0);
1013 DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
1015 bnx2x_update_pfc_bmac2(params, vars, 0);
1017 bnx2x_update_pfc_bmac1(params, vars);
1020 if ((params->feature_config_flags &
1021 FEATURE_CONFIG_PFC_ENABLED) ||
1022 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1024 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
1027 static u8 bnx2x_bmac1_enable(struct link_params *params,
1028 struct link_vars *vars,
1031 struct bnx2x *bp = params->bp;
1032 u8 port = params->port;
1033 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1034 NIG_REG_INGRESS_BMAC0_MEM;
1038 DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
1043 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
1047 wb_data[0] = ((params->mac_addr[2] << 24) |
1048 (params->mac_addr[3] << 16) |
1049 (params->mac_addr[4] << 8) |
1050 params->mac_addr[5]);
1051 wb_data[1] = ((params->mac_addr[0] << 8) |
1052 params->mac_addr[1]);
1053 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
1059 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
1063 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
1066 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1068 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
1070 bnx2x_update_pfc_bmac1(params, vars);
1073 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1075 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
1077 /* set cnt max size */
1078 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1080 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
1082 /* configure safc */
1083 wb_data[0] = 0x1000200;
1085 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
1087 /* fix for emulation */
1088 if (CHIP_REV_IS_EMUL(bp)) {
1089 wb_data[0] = 0xf000;
1091 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
1099 static u8 bnx2x_bmac2_enable(struct link_params *params,
1100 struct link_vars *vars,
1103 struct bnx2x *bp = params->bp;
1104 u8 port = params->port;
1105 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1106 NIG_REG_INGRESS_BMAC0_MEM;
1109 DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
1113 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
1116 /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
1119 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
1125 wb_data[0] = ((params->mac_addr[2] << 24) |
1126 (params->mac_addr[3] << 16) |
1127 (params->mac_addr[4] << 8) |
1128 params->mac_addr[5]);
1129 wb_data[1] = ((params->mac_addr[0] << 8) |
1130 params->mac_addr[1]);
1131 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
1136 /* Configure SAFC */
1137 wb_data[0] = 0x1000200;
1139 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
1144 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1146 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
1150 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1152 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
1154 /* set cnt max size */
1155 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
1157 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
1159 bnx2x_update_pfc_bmac2(params, vars, is_lb);
1164 static u8 bnx2x_bmac_enable(struct link_params *params,
1165 struct link_vars *vars,
1168 u8 rc, port = params->port;
1169 struct bnx2x *bp = params->bp;
1171 /* reset and unreset the BigMac */
1172 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1173 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1176 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1177 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1179 /* enable access for bmac registers */
1180 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
1182 /* Enable BMAC according to BMAC type*/
1184 rc = bnx2x_bmac2_enable(params, vars, is_lb);
1186 rc = bnx2x_bmac1_enable(params, vars, is_lb);
1187 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
1188 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
1189 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
1191 if ((params->feature_config_flags &
1192 FEATURE_CONFIG_PFC_ENABLED) ||
1193 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1195 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
1196 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
1197 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
1198 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
1199 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
1200 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
1202 vars->mac_type = MAC_TYPE_BMAC;
1207 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
1209 struct bnx2x *bp = params->bp;
1211 REG_WR(bp, params->shmem_base +
1212 offsetof(struct shmem_region,
1213 port_mb[params->port].link_status), link_status);
1216 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
1218 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1219 NIG_REG_INGRESS_BMAC0_MEM;
1221 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
1223 /* Only if the bmac is out of reset */
1224 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
1225 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
1228 if (CHIP_IS_E2(bp)) {
1229 /* Clear Rx Enable bit in BMAC_CONTROL register */
1230 REG_RD_DMAE(bp, bmac_addr +
1231 BIGMAC2_REGISTER_BMAC_CONTROL,
1233 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
1234 REG_WR_DMAE(bp, bmac_addr +
1235 BIGMAC2_REGISTER_BMAC_CONTROL,
1238 /* Clear Rx Enable bit in BMAC_CONTROL register */
1239 REG_RD_DMAE(bp, bmac_addr +
1240 BIGMAC_REGISTER_BMAC_CONTROL,
1242 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
1243 REG_WR_DMAE(bp, bmac_addr +
1244 BIGMAC_REGISTER_BMAC_CONTROL,
1251 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
1254 struct bnx2x *bp = params->bp;
1255 u8 port = params->port;
1260 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
1262 /* wait for init credit */
1263 init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
1264 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
1265 DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
1267 while ((init_crd != crd) && count) {
1270 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
1273 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
1274 if (init_crd != crd) {
1275 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
1280 if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
1281 line_speed == SPEED_10 ||
1282 line_speed == SPEED_100 ||
1283 line_speed == SPEED_1000 ||
1284 line_speed == SPEED_2500) {
1285 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
1286 /* update threshold */
1287 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
1288 /* update init credit */
1289 init_crd = 778; /* (800-18-4) */
1292 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
1294 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
1295 /* update threshold */
1296 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
1297 /* update init credit */
1298 switch (line_speed) {
1300 init_crd = thresh + 553 - 22;
1304 init_crd = thresh + 664 - 22;
1308 init_crd = thresh + 742 - 22;
1312 init_crd = thresh + 778 - 22;
1315 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1320 REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
1321 DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
1322 line_speed, init_crd);
1324 /* probe the credit changes */
1325 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
1327 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
1330 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
1334 static u32 bnx2x_get_emac_base(struct bnx2x *bp,
1335 u32 mdc_mdio_access, u8 port)
1338 switch (mdc_mdio_access) {
1339 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
1341 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
1342 if (REG_RD(bp, NIG_REG_PORT_SWAP))
1343 emac_base = GRCBASE_EMAC1;
1345 emac_base = GRCBASE_EMAC0;
1347 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
1348 if (REG_RD(bp, NIG_REG_PORT_SWAP))
1349 emac_base = GRCBASE_EMAC0;
1351 emac_base = GRCBASE_EMAC1;
1353 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
1354 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1356 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
1357 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
1366 u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
1367 u8 devad, u16 reg, u16 val)
1369 u32 tmp, saved_mode;
1372 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
1373 * (a value of 49==0x31) and make sure that the AUTO poll is off
1376 saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
1377 tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
1378 EMAC_MDIO_MODE_CLOCK_CNT);
1379 tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
1380 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
1381 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
1382 REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
1387 tmp = ((phy->addr << 21) | (devad << 16) | reg |
1388 EMAC_MDIO_COMM_COMMAND_ADDRESS |
1389 EMAC_MDIO_COMM_START_BUSY);
1390 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
1392 for (i = 0; i < 50; i++) {
1395 tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
1396 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
1401 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
1402 DP(NETIF_MSG_LINK, "write phy register failed\n");
1406 tmp = ((phy->addr << 21) | (devad << 16) | val |
1407 EMAC_MDIO_COMM_COMMAND_WRITE_45 |
1408 EMAC_MDIO_COMM_START_BUSY);
1409 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
1411 for (i = 0; i < 50; i++) {
1414 tmp = REG_RD(bp, phy->mdio_ctrl +
1415 EMAC_REG_EMAC_MDIO_COMM);
1416 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
1421 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
1422 DP(NETIF_MSG_LINK, "write phy register failed\n");
1427 /* Restore the saved mode */
1428 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
1433 u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
1434 u8 devad, u16 reg, u16 *ret_val)
1436 u32 val, saved_mode;
1440 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
1441 * (a value of 49==0x31) and make sure that the AUTO poll is off
1444 saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
1445 val = saved_mode & ~((EMAC_MDIO_MODE_AUTO_POLL |
1446 EMAC_MDIO_MODE_CLOCK_CNT));
1447 val |= (EMAC_MDIO_MODE_CLAUSE_45 |
1448 (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
1449 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
1450 REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
1454 val = ((phy->addr << 21) | (devad << 16) | reg |
1455 EMAC_MDIO_COMM_COMMAND_ADDRESS |
1456 EMAC_MDIO_COMM_START_BUSY);
1457 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
1459 for (i = 0; i < 50; i++) {
1462 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
1463 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
1468 if (val & EMAC_MDIO_COMM_START_BUSY) {
1469 DP(NETIF_MSG_LINK, "read phy register failed\n");
1476 val = ((phy->addr << 21) | (devad << 16) |
1477 EMAC_MDIO_COMM_COMMAND_READ_45 |
1478 EMAC_MDIO_COMM_START_BUSY);
1479 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
1481 for (i = 0; i < 50; i++) {
1484 val = REG_RD(bp, phy->mdio_ctrl +
1485 EMAC_REG_EMAC_MDIO_COMM);
1486 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
1487 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
1491 if (val & EMAC_MDIO_COMM_START_BUSY) {
1492 DP(NETIF_MSG_LINK, "read phy register failed\n");
1499 /* Restore the saved mode */
1500 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
1505 u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr,
1506 u8 devad, u16 reg, u16 *ret_val)
1510 * Probe for the phy according to the given phy_addr, and execute
1511 * the read request on it
1513 for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
1514 if (params->phy[phy_index].addr == phy_addr) {
1515 return bnx2x_cl45_read(params->bp,
1516 ¶ms->phy[phy_index], devad,
1523 u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr,
1524 u8 devad, u16 reg, u16 val)
1528 * Probe for the phy according to the given phy_addr, and execute
1529 * the write request on it
1531 for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
1532 if (params->phy[phy_index].addr == phy_addr) {
1533 return bnx2x_cl45_write(params->bp,
1534 ¶ms->phy[phy_index], devad,
1541 static void bnx2x_set_aer_mmd_xgxs(struct link_params *params,
1542 struct bnx2x_phy *phy)
1545 u16 offset, aer_val;
1546 struct bnx2x *bp = params->bp;
1547 ser_lane = ((params->lane_config &
1548 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1549 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1551 offset = phy->addr + ser_lane;
1553 aer_val = 0x3800 + offset - 1;
1555 aer_val = 0x3800 + offset;
1556 CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
1557 MDIO_AER_BLOCK_AER_REG, aer_val);
1559 static void bnx2x_set_aer_mmd_serdes(struct bnx2x *bp,
1560 struct bnx2x_phy *phy)
1562 CL22_WR_OVER_CL45(bp, phy,
1563 MDIO_REG_BANK_AER_BLOCK,
1564 MDIO_AER_BLOCK_AER_REG, 0x3800);
1567 /******************************************************************/
1568 /* Internal phy section */
1569 /******************************************************************/
1571 static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
1573 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1576 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
1577 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
1579 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
1582 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
1585 static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
1589 DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
1591 val = SERDES_RESET_BITS << (port*16);
1593 /* reset and unreset the SerDes/XGXS */
1594 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
1596 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
1598 bnx2x_set_serdes_access(bp, port);
1600 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + port*0x10,
1601 DEFAULT_PHY_DEV_ADDR);
1604 static void bnx2x_xgxs_deassert(struct link_params *params)
1606 struct bnx2x *bp = params->bp;
1609 DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
1610 port = params->port;
1612 val = XGXS_RESET_BITS << (port*16);
1614 /* reset and unreset the SerDes/XGXS */
1615 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
1617 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
1619 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0);
1620 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
1621 params->phy[INT_PHY].def_md_devad);
1625 void bnx2x_link_status_update(struct link_params *params,
1626 struct link_vars *vars)
1628 struct bnx2x *bp = params->bp;
1630 u8 port = params->port;
1632 vars->link_status = REG_RD(bp, params->shmem_base +
1633 offsetof(struct shmem_region,
1634 port_mb[port].link_status));
1636 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
1638 if (vars->link_up) {
1639 DP(NETIF_MSG_LINK, "phy link up\n");
1641 vars->phy_link_up = 1;
1642 vars->duplex = DUPLEX_FULL;
1643 switch (vars->link_status &
1644 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
1646 vars->duplex = DUPLEX_HALF;
1649 vars->line_speed = SPEED_10;
1653 vars->duplex = DUPLEX_HALF;
1657 vars->line_speed = SPEED_100;
1661 vars->duplex = DUPLEX_HALF;
1664 vars->line_speed = SPEED_1000;
1668 vars->duplex = DUPLEX_HALF;
1671 vars->line_speed = SPEED_2500;
1675 vars->line_speed = SPEED_10000;
1679 vars->line_speed = SPEED_12000;
1683 vars->line_speed = SPEED_12500;
1687 vars->line_speed = SPEED_13000;
1691 vars->line_speed = SPEED_15000;
1695 vars->line_speed = SPEED_16000;
1701 vars->flow_ctrl = 0;
1702 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
1703 vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
1705 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
1706 vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
1708 if (!vars->flow_ctrl)
1709 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1711 if (vars->line_speed &&
1712 ((vars->line_speed == SPEED_10) ||
1713 (vars->line_speed == SPEED_100))) {
1714 vars->phy_flags |= PHY_SGMII_FLAG;
1716 vars->phy_flags &= ~PHY_SGMII_FLAG;
1719 /* anything 10 and over uses the bmac */
1720 link_10g = ((vars->line_speed == SPEED_10000) ||
1721 (vars->line_speed == SPEED_12000) ||
1722 (vars->line_speed == SPEED_12500) ||
1723 (vars->line_speed == SPEED_13000) ||
1724 (vars->line_speed == SPEED_15000) ||
1725 (vars->line_speed == SPEED_16000));
1727 vars->mac_type = MAC_TYPE_BMAC;
1729 vars->mac_type = MAC_TYPE_EMAC;
1731 } else { /* link down */
1732 DP(NETIF_MSG_LINK, "phy link down\n");
1734 vars->phy_link_up = 0;
1736 vars->line_speed = 0;
1737 vars->duplex = DUPLEX_FULL;
1738 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1740 /* indicate no mac active */
1741 vars->mac_type = MAC_TYPE_NONE;
1744 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
1745 vars->link_status, vars->phy_link_up);
1746 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
1747 vars->line_speed, vars->duplex, vars->flow_ctrl);
1751 static void bnx2x_set_master_ln(struct link_params *params,
1752 struct bnx2x_phy *phy)
1754 struct bnx2x *bp = params->bp;
1755 u16 new_master_ln, ser_lane;
1756 ser_lane = ((params->lane_config &
1757 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1758 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1760 /* set the master_ln for AN */
1761 CL22_RD_OVER_CL45(bp, phy,
1762 MDIO_REG_BANK_XGXS_BLOCK2,
1763 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1766 CL22_WR_OVER_CL45(bp, phy,
1767 MDIO_REG_BANK_XGXS_BLOCK2 ,
1768 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1769 (new_master_ln | ser_lane));
1772 static u8 bnx2x_reset_unicore(struct link_params *params,
1773 struct bnx2x_phy *phy,
1776 struct bnx2x *bp = params->bp;
1779 CL22_RD_OVER_CL45(bp, phy,
1780 MDIO_REG_BANK_COMBO_IEEE0,
1781 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
1783 /* reset the unicore */
1784 CL22_WR_OVER_CL45(bp, phy,
1785 MDIO_REG_BANK_COMBO_IEEE0,
1786 MDIO_COMBO_IEEE0_MII_CONTROL,
1788 MDIO_COMBO_IEEO_MII_CONTROL_RESET));
1790 bnx2x_set_serdes_access(bp, params->port);
1792 /* wait for the reset to self clear */
1793 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
1796 /* the reset erased the previous bank value */
1797 CL22_RD_OVER_CL45(bp, phy,
1798 MDIO_REG_BANK_COMBO_IEEE0,
1799 MDIO_COMBO_IEEE0_MII_CONTROL,
1802 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1808 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1813 static void bnx2x_set_swap_lanes(struct link_params *params,
1814 struct bnx2x_phy *phy)
1816 struct bnx2x *bp = params->bp;
1817 /* Each two bits represents a lane number:
1818 No swap is 0123 => 0x1b no need to enable the swap */
1819 u16 ser_lane, rx_lane_swap, tx_lane_swap;
1821 ser_lane = ((params->lane_config &
1822 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1823 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1824 rx_lane_swap = ((params->lane_config &
1825 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1826 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1827 tx_lane_swap = ((params->lane_config &
1828 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1829 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1831 if (rx_lane_swap != 0x1b) {
1832 CL22_WR_OVER_CL45(bp, phy,
1833 MDIO_REG_BANK_XGXS_BLOCK2,
1834 MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1836 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1837 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1839 CL22_WR_OVER_CL45(bp, phy,
1840 MDIO_REG_BANK_XGXS_BLOCK2,
1841 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1844 if (tx_lane_swap != 0x1b) {
1845 CL22_WR_OVER_CL45(bp, phy,
1846 MDIO_REG_BANK_XGXS_BLOCK2,
1847 MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1849 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1851 CL22_WR_OVER_CL45(bp, phy,
1852 MDIO_REG_BANK_XGXS_BLOCK2,
1853 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1857 static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
1858 struct link_params *params)
1860 struct bnx2x *bp = params->bp;
1862 CL22_RD_OVER_CL45(bp, phy,
1863 MDIO_REG_BANK_SERDES_DIGITAL,
1864 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1866 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
1867 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1869 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1870 DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
1871 phy->speed_cap_mask, control2);
1872 CL22_WR_OVER_CL45(bp, phy,
1873 MDIO_REG_BANK_SERDES_DIGITAL,
1874 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1877 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
1878 (phy->speed_cap_mask &
1879 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
1880 DP(NETIF_MSG_LINK, "XGXS\n");
1882 CL22_WR_OVER_CL45(bp, phy,
1883 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1884 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1885 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1887 CL22_RD_OVER_CL45(bp, phy,
1888 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1889 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1894 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1896 CL22_WR_OVER_CL45(bp, phy,
1897 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1898 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1901 /* Disable parallel detection of HiG */
1902 CL22_WR_OVER_CL45(bp, phy,
1903 MDIO_REG_BANK_XGXS_BLOCK2,
1904 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1905 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1906 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1910 static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
1911 struct link_params *params,
1912 struct link_vars *vars,
1915 struct bnx2x *bp = params->bp;
1919 CL22_RD_OVER_CL45(bp, phy,
1920 MDIO_REG_BANK_COMBO_IEEE0,
1921 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
1923 /* CL37 Autoneg Enabled */
1924 if (vars->line_speed == SPEED_AUTO_NEG)
1925 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1926 else /* CL37 Autoneg Disabled */
1927 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1928 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1930 CL22_WR_OVER_CL45(bp, phy,
1931 MDIO_REG_BANK_COMBO_IEEE0,
1932 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1934 /* Enable/Disable Autodetection */
1936 CL22_RD_OVER_CL45(bp, phy,
1937 MDIO_REG_BANK_SERDES_DIGITAL,
1938 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val);
1939 reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
1940 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
1941 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
1942 if (vars->line_speed == SPEED_AUTO_NEG)
1943 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1945 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1947 CL22_WR_OVER_CL45(bp, phy,
1948 MDIO_REG_BANK_SERDES_DIGITAL,
1949 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1951 /* Enable TetonII and BAM autoneg */
1952 CL22_RD_OVER_CL45(bp, phy,
1953 MDIO_REG_BANK_BAM_NEXT_PAGE,
1954 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1956 if (vars->line_speed == SPEED_AUTO_NEG) {
1957 /* Enable BAM aneg Mode and TetonII aneg Mode */
1958 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1959 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1961 /* TetonII and BAM Autoneg Disabled */
1962 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1963 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1965 CL22_WR_OVER_CL45(bp, phy,
1966 MDIO_REG_BANK_BAM_NEXT_PAGE,
1967 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1971 /* Enable Cl73 FSM status bits */
1972 CL22_WR_OVER_CL45(bp, phy,
1973 MDIO_REG_BANK_CL73_USERB0,
1974 MDIO_CL73_USERB0_CL73_UCTRL,
1977 /* Enable BAM Station Manager*/
1978 CL22_WR_OVER_CL45(bp, phy,
1979 MDIO_REG_BANK_CL73_USERB0,
1980 MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1981 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1982 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1983 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
1985 /* Advertise CL73 link speeds */
1986 CL22_RD_OVER_CL45(bp, phy,
1987 MDIO_REG_BANK_CL73_IEEEB1,
1988 MDIO_CL73_IEEEB1_AN_ADV2,
1990 if (phy->speed_cap_mask &
1991 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1992 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1993 if (phy->speed_cap_mask &
1994 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
1995 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1997 CL22_WR_OVER_CL45(bp, phy,
1998 MDIO_REG_BANK_CL73_IEEEB1,
1999 MDIO_CL73_IEEEB1_AN_ADV2,
2002 /* CL73 Autoneg Enabled */
2003 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
2005 } else /* CL73 Autoneg Disabled */
2008 CL22_WR_OVER_CL45(bp, phy,
2009 MDIO_REG_BANK_CL73_IEEEB0,
2010 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
2013 /* program SerDes, forced speed */
2014 static void bnx2x_program_serdes(struct bnx2x_phy *phy,
2015 struct link_params *params,
2016 struct link_vars *vars)
2018 struct bnx2x *bp = params->bp;
2021 /* program duplex, disable autoneg and sgmii*/
2022 CL22_RD_OVER_CL45(bp, phy,
2023 MDIO_REG_BANK_COMBO_IEEE0,
2024 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
2025 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
2026 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
2027 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
2028 if (phy->req_duplex == DUPLEX_FULL)
2029 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
2030 CL22_WR_OVER_CL45(bp, phy,
2031 MDIO_REG_BANK_COMBO_IEEE0,
2032 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
2035 - needed only if the speed is greater than 1G (2.5G or 10G) */
2036 CL22_RD_OVER_CL45(bp, phy,
2037 MDIO_REG_BANK_SERDES_DIGITAL,
2038 MDIO_SERDES_DIGITAL_MISC1, ®_val);
2039 /* clearing the speed value before setting the right speed */
2040 DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
2042 reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
2043 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
2045 if (!((vars->line_speed == SPEED_1000) ||
2046 (vars->line_speed == SPEED_100) ||
2047 (vars->line_speed == SPEED_10))) {
2049 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
2050 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
2051 if (vars->line_speed == SPEED_10000)
2053 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
2054 if (vars->line_speed == SPEED_13000)
2056 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
2059 CL22_WR_OVER_CL45(bp, phy,
2060 MDIO_REG_BANK_SERDES_DIGITAL,
2061 MDIO_SERDES_DIGITAL_MISC1, reg_val);
2065 static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x_phy *phy,
2066 struct link_params *params)
2068 struct bnx2x *bp = params->bp;
2071 /* configure the 48 bits for BAM AN */
2073 /* set extended capabilities */
2074 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
2075 val |= MDIO_OVER_1G_UP1_2_5G;
2076 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2077 val |= MDIO_OVER_1G_UP1_10G;
2078 CL22_WR_OVER_CL45(bp, phy,
2079 MDIO_REG_BANK_OVER_1G,
2080 MDIO_OVER_1G_UP1, val);
2082 CL22_WR_OVER_CL45(bp, phy,
2083 MDIO_REG_BANK_OVER_1G,
2084 MDIO_OVER_1G_UP3, 0x400);
2087 static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
2088 struct link_params *params, u16 *ieee_fc)
2090 struct bnx2x *bp = params->bp;
2091 *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
2092 /* resolve pause mode and advertisement
2093 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
2095 switch (phy->req_flow_ctrl) {
2096 case BNX2X_FLOW_CTRL_AUTO:
2097 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH)
2098 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2101 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2103 case BNX2X_FLOW_CTRL_TX:
2104 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2107 case BNX2X_FLOW_CTRL_RX:
2108 case BNX2X_FLOW_CTRL_BOTH:
2109 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2112 case BNX2X_FLOW_CTRL_NONE:
2114 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
2117 DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
2120 static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x_phy *phy,
2121 struct link_params *params,
2124 struct bnx2x *bp = params->bp;
2126 /* for AN, we are always publishing full duplex */
2128 CL22_WR_OVER_CL45(bp, phy,
2129 MDIO_REG_BANK_COMBO_IEEE0,
2130 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
2131 CL22_RD_OVER_CL45(bp, phy,
2132 MDIO_REG_BANK_CL73_IEEEB1,
2133 MDIO_CL73_IEEEB1_AN_ADV1, &val);
2134 val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
2135 val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
2136 CL22_WR_OVER_CL45(bp, phy,
2137 MDIO_REG_BANK_CL73_IEEEB1,
2138 MDIO_CL73_IEEEB1_AN_ADV1, val);
2141 static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
2142 struct link_params *params,
2145 struct bnx2x *bp = params->bp;
2148 DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
2149 /* Enable and restart BAM/CL37 aneg */
2152 CL22_RD_OVER_CL45(bp, phy,
2153 MDIO_REG_BANK_CL73_IEEEB0,
2154 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2157 CL22_WR_OVER_CL45(bp, phy,
2158 MDIO_REG_BANK_CL73_IEEEB0,
2159 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2161 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
2162 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
2165 CL22_RD_OVER_CL45(bp, phy,
2166 MDIO_REG_BANK_COMBO_IEEE0,
2167 MDIO_COMBO_IEEE0_MII_CONTROL,
2170 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
2172 CL22_WR_OVER_CL45(bp, phy,
2173 MDIO_REG_BANK_COMBO_IEEE0,
2174 MDIO_COMBO_IEEE0_MII_CONTROL,
2176 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
2177 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
2181 static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
2182 struct link_params *params,
2183 struct link_vars *vars)
2185 struct bnx2x *bp = params->bp;
2188 /* in SGMII mode, the unicore is always slave */
2190 CL22_RD_OVER_CL45(bp, phy,
2191 MDIO_REG_BANK_SERDES_DIGITAL,
2192 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
2194 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
2195 /* set sgmii mode (and not fiber) */
2196 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
2197 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
2198 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
2199 CL22_WR_OVER_CL45(bp, phy,
2200 MDIO_REG_BANK_SERDES_DIGITAL,
2201 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
2204 /* if forced speed */
2205 if (!(vars->line_speed == SPEED_AUTO_NEG)) {
2206 /* set speed, disable autoneg */
2209 CL22_RD_OVER_CL45(bp, phy,
2210 MDIO_REG_BANK_COMBO_IEEE0,
2211 MDIO_COMBO_IEEE0_MII_CONTROL,
2213 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
2214 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
2215 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
2217 switch (vars->line_speed) {
2220 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
2224 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
2227 /* there is nothing to set for 10M */
2230 /* invalid speed for SGMII */
2231 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2236 /* setting the full duplex */
2237 if (phy->req_duplex == DUPLEX_FULL)
2239 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
2240 CL22_WR_OVER_CL45(bp, phy,
2241 MDIO_REG_BANK_COMBO_IEEE0,
2242 MDIO_COMBO_IEEE0_MII_CONTROL,
2245 } else { /* AN mode */
2246 /* enable and restart AN */
2247 bnx2x_restart_autoneg(phy, params, 0);
2256 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
2258 switch (pause_result) { /* ASYM P ASYM P */
2259 case 0xb: /* 1 0 1 1 */
2260 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
2263 case 0xe: /* 1 1 1 0 */
2264 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
2267 case 0x5: /* 0 1 0 1 */
2268 case 0x7: /* 0 1 1 1 */
2269 case 0xd: /* 1 1 0 1 */
2270 case 0xf: /* 1 1 1 1 */
2271 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
2277 if (pause_result & (1<<0))
2278 vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
2279 if (pause_result & (1<<1))
2280 vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
2283 static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
2284 struct link_params *params)
2286 struct bnx2x *bp = params->bp;
2287 u16 pd_10g, status2_1000x;
2288 if (phy->req_line_speed != SPEED_AUTO_NEG)
2290 CL22_RD_OVER_CL45(bp, phy,
2291 MDIO_REG_BANK_SERDES_DIGITAL,
2292 MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
2294 CL22_RD_OVER_CL45(bp, phy,
2295 MDIO_REG_BANK_SERDES_DIGITAL,
2296 MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
2298 if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
2299 DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
2304 CL22_RD_OVER_CL45(bp, phy,
2305 MDIO_REG_BANK_10G_PARALLEL_DETECT,
2306 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
2309 if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
2310 DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
2317 static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
2318 struct link_params *params,
2319 struct link_vars *vars,
2322 struct bnx2x *bp = params->bp;
2323 u16 ld_pause; /* local driver */
2324 u16 lp_pause; /* link partner */
2327 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
2329 /* resolve from gp_status in case of AN complete and not sgmii */
2330 if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
2331 vars->flow_ctrl = phy->req_flow_ctrl;
2332 else if (phy->req_line_speed != SPEED_AUTO_NEG)
2333 vars->flow_ctrl = params->req_fc_auto_adv;
2334 else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
2335 (!(vars->phy_flags & PHY_SGMII_FLAG))) {
2336 if (bnx2x_direct_parallel_detect_used(phy, params)) {
2337 vars->flow_ctrl = params->req_fc_auto_adv;
2341 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
2342 MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
2343 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
2344 MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
2346 CL22_RD_OVER_CL45(bp, phy,
2347 MDIO_REG_BANK_CL73_IEEEB1,
2348 MDIO_CL73_IEEEB1_AN_ADV1,
2350 CL22_RD_OVER_CL45(bp, phy,
2351 MDIO_REG_BANK_CL73_IEEEB1,
2352 MDIO_CL73_IEEEB1_AN_LP_ADV1,
2354 pause_result = (ld_pause &
2355 MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
2357 pause_result |= (lp_pause &
2358 MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
2360 DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
2363 CL22_RD_OVER_CL45(bp, phy,
2364 MDIO_REG_BANK_COMBO_IEEE0,
2365 MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
2367 CL22_RD_OVER_CL45(bp, phy,
2368 MDIO_REG_BANK_COMBO_IEEE0,
2369 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
2371 pause_result = (ld_pause &
2372 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
2373 pause_result |= (lp_pause &
2374 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
2375 DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
2378 bnx2x_pause_resolve(vars, pause_result);
2380 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
2383 static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
2384 struct link_params *params)
2386 struct bnx2x *bp = params->bp;
2387 u16 rx_status, ustat_val, cl37_fsm_recieved;
2388 DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
2389 /* Step 1: Make sure signal is detected */
2390 CL22_RD_OVER_CL45(bp, phy,
2394 if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
2395 (MDIO_RX0_RX_STATUS_SIGDET)) {
2396 DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
2397 "rx_status(0x80b0) = 0x%x\n", rx_status);
2398 CL22_WR_OVER_CL45(bp, phy,
2399 MDIO_REG_BANK_CL73_IEEEB0,
2400 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2401 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
2404 /* Step 2: Check CL73 state machine */
2405 CL22_RD_OVER_CL45(bp, phy,
2406 MDIO_REG_BANK_CL73_USERB0,
2407 MDIO_CL73_USERB0_CL73_USTAT1,
2410 (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
2411 MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
2412 (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
2413 MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
2414 DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
2415 "ustat_val(0x8371) = 0x%x\n", ustat_val);
2418 /* Step 3: Check CL37 Message Pages received to indicate LP
2419 supports only CL37 */
2420 CL22_RD_OVER_CL45(bp, phy,
2421 MDIO_REG_BANK_REMOTE_PHY,
2422 MDIO_REMOTE_PHY_MISC_RX_STATUS,
2423 &cl37_fsm_recieved);
2424 if ((cl37_fsm_recieved &
2425 (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
2426 MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
2427 (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
2428 MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
2429 DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
2430 "misc_rx_status(0x8330) = 0x%x\n",
2434 /* The combined cl37/cl73 fsm state information indicating that we are
2435 connected to a device which does not support cl73, but does support
2436 cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */
2438 CL22_WR_OVER_CL45(bp, phy,
2439 MDIO_REG_BANK_CL73_IEEEB0,
2440 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2442 /* Restart CL37 autoneg */
2443 bnx2x_restart_autoneg(phy, params, 0);
2444 DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
2447 static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
2448 struct link_params *params,
2449 struct link_vars *vars,
2452 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
2453 vars->link_status |=
2454 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
2456 if (bnx2x_direct_parallel_detect_used(phy, params))
2457 vars->link_status |=
2458 LINK_STATUS_PARALLEL_DETECTION_USED;
2461 static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy,
2462 struct link_params *params,
2463 struct link_vars *vars)
2465 struct bnx2x *bp = params->bp;
2466 u16 new_line_speed, gp_status;
2469 /* Read gp_status */
2470 CL22_RD_OVER_CL45(bp, phy,
2471 MDIO_REG_BANK_GP_STATUS,
2472 MDIO_GP_STATUS_TOP_AN_STATUS1,
2475 if (phy->req_line_speed == SPEED_AUTO_NEG)
2476 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
2477 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
2478 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
2481 vars->phy_link_up = 1;
2482 vars->link_status |= LINK_STATUS_LINK_UP;
2484 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
2485 vars->duplex = DUPLEX_FULL;
2487 vars->duplex = DUPLEX_HALF;
2489 if (SINGLE_MEDIA_DIRECT(params)) {
2490 bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
2491 if (phy->req_line_speed == SPEED_AUTO_NEG)
2492 bnx2x_xgxs_an_resolve(phy, params, vars,
2496 switch (gp_status & GP_STATUS_SPEED_MASK) {
2498 new_line_speed = SPEED_10;
2499 if (vars->duplex == DUPLEX_FULL)
2500 vars->link_status |= LINK_10TFD;
2502 vars->link_status |= LINK_10THD;
2505 case GP_STATUS_100M:
2506 new_line_speed = SPEED_100;
2507 if (vars->duplex == DUPLEX_FULL)
2508 vars->link_status |= LINK_100TXFD;
2510 vars->link_status |= LINK_100TXHD;
2514 case GP_STATUS_1G_KX:
2515 new_line_speed = SPEED_1000;
2516 if (vars->duplex == DUPLEX_FULL)
2517 vars->link_status |= LINK_1000TFD;
2519 vars->link_status |= LINK_1000THD;
2522 case GP_STATUS_2_5G:
2523 new_line_speed = SPEED_2500;
2524 if (vars->duplex == DUPLEX_FULL)
2525 vars->link_status |= LINK_2500TFD;
2527 vars->link_status |= LINK_2500THD;
2533 "link speed unsupported gp_status 0x%x\n",
2537 case GP_STATUS_10G_KX4:
2538 case GP_STATUS_10G_HIG:
2539 case GP_STATUS_10G_CX4:
2540 new_line_speed = SPEED_10000;
2541 vars->link_status |= LINK_10GTFD;
2544 case GP_STATUS_12G_HIG:
2545 new_line_speed = SPEED_12000;
2546 vars->link_status |= LINK_12GTFD;
2549 case GP_STATUS_12_5G:
2550 new_line_speed = SPEED_12500;
2551 vars->link_status |= LINK_12_5GTFD;
2555 new_line_speed = SPEED_13000;
2556 vars->link_status |= LINK_13GTFD;
2560 new_line_speed = SPEED_15000;
2561 vars->link_status |= LINK_15GTFD;
2565 new_line_speed = SPEED_16000;
2566 vars->link_status |= LINK_16GTFD;
2571 "link speed unsupported gp_status 0x%x\n",
2576 vars->line_speed = new_line_speed;
2578 } else { /* link_down */
2579 DP(NETIF_MSG_LINK, "phy link down\n");
2581 vars->phy_link_up = 0;
2583 vars->duplex = DUPLEX_FULL;
2584 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
2585 vars->mac_type = MAC_TYPE_NONE;
2587 if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
2588 SINGLE_MEDIA_DIRECT(params)) {
2589 /* Check signal is detected */
2590 bnx2x_check_fallback_to_cl37(phy, params);
2594 DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x\n",
2595 gp_status, vars->phy_link_up, vars->line_speed);
2596 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n",
2597 vars->duplex, vars->flow_ctrl, vars->link_status);
2601 static void bnx2x_set_gmii_tx_driver(struct link_params *params)
2603 struct bnx2x *bp = params->bp;
2604 struct bnx2x_phy *phy = ¶ms->phy[INT_PHY];
2610 CL22_RD_OVER_CL45(bp, phy,
2611 MDIO_REG_BANK_OVER_1G,
2612 MDIO_OVER_1G_LP_UP2, &lp_up2);
2614 /* bits [10:7] at lp_up2, positioned at [15:12] */
2615 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
2616 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
2617 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
2622 for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
2623 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
2624 CL22_RD_OVER_CL45(bp, phy,
2626 MDIO_TX0_TX_DRIVER, &tx_driver);
2628 /* replace tx_driver bits [15:12] */
2630 (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
2631 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
2632 tx_driver |= lp_up2;
2633 CL22_WR_OVER_CL45(bp, phy,
2635 MDIO_TX0_TX_DRIVER, tx_driver);
2640 static u8 bnx2x_emac_program(struct link_params *params,
2641 struct link_vars *vars)
2643 struct bnx2x *bp = params->bp;
2644 u8 port = params->port;
2647 DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
2648 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
2650 (EMAC_MODE_25G_MODE |
2651 EMAC_MODE_PORT_MII_10M |
2652 EMAC_MODE_HALF_DUPLEX));
2653 switch (vars->line_speed) {
2655 mode |= EMAC_MODE_PORT_MII_10M;
2659 mode |= EMAC_MODE_PORT_MII;
2663 mode |= EMAC_MODE_PORT_GMII;
2667 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
2671 /* 10G not valid for EMAC */
2672 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2677 if (vars->duplex == DUPLEX_HALF)
2678 mode |= EMAC_MODE_HALF_DUPLEX;
2680 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
2683 bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
2687 static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
2688 struct link_params *params)
2692 struct bnx2x *bp = params->bp;
2694 for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
2695 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
2696 CL22_WR_OVER_CL45(bp, phy,
2698 MDIO_RX0_RX_EQ_BOOST,
2699 phy->rx_preemphasis[i]);
2702 for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
2703 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
2704 CL22_WR_OVER_CL45(bp, phy,
2707 phy->tx_preemphasis[i]);
2711 static void bnx2x_init_internal_phy(struct bnx2x_phy *phy,
2712 struct link_params *params,
2713 struct link_vars *vars)
2715 struct bnx2x *bp = params->bp;
2716 u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
2717 (params->loopback_mode == LOOPBACK_XGXS));
2718 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2719 if (SINGLE_MEDIA_DIRECT(params) &&
2720 (params->feature_config_flags &
2721 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
2722 bnx2x_set_preemphasis(phy, params);
2724 /* forced speed requested? */
2725 if (vars->line_speed != SPEED_AUTO_NEG ||
2726 (SINGLE_MEDIA_DIRECT(params) &&
2727 params->loopback_mode == LOOPBACK_EXT)) {
2728 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2730 /* disable autoneg */
2731 bnx2x_set_autoneg(phy, params, vars, 0);
2733 /* program speed and duplex */
2734 bnx2x_program_serdes(phy, params, vars);
2736 } else { /* AN_mode */
2737 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2740 bnx2x_set_brcm_cl37_advertisment(phy, params);
2742 /* program duplex & pause advertisement (for aneg) */
2743 bnx2x_set_ieee_aneg_advertisment(phy, params,
2746 /* enable autoneg */
2747 bnx2x_set_autoneg(phy, params, vars, enable_cl73);
2749 /* enable and restart AN */
2750 bnx2x_restart_autoneg(phy, params, enable_cl73);
2753 } else { /* SGMII mode */
2754 DP(NETIF_MSG_LINK, "SGMII\n");
2756 bnx2x_initialize_sgmii_process(phy, params, vars);
2760 static u8 bnx2x_init_serdes(struct bnx2x_phy *phy,
2761 struct link_params *params,
2762 struct link_vars *vars)
2765 vars->phy_flags |= PHY_SGMII_FLAG;
2766 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2767 bnx2x_set_aer_mmd_serdes(params->bp, phy);
2768 rc = bnx2x_reset_unicore(params, phy, 1);
2769 /* reset the SerDes and wait for reset bit return low */
2772 bnx2x_set_aer_mmd_serdes(params->bp, phy);
2777 static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy,
2778 struct link_params *params,
2779 struct link_vars *vars)
2782 vars->phy_flags = PHY_XGXS_FLAG;
2783 if ((phy->req_line_speed &&
2784 ((phy->req_line_speed == SPEED_100) ||
2785 (phy->req_line_speed == SPEED_10))) ||
2786 (!phy->req_line_speed &&
2787 (phy->speed_cap_mask >=
2788 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
2789 (phy->speed_cap_mask <
2790 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
2792 vars->phy_flags |= PHY_SGMII_FLAG;
2794 vars->phy_flags &= ~PHY_SGMII_FLAG;
2796 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2797 bnx2x_set_aer_mmd_xgxs(params, phy);
2798 bnx2x_set_master_ln(params, phy);
2800 rc = bnx2x_reset_unicore(params, phy, 0);
2801 /* reset the SerDes and wait for reset bit return low */
2805 bnx2x_set_aer_mmd_xgxs(params, phy);
2807 /* setting the masterLn_def again after the reset */
2808 bnx2x_set_master_ln(params, phy);
2809 bnx2x_set_swap_lanes(params, phy);
2814 static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
2815 struct bnx2x_phy *phy)
2818 /* Wait for soft reset to get cleared upto 1 sec */
2819 for (cnt = 0; cnt < 1000; cnt++) {
2820 bnx2x_cl45_read(bp, phy,
2821 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl);
2822 if (!(ctrl & (1<<15)))
2826 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
2830 static void bnx2x_link_int_enable(struct link_params *params)
2832 u8 port = params->port;
2834 struct bnx2x *bp = params->bp;
2836 /* setting the status to report on link up
2837 for either XGXS or SerDes */
2839 if (params->switch_cfg == SWITCH_CFG_10G) {
2840 mask = (NIG_MASK_XGXS0_LINK10G |
2841 NIG_MASK_XGXS0_LINK_STATUS);
2842 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
2843 if (!(SINGLE_MEDIA_DIRECT(params)) &&
2844 params->phy[INT_PHY].type !=
2845 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
2846 mask |= NIG_MASK_MI_INT;
2847 DP(NETIF_MSG_LINK, "enabled external phy int\n");
2850 } else { /* SerDes */
2851 mask = NIG_MASK_SERDES0_LINK_STATUS;
2852 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
2853 if (!(SINGLE_MEDIA_DIRECT(params)) &&
2854 params->phy[INT_PHY].type !=
2855 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
2856 mask |= NIG_MASK_MI_INT;
2857 DP(NETIF_MSG_LINK, "enabled external phy int\n");
2861 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
2864 DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
2865 (params->switch_cfg == SWITCH_CFG_10G),
2866 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
2867 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
2868 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
2869 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
2870 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
2871 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
2872 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
2873 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
2876 static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port,
2879 u32 latch_status = 0;
2882 * Disable the MI INT ( external phy int ) by writing 1 to the
2883 * status register. Link down indication is high-active-signal,
2884 * so in this case we need to write the status to clear the XOR
2886 /* Read Latched signals */
2887 latch_status = REG_RD(bp,
2888 NIG_REG_LATCH_STATUS_0 + port*8);
2889 DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status);
2890 /* Handle only those with latched-signal=up.*/
2893 NIG_REG_STATUS_INTERRUPT_PORT0
2895 NIG_STATUS_EMAC0_MI_INT);
2898 NIG_REG_STATUS_INTERRUPT_PORT0
2900 NIG_STATUS_EMAC0_MI_INT);
2902 if (latch_status & 1) {
2904 /* For all latched-signal=up : Re-Arm Latch signals */
2905 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
2906 (latch_status & 0xfffe) | (latch_status & 1));
2908 /* For all latched-signal=up,Write original_signal to status */
2911 static void bnx2x_link_int_ack(struct link_params *params,
2912 struct link_vars *vars, u8 is_10g)
2914 struct bnx2x *bp = params->bp;
2915 u8 port = params->port;
2917 /* first reset all status
2918 * we assume only one line will be change at a time */
2919 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2920 (NIG_STATUS_XGXS0_LINK10G |
2921 NIG_STATUS_XGXS0_LINK_STATUS |
2922 NIG_STATUS_SERDES0_LINK_STATUS));
2923 if (vars->phy_link_up) {
2925 /* Disable the 10G link interrupt
2926 * by writing 1 to the status register
2928 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
2930 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2931 NIG_STATUS_XGXS0_LINK10G);
2933 } else if (params->switch_cfg == SWITCH_CFG_10G) {
2934 /* Disable the link interrupt
2935 * by writing 1 to the relevant lane
2936 * in the status register
2938 u32 ser_lane = ((params->lane_config &
2939 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
2940 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
2942 DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
2945 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2947 NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
2949 } else { /* SerDes */
2950 DP(NETIF_MSG_LINK, "SerDes phy link up\n");
2951 /* Disable the link interrupt
2952 * by writing 1 to the status register
2955 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2956 NIG_STATUS_SERDES0_LINK_STATUS);
2962 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len)
2965 u32 mask = 0xf0000000;
2968 u8 remove_leading_zeros = 1;
2970 /* Need more than 10chars for this format */
2978 digit = ((num & mask) >> shift);
2979 if (digit == 0 && remove_leading_zeros) {
2982 } else if (digit < 0xa)
2983 *str_ptr = digit + '0';
2985 *str_ptr = digit - 0xa + 'a';
2986 remove_leading_zeros = 0;
2994 remove_leading_zeros = 1;
3001 static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
3008 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3009 u8 *version, u16 len)
3014 u8 *ver_p = version;
3015 u16 remain_len = len;
3016 if (version == NULL || params == NULL)
3020 /* Extract first external phy*/
3022 spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
3024 if (params->phy[EXT_PHY1].format_fw_ver) {
3025 status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
3028 ver_p += (len - remain_len);
3030 if ((params->num_phys == MAX_PHYS) &&
3031 (params->phy[EXT_PHY2].ver_addr != 0)) {
3032 spirom_ver = REG_RD(bp, params->phy[EXT_PHY2].ver_addr);
3033 if (params->phy[EXT_PHY2].format_fw_ver) {
3037 status |= params->phy[EXT_PHY2].format_fw_ver(
3041 ver_p = version + (len - remain_len);
3048 static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
3049 struct link_params *params)
3051 u8 port = params->port;
3052 struct bnx2x *bp = params->bp;
3054 if (phy->req_line_speed != SPEED_1000) {
3057 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
3059 /* change the uni_phy_addr in the nig */
3060 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
3063 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
3065 bnx2x_cl45_write(bp, phy,
3067 (MDIO_REG_BANK_AER_BLOCK +
3068 (MDIO_AER_BLOCK_AER_REG & 0xf)),
3071 bnx2x_cl45_write(bp, phy,
3073 (MDIO_REG_BANK_CL73_IEEEB0 +
3074 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
3077 /* set aer mmd back */
3078 bnx2x_set_aer_mmd_xgxs(params, phy);
3081 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, md_devad);
3084 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
3085 bnx2x_cl45_read(bp, phy, 5,
3086 (MDIO_REG_BANK_COMBO_IEEE0 +
3087 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
3089 bnx2x_cl45_write(bp, phy, 5,
3090 (MDIO_REG_BANK_COMBO_IEEE0 +
3091 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
3093 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
3097 u8 bnx2x_set_led(struct link_params *params,
3098 struct link_vars *vars, u8 mode, u32 speed)
3100 u8 port = params->port;
3101 u16 hw_led_mode = params->hw_led_mode;
3104 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3105 struct bnx2x *bp = params->bp;
3106 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
3107 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
3108 speed, hw_led_mode);
3110 for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) {
3111 if (params->phy[phy_idx].set_link_led) {
3112 params->phy[phy_idx].set_link_led(
3113 ¶ms->phy[phy_idx], params, mode);
3118 case LED_MODE_FRONT_PANEL_OFF:
3120 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
3121 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
3122 SHARED_HW_CFG_LED_MAC1);
3124 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3125 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
3130 * For all other phys, OPER mode is same as ON, so in case
3131 * link is down, do nothing
3136 if (params->phy[EXT_PHY1].type ==
3137 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727 &&
3138 CHIP_IS_E2(bp) && params->num_phys == 2) {
3140 * This is a work-around for E2+8727 Configurations
3142 if (mode == LED_MODE_ON ||
3143 speed == SPEED_10000){
3144 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
3145 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
3147 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3148 EMAC_WR(bp, EMAC_REG_EMAC_LED,
3149 (tmp | EMAC_LED_OVERRIDE));
3152 } else if (SINGLE_MEDIA_DIRECT(params)) {
3154 * This is a work-around for HW issue found when link
3157 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
3158 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
3160 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
3163 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
3164 /* Set blinking rate to ~15.9Hz */
3165 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
3166 LED_BLINK_RATE_VAL);
3167 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
3169 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3170 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp & (~EMAC_LED_OVERRIDE)));
3172 if (CHIP_IS_E1(bp) &&
3173 ((speed == SPEED_2500) ||
3174 (speed == SPEED_1000) ||
3175 (speed == SPEED_100) ||
3176 (speed == SPEED_10))) {
3177 /* On Everest 1 Ax chip versions for speeds less than
3178 10G LED scheme is different */
3179 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3181 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
3183 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
3190 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
3199 * This function comes to reflect the actual link state read DIRECTLY from the
3202 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars,
3205 struct bnx2x *bp = params->bp;
3206 u16 gp_status = 0, phy_index = 0;
3207 u8 ext_phy_link_up = 0, serdes_phy_type;
3208 struct link_vars temp_vars;
3210 CL22_RD_OVER_CL45(bp, ¶ms->phy[INT_PHY],
3211 MDIO_REG_BANK_GP_STATUS,
3212 MDIO_GP_STATUS_TOP_AN_STATUS1,
3214 /* link is up only if both local phy and external phy are up */
3215 if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
3218 switch (params->num_phys) {
3220 /* No external PHY */
3223 ext_phy_link_up = params->phy[EXT_PHY1].read_status(
3224 ¶ms->phy[EXT_PHY1],
3225 params, &temp_vars);
3227 case 3: /* Dual Media */
3228 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3230 serdes_phy_type = ((params->phy[phy_index].media_type ==
3231 ETH_PHY_SFP_FIBER) ||
3232 (params->phy[phy_index].media_type ==
3233 ETH_PHY_XFP_FIBER));
3235 if (is_serdes != serdes_phy_type)
3237 if (params->phy[phy_index].read_status) {
3239 params->phy[phy_index].read_status(
3240 ¶ms->phy[phy_index],
3241 params, &temp_vars);
3246 if (ext_phy_link_up)
3251 static u8 bnx2x_link_initialize(struct link_params *params,
3252 struct link_vars *vars)
3255 u8 phy_index, non_ext_phy;
3256 struct bnx2x *bp = params->bp;
3258 * In case of external phy existence, the line speed would be the
3259 * line speed linked up by the external phy. In case it is direct
3260 * only, then the line_speed during initialization will be
3261 * equal to the req_line_speed
3263 vars->line_speed = params->phy[INT_PHY].req_line_speed;
3266 * Initialize the internal phy in case this is a direct board
3267 * (no external phys), or this board has external phy which requires
3271 if (params->phy[INT_PHY].config_init)
3272 params->phy[INT_PHY].config_init(
3273 ¶ms->phy[INT_PHY],
3276 /* init ext phy and enable link state int */
3277 non_ext_phy = (SINGLE_MEDIA_DIRECT(params) ||
3278 (params->loopback_mode == LOOPBACK_XGXS));
3281 (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) ||
3282 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
3283 struct bnx2x_phy *phy = ¶ms->phy[INT_PHY];
3284 if (vars->line_speed == SPEED_AUTO_NEG)
3285 bnx2x_set_parallel_detection(phy, params);
3286 bnx2x_init_internal_phy(phy, params, vars);
3289 /* Init external phy*/
3291 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3294 * No need to initialize second phy in case of first
3295 * phy only selection. In case of second phy, we do
3296 * need to initialize the first phy, since they are
3299 if (phy_index == EXT_PHY2 &&
3300 (bnx2x_phy_selection(params) ==
3301 PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
3302 DP(NETIF_MSG_LINK, "Not initializing"
3306 params->phy[phy_index].config_init(
3307 ¶ms->phy[phy_index],
3311 /* Reset the interrupt indication after phy was initialized */
3312 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
3314 (NIG_STATUS_XGXS0_LINK10G |
3315 NIG_STATUS_XGXS0_LINK_STATUS |
3316 NIG_STATUS_SERDES0_LINK_STATUS |
3321 static void bnx2x_int_link_reset(struct bnx2x_phy *phy,
3322 struct link_params *params)
3324 /* reset the SerDes/XGXS */
3325 REG_WR(params->bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
3326 (0x1ff << (params->port*16)));
3329 static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
3330 struct link_params *params)
3332 struct bnx2x *bp = params->bp;
3336 gpio_port = BP_PATH(bp);
3338 gpio_port = params->port;
3339 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3340 MISC_REGISTERS_GPIO_OUTPUT_LOW,
3342 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3343 MISC_REGISTERS_GPIO_OUTPUT_LOW,
3345 DP(NETIF_MSG_LINK, "reset external PHY\n");
3348 static u8 bnx2x_update_link_down(struct link_params *params,
3349 struct link_vars *vars)
3351 struct bnx2x *bp = params->bp;
3352 u8 port = params->port;
3354 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
3355 bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
3357 /* indicate no mac active */
3358 vars->mac_type = MAC_TYPE_NONE;
3360 /* update shared memory */
3361 vars->link_status = 0;
3362 vars->line_speed = 0;
3363 bnx2x_update_mng(params, vars->link_status);
3365 /* activate nig drain */
3366 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
3369 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
3374 bnx2x_bmac_rx_disable(bp, params->port);
3375 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
3376 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
3380 static u8 bnx2x_update_link_up(struct link_params *params,
3381 struct link_vars *vars,
3384 struct bnx2x *bp = params->bp;
3385 u8 port = params->port;
3388 vars->link_status |= LINK_STATUS_LINK_UP;
3390 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
3391 vars->link_status |=
3392 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
3394 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
3395 vars->link_status |=
3396 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
3399 bnx2x_bmac_enable(params, vars, 0);
3400 bnx2x_set_led(params, vars,
3401 LED_MODE_OPER, SPEED_10000);
3403 rc = bnx2x_emac_program(params, vars);
3405 bnx2x_emac_enable(params, vars, 0);
3408 if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
3409 && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
3410 SINGLE_MEDIA_DIRECT(params))
3411 bnx2x_set_gmii_tx_driver(params);
3415 if (!(CHIP_IS_E2(bp)))
3416 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
3420 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
3422 /* update shared memory */
3423 bnx2x_update_mng(params, vars->link_status);
3428 * The bnx2x_link_update function should be called upon link
3430 * Link is considered up as follows:
3431 * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
3433 * - SINGLE_MEDIA - The link between the 577xx and the external
3434 * phy (XGXS) need to up as well as the external link of the
3436 * - DUAL_MEDIA - The link between the 577xx and the first
3437 * external phy needs to be up, and at least one of the 2
3438 * external phy link must be up.
3440 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
3442 struct bnx2x *bp = params->bp;
3443 struct link_vars phy_vars[MAX_PHYS];
3444 u8 port = params->port;
3445 u8 link_10g, phy_index;
3446 u8 ext_phy_link_up = 0, cur_link_up, rc = 0;
3448 u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
3449 u8 active_external_phy = INT_PHY;
3450 vars->link_status = 0;
3451 for (phy_index = INT_PHY; phy_index < params->num_phys;
3453 phy_vars[phy_index].flow_ctrl = 0;
3454 phy_vars[phy_index].link_status = 0;
3455 phy_vars[phy_index].line_speed = 0;
3456 phy_vars[phy_index].duplex = DUPLEX_FULL;
3457 phy_vars[phy_index].phy_link_up = 0;
3458 phy_vars[phy_index].link_up = 0;
3461 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
3462 port, (vars->phy_flags & PHY_XGXS_FLAG),
3463 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
3465 is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
3467 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
3468 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
3470 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
3472 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
3473 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
3474 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
3477 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
3481 * Check external link change only for external phys, and apply
3482 * priority selection between them in case the link on both phys
3483 * is up. Note that the instead of the common vars, a temporary
3484 * vars argument is used since each phy may have different link/
3485 * speed/duplex result
3487 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3489 struct bnx2x_phy *phy = ¶ms->phy[phy_index];
3490 if (!phy->read_status)
3492 /* Read link status and params of this ext phy */
3493 cur_link_up = phy->read_status(phy, params,
3494 &phy_vars[phy_index]);
3496 DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
3499 DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
3504 if (!ext_phy_link_up) {
3505 ext_phy_link_up = 1;
3506 active_external_phy = phy_index;
3508 switch (bnx2x_phy_selection(params)) {
3509 case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
3510 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
3512 * In this option, the first PHY makes sure to pass the
3513 * traffic through itself only.
3514 * Its not clear how to reset the link on the second phy
3516 active_external_phy = EXT_PHY1;
3518 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
3520 * In this option, the first PHY makes sure to pass the
3521 * traffic through the second PHY.
3523 active_external_phy = EXT_PHY2;
3527 * Link indication on both PHYs with the following cases
3529 * - FIRST_PHY means that second phy wasn't initialized,
3530 * hence its link is expected to be down
3531 * - SECOND_PHY means that first phy should not be able
3532 * to link up by itself (using configuration)
3533 * - DEFAULT should be overriden during initialiazation
3535 DP(NETIF_MSG_LINK, "Invalid link indication"
3536 "mpc=0x%x. DISABLING LINK !!!\n",
3537 params->multi_phy_config);
3538 ext_phy_link_up = 0;
3543 prev_line_speed = vars->line_speed;
3546 * Read the status of the internal phy. In case of
3547 * DIRECT_SINGLE_MEDIA board, this link is the external link,
3548 * otherwise this is the link between the 577xx and the first
3551 if (params->phy[INT_PHY].read_status)
3552 params->phy[INT_PHY].read_status(
3553 ¶ms->phy[INT_PHY],
3556 * The INT_PHY flow control reside in the vars. This include the
3557 * case where the speed or flow control are not set to AUTO.
3558 * Otherwise, the active external phy flow control result is set
3559 * to the vars. The ext_phy_line_speed is needed to check if the
3560 * speed is different between the internal phy and external phy.
3561 * This case may be result of intermediate link speed change.
3563 if (active_external_phy > INT_PHY) {
3564 vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
3566 * Link speed is taken from the XGXS. AN and FC result from
3569 vars->link_status |= phy_vars[active_external_phy].link_status;
3572 * if active_external_phy is first PHY and link is up - disable
3573 * disable TX on second external PHY
3575 if (active_external_phy == EXT_PHY1) {
3576 if (params->phy[EXT_PHY2].phy_specific_func) {
3577 DP(NETIF_MSG_LINK, "Disabling TX on"
3579 params->phy[EXT_PHY2].phy_specific_func(
3580 ¶ms->phy[EXT_PHY2],
3581 params, DISABLE_TX);
3585 ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
3586 vars->duplex = phy_vars[active_external_phy].duplex;
3587 if (params->phy[active_external_phy].supported &
3589 vars->link_status |= LINK_STATUS_SERDES_LINK;
3590 DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
3591 active_external_phy);
3594 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3596 if (params->phy[phy_index].flags &
3597 FLAGS_REARM_LATCH_SIGNAL) {
3598 bnx2x_rearm_latch_signal(bp, port,
3600 active_external_phy);
3604 DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
3605 " ext_phy_line_speed = %d\n", vars->flow_ctrl,
3606 vars->link_status, ext_phy_line_speed);
3608 * Upon link speed change set the NIG into drain mode. Comes to
3609 * deals with possible FIFO glitch due to clk change when speed
3610 * is decreased without link down indicator
3613 if (vars->phy_link_up) {
3614 if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
3615 (ext_phy_line_speed != vars->line_speed)) {
3616 DP(NETIF_MSG_LINK, "Internal link speed %d is"
3617 " different than the external"
3618 " link speed %d\n", vars->line_speed,
3619 ext_phy_line_speed);
3620 vars->phy_link_up = 0;
3621 } else if (prev_line_speed != vars->line_speed) {
3622 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4,
3628 /* anything 10 and over uses the bmac */
3629 link_10g = ((vars->line_speed == SPEED_10000) ||
3630 (vars->line_speed == SPEED_12000) ||
3631 (vars->line_speed == SPEED_12500) ||
3632 (vars->line_speed == SPEED_13000) ||
3633 (vars->line_speed == SPEED_15000) ||
3634 (vars->line_speed == SPEED_16000));
3636 bnx2x_link_int_ack(params, vars, link_10g);
3639 * In case external phy link is up, and internal link is down
3640 * (not initialized yet probably after link initialization, it
3641 * needs to be initialized.
3642 * Note that after link down-up as result of cable plug, the xgxs
3643 * link would probably become up again without the need
3646 if (!(SINGLE_MEDIA_DIRECT(params))) {
3647 DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
3648 " init_preceding = %d\n", ext_phy_link_up,
3650 params->phy[EXT_PHY1].flags &
3651 FLAGS_INIT_XGXS_FIRST);
3652 if (!(params->phy[EXT_PHY1].flags &
3653 FLAGS_INIT_XGXS_FIRST)
3654 && ext_phy_link_up && !vars->phy_link_up) {
3655 vars->line_speed = ext_phy_line_speed;
3656 if (vars->line_speed < SPEED_1000)
3657 vars->phy_flags |= PHY_SGMII_FLAG;
3659 vars->phy_flags &= ~PHY_SGMII_FLAG;
3660 bnx2x_init_internal_phy(¶ms->phy[INT_PHY],
3666 * Link is up only if both local phy and external phy (in case of
3667 * non-direct board) are up
3669 vars->link_up = (vars->phy_link_up &&
3671 SINGLE_MEDIA_DIRECT(params)));
3674 rc = bnx2x_update_link_up(params, vars, link_10g);
3676 rc = bnx2x_update_link_down(params, vars);
3682 /*****************************************************************************/
3683 /* External Phy section */
3684 /*****************************************************************************/
3685 void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
3687 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3688 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
3690 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3691 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
3694 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
3695 u32 spirom_ver, u32 ver_addr)
3697 DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
3698 (u16)(spirom_ver>>16), (u16)spirom_ver, port);
3701 REG_WR(bp, ver_addr, spirom_ver);
3704 static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp,
3705 struct bnx2x_phy *phy,
3708 u16 fw_ver1, fw_ver2;
3710 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
3711 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
3712 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
3713 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
3714 bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2),
3718 static void bnx2x_ext_phy_set_pause(struct link_params *params,
3719 struct bnx2x_phy *phy,
3720 struct link_vars *vars)
3723 struct bnx2x *bp = params->bp;
3724 /* read modify write pause advertizing */
3725 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
3727 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3729 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3730 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
3731 if ((vars->ieee_fc &
3732 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3733 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3734 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3736 if ((vars->ieee_fc &
3737 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3738 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3739 val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
3741 DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
3742 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
3745 static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
3746 struct link_params *params,
3747 struct link_vars *vars)
3749 struct bnx2x *bp = params->bp;
3750 u16 ld_pause; /* local */
3751 u16 lp_pause; /* link partner */
3756 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3758 if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
3759 vars->flow_ctrl = phy->req_flow_ctrl;
3760 else if (phy->req_line_speed != SPEED_AUTO_NEG)
3761 vars->flow_ctrl = params->req_fc_auto_adv;
3762 else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
3764 bnx2x_cl45_read(bp, phy,
3766 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3767 bnx2x_cl45_read(bp, phy,
3769 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3770 pause_result = (ld_pause &
3771 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
3772 pause_result |= (lp_pause &
3773 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
3774 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
3776 bnx2x_pause_resolve(vars, pause_result);
3781 static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp,
3782 struct bnx2x_phy *phy,
3783 struct link_vars *vars)
3786 bnx2x_cl45_read(bp, phy,
3788 MDIO_AN_REG_STATUS, &val);
3789 bnx2x_cl45_read(bp, phy,
3791 MDIO_AN_REG_STATUS, &val);
3793 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
3794 if ((val & (1<<0)) == 0)
3795 vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
3798 /******************************************************************/
3799 /* common BCM8073/BCM8727 PHY SECTION */
3800 /******************************************************************/
3801 static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
3802 struct link_params *params,
3803 struct link_vars *vars)
3805 struct bnx2x *bp = params->bp;
3806 if (phy->req_line_speed == SPEED_10 ||
3807 phy->req_line_speed == SPEED_100) {
3808 vars->flow_ctrl = phy->req_flow_ctrl;
3812 if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
3813 (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) {
3815 u16 ld_pause; /* local */
3816 u16 lp_pause; /* link partner */
3817 bnx2x_cl45_read(bp, phy,
3819 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
3821 bnx2x_cl45_read(bp, phy,
3823 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
3824 pause_result = (ld_pause &
3825 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
3826 pause_result |= (lp_pause &
3827 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
3829 bnx2x_pause_resolve(vars, pause_result);
3830 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
3834 static u8 bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
3835 struct bnx2x_phy *phy,
3839 u16 fw_ver1, fw_msgout;
3842 /* Boot port from external ROM */
3844 bnx2x_cl45_write(bp, phy,
3846 MDIO_PMA_REG_GEN_CTRL,
3849 /* ucode reboot and rst */
3850 bnx2x_cl45_write(bp, phy,
3852 MDIO_PMA_REG_GEN_CTRL,
3855 bnx2x_cl45_write(bp, phy,
3857 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
3859 /* Reset internal microprocessor */
3860 bnx2x_cl45_write(bp, phy,
3862 MDIO_PMA_REG_GEN_CTRL,
3863 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
3865 /* Release srst bit */
3866 bnx2x_cl45_write(bp, phy,
3868 MDIO_PMA_REG_GEN_CTRL,
3869 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
3871 /* Delay 100ms per the PHY specifications */
3874 /* 8073 sometimes taking longer to download */
3879 "bnx2x_8073_8727_external_rom_boot port %x:"
3880 "Download failed. fw version = 0x%x\n",
3886 bnx2x_cl45_read(bp, phy,
3888 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
3889 bnx2x_cl45_read(bp, phy,
3891 MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
3894 } while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
3895 ((fw_msgout & 0xff) != 0x03 && (phy->type ==
3896 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)));
3898 /* Clear ser_boot_ctl bit */
3899 bnx2x_cl45_write(bp, phy,
3901 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
3902 bnx2x_save_bcm_spirom_ver(bp, phy, port);
3905 "bnx2x_8073_8727_external_rom_boot port %x:"
3906 "Download complete. fw version = 0x%x\n",
3912 /******************************************************************/
3913 /* BCM8073 PHY SECTION */
3914 /******************************************************************/
3915 static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
3917 /* This is only required for 8073A1, version 102 only */
3920 /* Read 8073 HW revision*/
3921 bnx2x_cl45_read(bp, phy,
3923 MDIO_PMA_REG_8073_CHIP_REV, &val);
3926 /* No need to workaround in 8073 A1 */
3930 bnx2x_cl45_read(bp, phy,
3932 MDIO_PMA_REG_ROM_VER2, &val);
3934 /* SNR should be applied only for version 0x102 */
3941 static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
3943 u16 val, cnt, cnt1 ;
3945 bnx2x_cl45_read(bp, phy,
3947 MDIO_PMA_REG_8073_CHIP_REV, &val);
3950 /* No need to workaround in 8073 A1 */
3953 /* XAUI workaround in 8073 A0: */
3955 /* After loading the boot ROM and restarting Autoneg,
3956 poll Dev1, Reg $C820: */
3958 for (cnt = 0; cnt < 1000; cnt++) {
3959 bnx2x_cl45_read(bp, phy,
3961 MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
3963 /* If bit [14] = 0 or bit [13] = 0, continue on with
3964 system initialization (XAUI work-around not required,
3965 as these bits indicate 2.5G or 1G link up). */
3966 if (!(val & (1<<14)) || !(val & (1<<13))) {
3967 DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
3969 } else if (!(val & (1<<15))) {
3970 DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
3971 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
3972 it's MSB (bit 15) goes to 1 (indicating that the
3973 XAUI workaround has completed),
3974 then continue on with system initialization.*/
3975 for (cnt1 = 0; cnt1 < 1000; cnt1++) {
3976 bnx2x_cl45_read(bp, phy,
3978 MDIO_PMA_REG_8073_XAUI_WA, &val);
3979 if (val & (1<<15)) {
3981 "XAUI workaround has completed\n");
3990 DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
3994 static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy)
3996 /* Force KR or KX */
3997 bnx2x_cl45_write(bp, phy,
3998 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
3999 bnx2x_cl45_write(bp, phy,
4000 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
4001 bnx2x_cl45_write(bp, phy,
4002 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
4003 bnx2x_cl45_write(bp, phy,
4004 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
4007 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
4008 struct bnx2x_phy *phy,
4009 struct link_vars *vars)
4012 struct bnx2x *bp = params->bp;
4013 bnx2x_cl45_read(bp, phy,
4014 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
4016 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
4017 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
4018 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
4019 if ((vars->ieee_fc &
4020 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
4021 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
4022 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
4024 if ((vars->ieee_fc &
4025 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
4026 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
4027 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
4029 if ((vars->ieee_fc &
4030 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
4031 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
4032 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
4035 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
4037 bnx2x_cl45_write(bp, phy,
4038 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
4042 static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy,
4043 struct link_params *params,
4044 struct link_vars *vars)
4046 struct bnx2x *bp = params->bp;
4049 DP(NETIF_MSG_LINK, "Init 8073\n");
4052 gpio_port = BP_PATH(bp);
4054 gpio_port = params->port;
4055 /* Restore normal power mode*/
4056 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4057 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
4059 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4060 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
4063 bnx2x_cl45_write(bp, phy,
4064 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2));
4065 bnx2x_cl45_write(bp, phy,
4066 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004);
4068 bnx2x_8073_set_pause_cl37(params, phy, vars);
4070 bnx2x_cl45_read(bp, phy,
4071 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
4073 bnx2x_cl45_read(bp, phy,
4074 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
4076 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
4079 * If this is forced speed, set to KR or KX (all other are not
4082 /* Swap polarity if required - Must be done only in non-1G mode */
4083 if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
4084 /* Configure the 8073 to swap _P and _N of the KR lines */
4085 DP(NETIF_MSG_LINK, "Swapping polarity for the 8073\n");
4086 /* 10G Rx/Tx and 1G Tx signal polarity swap */
4087 bnx2x_cl45_read(bp, phy,
4089 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
4090 bnx2x_cl45_write(bp, phy,
4092 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
4097 /* Enable CL37 BAM */
4098 if (REG_RD(bp, params->shmem_base +
4099 offsetof(struct shmem_region, dev_info.
4100 port_hw_config[params->port].default_cfg)) &
4101 PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
4103 bnx2x_cl45_read(bp, phy,
4105 MDIO_AN_REG_8073_BAM, &val);
4106 bnx2x_cl45_write(bp, phy,
4108 MDIO_AN_REG_8073_BAM, val | 1);
4109 DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
4111 if (params->loopback_mode == LOOPBACK_EXT) {
4112 bnx2x_807x_force_10G(bp, phy);
4113 DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
4116 bnx2x_cl45_write(bp, phy,
4117 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
4119 if (phy->req_line_speed != SPEED_AUTO_NEG) {
4120 if (phy->req_line_speed == SPEED_10000) {
4122 } else if (phy->req_line_speed == SPEED_2500) {
4124 /* Note that 2.5G works only
4125 when used with 1G advertisment */
4130 if (phy->speed_cap_mask &
4131 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4134 /* Note that 2.5G works only when
4135 used with 1G advertisment */
4136 if (phy->speed_cap_mask &
4137 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
4138 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
4140 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
4143 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
4144 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
4146 if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
4147 (phy->req_line_speed == SPEED_AUTO_NEG)) ||
4148 (phy->req_line_speed == SPEED_2500)) {
4150 /* Allow 2.5G for A1 and above */
4151 bnx2x_cl45_read(bp, phy,
4152 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
4154 DP(NETIF_MSG_LINK, "Add 2.5G\n");
4160 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
4164 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
4165 /* Add support for CL37 (passive mode) II */
4167 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
4168 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
4169 (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
4172 /* Add support for CL37 (passive mode) III */
4173 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
4175 /* The SNR will improve about 2db by changing
4176 BW and FEE main tap. Rest commands are executed
4178 if (bnx2x_8073_is_snr_needed(bp, phy))
4179 bnx2x_cl45_write(bp, phy,
4180 MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
4183 /* Enable FEC (Forware Error Correction) Request in the AN */
4184 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
4186 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
4188 bnx2x_ext_phy_set_pause(params, phy, vars);
4190 /* Restart autoneg */
4192 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
4193 DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
4194 ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
4198 static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
4199 struct link_params *params,
4200 struct link_vars *vars)
4202 struct bnx2x *bp = params->bp;
4205 u16 link_status = 0;
4206 u16 an1000_status = 0;
4208 bnx2x_cl45_read(bp, phy,
4209 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
4211 DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
4213 /* clear the interrupt LASI status register */
4214 bnx2x_cl45_read(bp, phy,
4215 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
4216 bnx2x_cl45_read(bp, phy,
4217 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
4218 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
4220 bnx2x_cl45_read(bp, phy,
4221 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
4223 /* Check the LASI */
4224 bnx2x_cl45_read(bp, phy,
4225 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
4227 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
4229 /* Check the link status */
4230 bnx2x_cl45_read(bp, phy,
4231 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
4232 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
4234 bnx2x_cl45_read(bp, phy,
4235 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
4236 bnx2x_cl45_read(bp, phy,
4237 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
4238 link_up = ((val1 & 4) == 4);
4239 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
4242 ((phy->req_line_speed != SPEED_10000))) {
4243 if (bnx2x_8073_xaui_wa(bp, phy) != 0)
4246 bnx2x_cl45_read(bp, phy,
4247 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
4248 bnx2x_cl45_read(bp, phy,
4249 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
4251 /* Check the link status on 1.1.2 */
4252 bnx2x_cl45_read(bp, phy,
4253 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
4254 bnx2x_cl45_read(bp, phy,
4255 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
4256 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
4257 "an_link_status=0x%x\n", val2, val1, an1000_status);
4259 link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
4260 if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
4261 /* The SNR will improve about 2dbby
4262 changing the BW and FEE main tap.*/
4263 /* The 1st write to change FFE main
4264 tap is set before restart AN */
4265 /* Change PLL Bandwidth in EDC
4267 bnx2x_cl45_write(bp, phy,
4268 MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
4271 /* Change CDR Bandwidth in EDC register */
4272 bnx2x_cl45_write(bp, phy,
4273 MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
4276 bnx2x_cl45_read(bp, phy,
4277 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
4280 /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
4281 if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
4283 vars->line_speed = SPEED_10000;
4284 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
4286 } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
4288 vars->line_speed = SPEED_2500;
4289 DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
4291 } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
4293 vars->line_speed = SPEED_1000;
4294 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
4298 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
4303 /* Swap polarity if required */
4304 if (params->lane_config &
4305 PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
4306 /* Configure the 8073 to swap P and N of the KR lines */
4307 bnx2x_cl45_read(bp, phy,
4309 MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
4311 * Set bit 3 to invert Rx in 1G mode and clear this bit
4312 * when it`s in 10G mode.
4314 if (vars->line_speed == SPEED_1000) {
4315 DP(NETIF_MSG_LINK, "Swapping 1G polarity for"
4321 bnx2x_cl45_write(bp, phy,
4323 MDIO_XS_REG_8073_RX_CTRL_PCIE,
4326 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
4327 bnx2x_8073_resolve_fc(phy, params, vars);
4328 vars->duplex = DUPLEX_FULL;
4333 static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
4334 struct link_params *params)
4336 struct bnx2x *bp = params->bp;
4339 gpio_port = BP_PATH(bp);
4341 gpio_port = params->port;
4342 DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
4344 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4345 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4349 /******************************************************************/
4350 /* BCM8705 PHY SECTION */
4351 /******************************************************************/
4352 static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy,
4353 struct link_params *params,
4354 struct link_vars *vars)
4356 struct bnx2x *bp = params->bp;
4357 DP(NETIF_MSG_LINK, "init 8705\n");
4358 /* Restore normal power mode*/
4359 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4360 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
4362 bnx2x_ext_phy_hw_reset(bp, params->port);
4363 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
4364 bnx2x_wait_reset_complete(bp, phy);
4366 bnx2x_cl45_write(bp, phy,
4367 MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
4368 bnx2x_cl45_write(bp, phy,
4369 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
4370 bnx2x_cl45_write(bp, phy,
4371 MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
4372 bnx2x_cl45_write(bp, phy,
4373 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
4374 /* BCM8705 doesn't have microcode, hence the 0 */
4375 bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
4379 static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
4380 struct link_params *params,
4381 struct link_vars *vars)
4385 struct bnx2x *bp = params->bp;
4386 DP(NETIF_MSG_LINK, "read status 8705\n");
4387 bnx2x_cl45_read(bp, phy,
4388 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
4389 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4391 bnx2x_cl45_read(bp, phy,
4392 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
4393 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4395 bnx2x_cl45_read(bp, phy,
4396 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
4398 bnx2x_cl45_read(bp, phy,
4399 MDIO_PMA_DEVAD, 0xc809, &val1);
4400 bnx2x_cl45_read(bp, phy,
4401 MDIO_PMA_DEVAD, 0xc809, &val1);
4403 DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
4404 link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
4406 vars->line_speed = SPEED_10000;
4407 bnx2x_ext_phy_resolve_fc(phy, params, vars);
4412 /******************************************************************/
4413 /* SFP+ module Section */
4414 /******************************************************************/
4415 static void bnx2x_sfp_set_transmitter(struct bnx2x *bp,
4416 struct bnx2x_phy *phy,
4422 DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
4424 /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
4425 bnx2x_cl45_read(bp, phy,
4427 MDIO_PMA_REG_PHY_IDENTIFIER,
4435 bnx2x_cl45_write(bp, phy,
4437 MDIO_PMA_REG_PHY_IDENTIFIER,
4441 static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
4442 struct link_params *params,
4443 u16 addr, u8 byte_cnt, u8 *o_buf)
4445 struct bnx2x *bp = params->bp;
4448 if (byte_cnt > 16) {
4449 DP(NETIF_MSG_LINK, "Reading from eeprom is"
4450 " is limited to 0xf\n");
4453 /* Set the read command byte count */
4454 bnx2x_cl45_write(bp, phy,
4455 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
4456 (byte_cnt | 0xa000));
4458 /* Set the read command address */
4459 bnx2x_cl45_write(bp, phy,
4460 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
4463 /* Activate read command */
4464 bnx2x_cl45_write(bp, phy,
4465 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
4468 /* Wait up to 500us for command complete status */
4469 for (i = 0; i < 100; i++) {
4470 bnx2x_cl45_read(bp, phy,
4472 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
4473 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
4474 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
4479 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
4480 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
4482 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
4483 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
4487 /* Read the buffer */
4488 for (i = 0; i < byte_cnt; i++) {
4489 bnx2x_cl45_read(bp, phy,
4491 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
4492 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
4495 for (i = 0; i < 100; i++) {
4496 bnx2x_cl45_read(bp, phy,
4498 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
4499 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
4500 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
4507 static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
4508 struct link_params *params,
4509 u16 addr, u8 byte_cnt, u8 *o_buf)
4511 struct bnx2x *bp = params->bp;
4514 if (byte_cnt > 16) {
4515 DP(NETIF_MSG_LINK, "Reading from eeprom is"
4516 " is limited to 0xf\n");
4520 /* Need to read from 1.8000 to clear it */
4521 bnx2x_cl45_read(bp, phy,
4523 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
4526 /* Set the read command byte count */
4527 bnx2x_cl45_write(bp, phy,
4529 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
4530 ((byte_cnt < 2) ? 2 : byte_cnt));
4532 /* Set the read command address */
4533 bnx2x_cl45_write(bp, phy,
4535 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
4537 /* Set the destination address */
4538 bnx2x_cl45_write(bp, phy,
4541 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
4543 /* Activate read command */
4544 bnx2x_cl45_write(bp, phy,
4546 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
4548 /* Wait appropriate time for two-wire command to finish before
4549 polling the status register */
4552 /* Wait up to 500us for command complete status */
4553 for (i = 0; i < 100; i++) {
4554 bnx2x_cl45_read(bp, phy,
4556 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
4557 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
4558 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
4563 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
4564 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
4566 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
4567 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
4571 /* Read the buffer */
4572 for (i = 0; i < byte_cnt; i++) {
4573 bnx2x_cl45_read(bp, phy,
4575 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
4576 o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
4579 for (i = 0; i < 100; i++) {
4580 bnx2x_cl45_read(bp, phy,
4582 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
4583 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
4584 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
4592 u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
4593 struct link_params *params, u16 addr,
4594 u8 byte_cnt, u8 *o_buf)
4596 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
4597 return bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
4599 else if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
4600 return bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
4605 static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy,
4606 struct link_params *params,
4609 struct bnx2x *bp = params->bp;
4610 u8 val, check_limiting_mode = 0;
4611 *edc_mode = EDC_MODE_LIMITING;
4613 /* First check for copper cable */
4614 if (bnx2x_read_sfp_module_eeprom(phy,
4616 SFP_EEPROM_CON_TYPE_ADDR,
4619 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
4624 case SFP_EEPROM_CON_TYPE_VAL_COPPER:
4626 u8 copper_module_type;
4628 /* Check if its active cable( includes SFP+ module)
4630 if (bnx2x_read_sfp_module_eeprom(phy,
4632 SFP_EEPROM_FC_TX_TECH_ADDR,
4634 &copper_module_type) !=
4637 "Failed to read copper-cable-type"
4638 " from SFP+ EEPROM\n");
4642 if (copper_module_type &
4643 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
4644 DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
4645 check_limiting_mode = 1;
4646 } else if (copper_module_type &
4647 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
4648 DP(NETIF_MSG_LINK, "Passive Copper"
4649 " cable detected\n");
4651 EDC_MODE_PASSIVE_DAC;
4653 DP(NETIF_MSG_LINK, "Unknown copper-cable-"
4654 "type 0x%x !!!\n", copper_module_type);
4659 case SFP_EEPROM_CON_TYPE_VAL_LC:
4660 DP(NETIF_MSG_LINK, "Optic module detected\n");
4661 check_limiting_mode = 1;
4664 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
4669 if (check_limiting_mode) {
4670 u8 options[SFP_EEPROM_OPTIONS_SIZE];
4671 if (bnx2x_read_sfp_module_eeprom(phy,
4673 SFP_EEPROM_OPTIONS_ADDR,
4674 SFP_EEPROM_OPTIONS_SIZE,
4676 DP(NETIF_MSG_LINK, "Failed to read Option"
4677 " field from module EEPROM\n");
4680 if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
4681 *edc_mode = EDC_MODE_LINEAR;
4683 *edc_mode = EDC_MODE_LIMITING;
4685 DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
4688 /* This function read the relevant field from the module ( SFP+ ),
4689 and verify it is compliant with this board */
4690 static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
4691 struct link_params *params)
4693 struct bnx2x *bp = params->bp;
4695 u32 fw_resp, fw_cmd_param;
4696 char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
4697 char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
4698 phy->flags &= ~FLAGS_SFP_NOT_APPROVED;
4699 val = REG_RD(bp, params->shmem_base +
4700 offsetof(struct shmem_region, dev_info.
4701 port_feature_config[params->port].config));
4702 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
4703 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
4704 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
4708 if (params->feature_config_flags &
4709 FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
4710 /* Use specific phy request */
4711 cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
4712 } else if (params->feature_config_flags &
4713 FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
4714 /* Use first phy request only in case of non-dual media*/
4715 if (DUAL_MEDIA(params)) {
4716 DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
4720 cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
4722 /* No support in OPT MDL detection */
4723 DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
4728 fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
4729 fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param);
4730 if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
4731 DP(NETIF_MSG_LINK, "Approved module\n");
4735 /* format the warning message */
4736 if (bnx2x_read_sfp_module_eeprom(phy,
4738 SFP_EEPROM_VENDOR_NAME_ADDR,
4739 SFP_EEPROM_VENDOR_NAME_SIZE,
4741 vendor_name[0] = '\0';
4743 vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
4744 if (bnx2x_read_sfp_module_eeprom(phy,
4746 SFP_EEPROM_PART_NO_ADDR,
4747 SFP_EEPROM_PART_NO_SIZE,
4749 vendor_pn[0] = '\0';
4751 vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
4753 netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected,"
4754 " Port %d from %s part number %s\n",
4755 params->port, vendor_name, vendor_pn);
4756 phy->flags |= FLAGS_SFP_NOT_APPROVED;
4760 static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
4761 struct link_params *params)
4765 struct bnx2x *bp = params->bp;
4767 /* Initialization time after hot-plug may take up to 300ms for some
4768 phys type ( e.g. JDSU ) */
4769 for (timeout = 0; timeout < 60; timeout++) {
4770 if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
4772 DP(NETIF_MSG_LINK, "SFP+ module initialization "
4773 "took %d ms\n", timeout * 5);
4781 static void bnx2x_8727_power_module(struct bnx2x *bp,
4782 struct bnx2x_phy *phy,
4784 /* Make sure GPIOs are not using for LED mode */
4787 * In the GPIO register, bit 4 is use to detemine if the GPIOs are
4788 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
4790 * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
4791 * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
4792 * where the 1st bit is the over-current(only input), and 2nd bit is
4793 * for power( only output )
4797 * In case of NOC feature is disabled and power is up, set GPIO control
4798 * as input to enable listening of over-current indication
4800 if (phy->flags & FLAGS_NOC)
4803 FLAGS_NOC) && is_power_up)
4807 * Set GPIO control to OUTPUT, and set the power bit
4808 * to according to the is_power_up
4810 val = ((!(is_power_up)) << 1);
4812 bnx2x_cl45_write(bp, phy,
4814 MDIO_PMA_REG_8727_GPIO_CTRL,
4818 static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
4819 struct bnx2x_phy *phy,
4822 u16 cur_limiting_mode;
4824 bnx2x_cl45_read(bp, phy,
4826 MDIO_PMA_REG_ROM_VER2,
4827 &cur_limiting_mode);
4828 DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
4831 if (edc_mode == EDC_MODE_LIMITING) {
4832 DP(NETIF_MSG_LINK, "Setting LIMITING MODE\n");
4833 bnx2x_cl45_write(bp, phy,
4835 MDIO_PMA_REG_ROM_VER2,
4837 } else { /* LRM mode ( default )*/
4839 DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
4841 /* Changing to LRM mode takes quite few seconds.
4842 So do it only if current mode is limiting
4843 ( default is LRM )*/
4844 if (cur_limiting_mode != EDC_MODE_LIMITING)
4847 bnx2x_cl45_write(bp, phy,
4849 MDIO_PMA_REG_LRM_MODE,
4851 bnx2x_cl45_write(bp, phy,
4853 MDIO_PMA_REG_ROM_VER2,
4855 bnx2x_cl45_write(bp, phy,
4857 MDIO_PMA_REG_MISC_CTRL0,
4859 bnx2x_cl45_write(bp, phy,
4861 MDIO_PMA_REG_LRM_MODE,
4867 static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
4868 struct bnx2x_phy *phy,
4873 bnx2x_cl45_read(bp, phy,
4875 MDIO_PMA_REG_PHY_IDENTIFIER,
4878 bnx2x_cl45_write(bp, phy,
4880 MDIO_PMA_REG_PHY_IDENTIFIER,
4881 (phy_identifier & ~(1<<9)));
4883 bnx2x_cl45_read(bp, phy,
4885 MDIO_PMA_REG_ROM_VER2,
4887 /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
4888 bnx2x_cl45_write(bp, phy,
4890 MDIO_PMA_REG_ROM_VER2,
4891 (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
4893 bnx2x_cl45_write(bp, phy,
4895 MDIO_PMA_REG_PHY_IDENTIFIER,
4896 (phy_identifier | (1<<9)));
4901 static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
4902 struct link_params *params,
4905 struct bnx2x *bp = params->bp;
4909 bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
4912 if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
4913 bnx2x_sfp_set_transmitter(bp, phy, params->port, 1);
4916 DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
4922 static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
4923 struct link_params *params)
4925 struct bnx2x *bp = params->bp;
4929 u32 val = REG_RD(bp, params->shmem_base +
4930 offsetof(struct shmem_region, dev_info.
4931 port_feature_config[params->port].config));
4933 DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
4936 if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
4937 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
4939 } else if (bnx2x_verify_sfp_module(phy, params) != 0) {
4940 /* check SFP+ module compatibility */
4941 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
4943 /* Turn on fault module-detected led */
4944 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4945 MISC_REGISTERS_GPIO_HIGH,
4947 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
4948 ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
4949 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) {
4950 /* Shutdown SFP+ module */
4951 DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
4952 bnx2x_8727_power_module(bp, phy, 0);
4956 /* Turn off fault module-detected led */
4957 DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n");
4958 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4959 MISC_REGISTERS_GPIO_LOW,
4963 /* power up the SFP module */
4964 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
4965 bnx2x_8727_power_module(bp, phy, 1);
4967 /* Check and set limiting mode / LRM mode on 8726.
4968 On 8727 it is done automatically */
4969 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
4970 bnx2x_8726_set_limiting_mode(bp, phy, edc_mode);
4972 bnx2x_8727_set_limiting_mode(bp, phy, edc_mode);
4974 * Enable transmit for this module if the module is approved, or
4975 * if unapproved modules should also enable the Tx laser
4978 (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
4979 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
4980 bnx2x_sfp_set_transmitter(bp, phy, params->port, 1);
4982 bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
4987 void bnx2x_handle_module_detect_int(struct link_params *params)
4989 struct bnx2x *bp = params->bp;
4990 struct bnx2x_phy *phy = ¶ms->phy[EXT_PHY1];
4992 u8 port = params->port;
4994 /* Set valid module led off */
4995 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4996 MISC_REGISTERS_GPIO_HIGH,
4999 /* Get current gpio val refelecting module plugged in / out*/
5000 gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
5002 /* Call the handling function in case module is detected */
5003 if (gpio_val == 0) {
5005 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
5006 MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
5009 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
5010 bnx2x_sfp_module_detection(phy, params);
5012 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
5014 u32 val = REG_RD(bp, params->shmem_base +
5015 offsetof(struct shmem_region, dev_info.
5016 port_feature_config[params->port].
5019 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
5020 MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
5022 /* Module was plugged out. */
5023 /* Disable transmit for this module */
5024 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
5025 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
5026 bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
5030 /******************************************************************/
5031 /* common BCM8706/BCM8726 PHY SECTION */
5032 /******************************************************************/
5033 static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
5034 struct link_params *params,
5035 struct link_vars *vars)
5038 u16 val1, val2, rx_sd, pcs_status;
5039 struct bnx2x *bp = params->bp;
5040 DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
5042 bnx2x_cl45_read(bp, phy,
5043 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
5044 /* clear LASI indication*/
5045 bnx2x_cl45_read(bp, phy,
5046 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
5047 bnx2x_cl45_read(bp, phy,
5048 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
5049 DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
5051 bnx2x_cl45_read(bp, phy,
5052 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
5053 bnx2x_cl45_read(bp, phy,
5054 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
5055 bnx2x_cl45_read(bp, phy,
5056 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
5057 bnx2x_cl45_read(bp, phy,
5058 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
5060 DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
5061 " link_status 0x%x\n", rx_sd, pcs_status, val2);
5062 /* link is up if both bit 0 of pmd_rx_sd and
5063 * bit 0 of pcs_status are set, or if the autoneg bit
5066 link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
5069 vars->line_speed = SPEED_1000;
5071 vars->line_speed = SPEED_10000;
5072 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5073 vars->duplex = DUPLEX_FULL;
5078 /******************************************************************/
5079 /* BCM8706 PHY SECTION */
5080 /******************************************************************/
5081 static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
5082 struct link_params *params,
5083 struct link_vars *vars)
5086 struct bnx2x *bp = params->bp;
5087 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5088 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
5090 bnx2x_ext_phy_hw_reset(bp, params->port);
5091 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
5092 bnx2x_wait_reset_complete(bp, phy);
5094 /* Wait until fw is loaded */
5095 for (cnt = 0; cnt < 100; cnt++) {
5096 bnx2x_cl45_read(bp, phy,
5097 MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
5102 DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt);
5103 if ((params->feature_config_flags &
5104 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
5107 for (i = 0; i < 4; i++) {
5108 reg = MDIO_XS_8706_REG_BANK_RX0 +
5109 i*(MDIO_XS_8706_REG_BANK_RX1 -
5110 MDIO_XS_8706_REG_BANK_RX0);
5111 bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val);
5112 /* Clear first 3 bits of the control */
5114 /* Set control bits according to configuration */
5115 val |= (phy->rx_preemphasis[i] & 0x7);
5116 DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706"
5117 " reg 0x%x <-- val 0x%x\n", reg, val);
5118 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val);
5122 if (phy->req_line_speed == SPEED_10000) {
5123 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
5125 bnx2x_cl45_write(bp, phy,
5127 MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
5128 bnx2x_cl45_write(bp, phy,
5129 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
5131 /* Force 1Gbps using autoneg with 1G advertisment */
5133 /* Allow CL37 through CL73 */
5134 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
5135 bnx2x_cl45_write(bp, phy,
5136 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
5138 /* Enable Full-Duplex advertisment on CL37 */
5139 bnx2x_cl45_write(bp, phy,
5140 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
5141 /* Enable CL37 AN */
5142 bnx2x_cl45_write(bp, phy,
5143 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
5145 bnx2x_cl45_write(bp, phy,
5146 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
5148 /* Enable clause 73 AN */
5149 bnx2x_cl45_write(bp, phy,
5150 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
5151 bnx2x_cl45_write(bp, phy,
5152 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5154 bnx2x_cl45_write(bp, phy,
5155 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
5158 bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
5162 static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy,
5163 struct link_params *params,
5164 struct link_vars *vars)
5166 return bnx2x_8706_8726_read_status(phy, params, vars);
5169 /******************************************************************/
5170 /* BCM8726 PHY SECTION */
5171 /******************************************************************/
5172 static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
5173 struct link_params *params)
5175 struct bnx2x *bp = params->bp;
5176 DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
5177 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
5180 static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
5181 struct link_params *params)
5183 struct bnx2x *bp = params->bp;
5184 /* Need to wait 100ms after reset */
5187 /* Micro controller re-boot */
5188 bnx2x_cl45_write(bp, phy,
5189 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
5191 /* Set soft reset */
5192 bnx2x_cl45_write(bp, phy,
5194 MDIO_PMA_REG_GEN_CTRL,
5195 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
5197 bnx2x_cl45_write(bp, phy,
5199 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
5201 bnx2x_cl45_write(bp, phy,
5203 MDIO_PMA_REG_GEN_CTRL,
5204 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
5206 /* wait for 150ms for microcode load */
5209 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
5210 bnx2x_cl45_write(bp, phy,
5212 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
5215 bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
5218 static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
5219 struct link_params *params,
5220 struct link_vars *vars)
5222 struct bnx2x *bp = params->bp;
5224 u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
5226 bnx2x_cl45_read(bp, phy,
5227 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
5229 if (val1 & (1<<15)) {
5230 DP(NETIF_MSG_LINK, "Tx is disabled\n");
5232 vars->line_speed = 0;
5239 static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy,
5240 struct link_params *params,
5241 struct link_vars *vars)
5243 struct bnx2x *bp = params->bp;
5245 u32 swap_val, swap_override, aeu_gpio_mask, offset;
5246 DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
5247 /* Restore normal power mode*/
5248 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5249 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
5251 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
5252 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
5254 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
5255 bnx2x_wait_reset_complete(bp, phy);
5257 bnx2x_8726_external_rom_boot(phy, params);
5259 /* Need to call module detected on initialization since
5260 the module detection triggered by actual module
5261 insertion might occur before driver is loaded, and when
5262 driver is loaded, it reset all registers, including the
5264 bnx2x_sfp_module_detection(phy, params);
5266 if (phy->req_line_speed == SPEED_1000) {
5267 DP(NETIF_MSG_LINK, "Setting 1G force\n");
5268 bnx2x_cl45_write(bp, phy,
5269 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
5270 bnx2x_cl45_write(bp, phy,
5271 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
5272 bnx2x_cl45_write(bp, phy,
5273 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5);
5274 bnx2x_cl45_write(bp, phy,
5275 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5277 } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
5278 (phy->speed_cap_mask &
5279 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
5280 ((phy->speed_cap_mask &
5281 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
5282 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
5283 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
5284 /* Set Flow control */
5285 bnx2x_ext_phy_set_pause(params, phy, vars);
5286 bnx2x_cl45_write(bp, phy,
5287 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
5288 bnx2x_cl45_write(bp, phy,
5289 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
5290 bnx2x_cl45_write(bp, phy,
5291 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
5292 bnx2x_cl45_write(bp, phy,
5293 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
5294 bnx2x_cl45_write(bp, phy,
5295 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
5296 /* Enable RX-ALARM control to receive
5297 interrupt for 1G speed change */
5298 bnx2x_cl45_write(bp, phy,
5299 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4);
5300 bnx2x_cl45_write(bp, phy,
5301 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5304 } else { /* Default 10G. Set only LASI control */
5305 bnx2x_cl45_write(bp, phy,
5306 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
5309 /* Set TX PreEmphasis if needed */
5310 if ((params->feature_config_flags &
5311 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
5312 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
5314 phy->tx_preemphasis[0],
5315 phy->tx_preemphasis[1]);
5316 bnx2x_cl45_write(bp, phy,
5318 MDIO_PMA_REG_8726_TX_CTRL1,
5319 phy->tx_preemphasis[0]);
5321 bnx2x_cl45_write(bp, phy,
5323 MDIO_PMA_REG_8726_TX_CTRL2,
5324 phy->tx_preemphasis[1]);
5327 /* Set GPIO3 to trigger SFP+ module insertion/removal */
5328 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
5329 MISC_REGISTERS_GPIO_INPUT_HI_Z, params->port);
5331 /* The GPIO should be swapped if the swap register is set and active */
5332 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
5333 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
5335 /* Select function upon port-swap configuration */
5336 if (params->port == 0) {
5337 offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
5338 aeu_gpio_mask = (swap_val && swap_override) ?
5339 AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 :
5340 AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0;
5342 offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
5343 aeu_gpio_mask = (swap_val && swap_override) ?
5344 AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 :
5345 AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1;
5347 val = REG_RD(bp, offset);
5348 /* add GPIO3 to group */
5349 val |= aeu_gpio_mask;
5350 REG_WR(bp, offset, val);
5355 static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
5356 struct link_params *params)
5358 struct bnx2x *bp = params->bp;
5359 DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
5360 /* Set serial boot control for external load */
5361 bnx2x_cl45_write(bp, phy,
5363 MDIO_PMA_REG_GEN_CTRL, 0x0001);
5366 /******************************************************************/
5367 /* BCM8727 PHY SECTION */
5368 /******************************************************************/
5370 static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy,
5371 struct link_params *params, u8 mode)
5373 struct bnx2x *bp = params->bp;
5374 u16 led_mode_bitmask = 0;
5375 u16 gpio_pins_bitmask = 0;
5377 /* Only NOC flavor requires to set the LED specifically */
5378 if (!(phy->flags & FLAGS_NOC))
5381 case LED_MODE_FRONT_PANEL_OFF:
5383 led_mode_bitmask = 0;
5384 gpio_pins_bitmask = 0x03;
5387 led_mode_bitmask = 0;
5388 gpio_pins_bitmask = 0x02;
5391 led_mode_bitmask = 0x60;
5392 gpio_pins_bitmask = 0x11;
5395 bnx2x_cl45_read(bp, phy,
5397 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
5400 val |= led_mode_bitmask;
5401 bnx2x_cl45_write(bp, phy,
5403 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
5405 bnx2x_cl45_read(bp, phy,
5407 MDIO_PMA_REG_8727_GPIO_CTRL,
5410 val |= gpio_pins_bitmask;
5411 bnx2x_cl45_write(bp, phy,
5413 MDIO_PMA_REG_8727_GPIO_CTRL,
5416 static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
5417 struct link_params *params) {
5418 u32 swap_val, swap_override;
5421 * The PHY reset is controlled by GPIO 1. Fake the port number
5422 * to cancel the swap done in set_gpio()
5424 struct bnx2x *bp = params->bp;
5425 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
5426 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
5427 port = (swap_val && swap_override) ^ 1;
5428 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
5429 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
5432 static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy,
5433 struct link_params *params,
5434 struct link_vars *vars)
5436 u16 tmp1, val, mod_abs;
5437 u16 rx_alarm_ctrl_val;
5439 struct bnx2x *bp = params->bp;
5440 /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
5442 bnx2x_wait_reset_complete(bp, phy);
5443 rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
5444 lasi_ctrl_val = 0x0004;
5446 DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
5448 bnx2x_cl45_write(bp, phy,
5449 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5452 bnx2x_cl45_write(bp, phy,
5453 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val);
5455 /* Initially configure MOD_ABS to interrupt when
5456 module is presence( bit 8) */
5457 bnx2x_cl45_read(bp, phy,
5458 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
5459 /* Set EDC off by setting OPTXLOS signal input to low
5461 When the EDC is off it locks onto a reference clock and
5462 avoids becoming 'lost'.*/
5464 if (!(phy->flags & FLAGS_NOC))
5466 bnx2x_cl45_write(bp, phy,
5467 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
5470 /* Make MOD_ABS give interrupt on change */
5471 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
5474 if (phy->flags & FLAGS_NOC)
5478 * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
5479 * status which reflect SFP+ module over-current
5481 if (!(phy->flags & FLAGS_NOC))
5482 val &= 0xff8f; /* Reset bits 4-6 */
5483 bnx2x_cl45_write(bp, phy,
5484 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val);
5486 bnx2x_8727_power_module(bp, phy, 1);
5488 bnx2x_cl45_read(bp, phy,
5489 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
5491 bnx2x_cl45_read(bp, phy,
5492 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
5494 /* Set option 1G speed */
5495 if (phy->req_line_speed == SPEED_1000) {
5496 DP(NETIF_MSG_LINK, "Setting 1G force\n");
5497 bnx2x_cl45_write(bp, phy,
5498 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
5499 bnx2x_cl45_write(bp, phy,
5500 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
5501 bnx2x_cl45_read(bp, phy,
5502 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
5503 DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
5505 * Power down the XAUI until link is up in case of dual-media
5508 if (DUAL_MEDIA(params)) {
5509 bnx2x_cl45_read(bp, phy,
5511 MDIO_PMA_REG_8727_PCS_GP, &val);
5513 bnx2x_cl45_write(bp, phy,
5515 MDIO_PMA_REG_8727_PCS_GP, val);
5517 } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
5518 ((phy->speed_cap_mask &
5519 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
5520 ((phy->speed_cap_mask &
5521 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
5522 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
5524 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
5525 bnx2x_cl45_write(bp, phy,
5526 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
5527 bnx2x_cl45_write(bp, phy,
5528 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
5531 * Since the 8727 has only single reset pin, need to set the 10G
5532 * registers although it is default
5534 bnx2x_cl45_write(bp, phy,
5535 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
5537 bnx2x_cl45_write(bp, phy,
5538 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
5539 bnx2x_cl45_write(bp, phy,
5540 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
5541 bnx2x_cl45_write(bp, phy,
5542 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
5546 /* Set 2-wire transfer rate of SFP+ module EEPROM
5547 * to 100Khz since some DACs(direct attached cables) do
5548 * not work at 400Khz.
5550 bnx2x_cl45_write(bp, phy,
5551 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
5554 /* Set TX PreEmphasis if needed */
5555 if ((params->feature_config_flags &
5556 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
5557 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
5558 phy->tx_preemphasis[0],
5559 phy->tx_preemphasis[1]);
5560 bnx2x_cl45_write(bp, phy,
5561 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
5562 phy->tx_preemphasis[0]);
5564 bnx2x_cl45_write(bp, phy,
5565 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
5566 phy->tx_preemphasis[1]);
5572 static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
5573 struct link_params *params)
5575 struct bnx2x *bp = params->bp;
5576 u16 mod_abs, rx_alarm_status;
5577 u32 val = REG_RD(bp, params->shmem_base +
5578 offsetof(struct shmem_region, dev_info.
5579 port_feature_config[params->port].
5581 bnx2x_cl45_read(bp, phy,
5583 MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
5584 if (mod_abs & (1<<8)) {
5586 /* Module is absent */
5587 DP(NETIF_MSG_LINK, "MOD_ABS indication "
5588 "show module is absent\n");
5590 /* 1. Set mod_abs to detect next module
5592 2. Set EDC off by setting OPTXLOS signal input to low
5594 When the EDC is off it locks onto a reference clock and
5595 avoids becoming 'lost'.*/
5597 if (!(phy->flags & FLAGS_NOC))
5599 bnx2x_cl45_write(bp, phy,
5601 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
5603 /* Clear RX alarm since it stays up as long as
5604 the mod_abs wasn't changed */
5605 bnx2x_cl45_read(bp, phy,
5607 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
5610 /* Module is present */
5611 DP(NETIF_MSG_LINK, "MOD_ABS indication "
5612 "show module is present\n");
5613 /* First thing, disable transmitter,
5614 and if the module is ok, the
5615 module_detection will enable it*/
5617 /* 1. Set mod_abs to detect next module
5618 absent event ( bit 8)
5619 2. Restore the default polarity of the OPRXLOS signal and
5620 this signal will then correctly indicate the presence or
5621 absence of the Rx signal. (bit 9) */
5623 if (!(phy->flags & FLAGS_NOC))
5625 bnx2x_cl45_write(bp, phy,
5627 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
5629 /* Clear RX alarm since it stays up as long as
5630 the mod_abs wasn't changed. This is need to be done
5631 before calling the module detection, otherwise it will clear
5632 the link update alarm */
5633 bnx2x_cl45_read(bp, phy,
5635 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
5638 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
5639 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
5640 bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
5642 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
5643 bnx2x_sfp_module_detection(phy, params);
5645 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
5648 DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
5650 /* No need to check link status in case of
5651 module plugged in/out */
5654 static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
5655 struct link_params *params,
5656 struct link_vars *vars)
5659 struct bnx2x *bp = params->bp;
5661 u16 link_status = 0;
5662 u16 rx_alarm_status, lasi_ctrl, val1;
5664 /* If PHY is not initialized, do not check link status */
5665 bnx2x_cl45_read(bp, phy,
5666 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
5671 /* Check the LASI */
5672 bnx2x_cl45_read(bp, phy,
5673 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
5675 vars->line_speed = 0;
5676 DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status);
5678 bnx2x_cl45_read(bp, phy,
5679 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
5681 DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
5684 bnx2x_cl45_read(bp, phy,
5685 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
5688 * If a module is present and there is need to check
5691 if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
5692 /* Check over-current using 8727 GPIO0 input*/
5693 bnx2x_cl45_read(bp, phy,
5694 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
5697 if ((val1 & (1<<8)) == 0) {
5698 DP(NETIF_MSG_LINK, "8727 Power fault has been detected"
5699 " on port %d\n", params->port);
5700 netdev_err(bp->dev, "Error: Power fault on Port %d has"
5701 " been detected and the power to "
5702 "that SFP+ module has been removed"
5703 " to prevent failure of the card."
5704 " Please remove the SFP+ module and"
5705 " restart the system to clear this"
5710 * Disable all RX_ALARMs except for
5713 bnx2x_cl45_write(bp, phy,
5715 MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5));
5717 bnx2x_cl45_read(bp, phy,
5719 MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
5720 /* Wait for module_absent_event */
5722 bnx2x_cl45_write(bp, phy,
5724 MDIO_PMA_REG_PHY_IDENTIFIER, val1);
5725 /* Clear RX alarm */
5726 bnx2x_cl45_read(bp, phy,
5728 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
5731 } /* Over current check */
5733 /* When module absent bit is set, check module */
5734 if (rx_alarm_status & (1<<5)) {
5735 bnx2x_8727_handle_mod_abs(phy, params);
5736 /* Enable all mod_abs and link detection bits */
5737 bnx2x_cl45_write(bp, phy,
5738 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5741 DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n");
5742 bnx2x_8727_specific_func(phy, params, ENABLE_TX);
5743 /* If transmitter is disabled, ignore false link up indication */
5744 bnx2x_cl45_read(bp, phy,
5745 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
5746 if (val1 & (1<<15)) {
5747 DP(NETIF_MSG_LINK, "Tx is disabled\n");
5751 bnx2x_cl45_read(bp, phy,
5753 MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
5755 /* Bits 0..2 --> speed detected,
5756 bits 13..15--> link is down */
5757 if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
5759 vars->line_speed = SPEED_10000;
5760 } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
5762 vars->line_speed = SPEED_1000;
5763 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
5767 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
5771 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5772 vars->duplex = DUPLEX_FULL;
5773 DP(NETIF_MSG_LINK, "duplex = 0x%x\n", vars->duplex);
5776 if ((DUAL_MEDIA(params)) &&
5777 (phy->req_line_speed == SPEED_1000)) {
5778 bnx2x_cl45_read(bp, phy,
5780 MDIO_PMA_REG_8727_PCS_GP, &val1);
5782 * In case of dual-media board and 1G, power up the XAUI side,
5783 * otherwise power it down. For 10G it is done automatically
5789 bnx2x_cl45_write(bp, phy,
5791 MDIO_PMA_REG_8727_PCS_GP, val1);
5796 static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
5797 struct link_params *params)
5799 struct bnx2x *bp = params->bp;
5800 /* Disable Transmitter */
5801 bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
5803 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0);
5807 /******************************************************************/
5808 /* BCM8481/BCM84823/BCM84833 PHY SECTION */
5809 /******************************************************************/
5810 static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
5811 struct link_params *params)
5813 u16 val, fw_ver1, fw_ver2, cnt;
5814 struct bnx2x *bp = params->bp;
5816 /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
5817 /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
5818 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
5819 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
5820 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
5821 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
5822 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
5824 for (cnt = 0; cnt < 100; cnt++) {
5825 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
5831 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n");
5832 bnx2x_save_spirom_version(bp, params->port, 0,
5838 /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
5839 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
5840 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
5841 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
5842 for (cnt = 0; cnt < 100; cnt++) {
5843 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
5849 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n");
5850 bnx2x_save_spirom_version(bp, params->port, 0,
5855 /* lower 16 bits of the register SPI_FW_STATUS */
5856 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
5857 /* upper 16 bits of register SPI_FW_STATUS */
5858 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
5860 bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1,
5864 static void bnx2x_848xx_set_led(struct bnx2x *bp,
5865 struct bnx2x_phy *phy)
5869 /* PHYC_CTL_LED_CTL */
5870 bnx2x_cl45_read(bp, phy,
5872 MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
5876 bnx2x_cl45_write(bp, phy,
5878 MDIO_PMA_REG_8481_LINK_SIGNAL, val);
5880 bnx2x_cl45_write(bp, phy,
5882 MDIO_PMA_REG_8481_LED1_MASK,
5885 bnx2x_cl45_write(bp, phy,
5887 MDIO_PMA_REG_8481_LED2_MASK,
5890 /* Select activity source by Tx and Rx, as suggested by PHY AE */
5891 bnx2x_cl45_write(bp, phy,
5893 MDIO_PMA_REG_8481_LED3_MASK,
5896 /* Select the closest activity blink rate to that in 10/100/1000 */
5897 bnx2x_cl45_write(bp, phy,
5899 MDIO_PMA_REG_8481_LED3_BLINK,
5902 bnx2x_cl45_read(bp, phy,
5904 MDIO_PMA_REG_84823_CTL_LED_CTL_1, &val);
5905 val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/
5907 bnx2x_cl45_write(bp, phy,
5909 MDIO_PMA_REG_84823_CTL_LED_CTL_1, val);
5911 /* 'Interrupt Mask' */
5912 bnx2x_cl45_write(bp, phy,
5917 static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
5918 struct link_params *params,
5919 struct link_vars *vars)
5921 struct bnx2x *bp = params->bp;
5922 u16 autoneg_val, an_1000_val, an_10_100_val;
5924 bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
5925 1 << NIG_LATCH_BC_ENABLE_MI_INT);
5927 bnx2x_cl45_write(bp, phy,
5928 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
5930 bnx2x_848xx_set_led(bp, phy);
5932 /* set 1000 speed advertisement */
5933 bnx2x_cl45_read(bp, phy,
5934 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
5937 bnx2x_ext_phy_set_pause(params, phy, vars);
5938 bnx2x_cl45_read(bp, phy,
5940 MDIO_AN_REG_8481_LEGACY_AN_ADV,
5942 bnx2x_cl45_read(bp, phy,
5943 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
5945 /* Disable forced speed */
5946 autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
5947 an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
5949 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
5950 (phy->speed_cap_mask &
5951 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
5952 (phy->req_line_speed == SPEED_1000)) {
5953 an_1000_val |= (1<<8);
5954 autoneg_val |= (1<<9 | 1<<12);
5955 if (phy->req_duplex == DUPLEX_FULL)
5956 an_1000_val |= (1<<9);
5957 DP(NETIF_MSG_LINK, "Advertising 1G\n");
5959 an_1000_val &= ~((1<<8) | (1<<9));
5961 bnx2x_cl45_write(bp, phy,
5962 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
5965 /* set 10 speed advertisement */
5966 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
5967 (phy->speed_cap_mask &
5968 (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
5969 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
5970 an_10_100_val |= (1<<7);
5971 /* Enable autoneg and restart autoneg for legacy speeds */
5972 autoneg_val |= (1<<9 | 1<<12);
5974 if (phy->req_duplex == DUPLEX_FULL)
5975 an_10_100_val |= (1<<8);
5976 DP(NETIF_MSG_LINK, "Advertising 100M\n");
5978 /* set 10 speed advertisement */
5979 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
5980 (phy->speed_cap_mask &
5981 (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
5982 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
5983 an_10_100_val |= (1<<5);
5984 autoneg_val |= (1<<9 | 1<<12);
5985 if (phy->req_duplex == DUPLEX_FULL)
5986 an_10_100_val |= (1<<6);
5987 DP(NETIF_MSG_LINK, "Advertising 10M\n");
5990 /* Only 10/100 are allowed to work in FORCE mode */
5991 if (phy->req_line_speed == SPEED_100) {
5992 autoneg_val |= (1<<13);
5993 /* Enabled AUTO-MDIX when autoneg is disabled */
5994 bnx2x_cl45_write(bp, phy,
5995 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
5996 (1<<15 | 1<<9 | 7<<0));
5997 DP(NETIF_MSG_LINK, "Setting 100M force\n");
5999 if (phy->req_line_speed == SPEED_10) {
6000 /* Enabled AUTO-MDIX when autoneg is disabled */
6001 bnx2x_cl45_write(bp, phy,
6002 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
6003 (1<<15 | 1<<9 | 7<<0));
6004 DP(NETIF_MSG_LINK, "Setting 10M force\n");
6007 bnx2x_cl45_write(bp, phy,
6008 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
6011 if (phy->req_duplex == DUPLEX_FULL)
6012 autoneg_val |= (1<<8);
6014 bnx2x_cl45_write(bp, phy,
6016 MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
6018 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
6019 (phy->speed_cap_mask &
6020 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
6021 (phy->req_line_speed == SPEED_10000)) {
6022 DP(NETIF_MSG_LINK, "Advertising 10G\n");
6023 /* Restart autoneg for 10G*/
6025 bnx2x_cl45_write(bp, phy,
6026 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
6028 } else if (phy->req_line_speed != SPEED_10 &&
6029 phy->req_line_speed != SPEED_100) {
6030 bnx2x_cl45_write(bp, phy,
6032 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
6035 /* Save spirom version */
6036 bnx2x_save_848xx_spirom_version(phy, params);
6041 static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy,
6042 struct link_params *params,
6043 struct link_vars *vars)
6045 struct bnx2x *bp = params->bp;
6046 /* Restore normal power mode*/
6047 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6048 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
6051 bnx2x_ext_phy_hw_reset(bp, params->port);
6052 bnx2x_wait_reset_complete(bp, phy);
6054 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
6055 return bnx2x_848xx_cmn_config_init(phy, params, vars);
6058 static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
6059 struct link_params *params,
6060 struct link_vars *vars)
6062 struct bnx2x *bp = params->bp;
6063 u8 port, initialize = 1;
6066 u32 actual_phy_selection;
6069 /* This is just for MDIO_CTL_REG_84823_MEDIA register. */
6075 port = params->port;
6076 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
6077 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
6079 bnx2x_wait_reset_complete(bp, phy);
6080 /* Wait for GPHY to come out of reset */
6082 /* BCM84823 requires that XGXS links up first @ 10G for normal
6084 temp = vars->line_speed;
6085 vars->line_speed = SPEED_10000;
6086 bnx2x_set_autoneg(¶ms->phy[INT_PHY], params, vars, 0);
6087 bnx2x_program_serdes(¶ms->phy[INT_PHY], params, vars);
6088 vars->line_speed = temp;
6090 /* Set dual-media configuration according to configuration */
6092 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
6093 MDIO_CTL_REG_84823_MEDIA, &val);
6094 val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
6095 MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
6096 MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
6097 MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
6098 MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
6099 val |= MDIO_CTL_REG_84823_CTRL_MAC_XFI |
6100 MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L;
6102 actual_phy_selection = bnx2x_phy_selection(params);
6104 switch (actual_phy_selection) {
6105 case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
6106 /* Do nothing. Essentialy this is like the priority copper */
6108 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
6109 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
6111 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
6112 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
6114 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
6115 /* Do nothing here. The first PHY won't be initialized at all */
6117 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
6118 val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
6122 if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000)
6123 val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
6125 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
6126 MDIO_CTL_REG_84823_MEDIA, val);
6127 DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
6128 params->multi_phy_config, val);
6131 rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
6133 bnx2x_save_848xx_spirom_version(phy, params);
6137 static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
6138 struct link_params *params,
6139 struct link_vars *vars)
6141 struct bnx2x *bp = params->bp;
6142 u16 val, val1, val2;
6145 /* Check 10G-BaseT link status */
6146 /* Check PMD signal ok */
6147 bnx2x_cl45_read(bp, phy,
6148 MDIO_AN_DEVAD, 0xFFFA, &val1);
6149 bnx2x_cl45_read(bp, phy,
6150 MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
6152 DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
6154 /* Check link 10G */
6155 if (val2 & (1<<11)) {
6156 vars->line_speed = SPEED_10000;
6157 vars->duplex = DUPLEX_FULL;
6159 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
6160 } else { /* Check Legacy speed link */
6161 u16 legacy_status, legacy_speed;
6163 /* Enable expansion register 0x42 (Operation mode status) */
6164 bnx2x_cl45_write(bp, phy,
6166 MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
6168 /* Get legacy speed operation status */
6169 bnx2x_cl45_read(bp, phy,
6171 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
6174 DP(NETIF_MSG_LINK, "Legacy speed status"
6175 " = 0x%x\n", legacy_status);
6176 link_up = ((legacy_status & (1<<11)) == (1<<11));
6178 legacy_speed = (legacy_status & (3<<9));
6179 if (legacy_speed == (0<<9))
6180 vars->line_speed = SPEED_10;
6181 else if (legacy_speed == (1<<9))
6182 vars->line_speed = SPEED_100;
6183 else if (legacy_speed == (2<<9))
6184 vars->line_speed = SPEED_1000;
6185 else /* Should not happen */
6186 vars->line_speed = 0;
6188 if (legacy_status & (1<<8))
6189 vars->duplex = DUPLEX_FULL;
6191 vars->duplex = DUPLEX_HALF;
6193 DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
6194 " is_duplex_full= %d\n", vars->line_speed,
6195 (vars->duplex == DUPLEX_FULL));
6196 /* Check legacy speed AN resolution */
6197 bnx2x_cl45_read(bp, phy,
6199 MDIO_AN_REG_8481_LEGACY_MII_STATUS,
6202 vars->link_status |=
6203 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6204 bnx2x_cl45_read(bp, phy,
6206 MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
6208 if ((val & (1<<0)) == 0)
6209 vars->link_status |=
6210 LINK_STATUS_PARALLEL_DETECTION_USED;
6214 DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n",
6216 bnx2x_ext_phy_resolve_fc(phy, params, vars);
6222 static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
6226 spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
6227 status = bnx2x_format_ver(spirom_ver, str, len);
6231 static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
6232 struct link_params *params)
6234 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
6235 MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
6236 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
6237 MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
6240 static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
6241 struct link_params *params)
6243 bnx2x_cl45_write(params->bp, phy,
6244 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
6245 bnx2x_cl45_write(params->bp, phy,
6246 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
6249 static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
6250 struct link_params *params)
6252 struct bnx2x *bp = params->bp;
6257 port = params->port;
6258 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
6259 MISC_REGISTERS_GPIO_OUTPUT_LOW,
6263 static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
6264 struct link_params *params, u8 mode)
6266 struct bnx2x *bp = params->bp;
6272 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", params->port);
6274 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
6275 SHARED_HW_CFG_LED_EXTPHY1) {
6278 bnx2x_cl45_write(bp, phy,
6280 MDIO_PMA_REG_8481_LED1_MASK,
6283 bnx2x_cl45_write(bp, phy,
6285 MDIO_PMA_REG_8481_LED2_MASK,
6288 bnx2x_cl45_write(bp, phy,
6290 MDIO_PMA_REG_8481_LED3_MASK,
6293 bnx2x_cl45_write(bp, phy,
6295 MDIO_PMA_REG_8481_LED5_MASK,
6299 bnx2x_cl45_write(bp, phy,
6301 MDIO_PMA_REG_8481_LED1_MASK,
6305 case LED_MODE_FRONT_PANEL_OFF:
6307 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
6310 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
6311 SHARED_HW_CFG_LED_EXTPHY1) {
6314 bnx2x_cl45_write(bp, phy,
6316 MDIO_PMA_REG_8481_LED1_MASK,
6319 bnx2x_cl45_write(bp, phy,
6321 MDIO_PMA_REG_8481_LED2_MASK,
6324 bnx2x_cl45_write(bp, phy,
6326 MDIO_PMA_REG_8481_LED3_MASK,
6329 bnx2x_cl45_write(bp, phy,
6331 MDIO_PMA_REG_8481_LED5_MASK,
6335 bnx2x_cl45_write(bp, phy,
6337 MDIO_PMA_REG_8481_LED1_MASK,
6343 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", params->port);
6345 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
6346 SHARED_HW_CFG_LED_EXTPHY1) {
6347 /* Set control reg */
6348 bnx2x_cl45_read(bp, phy,
6350 MDIO_PMA_REG_8481_LINK_SIGNAL,
6355 bnx2x_cl45_write(bp, phy,
6357 MDIO_PMA_REG_8481_LINK_SIGNAL,
6361 bnx2x_cl45_write(bp, phy,
6363 MDIO_PMA_REG_8481_LED1_MASK,
6366 bnx2x_cl45_write(bp, phy,
6368 MDIO_PMA_REG_8481_LED2_MASK,
6371 bnx2x_cl45_write(bp, phy,
6373 MDIO_PMA_REG_8481_LED3_MASK,
6376 bnx2x_cl45_write(bp, phy,
6378 MDIO_PMA_REG_8481_LED5_MASK,
6381 bnx2x_cl45_write(bp, phy,
6383 MDIO_PMA_REG_8481_LED1_MASK,
6390 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", params->port);
6392 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
6393 SHARED_HW_CFG_LED_EXTPHY1) {
6395 /* Set control reg */
6396 bnx2x_cl45_read(bp, phy,
6398 MDIO_PMA_REG_8481_LINK_SIGNAL,
6402 MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
6403 >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) {
6404 DP(NETIF_MSG_LINK, "Seting LINK_SIGNAL\n");
6405 bnx2x_cl45_write(bp, phy,
6407 MDIO_PMA_REG_8481_LINK_SIGNAL,
6412 bnx2x_cl45_write(bp, phy,
6414 MDIO_PMA_REG_8481_LED1_MASK,
6417 bnx2x_cl45_write(bp, phy,
6419 MDIO_PMA_REG_8481_LED2_MASK,
6422 bnx2x_cl45_write(bp, phy,
6424 MDIO_PMA_REG_8481_LED3_MASK,
6427 bnx2x_cl45_write(bp, phy,
6429 MDIO_PMA_REG_8481_LED5_MASK,
6433 bnx2x_cl45_write(bp, phy,
6435 MDIO_PMA_REG_8481_LED1_MASK,
6438 /* Tell LED3 to blink on source */
6439 bnx2x_cl45_read(bp, phy,
6441 MDIO_PMA_REG_8481_LINK_SIGNAL,
6444 val |= (1<<6); /* A83B[8:6]= 1 */
6445 bnx2x_cl45_write(bp, phy,
6447 MDIO_PMA_REG_8481_LINK_SIGNAL,
6453 /******************************************************************/
6454 /* SFX7101 PHY SECTION */
6455 /******************************************************************/
6456 static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
6457 struct link_params *params)
6459 struct bnx2x *bp = params->bp;
6460 /* SFX7101_XGXS_TEST1 */
6461 bnx2x_cl45_write(bp, phy,
6462 MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
6465 static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy,
6466 struct link_params *params,
6467 struct link_vars *vars)
6469 u16 fw_ver1, fw_ver2, val;
6470 struct bnx2x *bp = params->bp;
6471 DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
6473 /* Restore normal power mode*/
6474 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6475 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
6477 bnx2x_ext_phy_hw_reset(bp, params->port);
6478 bnx2x_wait_reset_complete(bp, phy);
6480 bnx2x_cl45_write(bp, phy,
6481 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1);
6482 DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
6483 bnx2x_cl45_write(bp, phy,
6484 MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
6486 bnx2x_ext_phy_set_pause(params, phy, vars);
6487 /* Restart autoneg */
6488 bnx2x_cl45_read(bp, phy,
6489 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
6491 bnx2x_cl45_write(bp, phy,
6492 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
6494 /* Save spirom version */
6495 bnx2x_cl45_read(bp, phy,
6496 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
6498 bnx2x_cl45_read(bp, phy,
6499 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
6500 bnx2x_save_spirom_version(bp, params->port,
6501 (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
6505 static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
6506 struct link_params *params,
6507 struct link_vars *vars)
6509 struct bnx2x *bp = params->bp;
6512 bnx2x_cl45_read(bp, phy,
6513 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
6514 bnx2x_cl45_read(bp, phy,
6515 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
6516 DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
6518 bnx2x_cl45_read(bp, phy,
6519 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
6520 bnx2x_cl45_read(bp, phy,
6521 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
6522 DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
6524 link_up = ((val1 & 4) == 4);
6526 * print the AN outcome of the SFX7101 PHY
6529 bnx2x_cl45_read(bp, phy,
6530 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
6532 vars->line_speed = SPEED_10000;
6533 vars->duplex = DUPLEX_FULL;
6534 DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
6535 val2, (val2 & (1<<14)));
6536 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
6537 bnx2x_ext_phy_resolve_fc(phy, params, vars);
6543 static u8 bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
6547 str[0] = (spirom_ver & 0xFF);
6548 str[1] = (spirom_ver & 0xFF00) >> 8;
6549 str[2] = (spirom_ver & 0xFF0000) >> 16;
6550 str[3] = (spirom_ver & 0xFF000000) >> 24;
6556 void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
6560 bnx2x_cl45_read(bp, phy,
6562 MDIO_PMA_REG_7101_RESET, &val);
6564 for (cnt = 0; cnt < 10; cnt++) {
6566 /* Writes a self-clearing reset */
6567 bnx2x_cl45_write(bp, phy,
6569 MDIO_PMA_REG_7101_RESET,
6571 /* Wait for clear */
6572 bnx2x_cl45_read(bp, phy,
6574 MDIO_PMA_REG_7101_RESET, &val);
6576 if ((val & (1<<15)) == 0)
6581 static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
6582 struct link_params *params) {
6583 /* Low power mode is controlled by GPIO 2 */
6584 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
6585 MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
6586 /* The PHY reset is controlled by GPIO 1 */
6587 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
6588 MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
6591 static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy,
6592 struct link_params *params, u8 mode)
6595 struct bnx2x *bp = params->bp;
6597 case LED_MODE_FRONT_PANEL_OFF:
6608 bnx2x_cl45_write(bp, phy,
6610 MDIO_PMA_REG_7107_LINK_LED_CNTL,
6614 /******************************************************************/
6615 /* STATIC PHY DECLARATION */
6616 /******************************************************************/
6618 static struct bnx2x_phy phy_null = {
6619 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
6621 .flags = FLAGS_INIT_XGXS_FIRST,
6624 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6625 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6628 .media_type = ETH_PHY_NOT_PRESENT,
6631 .req_line_speed = 0,
6632 .speed_cap_mask = 0,
6635 .config_init = (config_init_t)NULL,
6636 .read_status = (read_status_t)NULL,
6637 .link_reset = (link_reset_t)NULL,
6638 .config_loopback = (config_loopback_t)NULL,
6639 .format_fw_ver = (format_fw_ver_t)NULL,
6640 .hw_reset = (hw_reset_t)NULL,
6641 .set_link_led = (set_link_led_t)NULL,
6642 .phy_specific_func = (phy_specific_func_t)NULL
6645 static struct bnx2x_phy phy_serdes = {
6646 .type = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
6651 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6652 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6654 .supported = (SUPPORTED_10baseT_Half |
6655 SUPPORTED_10baseT_Full |
6656 SUPPORTED_100baseT_Half |
6657 SUPPORTED_100baseT_Full |
6658 SUPPORTED_1000baseT_Full |
6659 SUPPORTED_2500baseX_Full |
6663 SUPPORTED_Asym_Pause),
6664 .media_type = ETH_PHY_UNSPECIFIED,
6667 .req_line_speed = 0,
6668 .speed_cap_mask = 0,
6671 .config_init = (config_init_t)bnx2x_init_serdes,
6672 .read_status = (read_status_t)bnx2x_link_settings_status,
6673 .link_reset = (link_reset_t)bnx2x_int_link_reset,
6674 .config_loopback = (config_loopback_t)NULL,
6675 .format_fw_ver = (format_fw_ver_t)NULL,
6676 .hw_reset = (hw_reset_t)NULL,
6677 .set_link_led = (set_link_led_t)NULL,
6678 .phy_specific_func = (phy_specific_func_t)NULL
6681 static struct bnx2x_phy phy_xgxs = {
6682 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
6687 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6688 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6690 .supported = (SUPPORTED_10baseT_Half |
6691 SUPPORTED_10baseT_Full |
6692 SUPPORTED_100baseT_Half |
6693 SUPPORTED_100baseT_Full |
6694 SUPPORTED_1000baseT_Full |
6695 SUPPORTED_2500baseX_Full |
6696 SUPPORTED_10000baseT_Full |
6700 SUPPORTED_Asym_Pause),
6701 .media_type = ETH_PHY_UNSPECIFIED,
6704 .req_line_speed = 0,
6705 .speed_cap_mask = 0,
6708 .config_init = (config_init_t)bnx2x_init_xgxs,
6709 .read_status = (read_status_t)bnx2x_link_settings_status,
6710 .link_reset = (link_reset_t)bnx2x_int_link_reset,
6711 .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
6712 .format_fw_ver = (format_fw_ver_t)NULL,
6713 .hw_reset = (hw_reset_t)NULL,
6714 .set_link_led = (set_link_led_t)NULL,
6715 .phy_specific_func = (phy_specific_func_t)NULL
6718 static struct bnx2x_phy phy_7101 = {
6719 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6721 .flags = FLAGS_FAN_FAILURE_DET_REQ,
6724 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6725 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6727 .supported = (SUPPORTED_10000baseT_Full |
6731 SUPPORTED_Asym_Pause),
6732 .media_type = ETH_PHY_BASE_T,
6735 .req_line_speed = 0,
6736 .speed_cap_mask = 0,
6739 .config_init = (config_init_t)bnx2x_7101_config_init,
6740 .read_status = (read_status_t)bnx2x_7101_read_status,
6741 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
6742 .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
6743 .format_fw_ver = (format_fw_ver_t)bnx2x_7101_format_ver,
6744 .hw_reset = (hw_reset_t)bnx2x_7101_hw_reset,
6745 .set_link_led = (set_link_led_t)bnx2x_7101_set_link_led,
6746 .phy_specific_func = (phy_specific_func_t)NULL
6748 static struct bnx2x_phy phy_8073 = {
6749 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6751 .flags = FLAGS_HW_LOCK_REQUIRED,
6754 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6755 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6757 .supported = (SUPPORTED_10000baseT_Full |
6758 SUPPORTED_2500baseX_Full |
6759 SUPPORTED_1000baseT_Full |
6763 SUPPORTED_Asym_Pause),
6764 .media_type = ETH_PHY_UNSPECIFIED,
6767 .req_line_speed = 0,
6768 .speed_cap_mask = 0,
6771 .config_init = (config_init_t)bnx2x_8073_config_init,
6772 .read_status = (read_status_t)bnx2x_8073_read_status,
6773 .link_reset = (link_reset_t)bnx2x_8073_link_reset,
6774 .config_loopback = (config_loopback_t)NULL,
6775 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
6776 .hw_reset = (hw_reset_t)NULL,
6777 .set_link_led = (set_link_led_t)NULL,
6778 .phy_specific_func = (phy_specific_func_t)NULL
6780 static struct bnx2x_phy phy_8705 = {
6781 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
6783 .flags = FLAGS_INIT_XGXS_FIRST,
6786 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6787 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6789 .supported = (SUPPORTED_10000baseT_Full |
6792 SUPPORTED_Asym_Pause),
6793 .media_type = ETH_PHY_XFP_FIBER,
6796 .req_line_speed = 0,
6797 .speed_cap_mask = 0,
6800 .config_init = (config_init_t)bnx2x_8705_config_init,
6801 .read_status = (read_status_t)bnx2x_8705_read_status,
6802 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
6803 .config_loopback = (config_loopback_t)NULL,
6804 .format_fw_ver = (format_fw_ver_t)bnx2x_null_format_ver,
6805 .hw_reset = (hw_reset_t)NULL,
6806 .set_link_led = (set_link_led_t)NULL,
6807 .phy_specific_func = (phy_specific_func_t)NULL
6809 static struct bnx2x_phy phy_8706 = {
6810 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
6812 .flags = FLAGS_INIT_XGXS_FIRST,
6815 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6816 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6818 .supported = (SUPPORTED_10000baseT_Full |
6819 SUPPORTED_1000baseT_Full |
6822 SUPPORTED_Asym_Pause),
6823 .media_type = ETH_PHY_SFP_FIBER,
6826 .req_line_speed = 0,
6827 .speed_cap_mask = 0,
6830 .config_init = (config_init_t)bnx2x_8706_config_init,
6831 .read_status = (read_status_t)bnx2x_8706_read_status,
6832 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
6833 .config_loopback = (config_loopback_t)NULL,
6834 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
6835 .hw_reset = (hw_reset_t)NULL,
6836 .set_link_led = (set_link_led_t)NULL,
6837 .phy_specific_func = (phy_specific_func_t)NULL
6840 static struct bnx2x_phy phy_8726 = {
6841 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
6843 .flags = (FLAGS_HW_LOCK_REQUIRED |
6844 FLAGS_INIT_XGXS_FIRST),
6847 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6848 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6850 .supported = (SUPPORTED_10000baseT_Full |
6851 SUPPORTED_1000baseT_Full |
6855 SUPPORTED_Asym_Pause),
6856 .media_type = ETH_PHY_SFP_FIBER,
6859 .req_line_speed = 0,
6860 .speed_cap_mask = 0,
6863 .config_init = (config_init_t)bnx2x_8726_config_init,
6864 .read_status = (read_status_t)bnx2x_8726_read_status,
6865 .link_reset = (link_reset_t)bnx2x_8726_link_reset,
6866 .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
6867 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
6868 .hw_reset = (hw_reset_t)NULL,
6869 .set_link_led = (set_link_led_t)NULL,
6870 .phy_specific_func = (phy_specific_func_t)NULL
6873 static struct bnx2x_phy phy_8727 = {
6874 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6876 .flags = FLAGS_FAN_FAILURE_DET_REQ,
6879 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6880 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6882 .supported = (SUPPORTED_10000baseT_Full |
6883 SUPPORTED_1000baseT_Full |
6886 SUPPORTED_Asym_Pause),
6887 .media_type = ETH_PHY_SFP_FIBER,
6890 .req_line_speed = 0,
6891 .speed_cap_mask = 0,
6894 .config_init = (config_init_t)bnx2x_8727_config_init,
6895 .read_status = (read_status_t)bnx2x_8727_read_status,
6896 .link_reset = (link_reset_t)bnx2x_8727_link_reset,
6897 .config_loopback = (config_loopback_t)NULL,
6898 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
6899 .hw_reset = (hw_reset_t)bnx2x_8727_hw_reset,
6900 .set_link_led = (set_link_led_t)bnx2x_8727_set_link_led,
6901 .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func
6903 static struct bnx2x_phy phy_8481 = {
6904 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
6906 .flags = FLAGS_FAN_FAILURE_DET_REQ |
6907 FLAGS_REARM_LATCH_SIGNAL,
6910 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6911 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6913 .supported = (SUPPORTED_10baseT_Half |
6914 SUPPORTED_10baseT_Full |
6915 SUPPORTED_100baseT_Half |
6916 SUPPORTED_100baseT_Full |
6917 SUPPORTED_1000baseT_Full |
6918 SUPPORTED_10000baseT_Full |
6922 SUPPORTED_Asym_Pause),
6923 .media_type = ETH_PHY_BASE_T,
6926 .req_line_speed = 0,
6927 .speed_cap_mask = 0,
6930 .config_init = (config_init_t)bnx2x_8481_config_init,
6931 .read_status = (read_status_t)bnx2x_848xx_read_status,
6932 .link_reset = (link_reset_t)bnx2x_8481_link_reset,
6933 .config_loopback = (config_loopback_t)NULL,
6934 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
6935 .hw_reset = (hw_reset_t)bnx2x_8481_hw_reset,
6936 .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
6937 .phy_specific_func = (phy_specific_func_t)NULL
6940 static struct bnx2x_phy phy_84823 = {
6941 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
6943 .flags = FLAGS_FAN_FAILURE_DET_REQ |
6944 FLAGS_REARM_LATCH_SIGNAL,
6947 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6948 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6950 .supported = (SUPPORTED_10baseT_Half |
6951 SUPPORTED_10baseT_Full |
6952 SUPPORTED_100baseT_Half |
6953 SUPPORTED_100baseT_Full |
6954 SUPPORTED_1000baseT_Full |
6955 SUPPORTED_10000baseT_Full |
6959 SUPPORTED_Asym_Pause),
6960 .media_type = ETH_PHY_BASE_T,
6963 .req_line_speed = 0,
6964 .speed_cap_mask = 0,
6967 .config_init = (config_init_t)bnx2x_848x3_config_init,
6968 .read_status = (read_status_t)bnx2x_848xx_read_status,
6969 .link_reset = (link_reset_t)bnx2x_848x3_link_reset,
6970 .config_loopback = (config_loopback_t)NULL,
6971 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
6972 .hw_reset = (hw_reset_t)NULL,
6973 .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
6974 .phy_specific_func = (phy_specific_func_t)NULL
6977 /*****************************************************************/
6979 /* Populate the phy according. Main function: bnx2x_populate_phy */
6981 /*****************************************************************/
6983 static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
6984 struct bnx2x_phy *phy, u8 port,
6987 /* Get the 4 lanes xgxs config rx and tx */
6988 u32 rx = 0, tx = 0, i;
6989 for (i = 0; i < 2; i++) {
6991 * INT_PHY and EXT_PHY1 share the same value location in the
6992 * shmem. When num_phys is greater than 1, than this value
6993 * applies only to EXT_PHY1
6995 if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
6996 rx = REG_RD(bp, shmem_base +
6997 offsetof(struct shmem_region,
6998 dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
7000 tx = REG_RD(bp, shmem_base +
7001 offsetof(struct shmem_region,
7002 dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
7004 rx = REG_RD(bp, shmem_base +
7005 offsetof(struct shmem_region,
7006 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
7008 tx = REG_RD(bp, shmem_base +
7009 offsetof(struct shmem_region,
7010 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
7013 phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
7014 phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
7016 phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
7017 phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
7021 static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
7022 u8 phy_index, u8 port)
7024 u32 ext_phy_config = 0;
7025 switch (phy_index) {
7027 ext_phy_config = REG_RD(bp, shmem_base +
7028 offsetof(struct shmem_region,
7029 dev_info.port_hw_config[port].external_phy_config));
7032 ext_phy_config = REG_RD(bp, shmem_base +
7033 offsetof(struct shmem_region,
7034 dev_info.port_hw_config[port].external_phy_config2));
7037 DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
7041 return ext_phy_config;
7043 static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
7044 struct bnx2x_phy *phy)
7048 u32 switch_cfg = (REG_RD(bp, shmem_base +
7049 offsetof(struct shmem_region,
7050 dev_info.port_feature_config[port].link_config)) &
7051 PORT_FEATURE_CONNECTED_SWITCH_MASK);
7052 chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16;
7053 switch (switch_cfg) {
7055 phy_addr = REG_RD(bp,
7056 NIG_REG_SERDES0_CTRL_PHY_ADDR +
7060 case SWITCH_CFG_10G:
7061 phy_addr = REG_RD(bp,
7062 NIG_REG_XGXS0_CTRL_PHY_ADDR +
7067 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
7070 phy->addr = (u8)phy_addr;
7071 phy->mdio_ctrl = bnx2x_get_emac_base(bp,
7072 SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
7075 phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
7077 phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
7079 DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
7080 port, phy->addr, phy->mdio_ctrl);
7082 bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
7086 static u8 bnx2x_populate_ext_phy(struct bnx2x *bp,
7091 struct bnx2x_phy *phy)
7093 u32 ext_phy_config, phy_type, config2;
7094 u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
7095 ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
7097 phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
7098 /* Select the phy type */
7100 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
7101 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
7104 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
7107 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
7110 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7111 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
7114 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
7115 /* BCM8727_NOC => BCM8727 no over current */
7116 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
7118 phy->flags |= FLAGS_NOC;
7120 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7121 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
7124 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
7127 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
7130 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
7133 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
7141 phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
7142 bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
7145 * The shmem address of the phy version is located on different
7146 * structures. In case this structure is too old, do not set
7149 config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region,
7150 dev_info.shared_hw_config.config2));
7151 if (phy_index == EXT_PHY1) {
7152 phy->ver_addr = shmem_base + offsetof(struct shmem_region,
7153 port_mb[port].ext_phy_fw_version);
7155 /* Check specific mdc mdio settings */
7156 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
7157 mdc_mdio_access = config2 &
7158 SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
7160 u32 size = REG_RD(bp, shmem2_base);
7163 offsetof(struct shmem2_region, ext_phy_fw_version2)) {
7164 phy->ver_addr = shmem2_base +
7165 offsetof(struct shmem2_region,
7166 ext_phy_fw_version2[port]);
7168 /* Check specific mdc mdio settings */
7169 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
7170 mdc_mdio_access = (config2 &
7171 SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
7172 (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
7173 SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
7175 phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
7178 * In case mdc/mdio_access of the external phy is different than the
7179 * mdc/mdio access of the XGXS, a HW lock must be taken in each access
7180 * to prevent one port interfere with another port's CL45 operations.
7182 if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH)
7183 phy->flags |= FLAGS_HW_LOCK_REQUIRED;
7184 DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n",
7185 phy_type, port, phy_index);
7186 DP(NETIF_MSG_LINK, " addr=0x%x, mdio_ctl=0x%x\n",
7187 phy->addr, phy->mdio_ctrl);
7191 static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
7192 u32 shmem2_base, u8 port, struct bnx2x_phy *phy)
7195 phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
7196 if (phy_index == INT_PHY)
7197 return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
7198 status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
7203 static void bnx2x_phy_def_cfg(struct link_params *params,
7204 struct bnx2x_phy *phy,
7207 struct bnx2x *bp = params->bp;
7209 /* Populate the default phy configuration for MF mode */
7210 if (phy_index == EXT_PHY2) {
7211 link_config = REG_RD(bp, params->shmem_base +
7212 offsetof(struct shmem_region, dev_info.
7213 port_feature_config[params->port].link_config2));
7214 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
7215 offsetof(struct shmem_region,
7217 port_hw_config[params->port].speed_capability_mask2));
7219 link_config = REG_RD(bp, params->shmem_base +
7220 offsetof(struct shmem_region, dev_info.
7221 port_feature_config[params->port].link_config));
7222 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
7223 offsetof(struct shmem_region,
7225 port_hw_config[params->port].speed_capability_mask));
7227 DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask"
7228 " 0x%x\n", phy_index, link_config, phy->speed_cap_mask);
7230 phy->req_duplex = DUPLEX_FULL;
7231 switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) {
7232 case PORT_FEATURE_LINK_SPEED_10M_HALF:
7233 phy->req_duplex = DUPLEX_HALF;
7234 case PORT_FEATURE_LINK_SPEED_10M_FULL:
7235 phy->req_line_speed = SPEED_10;
7237 case PORT_FEATURE_LINK_SPEED_100M_HALF:
7238 phy->req_duplex = DUPLEX_HALF;
7239 case PORT_FEATURE_LINK_SPEED_100M_FULL:
7240 phy->req_line_speed = SPEED_100;
7242 case PORT_FEATURE_LINK_SPEED_1G:
7243 phy->req_line_speed = SPEED_1000;
7245 case PORT_FEATURE_LINK_SPEED_2_5G:
7246 phy->req_line_speed = SPEED_2500;
7248 case PORT_FEATURE_LINK_SPEED_10G_CX4:
7249 phy->req_line_speed = SPEED_10000;
7252 phy->req_line_speed = SPEED_AUTO_NEG;
7256 switch (link_config & PORT_FEATURE_FLOW_CONTROL_MASK) {
7257 case PORT_FEATURE_FLOW_CONTROL_AUTO:
7258 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
7260 case PORT_FEATURE_FLOW_CONTROL_TX:
7261 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
7263 case PORT_FEATURE_FLOW_CONTROL_RX:
7264 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
7266 case PORT_FEATURE_FLOW_CONTROL_BOTH:
7267 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
7270 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7275 u32 bnx2x_phy_selection(struct link_params *params)
7277 u32 phy_config_swapped, prio_cfg;
7278 u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
7280 phy_config_swapped = params->multi_phy_config &
7281 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
7283 prio_cfg = params->multi_phy_config &
7284 PORT_HW_CFG_PHY_SELECTION_MASK;
7286 if (phy_config_swapped) {
7288 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
7289 return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
7291 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
7292 return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
7294 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
7295 return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
7297 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
7298 return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
7302 return_cfg = prio_cfg;
7308 u8 bnx2x_phy_probe(struct link_params *params)
7310 u8 phy_index, actual_phy_idx, link_cfg_idx;
7311 u32 phy_config_swapped;
7312 struct bnx2x *bp = params->bp;
7313 struct bnx2x_phy *phy;
7314 params->num_phys = 0;
7315 DP(NETIF_MSG_LINK, "Begin phy probe\n");
7316 phy_config_swapped = params->multi_phy_config &
7317 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
7319 for (phy_index = INT_PHY; phy_index < MAX_PHYS;
7321 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
7322 actual_phy_idx = phy_index;
7323 if (phy_config_swapped) {
7324 if (phy_index == EXT_PHY1)
7325 actual_phy_idx = EXT_PHY2;
7326 else if (phy_index == EXT_PHY2)
7327 actual_phy_idx = EXT_PHY1;
7329 DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x,"
7330 " actual_phy_idx %x\n", phy_config_swapped,
7331 phy_index, actual_phy_idx);
7332 phy = ¶ms->phy[actual_phy_idx];
7333 if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
7334 params->shmem2_base, params->port,
7336 params->num_phys = 0;
7337 DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
7339 for (phy_index = INT_PHY;
7340 phy_index < MAX_PHYS;
7345 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
7348 bnx2x_phy_def_cfg(params, phy, phy_index);
7352 DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
7356 static void set_phy_vars(struct link_params *params)
7358 struct bnx2x *bp = params->bp;
7359 u8 actual_phy_idx, phy_index, link_cfg_idx;
7360 u8 phy_config_swapped = params->multi_phy_config &
7361 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
7362 for (phy_index = INT_PHY; phy_index < params->num_phys;
7364 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
7365 actual_phy_idx = phy_index;
7366 if (phy_config_swapped) {
7367 if (phy_index == EXT_PHY1)
7368 actual_phy_idx = EXT_PHY2;
7369 else if (phy_index == EXT_PHY2)
7370 actual_phy_idx = EXT_PHY1;
7372 params->phy[actual_phy_idx].req_flow_ctrl =
7373 params->req_flow_ctrl[link_cfg_idx];
7375 params->phy[actual_phy_idx].req_line_speed =
7376 params->req_line_speed[link_cfg_idx];
7378 params->phy[actual_phy_idx].speed_cap_mask =
7379 params->speed_cap_mask[link_cfg_idx];
7381 params->phy[actual_phy_idx].req_duplex =
7382 params->req_duplex[link_cfg_idx];
7384 DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
7385 " speed_cap_mask %x\n",
7386 params->phy[actual_phy_idx].req_flow_ctrl,
7387 params->phy[actual_phy_idx].req_line_speed,
7388 params->phy[actual_phy_idx].speed_cap_mask);
7392 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
7394 struct bnx2x *bp = params->bp;
7395 DP(NETIF_MSG_LINK, "Phy Initialization started\n");
7396 DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n",
7397 params->req_line_speed[0], params->req_flow_ctrl[0]);
7398 DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n",
7399 params->req_line_speed[1], params->req_flow_ctrl[1]);
7400 vars->link_status = 0;
7401 vars->phy_link_up = 0;
7403 vars->line_speed = 0;
7404 vars->duplex = DUPLEX_FULL;
7405 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7406 vars->mac_type = MAC_TYPE_NONE;
7407 vars->phy_flags = 0;
7409 /* disable attentions */
7410 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
7411 (NIG_MASK_XGXS0_LINK_STATUS |
7412 NIG_MASK_XGXS0_LINK10G |
7413 NIG_MASK_SERDES0_LINK_STATUS |
7416 bnx2x_emac_init(params, vars);
7418 if (params->num_phys == 0) {
7419 DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
7422 set_phy_vars(params);
7424 DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
7425 if (CHIP_REV_IS_FPGA(bp)) {
7428 vars->line_speed = SPEED_10000;
7429 vars->duplex = DUPLEX_FULL;
7430 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7431 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
7432 /* enable on E1.5 FPGA */
7433 if (CHIP_IS_E1H(bp)) {
7435 (BNX2X_FLOW_CTRL_TX |
7436 BNX2X_FLOW_CTRL_RX);
7437 vars->link_status |=
7438 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
7439 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
7442 bnx2x_emac_enable(params, vars, 0);
7443 if (!(CHIP_IS_E2(bp)))
7444 bnx2x_pbf_update(params, vars->flow_ctrl,
7447 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
7449 /* update shared memory */
7450 bnx2x_update_mng(params, vars->link_status);
7455 if (CHIP_REV_IS_EMUL(bp)) {
7458 vars->line_speed = SPEED_10000;
7459 vars->duplex = DUPLEX_FULL;
7460 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7461 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
7463 bnx2x_bmac_enable(params, vars, 0);
7465 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
7467 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
7468 + params->port*4, 0);
7470 /* update shared memory */
7471 bnx2x_update_mng(params, vars->link_status);
7476 if (params->loopback_mode == LOOPBACK_BMAC) {
7479 vars->line_speed = SPEED_10000;
7480 vars->duplex = DUPLEX_FULL;
7481 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7482 vars->mac_type = MAC_TYPE_BMAC;
7484 vars->phy_flags = PHY_XGXS_FLAG;
7486 bnx2x_xgxs_deassert(params);
7488 /* set bmac loopback */
7489 bnx2x_bmac_enable(params, vars, 1);
7491 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
7493 } else if (params->loopback_mode == LOOPBACK_EMAC) {
7496 vars->line_speed = SPEED_1000;
7497 vars->duplex = DUPLEX_FULL;
7498 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7499 vars->mac_type = MAC_TYPE_EMAC;
7501 vars->phy_flags = PHY_XGXS_FLAG;
7503 bnx2x_xgxs_deassert(params);
7504 /* set bmac loopback */
7505 bnx2x_emac_enable(params, vars, 1);
7506 bnx2x_emac_program(params, vars);
7507 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
7509 } else if ((params->loopback_mode == LOOPBACK_XGXS) ||
7510 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
7513 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7514 vars->duplex = DUPLEX_FULL;
7515 if (params->req_line_speed[0] == SPEED_1000) {
7516 vars->line_speed = SPEED_1000;
7517 vars->mac_type = MAC_TYPE_EMAC;
7519 vars->line_speed = SPEED_10000;
7520 vars->mac_type = MAC_TYPE_BMAC;
7523 bnx2x_xgxs_deassert(params);
7524 bnx2x_link_initialize(params, vars);
7526 if (params->req_line_speed[0] == SPEED_1000) {
7527 bnx2x_emac_program(params, vars);
7528 bnx2x_emac_enable(params, vars, 0);
7530 bnx2x_bmac_enable(params, vars, 0);
7531 if (params->loopback_mode == LOOPBACK_XGXS) {
7532 /* set 10G XGXS loopback */
7533 params->phy[INT_PHY].config_loopback(
7534 ¶ms->phy[INT_PHY],
7538 /* set external phy loopback */
7540 for (phy_index = EXT_PHY1;
7541 phy_index < params->num_phys; phy_index++) {
7542 if (params->phy[phy_index].config_loopback)
7543 params->phy[phy_index].config_loopback(
7544 ¶ms->phy[phy_index],
7548 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
7550 bnx2x_set_led(params, vars,
7551 LED_MODE_OPER, vars->line_speed);
7555 if (params->switch_cfg == SWITCH_CFG_10G)
7556 bnx2x_xgxs_deassert(params);
7558 bnx2x_serdes_deassert(bp, params->port);
7560 bnx2x_link_initialize(params, vars);
7562 bnx2x_link_int_enable(params);
7566 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
7569 struct bnx2x *bp = params->bp;
7570 u8 phy_index, port = params->port, clear_latch_ind = 0;
7571 DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
7572 /* disable attentions */
7573 vars->link_status = 0;
7574 bnx2x_update_mng(params, vars->link_status);
7575 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
7576 (NIG_MASK_XGXS0_LINK_STATUS |
7577 NIG_MASK_XGXS0_LINK10G |
7578 NIG_MASK_SERDES0_LINK_STATUS |
7581 /* activate nig drain */
7582 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
7584 /* disable nig egress interface */
7585 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
7586 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
7588 /* Stop BigMac rx */
7589 bnx2x_bmac_rx_disable(bp, port);
7592 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
7595 /* The PHY reset is controled by GPIO 1
7596 * Hold it as vars low
7598 /* clear link led */
7599 bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
7601 if (reset_ext_phy) {
7602 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
7604 if (params->phy[phy_index].link_reset)
7605 params->phy[phy_index].link_reset(
7606 ¶ms->phy[phy_index],
7608 if (params->phy[phy_index].flags &
7609 FLAGS_REARM_LATCH_SIGNAL)
7610 clear_latch_ind = 1;
7614 if (clear_latch_ind) {
7615 /* Clear latching indication */
7616 bnx2x_rearm_latch_signal(bp, port, 0);
7617 bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4,
7618 1 << NIG_LATCH_BC_ENABLE_MI_INT);
7620 if (params->phy[INT_PHY].link_reset)
7621 params->phy[INT_PHY].link_reset(
7622 ¶ms->phy[INT_PHY], params);
7624 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
7625 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
7627 /* disable nig ingress interface */
7628 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
7629 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
7630 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
7631 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
7636 /****************************************************************************/
7637 /* Common function */
7638 /****************************************************************************/
7639 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp,
7640 u32 shmem_base_path[],
7641 u32 shmem2_base_path[], u8 phy_index,
7644 struct bnx2x_phy phy[PORT_MAX];
7645 struct bnx2x_phy *phy_blk[PORT_MAX];
7648 s8 port_of_path = 0;
7649 u32 swap_val, swap_override;
7650 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
7651 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
7652 port ^= (swap_val && swap_override);
7653 bnx2x_ext_phy_hw_reset(bp, port);
7654 /* PART1 - Reset both phys */
7655 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7656 u32 shmem_base, shmem2_base;
7657 /* In E2, same phy is using for port0 of the two paths */
7658 if (CHIP_IS_E2(bp)) {
7659 shmem_base = shmem_base_path[port];
7660 shmem2_base = shmem2_base_path[port];
7663 shmem_base = shmem_base_path[0];
7664 shmem2_base = shmem2_base_path[0];
7665 port_of_path = port;
7668 /* Extract the ext phy address for the port */
7669 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7670 port_of_path, &phy[port]) !=
7672 DP(NETIF_MSG_LINK, "populate_phy failed\n");
7675 /* disable attentions */
7676 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
7678 (NIG_MASK_XGXS0_LINK_STATUS |
7679 NIG_MASK_XGXS0_LINK10G |
7680 NIG_MASK_SERDES0_LINK_STATUS |
7683 /* Need to take the phy out of low power mode in order
7684 to write to access its registers */
7685 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7686 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
7690 bnx2x_cl45_write(bp, &phy[port],
7696 /* Add delay of 150ms after reset */
7699 if (phy[PORT_0].addr & 0x1) {
7700 phy_blk[PORT_0] = &(phy[PORT_1]);
7701 phy_blk[PORT_1] = &(phy[PORT_0]);
7703 phy_blk[PORT_0] = &(phy[PORT_0]);
7704 phy_blk[PORT_1] = &(phy[PORT_1]);
7707 /* PART2 - Download firmware to both phys */
7708 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7712 port_of_path = port;
7714 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
7715 phy_blk[port]->addr);
7716 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
7720 /* Only set bit 10 = 1 (Tx power down) */
7721 bnx2x_cl45_read(bp, phy_blk[port],
7723 MDIO_PMA_REG_TX_POWER_DOWN, &val);
7725 /* Phase1 of TX_POWER_DOWN reset */
7726 bnx2x_cl45_write(bp, phy_blk[port],
7728 MDIO_PMA_REG_TX_POWER_DOWN,
7732 /* Toggle Transmitter: Power down and then up with 600ms
7736 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
7737 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7738 /* Phase2 of POWER_DOWN_RESET */
7739 /* Release bit 10 (Release Tx power down) */
7740 bnx2x_cl45_read(bp, phy_blk[port],
7742 MDIO_PMA_REG_TX_POWER_DOWN, &val);
7744 bnx2x_cl45_write(bp, phy_blk[port],
7746 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
7749 /* Read modify write the SPI-ROM version select register */
7750 bnx2x_cl45_read(bp, phy_blk[port],
7752 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
7753 bnx2x_cl45_write(bp, phy_blk[port],
7755 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
7757 /* set GPIO2 back to LOW */
7758 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7759 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
7763 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp,
7764 u32 shmem_base_path[],
7765 u32 shmem2_base_path[], u8 phy_index,
7770 struct bnx2x_phy phy;
7771 /* Use port1 because of the static port-swap */
7772 /* Enable the module detection interrupt */
7773 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
7774 val |= ((1<<MISC_REGISTERS_GPIO_3)|
7775 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
7776 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
7778 bnx2x_ext_phy_hw_reset(bp, 0);
7780 for (port = 0; port < PORT_MAX; port++) {
7781 u32 shmem_base, shmem2_base;
7783 /* In E2, same phy is using for port0 of the two paths */
7784 if (CHIP_IS_E2(bp)) {
7785 shmem_base = shmem_base_path[port];
7786 shmem2_base = shmem2_base_path[port];
7788 shmem_base = shmem_base_path[0];
7789 shmem2_base = shmem2_base_path[0];
7791 /* Extract the ext phy address for the port */
7792 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7795 DP(NETIF_MSG_LINK, "populate phy failed\n");
7800 bnx2x_cl45_write(bp, &phy,
7801 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
7804 /* Set fault module detected LED on */
7805 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
7806 MISC_REGISTERS_GPIO_HIGH,
7812 static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp,
7813 u32 shmem_base_path[],
7814 u32 shmem2_base_path[], u8 phy_index,
7818 u32 swap_val, swap_override;
7819 struct bnx2x_phy phy[PORT_MAX];
7820 struct bnx2x_phy *phy_blk[PORT_MAX];
7822 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
7823 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
7827 bnx2x_ext_phy_hw_reset(bp, port ^ (swap_val && swap_override));
7829 /* Calculate the port based on port swap */
7830 port ^= (swap_val && swap_override);
7834 /* PART1 - Reset both phys */
7835 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7836 u32 shmem_base, shmem2_base;
7838 /* In E2, same phy is using for port0 of the two paths */
7839 if (CHIP_IS_E2(bp)) {
7840 shmem_base = shmem_base_path[port];
7841 shmem2_base = shmem2_base_path[port];
7844 shmem_base = shmem_base_path[0];
7845 shmem2_base = shmem2_base_path[0];
7846 port_of_path = port;
7849 /* Extract the ext phy address for the port */
7850 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7851 port_of_path, &phy[port]) !=
7853 DP(NETIF_MSG_LINK, "populate phy failed\n");
7856 /* disable attentions */
7857 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
7859 (NIG_MASK_XGXS0_LINK_STATUS |
7860 NIG_MASK_XGXS0_LINK10G |
7861 NIG_MASK_SERDES0_LINK_STATUS |
7866 bnx2x_cl45_write(bp, &phy[port],
7867 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
7870 /* Add delay of 150ms after reset */
7872 if (phy[PORT_0].addr & 0x1) {
7873 phy_blk[PORT_0] = &(phy[PORT_1]);
7874 phy_blk[PORT_1] = &(phy[PORT_0]);
7876 phy_blk[PORT_0] = &(phy[PORT_0]);
7877 phy_blk[PORT_1] = &(phy[PORT_1]);
7879 /* PART2 - Download firmware to both phys */
7880 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7884 port_of_path = port;
7885 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
7886 phy_blk[port]->addr);
7887 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
7895 static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
7896 u32 shmem2_base_path[], u8 phy_index,
7897 u32 ext_phy_type, u32 chip_id)
7901 switch (ext_phy_type) {
7902 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
7903 rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
7905 phy_index, chip_id);
7908 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7909 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
7910 rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
7912 phy_index, chip_id);
7915 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7916 /* GPIO1 affects both ports, so there's need to pull
7917 it for single port alone */
7918 rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
7920 phy_index, chip_id);
7922 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
7927 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
7935 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
7936 u32 shmem2_base_path[], u32 chip_id)
7941 u32 ext_phy_type, ext_phy_config;
7942 DP(NETIF_MSG_LINK, "Begin common phy init\n");
7944 if (CHIP_REV_IS_EMUL(bp))
7947 /* Check if common init was already done */
7948 phy_ver = REG_RD(bp, shmem_base_path[0] +
7949 offsetof(struct shmem_region,
7950 port_mb[PORT_0].ext_phy_fw_version));
7952 DP(NETIF_MSG_LINK, "Not doing common init; phy ver is 0x%x\n",
7957 /* Read the ext_phy_type for arbitrary port(0) */
7958 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
7960 ext_phy_config = bnx2x_get_ext_phy_config(bp,
7963 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
7964 rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
7966 phy_index, ext_phy_type,
7972 u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
7975 struct bnx2x_phy phy;
7976 for (phy_index = INT_PHY; phy_index < MAX_PHYS;
7978 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7980 DP(NETIF_MSG_LINK, "populate phy failed\n");
7984 if (phy.flags & FLAGS_HW_LOCK_REQUIRED)
7990 u8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
7995 u8 phy_index, fan_failure_det_req = 0;
7996 struct bnx2x_phy phy;
7997 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
7999 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
8002 DP(NETIF_MSG_LINK, "populate phy failed\n");
8005 fan_failure_det_req |= (phy.flags &
8006 FLAGS_FAN_FAILURE_DET_REQ);
8008 return fan_failure_det_req;
8011 void bnx2x_hw_reset_phy(struct link_params *params)
8014 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
8016 if (params->phy[phy_index].hw_reset) {
8017 params->phy[phy_index].hw_reset(
8018 ¶ms->phy[phy_index],
8020 params->phy[phy_index] = phy_null;