1 /* Copyright 2008 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 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/pci.h>
20 #include <linux/netdevice.h>
21 #include <linux/delay.h>
22 #include <linux/ethtool.h>
23 #include <linux/mutex.h>
24 #include <linux/version.h>
26 #include "bnx2x_reg.h"
27 #include "bnx2x_fw_defs.h"
28 #include "bnx2x_hsi.h"
29 #include "bnx2x_link.h"
32 /********************************************************/
33 #define SUPPORT_CL73 0 /* Currently no */
35 #define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
36 #define ETH_MIN_PACKET_SIZE 60
37 #define ETH_MAX_PACKET_SIZE 1500
38 #define ETH_MAX_JUMBO_PACKET_SIZE 9600
39 #define MDIO_ACCESS_TIMEOUT 1000
40 #define BMAC_CONTROL_RX_ENABLE 2
42 /***********************************************************/
43 /* Shortcut definitions */
44 /***********************************************************/
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
143 /**********************************************************/
145 /**********************************************************/
146 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
147 bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
148 DEFAULT_PHY_DEV_ADDR, \
149 (_bank + (_addr & 0xf)), \
152 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
153 bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
154 DEFAULT_PHY_DEV_ADDR, \
155 (_bank + (_addr & 0xf)), \
158 static void bnx2x_set_phy_mdio(struct link_params
*params
)
160 struct bnx2x
*bp
= params
->bp
;
161 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_ST
+
162 params
->port
*0x18, 0);
163 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_DEVAD
+ params
->port
*0x18,
164 DEFAULT_PHY_DEV_ADDR
);
167 static u32
bnx2x_bits_en(struct bnx2x
*bp
, u32 reg
, u32 bits
)
169 u32 val
= REG_RD(bp
, reg
);
172 REG_WR(bp
, reg
, val
);
176 static u32
bnx2x_bits_dis(struct bnx2x
*bp
, u32 reg
, u32 bits
)
178 u32 val
= REG_RD(bp
, reg
);
181 REG_WR(bp
, reg
, val
);
185 static void bnx2x_emac_init(struct link_params
*params
,
186 struct link_vars
*vars
)
188 /* reset and unreset the emac core */
189 struct bnx2x
*bp
= params
->bp
;
190 u8 port
= params
->port
;
191 u32 emac_base
= port
? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
195 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
196 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE
<< port
));
198 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
199 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE
<< port
));
201 /* init emac - use read-modify-write */
202 /* self clear reset */
203 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
204 EMAC_WR(EMAC_REG_EMAC_MODE
, (val
| EMAC_MODE_RESET
));
209 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
210 DP(NETIF_MSG_LINK
, "EMAC reset reg is %u\n", val
);
212 DP(NETIF_MSG_LINK
, "EMAC timeout!\n");
216 }while (val
& EMAC_MODE_RESET
);
218 /* Set mac address */
219 val
= ((params
->mac_addr
[0] << 8) |
220 params
->mac_addr
[1]);
221 EMAC_WR(EMAC_REG_EMAC_MAC_MATCH
, val
);
223 val
= ((params
->mac_addr
[2] << 24) |
224 (params
->mac_addr
[3] << 16) |
225 (params
->mac_addr
[4] << 8) |
226 params
->mac_addr
[5]);
227 EMAC_WR(EMAC_REG_EMAC_MAC_MATCH
+ 4, val
);
230 static u8
bnx2x_emac_enable(struct link_params
*params
,
231 struct link_vars
*vars
, u8 lb
)
233 struct bnx2x
*bp
= params
->bp
;
234 u8 port
= params
->port
;
235 u32 emac_base
= port
? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
238 DP(NETIF_MSG_LINK
, "enabling EMAC\n");
240 /* enable emac and not bmac */
241 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_PORT
+ port
*4, 1);
244 if (CHIP_REV_IS_EMUL(bp
)) {
245 /* Use lane 1 (of lanes 0-3) */
246 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+ port
*4, 1);
247 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+
253 if (CHIP_REV_IS_FPGA(bp
)) {
254 /* Use lane 1 (of lanes 0-3) */
255 DP(NETIF_MSG_LINK
, "bnx2x_emac_enable: Setting FPGA\n");
257 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+ port
*4, 1);
258 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+ port
*4,
262 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
263 u32 ser_lane
= ((params
->lane_config
&
264 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
265 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
267 DP(NETIF_MSG_LINK
, "XGXS\n");
268 /* select the master lanes (out of 0-3) */
269 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+
272 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+
275 } else { /* SerDes */
276 DP(NETIF_MSG_LINK
, "SerDes\n");
278 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+
283 REG_WR(bp
, NIG_REG_NIG_EMAC0_EN
+ port
*4, 1);
285 if (CHIP_REV_IS_SLOW(bp
)) {
286 /* config GMII mode */
287 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
288 EMAC_WR(EMAC_REG_EMAC_MODE
,
289 (val
| EMAC_MODE_PORT_GMII
));
291 /* pause enable/disable */
292 bnx2x_bits_dis(bp
, emac_base
+ EMAC_REG_EMAC_RX_MODE
,
293 EMAC_RX_MODE_FLOW_EN
);
294 if (vars
->flow_ctrl
& FLOW_CTRL_RX
)
295 bnx2x_bits_en(bp
, emac_base
+
296 EMAC_REG_EMAC_RX_MODE
,
297 EMAC_RX_MODE_FLOW_EN
);
299 bnx2x_bits_dis(bp
, emac_base
+ EMAC_REG_EMAC_TX_MODE
,
300 (EMAC_TX_MODE_EXT_PAUSE_EN
|
301 EMAC_TX_MODE_FLOW_EN
));
302 if (vars
->flow_ctrl
& FLOW_CTRL_TX
)
303 bnx2x_bits_en(bp
, emac_base
+
304 EMAC_REG_EMAC_TX_MODE
,
305 (EMAC_TX_MODE_EXT_PAUSE_EN
|
306 EMAC_TX_MODE_FLOW_EN
));
309 /* KEEP_VLAN_TAG, promiscuous */
310 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_RX_MODE
);
311 val
|= EMAC_RX_MODE_KEEP_VLAN_TAG
| EMAC_RX_MODE_PROMISCUOUS
;
312 EMAC_WR(EMAC_REG_EMAC_RX_MODE
, val
);
315 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
320 EMAC_WR(EMAC_REG_EMAC_MODE
, val
);
322 /* enable emac for jumbo packets */
323 EMAC_WR(EMAC_REG_EMAC_RX_MTU_SIZE
,
324 (EMAC_RX_MTU_SIZE_JUMBO_ENA
|
325 (ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
)));
328 REG_WR(bp
, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC
+ port
*4, 0x1);
330 /* disable the NIG in/out to the bmac */
331 REG_WR(bp
, NIG_REG_BMAC0_IN_EN
+ port
*4, 0x0);
332 REG_WR(bp
, NIG_REG_BMAC0_PAUSE_OUT_EN
+ port
*4, 0x0);
333 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0x0);
335 /* enable the NIG in/out to the emac */
336 REG_WR(bp
, NIG_REG_EMAC0_IN_EN
+ port
*4, 0x1);
338 if (vars
->flow_ctrl
& FLOW_CTRL_TX
)
341 REG_WR(bp
, NIG_REG_EMAC0_PAUSE_OUT_EN
+ port
*4, val
);
342 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0x1);
344 if (CHIP_REV_IS_EMUL(bp
)) {
345 /* take the BigMac out of reset */
347 GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
348 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
350 /* enable access for bmac registers */
351 REG_WR(bp
, NIG_REG_BMAC0_REGS_OUT_EN
+ port
*4, 0x1);
354 vars
->mac_type
= MAC_TYPE_EMAC
;
360 static u8
bnx2x_bmac_enable(struct link_params
*params
, struct link_vars
*vars
,
363 struct bnx2x
*bp
= params
->bp
;
364 u8 port
= params
->port
;
365 u32 bmac_addr
= port
? NIG_REG_INGRESS_BMAC1_MEM
:
366 NIG_REG_INGRESS_BMAC0_MEM
;
370 DP(NETIF_MSG_LINK
, "Enabling BigMAC\n");
371 /* reset and unreset the BigMac */
372 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
373 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
376 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
377 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
379 /* enable access for bmac registers */
380 REG_WR(bp
, NIG_REG_BMAC0_REGS_OUT_EN
+ port
*4, 0x1);
385 REG_WR_DMAE(bp
, bmac_addr
+
386 BIGMAC_REGISTER_BMAC_XGXS_CONTROL
,
390 wb_data
[0] = ((params
->mac_addr
[2] << 24) |
391 (params
->mac_addr
[3] << 16) |
392 (params
->mac_addr
[4] << 8) |
393 params
->mac_addr
[5]);
394 wb_data
[1] = ((params
->mac_addr
[0] << 8) |
395 params
->mac_addr
[1]);
396 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_TX_SOURCE_ADDR
,
401 if (vars
->flow_ctrl
& FLOW_CTRL_TX
)
405 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_TX_CONTROL
,
412 DP(NETIF_MSG_LINK
, "enable bmac loopback\n");
416 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_BMAC_CONTROL
,
421 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
423 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_RX_MAX_SIZE
,
426 /* rx control set to don't strip crc */
428 if (vars
->flow_ctrl
& FLOW_CTRL_RX
)
432 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_RX_CONTROL
,
436 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
438 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_TX_MAX_SIZE
,
441 /* set cnt max size */
442 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
444 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_CNT_MAX_SIZE
,
448 wb_data
[0] = 0x1000200;
450 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_RX_LLFC_MSG_FLDS
,
452 /* fix for emulation */
453 if (CHIP_REV_IS_EMUL(bp
)) {
457 bmac_addr
+ BIGMAC_REGISTER_TX_PAUSE_THRESHOLD
,
461 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+ port
*4, 0x1);
462 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+ port
*4, 0x0);
463 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_PORT
+ port
*4, 0x0);
465 if (vars
->flow_ctrl
& FLOW_CTRL_TX
)
467 REG_WR(bp
, NIG_REG_BMAC0_PAUSE_OUT_EN
+ port
*4, val
);
468 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0x0);
469 REG_WR(bp
, NIG_REG_EMAC0_IN_EN
+ port
*4, 0x0);
470 REG_WR(bp
, NIG_REG_EMAC0_PAUSE_OUT_EN
+ port
*4, 0x0);
471 REG_WR(bp
, NIG_REG_BMAC0_IN_EN
+ port
*4, 0x1);
472 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0x1);
474 vars
->mac_type
= MAC_TYPE_BMAC
;
478 static void bnx2x_phy_deassert(struct link_params
*params
, u8 phy_flags
)
480 struct bnx2x
*bp
= params
->bp
;
483 if (phy_flags
& PHY_XGXS_FLAG
) {
484 DP(NETIF_MSG_LINK
, "bnx2x_phy_deassert:XGXS\n");
485 val
= XGXS_RESET_BITS
;
487 } else { /* SerDes */
488 DP(NETIF_MSG_LINK
, "bnx2x_phy_deassert:SerDes\n");
489 val
= SERDES_RESET_BITS
;
492 val
= val
<< (params
->port
*16);
494 /* reset and unreset the SerDes/XGXS */
495 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_CLEAR
,
498 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_SET
,
500 bnx2x_set_phy_mdio(params
);
503 void bnx2x_link_status_update(struct link_params
*params
,
504 struct link_vars
*vars
)
506 struct bnx2x
*bp
= params
->bp
;
508 u8 port
= params
->port
;
510 if (params
->switch_cfg
== SWITCH_CFG_1G
)
511 vars
->phy_flags
= PHY_SERDES_FLAG
;
513 vars
->phy_flags
= PHY_XGXS_FLAG
;
514 vars
->link_status
= REG_RD(bp
, params
->shmem_base
+
515 offsetof(struct shmem_region
,
516 port_mb
[port
].link_status
));
518 vars
->link_up
= (vars
->link_status
& LINK_STATUS_LINK_UP
);
521 DP(NETIF_MSG_LINK
, "phy link up\n");
523 vars
->phy_link_up
= 1;
524 vars
->duplex
= DUPLEX_FULL
;
525 switch (vars
->link_status
&
526 LINK_STATUS_SPEED_AND_DUPLEX_MASK
) {
528 vars
->duplex
= DUPLEX_HALF
;
531 vars
->line_speed
= SPEED_10
;
535 vars
->duplex
= DUPLEX_HALF
;
539 vars
->line_speed
= SPEED_100
;
543 vars
->duplex
= DUPLEX_HALF
;
546 vars
->line_speed
= SPEED_1000
;
550 vars
->duplex
= DUPLEX_HALF
;
553 vars
->line_speed
= SPEED_2500
;
557 vars
->line_speed
= SPEED_10000
;
561 vars
->line_speed
= SPEED_12000
;
565 vars
->line_speed
= SPEED_12500
;
569 vars
->line_speed
= SPEED_13000
;
573 vars
->line_speed
= SPEED_15000
;
577 vars
->line_speed
= SPEED_16000
;
584 if (vars
->link_status
& LINK_STATUS_TX_FLOW_CONTROL_ENABLED
)
585 vars
->flow_ctrl
|= FLOW_CTRL_TX
;
587 vars
->flow_ctrl
&= ~FLOW_CTRL_TX
;
589 if (vars
->link_status
& LINK_STATUS_RX_FLOW_CONTROL_ENABLED
)
590 vars
->flow_ctrl
|= FLOW_CTRL_RX
;
592 vars
->flow_ctrl
&= ~FLOW_CTRL_RX
;
594 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
595 if (vars
->line_speed
&&
596 ((vars
->line_speed
== SPEED_10
) ||
597 (vars
->line_speed
== SPEED_100
))) {
598 vars
->phy_flags
|= PHY_SGMII_FLAG
;
600 vars
->phy_flags
&= ~PHY_SGMII_FLAG
;
604 /* anything 10 and over uses the bmac */
605 link_10g
= ((vars
->line_speed
== SPEED_10000
) ||
606 (vars
->line_speed
== SPEED_12000
) ||
607 (vars
->line_speed
== SPEED_12500
) ||
608 (vars
->line_speed
== SPEED_13000
) ||
609 (vars
->line_speed
== SPEED_15000
) ||
610 (vars
->line_speed
== SPEED_16000
));
612 vars
->mac_type
= MAC_TYPE_BMAC
;
614 vars
->mac_type
= MAC_TYPE_EMAC
;
616 } else { /* link down */
617 DP(NETIF_MSG_LINK
, "phy link down\n");
619 vars
->phy_link_up
= 0;
621 vars
->line_speed
= 0;
622 vars
->duplex
= DUPLEX_FULL
;
623 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
625 /* indicate no mac active */
626 vars
->mac_type
= MAC_TYPE_NONE
;
629 DP(NETIF_MSG_LINK
, "link_status 0x%x phy_link_up %x\n",
630 vars
->link_status
, vars
->phy_link_up
);
631 DP(NETIF_MSG_LINK
, "line_speed %x duplex %x flow_ctrl 0x%x\n",
632 vars
->line_speed
, vars
->duplex
, vars
->flow_ctrl
);
635 static void bnx2x_update_mng(struct link_params
*params
, u32 link_status
)
637 struct bnx2x
*bp
= params
->bp
;
638 REG_WR(bp
, params
->shmem_base
+
639 offsetof(struct shmem_region
,
640 port_mb
[params
->port
].link_status
),
644 static void bnx2x_bmac_rx_disable(struct bnx2x
*bp
, u8 port
)
646 u32 bmac_addr
= port
? NIG_REG_INGRESS_BMAC1_MEM
:
647 NIG_REG_INGRESS_BMAC0_MEM
;
649 u32 nig_bmac_enable
= REG_RD(bp
, NIG_REG_BMAC0_REGS_OUT_EN
+ port
*4);
651 /* Only if the bmac is out of reset */
652 if (REG_RD(bp
, MISC_REG_RESET_REG_2
) &
653 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
) &&
656 /* Clear Rx Enable bit in BMAC_CONTROL register */
657 REG_RD_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_BMAC_CONTROL
,
659 wb_data
[0] &= ~BMAC_CONTROL_RX_ENABLE
;
660 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_BMAC_CONTROL
,
667 static u8
bnx2x_pbf_update(struct link_params
*params
, u32 flow_ctrl
,
670 struct bnx2x
*bp
= params
->bp
;
671 u8 port
= params
->port
;
676 REG_WR(bp
, PBF_REG_DISABLE_NEW_TASK_PROC_P0
+ port
*4, 0x1);
678 /* wait for init credit */
679 init_crd
= REG_RD(bp
, PBF_REG_P0_INIT_CRD
+ port
*4);
680 crd
= REG_RD(bp
, PBF_REG_P0_CREDIT
+ port
*8);
681 DP(NETIF_MSG_LINK
, "init_crd 0x%x crd 0x%x\n", init_crd
, crd
);
683 while ((init_crd
!= crd
) && count
) {
686 crd
= REG_RD(bp
, PBF_REG_P0_CREDIT
+ port
*8);
689 crd
= REG_RD(bp
, PBF_REG_P0_CREDIT
+ port
*8);
690 if (init_crd
!= crd
) {
691 DP(NETIF_MSG_LINK
, "BUG! init_crd 0x%x != crd 0x%x\n",
696 if (flow_ctrl
& FLOW_CTRL_RX
||
697 line_speed
== SPEED_10
||
698 line_speed
== SPEED_100
||
699 line_speed
== SPEED_1000
||
700 line_speed
== SPEED_2500
) {
701 REG_WR(bp
, PBF_REG_P0_PAUSE_ENABLE
+ port
*4, 1);
702 /* update threshold */
703 REG_WR(bp
, PBF_REG_P0_ARB_THRSH
+ port
*4, 0);
704 /* update init credit */
705 init_crd
= 778; /* (800-18-4) */
708 u32 thresh
= (ETH_MAX_JUMBO_PACKET_SIZE
+
710 REG_WR(bp
, PBF_REG_P0_PAUSE_ENABLE
+ port
*4, 0);
711 /* update threshold */
712 REG_WR(bp
, PBF_REG_P0_ARB_THRSH
+ port
*4, thresh
);
713 /* update init credit */
714 switch (line_speed
) {
716 init_crd
= thresh
+ 553 - 22;
720 init_crd
= thresh
+ 664 - 22;
724 init_crd
= thresh
+ 742 - 22;
728 init_crd
= thresh
+ 778 - 22;
731 DP(NETIF_MSG_LINK
, "Invalid line_speed 0x%x\n",
737 REG_WR(bp
, PBF_REG_P0_INIT_CRD
+ port
*4, init_crd
);
738 DP(NETIF_MSG_LINK
, "PBF updated to speed %d credit %d\n",
739 line_speed
, init_crd
);
741 /* probe the credit changes */
742 REG_WR(bp
, PBF_REG_INIT_P0
+ port
*4, 0x1);
744 REG_WR(bp
, PBF_REG_INIT_P0
+ port
*4, 0x0);
747 REG_WR(bp
, PBF_REG_DISABLE_NEW_TASK_PROC_P0
+ port
*4, 0x0);
751 static u32
bnx2x_get_emac_base(u32 ext_phy_type
, u8 port
)
754 switch (ext_phy_type
) {
755 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
756 emac_base
= GRCBASE_EMAC0
;
758 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
759 emac_base
= (port
) ? GRCBASE_EMAC0
: GRCBASE_EMAC1
;
762 emac_base
= (port
) ? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
769 u8
bnx2x_cl45_write(struct bnx2x
*bp
, u8 port
, u32 ext_phy_type
,
770 u8 phy_addr
, u8 devad
, u16 reg
, u16 val
)
774 u32 mdio_ctrl
= bnx2x_get_emac_base(ext_phy_type
, port
);
776 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
777 * (a value of 49==0x31) and make sure that the AUTO poll is off
779 saved_mode
= REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
780 tmp
= saved_mode
& ~(EMAC_MDIO_MODE_AUTO_POLL
|
781 EMAC_MDIO_MODE_CLOCK_CNT
);
782 tmp
|= (EMAC_MDIO_MODE_CLAUSE_45
|
783 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT
));
784 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, tmp
);
785 REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
790 tmp
= ((phy_addr
<< 21) | (devad
<< 16) | reg
|
791 EMAC_MDIO_COMM_COMMAND_ADDRESS
|
792 EMAC_MDIO_COMM_START_BUSY
);
793 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, tmp
);
795 for (i
= 0; i
< 50; i
++) {
798 tmp
= REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
);
799 if (!(tmp
& EMAC_MDIO_COMM_START_BUSY
)) {
804 if (tmp
& EMAC_MDIO_COMM_START_BUSY
) {
805 DP(NETIF_MSG_LINK
, "write phy register failed\n");
809 tmp
= ((phy_addr
<< 21) | (devad
<< 16) | val
|
810 EMAC_MDIO_COMM_COMMAND_WRITE_45
|
811 EMAC_MDIO_COMM_START_BUSY
);
812 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, tmp
);
814 for (i
= 0; i
< 50; i
++) {
817 tmp
= REG_RD(bp
, mdio_ctrl
+
818 EMAC_REG_EMAC_MDIO_COMM
);
819 if (!(tmp
& EMAC_MDIO_COMM_START_BUSY
)) {
824 if (tmp
& EMAC_MDIO_COMM_START_BUSY
) {
825 DP(NETIF_MSG_LINK
, "write phy register failed\n");
830 /* Restore the saved mode */
831 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, saved_mode
);
836 u8
bnx2x_cl45_read(struct bnx2x
*bp
, u8 port
, u32 ext_phy_type
,
837 u8 phy_addr
, u8 devad
, u16 reg
, u16
*ret_val
)
843 u32 mdio_ctrl
= bnx2x_get_emac_base(ext_phy_type
, port
);
844 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
845 * (a value of 49==0x31) and make sure that the AUTO poll is off
847 saved_mode
= REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
848 val
= saved_mode
& ((EMAC_MDIO_MODE_AUTO_POLL
|
849 EMAC_MDIO_MODE_CLOCK_CNT
));
850 val
|= (EMAC_MDIO_MODE_CLAUSE_45
|
851 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT
));
852 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, val
);
853 REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
857 val
= ((phy_addr
<< 21) | (devad
<< 16) | reg
|
858 EMAC_MDIO_COMM_COMMAND_ADDRESS
|
859 EMAC_MDIO_COMM_START_BUSY
);
860 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, val
);
862 for (i
= 0; i
< 50; i
++) {
865 val
= REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
);
866 if (!(val
& EMAC_MDIO_COMM_START_BUSY
)) {
871 if (val
& EMAC_MDIO_COMM_START_BUSY
) {
872 DP(NETIF_MSG_LINK
, "read phy register failed\n");
879 val
= ((phy_addr
<< 21) | (devad
<< 16) |
880 EMAC_MDIO_COMM_COMMAND_READ_45
|
881 EMAC_MDIO_COMM_START_BUSY
);
882 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, val
);
884 for (i
= 0; i
< 50; i
++) {
887 val
= REG_RD(bp
, mdio_ctrl
+
888 EMAC_REG_EMAC_MDIO_COMM
);
889 if (!(val
& EMAC_MDIO_COMM_START_BUSY
)) {
890 *ret_val
= (u16
)(val
& EMAC_MDIO_COMM_DATA
);
894 if (val
& EMAC_MDIO_COMM_START_BUSY
) {
895 DP(NETIF_MSG_LINK
, "read phy register failed\n");
902 /* Restore the saved mode */
903 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, saved_mode
);
908 static void bnx2x_set_aer_mmd(struct link_params
*params
,
909 struct link_vars
*vars
)
911 struct bnx2x
*bp
= params
->bp
;
915 ser_lane
= ((params
->lane_config
&
916 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
917 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
919 offset
= (vars
->phy_flags
& PHY_XGXS_FLAG
) ?
920 (params
->phy_addr
+ ser_lane
) : 0;
922 CL45_WR_OVER_CL22(bp
, params
->port
,
924 MDIO_REG_BANK_AER_BLOCK
,
925 MDIO_AER_BLOCK_AER_REG
, 0x3800 + offset
);
928 static void bnx2x_set_master_ln(struct link_params
*params
)
930 struct bnx2x
*bp
= params
->bp
;
931 u16 new_master_ln
, ser_lane
;
932 ser_lane
= ((params
->lane_config
&
933 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
934 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
936 /* set the master_ln for AN */
937 CL45_RD_OVER_CL22(bp
, params
->port
,
939 MDIO_REG_BANK_XGXS_BLOCK2
,
940 MDIO_XGXS_BLOCK2_TEST_MODE_LANE
,
943 CL45_WR_OVER_CL22(bp
, params
->port
,
945 MDIO_REG_BANK_XGXS_BLOCK2
,
946 MDIO_XGXS_BLOCK2_TEST_MODE_LANE
,
947 (new_master_ln
| ser_lane
));
950 static u8
bnx2x_reset_unicore(struct link_params
*params
)
952 struct bnx2x
*bp
= params
->bp
;
956 CL45_RD_OVER_CL22(bp
, params
->port
,
958 MDIO_REG_BANK_COMBO_IEEE0
,
959 MDIO_COMBO_IEEE0_MII_CONTROL
, &mii_control
);
961 /* reset the unicore */
962 CL45_WR_OVER_CL22(bp
, params
->port
,
964 MDIO_REG_BANK_COMBO_IEEE0
,
965 MDIO_COMBO_IEEE0_MII_CONTROL
,
967 MDIO_COMBO_IEEO_MII_CONTROL_RESET
));
969 /* wait for the reset to self clear */
970 for (i
= 0; i
< MDIO_ACCESS_TIMEOUT
; i
++) {
973 /* the reset erased the previous bank value */
974 CL45_RD_OVER_CL22(bp
, params
->port
,
976 MDIO_REG_BANK_COMBO_IEEE0
,
977 MDIO_COMBO_IEEE0_MII_CONTROL
,
980 if (!(mii_control
& MDIO_COMBO_IEEO_MII_CONTROL_RESET
)) {
986 DP(NETIF_MSG_LINK
, "BUG! XGXS is still in reset!\n");
991 static void bnx2x_set_swap_lanes(struct link_params
*params
)
993 struct bnx2x
*bp
= params
->bp
;
994 /* Each two bits represents a lane number:
995 No swap is 0123 => 0x1b no need to enable the swap */
996 u16 ser_lane
, rx_lane_swap
, tx_lane_swap
;
998 ser_lane
= ((params
->lane_config
&
999 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
1000 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
1001 rx_lane_swap
= ((params
->lane_config
&
1002 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK
) >>
1003 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT
);
1004 tx_lane_swap
= ((params
->lane_config
&
1005 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK
) >>
1006 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT
);
1008 if (rx_lane_swap
!= 0x1b) {
1009 CL45_WR_OVER_CL22(bp
, params
->port
,
1011 MDIO_REG_BANK_XGXS_BLOCK2
,
1012 MDIO_XGXS_BLOCK2_RX_LN_SWAP
,
1014 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE
|
1015 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE
));
1017 CL45_WR_OVER_CL22(bp
, params
->port
,
1019 MDIO_REG_BANK_XGXS_BLOCK2
,
1020 MDIO_XGXS_BLOCK2_RX_LN_SWAP
, 0);
1023 if (tx_lane_swap
!= 0x1b) {
1024 CL45_WR_OVER_CL22(bp
, params
->port
,
1026 MDIO_REG_BANK_XGXS_BLOCK2
,
1027 MDIO_XGXS_BLOCK2_TX_LN_SWAP
,
1029 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE
));
1031 CL45_WR_OVER_CL22(bp
, params
->port
,
1033 MDIO_REG_BANK_XGXS_BLOCK2
,
1034 MDIO_XGXS_BLOCK2_TX_LN_SWAP
, 0);
1038 static void bnx2x_set_parallel_detection(struct link_params
*params
,
1041 struct bnx2x
*bp
= params
->bp
;
1044 CL45_RD_OVER_CL22(bp
, params
->port
,
1046 MDIO_REG_BANK_SERDES_DIGITAL
,
1047 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2
,
1051 control2
|= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN
;
1054 CL45_WR_OVER_CL22(bp
, params
->port
,
1056 MDIO_REG_BANK_SERDES_DIGITAL
,
1057 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2
,
1060 if (phy_flags
& PHY_XGXS_FLAG
) {
1061 DP(NETIF_MSG_LINK
, "XGXS\n");
1063 CL45_WR_OVER_CL22(bp
, params
->port
,
1065 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
1066 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK
,
1067 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT
);
1069 CL45_RD_OVER_CL22(bp
, params
->port
,
1071 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
1072 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL
,
1077 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN
;
1079 CL45_WR_OVER_CL22(bp
, params
->port
,
1081 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
1082 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL
,
1085 /* Disable parallel detection of HiG */
1086 CL45_WR_OVER_CL22(bp
, params
->port
,
1088 MDIO_REG_BANK_XGXS_BLOCK2
,
1089 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G
,
1090 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS
|
1091 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS
);
1095 static void bnx2x_set_autoneg(struct link_params
*params
,
1096 struct link_vars
*vars
)
1098 struct bnx2x
*bp
= params
->bp
;
1103 CL45_RD_OVER_CL22(bp
, params
->port
,
1105 MDIO_REG_BANK_COMBO_IEEE0
,
1106 MDIO_COMBO_IEEE0_MII_CONTROL
, ®_val
);
1108 /* CL37 Autoneg Enabled */
1109 if (vars
->line_speed
== SPEED_AUTO_NEG
)
1110 reg_val
|= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
;
1111 else /* CL37 Autoneg Disabled */
1112 reg_val
&= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
|
1113 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN
);
1115 CL45_WR_OVER_CL22(bp
, params
->port
,
1117 MDIO_REG_BANK_COMBO_IEEE0
,
1118 MDIO_COMBO_IEEE0_MII_CONTROL
, reg_val
);
1120 /* Enable/Disable Autodetection */
1122 CL45_RD_OVER_CL22(bp
, params
->port
,
1124 MDIO_REG_BANK_SERDES_DIGITAL
,
1125 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
, ®_val
);
1126 reg_val
&= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN
;
1127 if (vars
->line_speed
== SPEED_AUTO_NEG
)
1128 reg_val
|= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET
;
1130 reg_val
&= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET
;
1132 CL45_WR_OVER_CL22(bp
, params
->port
,
1134 MDIO_REG_BANK_SERDES_DIGITAL
,
1135 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
, reg_val
);
1137 /* Enable TetonII and BAM autoneg */
1138 CL45_RD_OVER_CL22(bp
, params
->port
,
1140 MDIO_REG_BANK_BAM_NEXT_PAGE
,
1141 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL
,
1143 if (vars
->line_speed
== SPEED_AUTO_NEG
) {
1144 /* Enable BAM aneg Mode and TetonII aneg Mode */
1145 reg_val
|= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE
|
1146 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN
);
1148 /* TetonII and BAM Autoneg Disabled */
1149 reg_val
&= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE
|
1150 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN
);
1152 CL45_WR_OVER_CL22(bp
, params
->port
,
1154 MDIO_REG_BANK_BAM_NEXT_PAGE
,
1155 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL
,
1158 /* Enable Clause 73 Aneg */
1159 if ((vars
->line_speed
== SPEED_AUTO_NEG
) &&
1161 /* Enable BAM Station Manager */
1163 CL45_WR_OVER_CL22(bp
, params
->port
,
1165 MDIO_REG_BANK_CL73_USERB0
,
1166 MDIO_CL73_USERB0_CL73_BAM_CTRL1
,
1167 (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN
|
1168 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN
|
1169 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN
));
1171 /* Merge CL73 and CL37 aneg resolution */
1172 CL45_RD_OVER_CL22(bp
, params
->port
,
1174 MDIO_REG_BANK_CL73_USERB0
,
1175 MDIO_CL73_USERB0_CL73_BAM_CTRL3
,
1178 CL45_WR_OVER_CL22(bp
, params
->port
,
1180 MDIO_REG_BANK_CL73_USERB0
,
1181 MDIO_CL73_USERB0_CL73_BAM_CTRL3
,
1183 MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR
));
1185 /* Set the CL73 AN speed */
1187 CL45_RD_OVER_CL22(bp
, params
->port
,
1189 MDIO_REG_BANK_CL73_IEEEB1
,
1190 MDIO_CL73_IEEEB1_AN_ADV2
, ®_val
);
1191 /* In the SerDes we support only the 1G.
1192 In the XGXS we support the 10G KX4
1193 but we currently do not support the KR */
1194 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
1195 DP(NETIF_MSG_LINK
, "XGXS\n");
1197 reg_val
|= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4
;
1199 DP(NETIF_MSG_LINK
, "SerDes\n");
1201 reg_val
|= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX
;
1203 CL45_WR_OVER_CL22(bp
, params
->port
,
1205 MDIO_REG_BANK_CL73_IEEEB1
,
1206 MDIO_CL73_IEEEB1_AN_ADV2
, reg_val
);
1208 /* CL73 Autoneg Enabled */
1209 reg_val
= MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN
;
1211 /* CL73 Autoneg Disabled */
1214 CL45_WR_OVER_CL22(bp
, params
->port
,
1216 MDIO_REG_BANK_CL73_IEEEB0
,
1217 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
, reg_val
);
1220 /* program SerDes, forced speed */
1221 static void bnx2x_program_serdes(struct link_params
*params
,
1222 struct link_vars
*vars
)
1224 struct bnx2x
*bp
= params
->bp
;
1227 /* program duplex, disable autoneg */
1229 CL45_RD_OVER_CL22(bp
, params
->port
,
1231 MDIO_REG_BANK_COMBO_IEEE0
,
1232 MDIO_COMBO_IEEE0_MII_CONTROL
, ®_val
);
1233 reg_val
&= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
|
1234 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
);
1235 if (params
->req_duplex
== DUPLEX_FULL
)
1236 reg_val
|= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
;
1237 CL45_WR_OVER_CL22(bp
, params
->port
,
1239 MDIO_REG_BANK_COMBO_IEEE0
,
1240 MDIO_COMBO_IEEE0_MII_CONTROL
, reg_val
);
1243 - needed only if the speed is greater than 1G (2.5G or 10G) */
1244 CL45_RD_OVER_CL22(bp
, params
->port
,
1246 MDIO_REG_BANK_SERDES_DIGITAL
,
1247 MDIO_SERDES_DIGITAL_MISC1
, ®_val
);
1248 /* clearing the speed value before setting the right speed */
1249 DP(NETIF_MSG_LINK
, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val
);
1251 reg_val
&= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK
|
1252 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL
);
1254 if (!((vars
->line_speed
== SPEED_1000
) ||
1255 (vars
->line_speed
== SPEED_100
) ||
1256 (vars
->line_speed
== SPEED_10
))) {
1258 reg_val
|= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M
|
1259 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL
);
1260 if (vars
->line_speed
== SPEED_10000
)
1262 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4
;
1263 if (vars
->line_speed
== SPEED_13000
)
1265 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G
;
1268 CL45_WR_OVER_CL22(bp
, params
->port
,
1270 MDIO_REG_BANK_SERDES_DIGITAL
,
1271 MDIO_SERDES_DIGITAL_MISC1
, reg_val
);
1275 static void bnx2x_set_brcm_cl37_advertisment(struct link_params
*params
)
1277 struct bnx2x
*bp
= params
->bp
;
1280 /* configure the 48 bits for BAM AN */
1282 /* set extended capabilities */
1283 if (params
->speed_cap_mask
& PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G
)
1284 val
|= MDIO_OVER_1G_UP1_2_5G
;
1285 if (params
->speed_cap_mask
& PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)
1286 val
|= MDIO_OVER_1G_UP1_10G
;
1287 CL45_WR_OVER_CL22(bp
, params
->port
,
1289 MDIO_REG_BANK_OVER_1G
,
1290 MDIO_OVER_1G_UP1
, val
);
1292 CL45_WR_OVER_CL22(bp
, params
->port
,
1294 MDIO_REG_BANK_OVER_1G
,
1295 MDIO_OVER_1G_UP3
, 0);
1298 static void bnx2x_calc_ieee_aneg_adv(struct link_params
*params
, u32
*ieee_fc
)
1300 *ieee_fc
= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX
;
1301 /* resolve pause mode and advertisement
1302 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1304 switch (params
->req_flow_ctrl
) {
1305 case FLOW_CTRL_AUTO
:
1306 if (params
->req_fc_auto_adv
== FLOW_CTRL_BOTH
) {
1308 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
1311 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
;
1316 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
;
1320 case FLOW_CTRL_BOTH
:
1321 *ieee_fc
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
1324 case FLOW_CTRL_NONE
:
1326 *ieee_fc
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE
;
1331 static void bnx2x_set_ieee_aneg_advertisment(struct link_params
*params
,
1334 struct bnx2x
*bp
= params
->bp
;
1335 /* for AN, we are always publishing full duplex */
1337 CL45_WR_OVER_CL22(bp
, params
->port
,
1339 MDIO_REG_BANK_COMBO_IEEE0
,
1340 MDIO_COMBO_IEEE0_AUTO_NEG_ADV
, (u16
)ieee_fc
);
1343 static void bnx2x_restart_autoneg(struct link_params
*params
)
1345 struct bnx2x
*bp
= params
->bp
;
1346 DP(NETIF_MSG_LINK
, "bnx2x_restart_autoneg\n");
1348 /* enable and restart clause 73 aneg */
1351 CL45_RD_OVER_CL22(bp
, params
->port
,
1353 MDIO_REG_BANK_CL73_IEEEB0
,
1354 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
,
1356 CL45_WR_OVER_CL22(bp
, params
->port
,
1358 MDIO_REG_BANK_CL73_IEEEB0
,
1359 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
,
1361 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN
|
1362 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN
));
1365 /* Enable and restart BAM/CL37 aneg */
1368 CL45_RD_OVER_CL22(bp
, params
->port
,
1370 MDIO_REG_BANK_COMBO_IEEE0
,
1371 MDIO_COMBO_IEEE0_MII_CONTROL
,
1374 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1376 CL45_WR_OVER_CL22(bp
, params
->port
,
1378 MDIO_REG_BANK_COMBO_IEEE0
,
1379 MDIO_COMBO_IEEE0_MII_CONTROL
,
1381 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
|
1382 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN
));
1386 static void bnx2x_initialize_sgmii_process(struct link_params
*params
,
1387 struct link_vars
*vars
)
1389 struct bnx2x
*bp
= params
->bp
;
1392 /* in SGMII mode, the unicore is always slave */
1394 CL45_RD_OVER_CL22(bp
, params
->port
,
1396 MDIO_REG_BANK_SERDES_DIGITAL
,
1397 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
,
1399 control1
|= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT
;
1400 /* set sgmii mode (and not fiber) */
1401 control1
&= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE
|
1402 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET
|
1403 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE
);
1404 CL45_WR_OVER_CL22(bp
, params
->port
,
1406 MDIO_REG_BANK_SERDES_DIGITAL
,
1407 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
,
1410 /* if forced speed */
1411 if (!(vars
->line_speed
== SPEED_AUTO_NEG
)) {
1412 /* set speed, disable autoneg */
1415 CL45_RD_OVER_CL22(bp
, params
->port
,
1417 MDIO_REG_BANK_COMBO_IEEE0
,
1418 MDIO_COMBO_IEEE0_MII_CONTROL
,
1420 mii_control
&= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
|
1421 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK
|
1422 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
);
1424 switch (vars
->line_speed
) {
1427 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100
;
1431 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000
;
1434 /* there is nothing to set for 10M */
1437 /* invalid speed for SGMII */
1438 DP(NETIF_MSG_LINK
, "Invalid line_speed 0x%x\n",
1443 /* setting the full duplex */
1444 if (params
->req_duplex
== DUPLEX_FULL
)
1446 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
;
1447 CL45_WR_OVER_CL22(bp
, params
->port
,
1449 MDIO_REG_BANK_COMBO_IEEE0
,
1450 MDIO_COMBO_IEEE0_MII_CONTROL
,
1453 } else { /* AN mode */
1454 /* enable and restart AN */
1455 bnx2x_restart_autoneg(params
);
1464 static void bnx2x_pause_resolve(struct link_vars
*vars
, u32 pause_result
)
1466 switch (pause_result
) { /* ASYM P ASYM P */
1467 case 0xb: /* 1 0 1 1 */
1468 vars
->flow_ctrl
= FLOW_CTRL_TX
;
1471 case 0xe: /* 1 1 1 0 */
1472 vars
->flow_ctrl
= FLOW_CTRL_RX
;
1475 case 0x5: /* 0 1 0 1 */
1476 case 0x7: /* 0 1 1 1 */
1477 case 0xd: /* 1 1 0 1 */
1478 case 0xf: /* 1 1 1 1 */
1479 vars
->flow_ctrl
= FLOW_CTRL_BOTH
;
1487 static u8
bnx2x_ext_phy_resove_fc(struct link_params
*params
,
1488 struct link_vars
*vars
)
1490 struct bnx2x
*bp
= params
->bp
;
1492 u16 ld_pause
; /* local */
1493 u16 lp_pause
; /* link partner */
1494 u16 an_complete
; /* AN complete */
1498 u8 port
= params
->port
;
1499 ext_phy_addr
= ((params
->ext_phy_config
&
1500 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
1501 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
1503 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
1506 bnx2x_cl45_read(bp
, port
,
1510 MDIO_AN_REG_STATUS
, &an_complete
);
1511 bnx2x_cl45_read(bp
, port
,
1515 MDIO_AN_REG_STATUS
, &an_complete
);
1517 if (an_complete
& MDIO_AN_REG_STATUS_AN_COMPLETE
) {
1519 bnx2x_cl45_read(bp
, port
,
1523 MDIO_AN_REG_ADV_PAUSE
, &ld_pause
);
1524 bnx2x_cl45_read(bp
, port
,
1528 MDIO_AN_REG_LP_AUTO_NEG
, &lp_pause
);
1529 pause_result
= (ld_pause
&
1530 MDIO_AN_REG_ADV_PAUSE_MASK
) >> 8;
1531 pause_result
|= (lp_pause
&
1532 MDIO_AN_REG_ADV_PAUSE_MASK
) >> 10;
1533 DP(NETIF_MSG_LINK
, "Ext PHY pause result 0x%x \n",
1535 bnx2x_pause_resolve(vars
, pause_result
);
1536 if (vars
->flow_ctrl
== FLOW_CTRL_NONE
&&
1537 ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
1538 bnx2x_cl45_read(bp
, port
,
1542 MDIO_AN_REG_CL37_FC_LD
, &ld_pause
);
1544 bnx2x_cl45_read(bp
, port
,
1548 MDIO_AN_REG_CL37_FC_LP
, &lp_pause
);
1549 pause_result
= (ld_pause
&
1550 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) >> 5;
1551 pause_result
|= (lp_pause
&
1552 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) >> 7;
1554 bnx2x_pause_resolve(vars
, pause_result
);
1555 DP(NETIF_MSG_LINK
, "Ext PHY CL37 pause result 0x%x \n",
1563 static void bnx2x_flow_ctrl_resolve(struct link_params
*params
,
1564 struct link_vars
*vars
,
1567 struct bnx2x
*bp
= params
->bp
;
1568 u16 ld_pause
; /* local driver */
1569 u16 lp_pause
; /* link partner */
1572 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
1574 /* resolve from gp_status in case of AN complete and not sgmii */
1575 if ((params
->req_flow_ctrl
== FLOW_CTRL_AUTO
) &&
1576 (gp_status
& MDIO_AN_CL73_OR_37_COMPLETE
) &&
1577 (!(vars
->phy_flags
& PHY_SGMII_FLAG
)) &&
1578 (XGXS_EXT_PHY_TYPE(params
->ext_phy_config
) ==
1579 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
)) {
1580 CL45_RD_OVER_CL22(bp
, params
->port
,
1582 MDIO_REG_BANK_COMBO_IEEE0
,
1583 MDIO_COMBO_IEEE0_AUTO_NEG_ADV
,
1585 CL45_RD_OVER_CL22(bp
, params
->port
,
1587 MDIO_REG_BANK_COMBO_IEEE0
,
1588 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1
,
1590 pause_result
= (ld_pause
&
1591 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK
)>>5;
1592 pause_result
|= (lp_pause
&
1593 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK
)>>7;
1594 DP(NETIF_MSG_LINK
, "pause_result 0x%x\n", pause_result
);
1595 bnx2x_pause_resolve(vars
, pause_result
);
1596 } else if ((params
->req_flow_ctrl
== FLOW_CTRL_AUTO
) &&
1597 (bnx2x_ext_phy_resove_fc(params
, vars
))) {
1600 if (params
->req_flow_ctrl
== FLOW_CTRL_AUTO
)
1601 vars
->flow_ctrl
= params
->req_fc_auto_adv
;
1603 vars
->flow_ctrl
= params
->req_flow_ctrl
;
1605 DP(NETIF_MSG_LINK
, "flow_ctrl 0x%x\n", vars
->flow_ctrl
);
1609 static u8
bnx2x_link_settings_status(struct link_params
*params
,
1610 struct link_vars
*vars
,
1613 struct bnx2x
*bp
= params
->bp
;
1615 vars
->link_status
= 0;
1617 if (gp_status
& MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS
) {
1618 DP(NETIF_MSG_LINK
, "phy link up gp_status=0x%x\n",
1621 vars
->phy_link_up
= 1;
1622 vars
->link_status
|= LINK_STATUS_LINK_UP
;
1624 if (gp_status
& MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS
)
1625 vars
->duplex
= DUPLEX_FULL
;
1627 vars
->duplex
= DUPLEX_HALF
;
1629 bnx2x_flow_ctrl_resolve(params
, vars
, gp_status
);
1631 switch (gp_status
& GP_STATUS_SPEED_MASK
) {
1633 vars
->line_speed
= SPEED_10
;
1634 if (vars
->duplex
== DUPLEX_FULL
)
1635 vars
->link_status
|= LINK_10TFD
;
1637 vars
->link_status
|= LINK_10THD
;
1640 case GP_STATUS_100M
:
1641 vars
->line_speed
= SPEED_100
;
1642 if (vars
->duplex
== DUPLEX_FULL
)
1643 vars
->link_status
|= LINK_100TXFD
;
1645 vars
->link_status
|= LINK_100TXHD
;
1649 case GP_STATUS_1G_KX
:
1650 vars
->line_speed
= SPEED_1000
;
1651 if (vars
->duplex
== DUPLEX_FULL
)
1652 vars
->link_status
|= LINK_1000TFD
;
1654 vars
->link_status
|= LINK_1000THD
;
1657 case GP_STATUS_2_5G
:
1658 vars
->line_speed
= SPEED_2500
;
1659 if (vars
->duplex
== DUPLEX_FULL
)
1660 vars
->link_status
|= LINK_2500TFD
;
1662 vars
->link_status
|= LINK_2500THD
;
1668 "link speed unsupported gp_status 0x%x\n",
1672 case GP_STATUS_10G_KX4
:
1673 case GP_STATUS_10G_HIG
:
1674 case GP_STATUS_10G_CX4
:
1675 vars
->line_speed
= SPEED_10000
;
1676 vars
->link_status
|= LINK_10GTFD
;
1679 case GP_STATUS_12G_HIG
:
1680 vars
->line_speed
= SPEED_12000
;
1681 vars
->link_status
|= LINK_12GTFD
;
1684 case GP_STATUS_12_5G
:
1685 vars
->line_speed
= SPEED_12500
;
1686 vars
->link_status
|= LINK_12_5GTFD
;
1690 vars
->line_speed
= SPEED_13000
;
1691 vars
->link_status
|= LINK_13GTFD
;
1695 vars
->line_speed
= SPEED_15000
;
1696 vars
->link_status
|= LINK_15GTFD
;
1700 vars
->line_speed
= SPEED_16000
;
1701 vars
->link_status
|= LINK_16GTFD
;
1706 "link speed unsupported gp_status 0x%x\n",
1712 vars
->link_status
|= LINK_STATUS_SERDES_LINK
;
1714 if ((params
->req_line_speed
== SPEED_AUTO_NEG
) &&
1715 ((XGXS_EXT_PHY_TYPE(params
->ext_phy_config
) ==
1716 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) ||
1717 (XGXS_EXT_PHY_TYPE(params
->ext_phy_config
) ==
1718 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
))) {
1719 vars
->autoneg
= AUTO_NEG_ENABLED
;
1721 if (gp_status
& MDIO_AN_CL73_OR_37_COMPLETE
) {
1722 vars
->autoneg
|= AUTO_NEG_COMPLETE
;
1723 vars
->link_status
|=
1724 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE
;
1727 vars
->autoneg
|= AUTO_NEG_PARALLEL_DETECTION_USED
;
1728 vars
->link_status
|=
1729 LINK_STATUS_PARALLEL_DETECTION_USED
;
1732 if (vars
->flow_ctrl
& FLOW_CTRL_TX
)
1733 vars
->link_status
|=
1734 LINK_STATUS_TX_FLOW_CONTROL_ENABLED
;
1736 if (vars
->flow_ctrl
& FLOW_CTRL_RX
)
1737 vars
->link_status
|=
1738 LINK_STATUS_RX_FLOW_CONTROL_ENABLED
;
1740 } else { /* link_down */
1741 DP(NETIF_MSG_LINK
, "phy link down\n");
1743 vars
->phy_link_up
= 0;
1745 vars
->duplex
= DUPLEX_FULL
;
1746 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
1747 vars
->autoneg
= AUTO_NEG_DISABLED
;
1748 vars
->mac_type
= MAC_TYPE_NONE
;
1751 DP(NETIF_MSG_LINK
, "gp_status 0x%x phy_link_up %x line_speed %x \n",
1752 gp_status
, vars
->phy_link_up
, vars
->line_speed
);
1753 DP(NETIF_MSG_LINK
, "duplex %x flow_ctrl 0x%x"
1756 vars
->flow_ctrl
, vars
->autoneg
);
1757 DP(NETIF_MSG_LINK
, "link_status 0x%x\n", vars
->link_status
);
1762 static void bnx2x_set_sgmii_tx_driver(struct link_params
*params
)
1764 struct bnx2x
*bp
= params
->bp
;
1770 CL45_RD_OVER_CL22(bp
, params
->port
,
1772 MDIO_REG_BANK_OVER_1G
,
1773 MDIO_OVER_1G_LP_UP2
, &lp_up2
);
1775 CL45_RD_OVER_CL22(bp
, params
->port
,
1778 MDIO_TX0_TX_DRIVER
, &tx_driver
);
1780 /* bits [10:7] at lp_up2, positioned at [15:12] */
1781 lp_up2
= (((lp_up2
& MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK
) >>
1782 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT
) <<
1783 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT
);
1785 if ((lp_up2
!= 0) &&
1786 (lp_up2
!= (tx_driver
& MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK
))) {
1787 /* replace tx_driver bits [15:12] */
1788 tx_driver
&= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK
;
1789 tx_driver
|= lp_up2
;
1790 CL45_WR_OVER_CL22(bp
, params
->port
,
1793 MDIO_TX0_TX_DRIVER
, tx_driver
);
1797 static u8
bnx2x_emac_program(struct link_params
*params
,
1798 u32 line_speed
, u32 duplex
)
1800 struct bnx2x
*bp
= params
->bp
;
1801 u8 port
= params
->port
;
1804 DP(NETIF_MSG_LINK
, "setting link speed & duplex\n");
1805 bnx2x_bits_dis(bp
, GRCBASE_EMAC0
+ port
*0x400 +
1807 (EMAC_MODE_25G_MODE
|
1808 EMAC_MODE_PORT_MII_10M
|
1809 EMAC_MODE_HALF_DUPLEX
));
1810 switch (line_speed
) {
1812 mode
|= EMAC_MODE_PORT_MII_10M
;
1816 mode
|= EMAC_MODE_PORT_MII
;
1820 mode
|= EMAC_MODE_PORT_GMII
;
1824 mode
|= (EMAC_MODE_25G_MODE
| EMAC_MODE_PORT_GMII
);
1828 /* 10G not valid for EMAC */
1829 DP(NETIF_MSG_LINK
, "Invalid line_speed 0x%x\n", line_speed
);
1833 if (duplex
== DUPLEX_HALF
)
1834 mode
|= EMAC_MODE_HALF_DUPLEX
;
1836 GRCBASE_EMAC0
+ port
*0x400 + EMAC_REG_EMAC_MODE
,
1839 bnx2x_set_led(bp
, params
->port
, LED_MODE_OPER
,
1840 line_speed
, params
->hw_led_mode
, params
->chip_id
);
1844 /*****************************************************************************/
1845 /* External Phy section */
1846 /*****************************************************************************/
1847 static void bnx2x_hw_reset(struct bnx2x
*bp
, u8 port
)
1849 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
1850 MISC_REGISTERS_GPIO_OUTPUT_LOW
, port
);
1852 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
1853 MISC_REGISTERS_GPIO_OUTPUT_HIGH
, port
);
1856 static void bnx2x_ext_phy_reset(struct link_params
*params
,
1857 struct link_vars
*vars
)
1859 struct bnx2x
*bp
= params
->bp
;
1861 u8 ext_phy_addr
= ((params
->ext_phy_config
&
1862 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
1863 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
1864 DP(NETIF_MSG_LINK
, "Port %x: bnx2x_ext_phy_reset\n", params
->port
);
1865 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
1866 /* The PHY reset is controled by GPIO 1
1867 * Give it 1ms of reset pulse
1869 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
1871 switch (ext_phy_type
) {
1872 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
1873 DP(NETIF_MSG_LINK
, "XGXS Direct\n");
1876 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
1877 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
1878 DP(NETIF_MSG_LINK
, "XGXS 8705/8706\n");
1880 /* Restore normal power mode*/
1881 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
1882 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
1886 bnx2x_hw_reset(bp
, params
->port
);
1888 bnx2x_cl45_write(bp
, params
->port
,
1892 MDIO_PMA_REG_CTRL
, 0xa040);
1894 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
1895 /* Unset Low Power Mode and SW reset */
1896 /* Restore normal power mode*/
1897 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
1898 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
1901 DP(NETIF_MSG_LINK
, "XGXS 8072\n");
1902 bnx2x_cl45_write(bp
, params
->port
,
1909 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
1912 emac_base
= (params
->port
) ? GRCBASE_EMAC0
:
1915 /* Restore normal power mode*/
1916 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
1917 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
1920 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
1921 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
1924 DP(NETIF_MSG_LINK
, "XGXS 8073\n");
1928 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
1929 DP(NETIF_MSG_LINK
, "XGXS SFX7101\n");
1931 /* Restore normal power mode*/
1932 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
1933 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
1937 bnx2x_hw_reset(bp
, params
->port
);
1941 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
1942 DP(NETIF_MSG_LINK
, "XGXS PHY Failure detected\n");
1946 DP(NETIF_MSG_LINK
, "BAD XGXS ext_phy_config 0x%x\n",
1947 params
->ext_phy_config
);
1951 } else { /* SerDes */
1952 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
1953 switch (ext_phy_type
) {
1954 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
:
1955 DP(NETIF_MSG_LINK
, "SerDes Direct\n");
1958 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482
:
1959 DP(NETIF_MSG_LINK
, "SerDes 5482\n");
1960 bnx2x_hw_reset(bp
, params
->port
);
1965 "BAD SerDes ext_phy_config 0x%x\n",
1966 params
->ext_phy_config
);
1972 static void bnx2x_bcm8072_external_rom_boot(struct link_params
*params
)
1974 struct bnx2x
*bp
= params
->bp
;
1975 u8 port
= params
->port
;
1976 u8 ext_phy_addr
= ((params
->ext_phy_config
&
1977 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
1978 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
1979 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
1980 u16 fw_ver1
, fw_ver2
;
1982 /* Need to wait 200ms after reset */
1984 /* Boot port from external ROM
1985 * Set ser_boot_ctl bit in the MISC_CTRL1 register
1987 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
1989 MDIO_PMA_REG_MISC_CTRL1
, 0x0001);
1991 /* Reset internal microprocessor */
1992 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
1994 MDIO_PMA_REG_GEN_CTRL
,
1995 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP
);
1996 /* set micro reset = 0 */
1997 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
1999 MDIO_PMA_REG_GEN_CTRL
,
2000 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET
);
2001 /* Reset internal microprocessor */
2002 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2004 MDIO_PMA_REG_GEN_CTRL
,
2005 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP
);
2006 /* wait for 100ms for code download via SPI port */
2009 /* Clear ser_boot_ctl bit */
2010 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2012 MDIO_PMA_REG_MISC_CTRL1
, 0x0000);
2016 /* Print the PHY FW version */
2017 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
2019 MDIO_PMA_REG_ROM_VER1
, &fw_ver1
);
2020 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
2022 MDIO_PMA_REG_ROM_VER2
, &fw_ver2
);
2023 DP(NETIF_MSG_LINK
, "8072 FW version 0x%x:0x%x\n", fw_ver1
, fw_ver2
);
2026 static u8
bnx2x_8073_is_snr_needed(struct link_params
*params
)
2028 /* This is only required for 8073A1, version 102 only */
2030 struct bnx2x
*bp
= params
->bp
;
2031 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2032 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2033 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2036 /* Read 8073 HW revision*/
2037 bnx2x_cl45_read(bp
, params
->port
,
2038 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2044 /* No need to workaround in 8073 A1 */
2048 bnx2x_cl45_read(bp
, params
->port
,
2049 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2052 MDIO_PMA_REG_ROM_VER2
, &val
);
2054 /* SNR should be applied only for version 0x102 */
2061 static u8
bnx2x_bcm8073_xaui_wa(struct link_params
*params
)
2063 struct bnx2x
*bp
= params
->bp
;
2064 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2065 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2066 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2067 u16 val
, cnt
, cnt1
;
2069 bnx2x_cl45_read(bp
, params
->port
,
2070 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2076 /* No need to workaround in 8073 A1 */
2079 /* XAUI workaround in 8073 A0: */
2081 /* After loading the boot ROM and restarting Autoneg,
2082 poll Dev1, Reg $C820: */
2084 for (cnt
= 0; cnt
< 1000; cnt
++) {
2085 bnx2x_cl45_read(bp
, params
->port
,
2086 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2090 /* If bit [14] = 0 or bit [13] = 0, continue on with
2091 system initialization (XAUI work-around not required,
2092 as these bits indicate 2.5G or 1G link up). */
2093 if (!(val
& (1<<14)) || !(val
& (1<<13))) {
2094 DP(NETIF_MSG_LINK
, "XAUI work-around not required\n");
2096 } else if (!(val
& (1<<15))) {
2097 DP(NETIF_MSG_LINK
, "clc bit 15 went off\n");
2098 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2099 it's MSB (bit 15) goes to 1 (indicating that the
2100 XAUI workaround has completed),
2101 then continue on with system initialization.*/
2102 for (cnt1
= 0; cnt1
< 1000; cnt1
++) {
2103 bnx2x_cl45_read(bp
, params
->port
,
2104 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2108 if (val
& (1<<15)) {
2110 "XAUI workaround has completed\n");
2119 DP(NETIF_MSG_LINK
, "Warning: XAUI work-around timeout !!!\n");
2124 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x
*bp
, u8 port
,
2127 u16 fw_ver1
, fw_ver2
;
2128 /* Boot port from external ROM */
2130 bnx2x_cl45_write(bp
, port
,
2131 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2134 MDIO_PMA_REG_GEN_CTRL
,
2137 /* ucode reboot and rst */
2138 bnx2x_cl45_write(bp
, port
,
2139 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2142 MDIO_PMA_REG_GEN_CTRL
,
2145 bnx2x_cl45_write(bp
, port
,
2146 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2149 MDIO_PMA_REG_MISC_CTRL1
, 0x0001);
2151 /* Reset internal microprocessor */
2152 bnx2x_cl45_write(bp
, port
,
2153 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2156 MDIO_PMA_REG_GEN_CTRL
,
2157 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET
);
2159 /* Release srst bit */
2160 bnx2x_cl45_write(bp
, port
,
2161 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2164 MDIO_PMA_REG_GEN_CTRL
,
2165 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP
);
2167 /* wait for 100ms for code download via SPI port */
2170 /* Clear ser_boot_ctl bit */
2171 bnx2x_cl45_write(bp
, port
,
2172 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2175 MDIO_PMA_REG_MISC_CTRL1
, 0x0000);
2177 bnx2x_cl45_read(bp
, port
, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2180 MDIO_PMA_REG_ROM_VER1
, &fw_ver1
);
2181 bnx2x_cl45_read(bp
, port
,
2182 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2185 MDIO_PMA_REG_ROM_VER2
, &fw_ver2
);
2186 DP(NETIF_MSG_LINK
, "8073 FW version 0x%x:0x%x\n", fw_ver1
, fw_ver2
);
2190 static void bnx2x_bcm807x_force_10G(struct link_params
*params
)
2192 struct bnx2x
*bp
= params
->bp
;
2193 u8 port
= params
->port
;
2194 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2195 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2196 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2197 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2199 /* Force KR or KX */
2200 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2204 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2206 MDIO_PMA_REG_10G_CTRL2
,
2208 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2210 MDIO_PMA_REG_BCM_CTRL
,
2212 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2217 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params
*params
)
2219 struct bnx2x
*bp
= params
->bp
;
2220 u8 port
= params
->port
;
2222 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2223 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2224 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2225 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2227 bnx2x_cl45_read(bp
, params
->port
,
2228 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2234 /* Mustn't set low power mode in 8073 A0 */
2238 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2239 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
2241 MDIO_XS_PLL_SEQUENCER
, &val
);
2243 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2244 MDIO_XS_DEVAD
, MDIO_XS_PLL_SEQUENCER
, val
);
2247 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2248 MDIO_XS_DEVAD
, 0x805E, 0x1077);
2249 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2250 MDIO_XS_DEVAD
, 0x805D, 0x0000);
2251 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2252 MDIO_XS_DEVAD
, 0x805C, 0x030B);
2253 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2254 MDIO_XS_DEVAD
, 0x805B, 0x1240);
2255 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2256 MDIO_XS_DEVAD
, 0x805A, 0x2490);
2259 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2260 MDIO_XS_DEVAD
, 0x80A7, 0x0C74);
2261 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2262 MDIO_XS_DEVAD
, 0x80A6, 0x9041);
2263 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2264 MDIO_XS_DEVAD
, 0x80A5, 0x4640);
2267 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2268 MDIO_XS_DEVAD
, 0x80FE, 0x01C4);
2269 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2270 MDIO_XS_DEVAD
, 0x80FD, 0x9249);
2271 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2272 MDIO_XS_DEVAD
, 0x80FC, 0x2015);
2274 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
2275 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
2277 MDIO_XS_PLL_SEQUENCER
, &val
);
2279 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2280 MDIO_XS_DEVAD
, MDIO_XS_PLL_SEQUENCER
, val
);
2283 static void bnx2x_8073_set_pause_cl37(struct link_params
*params
,
2284 struct link_vars
*vars
)
2287 struct bnx2x
*bp
= params
->bp
;
2289 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2290 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2291 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2292 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2294 bnx2x_cl45_read(bp
, params
->port
,
2298 MDIO_AN_REG_CL37_FC_LD
, &cl37_val
);
2300 cl37_val
&= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
2301 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2303 if ((vars
->ieee_fc
&
2304 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC
) ==
2305 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC
) {
2306 cl37_val
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC
;
2308 if ((vars
->ieee_fc
&
2309 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) ==
2310 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) {
2311 cl37_val
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
;
2313 if ((vars
->ieee_fc
&
2314 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) ==
2315 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) {
2316 cl37_val
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
2319 "Ext phy AN advertize cl37 0x%x\n", cl37_val
);
2321 bnx2x_cl45_write(bp
, params
->port
,
2325 MDIO_AN_REG_CL37_FC_LD
, cl37_val
);
2329 static void bnx2x_ext_phy_set_pause(struct link_params
*params
,
2330 struct link_vars
*vars
)
2332 struct bnx2x
*bp
= params
->bp
;
2334 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2335 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2336 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2337 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2339 /* read modify write pause advertizing */
2340 bnx2x_cl45_read(bp
, params
->port
,
2344 MDIO_AN_REG_ADV_PAUSE
, &val
);
2346 val
&= ~MDIO_AN_REG_ADV_PAUSE_BOTH
;
2348 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2350 if ((vars
->ieee_fc
&
2351 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) ==
2352 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) {
2353 val
|= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC
;
2355 if ((vars
->ieee_fc
&
2356 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) ==
2357 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) {
2359 MDIO_AN_REG_ADV_PAUSE_PAUSE
;
2362 "Ext phy AN advertize 0x%x\n", val
);
2363 bnx2x_cl45_write(bp
, params
->port
,
2367 MDIO_AN_REG_ADV_PAUSE
, val
);
2371 static void bnx2x_init_internal_phy(struct link_params
*params
,
2372 struct link_vars
*vars
)
2374 struct bnx2x
*bp
= params
->bp
;
2375 u8 port
= params
->port
;
2376 if (!(vars
->phy_flags
& PHY_SGMII_FLAG
)) {
2379 rx_eq
= ((params
->serdes_config
&
2380 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK
) >>
2381 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT
);
2383 DP(NETIF_MSG_LINK
, "setting rx eq to 0x%x\n", rx_eq
);
2384 for (bank
= MDIO_REG_BANK_RX0
; bank
<= MDIO_REG_BANK_RX_ALL
;
2385 bank
+= (MDIO_REG_BANK_RX1
-MDIO_REG_BANK_RX0
)) {
2386 CL45_WR_OVER_CL22(bp
, port
,
2389 MDIO_RX0_RX_EQ_BOOST
,
2391 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK
) |
2392 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL
));
2395 /* forced speed requested? */
2396 if (vars
->line_speed
!= SPEED_AUTO_NEG
) {
2397 DP(NETIF_MSG_LINK
, "not SGMII, no AN\n");
2399 /* disable autoneg */
2400 bnx2x_set_autoneg(params
, vars
);
2402 /* program speed and duplex */
2403 bnx2x_program_serdes(params
, vars
);
2405 } else { /* AN_mode */
2406 DP(NETIF_MSG_LINK
, "not SGMII, AN\n");
2409 bnx2x_set_brcm_cl37_advertisment(params
);
2411 /* program duplex & pause advertisement (for aneg) */
2412 bnx2x_set_ieee_aneg_advertisment(params
,
2415 /* enable autoneg */
2416 bnx2x_set_autoneg(params
, vars
);
2418 /* enable and restart AN */
2419 bnx2x_restart_autoneg(params
);
2422 } else { /* SGMII mode */
2423 DP(NETIF_MSG_LINK
, "SGMII\n");
2425 bnx2x_initialize_sgmii_process(params
, vars
);
2429 static u8
bnx2x_ext_phy_init(struct link_params
*params
, struct link_vars
*vars
)
2431 struct bnx2x
*bp
= params
->bp
;
2438 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
2439 ext_phy_addr
= ((params
->ext_phy_config
&
2440 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2441 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2443 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2444 /* Make sure that the soft reset is off (expect for the 8072:
2445 * due to the lock, it will be done inside the specific
2448 if ((ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) &&
2449 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
) &&
2450 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
) &&
2451 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
) &&
2452 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
)) {
2453 /* Wait for soft reset to get cleared upto 1 sec */
2454 for (cnt
= 0; cnt
< 1000; cnt
++) {
2455 bnx2x_cl45_read(bp
, params
->port
,
2459 MDIO_PMA_REG_CTRL
, &ctrl
);
2460 if (!(ctrl
& (1<<15)))
2464 DP(NETIF_MSG_LINK
, "control reg 0x%x (after %d ms)\n",
2468 switch (ext_phy_type
) {
2469 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
2472 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
2473 DP(NETIF_MSG_LINK
, "XGXS 8705\n");
2475 bnx2x_cl45_write(bp
, params
->port
,
2479 MDIO_PMA_REG_MISC_CTRL
,
2481 bnx2x_cl45_write(bp
, params
->port
,
2485 MDIO_PMA_REG_PHY_IDENTIFIER
,
2487 bnx2x_cl45_write(bp
, params
->port
,
2491 MDIO_PMA_REG_CMU_PLL_BYPASS
,
2493 bnx2x_cl45_write(bp
, params
->port
,
2497 MDIO_WIS_REG_LASI_CNTL
, 0x1);
2500 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
2501 DP(NETIF_MSG_LINK
, "XGXS 8706\n");
2505 /* First enable LASI */
2506 bnx2x_cl45_write(bp
, params
->port
,
2510 MDIO_PMA_REG_RX_ALARM_CTRL
,
2512 bnx2x_cl45_write(bp
, params
->port
,
2516 MDIO_PMA_REG_LASI_CTRL
, 0x0004);
2518 if (params
->req_line_speed
== SPEED_10000
) {
2519 DP(NETIF_MSG_LINK
, "XGXS 8706 force 10Gbps\n");
2521 bnx2x_cl45_write(bp
, params
->port
,
2525 MDIO_PMA_REG_DIGITAL_CTRL
,
2528 /* Force 1Gbps using autoneg with 1G
2531 /* Allow CL37 through CL73 */
2532 DP(NETIF_MSG_LINK
, "XGXS 8706 AutoNeg\n");
2533 bnx2x_cl45_write(bp
, params
->port
,
2537 MDIO_AN_REG_CL37_CL73
,
2540 /* Enable Full-Duplex advertisment on CL37 */
2541 bnx2x_cl45_write(bp
, params
->port
,
2545 MDIO_AN_REG_CL37_FC_LP
,
2547 /* Enable CL37 AN */
2548 bnx2x_cl45_write(bp
, params
->port
,
2552 MDIO_AN_REG_CL37_AN
,
2555 bnx2x_cl45_write(bp
, params
->port
,
2559 MDIO_AN_REG_ADV
, (1<<5));
2561 /* Enable clause 73 AN */
2562 bnx2x_cl45_write(bp
, params
->port
,
2573 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
2574 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
2577 u16 rx_alarm_ctrl_val
;
2580 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
) {
2581 rx_alarm_ctrl_val
= 0x400;
2582 lasi_ctrl_val
= 0x0004;
2584 rx_alarm_ctrl_val
= (1<<2);
2585 lasi_ctrl_val
= 0x0004;
2589 bnx2x_cl45_write(bp
, params
->port
,
2593 MDIO_PMA_REG_RX_ALARM_CTRL
,
2596 bnx2x_cl45_write(bp
, params
->port
,
2600 MDIO_PMA_REG_LASI_CTRL
,
2603 bnx2x_8073_set_pause_cl37(params
, vars
);
2606 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
){
2607 bnx2x_bcm8072_external_rom_boot(params
);
2610 /* In case of 8073 with long xaui lines,
2611 don't set the 8073 xaui low power*/
2612 bnx2x_bcm8073_set_xaui_low_power_mode(params
);
2615 bnx2x_cl45_read(bp
, params
->port
,
2622 bnx2x_cl45_read(bp
, params
->port
,
2626 MDIO_PMA_REG_RX_ALARM
, &tmp1
);
2628 DP(NETIF_MSG_LINK
, "Before rom RX_ALARM(port1):"
2631 /* If this is forced speed, set to KR or KX
2632 * (all other are not supported)
2634 if (params
->loopback_mode
== LOOPBACK_EXT
) {
2635 bnx2x_bcm807x_force_10G(params
);
2637 "Forced speed 10G on 807X\n");
2640 bnx2x_cl45_write(bp
, params
->port
,
2641 ext_phy_type
, ext_phy_addr
,
2643 MDIO_PMA_REG_BCM_CTRL
,
2646 if (params
->req_line_speed
!= SPEED_AUTO_NEG
) {
2647 if (params
->req_line_speed
== SPEED_10000
) {
2649 } else if (params
->req_line_speed
==
2652 /* Note that 2.5G works only
2653 when used with 1G advertisment */
2659 if (params
->speed_cap_mask
&
2660 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)
2663 /* Note that 2.5G works only when
2664 used with 1G advertisment */
2665 if (params
->speed_cap_mask
&
2666 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
|
2667 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G
))
2670 "807x autoneg val = 0x%x\n", val
);
2673 bnx2x_cl45_write(bp
, params
->port
,
2677 MDIO_AN_REG_ADV
, val
);
2680 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
2682 bnx2x_cl45_read(bp
, params
->port
,
2688 if (((params
->speed_cap_mask
&
2689 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G
) &&
2690 (params
->req_line_speed
==
2692 (params
->req_line_speed
==
2695 /* Allow 2.5G for A1 and above */
2696 bnx2x_cl45_read(bp
, params
->port
,
2697 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2701 DP(NETIF_MSG_LINK
, "Add 2.5G\n");
2707 DP(NETIF_MSG_LINK
, "Disable 2.5G\n");
2711 bnx2x_cl45_write(bp
, params
->port
,
2718 /* Add support for CL37 (passive mode) II */
2720 bnx2x_cl45_read(bp
, params
->port
,
2724 MDIO_AN_REG_CL37_FC_LD
,
2727 bnx2x_cl45_write(bp
, params
->port
,
2731 MDIO_AN_REG_CL37_FC_LD
, (tmp1
|
2732 ((params
->req_duplex
== DUPLEX_FULL
) ?
2735 /* Add support for CL37 (passive mode) III */
2736 bnx2x_cl45_write(bp
, params
->port
,
2740 MDIO_AN_REG_CL37_AN
, 0x1000);
2743 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
2744 /* The SNR will improve about 2db by changing
2745 BW and FEE main tap. Rest commands are executed
2747 /*Change FFE main cursor to 5 in EDC register*/
2748 if (bnx2x_8073_is_snr_needed(params
))
2749 bnx2x_cl45_write(bp
, params
->port
,
2753 MDIO_PMA_REG_EDC_FFE_MAIN
,
2756 /* Enable FEC (Forware Error Correction)
2757 Request in the AN */
2758 bnx2x_cl45_read(bp
, params
->port
,
2762 MDIO_AN_REG_ADV2
, &tmp1
);
2766 bnx2x_cl45_write(bp
, params
->port
,
2770 MDIO_AN_REG_ADV2
, tmp1
);
2774 bnx2x_ext_phy_set_pause(params
, vars
);
2776 /* Restart autoneg */
2778 bnx2x_cl45_write(bp
, params
->port
,
2782 MDIO_AN_REG_CTRL
, 0x1200);
2783 DP(NETIF_MSG_LINK
, "807x Autoneg Restart: "
2784 "Advertise 1G=%x, 10G=%x\n",
2785 ((val
& (1<<5)) > 0),
2786 ((val
& (1<<7)) > 0));
2789 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
2791 "Setting the SFX7101 LASI indication\n");
2793 bnx2x_cl45_write(bp
, params
->port
,
2797 MDIO_PMA_REG_LASI_CTRL
, 0x1);
2799 "Setting the SFX7101 LED to blink on traffic\n");
2800 bnx2x_cl45_write(bp
, params
->port
,
2804 MDIO_PMA_REG_7107_LED_CNTL
, (1<<3));
2806 bnx2x_ext_phy_set_pause(params
, vars
);
2807 /* Restart autoneg */
2808 bnx2x_cl45_read(bp
, params
->port
,
2812 MDIO_AN_REG_CTRL
, &val
);
2814 bnx2x_cl45_write(bp
, params
->port
,
2818 MDIO_AN_REG_CTRL
, val
);
2820 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
2822 "XGXS PHY Failure detected 0x%x\n",
2823 params
->ext_phy_config
);
2827 DP(NETIF_MSG_LINK
, "BAD XGXS ext_phy_config 0x%x\n",
2828 params
->ext_phy_config
);
2833 } else { /* SerDes */
2835 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
2836 switch (ext_phy_type
) {
2837 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
:
2838 DP(NETIF_MSG_LINK
, "SerDes Direct\n");
2841 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482
:
2842 DP(NETIF_MSG_LINK
, "SerDes 5482\n");
2846 DP(NETIF_MSG_LINK
, "BAD SerDes ext_phy_config 0x%x\n",
2847 params
->ext_phy_config
);
2855 static u8
bnx2x_ext_phy_is_link_up(struct link_params
*params
,
2856 struct link_vars
*vars
)
2858 struct bnx2x
*bp
= params
->bp
;
2862 u16 rx_sd
, pcs_status
;
2863 u8 ext_phy_link_up
= 0;
2864 u8 port
= params
->port
;
2865 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
2866 ext_phy_addr
= ((params
->ext_phy_config
&
2867 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2868 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2870 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2871 switch (ext_phy_type
) {
2872 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
2873 DP(NETIF_MSG_LINK
, "XGXS Direct\n");
2874 ext_phy_link_up
= 1;
2877 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
2878 DP(NETIF_MSG_LINK
, "XGXS 8705\n");
2879 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2882 MDIO_WIS_REG_LASI_STATUS
, &val1
);
2883 DP(NETIF_MSG_LINK
, "8705 LASI status 0x%x\n", val1
);
2885 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2888 MDIO_WIS_REG_LASI_STATUS
, &val1
);
2889 DP(NETIF_MSG_LINK
, "8705 LASI status 0x%x\n", val1
);
2891 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2894 MDIO_PMA_REG_RX_SD
, &rx_sd
);
2895 DP(NETIF_MSG_LINK
, "8705 rx_sd 0x%x\n", rx_sd
);
2896 ext_phy_link_up
= (rx_sd
& 0x1);
2897 if (ext_phy_link_up
)
2898 vars
->line_speed
= SPEED_10000
;
2901 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
2902 DP(NETIF_MSG_LINK
, "XGXS 8706\n");
2903 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2906 MDIO_PMA_REG_LASI_STATUS
, &val1
);
2907 DP(NETIF_MSG_LINK
, "8706 LASI status 0x%x\n", val1
);
2909 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2912 MDIO_PMA_REG_LASI_STATUS
, &val1
);
2913 DP(NETIF_MSG_LINK
, "8706 LASI status 0x%x\n", val1
);
2915 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2918 MDIO_PMA_REG_RX_SD
, &rx_sd
);
2919 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2922 MDIO_PCS_REG_STATUS
, &pcs_status
);
2924 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2927 MDIO_AN_REG_LINK_STATUS
, &val2
);
2928 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2931 MDIO_AN_REG_LINK_STATUS
, &val2
);
2933 DP(NETIF_MSG_LINK
, "8706 rx_sd 0x%x"
2934 " pcs_status 0x%x 1Gbps link_status 0x%x\n",
2935 rx_sd
, pcs_status
, val2
);
2936 /* link is up if both bit 0 of pmd_rx_sd and
2937 * bit 0 of pcs_status are set, or if the autoneg bit
2940 ext_phy_link_up
= ((rx_sd
& pcs_status
& 0x1) ||
2942 if (ext_phy_link_up
) {
2944 vars
->line_speed
= SPEED_1000
;
2946 vars
->line_speed
= SPEED_10000
;
2949 /* clear LASI indication*/
2950 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2953 MDIO_PMA_REG_RX_ALARM
, &val2
);
2956 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
2957 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
2959 u16 link_status
= 0;
2960 u16 an1000_status
= 0;
2962 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
) {
2963 bnx2x_cl45_read(bp
, params
->port
,
2967 MDIO_PCS_REG_LASI_STATUS
, &val1
);
2968 bnx2x_cl45_read(bp
, params
->port
,
2972 MDIO_PCS_REG_LASI_STATUS
, &val2
);
2974 "870x LASI status 0x%x->0x%x\n",
2978 /* In 8073, port1 is directed through emac0 and
2979 * port0 is directed through emac1
2981 bnx2x_cl45_read(bp
, params
->port
,
2985 MDIO_PMA_REG_LASI_STATUS
, &val1
);
2988 "8703 LASI status 0x%x\n",
2992 /* clear the interrupt LASI status register */
2993 bnx2x_cl45_read(bp
, params
->port
,
2997 MDIO_PCS_REG_STATUS
, &val2
);
2998 bnx2x_cl45_read(bp
, params
->port
,
3002 MDIO_PCS_REG_STATUS
, &val1
);
3003 DP(NETIF_MSG_LINK
, "807x PCS status 0x%x->0x%x\n",
3006 bnx2x_cl45_read(bp
, params
->port
,
3013 /* Check the LASI */
3014 bnx2x_cl45_read(bp
, params
->port
,
3018 MDIO_PMA_REG_RX_ALARM
, &val2
);
3020 DP(NETIF_MSG_LINK
, "KR 0x9003 0x%x\n", val2
);
3022 /* Check the link status */
3023 bnx2x_cl45_read(bp
, params
->port
,
3027 MDIO_PCS_REG_STATUS
, &val2
);
3028 DP(NETIF_MSG_LINK
, "KR PCS status 0x%x\n", val2
);
3030 bnx2x_cl45_read(bp
, params
->port
,
3034 MDIO_PMA_REG_STATUS
, &val2
);
3035 bnx2x_cl45_read(bp
, params
->port
,
3039 MDIO_PMA_REG_STATUS
, &val1
);
3040 ext_phy_link_up
= ((val1
& 4) == 4);
3041 DP(NETIF_MSG_LINK
, "PMA_REG_STATUS=0x%x\n", val1
);
3043 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
3045 if (ext_phy_link_up
&&
3046 ((params
->req_line_speed
!=
3048 if (bnx2x_bcm8073_xaui_wa(params
)
3050 ext_phy_link_up
= 0;
3054 bnx2x_cl45_read(bp
, params
->port
,
3060 bnx2x_cl45_read(bp
, params
->port
,
3067 /* Check the link status on 1.1.2 */
3068 bnx2x_cl45_read(bp
, params
->port
,
3072 MDIO_PMA_REG_STATUS
, &val2
);
3073 bnx2x_cl45_read(bp
, params
->port
,
3077 MDIO_PMA_REG_STATUS
, &val1
);
3078 DP(NETIF_MSG_LINK
, "KR PMA status 0x%x->0x%x,"
3079 "an_link_status=0x%x\n",
3080 val2
, val1
, an1000_status
);
3082 ext_phy_link_up
= (((val1
& 4) == 4) ||
3083 (an1000_status
& (1<<1)));
3084 if (ext_phy_link_up
&&
3085 bnx2x_8073_is_snr_needed(params
)) {
3086 /* The SNR will improve about 2dbby
3087 changing the BW and FEE main tap.*/
3089 /* The 1st write to change FFE main
3090 tap is set before restart AN */
3091 /* Change PLL Bandwidth in EDC
3093 bnx2x_cl45_write(bp
, port
, ext_phy_type
,
3096 MDIO_PMA_REG_PLL_BANDWIDTH
,
3099 /* Change CDR Bandwidth in EDC
3101 bnx2x_cl45_write(bp
, port
, ext_phy_type
,
3104 MDIO_PMA_REG_CDR_BANDWIDTH
,
3109 bnx2x_cl45_read(bp
, params
->port
,
3116 /* Bits 0..2 --> speed detected,
3117 bits 13..15--> link is down */
3118 if ((link_status
& (1<<2)) &&
3119 (!(link_status
& (1<<15)))) {
3120 ext_phy_link_up
= 1;
3121 vars
->line_speed
= SPEED_10000
;
3123 "port %x: External link"
3124 " up in 10G\n", params
->port
);
3125 } else if ((link_status
& (1<<1)) &&
3126 (!(link_status
& (1<<14)))) {
3127 ext_phy_link_up
= 1;
3128 vars
->line_speed
= SPEED_2500
;
3130 "port %x: External link"
3131 " up in 2.5G\n", params
->port
);
3132 } else if ((link_status
& (1<<0)) &&
3133 (!(link_status
& (1<<13)))) {
3134 ext_phy_link_up
= 1;
3135 vars
->line_speed
= SPEED_1000
;
3137 "port %x: External link"
3138 " up in 1G\n", params
->port
);
3140 ext_phy_link_up
= 0;
3142 "port %x: External link"
3143 " is down\n", params
->port
);
3146 /* See if 1G link is up for the 8072 */
3147 bnx2x_cl45_read(bp
, params
->port
,
3153 bnx2x_cl45_read(bp
, params
->port
,
3159 if (an1000_status
& (1<<1)) {
3160 ext_phy_link_up
= 1;
3161 vars
->line_speed
= SPEED_1000
;
3163 "port %x: External link"
3164 " up in 1G\n", params
->port
);
3165 } else if (ext_phy_link_up
) {
3166 ext_phy_link_up
= 1;
3167 vars
->line_speed
= SPEED_10000
;
3169 "port %x: External link"
3170 " up in 10G\n", params
->port
);
3177 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
3178 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3181 MDIO_PMA_REG_LASI_STATUS
, &val2
);
3182 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3185 MDIO_PMA_REG_LASI_STATUS
, &val1
);
3187 "10G-base-T LASI status 0x%x->0x%x\n",
3189 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3192 MDIO_PMA_REG_STATUS
, &val2
);
3193 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3196 MDIO_PMA_REG_STATUS
, &val1
);
3198 "10G-base-T PMA status 0x%x->0x%x\n",
3200 ext_phy_link_up
= ((val1
& 4) == 4);
3202 * print the AN outcome of the SFX7101 PHY
3204 if (ext_phy_link_up
) {
3205 bnx2x_cl45_read(bp
, params
->port
,
3209 MDIO_AN_REG_MASTER_STATUS
,
3211 vars
->line_speed
= SPEED_10000
;
3213 "SFX7101 AN status 0x%x->Master=%x\n",
3220 DP(NETIF_MSG_LINK
, "BAD XGXS ext_phy_config 0x%x\n",
3221 params
->ext_phy_config
);
3222 ext_phy_link_up
= 0;
3226 } else { /* SerDes */
3227 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
3228 switch (ext_phy_type
) {
3229 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
:
3230 DP(NETIF_MSG_LINK
, "SerDes Direct\n");
3231 ext_phy_link_up
= 1;
3234 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482
:
3235 DP(NETIF_MSG_LINK
, "SerDes 5482\n");
3236 ext_phy_link_up
= 1;
3241 "BAD SerDes ext_phy_config 0x%x\n",
3242 params
->ext_phy_config
);
3243 ext_phy_link_up
= 0;
3248 return ext_phy_link_up
;
3251 static void bnx2x_link_int_enable(struct link_params
*params
)
3253 u8 port
= params
->port
;
3256 struct bnx2x
*bp
= params
->bp
;
3257 /* setting the status to report on link up
3258 for either XGXS or SerDes */
3260 if (params
->switch_cfg
== SWITCH_CFG_10G
) {
3261 mask
= (NIG_MASK_XGXS0_LINK10G
|
3262 NIG_MASK_XGXS0_LINK_STATUS
);
3263 DP(NETIF_MSG_LINK
, "enabled XGXS interrupt\n");
3264 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3265 if ((ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) &&
3266 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
) &&
3268 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
)) {
3269 mask
|= NIG_MASK_MI_INT
;
3270 DP(NETIF_MSG_LINK
, "enabled external phy int\n");
3273 } else { /* SerDes */
3274 mask
= NIG_MASK_SERDES0_LINK_STATUS
;
3275 DP(NETIF_MSG_LINK
, "enabled SerDes interrupt\n");
3276 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
3277 if ((ext_phy_type
!=
3278 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
) &&
3280 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN
)) {
3281 mask
|= NIG_MASK_MI_INT
;
3282 DP(NETIF_MSG_LINK
, "enabled external phy int\n");
3286 NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4,
3288 DP(NETIF_MSG_LINK
, "port %x, is_xgxs=%x, int_status 0x%x\n", port
,
3289 (params
->switch_cfg
== SWITCH_CFG_10G
),
3290 REG_RD(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4));
3292 DP(NETIF_MSG_LINK
, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
3293 REG_RD(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4),
3294 REG_RD(bp
, NIG_REG_EMAC0_STATUS_MISC_MI_INT
+ port
*0x18),
3295 REG_RD(bp
, NIG_REG_SERDES0_STATUS_LINK_STATUS
+port
*0x3c));
3296 DP(NETIF_MSG_LINK
, " 10G %x, XGXS_LINK %x\n",
3297 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK10G
+ port
*0x68),
3298 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK_STATUS
+ port
*0x68));
3305 static void bnx2x_link_int_ack(struct link_params
*params
,
3306 struct link_vars
*vars
, u16 is_10g
)
3308 struct bnx2x
*bp
= params
->bp
;
3309 u8 port
= params
->port
;
3311 /* first reset all status
3312 * we assume only one line will be change at a time */
3313 bnx2x_bits_dis(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
3314 (NIG_STATUS_XGXS0_LINK10G
|
3315 NIG_STATUS_XGXS0_LINK_STATUS
|
3316 NIG_STATUS_SERDES0_LINK_STATUS
));
3317 if (vars
->phy_link_up
) {
3319 /* Disable the 10G link interrupt
3320 * by writing 1 to the status register
3322 DP(NETIF_MSG_LINK
, "10G XGXS phy link up\n");
3324 NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
3325 NIG_STATUS_XGXS0_LINK10G
);
3327 } else if (params
->switch_cfg
== SWITCH_CFG_10G
) {
3328 /* Disable the link interrupt
3329 * by writing 1 to the relevant lane
3330 * in the status register
3332 u32 ser_lane
= ((params
->lane_config
&
3333 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
3334 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
3336 DP(NETIF_MSG_LINK
, "1G XGXS phy link up\n");
3338 NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
3340 NIG_STATUS_XGXS0_LINK_STATUS_SIZE
));
3342 } else { /* SerDes */
3343 DP(NETIF_MSG_LINK
, "SerDes phy link up\n");
3344 /* Disable the link interrupt
3345 * by writing 1 to the status register
3348 NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
3349 NIG_STATUS_SERDES0_LINK_STATUS
);
3352 } else { /* link_down */
3356 static u8
bnx2x_format_ver(u32 num
, u8
*str
, u16 len
)
3359 u32 mask
= 0xf0000000;
3363 /* Need more then 10chars for this format */
3370 digit
= ((num
& mask
) >> shift
);
3372 *str_ptr
= digit
+ '0';
3374 *str_ptr
= digit
- 0xa + 'a';
3387 static void bnx2x_turn_on_ef(struct bnx2x
*bp
, u8 port
, u8 ext_phy_addr
,
3392 /* Enable EMAC0 in to enable MDIO */
3393 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
3394 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE
<< port
));
3397 /* take ext phy out of reset */
3399 MISC_REGISTERS_GPIO_2
,
3400 MISC_REGISTERS_GPIO_HIGH
,
3404 MISC_REGISTERS_GPIO_1
,
3405 MISC_REGISTERS_GPIO_HIGH
,
3411 for (cnt
= 0; cnt
< 1000; cnt
++) {
3413 bnx2x_cl45_read(bp
, port
,
3419 if (!(ctrl
& (1<<15))) {
3420 DP(NETIF_MSG_LINK
, "Reset completed\n\n");
3426 static void bnx2x_turn_off_sf(struct bnx2x
*bp
, u8 port
)
3428 /* put sf to reset */
3430 MISC_REGISTERS_GPIO_1
,
3431 MISC_REGISTERS_GPIO_LOW
,
3434 MISC_REGISTERS_GPIO_2
,
3435 MISC_REGISTERS_GPIO_LOW
,
3439 u8
bnx2x_get_ext_phy_fw_version(struct link_params
*params
, u8 driver_loaded
,
3440 u8
*version
, u16 len
)
3442 struct bnx2x
*bp
= params
->bp
;
3443 u32 ext_phy_type
= 0;
3445 u8 ext_phy_addr
= 0 ;
3449 if (version
== NULL
|| params
== NULL
)
3452 /* reset the returned value to zero */
3453 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3454 ext_phy_addr
= ((params
->ext_phy_config
&
3455 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
3456 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
3458 switch (ext_phy_type
) {
3459 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
3464 /* Take ext phy out of reset */
3466 bnx2x_turn_on_ef(bp
, params
->port
, ext_phy_addr
,
3472 bnx2x_cl45_read(bp
, params
->port
,
3476 MDIO_PMA_REG_7101_VER1
, &val
);
3477 version
[2] = (val
& 0xFF);
3478 version
[3] = ((val
& 0xFF00)>>8);
3480 bnx2x_cl45_read(bp
, params
->port
,
3483 MDIO_PMA_DEVAD
, MDIO_PMA_REG_7101_VER2
,
3485 version
[0] = (val
& 0xFF);
3486 version
[1] = ((val
& 0xFF00)>>8);
3490 bnx2x_turn_off_sf(bp
, params
->port
);
3492 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
3493 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
3495 /* Take ext phy out of reset */
3497 bnx2x_turn_on_ef(bp
, params
->port
, ext_phy_addr
,
3500 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3503 MDIO_PMA_REG_ROM_VER1
, &val
);
3505 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3508 MDIO_PMA_REG_ROM_VER2
, &val
);
3510 status
= bnx2x_format_ver(ver_num
, version
, len
);
3513 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
3514 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
3516 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3519 MDIO_PMA_REG_ROM_VER1
, &val
);
3521 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3524 MDIO_PMA_REG_ROM_VER2
, &val
);
3526 status
= bnx2x_format_ver(ver_num
, version
, len
);
3529 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
3532 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
3533 DP(NETIF_MSG_LINK
, "bnx2x_get_ext_phy_fw_version:"
3534 " type is FAILURE!\n");
3544 static void bnx2x_set_xgxs_loopback(struct link_params
*params
,
3545 struct link_vars
*vars
,
3548 u8 port
= params
->port
;
3549 struct bnx2x
*bp
= params
->bp
;
3554 DP(NETIF_MSG_LINK
, "XGXS 10G loopback enable\n");
3556 /* change the uni_phy_addr in the nig */
3557 md_devad
= REG_RD(bp
, (NIG_REG_XGXS0_CTRL_MD_DEVAD
+
3560 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_DEVAD
+ port
*0x18, 0x5);
3562 bnx2x_cl45_write(bp
, port
, 0,
3565 (MDIO_REG_BANK_AER_BLOCK
+
3566 (MDIO_AER_BLOCK_AER_REG
& 0xf)),
3569 bnx2x_cl45_write(bp
, port
, 0,
3572 (MDIO_REG_BANK_CL73_IEEEB0
+
3573 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL
& 0xf)),
3576 /* set aer mmd back */
3577 bnx2x_set_aer_mmd(params
, vars
);
3580 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_DEVAD
+ port
*0x18,
3586 DP(NETIF_MSG_LINK
, "XGXS 1G loopback enable\n");
3588 CL45_RD_OVER_CL22(bp
, port
,
3590 MDIO_REG_BANK_COMBO_IEEE0
,
3591 MDIO_COMBO_IEEE0_MII_CONTROL
,
3594 CL45_WR_OVER_CL22(bp
, port
,
3596 MDIO_REG_BANK_COMBO_IEEE0
,
3597 MDIO_COMBO_IEEE0_MII_CONTROL
,
3599 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK
));
3604 static void bnx2x_ext_phy_loopback(struct link_params
*params
)
3606 struct bnx2x
*bp
= params
->bp
;
3610 if (params
->switch_cfg
== SWITCH_CFG_10G
) {
3611 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3612 /* CL37 Autoneg Enabled */
3613 ext_phy_addr
= ((params
->ext_phy_config
&
3614 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
3615 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
3616 switch (ext_phy_type
) {
3617 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
3618 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
:
3620 "ext_phy_loopback: We should not get here\n");
3622 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
3623 DP(NETIF_MSG_LINK
, "ext_phy_loopback: 8705\n");
3625 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
3626 DP(NETIF_MSG_LINK
, "ext_phy_loopback: 8706\n");
3628 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
3629 /* SFX7101_XGXS_TEST1 */
3630 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
3633 MDIO_XS_SFX7101_XGXS_TEST1
,
3636 "ext_phy_loopback: set ext phy loopback\n");
3638 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
3641 } /* switch external PHY type */
3644 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
3645 ext_phy_addr
= (params
->ext_phy_config
&
3646 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK
)
3647 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT
;
3653 *------------------------------------------------------------------------
3654 * bnx2x_override_led_value -
3656 * Override the led value of the requsted led
3658 *------------------------------------------------------------------------
3660 u8
bnx2x_override_led_value(struct bnx2x
*bp
, u8 port
,
3661 u32 led_idx
, u32 value
)
3665 /* If port 0 then use EMAC0, else use EMAC1*/
3666 u32 emac_base
= (port
) ? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
3669 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
3670 port
, led_idx
, value
);
3673 case 0: /* 10MB led */
3674 /* Read the current value of the LED register in
3676 reg_val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_LED
);
3677 /* Set the OVERRIDE bit to 1 */
3678 reg_val
|= EMAC_LED_OVERRIDE
;
3679 /* If value is 1, set the 10M_OVERRIDE bit,
3680 otherwise reset it.*/
3681 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_10MB_OVERRIDE
) :
3682 (reg_val
& ~EMAC_LED_10MB_OVERRIDE
);
3683 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
3685 case 1: /*100MB led */
3686 /*Read the current value of the LED register in
3688 reg_val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_LED
);
3689 /* Set the OVERRIDE bit to 1 */
3690 reg_val
|= EMAC_LED_OVERRIDE
;
3691 /* If value is 1, set the 100M_OVERRIDE bit,
3692 otherwise reset it.*/
3693 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_100MB_OVERRIDE
) :
3694 (reg_val
& ~EMAC_LED_100MB_OVERRIDE
);
3695 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
3697 case 2: /* 1000MB led */
3698 /* Read the current value of the LED register in the
3700 reg_val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_LED
);
3701 /* Set the OVERRIDE bit to 1 */
3702 reg_val
|= EMAC_LED_OVERRIDE
;
3703 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
3705 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_1000MB_OVERRIDE
) :
3706 (reg_val
& ~EMAC_LED_1000MB_OVERRIDE
);
3707 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
3709 case 3: /* 2500MB led */
3710 /* Read the current value of the LED register in the
3712 reg_val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_LED
);
3713 /* Set the OVERRIDE bit to 1 */
3714 reg_val
|= EMAC_LED_OVERRIDE
;
3715 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
3717 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_2500MB_OVERRIDE
) :
3718 (reg_val
& ~EMAC_LED_2500MB_OVERRIDE
);
3719 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
3721 case 4: /*10G led */
3723 REG_WR(bp
, NIG_REG_LED_10G_P0
,
3726 REG_WR(bp
, NIG_REG_LED_10G_P1
,
3730 case 5: /* TRAFFIC led */
3731 /* Find if the traffic control is via BMAC or EMAC */
3733 reg_val
= REG_RD(bp
, NIG_REG_NIG_EMAC0_EN
);
3735 reg_val
= REG_RD(bp
, NIG_REG_NIG_EMAC1_EN
);
3737 /* Override the traffic led in the EMAC:*/
3739 /* Read the current value of the LED register in
3741 reg_val
= REG_RD(bp
, emac_base
+
3743 /* Set the TRAFFIC_OVERRIDE bit to 1 */
3744 reg_val
|= EMAC_LED_OVERRIDE
;
3745 /* If value is 1, set the TRAFFIC bit, otherwise
3747 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_TRAFFIC
) :
3748 (reg_val
& ~EMAC_LED_TRAFFIC
);
3749 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
3750 } else { /* Override the traffic led in the BMAC: */
3751 REG_WR(bp
, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3753 REG_WR(bp
, NIG_REG_LED_CONTROL_TRAFFIC_P0
+ port
*4,
3759 "bnx2x_override_led_value() unknown led index %d "
3760 "(should be 0-5)\n", led_idx
);
3768 u8
bnx2x_set_led(struct bnx2x
*bp
, u8 port
, u8 mode
, u32 speed
,
3769 u16 hw_led_mode
, u32 chip_id
)
3772 DP(NETIF_MSG_LINK
, "bnx2x_set_led: port %x, mode %d\n", port
, mode
);
3773 DP(NETIF_MSG_LINK
, "speed 0x%x, hw_led_mode 0x%x\n",
3774 speed
, hw_led_mode
);
3777 REG_WR(bp
, NIG_REG_LED_10G_P0
+ port
*4, 0);
3778 REG_WR(bp
, NIG_REG_LED_MODE_P0
+ port
*4,
3779 SHARED_HW_CFG_LED_MAC1
);
3783 REG_WR(bp
, NIG_REG_LED_MODE_P0
+ port
*4, hw_led_mode
);
3784 REG_WR(bp
, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
+
3786 /* Set blinking rate to ~15.9Hz */
3787 REG_WR(bp
, NIG_REG_LED_CONTROL_BLINK_RATE_P0
+ port
*4,
3788 LED_BLINK_RATE_VAL
);
3789 REG_WR(bp
, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0
+
3791 if (!CHIP_IS_E1H(bp
) &&
3792 ((speed
== SPEED_2500
) ||
3793 (speed
== SPEED_1000
) ||
3794 (speed
== SPEED_100
) ||
3795 (speed
== SPEED_10
))) {
3796 /* On Everest 1 Ax chip versions for speeds less than
3797 10G LED scheme is different */
3798 REG_WR(bp
, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3800 REG_WR(bp
, NIG_REG_LED_CONTROL_TRAFFIC_P0
+
3802 REG_WR(bp
, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0
+
3809 DP(NETIF_MSG_LINK
, "bnx2x_set_led: Invalid led mode %d\n",
3817 u8
bnx2x_test_link(struct link_params
*params
, struct link_vars
*vars
)
3819 struct bnx2x
*bp
= params
->bp
;
3822 CL45_RD_OVER_CL22(bp
, params
->port
,
3824 MDIO_REG_BANK_GP_STATUS
,
3825 MDIO_GP_STATUS_TOP_AN_STATUS1
,
3827 /* link is up only if both local phy and external phy are up */
3828 if ((gp_status
& MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS
) &&
3829 bnx2x_ext_phy_is_link_up(params
, vars
))
3835 static u8
bnx2x_link_initialize(struct link_params
*params
,
3836 struct link_vars
*vars
)
3838 struct bnx2x
*bp
= params
->bp
;
3839 u8 port
= params
->port
;
3842 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3843 /* Activate the external PHY */
3844 bnx2x_ext_phy_reset(params
, vars
);
3846 bnx2x_set_aer_mmd(params
, vars
);
3848 if (vars
->phy_flags
& PHY_XGXS_FLAG
)
3849 bnx2x_set_master_ln(params
);
3851 rc
= bnx2x_reset_unicore(params
);
3852 /* reset the SerDes and wait for reset bit return low */
3856 bnx2x_set_aer_mmd(params
, vars
);
3858 /* setting the masterLn_def again after the reset */
3859 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
3860 bnx2x_set_master_ln(params
);
3861 bnx2x_set_swap_lanes(params
);
3864 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
3865 if (params
->req_line_speed
&&
3866 ((params
->req_line_speed
== SPEED_100
) ||
3867 (params
->req_line_speed
== SPEED_10
))) {
3868 vars
->phy_flags
|= PHY_SGMII_FLAG
;
3870 vars
->phy_flags
&= ~PHY_SGMII_FLAG
;
3873 /* In case of external phy existance, the line speed would be the
3874 line speed linked up by the external phy. In case it is direct only,
3875 then the line_speed during initialization will be equal to the
3877 vars
->line_speed
= params
->req_line_speed
;
3879 bnx2x_calc_ieee_aneg_adv(params
, &vars
->ieee_fc
);
3881 /* init ext phy and enable link state int */
3882 non_ext_phy
= ((ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) ||
3883 (params
->loopback_mode
== LOOPBACK_XGXS_10
) ||
3884 (params
->loopback_mode
== LOOPBACK_EXT_PHY
));
3887 (ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
)) {
3888 if (params
->req_line_speed
== SPEED_AUTO_NEG
)
3889 bnx2x_set_parallel_detection(params
, vars
->phy_flags
);
3890 bnx2x_init_internal_phy(params
, vars
);
3894 rc
|= bnx2x_ext_phy_init(params
, vars
);
3896 bnx2x_bits_dis(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
3897 (NIG_STATUS_XGXS0_LINK10G
|
3898 NIG_STATUS_XGXS0_LINK_STATUS
|
3899 NIG_STATUS_SERDES0_LINK_STATUS
));
3906 u8
bnx2x_phy_init(struct link_params
*params
, struct link_vars
*vars
)
3908 struct bnx2x
*bp
= params
->bp
;
3911 DP(NETIF_MSG_LINK
, "Phy Initialization started\n");
3912 DP(NETIF_MSG_LINK
, "req_speed = %d, req_flowctrl=%d\n",
3913 params
->req_line_speed
, params
->req_flow_ctrl
);
3914 vars
->link_status
= 0;
3915 vars
->phy_link_up
= 0;
3917 vars
->line_speed
= 0;
3918 vars
->duplex
= DUPLEX_FULL
;
3919 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
3920 vars
->mac_type
= MAC_TYPE_NONE
;
3922 if (params
->switch_cfg
== SWITCH_CFG_1G
)
3923 vars
->phy_flags
= PHY_SERDES_FLAG
;
3925 vars
->phy_flags
= PHY_XGXS_FLAG
;
3927 /* disable attentions */
3928 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ params
->port
*4,
3929 (NIG_MASK_XGXS0_LINK_STATUS
|
3930 NIG_MASK_XGXS0_LINK10G
|
3931 NIG_MASK_SERDES0_LINK_STATUS
|
3934 bnx2x_emac_init(params
, vars
);
3936 if (CHIP_REV_IS_FPGA(bp
)) {
3938 vars
->line_speed
= SPEED_10000
;
3939 vars
->duplex
= DUPLEX_FULL
;
3940 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
3941 vars
->link_status
= (LINK_STATUS_LINK_UP
| LINK_10GTFD
);
3942 /* enable on E1.5 FPGA */
3943 if (CHIP_IS_E1H(bp
)) {
3945 (FLOW_CTRL_TX
| FLOW_CTRL_RX
);
3946 vars
->link_status
|=
3947 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED
|
3948 LINK_STATUS_RX_FLOW_CONTROL_ENABLED
);
3951 bnx2x_emac_enable(params
, vars
, 0);
3952 bnx2x_pbf_update(params
, vars
->flow_ctrl
, vars
->line_speed
);
3954 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
3955 + params
->port
*4, 0);
3957 /* update shared memory */
3958 bnx2x_update_mng(params
, vars
->link_status
);
3963 if (CHIP_REV_IS_EMUL(bp
)) {
3966 vars
->line_speed
= SPEED_10000
;
3967 vars
->duplex
= DUPLEX_FULL
;
3968 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
3969 vars
->link_status
= (LINK_STATUS_LINK_UP
| LINK_10GTFD
);
3971 bnx2x_bmac_enable(params
, vars
, 0);
3973 bnx2x_pbf_update(params
, vars
->flow_ctrl
, vars
->line_speed
);
3975 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
3976 + params
->port
*4, 0);
3978 /* update shared memory */
3979 bnx2x_update_mng(params
, vars
->link_status
);
3984 if (params
->loopback_mode
== LOOPBACK_BMAC
) {
3986 vars
->line_speed
= SPEED_10000
;
3987 vars
->duplex
= DUPLEX_FULL
;
3988 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
3989 vars
->mac_type
= MAC_TYPE_BMAC
;
3991 vars
->phy_flags
= PHY_XGXS_FLAG
;
3993 bnx2x_phy_deassert(params
, vars
->phy_flags
);
3994 /* set bmac loopback */
3995 bnx2x_bmac_enable(params
, vars
, 1);
3997 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+
3999 } else if (params
->loopback_mode
== LOOPBACK_EMAC
) {
4001 vars
->line_speed
= SPEED_1000
;
4002 vars
->duplex
= DUPLEX_FULL
;
4003 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
4004 vars
->mac_type
= MAC_TYPE_EMAC
;
4006 vars
->phy_flags
= PHY_XGXS_FLAG
;
4008 bnx2x_phy_deassert(params
, vars
->phy_flags
);
4009 /* set bmac loopback */
4010 bnx2x_emac_enable(params
, vars
, 1);
4011 bnx2x_emac_program(params
, vars
->line_speed
,
4013 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+
4015 } else if ((params
->loopback_mode
== LOOPBACK_XGXS_10
) ||
4016 (params
->loopback_mode
== LOOPBACK_EXT_PHY
)) {
4018 vars
->line_speed
= SPEED_10000
;
4019 vars
->duplex
= DUPLEX_FULL
;
4020 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
4022 vars
->phy_flags
= PHY_XGXS_FLAG
;
4025 NIG_REG_XGXS0_CTRL_PHY_ADDR
+
4027 params
->phy_addr
= (u8
)val
;
4029 bnx2x_phy_deassert(params
, vars
->phy_flags
);
4030 bnx2x_link_initialize(params
, vars
);
4032 vars
->mac_type
= MAC_TYPE_BMAC
;
4034 bnx2x_bmac_enable(params
, vars
, 0);
4036 if (params
->loopback_mode
== LOOPBACK_XGXS_10
) {
4037 /* set 10G XGXS loopback */
4038 bnx2x_set_xgxs_loopback(params
, vars
, 1);
4040 /* set external phy loopback */
4041 bnx2x_ext_phy_loopback(params
);
4043 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+
4049 bnx2x_phy_deassert(params
, vars
->phy_flags
);
4050 switch (params
->switch_cfg
) {
4052 vars
->phy_flags
|= PHY_SERDES_FLAG
;
4053 if ((params
->ext_phy_config
&
4054 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK
) ==
4055 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482
) {
4061 NIG_REG_SERDES0_CTRL_PHY_ADDR
+
4064 params
->phy_addr
= (u8
)val
;
4067 case SWITCH_CFG_10G
:
4068 vars
->phy_flags
|= PHY_XGXS_FLAG
;
4070 NIG_REG_XGXS0_CTRL_PHY_ADDR
+
4072 params
->phy_addr
= (u8
)val
;
4076 DP(NETIF_MSG_LINK
, "Invalid switch_cfg\n");
4081 bnx2x_link_initialize(params
, vars
);
4083 bnx2x_link_int_enable(params
);
4088 u8
bnx2x_link_reset(struct link_params
*params
, struct link_vars
*vars
)
4091 struct bnx2x
*bp
= params
->bp
;
4092 u32 ext_phy_config
= params
->ext_phy_config
;
4093 u16 hw_led_mode
= params
->hw_led_mode
;
4094 u32 chip_id
= params
->chip_id
;
4095 u8 port
= params
->port
;
4096 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(ext_phy_config
);
4097 /* disable attentions */
4099 vars
->link_status
= 0;
4100 bnx2x_update_mng(params
, vars
->link_status
);
4101 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4,
4102 (NIG_MASK_XGXS0_LINK_STATUS
|
4103 NIG_MASK_XGXS0_LINK10G
|
4104 NIG_MASK_SERDES0_LINK_STATUS
|
4107 /* activate nig drain */
4108 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ port
*4, 1);
4110 /* disable nig egress interface */
4111 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0);
4112 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0);
4114 /* Stop BigMac rx */
4115 bnx2x_bmac_rx_disable(bp
, port
);
4118 REG_WR(bp
, NIG_REG_NIG_EMAC0_EN
+ port
*4, 0);
4121 /* The PHY reset is controled by GPIO 1
4122 * Hold it as vars low
4124 /* clear link led */
4125 bnx2x_set_led(bp
, port
, LED_MODE_OFF
, 0, hw_led_mode
, chip_id
);
4126 if (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) {
4127 if ((ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
) &&
4128 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
)) {
4131 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
4132 MISC_REGISTERS_GPIO_OUTPUT_LOW
,
4135 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
4136 MISC_REGISTERS_GPIO_OUTPUT_LOW
,
4139 DP(NETIF_MSG_LINK
, "reset external PHY\n");
4140 } else if (ext_phy_type
==
4141 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
4142 DP(NETIF_MSG_LINK
, "Setting 8073 port %d into "
4145 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
4146 MISC_REGISTERS_GPIO_OUTPUT_LOW
,
4150 /* reset the SerDes/XGXS */
4151 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_CLEAR
,
4152 (0x1ff << (port
*16)));
4155 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
4156 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
4158 /* disable nig ingress interface */
4159 REG_WR(bp
, NIG_REG_BMAC0_IN_EN
+ port
*4, 0);
4160 REG_WR(bp
, NIG_REG_EMAC0_IN_EN
+ port
*4, 0);
4161 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0);
4162 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0);
4167 static u8
bnx2x_update_link_down(struct link_params
*params
,
4168 struct link_vars
*vars
)
4170 struct bnx2x
*bp
= params
->bp
;
4171 u8 port
= params
->port
;
4172 DP(NETIF_MSG_LINK
, "Port %x: Link is down\n", port
);
4173 bnx2x_set_led(bp
, port
, LED_MODE_OFF
,
4174 0, params
->hw_led_mode
,
4177 /* indicate no mac active */
4178 vars
->mac_type
= MAC_TYPE_NONE
;
4180 /* update shared memory */
4181 vars
->link_status
= 0;
4182 vars
->line_speed
= 0;
4183 bnx2x_update_mng(params
, vars
->link_status
);
4185 /* activate nig drain */
4186 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ port
*4, 1);
4189 bnx2x_bmac_rx_disable(bp
, params
->port
);
4190 REG_WR(bp
, GRCBASE_MISC
+
4191 MISC_REGISTERS_RESET_REG_2_CLEAR
,
4192 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
4196 static u8
bnx2x_update_link_up(struct link_params
*params
,
4197 struct link_vars
*vars
,
4198 u8 link_10g
, u32 gp_status
)
4200 struct bnx2x
*bp
= params
->bp
;
4201 u8 port
= params
->port
;
4203 vars
->link_status
|= LINK_STATUS_LINK_UP
;
4205 bnx2x_bmac_enable(params
, vars
, 0);
4206 bnx2x_set_led(bp
, port
, LED_MODE_OPER
,
4207 SPEED_10000
, params
->hw_led_mode
,
4211 bnx2x_emac_enable(params
, vars
, 0);
4212 rc
= bnx2x_emac_program(params
, vars
->line_speed
,
4216 if (gp_status
& MDIO_AN_CL73_OR_37_COMPLETE
) {
4217 if (!(vars
->phy_flags
&
4219 bnx2x_set_sgmii_tx_driver(params
);
4224 rc
|= bnx2x_pbf_update(params
, vars
->flow_ctrl
,
4228 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ port
*4, 0);
4230 /* update shared memory */
4231 bnx2x_update_mng(params
, vars
->link_status
);
4234 /* This function should called upon link interrupt */
4235 /* In case vars->link_up, driver needs to
4238 3. Update the shared memory
4242 1. Update shared memory
4247 u8
bnx2x_link_update(struct link_params
*params
, struct link_vars
*vars
)
4249 struct bnx2x
*bp
= params
->bp
;
4250 u8 port
= params
->port
;
4253 u8 ext_phy_link_up
, rc
= 0;
4256 DP(NETIF_MSG_LINK
, "port %x, XGXS?%x, int_status 0x%x\n",
4258 (vars
->phy_flags
& PHY_XGXS_FLAG
),
4259 REG_RD(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4));
4261 DP(NETIF_MSG_LINK
, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4262 REG_RD(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4),
4263 REG_RD(bp
, NIG_REG_EMAC0_STATUS_MISC_MI_INT
+ port
*0x18),
4264 REG_RD(bp
, NIG_REG_SERDES0_STATUS_LINK_STATUS
+ port
*0x3c));
4266 DP(NETIF_MSG_LINK
, " 10G %x, XGXS_LINK %x\n",
4267 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK10G
+ port
*0x68),
4268 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK_STATUS
+ port
*0x68));
4270 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
4272 /* Check external link change only for non-direct */
4273 ext_phy_link_up
= bnx2x_ext_phy_is_link_up(params
, vars
);
4275 /* Read gp_status */
4276 CL45_RD_OVER_CL22(bp
, port
, params
->phy_addr
,
4277 MDIO_REG_BANK_GP_STATUS
,
4278 MDIO_GP_STATUS_TOP_AN_STATUS1
,
4281 rc
= bnx2x_link_settings_status(params
, vars
, gp_status
);
4285 /* anything 10 and over uses the bmac */
4286 link_10g
= ((vars
->line_speed
== SPEED_10000
) ||
4287 (vars
->line_speed
== SPEED_12000
) ||
4288 (vars
->line_speed
== SPEED_12500
) ||
4289 (vars
->line_speed
== SPEED_13000
) ||
4290 (vars
->line_speed
== SPEED_15000
) ||
4291 (vars
->line_speed
== SPEED_16000
));
4293 bnx2x_link_int_ack(params
, vars
, link_10g
);
4295 /* In case external phy link is up, and internal link is down
4296 ( not initialized yet probably after link initialization, it needs
4298 Note that after link down-up as result of cable plug,
4299 the xgxs link would probably become up again without the need to
4302 if ((ext_phy_type
!= PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
) &&
4303 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
) &&
4304 (ext_phy_link_up
&& !vars
->phy_link_up
))
4305 bnx2x_init_internal_phy(params
, vars
);
4307 /* link is up only if both local phy and external phy are up */
4308 vars
->link_up
= (ext_phy_link_up
&& vars
->phy_link_up
);
4311 rc
= bnx2x_update_link_up(params
, vars
, link_10g
, gp_status
);
4313 rc
= bnx2x_update_link_down(params
, vars
);
4318 static u8
bnx2x_8073_common_init_phy(struct bnx2x
*bp
, u32 shmem_base
)
4320 u8 ext_phy_addr
[PORT_MAX
];
4324 /* PART1 - Reset both phys */
4325 for (port
= PORT_MAX
- 1; port
>= PORT_0
; port
--) {
4326 /* Extract the ext phy address for the port */
4327 u32 ext_phy_config
= REG_RD(bp
, shmem_base
+
4328 offsetof(struct shmem_region
,
4329 dev_info
.port_hw_config
[port
].external_phy_config
));
4331 /* disable attentions */
4332 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4,
4333 (NIG_MASK_XGXS0_LINK_STATUS
|
4334 NIG_MASK_XGXS0_LINK10G
|
4335 NIG_MASK_SERDES0_LINK_STATUS
|
4338 ext_phy_addr
[port
] =
4340 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
4341 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
4343 /* Need to take the phy out of low power mode in order
4344 to write to access its registers */
4345 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
4346 MISC_REGISTERS_GPIO_OUTPUT_HIGH
, port
);
4349 bnx2x_cl45_write(bp
, port
,
4350 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4357 /* Add delay of 150ms after reset */
4360 /* PART2 - Download firmware to both phys */
4361 for (port
= PORT_MAX
- 1; port
>= PORT_0
; port
--) {
4364 bnx2x_bcm8073_external_rom_boot(bp
, port
,
4365 ext_phy_addr
[port
]);
4367 bnx2x_cl45_read(bp
, port
, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4370 MDIO_PMA_REG_ROM_VER1
, &fw_ver1
);
4373 "bnx2x_8073_common_init_phy port %x "
4374 "fw Download failed\n", port
);
4378 /* Only set bit 10 = 1 (Tx power down) */
4379 bnx2x_cl45_read(bp
, port
,
4380 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4383 MDIO_PMA_REG_TX_POWER_DOWN
, &val
);
4385 /* Phase1 of TX_POWER_DOWN reset */
4386 bnx2x_cl45_write(bp
, port
,
4387 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4390 MDIO_PMA_REG_TX_POWER_DOWN
,
4394 /* Toggle Transmitter: Power down and then up with 600ms
4398 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
4399 for (port
= PORT_MAX
- 1; port
>= PORT_0
; port
--) {
4400 /* Phase2 of POWER_DOWN_RESET*/
4401 /* Release bit 10 (Release Tx power down) */
4402 bnx2x_cl45_read(bp
, port
,
4403 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4406 MDIO_PMA_REG_TX_POWER_DOWN
, &val
);
4408 bnx2x_cl45_write(bp
, port
,
4409 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4412 MDIO_PMA_REG_TX_POWER_DOWN
, (val
& (~(1<<10))));
4415 /* Read modify write the SPI-ROM version select register */
4416 bnx2x_cl45_read(bp
, port
,
4417 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4420 MDIO_PMA_REG_EDC_FFE_MAIN
, &val
);
4421 bnx2x_cl45_write(bp
, port
,
4422 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4425 MDIO_PMA_REG_EDC_FFE_MAIN
, (val
| (1<<12)));
4427 /* set GPIO2 back to LOW */
4428 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
4429 MISC_REGISTERS_GPIO_OUTPUT_LOW
, port
);
4435 u8
bnx2x_common_init_phy(struct bnx2x
*bp
, u32 shmem_base
)
4440 DP(NETIF_MSG_LINK
, "bnx2x_common_init_phy\n");
4442 /* Read the ext_phy_type for arbitrary port(0) */
4443 ext_phy_type
= XGXS_EXT_PHY_TYPE(
4444 REG_RD(bp
, shmem_base
+
4445 offsetof(struct shmem_region
,
4446 dev_info
.port_hw_config
[0].external_phy_config
)));
4448 switch (ext_phy_type
) {
4449 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
4451 rc
= bnx2x_8073_common_init_phy(bp
, shmem_base
);
4456 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
4466 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x
*bp
, u8 port
, u8 phy_addr
)
4470 bnx2x_cl45_read(bp
, port
,
4471 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4474 MDIO_PMA_REG_7101_RESET
, &val
);
4476 for (cnt
= 0; cnt
< 10; cnt
++) {
4478 /* Writes a self-clearing reset */
4479 bnx2x_cl45_write(bp
, port
,
4480 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4483 MDIO_PMA_REG_7101_RESET
,
4485 /* Wait for clear */
4486 bnx2x_cl45_read(bp
, port
,
4487 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4490 MDIO_PMA_REG_7101_RESET
, &val
);
4492 if ((val
& (1<<15)) == 0)
4496 #define RESERVED_SIZE 256
4497 /* max application is 160K bytes - data at end of RAM */
4498 #define MAX_APP_SIZE 160*1024 - RESERVED_SIZE
4500 /* Header is 14 bytes */
4501 #define HEADER_SIZE 14
4502 #define DATA_OFFSET HEADER_SIZE
4504 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
4505 bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
4508 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
4510 /* Programs an image to DSP's flash via the SPI port*/
4511 static u8
bnx2x_sfx7101_flash_download(struct bnx2x
*bp
, u8 port
,
4513 char data
[], u32 size
)
4515 const u16 num_trans
= size
/4; /* 4 bytes can be sent at a time */
4516 /* Doesn't include last trans!*/
4517 const u16 last_trans_size
= size
%4; /* Num bytes on last trans */
4518 u16 trans_cnt
, byte_cnt
;
4521 u16 code_started
= 0;
4522 u16 image_revision1
, image_revision2
;
4525 DP(NETIF_MSG_LINK
, "bnx2x_sfx7101_flash_download file_size=%d\n", size
);
4527 if ((size
-HEADER_SIZE
) > MAX_APP_SIZE
) {
4528 /* This very often will be the case, because the image is built
4529 with 160Kbytes size whereas the total image size must actually
4530 be 160Kbytes-RESERVED_SIZE */
4531 DP(NETIF_MSG_LINK
, "Warning, file size was %d bytes "
4532 "truncated to %d bytes\n", size
, MAX_APP_SIZE
);
4533 size
= MAX_APP_SIZE
+HEADER_SIZE
;
4535 DP(NETIF_MSG_LINK
, "File version is %c%c\n", data
[0x14e], data
[0x14f]);
4536 DP(NETIF_MSG_LINK
, " %c%c\n", data
[0x150], data
[0x151]);
4537 /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
4538 and issuing a reset.*/
4540 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_0
,
4541 MISC_REGISTERS_GPIO_HIGH
, port
);
4543 bnx2x_sfx7101_sp_sw_reset(bp
, port
, ext_phy_addr
);
4546 for (cnt
= 0; cnt
< 100; cnt
++)
4549 /* Make sure we can access the DSP
4550 And it's in the correct mode (waiting for download) */
4552 bnx2x_cl45_read(bp
, port
,
4553 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4556 MDIO_PCS_REG_7101_DSP_ACCESS
, &tmp
);
4558 if (tmp
!= 0x000A) {
4559 DP(NETIF_MSG_LINK
, "DSP is not in waiting on download mode. "
4560 "Expected 0x000A, read 0x%04X\n", tmp
);
4561 DP(NETIF_MSG_LINK
, "Download failed\n");
4565 /* Mux the SPI interface away from the internal processor */
4566 bnx2x_cl45_write(bp
, port
,
4567 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4570 MDIO_PCS_REG_7101_SPI_MUX
, 1);
4572 /* Reset the SPI port */
4573 bnx2x_cl45_write(bp
, port
,
4574 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4577 MDIO_PCS_REG_7101_SPI_CTRL_ADDR
, 0);
4578 bnx2x_cl45_write(bp
, port
,
4579 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4582 MDIO_PCS_REG_7101_SPI_CTRL_ADDR
,
4583 (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT
));
4584 bnx2x_cl45_write(bp
, port
,
4585 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4588 MDIO_PCS_REG_7101_SPI_CTRL_ADDR
, 0);
4590 /* Erase the flash */
4591 bnx2x_cl45_write(bp
, port
,
4592 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4595 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4596 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD
);
4598 bnx2x_cl45_write(bp
, port
,
4599 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4602 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4605 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4606 bnx2x_cl45_write(bp
, port
,
4607 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4610 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4611 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD
);
4613 bnx2x_cl45_write(bp
, port
,
4614 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4617 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4619 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4621 /* Wait 10 seconds, the maximum time for the erase to complete */
4622 DP(NETIF_MSG_LINK
, "Erasing flash, this takes 10 seconds...\n");
4623 for (cnt
= 0; cnt
< 1000; cnt
++)
4626 DP(NETIF_MSG_LINK
, "Downloading flash, please wait...\n");
4628 for (trans_cnt
= 0; trans_cnt
< num_trans
; trans_cnt
++) {
4629 bnx2x_cl45_write(bp
, port
,
4630 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4633 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4634 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD
);
4636 bnx2x_cl45_write(bp
, port
,
4637 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4640 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4642 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4644 bnx2x_cl45_write(bp
, port
,
4645 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4648 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4649 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD
);
4651 /* Bits 23-16 of address */
4652 bnx2x_cl45_write(bp
, port
,
4653 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4656 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4658 /* Bits 15-8 of address */
4659 bnx2x_cl45_write(bp
, port
,
4660 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4663 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4666 /* Bits 7-0 of address */
4667 bnx2x_cl45_write(bp
, port
,
4668 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4671 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4675 while (byte_cnt
< 4 && data_index
< size
) {
4676 bnx2x_cl45_write(bp
, port
,
4677 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4680 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4681 data
[data_index
++]);
4685 bnx2x_cl45_write(bp
, port
,
4686 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4689 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4692 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4693 msleep(5); /* Wait 5 ms minimum between transs */
4695 /* Let the user know something's going on.*/
4696 /* a pacifier ever 4K */
4697 if ((data_index
% 1023) == 0)
4698 DP(NETIF_MSG_LINK
, "Download %d%%\n", data_index
/size
);
4701 DP(NETIF_MSG_LINK
, "\n");
4702 /* Transfer the last block if there is data remaining */
4703 if (last_trans_size
) {
4704 bnx2x_cl45_write(bp
, port
,
4705 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4708 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4709 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD
);
4711 bnx2x_cl45_write(bp
, port
,
4712 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4715 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4718 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4720 bnx2x_cl45_write(bp
, port
,
4721 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4724 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4725 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD
);
4727 /* Bits 23-16 of address */
4728 bnx2x_cl45_write(bp
, port
,
4729 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4732 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4734 /* Bits 15-8 of address */
4735 bnx2x_cl45_write(bp
, port
,
4736 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4739 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4742 /* Bits 7-0 of address */
4743 bnx2x_cl45_write(bp
, port
,
4744 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4747 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4751 while (byte_cnt
< last_trans_size
&& data_index
< size
) {
4752 /* Bits 7-0 of address */
4753 bnx2x_cl45_write(bp
, port
,
4754 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4757 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4758 data
[data_index
++]);
4762 bnx2x_cl45_write(bp
, port
,
4763 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4766 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4769 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4772 /* DSP Remove Download Mode */
4773 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_0
,
4774 MISC_REGISTERS_GPIO_LOW
, port
);
4776 bnx2x_sfx7101_sp_sw_reset(bp
, port
, ext_phy_addr
);
4778 /* wait 0.5 sec to allow it to run */
4779 for (cnt
= 0; cnt
< 100; cnt
++)
4782 bnx2x_hw_reset(bp
, port
);
4784 for (cnt
= 0; cnt
< 100; cnt
++)
4787 /* Check that the code is started. In case the download
4788 checksum failed, the code won't be started. */
4789 bnx2x_cl45_read(bp
, port
,
4790 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4793 MDIO_PCS_REG_7101_DSP_ACCESS
,
4796 code_started
= (tmp
& (1<<4));
4797 if (!code_started
) {
4798 DP(NETIF_MSG_LINK
, "Download failed. Please check file.\n");
4802 /* Verify that the file revision is now equal to the image
4803 revision within the DSP */
4804 bnx2x_cl45_read(bp
, port
,
4805 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4808 MDIO_PMA_REG_7101_VER1
,
4811 bnx2x_cl45_read(bp
, port
,
4812 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4815 MDIO_PMA_REG_7101_VER2
,
4818 if (data
[0x14e] != (image_revision2
&0xFF) ||
4819 data
[0x14f] != ((image_revision2
&0xFF00)>>8) ||
4820 data
[0x150] != (image_revision1
&0xFF) ||
4821 data
[0x151] != ((image_revision1
&0xFF00)>>8)) {
4822 DP(NETIF_MSG_LINK
, "Download failed.\n");
4825 DP(NETIF_MSG_LINK
, "Download %d%%\n", data_index
/size
);
4829 u8
bnx2x_flash_download(struct bnx2x
*bp
, u8 port
, u32 ext_phy_config
,
4830 u8 driver_loaded
, char data
[], u32 size
)
4835 ext_phy_addr
= ((ext_phy_config
&
4836 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
4837 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
4839 ext_phy_type
= XGXS_EXT_PHY_TYPE(ext_phy_config
);
4841 switch (ext_phy_type
) {
4842 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
4843 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
4844 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
4845 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
4847 "Flash download not supported for this ext phy\n");
4850 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
4851 /* Take ext phy out of reset */
4853 bnx2x_turn_on_ef(bp
, port
, ext_phy_addr
, ext_phy_type
);
4854 rc
= bnx2x_sfx7101_flash_download(bp
, port
, ext_phy_addr
,
4857 bnx2x_turn_off_sf(bp
, port
);
4859 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
4860 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
4861 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
:
4863 DP(NETIF_MSG_LINK
, "Invalid ext phy type\n");