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
41 #define MAX_MTU_SIZE 5000
43 /***********************************************************/
44 /* Shortcut definitions */
45 /***********************************************************/
47 #define NIG_STATUS_XGXS0_LINK10G \
48 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
49 #define NIG_STATUS_XGXS0_LINK_STATUS \
50 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
51 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
52 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
53 #define NIG_STATUS_SERDES0_LINK_STATUS \
54 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
55 #define NIG_MASK_MI_INT \
56 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
57 #define NIG_MASK_XGXS0_LINK10G \
58 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
59 #define NIG_MASK_XGXS0_LINK_STATUS \
60 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
61 #define NIG_MASK_SERDES0_LINK_STATUS \
62 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
64 #define MDIO_AN_CL73_OR_37_COMPLETE \
65 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
66 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
68 #define XGXS_RESET_BITS \
69 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
70 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
71 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
72 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
73 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
75 #define SERDES_RESET_BITS \
76 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
77 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
78 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
79 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
81 #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
82 #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
83 #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
84 #define AUTONEG_PARALLEL \
85 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
86 #define AUTONEG_SGMII_FIBER_AUTODET \
87 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
88 #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
90 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
91 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
92 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
93 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
94 #define GP_STATUS_SPEED_MASK \
95 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
96 #define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
97 #define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
98 #define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
99 #define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
100 #define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
101 #define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
102 #define GP_STATUS_10G_HIG \
103 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
104 #define GP_STATUS_10G_CX4 \
105 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
106 #define GP_STATUS_12G_HIG \
107 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
108 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
109 #define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
110 #define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
111 #define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
112 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
113 #define GP_STATUS_10G_KX4 \
114 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
116 #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
117 #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
118 #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
119 #define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
120 #define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
121 #define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
122 #define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
123 #define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
124 #define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
125 #define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
126 #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
127 #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
128 #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
129 #define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
130 #define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
131 #define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
132 #define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
133 #define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
134 #define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
135 #define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
136 #define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
137 #define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
138 #define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
140 #define PHY_XGXS_FLAG 0x1
141 #define PHY_SGMII_FLAG 0x2
142 #define PHY_SERDES_FLAG 0x4
144 /**********************************************************/
146 /**********************************************************/
147 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
148 bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
149 DEFAULT_PHY_DEV_ADDR, \
150 (_bank + (_addr & 0xf)), \
153 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
154 bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
155 DEFAULT_PHY_DEV_ADDR, \
156 (_bank + (_addr & 0xf)), \
159 static void bnx2x_set_phy_mdio(struct link_params
*params
)
161 struct bnx2x
*bp
= params
->bp
;
162 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_ST
+
163 params
->port
*0x18, 0);
164 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_DEVAD
+ params
->port
*0x18,
165 DEFAULT_PHY_DEV_ADDR
);
168 static u32
bnx2x_bits_en(struct bnx2x
*bp
, u32 reg
, u32 bits
)
170 u32 val
= REG_RD(bp
, reg
);
173 REG_WR(bp
, reg
, val
);
177 static u32
bnx2x_bits_dis(struct bnx2x
*bp
, u32 reg
, u32 bits
)
179 u32 val
= REG_RD(bp
, reg
);
182 REG_WR(bp
, reg
, val
);
186 static void bnx2x_emac_init(struct link_params
*params
,
187 struct link_vars
*vars
)
189 /* reset and unreset the emac core */
190 struct bnx2x
*bp
= params
->bp
;
191 u8 port
= params
->port
;
192 u32 emac_base
= port
? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
196 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
197 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE
<< port
));
199 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
200 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE
<< port
));
202 /* init emac - use read-modify-write */
203 /* self clear reset */
204 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
205 EMAC_WR(EMAC_REG_EMAC_MODE
, (val
| EMAC_MODE_RESET
));
210 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
211 DP(NETIF_MSG_LINK
, "EMAC reset reg is %u\n", val
);
213 DP(NETIF_MSG_LINK
, "EMAC timeout!\n");
217 }while (val
& EMAC_MODE_RESET
);
219 /* Set mac address */
220 val
= ((params
->mac_addr
[0] << 8) |
221 params
->mac_addr
[1]);
222 EMAC_WR(EMAC_REG_EMAC_MAC_MATCH
, val
);
224 val
= ((params
->mac_addr
[2] << 24) |
225 (params
->mac_addr
[3] << 16) |
226 (params
->mac_addr
[4] << 8) |
227 params
->mac_addr
[5]);
228 EMAC_WR(EMAC_REG_EMAC_MAC_MATCH
+ 4, val
);
231 static u8
bnx2x_emac_enable(struct link_params
*params
,
232 struct link_vars
*vars
, u8 lb
)
234 struct bnx2x
*bp
= params
->bp
;
235 u8 port
= params
->port
;
236 u32 emac_base
= port
? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
239 DP(NETIF_MSG_LINK
, "enabling EMAC\n");
241 /* enable emac and not bmac */
242 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_PORT
+ port
*4, 1);
245 if (CHIP_REV_IS_EMUL(bp
)) {
246 /* Use lane 1 (of lanes 0-3) */
247 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+ port
*4, 1);
248 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+
254 if (CHIP_REV_IS_FPGA(bp
)) {
255 /* Use lane 1 (of lanes 0-3) */
256 DP(NETIF_MSG_LINK
, "bnx2x_emac_enable: Setting FPGA\n");
258 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+ port
*4, 1);
259 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+ port
*4,
263 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
264 u32 ser_lane
= ((params
->lane_config
&
265 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
266 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
268 DP(NETIF_MSG_LINK
, "XGXS\n");
269 /* select the master lanes (out of 0-3) */
270 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+
273 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+
276 } else { /* SerDes */
277 DP(NETIF_MSG_LINK
, "SerDes\n");
279 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+
284 REG_WR(bp
, NIG_REG_NIG_EMAC0_EN
+ port
*4, 1);
286 if (CHIP_REV_IS_SLOW(bp
)) {
287 /* config GMII mode */
288 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
289 EMAC_WR(EMAC_REG_EMAC_MODE
,
290 (val
| EMAC_MODE_PORT_GMII
));
292 /* pause enable/disable */
293 bnx2x_bits_dis(bp
, emac_base
+ EMAC_REG_EMAC_RX_MODE
,
294 EMAC_RX_MODE_FLOW_EN
);
295 if (vars
->flow_ctrl
& FLOW_CTRL_RX
)
296 bnx2x_bits_en(bp
, emac_base
+
297 EMAC_REG_EMAC_RX_MODE
,
298 EMAC_RX_MODE_FLOW_EN
);
300 bnx2x_bits_dis(bp
, emac_base
+ EMAC_REG_EMAC_TX_MODE
,
301 EMAC_TX_MODE_EXT_PAUSE_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
);
308 /* KEEP_VLAN_TAG, promiscuous */
309 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_RX_MODE
);
310 val
|= EMAC_RX_MODE_KEEP_VLAN_TAG
| EMAC_RX_MODE_PROMISCUOUS
;
311 EMAC_WR(EMAC_REG_EMAC_RX_MODE
, val
);
314 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
319 EMAC_WR(EMAC_REG_EMAC_MODE
, val
);
321 /* enable emac for jumbo packets */
322 EMAC_WR(EMAC_REG_EMAC_RX_MTU_SIZE
,
323 (EMAC_RX_MTU_SIZE_JUMBO_ENA
|
324 (ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
)));
327 REG_WR(bp
, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC
+ port
*4, 0x1);
329 /* disable the NIG in/out to the bmac */
330 REG_WR(bp
, NIG_REG_BMAC0_IN_EN
+ port
*4, 0x0);
331 REG_WR(bp
, NIG_REG_BMAC0_PAUSE_OUT_EN
+ port
*4, 0x0);
332 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0x0);
334 /* enable the NIG in/out to the emac */
335 REG_WR(bp
, NIG_REG_EMAC0_IN_EN
+ port
*4, 0x1);
337 if (vars
->flow_ctrl
& FLOW_CTRL_TX
)
340 REG_WR(bp
, NIG_REG_EMAC0_PAUSE_OUT_EN
+ port
*4, val
);
341 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0x1);
343 if (CHIP_REV_IS_EMUL(bp
)) {
344 /* take the BigMac out of reset */
346 GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
347 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
349 /* enable access for bmac registers */
350 REG_WR(bp
, NIG_REG_BMAC0_REGS_OUT_EN
+ port
*4, 0x1);
353 vars
->mac_type
= MAC_TYPE_EMAC
;
359 static u8
bnx2x_bmac_enable(struct link_params
*params
, struct link_vars
*vars
,
362 struct bnx2x
*bp
= params
->bp
;
363 u8 port
= params
->port
;
364 u32 bmac_addr
= port
? NIG_REG_INGRESS_BMAC1_MEM
:
365 NIG_REG_INGRESS_BMAC0_MEM
;
369 DP(NETIF_MSG_LINK
, "Enabling BigMAC\n");
370 /* reset and unreset the BigMac */
371 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
372 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
375 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
376 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
378 /* enable access for bmac registers */
379 REG_WR(bp
, NIG_REG_BMAC0_REGS_OUT_EN
+ port
*4, 0x1);
384 REG_WR_DMAE(bp
, bmac_addr
+
385 BIGMAC_REGISTER_BMAC_XGXS_CONTROL
,
389 wb_data
[0] = ((params
->mac_addr
[2] << 24) |
390 (params
->mac_addr
[3] << 16) |
391 (params
->mac_addr
[4] << 8) |
392 params
->mac_addr
[5]);
393 wb_data
[1] = ((params
->mac_addr
[0] << 8) |
394 params
->mac_addr
[1]);
395 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_TX_SOURCE_ADDR
,
400 if (vars
->flow_ctrl
& FLOW_CTRL_TX
)
404 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_TX_CONTROL
,
411 DP(NETIF_MSG_LINK
, "enable bmac loopback\n");
415 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_BMAC_CONTROL
,
420 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
422 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_RX_MAX_SIZE
,
425 /* rx control set to don't strip crc */
427 if (vars
->flow_ctrl
& FLOW_CTRL_RX
)
431 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_RX_CONTROL
,
435 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
437 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_TX_MAX_SIZE
,
440 /* set cnt max size */
441 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
443 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_CNT_MAX_SIZE
,
447 wb_data
[0] = 0x1000200;
449 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_RX_LLFC_MSG_FLDS
,
451 /* fix for emulation */
452 if (CHIP_REV_IS_EMUL(bp
)) {
456 bmac_addr
+ BIGMAC_REGISTER_TX_PAUSE_THRESHOLD
,
460 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+ port
*4, 0x1);
461 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+ port
*4, 0x0);
462 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_PORT
+ port
*4, 0x0);
464 if (vars
->flow_ctrl
& FLOW_CTRL_TX
)
466 REG_WR(bp
, NIG_REG_BMAC0_PAUSE_OUT_EN
+ port
*4, val
);
467 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0x0);
468 REG_WR(bp
, NIG_REG_EMAC0_IN_EN
+ port
*4, 0x0);
469 REG_WR(bp
, NIG_REG_EMAC0_PAUSE_OUT_EN
+ port
*4, 0x0);
470 REG_WR(bp
, NIG_REG_BMAC0_IN_EN
+ port
*4, 0x1);
471 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0x1);
473 vars
->mac_type
= MAC_TYPE_BMAC
;
477 static void bnx2x_phy_deassert(struct link_params
*params
, u8 phy_flags
)
479 struct bnx2x
*bp
= params
->bp
;
482 if (phy_flags
& PHY_XGXS_FLAG
) {
483 DP(NETIF_MSG_LINK
, "bnx2x_phy_deassert:XGXS\n");
484 val
= XGXS_RESET_BITS
;
486 } else { /* SerDes */
487 DP(NETIF_MSG_LINK
, "bnx2x_phy_deassert:SerDes\n");
488 val
= SERDES_RESET_BITS
;
491 val
= val
<< (params
->port
*16);
493 /* reset and unreset the SerDes/XGXS */
494 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_CLEAR
,
497 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_SET
,
499 bnx2x_set_phy_mdio(params
);
502 void bnx2x_link_status_update(struct link_params
*params
,
503 struct link_vars
*vars
)
505 struct bnx2x
*bp
= params
->bp
;
507 u8 port
= params
->port
;
509 if (params
->switch_cfg
== SWITCH_CFG_1G
)
510 vars
->phy_flags
= PHY_SERDES_FLAG
;
512 vars
->phy_flags
= PHY_XGXS_FLAG
;
513 vars
->link_status
= REG_RD(bp
, params
->shmem_base
+
514 offsetof(struct shmem_region
,
515 port_mb
[port
].link_status
));
517 vars
->link_up
= (vars
->link_status
& LINK_STATUS_LINK_UP
);
520 DP(NETIF_MSG_LINK
, "phy link up\n");
522 vars
->phy_link_up
= 1;
523 vars
->duplex
= DUPLEX_FULL
;
524 switch (vars
->link_status
&
525 LINK_STATUS_SPEED_AND_DUPLEX_MASK
) {
527 vars
->duplex
= DUPLEX_HALF
;
530 vars
->line_speed
= SPEED_10
;
534 vars
->duplex
= DUPLEX_HALF
;
538 vars
->line_speed
= SPEED_100
;
542 vars
->duplex
= DUPLEX_HALF
;
545 vars
->line_speed
= SPEED_1000
;
549 vars
->duplex
= DUPLEX_HALF
;
552 vars
->line_speed
= SPEED_2500
;
556 vars
->line_speed
= SPEED_10000
;
560 vars
->line_speed
= SPEED_12000
;
564 vars
->line_speed
= SPEED_12500
;
568 vars
->line_speed
= SPEED_13000
;
572 vars
->line_speed
= SPEED_15000
;
576 vars
->line_speed
= SPEED_16000
;
583 if (vars
->link_status
& LINK_STATUS_TX_FLOW_CONTROL_ENABLED
)
584 vars
->flow_ctrl
|= FLOW_CTRL_TX
;
586 vars
->flow_ctrl
&= ~FLOW_CTRL_TX
;
588 if (vars
->link_status
& LINK_STATUS_RX_FLOW_CONTROL_ENABLED
)
589 vars
->flow_ctrl
|= FLOW_CTRL_RX
;
591 vars
->flow_ctrl
&= ~FLOW_CTRL_RX
;
593 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
594 if (params
->req_line_speed
&&
595 ((params
->req_line_speed
== SPEED_10
) ||
596 (params
->req_line_speed
== SPEED_100
))) {
597 vars
->phy_flags
|= PHY_SGMII_FLAG
;
599 vars
->phy_flags
&= ~PHY_SGMII_FLAG
;
603 /* anything 10 and over uses the bmac */
604 link_10g
= ((vars
->line_speed
== SPEED_10000
) ||
605 (vars
->line_speed
== SPEED_12000
) ||
606 (vars
->line_speed
== SPEED_12500
) ||
607 (vars
->line_speed
== SPEED_13000
) ||
608 (vars
->line_speed
== SPEED_15000
) ||
609 (vars
->line_speed
== SPEED_16000
));
611 vars
->mac_type
= MAC_TYPE_BMAC
;
613 vars
->mac_type
= MAC_TYPE_EMAC
;
615 } else { /* link down */
616 DP(NETIF_MSG_LINK
, "phy link down\n");
618 vars
->phy_link_up
= 0;
620 vars
->line_speed
= 0;
621 vars
->duplex
= DUPLEX_FULL
;
622 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
624 /* indicate no mac active */
625 vars
->mac_type
= MAC_TYPE_NONE
;
628 DP(NETIF_MSG_LINK
, "link_status 0x%x phy_link_up %x\n",
629 vars
->link_status
, vars
->phy_link_up
);
630 DP(NETIF_MSG_LINK
, "line_speed %x duplex %x flow_ctrl 0x%x\n",
631 vars
->line_speed
, vars
->duplex
, vars
->flow_ctrl
);
634 static void bnx2x_update_mng(struct link_params
*params
, u32 link_status
)
636 struct bnx2x
*bp
= params
->bp
;
637 REG_WR(bp
, params
->shmem_base
+
638 offsetof(struct shmem_region
,
639 port_mb
[params
->port
].link_status
),
643 static void bnx2x_bmac_rx_disable(struct bnx2x
*bp
, u8 port
)
645 u32 bmac_addr
= port
? NIG_REG_INGRESS_BMAC1_MEM
:
646 NIG_REG_INGRESS_BMAC0_MEM
;
648 u32 nig_bmac_enable
= REG_RD(bp
, NIG_REG_BMAC0_REGS_OUT_EN
+ port
*4);
650 /* Only if the bmac is out of reset */
651 if (REG_RD(bp
, MISC_REG_RESET_REG_2
) &
652 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
) &&
655 /* Clear Rx Enable bit in BMAC_CONTROL register */
656 REG_RD_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_BMAC_CONTROL
,
658 wb_data
[0] &= ~BMAC_CONTROL_RX_ENABLE
;
659 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_BMAC_CONTROL
,
666 static u8
bnx2x_pbf_update(struct link_params
*params
, u32 flow_ctrl
,
669 struct bnx2x
*bp
= params
->bp
;
670 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
)
698 REG_WR(bp
, PBF_REG_P0_PAUSE_ENABLE
+ port
*4, pause
);
700 /* update threshold */
701 REG_WR(bp
, PBF_REG_P0_ARB_THRSH
+ port
*4, 0);
702 /* update init credit */
703 init_crd
= 778; /* (800-18-4) */
706 u32 thresh
= (ETH_MAX_JUMBO_PACKET_SIZE
+
709 /* update threshold */
710 REG_WR(bp
, PBF_REG_P0_ARB_THRSH
+ port
*4, thresh
);
711 /* update init credit */
712 switch (line_speed
) {
716 init_crd
= thresh
+ 55 - 22;
720 init_crd
= thresh
+ 138 - 22;
724 init_crd
= thresh
+ 553 - 22;
728 init_crd
= thresh
+ 664 - 22;
732 init_crd
= thresh
+ 742 - 22;
736 init_crd
= thresh
+ 778 - 22;
739 DP(NETIF_MSG_LINK
, "Invalid line_speed 0x%x\n",
745 REG_WR(bp
, PBF_REG_P0_INIT_CRD
+ port
*4, init_crd
);
746 DP(NETIF_MSG_LINK
, "PBF updated to speed %d credit %d\n",
747 line_speed
, init_crd
);
749 /* probe the credit changes */
750 REG_WR(bp
, PBF_REG_INIT_P0
+ port
*4, 0x1);
752 REG_WR(bp
, PBF_REG_INIT_P0
+ port
*4, 0x0);
755 REG_WR(bp
, PBF_REG_DISABLE_NEW_TASK_PROC_P0
+ port
*4, 0x0);
759 static u32
bnx2x_get_emac_base(u32 ext_phy_type
, u8 port
)
762 switch (ext_phy_type
) {
763 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
764 emac_base
= GRCBASE_EMAC0
;
766 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
767 emac_base
= (port
) ? GRCBASE_EMAC0
: GRCBASE_EMAC1
;
770 emac_base
= (port
) ? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
777 u8
bnx2x_cl45_write(struct bnx2x
*bp
, u8 port
, u32 ext_phy_type
,
778 u8 phy_addr
, u8 devad
, u16 reg
, u16 val
)
782 u32 mdio_ctrl
= bnx2x_get_emac_base(ext_phy_type
, port
);
784 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
785 * (a value of 49==0x31) and make sure that the AUTO poll is off
787 saved_mode
= REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
788 tmp
= saved_mode
& ~(EMAC_MDIO_MODE_AUTO_POLL
|
789 EMAC_MDIO_MODE_CLOCK_CNT
);
790 tmp
|= (EMAC_MDIO_MODE_CLAUSE_45
|
791 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT
));
792 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, tmp
);
793 REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
798 tmp
= ((phy_addr
<< 21) | (devad
<< 16) | reg
|
799 EMAC_MDIO_COMM_COMMAND_ADDRESS
|
800 EMAC_MDIO_COMM_START_BUSY
);
801 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, tmp
);
803 for (i
= 0; i
< 50; i
++) {
806 tmp
= REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
);
807 if (!(tmp
& EMAC_MDIO_COMM_START_BUSY
)) {
812 if (tmp
& EMAC_MDIO_COMM_START_BUSY
) {
813 DP(NETIF_MSG_LINK
, "write phy register failed\n");
817 tmp
= ((phy_addr
<< 21) | (devad
<< 16) | val
|
818 EMAC_MDIO_COMM_COMMAND_WRITE_45
|
819 EMAC_MDIO_COMM_START_BUSY
);
820 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, tmp
);
822 for (i
= 0; i
< 50; i
++) {
825 tmp
= REG_RD(bp
, mdio_ctrl
+
826 EMAC_REG_EMAC_MDIO_COMM
);
827 if (!(tmp
& EMAC_MDIO_COMM_START_BUSY
)) {
832 if (tmp
& EMAC_MDIO_COMM_START_BUSY
) {
833 DP(NETIF_MSG_LINK
, "write phy register failed\n");
838 /* Restore the saved mode */
839 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, saved_mode
);
844 u8
bnx2x_cl45_read(struct bnx2x
*bp
, u8 port
, u32 ext_phy_type
,
845 u8 phy_addr
, u8 devad
, u16 reg
, u16
*ret_val
)
851 u32 mdio_ctrl
= bnx2x_get_emac_base(ext_phy_type
, port
);
852 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
853 * (a value of 49==0x31) and make sure that the AUTO poll is off
855 saved_mode
= REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
856 val
= saved_mode
& ((EMAC_MDIO_MODE_AUTO_POLL
|
857 EMAC_MDIO_MODE_CLOCK_CNT
));
858 val
|= (EMAC_MDIO_MODE_CLAUSE_45
|
859 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT
));
860 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, val
);
861 REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
865 val
= ((phy_addr
<< 21) | (devad
<< 16) | reg
|
866 EMAC_MDIO_COMM_COMMAND_ADDRESS
|
867 EMAC_MDIO_COMM_START_BUSY
);
868 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, val
);
870 for (i
= 0; i
< 50; i
++) {
873 val
= REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
);
874 if (!(val
& EMAC_MDIO_COMM_START_BUSY
)) {
879 if (val
& EMAC_MDIO_COMM_START_BUSY
) {
880 DP(NETIF_MSG_LINK
, "read phy register failed\n");
887 val
= ((phy_addr
<< 21) | (devad
<< 16) |
888 EMAC_MDIO_COMM_COMMAND_READ_45
|
889 EMAC_MDIO_COMM_START_BUSY
);
890 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, val
);
892 for (i
= 0; i
< 50; i
++) {
895 val
= REG_RD(bp
, mdio_ctrl
+
896 EMAC_REG_EMAC_MDIO_COMM
);
897 if (!(val
& EMAC_MDIO_COMM_START_BUSY
)) {
898 *ret_val
= (u16
)(val
& EMAC_MDIO_COMM_DATA
);
902 if (val
& EMAC_MDIO_COMM_START_BUSY
) {
903 DP(NETIF_MSG_LINK
, "read phy register failed\n");
910 /* Restore the saved mode */
911 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, saved_mode
);
916 static void bnx2x_set_aer_mmd(struct link_params
*params
,
917 struct link_vars
*vars
)
919 struct bnx2x
*bp
= params
->bp
;
923 ser_lane
= ((params
->lane_config
&
924 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
925 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
927 offset
= (vars
->phy_flags
& PHY_XGXS_FLAG
) ?
928 (params
->phy_addr
+ ser_lane
) : 0;
930 CL45_WR_OVER_CL22(bp
, params
->port
,
932 MDIO_REG_BANK_AER_BLOCK
,
933 MDIO_AER_BLOCK_AER_REG
, 0x3800 + offset
);
936 static void bnx2x_set_master_ln(struct link_params
*params
)
938 struct bnx2x
*bp
= params
->bp
;
939 u16 new_master_ln
, ser_lane
;
940 ser_lane
= ((params
->lane_config
&
941 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
942 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
944 /* set the master_ln for AN */
945 CL45_RD_OVER_CL22(bp
, params
->port
,
947 MDIO_REG_BANK_XGXS_BLOCK2
,
948 MDIO_XGXS_BLOCK2_TEST_MODE_LANE
,
951 CL45_WR_OVER_CL22(bp
, params
->port
,
953 MDIO_REG_BANK_XGXS_BLOCK2
,
954 MDIO_XGXS_BLOCK2_TEST_MODE_LANE
,
955 (new_master_ln
| ser_lane
));
958 static u8
bnx2x_reset_unicore(struct link_params
*params
)
960 struct bnx2x
*bp
= params
->bp
;
964 CL45_RD_OVER_CL22(bp
, params
->port
,
966 MDIO_REG_BANK_COMBO_IEEE0
,
967 MDIO_COMBO_IEEE0_MII_CONTROL
, &mii_control
);
969 /* reset the unicore */
970 CL45_WR_OVER_CL22(bp
, params
->port
,
972 MDIO_REG_BANK_COMBO_IEEE0
,
973 MDIO_COMBO_IEEE0_MII_CONTROL
,
975 MDIO_COMBO_IEEO_MII_CONTROL_RESET
));
977 /* wait for the reset to self clear */
978 for (i
= 0; i
< MDIO_ACCESS_TIMEOUT
; i
++) {
981 /* the reset erased the previous bank value */
982 CL45_RD_OVER_CL22(bp
, params
->port
,
984 MDIO_REG_BANK_COMBO_IEEE0
,
985 MDIO_COMBO_IEEE0_MII_CONTROL
,
988 if (!(mii_control
& MDIO_COMBO_IEEO_MII_CONTROL_RESET
)) {
994 DP(NETIF_MSG_LINK
, "BUG! XGXS is still in reset!\n");
999 static void bnx2x_set_swap_lanes(struct link_params
*params
)
1001 struct bnx2x
*bp
= params
->bp
;
1002 /* Each two bits represents a lane number:
1003 No swap is 0123 => 0x1b no need to enable the swap */
1004 u16 ser_lane
, rx_lane_swap
, tx_lane_swap
;
1006 ser_lane
= ((params
->lane_config
&
1007 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
1008 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
1009 rx_lane_swap
= ((params
->lane_config
&
1010 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK
) >>
1011 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT
);
1012 tx_lane_swap
= ((params
->lane_config
&
1013 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK
) >>
1014 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT
);
1016 if (rx_lane_swap
!= 0x1b) {
1017 CL45_WR_OVER_CL22(bp
, params
->port
,
1019 MDIO_REG_BANK_XGXS_BLOCK2
,
1020 MDIO_XGXS_BLOCK2_RX_LN_SWAP
,
1022 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE
|
1023 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE
));
1025 CL45_WR_OVER_CL22(bp
, params
->port
,
1027 MDIO_REG_BANK_XGXS_BLOCK2
,
1028 MDIO_XGXS_BLOCK2_RX_LN_SWAP
, 0);
1031 if (tx_lane_swap
!= 0x1b) {
1032 CL45_WR_OVER_CL22(bp
, params
->port
,
1034 MDIO_REG_BANK_XGXS_BLOCK2
,
1035 MDIO_XGXS_BLOCK2_TX_LN_SWAP
,
1037 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE
));
1039 CL45_WR_OVER_CL22(bp
, params
->port
,
1041 MDIO_REG_BANK_XGXS_BLOCK2
,
1042 MDIO_XGXS_BLOCK2_TX_LN_SWAP
, 0);
1046 static void bnx2x_set_parallel_detection(struct link_params
*params
,
1049 struct bnx2x
*bp
= params
->bp
;
1052 CL45_RD_OVER_CL22(bp
, params
->port
,
1054 MDIO_REG_BANK_SERDES_DIGITAL
,
1055 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2
,
1059 control2
|= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN
;
1062 CL45_WR_OVER_CL22(bp
, params
->port
,
1064 MDIO_REG_BANK_SERDES_DIGITAL
,
1065 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2
,
1068 if (phy_flags
& PHY_XGXS_FLAG
) {
1069 DP(NETIF_MSG_LINK
, "XGXS\n");
1071 CL45_WR_OVER_CL22(bp
, params
->port
,
1073 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
1074 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK
,
1075 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT
);
1077 CL45_RD_OVER_CL22(bp
, params
->port
,
1079 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
1080 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL
,
1085 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN
;
1087 CL45_WR_OVER_CL22(bp
, params
->port
,
1089 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
1090 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL
,
1093 /* Disable parallel detection of HiG */
1094 CL45_WR_OVER_CL22(bp
, params
->port
,
1096 MDIO_REG_BANK_XGXS_BLOCK2
,
1097 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G
,
1098 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS
|
1099 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS
);
1103 static void bnx2x_set_autoneg(struct link_params
*params
,
1104 struct link_vars
*vars
)
1106 struct bnx2x
*bp
= params
->bp
;
1111 CL45_RD_OVER_CL22(bp
, params
->port
,
1113 MDIO_REG_BANK_COMBO_IEEE0
,
1114 MDIO_COMBO_IEEE0_MII_CONTROL
, ®_val
);
1116 /* CL37 Autoneg Enabled */
1117 if (params
->req_line_speed
== SPEED_AUTO_NEG
)
1118 reg_val
|= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
;
1119 else /* CL37 Autoneg Disabled */
1120 reg_val
&= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
|
1121 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN
);
1123 CL45_WR_OVER_CL22(bp
, params
->port
,
1125 MDIO_REG_BANK_COMBO_IEEE0
,
1126 MDIO_COMBO_IEEE0_MII_CONTROL
, reg_val
);
1128 /* Enable/Disable Autodetection */
1130 CL45_RD_OVER_CL22(bp
, params
->port
,
1132 MDIO_REG_BANK_SERDES_DIGITAL
,
1133 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
, ®_val
);
1134 reg_val
&= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN
;
1135 if (params
->req_line_speed
== SPEED_AUTO_NEG
)
1136 reg_val
|= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET
;
1138 reg_val
&= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET
;
1140 CL45_WR_OVER_CL22(bp
, params
->port
,
1142 MDIO_REG_BANK_SERDES_DIGITAL
,
1143 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
, reg_val
);
1145 /* Enable TetonII and BAM autoneg */
1146 CL45_RD_OVER_CL22(bp
, params
->port
,
1148 MDIO_REG_BANK_BAM_NEXT_PAGE
,
1149 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL
,
1151 if (params
->req_line_speed
== SPEED_AUTO_NEG
) {
1152 /* Enable BAM aneg Mode and TetonII aneg Mode */
1153 reg_val
|= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE
|
1154 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN
);
1156 /* TetonII and BAM Autoneg Disabled */
1157 reg_val
&= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE
|
1158 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN
);
1160 CL45_WR_OVER_CL22(bp
, params
->port
,
1162 MDIO_REG_BANK_BAM_NEXT_PAGE
,
1163 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL
,
1166 /* Enable Clause 73 Aneg */
1167 if ((params
->req_line_speed
== SPEED_AUTO_NEG
) &&
1169 /* Enable BAM Station Manager */
1171 CL45_WR_OVER_CL22(bp
, params
->port
,
1173 MDIO_REG_BANK_CL73_USERB0
,
1174 MDIO_CL73_USERB0_CL73_BAM_CTRL1
,
1175 (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN
|
1176 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN
|
1177 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN
));
1179 /* Merge CL73 and CL37 aneg resolution */
1180 CL45_RD_OVER_CL22(bp
, params
->port
,
1182 MDIO_REG_BANK_CL73_USERB0
,
1183 MDIO_CL73_USERB0_CL73_BAM_CTRL3
,
1186 CL45_WR_OVER_CL22(bp
, params
->port
,
1188 MDIO_REG_BANK_CL73_USERB0
,
1189 MDIO_CL73_USERB0_CL73_BAM_CTRL3
,
1191 MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR
));
1193 /* Set the CL73 AN speed */
1195 CL45_RD_OVER_CL22(bp
, params
->port
,
1197 MDIO_REG_BANK_CL73_IEEEB1
,
1198 MDIO_CL73_IEEEB1_AN_ADV2
, ®_val
);
1199 /* In the SerDes we support only the 1G.
1200 In the XGXS we support the 10G KX4
1201 but we currently do not support the KR */
1202 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
1203 DP(NETIF_MSG_LINK
, "XGXS\n");
1205 reg_val
|= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4
;
1207 DP(NETIF_MSG_LINK
, "SerDes\n");
1209 reg_val
|= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX
;
1211 CL45_WR_OVER_CL22(bp
, params
->port
,
1213 MDIO_REG_BANK_CL73_IEEEB1
,
1214 MDIO_CL73_IEEEB1_AN_ADV2
, reg_val
);
1216 /* CL73 Autoneg Enabled */
1217 reg_val
= MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN
;
1219 /* CL73 Autoneg Disabled */
1222 CL45_WR_OVER_CL22(bp
, params
->port
,
1224 MDIO_REG_BANK_CL73_IEEEB0
,
1225 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
, reg_val
);
1228 /* program SerDes, forced speed */
1229 static void bnx2x_program_serdes(struct link_params
*params
)
1231 struct bnx2x
*bp
= params
->bp
;
1234 /* program duplex, disable autoneg */
1236 CL45_RD_OVER_CL22(bp
, params
->port
,
1238 MDIO_REG_BANK_COMBO_IEEE0
,
1239 MDIO_COMBO_IEEE0_MII_CONTROL
, ®_val
);
1240 reg_val
&= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
|
1241 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
);
1242 if (params
->req_duplex
== DUPLEX_FULL
)
1243 reg_val
|= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
;
1244 CL45_WR_OVER_CL22(bp
, params
->port
,
1246 MDIO_REG_BANK_COMBO_IEEE0
,
1247 MDIO_COMBO_IEEE0_MII_CONTROL
, reg_val
);
1250 - needed only if the speed is greater than 1G (2.5G or 10G) */
1251 if (!((params
->req_line_speed
== SPEED_1000
) ||
1252 (params
->req_line_speed
== SPEED_100
) ||
1253 (params
->req_line_speed
== SPEED_10
))) {
1254 CL45_RD_OVER_CL22(bp
, params
->port
,
1256 MDIO_REG_BANK_SERDES_DIGITAL
,
1257 MDIO_SERDES_DIGITAL_MISC1
, ®_val
);
1258 /* clearing the speed value before setting the right speed */
1259 reg_val
&= ~MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK
;
1260 reg_val
|= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M
|
1261 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL
);
1262 if (params
->req_line_speed
== SPEED_10000
)
1264 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4
;
1265 if (params
->req_line_speed
== SPEED_13000
)
1267 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_set_ieee_aneg_advertisment(struct link_params
*params
,
1301 struct bnx2x
*bp
= params
->bp
;
1302 /* for AN, we are always publishing full duplex */
1303 u16 an_adv
= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX
;
1305 /* resolve pause mode and advertisement
1306 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1308 switch (params
->req_flow_ctrl
) {
1309 case FLOW_CTRL_AUTO
:
1310 if (params
->mtu
<= MAX_MTU_SIZE
) {
1312 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
1315 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
;
1320 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
;
1324 case FLOW_CTRL_BOTH
:
1325 an_adv
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
1328 case FLOW_CTRL_NONE
:
1330 an_adv
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE
;
1336 CL45_WR_OVER_CL22(bp
, params
->port
,
1338 MDIO_REG_BANK_COMBO_IEEE0
,
1339 MDIO_COMBO_IEEE0_AUTO_NEG_ADV
, an_adv
);
1342 static void bnx2x_restart_autoneg(struct link_params
*params
)
1344 struct bnx2x
*bp
= params
->bp
;
1345 DP(NETIF_MSG_LINK
, "bnx2x_restart_autoneg\n");
1347 /* enable and restart clause 73 aneg */
1350 CL45_RD_OVER_CL22(bp
, params
->port
,
1352 MDIO_REG_BANK_CL73_IEEEB0
,
1353 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
,
1355 CL45_WR_OVER_CL22(bp
, params
->port
,
1357 MDIO_REG_BANK_CL73_IEEEB0
,
1358 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
,
1360 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN
|
1361 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN
));
1364 /* Enable and restart BAM/CL37 aneg */
1367 CL45_RD_OVER_CL22(bp
, params
->port
,
1369 MDIO_REG_BANK_COMBO_IEEE0
,
1370 MDIO_COMBO_IEEE0_MII_CONTROL
,
1373 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1375 CL45_WR_OVER_CL22(bp
, params
->port
,
1377 MDIO_REG_BANK_COMBO_IEEE0
,
1378 MDIO_COMBO_IEEE0_MII_CONTROL
,
1380 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
|
1381 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN
));
1385 static void bnx2x_initialize_sgmii_process(struct link_params
*params
)
1387 struct bnx2x
*bp
= params
->bp
;
1390 /* in SGMII mode, the unicore is always slave */
1392 CL45_RD_OVER_CL22(bp
, params
->port
,
1394 MDIO_REG_BANK_SERDES_DIGITAL
,
1395 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
,
1397 control1
|= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT
;
1398 /* set sgmii mode (and not fiber) */
1399 control1
&= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE
|
1400 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET
|
1401 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE
);
1402 CL45_WR_OVER_CL22(bp
, params
->port
,
1404 MDIO_REG_BANK_SERDES_DIGITAL
,
1405 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
,
1408 /* if forced speed */
1409 if (!(params
->req_line_speed
== SPEED_AUTO_NEG
)) {
1410 /* set speed, disable autoneg */
1413 CL45_RD_OVER_CL22(bp
, params
->port
,
1415 MDIO_REG_BANK_COMBO_IEEE0
,
1416 MDIO_COMBO_IEEE0_MII_CONTROL
,
1418 mii_control
&= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
|
1419 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK
|
1420 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
);
1422 switch (params
->req_line_speed
) {
1425 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100
;
1429 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000
;
1432 /* there is nothing to set for 10M */
1435 /* invalid speed for SGMII */
1436 DP(NETIF_MSG_LINK
, "Invalid req_line_speed 0x%x\n",
1437 params
->req_line_speed
);
1441 /* setting the full duplex */
1442 if (params
->req_duplex
== DUPLEX_FULL
)
1444 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
;
1445 CL45_WR_OVER_CL22(bp
, params
->port
,
1447 MDIO_REG_BANK_COMBO_IEEE0
,
1448 MDIO_COMBO_IEEE0_MII_CONTROL
,
1451 } else { /* AN mode */
1452 /* enable and restart AN */
1453 bnx2x_restart_autoneg(params
);
1462 static void bnx2x_pause_resolve(struct link_vars
*vars
, u32 pause_result
)
1464 switch (pause_result
) { /* ASYM P ASYM P */
1465 case 0xb: /* 1 0 1 1 */
1466 vars
->flow_ctrl
= FLOW_CTRL_TX
;
1469 case 0xe: /* 1 1 1 0 */
1470 vars
->flow_ctrl
= FLOW_CTRL_RX
;
1473 case 0x5: /* 0 1 0 1 */
1474 case 0x7: /* 0 1 1 1 */
1475 case 0xd: /* 1 1 0 1 */
1476 case 0xf: /* 1 1 1 1 */
1477 vars
->flow_ctrl
= FLOW_CTRL_BOTH
;
1485 static u8
bnx2x_ext_phy_resove_fc(struct link_params
*params
,
1486 struct link_vars
*vars
)
1488 struct bnx2x
*bp
= params
->bp
;
1490 u16 ld_pause
; /* local */
1491 u16 lp_pause
; /* link partner */
1492 u16 an_complete
; /* AN complete */
1496 u8 port
= params
->port
;
1497 ext_phy_addr
= ((params
->ext_phy_config
&
1498 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
1499 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
1501 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
1504 bnx2x_cl45_read(bp
, port
,
1508 MDIO_AN_REG_STATUS
, &an_complete
);
1509 bnx2x_cl45_read(bp
, port
,
1513 MDIO_AN_REG_STATUS
, &an_complete
);
1515 if (an_complete
& MDIO_AN_REG_STATUS_AN_COMPLETE
) {
1517 bnx2x_cl45_read(bp
, port
,
1521 MDIO_AN_REG_ADV_PAUSE
, &ld_pause
);
1522 bnx2x_cl45_read(bp
, port
,
1526 MDIO_AN_REG_LP_AUTO_NEG
, &lp_pause
);
1527 pause_result
= (ld_pause
&
1528 MDIO_AN_REG_ADV_PAUSE_MASK
) >> 8;
1529 pause_result
|= (lp_pause
&
1530 MDIO_AN_REG_ADV_PAUSE_MASK
) >> 10;
1531 DP(NETIF_MSG_LINK
, "Ext PHY pause result 0x%x \n",
1533 bnx2x_pause_resolve(vars
, pause_result
);
1539 static void bnx2x_flow_ctrl_resolve(struct link_params
*params
,
1540 struct link_vars
*vars
,
1543 struct bnx2x
*bp
= params
->bp
;
1544 u16 ld_pause
; /* local driver */
1545 u16 lp_pause
; /* link partner */
1548 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
1550 /* resolve from gp_status in case of AN complete and not sgmii */
1551 if ((params
->req_flow_ctrl
== FLOW_CTRL_AUTO
) &&
1552 (gp_status
& MDIO_AN_CL73_OR_37_COMPLETE
) &&
1553 (!(vars
->phy_flags
& PHY_SGMII_FLAG
)) &&
1554 (XGXS_EXT_PHY_TYPE(params
->ext_phy_config
) ==
1555 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
)) {
1556 CL45_RD_OVER_CL22(bp
, params
->port
,
1558 MDIO_REG_BANK_COMBO_IEEE0
,
1559 MDIO_COMBO_IEEE0_AUTO_NEG_ADV
,
1561 CL45_RD_OVER_CL22(bp
, params
->port
,
1563 MDIO_REG_BANK_COMBO_IEEE0
,
1564 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1
,
1566 pause_result
= (ld_pause
&
1567 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK
)>>5;
1568 pause_result
|= (lp_pause
&
1569 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK
)>>7;
1570 DP(NETIF_MSG_LINK
, "pause_result 0x%x\n", pause_result
);
1571 bnx2x_pause_resolve(vars
, pause_result
);
1572 } else if ((params
->req_flow_ctrl
== FLOW_CTRL_AUTO
) &&
1573 (bnx2x_ext_phy_resove_fc(params
, vars
))) {
1576 vars
->flow_ctrl
= params
->req_flow_ctrl
;
1577 if (vars
->flow_ctrl
== FLOW_CTRL_AUTO
) {
1578 if (params
->mtu
<= MAX_MTU_SIZE
)
1579 vars
->flow_ctrl
= FLOW_CTRL_BOTH
;
1581 vars
->flow_ctrl
= FLOW_CTRL_TX
;
1584 DP(NETIF_MSG_LINK
, "flow_ctrl 0x%x\n", vars
->flow_ctrl
);
1588 static u8
bnx2x_link_settings_status(struct link_params
*params
,
1589 struct link_vars
*vars
,
1592 struct bnx2x
*bp
= params
->bp
;
1594 vars
->link_status
= 0;
1596 if (gp_status
& MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS
) {
1597 DP(NETIF_MSG_LINK
, "phy link up gp_status=0x%x\n",
1600 vars
->phy_link_up
= 1;
1601 vars
->link_status
|= LINK_STATUS_LINK_UP
;
1603 if (gp_status
& MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS
)
1604 vars
->duplex
= DUPLEX_FULL
;
1606 vars
->duplex
= DUPLEX_HALF
;
1608 bnx2x_flow_ctrl_resolve(params
, vars
, gp_status
);
1610 switch (gp_status
& GP_STATUS_SPEED_MASK
) {
1612 vars
->line_speed
= SPEED_10
;
1613 if (vars
->duplex
== DUPLEX_FULL
)
1614 vars
->link_status
|= LINK_10TFD
;
1616 vars
->link_status
|= LINK_10THD
;
1619 case GP_STATUS_100M
:
1620 vars
->line_speed
= SPEED_100
;
1621 if (vars
->duplex
== DUPLEX_FULL
)
1622 vars
->link_status
|= LINK_100TXFD
;
1624 vars
->link_status
|= LINK_100TXHD
;
1628 case GP_STATUS_1G_KX
:
1629 vars
->line_speed
= SPEED_1000
;
1630 if (vars
->duplex
== DUPLEX_FULL
)
1631 vars
->link_status
|= LINK_1000TFD
;
1633 vars
->link_status
|= LINK_1000THD
;
1636 case GP_STATUS_2_5G
:
1637 vars
->line_speed
= SPEED_2500
;
1638 if (vars
->duplex
== DUPLEX_FULL
)
1639 vars
->link_status
|= LINK_2500TFD
;
1641 vars
->link_status
|= LINK_2500THD
;
1647 "link speed unsupported gp_status 0x%x\n",
1651 case GP_STATUS_10G_KX4
:
1652 case GP_STATUS_10G_HIG
:
1653 case GP_STATUS_10G_CX4
:
1654 vars
->line_speed
= SPEED_10000
;
1655 vars
->link_status
|= LINK_10GTFD
;
1658 case GP_STATUS_12G_HIG
:
1659 vars
->line_speed
= SPEED_12000
;
1660 vars
->link_status
|= LINK_12GTFD
;
1663 case GP_STATUS_12_5G
:
1664 vars
->line_speed
= SPEED_12500
;
1665 vars
->link_status
|= LINK_12_5GTFD
;
1669 vars
->line_speed
= SPEED_13000
;
1670 vars
->link_status
|= LINK_13GTFD
;
1674 vars
->line_speed
= SPEED_15000
;
1675 vars
->link_status
|= LINK_15GTFD
;
1679 vars
->line_speed
= SPEED_16000
;
1680 vars
->link_status
|= LINK_16GTFD
;
1685 "link speed unsupported gp_status 0x%x\n",
1691 vars
->link_status
|= LINK_STATUS_SERDES_LINK
;
1693 if (params
->req_line_speed
== SPEED_AUTO_NEG
) {
1694 vars
->autoneg
= AUTO_NEG_ENABLED
;
1696 if (gp_status
& MDIO_AN_CL73_OR_37_COMPLETE
) {
1697 vars
->autoneg
|= AUTO_NEG_COMPLETE
;
1698 vars
->link_status
|=
1699 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE
;
1702 vars
->autoneg
|= AUTO_NEG_PARALLEL_DETECTION_USED
;
1703 vars
->link_status
|=
1704 LINK_STATUS_PARALLEL_DETECTION_USED
;
1707 if (vars
->flow_ctrl
& FLOW_CTRL_TX
)
1708 vars
->link_status
|=
1709 LINK_STATUS_TX_FLOW_CONTROL_ENABLED
;
1711 if (vars
->flow_ctrl
& FLOW_CTRL_RX
)
1712 vars
->link_status
|=
1713 LINK_STATUS_RX_FLOW_CONTROL_ENABLED
;
1715 } else { /* link_down */
1716 DP(NETIF_MSG_LINK
, "phy link down\n");
1718 vars
->phy_link_up
= 0;
1719 vars
->line_speed
= 0;
1720 vars
->duplex
= DUPLEX_FULL
;
1721 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
1722 vars
->autoneg
= AUTO_NEG_DISABLED
;
1723 vars
->mac_type
= MAC_TYPE_NONE
;
1726 DP(NETIF_MSG_LINK
, "gp_status 0x%x phy_link_up %x line_speed %x \n",
1727 gp_status
, vars
->phy_link_up
, vars
->line_speed
);
1728 DP(NETIF_MSG_LINK
, "duplex %x flow_ctrl 0x%x"
1731 vars
->flow_ctrl
, vars
->autoneg
);
1732 DP(NETIF_MSG_LINK
, "link_status 0x%x\n", vars
->link_status
);
1737 static void bnx2x_set_sgmii_tx_driver(struct link_params
*params
)
1739 struct bnx2x
*bp
= params
->bp
;
1745 CL45_RD_OVER_CL22(bp
, params
->port
,
1747 MDIO_REG_BANK_OVER_1G
,
1748 MDIO_OVER_1G_LP_UP2
, &lp_up2
);
1750 CL45_RD_OVER_CL22(bp
, params
->port
,
1753 MDIO_TX0_TX_DRIVER
, &tx_driver
);
1755 /* bits [10:7] at lp_up2, positioned at [15:12] */
1756 lp_up2
= (((lp_up2
& MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK
) >>
1757 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT
) <<
1758 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT
);
1760 if ((lp_up2
!= 0) &&
1761 (lp_up2
!= (tx_driver
& MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK
))) {
1762 /* replace tx_driver bits [15:12] */
1763 tx_driver
&= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK
;
1764 tx_driver
|= lp_up2
;
1765 CL45_WR_OVER_CL22(bp
, params
->port
,
1768 MDIO_TX0_TX_DRIVER
, tx_driver
);
1772 static u8
bnx2x_emac_program(struct link_params
*params
,
1773 u32 line_speed
, u32 duplex
)
1775 struct bnx2x
*bp
= params
->bp
;
1776 u8 port
= params
->port
;
1779 DP(NETIF_MSG_LINK
, "setting link speed & duplex\n");
1780 bnx2x_bits_dis(bp
, GRCBASE_EMAC0
+ port
*0x400 +
1782 (EMAC_MODE_25G_MODE
|
1783 EMAC_MODE_PORT_MII_10M
|
1784 EMAC_MODE_HALF_DUPLEX
));
1785 switch (line_speed
) {
1787 mode
|= EMAC_MODE_PORT_MII_10M
;
1791 mode
|= EMAC_MODE_PORT_MII
;
1795 mode
|= EMAC_MODE_PORT_GMII
;
1799 mode
|= (EMAC_MODE_25G_MODE
| EMAC_MODE_PORT_GMII
);
1803 /* 10G not valid for EMAC */
1804 DP(NETIF_MSG_LINK
, "Invalid line_speed 0x%x\n", line_speed
);
1808 if (duplex
== DUPLEX_HALF
)
1809 mode
|= EMAC_MODE_HALF_DUPLEX
;
1811 GRCBASE_EMAC0
+ port
*0x400 + EMAC_REG_EMAC_MODE
,
1814 bnx2x_set_led(bp
, params
->port
, LED_MODE_OPER
,
1815 line_speed
, params
->hw_led_mode
, params
->chip_id
);
1819 /*****************************************************************************/
1820 /* External Phy section */
1821 /*****************************************************************************/
1822 static void bnx2x_hw_reset(struct bnx2x
*bp
)
1824 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
1825 MISC_REGISTERS_GPIO_OUTPUT_LOW
);
1827 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
1828 MISC_REGISTERS_GPIO_OUTPUT_HIGH
);
1831 static void bnx2x_ext_phy_reset(struct link_params
*params
,
1832 struct link_vars
*vars
)
1834 struct bnx2x
*bp
= params
->bp
;
1836 u8 ext_phy_addr
= ((params
->ext_phy_config
&
1837 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
1838 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
1839 DP(NETIF_MSG_LINK
, "Port %x: bnx2x_ext_phy_reset\n", params
->port
);
1840 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
1841 /* The PHY reset is controled by GPIO 1
1842 * Give it 1ms of reset pulse
1844 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
1846 switch (ext_phy_type
) {
1847 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
1848 DP(NETIF_MSG_LINK
, "XGXS Direct\n");
1851 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
1852 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
1853 DP(NETIF_MSG_LINK
, "XGXS 8705/8706\n");
1855 /* Restore normal power mode*/
1856 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
1857 MISC_REGISTERS_GPIO_OUTPUT_HIGH
);
1862 bnx2x_cl45_write(bp
, params
->port
,
1866 MDIO_PMA_REG_CTRL
, 0xa040);
1868 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
1869 /* Unset Low Power Mode and SW reset */
1870 /* Restore normal power mode*/
1871 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
1872 MISC_REGISTERS_GPIO_OUTPUT_HIGH
);
1874 DP(NETIF_MSG_LINK
, "XGXS 8072\n");
1875 bnx2x_cl45_write(bp
, params
->port
,
1882 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
1885 emac_base
= (params
->port
) ? GRCBASE_EMAC0
:
1888 /* Restore normal power mode*/
1889 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
1890 MISC_REGISTERS_GPIO_OUTPUT_HIGH
);
1892 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
1893 MISC_REGISTERS_GPIO_OUTPUT_HIGH
);
1895 DP(NETIF_MSG_LINK
, "XGXS 8073\n");
1896 bnx2x_cl45_write(bp
,
1906 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
1907 DP(NETIF_MSG_LINK
, "XGXS SFX7101\n");
1909 /* Restore normal power mode*/
1910 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
1911 MISC_REGISTERS_GPIO_OUTPUT_HIGH
);
1918 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
1919 DP(NETIF_MSG_LINK
, "XGXS PHY Failure detected\n");
1923 DP(NETIF_MSG_LINK
, "BAD XGXS ext_phy_config 0x%x\n",
1924 params
->ext_phy_config
);
1928 } else { /* SerDes */
1929 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
1930 switch (ext_phy_type
) {
1931 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
:
1932 DP(NETIF_MSG_LINK
, "SerDes Direct\n");
1935 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482
:
1936 DP(NETIF_MSG_LINK
, "SerDes 5482\n");
1942 "BAD SerDes ext_phy_config 0x%x\n",
1943 params
->ext_phy_config
);
1949 static void bnx2x_bcm8072_external_rom_boot(struct link_params
*params
)
1951 struct bnx2x
*bp
= params
->bp
;
1952 u8 port
= params
->port
;
1953 u8 ext_phy_addr
= ((params
->ext_phy_config
&
1954 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
1955 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
1956 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
1957 u16 fw_ver1
, fw_ver2
;
1959 /* Need to wait 200ms after reset */
1961 /* Boot port from external ROM
1962 * Set ser_boot_ctl bit in the MISC_CTRL1 register
1964 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
1966 MDIO_PMA_REG_MISC_CTRL1
, 0x0001);
1968 /* Reset internal microprocessor */
1969 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
1971 MDIO_PMA_REG_GEN_CTRL
,
1972 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP
);
1973 /* set micro reset = 0 */
1974 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
1976 MDIO_PMA_REG_GEN_CTRL
,
1977 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET
);
1978 /* Reset internal microprocessor */
1979 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
1981 MDIO_PMA_REG_GEN_CTRL
,
1982 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP
);
1983 /* wait for 100ms for code download via SPI port */
1986 /* Clear ser_boot_ctl bit */
1987 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
1989 MDIO_PMA_REG_MISC_CTRL1
, 0x0000);
1993 /* Print the PHY FW version */
1994 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
1996 MDIO_PMA_REG_ROM_VER1
, &fw_ver1
);
1997 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
1999 MDIO_PMA_REG_ROM_VER2
, &fw_ver2
);
2000 DP(NETIF_MSG_LINK
, "8072 FW version 0x%x:0x%x\n", fw_ver1
, fw_ver2
);
2003 static u8
bnx2x_8073_is_snr_needed(struct link_params
*params
)
2005 /* This is only required for 8073A1, version 102 only */
2007 struct bnx2x
*bp
= params
->bp
;
2008 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2009 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2010 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2013 /* Read 8073 HW revision*/
2014 bnx2x_cl45_read(bp
, params
->port
,
2015 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2021 /* No need to workaround in 8073 A1 */
2025 bnx2x_cl45_read(bp
, params
->port
,
2026 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2029 MDIO_PMA_REG_ROM_VER2
, &val
);
2031 /* SNR should be applied only for version 0x102 */
2038 static u8
bnx2x_bcm8073_xaui_wa(struct link_params
*params
)
2040 struct bnx2x
*bp
= params
->bp
;
2041 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2042 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2043 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2044 u16 val
, cnt
, cnt1
;
2046 bnx2x_cl45_read(bp
, params
->port
,
2047 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2053 /* No need to workaround in 8073 A1 */
2056 /* XAUI workaround in 8073 A0: */
2058 /* After loading the boot ROM and restarting Autoneg,
2059 poll Dev1, Reg $C820: */
2061 for (cnt
= 0; cnt
< 1000; cnt
++) {
2062 bnx2x_cl45_read(bp
, params
->port
,
2063 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2067 /* If bit [14] = 0 or bit [13] = 0, continue on with
2068 system initialization (XAUI work-around not required,
2069 as these bits indicate 2.5G or 1G link up). */
2070 if (!(val
& (1<<14)) || !(val
& (1<<13))) {
2071 DP(NETIF_MSG_LINK
, "XAUI work-around not required\n");
2073 } else if (!(val
& (1<<15))) {
2074 DP(NETIF_MSG_LINK
, "clc bit 15 went off\n");
2075 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2076 it's MSB (bit 15) goes to 1 (indicating that the
2077 XAUI workaround has completed),
2078 then continue on with system initialization.*/
2079 for (cnt1
= 0; cnt1
< 1000; cnt1
++) {
2080 bnx2x_cl45_read(bp
, params
->port
,
2081 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2085 if (val
& (1<<15)) {
2087 "XAUI workaround has completed\n");
2096 DP(NETIF_MSG_LINK
, "Warning: XAUI work-around timeout !!!\n");
2101 static void bnx2x_bcm8073_external_rom_boot(struct link_params
*params
)
2103 struct bnx2x
*bp
= params
->bp
;
2104 u8 port
= params
->port
;
2105 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2106 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2107 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2108 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2109 u16 fw_ver1
, fw_ver2
, val
;
2110 /* Need to wait 100ms after reset */
2112 /* Boot port from external ROM */
2114 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2116 MDIO_PMA_REG_GEN_CTRL
,
2119 /* ucode reboot and rst */
2120 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2122 MDIO_PMA_REG_GEN_CTRL
,
2125 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2127 MDIO_PMA_REG_MISC_CTRL1
, 0x0001);
2129 /* Reset internal microprocessor */
2130 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2132 MDIO_PMA_REG_GEN_CTRL
,
2133 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET
);
2135 /* Release srst bit */
2136 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2138 MDIO_PMA_REG_GEN_CTRL
,
2139 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP
);
2141 /* wait for 100ms for code download via SPI port */
2144 /* Clear ser_boot_ctl bit */
2145 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2147 MDIO_PMA_REG_MISC_CTRL1
, 0x0000);
2149 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
2151 MDIO_PMA_REG_ROM_VER1
, &fw_ver1
);
2152 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
2154 MDIO_PMA_REG_ROM_VER2
, &fw_ver2
);
2155 DP(NETIF_MSG_LINK
, "8073 FW version 0x%x:0x%x\n", fw_ver1
, fw_ver2
);
2157 /* Only set bit 10 = 1 (Tx power down) */
2158 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
2160 MDIO_PMA_REG_TX_POWER_DOWN
, &val
);
2162 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2164 MDIO_PMA_REG_TX_POWER_DOWN
, (val
| 1<<10));
2167 /* Release bit 10 (Release Tx power down) */
2168 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2170 MDIO_PMA_REG_TX_POWER_DOWN
, (val
& (~(1<<10))));
2174 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params
*params
)
2176 struct bnx2x
*bp
= params
->bp
;
2177 u8 port
= params
->port
;
2179 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2180 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2181 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2182 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2184 bnx2x_cl45_read(bp
, params
->port
,
2185 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2191 /* Mustn't set low power mode in 8073 A0 */
2195 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2196 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
2198 MDIO_XS_PLL_SEQUENCER
, &val
);
2200 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2201 MDIO_XS_DEVAD
, MDIO_XS_PLL_SEQUENCER
, val
);
2204 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2205 MDIO_XS_DEVAD
, 0x805E, 0x1077);
2206 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2207 MDIO_XS_DEVAD
, 0x805D, 0x0000);
2208 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2209 MDIO_XS_DEVAD
, 0x805C, 0x030B);
2210 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2211 MDIO_XS_DEVAD
, 0x805B, 0x1240);
2212 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2213 MDIO_XS_DEVAD
, 0x805A, 0x2490);
2216 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2217 MDIO_XS_DEVAD
, 0x80A7, 0x0C74);
2218 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2219 MDIO_XS_DEVAD
, 0x80A6, 0x9041);
2220 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2221 MDIO_XS_DEVAD
, 0x80A5, 0x4640);
2224 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2225 MDIO_XS_DEVAD
, 0x80FE, 0x01C4);
2226 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2227 MDIO_XS_DEVAD
, 0x80FD, 0x9249);
2228 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2229 MDIO_XS_DEVAD
, 0x80FC, 0x2015);
2231 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
2232 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
2234 MDIO_XS_PLL_SEQUENCER
, &val
);
2236 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2237 MDIO_XS_DEVAD
, MDIO_XS_PLL_SEQUENCER
, val
);
2239 static void bnx2x_bcm807x_force_10G(struct link_params
*params
)
2241 struct bnx2x
*bp
= params
->bp
;
2242 u8 port
= params
->port
;
2243 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2244 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2245 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2246 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2248 /* Force KR or KX */
2249 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2253 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2255 MDIO_PMA_REG_10G_CTRL2
,
2257 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2259 MDIO_PMA_REG_BCM_CTRL
,
2261 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2267 static void bnx2x_ext_phy_set_pause(struct link_params
*params
,
2268 struct link_vars
*vars
)
2270 struct bnx2x
*bp
= params
->bp
;
2272 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2273 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2274 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2275 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2277 /* read modify write pause advertizing */
2278 bnx2x_cl45_read(bp
, params
->port
,
2282 MDIO_AN_REG_ADV_PAUSE
, &val
);
2284 val
&= ~MDIO_AN_REG_ADV_PAUSE_BOTH
;
2285 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2288 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) {
2289 val
|= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC
;
2292 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) {
2294 MDIO_AN_REG_ADV_PAUSE_PAUSE
;
2297 "Ext phy AN advertize 0x%x\n", val
);
2298 bnx2x_cl45_write(bp
, params
->port
,
2302 MDIO_AN_REG_ADV_PAUSE
, val
);
2305 static u8
bnx2x_ext_phy_init(struct link_params
*params
, struct link_vars
*vars
)
2307 struct bnx2x
*bp
= params
->bp
;
2314 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
2315 ext_phy_addr
= ((params
->ext_phy_config
&
2316 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2317 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2319 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2320 /* Make sure that the soft reset is off (expect for the 8072:
2321 * due to the lock, it will be done inside the specific
2324 if ((ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) &&
2325 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
) &&
2326 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
) &&
2327 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
) &&
2328 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
)) {
2329 /* Wait for soft reset to get cleared upto 1 sec */
2330 for (cnt
= 0; cnt
< 1000; cnt
++) {
2331 bnx2x_cl45_read(bp
, params
->port
,
2335 MDIO_PMA_REG_CTRL
, &ctrl
);
2336 if (!(ctrl
& (1<<15)))
2340 DP(NETIF_MSG_LINK
, "control reg 0x%x (after %d ms)\n",
2344 switch (ext_phy_type
) {
2345 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
2346 DP(NETIF_MSG_LINK
, "XGXS Direct\n");
2349 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
2350 DP(NETIF_MSG_LINK
, "XGXS 8705\n");
2352 bnx2x_cl45_write(bp
, params
->port
,
2356 MDIO_PMA_REG_MISC_CTRL
,
2358 bnx2x_cl45_write(bp
, params
->port
,
2362 MDIO_PMA_REG_PHY_IDENTIFIER
,
2364 bnx2x_cl45_write(bp
, params
->port
,
2368 MDIO_PMA_REG_CMU_PLL_BYPASS
,
2370 bnx2x_cl45_write(bp
, params
->port
,
2374 MDIO_WIS_REG_LASI_CNTL
, 0x1);
2377 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
2378 DP(NETIF_MSG_LINK
, "XGXS 8706\n");
2382 /* First enable LASI */
2383 bnx2x_cl45_write(bp
, params
->port
,
2387 MDIO_PMA_REG_RX_ALARM_CTRL
,
2389 bnx2x_cl45_write(bp
, params
->port
,
2393 MDIO_PMA_REG_LASI_CTRL
, 0x0004);
2395 if (params
->req_line_speed
== SPEED_10000
) {
2396 DP(NETIF_MSG_LINK
, "XGXS 8706 force 10Gbps\n");
2398 bnx2x_cl45_write(bp
, params
->port
,
2402 MDIO_PMA_REG_DIGITAL_CTRL
,
2405 /* Force 1Gbps using autoneg with 1G
2408 /* Allow CL37 through CL73 */
2409 DP(NETIF_MSG_LINK
, "XGXS 8706 AutoNeg\n");
2410 bnx2x_cl45_write(bp
, params
->port
,
2414 MDIO_AN_REG_CL37_CL73
,
2417 /* Enable Full-Duplex advertisment on CL37 */
2418 bnx2x_cl45_write(bp
, params
->port
,
2422 MDIO_AN_REG_CL37_FD
,
2424 /* Enable CL37 AN */
2425 bnx2x_cl45_write(bp
, params
->port
,
2429 MDIO_AN_REG_CL37_AN
,
2432 bnx2x_cl45_write(bp
, params
->port
,
2436 MDIO_AN_REG_ADV
, (1<<5));
2438 /* Enable clause 73 AN */
2439 bnx2x_cl45_write(bp
, params
->port
,
2450 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
2451 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
2454 u16 rx_alarm_ctrl_val
;
2457 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
) {
2458 rx_alarm_ctrl_val
= 0x400;
2459 lasi_ctrl_val
= 0x0004;
2461 /* In 8073, port1 is directed through emac0 and
2462 * port0 is directed through emac1
2464 rx_alarm_ctrl_val
= (1<<2);
2465 /*lasi_ctrl_val = 0x0005;*/
2466 lasi_ctrl_val
= 0x0004;
2469 /* Wait for soft reset to get cleared upto 1 sec */
2470 for (cnt
= 0; cnt
< 1000; cnt
++) {
2471 bnx2x_cl45_read(bp
, params
->port
,
2477 if (!(ctrl
& (1<<15)))
2482 "807x control reg 0x%x (after %d ms)\n",
2486 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
){
2487 bnx2x_bcm8072_external_rom_boot(params
);
2489 bnx2x_bcm8073_external_rom_boot(params
);
2490 /* In case of 8073 with long xaui lines,
2491 don't set the 8073 xaui low power*/
2492 bnx2x_bcm8073_set_xaui_low_power_mode(params
);
2496 bnx2x_cl45_write(bp
, params
->port
,
2500 MDIO_PMA_REG_RX_ALARM_CTRL
,
2503 bnx2x_cl45_write(bp
, params
->port
,
2507 MDIO_PMA_REG_LASI_CTRL
,
2510 bnx2x_cl45_read(bp
, params
->port
,
2514 MDIO_PMA_REG_RX_ALARM
, &tmp1
);
2516 DP(NETIF_MSG_LINK
, "Before rom RX_ALARM(port1):"
2519 /* If this is forced speed, set to KR or KX
2520 * (all other are not supported)
2522 if (!(params
->req_line_speed
== SPEED_AUTO_NEG
)) {
2523 if (params
->req_line_speed
== SPEED_10000
) {
2524 bnx2x_bcm807x_force_10G(params
);
2526 "Forced speed 10G on 807X\n");
2528 } else if (params
->req_line_speed
==
2531 /* Note that 2.5G works only
2532 when used with 1G advertisment */
2538 if (params
->speed_cap_mask
&
2539 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)
2542 if (params
->speed_cap_mask
&
2543 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
)
2545 DP(NETIF_MSG_LINK
, "807x autoneg val = 0x%x\n", val
);
2546 /*val = ((1<<5)|(1<<7));*/
2549 bnx2x_cl45_write(bp
, params
->port
,
2553 MDIO_AN_REG_ADV
, val
);
2556 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
2557 /* Disable 2.5Ghz */
2558 bnx2x_cl45_read(bp
, params
->port
,
2563 /* SUPPORT_SPEED_CAPABILITY
2564 (Due to the nature of the link order, its not
2565 possible to enable 2.5G within the autoneg
2567 if (params->speed_cap_mask &
2568 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
2570 if (params
->req_line_speed
== SPEED_2500
) {
2572 /* Allow 2.5G for A1 and above */
2573 bnx2x_cl45_read(bp
, params
->port
,
2574 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2587 bnx2x_cl45_write(bp
, params
->port
,
2593 /* Add support for CL37 (passive mode) I */
2594 bnx2x_cl45_write(bp
, params
->port
,
2598 MDIO_AN_REG_CL37_CL73
, 0x040c);
2599 /* Add support for CL37 (passive mode) II */
2600 bnx2x_cl45_write(bp
, params
->port
,
2604 MDIO_AN_REG_CL37_FD
, 0x20);
2605 /* Add support for CL37 (passive mode) III */
2606 bnx2x_cl45_write(bp
, params
->port
,
2610 MDIO_AN_REG_CL37_AN
, 0x1000);
2611 /* Restart autoneg */
2615 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
2617 /* The SNR will improve about 2db by changing the
2618 BW and FEE main tap. Rest commands are executed
2620 /* Change FFE main cursor to 5 in EDC register */
2621 if (bnx2x_8073_is_snr_needed(params
))
2622 bnx2x_cl45_write(bp
, params
->port
,
2626 MDIO_PMA_REG_EDC_FFE_MAIN
,
2629 /* Enable FEC (Forware Error Correction)
2630 Request in the AN */
2631 bnx2x_cl45_read(bp
, params
->port
,
2635 MDIO_AN_REG_ADV2
, &tmp1
);
2639 bnx2x_cl45_write(bp
, params
->port
,
2643 MDIO_AN_REG_ADV2
, tmp1
);
2646 bnx2x_ext_phy_set_pause(params
, vars
);
2648 bnx2x_cl45_write(bp
, params
->port
,
2652 MDIO_AN_REG_CTRL
, 0x1200);
2653 DP(NETIF_MSG_LINK
, "807x Autoneg Restart: "
2654 "Advertise 1G=%x, 10G=%x\n",
2655 ((val
& (1<<5)) > 0),
2656 ((val
& (1<<7)) > 0));
2659 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
2661 "Setting the SFX7101 LASI indication\n");
2663 bnx2x_cl45_write(bp
, params
->port
,
2667 MDIO_PMA_REG_LASI_CTRL
, 0x1);
2669 "Setting the SFX7101 LED to blink on traffic\n");
2670 bnx2x_cl45_write(bp
, params
->port
,
2674 MDIO_PMA_REG_7107_LED_CNTL
, (1<<3));
2676 bnx2x_ext_phy_set_pause(params
, vars
);
2677 /* Restart autoneg */
2678 bnx2x_cl45_read(bp
, params
->port
,
2682 MDIO_AN_REG_CTRL
, &val
);
2684 bnx2x_cl45_write(bp
, params
->port
,
2688 MDIO_AN_REG_CTRL
, val
);
2690 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
2692 "XGXS PHY Failure detected 0x%x\n",
2693 params
->ext_phy_config
);
2697 DP(NETIF_MSG_LINK
, "BAD XGXS ext_phy_config 0x%x\n",
2698 params
->ext_phy_config
);
2703 } else { /* SerDes */
2704 /* ext_phy_addr = ((bp->ext_phy_config &
2705 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) >>
2706 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT);
2708 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
2709 switch (ext_phy_type
) {
2710 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
:
2711 DP(NETIF_MSG_LINK
, "SerDes Direct\n");
2714 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482
:
2715 DP(NETIF_MSG_LINK
, "SerDes 5482\n");
2719 DP(NETIF_MSG_LINK
, "BAD SerDes ext_phy_config 0x%x\n",
2720 params
->ext_phy_config
);
2728 static u8
bnx2x_ext_phy_is_link_up(struct link_params
*params
,
2729 struct link_vars
*vars
)
2731 struct bnx2x
*bp
= params
->bp
;
2735 u16 rx_sd
, pcs_status
;
2736 u8 ext_phy_link_up
= 0;
2737 u8 port
= params
->port
;
2738 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
2739 ext_phy_addr
= ((params
->ext_phy_config
&
2740 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2741 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2743 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2744 switch (ext_phy_type
) {
2745 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
2746 DP(NETIF_MSG_LINK
, "XGXS Direct\n");
2747 ext_phy_link_up
= 1;
2750 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
2751 DP(NETIF_MSG_LINK
, "XGXS 8705\n");
2752 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2755 MDIO_WIS_REG_LASI_STATUS
, &val1
);
2756 DP(NETIF_MSG_LINK
, "8705 LASI status 0x%x\n", val1
);
2758 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2761 MDIO_WIS_REG_LASI_STATUS
, &val1
);
2762 DP(NETIF_MSG_LINK
, "8705 LASI status 0x%x\n", val1
);
2764 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2767 MDIO_PMA_REG_RX_SD
, &rx_sd
);
2768 DP(NETIF_MSG_LINK
, "8705 rx_sd 0x%x\n", rx_sd
);
2769 ext_phy_link_up
= (rx_sd
& 0x1);
2772 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
2773 DP(NETIF_MSG_LINK
, "XGXS 8706\n");
2774 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2777 MDIO_PMA_REG_LASI_STATUS
, &val1
);
2778 DP(NETIF_MSG_LINK
, "8706 LASI status 0x%x\n", val1
);
2780 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2783 MDIO_PMA_REG_LASI_STATUS
, &val1
);
2784 DP(NETIF_MSG_LINK
, "8706 LASI status 0x%x\n", val1
);
2786 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2789 MDIO_PMA_REG_RX_SD
, &rx_sd
);
2790 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2793 MDIO_PCS_REG_STATUS
, &pcs_status
);
2795 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2798 MDIO_AN_REG_LINK_STATUS
, &val2
);
2799 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2802 MDIO_AN_REG_LINK_STATUS
, &val2
);
2804 DP(NETIF_MSG_LINK
, "8706 rx_sd 0x%x"
2805 " pcs_status 0x%x 1Gbps link_status 0x%x\n",
2806 rx_sd
, pcs_status
, val2
);
2807 /* link is up if both bit 0 of pmd_rx_sd and
2808 * bit 0 of pcs_status are set, or if the autoneg bit
2811 ext_phy_link_up
= ((rx_sd
& pcs_status
& 0x1) ||
2813 /* clear LASI indication*/
2814 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2817 MDIO_PMA_REG_RX_ALARM
, &val2
);
2820 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
2821 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
2824 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
) {
2825 bnx2x_cl45_read(bp
, params
->port
,
2829 MDIO_PCS_REG_LASI_STATUS
, &val1
);
2830 bnx2x_cl45_read(bp
, params
->port
,
2834 MDIO_PCS_REG_LASI_STATUS
, &val2
);
2836 "870x LASI status 0x%x->0x%x\n",
2840 /* In 8073, port1 is directed through emac0 and
2841 * port0 is directed through emac1
2843 bnx2x_cl45_read(bp
, params
->port
,
2847 MDIO_PMA_REG_LASI_STATUS
, &val1
);
2849 bnx2x_cl45_read(bp
, params
->port
,
2853 MDIO_PMA_REG_LASI_STATUS
, &val2
);
2855 "8703 LASI status 0x%x->0x%x\n",
2859 /* clear the interrupt LASI status register */
2860 bnx2x_cl45_read(bp
, params
->port
,
2864 MDIO_PCS_REG_STATUS
, &val2
);
2865 bnx2x_cl45_read(bp
, params
->port
,
2869 MDIO_PCS_REG_STATUS
, &val1
);
2870 DP(NETIF_MSG_LINK
, "807x PCS status 0x%x->0x%x\n",
2872 /* Check the LASI */
2873 bnx2x_cl45_read(bp
, params
->port
,
2877 MDIO_PMA_REG_RX_ALARM
, &val2
);
2878 bnx2x_cl45_read(bp
, params
->port
,
2882 MDIO_PMA_REG_RX_ALARM
,
2884 DP(NETIF_MSG_LINK
, "KR 0x9003 0x%x->0x%x\n",
2886 /* Check the link status */
2887 bnx2x_cl45_read(bp
, params
->port
,
2891 MDIO_PCS_REG_STATUS
, &val2
);
2892 DP(NETIF_MSG_LINK
, "KR PCS status 0x%x\n", val2
);
2894 bnx2x_cl45_read(bp
, params
->port
,
2898 MDIO_PMA_REG_STATUS
, &val2
);
2899 bnx2x_cl45_read(bp
, params
->port
,
2903 MDIO_PMA_REG_STATUS
, &val1
);
2904 ext_phy_link_up
= ((val1
& 4) == 4);
2905 DP(NETIF_MSG_LINK
, "PMA_REG_STATUS=0x%x\n", val1
);
2907 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
2908 u16 an1000_status
= 0;
2909 if (ext_phy_link_up
&&
2911 (params
->req_line_speed
!= SPEED_10000
)
2913 if (bnx2x_bcm8073_xaui_wa(params
)
2915 ext_phy_link_up
= 0;
2918 bnx2x_cl45_read(bp
, params
->port
,
2924 bnx2x_cl45_read(bp
, params
->port
,
2931 /* Check the link status on 1.1.2 */
2932 bnx2x_cl45_read(bp
, params
->port
,
2936 MDIO_PMA_REG_STATUS
, &val2
);
2937 bnx2x_cl45_read(bp
, params
->port
,
2941 MDIO_PMA_REG_STATUS
, &val1
);
2942 DP(NETIF_MSG_LINK
, "KR PMA status 0x%x->0x%x,"
2943 "an_link_status=0x%x\n",
2944 val2
, val1
, an1000_status
);
2946 ext_phy_link_up
= (((val1
& 4) == 4) ||
2947 (an1000_status
& (1<<1)));
2948 if (ext_phy_link_up
&&
2949 bnx2x_8073_is_snr_needed(params
)) {
2950 /* The SNR will improve about 2dbby
2951 changing the BW and FEE main tap.*/
2953 /* The 1st write to change FFE main
2954 tap is set before restart AN */
2955 /* Change PLL Bandwidth in EDC
2957 bnx2x_cl45_write(bp
, port
, ext_phy_type
,
2960 MDIO_PMA_REG_PLL_BANDWIDTH
,
2963 /* Change CDR Bandwidth in EDC
2965 bnx2x_cl45_write(bp
, port
, ext_phy_type
,
2968 MDIO_PMA_REG_CDR_BANDWIDTH
,
2975 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
2976 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2979 MDIO_PMA_REG_LASI_STATUS
, &val2
);
2980 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2983 MDIO_PMA_REG_LASI_STATUS
, &val1
);
2985 "10G-base-T LASI status 0x%x->0x%x\n",
2987 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2990 MDIO_PMA_REG_STATUS
, &val2
);
2991 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2994 MDIO_PMA_REG_STATUS
, &val1
);
2996 "10G-base-T PMA status 0x%x->0x%x\n",
2998 ext_phy_link_up
= ((val1
& 4) == 4);
3000 * print the AN outcome of the SFX7101 PHY
3002 if (ext_phy_link_up
) {
3003 bnx2x_cl45_read(bp
, params
->port
,
3007 MDIO_AN_REG_MASTER_STATUS
,
3010 "SFX7101 AN status 0x%x->Master=%x\n",
3017 DP(NETIF_MSG_LINK
, "BAD XGXS ext_phy_config 0x%x\n",
3018 params
->ext_phy_config
);
3019 ext_phy_link_up
= 0;
3023 } else { /* SerDes */
3024 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
3025 switch (ext_phy_type
) {
3026 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
:
3027 DP(NETIF_MSG_LINK
, "SerDes Direct\n");
3028 ext_phy_link_up
= 1;
3031 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482
:
3032 DP(NETIF_MSG_LINK
, "SerDes 5482\n");
3033 ext_phy_link_up
= 1;
3038 "BAD SerDes ext_phy_config 0x%x\n",
3039 params
->ext_phy_config
);
3040 ext_phy_link_up
= 0;
3045 return ext_phy_link_up
;
3048 static void bnx2x_link_int_enable(struct link_params
*params
)
3050 u8 port
= params
->port
;
3053 struct bnx2x
*bp
= params
->bp
;
3054 /* setting the status to report on link up
3055 for either XGXS or SerDes */
3057 if (params
->switch_cfg
== SWITCH_CFG_10G
) {
3058 mask
= (NIG_MASK_XGXS0_LINK10G
|
3059 NIG_MASK_XGXS0_LINK_STATUS
);
3060 DP(NETIF_MSG_LINK
, "enabled XGXS interrupt\n");
3061 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3062 if ((ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) &&
3063 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
) &&
3065 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
)) {
3066 mask
|= NIG_MASK_MI_INT
;
3067 DP(NETIF_MSG_LINK
, "enabled external phy int\n");
3070 } else { /* SerDes */
3071 mask
= NIG_MASK_SERDES0_LINK_STATUS
;
3072 DP(NETIF_MSG_LINK
, "enabled SerDes interrupt\n");
3073 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
3074 if ((ext_phy_type
!=
3075 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
) &&
3077 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN
)) {
3078 mask
|= NIG_MASK_MI_INT
;
3079 DP(NETIF_MSG_LINK
, "enabled external phy int\n");
3083 NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4,
3085 DP(NETIF_MSG_LINK
, "port %x, is_xgxs=%x, int_status 0x%x\n", port
,
3086 (params
->switch_cfg
== SWITCH_CFG_10G
),
3087 REG_RD(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4));
3089 DP(NETIF_MSG_LINK
, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
3090 REG_RD(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4),
3091 REG_RD(bp
, NIG_REG_EMAC0_STATUS_MISC_MI_INT
+ port
*0x18),
3092 REG_RD(bp
, NIG_REG_SERDES0_STATUS_LINK_STATUS
+port
*0x3c));
3093 DP(NETIF_MSG_LINK
, " 10G %x, XGXS_LINK %x\n",
3094 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK10G
+ port
*0x68),
3095 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK_STATUS
+ port
*0x68));
3102 static void bnx2x_link_int_ack(struct link_params
*params
,
3103 struct link_vars
*vars
, u16 is_10g
)
3105 struct bnx2x
*bp
= params
->bp
;
3106 u8 port
= params
->port
;
3108 /* first reset all status
3109 * we assume only one line will be change at a time */
3110 bnx2x_bits_dis(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
3111 (NIG_STATUS_XGXS0_LINK10G
|
3112 NIG_STATUS_XGXS0_LINK_STATUS
|
3113 NIG_STATUS_SERDES0_LINK_STATUS
));
3114 if (vars
->phy_link_up
) {
3116 /* Disable the 10G link interrupt
3117 * by writing 1 to the status register
3119 DP(NETIF_MSG_LINK
, "10G XGXS phy link up\n");
3121 NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
3122 NIG_STATUS_XGXS0_LINK10G
);
3124 } else if (params
->switch_cfg
== SWITCH_CFG_10G
) {
3125 /* Disable the link interrupt
3126 * by writing 1 to the relevant lane
3127 * in the status register
3129 u32 ser_lane
= ((params
->lane_config
&
3130 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
3131 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
3133 DP(NETIF_MSG_LINK
, "1G XGXS phy link up\n");
3135 NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
3137 NIG_STATUS_XGXS0_LINK_STATUS_SIZE
));
3139 } else { /* SerDes */
3140 DP(NETIF_MSG_LINK
, "SerDes phy link up\n");
3141 /* Disable the link interrupt
3142 * by writing 1 to the status register
3145 NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
3146 NIG_STATUS_SERDES0_LINK_STATUS
);
3149 } else { /* link_down */
3153 static u8
bnx2x_format_ver(u32 num
, u8
*str
, u16 len
)
3156 u32 mask
= 0xf0000000;
3160 /* Need more then 10chars for this format */
3167 digit
= ((num
& mask
) >> shift
);
3169 *str_ptr
= digit
+ '0';
3171 *str_ptr
= digit
- 0xa + 'a';
3184 static void bnx2x_turn_on_sf(struct bnx2x
*bp
, u8 port
, u8 ext_phy_addr
)
3188 /* Enable EMAC0 in to enable MDIO */
3189 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
3190 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE
<< port
));
3193 /* take ext phy out of reset */
3195 MISC_REGISTERS_GPIO_2
,
3196 MISC_REGISTERS_GPIO_HIGH
);
3199 MISC_REGISTERS_GPIO_1
,
3200 MISC_REGISTERS_GPIO_HIGH
);
3205 for (cnt
= 0; cnt
< 1000; cnt
++) {
3207 bnx2x_cl45_read(bp
, port
,
3208 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
3213 if (!(ctrl
& (1<<15))) {
3214 DP(NETIF_MSG_LINK
, "Reset completed\n\n");
3220 static void bnx2x_turn_off_sf(struct bnx2x
*bp
)
3222 /* put sf to reset */
3223 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
, MISC_REGISTERS_GPIO_LOW
);
3225 MISC_REGISTERS_GPIO_2
,
3226 MISC_REGISTERS_GPIO_LOW
);
3229 u8
bnx2x_get_ext_phy_fw_version(struct link_params
*params
, u8 driver_loaded
,
3230 u8
*version
, u16 len
)
3232 struct bnx2x
*bp
= params
->bp
;
3233 u32 ext_phy_type
= 0;
3235 u8 ext_phy_addr
= 0 ;
3239 if (version
== NULL
|| params
== NULL
)
3242 /* reset the returned value to zero */
3243 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3244 ext_phy_addr
= ((params
->ext_phy_config
&
3245 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
3246 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
3248 switch (ext_phy_type
) {
3249 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
3254 /* Take ext phy out of reset */
3256 bnx2x_turn_on_sf(bp
, params
->port
, ext_phy_addr
);
3261 bnx2x_cl45_read(bp
, params
->port
,
3265 MDIO_PMA_REG_7101_VER1
, &val
);
3266 version
[2] = (val
& 0xFF);
3267 version
[3] = ((val
& 0xFF00)>>8);
3269 bnx2x_cl45_read(bp
, params
->port
,
3272 MDIO_PMA_DEVAD
, MDIO_PMA_REG_7101_VER2
,
3274 version
[0] = (val
& 0xFF);
3275 version
[1] = ((val
& 0xFF00)>>8);
3279 bnx2x_turn_off_sf(bp
);
3281 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
3282 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
3284 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3287 MDIO_PMA_REG_ROM_VER1
, &val
);
3289 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3292 MDIO_PMA_REG_ROM_VER2
, &val
);
3294 status
= bnx2x_format_ver(ver_num
, version
, len
);
3297 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
3298 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
3300 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3303 MDIO_PMA_REG_ROM_VER1
, &val
);
3305 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3308 MDIO_PMA_REG_ROM_VER2
, &val
);
3310 status
= bnx2x_format_ver(ver_num
, version
, len
);
3313 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
3316 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
3317 DP(NETIF_MSG_LINK
, "bnx2x_get_ext_phy_fw_version:"
3318 " type is FAILURE!\n");
3328 static void bnx2x_set_xgxs_loopback(struct link_params
*params
,
3329 struct link_vars
*vars
,
3332 u8 port
= params
->port
;
3333 struct bnx2x
*bp
= params
->bp
;
3338 DP(NETIF_MSG_LINK
, "XGXS 10G loopback enable\n");
3340 /* change the uni_phy_addr in the nig */
3341 md_devad
= REG_RD(bp
, (NIG_REG_XGXS0_CTRL_MD_DEVAD
+
3344 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_DEVAD
+ port
*0x18, 0x5);
3346 bnx2x_cl45_write(bp
, port
, 0,
3349 (MDIO_REG_BANK_AER_BLOCK
+
3350 (MDIO_AER_BLOCK_AER_REG
& 0xf)),
3353 bnx2x_cl45_write(bp
, port
, 0,
3356 (MDIO_REG_BANK_CL73_IEEEB0
+
3357 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL
& 0xf)),
3360 /* set aer mmd back */
3361 bnx2x_set_aer_mmd(params
, vars
);
3364 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_DEVAD
+ port
*0x18,
3370 DP(NETIF_MSG_LINK
, "XGXS 1G loopback enable\n");
3372 CL45_RD_OVER_CL22(bp
, port
,
3374 MDIO_REG_BANK_COMBO_IEEE0
,
3375 MDIO_COMBO_IEEE0_MII_CONTROL
,
3378 CL45_WR_OVER_CL22(bp
, port
,
3380 MDIO_REG_BANK_COMBO_IEEE0
,
3381 MDIO_COMBO_IEEE0_MII_CONTROL
,
3383 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK
));
3388 static void bnx2x_ext_phy_loopback(struct link_params
*params
)
3390 struct bnx2x
*bp
= params
->bp
;
3394 if (params
->switch_cfg
== SWITCH_CFG_10G
) {
3395 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3396 /* CL37 Autoneg Enabled */
3397 ext_phy_addr
= ((params
->ext_phy_config
&
3398 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
3399 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
3400 switch (ext_phy_type
) {
3401 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
3402 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
:
3404 "ext_phy_loopback: We should not get here\n");
3406 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
3407 DP(NETIF_MSG_LINK
, "ext_phy_loopback: 8705\n");
3409 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
3410 DP(NETIF_MSG_LINK
, "ext_phy_loopback: 8706\n");
3412 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
3413 /* SFX7101_XGXS_TEST1 */
3414 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
3417 MDIO_XS_SFX7101_XGXS_TEST1
,
3420 "ext_phy_loopback: set ext phy loopback\n");
3422 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
3425 } /* switch external PHY type */
3428 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
3429 ext_phy_addr
= (params
->ext_phy_config
&
3430 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK
)
3431 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT
;
3437 *------------------------------------------------------------------------
3438 * bnx2x_override_led_value -
3440 * Override the led value of the requsted led
3442 *------------------------------------------------------------------------
3444 u8
bnx2x_override_led_value(struct bnx2x
*bp
, u8 port
,
3445 u32 led_idx
, u32 value
)
3449 /* If port 0 then use EMAC0, else use EMAC1*/
3450 u32 emac_base
= (port
) ? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
3453 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
3454 port
, led_idx
, value
);
3457 case 0: /* 10MB led */
3458 /* Read the current value of the LED register in
3460 reg_val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_LED
);
3461 /* Set the OVERRIDE bit to 1 */
3462 reg_val
|= EMAC_LED_OVERRIDE
;
3463 /* If value is 1, set the 10M_OVERRIDE bit,
3464 otherwise reset it.*/
3465 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_10MB_OVERRIDE
) :
3466 (reg_val
& ~EMAC_LED_10MB_OVERRIDE
);
3467 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
3469 case 1: /*100MB led */
3470 /*Read the current value of the LED register in
3472 reg_val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_LED
);
3473 /* Set the OVERRIDE bit to 1 */
3474 reg_val
|= EMAC_LED_OVERRIDE
;
3475 /* If value is 1, set the 100M_OVERRIDE bit,
3476 otherwise reset it.*/
3477 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_100MB_OVERRIDE
) :
3478 (reg_val
& ~EMAC_LED_100MB_OVERRIDE
);
3479 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
3481 case 2: /* 1000MB led */
3482 /* Read the current value of the LED register in the
3484 reg_val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_LED
);
3485 /* Set the OVERRIDE bit to 1 */
3486 reg_val
|= EMAC_LED_OVERRIDE
;
3487 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
3489 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_1000MB_OVERRIDE
) :
3490 (reg_val
& ~EMAC_LED_1000MB_OVERRIDE
);
3491 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
3493 case 3: /* 2500MB led */
3494 /* Read the current value of the LED register in the
3496 reg_val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_LED
);
3497 /* Set the OVERRIDE bit to 1 */
3498 reg_val
|= EMAC_LED_OVERRIDE
;
3499 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
3501 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_2500MB_OVERRIDE
) :
3502 (reg_val
& ~EMAC_LED_2500MB_OVERRIDE
);
3503 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
3505 case 4: /*10G led */
3507 REG_WR(bp
, NIG_REG_LED_10G_P0
,
3510 REG_WR(bp
, NIG_REG_LED_10G_P1
,
3514 case 5: /* TRAFFIC led */
3515 /* Find if the traffic control is via BMAC or EMAC */
3517 reg_val
= REG_RD(bp
, NIG_REG_NIG_EMAC0_EN
);
3519 reg_val
= REG_RD(bp
, NIG_REG_NIG_EMAC1_EN
);
3521 /* Override the traffic led in the EMAC:*/
3523 /* Read the current value of the LED register in
3525 reg_val
= REG_RD(bp
, emac_base
+
3527 /* Set the TRAFFIC_OVERRIDE bit to 1 */
3528 reg_val
|= EMAC_LED_OVERRIDE
;
3529 /* If value is 1, set the TRAFFIC bit, otherwise
3531 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_TRAFFIC
) :
3532 (reg_val
& ~EMAC_LED_TRAFFIC
);
3533 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
3534 } else { /* Override the traffic led in the BMAC: */
3535 REG_WR(bp
, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3537 REG_WR(bp
, NIG_REG_LED_CONTROL_TRAFFIC_P0
+ port
*4,
3543 "bnx2x_override_led_value() unknown led index %d "
3544 "(should be 0-5)\n", led_idx
);
3552 u8
bnx2x_set_led(struct bnx2x
*bp
, u8 port
, u8 mode
, u32 speed
,
3553 u16 hw_led_mode
, u32 chip_id
)
3556 DP(NETIF_MSG_LINK
, "bnx2x_set_led: port %x, mode %d\n", port
, mode
);
3557 DP(NETIF_MSG_LINK
, "speed 0x%x, hw_led_mode 0x%x\n",
3558 speed
, hw_led_mode
);
3561 REG_WR(bp
, NIG_REG_LED_10G_P0
+ port
*4, 0);
3562 REG_WR(bp
, NIG_REG_LED_MODE_P0
+ port
*4,
3563 SHARED_HW_CFG_LED_MAC1
);
3567 REG_WR(bp
, NIG_REG_LED_MODE_P0
+ port
*4, hw_led_mode
);
3568 REG_WR(bp
, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
+
3570 /* Set blinking rate to ~15.9Hz */
3571 REG_WR(bp
, NIG_REG_LED_CONTROL_BLINK_RATE_P0
+ port
*4,
3572 LED_BLINK_RATE_VAL
);
3573 REG_WR(bp
, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0
+
3575 if (((speed
== SPEED_2500
) ||
3576 (speed
== SPEED_1000
) ||
3577 (speed
== SPEED_100
) ||
3578 (speed
== SPEED_10
))) {
3579 /* On Everest 1 Ax chip versions for speeds less than
3580 10G LED scheme is different */
3581 REG_WR(bp
, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3583 REG_WR(bp
, NIG_REG_LED_CONTROL_TRAFFIC_P0
+
3585 REG_WR(bp
, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0
+
3592 DP(NETIF_MSG_LINK
, "bnx2x_set_led: Invalid led mode %d\n",
3600 u8
bnx2x_test_link(struct link_params
*params
, struct link_vars
*vars
)
3602 struct bnx2x
*bp
= params
->bp
;
3605 CL45_RD_OVER_CL22(bp
, params
->port
,
3607 MDIO_REG_BANK_GP_STATUS
,
3608 MDIO_GP_STATUS_TOP_AN_STATUS1
,
3610 /* link is up only if both local phy and external phy are up */
3611 if ((gp_status
& MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS
) &&
3612 bnx2x_ext_phy_is_link_up(params
, vars
))
3618 static u8
bnx2x_link_initialize(struct link_params
*params
,
3619 struct link_vars
*vars
)
3621 struct bnx2x
*bp
= params
->bp
;
3622 u8 port
= params
->port
;
3625 /* Activate the external PHY */
3626 bnx2x_ext_phy_reset(params
, vars
);
3628 bnx2x_set_aer_mmd(params
, vars
);
3630 if (vars
->phy_flags
& PHY_XGXS_FLAG
)
3631 bnx2x_set_master_ln(params
);
3633 rc
= bnx2x_reset_unicore(params
);
3634 /* reset the SerDes and wait for reset bit return low */
3638 bnx2x_set_aer_mmd(params
, vars
);
3640 /* setting the masterLn_def again after the reset */
3641 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
3642 bnx2x_set_master_ln(params
);
3643 bnx2x_set_swap_lanes(params
);
3646 /* Set Parallel Detect */
3647 if (params
->req_line_speed
== SPEED_AUTO_NEG
)
3648 bnx2x_set_parallel_detection(params
, vars
->phy_flags
);
3650 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
3651 if (params
->req_line_speed
&&
3652 ((params
->req_line_speed
== SPEED_100
) ||
3653 (params
->req_line_speed
== SPEED_10
))) {
3654 vars
->phy_flags
|= PHY_SGMII_FLAG
;
3656 vars
->phy_flags
&= ~PHY_SGMII_FLAG
;
3660 if (!(vars
->phy_flags
& PHY_SGMII_FLAG
)) {
3663 rx_eq
= ((params
->serdes_config
&
3664 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK
) >>
3665 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT
);
3667 DP(NETIF_MSG_LINK
, "setting rx eq to 0x%x\n", rx_eq
);
3668 for (bank
= MDIO_REG_BANK_RX0
; bank
<= MDIO_REG_BANK_RX_ALL
;
3669 bank
+= (MDIO_REG_BANK_RX1
-MDIO_REG_BANK_RX0
)) {
3670 CL45_WR_OVER_CL22(bp
, port
,
3673 MDIO_RX0_RX_EQ_BOOST
,
3675 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK
) |
3676 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL
));
3679 /* forced speed requested? */
3680 if (params
->req_line_speed
!= SPEED_AUTO_NEG
) {
3681 DP(NETIF_MSG_LINK
, "not SGMII, no AN\n");
3683 /* disable autoneg */
3684 bnx2x_set_autoneg(params
, vars
);
3686 /* program speed and duplex */
3687 bnx2x_program_serdes(params
);
3689 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE
;
3691 } else { /* AN_mode */
3692 DP(NETIF_MSG_LINK
, "not SGMII, AN\n");
3695 bnx2x_set_brcm_cl37_advertisment(params
);
3697 /* program duplex & pause advertisement (for aneg) */
3698 bnx2x_set_ieee_aneg_advertisment(params
,
3701 /* enable autoneg */
3702 bnx2x_set_autoneg(params
, vars
);
3704 /* enable and restart AN */
3705 bnx2x_restart_autoneg(params
);
3708 } else { /* SGMII mode */
3709 DP(NETIF_MSG_LINK
, "SGMII\n");
3711 bnx2x_initialize_sgmii_process(params
);
3714 /* init ext phy and enable link state int */
3715 rc
|= bnx2x_ext_phy_init(params
, vars
);
3717 bnx2x_bits_dis(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
3718 (NIG_STATUS_XGXS0_LINK10G
|
3719 NIG_STATUS_XGXS0_LINK_STATUS
|
3720 NIG_STATUS_SERDES0_LINK_STATUS
));
3727 u8
bnx2x_phy_init(struct link_params
*params
, struct link_vars
*vars
)
3729 struct bnx2x
*bp
= params
->bp
;
3732 DP(NETIF_MSG_LINK
, "Phy Initialization started\n");
3733 DP(NETIF_MSG_LINK
, "req_speed = %d, req_flowctrl=%d\n",
3734 params
->req_line_speed
, params
->req_flow_ctrl
);
3735 vars
->link_status
= 0;
3736 if (params
->switch_cfg
== SWITCH_CFG_1G
)
3737 vars
->phy_flags
= PHY_SERDES_FLAG
;
3739 vars
->phy_flags
= PHY_XGXS_FLAG
;
3741 /* disable attentions */
3742 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ params
->port
*4,
3743 (NIG_MASK_XGXS0_LINK_STATUS
|
3744 NIG_MASK_XGXS0_LINK10G
|
3745 NIG_MASK_SERDES0_LINK_STATUS
|
3748 bnx2x_emac_init(params
, vars
);
3750 if (CHIP_REV_IS_FPGA(bp
)) {
3752 vars
->line_speed
= SPEED_10000
;
3753 vars
->duplex
= DUPLEX_FULL
;
3754 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
3755 vars
->link_status
= (LINK_STATUS_LINK_UP
| LINK_10GTFD
);
3757 bnx2x_emac_enable(params
, vars
, 0);
3758 bnx2x_pbf_update(params
, vars
->flow_ctrl
, vars
->line_speed
);
3760 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
3761 + params
->port
*4, 0);
3763 /* update shared memory */
3764 bnx2x_update_mng(params
, vars
->link_status
);
3769 if (CHIP_REV_IS_EMUL(bp
)) {
3772 vars
->line_speed
= SPEED_10000
;
3773 vars
->duplex
= DUPLEX_FULL
;
3774 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
3775 vars
->link_status
= (LINK_STATUS_LINK_UP
| LINK_10GTFD
);
3777 bnx2x_bmac_enable(params
, vars
, 0);
3779 bnx2x_pbf_update(params
, vars
->flow_ctrl
, vars
->line_speed
);
3781 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
3782 + params
->port
*4, 0);
3784 /* update shared memory */
3785 bnx2x_update_mng(params
, vars
->link_status
);
3790 if (params
->loopback_mode
== LOOPBACK_BMAC
) {
3792 vars
->line_speed
= SPEED_10000
;
3793 vars
->duplex
= DUPLEX_FULL
;
3794 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
3795 vars
->mac_type
= MAC_TYPE_BMAC
;
3797 vars
->phy_flags
= PHY_XGXS_FLAG
;
3799 bnx2x_phy_deassert(params
, vars
->phy_flags
);
3800 /* set bmac loopback */
3801 bnx2x_bmac_enable(params
, vars
, 1);
3803 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+
3805 } else if (params
->loopback_mode
== LOOPBACK_EMAC
) {
3807 vars
->line_speed
= SPEED_1000
;
3808 vars
->duplex
= DUPLEX_FULL
;
3809 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
3810 vars
->mac_type
= MAC_TYPE_EMAC
;
3812 vars
->phy_flags
= PHY_XGXS_FLAG
;
3814 bnx2x_phy_deassert(params
, vars
->phy_flags
);
3815 /* set bmac loopback */
3816 bnx2x_emac_enable(params
, vars
, 1);
3817 bnx2x_emac_program(params
, vars
->line_speed
,
3819 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+
3821 } else if ((params
->loopback_mode
== LOOPBACK_XGXS_10
) ||
3822 (params
->loopback_mode
== LOOPBACK_EXT_PHY
)) {
3824 vars
->line_speed
= SPEED_10000
;
3825 vars
->duplex
= DUPLEX_FULL
;
3826 vars
->flow_ctrl
= FLOW_CTRL_NONE
;
3828 vars
->phy_flags
= PHY_XGXS_FLAG
;
3831 NIG_REG_XGXS0_CTRL_PHY_ADDR
+
3833 params
->phy_addr
= (u8
)val
;
3835 bnx2x_phy_deassert(params
, vars
->phy_flags
);
3836 bnx2x_link_initialize(params
, vars
);
3838 vars
->mac_type
= MAC_TYPE_BMAC
;
3840 bnx2x_bmac_enable(params
, vars
, 0);
3842 if (params
->loopback_mode
== LOOPBACK_XGXS_10
) {
3843 /* set 10G XGXS loopback */
3844 bnx2x_set_xgxs_loopback(params
, vars
, 1);
3846 /* set external phy loopback */
3847 bnx2x_ext_phy_loopback(params
);
3849 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+
3855 bnx2x_phy_deassert(params
, vars
->phy_flags
);
3856 switch (params
->switch_cfg
) {
3858 vars
->phy_flags
|= PHY_SERDES_FLAG
;
3859 if ((params
->ext_phy_config
&
3860 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK
) ==
3861 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482
) {
3867 NIG_REG_SERDES0_CTRL_PHY_ADDR
+
3870 params
->phy_addr
= (u8
)val
;
3873 case SWITCH_CFG_10G
:
3874 vars
->phy_flags
|= PHY_XGXS_FLAG
;
3876 NIG_REG_XGXS0_CTRL_PHY_ADDR
+
3878 params
->phy_addr
= (u8
)val
;
3882 DP(NETIF_MSG_LINK
, "Invalid switch_cfg\n");
3887 bnx2x_link_initialize(params
, vars
);
3888 bnx2x_link_int_enable(params
);
3893 u8
bnx2x_link_reset(struct link_params
*params
, struct link_vars
*vars
)
3896 struct bnx2x
*bp
= params
->bp
;
3897 u32 ext_phy_config
= params
->ext_phy_config
;
3898 u16 hw_led_mode
= params
->hw_led_mode
;
3899 u32 chip_id
= params
->chip_id
;
3900 u8 port
= params
->port
;
3901 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(ext_phy_config
);
3902 /* disable attentions */
3904 vars
->link_status
= 0;
3905 bnx2x_update_mng(params
, vars
->link_status
);
3906 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4,
3907 (NIG_MASK_XGXS0_LINK_STATUS
|
3908 NIG_MASK_XGXS0_LINK10G
|
3909 NIG_MASK_SERDES0_LINK_STATUS
|
3912 /* activate nig drain */
3913 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ port
*4, 1);
3915 /* disable nig egress interface */
3916 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0);
3917 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0);
3919 /* Stop BigMac rx */
3920 bnx2x_bmac_rx_disable(bp
, port
);
3923 REG_WR(bp
, NIG_REG_NIG_EMAC0_EN
+ port
*4, 0);
3926 /* The PHY reset is controled by GPIO 1
3927 * Hold it as vars low
3929 /* clear link led */
3930 bnx2x_set_led(bp
, port
, LED_MODE_OFF
, 0, hw_led_mode
, chip_id
);
3931 if (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) {
3932 if ((ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
) &&
3933 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
)) {
3936 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
3937 MISC_REGISTERS_GPIO_OUTPUT_LOW
);
3939 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
3940 MISC_REGISTERS_GPIO_OUTPUT_LOW
);
3942 DP(NETIF_MSG_LINK
, "reset external PHY\n");
3945 u8 ext_phy_addr
= ((ext_phy_config
&
3946 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
3947 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
3950 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3955 /* Set Low Power Mode */
3956 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
3963 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
3964 DP(NETIF_MSG_LINK
, "Setting 8073 port %d into"
3967 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
3968 MISC_REGISTERS_GPIO_OUTPUT_LOW
);
3972 /* reset the SerDes/XGXS */
3973 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_CLEAR
,
3974 (0x1ff << (port
*16)));
3977 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
3978 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
3980 /* disable nig ingress interface */
3981 REG_WR(bp
, NIG_REG_BMAC0_IN_EN
+ port
*4, 0);
3982 REG_WR(bp
, NIG_REG_EMAC0_IN_EN
+ port
*4, 0);
3983 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0);
3984 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0);
3989 /* This function should called upon link interrupt */
3990 /* In case vars->link_up, driver needs to
3993 3. Update the shared memory
3997 1. Update shared memory
4002 u8
bnx2x_link_update(struct link_params
*params
, struct link_vars
*vars
)
4004 struct bnx2x
*bp
= params
->bp
;
4005 u8 port
= params
->port
;
4011 DP(NETIF_MSG_LINK
, "port %x, XGXS?%x, int_status 0x%x\n",
4013 (vars
->phy_flags
& PHY_XGXS_FLAG
),
4014 REG_RD(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4));
4016 DP(NETIF_MSG_LINK
, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4017 REG_RD(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4),
4018 REG_RD(bp
, NIG_REG_EMAC0_STATUS_MISC_MI_INT
+ port
*0x18),
4019 REG_RD(bp
, NIG_REG_SERDES0_STATUS_LINK_STATUS
+ port
*0x3c));
4021 DP(NETIF_MSG_LINK
, " 10G %x, XGXS_LINK %x\n",
4022 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK10G
+ port
*0x68),
4023 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK_STATUS
+ port
*0x68));
4026 /* avoid fast toggling */
4027 for (i
= 0; i
< 10; i
++) {
4029 CL45_RD_OVER_CL22(bp
, port
, params
->phy_addr
,
4030 MDIO_REG_BANK_GP_STATUS
,
4031 MDIO_GP_STATUS_TOP_AN_STATUS1
,
4035 rc
= bnx2x_link_settings_status(params
, vars
, gp_status
);
4039 /* anything 10 and over uses the bmac */
4040 link_10g
= ((vars
->line_speed
== SPEED_10000
) ||
4041 (vars
->line_speed
== SPEED_12000
) ||
4042 (vars
->line_speed
== SPEED_12500
) ||
4043 (vars
->line_speed
== SPEED_13000
) ||
4044 (vars
->line_speed
== SPEED_15000
) ||
4045 (vars
->line_speed
== SPEED_16000
));
4047 bnx2x_link_int_ack(params
, vars
, link_10g
);
4049 /* link is up only if both local phy and external phy are up */
4050 vars
->link_up
= (vars
->phy_link_up
&&
4051 bnx2x_ext_phy_is_link_up(params
, vars
));
4053 if (!vars
->phy_link_up
&&
4054 REG_RD(bp
, NIG_REG_EMAC0_STATUS_MISC_MI_INT
+ port
*0x18)) {
4055 bnx2x_ext_phy_is_link_up(params
, vars
); /* Clear interrupt */
4058 if (vars
->link_up
) {
4059 vars
->link_status
|= LINK_STATUS_LINK_UP
;
4061 bnx2x_bmac_enable(params
, vars
, 0);
4062 bnx2x_set_led(bp
, port
, LED_MODE_OPER
,
4063 SPEED_10000
, params
->hw_led_mode
,
4067 bnx2x_emac_enable(params
, vars
, 0);
4068 rc
= bnx2x_emac_program(params
, vars
->line_speed
,
4072 if (gp_status
& MDIO_AN_CL73_OR_37_COMPLETE
) {
4073 if (!(vars
->phy_flags
&
4075 bnx2x_set_sgmii_tx_driver(params
);
4080 rc
|= bnx2x_pbf_update(params
, vars
->flow_ctrl
,
4084 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ port
*4, 0);
4086 /* update shared memory */
4087 bnx2x_update_mng(params
, vars
->link_status
);
4089 } else { /* link down */
4090 DP(NETIF_MSG_LINK
, "Port %x: Link is down\n", params
->port
);
4091 bnx2x_set_led(bp
, port
, LED_MODE_OFF
,
4092 0, params
->hw_led_mode
,
4095 /* indicate no mac active */
4096 vars
->mac_type
= MAC_TYPE_NONE
;
4098 /* update shared memory */
4099 vars
->link_status
= 0;
4100 bnx2x_update_mng(params
, vars
->link_status
);
4102 /* activate nig drain */
4103 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ port
*4, 1);
4106 bnx2x_bmac_rx_disable(bp
, params
->port
);
4107 REG_WR(bp
, GRCBASE_MISC
+
4108 MISC_REGISTERS_RESET_REG_2_CLEAR
,
4109 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
4116 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x
*bp
, u8 port
, u8 phy_addr
)
4120 bnx2x_cl45_read(bp
, port
,
4121 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4124 MDIO_PMA_REG_7101_RESET
, &val
);
4126 for (cnt
= 0; cnt
< 10; cnt
++) {
4128 /* Writes a self-clearing reset */
4129 bnx2x_cl45_write(bp
, port
,
4130 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4133 MDIO_PMA_REG_7101_RESET
,
4135 /* Wait for clear */
4136 bnx2x_cl45_read(bp
, port
,
4137 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4140 MDIO_PMA_REG_7101_RESET
, &val
);
4142 if ((val
& (1<<15)) == 0)
4146 #define RESERVED_SIZE 256
4147 /* max application is 160K bytes - data at end of RAM */
4148 #define MAX_APP_SIZE 160*1024 - RESERVED_SIZE
4150 /* Header is 14 bytes */
4151 #define HEADER_SIZE 14
4152 #define DATA_OFFSET HEADER_SIZE
4154 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
4155 bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
4158 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
4160 /* Programs an image to DSP's flash via the SPI port*/
4161 static u8
bnx2x_sfx7101_flash_download(struct bnx2x
*bp
, u8 port
,
4163 char data
[], u32 size
)
4165 const u16 num_trans
= size
/4; /* 4 bytes can be sent at a time */
4166 /* Doesn't include last trans!*/
4167 const u16 last_trans_size
= size
%4; /* Num bytes on last trans */
4168 u16 trans_cnt
, byte_cnt
;
4171 u16 code_started
= 0;
4172 u16 image_revision1
, image_revision2
;
4175 DP(NETIF_MSG_LINK
, "bnx2x_sfx7101_flash_download file_size=%d\n", size
);
4177 if ((size
-HEADER_SIZE
) > MAX_APP_SIZE
) {
4178 /* This very often will be the case, because the image is built
4179 with 160Kbytes size whereas the total image size must actually
4180 be 160Kbytes-RESERVED_SIZE */
4181 DP(NETIF_MSG_LINK
, "Warning, file size was %d bytes "
4182 "truncated to %d bytes\n", size
, MAX_APP_SIZE
);
4183 size
= MAX_APP_SIZE
+HEADER_SIZE
;
4185 DP(NETIF_MSG_LINK
, "File version is %c%c\n", data
[0x14e], data
[0x14f]);
4186 DP(NETIF_MSG_LINK
, " %c%c\n", data
[0x150], data
[0x151]);
4187 /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
4188 and issuing a reset.*/
4190 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_0
,
4191 MISC_REGISTERS_GPIO_HIGH
);
4193 bnx2x_sfx7101_sp_sw_reset(bp
, port
, ext_phy_addr
);
4196 for (cnt
= 0; cnt
< 100; cnt
++)
4199 /* Make sure we can access the DSP
4200 And it's in the correct mode (waiting for download) */
4202 bnx2x_cl45_read(bp
, port
,
4203 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4206 MDIO_PCS_REG_7101_DSP_ACCESS
, &tmp
);
4208 if (tmp
!= 0x000A) {
4209 DP(NETIF_MSG_LINK
, "DSP is not in waiting on download mode. "
4210 "Expected 0x000A, read 0x%04X\n", tmp
);
4211 DP(NETIF_MSG_LINK
, "Download failed\n");
4215 /* Mux the SPI interface away from the internal processor */
4216 bnx2x_cl45_write(bp
, port
,
4217 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4220 MDIO_PCS_REG_7101_SPI_MUX
, 1);
4222 /* Reset the SPI port */
4223 bnx2x_cl45_write(bp
, port
,
4224 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4227 MDIO_PCS_REG_7101_SPI_CTRL_ADDR
, 0);
4228 bnx2x_cl45_write(bp
, port
,
4229 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4232 MDIO_PCS_REG_7101_SPI_CTRL_ADDR
,
4233 (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT
));
4234 bnx2x_cl45_write(bp
, port
,
4235 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4238 MDIO_PCS_REG_7101_SPI_CTRL_ADDR
, 0);
4240 /* Erase the flash */
4241 bnx2x_cl45_write(bp
, port
,
4242 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4245 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4246 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD
);
4248 bnx2x_cl45_write(bp
, port
,
4249 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4252 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4255 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4256 bnx2x_cl45_write(bp
, port
,
4257 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4260 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4261 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD
);
4263 bnx2x_cl45_write(bp
, port
,
4264 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4267 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4269 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4271 /* Wait 10 seconds, the maximum time for the erase to complete */
4272 DP(NETIF_MSG_LINK
, "Erasing flash, this takes 10 seconds...\n");
4273 for (cnt
= 0; cnt
< 1000; cnt
++)
4276 DP(NETIF_MSG_LINK
, "Downloading flash, please wait...\n");
4278 for (trans_cnt
= 0; trans_cnt
< num_trans
; trans_cnt
++) {
4279 bnx2x_cl45_write(bp
, port
,
4280 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4283 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4284 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD
);
4286 bnx2x_cl45_write(bp
, port
,
4287 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4290 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4292 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4294 bnx2x_cl45_write(bp
, port
,
4295 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4298 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4299 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD
);
4301 /* Bits 23-16 of address */
4302 bnx2x_cl45_write(bp
, port
,
4303 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4306 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4308 /* Bits 15-8 of address */
4309 bnx2x_cl45_write(bp
, port
,
4310 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4313 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4316 /* Bits 7-0 of address */
4317 bnx2x_cl45_write(bp
, port
,
4318 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4321 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4325 while (byte_cnt
< 4 && data_index
< size
) {
4326 bnx2x_cl45_write(bp
, port
,
4327 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4330 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4331 data
[data_index
++]);
4335 bnx2x_cl45_write(bp
, port
,
4336 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4339 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4342 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4343 msleep(5); /* Wait 5 ms minimum between transs */
4345 /* Let the user know something's going on.*/
4346 /* a pacifier ever 4K */
4347 if ((data_index
% 1023) == 0)
4348 DP(NETIF_MSG_LINK
, "Download %d%%\n", data_index
/size
);
4351 DP(NETIF_MSG_LINK
, "\n");
4352 /* Transfer the last block if there is data remaining */
4353 if (last_trans_size
) {
4354 bnx2x_cl45_write(bp
, port
,
4355 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4358 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4359 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD
);
4361 bnx2x_cl45_write(bp
, port
,
4362 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4365 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4368 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4370 bnx2x_cl45_write(bp
, port
,
4371 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4374 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4375 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD
);
4377 /* Bits 23-16 of address */
4378 bnx2x_cl45_write(bp
, port
,
4379 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4382 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4384 /* Bits 15-8 of address */
4385 bnx2x_cl45_write(bp
, port
,
4386 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4389 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4392 /* Bits 7-0 of address */
4393 bnx2x_cl45_write(bp
, port
,
4394 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4397 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4401 while (byte_cnt
< last_trans_size
&& data_index
< size
) {
4402 /* Bits 7-0 of address */
4403 bnx2x_cl45_write(bp
, port
,
4404 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4407 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4408 data
[data_index
++]);
4412 bnx2x_cl45_write(bp
, port
,
4413 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4416 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4419 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4422 /* DSP Remove Download Mode */
4423 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_0
, MISC_REGISTERS_GPIO_LOW
);
4425 bnx2x_sfx7101_sp_sw_reset(bp
, port
, ext_phy_addr
);
4427 /* wait 0.5 sec to allow it to run */
4428 for (cnt
= 0; cnt
< 100; cnt
++)
4433 for (cnt
= 0; cnt
< 100; cnt
++)
4436 /* Check that the code is started. In case the download
4437 checksum failed, the code won't be started. */
4438 bnx2x_cl45_read(bp
, port
,
4439 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4442 MDIO_PCS_REG_7101_DSP_ACCESS
,
4445 code_started
= (tmp
& (1<<4));
4446 if (!code_started
) {
4447 DP(NETIF_MSG_LINK
, "Download failed. Please check file.\n");
4451 /* Verify that the file revision is now equal to the image
4452 revision within the DSP */
4453 bnx2x_cl45_read(bp
, port
,
4454 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4457 MDIO_PMA_REG_7101_VER1
,
4460 bnx2x_cl45_read(bp
, port
,
4461 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4464 MDIO_PMA_REG_7101_VER2
,
4467 if (data
[0x14e] != (image_revision2
&0xFF) ||
4468 data
[0x14f] != ((image_revision2
&0xFF00)>>8) ||
4469 data
[0x150] != (image_revision1
&0xFF) ||
4470 data
[0x151] != ((image_revision1
&0xFF00)>>8)) {
4471 DP(NETIF_MSG_LINK
, "Download failed.\n");
4474 DP(NETIF_MSG_LINK
, "Download %d%%\n", data_index
/size
);
4478 u8
bnx2x_flash_download(struct bnx2x
*bp
, u8 port
, u32 ext_phy_config
,
4479 u8 driver_loaded
, char data
[], u32 size
)
4484 ext_phy_addr
= ((ext_phy_config
&
4485 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
4486 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
4488 ext_phy_type
= XGXS_EXT_PHY_TYPE(ext_phy_config
);
4490 switch (ext_phy_type
) {
4491 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
4492 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
4493 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
4494 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
4496 "Flash download not supported for this ext phy\n");
4499 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
4500 /* Take ext phy out of reset */
4502 bnx2x_turn_on_sf(bp
, port
, ext_phy_addr
);
4503 rc
= bnx2x_sfx7101_flash_download(bp
, port
, ext_phy_addr
,
4506 bnx2x_turn_off_sf(bp
);
4508 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
4509 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
4510 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
:
4512 DP(NETIF_MSG_LINK
, "Invalid ext phy type\n");