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>
25 #include "bnx2x_reg.h"
26 #include "bnx2x_fw_defs.h"
27 #include "bnx2x_hsi.h"
28 #include "bnx2x_link.h"
31 /********************************************************/
32 #define SUPPORT_CL73 0 /* Currently no */
34 #define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
35 #define ETH_MIN_PACKET_SIZE 60
36 #define ETH_MAX_PACKET_SIZE 1500
37 #define ETH_MAX_JUMBO_PACKET_SIZE 9600
38 #define MDIO_ACCESS_TIMEOUT 1000
39 #define BMAC_CONTROL_RX_ENABLE 2
41 /***********************************************************/
42 /* Shortcut definitions */
43 /***********************************************************/
45 #define NIG_STATUS_XGXS0_LINK10G \
46 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
47 #define NIG_STATUS_XGXS0_LINK_STATUS \
48 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
49 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
50 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
51 #define NIG_STATUS_SERDES0_LINK_STATUS \
52 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
53 #define NIG_MASK_MI_INT \
54 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
55 #define NIG_MASK_XGXS0_LINK10G \
56 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
57 #define NIG_MASK_XGXS0_LINK_STATUS \
58 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
59 #define NIG_MASK_SERDES0_LINK_STATUS \
60 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
62 #define MDIO_AN_CL73_OR_37_COMPLETE \
63 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
64 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
66 #define XGXS_RESET_BITS \
67 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
68 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
69 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
70 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
71 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
73 #define SERDES_RESET_BITS \
74 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
75 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
76 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
77 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
79 #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
80 #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
81 #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
82 #define AUTONEG_PARALLEL \
83 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
84 #define AUTONEG_SGMII_FIBER_AUTODET \
85 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
86 #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
88 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
89 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
90 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
91 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
92 #define GP_STATUS_SPEED_MASK \
93 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
94 #define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
95 #define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
96 #define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
97 #define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
98 #define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
99 #define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
100 #define GP_STATUS_10G_HIG \
101 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
102 #define GP_STATUS_10G_CX4 \
103 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
104 #define GP_STATUS_12G_HIG \
105 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
106 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
107 #define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
108 #define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
109 #define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
110 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
111 #define GP_STATUS_10G_KX4 \
112 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
114 #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
115 #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
116 #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
117 #define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
118 #define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
119 #define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
120 #define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
121 #define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
122 #define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
123 #define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
124 #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
125 #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
126 #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
127 #define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
128 #define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
129 #define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
130 #define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
131 #define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
132 #define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
133 #define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
134 #define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
135 #define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
136 #define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
138 #define PHY_XGXS_FLAG 0x1
139 #define PHY_SGMII_FLAG 0x2
140 #define PHY_SERDES_FLAG 0x4
142 /**********************************************************/
144 /**********************************************************/
145 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
146 bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
147 DEFAULT_PHY_DEV_ADDR, \
148 (_bank + (_addr & 0xf)), \
151 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
152 bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
153 DEFAULT_PHY_DEV_ADDR, \
154 (_bank + (_addr & 0xf)), \
157 static void bnx2x_set_phy_mdio(struct link_params
*params
)
159 struct bnx2x
*bp
= params
->bp
;
160 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_ST
+
161 params
->port
*0x18, 0);
162 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_DEVAD
+ params
->port
*0x18,
163 DEFAULT_PHY_DEV_ADDR
);
166 static u32
bnx2x_bits_en(struct bnx2x
*bp
, u32 reg
, u32 bits
)
168 u32 val
= REG_RD(bp
, reg
);
171 REG_WR(bp
, reg
, val
);
175 static u32
bnx2x_bits_dis(struct bnx2x
*bp
, u32 reg
, u32 bits
)
177 u32 val
= REG_RD(bp
, reg
);
180 REG_WR(bp
, reg
, val
);
184 static void bnx2x_emac_init(struct link_params
*params
,
185 struct link_vars
*vars
)
187 /* reset and unreset the emac core */
188 struct bnx2x
*bp
= params
->bp
;
189 u8 port
= params
->port
;
190 u32 emac_base
= port
? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
194 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
195 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE
<< port
));
197 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
198 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE
<< port
));
200 /* init emac - use read-modify-write */
201 /* self clear reset */
202 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
203 EMAC_WR(bp
, EMAC_REG_EMAC_MODE
, (val
| EMAC_MODE_RESET
));
207 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
208 DP(NETIF_MSG_LINK
, "EMAC reset reg is %u\n", val
);
210 DP(NETIF_MSG_LINK
, "EMAC timeout!\n");
214 } while (val
& EMAC_MODE_RESET
);
216 /* Set mac address */
217 val
= ((params
->mac_addr
[0] << 8) |
218 params
->mac_addr
[1]);
219 EMAC_WR(bp
, EMAC_REG_EMAC_MAC_MATCH
, val
);
221 val
= ((params
->mac_addr
[2] << 24) |
222 (params
->mac_addr
[3] << 16) |
223 (params
->mac_addr
[4] << 8) |
224 params
->mac_addr
[5]);
225 EMAC_WR(bp
, EMAC_REG_EMAC_MAC_MATCH
+ 4, val
);
228 static u8
bnx2x_emac_enable(struct link_params
*params
,
229 struct link_vars
*vars
, u8 lb
)
231 struct bnx2x
*bp
= params
->bp
;
232 u8 port
= params
->port
;
233 u32 emac_base
= port
? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
236 DP(NETIF_MSG_LINK
, "enabling EMAC\n");
238 /* enable emac and not bmac */
239 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_PORT
+ port
*4, 1);
242 if (CHIP_REV_IS_EMUL(bp
)) {
243 /* Use lane 1 (of lanes 0-3) */
244 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+ port
*4, 1);
245 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+
251 if (CHIP_REV_IS_FPGA(bp
)) {
252 /* Use lane 1 (of lanes 0-3) */
253 DP(NETIF_MSG_LINK
, "bnx2x_emac_enable: Setting FPGA\n");
255 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+ port
*4, 1);
256 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+ port
*4,
260 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
261 u32 ser_lane
= ((params
->lane_config
&
262 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
263 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
265 DP(NETIF_MSG_LINK
, "XGXS\n");
266 /* select the master lanes (out of 0-3) */
267 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+
270 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+
273 } else { /* SerDes */
274 DP(NETIF_MSG_LINK
, "SerDes\n");
276 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+
281 REG_WR(bp
, NIG_REG_NIG_EMAC0_EN
+ port
*4, 1);
283 if (CHIP_REV_IS_SLOW(bp
)) {
284 /* config GMII mode */
285 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
286 EMAC_WR(bp
, EMAC_REG_EMAC_MODE
,
287 (val
| EMAC_MODE_PORT_GMII
));
289 /* pause enable/disable */
290 bnx2x_bits_dis(bp
, emac_base
+ EMAC_REG_EMAC_RX_MODE
,
291 EMAC_RX_MODE_FLOW_EN
);
292 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_RX
)
293 bnx2x_bits_en(bp
, emac_base
+
294 EMAC_REG_EMAC_RX_MODE
,
295 EMAC_RX_MODE_FLOW_EN
);
297 bnx2x_bits_dis(bp
, emac_base
+ EMAC_REG_EMAC_TX_MODE
,
298 (EMAC_TX_MODE_EXT_PAUSE_EN
|
299 EMAC_TX_MODE_FLOW_EN
));
300 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
)
301 bnx2x_bits_en(bp
, emac_base
+
302 EMAC_REG_EMAC_TX_MODE
,
303 (EMAC_TX_MODE_EXT_PAUSE_EN
|
304 EMAC_TX_MODE_FLOW_EN
));
307 /* KEEP_VLAN_TAG, promiscuous */
308 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_RX_MODE
);
309 val
|= EMAC_RX_MODE_KEEP_VLAN_TAG
| EMAC_RX_MODE_PROMISCUOUS
;
310 EMAC_WR(bp
, EMAC_REG_EMAC_RX_MODE
, val
);
313 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
318 EMAC_WR(bp
, EMAC_REG_EMAC_MODE
, val
);
320 /* enable emac for jumbo packets */
321 EMAC_WR(bp
, EMAC_REG_EMAC_RX_MTU_SIZE
,
322 (EMAC_RX_MTU_SIZE_JUMBO_ENA
|
323 (ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
)));
326 REG_WR(bp
, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC
+ port
*4, 0x1);
328 /* disable the NIG in/out to the bmac */
329 REG_WR(bp
, NIG_REG_BMAC0_IN_EN
+ port
*4, 0x0);
330 REG_WR(bp
, NIG_REG_BMAC0_PAUSE_OUT_EN
+ port
*4, 0x0);
331 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0x0);
333 /* enable the NIG in/out to the emac */
334 REG_WR(bp
, NIG_REG_EMAC0_IN_EN
+ port
*4, 0x1);
336 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
)
339 REG_WR(bp
, NIG_REG_EMAC0_PAUSE_OUT_EN
+ port
*4, val
);
340 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0x1);
342 if (CHIP_REV_IS_EMUL(bp
)) {
343 /* take the BigMac out of reset */
345 GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
346 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
348 /* enable access for bmac registers */
349 REG_WR(bp
, NIG_REG_BMAC0_REGS_OUT_EN
+ port
*4, 0x1);
352 vars
->mac_type
= MAC_TYPE_EMAC
;
358 static u8
bnx2x_bmac_enable(struct link_params
*params
, struct link_vars
*vars
,
361 struct bnx2x
*bp
= params
->bp
;
362 u8 port
= params
->port
;
363 u32 bmac_addr
= port
? NIG_REG_INGRESS_BMAC1_MEM
:
364 NIG_REG_INGRESS_BMAC0_MEM
;
368 DP(NETIF_MSG_LINK
, "Enabling BigMAC\n");
369 /* reset and unreset the BigMac */
370 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
371 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
374 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
375 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
377 /* enable access for bmac registers */
378 REG_WR(bp
, NIG_REG_BMAC0_REGS_OUT_EN
+ port
*4, 0x1);
383 REG_WR_DMAE(bp
, bmac_addr
+
384 BIGMAC_REGISTER_BMAC_XGXS_CONTROL
,
388 wb_data
[0] = ((params
->mac_addr
[2] << 24) |
389 (params
->mac_addr
[3] << 16) |
390 (params
->mac_addr
[4] << 8) |
391 params
->mac_addr
[5]);
392 wb_data
[1] = ((params
->mac_addr
[0] << 8) |
393 params
->mac_addr
[1]);
394 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_TX_SOURCE_ADDR
,
399 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
)
403 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_TX_CONTROL
,
410 DP(NETIF_MSG_LINK
, "enable bmac loopback\n");
414 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_BMAC_CONTROL
,
419 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
421 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_RX_MAX_SIZE
,
424 /* rx control set to don't strip crc */
426 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_RX
)
430 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_RX_CONTROL
,
434 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
436 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_TX_MAX_SIZE
,
439 /* set cnt max size */
440 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
442 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_CNT_MAX_SIZE
,
446 wb_data
[0] = 0x1000200;
448 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_RX_LLFC_MSG_FLDS
,
450 /* fix for emulation */
451 if (CHIP_REV_IS_EMUL(bp
)) {
455 bmac_addr
+ BIGMAC_REGISTER_TX_PAUSE_THRESHOLD
,
459 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+ port
*4, 0x1);
460 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+ port
*4, 0x0);
461 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_PORT
+ port
*4, 0x0);
463 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
)
465 REG_WR(bp
, NIG_REG_BMAC0_PAUSE_OUT_EN
+ port
*4, val
);
466 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0x0);
467 REG_WR(bp
, NIG_REG_EMAC0_IN_EN
+ port
*4, 0x0);
468 REG_WR(bp
, NIG_REG_EMAC0_PAUSE_OUT_EN
+ port
*4, 0x0);
469 REG_WR(bp
, NIG_REG_BMAC0_IN_EN
+ port
*4, 0x1);
470 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0x1);
472 vars
->mac_type
= MAC_TYPE_BMAC
;
476 static void bnx2x_phy_deassert(struct link_params
*params
, u8 phy_flags
)
478 struct bnx2x
*bp
= params
->bp
;
481 if (phy_flags
& PHY_XGXS_FLAG
) {
482 DP(NETIF_MSG_LINK
, "bnx2x_phy_deassert:XGXS\n");
483 val
= XGXS_RESET_BITS
;
485 } else { /* SerDes */
486 DP(NETIF_MSG_LINK
, "bnx2x_phy_deassert:SerDes\n");
487 val
= SERDES_RESET_BITS
;
490 val
= val
<< (params
->port
*16);
492 /* reset and unreset the SerDes/XGXS */
493 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_CLEAR
,
496 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_SET
,
498 bnx2x_set_phy_mdio(params
);
501 void bnx2x_link_status_update(struct link_params
*params
,
502 struct link_vars
*vars
)
504 struct bnx2x
*bp
= params
->bp
;
506 u8 port
= params
->port
;
508 if (params
->switch_cfg
== SWITCH_CFG_1G
)
509 vars
->phy_flags
= PHY_SERDES_FLAG
;
511 vars
->phy_flags
= PHY_XGXS_FLAG
;
512 vars
->link_status
= REG_RD(bp
, params
->shmem_base
+
513 offsetof(struct shmem_region
,
514 port_mb
[port
].link_status
));
516 vars
->link_up
= (vars
->link_status
& LINK_STATUS_LINK_UP
);
519 DP(NETIF_MSG_LINK
, "phy link up\n");
521 vars
->phy_link_up
= 1;
522 vars
->duplex
= DUPLEX_FULL
;
523 switch (vars
->link_status
&
524 LINK_STATUS_SPEED_AND_DUPLEX_MASK
) {
526 vars
->duplex
= DUPLEX_HALF
;
529 vars
->line_speed
= SPEED_10
;
533 vars
->duplex
= DUPLEX_HALF
;
537 vars
->line_speed
= SPEED_100
;
541 vars
->duplex
= DUPLEX_HALF
;
544 vars
->line_speed
= SPEED_1000
;
548 vars
->duplex
= DUPLEX_HALF
;
551 vars
->line_speed
= SPEED_2500
;
555 vars
->line_speed
= SPEED_10000
;
559 vars
->line_speed
= SPEED_12000
;
563 vars
->line_speed
= SPEED_12500
;
567 vars
->line_speed
= SPEED_13000
;
571 vars
->line_speed
= SPEED_15000
;
575 vars
->line_speed
= SPEED_16000
;
582 if (vars
->link_status
& LINK_STATUS_TX_FLOW_CONTROL_ENABLED
)
583 vars
->flow_ctrl
|= BNX2X_FLOW_CTRL_TX
;
585 vars
->flow_ctrl
&= ~BNX2X_FLOW_CTRL_TX
;
587 if (vars
->link_status
& LINK_STATUS_RX_FLOW_CONTROL_ENABLED
)
588 vars
->flow_ctrl
|= BNX2X_FLOW_CTRL_RX
;
590 vars
->flow_ctrl
&= ~BNX2X_FLOW_CTRL_RX
;
592 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
593 if (vars
->line_speed
&&
594 ((vars
->line_speed
== SPEED_10
) ||
595 (vars
->line_speed
== SPEED_100
))) {
596 vars
->phy_flags
|= PHY_SGMII_FLAG
;
598 vars
->phy_flags
&= ~PHY_SGMII_FLAG
;
602 /* anything 10 and over uses the bmac */
603 link_10g
= ((vars
->line_speed
== SPEED_10000
) ||
604 (vars
->line_speed
== SPEED_12000
) ||
605 (vars
->line_speed
== SPEED_12500
) ||
606 (vars
->line_speed
== SPEED_13000
) ||
607 (vars
->line_speed
== SPEED_15000
) ||
608 (vars
->line_speed
== SPEED_16000
));
610 vars
->mac_type
= MAC_TYPE_BMAC
;
612 vars
->mac_type
= MAC_TYPE_EMAC
;
614 } else { /* link down */
615 DP(NETIF_MSG_LINK
, "phy link down\n");
617 vars
->phy_link_up
= 0;
619 vars
->line_speed
= 0;
620 vars
->duplex
= DUPLEX_FULL
;
621 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
623 /* indicate no mac active */
624 vars
->mac_type
= MAC_TYPE_NONE
;
627 DP(NETIF_MSG_LINK
, "link_status 0x%x phy_link_up %x\n",
628 vars
->link_status
, vars
->phy_link_up
);
629 DP(NETIF_MSG_LINK
, "line_speed %x duplex %x flow_ctrl 0x%x\n",
630 vars
->line_speed
, vars
->duplex
, vars
->flow_ctrl
);
633 static void bnx2x_update_mng(struct link_params
*params
, u32 link_status
)
635 struct bnx2x
*bp
= params
->bp
;
636 REG_WR(bp
, params
->shmem_base
+
637 offsetof(struct shmem_region
,
638 port_mb
[params
->port
].link_status
),
642 static void bnx2x_bmac_rx_disable(struct bnx2x
*bp
, u8 port
)
644 u32 bmac_addr
= port
? NIG_REG_INGRESS_BMAC1_MEM
:
645 NIG_REG_INGRESS_BMAC0_MEM
;
647 u32 nig_bmac_enable
= REG_RD(bp
, NIG_REG_BMAC0_REGS_OUT_EN
+ port
*4);
649 /* Only if the bmac is out of reset */
650 if (REG_RD(bp
, MISC_REG_RESET_REG_2
) &
651 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
) &&
654 /* Clear Rx Enable bit in BMAC_CONTROL register */
655 REG_RD_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_BMAC_CONTROL
,
657 wb_data
[0] &= ~BMAC_CONTROL_RX_ENABLE
;
658 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_BMAC_CONTROL
,
665 static u8
bnx2x_pbf_update(struct link_params
*params
, u32 flow_ctrl
,
668 struct bnx2x
*bp
= params
->bp
;
669 u8 port
= params
->port
;
674 REG_WR(bp
, PBF_REG_DISABLE_NEW_TASK_PROC_P0
+ port
*4, 0x1);
676 /* wait for init credit */
677 init_crd
= REG_RD(bp
, PBF_REG_P0_INIT_CRD
+ port
*4);
678 crd
= REG_RD(bp
, PBF_REG_P0_CREDIT
+ port
*8);
679 DP(NETIF_MSG_LINK
, "init_crd 0x%x crd 0x%x\n", init_crd
, crd
);
681 while ((init_crd
!= crd
) && count
) {
684 crd
= REG_RD(bp
, PBF_REG_P0_CREDIT
+ port
*8);
687 crd
= REG_RD(bp
, PBF_REG_P0_CREDIT
+ port
*8);
688 if (init_crd
!= crd
) {
689 DP(NETIF_MSG_LINK
, "BUG! init_crd 0x%x != crd 0x%x\n",
694 if (flow_ctrl
& BNX2X_FLOW_CTRL_RX
||
695 line_speed
== SPEED_10
||
696 line_speed
== SPEED_100
||
697 line_speed
== SPEED_1000
||
698 line_speed
== SPEED_2500
) {
699 REG_WR(bp
, PBF_REG_P0_PAUSE_ENABLE
+ port
*4, 1);
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
+
708 REG_WR(bp
, PBF_REG_P0_PAUSE_ENABLE
+ port
*4, 0);
709 /* update threshold */
710 REG_WR(bp
, PBF_REG_P0_ARB_THRSH
+ port
*4, thresh
);
711 /* update init credit */
712 switch (line_speed
) {
714 init_crd
= thresh
+ 553 - 22;
718 init_crd
= thresh
+ 664 - 22;
722 init_crd
= thresh
+ 742 - 22;
726 init_crd
= thresh
+ 778 - 22;
729 DP(NETIF_MSG_LINK
, "Invalid line_speed 0x%x\n",
735 REG_WR(bp
, PBF_REG_P0_INIT_CRD
+ port
*4, init_crd
);
736 DP(NETIF_MSG_LINK
, "PBF updated to speed %d credit %d\n",
737 line_speed
, init_crd
);
739 /* probe the credit changes */
740 REG_WR(bp
, PBF_REG_INIT_P0
+ port
*4, 0x1);
742 REG_WR(bp
, PBF_REG_INIT_P0
+ port
*4, 0x0);
745 REG_WR(bp
, PBF_REG_DISABLE_NEW_TASK_PROC_P0
+ port
*4, 0x0);
749 static u32
bnx2x_get_emac_base(u32 ext_phy_type
, u8 port
)
752 switch (ext_phy_type
) {
753 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
754 emac_base
= GRCBASE_EMAC0
;
756 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
757 emac_base
= (port
) ? GRCBASE_EMAC0
: GRCBASE_EMAC1
;
760 emac_base
= (port
) ? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
767 u8
bnx2x_cl45_write(struct bnx2x
*bp
, u8 port
, u32 ext_phy_type
,
768 u8 phy_addr
, u8 devad
, u16 reg
, u16 val
)
772 u32 mdio_ctrl
= bnx2x_get_emac_base(ext_phy_type
, port
);
774 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
775 * (a value of 49==0x31) and make sure that the AUTO poll is off
777 saved_mode
= REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
778 tmp
= saved_mode
& ~(EMAC_MDIO_MODE_AUTO_POLL
|
779 EMAC_MDIO_MODE_CLOCK_CNT
);
780 tmp
|= (EMAC_MDIO_MODE_CLAUSE_45
|
781 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT
));
782 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, tmp
);
783 REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
788 tmp
= ((phy_addr
<< 21) | (devad
<< 16) | reg
|
789 EMAC_MDIO_COMM_COMMAND_ADDRESS
|
790 EMAC_MDIO_COMM_START_BUSY
);
791 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, tmp
);
793 for (i
= 0; i
< 50; i
++) {
796 tmp
= REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
);
797 if (!(tmp
& EMAC_MDIO_COMM_START_BUSY
)) {
802 if (tmp
& EMAC_MDIO_COMM_START_BUSY
) {
803 DP(NETIF_MSG_LINK
, "write phy register failed\n");
807 tmp
= ((phy_addr
<< 21) | (devad
<< 16) | val
|
808 EMAC_MDIO_COMM_COMMAND_WRITE_45
|
809 EMAC_MDIO_COMM_START_BUSY
);
810 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, tmp
);
812 for (i
= 0; i
< 50; i
++) {
815 tmp
= REG_RD(bp
, mdio_ctrl
+
816 EMAC_REG_EMAC_MDIO_COMM
);
817 if (!(tmp
& EMAC_MDIO_COMM_START_BUSY
)) {
822 if (tmp
& EMAC_MDIO_COMM_START_BUSY
) {
823 DP(NETIF_MSG_LINK
, "write phy register failed\n");
828 /* Restore the saved mode */
829 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, saved_mode
);
834 u8
bnx2x_cl45_read(struct bnx2x
*bp
, u8 port
, u32 ext_phy_type
,
835 u8 phy_addr
, u8 devad
, u16 reg
, u16
*ret_val
)
841 u32 mdio_ctrl
= bnx2x_get_emac_base(ext_phy_type
, port
);
842 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
843 * (a value of 49==0x31) and make sure that the AUTO poll is off
845 saved_mode
= REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
846 val
= saved_mode
& ((EMAC_MDIO_MODE_AUTO_POLL
|
847 EMAC_MDIO_MODE_CLOCK_CNT
));
848 val
|= (EMAC_MDIO_MODE_CLAUSE_45
|
849 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT
));
850 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, val
);
851 REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
855 val
= ((phy_addr
<< 21) | (devad
<< 16) | reg
|
856 EMAC_MDIO_COMM_COMMAND_ADDRESS
|
857 EMAC_MDIO_COMM_START_BUSY
);
858 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, val
);
860 for (i
= 0; i
< 50; i
++) {
863 val
= REG_RD(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
);
864 if (!(val
& EMAC_MDIO_COMM_START_BUSY
)) {
869 if (val
& EMAC_MDIO_COMM_START_BUSY
) {
870 DP(NETIF_MSG_LINK
, "read phy register failed\n");
877 val
= ((phy_addr
<< 21) | (devad
<< 16) |
878 EMAC_MDIO_COMM_COMMAND_READ_45
|
879 EMAC_MDIO_COMM_START_BUSY
);
880 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, val
);
882 for (i
= 0; i
< 50; i
++) {
885 val
= REG_RD(bp
, mdio_ctrl
+
886 EMAC_REG_EMAC_MDIO_COMM
);
887 if (!(val
& EMAC_MDIO_COMM_START_BUSY
)) {
888 *ret_val
= (u16
)(val
& EMAC_MDIO_COMM_DATA
);
892 if (val
& EMAC_MDIO_COMM_START_BUSY
) {
893 DP(NETIF_MSG_LINK
, "read phy register failed\n");
900 /* Restore the saved mode */
901 REG_WR(bp
, mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, saved_mode
);
906 static void bnx2x_set_aer_mmd(struct link_params
*params
,
907 struct link_vars
*vars
)
909 struct bnx2x
*bp
= params
->bp
;
913 ser_lane
= ((params
->lane_config
&
914 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
915 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
917 offset
= (vars
->phy_flags
& PHY_XGXS_FLAG
) ?
918 (params
->phy_addr
+ ser_lane
) : 0;
920 CL45_WR_OVER_CL22(bp
, params
->port
,
922 MDIO_REG_BANK_AER_BLOCK
,
923 MDIO_AER_BLOCK_AER_REG
, 0x3800 + offset
);
926 static void bnx2x_set_master_ln(struct link_params
*params
)
928 struct bnx2x
*bp
= params
->bp
;
929 u16 new_master_ln
, ser_lane
;
930 ser_lane
= ((params
->lane_config
&
931 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
932 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
934 /* set the master_ln for AN */
935 CL45_RD_OVER_CL22(bp
, params
->port
,
937 MDIO_REG_BANK_XGXS_BLOCK2
,
938 MDIO_XGXS_BLOCK2_TEST_MODE_LANE
,
941 CL45_WR_OVER_CL22(bp
, params
->port
,
943 MDIO_REG_BANK_XGXS_BLOCK2
,
944 MDIO_XGXS_BLOCK2_TEST_MODE_LANE
,
945 (new_master_ln
| ser_lane
));
948 static u8
bnx2x_reset_unicore(struct link_params
*params
)
950 struct bnx2x
*bp
= params
->bp
;
954 CL45_RD_OVER_CL22(bp
, params
->port
,
956 MDIO_REG_BANK_COMBO_IEEE0
,
957 MDIO_COMBO_IEEE0_MII_CONTROL
, &mii_control
);
959 /* reset the unicore */
960 CL45_WR_OVER_CL22(bp
, params
->port
,
962 MDIO_REG_BANK_COMBO_IEEE0
,
963 MDIO_COMBO_IEEE0_MII_CONTROL
,
965 MDIO_COMBO_IEEO_MII_CONTROL_RESET
));
967 /* wait for the reset to self clear */
968 for (i
= 0; i
< MDIO_ACCESS_TIMEOUT
; i
++) {
971 /* the reset erased the previous bank value */
972 CL45_RD_OVER_CL22(bp
, params
->port
,
974 MDIO_REG_BANK_COMBO_IEEE0
,
975 MDIO_COMBO_IEEE0_MII_CONTROL
,
978 if (!(mii_control
& MDIO_COMBO_IEEO_MII_CONTROL_RESET
)) {
984 DP(NETIF_MSG_LINK
, "BUG! XGXS is still in reset!\n");
989 static void bnx2x_set_swap_lanes(struct link_params
*params
)
991 struct bnx2x
*bp
= params
->bp
;
992 /* Each two bits represents a lane number:
993 No swap is 0123 => 0x1b no need to enable the swap */
994 u16 ser_lane
, rx_lane_swap
, tx_lane_swap
;
996 ser_lane
= ((params
->lane_config
&
997 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
998 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
999 rx_lane_swap
= ((params
->lane_config
&
1000 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK
) >>
1001 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT
);
1002 tx_lane_swap
= ((params
->lane_config
&
1003 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK
) >>
1004 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT
);
1006 if (rx_lane_swap
!= 0x1b) {
1007 CL45_WR_OVER_CL22(bp
, params
->port
,
1009 MDIO_REG_BANK_XGXS_BLOCK2
,
1010 MDIO_XGXS_BLOCK2_RX_LN_SWAP
,
1012 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE
|
1013 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE
));
1015 CL45_WR_OVER_CL22(bp
, params
->port
,
1017 MDIO_REG_BANK_XGXS_BLOCK2
,
1018 MDIO_XGXS_BLOCK2_RX_LN_SWAP
, 0);
1021 if (tx_lane_swap
!= 0x1b) {
1022 CL45_WR_OVER_CL22(bp
, params
->port
,
1024 MDIO_REG_BANK_XGXS_BLOCK2
,
1025 MDIO_XGXS_BLOCK2_TX_LN_SWAP
,
1027 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE
));
1029 CL45_WR_OVER_CL22(bp
, params
->port
,
1031 MDIO_REG_BANK_XGXS_BLOCK2
,
1032 MDIO_XGXS_BLOCK2_TX_LN_SWAP
, 0);
1036 static void bnx2x_set_parallel_detection(struct link_params
*params
,
1039 struct bnx2x
*bp
= params
->bp
;
1042 CL45_RD_OVER_CL22(bp
, params
->port
,
1044 MDIO_REG_BANK_SERDES_DIGITAL
,
1045 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2
,
1049 control2
|= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN
;
1052 CL45_WR_OVER_CL22(bp
, params
->port
,
1054 MDIO_REG_BANK_SERDES_DIGITAL
,
1055 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2
,
1058 if (phy_flags
& PHY_XGXS_FLAG
) {
1059 DP(NETIF_MSG_LINK
, "XGXS\n");
1061 CL45_WR_OVER_CL22(bp
, params
->port
,
1063 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
1064 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK
,
1065 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT
);
1067 CL45_RD_OVER_CL22(bp
, params
->port
,
1069 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
1070 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL
,
1075 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN
;
1077 CL45_WR_OVER_CL22(bp
, params
->port
,
1079 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
1080 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL
,
1083 /* Disable parallel detection of HiG */
1084 CL45_WR_OVER_CL22(bp
, params
->port
,
1086 MDIO_REG_BANK_XGXS_BLOCK2
,
1087 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G
,
1088 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS
|
1089 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS
);
1093 static void bnx2x_set_autoneg(struct link_params
*params
,
1094 struct link_vars
*vars
)
1096 struct bnx2x
*bp
= params
->bp
;
1101 CL45_RD_OVER_CL22(bp
, params
->port
,
1103 MDIO_REG_BANK_COMBO_IEEE0
,
1104 MDIO_COMBO_IEEE0_MII_CONTROL
, ®_val
);
1106 /* CL37 Autoneg Enabled */
1107 if (vars
->line_speed
== SPEED_AUTO_NEG
)
1108 reg_val
|= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
;
1109 else /* CL37 Autoneg Disabled */
1110 reg_val
&= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
|
1111 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN
);
1113 CL45_WR_OVER_CL22(bp
, params
->port
,
1115 MDIO_REG_BANK_COMBO_IEEE0
,
1116 MDIO_COMBO_IEEE0_MII_CONTROL
, reg_val
);
1118 /* Enable/Disable Autodetection */
1120 CL45_RD_OVER_CL22(bp
, params
->port
,
1122 MDIO_REG_BANK_SERDES_DIGITAL
,
1123 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
, ®_val
);
1124 reg_val
&= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN
;
1125 if (vars
->line_speed
== SPEED_AUTO_NEG
)
1126 reg_val
|= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET
;
1128 reg_val
&= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET
;
1130 CL45_WR_OVER_CL22(bp
, params
->port
,
1132 MDIO_REG_BANK_SERDES_DIGITAL
,
1133 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
, reg_val
);
1135 /* Enable TetonII and BAM autoneg */
1136 CL45_RD_OVER_CL22(bp
, params
->port
,
1138 MDIO_REG_BANK_BAM_NEXT_PAGE
,
1139 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL
,
1141 if (vars
->line_speed
== SPEED_AUTO_NEG
) {
1142 /* Enable BAM aneg Mode and TetonII aneg Mode */
1143 reg_val
|= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE
|
1144 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN
);
1146 /* TetonII and BAM Autoneg Disabled */
1147 reg_val
&= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE
|
1148 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN
);
1150 CL45_WR_OVER_CL22(bp
, params
->port
,
1152 MDIO_REG_BANK_BAM_NEXT_PAGE
,
1153 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL
,
1156 /* Enable Clause 73 Aneg */
1157 if ((vars
->line_speed
== SPEED_AUTO_NEG
) &&
1159 /* Enable BAM Station Manager */
1161 CL45_WR_OVER_CL22(bp
, params
->port
,
1163 MDIO_REG_BANK_CL73_USERB0
,
1164 MDIO_CL73_USERB0_CL73_BAM_CTRL1
,
1165 (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN
|
1166 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN
|
1167 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN
));
1169 /* Merge CL73 and CL37 aneg resolution */
1170 CL45_RD_OVER_CL22(bp
, params
->port
,
1172 MDIO_REG_BANK_CL73_USERB0
,
1173 MDIO_CL73_USERB0_CL73_BAM_CTRL3
,
1176 CL45_WR_OVER_CL22(bp
, params
->port
,
1178 MDIO_REG_BANK_CL73_USERB0
,
1179 MDIO_CL73_USERB0_CL73_BAM_CTRL3
,
1181 MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR
));
1183 /* Set the CL73 AN speed */
1185 CL45_RD_OVER_CL22(bp
, params
->port
,
1187 MDIO_REG_BANK_CL73_IEEEB1
,
1188 MDIO_CL73_IEEEB1_AN_ADV2
, ®_val
);
1189 /* In the SerDes we support only the 1G.
1190 In the XGXS we support the 10G KX4
1191 but we currently do not support the KR */
1192 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
1193 DP(NETIF_MSG_LINK
, "XGXS\n");
1195 reg_val
|= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4
;
1197 DP(NETIF_MSG_LINK
, "SerDes\n");
1199 reg_val
|= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX
;
1201 CL45_WR_OVER_CL22(bp
, params
->port
,
1203 MDIO_REG_BANK_CL73_IEEEB1
,
1204 MDIO_CL73_IEEEB1_AN_ADV2
, reg_val
);
1206 /* CL73 Autoneg Enabled */
1207 reg_val
= MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN
;
1209 /* CL73 Autoneg Disabled */
1212 CL45_WR_OVER_CL22(bp
, params
->port
,
1214 MDIO_REG_BANK_CL73_IEEEB0
,
1215 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
, reg_val
);
1218 /* program SerDes, forced speed */
1219 static void bnx2x_program_serdes(struct link_params
*params
,
1220 struct link_vars
*vars
)
1222 struct bnx2x
*bp
= params
->bp
;
1225 /* program duplex, disable autoneg */
1227 CL45_RD_OVER_CL22(bp
, params
->port
,
1229 MDIO_REG_BANK_COMBO_IEEE0
,
1230 MDIO_COMBO_IEEE0_MII_CONTROL
, ®_val
);
1231 reg_val
&= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
|
1232 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
);
1233 if (params
->req_duplex
== DUPLEX_FULL
)
1234 reg_val
|= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
;
1235 CL45_WR_OVER_CL22(bp
, params
->port
,
1237 MDIO_REG_BANK_COMBO_IEEE0
,
1238 MDIO_COMBO_IEEE0_MII_CONTROL
, reg_val
);
1241 - needed only if the speed is greater than 1G (2.5G or 10G) */
1242 CL45_RD_OVER_CL22(bp
, params
->port
,
1244 MDIO_REG_BANK_SERDES_DIGITAL
,
1245 MDIO_SERDES_DIGITAL_MISC1
, ®_val
);
1246 /* clearing the speed value before setting the right speed */
1247 DP(NETIF_MSG_LINK
, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val
);
1249 reg_val
&= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK
|
1250 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL
);
1252 if (!((vars
->line_speed
== SPEED_1000
) ||
1253 (vars
->line_speed
== SPEED_100
) ||
1254 (vars
->line_speed
== SPEED_10
))) {
1256 reg_val
|= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M
|
1257 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL
);
1258 if (vars
->line_speed
== SPEED_10000
)
1260 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4
;
1261 if (vars
->line_speed
== SPEED_13000
)
1263 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G
;
1266 CL45_WR_OVER_CL22(bp
, params
->port
,
1268 MDIO_REG_BANK_SERDES_DIGITAL
,
1269 MDIO_SERDES_DIGITAL_MISC1
, reg_val
);
1273 static void bnx2x_set_brcm_cl37_advertisment(struct link_params
*params
)
1275 struct bnx2x
*bp
= params
->bp
;
1278 /* configure the 48 bits for BAM AN */
1280 /* set extended capabilities */
1281 if (params
->speed_cap_mask
& PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G
)
1282 val
|= MDIO_OVER_1G_UP1_2_5G
;
1283 if (params
->speed_cap_mask
& PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)
1284 val
|= MDIO_OVER_1G_UP1_10G
;
1285 CL45_WR_OVER_CL22(bp
, params
->port
,
1287 MDIO_REG_BANK_OVER_1G
,
1288 MDIO_OVER_1G_UP1
, val
);
1290 CL45_WR_OVER_CL22(bp
, params
->port
,
1292 MDIO_REG_BANK_OVER_1G
,
1293 MDIO_OVER_1G_UP3
, 0);
1296 static void bnx2x_calc_ieee_aneg_adv(struct link_params
*params
, u32
*ieee_fc
)
1298 *ieee_fc
= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX
;
1299 /* resolve pause mode and advertisement
1300 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1302 switch (params
->req_flow_ctrl
) {
1303 case BNX2X_FLOW_CTRL_AUTO
:
1304 if (params
->req_fc_auto_adv
== BNX2X_FLOW_CTRL_BOTH
) {
1306 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
1309 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
;
1312 case BNX2X_FLOW_CTRL_TX
:
1314 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
;
1317 case BNX2X_FLOW_CTRL_RX
:
1318 case BNX2X_FLOW_CTRL_BOTH
:
1319 *ieee_fc
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
1322 case BNX2X_FLOW_CTRL_NONE
:
1324 *ieee_fc
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE
;
1329 static void bnx2x_set_ieee_aneg_advertisment(struct link_params
*params
,
1332 struct bnx2x
*bp
= params
->bp
;
1333 /* for AN, we are always publishing full duplex */
1335 CL45_WR_OVER_CL22(bp
, params
->port
,
1337 MDIO_REG_BANK_COMBO_IEEE0
,
1338 MDIO_COMBO_IEEE0_AUTO_NEG_ADV
, (u16
)ieee_fc
);
1341 static void bnx2x_restart_autoneg(struct link_params
*params
)
1343 struct bnx2x
*bp
= params
->bp
;
1344 DP(NETIF_MSG_LINK
, "bnx2x_restart_autoneg\n");
1346 /* enable and restart clause 73 aneg */
1349 CL45_RD_OVER_CL22(bp
, params
->port
,
1351 MDIO_REG_BANK_CL73_IEEEB0
,
1352 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
,
1354 CL45_WR_OVER_CL22(bp
, params
->port
,
1356 MDIO_REG_BANK_CL73_IEEEB0
,
1357 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
,
1359 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN
|
1360 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN
));
1363 /* Enable and restart BAM/CL37 aneg */
1366 CL45_RD_OVER_CL22(bp
, params
->port
,
1368 MDIO_REG_BANK_COMBO_IEEE0
,
1369 MDIO_COMBO_IEEE0_MII_CONTROL
,
1372 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1374 CL45_WR_OVER_CL22(bp
, params
->port
,
1376 MDIO_REG_BANK_COMBO_IEEE0
,
1377 MDIO_COMBO_IEEE0_MII_CONTROL
,
1379 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
|
1380 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN
));
1384 static void bnx2x_initialize_sgmii_process(struct link_params
*params
,
1385 struct link_vars
*vars
)
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 (!(vars
->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 (vars
->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 line_speed 0x%x\n",
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
= BNX2X_FLOW_CTRL_TX
;
1469 case 0xe: /* 1 1 1 0 */
1470 vars
->flow_ctrl
= BNX2X_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
= BNX2X_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
);
1534 if (vars
->flow_ctrl
== BNX2X_FLOW_CTRL_NONE
&&
1535 ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
1536 bnx2x_cl45_read(bp
, port
,
1540 MDIO_AN_REG_CL37_FC_LD
, &ld_pause
);
1542 bnx2x_cl45_read(bp
, port
,
1546 MDIO_AN_REG_CL37_FC_LP
, &lp_pause
);
1547 pause_result
= (ld_pause
&
1548 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) >> 5;
1549 pause_result
|= (lp_pause
&
1550 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) >> 7;
1552 bnx2x_pause_resolve(vars
, pause_result
);
1553 DP(NETIF_MSG_LINK
, "Ext PHY CL37 pause result 0x%x \n",
1561 static void bnx2x_flow_ctrl_resolve(struct link_params
*params
,
1562 struct link_vars
*vars
,
1565 struct bnx2x
*bp
= params
->bp
;
1566 u16 ld_pause
; /* local driver */
1567 u16 lp_pause
; /* link partner */
1570 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
1572 /* resolve from gp_status in case of AN complete and not sgmii */
1573 if ((params
->req_flow_ctrl
== BNX2X_FLOW_CTRL_AUTO
) &&
1574 (gp_status
& MDIO_AN_CL73_OR_37_COMPLETE
) &&
1575 (!(vars
->phy_flags
& PHY_SGMII_FLAG
)) &&
1576 (XGXS_EXT_PHY_TYPE(params
->ext_phy_config
) ==
1577 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
)) {
1578 CL45_RD_OVER_CL22(bp
, params
->port
,
1580 MDIO_REG_BANK_COMBO_IEEE0
,
1581 MDIO_COMBO_IEEE0_AUTO_NEG_ADV
,
1583 CL45_RD_OVER_CL22(bp
, params
->port
,
1585 MDIO_REG_BANK_COMBO_IEEE0
,
1586 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1
,
1588 pause_result
= (ld_pause
&
1589 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK
)>>5;
1590 pause_result
|= (lp_pause
&
1591 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK
)>>7;
1592 DP(NETIF_MSG_LINK
, "pause_result 0x%x\n", pause_result
);
1593 bnx2x_pause_resolve(vars
, pause_result
);
1594 } else if ((params
->req_flow_ctrl
== BNX2X_FLOW_CTRL_AUTO
) &&
1595 (bnx2x_ext_phy_resove_fc(params
, vars
))) {
1598 if (params
->req_flow_ctrl
== BNX2X_FLOW_CTRL_AUTO
)
1599 vars
->flow_ctrl
= params
->req_fc_auto_adv
;
1601 vars
->flow_ctrl
= params
->req_flow_ctrl
;
1603 DP(NETIF_MSG_LINK
, "flow_ctrl 0x%x\n", vars
->flow_ctrl
);
1607 static u8
bnx2x_link_settings_status(struct link_params
*params
,
1608 struct link_vars
*vars
,
1611 struct bnx2x
*bp
= params
->bp
;
1614 vars
->link_status
= 0;
1616 if (gp_status
& MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS
) {
1617 DP(NETIF_MSG_LINK
, "phy link up gp_status=0x%x\n",
1620 vars
->phy_link_up
= 1;
1621 vars
->link_status
|= LINK_STATUS_LINK_UP
;
1623 if (gp_status
& MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS
)
1624 vars
->duplex
= DUPLEX_FULL
;
1626 vars
->duplex
= DUPLEX_HALF
;
1628 bnx2x_flow_ctrl_resolve(params
, vars
, gp_status
);
1630 switch (gp_status
& GP_STATUS_SPEED_MASK
) {
1632 vars
->line_speed
= SPEED_10
;
1633 if (vars
->duplex
== DUPLEX_FULL
)
1634 vars
->link_status
|= LINK_10TFD
;
1636 vars
->link_status
|= LINK_10THD
;
1639 case GP_STATUS_100M
:
1640 vars
->line_speed
= SPEED_100
;
1641 if (vars
->duplex
== DUPLEX_FULL
)
1642 vars
->link_status
|= LINK_100TXFD
;
1644 vars
->link_status
|= LINK_100TXHD
;
1648 case GP_STATUS_1G_KX
:
1649 vars
->line_speed
= SPEED_1000
;
1650 if (vars
->duplex
== DUPLEX_FULL
)
1651 vars
->link_status
|= LINK_1000TFD
;
1653 vars
->link_status
|= LINK_1000THD
;
1656 case GP_STATUS_2_5G
:
1657 vars
->line_speed
= SPEED_2500
;
1658 if (vars
->duplex
== DUPLEX_FULL
)
1659 vars
->link_status
|= LINK_2500TFD
;
1661 vars
->link_status
|= LINK_2500THD
;
1667 "link speed unsupported gp_status 0x%x\n",
1671 case GP_STATUS_10G_KX4
:
1672 case GP_STATUS_10G_HIG
:
1673 case GP_STATUS_10G_CX4
:
1674 vars
->line_speed
= SPEED_10000
;
1675 vars
->link_status
|= LINK_10GTFD
;
1678 case GP_STATUS_12G_HIG
:
1679 vars
->line_speed
= SPEED_12000
;
1680 vars
->link_status
|= LINK_12GTFD
;
1683 case GP_STATUS_12_5G
:
1684 vars
->line_speed
= SPEED_12500
;
1685 vars
->link_status
|= LINK_12_5GTFD
;
1689 vars
->line_speed
= SPEED_13000
;
1690 vars
->link_status
|= LINK_13GTFD
;
1694 vars
->line_speed
= SPEED_15000
;
1695 vars
->link_status
|= LINK_15GTFD
;
1699 vars
->line_speed
= SPEED_16000
;
1700 vars
->link_status
|= LINK_16GTFD
;
1705 "link speed unsupported gp_status 0x%x\n",
1711 vars
->link_status
|= LINK_STATUS_SERDES_LINK
;
1713 if ((params
->req_line_speed
== SPEED_AUTO_NEG
) &&
1714 ((XGXS_EXT_PHY_TYPE(params
->ext_phy_config
) ==
1715 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) ||
1716 (XGXS_EXT_PHY_TYPE(params
->ext_phy_config
) ==
1717 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
))) {
1718 vars
->autoneg
= AUTO_NEG_ENABLED
;
1720 if (gp_status
& MDIO_AN_CL73_OR_37_COMPLETE
) {
1721 vars
->autoneg
|= AUTO_NEG_COMPLETE
;
1722 vars
->link_status
|=
1723 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE
;
1726 vars
->autoneg
|= AUTO_NEG_PARALLEL_DETECTION_USED
;
1727 vars
->link_status
|=
1728 LINK_STATUS_PARALLEL_DETECTION_USED
;
1731 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
)
1732 vars
->link_status
|=
1733 LINK_STATUS_TX_FLOW_CONTROL_ENABLED
;
1735 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_RX
)
1736 vars
->link_status
|=
1737 LINK_STATUS_RX_FLOW_CONTROL_ENABLED
;
1739 } else { /* link_down */
1740 DP(NETIF_MSG_LINK
, "phy link down\n");
1742 vars
->phy_link_up
= 0;
1744 vars
->duplex
= DUPLEX_FULL
;
1745 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
1746 vars
->autoneg
= AUTO_NEG_DISABLED
;
1747 vars
->mac_type
= MAC_TYPE_NONE
;
1750 DP(NETIF_MSG_LINK
, "gp_status 0x%x phy_link_up %x line_speed %x \n",
1751 gp_status
, vars
->phy_link_up
, vars
->line_speed
);
1752 DP(NETIF_MSG_LINK
, "duplex %x flow_ctrl 0x%x"
1755 vars
->flow_ctrl
, vars
->autoneg
);
1756 DP(NETIF_MSG_LINK
, "link_status 0x%x\n", vars
->link_status
);
1761 static void bnx2x_set_sgmii_tx_driver(struct link_params
*params
)
1763 struct bnx2x
*bp
= params
->bp
;
1769 CL45_RD_OVER_CL22(bp
, params
->port
,
1771 MDIO_REG_BANK_OVER_1G
,
1772 MDIO_OVER_1G_LP_UP2
, &lp_up2
);
1774 CL45_RD_OVER_CL22(bp
, params
->port
,
1777 MDIO_TX0_TX_DRIVER
, &tx_driver
);
1779 /* bits [10:7] at lp_up2, positioned at [15:12] */
1780 lp_up2
= (((lp_up2
& MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK
) >>
1781 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT
) <<
1782 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT
);
1784 if ((lp_up2
!= 0) &&
1785 (lp_up2
!= (tx_driver
& MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK
))) {
1786 /* replace tx_driver bits [15:12] */
1787 tx_driver
&= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK
;
1788 tx_driver
|= lp_up2
;
1789 CL45_WR_OVER_CL22(bp
, params
->port
,
1792 MDIO_TX0_TX_DRIVER
, tx_driver
);
1796 static u8
bnx2x_emac_program(struct link_params
*params
,
1797 u32 line_speed
, u32 duplex
)
1799 struct bnx2x
*bp
= params
->bp
;
1800 u8 port
= params
->port
;
1803 DP(NETIF_MSG_LINK
, "setting link speed & duplex\n");
1804 bnx2x_bits_dis(bp
, GRCBASE_EMAC0
+ port
*0x400 +
1806 (EMAC_MODE_25G_MODE
|
1807 EMAC_MODE_PORT_MII_10M
|
1808 EMAC_MODE_HALF_DUPLEX
));
1809 switch (line_speed
) {
1811 mode
|= EMAC_MODE_PORT_MII_10M
;
1815 mode
|= EMAC_MODE_PORT_MII
;
1819 mode
|= EMAC_MODE_PORT_GMII
;
1823 mode
|= (EMAC_MODE_25G_MODE
| EMAC_MODE_PORT_GMII
);
1827 /* 10G not valid for EMAC */
1828 DP(NETIF_MSG_LINK
, "Invalid line_speed 0x%x\n", line_speed
);
1832 if (duplex
== DUPLEX_HALF
)
1833 mode
|= EMAC_MODE_HALF_DUPLEX
;
1835 GRCBASE_EMAC0
+ port
*0x400 + EMAC_REG_EMAC_MODE
,
1838 bnx2x_set_led(bp
, params
->port
, LED_MODE_OPER
,
1839 line_speed
, params
->hw_led_mode
, params
->chip_id
);
1843 /*****************************************************************************/
1844 /* External Phy section */
1845 /*****************************************************************************/
1846 static void bnx2x_hw_reset(struct bnx2x
*bp
, u8 port
)
1848 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
1849 MISC_REGISTERS_GPIO_OUTPUT_LOW
, port
);
1851 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
1852 MISC_REGISTERS_GPIO_OUTPUT_HIGH
, port
);
1855 static void bnx2x_ext_phy_reset(struct link_params
*params
,
1856 struct link_vars
*vars
)
1858 struct bnx2x
*bp
= params
->bp
;
1860 u8 ext_phy_addr
= ((params
->ext_phy_config
&
1861 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
1862 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
1863 DP(NETIF_MSG_LINK
, "Port %x: bnx2x_ext_phy_reset\n", params
->port
);
1864 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
1865 /* The PHY reset is controled by GPIO 1
1866 * Give it 1ms of reset pulse
1868 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
1870 switch (ext_phy_type
) {
1871 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
1872 DP(NETIF_MSG_LINK
, "XGXS Direct\n");
1875 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
1876 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
1877 DP(NETIF_MSG_LINK
, "XGXS 8705/8706\n");
1879 /* Restore normal power mode*/
1880 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
1881 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
1885 bnx2x_hw_reset(bp
, params
->port
);
1887 bnx2x_cl45_write(bp
, params
->port
,
1891 MDIO_PMA_REG_CTRL
, 0xa040);
1893 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
1894 /* Unset Low Power Mode and SW reset */
1895 /* Restore normal power mode*/
1896 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
1897 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
1900 DP(NETIF_MSG_LINK
, "XGXS 8072\n");
1901 bnx2x_cl45_write(bp
, params
->port
,
1908 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
1911 emac_base
= (params
->port
) ? GRCBASE_EMAC0
:
1914 /* Restore normal power mode*/
1915 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
1916 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
1919 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
1920 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
1923 DP(NETIF_MSG_LINK
, "XGXS 8073\n");
1927 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
1928 DP(NETIF_MSG_LINK
, "XGXS SFX7101\n");
1930 /* Restore normal power mode*/
1931 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
1932 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
1936 bnx2x_hw_reset(bp
, params
->port
);
1940 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
1941 DP(NETIF_MSG_LINK
, "XGXS PHY Failure detected\n");
1945 DP(NETIF_MSG_LINK
, "BAD XGXS ext_phy_config 0x%x\n",
1946 params
->ext_phy_config
);
1950 } else { /* SerDes */
1951 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
1952 switch (ext_phy_type
) {
1953 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
:
1954 DP(NETIF_MSG_LINK
, "SerDes Direct\n");
1957 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482
:
1958 DP(NETIF_MSG_LINK
, "SerDes 5482\n");
1959 bnx2x_hw_reset(bp
, params
->port
);
1964 "BAD SerDes ext_phy_config 0x%x\n",
1965 params
->ext_phy_config
);
1971 static void bnx2x_bcm8072_external_rom_boot(struct link_params
*params
)
1973 struct bnx2x
*bp
= params
->bp
;
1974 u8 port
= params
->port
;
1975 u8 ext_phy_addr
= ((params
->ext_phy_config
&
1976 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
1977 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
1978 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
1979 u16 fw_ver1
, fw_ver2
;
1981 /* Need to wait 200ms after reset */
1983 /* Boot port from external ROM
1984 * Set ser_boot_ctl bit in the MISC_CTRL1 register
1986 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
1988 MDIO_PMA_REG_MISC_CTRL1
, 0x0001);
1990 /* Reset internal microprocessor */
1991 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
1993 MDIO_PMA_REG_GEN_CTRL
,
1994 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP
);
1995 /* set micro reset = 0 */
1996 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
1998 MDIO_PMA_REG_GEN_CTRL
,
1999 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET
);
2000 /* Reset internal microprocessor */
2001 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2003 MDIO_PMA_REG_GEN_CTRL
,
2004 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP
);
2005 /* wait for 100ms for code download via SPI port */
2008 /* Clear ser_boot_ctl bit */
2009 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2011 MDIO_PMA_REG_MISC_CTRL1
, 0x0000);
2015 /* Print the PHY FW version */
2016 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
2018 MDIO_PMA_REG_ROM_VER1
, &fw_ver1
);
2019 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
2021 MDIO_PMA_REG_ROM_VER2
, &fw_ver2
);
2022 DP(NETIF_MSG_LINK
, "8072 FW version 0x%x:0x%x\n", fw_ver1
, fw_ver2
);
2025 static u8
bnx2x_8073_is_snr_needed(struct link_params
*params
)
2027 /* This is only required for 8073A1, version 102 only */
2029 struct bnx2x
*bp
= params
->bp
;
2030 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2031 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2032 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2035 /* Read 8073 HW revision*/
2036 bnx2x_cl45_read(bp
, params
->port
,
2037 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2043 /* No need to workaround in 8073 A1 */
2047 bnx2x_cl45_read(bp
, params
->port
,
2048 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2051 MDIO_PMA_REG_ROM_VER2
, &val
);
2053 /* SNR should be applied only for version 0x102 */
2060 static u8
bnx2x_bcm8073_xaui_wa(struct link_params
*params
)
2062 struct bnx2x
*bp
= params
->bp
;
2063 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2064 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2065 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2066 u16 val
, cnt
, cnt1
;
2068 bnx2x_cl45_read(bp
, params
->port
,
2069 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2075 /* No need to workaround in 8073 A1 */
2078 /* XAUI workaround in 8073 A0: */
2080 /* After loading the boot ROM and restarting Autoneg,
2081 poll Dev1, Reg $C820: */
2083 for (cnt
= 0; cnt
< 1000; cnt
++) {
2084 bnx2x_cl45_read(bp
, params
->port
,
2085 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2089 /* If bit [14] = 0 or bit [13] = 0, continue on with
2090 system initialization (XAUI work-around not required,
2091 as these bits indicate 2.5G or 1G link up). */
2092 if (!(val
& (1<<14)) || !(val
& (1<<13))) {
2093 DP(NETIF_MSG_LINK
, "XAUI work-around not required\n");
2095 } else if (!(val
& (1<<15))) {
2096 DP(NETIF_MSG_LINK
, "clc bit 15 went off\n");
2097 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2098 it's MSB (bit 15) goes to 1 (indicating that the
2099 XAUI workaround has completed),
2100 then continue on with system initialization.*/
2101 for (cnt1
= 0; cnt1
< 1000; cnt1
++) {
2102 bnx2x_cl45_read(bp
, params
->port
,
2103 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2107 if (val
& (1<<15)) {
2109 "XAUI workaround has completed\n");
2118 DP(NETIF_MSG_LINK
, "Warning: XAUI work-around timeout !!!\n");
2123 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x
*bp
, u8 port
,
2126 u16 fw_ver1
, fw_ver2
;
2127 /* Boot port from external ROM */
2129 bnx2x_cl45_write(bp
, port
,
2130 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2133 MDIO_PMA_REG_GEN_CTRL
,
2136 /* ucode reboot and rst */
2137 bnx2x_cl45_write(bp
, port
,
2138 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2141 MDIO_PMA_REG_GEN_CTRL
,
2144 bnx2x_cl45_write(bp
, port
,
2145 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2148 MDIO_PMA_REG_MISC_CTRL1
, 0x0001);
2150 /* Reset internal microprocessor */
2151 bnx2x_cl45_write(bp
, port
,
2152 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2155 MDIO_PMA_REG_GEN_CTRL
,
2156 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET
);
2158 /* Release srst bit */
2159 bnx2x_cl45_write(bp
, port
,
2160 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2163 MDIO_PMA_REG_GEN_CTRL
,
2164 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP
);
2166 /* wait for 100ms for code download via SPI port */
2169 /* Clear ser_boot_ctl bit */
2170 bnx2x_cl45_write(bp
, port
,
2171 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2174 MDIO_PMA_REG_MISC_CTRL1
, 0x0000);
2176 bnx2x_cl45_read(bp
, port
, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2179 MDIO_PMA_REG_ROM_VER1
, &fw_ver1
);
2180 bnx2x_cl45_read(bp
, port
,
2181 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2184 MDIO_PMA_REG_ROM_VER2
, &fw_ver2
);
2185 DP(NETIF_MSG_LINK
, "8073 FW version 0x%x:0x%x\n", fw_ver1
, fw_ver2
);
2189 static void bnx2x_bcm807x_force_10G(struct link_params
*params
)
2191 struct bnx2x
*bp
= params
->bp
;
2192 u8 port
= params
->port
;
2193 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2194 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2195 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2196 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2198 /* Force KR or KX */
2199 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2203 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2205 MDIO_PMA_REG_10G_CTRL2
,
2207 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2209 MDIO_PMA_REG_BCM_CTRL
,
2211 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2216 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params
*params
)
2218 struct bnx2x
*bp
= params
->bp
;
2219 u8 port
= params
->port
;
2221 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2222 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2223 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2224 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2226 bnx2x_cl45_read(bp
, params
->port
,
2227 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2233 /* Mustn't set low power mode in 8073 A0 */
2237 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2238 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
2240 MDIO_XS_PLL_SEQUENCER
, &val
);
2242 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2243 MDIO_XS_DEVAD
, MDIO_XS_PLL_SEQUENCER
, val
);
2246 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2247 MDIO_XS_DEVAD
, 0x805E, 0x1077);
2248 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2249 MDIO_XS_DEVAD
, 0x805D, 0x0000);
2250 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2251 MDIO_XS_DEVAD
, 0x805C, 0x030B);
2252 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2253 MDIO_XS_DEVAD
, 0x805B, 0x1240);
2254 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2255 MDIO_XS_DEVAD
, 0x805A, 0x2490);
2258 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2259 MDIO_XS_DEVAD
, 0x80A7, 0x0C74);
2260 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2261 MDIO_XS_DEVAD
, 0x80A6, 0x9041);
2262 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2263 MDIO_XS_DEVAD
, 0x80A5, 0x4640);
2266 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2267 MDIO_XS_DEVAD
, 0x80FE, 0x01C4);
2268 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2269 MDIO_XS_DEVAD
, 0x80FD, 0x9249);
2270 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2271 MDIO_XS_DEVAD
, 0x80FC, 0x2015);
2273 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
2274 bnx2x_cl45_read(bp
, port
, ext_phy_type
, ext_phy_addr
,
2276 MDIO_XS_PLL_SEQUENCER
, &val
);
2278 bnx2x_cl45_write(bp
, port
, ext_phy_type
, ext_phy_addr
,
2279 MDIO_XS_DEVAD
, MDIO_XS_PLL_SEQUENCER
, val
);
2282 static void bnx2x_8073_set_pause_cl37(struct link_params
*params
,
2283 struct link_vars
*vars
)
2286 struct bnx2x
*bp
= params
->bp
;
2288 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2289 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2290 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2291 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2293 bnx2x_cl45_read(bp
, params
->port
,
2297 MDIO_AN_REG_CL37_FC_LD
, &cl37_val
);
2299 cl37_val
&= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
2300 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2302 if ((vars
->ieee_fc
&
2303 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC
) ==
2304 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC
) {
2305 cl37_val
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC
;
2307 if ((vars
->ieee_fc
&
2308 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) ==
2309 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) {
2310 cl37_val
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
;
2312 if ((vars
->ieee_fc
&
2313 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) ==
2314 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) {
2315 cl37_val
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
2318 "Ext phy AN advertize cl37 0x%x\n", cl37_val
);
2320 bnx2x_cl45_write(bp
, params
->port
,
2324 MDIO_AN_REG_CL37_FC_LD
, cl37_val
);
2328 static void bnx2x_ext_phy_set_pause(struct link_params
*params
,
2329 struct link_vars
*vars
)
2331 struct bnx2x
*bp
= params
->bp
;
2333 u8 ext_phy_addr
= ((params
->ext_phy_config
&
2334 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2335 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2336 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2338 /* read modify write pause advertizing */
2339 bnx2x_cl45_read(bp
, params
->port
,
2343 MDIO_AN_REG_ADV_PAUSE
, &val
);
2345 val
&= ~MDIO_AN_REG_ADV_PAUSE_BOTH
;
2347 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2349 if ((vars
->ieee_fc
&
2350 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) ==
2351 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) {
2352 val
|= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC
;
2354 if ((vars
->ieee_fc
&
2355 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) ==
2356 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) {
2358 MDIO_AN_REG_ADV_PAUSE_PAUSE
;
2361 "Ext phy AN advertize 0x%x\n", val
);
2362 bnx2x_cl45_write(bp
, params
->port
,
2366 MDIO_AN_REG_ADV_PAUSE
, val
);
2370 static void bnx2x_init_internal_phy(struct link_params
*params
,
2371 struct link_vars
*vars
)
2373 struct bnx2x
*bp
= params
->bp
;
2374 u8 port
= params
->port
;
2375 if (!(vars
->phy_flags
& PHY_SGMII_FLAG
)) {
2378 rx_eq
= ((params
->serdes_config
&
2379 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK
) >>
2380 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT
);
2382 DP(NETIF_MSG_LINK
, "setting rx eq to 0x%x\n", rx_eq
);
2383 for (bank
= MDIO_REG_BANK_RX0
; bank
<= MDIO_REG_BANK_RX_ALL
;
2384 bank
+= (MDIO_REG_BANK_RX1
-MDIO_REG_BANK_RX0
)) {
2385 CL45_WR_OVER_CL22(bp
, port
,
2388 MDIO_RX0_RX_EQ_BOOST
,
2390 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK
) |
2391 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL
));
2394 /* forced speed requested? */
2395 if (vars
->line_speed
!= SPEED_AUTO_NEG
) {
2396 DP(NETIF_MSG_LINK
, "not SGMII, no AN\n");
2398 /* disable autoneg */
2399 bnx2x_set_autoneg(params
, vars
);
2401 /* program speed and duplex */
2402 bnx2x_program_serdes(params
, vars
);
2404 } else { /* AN_mode */
2405 DP(NETIF_MSG_LINK
, "not SGMII, AN\n");
2408 bnx2x_set_brcm_cl37_advertisment(params
);
2410 /* program duplex & pause advertisement (for aneg) */
2411 bnx2x_set_ieee_aneg_advertisment(params
,
2414 /* enable autoneg */
2415 bnx2x_set_autoneg(params
, vars
);
2417 /* enable and restart AN */
2418 bnx2x_restart_autoneg(params
);
2421 } else { /* SGMII mode */
2422 DP(NETIF_MSG_LINK
, "SGMII\n");
2424 bnx2x_initialize_sgmii_process(params
, vars
);
2428 static u8
bnx2x_ext_phy_init(struct link_params
*params
, struct link_vars
*vars
)
2430 struct bnx2x
*bp
= params
->bp
;
2437 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
2438 ext_phy_addr
= ((params
->ext_phy_config
&
2439 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2440 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2442 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2443 /* Make sure that the soft reset is off (expect for the 8072:
2444 * due to the lock, it will be done inside the specific
2447 if ((ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) &&
2448 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
) &&
2449 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
) &&
2450 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
) &&
2451 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
)) {
2452 /* Wait for soft reset to get cleared upto 1 sec */
2453 for (cnt
= 0; cnt
< 1000; cnt
++) {
2454 bnx2x_cl45_read(bp
, params
->port
,
2458 MDIO_PMA_REG_CTRL
, &ctrl
);
2459 if (!(ctrl
& (1<<15)))
2463 DP(NETIF_MSG_LINK
, "control reg 0x%x (after %d ms)\n",
2467 switch (ext_phy_type
) {
2468 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
2471 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
2472 DP(NETIF_MSG_LINK
, "XGXS 8705\n");
2474 bnx2x_cl45_write(bp
, params
->port
,
2478 MDIO_PMA_REG_MISC_CTRL
,
2480 bnx2x_cl45_write(bp
, params
->port
,
2484 MDIO_PMA_REG_PHY_IDENTIFIER
,
2486 bnx2x_cl45_write(bp
, params
->port
,
2490 MDIO_PMA_REG_CMU_PLL_BYPASS
,
2492 bnx2x_cl45_write(bp
, params
->port
,
2496 MDIO_WIS_REG_LASI_CNTL
, 0x1);
2499 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
2500 DP(NETIF_MSG_LINK
, "XGXS 8706\n");
2504 /* First enable LASI */
2505 bnx2x_cl45_write(bp
, params
->port
,
2509 MDIO_PMA_REG_RX_ALARM_CTRL
,
2511 bnx2x_cl45_write(bp
, params
->port
,
2515 MDIO_PMA_REG_LASI_CTRL
, 0x0004);
2517 if (params
->req_line_speed
== SPEED_10000
) {
2518 DP(NETIF_MSG_LINK
, "XGXS 8706 force 10Gbps\n");
2520 bnx2x_cl45_write(bp
, params
->port
,
2524 MDIO_PMA_REG_DIGITAL_CTRL
,
2527 /* Force 1Gbps using autoneg with 1G
2530 /* Allow CL37 through CL73 */
2531 DP(NETIF_MSG_LINK
, "XGXS 8706 AutoNeg\n");
2532 bnx2x_cl45_write(bp
, params
->port
,
2536 MDIO_AN_REG_CL37_CL73
,
2539 /* Enable Full-Duplex advertisment on CL37 */
2540 bnx2x_cl45_write(bp
, params
->port
,
2544 MDIO_AN_REG_CL37_FC_LP
,
2546 /* Enable CL37 AN */
2547 bnx2x_cl45_write(bp
, params
->port
,
2551 MDIO_AN_REG_CL37_AN
,
2554 bnx2x_cl45_write(bp
, params
->port
,
2558 MDIO_AN_REG_ADV
, (1<<5));
2560 /* Enable clause 73 AN */
2561 bnx2x_cl45_write(bp
, params
->port
,
2572 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
2573 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
2576 u16 rx_alarm_ctrl_val
;
2579 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
) {
2580 rx_alarm_ctrl_val
= 0x400;
2581 lasi_ctrl_val
= 0x0004;
2583 rx_alarm_ctrl_val
= (1<<2);
2584 lasi_ctrl_val
= 0x0004;
2588 bnx2x_cl45_write(bp
, params
->port
,
2592 MDIO_PMA_REG_RX_ALARM_CTRL
,
2595 bnx2x_cl45_write(bp
, params
->port
,
2599 MDIO_PMA_REG_LASI_CTRL
,
2602 bnx2x_8073_set_pause_cl37(params
, vars
);
2605 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
){
2606 bnx2x_bcm8072_external_rom_boot(params
);
2609 /* In case of 8073 with long xaui lines,
2610 don't set the 8073 xaui low power*/
2611 bnx2x_bcm8073_set_xaui_low_power_mode(params
);
2614 bnx2x_cl45_read(bp
, params
->port
,
2621 bnx2x_cl45_read(bp
, params
->port
,
2625 MDIO_PMA_REG_RX_ALARM
, &tmp1
);
2627 DP(NETIF_MSG_LINK
, "Before rom RX_ALARM(port1):"
2630 /* If this is forced speed, set to KR or KX
2631 * (all other are not supported)
2633 if (params
->loopback_mode
== LOOPBACK_EXT
) {
2634 bnx2x_bcm807x_force_10G(params
);
2636 "Forced speed 10G on 807X\n");
2639 bnx2x_cl45_write(bp
, params
->port
,
2640 ext_phy_type
, ext_phy_addr
,
2642 MDIO_PMA_REG_BCM_CTRL
,
2645 if (params
->req_line_speed
!= SPEED_AUTO_NEG
) {
2646 if (params
->req_line_speed
== SPEED_10000
) {
2648 } else if (params
->req_line_speed
==
2651 /* Note that 2.5G works only
2652 when used with 1G advertisment */
2658 if (params
->speed_cap_mask
&
2659 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)
2662 /* Note that 2.5G works only when
2663 used with 1G advertisment */
2664 if (params
->speed_cap_mask
&
2665 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
|
2666 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G
))
2669 "807x autoneg val = 0x%x\n", val
);
2672 bnx2x_cl45_write(bp
, params
->port
,
2676 MDIO_AN_REG_ADV
, val
);
2679 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
2681 bnx2x_cl45_read(bp
, params
->port
,
2687 if (((params
->speed_cap_mask
&
2688 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G
) &&
2689 (params
->req_line_speed
==
2691 (params
->req_line_speed
==
2694 /* Allow 2.5G for A1 and above */
2695 bnx2x_cl45_read(bp
, params
->port
,
2696 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
2700 DP(NETIF_MSG_LINK
, "Add 2.5G\n");
2706 DP(NETIF_MSG_LINK
, "Disable 2.5G\n");
2710 bnx2x_cl45_write(bp
, params
->port
,
2717 /* Add support for CL37 (passive mode) II */
2719 bnx2x_cl45_read(bp
, params
->port
,
2723 MDIO_AN_REG_CL37_FC_LD
,
2726 bnx2x_cl45_write(bp
, params
->port
,
2730 MDIO_AN_REG_CL37_FC_LD
, (tmp1
|
2731 ((params
->req_duplex
== DUPLEX_FULL
) ?
2734 /* Add support for CL37 (passive mode) III */
2735 bnx2x_cl45_write(bp
, params
->port
,
2739 MDIO_AN_REG_CL37_AN
, 0x1000);
2742 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
2743 /* The SNR will improve about 2db by changing
2744 BW and FEE main tap. Rest commands are executed
2746 /*Change FFE main cursor to 5 in EDC register*/
2747 if (bnx2x_8073_is_snr_needed(params
))
2748 bnx2x_cl45_write(bp
, params
->port
,
2752 MDIO_PMA_REG_EDC_FFE_MAIN
,
2755 /* Enable FEC (Forware Error Correction)
2756 Request in the AN */
2757 bnx2x_cl45_read(bp
, params
->port
,
2761 MDIO_AN_REG_ADV2
, &tmp1
);
2765 bnx2x_cl45_write(bp
, params
->port
,
2769 MDIO_AN_REG_ADV2
, tmp1
);
2773 bnx2x_ext_phy_set_pause(params
, vars
);
2775 /* Restart autoneg */
2777 bnx2x_cl45_write(bp
, params
->port
,
2781 MDIO_AN_REG_CTRL
, 0x1200);
2782 DP(NETIF_MSG_LINK
, "807x Autoneg Restart: "
2783 "Advertise 1G=%x, 10G=%x\n",
2784 ((val
& (1<<5)) > 0),
2785 ((val
& (1<<7)) > 0));
2788 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
2790 "Setting the SFX7101 LASI indication\n");
2792 bnx2x_cl45_write(bp
, params
->port
,
2796 MDIO_PMA_REG_LASI_CTRL
, 0x1);
2798 "Setting the SFX7101 LED to blink on traffic\n");
2799 bnx2x_cl45_write(bp
, params
->port
,
2803 MDIO_PMA_REG_7107_LED_CNTL
, (1<<3));
2805 bnx2x_ext_phy_set_pause(params
, vars
);
2806 /* Restart autoneg */
2807 bnx2x_cl45_read(bp
, params
->port
,
2811 MDIO_AN_REG_CTRL
, &val
);
2813 bnx2x_cl45_write(bp
, params
->port
,
2817 MDIO_AN_REG_CTRL
, val
);
2819 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
2821 "XGXS PHY Failure detected 0x%x\n",
2822 params
->ext_phy_config
);
2826 DP(NETIF_MSG_LINK
, "BAD XGXS ext_phy_config 0x%x\n",
2827 params
->ext_phy_config
);
2832 } else { /* SerDes */
2834 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
2835 switch (ext_phy_type
) {
2836 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
:
2837 DP(NETIF_MSG_LINK
, "SerDes Direct\n");
2840 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482
:
2841 DP(NETIF_MSG_LINK
, "SerDes 5482\n");
2845 DP(NETIF_MSG_LINK
, "BAD SerDes ext_phy_config 0x%x\n",
2846 params
->ext_phy_config
);
2854 static u8
bnx2x_ext_phy_is_link_up(struct link_params
*params
,
2855 struct link_vars
*vars
)
2857 struct bnx2x
*bp
= params
->bp
;
2861 u16 rx_sd
, pcs_status
;
2862 u8 ext_phy_link_up
= 0;
2863 u8 port
= params
->port
;
2864 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
2865 ext_phy_addr
= ((params
->ext_phy_config
&
2866 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
2867 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
2869 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
2870 switch (ext_phy_type
) {
2871 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
2872 DP(NETIF_MSG_LINK
, "XGXS Direct\n");
2873 ext_phy_link_up
= 1;
2876 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
2877 DP(NETIF_MSG_LINK
, "XGXS 8705\n");
2878 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2881 MDIO_WIS_REG_LASI_STATUS
, &val1
);
2882 DP(NETIF_MSG_LINK
, "8705 LASI status 0x%x\n", val1
);
2884 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2887 MDIO_WIS_REG_LASI_STATUS
, &val1
);
2888 DP(NETIF_MSG_LINK
, "8705 LASI status 0x%x\n", val1
);
2890 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2893 MDIO_PMA_REG_RX_SD
, &rx_sd
);
2894 DP(NETIF_MSG_LINK
, "8705 rx_sd 0x%x\n", rx_sd
);
2895 ext_phy_link_up
= (rx_sd
& 0x1);
2896 if (ext_phy_link_up
)
2897 vars
->line_speed
= SPEED_10000
;
2900 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
2901 DP(NETIF_MSG_LINK
, "XGXS 8706\n");
2902 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2905 MDIO_PMA_REG_LASI_STATUS
, &val1
);
2906 DP(NETIF_MSG_LINK
, "8706 LASI status 0x%x\n", val1
);
2908 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2911 MDIO_PMA_REG_LASI_STATUS
, &val1
);
2912 DP(NETIF_MSG_LINK
, "8706 LASI status 0x%x\n", val1
);
2914 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2917 MDIO_PMA_REG_RX_SD
, &rx_sd
);
2918 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2921 MDIO_PCS_REG_STATUS
, &pcs_status
);
2923 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2926 MDIO_AN_REG_LINK_STATUS
, &val2
);
2927 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2930 MDIO_AN_REG_LINK_STATUS
, &val2
);
2932 DP(NETIF_MSG_LINK
, "8706 rx_sd 0x%x"
2933 " pcs_status 0x%x 1Gbps link_status 0x%x\n",
2934 rx_sd
, pcs_status
, val2
);
2935 /* link is up if both bit 0 of pmd_rx_sd and
2936 * bit 0 of pcs_status are set, or if the autoneg bit
2939 ext_phy_link_up
= ((rx_sd
& pcs_status
& 0x1) ||
2941 if (ext_phy_link_up
) {
2943 vars
->line_speed
= SPEED_1000
;
2945 vars
->line_speed
= SPEED_10000
;
2948 /* clear LASI indication*/
2949 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
2952 MDIO_PMA_REG_RX_ALARM
, &val2
);
2955 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
2956 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
2958 u16 link_status
= 0;
2959 u16 an1000_status
= 0;
2961 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
) {
2962 bnx2x_cl45_read(bp
, params
->port
,
2966 MDIO_PCS_REG_LASI_STATUS
, &val1
);
2967 bnx2x_cl45_read(bp
, params
->port
,
2971 MDIO_PCS_REG_LASI_STATUS
, &val2
);
2973 "870x LASI status 0x%x->0x%x\n",
2977 /* In 8073, port1 is directed through emac0 and
2978 * port0 is directed through emac1
2980 bnx2x_cl45_read(bp
, params
->port
,
2984 MDIO_PMA_REG_LASI_STATUS
, &val1
);
2987 "8703 LASI status 0x%x\n",
2991 /* clear the interrupt LASI status register */
2992 bnx2x_cl45_read(bp
, params
->port
,
2996 MDIO_PCS_REG_STATUS
, &val2
);
2997 bnx2x_cl45_read(bp
, params
->port
,
3001 MDIO_PCS_REG_STATUS
, &val1
);
3002 DP(NETIF_MSG_LINK
, "807x PCS status 0x%x->0x%x\n",
3005 bnx2x_cl45_read(bp
, params
->port
,
3012 /* Check the LASI */
3013 bnx2x_cl45_read(bp
, params
->port
,
3017 MDIO_PMA_REG_RX_ALARM
, &val2
);
3019 DP(NETIF_MSG_LINK
, "KR 0x9003 0x%x\n", val2
);
3021 /* Check the link status */
3022 bnx2x_cl45_read(bp
, params
->port
,
3026 MDIO_PCS_REG_STATUS
, &val2
);
3027 DP(NETIF_MSG_LINK
, "KR PCS status 0x%x\n", val2
);
3029 bnx2x_cl45_read(bp
, params
->port
,
3033 MDIO_PMA_REG_STATUS
, &val2
);
3034 bnx2x_cl45_read(bp
, params
->port
,
3038 MDIO_PMA_REG_STATUS
, &val1
);
3039 ext_phy_link_up
= ((val1
& 4) == 4);
3040 DP(NETIF_MSG_LINK
, "PMA_REG_STATUS=0x%x\n", val1
);
3042 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
3044 if (ext_phy_link_up
&&
3045 ((params
->req_line_speed
!=
3047 if (bnx2x_bcm8073_xaui_wa(params
)
3049 ext_phy_link_up
= 0;
3053 bnx2x_cl45_read(bp
, params
->port
,
3059 bnx2x_cl45_read(bp
, params
->port
,
3066 /* Check the link status on 1.1.2 */
3067 bnx2x_cl45_read(bp
, params
->port
,
3071 MDIO_PMA_REG_STATUS
, &val2
);
3072 bnx2x_cl45_read(bp
, params
->port
,
3076 MDIO_PMA_REG_STATUS
, &val1
);
3077 DP(NETIF_MSG_LINK
, "KR PMA status 0x%x->0x%x,"
3078 "an_link_status=0x%x\n",
3079 val2
, val1
, an1000_status
);
3081 ext_phy_link_up
= (((val1
& 4) == 4) ||
3082 (an1000_status
& (1<<1)));
3083 if (ext_phy_link_up
&&
3084 bnx2x_8073_is_snr_needed(params
)) {
3085 /* The SNR will improve about 2dbby
3086 changing the BW and FEE main tap.*/
3088 /* The 1st write to change FFE main
3089 tap is set before restart AN */
3090 /* Change PLL Bandwidth in EDC
3092 bnx2x_cl45_write(bp
, port
, ext_phy_type
,
3095 MDIO_PMA_REG_PLL_BANDWIDTH
,
3098 /* Change CDR Bandwidth in EDC
3100 bnx2x_cl45_write(bp
, port
, ext_phy_type
,
3103 MDIO_PMA_REG_CDR_BANDWIDTH
,
3108 bnx2x_cl45_read(bp
, params
->port
,
3115 /* Bits 0..2 --> speed detected,
3116 bits 13..15--> link is down */
3117 if ((link_status
& (1<<2)) &&
3118 (!(link_status
& (1<<15)))) {
3119 ext_phy_link_up
= 1;
3120 vars
->line_speed
= SPEED_10000
;
3122 "port %x: External link"
3123 " up in 10G\n", params
->port
);
3124 } else if ((link_status
& (1<<1)) &&
3125 (!(link_status
& (1<<14)))) {
3126 ext_phy_link_up
= 1;
3127 vars
->line_speed
= SPEED_2500
;
3129 "port %x: External link"
3130 " up in 2.5G\n", params
->port
);
3131 } else if ((link_status
& (1<<0)) &&
3132 (!(link_status
& (1<<13)))) {
3133 ext_phy_link_up
= 1;
3134 vars
->line_speed
= SPEED_1000
;
3136 "port %x: External link"
3137 " up in 1G\n", params
->port
);
3139 ext_phy_link_up
= 0;
3141 "port %x: External link"
3142 " is down\n", params
->port
);
3145 /* See if 1G link is up for the 8072 */
3146 bnx2x_cl45_read(bp
, params
->port
,
3152 bnx2x_cl45_read(bp
, params
->port
,
3158 if (an1000_status
& (1<<1)) {
3159 ext_phy_link_up
= 1;
3160 vars
->line_speed
= SPEED_1000
;
3162 "port %x: External link"
3163 " up in 1G\n", params
->port
);
3164 } else if (ext_phy_link_up
) {
3165 ext_phy_link_up
= 1;
3166 vars
->line_speed
= SPEED_10000
;
3168 "port %x: External link"
3169 " up in 10G\n", params
->port
);
3176 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
3177 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3180 MDIO_PMA_REG_LASI_STATUS
, &val2
);
3181 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3184 MDIO_PMA_REG_LASI_STATUS
, &val1
);
3186 "10G-base-T LASI status 0x%x->0x%x\n",
3188 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3191 MDIO_PMA_REG_STATUS
, &val2
);
3192 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3195 MDIO_PMA_REG_STATUS
, &val1
);
3197 "10G-base-T PMA status 0x%x->0x%x\n",
3199 ext_phy_link_up
= ((val1
& 4) == 4);
3201 * print the AN outcome of the SFX7101 PHY
3203 if (ext_phy_link_up
) {
3204 bnx2x_cl45_read(bp
, params
->port
,
3208 MDIO_AN_REG_MASTER_STATUS
,
3210 vars
->line_speed
= SPEED_10000
;
3212 "SFX7101 AN status 0x%x->Master=%x\n",
3219 DP(NETIF_MSG_LINK
, "BAD XGXS ext_phy_config 0x%x\n",
3220 params
->ext_phy_config
);
3221 ext_phy_link_up
= 0;
3225 } else { /* SerDes */
3226 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
3227 switch (ext_phy_type
) {
3228 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
:
3229 DP(NETIF_MSG_LINK
, "SerDes Direct\n");
3230 ext_phy_link_up
= 1;
3233 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482
:
3234 DP(NETIF_MSG_LINK
, "SerDes 5482\n");
3235 ext_phy_link_up
= 1;
3240 "BAD SerDes ext_phy_config 0x%x\n",
3241 params
->ext_phy_config
);
3242 ext_phy_link_up
= 0;
3247 return ext_phy_link_up
;
3250 static void bnx2x_link_int_enable(struct link_params
*params
)
3252 u8 port
= params
->port
;
3255 struct bnx2x
*bp
= params
->bp
;
3256 /* setting the status to report on link up
3257 for either XGXS or SerDes */
3259 if (params
->switch_cfg
== SWITCH_CFG_10G
) {
3260 mask
= (NIG_MASK_XGXS0_LINK10G
|
3261 NIG_MASK_XGXS0_LINK_STATUS
);
3262 DP(NETIF_MSG_LINK
, "enabled XGXS interrupt\n");
3263 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3264 if ((ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) &&
3265 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
) &&
3267 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
)) {
3268 mask
|= NIG_MASK_MI_INT
;
3269 DP(NETIF_MSG_LINK
, "enabled external phy int\n");
3272 } else { /* SerDes */
3273 mask
= NIG_MASK_SERDES0_LINK_STATUS
;
3274 DP(NETIF_MSG_LINK
, "enabled SerDes interrupt\n");
3275 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
3276 if ((ext_phy_type
!=
3277 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
) &&
3279 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN
)) {
3280 mask
|= NIG_MASK_MI_INT
;
3281 DP(NETIF_MSG_LINK
, "enabled external phy int\n");
3285 NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4,
3287 DP(NETIF_MSG_LINK
, "port %x, is_xgxs=%x, int_status 0x%x\n", port
,
3288 (params
->switch_cfg
== SWITCH_CFG_10G
),
3289 REG_RD(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4));
3291 DP(NETIF_MSG_LINK
, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
3292 REG_RD(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4),
3293 REG_RD(bp
, NIG_REG_EMAC0_STATUS_MISC_MI_INT
+ port
*0x18),
3294 REG_RD(bp
, NIG_REG_SERDES0_STATUS_LINK_STATUS
+port
*0x3c));
3295 DP(NETIF_MSG_LINK
, " 10G %x, XGXS_LINK %x\n",
3296 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK10G
+ port
*0x68),
3297 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK_STATUS
+ port
*0x68));
3304 static void bnx2x_link_int_ack(struct link_params
*params
,
3305 struct link_vars
*vars
, u8 is_10g
)
3307 struct bnx2x
*bp
= params
->bp
;
3308 u8 port
= params
->port
;
3310 /* first reset all status
3311 * we assume only one line will be change at a time */
3312 bnx2x_bits_dis(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
3313 (NIG_STATUS_XGXS0_LINK10G
|
3314 NIG_STATUS_XGXS0_LINK_STATUS
|
3315 NIG_STATUS_SERDES0_LINK_STATUS
));
3316 if (vars
->phy_link_up
) {
3318 /* Disable the 10G link interrupt
3319 * by writing 1 to the status register
3321 DP(NETIF_MSG_LINK
, "10G XGXS phy link up\n");
3323 NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
3324 NIG_STATUS_XGXS0_LINK10G
);
3326 } else if (params
->switch_cfg
== SWITCH_CFG_10G
) {
3327 /* Disable the link interrupt
3328 * by writing 1 to the relevant lane
3329 * in the status register
3331 u32 ser_lane
= ((params
->lane_config
&
3332 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
3333 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
3335 DP(NETIF_MSG_LINK
, "1G XGXS phy link up\n");
3337 NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
3339 NIG_STATUS_XGXS0_LINK_STATUS_SIZE
));
3341 } else { /* SerDes */
3342 DP(NETIF_MSG_LINK
, "SerDes phy link up\n");
3343 /* Disable the link interrupt
3344 * by writing 1 to the status register
3347 NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
3348 NIG_STATUS_SERDES0_LINK_STATUS
);
3351 } else { /* link_down */
3355 static u8
bnx2x_format_ver(u32 num
, u8
*str
, u16 len
)
3358 u32 mask
= 0xf0000000;
3362 /* Need more then 10chars for this format */
3369 digit
= ((num
& mask
) >> shift
);
3371 *str_ptr
= digit
+ '0';
3373 *str_ptr
= digit
- 0xa + 'a';
3386 static void bnx2x_turn_on_ef(struct bnx2x
*bp
, u8 port
, u8 ext_phy_addr
,
3391 /* Enable EMAC0 in to enable MDIO */
3392 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
3393 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE
<< port
));
3396 /* take ext phy out of reset */
3398 MISC_REGISTERS_GPIO_2
,
3399 MISC_REGISTERS_GPIO_HIGH
,
3403 MISC_REGISTERS_GPIO_1
,
3404 MISC_REGISTERS_GPIO_HIGH
,
3410 for (cnt
= 0; cnt
< 1000; cnt
++) {
3412 bnx2x_cl45_read(bp
, port
,
3418 if (!(ctrl
& (1<<15))) {
3419 DP(NETIF_MSG_LINK
, "Reset completed\n\n");
3425 static void bnx2x_turn_off_sf(struct bnx2x
*bp
, u8 port
)
3427 /* put sf to reset */
3429 MISC_REGISTERS_GPIO_1
,
3430 MISC_REGISTERS_GPIO_LOW
,
3433 MISC_REGISTERS_GPIO_2
,
3434 MISC_REGISTERS_GPIO_LOW
,
3438 u8
bnx2x_get_ext_phy_fw_version(struct link_params
*params
, u8 driver_loaded
,
3439 u8
*version
, u16 len
)
3441 struct bnx2x
*bp
= params
->bp
;
3442 u32 ext_phy_type
= 0;
3444 u8 ext_phy_addr
= 0 ;
3448 if (version
== NULL
|| params
== NULL
)
3451 /* reset the returned value to zero */
3452 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3453 ext_phy_addr
= ((params
->ext_phy_config
&
3454 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
3455 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
3457 switch (ext_phy_type
) {
3458 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
3463 /* Take ext phy out of reset */
3465 bnx2x_turn_on_ef(bp
, params
->port
, ext_phy_addr
,
3471 bnx2x_cl45_read(bp
, params
->port
,
3475 MDIO_PMA_REG_7101_VER1
, &val
);
3476 version
[2] = (val
& 0xFF);
3477 version
[3] = ((val
& 0xFF00)>>8);
3479 bnx2x_cl45_read(bp
, params
->port
,
3482 MDIO_PMA_DEVAD
, MDIO_PMA_REG_7101_VER2
,
3484 version
[0] = (val
& 0xFF);
3485 version
[1] = ((val
& 0xFF00)>>8);
3489 bnx2x_turn_off_sf(bp
, params
->port
);
3491 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
3492 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
3494 /* Take ext phy out of reset */
3496 bnx2x_turn_on_ef(bp
, params
->port
, ext_phy_addr
,
3499 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3502 MDIO_PMA_REG_ROM_VER1
, &val
);
3504 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3507 MDIO_PMA_REG_ROM_VER2
, &val
);
3509 status
= bnx2x_format_ver(ver_num
, version
, len
);
3512 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
3513 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
3515 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3518 MDIO_PMA_REG_ROM_VER1
, &val
);
3520 bnx2x_cl45_read(bp
, params
->port
, ext_phy_type
,
3523 MDIO_PMA_REG_ROM_VER2
, &val
);
3525 status
= bnx2x_format_ver(ver_num
, version
, len
);
3528 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
3531 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
3532 DP(NETIF_MSG_LINK
, "bnx2x_get_ext_phy_fw_version:"
3533 " type is FAILURE!\n");
3543 static void bnx2x_set_xgxs_loopback(struct link_params
*params
,
3544 struct link_vars
*vars
,
3547 u8 port
= params
->port
;
3548 struct bnx2x
*bp
= params
->bp
;
3553 DP(NETIF_MSG_LINK
, "XGXS 10G loopback enable\n");
3555 /* change the uni_phy_addr in the nig */
3556 md_devad
= REG_RD(bp
, (NIG_REG_XGXS0_CTRL_MD_DEVAD
+
3559 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_DEVAD
+ port
*0x18, 0x5);
3561 bnx2x_cl45_write(bp
, port
, 0,
3564 (MDIO_REG_BANK_AER_BLOCK
+
3565 (MDIO_AER_BLOCK_AER_REG
& 0xf)),
3568 bnx2x_cl45_write(bp
, port
, 0,
3571 (MDIO_REG_BANK_CL73_IEEEB0
+
3572 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL
& 0xf)),
3575 /* set aer mmd back */
3576 bnx2x_set_aer_mmd(params
, vars
);
3579 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_DEVAD
+ port
*0x18,
3585 DP(NETIF_MSG_LINK
, "XGXS 1G loopback enable\n");
3587 CL45_RD_OVER_CL22(bp
, port
,
3589 MDIO_REG_BANK_COMBO_IEEE0
,
3590 MDIO_COMBO_IEEE0_MII_CONTROL
,
3593 CL45_WR_OVER_CL22(bp
, port
,
3595 MDIO_REG_BANK_COMBO_IEEE0
,
3596 MDIO_COMBO_IEEE0_MII_CONTROL
,
3598 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK
));
3603 static void bnx2x_ext_phy_loopback(struct link_params
*params
)
3605 struct bnx2x
*bp
= params
->bp
;
3609 if (params
->switch_cfg
== SWITCH_CFG_10G
) {
3610 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3611 /* CL37 Autoneg Enabled */
3612 ext_phy_addr
= ((params
->ext_phy_config
&
3613 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
3614 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
3615 switch (ext_phy_type
) {
3616 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
3617 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
:
3619 "ext_phy_loopback: We should not get here\n");
3621 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
3622 DP(NETIF_MSG_LINK
, "ext_phy_loopback: 8705\n");
3624 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
3625 DP(NETIF_MSG_LINK
, "ext_phy_loopback: 8706\n");
3627 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
3628 /* SFX7101_XGXS_TEST1 */
3629 bnx2x_cl45_write(bp
, params
->port
, ext_phy_type
,
3632 MDIO_XS_SFX7101_XGXS_TEST1
,
3635 "ext_phy_loopback: set ext phy loopback\n");
3637 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
3640 } /* switch external PHY type */
3643 ext_phy_type
= SERDES_EXT_PHY_TYPE(params
->ext_phy_config
);
3644 ext_phy_addr
= (params
->ext_phy_config
&
3645 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK
)
3646 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT
;
3652 *------------------------------------------------------------------------
3653 * bnx2x_override_led_value -
3655 * Override the led value of the requsted led
3657 *------------------------------------------------------------------------
3659 u8
bnx2x_override_led_value(struct bnx2x
*bp
, u8 port
,
3660 u32 led_idx
, u32 value
)
3664 /* If port 0 then use EMAC0, else use EMAC1*/
3665 u32 emac_base
= (port
) ? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
3668 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
3669 port
, led_idx
, value
);
3672 case 0: /* 10MB led */
3673 /* Read the current value of the LED register in
3675 reg_val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_LED
);
3676 /* Set the OVERRIDE bit to 1 */
3677 reg_val
|= EMAC_LED_OVERRIDE
;
3678 /* If value is 1, set the 10M_OVERRIDE bit,
3679 otherwise reset it.*/
3680 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_10MB_OVERRIDE
) :
3681 (reg_val
& ~EMAC_LED_10MB_OVERRIDE
);
3682 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
3684 case 1: /*100MB led */
3685 /*Read the current value of the LED register in
3687 reg_val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_LED
);
3688 /* Set the OVERRIDE bit to 1 */
3689 reg_val
|= EMAC_LED_OVERRIDE
;
3690 /* If value is 1, set the 100M_OVERRIDE bit,
3691 otherwise reset it.*/
3692 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_100MB_OVERRIDE
) :
3693 (reg_val
& ~EMAC_LED_100MB_OVERRIDE
);
3694 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
3696 case 2: /* 1000MB led */
3697 /* Read the current value of the LED register in the
3699 reg_val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_LED
);
3700 /* Set the OVERRIDE bit to 1 */
3701 reg_val
|= EMAC_LED_OVERRIDE
;
3702 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
3704 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_1000MB_OVERRIDE
) :
3705 (reg_val
& ~EMAC_LED_1000MB_OVERRIDE
);
3706 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
3708 case 3: /* 2500MB led */
3709 /* Read the current value of the LED register in the
3711 reg_val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_LED
);
3712 /* Set the OVERRIDE bit to 1 */
3713 reg_val
|= EMAC_LED_OVERRIDE
;
3714 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
3716 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_2500MB_OVERRIDE
) :
3717 (reg_val
& ~EMAC_LED_2500MB_OVERRIDE
);
3718 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
3720 case 4: /*10G led */
3722 REG_WR(bp
, NIG_REG_LED_10G_P0
,
3725 REG_WR(bp
, NIG_REG_LED_10G_P1
,
3729 case 5: /* TRAFFIC led */
3730 /* Find if the traffic control is via BMAC or EMAC */
3732 reg_val
= REG_RD(bp
, NIG_REG_NIG_EMAC0_EN
);
3734 reg_val
= REG_RD(bp
, NIG_REG_NIG_EMAC1_EN
);
3736 /* Override the traffic led in the EMAC:*/
3738 /* Read the current value of the LED register in
3740 reg_val
= REG_RD(bp
, emac_base
+
3742 /* Set the TRAFFIC_OVERRIDE bit to 1 */
3743 reg_val
|= EMAC_LED_OVERRIDE
;
3744 /* If value is 1, set the TRAFFIC bit, otherwise
3746 reg_val
= (value
== 1) ? (reg_val
| EMAC_LED_TRAFFIC
) :
3747 (reg_val
& ~EMAC_LED_TRAFFIC
);
3748 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_LED
, reg_val
);
3749 } else { /* Override the traffic led in the BMAC: */
3750 REG_WR(bp
, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3752 REG_WR(bp
, NIG_REG_LED_CONTROL_TRAFFIC_P0
+ port
*4,
3758 "bnx2x_override_led_value() unknown led index %d "
3759 "(should be 0-5)\n", led_idx
);
3767 u8
bnx2x_set_led(struct bnx2x
*bp
, u8 port
, u8 mode
, u32 speed
,
3768 u16 hw_led_mode
, u32 chip_id
)
3772 u32 emac_base
= port
? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
3773 DP(NETIF_MSG_LINK
, "bnx2x_set_led: port %x, mode %d\n", port
, mode
);
3774 DP(NETIF_MSG_LINK
, "speed 0x%x, hw_led_mode 0x%x\n",
3775 speed
, hw_led_mode
);
3778 REG_WR(bp
, NIG_REG_LED_10G_P0
+ port
*4, 0);
3779 REG_WR(bp
, NIG_REG_LED_MODE_P0
+ port
*4,
3780 SHARED_HW_CFG_LED_MAC1
);
3782 tmp
= EMAC_RD(bp
, EMAC_REG_EMAC_LED
);
3783 EMAC_WR(bp
, EMAC_REG_EMAC_LED
, (tmp
| EMAC_LED_OVERRIDE
));
3787 REG_WR(bp
, NIG_REG_LED_MODE_P0
+ port
*4, hw_led_mode
);
3788 REG_WR(bp
, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
+
3790 /* Set blinking rate to ~15.9Hz */
3791 REG_WR(bp
, NIG_REG_LED_CONTROL_BLINK_RATE_P0
+ port
*4,
3792 LED_BLINK_RATE_VAL
);
3793 REG_WR(bp
, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0
+
3795 tmp
= EMAC_RD(bp
, EMAC_REG_EMAC_LED
);
3796 EMAC_WR(bp
, EMAC_REG_EMAC_LED
,
3797 (tmp
& (~EMAC_LED_OVERRIDE
)));
3799 if (!CHIP_IS_E1H(bp
) &&
3800 ((speed
== SPEED_2500
) ||
3801 (speed
== SPEED_1000
) ||
3802 (speed
== SPEED_100
) ||
3803 (speed
== SPEED_10
))) {
3804 /* On Everest 1 Ax chip versions for speeds less than
3805 10G LED scheme is different */
3806 REG_WR(bp
, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3808 REG_WR(bp
, NIG_REG_LED_CONTROL_TRAFFIC_P0
+
3810 REG_WR(bp
, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0
+
3817 DP(NETIF_MSG_LINK
, "bnx2x_set_led: Invalid led mode %d\n",
3825 u8
bnx2x_test_link(struct link_params
*params
, struct link_vars
*vars
)
3827 struct bnx2x
*bp
= params
->bp
;
3830 CL45_RD_OVER_CL22(bp
, params
->port
,
3832 MDIO_REG_BANK_GP_STATUS
,
3833 MDIO_GP_STATUS_TOP_AN_STATUS1
,
3835 /* link is up only if both local phy and external phy are up */
3836 if ((gp_status
& MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS
) &&
3837 bnx2x_ext_phy_is_link_up(params
, vars
))
3843 static u8
bnx2x_link_initialize(struct link_params
*params
,
3844 struct link_vars
*vars
)
3846 struct bnx2x
*bp
= params
->bp
;
3847 u8 port
= params
->port
;
3850 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
3851 /* Activate the external PHY */
3852 bnx2x_ext_phy_reset(params
, vars
);
3854 bnx2x_set_aer_mmd(params
, vars
);
3856 if (vars
->phy_flags
& PHY_XGXS_FLAG
)
3857 bnx2x_set_master_ln(params
);
3859 rc
= bnx2x_reset_unicore(params
);
3860 /* reset the SerDes and wait for reset bit return low */
3864 bnx2x_set_aer_mmd(params
, vars
);
3866 /* setting the masterLn_def again after the reset */
3867 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
3868 bnx2x_set_master_ln(params
);
3869 bnx2x_set_swap_lanes(params
);
3872 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
3873 if (params
->req_line_speed
&&
3874 ((params
->req_line_speed
== SPEED_100
) ||
3875 (params
->req_line_speed
== SPEED_10
))) {
3876 vars
->phy_flags
|= PHY_SGMII_FLAG
;
3878 vars
->phy_flags
&= ~PHY_SGMII_FLAG
;
3881 /* In case of external phy existance, the line speed would be the
3882 line speed linked up by the external phy. In case it is direct only,
3883 then the line_speed during initialization will be equal to the
3885 vars
->line_speed
= params
->req_line_speed
;
3887 bnx2x_calc_ieee_aneg_adv(params
, &vars
->ieee_fc
);
3889 /* init ext phy and enable link state int */
3890 non_ext_phy
= ((ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) ||
3891 (params
->loopback_mode
== LOOPBACK_XGXS_10
) ||
3892 (params
->loopback_mode
== LOOPBACK_EXT_PHY
));
3895 (ext_phy_type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
)) {
3896 if (params
->req_line_speed
== SPEED_AUTO_NEG
)
3897 bnx2x_set_parallel_detection(params
, vars
->phy_flags
);
3898 bnx2x_init_internal_phy(params
, vars
);
3902 rc
|= bnx2x_ext_phy_init(params
, vars
);
3904 bnx2x_bits_dis(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
3905 (NIG_STATUS_XGXS0_LINK10G
|
3906 NIG_STATUS_XGXS0_LINK_STATUS
|
3907 NIG_STATUS_SERDES0_LINK_STATUS
));
3914 u8
bnx2x_phy_init(struct link_params
*params
, struct link_vars
*vars
)
3916 struct bnx2x
*bp
= params
->bp
;
3919 DP(NETIF_MSG_LINK
, "Phy Initialization started \n");
3920 DP(NETIF_MSG_LINK
, "req_speed = %d, req_flowctrl=%d\n",
3921 params
->req_line_speed
, params
->req_flow_ctrl
);
3922 vars
->link_status
= 0;
3923 vars
->phy_link_up
= 0;
3925 vars
->line_speed
= 0;
3926 vars
->duplex
= DUPLEX_FULL
;
3927 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
3928 vars
->mac_type
= MAC_TYPE_NONE
;
3930 if (params
->switch_cfg
== SWITCH_CFG_1G
)
3931 vars
->phy_flags
= PHY_SERDES_FLAG
;
3933 vars
->phy_flags
= PHY_XGXS_FLAG
;
3936 /* disable attentions */
3937 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ params
->port
*4,
3938 (NIG_MASK_XGXS0_LINK_STATUS
|
3939 NIG_MASK_XGXS0_LINK10G
|
3940 NIG_MASK_SERDES0_LINK_STATUS
|
3943 bnx2x_emac_init(params
, vars
);
3945 if (CHIP_REV_IS_FPGA(bp
)) {
3947 vars
->line_speed
= SPEED_10000
;
3948 vars
->duplex
= DUPLEX_FULL
;
3949 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
3950 vars
->link_status
= (LINK_STATUS_LINK_UP
| LINK_10GTFD
);
3951 /* enable on E1.5 FPGA */
3952 if (CHIP_IS_E1H(bp
)) {
3954 (BNX2X_FLOW_CTRL_TX
| BNX2X_FLOW_CTRL_RX
);
3955 vars
->link_status
|=
3956 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED
|
3957 LINK_STATUS_RX_FLOW_CONTROL_ENABLED
);
3960 bnx2x_emac_enable(params
, vars
, 0);
3961 bnx2x_pbf_update(params
, vars
->flow_ctrl
, vars
->line_speed
);
3963 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
3964 + params
->port
*4, 0);
3966 /* update shared memory */
3967 bnx2x_update_mng(params
, vars
->link_status
);
3972 if (CHIP_REV_IS_EMUL(bp
)) {
3975 vars
->line_speed
= SPEED_10000
;
3976 vars
->duplex
= DUPLEX_FULL
;
3977 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
3978 vars
->link_status
= (LINK_STATUS_LINK_UP
| LINK_10GTFD
);
3980 bnx2x_bmac_enable(params
, vars
, 0);
3982 bnx2x_pbf_update(params
, vars
->flow_ctrl
, vars
->line_speed
);
3984 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
3985 + params
->port
*4, 0);
3987 /* update shared memory */
3988 bnx2x_update_mng(params
, vars
->link_status
);
3993 if (params
->loopback_mode
== LOOPBACK_BMAC
) {
3995 vars
->line_speed
= SPEED_10000
;
3996 vars
->duplex
= DUPLEX_FULL
;
3997 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
3998 vars
->mac_type
= MAC_TYPE_BMAC
;
4000 vars
->phy_flags
= PHY_XGXS_FLAG
;
4002 bnx2x_phy_deassert(params
, vars
->phy_flags
);
4003 /* set bmac loopback */
4004 bnx2x_bmac_enable(params
, vars
, 1);
4006 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+
4008 } else if (params
->loopback_mode
== LOOPBACK_EMAC
) {
4010 vars
->line_speed
= SPEED_1000
;
4011 vars
->duplex
= DUPLEX_FULL
;
4012 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
4013 vars
->mac_type
= MAC_TYPE_EMAC
;
4015 vars
->phy_flags
= PHY_XGXS_FLAG
;
4017 bnx2x_phy_deassert(params
, vars
->phy_flags
);
4018 /* set bmac loopback */
4019 bnx2x_emac_enable(params
, vars
, 1);
4020 bnx2x_emac_program(params
, vars
->line_speed
,
4022 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+
4024 } else if ((params
->loopback_mode
== LOOPBACK_XGXS_10
) ||
4025 (params
->loopback_mode
== LOOPBACK_EXT_PHY
)) {
4027 vars
->line_speed
= SPEED_10000
;
4028 vars
->duplex
= DUPLEX_FULL
;
4029 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
4031 vars
->phy_flags
= PHY_XGXS_FLAG
;
4034 NIG_REG_XGXS0_CTRL_PHY_ADDR
+
4036 params
->phy_addr
= (u8
)val
;
4038 bnx2x_phy_deassert(params
, vars
->phy_flags
);
4039 bnx2x_link_initialize(params
, vars
);
4041 vars
->mac_type
= MAC_TYPE_BMAC
;
4043 bnx2x_bmac_enable(params
, vars
, 0);
4045 if (params
->loopback_mode
== LOOPBACK_XGXS_10
) {
4046 /* set 10G XGXS loopback */
4047 bnx2x_set_xgxs_loopback(params
, vars
, 1);
4049 /* set external phy loopback */
4050 bnx2x_ext_phy_loopback(params
);
4052 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+
4058 bnx2x_phy_deassert(params
, vars
->phy_flags
);
4059 switch (params
->switch_cfg
) {
4061 vars
->phy_flags
|= PHY_SERDES_FLAG
;
4062 if ((params
->ext_phy_config
&
4063 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK
) ==
4064 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482
) {
4070 NIG_REG_SERDES0_CTRL_PHY_ADDR
+
4073 params
->phy_addr
= (u8
)val
;
4076 case SWITCH_CFG_10G
:
4077 vars
->phy_flags
|= PHY_XGXS_FLAG
;
4079 NIG_REG_XGXS0_CTRL_PHY_ADDR
+
4081 params
->phy_addr
= (u8
)val
;
4085 DP(NETIF_MSG_LINK
, "Invalid switch_cfg\n");
4090 bnx2x_link_initialize(params
, vars
);
4092 bnx2x_link_int_enable(params
);
4097 u8
bnx2x_link_reset(struct link_params
*params
, struct link_vars
*vars
)
4100 struct bnx2x
*bp
= params
->bp
;
4101 u32 ext_phy_config
= params
->ext_phy_config
;
4102 u16 hw_led_mode
= params
->hw_led_mode
;
4103 u32 chip_id
= params
->chip_id
;
4104 u8 port
= params
->port
;
4105 u32 ext_phy_type
= XGXS_EXT_PHY_TYPE(ext_phy_config
);
4106 /* disable attentions */
4108 vars
->link_status
= 0;
4109 bnx2x_update_mng(params
, vars
->link_status
);
4110 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4,
4111 (NIG_MASK_XGXS0_LINK_STATUS
|
4112 NIG_MASK_XGXS0_LINK10G
|
4113 NIG_MASK_SERDES0_LINK_STATUS
|
4116 /* activate nig drain */
4117 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ port
*4, 1);
4119 /* disable nig egress interface */
4120 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0);
4121 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0);
4123 /* Stop BigMac rx */
4124 bnx2x_bmac_rx_disable(bp
, port
);
4127 REG_WR(bp
, NIG_REG_NIG_EMAC0_EN
+ port
*4, 0);
4130 /* The PHY reset is controled by GPIO 1
4131 * Hold it as vars low
4133 /* clear link led */
4134 bnx2x_set_led(bp
, port
, LED_MODE_OFF
, 0, hw_led_mode
, chip_id
);
4135 if (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) {
4136 if ((ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
) &&
4137 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
)) {
4140 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
4141 MISC_REGISTERS_GPIO_OUTPUT_LOW
,
4144 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
4145 MISC_REGISTERS_GPIO_OUTPUT_LOW
,
4148 DP(NETIF_MSG_LINK
, "reset external PHY\n");
4149 } else if (ext_phy_type
==
4150 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
) {
4151 DP(NETIF_MSG_LINK
, "Setting 8073 port %d into "
4154 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
4155 MISC_REGISTERS_GPIO_OUTPUT_LOW
,
4159 /* reset the SerDes/XGXS */
4160 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_CLEAR
,
4161 (0x1ff << (port
*16)));
4164 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
4165 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
4167 /* disable nig ingress interface */
4168 REG_WR(bp
, NIG_REG_BMAC0_IN_EN
+ port
*4, 0);
4169 REG_WR(bp
, NIG_REG_EMAC0_IN_EN
+ port
*4, 0);
4170 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0);
4171 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0);
4176 static u8
bnx2x_update_link_down(struct link_params
*params
,
4177 struct link_vars
*vars
)
4179 struct bnx2x
*bp
= params
->bp
;
4180 u8 port
= params
->port
;
4181 DP(NETIF_MSG_LINK
, "Port %x: Link is down\n", port
);
4182 bnx2x_set_led(bp
, port
, LED_MODE_OFF
,
4183 0, params
->hw_led_mode
,
4186 /* indicate no mac active */
4187 vars
->mac_type
= MAC_TYPE_NONE
;
4189 /* update shared memory */
4190 vars
->link_status
= 0;
4191 vars
->line_speed
= 0;
4192 bnx2x_update_mng(params
, vars
->link_status
);
4194 /* activate nig drain */
4195 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ port
*4, 1);
4198 bnx2x_bmac_rx_disable(bp
, params
->port
);
4199 REG_WR(bp
, GRCBASE_MISC
+
4200 MISC_REGISTERS_RESET_REG_2_CLEAR
,
4201 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
4205 static u8
bnx2x_update_link_up(struct link_params
*params
,
4206 struct link_vars
*vars
,
4207 u8 link_10g
, u32 gp_status
)
4209 struct bnx2x
*bp
= params
->bp
;
4210 u8 port
= params
->port
;
4212 vars
->link_status
|= LINK_STATUS_LINK_UP
;
4214 bnx2x_bmac_enable(params
, vars
, 0);
4215 bnx2x_set_led(bp
, port
, LED_MODE_OPER
,
4216 SPEED_10000
, params
->hw_led_mode
,
4220 bnx2x_emac_enable(params
, vars
, 0);
4221 rc
= bnx2x_emac_program(params
, vars
->line_speed
,
4225 if (gp_status
& MDIO_AN_CL73_OR_37_COMPLETE
) {
4226 if (!(vars
->phy_flags
&
4228 bnx2x_set_sgmii_tx_driver(params
);
4233 rc
|= bnx2x_pbf_update(params
, vars
->flow_ctrl
,
4237 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ port
*4, 0);
4239 /* update shared memory */
4240 bnx2x_update_mng(params
, vars
->link_status
);
4243 /* This function should called upon link interrupt */
4244 /* In case vars->link_up, driver needs to
4247 3. Update the shared memory
4251 1. Update shared memory
4256 u8
bnx2x_link_update(struct link_params
*params
, struct link_vars
*vars
)
4258 struct bnx2x
*bp
= params
->bp
;
4259 u8 port
= params
->port
;
4262 u8 ext_phy_link_up
, rc
= 0;
4265 DP(NETIF_MSG_LINK
, "port %x, XGXS?%x, int_status 0x%x\n",
4267 (vars
->phy_flags
& PHY_XGXS_FLAG
),
4268 REG_RD(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4));
4270 DP(NETIF_MSG_LINK
, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4271 REG_RD(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4),
4272 REG_RD(bp
, NIG_REG_EMAC0_STATUS_MISC_MI_INT
+ port
*0x18),
4273 REG_RD(bp
, NIG_REG_SERDES0_STATUS_LINK_STATUS
+ port
*0x3c));
4275 DP(NETIF_MSG_LINK
, " 10G %x, XGXS_LINK %x\n",
4276 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK10G
+ port
*0x68),
4277 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK_STATUS
+ port
*0x68));
4279 ext_phy_type
= XGXS_EXT_PHY_TYPE(params
->ext_phy_config
);
4281 /* Check external link change only for non-direct */
4282 ext_phy_link_up
= bnx2x_ext_phy_is_link_up(params
, vars
);
4284 /* Read gp_status */
4285 CL45_RD_OVER_CL22(bp
, port
, params
->phy_addr
,
4286 MDIO_REG_BANK_GP_STATUS
,
4287 MDIO_GP_STATUS_TOP_AN_STATUS1
,
4290 rc
= bnx2x_link_settings_status(params
, vars
, gp_status
);
4294 /* anything 10 and over uses the bmac */
4295 link_10g
= ((vars
->line_speed
== SPEED_10000
) ||
4296 (vars
->line_speed
== SPEED_12000
) ||
4297 (vars
->line_speed
== SPEED_12500
) ||
4298 (vars
->line_speed
== SPEED_13000
) ||
4299 (vars
->line_speed
== SPEED_15000
) ||
4300 (vars
->line_speed
== SPEED_16000
));
4302 bnx2x_link_int_ack(params
, vars
, link_10g
);
4304 /* In case external phy link is up, and internal link is down
4305 ( not initialized yet probably after link initialization, it needs
4307 Note that after link down-up as result of cable plug,
4308 the xgxs link would probably become up again without the need to
4311 if ((ext_phy_type
!= PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
) &&
4312 (ext_phy_type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
) &&
4313 (ext_phy_link_up
&& !vars
->phy_link_up
))
4314 bnx2x_init_internal_phy(params
, vars
);
4316 /* link is up only if both local phy and external phy are up */
4317 vars
->link_up
= (ext_phy_link_up
&& vars
->phy_link_up
);
4320 rc
= bnx2x_update_link_up(params
, vars
, link_10g
, gp_status
);
4322 rc
= bnx2x_update_link_down(params
, vars
);
4327 static u8
bnx2x_8073_common_init_phy(struct bnx2x
*bp
, u32 shmem_base
)
4329 u8 ext_phy_addr
[PORT_MAX
];
4333 /* PART1 - Reset both phys */
4334 for (port
= PORT_MAX
- 1; port
>= PORT_0
; port
--) {
4335 /* Extract the ext phy address for the port */
4336 u32 ext_phy_config
= REG_RD(bp
, shmem_base
+
4337 offsetof(struct shmem_region
,
4338 dev_info
.port_hw_config
[port
].external_phy_config
));
4340 /* disable attentions */
4341 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4,
4342 (NIG_MASK_XGXS0_LINK_STATUS
|
4343 NIG_MASK_XGXS0_LINK10G
|
4344 NIG_MASK_SERDES0_LINK_STATUS
|
4347 ext_phy_addr
[port
] =
4349 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
4350 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
4352 /* Need to take the phy out of low power mode in order
4353 to write to access its registers */
4354 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
4355 MISC_REGISTERS_GPIO_OUTPUT_HIGH
, port
);
4358 bnx2x_cl45_write(bp
, port
,
4359 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4366 /* Add delay of 150ms after reset */
4369 /* PART2 - Download firmware to both phys */
4370 for (port
= PORT_MAX
- 1; port
>= PORT_0
; port
--) {
4373 bnx2x_bcm8073_external_rom_boot(bp
, port
,
4374 ext_phy_addr
[port
]);
4376 bnx2x_cl45_read(bp
, port
, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4379 MDIO_PMA_REG_ROM_VER1
, &fw_ver1
);
4382 "bnx2x_8073_common_init_phy port %x "
4383 "fw Download failed\n", port
);
4387 /* Only set bit 10 = 1 (Tx power down) */
4388 bnx2x_cl45_read(bp
, port
,
4389 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4392 MDIO_PMA_REG_TX_POWER_DOWN
, &val
);
4394 /* Phase1 of TX_POWER_DOWN reset */
4395 bnx2x_cl45_write(bp
, port
,
4396 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4399 MDIO_PMA_REG_TX_POWER_DOWN
,
4403 /* Toggle Transmitter: Power down and then up with 600ms
4407 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
4408 for (port
= PORT_MAX
- 1; port
>= PORT_0
; port
--) {
4409 /* Phase2 of POWER_DOWN_RESET*/
4410 /* Release bit 10 (Release Tx power down) */
4411 bnx2x_cl45_read(bp
, port
,
4412 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4415 MDIO_PMA_REG_TX_POWER_DOWN
, &val
);
4417 bnx2x_cl45_write(bp
, port
,
4418 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4421 MDIO_PMA_REG_TX_POWER_DOWN
, (val
& (~(1<<10))));
4424 /* Read modify write the SPI-ROM version select register */
4425 bnx2x_cl45_read(bp
, port
,
4426 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4429 MDIO_PMA_REG_EDC_FFE_MAIN
, &val
);
4430 bnx2x_cl45_write(bp
, port
,
4431 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
4434 MDIO_PMA_REG_EDC_FFE_MAIN
, (val
| (1<<12)));
4436 /* set GPIO2 back to LOW */
4437 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
4438 MISC_REGISTERS_GPIO_OUTPUT_LOW
, port
);
4444 u8
bnx2x_common_init_phy(struct bnx2x
*bp
, u32 shmem_base
)
4449 DP(NETIF_MSG_LINK
, "bnx2x_common_init_phy\n");
4451 /* Read the ext_phy_type for arbitrary port(0) */
4452 ext_phy_type
= XGXS_EXT_PHY_TYPE(
4453 REG_RD(bp
, shmem_base
+
4454 offsetof(struct shmem_region
,
4455 dev_info
.port_hw_config
[0].external_phy_config
)));
4457 switch (ext_phy_type
) {
4458 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
4460 rc
= bnx2x_8073_common_init_phy(bp
, shmem_base
);
4465 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
4475 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x
*bp
, u8 port
, u8 phy_addr
)
4479 bnx2x_cl45_read(bp
, port
,
4480 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4483 MDIO_PMA_REG_7101_RESET
, &val
);
4485 for (cnt
= 0; cnt
< 10; cnt
++) {
4487 /* Writes a self-clearing reset */
4488 bnx2x_cl45_write(bp
, port
,
4489 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4492 MDIO_PMA_REG_7101_RESET
,
4494 /* Wait for clear */
4495 bnx2x_cl45_read(bp
, port
,
4496 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4499 MDIO_PMA_REG_7101_RESET
, &val
);
4501 if ((val
& (1<<15)) == 0)
4505 #define RESERVED_SIZE 256
4506 /* max application is 160K bytes - data at end of RAM */
4507 #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
4509 /* Header is 14 bytes */
4510 #define HEADER_SIZE 14
4511 #define DATA_OFFSET HEADER_SIZE
4513 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
4514 bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
4517 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
4519 /* Programs an image to DSP's flash via the SPI port*/
4520 static u8
bnx2x_sfx7101_flash_download(struct bnx2x
*bp
, u8 port
,
4522 char data
[], u32 size
)
4524 const u16 num_trans
= size
/4; /* 4 bytes can be sent at a time */
4525 /* Doesn't include last trans!*/
4526 const u16 last_trans_size
= size
%4; /* Num bytes on last trans */
4527 u16 trans_cnt
, byte_cnt
;
4530 u16 code_started
= 0;
4531 u16 image_revision1
, image_revision2
;
4534 DP(NETIF_MSG_LINK
, "bnx2x_sfx7101_flash_download file_size=%d\n", size
);
4536 if ((size
-HEADER_SIZE
) > MAX_APP_SIZE
) {
4537 /* This very often will be the case, because the image is built
4538 with 160Kbytes size whereas the total image size must actually
4539 be 160Kbytes-RESERVED_SIZE */
4540 DP(NETIF_MSG_LINK
, "Warning, file size was %d bytes "
4541 "truncated to %d bytes\n", size
, MAX_APP_SIZE
);
4542 size
= MAX_APP_SIZE
+HEADER_SIZE
;
4544 DP(NETIF_MSG_LINK
, "File version is %c%c\n", data
[0x14e], data
[0x14f]);
4545 DP(NETIF_MSG_LINK
, " %c%c\n", data
[0x150], data
[0x151]);
4546 /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
4547 and issuing a reset.*/
4549 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_0
,
4550 MISC_REGISTERS_GPIO_HIGH
, port
);
4552 bnx2x_sfx7101_sp_sw_reset(bp
, port
, ext_phy_addr
);
4555 for (cnt
= 0; cnt
< 100; cnt
++)
4558 /* Make sure we can access the DSP
4559 And it's in the correct mode (waiting for download) */
4561 bnx2x_cl45_read(bp
, port
,
4562 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4565 MDIO_PCS_REG_7101_DSP_ACCESS
, &tmp
);
4567 if (tmp
!= 0x000A) {
4568 DP(NETIF_MSG_LINK
, "DSP is not in waiting on download mode. "
4569 "Expected 0x000A, read 0x%04X\n", tmp
);
4570 DP(NETIF_MSG_LINK
, "Download failed\n");
4574 /* Mux the SPI interface away from the internal processor */
4575 bnx2x_cl45_write(bp
, port
,
4576 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4579 MDIO_PCS_REG_7101_SPI_MUX
, 1);
4581 /* Reset the SPI port */
4582 bnx2x_cl45_write(bp
, port
,
4583 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4586 MDIO_PCS_REG_7101_SPI_CTRL_ADDR
, 0);
4587 bnx2x_cl45_write(bp
, port
,
4588 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4591 MDIO_PCS_REG_7101_SPI_CTRL_ADDR
,
4592 (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT
));
4593 bnx2x_cl45_write(bp
, port
,
4594 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4597 MDIO_PCS_REG_7101_SPI_CTRL_ADDR
, 0);
4599 /* Erase the flash */
4600 bnx2x_cl45_write(bp
, port
,
4601 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4604 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4605 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD
);
4607 bnx2x_cl45_write(bp
, port
,
4608 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4611 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4614 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4615 bnx2x_cl45_write(bp
, port
,
4616 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4619 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4620 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD
);
4622 bnx2x_cl45_write(bp
, port
,
4623 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4626 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4628 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4630 /* Wait 10 seconds, the maximum time for the erase to complete */
4631 DP(NETIF_MSG_LINK
, "Erasing flash, this takes 10 seconds...\n");
4632 for (cnt
= 0; cnt
< 1000; cnt
++)
4635 DP(NETIF_MSG_LINK
, "Downloading flash, please wait...\n");
4637 for (trans_cnt
= 0; trans_cnt
< num_trans
; trans_cnt
++) {
4638 bnx2x_cl45_write(bp
, port
,
4639 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4642 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4643 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD
);
4645 bnx2x_cl45_write(bp
, port
,
4646 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4649 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4651 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4653 bnx2x_cl45_write(bp
, port
,
4654 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4657 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4658 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD
);
4660 /* Bits 23-16 of address */
4661 bnx2x_cl45_write(bp
, port
,
4662 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4665 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4667 /* Bits 15-8 of address */
4668 bnx2x_cl45_write(bp
, port
,
4669 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4672 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4675 /* Bits 7-0 of address */
4676 bnx2x_cl45_write(bp
, port
,
4677 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4680 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4684 while (byte_cnt
< 4 && data_index
< size
) {
4685 bnx2x_cl45_write(bp
, port
,
4686 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4689 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4690 data
[data_index
++]);
4694 bnx2x_cl45_write(bp
, port
,
4695 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4698 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4701 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4702 msleep(5); /* Wait 5 ms minimum between transs */
4704 /* Let the user know something's going on.*/
4705 /* a pacifier ever 4K */
4706 if ((data_index
% 1023) == 0)
4707 DP(NETIF_MSG_LINK
, "Download %d%%\n", data_index
/size
);
4710 DP(NETIF_MSG_LINK
, "\n");
4711 /* Transfer the last block if there is data remaining */
4712 if (last_trans_size
) {
4713 bnx2x_cl45_write(bp
, port
,
4714 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4717 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4718 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD
);
4720 bnx2x_cl45_write(bp
, port
,
4721 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4724 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4727 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4729 bnx2x_cl45_write(bp
, port
,
4730 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4733 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4734 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD
);
4736 /* Bits 23-16 of address */
4737 bnx2x_cl45_write(bp
, port
,
4738 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4741 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4743 /* Bits 15-8 of address */
4744 bnx2x_cl45_write(bp
, port
,
4745 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4748 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4751 /* Bits 7-0 of address */
4752 bnx2x_cl45_write(bp
, port
,
4753 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4756 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4760 while (byte_cnt
< last_trans_size
&& data_index
< size
) {
4761 /* Bits 7-0 of address */
4762 bnx2x_cl45_write(bp
, port
,
4763 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4766 MDIO_PCS_REG_7101_SPI_FIFO_ADDR
,
4767 data
[data_index
++]);
4771 bnx2x_cl45_write(bp
, port
,
4772 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4775 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR
,
4778 SPI_START_TRANSFER(bp
, port
, ext_phy_addr
);
4781 /* DSP Remove Download Mode */
4782 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_0
,
4783 MISC_REGISTERS_GPIO_LOW
, port
);
4785 bnx2x_sfx7101_sp_sw_reset(bp
, port
, ext_phy_addr
);
4787 /* wait 0.5 sec to allow it to run */
4788 for (cnt
= 0; cnt
< 100; cnt
++)
4791 bnx2x_hw_reset(bp
, port
);
4793 for (cnt
= 0; cnt
< 100; cnt
++)
4796 /* Check that the code is started. In case the download
4797 checksum failed, the code won't be started. */
4798 bnx2x_cl45_read(bp
, port
,
4799 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4802 MDIO_PCS_REG_7101_DSP_ACCESS
,
4805 code_started
= (tmp
& (1<<4));
4806 if (!code_started
) {
4807 DP(NETIF_MSG_LINK
, "Download failed. Please check file.\n");
4811 /* Verify that the file revision is now equal to the image
4812 revision within the DSP */
4813 bnx2x_cl45_read(bp
, port
,
4814 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4817 MDIO_PMA_REG_7101_VER1
,
4820 bnx2x_cl45_read(bp
, port
,
4821 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
4824 MDIO_PMA_REG_7101_VER2
,
4827 if (data
[0x14e] != (image_revision2
&0xFF) ||
4828 data
[0x14f] != ((image_revision2
&0xFF00)>>8) ||
4829 data
[0x150] != (image_revision1
&0xFF) ||
4830 data
[0x151] != ((image_revision1
&0xFF00)>>8)) {
4831 DP(NETIF_MSG_LINK
, "Download failed.\n");
4834 DP(NETIF_MSG_LINK
, "Download %d%%\n", data_index
/size
);
4838 u8
bnx2x_flash_download(struct bnx2x
*bp
, u8 port
, u32 ext_phy_config
,
4839 u8 driver_loaded
, char data
[], u32 size
)
4844 ext_phy_addr
= ((ext_phy_config
&
4845 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK
) >>
4846 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT
);
4848 ext_phy_type
= XGXS_EXT_PHY_TYPE(ext_phy_config
);
4850 switch (ext_phy_type
) {
4851 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
:
4852 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
4853 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
4854 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
4856 "Flash download not supported for this ext phy\n");
4859 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
4860 /* Take ext phy out of reset */
4862 bnx2x_turn_on_ef(bp
, port
, ext_phy_addr
, ext_phy_type
);
4863 rc
= bnx2x_sfx7101_flash_download(bp
, port
, ext_phy_addr
,
4866 bnx2x_turn_off_sf(bp
, port
);
4868 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
4869 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
4870 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
:
4872 DP(NETIF_MSG_LINK
, "Invalid ext phy type\n");