1 /* Copyright 2008 Broadcom Corporation
3 * Unless you and Broadcom execute a separate written software license
4 * agreement governing use of this software, this software is licensed to you
5 * under the terms of the GNU General Public License version 2, available
6 * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
8 * Notwithstanding the above, under no circumstances may you combine this
9 * software in any way with any other Broadcom software provided under a
10 * license other than the GPL, without Broadcom's express prior written
13 * Written by Yaniv Rosner
17 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/pci.h>
20 #include <linux/netdevice.h>
21 #include <linux/delay.h>
22 #include <linux/ethtool.h>
23 #include <linux/mutex.h>
24 #include <linux/version.h>
26 #include "bnx2x_reg.h"
27 #include "bnx2x_fw_defs.h"
28 #include "bnx2x_hsi.h"
29 #include "bnx2x_link.h"
32 /********************************************************/
33 #define SUPPORT_CL73 0 /* Currently no */
35 #define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
36 #define ETH_MIN_PACKET_SIZE 60
37 #define ETH_MAX_PACKET_SIZE 1500
38 #define ETH_MAX_JUMBO_PACKET_SIZE 9600
39 #define MDIO_ACCESS_TIMEOUT 1000
40 #define BMAC_CONTROL_RX_ENABLE 2
42 /***********************************************************/
43 /* Shortcut definitions */
44 /***********************************************************/
46 #define NIG_STATUS_XGXS0_LINK10G \
47 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
48 #define NIG_STATUS_XGXS0_LINK_STATUS \
49 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
50 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
51 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
52 #define NIG_STATUS_SERDES0_LINK_STATUS \
53 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
54 #define NIG_MASK_MI_INT \
55 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
56 #define NIG_MASK_XGXS0_LINK10G \
57 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
58 #define NIG_MASK_XGXS0_LINK_STATUS \
59 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
60 #define NIG_MASK_SERDES0_LINK_STATUS \
61 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
63 #define MDIO_AN_CL73_OR_37_COMPLETE \
64 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
65 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
67 #define XGXS_RESET_BITS \
68 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
69 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
70 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
71 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
72 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
74 #define SERDES_RESET_BITS \
75 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
76 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
77 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
78 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
80 #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
81 #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
82 #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
83 #define AUTONEG_PARALLEL \
84 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
85 #define AUTONEG_SGMII_FIBER_AUTODET \
86 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
87 #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
89 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
90 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
91 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
92 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
93 #define GP_STATUS_SPEED_MASK \
94 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
95 #define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
96 #define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
97 #define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
98 #define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
99 #define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
100 #define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
101 #define GP_STATUS_10G_HIG \
102 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
103 #define GP_STATUS_10G_CX4 \
104 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
105 #define GP_STATUS_12G_HIG \
106 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
107 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
108 #define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
109 #define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
110 #define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
111 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
112 #define GP_STATUS_10G_KX4 \
113 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
115 #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
116 #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
117 #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
118 #define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
119 #define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
120 #define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
121 #define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
122 #define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
123 #define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
124 #define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
125 #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
126 #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
127 #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
128 #define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
129 #define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
130 #define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
131 #define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
132 #define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
133 #define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
134 #define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
135 #define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
136 #define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
137 #define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
139 #define PHY_XGXS_FLAG 0x1
140 #define PHY_SGMII_FLAG 0x2
141 #define PHY_SERDES_FLAG 0x4
143 /**********************************************************/
145 /**********************************************************/
146 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
147 bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
148 DEFAULT_PHY_DEV_ADDR, \
149 (_bank + (_addr & 0xf)), \
152 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
153 bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
154 DEFAULT_PHY_DEV_ADDR, \
155 (_bank + (_addr & 0xf)), \
158 static void bnx2x_set_phy_mdio(struct link_params *params)
160 struct bnx2x *bp = params->bp;
161 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
162 params->port*0x18, 0);
163 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
164 DEFAULT_PHY_DEV_ADDR);
167 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
169 u32 val = REG_RD(bp, reg);
172 REG_WR(bp, reg, val);
176 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
178 u32 val = REG_RD(bp, reg);
181 REG_WR(bp, reg, val);
185 static void bnx2x_emac_init(struct link_params *params,
186 struct link_vars *vars)
188 /* reset and unreset the emac core */
189 struct bnx2x *bp = params->bp;
190 u8 port = params->port;
191 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
195 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
196 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
198 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
199 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
201 /* init emac - use read-modify-write */
202 /* self clear reset */
203 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
204 EMAC_WR(EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
209 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
210 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
212 DP(NETIF_MSG_LINK, "EMAC timeout!\n");
216 }while (val & EMAC_MODE_RESET);
218 /* Set mac address */
219 val = ((params->mac_addr[0] << 8) |
220 params->mac_addr[1]);
221 EMAC_WR(EMAC_REG_EMAC_MAC_MATCH, val);
223 val = ((params->mac_addr[2] << 24) |
224 (params->mac_addr[3] << 16) |
225 (params->mac_addr[4] << 8) |
226 params->mac_addr[5]);
227 EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val);
230 static u8 bnx2x_emac_enable(struct link_params *params,
231 struct link_vars *vars, u8 lb)
233 struct bnx2x *bp = params->bp;
234 u8 port = params->port;
235 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
238 DP(NETIF_MSG_LINK, "enabling EMAC\n");
240 /* enable emac and not bmac */
241 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
244 if (CHIP_REV_IS_EMUL(bp)) {
245 /* Use lane 1 (of lanes 0-3) */
246 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
247 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
253 if (CHIP_REV_IS_FPGA(bp)) {
254 /* Use lane 1 (of lanes 0-3) */
255 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
257 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
258 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
262 if (vars->phy_flags & PHY_XGXS_FLAG) {
263 u32 ser_lane = ((params->lane_config &
264 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
265 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
267 DP(NETIF_MSG_LINK, "XGXS\n");
268 /* select the master lanes (out of 0-3) */
269 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
272 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
275 } else { /* SerDes */
276 DP(NETIF_MSG_LINK, "SerDes\n");
278 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
283 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
285 if (CHIP_REV_IS_SLOW(bp)) {
286 /* config GMII mode */
287 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
288 EMAC_WR(EMAC_REG_EMAC_MODE,
289 (val | EMAC_MODE_PORT_GMII));
291 /* pause enable/disable */
292 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
293 EMAC_RX_MODE_FLOW_EN);
294 if (vars->flow_ctrl & FLOW_CTRL_RX)
295 bnx2x_bits_en(bp, emac_base +
296 EMAC_REG_EMAC_RX_MODE,
297 EMAC_RX_MODE_FLOW_EN);
299 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
300 (EMAC_TX_MODE_EXT_PAUSE_EN |
301 EMAC_TX_MODE_FLOW_EN));
302 if (vars->flow_ctrl & FLOW_CTRL_TX)
303 bnx2x_bits_en(bp, emac_base +
304 EMAC_REG_EMAC_TX_MODE,
305 (EMAC_TX_MODE_EXT_PAUSE_EN |
306 EMAC_TX_MODE_FLOW_EN));
309 /* KEEP_VLAN_TAG, promiscuous */
310 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
311 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
312 EMAC_WR(EMAC_REG_EMAC_RX_MODE, val);
315 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
320 EMAC_WR(EMAC_REG_EMAC_MODE, val);
322 /* enable emac for jumbo packets */
323 EMAC_WR(EMAC_REG_EMAC_RX_MTU_SIZE,
324 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
325 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
328 REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
330 /* disable the NIG in/out to the bmac */
331 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
332 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
333 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
335 /* enable the NIG in/out to the emac */
336 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
338 if (vars->flow_ctrl & FLOW_CTRL_TX)
341 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
342 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
344 if (CHIP_REV_IS_EMUL(bp)) {
345 /* take the BigMac out of reset */
347 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
348 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
350 /* enable access for bmac registers */
351 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
354 vars->mac_type = MAC_TYPE_EMAC;
360 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
363 struct bnx2x *bp = params->bp;
364 u8 port = params->port;
365 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
366 NIG_REG_INGRESS_BMAC0_MEM;
370 DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
371 /* reset and unreset the BigMac */
372 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
373 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
376 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
377 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
379 /* enable access for bmac registers */
380 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
385 REG_WR_DMAE(bp, bmac_addr +
386 BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
390 wb_data[0] = ((params->mac_addr[2] << 24) |
391 (params->mac_addr[3] << 16) |
392 (params->mac_addr[4] << 8) |
393 params->mac_addr[5]);
394 wb_data[1] = ((params->mac_addr[0] << 8) |
395 params->mac_addr[1]);
396 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
401 if (vars->flow_ctrl & FLOW_CTRL_TX)
405 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
412 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
416 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
421 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
423 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
426 /* rx control set to don't strip crc */
428 if (vars->flow_ctrl & FLOW_CTRL_RX)
432 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
436 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
438 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
441 /* set cnt max size */
442 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
444 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
448 wb_data[0] = 0x1000200;
450 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
452 /* fix for emulation */
453 if (CHIP_REV_IS_EMUL(bp)) {
457 bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
461 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
462 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
463 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
465 if (vars->flow_ctrl & FLOW_CTRL_TX)
467 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
468 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
469 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
470 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
471 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
472 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
474 vars->mac_type = MAC_TYPE_BMAC;
478 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
480 struct bnx2x *bp = params->bp;
483 if (phy_flags & PHY_XGXS_FLAG) {
484 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
485 val = XGXS_RESET_BITS;
487 } else { /* SerDes */
488 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
489 val = SERDES_RESET_BITS;
492 val = val << (params->port*16);
494 /* reset and unreset the SerDes/XGXS */
495 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
498 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
500 bnx2x_set_phy_mdio(params);
503 void bnx2x_link_status_update(struct link_params *params,
504 struct link_vars *vars)
506 struct bnx2x *bp = params->bp;
508 u8 port = params->port;
510 if (params->switch_cfg == SWITCH_CFG_1G)
511 vars->phy_flags = PHY_SERDES_FLAG;
513 vars->phy_flags = PHY_XGXS_FLAG;
514 vars->link_status = REG_RD(bp, params->shmem_base +
515 offsetof(struct shmem_region,
516 port_mb[port].link_status));
518 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
521 DP(NETIF_MSG_LINK, "phy link up\n");
523 vars->phy_link_up = 1;
524 vars->duplex = DUPLEX_FULL;
525 switch (vars->link_status &
526 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
528 vars->duplex = DUPLEX_HALF;
531 vars->line_speed = SPEED_10;
535 vars->duplex = DUPLEX_HALF;
539 vars->line_speed = SPEED_100;
543 vars->duplex = DUPLEX_HALF;
546 vars->line_speed = SPEED_1000;
550 vars->duplex = DUPLEX_HALF;
553 vars->line_speed = SPEED_2500;
557 vars->line_speed = SPEED_10000;
561 vars->line_speed = SPEED_12000;
565 vars->line_speed = SPEED_12500;
569 vars->line_speed = SPEED_13000;
573 vars->line_speed = SPEED_15000;
577 vars->line_speed = SPEED_16000;
584 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
585 vars->flow_ctrl |= FLOW_CTRL_TX;
587 vars->flow_ctrl &= ~FLOW_CTRL_TX;
589 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
590 vars->flow_ctrl |= FLOW_CTRL_RX;
592 vars->flow_ctrl &= ~FLOW_CTRL_RX;
594 if (vars->phy_flags & PHY_XGXS_FLAG) {
595 if (vars->line_speed &&
596 ((vars->line_speed == SPEED_10) ||
597 (vars->line_speed == SPEED_100))) {
598 vars->phy_flags |= PHY_SGMII_FLAG;
600 vars->phy_flags &= ~PHY_SGMII_FLAG;
604 /* anything 10 and over uses the bmac */
605 link_10g = ((vars->line_speed == SPEED_10000) ||
606 (vars->line_speed == SPEED_12000) ||
607 (vars->line_speed == SPEED_12500) ||
608 (vars->line_speed == SPEED_13000) ||
609 (vars->line_speed == SPEED_15000) ||
610 (vars->line_speed == SPEED_16000));
612 vars->mac_type = MAC_TYPE_BMAC;
614 vars->mac_type = MAC_TYPE_EMAC;
616 } else { /* link down */
617 DP(NETIF_MSG_LINK, "phy link down\n");
619 vars->phy_link_up = 0;
621 vars->line_speed = 0;
622 vars->duplex = DUPLEX_FULL;
623 vars->flow_ctrl = FLOW_CTRL_NONE;
625 /* indicate no mac active */
626 vars->mac_type = MAC_TYPE_NONE;
629 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
630 vars->link_status, vars->phy_link_up);
631 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
632 vars->line_speed, vars->duplex, vars->flow_ctrl);
635 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
637 struct bnx2x *bp = params->bp;
638 REG_WR(bp, params->shmem_base +
639 offsetof(struct shmem_region,
640 port_mb[params->port].link_status),
644 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
646 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
647 NIG_REG_INGRESS_BMAC0_MEM;
649 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
651 /* Only if the bmac is out of reset */
652 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
653 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
656 /* Clear Rx Enable bit in BMAC_CONTROL register */
657 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
659 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
660 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
667 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
670 struct bnx2x *bp = params->bp;
671 u8 port = params->port;
676 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
678 /* wait for init credit */
679 init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
680 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
681 DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
683 while ((init_crd != crd) && count) {
686 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
689 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
690 if (init_crd != crd) {
691 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
696 if (flow_ctrl & FLOW_CTRL_RX ||
697 line_speed == SPEED_10 ||
698 line_speed == SPEED_100 ||
699 line_speed == SPEED_1000 ||
700 line_speed == SPEED_2500) {
701 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
702 /* update threshold */
703 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
704 /* update init credit */
705 init_crd = 778; /* (800-18-4) */
708 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
710 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
711 /* update threshold */
712 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
713 /* update init credit */
714 switch (line_speed) {
716 init_crd = thresh + 553 - 22;
720 init_crd = thresh + 664 - 22;
724 init_crd = thresh + 742 - 22;
728 init_crd = thresh + 778 - 22;
731 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
737 REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
738 DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
739 line_speed, init_crd);
741 /* probe the credit changes */
742 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
744 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
747 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
751 static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port)
754 switch (ext_phy_type) {
755 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
756 emac_base = GRCBASE_EMAC0;
758 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
759 emac_base = (port) ? GRCBASE_EMAC0: GRCBASE_EMAC1;
762 emac_base = (port) ? GRCBASE_EMAC1: GRCBASE_EMAC0;
769 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
770 u8 phy_addr, u8 devad, u16 reg, u16 val)
774 u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
776 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
777 * (a value of 49==0x31) and make sure that the AUTO poll is off
779 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
780 tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
781 EMAC_MDIO_MODE_CLOCK_CNT);
782 tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
783 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
784 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
785 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
790 tmp = ((phy_addr << 21) | (devad << 16) | reg |
791 EMAC_MDIO_COMM_COMMAND_ADDRESS |
792 EMAC_MDIO_COMM_START_BUSY);
793 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
795 for (i = 0; i < 50; i++) {
798 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
799 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
804 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
805 DP(NETIF_MSG_LINK, "write phy register failed\n");
809 tmp = ((phy_addr << 21) | (devad << 16) | val |
810 EMAC_MDIO_COMM_COMMAND_WRITE_45 |
811 EMAC_MDIO_COMM_START_BUSY);
812 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
814 for (i = 0; i < 50; i++) {
817 tmp = REG_RD(bp, mdio_ctrl +
818 EMAC_REG_EMAC_MDIO_COMM);
819 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
824 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
825 DP(NETIF_MSG_LINK, "write phy register failed\n");
830 /* Restore the saved mode */
831 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
836 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
837 u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
843 u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
844 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
845 * (a value of 49==0x31) and make sure that the AUTO poll is off
847 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
848 val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
849 EMAC_MDIO_MODE_CLOCK_CNT));
850 val |= (EMAC_MDIO_MODE_CLAUSE_45 |
851 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
852 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
853 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
857 val = ((phy_addr << 21) | (devad << 16) | reg |
858 EMAC_MDIO_COMM_COMMAND_ADDRESS |
859 EMAC_MDIO_COMM_START_BUSY);
860 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
862 for (i = 0; i < 50; i++) {
865 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
866 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
871 if (val & EMAC_MDIO_COMM_START_BUSY) {
872 DP(NETIF_MSG_LINK, "read phy register failed\n");
879 val = ((phy_addr << 21) | (devad << 16) |
880 EMAC_MDIO_COMM_COMMAND_READ_45 |
881 EMAC_MDIO_COMM_START_BUSY);
882 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
884 for (i = 0; i < 50; i++) {
887 val = REG_RD(bp, mdio_ctrl +
888 EMAC_REG_EMAC_MDIO_COMM);
889 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
890 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
894 if (val & EMAC_MDIO_COMM_START_BUSY) {
895 DP(NETIF_MSG_LINK, "read phy register failed\n");
902 /* Restore the saved mode */
903 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
908 static void bnx2x_set_aer_mmd(struct link_params *params,
909 struct link_vars *vars)
911 struct bnx2x *bp = params->bp;
915 ser_lane = ((params->lane_config &
916 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
917 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
919 offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
920 (params->phy_addr + ser_lane) : 0;
922 CL45_WR_OVER_CL22(bp, params->port,
924 MDIO_REG_BANK_AER_BLOCK,
925 MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
928 static void bnx2x_set_master_ln(struct link_params *params)
930 struct bnx2x *bp = params->bp;
931 u16 new_master_ln, ser_lane;
932 ser_lane = ((params->lane_config &
933 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
934 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
936 /* set the master_ln for AN */
937 CL45_RD_OVER_CL22(bp, params->port,
939 MDIO_REG_BANK_XGXS_BLOCK2,
940 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
943 CL45_WR_OVER_CL22(bp, params->port,
945 MDIO_REG_BANK_XGXS_BLOCK2 ,
946 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
947 (new_master_ln | ser_lane));
950 static u8 bnx2x_reset_unicore(struct link_params *params)
952 struct bnx2x *bp = params->bp;
956 CL45_RD_OVER_CL22(bp, params->port,
958 MDIO_REG_BANK_COMBO_IEEE0,
959 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
961 /* reset the unicore */
962 CL45_WR_OVER_CL22(bp, params->port,
964 MDIO_REG_BANK_COMBO_IEEE0,
965 MDIO_COMBO_IEEE0_MII_CONTROL,
967 MDIO_COMBO_IEEO_MII_CONTROL_RESET));
969 /* wait for the reset to self clear */
970 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
973 /* the reset erased the previous bank value */
974 CL45_RD_OVER_CL22(bp, params->port,
976 MDIO_REG_BANK_COMBO_IEEE0,
977 MDIO_COMBO_IEEE0_MII_CONTROL,
980 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
986 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
991 static void bnx2x_set_swap_lanes(struct link_params *params)
993 struct bnx2x *bp = params->bp;
994 /* Each two bits represents a lane number:
995 No swap is 0123 => 0x1b no need to enable the swap */
996 u16 ser_lane, rx_lane_swap, tx_lane_swap;
998 ser_lane = ((params->lane_config &
999 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1000 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1001 rx_lane_swap = ((params->lane_config &
1002 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1003 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1004 tx_lane_swap = ((params->lane_config &
1005 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1006 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1008 if (rx_lane_swap != 0x1b) {
1009 CL45_WR_OVER_CL22(bp, params->port,
1011 MDIO_REG_BANK_XGXS_BLOCK2,
1012 MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1014 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1015 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1017 CL45_WR_OVER_CL22(bp, params->port,
1019 MDIO_REG_BANK_XGXS_BLOCK2,
1020 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1023 if (tx_lane_swap != 0x1b) {
1024 CL45_WR_OVER_CL22(bp, params->port,
1026 MDIO_REG_BANK_XGXS_BLOCK2,
1027 MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1029 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1031 CL45_WR_OVER_CL22(bp, params->port,
1033 MDIO_REG_BANK_XGXS_BLOCK2,
1034 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1038 static void bnx2x_set_parallel_detection(struct link_params *params,
1041 struct bnx2x *bp = params->bp;
1044 CL45_RD_OVER_CL22(bp, params->port,
1046 MDIO_REG_BANK_SERDES_DIGITAL,
1047 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1051 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1054 CL45_WR_OVER_CL22(bp, params->port,
1056 MDIO_REG_BANK_SERDES_DIGITAL,
1057 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1060 if (phy_flags & PHY_XGXS_FLAG) {
1061 DP(NETIF_MSG_LINK, "XGXS\n");
1063 CL45_WR_OVER_CL22(bp, params->port,
1065 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1066 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1067 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1069 CL45_RD_OVER_CL22(bp, params->port,
1071 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1072 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1077 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1079 CL45_WR_OVER_CL22(bp, params->port,
1081 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1082 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1085 /* Disable parallel detection of HiG */
1086 CL45_WR_OVER_CL22(bp, params->port,
1088 MDIO_REG_BANK_XGXS_BLOCK2,
1089 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1090 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1091 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1095 static void bnx2x_set_autoneg(struct link_params *params,
1096 struct link_vars *vars)
1098 struct bnx2x *bp = params->bp;
1103 CL45_RD_OVER_CL22(bp, params->port,
1105 MDIO_REG_BANK_COMBO_IEEE0,
1106 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
1108 /* CL37 Autoneg Enabled */
1109 if (vars->line_speed == SPEED_AUTO_NEG)
1110 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1111 else /* CL37 Autoneg Disabled */
1112 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1113 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1115 CL45_WR_OVER_CL22(bp, params->port,
1117 MDIO_REG_BANK_COMBO_IEEE0,
1118 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1120 /* Enable/Disable Autodetection */
1122 CL45_RD_OVER_CL22(bp, params->port,
1124 MDIO_REG_BANK_SERDES_DIGITAL,
1125 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val);
1126 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1127 if (vars->line_speed == SPEED_AUTO_NEG)
1128 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1130 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1132 CL45_WR_OVER_CL22(bp, params->port,
1134 MDIO_REG_BANK_SERDES_DIGITAL,
1135 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1137 /* Enable TetonII and BAM autoneg */
1138 CL45_RD_OVER_CL22(bp, params->port,
1140 MDIO_REG_BANK_BAM_NEXT_PAGE,
1141 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1143 if (vars->line_speed == SPEED_AUTO_NEG) {
1144 /* Enable BAM aneg Mode and TetonII aneg Mode */
1145 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1146 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1148 /* TetonII and BAM Autoneg Disabled */
1149 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1150 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1152 CL45_WR_OVER_CL22(bp, params->port,
1154 MDIO_REG_BANK_BAM_NEXT_PAGE,
1155 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1158 /* Enable Clause 73 Aneg */
1159 if ((vars->line_speed == SPEED_AUTO_NEG) &&
1161 /* Enable BAM Station Manager */
1163 CL45_WR_OVER_CL22(bp, params->port,
1165 MDIO_REG_BANK_CL73_USERB0,
1166 MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1167 (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1168 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1169 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
1171 /* Merge CL73 and CL37 aneg resolution */
1172 CL45_RD_OVER_CL22(bp, params->port,
1174 MDIO_REG_BANK_CL73_USERB0,
1175 MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1178 CL45_WR_OVER_CL22(bp, params->port,
1180 MDIO_REG_BANK_CL73_USERB0,
1181 MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1183 MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
1185 /* Set the CL73 AN speed */
1187 CL45_RD_OVER_CL22(bp, params->port,
1189 MDIO_REG_BANK_CL73_IEEEB1,
1190 MDIO_CL73_IEEEB1_AN_ADV2, ®_val);
1191 /* In the SerDes we support only the 1G.
1192 In the XGXS we support the 10G KX4
1193 but we currently do not support the KR */
1194 if (vars->phy_flags & PHY_XGXS_FLAG) {
1195 DP(NETIF_MSG_LINK, "XGXS\n");
1197 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1199 DP(NETIF_MSG_LINK, "SerDes\n");
1201 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1203 CL45_WR_OVER_CL22(bp, params->port,
1205 MDIO_REG_BANK_CL73_IEEEB1,
1206 MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
1208 /* CL73 Autoneg Enabled */
1209 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
1211 /* CL73 Autoneg Disabled */
1214 CL45_WR_OVER_CL22(bp, params->port,
1216 MDIO_REG_BANK_CL73_IEEEB0,
1217 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1220 /* program SerDes, forced speed */
1221 static void bnx2x_program_serdes(struct link_params *params,
1222 struct link_vars *vars)
1224 struct bnx2x *bp = params->bp;
1227 /* program duplex, disable autoneg */
1229 CL45_RD_OVER_CL22(bp, params->port,
1231 MDIO_REG_BANK_COMBO_IEEE0,
1232 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
1233 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1234 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
1235 if (params->req_duplex == DUPLEX_FULL)
1236 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1237 CL45_WR_OVER_CL22(bp, params->port,
1239 MDIO_REG_BANK_COMBO_IEEE0,
1240 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1243 - needed only if the speed is greater than 1G (2.5G or 10G) */
1244 CL45_RD_OVER_CL22(bp, params->port,
1246 MDIO_REG_BANK_SERDES_DIGITAL,
1247 MDIO_SERDES_DIGITAL_MISC1, ®_val);
1248 /* clearing the speed value before setting the right speed */
1249 DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1251 reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1252 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1254 if (!((vars->line_speed == SPEED_1000) ||
1255 (vars->line_speed == SPEED_100) ||
1256 (vars->line_speed == SPEED_10))) {
1258 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1259 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1260 if (vars->line_speed == SPEED_10000)
1262 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1263 if (vars->line_speed == SPEED_13000)
1265 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1268 CL45_WR_OVER_CL22(bp, params->port,
1270 MDIO_REG_BANK_SERDES_DIGITAL,
1271 MDIO_SERDES_DIGITAL_MISC1, reg_val);
1275 static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1277 struct bnx2x *bp = params->bp;
1280 /* configure the 48 bits for BAM AN */
1282 /* set extended capabilities */
1283 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1284 val |= MDIO_OVER_1G_UP1_2_5G;
1285 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1286 val |= MDIO_OVER_1G_UP1_10G;
1287 CL45_WR_OVER_CL22(bp, params->port,
1289 MDIO_REG_BANK_OVER_1G,
1290 MDIO_OVER_1G_UP1, val);
1292 CL45_WR_OVER_CL22(bp, params->port,
1294 MDIO_REG_BANK_OVER_1G,
1295 MDIO_OVER_1G_UP3, 0);
1298 static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
1300 *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1301 /* resolve pause mode and advertisement
1302 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1304 switch (params->req_flow_ctrl) {
1305 case FLOW_CTRL_AUTO:
1306 if (params->req_fc_auto_adv == FLOW_CTRL_BOTH) {
1308 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1311 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1316 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1320 case FLOW_CTRL_BOTH:
1321 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1324 case FLOW_CTRL_NONE:
1326 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1331 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1334 struct bnx2x *bp = params->bp;
1335 /* for AN, we are always publishing full duplex */
1337 CL45_WR_OVER_CL22(bp, params->port,
1339 MDIO_REG_BANK_COMBO_IEEE0,
1340 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
1343 static void bnx2x_restart_autoneg(struct link_params *params)
1345 struct bnx2x *bp = params->bp;
1346 DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1348 /* enable and restart clause 73 aneg */
1351 CL45_RD_OVER_CL22(bp, params->port,
1353 MDIO_REG_BANK_CL73_IEEEB0,
1354 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1356 CL45_WR_OVER_CL22(bp, params->port,
1358 MDIO_REG_BANK_CL73_IEEEB0,
1359 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1361 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1362 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1365 /* Enable and restart BAM/CL37 aneg */
1368 CL45_RD_OVER_CL22(bp, params->port,
1370 MDIO_REG_BANK_COMBO_IEEE0,
1371 MDIO_COMBO_IEEE0_MII_CONTROL,
1374 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1376 CL45_WR_OVER_CL22(bp, params->port,
1378 MDIO_REG_BANK_COMBO_IEEE0,
1379 MDIO_COMBO_IEEE0_MII_CONTROL,
1381 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1382 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1386 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1387 struct link_vars *vars)
1389 struct bnx2x *bp = params->bp;
1392 /* in SGMII mode, the unicore is always slave */
1394 CL45_RD_OVER_CL22(bp, params->port,
1396 MDIO_REG_BANK_SERDES_DIGITAL,
1397 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1399 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1400 /* set sgmii mode (and not fiber) */
1401 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1402 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1403 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1404 CL45_WR_OVER_CL22(bp, params->port,
1406 MDIO_REG_BANK_SERDES_DIGITAL,
1407 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1410 /* if forced speed */
1411 if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1412 /* set speed, disable autoneg */
1415 CL45_RD_OVER_CL22(bp, params->port,
1417 MDIO_REG_BANK_COMBO_IEEE0,
1418 MDIO_COMBO_IEEE0_MII_CONTROL,
1420 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1421 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1422 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1424 switch (vars->line_speed) {
1427 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1431 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1434 /* there is nothing to set for 10M */
1437 /* invalid speed for SGMII */
1438 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1443 /* setting the full duplex */
1444 if (params->req_duplex == DUPLEX_FULL)
1446 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1447 CL45_WR_OVER_CL22(bp, params->port,
1449 MDIO_REG_BANK_COMBO_IEEE0,
1450 MDIO_COMBO_IEEE0_MII_CONTROL,
1453 } else { /* AN mode */
1454 /* enable and restart AN */
1455 bnx2x_restart_autoneg(params);
1464 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1466 switch (pause_result) { /* ASYM P ASYM P */
1467 case 0xb: /* 1 0 1 1 */
1468 vars->flow_ctrl = FLOW_CTRL_TX;
1471 case 0xe: /* 1 1 1 0 */
1472 vars->flow_ctrl = FLOW_CTRL_RX;
1475 case 0x5: /* 0 1 0 1 */
1476 case 0x7: /* 0 1 1 1 */
1477 case 0xd: /* 1 1 0 1 */
1478 case 0xf: /* 1 1 1 1 */
1479 vars->flow_ctrl = FLOW_CTRL_BOTH;
1487 static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1488 struct link_vars *vars)
1490 struct bnx2x *bp = params->bp;
1492 u16 ld_pause; /* local */
1493 u16 lp_pause; /* link partner */
1494 u16 an_complete; /* AN complete */
1498 u8 port = params->port;
1499 ext_phy_addr = ((params->ext_phy_config &
1500 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1501 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1503 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1506 bnx2x_cl45_read(bp, port,
1510 MDIO_AN_REG_STATUS, &an_complete);
1511 bnx2x_cl45_read(bp, port,
1515 MDIO_AN_REG_STATUS, &an_complete);
1517 if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1519 bnx2x_cl45_read(bp, port,
1523 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1524 bnx2x_cl45_read(bp, port,
1528 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1529 pause_result = (ld_pause &
1530 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1531 pause_result |= (lp_pause &
1532 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1533 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1535 bnx2x_pause_resolve(vars, pause_result);
1536 if (vars->flow_ctrl == FLOW_CTRL_NONE &&
1537 ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1538 bnx2x_cl45_read(bp, port,
1542 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1544 bnx2x_cl45_read(bp, port,
1548 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1549 pause_result = (ld_pause &
1550 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1551 pause_result |= (lp_pause &
1552 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1554 bnx2x_pause_resolve(vars, pause_result);
1555 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1563 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1564 struct link_vars *vars,
1567 struct bnx2x *bp = params->bp;
1568 u16 ld_pause; /* local driver */
1569 u16 lp_pause; /* link partner */
1572 vars->flow_ctrl = FLOW_CTRL_NONE;
1574 /* resolve from gp_status in case of AN complete and not sgmii */
1575 if ((params->req_flow_ctrl == FLOW_CTRL_AUTO) &&
1576 (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1577 (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1578 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1579 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1580 CL45_RD_OVER_CL22(bp, params->port,
1582 MDIO_REG_BANK_COMBO_IEEE0,
1583 MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1585 CL45_RD_OVER_CL22(bp, params->port,
1587 MDIO_REG_BANK_COMBO_IEEE0,
1588 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1590 pause_result = (ld_pause &
1591 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1592 pause_result |= (lp_pause &
1593 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1594 DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1595 bnx2x_pause_resolve(vars, pause_result);
1596 } else if ((params->req_flow_ctrl == FLOW_CTRL_AUTO) &&
1597 (bnx2x_ext_phy_resove_fc(params, vars))) {
1600 if (params->req_flow_ctrl == FLOW_CTRL_AUTO)
1601 vars->flow_ctrl = params->req_fc_auto_adv;
1603 vars->flow_ctrl = params->req_flow_ctrl;
1605 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1609 static u8 bnx2x_link_settings_status(struct link_params *params,
1610 struct link_vars *vars,
1613 struct bnx2x *bp = params->bp;
1615 vars->link_status = 0;
1617 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1618 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1621 vars->phy_link_up = 1;
1622 vars->link_status |= LINK_STATUS_LINK_UP;
1624 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1625 vars->duplex = DUPLEX_FULL;
1627 vars->duplex = DUPLEX_HALF;
1629 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1631 switch (gp_status & GP_STATUS_SPEED_MASK) {
1633 vars->line_speed = SPEED_10;
1634 if (vars->duplex == DUPLEX_FULL)
1635 vars->link_status |= LINK_10TFD;
1637 vars->link_status |= LINK_10THD;
1640 case GP_STATUS_100M:
1641 vars->line_speed = SPEED_100;
1642 if (vars->duplex == DUPLEX_FULL)
1643 vars->link_status |= LINK_100TXFD;
1645 vars->link_status |= LINK_100TXHD;
1649 case GP_STATUS_1G_KX:
1650 vars->line_speed = SPEED_1000;
1651 if (vars->duplex == DUPLEX_FULL)
1652 vars->link_status |= LINK_1000TFD;
1654 vars->link_status |= LINK_1000THD;
1657 case GP_STATUS_2_5G:
1658 vars->line_speed = SPEED_2500;
1659 if (vars->duplex == DUPLEX_FULL)
1660 vars->link_status |= LINK_2500TFD;
1662 vars->link_status |= LINK_2500THD;
1668 "link speed unsupported gp_status 0x%x\n",
1672 case GP_STATUS_10G_KX4:
1673 case GP_STATUS_10G_HIG:
1674 case GP_STATUS_10G_CX4:
1675 vars->line_speed = SPEED_10000;
1676 vars->link_status |= LINK_10GTFD;
1679 case GP_STATUS_12G_HIG:
1680 vars->line_speed = SPEED_12000;
1681 vars->link_status |= LINK_12GTFD;
1684 case GP_STATUS_12_5G:
1685 vars->line_speed = SPEED_12500;
1686 vars->link_status |= LINK_12_5GTFD;
1690 vars->line_speed = SPEED_13000;
1691 vars->link_status |= LINK_13GTFD;
1695 vars->line_speed = SPEED_15000;
1696 vars->link_status |= LINK_15GTFD;
1700 vars->line_speed = SPEED_16000;
1701 vars->link_status |= LINK_16GTFD;
1706 "link speed unsupported gp_status 0x%x\n",
1712 vars->link_status |= LINK_STATUS_SERDES_LINK;
1714 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1715 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1716 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1717 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1718 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) {
1719 vars->autoneg = AUTO_NEG_ENABLED;
1721 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1722 vars->autoneg |= AUTO_NEG_COMPLETE;
1723 vars->link_status |=
1724 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1727 vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1728 vars->link_status |=
1729 LINK_STATUS_PARALLEL_DETECTION_USED;
1732 if (vars->flow_ctrl & FLOW_CTRL_TX)
1733 vars->link_status |=
1734 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1736 if (vars->flow_ctrl & FLOW_CTRL_RX)
1737 vars->link_status |=
1738 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1740 } else { /* link_down */
1741 DP(NETIF_MSG_LINK, "phy link down\n");
1743 vars->phy_link_up = 0;
1745 vars->duplex = DUPLEX_FULL;
1746 vars->flow_ctrl = FLOW_CTRL_NONE;
1747 vars->autoneg = AUTO_NEG_DISABLED;
1748 vars->mac_type = MAC_TYPE_NONE;
1751 DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x \n",
1752 gp_status, vars->phy_link_up, vars->line_speed);
1753 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x"
1756 vars->flow_ctrl, vars->autoneg);
1757 DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1762 static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
1764 struct bnx2x *bp = params->bp;
1770 CL45_RD_OVER_CL22(bp, params->port,
1772 MDIO_REG_BANK_OVER_1G,
1773 MDIO_OVER_1G_LP_UP2, &lp_up2);
1775 CL45_RD_OVER_CL22(bp, params->port,
1778 MDIO_TX0_TX_DRIVER, &tx_driver);
1780 /* bits [10:7] at lp_up2, positioned at [15:12] */
1781 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1782 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1783 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1785 if ((lp_up2 != 0) &&
1786 (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
1787 /* replace tx_driver bits [15:12] */
1788 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1789 tx_driver |= lp_up2;
1790 CL45_WR_OVER_CL22(bp, params->port,
1793 MDIO_TX0_TX_DRIVER, tx_driver);
1797 static u8 bnx2x_emac_program(struct link_params *params,
1798 u32 line_speed, u32 duplex)
1800 struct bnx2x *bp = params->bp;
1801 u8 port = params->port;
1804 DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1805 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1807 (EMAC_MODE_25G_MODE |
1808 EMAC_MODE_PORT_MII_10M |
1809 EMAC_MODE_HALF_DUPLEX));
1810 switch (line_speed) {
1812 mode |= EMAC_MODE_PORT_MII_10M;
1816 mode |= EMAC_MODE_PORT_MII;
1820 mode |= EMAC_MODE_PORT_GMII;
1824 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1828 /* 10G not valid for EMAC */
1829 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1833 if (duplex == DUPLEX_HALF)
1834 mode |= EMAC_MODE_HALF_DUPLEX;
1836 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1839 bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1840 line_speed, params->hw_led_mode, params->chip_id);
1844 /*****************************************************************************/
1845 /* External Phy section */
1846 /*****************************************************************************/
1847 static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
1849 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1850 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
1852 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1853 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
1856 static void bnx2x_ext_phy_reset(struct link_params *params,
1857 struct link_vars *vars)
1859 struct bnx2x *bp = params->bp;
1861 u8 ext_phy_addr = ((params->ext_phy_config &
1862 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1863 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1864 DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1865 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1866 /* The PHY reset is controled by GPIO 1
1867 * Give it 1ms of reset pulse
1869 if (vars->phy_flags & PHY_XGXS_FLAG) {
1871 switch (ext_phy_type) {
1872 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1873 DP(NETIF_MSG_LINK, "XGXS Direct\n");
1876 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1877 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1878 DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1880 /* Restore normal power mode*/
1881 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1882 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1886 bnx2x_hw_reset(bp, params->port);
1888 bnx2x_cl45_write(bp, params->port,
1892 MDIO_PMA_REG_CTRL, 0xa040);
1894 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1895 /* Unset Low Power Mode and SW reset */
1896 /* Restore normal power mode*/
1897 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1898 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1901 DP(NETIF_MSG_LINK, "XGXS 8072\n");
1902 bnx2x_cl45_write(bp, params->port,
1909 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1912 emac_base = (params->port) ? GRCBASE_EMAC0 :
1915 /* Restore normal power mode*/
1916 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1917 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1920 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1921 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1924 DP(NETIF_MSG_LINK, "XGXS 8073\n");
1928 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1929 DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1931 /* Restore normal power mode*/
1932 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1933 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1937 bnx2x_hw_reset(bp, params->port);
1941 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
1942 DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
1946 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
1947 params->ext_phy_config);
1951 } else { /* SerDes */
1952 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
1953 switch (ext_phy_type) {
1954 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
1955 DP(NETIF_MSG_LINK, "SerDes Direct\n");
1958 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
1959 DP(NETIF_MSG_LINK, "SerDes 5482\n");
1960 bnx2x_hw_reset(bp, params->port);
1965 "BAD SerDes ext_phy_config 0x%x\n",
1966 params->ext_phy_config);
1972 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
1974 struct bnx2x *bp = params->bp;
1975 u8 port = params->port;
1976 u8 ext_phy_addr = ((params->ext_phy_config &
1977 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1978 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1979 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1980 u16 fw_ver1, fw_ver2;
1982 /* Need to wait 200ms after reset */
1984 /* Boot port from external ROM
1985 * Set ser_boot_ctl bit in the MISC_CTRL1 register
1987 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1989 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
1991 /* Reset internal microprocessor */
1992 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1994 MDIO_PMA_REG_GEN_CTRL,
1995 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
1996 /* set micro reset = 0 */
1997 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1999 MDIO_PMA_REG_GEN_CTRL,
2000 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2001 /* Reset internal microprocessor */
2002 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2004 MDIO_PMA_REG_GEN_CTRL,
2005 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2006 /* wait for 100ms for code download via SPI port */
2009 /* Clear ser_boot_ctl bit */
2010 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2012 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2016 /* Print the PHY FW version */
2017 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2019 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2020 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2022 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2023 DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2026 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2028 /* This is only required for 8073A1, version 102 only */
2030 struct bnx2x *bp = params->bp;
2031 u8 ext_phy_addr = ((params->ext_phy_config &
2032 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2033 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2036 /* Read 8073 HW revision*/
2037 bnx2x_cl45_read(bp, params->port,
2038 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2044 /* No need to workaround in 8073 A1 */
2048 bnx2x_cl45_read(bp, params->port,
2049 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2052 MDIO_PMA_REG_ROM_VER2, &val);
2054 /* SNR should be applied only for version 0x102 */
2061 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2063 struct bnx2x *bp = params->bp;
2064 u8 ext_phy_addr = ((params->ext_phy_config &
2065 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2066 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2067 u16 val, cnt, cnt1 ;
2069 bnx2x_cl45_read(bp, params->port,
2070 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2076 /* No need to workaround in 8073 A1 */
2079 /* XAUI workaround in 8073 A0: */
2081 /* After loading the boot ROM and restarting Autoneg,
2082 poll Dev1, Reg $C820: */
2084 for (cnt = 0; cnt < 1000; cnt++) {
2085 bnx2x_cl45_read(bp, params->port,
2086 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2090 /* If bit [14] = 0 or bit [13] = 0, continue on with
2091 system initialization (XAUI work-around not required,
2092 as these bits indicate 2.5G or 1G link up). */
2093 if (!(val & (1<<14)) || !(val & (1<<13))) {
2094 DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2096 } else if (!(val & (1<<15))) {
2097 DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2098 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2099 it's MSB (bit 15) goes to 1 (indicating that the
2100 XAUI workaround has completed),
2101 then continue on with system initialization.*/
2102 for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2103 bnx2x_cl45_read(bp, params->port,
2104 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2108 if (val & (1<<15)) {
2110 "XAUI workaround has completed\n");
2119 DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2124 static void bnx2x_bcm8073_external_rom_boot(struct link_params *params)
2126 struct bnx2x *bp = params->bp;
2127 u8 port = params->port;
2128 u8 ext_phy_addr = ((params->ext_phy_config &
2129 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2130 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2131 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2132 u16 fw_ver1, fw_ver2, val;
2133 /* Need to wait 100ms after reset */
2135 /* Boot port from external ROM */
2137 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2139 MDIO_PMA_REG_GEN_CTRL,
2142 /* ucode reboot and rst */
2143 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2145 MDIO_PMA_REG_GEN_CTRL,
2148 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2150 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2152 /* Reset internal microprocessor */
2153 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
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, ext_phy_type, ext_phy_addr,
2161 MDIO_PMA_REG_GEN_CTRL,
2162 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2164 /* wait for 100ms for code download via SPI port */
2167 /* Clear ser_boot_ctl bit */
2168 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2170 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2172 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2174 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2175 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2177 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2178 DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2180 /* Only set bit 10 = 1 (Tx power down) */
2181 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2183 MDIO_PMA_REG_TX_POWER_DOWN, &val);
2185 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2187 MDIO_PMA_REG_TX_POWER_DOWN, (val | 1<<10));
2190 /* Release bit 10 (Release Tx power down) */
2191 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2193 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
2197 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2199 struct bnx2x *bp = params->bp;
2200 u8 port = params->port;
2202 u8 ext_phy_addr = ((params->ext_phy_config &
2203 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2204 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2205 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2207 bnx2x_cl45_read(bp, params->port,
2208 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2214 /* Mustn't set low power mode in 8073 A0 */
2218 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2219 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2221 MDIO_XS_PLL_SEQUENCER, &val);
2223 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2224 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2227 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2228 MDIO_XS_DEVAD, 0x805E, 0x1077);
2229 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2230 MDIO_XS_DEVAD, 0x805D, 0x0000);
2231 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2232 MDIO_XS_DEVAD, 0x805C, 0x030B);
2233 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2234 MDIO_XS_DEVAD, 0x805B, 0x1240);
2235 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2236 MDIO_XS_DEVAD, 0x805A, 0x2490);
2239 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2240 MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2241 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2242 MDIO_XS_DEVAD, 0x80A6, 0x9041);
2243 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2244 MDIO_XS_DEVAD, 0x80A5, 0x4640);
2247 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2248 MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2249 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2250 MDIO_XS_DEVAD, 0x80FD, 0x9249);
2251 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2252 MDIO_XS_DEVAD, 0x80FC, 0x2015);
2254 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
2255 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2257 MDIO_XS_PLL_SEQUENCER, &val);
2259 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2260 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2262 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2264 struct bnx2x *bp = params->bp;
2265 u8 port = params->port;
2266 u8 ext_phy_addr = ((params->ext_phy_config &
2267 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2268 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2269 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2271 /* Force KR or KX */
2272 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2276 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2278 MDIO_PMA_REG_10G_CTRL2,
2280 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2282 MDIO_PMA_REG_BCM_CTRL,
2284 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2290 static void bnx2x_ext_phy_set_pause(struct link_params *params,
2291 struct link_vars *vars)
2293 struct bnx2x *bp = params->bp;
2295 u8 ext_phy_addr = ((params->ext_phy_config &
2296 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2297 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2298 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2300 /* read modify write pause advertizing */
2301 bnx2x_cl45_read(bp, params->port,
2305 MDIO_AN_REG_ADV_PAUSE, &val);
2307 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2309 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2311 if ((vars->ieee_fc &
2312 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2313 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2314 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2316 if ((vars->ieee_fc &
2317 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2318 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2320 MDIO_AN_REG_ADV_PAUSE_PAUSE;
2323 "Ext phy AN advertize 0x%x\n", val);
2324 bnx2x_cl45_write(bp, params->port,
2328 MDIO_AN_REG_ADV_PAUSE, val);
2332 static void bnx2x_init_internal_phy(struct link_params *params,
2333 struct link_vars *vars)
2335 struct bnx2x *bp = params->bp;
2336 u8 port = params->port;
2337 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2340 rx_eq = ((params->serdes_config &
2341 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2342 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2344 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2345 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2346 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2347 CL45_WR_OVER_CL22(bp, port,
2350 MDIO_RX0_RX_EQ_BOOST,
2352 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2353 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2356 /* forced speed requested? */
2357 if (vars->line_speed != SPEED_AUTO_NEG) {
2358 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2360 /* disable autoneg */
2361 bnx2x_set_autoneg(params, vars);
2363 /* program speed and duplex */
2364 bnx2x_program_serdes(params, vars);
2366 } else { /* AN_mode */
2367 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2370 bnx2x_set_brcm_cl37_advertisment(params);
2372 /* program duplex & pause advertisement (for aneg) */
2373 bnx2x_set_ieee_aneg_advertisment(params,
2376 /* enable autoneg */
2377 bnx2x_set_autoneg(params, vars);
2379 /* enable and restart AN */
2380 bnx2x_restart_autoneg(params);
2383 } else { /* SGMII mode */
2384 DP(NETIF_MSG_LINK, "SGMII\n");
2386 bnx2x_initialize_sgmii_process(params, vars);
2390 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2392 struct bnx2x *bp = params->bp;
2399 if (vars->phy_flags & PHY_XGXS_FLAG) {
2400 ext_phy_addr = ((params->ext_phy_config &
2401 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2402 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2404 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2405 /* Make sure that the soft reset is off (expect for the 8072:
2406 * due to the lock, it will be done inside the specific
2409 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
2410 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
2411 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
2412 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
2413 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
2414 /* Wait for soft reset to get cleared upto 1 sec */
2415 for (cnt = 0; cnt < 1000; cnt++) {
2416 bnx2x_cl45_read(bp, params->port,
2420 MDIO_PMA_REG_CTRL, &ctrl);
2421 if (!(ctrl & (1<<15)))
2425 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
2429 switch (ext_phy_type) {
2430 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2433 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2434 DP(NETIF_MSG_LINK, "XGXS 8705\n");
2436 bnx2x_cl45_write(bp, params->port,
2440 MDIO_PMA_REG_MISC_CTRL,
2442 bnx2x_cl45_write(bp, params->port,
2446 MDIO_PMA_REG_PHY_IDENTIFIER,
2448 bnx2x_cl45_write(bp, params->port,
2452 MDIO_PMA_REG_CMU_PLL_BYPASS,
2454 bnx2x_cl45_write(bp, params->port,
2458 MDIO_WIS_REG_LASI_CNTL, 0x1);
2461 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2462 DP(NETIF_MSG_LINK, "XGXS 8706\n");
2466 /* First enable LASI */
2467 bnx2x_cl45_write(bp, params->port,
2471 MDIO_PMA_REG_RX_ALARM_CTRL,
2473 bnx2x_cl45_write(bp, params->port,
2477 MDIO_PMA_REG_LASI_CTRL, 0x0004);
2479 if (params->req_line_speed == SPEED_10000) {
2480 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
2482 bnx2x_cl45_write(bp, params->port,
2486 MDIO_PMA_REG_DIGITAL_CTRL,
2489 /* Force 1Gbps using autoneg with 1G
2492 /* Allow CL37 through CL73 */
2493 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
2494 bnx2x_cl45_write(bp, params->port,
2498 MDIO_AN_REG_CL37_CL73,
2501 /* Enable Full-Duplex advertisment on CL37 */
2502 bnx2x_cl45_write(bp, params->port,
2506 MDIO_AN_REG_CL37_FC_LP,
2508 /* Enable CL37 AN */
2509 bnx2x_cl45_write(bp, params->port,
2513 MDIO_AN_REG_CL37_AN,
2516 bnx2x_cl45_write(bp, params->port,
2520 MDIO_AN_REG_ADV, (1<<5));
2522 /* Enable clause 73 AN */
2523 bnx2x_cl45_write(bp, params->port,
2534 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2535 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2538 u16 rx_alarm_ctrl_val;
2541 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2542 rx_alarm_ctrl_val = 0x400;
2543 lasi_ctrl_val = 0x0004;
2545 /* In 8073, port1 is directed through emac0 and
2546 * port0 is directed through emac1
2548 rx_alarm_ctrl_val = (1<<2);
2549 /*lasi_ctrl_val = 0x0005;*/
2550 lasi_ctrl_val = 0x0004;
2553 /* Wait for soft reset to get cleared upto 1 sec */
2554 for (cnt = 0; cnt < 1000; cnt++) {
2555 bnx2x_cl45_read(bp, params->port,
2561 if (!(ctrl & (1<<15)))
2566 "807x control reg 0x%x (after %d ms)\n",
2570 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
2571 bnx2x_bcm8072_external_rom_boot(params);
2573 bnx2x_bcm8073_external_rom_boot(params);
2574 /* In case of 8073 with long xaui lines,
2575 don't set the 8073 xaui low power*/
2576 bnx2x_bcm8073_set_xaui_low_power_mode(params);
2580 bnx2x_cl45_write(bp, params->port,
2584 MDIO_PMA_REG_RX_ALARM_CTRL,
2587 bnx2x_cl45_write(bp, params->port,
2591 MDIO_PMA_REG_LASI_CTRL,
2594 bnx2x_cl45_read(bp, params->port,
2598 MDIO_PMA_REG_RX_ALARM, &tmp1);
2600 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
2603 /* If this is forced speed, set to KR or KX
2604 * (all other are not supported)
2606 if (!(params->req_line_speed == SPEED_AUTO_NEG)) {
2607 if (params->req_line_speed == SPEED_10000) {
2608 bnx2x_bcm807x_force_10G(params);
2610 "Forced speed 10G on 807X\n");
2612 } else if (params->req_line_speed ==
2615 /* Note that 2.5G works only
2616 when used with 1G advertisment */
2622 if (params->speed_cap_mask &
2623 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2626 if (params->speed_cap_mask &
2627 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
2629 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
2630 /*val = ((1<<5)|(1<<7));*/
2633 bnx2x_cl45_write(bp, params->port,
2637 MDIO_AN_REG_ADV, val);
2640 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2641 /* Disable 2.5Ghz */
2642 bnx2x_cl45_read(bp, params->port,
2647 /* SUPPORT_SPEED_CAPABILITY
2648 (Due to the nature of the link order, its not
2649 possible to enable 2.5G within the autoneg
2651 if (params->speed_cap_mask &
2652 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
2654 if (params->req_line_speed == SPEED_2500) {
2656 /* Allow 2.5G for A1 and above */
2657 bnx2x_cl45_read(bp, params->port,
2658 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2671 bnx2x_cl45_write(bp, params->port,
2677 /* Add support for CL37 (passive mode) I */
2678 bnx2x_cl45_write(bp, params->port,
2682 MDIO_AN_REG_CL37_FC_LD, 0x040c);
2683 /* Add support for CL37 (passive mode) II */
2684 bnx2x_cl45_write(bp, params->port,
2688 MDIO_AN_REG_CL37_FC_LD, 0x20);
2689 /* Add support for CL37 (passive mode) III */
2690 bnx2x_cl45_write(bp, params->port,
2694 MDIO_AN_REG_CL37_AN, 0x1000);
2695 /* Restart autoneg */
2699 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2701 /* The SNR will improve about 2db by changing the
2702 BW and FEE main tap. Rest commands are executed
2704 /* Change FFE main cursor to 5 in EDC register */
2705 if (bnx2x_8073_is_snr_needed(params))
2706 bnx2x_cl45_write(bp, params->port,
2710 MDIO_PMA_REG_EDC_FFE_MAIN,
2713 /* Enable FEC (Forware Error Correction)
2714 Request in the AN */
2715 bnx2x_cl45_read(bp, params->port,
2719 MDIO_AN_REG_ADV2, &tmp1);
2723 bnx2x_cl45_write(bp, params->port,
2727 MDIO_AN_REG_ADV2, tmp1);
2730 bnx2x_ext_phy_set_pause(params, vars);
2732 bnx2x_cl45_write(bp, params->port,
2736 MDIO_AN_REG_CTRL, 0x1200);
2737 DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
2738 "Advertise 1G=%x, 10G=%x\n",
2739 ((val & (1<<5)) > 0),
2740 ((val & (1<<7)) > 0));
2743 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
2745 "Setting the SFX7101 LASI indication\n");
2747 bnx2x_cl45_write(bp, params->port,
2751 MDIO_PMA_REG_LASI_CTRL, 0x1);
2753 "Setting the SFX7101 LED to blink on traffic\n");
2754 bnx2x_cl45_write(bp, params->port,
2758 MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
2760 bnx2x_ext_phy_set_pause(params, vars);
2761 /* Restart autoneg */
2762 bnx2x_cl45_read(bp, params->port,
2766 MDIO_AN_REG_CTRL, &val);
2768 bnx2x_cl45_write(bp, params->port,
2772 MDIO_AN_REG_CTRL, val);
2774 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2776 "XGXS PHY Failure detected 0x%x\n",
2777 params->ext_phy_config);
2781 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
2782 params->ext_phy_config);
2787 } else { /* SerDes */
2789 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2790 switch (ext_phy_type) {
2791 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
2792 DP(NETIF_MSG_LINK, "SerDes Direct\n");
2795 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
2796 DP(NETIF_MSG_LINK, "SerDes 5482\n");
2800 DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
2801 params->ext_phy_config);
2809 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2810 struct link_vars *vars)
2812 struct bnx2x *bp = params->bp;
2816 u16 rx_sd, pcs_status;
2817 u8 ext_phy_link_up = 0;
2818 u8 port = params->port;
2819 if (vars->phy_flags & PHY_XGXS_FLAG) {
2820 ext_phy_addr = ((params->ext_phy_config &
2821 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2822 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2824 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2825 switch (ext_phy_type) {
2826 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2827 DP(NETIF_MSG_LINK, "XGXS Direct\n");
2828 ext_phy_link_up = 1;
2831 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2832 DP(NETIF_MSG_LINK, "XGXS 8705\n");
2833 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2836 MDIO_WIS_REG_LASI_STATUS, &val1);
2837 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2839 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2842 MDIO_WIS_REG_LASI_STATUS, &val1);
2843 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2845 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2848 MDIO_PMA_REG_RX_SD, &rx_sd);
2849 DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
2850 ext_phy_link_up = (rx_sd & 0x1);
2851 if (ext_phy_link_up)
2852 vars->line_speed = SPEED_10000;
2855 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2856 DP(NETIF_MSG_LINK, "XGXS 8706\n");
2857 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2860 MDIO_PMA_REG_LASI_STATUS, &val1);
2861 DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2863 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2866 MDIO_PMA_REG_LASI_STATUS, &val1);
2867 DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2869 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2872 MDIO_PMA_REG_RX_SD, &rx_sd);
2873 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2876 MDIO_PCS_REG_STATUS, &pcs_status);
2878 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2881 MDIO_AN_REG_LINK_STATUS, &val2);
2882 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2885 MDIO_AN_REG_LINK_STATUS, &val2);
2887 DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
2888 " pcs_status 0x%x 1Gbps link_status 0x%x\n",
2889 rx_sd, pcs_status, val2);
2890 /* link is up if both bit 0 of pmd_rx_sd and
2891 * bit 0 of pcs_status are set, or if the autoneg bit
2894 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
2896 if (ext_phy_link_up) {
2898 vars->line_speed = SPEED_1000;
2900 vars->line_speed = SPEED_10000;
2903 /* clear LASI indication*/
2904 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2907 MDIO_PMA_REG_RX_ALARM, &val2);
2910 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2911 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2914 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2915 bnx2x_cl45_read(bp, params->port,
2919 MDIO_PCS_REG_LASI_STATUS, &val1);
2920 bnx2x_cl45_read(bp, params->port,
2924 MDIO_PCS_REG_LASI_STATUS, &val2);
2926 "870x LASI status 0x%x->0x%x\n",
2930 /* In 8073, port1 is directed through emac0 and
2931 * port0 is directed through emac1
2933 bnx2x_cl45_read(bp, params->port,
2937 MDIO_PMA_REG_LASI_STATUS, &val1);
2939 bnx2x_cl45_read(bp, params->port,
2943 MDIO_PMA_REG_LASI_STATUS, &val2);
2945 "8703 LASI status 0x%x->0x%x\n",
2949 /* clear the interrupt LASI status register */
2950 bnx2x_cl45_read(bp, params->port,
2954 MDIO_PCS_REG_STATUS, &val2);
2955 bnx2x_cl45_read(bp, params->port,
2959 MDIO_PCS_REG_STATUS, &val1);
2960 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
2962 /* Check the LASI */
2963 bnx2x_cl45_read(bp, params->port,
2967 MDIO_PMA_REG_RX_ALARM, &val2);
2968 bnx2x_cl45_read(bp, params->port,
2972 MDIO_PMA_REG_RX_ALARM,
2974 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x->0x%x\n",
2976 /* Check the link status */
2977 bnx2x_cl45_read(bp, params->port,
2981 MDIO_PCS_REG_STATUS, &val2);
2982 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
2984 bnx2x_cl45_read(bp, params->port,
2988 MDIO_PMA_REG_STATUS, &val2);
2989 bnx2x_cl45_read(bp, params->port,
2993 MDIO_PMA_REG_STATUS, &val1);
2994 ext_phy_link_up = ((val1 & 4) == 4);
2995 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
2997 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2998 u16 an1000_status = 0;
2999 if (ext_phy_link_up &&
3001 (params->req_line_speed != SPEED_10000)
3003 if (bnx2x_bcm8073_xaui_wa(params)
3005 ext_phy_link_up = 0;
3008 bnx2x_cl45_read(bp, params->port,
3014 bnx2x_cl45_read(bp, params->port,
3021 /* Check the link status on 1.1.2 */
3022 bnx2x_cl45_read(bp, params->port,
3026 MDIO_PMA_REG_STATUS, &val2);
3027 bnx2x_cl45_read(bp, params->port,
3031 MDIO_PMA_REG_STATUS, &val1);
3032 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3033 "an_link_status=0x%x\n",
3034 val2, val1, an1000_status);
3036 ext_phy_link_up = (((val1 & 4) == 4) ||
3037 (an1000_status & (1<<1)));
3038 if (ext_phy_link_up &&
3039 bnx2x_8073_is_snr_needed(params)) {
3040 /* The SNR will improve about 2dbby
3041 changing the BW and FEE main tap.*/
3043 /* The 1st write to change FFE main
3044 tap is set before restart AN */
3045 /* Change PLL Bandwidth in EDC
3047 bnx2x_cl45_write(bp, port, ext_phy_type,
3050 MDIO_PMA_REG_PLL_BANDWIDTH,
3053 /* Change CDR Bandwidth in EDC
3055 bnx2x_cl45_write(bp, port, ext_phy_type,
3058 MDIO_PMA_REG_CDR_BANDWIDTH,
3065 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3066 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3069 MDIO_PMA_REG_LASI_STATUS, &val2);
3070 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3073 MDIO_PMA_REG_LASI_STATUS, &val1);
3075 "10G-base-T LASI status 0x%x->0x%x\n",
3077 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3080 MDIO_PMA_REG_STATUS, &val2);
3081 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3084 MDIO_PMA_REG_STATUS, &val1);
3086 "10G-base-T PMA status 0x%x->0x%x\n",
3088 ext_phy_link_up = ((val1 & 4) == 4);
3090 * print the AN outcome of the SFX7101 PHY
3092 if (ext_phy_link_up) {
3093 bnx2x_cl45_read(bp, params->port,
3097 MDIO_AN_REG_MASTER_STATUS,
3099 vars->line_speed = SPEED_10000;
3101 "SFX7101 AN status 0x%x->Master=%x\n",
3108 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3109 params->ext_phy_config);
3110 ext_phy_link_up = 0;
3114 } else { /* SerDes */
3115 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3116 switch (ext_phy_type) {
3117 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3118 DP(NETIF_MSG_LINK, "SerDes Direct\n");
3119 ext_phy_link_up = 1;
3122 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3123 DP(NETIF_MSG_LINK, "SerDes 5482\n");
3124 ext_phy_link_up = 1;
3129 "BAD SerDes ext_phy_config 0x%x\n",
3130 params->ext_phy_config);
3131 ext_phy_link_up = 0;
3136 return ext_phy_link_up;
3139 static void bnx2x_link_int_enable(struct link_params *params)
3141 u8 port = params->port;
3144 struct bnx2x *bp = params->bp;
3145 /* setting the status to report on link up
3146 for either XGXS or SerDes */
3148 if (params->switch_cfg == SWITCH_CFG_10G) {
3149 mask = (NIG_MASK_XGXS0_LINK10G |
3150 NIG_MASK_XGXS0_LINK_STATUS);
3151 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
3152 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3153 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3154 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3156 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
3157 mask |= NIG_MASK_MI_INT;
3158 DP(NETIF_MSG_LINK, "enabled external phy int\n");
3161 } else { /* SerDes */
3162 mask = NIG_MASK_SERDES0_LINK_STATUS;
3163 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
3164 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3165 if ((ext_phy_type !=
3166 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
3168 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
3169 mask |= NIG_MASK_MI_INT;
3170 DP(NETIF_MSG_LINK, "enabled external phy int\n");
3174 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3176 DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
3177 (params->switch_cfg == SWITCH_CFG_10G),
3178 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
3180 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
3181 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
3182 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
3183 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
3184 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
3185 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
3186 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
3193 static void bnx2x_link_int_ack(struct link_params *params,
3194 struct link_vars *vars, u16 is_10g)
3196 struct bnx2x *bp = params->bp;
3197 u8 port = params->port;
3199 /* first reset all status
3200 * we assume only one line will be change at a time */
3201 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3202 (NIG_STATUS_XGXS0_LINK10G |
3203 NIG_STATUS_XGXS0_LINK_STATUS |
3204 NIG_STATUS_SERDES0_LINK_STATUS));
3205 if (vars->phy_link_up) {
3207 /* Disable the 10G link interrupt
3208 * by writing 1 to the status register
3210 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
3212 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3213 NIG_STATUS_XGXS0_LINK10G);
3215 } else if (params->switch_cfg == SWITCH_CFG_10G) {
3216 /* Disable the link interrupt
3217 * by writing 1 to the relevant lane
3218 * in the status register
3220 u32 ser_lane = ((params->lane_config &
3221 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3222 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3224 DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
3226 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3228 NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
3230 } else { /* SerDes */
3231 DP(NETIF_MSG_LINK, "SerDes phy link up\n");
3232 /* Disable the link interrupt
3233 * by writing 1 to the status register
3236 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3237 NIG_STATUS_SERDES0_LINK_STATUS);
3240 } else { /* link_down */
3244 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
3247 u32 mask = 0xf0000000;
3251 /* Need more then 10chars for this format */
3258 digit = ((num & mask) >> shift);
3260 *str_ptr = digit + '0';
3262 *str_ptr = digit - 0xa + 'a';
3275 static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
3280 /* Enable EMAC0 in to enable MDIO */
3281 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
3282 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
3285 /* take ext phy out of reset */
3287 MISC_REGISTERS_GPIO_2,
3288 MISC_REGISTERS_GPIO_HIGH,
3292 MISC_REGISTERS_GPIO_1,
3293 MISC_REGISTERS_GPIO_HIGH,
3299 for (cnt = 0; cnt < 1000; cnt++) {
3301 bnx2x_cl45_read(bp, port,
3307 if (!(ctrl & (1<<15))) {
3308 DP(NETIF_MSG_LINK, "Reset completed\n\n");
3314 static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
3316 /* put sf to reset */
3318 MISC_REGISTERS_GPIO_1,
3319 MISC_REGISTERS_GPIO_LOW,
3322 MISC_REGISTERS_GPIO_2,
3323 MISC_REGISTERS_GPIO_LOW,
3327 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3328 u8 *version, u16 len)
3330 struct bnx2x *bp = params->bp;
3331 u32 ext_phy_type = 0;
3333 u8 ext_phy_addr = 0 ;
3337 if (version == NULL || params == NULL)
3340 /* reset the returned value to zero */
3341 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3342 ext_phy_addr = ((params->ext_phy_config &
3343 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3344 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3346 switch (ext_phy_type) {
3347 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3352 /* Take ext phy out of reset */
3354 bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3360 bnx2x_cl45_read(bp, params->port,
3364 MDIO_PMA_REG_7101_VER1, &val);
3365 version[2] = (val & 0xFF);
3366 version[3] = ((val & 0xFF00)>>8);
3368 bnx2x_cl45_read(bp, params->port,
3371 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2,
3373 version[0] = (val & 0xFF);
3374 version[1] = ((val & 0xFF00)>>8);
3378 bnx2x_turn_off_sf(bp, params->port);
3380 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3381 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3383 /* Take ext phy out of reset */
3385 bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3388 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3391 MDIO_PMA_REG_ROM_VER1, &val);
3393 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3396 MDIO_PMA_REG_ROM_VER2, &val);
3398 status = bnx2x_format_ver(ver_num, version, len);
3401 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3402 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3404 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3407 MDIO_PMA_REG_ROM_VER1, &val);
3409 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3412 MDIO_PMA_REG_ROM_VER2, &val);
3414 status = bnx2x_format_ver(ver_num, version, len);
3417 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3420 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
3421 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
3422 " type is FAILURE!\n");
3432 static void bnx2x_set_xgxs_loopback(struct link_params *params,
3433 struct link_vars *vars,
3436 u8 port = params->port;
3437 struct bnx2x *bp = params->bp;
3442 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
3444 /* change the uni_phy_addr in the nig */
3445 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
3448 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
3450 bnx2x_cl45_write(bp, port, 0,
3453 (MDIO_REG_BANK_AER_BLOCK +
3454 (MDIO_AER_BLOCK_AER_REG & 0xf)),
3457 bnx2x_cl45_write(bp, port, 0,
3460 (MDIO_REG_BANK_CL73_IEEEB0 +
3461 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
3464 /* set aer mmd back */
3465 bnx2x_set_aer_mmd(params, vars);
3468 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
3474 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
3476 CL45_RD_OVER_CL22(bp, port,
3478 MDIO_REG_BANK_COMBO_IEEE0,
3479 MDIO_COMBO_IEEE0_MII_CONTROL,
3482 CL45_WR_OVER_CL22(bp, port,
3484 MDIO_REG_BANK_COMBO_IEEE0,
3485 MDIO_COMBO_IEEE0_MII_CONTROL,
3487 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
3492 static void bnx2x_ext_phy_loopback(struct link_params *params)
3494 struct bnx2x *bp = params->bp;
3498 if (params->switch_cfg == SWITCH_CFG_10G) {
3499 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3500 /* CL37 Autoneg Enabled */
3501 ext_phy_addr = ((params->ext_phy_config &
3502 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3503 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3504 switch (ext_phy_type) {
3505 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3506 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
3508 "ext_phy_loopback: We should not get here\n");
3510 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3511 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
3513 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3514 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
3516 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3517 /* SFX7101_XGXS_TEST1 */
3518 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3521 MDIO_XS_SFX7101_XGXS_TEST1,
3524 "ext_phy_loopback: set ext phy loopback\n");
3526 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3529 } /* switch external PHY type */
3532 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3533 ext_phy_addr = (params->ext_phy_config &
3534 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
3535 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
3541 *------------------------------------------------------------------------
3542 * bnx2x_override_led_value -
3544 * Override the led value of the requsted led
3546 *------------------------------------------------------------------------
3548 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
3549 u32 led_idx, u32 value)
3553 /* If port 0 then use EMAC0, else use EMAC1*/
3554 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3557 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
3558 port, led_idx, value);
3561 case 0: /* 10MB led */
3562 /* Read the current value of the LED register in
3564 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3565 /* Set the OVERRIDE bit to 1 */
3566 reg_val |= EMAC_LED_OVERRIDE;
3567 /* If value is 1, set the 10M_OVERRIDE bit,
3568 otherwise reset it.*/
3569 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
3570 (reg_val & ~EMAC_LED_10MB_OVERRIDE);
3571 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3573 case 1: /*100MB led */
3574 /*Read the current value of the LED register in
3576 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3577 /* Set the OVERRIDE bit to 1 */
3578 reg_val |= EMAC_LED_OVERRIDE;
3579 /* If value is 1, set the 100M_OVERRIDE bit,
3580 otherwise reset it.*/
3581 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
3582 (reg_val & ~EMAC_LED_100MB_OVERRIDE);
3583 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3585 case 2: /* 1000MB led */
3586 /* Read the current value of the LED register in the
3588 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3589 /* Set the OVERRIDE bit to 1 */
3590 reg_val |= EMAC_LED_OVERRIDE;
3591 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
3593 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
3594 (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
3595 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3597 case 3: /* 2500MB led */
3598 /* Read the current value of the LED register in the
3600 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3601 /* Set the OVERRIDE bit to 1 */
3602 reg_val |= EMAC_LED_OVERRIDE;
3603 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
3605 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
3606 (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
3607 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3609 case 4: /*10G led */
3611 REG_WR(bp, NIG_REG_LED_10G_P0,
3614 REG_WR(bp, NIG_REG_LED_10G_P1,
3618 case 5: /* TRAFFIC led */
3619 /* Find if the traffic control is via BMAC or EMAC */
3621 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
3623 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
3625 /* Override the traffic led in the EMAC:*/
3627 /* Read the current value of the LED register in
3629 reg_val = REG_RD(bp, emac_base +
3631 /* Set the TRAFFIC_OVERRIDE bit to 1 */
3632 reg_val |= EMAC_LED_OVERRIDE;
3633 /* If value is 1, set the TRAFFIC bit, otherwise
3635 reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
3636 (reg_val & ~EMAC_LED_TRAFFIC);
3637 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3638 } else { /* Override the traffic led in the BMAC: */
3639 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3641 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
3647 "bnx2x_override_led_value() unknown led index %d "
3648 "(should be 0-5)\n", led_idx);
3656 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
3657 u16 hw_led_mode, u32 chip_id)
3660 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
3661 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
3662 speed, hw_led_mode);
3665 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
3666 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
3667 SHARED_HW_CFG_LED_MAC1);
3671 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
3672 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
3674 /* Set blinking rate to ~15.9Hz */
3675 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
3676 LED_BLINK_RATE_VAL);
3677 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
3679 if (!CHIP_IS_E1H(bp) &&
3680 ((speed == SPEED_2500) ||
3681 (speed == SPEED_1000) ||
3682 (speed == SPEED_100) ||
3683 (speed == SPEED_10))) {
3684 /* On Everest 1 Ax chip versions for speeds less than
3685 10G LED scheme is different */
3686 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3688 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
3690 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
3697 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
3705 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
3707 struct bnx2x *bp = params->bp;
3710 CL45_RD_OVER_CL22(bp, params->port,
3712 MDIO_REG_BANK_GP_STATUS,
3713 MDIO_GP_STATUS_TOP_AN_STATUS1,
3715 /* link is up only if both local phy and external phy are up */
3716 if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
3717 bnx2x_ext_phy_is_link_up(params, vars))
3723 static u8 bnx2x_link_initialize(struct link_params *params,
3724 struct link_vars *vars)
3726 struct bnx2x *bp = params->bp;
3727 u8 port = params->port;
3730 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3731 /* Activate the external PHY */
3732 bnx2x_ext_phy_reset(params, vars);
3734 bnx2x_set_aer_mmd(params, vars);
3736 if (vars->phy_flags & PHY_XGXS_FLAG)
3737 bnx2x_set_master_ln(params);
3739 rc = bnx2x_reset_unicore(params);
3740 /* reset the SerDes and wait for reset bit return low */
3744 bnx2x_set_aer_mmd(params, vars);
3746 /* setting the masterLn_def again after the reset */
3747 if (vars->phy_flags & PHY_XGXS_FLAG) {
3748 bnx2x_set_master_ln(params);
3749 bnx2x_set_swap_lanes(params);
3752 if (vars->phy_flags & PHY_XGXS_FLAG) {
3753 if (params->req_line_speed &&
3754 ((params->req_line_speed == SPEED_100) ||
3755 (params->req_line_speed == SPEED_10))) {
3756 vars->phy_flags |= PHY_SGMII_FLAG;
3758 vars->phy_flags &= ~PHY_SGMII_FLAG;
3761 /* In case of external phy existance, the line speed would be the
3762 line speed linked up by the external phy. In case it is direct only,
3763 then the line_speed during initialization will be equal to the
3765 vars->line_speed = params->req_line_speed;
3767 bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
3769 /* init ext phy and enable link state int */
3770 non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
3771 (params->loopback_mode == LOOPBACK_XGXS_10) ||
3772 (params->loopback_mode == LOOPBACK_EXT_PHY));
3775 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705)) {
3776 if (params->req_line_speed == SPEED_AUTO_NEG)
3777 bnx2x_set_parallel_detection(params, vars->phy_flags);
3778 bnx2x_init_internal_phy(params, vars);
3782 rc |= bnx2x_ext_phy_init(params, vars);
3784 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3785 (NIG_STATUS_XGXS0_LINK10G |
3786 NIG_STATUS_XGXS0_LINK_STATUS |
3787 NIG_STATUS_SERDES0_LINK_STATUS));
3794 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
3796 struct bnx2x *bp = params->bp;
3799 DP(NETIF_MSG_LINK, "Phy Initialization started\n");
3800 DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
3801 params->req_line_speed, params->req_flow_ctrl);
3802 vars->link_status = 0;
3803 vars->phy_link_up = 0;
3805 vars->line_speed = 0;
3806 vars->duplex = DUPLEX_FULL;
3807 vars->flow_ctrl = FLOW_CTRL_NONE;
3808 vars->mac_type = MAC_TYPE_NONE;
3810 if (params->switch_cfg == SWITCH_CFG_1G)
3811 vars->phy_flags = PHY_SERDES_FLAG;
3813 vars->phy_flags = PHY_XGXS_FLAG;
3815 /* disable attentions */
3816 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
3817 (NIG_MASK_XGXS0_LINK_STATUS |
3818 NIG_MASK_XGXS0_LINK10G |
3819 NIG_MASK_SERDES0_LINK_STATUS |
3822 bnx2x_emac_init(params, vars);
3824 if (CHIP_REV_IS_FPGA(bp)) {
3826 vars->line_speed = SPEED_10000;
3827 vars->duplex = DUPLEX_FULL;
3828 vars->flow_ctrl = FLOW_CTRL_NONE;
3829 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3830 /* enable on E1.5 FPGA */
3831 if (CHIP_IS_E1H(bp)) {
3833 (FLOW_CTRL_TX | FLOW_CTRL_RX);
3834 vars->link_status |=
3835 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
3836 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
3839 bnx2x_emac_enable(params, vars, 0);
3840 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3842 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3843 + params->port*4, 0);
3845 /* update shared memory */
3846 bnx2x_update_mng(params, vars->link_status);
3851 if (CHIP_REV_IS_EMUL(bp)) {
3854 vars->line_speed = SPEED_10000;
3855 vars->duplex = DUPLEX_FULL;
3856 vars->flow_ctrl = FLOW_CTRL_NONE;
3857 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3859 bnx2x_bmac_enable(params, vars, 0);
3861 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3863 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3864 + params->port*4, 0);
3866 /* update shared memory */
3867 bnx2x_update_mng(params, vars->link_status);
3872 if (params->loopback_mode == LOOPBACK_BMAC) {
3874 vars->line_speed = SPEED_10000;
3875 vars->duplex = DUPLEX_FULL;
3876 vars->flow_ctrl = FLOW_CTRL_NONE;
3877 vars->mac_type = MAC_TYPE_BMAC;
3879 vars->phy_flags = PHY_XGXS_FLAG;
3881 bnx2x_phy_deassert(params, vars->phy_flags);
3882 /* set bmac loopback */
3883 bnx2x_bmac_enable(params, vars, 1);
3885 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
3887 } else if (params->loopback_mode == LOOPBACK_EMAC) {
3889 vars->line_speed = SPEED_1000;
3890 vars->duplex = DUPLEX_FULL;
3891 vars->flow_ctrl = FLOW_CTRL_NONE;
3892 vars->mac_type = MAC_TYPE_EMAC;
3894 vars->phy_flags = PHY_XGXS_FLAG;
3896 bnx2x_phy_deassert(params, vars->phy_flags);
3897 /* set bmac loopback */
3898 bnx2x_emac_enable(params, vars, 1);
3899 bnx2x_emac_program(params, vars->line_speed,
3901 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
3903 } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
3904 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
3906 vars->line_speed = SPEED_10000;
3907 vars->duplex = DUPLEX_FULL;
3908 vars->flow_ctrl = FLOW_CTRL_NONE;
3910 vars->phy_flags = PHY_XGXS_FLAG;
3913 NIG_REG_XGXS0_CTRL_PHY_ADDR+
3915 params->phy_addr = (u8)val;
3917 bnx2x_phy_deassert(params, vars->phy_flags);
3918 bnx2x_link_initialize(params, vars);
3920 vars->mac_type = MAC_TYPE_BMAC;
3922 bnx2x_bmac_enable(params, vars, 0);
3924 if (params->loopback_mode == LOOPBACK_XGXS_10) {
3925 /* set 10G XGXS loopback */
3926 bnx2x_set_xgxs_loopback(params, vars, 1);
3928 /* set external phy loopback */
3929 bnx2x_ext_phy_loopback(params);
3931 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
3937 bnx2x_phy_deassert(params, vars->phy_flags);
3938 switch (params->switch_cfg) {
3940 vars->phy_flags |= PHY_SERDES_FLAG;
3941 if ((params->ext_phy_config &
3942 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
3943 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
3949 NIG_REG_SERDES0_CTRL_PHY_ADDR+
3952 params->phy_addr = (u8)val;
3955 case SWITCH_CFG_10G:
3956 vars->phy_flags |= PHY_XGXS_FLAG;
3958 NIG_REG_XGXS0_CTRL_PHY_ADDR+
3960 params->phy_addr = (u8)val;
3964 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
3969 bnx2x_link_initialize(params, vars);
3971 bnx2x_link_int_enable(params);
3976 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
3979 struct bnx2x *bp = params->bp;
3980 u32 ext_phy_config = params->ext_phy_config;
3981 u16 hw_led_mode = params->hw_led_mode;
3982 u32 chip_id = params->chip_id;
3983 u8 port = params->port;
3984 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
3985 /* disable attentions */
3987 vars->link_status = 0;
3988 bnx2x_update_mng(params, vars->link_status);
3989 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3990 (NIG_MASK_XGXS0_LINK_STATUS |
3991 NIG_MASK_XGXS0_LINK10G |
3992 NIG_MASK_SERDES0_LINK_STATUS |
3995 /* activate nig drain */
3996 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
3998 /* disable nig egress interface */
3999 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4000 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4002 /* Stop BigMac rx */
4003 bnx2x_bmac_rx_disable(bp, port);
4006 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4009 /* The PHY reset is controled by GPIO 1
4010 * Hold it as vars low
4012 /* clear link led */
4013 bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4014 if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
4015 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
4016 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
4019 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4020 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4023 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4024 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4027 DP(NETIF_MSG_LINK, "reset external PHY\n");
4028 } else if (ext_phy_type ==
4029 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4030 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4033 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4034 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4038 /* reset the SerDes/XGXS */
4039 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4040 (0x1ff << (port*16)));
4043 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4044 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4046 /* disable nig ingress interface */
4047 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4048 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4049 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4050 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4055 static u8 bnx2x_update_link_down(struct link_params *params,
4056 struct link_vars *vars)
4058 struct bnx2x *bp = params->bp;
4059 u8 port = params->port;
4060 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4061 bnx2x_set_led(bp, port, LED_MODE_OFF,
4062 0, params->hw_led_mode,
4065 /* indicate no mac active */
4066 vars->mac_type = MAC_TYPE_NONE;
4068 /* update shared memory */
4069 vars->link_status = 0;
4070 vars->line_speed = 0;
4071 bnx2x_update_mng(params, vars->link_status);
4073 /* activate nig drain */
4074 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4077 bnx2x_bmac_rx_disable(bp, params->port);
4078 REG_WR(bp, GRCBASE_MISC +
4079 MISC_REGISTERS_RESET_REG_2_CLEAR,
4080 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4084 static u8 bnx2x_update_link_up(struct link_params *params,
4085 struct link_vars *vars,
4086 u8 link_10g, u32 gp_status)
4088 struct bnx2x *bp = params->bp;
4089 u8 port = params->port;
4091 vars->link_status |= LINK_STATUS_LINK_UP;
4093 bnx2x_bmac_enable(params, vars, 0);
4094 bnx2x_set_led(bp, port, LED_MODE_OPER,
4095 SPEED_10000, params->hw_led_mode,
4099 bnx2x_emac_enable(params, vars, 0);
4100 rc = bnx2x_emac_program(params, vars->line_speed,
4104 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4105 if (!(vars->phy_flags &
4107 bnx2x_set_sgmii_tx_driver(params);
4112 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4116 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4118 /* update shared memory */
4119 bnx2x_update_mng(params, vars->link_status);
4122 /* This function should called upon link interrupt */
4123 /* In case vars->link_up, driver needs to
4126 3. Update the shared memory
4130 1. Update shared memory
4135 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4137 struct bnx2x *bp = params->bp;
4138 u8 port = params->port;
4141 u8 ext_phy_link_up, rc = 0;
4144 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
4146 (vars->phy_flags & PHY_XGXS_FLAG),
4147 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4149 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4150 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4151 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4152 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
4154 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4155 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4156 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4158 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4160 /* Check external link change only for non-direct */
4161 ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
4163 /* Read gp_status */
4164 CL45_RD_OVER_CL22(bp, port, params->phy_addr,
4165 MDIO_REG_BANK_GP_STATUS,
4166 MDIO_GP_STATUS_TOP_AN_STATUS1,
4169 rc = bnx2x_link_settings_status(params, vars, gp_status);
4173 /* anything 10 and over uses the bmac */
4174 link_10g = ((vars->line_speed == SPEED_10000) ||
4175 (vars->line_speed == SPEED_12000) ||
4176 (vars->line_speed == SPEED_12500) ||
4177 (vars->line_speed == SPEED_13000) ||
4178 (vars->line_speed == SPEED_15000) ||
4179 (vars->line_speed == SPEED_16000));
4181 bnx2x_link_int_ack(params, vars, link_10g);
4183 /* In case external phy link is up, and internal link is down
4184 ( not initialized yet probably after link initialization, it needs
4186 Note that after link down-up as result of cable plug,
4187 the xgxs link would probably become up again without the need to
4190 if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4191 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
4192 (ext_phy_link_up && !vars->phy_link_up))
4193 bnx2x_init_internal_phy(params, vars);
4195 /* link is up only if both local phy and external phy are up */
4196 vars->link_up = (ext_phy_link_up && vars->phy_link_up);
4199 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
4201 rc = bnx2x_update_link_down(params, vars);
4206 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
4210 bnx2x_cl45_read(bp, port,
4211 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4214 MDIO_PMA_REG_7101_RESET, &val);
4216 for (cnt = 0; cnt < 10; cnt++) {
4218 /* Writes a self-clearing reset */
4219 bnx2x_cl45_write(bp, port,
4220 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4223 MDIO_PMA_REG_7101_RESET,
4225 /* Wait for clear */
4226 bnx2x_cl45_read(bp, port,
4227 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4230 MDIO_PMA_REG_7101_RESET, &val);
4232 if ((val & (1<<15)) == 0)
4236 #define RESERVED_SIZE 256
4237 /* max application is 160K bytes - data at end of RAM */
4238 #define MAX_APP_SIZE 160*1024 - RESERVED_SIZE
4240 /* Header is 14 bytes */
4241 #define HEADER_SIZE 14
4242 #define DATA_OFFSET HEADER_SIZE
4244 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
4245 bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
4248 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
4250 /* Programs an image to DSP's flash via the SPI port*/
4251 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
4253 char data[], u32 size)
4255 const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
4256 /* Doesn't include last trans!*/
4257 const u16 last_trans_size = size%4; /* Num bytes on last trans */
4258 u16 trans_cnt, byte_cnt;
4261 u16 code_started = 0;
4262 u16 image_revision1, image_revision2;
4265 DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
4267 if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
4268 /* This very often will be the case, because the image is built
4269 with 160Kbytes size whereas the total image size must actually
4270 be 160Kbytes-RESERVED_SIZE */
4271 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
4272 "truncated to %d bytes\n", size, MAX_APP_SIZE);
4273 size = MAX_APP_SIZE+HEADER_SIZE;
4275 DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
4276 DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]);
4277 /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
4278 and issuing a reset.*/
4280 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4281 MISC_REGISTERS_GPIO_HIGH, port);
4283 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4286 for (cnt = 0; cnt < 100; cnt++)
4289 /* Make sure we can access the DSP
4290 And it's in the correct mode (waiting for download) */
4292 bnx2x_cl45_read(bp, port,
4293 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4296 MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
4298 if (tmp != 0x000A) {
4299 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
4300 "Expected 0x000A, read 0x%04X\n", tmp);
4301 DP(NETIF_MSG_LINK, "Download failed\n");
4305 /* Mux the SPI interface away from the internal processor */
4306 bnx2x_cl45_write(bp, port,
4307 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4310 MDIO_PCS_REG_7101_SPI_MUX, 1);
4312 /* Reset the SPI port */
4313 bnx2x_cl45_write(bp, port,
4314 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4317 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4318 bnx2x_cl45_write(bp, port,
4319 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4322 MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
4323 (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
4324 bnx2x_cl45_write(bp, port,
4325 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4328 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4330 /* Erase the flash */
4331 bnx2x_cl45_write(bp, port,
4332 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4335 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4336 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4338 bnx2x_cl45_write(bp, port,
4339 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4342 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4345 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4346 bnx2x_cl45_write(bp, port,
4347 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4350 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4351 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
4353 bnx2x_cl45_write(bp, port,
4354 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4357 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4359 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4361 /* Wait 10 seconds, the maximum time for the erase to complete */
4362 DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
4363 for (cnt = 0; cnt < 1000; cnt++)
4366 DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
4368 for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
4369 bnx2x_cl45_write(bp, port,
4370 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4373 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4374 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4376 bnx2x_cl45_write(bp, port,
4377 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4380 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4382 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4384 bnx2x_cl45_write(bp, port,
4385 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4388 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4389 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4391 /* Bits 23-16 of address */
4392 bnx2x_cl45_write(bp, port,
4393 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4396 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4398 /* Bits 15-8 of address */
4399 bnx2x_cl45_write(bp, port,
4400 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4403 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4406 /* Bits 7-0 of address */
4407 bnx2x_cl45_write(bp, port,
4408 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4411 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4415 while (byte_cnt < 4 && data_index < size) {
4416 bnx2x_cl45_write(bp, port,
4417 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4420 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4421 data[data_index++]);
4425 bnx2x_cl45_write(bp, port,
4426 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4429 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4432 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4433 msleep(5); /* Wait 5 ms minimum between transs */
4435 /* Let the user know something's going on.*/
4436 /* a pacifier ever 4K */
4437 if ((data_index % 1023) == 0)
4438 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4441 DP(NETIF_MSG_LINK, "\n");
4442 /* Transfer the last block if there is data remaining */
4443 if (last_trans_size) {
4444 bnx2x_cl45_write(bp, port,
4445 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4448 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4449 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4451 bnx2x_cl45_write(bp, port,
4452 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4455 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4458 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4460 bnx2x_cl45_write(bp, port,
4461 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4464 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4465 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4467 /* Bits 23-16 of address */
4468 bnx2x_cl45_write(bp, port,
4469 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4472 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4474 /* Bits 15-8 of address */
4475 bnx2x_cl45_write(bp, port,
4476 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4479 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4482 /* Bits 7-0 of address */
4483 bnx2x_cl45_write(bp, port,
4484 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4487 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4491 while (byte_cnt < last_trans_size && data_index < size) {
4492 /* Bits 7-0 of address */
4493 bnx2x_cl45_write(bp, port,
4494 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4497 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4498 data[data_index++]);
4502 bnx2x_cl45_write(bp, port,
4503 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4506 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4509 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4512 /* DSP Remove Download Mode */
4513 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4514 MISC_REGISTERS_GPIO_LOW, port);
4516 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4518 /* wait 0.5 sec to allow it to run */
4519 for (cnt = 0; cnt < 100; cnt++)
4522 bnx2x_hw_reset(bp, port);
4524 for (cnt = 0; cnt < 100; cnt++)
4527 /* Check that the code is started. In case the download
4528 checksum failed, the code won't be started. */
4529 bnx2x_cl45_read(bp, port,
4530 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4533 MDIO_PCS_REG_7101_DSP_ACCESS,
4536 code_started = (tmp & (1<<4));
4537 if (!code_started) {
4538 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
4542 /* Verify that the file revision is now equal to the image
4543 revision within the DSP */
4544 bnx2x_cl45_read(bp, port,
4545 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4548 MDIO_PMA_REG_7101_VER1,
4551 bnx2x_cl45_read(bp, port,
4552 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4555 MDIO_PMA_REG_7101_VER2,
4558 if (data[0x14e] != (image_revision2&0xFF) ||
4559 data[0x14f] != ((image_revision2&0xFF00)>>8) ||
4560 data[0x150] != (image_revision1&0xFF) ||
4561 data[0x151] != ((image_revision1&0xFF00)>>8)) {
4562 DP(NETIF_MSG_LINK, "Download failed.\n");
4565 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4569 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
4570 u8 driver_loaded, char data[], u32 size)
4575 ext_phy_addr = ((ext_phy_config &
4576 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4577 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4579 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4581 switch (ext_phy_type) {
4582 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4583 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4584 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4585 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4587 "Flash download not supported for this ext phy\n");
4590 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4591 /* Take ext phy out of reset */
4593 bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
4594 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
4597 bnx2x_turn_off_sf(bp, port);
4599 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4600 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4601 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4603 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");