1 /* Copyright 2008-2009 Broadcom Corporation
3 * Unless you and Broadcom execute a separate written software license
4 * agreement governing use of this software, this software is licensed to you
5 * under the terms of the GNU General Public License version 2, available
6 * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
8 * Notwithstanding the above, under no circumstances may you combine this
9 * software in any way with any other Broadcom software provided under a
10 * license other than the GPL, without Broadcom's express prior written
13 * Written by Yaniv Rosner
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/pci.h>
22 #include <linux/netdevice.h>
23 #include <linux/delay.h>
24 #include <linux/ethtool.h>
25 #include <linux/mutex.h>
29 /********************************************************/
31 #define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
32 #define ETH_MIN_PACKET_SIZE 60
33 #define ETH_MAX_PACKET_SIZE 1500
34 #define ETH_MAX_JUMBO_PACKET_SIZE 9600
35 #define MDIO_ACCESS_TIMEOUT 1000
36 #define BMAC_CONTROL_RX_ENABLE 2
38 /***********************************************************/
39 /* Shortcut definitions */
40 /***********************************************************/
42 #define NIG_LATCH_BC_ENABLE_MI_INT 0
44 #define NIG_STATUS_EMAC0_MI_INT \
45 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
46 #define NIG_STATUS_XGXS0_LINK10G \
47 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
48 #define NIG_STATUS_XGXS0_LINK_STATUS \
49 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
50 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
51 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
52 #define NIG_STATUS_SERDES0_LINK_STATUS \
53 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
54 #define NIG_MASK_MI_INT \
55 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
56 #define NIG_MASK_XGXS0_LINK10G \
57 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
58 #define NIG_MASK_XGXS0_LINK_STATUS \
59 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
60 #define NIG_MASK_SERDES0_LINK_STATUS \
61 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
63 #define MDIO_AN_CL73_OR_37_COMPLETE \
64 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
65 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
67 #define XGXS_RESET_BITS \
68 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
69 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
70 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
71 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
72 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
74 #define SERDES_RESET_BITS \
75 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
76 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
77 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
78 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
80 #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
81 #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
82 #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
83 #define AUTONEG_PARALLEL \
84 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
85 #define AUTONEG_SGMII_FIBER_AUTODET \
86 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
87 #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
89 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
90 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
91 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
92 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
93 #define GP_STATUS_SPEED_MASK \
94 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
95 #define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
96 #define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
97 #define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
98 #define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
99 #define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
100 #define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
101 #define GP_STATUS_10G_HIG \
102 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
103 #define GP_STATUS_10G_CX4 \
104 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
105 #define GP_STATUS_12G_HIG \
106 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
107 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
108 #define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
109 #define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
110 #define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
111 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
112 #define GP_STATUS_10G_KX4 \
113 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
115 #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
116 #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
117 #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
118 #define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
119 #define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
120 #define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
121 #define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
122 #define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
123 #define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
124 #define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
125 #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
126 #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
127 #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
128 #define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
129 #define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
130 #define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
131 #define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
132 #define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
133 #define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
134 #define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
135 #define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
136 #define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
137 #define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
139 #define PHY_XGXS_FLAG 0x1
140 #define PHY_SGMII_FLAG 0x2
141 #define PHY_SERDES_FLAG 0x4
144 #define SFP_EEPROM_CON_TYPE_ADDR 0x2
145 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
146 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
149 #define SFP_EEPROM_COMP_CODE_ADDR 0x3
150 #define SFP_EEPROM_COMP_CODE_SR_MASK (1<<4)
151 #define SFP_EEPROM_COMP_CODE_LR_MASK (1<<5)
152 #define SFP_EEPROM_COMP_CODE_LRM_MASK (1<<6)
154 #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
155 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
156 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
158 #define SFP_EEPROM_OPTIONS_ADDR 0x40
159 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
160 #define SFP_EEPROM_OPTIONS_SIZE 2
162 #define EDC_MODE_LINEAR 0x0022
163 #define EDC_MODE_LIMITING 0x0044
164 #define EDC_MODE_PASSIVE_DAC 0x0055
168 /**********************************************************/
170 /**********************************************************/
171 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
172 bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
173 DEFAULT_PHY_DEV_ADDR, \
174 (_bank + (_addr & 0xf)), \
177 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
178 bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
179 DEFAULT_PHY_DEV_ADDR, \
180 (_bank + (_addr & 0xf)), \
183 static void bnx2x_set_serdes_access(struct link_params
*params
)
185 struct bnx2x
*bp
= params
->bp
;
186 u32 emac_base
= (params
->port
) ? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
189 REG_WR(bp
, NIG_REG_SERDES0_CTRL_MD_ST
+ params
->port
*0x10, 1);
190 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_MDIO_COMM
, 0x245f8000);
192 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_MDIO_COMM
, 0x245d000f);
195 REG_WR(bp
, NIG_REG_SERDES0_CTRL_MD_ST
+ params
->port
*0x10, 0);
197 static void bnx2x_set_phy_mdio(struct link_params
*params
, u8 phy_flags
)
199 struct bnx2x
*bp
= params
->bp
;
201 if (phy_flags
& PHY_XGXS_FLAG
) {
202 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_ST
+
203 params
->port
*0x18, 0);
204 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_DEVAD
+ params
->port
*0x18,
205 DEFAULT_PHY_DEV_ADDR
);
207 bnx2x_set_serdes_access(params
);
209 REG_WR(bp
, NIG_REG_SERDES0_CTRL_MD_DEVAD
+
211 DEFAULT_PHY_DEV_ADDR
);
215 static u32
bnx2x_bits_en(struct bnx2x
*bp
, u32 reg
, u32 bits
)
217 u32 val
= REG_RD(bp
, reg
);
220 REG_WR(bp
, reg
, val
);
224 static u32
bnx2x_bits_dis(struct bnx2x
*bp
, u32 reg
, u32 bits
)
226 u32 val
= REG_RD(bp
, reg
);
229 REG_WR(bp
, reg
, val
);
233 static void bnx2x_emac_init(struct link_params
*params
,
234 struct link_vars
*vars
)
236 /* reset and unreset the emac core */
237 struct bnx2x
*bp
= params
->bp
;
238 u8 port
= params
->port
;
239 u32 emac_base
= port
? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
243 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
244 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE
<< port
));
246 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
247 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE
<< port
));
249 /* init emac - use read-modify-write */
250 /* self clear reset */
251 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
252 EMAC_WR(bp
, EMAC_REG_EMAC_MODE
, (val
| EMAC_MODE_RESET
));
256 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
257 DP(NETIF_MSG_LINK
, "EMAC reset reg is %u\n", val
);
259 DP(NETIF_MSG_LINK
, "EMAC timeout!\n");
263 } while (val
& EMAC_MODE_RESET
);
265 /* Set mac address */
266 val
= ((params
->mac_addr
[0] << 8) |
267 params
->mac_addr
[1]);
268 EMAC_WR(bp
, EMAC_REG_EMAC_MAC_MATCH
, val
);
270 val
= ((params
->mac_addr
[2] << 24) |
271 (params
->mac_addr
[3] << 16) |
272 (params
->mac_addr
[4] << 8) |
273 params
->mac_addr
[5]);
274 EMAC_WR(bp
, EMAC_REG_EMAC_MAC_MATCH
+ 4, val
);
277 static u8
bnx2x_emac_enable(struct link_params
*params
,
278 struct link_vars
*vars
, u8 lb
)
280 struct bnx2x
*bp
= params
->bp
;
281 u8 port
= params
->port
;
282 u32 emac_base
= port
? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
285 DP(NETIF_MSG_LINK
, "enabling EMAC\n");
287 /* enable emac and not bmac */
288 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_PORT
+ port
*4, 1);
291 if (CHIP_REV_IS_EMUL(bp
)) {
292 /* Use lane 1 (of lanes 0-3) */
293 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+ port
*4, 1);
294 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+
300 if (CHIP_REV_IS_FPGA(bp
)) {
301 /* Use lane 1 (of lanes 0-3) */
302 DP(NETIF_MSG_LINK
, "bnx2x_emac_enable: Setting FPGA\n");
304 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+ port
*4, 1);
305 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+ port
*4,
309 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
310 u32 ser_lane
= ((params
->lane_config
&
311 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
312 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
314 DP(NETIF_MSG_LINK
, "XGXS\n");
315 /* select the master lanes (out of 0-3) */
316 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+
319 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+
322 } else { /* SerDes */
323 DP(NETIF_MSG_LINK
, "SerDes\n");
325 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+
329 bnx2x_bits_en(bp
, emac_base
+ EMAC_REG_EMAC_RX_MODE
,
331 bnx2x_bits_en(bp
, emac_base
+ EMAC_REG_EMAC_TX_MODE
,
334 if (CHIP_REV_IS_SLOW(bp
)) {
335 /* config GMII mode */
336 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
337 EMAC_WR(bp
, EMAC_REG_EMAC_MODE
,
338 (val
| EMAC_MODE_PORT_GMII
));
340 /* pause enable/disable */
341 bnx2x_bits_dis(bp
, emac_base
+ EMAC_REG_EMAC_RX_MODE
,
342 EMAC_RX_MODE_FLOW_EN
);
343 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_RX
)
344 bnx2x_bits_en(bp
, emac_base
+
345 EMAC_REG_EMAC_RX_MODE
,
346 EMAC_RX_MODE_FLOW_EN
);
348 bnx2x_bits_dis(bp
, emac_base
+ EMAC_REG_EMAC_TX_MODE
,
349 (EMAC_TX_MODE_EXT_PAUSE_EN
|
350 EMAC_TX_MODE_FLOW_EN
));
351 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
)
352 bnx2x_bits_en(bp
, emac_base
+
353 EMAC_REG_EMAC_TX_MODE
,
354 (EMAC_TX_MODE_EXT_PAUSE_EN
|
355 EMAC_TX_MODE_FLOW_EN
));
358 /* KEEP_VLAN_TAG, promiscuous */
359 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_RX_MODE
);
360 val
|= EMAC_RX_MODE_KEEP_VLAN_TAG
| EMAC_RX_MODE_PROMISCUOUS
;
361 EMAC_WR(bp
, EMAC_REG_EMAC_RX_MODE
, val
);
364 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
369 EMAC_WR(bp
, EMAC_REG_EMAC_MODE
, val
);
372 REG_WR(bp
, NIG_REG_NIG_EMAC0_EN
+ port
*4, 1);
374 /* enable emac for jumbo packets */
375 EMAC_WR(bp
, EMAC_REG_EMAC_RX_MTU_SIZE
,
376 (EMAC_RX_MTU_SIZE_JUMBO_ENA
|
377 (ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
)));
380 REG_WR(bp
, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC
+ port
*4, 0x1);
382 /* disable the NIG in/out to the bmac */
383 REG_WR(bp
, NIG_REG_BMAC0_IN_EN
+ port
*4, 0x0);
384 REG_WR(bp
, NIG_REG_BMAC0_PAUSE_OUT_EN
+ port
*4, 0x0);
385 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0x0);
387 /* enable the NIG in/out to the emac */
388 REG_WR(bp
, NIG_REG_EMAC0_IN_EN
+ port
*4, 0x1);
390 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
)
393 REG_WR(bp
, NIG_REG_EMAC0_PAUSE_OUT_EN
+ port
*4, val
);
394 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0x1);
396 if (CHIP_REV_IS_EMUL(bp
)) {
397 /* take the BigMac out of reset */
399 GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
400 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
402 /* enable access for bmac registers */
403 REG_WR(bp
, NIG_REG_BMAC0_REGS_OUT_EN
+ port
*4, 0x1);
405 REG_WR(bp
, NIG_REG_BMAC0_REGS_OUT_EN
+ port
*4, 0x0);
407 vars
->mac_type
= MAC_TYPE_EMAC
;
413 static u8
bnx2x_bmac_enable(struct link_params
*params
, struct link_vars
*vars
,
416 struct bnx2x
*bp
= params
->bp
;
417 u8 port
= params
->port
;
418 u32 bmac_addr
= port
? NIG_REG_INGRESS_BMAC1_MEM
:
419 NIG_REG_INGRESS_BMAC0_MEM
;
423 DP(NETIF_MSG_LINK
, "Enabling BigMAC\n");
424 /* reset and unreset the BigMac */
425 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
426 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
429 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
430 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
432 /* enable access for bmac registers */
433 REG_WR(bp
, NIG_REG_BMAC0_REGS_OUT_EN
+ port
*4, 0x1);
438 REG_WR_DMAE(bp
, bmac_addr
+
439 BIGMAC_REGISTER_BMAC_XGXS_CONTROL
,
443 wb_data
[0] = ((params
->mac_addr
[2] << 24) |
444 (params
->mac_addr
[3] << 16) |
445 (params
->mac_addr
[4] << 8) |
446 params
->mac_addr
[5]);
447 wb_data
[1] = ((params
->mac_addr
[0] << 8) |
448 params
->mac_addr
[1]);
449 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_TX_SOURCE_ADDR
,
454 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
)
458 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_TX_CONTROL
,
465 DP(NETIF_MSG_LINK
, "enable bmac loopback\n");
469 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_BMAC_CONTROL
,
473 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
475 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_RX_MAX_SIZE
,
478 /* rx control set to don't strip crc */
480 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_RX
)
484 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_RX_CONTROL
,
488 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
490 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_TX_MAX_SIZE
,
493 /* set cnt max size */
494 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
496 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_CNT_MAX_SIZE
,
500 wb_data
[0] = 0x1000200;
502 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_RX_LLFC_MSG_FLDS
,
504 /* fix for emulation */
505 if (CHIP_REV_IS_EMUL(bp
)) {
509 bmac_addr
+ BIGMAC_REGISTER_TX_PAUSE_THRESHOLD
,
513 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+ port
*4, 0x1);
514 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+ port
*4, 0x0);
515 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_PORT
+ port
*4, 0x0);
517 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
)
519 REG_WR(bp
, NIG_REG_BMAC0_PAUSE_OUT_EN
+ port
*4, val
);
520 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0x0);
521 REG_WR(bp
, NIG_REG_EMAC0_IN_EN
+ port
*4, 0x0);
522 REG_WR(bp
, NIG_REG_EMAC0_PAUSE_OUT_EN
+ port
*4, 0x0);
523 REG_WR(bp
, NIG_REG_BMAC0_IN_EN
+ port
*4, 0x1);
524 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0x1);
526 vars
->mac_type
= MAC_TYPE_BMAC
;
530 static void bnx2x_phy_deassert(struct link_params
*params
, u8 phy_flags
)
532 struct bnx2x
*bp
= params
->bp
;
535 if (phy_flags
& PHY_XGXS_FLAG
) {
536 DP(NETIF_MSG_LINK
, "bnx2x_phy_deassert:XGXS\n");
537 val
= XGXS_RESET_BITS
;
539 } else { /* SerDes */
540 DP(NETIF_MSG_LINK
, "bnx2x_phy_deassert:SerDes\n");
541 val
= SERDES_RESET_BITS
;
544 val
= val
<< (params
->port
*16);
546 /* reset and unreset the SerDes/XGXS */
547 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_CLEAR
,
550 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_SET
,
552 bnx2x_set_phy_mdio(params
, phy_flags
);
555 void bnx2x_link_status_update(struct link_params
*params
,
556 struct link_vars
*vars
)
558 struct bnx2x
*bp
= params
->bp
;
560 u8 port
= params
->port
;
562 if (params
->switch_cfg
== SWITCH_CFG_1G
)
563 vars
->phy_flags
= PHY_SERDES_FLAG
;
565 vars
->phy_flags
= PHY_XGXS_FLAG
;
566 vars
->link_status
= REG_RD(bp
, params
->shmem_base
+
567 offsetof(struct shmem_region
,
568 port_mb
[port
].link_status
));
570 vars
->link_up
= (vars
->link_status
& LINK_STATUS_LINK_UP
);
573 DP(NETIF_MSG_LINK
, "phy link up\n");
575 vars
->phy_link_up
= 1;
576 vars
->duplex
= DUPLEX_FULL
;
577 switch (vars
->link_status
&
578 LINK_STATUS_SPEED_AND_DUPLEX_MASK
) {
580 vars
->duplex
= DUPLEX_HALF
;
583 vars
->line_speed
= SPEED_10
;
587 vars
->duplex
= DUPLEX_HALF
;
591 vars
->line_speed
= SPEED_100
;
595 vars
->duplex
= DUPLEX_HALF
;
598 vars
->line_speed
= SPEED_1000
;
602 vars
->duplex
= DUPLEX_HALF
;
605 vars
->line_speed
= SPEED_2500
;
609 vars
->line_speed
= SPEED_10000
;
613 vars
->line_speed
= SPEED_12000
;
617 vars
->line_speed
= SPEED_12500
;
621 vars
->line_speed
= SPEED_13000
;
625 vars
->line_speed
= SPEED_15000
;
629 vars
->line_speed
= SPEED_16000
;
636 if (vars
->link_status
& LINK_STATUS_TX_FLOW_CONTROL_ENABLED
)
637 vars
->flow_ctrl
|= BNX2X_FLOW_CTRL_TX
;
639 vars
->flow_ctrl
&= ~BNX2X_FLOW_CTRL_TX
;
641 if (vars
->link_status
& LINK_STATUS_RX_FLOW_CONTROL_ENABLED
)
642 vars
->flow_ctrl
|= BNX2X_FLOW_CTRL_RX
;
644 vars
->flow_ctrl
&= ~BNX2X_FLOW_CTRL_RX
;
646 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
647 if (vars
->line_speed
&&
648 ((vars
->line_speed
== SPEED_10
) ||
649 (vars
->line_speed
== SPEED_100
))) {
650 vars
->phy_flags
|= PHY_SGMII_FLAG
;
652 vars
->phy_flags
&= ~PHY_SGMII_FLAG
;
656 /* anything 10 and over uses the bmac */
657 link_10g
= ((vars
->line_speed
== SPEED_10000
) ||
658 (vars
->line_speed
== SPEED_12000
) ||
659 (vars
->line_speed
== SPEED_12500
) ||
660 (vars
->line_speed
== SPEED_13000
) ||
661 (vars
->line_speed
== SPEED_15000
) ||
662 (vars
->line_speed
== SPEED_16000
));
664 vars
->mac_type
= MAC_TYPE_BMAC
;
666 vars
->mac_type
= MAC_TYPE_EMAC
;
668 } else { /* link down */
669 DP(NETIF_MSG_LINK
, "phy link down\n");
671 vars
->phy_link_up
= 0;
673 vars
->line_speed
= 0;
674 vars
->duplex
= DUPLEX_FULL
;
675 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
677 /* indicate no mac active */
678 vars
->mac_type
= MAC_TYPE_NONE
;
681 DP(NETIF_MSG_LINK
, "link_status 0x%x phy_link_up %x\n",
682 vars
->link_status
, vars
->phy_link_up
);
683 DP(NETIF_MSG_LINK
, "line_speed %x duplex %x flow_ctrl 0x%x\n",
684 vars
->line_speed
, vars
->duplex
, vars
->flow_ctrl
);
687 static void bnx2x_update_mng(struct link_params
*params
, u32 link_status
)
689 struct bnx2x
*bp
= params
->bp
;
691 REG_WR(bp
, params
->shmem_base
+
692 offsetof(struct shmem_region
,
693 port_mb
[params
->port
].link_status
),
697 static void bnx2x_bmac_rx_disable(struct bnx2x
*bp
, u8 port
)
699 u32 bmac_addr
= port
? NIG_REG_INGRESS_BMAC1_MEM
:
700 NIG_REG_INGRESS_BMAC0_MEM
;
702 u32 nig_bmac_enable
= REG_RD(bp
, NIG_REG_BMAC0_REGS_OUT_EN
+ port
*4);
704 /* Only if the bmac is out of reset */
705 if (REG_RD(bp
, MISC_REG_RESET_REG_2
) &
706 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
) &&
709 /* Clear Rx Enable bit in BMAC_CONTROL register */
710 REG_RD_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_BMAC_CONTROL
,
712 wb_data
[0] &= ~BMAC_CONTROL_RX_ENABLE
;
713 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_BMAC_CONTROL
,
720 static u8
bnx2x_pbf_update(struct link_params
*params
, u32 flow_ctrl
,
723 struct bnx2x
*bp
= params
->bp
;
724 u8 port
= params
->port
;
729 REG_WR(bp
, PBF_REG_DISABLE_NEW_TASK_PROC_P0
+ port
*4, 0x1);
731 /* wait for init credit */
732 init_crd
= REG_RD(bp
, PBF_REG_P0_INIT_CRD
+ port
*4);
733 crd
= REG_RD(bp
, PBF_REG_P0_CREDIT
+ port
*8);
734 DP(NETIF_MSG_LINK
, "init_crd 0x%x crd 0x%x\n", init_crd
, crd
);
736 while ((init_crd
!= crd
) && count
) {
739 crd
= REG_RD(bp
, PBF_REG_P0_CREDIT
+ port
*8);
742 crd
= REG_RD(bp
, PBF_REG_P0_CREDIT
+ port
*8);
743 if (init_crd
!= crd
) {
744 DP(NETIF_MSG_LINK
, "BUG! init_crd 0x%x != crd 0x%x\n",
749 if (flow_ctrl
& BNX2X_FLOW_CTRL_RX
||
750 line_speed
== SPEED_10
||
751 line_speed
== SPEED_100
||
752 line_speed
== SPEED_1000
||
753 line_speed
== SPEED_2500
) {
754 REG_WR(bp
, PBF_REG_P0_PAUSE_ENABLE
+ port
*4, 1);
755 /* update threshold */
756 REG_WR(bp
, PBF_REG_P0_ARB_THRSH
+ port
*4, 0);
757 /* update init credit */
758 init_crd
= 778; /* (800-18-4) */
761 u32 thresh
= (ETH_MAX_JUMBO_PACKET_SIZE
+
763 REG_WR(bp
, PBF_REG_P0_PAUSE_ENABLE
+ port
*4, 0);
764 /* update threshold */
765 REG_WR(bp
, PBF_REG_P0_ARB_THRSH
+ port
*4, thresh
);
766 /* update init credit */
767 switch (line_speed
) {
769 init_crd
= thresh
+ 553 - 22;
773 init_crd
= thresh
+ 664 - 22;
777 init_crd
= thresh
+ 742 - 22;
781 init_crd
= thresh
+ 778 - 22;
784 DP(NETIF_MSG_LINK
, "Invalid line_speed 0x%x\n",
789 REG_WR(bp
, PBF_REG_P0_INIT_CRD
+ port
*4, init_crd
);
790 DP(NETIF_MSG_LINK
, "PBF updated to speed %d credit %d\n",
791 line_speed
, init_crd
);
793 /* probe the credit changes */
794 REG_WR(bp
, PBF_REG_INIT_P0
+ port
*4, 0x1);
796 REG_WR(bp
, PBF_REG_INIT_P0
+ port
*4, 0x0);
799 REG_WR(bp
, PBF_REG_DISABLE_NEW_TASK_PROC_P0
+ port
*4, 0x0);
803 static u32
bnx2x_get_emac_base(struct bnx2x
*bp
, u32 ext_phy_type
, u8 port
)
807 switch (ext_phy_type
) {
808 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
809 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
:
810 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
:
811 /* All MDC/MDIO is directed through single EMAC */
812 if (REG_RD(bp
, NIG_REG_PORT_SWAP
))
813 emac_base
= GRCBASE_EMAC0
;
815 emac_base
= GRCBASE_EMAC1
;
817 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
818 emac_base
= (port
) ? GRCBASE_EMAC0
: GRCBASE_EMAC1
;
821 emac_base
= (port
) ? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
828 u8
bnx2x_cl45_write(struct bnx2x
*bp
, u8 port
, u32 ext_phy_type
,
829 u8 phy_addr
, u8 devad
, u16 reg
, u16 val
)
833 u32 mdio_ctrl
= bnx2x_get_emac_base(bp
, ext_phy_type
, port
);
835 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
836 * (a value of 49==0x31) and make sure that the AUTO poll is off
839 saved_mode
= REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
840 tmp
= saved_mode
& ~(EMAC_MDIO_MODE_AUTO_POLL
|
841 EMAC_MDIO_MODE_CLOCK_CNT
);
842 tmp
|= (EMAC_MDIO_MODE_CLAUSE_45
|
843 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT
));
844 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, tmp
);
845 REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
850 tmp
= ((phy_addr
<< 21) | (devad
<< 16) | reg
|
851 EMAC_MDIO_COMM_COMMAND_ADDRESS
|
852 EMAC_MDIO_COMM_START_BUSY
);
853 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, tmp
);
855 for (i
= 0; i
< 50; i
++) {
858 tmp
= REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
);
859 if (!(tmp
& EMAC_MDIO_COMM_START_BUSY
)) {
864 if (tmp
& EMAC_MDIO_COMM_START_BUSY
) {
865 DP(NETIF_MSG_LINK
, "write phy register failed\n");
869 tmp
= ((phy_addr
<< 21) | (devad
<< 16) | val
|
870 EMAC_MDIO_COMM_COMMAND_WRITE_45
|
871 EMAC_MDIO_COMM_START_BUSY
);
872 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, tmp
);
874 for (i
= 0; i
< 50; i
++) {
877 tmp
= REG_RD(bp
, mdio_ctrl
+
878 EMAC_REG_EMAC_MDIO_COMM
);
879 if (!(tmp
& EMAC_MDIO_COMM_START_BUSY
)) {
884 if (tmp
& EMAC_MDIO_COMM_START_BUSY
) {
885 DP(NETIF_MSG_LINK
, "write phy register failed\n");
890 /* Restore the saved mode */
891 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, saved_mode
);
896 u8
bnx2x_cl45_read(struct bnx2x
*bp
, u8 port
, u32 ext_phy_type
,
897 u8 phy_addr
, u8 devad
, u16 reg
, u16
*ret_val
)
903 u32 mdio_ctrl
= bnx2x_get_emac_base(bp
, ext_phy_type
, port
);
904 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
905 * (a value of 49==0x31) and make sure that the AUTO poll is off
908 saved_mode
= REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
909 val
= saved_mode
& ((EMAC_MDIO_MODE_AUTO_POLL
|
910 EMAC_MDIO_MODE_CLOCK_CNT
));
911 val
|= (EMAC_MDIO_MODE_CLAUSE_45
|
912 (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT
));
913 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, val
);
914 REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
918 val
= ((phy_addr
<< 21) | (devad
<< 16) | reg
|
919 EMAC_MDIO_COMM_COMMAND_ADDRESS
|
920 EMAC_MDIO_COMM_START_BUSY
);
921 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, val
);
923 for (i
= 0; i
< 50; i
++) {
926 val
= REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
);
927 if (!(val
& EMAC_MDIO_COMM_START_BUSY
)) {
932 if (val
& EMAC_MDIO_COMM_START_BUSY
) {
933 DP(NETIF_MSG_LINK
, "read phy register failed\n");
940 val
= ((phy_addr
<< 21) | (devad
<< 16) |
941 EMAC_MDIO_COMM_COMMAND_READ_45
|
942 EMAC_MDIO_COMM_START_BUSY
);
943 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, val
);
945 for (i
= 0; i
< 50; i
++) {
948 val
= REG_RD(bp
, mdio_ctrl
+
949 EMAC_REG_EMAC_MDIO_COMM
);
950 if (!(val
& EMAC_MDIO_COMM_START_BUSY
)) {
951 *ret_val
= (u16
)(val
& EMAC_MDIO_COMM_DATA
);
955 if (val
& EMAC_MDIO_COMM_START_BUSY
) {
956 DP(NETIF_MSG_LINK
, "read phy register failed\n");
963 /* Restore the saved mode */
964 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, saved_mode
);
969 static void bnx2x_set_aer_mmd(struct link_params
*params
,
970 struct link_vars
*vars
)
972 struct bnx2x
*bp
= params
->bp
;
976 ser_lane
= ((params
->lane_config
&
977 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
978 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
980 offset
= (vars
->phy_flags
& PHY_XGXS_FLAG
) ?
981 (params
->phy_addr
+ ser_lane
) : 0;
983 CL45_WR_OVER_CL22(bp
, params
->port
,
985 MDIO_REG_BANK_AER_BLOCK
,
986 MDIO_AER_BLOCK_AER_REG
, 0x3800 + offset
);
989 static void bnx2x_set_master_ln(struct link_params
*params
)
991 struct bnx2x
*bp
= params
->bp
;
992 u16 new_master_ln
, ser_lane
;
993 ser_lane
= ((params
->lane_config
&
994 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
995 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
997 /* set the master_ln for AN */
998 CL45_RD_OVER_CL22(bp
, params
->port
,
1000 MDIO_REG_BANK_XGXS_BLOCK2
,
1001 MDIO_XGXS_BLOCK2_TEST_MODE_LANE
,
1004 CL45_WR_OVER_CL22(bp
, params
->port
,
1006 MDIO_REG_BANK_XGXS_BLOCK2
,
1007 MDIO_XGXS_BLOCK2_TEST_MODE_LANE
,
1008 (new_master_ln
| ser_lane
));
1011 static u8
bnx2x_reset_unicore(struct link_params
*params
)
1013 struct bnx2x
*bp
= params
->bp
;
1017 CL45_RD_OVER_CL22(bp
, params
->port
,
1019 MDIO_REG_BANK_COMBO_IEEE0
,
1020 MDIO_COMBO_IEEE0_MII_CONTROL
, &mii_control
);
1022 /* reset the unicore */
1023 CL45_WR_OVER_CL22(bp
, params
->port
,
1025 MDIO_REG_BANK_COMBO_IEEE0
,
1026 MDIO_COMBO_IEEE0_MII_CONTROL
,
1028 MDIO_COMBO_IEEO_MII_CONTROL_RESET
));
1029 if (params
->switch_cfg
== SWITCH_CFG_1G
)
1030 bnx2x_set_serdes_access(params
);
1032 /* wait for the reset to self clear */
1033 for (i
= 0; i
< MDIO_ACCESS_TIMEOUT
; i
++) {
1036 /* the reset erased the previous bank value */
1037 CL45_RD_OVER_CL22(bp
, params
->port
,
1039 MDIO_REG_BANK_COMBO_IEEE0
,
1040 MDIO_COMBO_IEEE0_MII_CONTROL
,
1043 if (!(mii_control
& MDIO_COMBO_IEEO_MII_CONTROL_RESET
)) {
1049 DP(NETIF_MSG_LINK
, "BUG! XGXS is still in reset!\n");
1054 static void bnx2x_set_swap_lanes(struct link_params
*params
)
1056 struct bnx2x
*bp
= params
->bp
;
1057 /* Each two bits represents a lane number:
1058 No swap is 0123 => 0x1b no need to enable the swap */
1059 u16 ser_lane
, rx_lane_swap
, tx_lane_swap
;
1061 ser_lane
= ((params
->lane_config
&
1062 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
1063 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
1064 rx_lane_swap
= ((params
->lane_config
&
1065 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK
) >>
1066 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT
);
1067 tx_lane_swap
= ((params
->lane_config
&
1068 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK
) >>
1069 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT
);
1071 if (rx_lane_swap
!= 0x1b) {
1072 CL45_WR_OVER_CL22(bp
, params
->port
,
1074 MDIO_REG_BANK_XGXS_BLOCK2
,
1075 MDIO_XGXS_BLOCK2_RX_LN_SWAP
,
1077 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE
|
1078 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE
));
1080 CL45_WR_OVER_CL22(bp
, params
->port
,
1082 MDIO_REG_BANK_XGXS_BLOCK2
,
1083 MDIO_XGXS_BLOCK2_RX_LN_SWAP
, 0);
1086 if (tx_lane_swap
!= 0x1b) {
1087 CL45_WR_OVER_CL22(bp
, params
->port
,
1089 MDIO_REG_BANK_XGXS_BLOCK2
,
1090 MDIO_XGXS_BLOCK2_TX_LN_SWAP
,
1092 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE
));
1094 CL45_WR_OVER_CL22(bp
, params
->port
,
1096 MDIO_REG_BANK_XGXS_BLOCK2
,
1097 MDIO_XGXS_BLOCK2_TX_LN_SWAP
, 0);
1101 static void bnx2x_set_parallel_detection(struct link_params
*params
,
1104 struct bnx2x
*bp
= params
->bp
;
1107 CL45_RD_OVER_CL22(bp
, params
->port
,
1109 MDIO_REG_BANK_SERDES_DIGITAL
,
1110 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2
,
1112 if (params
->speed_cap_mask
& PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
)
1113 control2
|= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN
;
1115 control2
&= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN
;
1116 DP(NETIF_MSG_LINK
, "params->speed_cap_mask = 0x%x, control2 = 0x%x\n",
1117 params
->speed_cap_mask
, control2
);
1118 CL45_WR_OVER_CL22(bp
, params
->port
,
1120 MDIO_REG_BANK_SERDES_DIGITAL
,
1121 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2
,
1124 if ((phy_flags
& PHY_XGXS_FLAG
) &&
1125 (params
->speed_cap_mask
&
1126 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)) {
1127 DP(NETIF_MSG_LINK
, "XGXS\n");
1129 CL45_WR_OVER_CL22(bp
, params
->port
,
1131 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
1132 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK
,
1133 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT
);
1135 CL45_RD_OVER_CL22(bp
, params
->port
,
1137 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
1138 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL
,
1143 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN
;
1145 CL45_WR_OVER_CL22(bp
, params
->port
,
1147 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
1148 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL
,
1151 /* Disable parallel detection of HiG */
1152 CL45_WR_OVER_CL22(bp
, params
->port
,
1154 MDIO_REG_BANK_XGXS_BLOCK2
,
1155 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G
,
1156 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS
|
1157 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS
);
1161 static void bnx2x_set_autoneg(struct link_params
*params
,
1162 struct link_vars
*vars
,
1165 struct bnx2x
*bp
= params
->bp
;
1170 CL45_RD_OVER_CL22(bp
, params
->port
,
1172 MDIO_REG_BANK_COMBO_IEEE0
,
1173 MDIO_COMBO_IEEE0_MII_CONTROL
, ®_val
);
1175 /* CL37 Autoneg Enabled */
1176 if (vars
->line_speed
== SPEED_AUTO_NEG
)
1177 reg_val
|= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
;
1178 else /* CL37 Autoneg Disabled */
1179 reg_val
&= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
|
1180 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN
);
1182 CL45_WR_OVER_CL22(bp
, params
->port
,
1184 MDIO_REG_BANK_COMBO_IEEE0
,
1185 MDIO_COMBO_IEEE0_MII_CONTROL
, reg_val
);
1187 /* Enable/Disable Autodetection */
1189 CL45_RD_OVER_CL22(bp
, params
->port
,
1191 MDIO_REG_BANK_SERDES_DIGITAL
,
1192 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
, ®_val
);
1193 reg_val
&= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN
|
1194 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT
);
1195 reg_val
|= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE
;
1196 if (vars
->line_speed
== SPEED_AUTO_NEG
)
1197 reg_val
|= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET
;
1199 reg_val
&= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET
;
1201 CL45_WR_OVER_CL22(bp
, params
->port
,
1203 MDIO_REG_BANK_SERDES_DIGITAL
,
1204 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
, reg_val
);
1206 /* Enable TetonII and BAM autoneg */
1207 CL45_RD_OVER_CL22(bp
, params
->port
,
1209 MDIO_REG_BANK_BAM_NEXT_PAGE
,
1210 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL
,
1212 if (vars
->line_speed
== SPEED_AUTO_NEG
) {
1213 /* Enable BAM aneg Mode and TetonII aneg Mode */
1214 reg_val
|= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE
|
1215 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN
);
1217 /* TetonII and BAM Autoneg Disabled */
1218 reg_val
&= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE
|
1219 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN
);
1221 CL45_WR_OVER_CL22(bp
, params
->port
,
1223 MDIO_REG_BANK_BAM_NEXT_PAGE
,
1224 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL
,
1228 /* Enable Cl73 FSM status bits */
1229 CL45_WR_OVER_CL22(bp
, params
->port
,
1231 MDIO_REG_BANK_CL73_USERB0
,
1232 MDIO_CL73_USERB0_CL73_UCTRL
,
1235 /* Enable BAM Station Manager*/
1236 CL45_WR_OVER_CL22(bp
, params
->port
,
1238 MDIO_REG_BANK_CL73_USERB0
,
1239 MDIO_CL73_USERB0_CL73_BAM_CTRL1
,
1240 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN
|
1241 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN
|
1242 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN
);
1244 /* Advertise CL73 link speeds */
1245 CL45_RD_OVER_CL22(bp
, params
->port
,
1247 MDIO_REG_BANK_CL73_IEEEB1
,
1248 MDIO_CL73_IEEEB1_AN_ADV2
,
1250 if (params
->speed_cap_mask
&
1251 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)
1252 reg_val
|= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4
;
1253 if (params
->speed_cap_mask
&
1254 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
)
1255 reg_val
|= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX
;
1257 CL45_WR_OVER_CL22(bp
, params
->port
,
1259 MDIO_REG_BANK_CL73_IEEEB1
,
1260 MDIO_CL73_IEEEB1_AN_ADV2
,
1263 /* CL73 Autoneg Enabled */
1264 reg_val
= MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN
;
1266 } else /* CL73 Autoneg Disabled */
1269 CL45_WR_OVER_CL22(bp
, params
->port
,
1271 MDIO_REG_BANK_CL73_IEEEB0
,
1272 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
, reg_val
);
1275 /* program SerDes, forced speed */
1276 static void bnx2x_program_serdes(struct link_params
*params
,
1277 struct link_vars
*vars
)
1279 struct bnx2x
*bp
= params
->bp
;
1282 /* program duplex, disable autoneg and sgmii*/
1283 CL45_RD_OVER_CL22(bp
, params
->port
,
1285 MDIO_REG_BANK_COMBO_IEEE0
,
1286 MDIO_COMBO_IEEE0_MII_CONTROL
, ®_val
);
1287 reg_val
&= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
|
1288 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
|
1289 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK
);
1290 if (params
->req_duplex
== DUPLEX_FULL
)
1291 reg_val
|= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
;
1292 CL45_WR_OVER_CL22(bp
, params
->port
,
1294 MDIO_REG_BANK_COMBO_IEEE0
,
1295 MDIO_COMBO_IEEE0_MII_CONTROL
, reg_val
);
1298 - needed only if the speed is greater than 1G (2.5G or 10G) */
1299 CL45_RD_OVER_CL22(bp
, params
->port
,
1301 MDIO_REG_BANK_SERDES_DIGITAL
,
1302 MDIO_SERDES_DIGITAL_MISC1
, ®_val
);
1303 /* clearing the speed value before setting the right speed */
1304 DP(NETIF_MSG_LINK
, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val
);
1306 reg_val
&= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK
|
1307 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL
);
1309 if (!((vars
->line_speed
== SPEED_1000
) ||
1310 (vars
->line_speed
== SPEED_100
) ||
1311 (vars
->line_speed
== SPEED_10
))) {
1313 reg_val
|= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M
|
1314 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL
);
1315 if (vars
->line_speed
== SPEED_10000
)
1317 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4
;
1318 if (vars
->line_speed
== SPEED_13000
)
1320 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G
;
1323 CL45_WR_OVER_CL22(bp
, params
->port
,
1325 MDIO_REG_BANK_SERDES_DIGITAL
,
1326 MDIO_SERDES_DIGITAL_MISC1
, reg_val
);
1330 static void bnx2x_set_brcm_cl37_advertisment(struct link_params
*params
)
1332 struct bnx2x
*bp
= params
->bp
;
1335 /* configure the 48 bits for BAM AN */
1337 /* set extended capabilities */
1338 if (params
->speed_cap_mask
& PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G
)
1339 val
|= MDIO_OVER_1G_UP1_2_5G
;
1340 if (params
->speed_cap_mask
& PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)
1341 val
|= MDIO_OVER_1G_UP1_10G
;
1342 CL45_WR_OVER_CL22(bp
, params
->port
,
1344 MDIO_REG_BANK_OVER_1G
,
1345 MDIO_OVER_1G_UP1
, val
);
1347 CL45_WR_OVER_CL22(bp
, params
->port
,
1349 MDIO_REG_BANK_OVER_1G
,
1350 MDIO_OVER_1G_UP3
, 0x400);
1353 static void bnx2x_calc_ieee_aneg_adv(struct link_params
*params
, u16
*ieee_fc
)
1355 struct bnx2x
*bp
= params
->bp
;
1356 *ieee_fc
= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX
;
1357 /* resolve pause mode and advertisement
1358 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1360 switch (params
->req_flow_ctrl
) {
1361 case BNX2X_FLOW_CTRL_AUTO
:
1362 if (params
->req_fc_auto_adv
== BNX2X_FLOW_CTRL_BOTH
) {
1364 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
1367 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
;
1370 case BNX2X_FLOW_CTRL_TX
:
1372 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
;
1375 case BNX2X_FLOW_CTRL_RX
:
1376 case BNX2X_FLOW_CTRL_BOTH
:
1377 *ieee_fc
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
1380 case BNX2X_FLOW_CTRL_NONE
:
1382 *ieee_fc
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE
;
1385 DP(NETIF_MSG_LINK
, "ieee_fc = 0x%x\n", *ieee_fc
);
1388 static void bnx2x_set_ieee_aneg_advertisment(struct link_params
*params
,
1391 struct bnx2x
*bp
= params
->bp
;
1393 /* for AN, we are always publishing full duplex */
1395 CL45_WR_OVER_CL22(bp
, params
->port
,
1397 MDIO_REG_BANK_COMBO_IEEE0
,
1398 MDIO_COMBO_IEEE0_AUTO_NEG_ADV
, ieee_fc
);
1399 CL45_RD_OVER_CL22(bp
, params
->port
,
1401 MDIO_REG_BANK_CL73_IEEEB1
,
1402 MDIO_CL73_IEEEB1_AN_ADV1
, &val
);
1403 val
&= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH
;
1404 val
|= ((ieee_fc
<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK
);
1405 CL45_WR_OVER_CL22(bp
, params
->port
,
1407 MDIO_REG_BANK_CL73_IEEEB1
,
1408 MDIO_CL73_IEEEB1_AN_ADV1
, val
);
1411 static void bnx2x_restart_autoneg(struct link_params
*params
, u8 enable_cl73
)
1413 struct bnx2x
*bp
= params
->bp
;
1416 DP(NETIF_MSG_LINK
, "bnx2x_restart_autoneg\n");
1417 /* Enable and restart BAM/CL37 aneg */
1420 CL45_RD_OVER_CL22(bp
, params
->port
,
1422 MDIO_REG_BANK_CL73_IEEEB0
,
1423 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
,
1426 CL45_WR_OVER_CL22(bp
, params
->port
,
1428 MDIO_REG_BANK_CL73_IEEEB0
,
1429 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
,
1431 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN
|
1432 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN
));
1435 CL45_RD_OVER_CL22(bp
, params
->port
,
1437 MDIO_REG_BANK_COMBO_IEEE0
,
1438 MDIO_COMBO_IEEE0_MII_CONTROL
,
1441 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1443 CL45_WR_OVER_CL22(bp
, params
->port
,
1445 MDIO_REG_BANK_COMBO_IEEE0
,
1446 MDIO_COMBO_IEEE0_MII_CONTROL
,
1448 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
|
1449 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN
));
1453 static void bnx2x_initialize_sgmii_process(struct link_params
*params
,
1454 struct link_vars
*vars
)
1456 struct bnx2x
*bp
= params
->bp
;
1459 /* in SGMII mode, the unicore is always slave */
1461 CL45_RD_OVER_CL22(bp
, params
->port
,
1463 MDIO_REG_BANK_SERDES_DIGITAL
,
1464 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
,
1466 control1
|= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT
;
1467 /* set sgmii mode (and not fiber) */
1468 control1
&= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE
|
1469 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET
|
1470 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE
);
1471 CL45_WR_OVER_CL22(bp
, params
->port
,
1473 MDIO_REG_BANK_SERDES_DIGITAL
,
1474 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
,
1477 /* if forced speed */
1478 if (!(vars
->line_speed
== SPEED_AUTO_NEG
)) {
1479 /* set speed, disable autoneg */
1482 CL45_RD_OVER_CL22(bp
, params
->port
,
1484 MDIO_REG_BANK_COMBO_IEEE0
,
1485 MDIO_COMBO_IEEE0_MII_CONTROL
,
1487 mii_control
&= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
|
1488 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK
|
1489 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
);
1491 switch (vars
->line_speed
) {
1494 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100
;
1498 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000
;
1501 /* there is nothing to set for 10M */
1504 /* invalid speed for SGMII */
1505 DP(NETIF_MSG_LINK
, "Invalid line_speed 0x%x\n",
1510 /* setting the full duplex */
1511 if (params
->req_duplex
== DUPLEX_FULL
)
1513 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
;
1514 CL45_WR_OVER_CL22(bp
, params
->port
,
1516 MDIO_REG_BANK_COMBO_IEEE0
,
1517 MDIO_COMBO_IEEE0_MII_CONTROL
,
1520 } else { /* AN mode */
1521 /* enable and restart AN */
1522 bnx2x_restart_autoneg(params
, 0);
1531 static void bnx2x_pause_resolve(struct link_vars
*vars
, u32 pause_result
)
1533 switch (pause_result
) { /* ASYM P ASYM P */
1534 case 0xb: /* 1 0 1 1 */
1535 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_TX
;
1538 case 0xe: /* 1 1 1 0 */
1539 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_RX
;
1542 case 0x5: /* 0 1 0 1 */
1543 case 0x7: /* 0 1 1 1 */
1544 case 0xd: /* 1 1 0 1 */
1545 case 0xf: /* 1 1 1 1 */
1546 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_BOTH
;
1554 static u8
bnx2x_ext_phy_resolve_fc(struct link_params
*params
,
1555 struct link_vars
*vars
)
1557 struct bnx2x
*bp
= params
->bp
;
1559 u16 ld_pause
; /* local */
1560 u16 lp_pause
; /* link partner */
1561 u16 an_complete
; /* AN complete */
1565 u8 port
= params
->port
;
1566 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
1567 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
1570 bnx2x_cl45_read(bp
, port
,
1574 MDIO_AN_REG_STATUS
, &an_complete
);
1575 bnx2x_cl45_read(bp
, port
,
1579 MDIO_AN_REG_STATUS
, &an_complete
);
1581 if (an_complete
& MDIO_AN_REG_STATUS_AN_COMPLETE
) {
1583 bnx2x_cl45_read(bp
, port
,
1587 MDIO_AN_REG_ADV_PAUSE
, &ld_pause
);
1588 bnx2x_cl45_read(bp
, port
,
1592 MDIO_AN_REG_LP_AUTO_NEG
, &lp_pause
);
1593 pause_result
= (ld_pause
&
1594 MDIO_AN_REG_ADV_PAUSE_MASK
) >> 8;
1595 pause_result
|= (lp_pause
&
1596 MDIO_AN_REG_ADV_PAUSE_MASK
) >> 10;
1597 DP(NETIF_MSG_LINK
, "Ext PHY pause result 0x%x\n",
1599 bnx2x_pause_resolve(vars
, pause_result
);
1600 if (vars
->flow_ctrl
== BNX2X_FLOW_CTRL_NONE
&&
1601 ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
1602 bnx2x_cl45_read(bp
, port
,
1606 MDIO_AN_REG_CL37_FC_LD
, &ld_pause
);
1608 bnx2x_cl45_read(bp
, port
,
1612 MDIO_AN_REG_CL37_FC_LP
, &lp_pause
);
1613 pause_result
= (ld_pause
&
1614 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) >> 5;
1615 pause_result
|= (lp_pause
&
1616 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) >> 7;
1618 bnx2x_pause_resolve(vars
, pause_result
);
1619 DP(NETIF_MSG_LINK
, "Ext PHY CL37 pause result 0x%x\n",
1626 static u8
bnx2x_direct_parallel_detect_used(struct link_params
*params
)
1628 struct bnx2x
*bp
= params
->bp
;
1629 u16 pd_10g
, status2_1000x
;
1630 CL45_RD_OVER_CL22(bp
, params
->port
,
1632 MDIO_REG_BANK_SERDES_DIGITAL
,
1633 MDIO_SERDES_DIGITAL_A_1000X_STATUS2
,
1635 CL45_RD_OVER_CL22(bp
, params
->port
,
1637 MDIO_REG_BANK_SERDES_DIGITAL
,
1638 MDIO_SERDES_DIGITAL_A_1000X_STATUS2
,
1640 if (status2_1000x
& MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED
) {
1641 DP(NETIF_MSG_LINK
, "1G parallel detect link on port %d\n",
1646 CL45_RD_OVER_CL22(bp
, params
->port
,
1648 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
1649 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS
,
1652 if (pd_10g
& MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK
) {
1653 DP(NETIF_MSG_LINK
, "10G parallel detect link on port %d\n",
1660 static void bnx2x_flow_ctrl_resolve(struct link_params
*params
,
1661 struct link_vars
*vars
,
1664 struct bnx2x
*bp
= params
->bp
;
1665 u16 ld_pause
; /* local driver */
1666 u16 lp_pause
; /* link partner */
1669 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
1671 /* resolve from gp_status in case of AN complete and not sgmii */
1672 if ((params
->req_flow_ctrl
== BNX2X_FLOW_CTRL_AUTO
) &&
1673 (gp_status
& MDIO_AN_CL73_OR_37_COMPLETE
) &&
1674 (!(vars
->phy_flags
& PHY_SGMII_FLAG
)) &&
1675 (XGXS_EXT_PHY_TYPE(params
->ext_phy_config
) ==
1676 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
)) {
1677 if (bnx2x_direct_parallel_detect_used(params
)) {
1678 vars
->flow_ctrl
= params
->req_fc_auto_adv
;
1682 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE
|
1683 MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE
)) ==
1684 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE
|
1685 MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE
)) {
1687 CL45_RD_OVER_CL22(bp
, params
->port
,
1689 MDIO_REG_BANK_CL73_IEEEB1
,
1690 MDIO_CL73_IEEEB1_AN_ADV1
,
1692 CL45_RD_OVER_CL22(bp
, params
->port
,
1694 MDIO_REG_BANK_CL73_IEEEB1
,
1695 MDIO_CL73_IEEEB1_AN_LP_ADV1
,
1697 pause_result
= (ld_pause
&
1698 MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK
)
1700 pause_result
|= (lp_pause
&
1701 MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK
)
1703 DP(NETIF_MSG_LINK
, "pause_result CL73 0x%x\n",
1707 CL45_RD_OVER_CL22(bp
, params
->port
,
1709 MDIO_REG_BANK_COMBO_IEEE0
,
1710 MDIO_COMBO_IEEE0_AUTO_NEG_ADV
,
1712 CL45_RD_OVER_CL22(bp
, params
->port
,
1714 MDIO_REG_BANK_COMBO_IEEE0
,
1715 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1
,
1717 pause_result
= (ld_pause
&
1718 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK
)>>5;
1719 pause_result
|= (lp_pause
&
1720 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK
)>>7;
1721 DP(NETIF_MSG_LINK
, "pause_result CL37 0x%x\n",
1724 bnx2x_pause_resolve(vars
, pause_result
);
1725 } else if ((params
->req_flow_ctrl
== BNX2X_FLOW_CTRL_AUTO
) &&
1726 (bnx2x_ext_phy_resolve_fc(params
, vars
))) {
1729 if (params
->req_flow_ctrl
== BNX2X_FLOW_CTRL_AUTO
)
1730 vars
->flow_ctrl
= params
->req_fc_auto_adv
;
1732 vars
->flow_ctrl
= params
->req_flow_ctrl
;
1734 DP(NETIF_MSG_LINK
, "flow_ctrl 0x%x\n", vars
->flow_ctrl
);
1737 static void bnx2x_check_fallback_to_cl37(struct link_params
*params
)
1739 struct bnx2x
*bp
= params
->bp
;
1740 u16 rx_status
, ustat_val
, cl37_fsm_recieved
;
1741 DP(NETIF_MSG_LINK
, "bnx2x_check_fallback_to_cl37\n");
1742 /* Step 1: Make sure signal is detected */
1743 CL45_RD_OVER_CL22(bp
, params
->port
,
1748 if ((rx_status
& MDIO_RX0_RX_STATUS_SIGDET
) !=
1749 (MDIO_RX0_RX_STATUS_SIGDET
)) {
1750 DP(NETIF_MSG_LINK
, "Signal is not detected. Restoring CL73."
1751 "rx_status(0x80b0) = 0x%x\n", rx_status
);
1752 CL45_WR_OVER_CL22(bp
, params
->port
,
1754 MDIO_REG_BANK_CL73_IEEEB0
,
1755 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
,
1756 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN
);
1759 /* Step 2: Check CL73 state machine */
1760 CL45_RD_OVER_CL22(bp
, params
->port
,
1762 MDIO_REG_BANK_CL73_USERB0
,
1763 MDIO_CL73_USERB0_CL73_USTAT1
,
1766 (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK
|
1767 MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37
)) !=
1768 (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK
|
1769 MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37
)) {
1770 DP(NETIF_MSG_LINK
, "CL73 state-machine is not stable. "
1771 "ustat_val(0x8371) = 0x%x\n", ustat_val
);
1774 /* Step 3: Check CL37 Message Pages received to indicate LP
1775 supports only CL37 */
1776 CL45_RD_OVER_CL22(bp
, params
->port
,
1778 MDIO_REG_BANK_REMOTE_PHY
,
1779 MDIO_REMOTE_PHY_MISC_RX_STATUS
,
1780 &cl37_fsm_recieved
);
1781 if ((cl37_fsm_recieved
&
1782 (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG
|
1783 MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG
)) !=
1784 (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG
|
1785 MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG
)) {
1786 DP(NETIF_MSG_LINK
, "No CL37 FSM were received. "
1787 "misc_rx_status(0x8330) = 0x%x\n",
1791 /* The combined cl37/cl73 fsm state information indicating that we are
1792 connected to a device which does not support cl73, but does support
1793 cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */
1795 CL45_WR_OVER_CL22(bp
, params
->port
,
1797 MDIO_REG_BANK_CL73_IEEEB0
,
1798 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
,
1800 /* Restart CL37 autoneg */
1801 bnx2x_restart_autoneg(params
, 0);
1802 DP(NETIF_MSG_LINK
, "Disabling CL73, and restarting CL37 autoneg\n");
1804 static u8
bnx2x_link_settings_status(struct link_params
*params
,
1805 struct link_vars
*vars
,
1809 struct bnx2x
*bp
= params
->bp
;
1812 vars
->link_status
= 0;
1814 if (gp_status
& MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS
) {
1815 DP(NETIF_MSG_LINK
, "phy link up gp_status=0x%x\n",
1818 vars
->phy_link_up
= 1;
1819 vars
->link_status
|= LINK_STATUS_LINK_UP
;
1821 if (gp_status
& MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS
)
1822 vars
->duplex
= DUPLEX_FULL
;
1824 vars
->duplex
= DUPLEX_HALF
;
1826 bnx2x_flow_ctrl_resolve(params
, vars
, gp_status
);
1828 switch (gp_status
& GP_STATUS_SPEED_MASK
) {
1830 new_line_speed
= SPEED_10
;
1831 if (vars
->duplex
== DUPLEX_FULL
)
1832 vars
->link_status
|= LINK_10TFD
;
1834 vars
->link_status
|= LINK_10THD
;
1837 case GP_STATUS_100M
:
1838 new_line_speed
= SPEED_100
;
1839 if (vars
->duplex
== DUPLEX_FULL
)
1840 vars
->link_status
|= LINK_100TXFD
;
1842 vars
->link_status
|= LINK_100TXHD
;
1846 case GP_STATUS_1G_KX
:
1847 new_line_speed
= SPEED_1000
;
1848 if (vars
->duplex
== DUPLEX_FULL
)
1849 vars
->link_status
|= LINK_1000TFD
;
1851 vars
->link_status
|= LINK_1000THD
;
1854 case GP_STATUS_2_5G
:
1855 new_line_speed
= SPEED_2500
;
1856 if (vars
->duplex
== DUPLEX_FULL
)
1857 vars
->link_status
|= LINK_2500TFD
;
1859 vars
->link_status
|= LINK_2500THD
;
1865 "link speed unsupported gp_status 0x%x\n",
1869 case GP_STATUS_10G_KX4
:
1870 case GP_STATUS_10G_HIG
:
1871 case GP_STATUS_10G_CX4
:
1872 new_line_speed
= SPEED_10000
;
1873 vars
->link_status
|= LINK_10GTFD
;
1876 case GP_STATUS_12G_HIG
:
1877 new_line_speed
= SPEED_12000
;
1878 vars
->link_status
|= LINK_12GTFD
;
1881 case GP_STATUS_12_5G
:
1882 new_line_speed
= SPEED_12500
;
1883 vars
->link_status
|= LINK_12_5GTFD
;
1887 new_line_speed
= SPEED_13000
;
1888 vars
->link_status
|= LINK_13GTFD
;
1892 new_line_speed
= SPEED_15000
;
1893 vars
->link_status
|= LINK_15GTFD
;
1897 new_line_speed
= SPEED_16000
;
1898 vars
->link_status
|= LINK_16GTFD
;
1903 "link speed unsupported gp_status 0x%x\n",
1908 /* Upon link speed change set the NIG into drain mode.
1909 Comes to deals with possible FIFO glitch due to clk change
1910 when speed is decreased without link down indicator */
1911 if (new_line_speed
!= vars
->line_speed
) {
1912 if (XGXS_EXT_PHY_TYPE(params
->ext_phy_config
) !=
1913 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
&&
1915 DP(NETIF_MSG_LINK
, "Internal link speed %d is"
1916 " different than the external"
1917 " link speed %d\n", new_line_speed
,
1919 vars
->phy_link_up
= 0;
1922 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
1923 + params
->port
*4, 0);
1926 vars
->line_speed
= new_line_speed
;
1927 vars
->link_status
|= LINK_STATUS_SERDES_LINK
;
1929 if ((params
->req_line_speed
== SPEED_AUTO_NEG
) &&
1930 ((XGXS_EXT_PHY_TYPE(params
->ext_phy_config
) ==
1931 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) ||
1932 (XGXS_EXT_PHY_TYPE(params
->ext_phy_config
) ==
1933 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
) ||
1934 (XGXS_EXT_PHY_TYPE(params
->ext_phy_config
) ==
1935 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
) ||
1936 (XGXS_EXT_PHY_TYPE(params
->ext_phy_config
) ==
1937 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
))) {
1938 vars
->autoneg
= AUTO_NEG_ENABLED
;
1940 if (gp_status
& MDIO_AN_CL73_OR_37_COMPLETE
) {
1941 vars
->autoneg
|= AUTO_NEG_COMPLETE
;
1942 vars
->link_status
|=
1943 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE
;
1946 vars
->autoneg
|= AUTO_NEG_PARALLEL_DETECTION_USED
;
1947 vars
->link_status
|=
1948 LINK_STATUS_PARALLEL_DETECTION_USED
;
1951 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
)
1952 vars
->link_status
|=
1953 LINK_STATUS_TX_FLOW_CONTROL_ENABLED
;
1955 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_RX
)
1956 vars
->link_status
|=
1957 LINK_STATUS_RX_FLOW_CONTROL_ENABLED
;
1959 } else { /* link_down */
1960 DP(NETIF_MSG_LINK
, "phy link down\n");
1962 vars
->phy_link_up
= 0;
1964 vars
->duplex
= DUPLEX_FULL
;
1965 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
1966 vars
->autoneg
= AUTO_NEG_DISABLED
;
1967 vars
->mac_type
= MAC_TYPE_NONE
;
1969 if ((params
->req_line_speed
== SPEED_AUTO_NEG
) &&
1970 ((XGXS_EXT_PHY_TYPE(params
->ext_phy_config
) ==
1971 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
))) {
1972 /* Check signal is detected */
1973 bnx2x_check_fallback_to_cl37(params
);
1977 DP(NETIF_MSG_LINK
, "gp_status 0x%x phy_link_up %x line_speed %x\n",
1978 gp_status
, vars
->phy_link_up
, vars
->line_speed
);
1979 DP(NETIF_MSG_LINK
, "duplex %x flow_ctrl 0x%x"
1982 vars
->flow_ctrl
, vars
->autoneg
);
1983 DP(NETIF_MSG_LINK
, "link_status 0x%x\n", vars
->link_status
);
1988 static void bnx2x_set_gmii_tx_driver(struct link_params
*params
)
1990 struct bnx2x
*bp
= params
->bp
;
1996 CL45_RD_OVER_CL22(bp
, params
->port
,
1998 MDIO_REG_BANK_OVER_1G
,
1999 MDIO_OVER_1G_LP_UP2
, &lp_up2
);
2001 /* bits [10:7] at lp_up2, positioned at [15:12] */
2002 lp_up2
= (((lp_up2
& MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK
) >>
2003 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT
) <<
2004 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT
);
2009 for (bank
= MDIO_REG_BANK_TX0
; bank
<= MDIO_REG_BANK_TX3
;
2010 bank
+= (MDIO_REG_BANK_TX1
- MDIO_REG_BANK_TX0
)) {
2011 CL45_RD_OVER_CL22(bp
, params
->port
,
2014 MDIO_TX0_TX_DRIVER
, &tx_driver
);
2016 /* replace tx_driver bits [15:12] */
2018 (tx_driver
& MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK
)) {
2019 tx_driver
&= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK
;
2020 tx_driver
|= lp_up2
;
2021 CL45_WR_OVER_CL22(bp
, params
->port
,
2024 MDIO_TX0_TX_DRIVER
, tx_driver
);
2029 static u8
bnx2x_emac_program(struct link_params
*params
,
2030 u32 line_speed
, u32 duplex
)
2032 struct bnx2x
*bp
= params
->bp
;
2033 u8 port
= params
->port
;
2036 DP(NETIF_MSG_LINK
, "setting link speed & duplex\n");
2037 bnx2x_bits_dis(bp
, GRCBASE_EMAC0
+ port
*0x400 +
2039 (EMAC_MODE_25G_MODE
|
2040 EMAC_MODE_PORT_MII_10M
|
2041 EMAC_MODE_HALF_DUPLEX
));
2042 switch (line_speed
) {
2044 mode
|= EMAC_MODE_PORT_MII_10M
;
2048 mode
|= EMAC_MODE_PORT_MII
;
2052 mode
|= EMAC_MODE_PORT_GMII
;
2056 mode
|= (EMAC_MODE_25G_MODE
| EMAC_MODE_PORT_GMII
);
2060 /* 10G not valid for EMAC */
2061 DP(NETIF_MSG_LINK
, "Invalid line_speed 0x%x\n", line_speed
);
2065 if (duplex
== DUPLEX_HALF
)
2066 mode
|= EMAC_MODE_HALF_DUPLEX
;
2068 GRCBASE_EMAC0
+ port
*0x400 + EMAC_REG_EMAC_MODE
,
2071 bnx2x_set_led(params
, LED_MODE_OPER
, line_speed
);
2075 /*****************************************************************************/
2076 /* External Phy section */
2077 /*****************************************************************************/
2078 void bnx2x_ext_phy_hw_reset(struct bnx2x
*bp
, u8 port
)
2080 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
2081 MISC_REGISTERS_GPIO_OUTPUT_LOW
, port
);
2083 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
2084 MISC_REGISTERS_GPIO_OUTPUT_HIGH
, port
);
2087 static void bnx2x_ext_phy_reset(struct link_params
*params
,
2088 struct link_vars
*vars
)
2090 struct bnx2x
*bp
= params
->bp
;
2092 u8 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
2094 DP(NETIF_MSG_LINK
, "Port %x: bnx2x_ext_phy_reset\n", params
->port
);
2095 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2096 /* The PHY reset is controled by GPIO 1
2097 * Give it 1ms of reset pulse
2099 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
2101 switch (ext_phy_type
) {
2102 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
2103 DP(NETIF_MSG_LINK
, "XGXS Direct\n");
2106 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
2107 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
2108 DP(NETIF_MSG_LINK
, "XGXS 8705/8706\n");
2110 /* Restore normal power mode*/
2111 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
2112 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
2116 bnx2x_ext_phy_hw_reset(bp
, params
->port
);
2118 bnx2x_cl45_write(bp
, params
->port
,
2122 MDIO_PMA_REG_CTRL
, 0xa040);
2125 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
:
2128 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
:
2130 /* Restore normal power mode*/
2131 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
2132 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
2135 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
2136 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
2139 bnx2x_cl45_write(bp
, params
->port
,
2147 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
2148 DP(NETIF_MSG_LINK
, "XGXS 8072\n");
2150 /* Unset Low Power Mode and SW reset */
2151 /* Restore normal power mode*/
2152 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
2153 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
2156 bnx2x_cl45_write(bp
, params
->port
,
2164 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
2165 DP(NETIF_MSG_LINK
, "XGXS 8073\n");
2167 /* Restore normal power mode*/
2168 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
2169 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
2172 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
2173 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
2177 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
2178 DP(NETIF_MSG_LINK
, "XGXS SFX7101\n");
2180 /* Restore normal power mode*/
2181 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
2182 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
2186 bnx2x_ext_phy_hw_reset(bp
, params
->port
);
2189 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
:
2190 /* Restore normal power mode*/
2191 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
2192 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
2196 bnx2x_ext_phy_hw_reset(bp
, params
->port
);
2198 bnx2x_cl45_write(bp
, params
->port
,
2205 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823
:
2207 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
2208 DP(NETIF_MSG_LINK
, "XGXS PHY Failure detected\n");
2212 DP(NETIF_MSG_LINK
, "BAD XGXS ext_phy_config 0x%x\n",
2213 params
->ext_phy_config
);
2217 } else { /* SerDes */
2218 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
2219 switch (ext_phy_type
) {
2220 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
:
2221 DP(NETIF_MSG_LINK
, "SerDes Direct\n");
2224 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482
:
2225 DP(NETIF_MSG_LINK
, "SerDes 5482\n");
2226 bnx2x_ext_phy_hw_reset(bp
, params
->port
);
2230 DP(NETIF_MSG_LINK
, "BAD SerDes ext_phy_config 0x%x\n",
2231 params
->ext_phy_config
);
2237 static void bnx2x_save_spirom_version(struct bnx2x
*bp
, u8 port
,
2238 u32 shmem_base
, u32 spirom_ver
)
2240 DP(NETIF_MSG_LINK
, "FW version 0x%x:0x%x for port %d\n",
2241 (u16
)(spirom_ver
>>16), (u16
)spirom_ver
, port
);
2242 REG_WR(bp
, shmem_base
+
2243 offsetof(struct shmem_region
,
2244 port_mb
[port
].ext_phy_fw_version
),
2248 static void bnx2x_save_bcm_spirom_ver(struct bnx2x
*bp
, u8 port
,
2249 u32 ext_phy_type
, u8 ext_phy_addr
,
2252 u16 fw_ver1
, fw_ver2
;
2254 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
, MDIO_PMA_DEVAD
,
2255 MDIO_PMA_REG_ROM_VER1
, &fw_ver1
);
2256 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
, MDIO_PMA_DEVAD
,
2257 MDIO_PMA_REG_ROM_VER2
, &fw_ver2
);
2258 bnx2x_save_spirom_version(bp
, port
, shmem_base
,
2259 (u32
)(fw_ver1
<<16 | fw_ver2
));
2263 static void bnx2x_save_8481_spirom_version(struct bnx2x
*bp
, u8 port
,
2264 u8 ext_phy_addr
, u32 shmem_base
)
2266 u16 val
, fw_ver1
, fw_ver2
, cnt
;
2267 /* For the 32 bits registers in 8481, access via MDIO2ARM interface.*/
2268 /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
2269 bnx2x_cl45_write(bp
, port
,
2270 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
,
2271 ext_phy_addr
, MDIO_PMA_DEVAD
,
2273 bnx2x_cl45_write(bp
, port
,
2274 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
,
2279 bnx2x_cl45_write(bp
, port
,
2280 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
,
2285 bnx2x_cl45_write(bp
, port
,
2286 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
,
2291 bnx2x_cl45_write(bp
, port
,
2292 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
,
2298 for (cnt
= 0; cnt
< 100; cnt
++) {
2299 bnx2x_cl45_read(bp
, port
,
2300 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
,
2310 DP(NETIF_MSG_LINK
, "Unable to read 8481 phy fw version(1)\n");
2311 bnx2x_save_spirom_version(bp
, port
,
2317 /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
2318 bnx2x_cl45_write(bp
, port
,
2319 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
,
2320 ext_phy_addr
, MDIO_PMA_DEVAD
,
2322 bnx2x_cl45_write(bp
, port
,
2323 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
,
2324 ext_phy_addr
, MDIO_PMA_DEVAD
,
2326 bnx2x_cl45_write(bp
, port
,
2327 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
,
2328 ext_phy_addr
, MDIO_PMA_DEVAD
,
2330 for (cnt
= 0; cnt
< 100; cnt
++) {
2331 bnx2x_cl45_read(bp
, port
,
2332 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
,
2342 DP(NETIF_MSG_LINK
, "Unable to read 8481 phy fw version(2)\n");
2343 bnx2x_save_spirom_version(bp
, port
,
2348 /* lower 16 bits of the register SPI_FW_STATUS */
2349 bnx2x_cl45_read(bp
, port
,
2350 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
,
2355 /* upper 16 bits of register SPI_FW_STATUS */
2356 bnx2x_cl45_read(bp
, port
,
2357 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
,
2363 bnx2x_save_spirom_version(bp
, port
,
2364 shmem_base
, (fw_ver2
<<16) | fw_ver1
);
2367 static void bnx2x_bcm8072_external_rom_boot(struct link_params
*params
)
2369 struct bnx2x
*bp
= params
->bp
;
2370 u8 port
= params
->port
;
2371 u8 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
2372 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2374 /* Need to wait 200ms after reset */
2376 /* Boot port from external ROM
2377 * Set ser_boot_ctl bit in the MISC_CTRL1 register
2379 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2381 MDIO_PMA_REG_MISC_CTRL1
, 0x0001);
2383 /* Reset internal microprocessor */
2384 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2386 MDIO_PMA_REG_GEN_CTRL
,
2387 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP
);
2388 /* set micro reset = 0 */
2389 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2391 MDIO_PMA_REG_GEN_CTRL
,
2392 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET
);
2393 /* Reset internal microprocessor */
2394 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2396 MDIO_PMA_REG_GEN_CTRL
,
2397 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP
);
2398 /* wait for 100ms for code download via SPI port */
2401 /* Clear ser_boot_ctl bit */
2402 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2404 MDIO_PMA_REG_MISC_CTRL1
, 0x0000);
2408 bnx2x_save_bcm_spirom_ver(bp
, port
,
2411 params
->shmem_base
);
2414 static u8
bnx2x_8073_is_snr_needed(struct link_params
*params
)
2416 /* This is only required for 8073A1, version 102 only */
2418 struct bnx2x
*bp
= params
->bp
;
2419 u8 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
2422 /* Read 8073 HW revision*/
2423 bnx2x_cl45_read(bp
, params
->port
,
2424 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2427 MDIO_PMA_REG_8073_CHIP_REV
, &val
);
2430 /* No need to workaround in 8073 A1 */
2434 bnx2x_cl45_read(bp
, params
->port
,
2435 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2438 MDIO_PMA_REG_ROM_VER2
, &val
);
2440 /* SNR should be applied only for version 0x102 */
2447 static u8
bnx2x_bcm8073_xaui_wa(struct link_params
*params
)
2449 struct bnx2x
*bp
= params
->bp
;
2450 u8 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
2451 u16 val
, cnt
, cnt1
;
2453 bnx2x_cl45_read(bp
, params
->port
,
2454 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2457 MDIO_PMA_REG_8073_CHIP_REV
, &val
);
2460 /* No need to workaround in 8073 A1 */
2463 /* XAUI workaround in 8073 A0: */
2465 /* After loading the boot ROM and restarting Autoneg,
2466 poll Dev1, Reg $C820: */
2468 for (cnt
= 0; cnt
< 1000; cnt
++) {
2469 bnx2x_cl45_read(bp
, params
->port
,
2470 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2473 MDIO_PMA_REG_8073_SPEED_LINK_STATUS
,
2475 /* If bit [14] = 0 or bit [13] = 0, continue on with
2476 system initialization (XAUI work-around not required,
2477 as these bits indicate 2.5G or 1G link up). */
2478 if (!(val
& (1<<14)) || !(val
& (1<<13))) {
2479 DP(NETIF_MSG_LINK
, "XAUI work-around not required\n");
2481 } else if (!(val
& (1<<15))) {
2482 DP(NETIF_MSG_LINK
, "clc bit 15 went off\n");
2483 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2484 it's MSB (bit 15) goes to 1 (indicating that the
2485 XAUI workaround has completed),
2486 then continue on with system initialization.*/
2487 for (cnt1
= 0; cnt1
< 1000; cnt1
++) {
2488 bnx2x_cl45_read(bp
, params
->port
,
2489 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2492 MDIO_PMA_REG_8073_XAUI_WA
, &val
);
2493 if (val
& (1<<15)) {
2495 "XAUI workaround has completed\n");
2504 DP(NETIF_MSG_LINK
, "Warning: XAUI work-around timeout !!!\n");
2508 static void bnx2x_bcm8073_bcm8727_external_rom_boot(struct bnx2x
*bp
, u8 port
,
2513 /* Boot port from external ROM */
2515 bnx2x_cl45_write(bp
, port
,
2519 MDIO_PMA_REG_GEN_CTRL
,
2522 /* ucode reboot and rst */
2523 bnx2x_cl45_write(bp
, port
,
2527 MDIO_PMA_REG_GEN_CTRL
,
2530 bnx2x_cl45_write(bp
, port
,
2534 MDIO_PMA_REG_MISC_CTRL1
, 0x0001);
2536 /* Reset internal microprocessor */
2537 bnx2x_cl45_write(bp
, port
,
2541 MDIO_PMA_REG_GEN_CTRL
,
2542 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET
);
2544 /* Release srst bit */
2545 bnx2x_cl45_write(bp
, port
,
2549 MDIO_PMA_REG_GEN_CTRL
,
2550 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP
);
2552 /* wait for 100ms for code download via SPI port */
2555 /* Clear ser_boot_ctl bit */
2556 bnx2x_cl45_write(bp
, port
,
2560 MDIO_PMA_REG_MISC_CTRL1
, 0x0000);
2562 bnx2x_save_bcm_spirom_ver(bp
, port
,
2568 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x
*bp
, u8 port
,
2572 bnx2x_bcm8073_bcm8727_external_rom_boot(bp
, port
, ext_phy_addr
,
2573 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2577 static void bnx2x_bcm8727_external_rom_boot(struct bnx2x
*bp
, u8 port
,
2581 bnx2x_bcm8073_bcm8727_external_rom_boot(bp
, port
, ext_phy_addr
,
2582 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
2587 static void bnx2x_bcm8726_external_rom_boot(struct link_params
*params
)
2589 struct bnx2x
*bp
= params
->bp
;
2590 u8 port
= params
->port
;
2591 u8 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
2592 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2594 /* Need to wait 100ms after reset */
2597 /* Micro controller re-boot */
2598 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2600 MDIO_PMA_REG_GEN_CTRL
,
2603 /* Set soft reset */
2604 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2606 MDIO_PMA_REG_GEN_CTRL
,
2607 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET
);
2609 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2611 MDIO_PMA_REG_MISC_CTRL1
, 0x0001);
2613 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2615 MDIO_PMA_REG_GEN_CTRL
,
2616 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP
);
2618 /* wait for 150ms for microcode load */
2621 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
2622 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2624 MDIO_PMA_REG_MISC_CTRL1
, 0x0000);
2627 bnx2x_save_bcm_spirom_ver(bp
, port
,
2630 params
->shmem_base
);
2633 static void bnx2x_sfp_set_transmitter(struct bnx2x
*bp
, u8 port
,
2634 u32 ext_phy_type
, u8 ext_phy_addr
,
2639 DP(NETIF_MSG_LINK
, "Setting transmitter tx_en=%x for port %x\n",
2641 /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
2642 bnx2x_cl45_read(bp
, port
,
2646 MDIO_PMA_REG_PHY_IDENTIFIER
,
2654 bnx2x_cl45_write(bp
, port
,
2658 MDIO_PMA_REG_PHY_IDENTIFIER
,
2662 static u8
bnx2x_8726_read_sfp_module_eeprom(struct link_params
*params
,
2663 u16 addr
, u8 byte_cnt
, u8
*o_buf
)
2665 struct bnx2x
*bp
= params
->bp
;
2668 u8 port
= params
->port
;
2669 u8 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
2670 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2672 if (byte_cnt
> 16) {
2673 DP(NETIF_MSG_LINK
, "Reading from eeprom is"
2674 " is limited to 0xf\n");
2677 /* Set the read command byte count */
2678 bnx2x_cl45_write(bp
, port
,
2682 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT
,
2683 (byte_cnt
| 0xa000));
2685 /* Set the read command address */
2686 bnx2x_cl45_write(bp
, port
,
2690 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR
,
2693 /* Activate read command */
2694 bnx2x_cl45_write(bp
, port
,
2698 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL
,
2701 /* Wait up to 500us for command complete status */
2702 for (i
= 0; i
< 100; i
++) {
2703 bnx2x_cl45_read(bp
, port
,
2707 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL
, &val
);
2708 if ((val
& MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK
) ==
2709 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE
)
2714 if ((val
& MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK
) !=
2715 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE
) {
2717 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2718 (val
& MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK
));
2722 /* Read the buffer */
2723 for (i
= 0; i
< byte_cnt
; i
++) {
2724 bnx2x_cl45_read(bp
, port
,
2728 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF
+ i
, &val
);
2729 o_buf
[i
] = (u8
)(val
& MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK
);
2732 for (i
= 0; i
< 100; i
++) {
2733 bnx2x_cl45_read(bp
, port
,
2737 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL
, &val
);
2738 if ((val
& MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK
) ==
2739 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE
)
2746 static u8
bnx2x_8727_read_sfp_module_eeprom(struct link_params
*params
,
2747 u16 addr
, u8 byte_cnt
, u8
*o_buf
)
2749 struct bnx2x
*bp
= params
->bp
;
2751 u8 port
= params
->port
;
2752 u8 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
2753 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2755 if (byte_cnt
> 16) {
2756 DP(NETIF_MSG_LINK
, "Reading from eeprom is"
2757 " is limited to 0xf\n");
2761 /* Need to read from 1.8000 to clear it */
2762 bnx2x_cl45_read(bp
, port
,
2763 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
2766 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL
,
2769 /* Set the read command byte count */
2770 bnx2x_cl45_write(bp
, port
,
2774 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT
,
2775 ((byte_cnt
< 2) ? 2 : byte_cnt
));
2777 /* Set the read command address */
2778 bnx2x_cl45_write(bp
, port
,
2782 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR
,
2784 /* Set the destination address */
2785 bnx2x_cl45_write(bp
, port
,
2790 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF
);
2792 /* Activate read command */
2793 bnx2x_cl45_write(bp
, port
,
2797 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL
,
2799 /* Wait appropriate time for two-wire command to finish before
2800 polling the status register */
2803 /* Wait up to 500us for command complete status */
2804 for (i
= 0; i
< 100; i
++) {
2805 bnx2x_cl45_read(bp
, port
,
2809 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL
, &val
);
2810 if ((val
& MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK
) ==
2811 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE
)
2816 if ((val
& MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK
) !=
2817 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE
) {
2819 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2820 (val
& MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK
));
2824 /* Read the buffer */
2825 for (i
= 0; i
< byte_cnt
; i
++) {
2826 bnx2x_cl45_read(bp
, port
,
2830 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF
+ i
, &val
);
2831 o_buf
[i
] = (u8
)(val
& MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK
);
2834 for (i
= 0; i
< 100; i
++) {
2835 bnx2x_cl45_read(bp
, port
,
2839 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL
, &val
);
2840 if ((val
& MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK
) ==
2841 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE
)
2849 u8
bnx2x_read_sfp_module_eeprom(struct link_params
*params
, u16 addr
,
2850 u8 byte_cnt
, u8
*o_buf
)
2852 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2854 if (ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
)
2855 return bnx2x_8726_read_sfp_module_eeprom(params
, addr
,
2857 else if (ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
)
2858 return bnx2x_8727_read_sfp_module_eeprom(params
, addr
,
2863 static u8
bnx2x_get_edc_mode(struct link_params
*params
,
2866 struct bnx2x
*bp
= params
->bp
;
2867 u8 val
, check_limiting_mode
= 0;
2868 *edc_mode
= EDC_MODE_LIMITING
;
2870 /* First check for copper cable */
2871 if (bnx2x_read_sfp_module_eeprom(params
,
2872 SFP_EEPROM_CON_TYPE_ADDR
,
2875 DP(NETIF_MSG_LINK
, "Failed to read from SFP+ module EEPROM\n");
2880 case SFP_EEPROM_CON_TYPE_VAL_COPPER
:
2882 u8 copper_module_type
;
2884 /* Check if its active cable( includes SFP+ module)
2886 if (bnx2x_read_sfp_module_eeprom(params
,
2887 SFP_EEPROM_FC_TX_TECH_ADDR
,
2889 &copper_module_type
) !=
2892 "Failed to read copper-cable-type"
2893 " from SFP+ EEPROM\n");
2897 if (copper_module_type
&
2898 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE
) {
2899 DP(NETIF_MSG_LINK
, "Active Copper cable detected\n");
2900 check_limiting_mode
= 1;
2901 } else if (copper_module_type
&
2902 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE
) {
2903 DP(NETIF_MSG_LINK
, "Passive Copper"
2904 " cable detected\n");
2906 EDC_MODE_PASSIVE_DAC
;
2908 DP(NETIF_MSG_LINK
, "Unknown copper-cable-"
2909 "type 0x%x !!!\n", copper_module_type
);
2914 case SFP_EEPROM_CON_TYPE_VAL_LC
:
2915 DP(NETIF_MSG_LINK
, "Optic module detected\n");
2916 check_limiting_mode
= 1;
2919 DP(NETIF_MSG_LINK
, "Unable to determine module type 0x%x !!!\n",
2924 if (check_limiting_mode
) {
2925 u8 options
[SFP_EEPROM_OPTIONS_SIZE
];
2926 if (bnx2x_read_sfp_module_eeprom(params
,
2927 SFP_EEPROM_OPTIONS_ADDR
,
2928 SFP_EEPROM_OPTIONS_SIZE
,
2930 DP(NETIF_MSG_LINK
, "Failed to read Option"
2931 " field from module EEPROM\n");
2934 if ((options
[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK
))
2935 *edc_mode
= EDC_MODE_LINEAR
;
2937 *edc_mode
= EDC_MODE_LIMITING
;
2939 DP(NETIF_MSG_LINK
, "EDC mode is set to 0x%x\n", *edc_mode
);
2943 /* This function read the relevant field from the module ( SFP+ ),
2944 and verify it is compliant with this board */
2945 static u8
bnx2x_verify_sfp_module(struct link_params
*params
)
2947 struct bnx2x
*bp
= params
->bp
;
2950 char vendor_name
[SFP_EEPROM_VENDOR_NAME_SIZE
+1];
2951 char vendor_pn
[SFP_EEPROM_PART_NO_SIZE
+1];
2953 val
= REG_RD(bp
, params
->shmem_base
+
2954 offsetof(struct shmem_region
, dev_info
.
2955 port_feature_config
[params
->port
].config
));
2956 if ((val
& PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK
) ==
2957 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT
) {
2958 DP(NETIF_MSG_LINK
, "NOT enforcing module verification\n");
2962 /* Ask the FW to validate the module */
2963 if (!(params
->feature_config_flags
&
2964 FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY
)) {
2965 DP(NETIF_MSG_LINK
, "FW does not support OPT MDL "
2970 fw_resp
= bnx2x_fw_command(bp
, DRV_MSG_CODE_VRFY_OPT_MDL
);
2971 if (fw_resp
== FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS
) {
2972 DP(NETIF_MSG_LINK
, "Approved module\n");
2976 /* format the warning message */
2977 if (bnx2x_read_sfp_module_eeprom(params
,
2978 SFP_EEPROM_VENDOR_NAME_ADDR
,
2979 SFP_EEPROM_VENDOR_NAME_SIZE
,
2981 vendor_name
[0] = '\0';
2983 vendor_name
[SFP_EEPROM_VENDOR_NAME_SIZE
] = '\0';
2984 if (bnx2x_read_sfp_module_eeprom(params
,
2985 SFP_EEPROM_PART_NO_ADDR
,
2986 SFP_EEPROM_PART_NO_SIZE
,
2988 vendor_pn
[0] = '\0';
2990 vendor_pn
[SFP_EEPROM_PART_NO_SIZE
] = '\0';
2992 netdev_info(bp
->dev
, "Warning: Unqualified SFP+ module detected, Port %d from %s part number %s\n",
2993 params
->port
, vendor_name
, vendor_pn
);
2997 static u8
bnx2x_bcm8726_set_limiting_mode(struct link_params
*params
,
3000 struct bnx2x
*bp
= params
->bp
;
3001 u8 port
= params
->port
;
3002 u8 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
3003 u16 cur_limiting_mode
;
3005 bnx2x_cl45_read(bp
, port
,
3006 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
,
3009 MDIO_PMA_REG_ROM_VER2
,
3010 &cur_limiting_mode
);
3011 DP(NETIF_MSG_LINK
, "Current Limiting mode is 0x%x\n",
3014 if (edc_mode
== EDC_MODE_LIMITING
) {
3016 "Setting LIMITING MODE\n");
3017 bnx2x_cl45_write(bp
, port
,
3018 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
,
3021 MDIO_PMA_REG_ROM_VER2
,
3023 } else { /* LRM mode ( default )*/
3025 DP(NETIF_MSG_LINK
, "Setting LRM MODE\n");
3027 /* Changing to LRM mode takes quite few seconds.
3028 So do it only if current mode is limiting
3029 ( default is LRM )*/
3030 if (cur_limiting_mode
!= EDC_MODE_LIMITING
)
3033 bnx2x_cl45_write(bp
, port
,
3034 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
,
3037 MDIO_PMA_REG_LRM_MODE
,
3039 bnx2x_cl45_write(bp
, port
,
3040 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
,
3043 MDIO_PMA_REG_ROM_VER2
,
3045 bnx2x_cl45_write(bp
, port
,
3046 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
,
3049 MDIO_PMA_REG_MISC_CTRL0
,
3051 bnx2x_cl45_write(bp
, port
,
3052 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
,
3055 MDIO_PMA_REG_LRM_MODE
,
3061 static u8
bnx2x_bcm8727_set_limiting_mode(struct link_params
*params
,
3064 struct bnx2x
*bp
= params
->bp
;
3065 u8 port
= params
->port
;
3068 u8 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
3070 bnx2x_cl45_read(bp
, port
,
3071 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
3074 MDIO_PMA_REG_PHY_IDENTIFIER
,
3077 bnx2x_cl45_write(bp
, port
,
3078 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
3081 MDIO_PMA_REG_PHY_IDENTIFIER
,
3082 (phy_identifier
& ~(1<<9)));
3084 bnx2x_cl45_read(bp
, port
,
3085 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
3088 MDIO_PMA_REG_ROM_VER2
,
3090 /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
3091 bnx2x_cl45_write(bp
, port
,
3092 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
3095 MDIO_PMA_REG_ROM_VER2
,
3096 (rom_ver2_val
& 0xff00) | (edc_mode
& 0x00ff));
3098 bnx2x_cl45_write(bp
, port
,
3099 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
3102 MDIO_PMA_REG_PHY_IDENTIFIER
,
3103 (phy_identifier
| (1<<9)));
3109 static u8
bnx2x_wait_for_sfp_module_initialized(struct link_params
*params
)
3112 struct bnx2x
*bp
= params
->bp
;
3114 /* Initialization time after hot-plug may take up to 300ms for some
3115 phys type ( e.g. JDSU ) */
3116 for (timeout
= 0; timeout
< 60; timeout
++) {
3117 if (bnx2x_read_sfp_module_eeprom(params
, 1, 1, &val
)
3119 DP(NETIF_MSG_LINK
, "SFP+ module initialization "
3120 "took %d ms\n", timeout
* 5);
3128 static void bnx2x_8727_power_module(struct bnx2x
*bp
,
3129 struct link_params
*params
,
3130 u8 ext_phy_addr
, u8 is_power_up
) {
3131 /* Make sure GPIOs are not using for LED mode */
3133 u8 port
= params
->port
;
3135 * In the GPIO register, bit 4 is use to detemine if the GPIOs are
3136 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
3138 * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
3139 * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
3140 * where the 1st bit is the over-current(only input), and 2nd bit is
3141 * for power( only output )
3145 * In case of NOC feature is disabled and power is up, set GPIO control
3146 * as input to enable listening of over-current indication
3149 if (!(params
->feature_config_flags
&
3150 FEATURE_CONFIG_BCM8727_NOC
) && is_power_up
)
3154 * Set GPIO control to OUTPUT, and set the power bit
3155 * to according to the is_power_up
3157 val
= ((!(is_power_up
)) << 1);
3159 bnx2x_cl45_write(bp
, port
,
3160 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
3163 MDIO_PMA_REG_8727_GPIO_CTRL
,
3167 static u8
bnx2x_sfp_module_detection(struct link_params
*params
)
3169 struct bnx2x
*bp
= params
->bp
;
3172 u8 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
3173 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3174 u32 val
= REG_RD(bp
, params
->shmem_base
+
3175 offsetof(struct shmem_region
, dev_info
.
3176 port_feature_config
[params
->port
].config
));
3178 DP(NETIF_MSG_LINK
, "SFP+ module plugged in/out detected on port %d\n",
3181 if (bnx2x_get_edc_mode(params
, &edc_mode
) != 0) {
3182 DP(NETIF_MSG_LINK
, "Failed to get valid module type\n");
3184 } else if (bnx2x_verify_sfp_module(params
) !=
3186 /* check SFP+ module compatibility */
3187 DP(NETIF_MSG_LINK
, "Module verification failed!!\n");
3189 /* Turn on fault module-detected led */
3190 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_0
,
3191 MISC_REGISTERS_GPIO_HIGH
,
3193 if ((ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
) &&
3194 ((val
& PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK
) ==
3195 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN
)) {
3196 /* Shutdown SFP+ module */
3197 DP(NETIF_MSG_LINK
, "Shutdown SFP+ module!!\n");
3198 bnx2x_8727_power_module(bp
, params
,
3203 /* Turn off fault module-detected led */
3204 DP(NETIF_MSG_LINK
, "Turn off fault module-detected led\n");
3205 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_0
,
3206 MISC_REGISTERS_GPIO_LOW
,
3210 /* power up the SFP module */
3211 if (ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
)
3212 bnx2x_8727_power_module(bp
, params
, ext_phy_addr
, 1);
3214 /* Check and set limiting mode / LRM mode on 8726.
3215 On 8727 it is done automatically */
3216 if (ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
)
3217 bnx2x_bcm8726_set_limiting_mode(params
, edc_mode
);
3219 bnx2x_bcm8727_set_limiting_mode(params
, edc_mode
);
3221 * Enable transmit for this module if the module is approved, or
3222 * if unapproved modules should also enable the Tx laser
3225 (val
& PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK
) !=
3226 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER
)
3227 bnx2x_sfp_set_transmitter(bp
, params
->port
,
3228 ext_phy_type
, ext_phy_addr
, 1);
3230 bnx2x_sfp_set_transmitter(bp
, params
->port
,
3231 ext_phy_type
, ext_phy_addr
, 0);
3236 void bnx2x_handle_module_detect_int(struct link_params
*params
)
3238 struct bnx2x
*bp
= params
->bp
;
3240 u8 port
= params
->port
;
3242 /* Set valid module led off */
3243 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_0
,
3244 MISC_REGISTERS_GPIO_HIGH
,
3247 /* Get current gpio val refelecting module plugged in / out*/
3248 gpio_val
= bnx2x_get_gpio(bp
, MISC_REGISTERS_GPIO_3
, port
);
3250 /* Call the handling function in case module is detected */
3251 if (gpio_val
== 0) {
3253 bnx2x_set_gpio_int(bp
, MISC_REGISTERS_GPIO_3
,
3254 MISC_REGISTERS_GPIO_INT_OUTPUT_CLR
,
3257 if (bnx2x_wait_for_sfp_module_initialized(params
) ==
3259 bnx2x_sfp_module_detection(params
);
3261 DP(NETIF_MSG_LINK
, "SFP+ module is not initialized\n");
3263 u8 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
3266 XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3267 u32 val
= REG_RD(bp
, params
->shmem_base
+
3268 offsetof(struct shmem_region
, dev_info
.
3269 port_feature_config
[params
->port
].
3272 bnx2x_set_gpio_int(bp
, MISC_REGISTERS_GPIO_3
,
3273 MISC_REGISTERS_GPIO_INT_OUTPUT_SET
,
3275 /* Module was plugged out. */
3276 /* Disable transmit for this module */
3277 if ((val
& PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK
) ==
3278 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER
)
3279 bnx2x_sfp_set_transmitter(bp
, params
->port
,
3280 ext_phy_type
, ext_phy_addr
, 0);
3284 static void bnx2x_bcm807x_force_10G(struct link_params
*params
)
3286 struct bnx2x
*bp
= params
->bp
;
3287 u8 port
= params
->port
;
3288 u8 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
3289 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3291 /* Force KR or KX */
3292 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3296 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3298 MDIO_PMA_REG_10G_CTRL2
,
3300 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3302 MDIO_PMA_REG_BCM_CTRL
,
3304 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3310 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params
*params
)
3312 struct bnx2x
*bp
= params
->bp
;
3313 u8 port
= params
->port
;
3315 u8 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
3316 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3318 bnx2x_cl45_read(bp
, params
->port
,
3319 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
3322 MDIO_PMA_REG_8073_CHIP_REV
, &val
);
3325 /* Mustn't set low power mode in 8073 A0 */
3329 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
3330 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
3332 MDIO_XS_PLL_SEQUENCER
, &val
);
3334 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3335 MDIO_XS_DEVAD
, MDIO_XS_PLL_SEQUENCER
, val
);
3338 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3339 MDIO_XS_DEVAD
, 0x805E, 0x1077);
3340 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3341 MDIO_XS_DEVAD
, 0x805D, 0x0000);
3342 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3343 MDIO_XS_DEVAD
, 0x805C, 0x030B);
3344 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3345 MDIO_XS_DEVAD
, 0x805B, 0x1240);
3346 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3347 MDIO_XS_DEVAD
, 0x805A, 0x2490);
3350 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3351 MDIO_XS_DEVAD
, 0x80A7, 0x0C74);
3352 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3353 MDIO_XS_DEVAD
, 0x80A6, 0x9041);
3354 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3355 MDIO_XS_DEVAD
, 0x80A5, 0x4640);
3358 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3359 MDIO_XS_DEVAD
, 0x80FE, 0x01C4);
3360 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3361 MDIO_XS_DEVAD
, 0x80FD, 0x9249);
3362 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3363 MDIO_XS_DEVAD
, 0x80FC, 0x2015);
3365 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
3366 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
3368 MDIO_XS_PLL_SEQUENCER
, &val
);
3370 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3371 MDIO_XS_DEVAD
, MDIO_XS_PLL_SEQUENCER
, val
);
3374 static void bnx2x_8073_set_pause_cl37(struct link_params
*params
,
3375 struct link_vars
*vars
)
3377 struct bnx2x
*bp
= params
->bp
;
3379 u8 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
3380 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3382 bnx2x_cl45_read(bp
, params
->port
,
3386 MDIO_AN_REG_CL37_FC_LD
, &cl37_val
);
3388 cl37_val
&= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
3389 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3391 if ((vars
->ieee_fc
&
3392 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC
) ==
3393 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC
) {
3394 cl37_val
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC
;
3396 if ((vars
->ieee_fc
&
3397 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) ==
3398 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) {
3399 cl37_val
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
;
3401 if ((vars
->ieee_fc
&
3402 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) ==
3403 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) {
3404 cl37_val
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
3407 "Ext phy AN advertize cl37 0x%x\n", cl37_val
);
3409 bnx2x_cl45_write(bp
, params
->port
,
3413 MDIO_AN_REG_CL37_FC_LD
, cl37_val
);
3417 static void bnx2x_ext_phy_set_pause(struct link_params
*params
,
3418 struct link_vars
*vars
)
3420 struct bnx2x
*bp
= params
->bp
;
3422 u8 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
3423 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3425 /* read modify write pause advertizing */
3426 bnx2x_cl45_read(bp
, params
->port
,
3430 MDIO_AN_REG_ADV_PAUSE
, &val
);
3432 val
&= ~MDIO_AN_REG_ADV_PAUSE_BOTH
;
3434 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3436 if ((vars
->ieee_fc
&
3437 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) ==
3438 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) {
3439 val
|= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC
;
3441 if ((vars
->ieee_fc
&
3442 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) ==
3443 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) {
3445 MDIO_AN_REG_ADV_PAUSE_PAUSE
;
3448 "Ext phy AN advertize 0x%x\n", val
);
3449 bnx2x_cl45_write(bp
, params
->port
,
3453 MDIO_AN_REG_ADV_PAUSE
, val
);
3455 static void bnx2x_set_preemphasis(struct link_params
*params
)
3458 struct bnx2x
*bp
= params
->bp
;
3460 for (bank
= MDIO_REG_BANK_RX0
, i
= 0; bank
<= MDIO_REG_BANK_RX3
;
3461 bank
+= (MDIO_REG_BANK_RX1
-MDIO_REG_BANK_RX0
), i
++) {
3462 CL45_WR_OVER_CL22(bp
, params
->port
,
3465 MDIO_RX0_RX_EQ_BOOST
,
3466 params
->xgxs_config_rx
[i
]);
3469 for (bank
= MDIO_REG_BANK_TX0
, i
= 0; bank
<= MDIO_REG_BANK_TX3
;
3470 bank
+= (MDIO_REG_BANK_TX1
- MDIO_REG_BANK_TX0
), i
++) {
3471 CL45_WR_OVER_CL22(bp
, params
->port
,
3475 params
->xgxs_config_tx
[i
]);
3480 static void bnx2x_8481_set_led4(struct link_params
*params
,
3481 u32 ext_phy_type
, u8 ext_phy_addr
)
3483 struct bnx2x
*bp
= params
->bp
;
3485 /* PHYC_CTL_LED_CTL */
3486 bnx2x_cl45_write(bp
, params
->port
,
3490 MDIO_PMA_REG_8481_LINK_SIGNAL
, 0xa482);
3492 /* Unmask LED4 for 10G link */
3493 bnx2x_cl45_write(bp
, params
->port
,
3497 MDIO_PMA_REG_8481_SIGNAL_MASK
, (1<<6));
3498 /* 'Interrupt Mask' */
3499 bnx2x_cl45_write(bp
, params
->port
,
3505 static void bnx2x_8481_set_legacy_led_mode(struct link_params
*params
,
3506 u32 ext_phy_type
, u8 ext_phy_addr
)
3508 struct bnx2x
*bp
= params
->bp
;
3510 /* LED1 (10G Link): Disable LED1 when 10/100/1000 link */
3511 /* LED2 (1G/100/10 Link): Enable LED2 when 10/100/1000 link) */
3512 bnx2x_cl45_write(bp
, params
->port
,
3516 MDIO_AN_REG_8481_LEGACY_SHADOW
,
3517 (1<<15) | (0xd << 10) | (0xc<<4) | 0xe);
3520 static void bnx2x_8481_set_10G_led_mode(struct link_params
*params
,
3521 u32 ext_phy_type
, u8 ext_phy_addr
)
3523 struct bnx2x
*bp
= params
->bp
;
3526 /* LED1 (10G Link) */
3527 /* Enable continuse based on source 7(10G-link) */
3528 bnx2x_cl45_read(bp
, params
->port
,
3532 MDIO_PMA_REG_8481_LINK_SIGNAL
,
3534 /* Set bit 2 to 0, and bits [1:0] to 10 */
3535 val1
&= ~((1<<0) | (1<<2) | (1<<7)); /* Clear bits 0,2,7*/
3536 val1
|= ((1<<1) | (1<<6)); /* Set bit 1, 6 */
3538 bnx2x_cl45_write(bp
, params
->port
,
3542 MDIO_PMA_REG_8481_LINK_SIGNAL
,
3545 /* Unmask LED1 for 10G link */
3546 bnx2x_cl45_read(bp
, params
->port
,
3550 MDIO_PMA_REG_8481_LED1_MASK
,
3552 /* Set bit 2 to 0, and bits [1:0] to 10 */
3554 bnx2x_cl45_write(bp
, params
->port
,
3558 MDIO_PMA_REG_8481_LED1_MASK
,
3561 /* LED2 (1G/100/10G Link) */
3562 /* Mask LED2 for 10G link */
3563 bnx2x_cl45_write(bp
, params
->port
,
3567 MDIO_PMA_REG_8481_LED2_MASK
,
3570 /* Unmask LED3 for 10G link */
3571 bnx2x_cl45_write(bp
, params
->port
,
3575 MDIO_PMA_REG_8481_LED3_MASK
,
3577 bnx2x_cl45_write(bp
, params
->port
,
3581 MDIO_PMA_REG_8481_LED3_BLINK
,
3586 static void bnx2x_init_internal_phy(struct link_params
*params
,
3587 struct link_vars
*vars
,
3590 struct bnx2x
*bp
= params
->bp
;
3592 if (!(vars
->phy_flags
& PHY_SGMII_FLAG
)) {
3593 if ((XGXS_EXT_PHY_TYPE(params
->ext_phy_config
) ==
3594 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) &&
3595 (params
->feature_config_flags
&
3596 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED
))
3597 bnx2x_set_preemphasis(params
);
3599 /* forced speed requested? */
3600 if (vars
->line_speed
!= SPEED_AUTO_NEG
||
3601 ((XGXS_EXT_PHY_TYPE(params
->ext_phy_config
) ==
3602 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) &&
3603 params
->loopback_mode
== LOOPBACK_EXT
)) {
3604 DP(NETIF_MSG_LINK
, "not SGMII, no AN\n");
3606 /* disable autoneg */
3607 bnx2x_set_autoneg(params
, vars
, 0);
3609 /* program speed and duplex */
3610 bnx2x_program_serdes(params
, vars
);
3612 } else { /* AN_mode */
3613 DP(NETIF_MSG_LINK
, "not SGMII, AN\n");
3616 bnx2x_set_brcm_cl37_advertisment(params
);
3618 /* program duplex & pause advertisement (for aneg) */
3619 bnx2x_set_ieee_aneg_advertisment(params
,
3622 /* enable autoneg */
3623 bnx2x_set_autoneg(params
, vars
, enable_cl73
);
3625 /* enable and restart AN */
3626 bnx2x_restart_autoneg(params
, enable_cl73
);
3629 } else { /* SGMII mode */
3630 DP(NETIF_MSG_LINK
, "SGMII\n");
3632 bnx2x_initialize_sgmii_process(params
, vars
);
3636 static u8
bnx2x_ext_phy_init(struct link_params
*params
, struct link_vars
*vars
)
3638 struct bnx2x
*bp
= params
->bp
;
3646 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
3647 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
3649 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3650 /* Make sure that the soft reset is off (expect for the 8072:
3651 * due to the lock, it will be done inside the specific
3654 if ((ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) &&
3655 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
) &&
3656 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
) &&
3657 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
) &&
3658 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
)) {
3659 /* Wait for soft reset to get cleared upto 1 sec */
3660 for (cnt
= 0; cnt
< 1000; cnt
++) {
3661 bnx2x_cl45_read(bp
, params
->port
,
3665 MDIO_PMA_REG_CTRL
, &ctrl
);
3666 if (!(ctrl
& (1<<15)))
3670 DP(NETIF_MSG_LINK
, "control reg 0x%x (after %d ms)\n",
3674 switch (ext_phy_type
) {
3675 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
3678 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
3679 DP(NETIF_MSG_LINK
, "XGXS 8705\n");
3681 bnx2x_cl45_write(bp
, params
->port
,
3685 MDIO_PMA_REG_MISC_CTRL
,
3687 bnx2x_cl45_write(bp
, params
->port
,
3691 MDIO_PMA_REG_PHY_IDENTIFIER
,
3693 bnx2x_cl45_write(bp
, params
->port
,
3697 MDIO_PMA_REG_CMU_PLL_BYPASS
,
3699 bnx2x_cl45_write(bp
, params
->port
,
3703 MDIO_WIS_REG_LASI_CNTL
, 0x1);
3705 /* BCM8705 doesn't have microcode, hence the 0 */
3706 bnx2x_save_spirom_version(bp
, params
->port
,
3707 params
->shmem_base
, 0);
3710 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
3711 /* Wait until fw is loaded */
3712 for (cnt
= 0; cnt
< 100; cnt
++) {
3713 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3714 ext_phy_addr
, MDIO_PMA_DEVAD
,
3715 MDIO_PMA_REG_ROM_VER1
, &val
);
3720 DP(NETIF_MSG_LINK
, "XGXS 8706 is initialized "
3721 "after %d ms\n", cnt
);
3722 if ((params
->feature_config_flags
&
3723 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED
)) {
3726 for (i
= 0; i
< 4; i
++) {
3727 reg
= MDIO_XS_8706_REG_BANK_RX0
+
3728 i
*(MDIO_XS_8706_REG_BANK_RX1
-
3729 MDIO_XS_8706_REG_BANK_RX0
);
3730 bnx2x_cl45_read(bp
, params
->port
,
3735 /* Clear first 3 bits of the control */
3737 /* Set control bits according to
3739 val
|= (params
->xgxs_config_rx
[i
] &
3741 DP(NETIF_MSG_LINK
, "Setting RX"
3742 "Equalizer to BCM8706 reg 0x%x"
3743 " <-- val 0x%x\n", reg
, val
);
3744 bnx2x_cl45_write(bp
, params
->port
,
3752 if (params
->req_line_speed
== SPEED_10000
) {
3753 DP(NETIF_MSG_LINK
, "XGXS 8706 force 10Gbps\n");
3755 bnx2x_cl45_write(bp
, params
->port
,
3759 MDIO_PMA_REG_DIGITAL_CTRL
,
3761 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
3762 ext_phy_addr
, MDIO_PMA_DEVAD
,
3763 MDIO_PMA_REG_LASI_CTRL
, 1);
3765 /* Force 1Gbps using autoneg with 1G
3768 /* Allow CL37 through CL73 */
3769 DP(NETIF_MSG_LINK
, "XGXS 8706 AutoNeg\n");
3770 bnx2x_cl45_write(bp
, params
->port
,
3774 MDIO_AN_REG_CL37_CL73
,
3777 /* Enable Full-Duplex advertisment on CL37 */
3778 bnx2x_cl45_write(bp
, params
->port
,
3782 MDIO_AN_REG_CL37_FC_LP
,
3784 /* Enable CL37 AN */
3785 bnx2x_cl45_write(bp
, params
->port
,
3789 MDIO_AN_REG_CL37_AN
,
3792 bnx2x_cl45_write(bp
, params
->port
,
3796 MDIO_AN_REG_ADV
, (1<<5));
3798 /* Enable clause 73 AN */
3799 bnx2x_cl45_write(bp
, params
->port
,
3805 bnx2x_cl45_write(bp
, params
->port
,
3809 MDIO_PMA_REG_RX_ALARM_CTRL
,
3811 bnx2x_cl45_write(bp
, params
->port
,
3815 MDIO_PMA_REG_LASI_CTRL
, 0x0004);
3818 bnx2x_save_bcm_spirom_ver(bp
, params
->port
,
3821 params
->shmem_base
);
3823 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
:
3824 DP(NETIF_MSG_LINK
, "Initializing BCM8726\n");
3825 bnx2x_bcm8726_external_rom_boot(params
);
3827 /* Need to call module detected on initialization since
3828 the module detection triggered by actual module
3829 insertion might occur before driver is loaded, and when
3830 driver is loaded, it reset all registers, including the
3832 bnx2x_sfp_module_detection(params
);
3834 /* Set Flow control */
3835 bnx2x_ext_phy_set_pause(params
, vars
);
3836 if (params
->req_line_speed
== SPEED_1000
) {
3837 DP(NETIF_MSG_LINK
, "Setting 1G force\n");
3838 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
3839 ext_phy_addr
, MDIO_PMA_DEVAD
,
3840 MDIO_PMA_REG_CTRL
, 0x40);
3841 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
3842 ext_phy_addr
, MDIO_PMA_DEVAD
,
3843 MDIO_PMA_REG_10G_CTRL2
, 0xD);
3844 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
3845 ext_phy_addr
, MDIO_PMA_DEVAD
,
3846 MDIO_PMA_REG_LASI_CTRL
, 0x5);
3847 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
3848 ext_phy_addr
, MDIO_PMA_DEVAD
,
3849 MDIO_PMA_REG_RX_ALARM_CTRL
,
3851 } else if ((params
->req_line_speed
==
3853 ((params
->speed_cap_mask
&
3854 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
))) {
3855 DP(NETIF_MSG_LINK
, "Setting 1G clause37\n");
3856 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
3857 ext_phy_addr
, MDIO_AN_DEVAD
,
3858 MDIO_AN_REG_ADV
, 0x20);
3859 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
3860 ext_phy_addr
, MDIO_AN_DEVAD
,
3861 MDIO_AN_REG_CL37_CL73
, 0x040c);
3862 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
3863 ext_phy_addr
, MDIO_AN_DEVAD
,
3864 MDIO_AN_REG_CL37_FC_LD
, 0x0020);
3865 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
3866 ext_phy_addr
, MDIO_AN_DEVAD
,
3867 MDIO_AN_REG_CL37_AN
, 0x1000);
3868 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
3869 ext_phy_addr
, MDIO_AN_DEVAD
,
3870 MDIO_AN_REG_CTRL
, 0x1200);
3872 /* Enable RX-ALARM control to receive
3873 interrupt for 1G speed change */
3874 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
3875 ext_phy_addr
, MDIO_PMA_DEVAD
,
3876 MDIO_PMA_REG_LASI_CTRL
, 0x4);
3877 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
3878 ext_phy_addr
, MDIO_PMA_DEVAD
,
3879 MDIO_PMA_REG_RX_ALARM_CTRL
,
3882 } else { /* Default 10G. Set only LASI control */
3883 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
3884 ext_phy_addr
, MDIO_PMA_DEVAD
,
3885 MDIO_PMA_REG_LASI_CTRL
, 1);
3888 /* Set TX PreEmphasis if needed */
3889 if ((params
->feature_config_flags
&
3890 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED
)) {
3891 DP(NETIF_MSG_LINK
, "Setting TX_CTRL1 0x%x,"
3893 params
->xgxs_config_tx
[0],
3894 params
->xgxs_config_tx
[1]);
3895 bnx2x_cl45_write(bp
, params
->port
,
3899 MDIO_PMA_REG_8726_TX_CTRL1
,
3900 params
->xgxs_config_tx
[0]);
3902 bnx2x_cl45_write(bp
, params
->port
,
3906 MDIO_PMA_REG_8726_TX_CTRL2
,
3907 params
->xgxs_config_tx
[1]);
3910 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
3911 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
3914 u16 rx_alarm_ctrl_val
;
3917 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
) {
3918 rx_alarm_ctrl_val
= 0x400;
3919 lasi_ctrl_val
= 0x0004;
3921 rx_alarm_ctrl_val
= (1<<2);
3922 lasi_ctrl_val
= 0x0004;
3926 bnx2x_cl45_write(bp
, params
->port
,
3930 MDIO_PMA_REG_RX_ALARM_CTRL
,
3933 bnx2x_cl45_write(bp
, params
->port
,
3937 MDIO_PMA_REG_LASI_CTRL
,
3940 bnx2x_8073_set_pause_cl37(params
, vars
);
3943 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
)
3944 bnx2x_bcm8072_external_rom_boot(params
);
3946 /* In case of 8073 with long xaui lines,
3947 don't set the 8073 xaui low power*/
3948 bnx2x_bcm8073_set_xaui_low_power_mode(params
);
3950 bnx2x_cl45_read(bp
, params
->port
,
3954 MDIO_PMA_REG_M8051_MSGOUT_REG
,
3957 bnx2x_cl45_read(bp
, params
->port
,
3961 MDIO_PMA_REG_RX_ALARM
, &tmp1
);
3963 DP(NETIF_MSG_LINK
, "Before rom RX_ALARM(port1):"
3966 /* If this is forced speed, set to KR or KX
3967 * (all other are not supported)
3969 if (params
->loopback_mode
== LOOPBACK_EXT
) {
3970 bnx2x_bcm807x_force_10G(params
);
3972 "Forced speed 10G on 807X\n");
3975 bnx2x_cl45_write(bp
, params
->port
,
3976 ext_phy_type
, ext_phy_addr
,
3978 MDIO_PMA_REG_BCM_CTRL
,
3981 if (params
->req_line_speed
!= SPEED_AUTO_NEG
) {
3982 if (params
->req_line_speed
== SPEED_10000
) {
3984 } else if (params
->req_line_speed
==
3987 /* Note that 2.5G works only
3988 when used with 1G advertisment */
3994 if (params
->speed_cap_mask
&
3995 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)
3998 /* Note that 2.5G works only when
3999 used with 1G advertisment */
4000 if (params
->speed_cap_mask
&
4001 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
|
4002 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G
))
4005 "807x autoneg val = 0x%x\n", val
);
4008 bnx2x_cl45_write(bp
, params
->port
,
4012 MDIO_AN_REG_ADV
, val
);
4014 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
4015 bnx2x_cl45_read(bp
, params
->port
,
4019 MDIO_AN_REG_8073_2_5G
, &tmp1
);
4021 if (((params
->speed_cap_mask
&
4022 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G
) &&
4023 (params
->req_line_speed
==
4025 (params
->req_line_speed
==
4028 /* Allow 2.5G for A1 and above */
4029 bnx2x_cl45_read(bp
, params
->port
,
4030 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4033 MDIO_PMA_REG_8073_CHIP_REV
, &phy_ver
);
4034 DP(NETIF_MSG_LINK
, "Add 2.5G\n");
4040 DP(NETIF_MSG_LINK
, "Disable 2.5G\n");
4044 bnx2x_cl45_write(bp
, params
->port
,
4048 MDIO_AN_REG_8073_2_5G
, tmp1
);
4051 /* Add support for CL37 (passive mode) II */
4053 bnx2x_cl45_read(bp
, params
->port
,
4057 MDIO_AN_REG_CL37_FC_LD
,
4060 bnx2x_cl45_write(bp
, params
->port
,
4064 MDIO_AN_REG_CL37_FC_LD
, (tmp1
|
4065 ((params
->req_duplex
== DUPLEX_FULL
) ?
4068 /* Add support for CL37 (passive mode) III */
4069 bnx2x_cl45_write(bp
, params
->port
,
4073 MDIO_AN_REG_CL37_AN
, 0x1000);
4076 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
4077 /* The SNR will improve about 2db by changing
4078 BW and FEE main tap. Rest commands are executed
4080 /*Change FFE main cursor to 5 in EDC register*/
4081 if (bnx2x_8073_is_snr_needed(params
))
4082 bnx2x_cl45_write(bp
, params
->port
,
4086 MDIO_PMA_REG_EDC_FFE_MAIN
,
4089 /* Enable FEC (Forware Error Correction)
4090 Request in the AN */
4091 bnx2x_cl45_read(bp
, params
->port
,
4095 MDIO_AN_REG_ADV2
, &tmp1
);
4099 bnx2x_cl45_write(bp
, params
->port
,
4103 MDIO_AN_REG_ADV2
, tmp1
);
4107 bnx2x_ext_phy_set_pause(params
, vars
);
4109 /* Restart autoneg */
4111 bnx2x_cl45_write(bp
, params
->port
,
4115 MDIO_AN_REG_CTRL
, 0x1200);
4116 DP(NETIF_MSG_LINK
, "807x Autoneg Restart: "
4117 "Advertise 1G=%x, 10G=%x\n",
4118 ((val
& (1<<5)) > 0),
4119 ((val
& (1<<7)) > 0));
4123 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
:
4126 u16 rx_alarm_ctrl_val
;
4129 /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
4132 rx_alarm_ctrl_val
= (1<<2) | (1<<5) ;
4133 lasi_ctrl_val
= 0x0004;
4135 DP(NETIF_MSG_LINK
, "Initializing BCM8727\n");
4137 bnx2x_cl45_write(bp
, params
->port
,
4141 MDIO_PMA_REG_RX_ALARM_CTRL
,
4144 bnx2x_cl45_write(bp
, params
->port
,
4148 MDIO_PMA_REG_LASI_CTRL
,
4151 /* Initially configure MOD_ABS to interrupt when
4152 module is presence( bit 8) */
4153 bnx2x_cl45_read(bp
, params
->port
,
4157 MDIO_PMA_REG_PHY_IDENTIFIER
, &mod_abs
);
4158 /* Set EDC off by setting OPTXLOS signal input to low
4160 When the EDC is off it locks onto a reference clock and
4161 avoids becoming 'lost'.*/
4162 mod_abs
&= ~((1<<8) | (1<<9));
4163 bnx2x_cl45_write(bp
, params
->port
,
4167 MDIO_PMA_REG_PHY_IDENTIFIER
, mod_abs
);
4169 /* Make MOD_ABS give interrupt on change */
4170 bnx2x_cl45_read(bp
, params
->port
,
4174 MDIO_PMA_REG_8727_PCS_OPT_CTRL
,
4177 bnx2x_cl45_write(bp
, params
->port
,
4181 MDIO_PMA_REG_8727_PCS_OPT_CTRL
,
4184 /* Set 8727 GPIOs to input to allow reading from the
4185 8727 GPIO0 status which reflect SFP+ module
4188 bnx2x_cl45_read(bp
, params
->port
,
4189 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
4192 MDIO_PMA_REG_8727_PCS_OPT_CTRL
,
4194 val
&= 0xff8f; /* Reset bits 4-6 */
4195 bnx2x_cl45_write(bp
, params
->port
,
4196 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
4199 MDIO_PMA_REG_8727_PCS_OPT_CTRL
,
4202 bnx2x_8727_power_module(bp
, params
, ext_phy_addr
, 1);
4203 bnx2x_bcm8073_set_xaui_low_power_mode(params
);
4205 bnx2x_cl45_read(bp
, params
->port
,
4209 MDIO_PMA_REG_M8051_MSGOUT_REG
,
4212 bnx2x_cl45_read(bp
, params
->port
,
4216 MDIO_PMA_REG_RX_ALARM
, &tmp1
);
4218 /* Set option 1G speed */
4219 if (params
->req_line_speed
== SPEED_1000
) {
4221 DP(NETIF_MSG_LINK
, "Setting 1G force\n");
4222 bnx2x_cl45_write(bp
, params
->port
,
4226 MDIO_PMA_REG_CTRL
, 0x40);
4227 bnx2x_cl45_write(bp
, params
->port
,
4231 MDIO_PMA_REG_10G_CTRL2
, 0xD);
4232 bnx2x_cl45_read(bp
, params
->port
,
4236 MDIO_PMA_REG_10G_CTRL2
, &tmp1
);
4237 DP(NETIF_MSG_LINK
, "1.7 = 0x%x\n", tmp1
);
4239 } else if ((params
->req_line_speed
==
4241 ((params
->speed_cap_mask
&
4242 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
))) {
4244 DP(NETIF_MSG_LINK
, "Setting 1G clause37\n");
4245 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
4246 ext_phy_addr
, MDIO_AN_DEVAD
,
4247 MDIO_PMA_REG_8727_MISC_CTRL
, 0);
4248 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
4249 ext_phy_addr
, MDIO_AN_DEVAD
,
4250 MDIO_AN_REG_CL37_AN
, 0x1300);
4252 /* Since the 8727 has only single reset pin,
4253 need to set the 10G registers although it is
4255 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
4256 ext_phy_addr
, MDIO_AN_DEVAD
,
4257 MDIO_AN_REG_CTRL
, 0x0020);
4258 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
4259 ext_phy_addr
, MDIO_AN_DEVAD
,
4261 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
4262 ext_phy_addr
, MDIO_PMA_DEVAD
,
4263 MDIO_PMA_REG_CTRL
, 0x2040);
4264 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
4265 ext_phy_addr
, MDIO_PMA_DEVAD
,
4266 MDIO_PMA_REG_10G_CTRL2
, 0x0008);
4269 /* Set 2-wire transfer rate of SFP+ module EEPROM
4270 * to 100Khz since some DACs(direct attached cables) do
4271 * not work at 400Khz.
4273 bnx2x_cl45_write(bp
, params
->port
,
4277 MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR
,
4280 /* Set TX PreEmphasis if needed */
4281 if ((params
->feature_config_flags
&
4282 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED
)) {
4283 DP(NETIF_MSG_LINK
, "Setting TX_CTRL1 0x%x,"
4285 params
->xgxs_config_tx
[0],
4286 params
->xgxs_config_tx
[1]);
4287 bnx2x_cl45_write(bp
, params
->port
,
4291 MDIO_PMA_REG_8727_TX_CTRL1
,
4292 params
->xgxs_config_tx
[0]);
4294 bnx2x_cl45_write(bp
, params
->port
,
4298 MDIO_PMA_REG_8727_TX_CTRL2
,
4299 params
->xgxs_config_tx
[1]);
4305 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
4307 u16 fw_ver1
, fw_ver2
;
4309 "Setting the SFX7101 LASI indication\n");
4311 bnx2x_cl45_write(bp
, params
->port
,
4315 MDIO_PMA_REG_LASI_CTRL
, 0x1);
4317 "Setting the SFX7101 LED to blink on traffic\n");
4318 bnx2x_cl45_write(bp
, params
->port
,
4322 MDIO_PMA_REG_7107_LED_CNTL
, (1<<3));
4324 bnx2x_ext_phy_set_pause(params
, vars
);
4325 /* Restart autoneg */
4326 bnx2x_cl45_read(bp
, params
->port
,
4330 MDIO_AN_REG_CTRL
, &val
);
4332 bnx2x_cl45_write(bp
, params
->port
,
4336 MDIO_AN_REG_CTRL
, val
);
4338 /* Save spirom version */
4339 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
4340 ext_phy_addr
, MDIO_PMA_DEVAD
,
4341 MDIO_PMA_REG_7101_VER1
, &fw_ver1
);
4343 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
4344 ext_phy_addr
, MDIO_PMA_DEVAD
,
4345 MDIO_PMA_REG_7101_VER2
, &fw_ver2
);
4347 bnx2x_save_spirom_version(params
->bp
, params
->port
,
4349 (u32
)(fw_ver1
<<16 | fw_ver2
));
4352 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
:
4353 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823
:
4354 /* This phy uses the NIG latch mechanism since link
4355 indication arrives through its LED4 and not via
4356 its LASI signal, so we get steady signal
4357 instead of clear on read */
4358 bnx2x_bits_en(bp
, NIG_REG_LATCH_BC_0
+ params
->port
*4,
4359 1 << NIG_LATCH_BC_ENABLE_MI_INT
);
4361 bnx2x_cl45_write(bp
, params
->port
,
4362 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
,
4365 MDIO_PMA_REG_CTRL
, 0x0000);
4367 bnx2x_8481_set_led4(params
, ext_phy_type
, ext_phy_addr
);
4368 if (params
->req_line_speed
== SPEED_AUTO_NEG
) {
4370 u16 autoneg_val
, an_1000_val
, an_10_100_val
;
4371 /* set 1000 speed advertisement */
4372 bnx2x_cl45_read(bp
, params
->port
,
4376 MDIO_AN_REG_8481_1000T_CTRL
,
4379 if (params
->speed_cap_mask
&
4380 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
) {
4381 an_1000_val
|= (1<<8);
4382 if (params
->req_duplex
== DUPLEX_FULL
)
4383 an_1000_val
|= (1<<9);
4384 DP(NETIF_MSG_LINK
, "Advertising 1G\n");
4386 an_1000_val
&= ~((1<<8) | (1<<9));
4388 bnx2x_cl45_write(bp
, params
->port
,
4392 MDIO_AN_REG_8481_1000T_CTRL
,
4395 /* set 100 speed advertisement */
4396 bnx2x_cl45_read(bp
, params
->port
,
4400 MDIO_AN_REG_8481_LEGACY_AN_ADV
,
4403 if (params
->speed_cap_mask
&
4404 (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL
|
4405 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF
)) {
4406 an_10_100_val
|= (1<<7);
4407 if (params
->req_duplex
== DUPLEX_FULL
)
4408 an_10_100_val
|= (1<<8);
4410 "Advertising 100M\n");
4412 an_10_100_val
&= ~((1<<7) | (1<<8));
4414 /* set 10 speed advertisement */
4415 if (params
->speed_cap_mask
&
4416 (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL
|
4417 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF
)) {
4418 an_10_100_val
|= (1<<5);
4419 if (params
->req_duplex
== DUPLEX_FULL
)
4420 an_10_100_val
|= (1<<6);
4421 DP(NETIF_MSG_LINK
, "Advertising 10M\n");
4424 an_10_100_val
&= ~((1<<5) | (1<<6));
4426 bnx2x_cl45_write(bp
, params
->port
,
4430 MDIO_AN_REG_8481_LEGACY_AN_ADV
,
4433 bnx2x_cl45_read(bp
, params
->port
,
4437 MDIO_AN_REG_8481_LEGACY_MII_CTRL
,
4440 /* Disable forced speed */
4441 autoneg_val
&= ~(1<<6|1<<13);
4443 /* Enable autoneg and restart autoneg
4444 for legacy speeds */
4445 autoneg_val
|= (1<<9|1<<12);
4447 if (params
->req_duplex
== DUPLEX_FULL
)
4448 autoneg_val
|= (1<<8);
4450 autoneg_val
&= ~(1<<8);
4452 bnx2x_cl45_write(bp
, params
->port
,
4456 MDIO_AN_REG_8481_LEGACY_MII_CTRL
,
4459 if (params
->speed_cap_mask
&
4460 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
) {
4461 DP(NETIF_MSG_LINK
, "Advertising 10G\n");
4462 /* Restart autoneg for 10G*/
4464 bnx2x_cl45_write(bp
, params
->port
,
4468 MDIO_AN_REG_CTRL
, 0x3200);
4472 u16 autoneg_ctrl
, pma_ctrl
;
4473 bnx2x_cl45_read(bp
, params
->port
,
4477 MDIO_AN_REG_8481_LEGACY_MII_CTRL
,
4480 /* Disable autoneg */
4481 autoneg_ctrl
&= ~(1<<12);
4483 /* Set 1000 force */
4484 switch (params
->req_line_speed
) {
4487 "Unable to set 10G force !\n");
4490 bnx2x_cl45_read(bp
, params
->port
,
4496 autoneg_ctrl
&= ~(1<<13);
4497 autoneg_ctrl
|= (1<<6);
4498 pma_ctrl
&= ~(1<<13);
4501 "Setting 1000M force\n");
4502 bnx2x_cl45_write(bp
, params
->port
,
4510 autoneg_ctrl
|= (1<<13);
4511 autoneg_ctrl
&= ~(1<<6);
4513 "Setting 100M force\n");
4516 autoneg_ctrl
&= ~(1<<13);
4517 autoneg_ctrl
&= ~(1<<6);
4519 "Setting 10M force\n");
4524 if (params
->req_duplex
== DUPLEX_FULL
) {
4525 autoneg_ctrl
|= (1<<8);
4527 "Setting full duplex\n");
4529 autoneg_ctrl
&= ~(1<<8);
4531 /* Update autoneg ctrl and pma ctrl */
4532 bnx2x_cl45_write(bp
, params
->port
,
4536 MDIO_AN_REG_8481_LEGACY_MII_CTRL
,
4540 /* Save spirom version */
4541 bnx2x_save_8481_spirom_version(bp
, params
->port
,
4543 params
->shmem_base
);
4545 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
4547 "XGXS PHY Failure detected 0x%x\n",
4548 params
->ext_phy_config
);
4552 DP(NETIF_MSG_LINK
, "BAD XGXS ext_phy_config 0x%x\n",
4553 params
->ext_phy_config
);
4558 } else { /* SerDes */
4560 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
4561 switch (ext_phy_type
) {
4562 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
:
4563 DP(NETIF_MSG_LINK
, "SerDes Direct\n");
4566 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482
:
4567 DP(NETIF_MSG_LINK
, "SerDes 5482\n");
4571 DP(NETIF_MSG_LINK
, "BAD SerDes ext_phy_config 0x%x\n",
4572 params
->ext_phy_config
);
4579 static void bnx2x_8727_handle_mod_abs(struct link_params
*params
)
4581 struct bnx2x
*bp
= params
->bp
;
4582 u16 mod_abs
, rx_alarm_status
;
4583 u8 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
4584 u32 val
= REG_RD(bp
, params
->shmem_base
+
4585 offsetof(struct shmem_region
, dev_info
.
4586 port_feature_config
[params
->port
].
4588 bnx2x_cl45_read(bp
, params
->port
,
4589 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
4592 MDIO_PMA_REG_PHY_IDENTIFIER
, &mod_abs
);
4593 if (mod_abs
& (1<<8)) {
4595 /* Module is absent */
4596 DP(NETIF_MSG_LINK
, "MOD_ABS indication "
4597 "show module is absent\n");
4599 /* 1. Set mod_abs to detect next module
4601 2. Set EDC off by setting OPTXLOS signal input to low
4603 When the EDC is off it locks onto a reference clock and
4604 avoids becoming 'lost'.*/
4605 mod_abs
&= ~((1<<8)|(1<<9));
4606 bnx2x_cl45_write(bp
, params
->port
,
4607 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
4610 MDIO_PMA_REG_PHY_IDENTIFIER
, mod_abs
);
4612 /* Clear RX alarm since it stays up as long as
4613 the mod_abs wasn't changed */
4614 bnx2x_cl45_read(bp
, params
->port
,
4615 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
4618 MDIO_PMA_REG_RX_ALARM
, &rx_alarm_status
);
4621 /* Module is present */
4622 DP(NETIF_MSG_LINK
, "MOD_ABS indication "
4623 "show module is present\n");
4624 /* First thing, disable transmitter,
4625 and if the module is ok, the
4626 module_detection will enable it*/
4628 /* 1. Set mod_abs to detect next module
4629 absent event ( bit 8)
4630 2. Restore the default polarity of the OPRXLOS signal and
4631 this signal will then correctly indicate the presence or
4632 absence of the Rx signal. (bit 9) */
4633 mod_abs
|= ((1<<8)|(1<<9));
4634 bnx2x_cl45_write(bp
, params
->port
,
4635 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
4638 MDIO_PMA_REG_PHY_IDENTIFIER
, mod_abs
);
4640 /* Clear RX alarm since it stays up as long as
4641 the mod_abs wasn't changed. This is need to be done
4642 before calling the module detection, otherwise it will clear
4643 the link update alarm */
4644 bnx2x_cl45_read(bp
, params
->port
,
4645 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
4648 MDIO_PMA_REG_RX_ALARM
, &rx_alarm_status
);
4651 if ((val
& PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK
) ==
4652 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER
)
4653 bnx2x_sfp_set_transmitter(bp
, params
->port
,
4654 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
4657 if (bnx2x_wait_for_sfp_module_initialized(params
)
4659 bnx2x_sfp_module_detection(params
);
4661 DP(NETIF_MSG_LINK
, "SFP+ module is not initialized\n");
4664 DP(NETIF_MSG_LINK
, "8727 RX_ALARM_STATUS 0x%x\n",
4666 /* No need to check link status in case of
4667 module plugged in/out */
4671 static u8
bnx2x_ext_phy_is_link_up(struct link_params
*params
,
4672 struct link_vars
*vars
,
4675 struct bnx2x
*bp
= params
->bp
;
4679 u16 rx_sd
, pcs_status
;
4680 u8 ext_phy_link_up
= 0;
4681 u8 port
= params
->port
;
4683 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
4684 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
4685 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
4686 switch (ext_phy_type
) {
4687 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
4688 DP(NETIF_MSG_LINK
, "XGXS Direct\n");
4689 ext_phy_link_up
= 1;
4692 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
4693 DP(NETIF_MSG_LINK
, "XGXS 8705\n");
4694 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
4697 MDIO_WIS_REG_LASI_STATUS
, &val1
);
4698 DP(NETIF_MSG_LINK
, "8705 LASI status 0x%x\n", val1
);
4700 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
4703 MDIO_WIS_REG_LASI_STATUS
, &val1
);
4704 DP(NETIF_MSG_LINK
, "8705 LASI status 0x%x\n", val1
);
4706 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
4709 MDIO_PMA_REG_RX_SD
, &rx_sd
);
4711 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
4715 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
4720 DP(NETIF_MSG_LINK
, "8705 1.c809 val=0x%x\n", val1
);
4721 ext_phy_link_up
= ((rx_sd
& 0x1) && (val1
& (1<<9)) &&
4722 ((val1
& (1<<8)) == 0));
4723 if (ext_phy_link_up
)
4724 vars
->line_speed
= SPEED_10000
;
4727 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
4728 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
:
4729 DP(NETIF_MSG_LINK
, "XGXS 8706/8726\n");
4731 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
4733 MDIO_PMA_DEVAD
, MDIO_PMA_REG_RX_ALARM
,
4735 /* clear LASI indication*/
4736 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
4738 MDIO_PMA_DEVAD
, MDIO_PMA_REG_LASI_STATUS
,
4740 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
4742 MDIO_PMA_DEVAD
, MDIO_PMA_REG_LASI_STATUS
,
4744 DP(NETIF_MSG_LINK
, "8706/8726 LASI status 0x%x-->"
4745 "0x%x\n", val1
, val2
);
4747 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
4749 MDIO_PMA_DEVAD
, MDIO_PMA_REG_RX_SD
,
4751 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
4753 MDIO_PCS_DEVAD
, MDIO_PCS_REG_STATUS
,
4755 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
4757 MDIO_AN_DEVAD
, MDIO_AN_REG_LINK_STATUS
,
4759 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
4761 MDIO_AN_DEVAD
, MDIO_AN_REG_LINK_STATUS
,
4764 DP(NETIF_MSG_LINK
, "8706/8726 rx_sd 0x%x"
4765 " pcs_status 0x%x 1Gbps link_status 0x%x\n",
4766 rx_sd
, pcs_status
, val2
);
4767 /* link is up if both bit 0 of pmd_rx_sd and
4768 * bit 0 of pcs_status are set, or if the autoneg bit
4771 ext_phy_link_up
= ((rx_sd
& pcs_status
& 0x1) ||
4773 if (ext_phy_link_up
) {
4775 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
) {
4776 /* If transmitter is disabled,
4777 ignore false link up indication */
4778 bnx2x_cl45_read(bp
, params
->port
,
4782 MDIO_PMA_REG_PHY_IDENTIFIER
,
4784 if (val1
& (1<<15)) {
4785 DP(NETIF_MSG_LINK
, "Tx is "
4787 ext_phy_link_up
= 0;
4792 vars
->line_speed
= SPEED_1000
;
4794 vars
->line_speed
= SPEED_10000
;
4798 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
:
4800 u16 link_status
= 0;
4801 u16 rx_alarm_status
;
4802 /* Check the LASI */
4803 bnx2x_cl45_read(bp
, params
->port
,
4807 MDIO_PMA_REG_RX_ALARM
, &rx_alarm_status
);
4809 DP(NETIF_MSG_LINK
, "8727 RX_ALARM_STATUS 0x%x\n",
4812 bnx2x_cl45_read(bp
, params
->port
,
4816 MDIO_PMA_REG_LASI_STATUS
, &val1
);
4819 "8727 LASI status 0x%x\n",
4823 bnx2x_cl45_read(bp
, params
->port
,
4827 MDIO_PMA_REG_M8051_MSGOUT_REG
,
4831 * If a module is present and there is need to check
4834 if (!(params
->feature_config_flags
&
4835 FEATURE_CONFIG_BCM8727_NOC
) &&
4836 !(rx_alarm_status
& (1<<5))) {
4837 /* Check over-current using 8727 GPIO0 input*/
4838 bnx2x_cl45_read(bp
, params
->port
,
4842 MDIO_PMA_REG_8727_GPIO_CTRL
,
4845 if ((val1
& (1<<8)) == 0) {
4846 DP(NETIF_MSG_LINK
, "8727 Power fault"
4847 " has been detected on "
4850 netdev_err(bp
->dev
, "Error: Power fault on Port %d has been detected and the power to that SFP+ module has been removed to prevent failure of the card. Please remove the SFP+ module and restart the system to clear this error.\n",
4853 * Disable all RX_ALARMs except for
4856 bnx2x_cl45_write(bp
, params
->port
,
4860 MDIO_PMA_REG_RX_ALARM_CTRL
,
4863 bnx2x_cl45_read(bp
, params
->port
,
4867 MDIO_PMA_REG_PHY_IDENTIFIER
,
4869 /* Wait for module_absent_event */
4871 bnx2x_cl45_write(bp
, params
->port
,
4875 MDIO_PMA_REG_PHY_IDENTIFIER
,
4877 /* Clear RX alarm */
4878 bnx2x_cl45_read(bp
, params
->port
,
4882 MDIO_PMA_REG_RX_ALARM
,
4886 } /* Over current check */
4888 /* When module absent bit is set, check module */
4889 if (rx_alarm_status
& (1<<5)) {
4890 bnx2x_8727_handle_mod_abs(params
);
4891 /* Enable all mod_abs and link detection bits */
4892 bnx2x_cl45_write(bp
, params
->port
,
4896 MDIO_PMA_REG_RX_ALARM_CTRL
,
4900 /* If transmitter is disabled,
4901 ignore false link up indication */
4902 bnx2x_cl45_read(bp
, params
->port
,
4906 MDIO_PMA_REG_PHY_IDENTIFIER
,
4908 if (val1
& (1<<15)) {
4909 DP(NETIF_MSG_LINK
, "Tx is disabled\n");
4910 ext_phy_link_up
= 0;
4914 bnx2x_cl45_read(bp
, params
->port
,
4918 MDIO_PMA_REG_8073_SPEED_LINK_STATUS
,
4921 /* Bits 0..2 --> speed detected,
4922 bits 13..15--> link is down */
4923 if ((link_status
& (1<<2)) &&
4924 (!(link_status
& (1<<15)))) {
4925 ext_phy_link_up
= 1;
4926 vars
->line_speed
= SPEED_10000
;
4927 } else if ((link_status
& (1<<0)) &&
4928 (!(link_status
& (1<<13)))) {
4929 ext_phy_link_up
= 1;
4930 vars
->line_speed
= SPEED_1000
;
4932 "port %x: External link"
4933 " up in 1G\n", params
->port
);
4935 ext_phy_link_up
= 0;
4937 "port %x: External link"
4938 " is down\n", params
->port
);
4943 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
4944 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
4946 u16 link_status
= 0;
4947 u16 an1000_status
= 0;
4950 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
) {
4951 bnx2x_cl45_read(bp
, params
->port
,
4955 MDIO_PCS_REG_LASI_STATUS
, &val1
);
4956 bnx2x_cl45_read(bp
, params
->port
,
4960 MDIO_PCS_REG_LASI_STATUS
, &val2
);
4962 "870x LASI status 0x%x->0x%x\n",
4965 /* In 8073, port1 is directed through emac0 and
4966 * port0 is directed through emac1
4968 bnx2x_cl45_read(bp
, params
->port
,
4972 MDIO_PMA_REG_LASI_STATUS
, &val1
);
4975 "8703 LASI status 0x%x\n",
4979 /* clear the interrupt LASI status register */
4980 bnx2x_cl45_read(bp
, params
->port
,
4984 MDIO_PCS_REG_STATUS
, &val2
);
4985 bnx2x_cl45_read(bp
, params
->port
,
4989 MDIO_PCS_REG_STATUS
, &val1
);
4990 DP(NETIF_MSG_LINK
, "807x PCS status 0x%x->0x%x\n",
4993 bnx2x_cl45_read(bp
, params
->port
,
4997 MDIO_PMA_REG_M8051_MSGOUT_REG
,
5000 /* Check the LASI */
5001 bnx2x_cl45_read(bp
, params
->port
,
5005 MDIO_PMA_REG_RX_ALARM
, &val2
);
5007 DP(NETIF_MSG_LINK
, "KR 0x9003 0x%x\n", val2
);
5009 /* Check the link status */
5010 bnx2x_cl45_read(bp
, params
->port
,
5014 MDIO_PCS_REG_STATUS
, &val2
);
5015 DP(NETIF_MSG_LINK
, "KR PCS status 0x%x\n", val2
);
5017 bnx2x_cl45_read(bp
, params
->port
,
5021 MDIO_PMA_REG_STATUS
, &val2
);
5022 bnx2x_cl45_read(bp
, params
->port
,
5026 MDIO_PMA_REG_STATUS
, &val1
);
5027 ext_phy_link_up
= ((val1
& 4) == 4);
5028 DP(NETIF_MSG_LINK
, "PMA_REG_STATUS=0x%x\n", val1
);
5030 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
5032 if (ext_phy_link_up
&&
5033 ((params
->req_line_speed
!=
5035 if (bnx2x_bcm8073_xaui_wa(params
)
5037 ext_phy_link_up
= 0;
5041 bnx2x_cl45_read(bp
, params
->port
,
5045 MDIO_AN_REG_LINK_STATUS
,
5047 bnx2x_cl45_read(bp
, params
->port
,
5051 MDIO_AN_REG_LINK_STATUS
,
5054 /* Check the link status on 1.1.2 */
5055 bnx2x_cl45_read(bp
, params
->port
,
5059 MDIO_PMA_REG_STATUS
, &val2
);
5060 bnx2x_cl45_read(bp
, params
->port
,
5064 MDIO_PMA_REG_STATUS
, &val1
);
5065 DP(NETIF_MSG_LINK
, "KR PMA status 0x%x->0x%x,"
5066 "an_link_status=0x%x\n",
5067 val2
, val1
, an1000_status
);
5069 ext_phy_link_up
= (((val1
& 4) == 4) ||
5070 (an1000_status
& (1<<1)));
5071 if (ext_phy_link_up
&&
5072 bnx2x_8073_is_snr_needed(params
)) {
5073 /* The SNR will improve about 2dbby
5074 changing the BW and FEE main tap.*/
5076 /* The 1st write to change FFE main
5077 tap is set before restart AN */
5078 /* Change PLL Bandwidth in EDC
5080 bnx2x_cl45_write(bp
, port
, ext_phy_type
,
5083 MDIO_PMA_REG_PLL_BANDWIDTH
,
5086 /* Change CDR Bandwidth in EDC
5088 bnx2x_cl45_write(bp
, port
, ext_phy_type
,
5091 MDIO_PMA_REG_CDR_BANDWIDTH
,
5094 bnx2x_cl45_read(bp
, params
->port
,
5098 MDIO_PMA_REG_8073_SPEED_LINK_STATUS
,
5101 /* Bits 0..2 --> speed detected,
5102 bits 13..15--> link is down */
5103 if ((link_status
& (1<<2)) &&
5104 (!(link_status
& (1<<15)))) {
5105 ext_phy_link_up
= 1;
5106 vars
->line_speed
= SPEED_10000
;
5108 "port %x: External link"
5109 " up in 10G\n", params
->port
);
5110 } else if ((link_status
& (1<<1)) &&
5111 (!(link_status
& (1<<14)))) {
5112 ext_phy_link_up
= 1;
5113 vars
->line_speed
= SPEED_2500
;
5115 "port %x: External link"
5116 " up in 2.5G\n", params
->port
);
5117 } else if ((link_status
& (1<<0)) &&
5118 (!(link_status
& (1<<13)))) {
5119 ext_phy_link_up
= 1;
5120 vars
->line_speed
= SPEED_1000
;
5122 "port %x: External link"
5123 " up in 1G\n", params
->port
);
5125 ext_phy_link_up
= 0;
5127 "port %x: External link"
5128 " is down\n", params
->port
);
5131 /* See if 1G link is up for the 8072 */
5132 bnx2x_cl45_read(bp
, params
->port
,
5136 MDIO_AN_REG_LINK_STATUS
,
5138 bnx2x_cl45_read(bp
, params
->port
,
5142 MDIO_AN_REG_LINK_STATUS
,
5144 if (an1000_status
& (1<<1)) {
5145 ext_phy_link_up
= 1;
5146 vars
->line_speed
= SPEED_1000
;
5148 "port %x: External link"
5149 " up in 1G\n", params
->port
);
5150 } else if (ext_phy_link_up
) {
5151 ext_phy_link_up
= 1;
5152 vars
->line_speed
= SPEED_10000
;
5154 "port %x: External link"
5155 " up in 10G\n", params
->port
);
5162 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
5163 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
5166 MDIO_PMA_REG_LASI_STATUS
, &val2
);
5167 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
5170 MDIO_PMA_REG_LASI_STATUS
, &val1
);
5172 "10G-base-T LASI status 0x%x->0x%x\n",
5174 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
5177 MDIO_PMA_REG_STATUS
, &val2
);
5178 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
5181 MDIO_PMA_REG_STATUS
, &val1
);
5183 "10G-base-T PMA status 0x%x->0x%x\n",
5185 ext_phy_link_up
= ((val1
& 4) == 4);
5187 * print the AN outcome of the SFX7101 PHY
5189 if (ext_phy_link_up
) {
5190 bnx2x_cl45_read(bp
, params
->port
,
5194 MDIO_AN_REG_MASTER_STATUS
,
5196 vars
->line_speed
= SPEED_10000
;
5198 "SFX7101 AN status 0x%x->Master=%x\n",
5203 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
:
5204 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823
:
5205 /* Check 10G-BaseT link status */
5206 /* Check PMD signal ok */
5207 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
5212 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
5215 MDIO_PMA_REG_8481_PMD_SIGNAL
,
5217 DP(NETIF_MSG_LINK
, "PMD_SIGNAL 1.a811 = 0x%x\n", val2
);
5219 /* Check link 10G */
5220 if (val2
& (1<<11)) {
5221 vars
->line_speed
= SPEED_10000
;
5222 ext_phy_link_up
= 1;
5223 bnx2x_8481_set_10G_led_mode(params
,
5226 } else { /* Check Legacy speed link */
5227 u16 legacy_status
, legacy_speed
;
5229 /* Enable expansion register 0x42
5230 (Operation mode status) */
5231 bnx2x_cl45_write(bp
, params
->port
,
5235 MDIO_AN_REG_8481_EXPANSION_REG_ACCESS
,
5238 /* Get legacy speed operation status */
5239 bnx2x_cl45_read(bp
, params
->port
,
5243 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW
,
5246 DP(NETIF_MSG_LINK
, "Legacy speed status"
5247 " = 0x%x\n", legacy_status
);
5248 ext_phy_link_up
= ((legacy_status
& (1<<11))
5250 if (ext_phy_link_up
) {
5251 legacy_speed
= (legacy_status
& (3<<9));
5252 if (legacy_speed
== (0<<9))
5253 vars
->line_speed
= SPEED_10
;
5254 else if (legacy_speed
== (1<<9))
5257 else if (legacy_speed
== (2<<9))
5260 else /* Should not happen */
5261 vars
->line_speed
= 0;
5263 if (legacy_status
& (1<<8))
5264 vars
->duplex
= DUPLEX_FULL
;
5266 vars
->duplex
= DUPLEX_HALF
;
5268 DP(NETIF_MSG_LINK
, "Link is up "
5269 "in %dMbps, is_duplex_full"
5272 (vars
->duplex
== DUPLEX_FULL
));
5273 bnx2x_8481_set_legacy_led_mode(params
,
5280 DP(NETIF_MSG_LINK
, "BAD XGXS ext_phy_config 0x%x\n",
5281 params
->ext_phy_config
);
5282 ext_phy_link_up
= 0;
5285 /* Set SGMII mode for external phy */
5286 if (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) {
5287 if (vars
->line_speed
< SPEED_1000
)
5288 vars
->phy_flags
|= PHY_SGMII_FLAG
;
5290 vars
->phy_flags
&= ~PHY_SGMII_FLAG
;
5293 } else { /* SerDes */
5294 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
5295 switch (ext_phy_type
) {
5296 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
:
5297 DP(NETIF_MSG_LINK
, "SerDes Direct\n");
5298 ext_phy_link_up
= 1;
5301 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482
:
5302 DP(NETIF_MSG_LINK
, "SerDes 5482\n");
5303 ext_phy_link_up
= 1;
5308 "BAD SerDes ext_phy_config 0x%x\n",
5309 params
->ext_phy_config
);
5310 ext_phy_link_up
= 0;
5315 return ext_phy_link_up
;
5318 static void bnx2x_link_int_enable(struct link_params
*params
)
5320 u8 port
= params
->port
;
5323 struct bnx2x
*bp
= params
->bp
;
5325 /* setting the status to report on link up
5326 for either XGXS or SerDes */
5328 if (params
->switch_cfg
== SWITCH_CFG_10G
) {
5329 mask
= (NIG_MASK_XGXS0_LINK10G
|
5330 NIG_MASK_XGXS0_LINK_STATUS
);
5331 DP(NETIF_MSG_LINK
, "enabled XGXS interrupt\n");
5332 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
5333 if ((ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) &&
5334 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
) &&
5336 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
)) {
5337 mask
|= NIG_MASK_MI_INT
;
5338 DP(NETIF_MSG_LINK
, "enabled external phy int\n");
5341 } else { /* SerDes */
5342 mask
= NIG_MASK_SERDES0_LINK_STATUS
;
5343 DP(NETIF_MSG_LINK
, "enabled SerDes interrupt\n");
5344 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
5345 if ((ext_phy_type
!=
5346 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
) &&
5348 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN
)) {
5349 mask
|= NIG_MASK_MI_INT
;
5350 DP(NETIF_MSG_LINK
, "enabled external phy int\n");
5354 NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4,
5357 DP(NETIF_MSG_LINK
, "port %x, is_xgxs %x, int_status 0x%x\n", port
,
5358 (params
->switch_cfg
== SWITCH_CFG_10G
),
5359 REG_RD(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4));
5360 DP(NETIF_MSG_LINK
, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
5361 REG_RD(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4),
5362 REG_RD(bp
, NIG_REG_EMAC0_STATUS_MISC_MI_INT
+ port
*0x18),
5363 REG_RD(bp
, NIG_REG_SERDES0_STATUS_LINK_STATUS
+port
*0x3c));
5364 DP(NETIF_MSG_LINK
, " 10G %x, XGXS_LINK %x\n",
5365 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK10G
+ port
*0x68),
5366 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK_STATUS
+ port
*0x68));
5369 static void bnx2x_8481_rearm_latch_signal(struct bnx2x
*bp
, u8 port
,
5372 u32 latch_status
= 0, is_mi_int_status
;
5373 /* Disable the MI INT ( external phy int )
5374 * by writing 1 to the status register. Link down indication
5375 * is high-active-signal, so in this case we need to write the
5376 * status to clear the XOR
5378 /* Read Latched signals */
5379 latch_status
= REG_RD(bp
,
5380 NIG_REG_LATCH_STATUS_0
+ port
*8);
5381 is_mi_int_status
= REG_RD(bp
,
5382 NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4);
5383 DP(NETIF_MSG_LINK
, "original_signal = 0x%x, nig_status = 0x%x,"
5384 "latch_status = 0x%x\n",
5385 is_mi_int
, is_mi_int_status
, latch_status
);
5386 /* Handle only those with latched-signal=up.*/
5387 if (latch_status
& 1) {
5388 /* For all latched-signal=up,Write original_signal to status */
5391 NIG_REG_STATUS_INTERRUPT_PORT0
5393 NIG_STATUS_EMAC0_MI_INT
);
5396 NIG_REG_STATUS_INTERRUPT_PORT0
5398 NIG_STATUS_EMAC0_MI_INT
);
5399 /* For all latched-signal=up : Re-Arm Latch signals */
5400 REG_WR(bp
, NIG_REG_LATCH_STATUS_0
+ port
*8,
5401 (latch_status
& 0xfffe) | (latch_status
& 1));
5407 static void bnx2x_link_int_ack(struct link_params
*params
,
5408 struct link_vars
*vars
, u8 is_10g
,
5411 struct bnx2x
*bp
= params
->bp
;
5412 u8 port
= params
->port
;
5414 /* first reset all status
5415 * we assume only one line will be change at a time */
5416 bnx2x_bits_dis(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
5417 (NIG_STATUS_XGXS0_LINK10G
|
5418 NIG_STATUS_XGXS0_LINK_STATUS
|
5419 NIG_STATUS_SERDES0_LINK_STATUS
));
5420 if ((XGXS_EXT_PHY_TYPE(params
->ext_phy_config
)
5421 == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
) ||
5422 (XGXS_EXT_PHY_TYPE(params
->ext_phy_config
)
5423 == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823
)) {
5424 bnx2x_8481_rearm_latch_signal(bp
, port
, is_mi_int
);
5426 if (vars
->phy_link_up
) {
5428 /* Disable the 10G link interrupt
5429 * by writing 1 to the status register
5431 DP(NETIF_MSG_LINK
, "10G XGXS phy link up\n");
5433 NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
5434 NIG_STATUS_XGXS0_LINK10G
);
5436 } else if (params
->switch_cfg
== SWITCH_CFG_10G
) {
5437 /* Disable the link interrupt
5438 * by writing 1 to the relevant lane
5439 * in the status register
5441 u32 ser_lane
= ((params
->lane_config
&
5442 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
5443 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
5445 DP(NETIF_MSG_LINK
, "%d speed XGXS phy link up\n",
5448 NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
5450 NIG_STATUS_XGXS0_LINK_STATUS_SIZE
));
5452 } else { /* SerDes */
5453 DP(NETIF_MSG_LINK
, "SerDes phy link up\n");
5454 /* Disable the link interrupt
5455 * by writing 1 to the status register
5458 NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
5459 NIG_STATUS_SERDES0_LINK_STATUS
);
5462 } else { /* link_down */
5466 static u8
bnx2x_format_ver(u32 num
, u8
*str
, u16 len
)
5469 u32 mask
= 0xf0000000;
5473 /* Need more than 10chars for this format */
5480 digit
= ((num
& mask
) >> shift
);
5482 *str_ptr
= digit
+ '0';
5484 *str_ptr
= digit
- 0xa + 'a';
5496 u8
bnx2x_get_ext_phy_fw_version(struct link_params
*params
, u8 driver_loaded
,
5497 u8
*version
, u16 len
)
5500 u32 ext_phy_type
= 0;
5504 if (version
== NULL
|| params
== NULL
)
5508 spirom_ver
= REG_RD(bp
, params
->shmem_base
+
5509 offsetof(struct shmem_region
,
5510 port_mb
[params
->port
].ext_phy_fw_version
));
5513 /* reset the returned value to zero */
5514 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
5515 switch (ext_phy_type
) {
5516 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
5521 version
[0] = (spirom_ver
& 0xFF);
5522 version
[1] = (spirom_ver
& 0xFF00) >> 8;
5523 version
[2] = (spirom_ver
& 0xFF0000) >> 16;
5524 version
[3] = (spirom_ver
& 0xFF000000) >> 24;
5528 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
5529 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
5530 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
:
5531 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
5532 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
:
5533 status
= bnx2x_format_ver(spirom_ver
, version
, len
);
5535 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
:
5536 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823
:
5537 spirom_ver
= ((spirom_ver
& 0xF80) >> 7) << 16 |
5538 (spirom_ver
& 0x7F);
5539 status
= bnx2x_format_ver(spirom_ver
, version
, len
);
5541 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
5542 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
5546 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
5547 DP(NETIF_MSG_LINK
, "bnx2x_get_ext_phy_fw_version:"
5548 " type is FAILURE!\n");
5558 static void bnx2x_set_xgxs_loopback(struct link_params
*params
,
5559 struct link_vars
*vars
,
5562 u8 port
= params
->port
;
5563 struct bnx2x
*bp
= params
->bp
;
5568 DP(NETIF_MSG_LINK
, "XGXS 10G loopback enable\n");
5570 /* change the uni_phy_addr in the nig */
5571 md_devad
= REG_RD(bp
, (NIG_REG_XGXS0_CTRL_MD_DEVAD
+
5574 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_DEVAD
+ port
*0x18, 0x5);
5576 bnx2x_cl45_write(bp
, port
, 0,
5579 (MDIO_REG_BANK_AER_BLOCK
+
5580 (MDIO_AER_BLOCK_AER_REG
& 0xf)),
5583 bnx2x_cl45_write(bp
, port
, 0,
5586 (MDIO_REG_BANK_CL73_IEEEB0
+
5587 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL
& 0xf)),
5590 /* set aer mmd back */
5591 bnx2x_set_aer_mmd(params
, vars
);
5594 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_DEVAD
+ port
*0x18,
5600 DP(NETIF_MSG_LINK
, "XGXS 1G loopback enable\n");
5602 CL45_RD_OVER_CL22(bp
, port
,
5604 MDIO_REG_BANK_COMBO_IEEE0
,
5605 MDIO_COMBO_IEEE0_MII_CONTROL
,
5608 CL45_WR_OVER_CL22(bp
, port
,
5610 MDIO_REG_BANK_COMBO_IEEE0
,
5611 MDIO_COMBO_IEEE0_MII_CONTROL
,
5613 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK
));
5618 static void bnx2x_ext_phy_loopback(struct link_params
*params
)
5620 struct bnx2x
*bp
= params
->bp
;
5624 if (params
->switch_cfg
== SWITCH_CFG_10G
) {
5625 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
5626 ext_phy_addr
= XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
5627 /* CL37 Autoneg Enabled */
5628 switch (ext_phy_type
) {
5629 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
5630 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
:
5632 "ext_phy_loopback: We should not get here\n");
5634 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
5635 DP(NETIF_MSG_LINK
, "ext_phy_loopback: 8705\n");
5637 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
5638 DP(NETIF_MSG_LINK
, "ext_phy_loopback: 8706\n");
5640 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
:
5641 DP(NETIF_MSG_LINK
, "PMA/PMD ext_phy_loopback: 8726\n");
5642 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
5648 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
5649 /* SFX7101_XGXS_TEST1 */
5650 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
5653 MDIO_XS_SFX7101_XGXS_TEST1
,
5656 "ext_phy_loopback: set ext phy loopback\n");
5658 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
5661 } /* switch external PHY type */
5664 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
5665 ext_phy_addr
= (params
->ext_phy_config
&
5666 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK
)
5667 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT
;
5673 *------------------------------------------------------------------------
5674 * bnx2x_override_led_value -
5676 * Override the led value of the requsted led
5678 *------------------------------------------------------------------------
5680 u8
bnx2x_override_led_value(struct bnx2x
*bp
, u8 port
,
5681 u32 led_idx
, u32 value
)
5685 /* If port 0 then use EMAC0, else use EMAC1*/
5686 u32 emac_base
= (port
) ? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
5689 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
5690 port
, led_idx
, value
);
5693 case 0: /* 10MB led */
5694 /* Read the current value of the LED register in
5696 reg_val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_LED
);
5697 /* Set the OVERRIDE bit to 1 */
5698 reg_val
|= EMAC_LED_OVERRIDE
;
5699 /* If value is 1, set the 10M_OVERRIDE bit,
5700 otherwise reset it.*/
5701 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_10MB_OVERRIDE
) :
5702 (reg_val
& ~EMAC_LED_10MB_OVERRIDE
);
5703 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
5705 case 1: /*100MB led */
5706 /*Read the current value of the LED register in
5708 reg_val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_LED
);
5709 /* Set the OVERRIDE bit to 1 */
5710 reg_val
|= EMAC_LED_OVERRIDE
;
5711 /* If value is 1, set the 100M_OVERRIDE bit,
5712 otherwise reset it.*/
5713 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_100MB_OVERRIDE
) :
5714 (reg_val
& ~EMAC_LED_100MB_OVERRIDE
);
5715 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
5717 case 2: /* 1000MB led */
5718 /* Read the current value of the LED register in the
5720 reg_val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_LED
);
5721 /* Set the OVERRIDE bit to 1 */
5722 reg_val
|= EMAC_LED_OVERRIDE
;
5723 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
5725 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_1000MB_OVERRIDE
) :
5726 (reg_val
& ~EMAC_LED_1000MB_OVERRIDE
);
5727 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
5729 case 3: /* 2500MB led */
5730 /* Read the current value of the LED register in the
5732 reg_val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_LED
);
5733 /* Set the OVERRIDE bit to 1 */
5734 reg_val
|= EMAC_LED_OVERRIDE
;
5735 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
5737 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_2500MB_OVERRIDE
) :
5738 (reg_val
& ~EMAC_LED_2500MB_OVERRIDE
);
5739 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
5741 case 4: /*10G led */
5743 REG_WR(bp
, NIG_REG_LED_10G_P0
,
5746 REG_WR(bp
, NIG_REG_LED_10G_P1
,
5750 case 5: /* TRAFFIC led */
5751 /* Find if the traffic control is via BMAC or EMAC */
5753 reg_val
= REG_RD(bp
, NIG_REG_NIG_EMAC0_EN
);
5755 reg_val
= REG_RD(bp
, NIG_REG_NIG_EMAC1_EN
);
5757 /* Override the traffic led in the EMAC:*/
5759 /* Read the current value of the LED register in
5761 reg_val
= REG_RD(bp
, emac_base
+
5763 /* Set the TRAFFIC_OVERRIDE bit to 1 */
5764 reg_val
|= EMAC_LED_OVERRIDE
;
5765 /* If value is 1, set the TRAFFIC bit, otherwise
5767 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_TRAFFIC
) :
5768 (reg_val
& ~EMAC_LED_TRAFFIC
);
5769 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
5770 } else { /* Override the traffic led in the BMAC: */
5771 REG_WR(bp
, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5773 REG_WR(bp
, NIG_REG_LED_CONTROL_TRAFFIC_P0
+ port
*4,
5779 "bnx2x_override_led_value() unknown led index %d "
5780 "(should be 0-5)\n", led_idx
);
5788 u8
bnx2x_set_led(struct link_params
*params
, u8 mode
, u32 speed
)
5790 u8 port
= params
->port
;
5791 u16 hw_led_mode
= params
->hw_led_mode
;
5794 u32 emac_base
= port
? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
5795 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
5796 struct bnx2x
*bp
= params
->bp
;
5797 DP(NETIF_MSG_LINK
, "bnx2x_set_led: port %x, mode %d\n", port
, mode
);
5798 DP(NETIF_MSG_LINK
, "speed 0x%x, hw_led_mode 0x%x\n",
5799 speed
, hw_led_mode
);
5802 REG_WR(bp
, NIG_REG_LED_10G_P0
+ port
*4, 0);
5803 REG_WR(bp
, NIG_REG_LED_MODE_P0
+ port
*4,
5804 SHARED_HW_CFG_LED_MAC1
);
5806 tmp
= EMAC_RD(bp
, EMAC_REG_EMAC_LED
);
5807 EMAC_WR(bp
, EMAC_REG_EMAC_LED
, (tmp
| EMAC_LED_OVERRIDE
));
5811 if (ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) {
5812 REG_WR(bp
, NIG_REG_LED_MODE_P0
+ port
*4, 0);
5813 REG_WR(bp
, NIG_REG_LED_10G_P0
+ port
*4, 1);
5815 REG_WR(bp
, NIG_REG_LED_MODE_P0
+ port
*4,
5819 REG_WR(bp
, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
+
5821 /* Set blinking rate to ~15.9Hz */
5822 REG_WR(bp
, NIG_REG_LED_CONTROL_BLINK_RATE_P0
+ port
*4,
5823 LED_BLINK_RATE_VAL
);
5824 REG_WR(bp
, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0
+
5826 tmp
= EMAC_RD(bp
, EMAC_REG_EMAC_LED
);
5827 EMAC_WR(bp
, EMAC_REG_EMAC_LED
,
5828 (tmp
& (~EMAC_LED_OVERRIDE
)));
5830 if (CHIP_IS_E1(bp
) &&
5831 ((speed
== SPEED_2500
) ||
5832 (speed
== SPEED_1000
) ||
5833 (speed
== SPEED_100
) ||
5834 (speed
== SPEED_10
))) {
5835 /* On Everest 1 Ax chip versions for speeds less than
5836 10G LED scheme is different */
5837 REG_WR(bp
, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5839 REG_WR(bp
, NIG_REG_LED_CONTROL_TRAFFIC_P0
+
5841 REG_WR(bp
, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0
+
5848 DP(NETIF_MSG_LINK
, "bnx2x_set_led: Invalid led mode %d\n",
5856 u8
bnx2x_test_link(struct link_params
*params
, struct link_vars
*vars
)
5858 struct bnx2x
*bp
= params
->bp
;
5861 CL45_RD_OVER_CL22(bp
, params
->port
,
5863 MDIO_REG_BANK_GP_STATUS
,
5864 MDIO_GP_STATUS_TOP_AN_STATUS1
,
5866 /* link is up only if both local phy and external phy are up */
5867 if ((gp_status
& MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS
) &&
5868 bnx2x_ext_phy_is_link_up(params
, vars
, 1))
5874 static u8
bnx2x_link_initialize(struct link_params
*params
,
5875 struct link_vars
*vars
)
5877 struct bnx2x
*bp
= params
->bp
;
5878 u8 port
= params
->port
;
5881 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
5883 /* Activate the external PHY */
5884 bnx2x_ext_phy_reset(params
, vars
);
5886 bnx2x_set_aer_mmd(params
, vars
);
5888 if (vars
->phy_flags
& PHY_XGXS_FLAG
)
5889 bnx2x_set_master_ln(params
);
5891 rc
= bnx2x_reset_unicore(params
);
5892 /* reset the SerDes and wait for reset bit return low */
5896 bnx2x_set_aer_mmd(params
, vars
);
5898 /* setting the masterLn_def again after the reset */
5899 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
5900 bnx2x_set_master_ln(params
);
5901 bnx2x_set_swap_lanes(params
);
5904 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
5905 if ((params
->req_line_speed
&&
5906 ((params
->req_line_speed
== SPEED_100
) ||
5907 (params
->req_line_speed
== SPEED_10
))) ||
5908 (!params
->req_line_speed
&&
5909 (params
->speed_cap_mask
>=
5910 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL
) &&
5911 (params
->speed_cap_mask
<
5912 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
)
5914 vars
->phy_flags
|= PHY_SGMII_FLAG
;
5916 vars
->phy_flags
&= ~PHY_SGMII_FLAG
;
5919 /* In case of external phy existance, the line speed would be the
5920 line speed linked up by the external phy. In case it is direct only,
5921 then the line_speed during initialization will be equal to the
5923 vars
->line_speed
= params
->req_line_speed
;
5925 bnx2x_calc_ieee_aneg_adv(params
, &vars
->ieee_fc
);
5927 /* init ext phy and enable link state int */
5928 non_ext_phy
= ((ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) ||
5929 (params
->loopback_mode
== LOOPBACK_XGXS_10
));
5932 (ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
) ||
5933 (ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
) ||
5934 (ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
) ||
5935 (params
->loopback_mode
== LOOPBACK_EXT_PHY
)) {
5936 if (params
->req_line_speed
== SPEED_AUTO_NEG
)
5937 bnx2x_set_parallel_detection(params
, vars
->phy_flags
);
5938 bnx2x_init_internal_phy(params
, vars
, non_ext_phy
);
5942 rc
|= bnx2x_ext_phy_init(params
, vars
);
5944 bnx2x_bits_dis(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
5945 (NIG_STATUS_XGXS0_LINK10G
|
5946 NIG_STATUS_XGXS0_LINK_STATUS
|
5947 NIG_STATUS_SERDES0_LINK_STATUS
));
5954 u8
bnx2x_phy_init(struct link_params
*params
, struct link_vars
*vars
)
5956 struct bnx2x
*bp
= params
->bp
;
5959 DP(NETIF_MSG_LINK
, "Phy Initialization started\n");
5960 DP(NETIF_MSG_LINK
, "req_speed %d, req_flowctrl %d\n",
5961 params
->req_line_speed
, params
->req_flow_ctrl
);
5962 vars
->link_status
= 0;
5963 vars
->phy_link_up
= 0;
5965 vars
->line_speed
= 0;
5966 vars
->duplex
= DUPLEX_FULL
;
5967 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
5968 vars
->mac_type
= MAC_TYPE_NONE
;
5970 if (params
->switch_cfg
== SWITCH_CFG_1G
)
5971 vars
->phy_flags
= PHY_SERDES_FLAG
;
5973 vars
->phy_flags
= PHY_XGXS_FLAG
;
5975 /* disable attentions */
5976 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ params
->port
*4,
5977 (NIG_MASK_XGXS0_LINK_STATUS
|
5978 NIG_MASK_XGXS0_LINK10G
|
5979 NIG_MASK_SERDES0_LINK_STATUS
|
5982 bnx2x_emac_init(params
, vars
);
5984 if (CHIP_REV_IS_FPGA(bp
)) {
5987 vars
->line_speed
= SPEED_10000
;
5988 vars
->duplex
= DUPLEX_FULL
;
5989 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
5990 vars
->link_status
= (LINK_STATUS_LINK_UP
| LINK_10GTFD
);
5991 /* enable on E1.5 FPGA */
5992 if (CHIP_IS_E1H(bp
)) {
5994 (BNX2X_FLOW_CTRL_TX
|
5995 BNX2X_FLOW_CTRL_RX
);
5996 vars
->link_status
|=
5997 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED
|
5998 LINK_STATUS_RX_FLOW_CONTROL_ENABLED
);
6001 bnx2x_emac_enable(params
, vars
, 0);
6002 bnx2x_pbf_update(params
, vars
->flow_ctrl
, vars
->line_speed
);
6004 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ params
->port
*4, 0);
6006 /* update shared memory */
6007 bnx2x_update_mng(params
, vars
->link_status
);
6012 if (CHIP_REV_IS_EMUL(bp
)) {
6015 vars
->line_speed
= SPEED_10000
;
6016 vars
->duplex
= DUPLEX_FULL
;
6017 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
6018 vars
->link_status
= (LINK_STATUS_LINK_UP
| LINK_10GTFD
);
6020 bnx2x_bmac_enable(params
, vars
, 0);
6022 bnx2x_pbf_update(params
, vars
->flow_ctrl
, vars
->line_speed
);
6024 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
6025 + params
->port
*4, 0);
6027 /* update shared memory */
6028 bnx2x_update_mng(params
, vars
->link_status
);
6033 if (params
->loopback_mode
== LOOPBACK_BMAC
) {
6036 vars
->line_speed
= SPEED_10000
;
6037 vars
->duplex
= DUPLEX_FULL
;
6038 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
6039 vars
->mac_type
= MAC_TYPE_BMAC
;
6041 vars
->phy_flags
= PHY_XGXS_FLAG
;
6043 bnx2x_phy_deassert(params
, vars
->phy_flags
);
6044 /* set bmac loopback */
6045 bnx2x_bmac_enable(params
, vars
, 1);
6047 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+
6050 } else if (params
->loopback_mode
== LOOPBACK_EMAC
) {
6053 vars
->line_speed
= SPEED_1000
;
6054 vars
->duplex
= DUPLEX_FULL
;
6055 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
6056 vars
->mac_type
= MAC_TYPE_EMAC
;
6058 vars
->phy_flags
= PHY_XGXS_FLAG
;
6060 bnx2x_phy_deassert(params
, vars
->phy_flags
);
6061 /* set bmac loopback */
6062 bnx2x_emac_enable(params
, vars
, 1);
6063 bnx2x_emac_program(params
, vars
->line_speed
,
6065 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+
6068 } else if ((params
->loopback_mode
== LOOPBACK_XGXS_10
) ||
6069 (params
->loopback_mode
== LOOPBACK_EXT_PHY
)) {
6072 vars
->line_speed
= SPEED_10000
;
6073 vars
->duplex
= DUPLEX_FULL
;
6074 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
6076 vars
->phy_flags
= PHY_XGXS_FLAG
;
6079 NIG_REG_XGXS0_CTRL_PHY_ADDR
+
6081 params
->phy_addr
= (u8
)val
;
6083 bnx2x_phy_deassert(params
, vars
->phy_flags
);
6084 bnx2x_link_initialize(params
, vars
);
6086 vars
->mac_type
= MAC_TYPE_BMAC
;
6088 bnx2x_bmac_enable(params
, vars
, 0);
6090 if (params
->loopback_mode
== LOOPBACK_XGXS_10
) {
6091 /* set 10G XGXS loopback */
6092 bnx2x_set_xgxs_loopback(params
, vars
, 1);
6094 /* set external phy loopback */
6095 bnx2x_ext_phy_loopback(params
);
6097 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+
6100 bnx2x_set_led(params
, LED_MODE_OPER
, vars
->line_speed
);
6104 bnx2x_phy_deassert(params
, vars
->phy_flags
);
6105 switch (params
->switch_cfg
) {
6107 vars
->phy_flags
|= PHY_SERDES_FLAG
;
6108 if ((params
->ext_phy_config
&
6109 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK
) ==
6110 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482
) {
6111 vars
->phy_flags
|= PHY_SGMII_FLAG
;
6115 NIG_REG_SERDES0_CTRL_PHY_ADDR
+
6118 params
->phy_addr
= (u8
)val
;
6121 case SWITCH_CFG_10G
:
6122 vars
->phy_flags
|= PHY_XGXS_FLAG
;
6124 NIG_REG_XGXS0_CTRL_PHY_ADDR
+
6126 params
->phy_addr
= (u8
)val
;
6130 DP(NETIF_MSG_LINK
, "Invalid switch_cfg\n");
6133 DP(NETIF_MSG_LINK
, "Phy address = 0x%x\n", params
->phy_addr
);
6135 bnx2x_link_initialize(params
, vars
);
6137 bnx2x_link_int_enable(params
);
6142 static void bnx2x_8726_reset_phy(struct bnx2x
*bp
, u8 port
, u8 ext_phy_addr
)
6144 DP(NETIF_MSG_LINK
, "bnx2x_8726_reset_phy port %d\n", port
);
6146 /* Set serial boot control for external load */
6147 bnx2x_cl45_write(bp
, port
,
6148 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
, ext_phy_addr
,
6150 MDIO_PMA_REG_GEN_CTRL
, 0x0001);
6153 u8
bnx2x_link_reset(struct link_params
*params
, struct link_vars
*vars
,
6156 struct bnx2x
*bp
= params
->bp
;
6157 u32 ext_phy_config
= params
->ext_phy_config
;
6158 u8 port
= params
->port
;
6159 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(ext_phy_config
);
6160 u32 val
= REG_RD(bp
, params
->shmem_base
+
6161 offsetof(struct shmem_region
, dev_info
.
6162 port_feature_config
[params
->port
].
6164 DP(NETIF_MSG_LINK
, "Resetting the link of port %d\n", port
);
6165 /* disable attentions */
6166 vars
->link_status
= 0;
6167 bnx2x_update_mng(params
, vars
->link_status
);
6168 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4,
6169 (NIG_MASK_XGXS0_LINK_STATUS
|
6170 NIG_MASK_XGXS0_LINK10G
|
6171 NIG_MASK_SERDES0_LINK_STATUS
|
6174 /* activate nig drain */
6175 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ port
*4, 1);
6177 /* disable nig egress interface */
6178 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0);
6179 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0);
6181 /* Stop BigMac rx */
6182 bnx2x_bmac_rx_disable(bp
, port
);
6185 REG_WR(bp
, NIG_REG_NIG_EMAC0_EN
+ port
*4, 0);
6188 /* The PHY reset is controled by GPIO 1
6189 * Hold it as vars low
6191 /* clear link led */
6192 bnx2x_set_led(params
, LED_MODE_OFF
, 0);
6193 if (reset_ext_phy
) {
6194 switch (ext_phy_type
) {
6195 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
6196 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
6199 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
:
6202 /* Disable Transmitter */
6204 XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
6205 if ((val
& PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK
) ==
6206 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER
)
6207 bnx2x_sfp_set_transmitter(bp
, port
,
6208 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
6212 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
6213 DP(NETIF_MSG_LINK
, "Setting 8073 port %d into "
6216 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
6217 MISC_REGISTERS_GPIO_OUTPUT_LOW
,
6220 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
:
6223 XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
6224 /* Set soft reset */
6225 bnx2x_8726_reset_phy(bp
, params
->port
, ext_phy_addr
);
6228 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823
:
6231 XGXS_EXT_PHY_ADDR(params
->ext_phy_config
);
6232 bnx2x_cl45_write(bp
, port
,
6233 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
,
6236 MDIO_AN_REG_CTRL
, 0x0000);
6237 bnx2x_cl45_write(bp
, port
,
6238 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
,
6241 MDIO_PMA_REG_CTRL
, 1);
6246 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
6247 MISC_REGISTERS_GPIO_OUTPUT_LOW
,
6249 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
6250 MISC_REGISTERS_GPIO_OUTPUT_LOW
,
6252 DP(NETIF_MSG_LINK
, "reset external PHY\n");
6255 /* reset the SerDes/XGXS */
6256 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_CLEAR
,
6257 (0x1ff << (port
*16)));
6260 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
6261 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
6263 /* disable nig ingress interface */
6264 REG_WR(bp
, NIG_REG_BMAC0_IN_EN
+ port
*4, 0);
6265 REG_WR(bp
, NIG_REG_EMAC0_IN_EN
+ port
*4, 0);
6266 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0);
6267 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0);
6272 static u8
bnx2x_update_link_down(struct link_params
*params
,
6273 struct link_vars
*vars
)
6275 struct bnx2x
*bp
= params
->bp
;
6276 u8 port
= params
->port
;
6278 DP(NETIF_MSG_LINK
, "Port %x: Link is down\n", port
);
6279 bnx2x_set_led(params
, LED_MODE_OFF
, 0);
6281 /* indicate no mac active */
6282 vars
->mac_type
= MAC_TYPE_NONE
;
6284 /* update shared memory */
6285 vars
->link_status
= 0;
6286 vars
->line_speed
= 0;
6287 bnx2x_update_mng(params
, vars
->link_status
);
6289 /* activate nig drain */
6290 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ port
*4, 1);
6293 REG_WR(bp
, NIG_REG_NIG_EMAC0_EN
+ port
*4, 0);
6298 bnx2x_bmac_rx_disable(bp
, params
->port
);
6299 REG_WR(bp
, GRCBASE_MISC
+
6300 MISC_REGISTERS_RESET_REG_2_CLEAR
,
6301 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
6305 static u8
bnx2x_update_link_up(struct link_params
*params
,
6306 struct link_vars
*vars
,
6307 u8 link_10g
, u32 gp_status
)
6309 struct bnx2x
*bp
= params
->bp
;
6310 u8 port
= params
->port
;
6313 vars
->link_status
|= LINK_STATUS_LINK_UP
;
6315 bnx2x_bmac_enable(params
, vars
, 0);
6316 bnx2x_set_led(params
, LED_MODE_OPER
, SPEED_10000
);
6318 rc
= bnx2x_emac_program(params
, vars
->line_speed
,
6321 bnx2x_emac_enable(params
, vars
, 0);
6324 if (gp_status
& MDIO_AN_CL73_OR_37_COMPLETE
) {
6325 if (!(vars
->phy_flags
&
6327 bnx2x_set_gmii_tx_driver(params
);
6332 rc
|= bnx2x_pbf_update(params
, vars
->flow_ctrl
,
6336 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ port
*4, 0);
6338 /* update shared memory */
6339 bnx2x_update_mng(params
, vars
->link_status
);
6343 /* This function should called upon link interrupt */
6344 /* In case vars->link_up, driver needs to
6347 3. Update the shared memory
6351 1. Update shared memory
6356 u8
bnx2x_link_update(struct link_params
*params
, struct link_vars
*vars
)
6358 struct bnx2x
*bp
= params
->bp
;
6359 u8 port
= params
->port
;
6362 u8 ext_phy_link_up
, rc
= 0;
6366 DP(NETIF_MSG_LINK
, "port %x, XGXS?%x, int_status 0x%x\n",
6367 port
, (vars
->phy_flags
& PHY_XGXS_FLAG
),
6368 REG_RD(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4));
6370 is_mi_int
= (u8
)(REG_RD(bp
, NIG_REG_EMAC0_STATUS_MISC_MI_INT
+
6372 DP(NETIF_MSG_LINK
, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
6373 REG_RD(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4),
6376 NIG_REG_SERDES0_STATUS_LINK_STATUS
+ port
*0x3c));
6378 DP(NETIF_MSG_LINK
, " 10G %x, XGXS_LINK %x\n",
6379 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK10G
+ port
*0x68),
6380 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK_STATUS
+ port
*0x68));
6383 REG_WR(bp
, NIG_REG_NIG_EMAC0_EN
+ port
*4, 0);
6385 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
6387 /* Check external link change only for non-direct */
6388 ext_phy_link_up
= bnx2x_ext_phy_is_link_up(params
, vars
, is_mi_int
);
6390 /* Read gp_status */
6391 CL45_RD_OVER_CL22(bp
, port
, params
->phy_addr
,
6392 MDIO_REG_BANK_GP_STATUS
,
6393 MDIO_GP_STATUS_TOP_AN_STATUS1
,
6396 rc
= bnx2x_link_settings_status(params
, vars
, gp_status
,
6401 /* anything 10 and over uses the bmac */
6402 link_10g
= ((vars
->line_speed
== SPEED_10000
) ||
6403 (vars
->line_speed
== SPEED_12000
) ||
6404 (vars
->line_speed
== SPEED_12500
) ||
6405 (vars
->line_speed
== SPEED_13000
) ||
6406 (vars
->line_speed
== SPEED_15000
) ||
6407 (vars
->line_speed
== SPEED_16000
));
6409 bnx2x_link_int_ack(params
, vars
, link_10g
, is_mi_int
);
6411 /* In case external phy link is up, and internal link is down
6412 ( not initialized yet probably after link initialization, it needs
6414 Note that after link down-up as result of cable plug,
6415 the xgxs link would probably become up again without the need to
6418 if ((ext_phy_type
!= PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
) &&
6419 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
) &&
6420 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
) &&
6421 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
) &&
6422 (ext_phy_link_up
&& !vars
->phy_link_up
))
6423 bnx2x_init_internal_phy(params
, vars
, 0);
6425 /* link is up only if both local phy and external phy are up */
6426 vars
->link_up
= (ext_phy_link_up
&& vars
->phy_link_up
);
6429 rc
= bnx2x_update_link_up(params
, vars
, link_10g
, gp_status
);
6431 rc
= bnx2x_update_link_down(params
, vars
);
6436 static u8
bnx2x_8073_common_init_phy(struct bnx2x
*bp
, u32 shmem_base
)
6438 u8 ext_phy_addr
[PORT_MAX
];
6442 /* PART1 - Reset both phys */
6443 for (port
= PORT_MAX
- 1; port
>= PORT_0
; port
--) {
6444 /* Extract the ext phy address for the port */
6445 u32 ext_phy_config
= REG_RD(bp
, shmem_base
+
6446 offsetof(struct shmem_region
,
6447 dev_info
.port_hw_config
[port
].external_phy_config
));
6449 /* disable attentions */
6450 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4,
6451 (NIG_MASK_XGXS0_LINK_STATUS
|
6452 NIG_MASK_XGXS0_LINK10G
|
6453 NIG_MASK_SERDES0_LINK_STATUS
|
6456 ext_phy_addr
[port
] = XGXS_EXT_PHY_ADDR(ext_phy_config
);
6458 /* Need to take the phy out of low power mode in order
6459 to write to access its registers */
6460 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
6461 MISC_REGISTERS_GPIO_OUTPUT_HIGH
, port
);
6464 bnx2x_cl45_write(bp
, port
,
6465 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
6472 /* Add delay of 150ms after reset */
6475 /* PART2 - Download firmware to both phys */
6476 for (port
= PORT_MAX
- 1; port
>= PORT_0
; port
--) {
6479 bnx2x_bcm8073_external_rom_boot(bp
, port
,
6480 ext_phy_addr
[port
], shmem_base
);
6482 bnx2x_cl45_read(bp
, port
, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
6485 MDIO_PMA_REG_ROM_VER1
, &fw_ver1
);
6486 if (fw_ver1
== 0 || fw_ver1
== 0x4321) {
6488 "bnx2x_8073_common_init_phy port %x:"
6489 "Download failed. fw version = 0x%x\n",
6494 /* Only set bit 10 = 1 (Tx power down) */
6495 bnx2x_cl45_read(bp
, port
,
6496 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
6499 MDIO_PMA_REG_TX_POWER_DOWN
, &val
);
6501 /* Phase1 of TX_POWER_DOWN reset */
6502 bnx2x_cl45_write(bp
, port
,
6503 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
6506 MDIO_PMA_REG_TX_POWER_DOWN
,
6510 /* Toggle Transmitter: Power down and then up with 600ms
6514 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
6515 for (port
= PORT_MAX
- 1; port
>= PORT_0
; port
--) {
6516 /* Phase2 of POWER_DOWN_RESET */
6517 /* Release bit 10 (Release Tx power down) */
6518 bnx2x_cl45_read(bp
, port
,
6519 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
6522 MDIO_PMA_REG_TX_POWER_DOWN
, &val
);
6524 bnx2x_cl45_write(bp
, port
,
6525 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
6528 MDIO_PMA_REG_TX_POWER_DOWN
, (val
& (~(1<<10))));
6531 /* Read modify write the SPI-ROM version select register */
6532 bnx2x_cl45_read(bp
, port
,
6533 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
6536 MDIO_PMA_REG_EDC_FFE_MAIN
, &val
);
6537 bnx2x_cl45_write(bp
, port
,
6538 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
6541 MDIO_PMA_REG_EDC_FFE_MAIN
, (val
| (1<<12)));
6543 /* set GPIO2 back to LOW */
6544 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
6545 MISC_REGISTERS_GPIO_OUTPUT_LOW
, port
);
6551 static u8
bnx2x_8727_common_init_phy(struct bnx2x
*bp
, u32 shmem_base
)
6553 u8 ext_phy_addr
[PORT_MAX
];
6554 s8 port
, first_port
, i
;
6555 u32 swap_val
, swap_override
;
6556 DP(NETIF_MSG_LINK
, "Executing BCM8727 common init\n");
6557 swap_val
= REG_RD(bp
, NIG_REG_PORT_SWAP
);
6558 swap_override
= REG_RD(bp
, NIG_REG_STRAP_OVERRIDE
);
6560 bnx2x_ext_phy_hw_reset(bp
, 1 ^ (swap_val
&& swap_override
));
6563 if (swap_val
&& swap_override
)
6564 first_port
= PORT_0
;
6566 first_port
= PORT_1
;
6568 /* PART1 - Reset both phys */
6569 for (i
= 0, port
= first_port
; i
< PORT_MAX
; i
++, port
= !port
) {
6570 /* Extract the ext phy address for the port */
6571 u32 ext_phy_config
= REG_RD(bp
, shmem_base
+
6572 offsetof(struct shmem_region
,
6573 dev_info
.port_hw_config
[port
].external_phy_config
));
6575 /* disable attentions */
6576 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4,
6577 (NIG_MASK_XGXS0_LINK_STATUS
|
6578 NIG_MASK_XGXS0_LINK10G
|
6579 NIG_MASK_SERDES0_LINK_STATUS
|
6582 ext_phy_addr
[port
] = XGXS_EXT_PHY_ADDR(ext_phy_config
);
6585 bnx2x_cl45_write(bp
, port
,
6586 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
6593 /* Add delay of 150ms after reset */
6596 /* PART2 - Download firmware to both phys */
6597 for (i
= 0, port
= first_port
; i
< PORT_MAX
; i
++, port
= !port
) {
6600 bnx2x_bcm8727_external_rom_boot(bp
, port
,
6601 ext_phy_addr
[port
], shmem_base
);
6603 bnx2x_cl45_read(bp
, port
, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
6606 MDIO_PMA_REG_ROM_VER1
, &fw_ver1
);
6607 if (fw_ver1
== 0 || fw_ver1
== 0x4321) {
6609 "bnx2x_8727_common_init_phy port %x:"
6610 "Download failed. fw version = 0x%x\n",
6620 static u8
bnx2x_8726_common_init_phy(struct bnx2x
*bp
, u32 shmem_base
)
6626 /* Use port1 because of the static port-swap */
6627 /* Enable the module detection interrupt */
6628 val
= REG_RD(bp
, MISC_REG_GPIO_EVENT_EN
);
6629 val
|= ((1<<MISC_REGISTERS_GPIO_3
)|
6630 (1<<(MISC_REGISTERS_GPIO_3
+ MISC_REGISTERS_GPIO_PORT_SHIFT
)));
6631 REG_WR(bp
, MISC_REG_GPIO_EVENT_EN
, val
);
6633 bnx2x_ext_phy_hw_reset(bp
, 1);
6635 for (port
= 0; port
< PORT_MAX
; port
++) {
6636 /* Extract the ext phy address for the port */
6637 u32 ext_phy_config
= REG_RD(bp
, shmem_base
+
6638 offsetof(struct shmem_region
,
6639 dev_info
.port_hw_config
[port
].external_phy_config
));
6641 ext_phy_addr
= XGXS_EXT_PHY_ADDR(ext_phy_config
);
6642 DP(NETIF_MSG_LINK
, "8726_common_init : ext_phy_addr = 0x%x\n",
6645 bnx2x_8726_reset_phy(bp
, port
, ext_phy_addr
);
6647 /* Set fault module detected LED on */
6648 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_0
,
6649 MISC_REGISTERS_GPIO_HIGH
,
6657 static u8
bnx2x_84823_common_init_phy(struct bnx2x
*bp
, u32 shmem_base
)
6660 bnx2x_ext_phy_hw_reset(bp
, 1);
6663 u8
bnx2x_common_init_phy(struct bnx2x
*bp
, u32 shmem_base
)
6668 DP(NETIF_MSG_LINK
, "Begin common phy init\n");
6670 /* Read the ext_phy_type for arbitrary port(0) */
6671 ext_phy_type
= XGXS_EXT_PHY_TYPE(
6672 REG_RD(bp
, shmem_base
+
6673 offsetof(struct shmem_region
,
6674 dev_info
.port_hw_config
[0].external_phy_config
)));
6676 switch (ext_phy_type
) {
6677 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
6679 rc
= bnx2x_8073_common_init_phy(bp
, shmem_base
);
6683 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
:
6684 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC
:
6685 rc
= bnx2x_8727_common_init_phy(bp
, shmem_base
);
6688 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
:
6689 /* GPIO1 affects both ports, so there's need to pull
6690 it for single port alone */
6691 rc
= bnx2x_8726_common_init_phy(bp
, shmem_base
);
6693 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823
:
6694 rc
= bnx2x_84823_common_init_phy(bp
, shmem_base
);
6698 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
6706 void bnx2x_sfx7101_sp_sw_reset(struct bnx2x
*bp
, u8 port
, u8 phy_addr
)
6710 bnx2x_cl45_read(bp
, port
,
6711 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
6714 MDIO_PMA_REG_7101_RESET
, &val
);
6716 for (cnt
= 0; cnt
< 10; cnt
++) {
6718 /* Writes a self-clearing reset */
6719 bnx2x_cl45_write(bp
, port
,
6720 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
6723 MDIO_PMA_REG_7101_RESET
,
6725 /* Wait for clear */
6726 bnx2x_cl45_read(bp
, port
,
6727 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
6730 MDIO_PMA_REG_7101_RESET
, &val
);
6732 if ((val
& (1<<15)) == 0)