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(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
208 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
209 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
211 DP(NETIF_MSG_LINK, "EMAC timeout!\n");
215 } while (val & EMAC_MODE_RESET);
217 /* Set mac address */
218 val = ((params->mac_addr[0] << 8) |
219 params->mac_addr[1]);
220 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
222 val = ((params->mac_addr[2] << 24) |
223 (params->mac_addr[3] << 16) |
224 (params->mac_addr[4] << 8) |
225 params->mac_addr[5]);
226 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
229 static u8 bnx2x_emac_enable(struct link_params *params,
230 struct link_vars *vars, u8 lb)
232 struct bnx2x *bp = params->bp;
233 u8 port = params->port;
234 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
237 DP(NETIF_MSG_LINK, "enabling EMAC\n");
239 /* enable emac and not bmac */
240 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
243 if (CHIP_REV_IS_EMUL(bp)) {
244 /* Use lane 1 (of lanes 0-3) */
245 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
246 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
252 if (CHIP_REV_IS_FPGA(bp)) {
253 /* Use lane 1 (of lanes 0-3) */
254 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
256 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
257 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
261 if (vars->phy_flags & PHY_XGXS_FLAG) {
262 u32 ser_lane = ((params->lane_config &
263 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
264 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
266 DP(NETIF_MSG_LINK, "XGXS\n");
267 /* select the master lanes (out of 0-3) */
268 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
271 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
274 } else { /* SerDes */
275 DP(NETIF_MSG_LINK, "SerDes\n");
277 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
282 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
284 if (CHIP_REV_IS_SLOW(bp)) {
285 /* config GMII mode */
286 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
287 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
288 (val | EMAC_MODE_PORT_GMII));
290 /* pause enable/disable */
291 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
292 EMAC_RX_MODE_FLOW_EN);
293 if (vars->flow_ctrl & FLOW_CTRL_RX)
294 bnx2x_bits_en(bp, emac_base +
295 EMAC_REG_EMAC_RX_MODE,
296 EMAC_RX_MODE_FLOW_EN);
298 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
299 (EMAC_TX_MODE_EXT_PAUSE_EN |
300 EMAC_TX_MODE_FLOW_EN));
301 if (vars->flow_ctrl & FLOW_CTRL_TX)
302 bnx2x_bits_en(bp, emac_base +
303 EMAC_REG_EMAC_TX_MODE,
304 (EMAC_TX_MODE_EXT_PAUSE_EN |
305 EMAC_TX_MODE_FLOW_EN));
308 /* KEEP_VLAN_TAG, promiscuous */
309 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
310 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
311 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
314 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
319 EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
321 /* enable emac for jumbo packets */
322 EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
323 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
324 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
327 REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
329 /* disable the NIG in/out to the bmac */
330 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
331 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
332 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
334 /* enable the NIG in/out to the emac */
335 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
337 if (vars->flow_ctrl & FLOW_CTRL_TX)
340 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
341 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
343 if (CHIP_REV_IS_EMUL(bp)) {
344 /* take the BigMac out of reset */
346 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
347 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
349 /* enable access for bmac registers */
350 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
353 vars->mac_type = MAC_TYPE_EMAC;
359 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
362 struct bnx2x *bp = params->bp;
363 u8 port = params->port;
364 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
365 NIG_REG_INGRESS_BMAC0_MEM;
369 DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
370 /* reset and unreset the BigMac */
371 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
372 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
375 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
376 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
378 /* enable access for bmac registers */
379 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
384 REG_WR_DMAE(bp, bmac_addr +
385 BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
389 wb_data[0] = ((params->mac_addr[2] << 24) |
390 (params->mac_addr[3] << 16) |
391 (params->mac_addr[4] << 8) |
392 params->mac_addr[5]);
393 wb_data[1] = ((params->mac_addr[0] << 8) |
394 params->mac_addr[1]);
395 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
400 if (vars->flow_ctrl & FLOW_CTRL_TX)
404 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
411 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
415 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
420 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
422 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
425 /* rx control set to don't strip crc */
427 if (vars->flow_ctrl & FLOW_CTRL_RX)
431 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
435 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
437 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
440 /* set cnt max size */
441 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
443 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
447 wb_data[0] = 0x1000200;
449 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
451 /* fix for emulation */
452 if (CHIP_REV_IS_EMUL(bp)) {
456 bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
460 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
461 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
462 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
464 if (vars->flow_ctrl & FLOW_CTRL_TX)
466 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
467 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
468 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
469 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
470 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
471 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
473 vars->mac_type = MAC_TYPE_BMAC;
477 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
479 struct bnx2x *bp = params->bp;
482 if (phy_flags & PHY_XGXS_FLAG) {
483 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
484 val = XGXS_RESET_BITS;
486 } else { /* SerDes */
487 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
488 val = SERDES_RESET_BITS;
491 val = val << (params->port*16);
493 /* reset and unreset the SerDes/XGXS */
494 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
497 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
499 bnx2x_set_phy_mdio(params);
502 void bnx2x_link_status_update(struct link_params *params,
503 struct link_vars *vars)
505 struct bnx2x *bp = params->bp;
507 u8 port = params->port;
509 if (params->switch_cfg == SWITCH_CFG_1G)
510 vars->phy_flags = PHY_SERDES_FLAG;
512 vars->phy_flags = PHY_XGXS_FLAG;
513 vars->link_status = REG_RD(bp, params->shmem_base +
514 offsetof(struct shmem_region,
515 port_mb[port].link_status));
517 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
520 DP(NETIF_MSG_LINK, "phy link up\n");
522 vars->phy_link_up = 1;
523 vars->duplex = DUPLEX_FULL;
524 switch (vars->link_status &
525 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
527 vars->duplex = DUPLEX_HALF;
530 vars->line_speed = SPEED_10;
534 vars->duplex = DUPLEX_HALF;
538 vars->line_speed = SPEED_100;
542 vars->duplex = DUPLEX_HALF;
545 vars->line_speed = SPEED_1000;
549 vars->duplex = DUPLEX_HALF;
552 vars->line_speed = SPEED_2500;
556 vars->line_speed = SPEED_10000;
560 vars->line_speed = SPEED_12000;
564 vars->line_speed = SPEED_12500;
568 vars->line_speed = SPEED_13000;
572 vars->line_speed = SPEED_15000;
576 vars->line_speed = SPEED_16000;
583 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
584 vars->flow_ctrl |= FLOW_CTRL_TX;
586 vars->flow_ctrl &= ~FLOW_CTRL_TX;
588 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
589 vars->flow_ctrl |= FLOW_CTRL_RX;
591 vars->flow_ctrl &= ~FLOW_CTRL_RX;
593 if (vars->phy_flags & PHY_XGXS_FLAG) {
594 if (vars->line_speed &&
595 ((vars->line_speed == SPEED_10) ||
596 (vars->line_speed == SPEED_100))) {
597 vars->phy_flags |= PHY_SGMII_FLAG;
599 vars->phy_flags &= ~PHY_SGMII_FLAG;
603 /* anything 10 and over uses the bmac */
604 link_10g = ((vars->line_speed == SPEED_10000) ||
605 (vars->line_speed == SPEED_12000) ||
606 (vars->line_speed == SPEED_12500) ||
607 (vars->line_speed == SPEED_13000) ||
608 (vars->line_speed == SPEED_15000) ||
609 (vars->line_speed == SPEED_16000));
611 vars->mac_type = MAC_TYPE_BMAC;
613 vars->mac_type = MAC_TYPE_EMAC;
615 } else { /* link down */
616 DP(NETIF_MSG_LINK, "phy link down\n");
618 vars->phy_link_up = 0;
620 vars->line_speed = 0;
621 vars->duplex = DUPLEX_FULL;
622 vars->flow_ctrl = FLOW_CTRL_NONE;
624 /* indicate no mac active */
625 vars->mac_type = MAC_TYPE_NONE;
628 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
629 vars->link_status, vars->phy_link_up);
630 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
631 vars->line_speed, vars->duplex, vars->flow_ctrl);
634 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
636 struct bnx2x *bp = params->bp;
637 REG_WR(bp, params->shmem_base +
638 offsetof(struct shmem_region,
639 port_mb[params->port].link_status),
643 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
645 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
646 NIG_REG_INGRESS_BMAC0_MEM;
648 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
650 /* Only if the bmac is out of reset */
651 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
652 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
655 /* Clear Rx Enable bit in BMAC_CONTROL register */
656 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
658 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
659 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
666 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
669 struct bnx2x *bp = params->bp;
670 u8 port = params->port;
675 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
677 /* wait for init credit */
678 init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
679 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
680 DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
682 while ((init_crd != crd) && count) {
685 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
688 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
689 if (init_crd != crd) {
690 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
695 if (flow_ctrl & FLOW_CTRL_RX ||
696 line_speed == SPEED_10 ||
697 line_speed == SPEED_100 ||
698 line_speed == SPEED_1000 ||
699 line_speed == SPEED_2500) {
700 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
701 /* update threshold */
702 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
703 /* update init credit */
704 init_crd = 778; /* (800-18-4) */
707 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
709 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
710 /* update threshold */
711 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
712 /* update init credit */
713 switch (line_speed) {
715 init_crd = thresh + 553 - 22;
719 init_crd = thresh + 664 - 22;
723 init_crd = thresh + 742 - 22;
727 init_crd = thresh + 778 - 22;
730 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
736 REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
737 DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
738 line_speed, init_crd);
740 /* probe the credit changes */
741 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
743 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
746 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
750 static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port)
753 switch (ext_phy_type) {
754 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
755 emac_base = GRCBASE_EMAC0;
757 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
758 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
761 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
768 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
769 u8 phy_addr, u8 devad, u16 reg, u16 val)
773 u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
775 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
776 * (a value of 49==0x31) and make sure that the AUTO poll is off
778 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
779 tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
780 EMAC_MDIO_MODE_CLOCK_CNT);
781 tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
782 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
783 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
784 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
789 tmp = ((phy_addr << 21) | (devad << 16) | reg |
790 EMAC_MDIO_COMM_COMMAND_ADDRESS |
791 EMAC_MDIO_COMM_START_BUSY);
792 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
794 for (i = 0; i < 50; i++) {
797 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
798 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
803 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
804 DP(NETIF_MSG_LINK, "write phy register failed\n");
808 tmp = ((phy_addr << 21) | (devad << 16) | val |
809 EMAC_MDIO_COMM_COMMAND_WRITE_45 |
810 EMAC_MDIO_COMM_START_BUSY);
811 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
813 for (i = 0; i < 50; i++) {
816 tmp = REG_RD(bp, mdio_ctrl +
817 EMAC_REG_EMAC_MDIO_COMM);
818 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
823 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
824 DP(NETIF_MSG_LINK, "write phy register failed\n");
829 /* Restore the saved mode */
830 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
835 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
836 u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
842 u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
843 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
844 * (a value of 49==0x31) and make sure that the AUTO poll is off
846 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
847 val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
848 EMAC_MDIO_MODE_CLOCK_CNT));
849 val |= (EMAC_MDIO_MODE_CLAUSE_45 |
850 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
851 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
852 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
856 val = ((phy_addr << 21) | (devad << 16) | reg |
857 EMAC_MDIO_COMM_COMMAND_ADDRESS |
858 EMAC_MDIO_COMM_START_BUSY);
859 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
861 for (i = 0; i < 50; i++) {
864 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
865 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
870 if (val & EMAC_MDIO_COMM_START_BUSY) {
871 DP(NETIF_MSG_LINK, "read phy register failed\n");
878 val = ((phy_addr << 21) | (devad << 16) |
879 EMAC_MDIO_COMM_COMMAND_READ_45 |
880 EMAC_MDIO_COMM_START_BUSY);
881 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
883 for (i = 0; i < 50; i++) {
886 val = REG_RD(bp, mdio_ctrl +
887 EMAC_REG_EMAC_MDIO_COMM);
888 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
889 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
893 if (val & EMAC_MDIO_COMM_START_BUSY) {
894 DP(NETIF_MSG_LINK, "read phy register failed\n");
901 /* Restore the saved mode */
902 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
907 static void bnx2x_set_aer_mmd(struct link_params *params,
908 struct link_vars *vars)
910 struct bnx2x *bp = params->bp;
914 ser_lane = ((params->lane_config &
915 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
916 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
918 offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
919 (params->phy_addr + ser_lane) : 0;
921 CL45_WR_OVER_CL22(bp, params->port,
923 MDIO_REG_BANK_AER_BLOCK,
924 MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
927 static void bnx2x_set_master_ln(struct link_params *params)
929 struct bnx2x *bp = params->bp;
930 u16 new_master_ln, ser_lane;
931 ser_lane = ((params->lane_config &
932 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
933 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
935 /* set the master_ln for AN */
936 CL45_RD_OVER_CL22(bp, params->port,
938 MDIO_REG_BANK_XGXS_BLOCK2,
939 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
942 CL45_WR_OVER_CL22(bp, params->port,
944 MDIO_REG_BANK_XGXS_BLOCK2 ,
945 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
946 (new_master_ln | ser_lane));
949 static u8 bnx2x_reset_unicore(struct link_params *params)
951 struct bnx2x *bp = params->bp;
955 CL45_RD_OVER_CL22(bp, params->port,
957 MDIO_REG_BANK_COMBO_IEEE0,
958 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
960 /* reset the unicore */
961 CL45_WR_OVER_CL22(bp, params->port,
963 MDIO_REG_BANK_COMBO_IEEE0,
964 MDIO_COMBO_IEEE0_MII_CONTROL,
966 MDIO_COMBO_IEEO_MII_CONTROL_RESET));
968 /* wait for the reset to self clear */
969 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
972 /* the reset erased the previous bank value */
973 CL45_RD_OVER_CL22(bp, params->port,
975 MDIO_REG_BANK_COMBO_IEEE0,
976 MDIO_COMBO_IEEE0_MII_CONTROL,
979 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
985 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
990 static void bnx2x_set_swap_lanes(struct link_params *params)
992 struct bnx2x *bp = params->bp;
993 /* Each two bits represents a lane number:
994 No swap is 0123 => 0x1b no need to enable the swap */
995 u16 ser_lane, rx_lane_swap, tx_lane_swap;
997 ser_lane = ((params->lane_config &
998 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
999 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1000 rx_lane_swap = ((params->lane_config &
1001 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1002 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1003 tx_lane_swap = ((params->lane_config &
1004 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1005 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1007 if (rx_lane_swap != 0x1b) {
1008 CL45_WR_OVER_CL22(bp, params->port,
1010 MDIO_REG_BANK_XGXS_BLOCK2,
1011 MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1013 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1014 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1016 CL45_WR_OVER_CL22(bp, params->port,
1018 MDIO_REG_BANK_XGXS_BLOCK2,
1019 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1022 if (tx_lane_swap != 0x1b) {
1023 CL45_WR_OVER_CL22(bp, params->port,
1025 MDIO_REG_BANK_XGXS_BLOCK2,
1026 MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1028 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1030 CL45_WR_OVER_CL22(bp, params->port,
1032 MDIO_REG_BANK_XGXS_BLOCK2,
1033 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1037 static void bnx2x_set_parallel_detection(struct link_params *params,
1040 struct bnx2x *bp = params->bp;
1043 CL45_RD_OVER_CL22(bp, params->port,
1045 MDIO_REG_BANK_SERDES_DIGITAL,
1046 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1050 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1053 CL45_WR_OVER_CL22(bp, params->port,
1055 MDIO_REG_BANK_SERDES_DIGITAL,
1056 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1059 if (phy_flags & PHY_XGXS_FLAG) {
1060 DP(NETIF_MSG_LINK, "XGXS\n");
1062 CL45_WR_OVER_CL22(bp, params->port,
1064 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1065 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1066 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1068 CL45_RD_OVER_CL22(bp, params->port,
1070 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1071 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1076 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1078 CL45_WR_OVER_CL22(bp, params->port,
1080 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1081 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1084 /* Disable parallel detection of HiG */
1085 CL45_WR_OVER_CL22(bp, params->port,
1087 MDIO_REG_BANK_XGXS_BLOCK2,
1088 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1089 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1090 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1094 static void bnx2x_set_autoneg(struct link_params *params,
1095 struct link_vars *vars)
1097 struct bnx2x *bp = params->bp;
1102 CL45_RD_OVER_CL22(bp, params->port,
1104 MDIO_REG_BANK_COMBO_IEEE0,
1105 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
1107 /* CL37 Autoneg Enabled */
1108 if (vars->line_speed == SPEED_AUTO_NEG)
1109 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1110 else /* CL37 Autoneg Disabled */
1111 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1112 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1114 CL45_WR_OVER_CL22(bp, params->port,
1116 MDIO_REG_BANK_COMBO_IEEE0,
1117 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1119 /* Enable/Disable Autodetection */
1121 CL45_RD_OVER_CL22(bp, params->port,
1123 MDIO_REG_BANK_SERDES_DIGITAL,
1124 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val);
1125 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1126 if (vars->line_speed == SPEED_AUTO_NEG)
1127 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1129 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1131 CL45_WR_OVER_CL22(bp, params->port,
1133 MDIO_REG_BANK_SERDES_DIGITAL,
1134 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1136 /* Enable TetonII and BAM autoneg */
1137 CL45_RD_OVER_CL22(bp, params->port,
1139 MDIO_REG_BANK_BAM_NEXT_PAGE,
1140 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1142 if (vars->line_speed == SPEED_AUTO_NEG) {
1143 /* Enable BAM aneg Mode and TetonII aneg Mode */
1144 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1145 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1147 /* TetonII and BAM Autoneg Disabled */
1148 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1149 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1151 CL45_WR_OVER_CL22(bp, params->port,
1153 MDIO_REG_BANK_BAM_NEXT_PAGE,
1154 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1157 /* Enable Clause 73 Aneg */
1158 if ((vars->line_speed == SPEED_AUTO_NEG) &&
1160 /* Enable BAM Station Manager */
1162 CL45_WR_OVER_CL22(bp, params->port,
1164 MDIO_REG_BANK_CL73_USERB0,
1165 MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1166 (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1167 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1168 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
1170 /* Merge CL73 and CL37 aneg resolution */
1171 CL45_RD_OVER_CL22(bp, params->port,
1173 MDIO_REG_BANK_CL73_USERB0,
1174 MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1177 CL45_WR_OVER_CL22(bp, params->port,
1179 MDIO_REG_BANK_CL73_USERB0,
1180 MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1182 MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
1184 /* Set the CL73 AN speed */
1186 CL45_RD_OVER_CL22(bp, params->port,
1188 MDIO_REG_BANK_CL73_IEEEB1,
1189 MDIO_CL73_IEEEB1_AN_ADV2, ®_val);
1190 /* In the SerDes we support only the 1G.
1191 In the XGXS we support the 10G KX4
1192 but we currently do not support the KR */
1193 if (vars->phy_flags & PHY_XGXS_FLAG) {
1194 DP(NETIF_MSG_LINK, "XGXS\n");
1196 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1198 DP(NETIF_MSG_LINK, "SerDes\n");
1200 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1202 CL45_WR_OVER_CL22(bp, params->port,
1204 MDIO_REG_BANK_CL73_IEEEB1,
1205 MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
1207 /* CL73 Autoneg Enabled */
1208 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
1210 /* CL73 Autoneg Disabled */
1213 CL45_WR_OVER_CL22(bp, params->port,
1215 MDIO_REG_BANK_CL73_IEEEB0,
1216 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1219 /* program SerDes, forced speed */
1220 static void bnx2x_program_serdes(struct link_params *params,
1221 struct link_vars *vars)
1223 struct bnx2x *bp = params->bp;
1226 /* program duplex, disable autoneg */
1228 CL45_RD_OVER_CL22(bp, params->port,
1230 MDIO_REG_BANK_COMBO_IEEE0,
1231 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
1232 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1233 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
1234 if (params->req_duplex == DUPLEX_FULL)
1235 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1236 CL45_WR_OVER_CL22(bp, params->port,
1238 MDIO_REG_BANK_COMBO_IEEE0,
1239 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1242 - needed only if the speed is greater than 1G (2.5G or 10G) */
1243 CL45_RD_OVER_CL22(bp, params->port,
1245 MDIO_REG_BANK_SERDES_DIGITAL,
1246 MDIO_SERDES_DIGITAL_MISC1, ®_val);
1247 /* clearing the speed value before setting the right speed */
1248 DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1250 reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1251 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1253 if (!((vars->line_speed == SPEED_1000) ||
1254 (vars->line_speed == SPEED_100) ||
1255 (vars->line_speed == SPEED_10))) {
1257 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1258 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1259 if (vars->line_speed == SPEED_10000)
1261 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1262 if (vars->line_speed == SPEED_13000)
1264 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1267 CL45_WR_OVER_CL22(bp, params->port,
1269 MDIO_REG_BANK_SERDES_DIGITAL,
1270 MDIO_SERDES_DIGITAL_MISC1, reg_val);
1274 static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1276 struct bnx2x *bp = params->bp;
1279 /* configure the 48 bits for BAM AN */
1281 /* set extended capabilities */
1282 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1283 val |= MDIO_OVER_1G_UP1_2_5G;
1284 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1285 val |= MDIO_OVER_1G_UP1_10G;
1286 CL45_WR_OVER_CL22(bp, params->port,
1288 MDIO_REG_BANK_OVER_1G,
1289 MDIO_OVER_1G_UP1, val);
1291 CL45_WR_OVER_CL22(bp, params->port,
1293 MDIO_REG_BANK_OVER_1G,
1294 MDIO_OVER_1G_UP3, 0);
1297 static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
1299 *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1300 /* resolve pause mode and advertisement
1301 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1303 switch (params->req_flow_ctrl) {
1304 case FLOW_CTRL_AUTO:
1305 if (params->req_fc_auto_adv == FLOW_CTRL_BOTH) {
1307 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1310 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1315 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1319 case FLOW_CTRL_BOTH:
1320 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1323 case FLOW_CTRL_NONE:
1325 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1330 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1333 struct bnx2x *bp = params->bp;
1334 /* for AN, we are always publishing full duplex */
1336 CL45_WR_OVER_CL22(bp, params->port,
1338 MDIO_REG_BANK_COMBO_IEEE0,
1339 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
1342 static void bnx2x_restart_autoneg(struct link_params *params)
1344 struct bnx2x *bp = params->bp;
1345 DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1347 /* enable and restart clause 73 aneg */
1350 CL45_RD_OVER_CL22(bp, params->port,
1352 MDIO_REG_BANK_CL73_IEEEB0,
1353 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1355 CL45_WR_OVER_CL22(bp, params->port,
1357 MDIO_REG_BANK_CL73_IEEEB0,
1358 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1360 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1361 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1364 /* Enable and restart BAM/CL37 aneg */
1367 CL45_RD_OVER_CL22(bp, params->port,
1369 MDIO_REG_BANK_COMBO_IEEE0,
1370 MDIO_COMBO_IEEE0_MII_CONTROL,
1373 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1375 CL45_WR_OVER_CL22(bp, params->port,
1377 MDIO_REG_BANK_COMBO_IEEE0,
1378 MDIO_COMBO_IEEE0_MII_CONTROL,
1380 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1381 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1385 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1386 struct link_vars *vars)
1388 struct bnx2x *bp = params->bp;
1391 /* in SGMII mode, the unicore is always slave */
1393 CL45_RD_OVER_CL22(bp, params->port,
1395 MDIO_REG_BANK_SERDES_DIGITAL,
1396 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1398 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1399 /* set sgmii mode (and not fiber) */
1400 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1401 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1402 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1403 CL45_WR_OVER_CL22(bp, params->port,
1405 MDIO_REG_BANK_SERDES_DIGITAL,
1406 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1409 /* if forced speed */
1410 if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1411 /* set speed, disable autoneg */
1414 CL45_RD_OVER_CL22(bp, params->port,
1416 MDIO_REG_BANK_COMBO_IEEE0,
1417 MDIO_COMBO_IEEE0_MII_CONTROL,
1419 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1420 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1421 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1423 switch (vars->line_speed) {
1426 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1430 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1433 /* there is nothing to set for 10M */
1436 /* invalid speed for SGMII */
1437 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1442 /* setting the full duplex */
1443 if (params->req_duplex == DUPLEX_FULL)
1445 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1446 CL45_WR_OVER_CL22(bp, params->port,
1448 MDIO_REG_BANK_COMBO_IEEE0,
1449 MDIO_COMBO_IEEE0_MII_CONTROL,
1452 } else { /* AN mode */
1453 /* enable and restart AN */
1454 bnx2x_restart_autoneg(params);
1463 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1465 switch (pause_result) { /* ASYM P ASYM P */
1466 case 0xb: /* 1 0 1 1 */
1467 vars->flow_ctrl = FLOW_CTRL_TX;
1470 case 0xe: /* 1 1 1 0 */
1471 vars->flow_ctrl = FLOW_CTRL_RX;
1474 case 0x5: /* 0 1 0 1 */
1475 case 0x7: /* 0 1 1 1 */
1476 case 0xd: /* 1 1 0 1 */
1477 case 0xf: /* 1 1 1 1 */
1478 vars->flow_ctrl = FLOW_CTRL_BOTH;
1486 static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1487 struct link_vars *vars)
1489 struct bnx2x *bp = params->bp;
1491 u16 ld_pause; /* local */
1492 u16 lp_pause; /* link partner */
1493 u16 an_complete; /* AN complete */
1497 u8 port = params->port;
1498 ext_phy_addr = ((params->ext_phy_config &
1499 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1500 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1502 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1505 bnx2x_cl45_read(bp, port,
1509 MDIO_AN_REG_STATUS, &an_complete);
1510 bnx2x_cl45_read(bp, port,
1514 MDIO_AN_REG_STATUS, &an_complete);
1516 if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1518 bnx2x_cl45_read(bp, port,
1522 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1523 bnx2x_cl45_read(bp, port,
1527 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1528 pause_result = (ld_pause &
1529 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1530 pause_result |= (lp_pause &
1531 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1532 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1534 bnx2x_pause_resolve(vars, pause_result);
1535 if (vars->flow_ctrl == FLOW_CTRL_NONE &&
1536 ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1537 bnx2x_cl45_read(bp, port,
1541 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1543 bnx2x_cl45_read(bp, port,
1547 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1548 pause_result = (ld_pause &
1549 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1550 pause_result |= (lp_pause &
1551 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1553 bnx2x_pause_resolve(vars, pause_result);
1554 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1562 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1563 struct link_vars *vars,
1566 struct bnx2x *bp = params->bp;
1567 u16 ld_pause; /* local driver */
1568 u16 lp_pause; /* link partner */
1571 vars->flow_ctrl = FLOW_CTRL_NONE;
1573 /* resolve from gp_status in case of AN complete and not sgmii */
1574 if ((params->req_flow_ctrl == FLOW_CTRL_AUTO) &&
1575 (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1576 (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1577 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1578 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1579 CL45_RD_OVER_CL22(bp, params->port,
1581 MDIO_REG_BANK_COMBO_IEEE0,
1582 MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1584 CL45_RD_OVER_CL22(bp, params->port,
1586 MDIO_REG_BANK_COMBO_IEEE0,
1587 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1589 pause_result = (ld_pause &
1590 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1591 pause_result |= (lp_pause &
1592 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1593 DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1594 bnx2x_pause_resolve(vars, pause_result);
1595 } else if ((params->req_flow_ctrl == FLOW_CTRL_AUTO) &&
1596 (bnx2x_ext_phy_resove_fc(params, vars))) {
1599 if (params->req_flow_ctrl == FLOW_CTRL_AUTO)
1600 vars->flow_ctrl = params->req_fc_auto_adv;
1602 vars->flow_ctrl = params->req_flow_ctrl;
1604 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1608 static u8 bnx2x_link_settings_status(struct link_params *params,
1609 struct link_vars *vars,
1612 struct bnx2x *bp = params->bp;
1615 vars->link_status = 0;
1617 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1618 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1621 vars->phy_link_up = 1;
1622 vars->link_status |= LINK_STATUS_LINK_UP;
1624 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1625 vars->duplex = DUPLEX_FULL;
1627 vars->duplex = DUPLEX_HALF;
1629 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1631 switch (gp_status & GP_STATUS_SPEED_MASK) {
1633 vars->line_speed = SPEED_10;
1634 if (vars->duplex == DUPLEX_FULL)
1635 vars->link_status |= LINK_10TFD;
1637 vars->link_status |= LINK_10THD;
1640 case GP_STATUS_100M:
1641 vars->line_speed = SPEED_100;
1642 if (vars->duplex == DUPLEX_FULL)
1643 vars->link_status |= LINK_100TXFD;
1645 vars->link_status |= LINK_100TXHD;
1649 case GP_STATUS_1G_KX:
1650 vars->line_speed = SPEED_1000;
1651 if (vars->duplex == DUPLEX_FULL)
1652 vars->link_status |= LINK_1000TFD;
1654 vars->link_status |= LINK_1000THD;
1657 case GP_STATUS_2_5G:
1658 vars->line_speed = SPEED_2500;
1659 if (vars->duplex == DUPLEX_FULL)
1660 vars->link_status |= LINK_2500TFD;
1662 vars->link_status |= LINK_2500THD;
1668 "link speed unsupported gp_status 0x%x\n",
1672 case GP_STATUS_10G_KX4:
1673 case GP_STATUS_10G_HIG:
1674 case GP_STATUS_10G_CX4:
1675 vars->line_speed = SPEED_10000;
1676 vars->link_status |= LINK_10GTFD;
1679 case GP_STATUS_12G_HIG:
1680 vars->line_speed = SPEED_12000;
1681 vars->link_status |= LINK_12GTFD;
1684 case GP_STATUS_12_5G:
1685 vars->line_speed = SPEED_12500;
1686 vars->link_status |= LINK_12_5GTFD;
1690 vars->line_speed = SPEED_13000;
1691 vars->link_status |= LINK_13GTFD;
1695 vars->line_speed = SPEED_15000;
1696 vars->link_status |= LINK_15GTFD;
1700 vars->line_speed = SPEED_16000;
1701 vars->link_status |= LINK_16GTFD;
1706 "link speed unsupported gp_status 0x%x\n",
1712 vars->link_status |= LINK_STATUS_SERDES_LINK;
1714 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1715 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1716 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1717 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1718 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) {
1719 vars->autoneg = AUTO_NEG_ENABLED;
1721 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1722 vars->autoneg |= AUTO_NEG_COMPLETE;
1723 vars->link_status |=
1724 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1727 vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1728 vars->link_status |=
1729 LINK_STATUS_PARALLEL_DETECTION_USED;
1732 if (vars->flow_ctrl & FLOW_CTRL_TX)
1733 vars->link_status |=
1734 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1736 if (vars->flow_ctrl & FLOW_CTRL_RX)
1737 vars->link_status |=
1738 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1740 } else { /* link_down */
1741 DP(NETIF_MSG_LINK, "phy link down\n");
1743 vars->phy_link_up = 0;
1745 vars->duplex = DUPLEX_FULL;
1746 vars->flow_ctrl = FLOW_CTRL_NONE;
1747 vars->autoneg = AUTO_NEG_DISABLED;
1748 vars->mac_type = MAC_TYPE_NONE;
1751 DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x \n",
1752 gp_status, vars->phy_link_up, vars->line_speed);
1753 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x"
1756 vars->flow_ctrl, vars->autoneg);
1757 DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1762 static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
1764 struct bnx2x *bp = params->bp;
1770 CL45_RD_OVER_CL22(bp, params->port,
1772 MDIO_REG_BANK_OVER_1G,
1773 MDIO_OVER_1G_LP_UP2, &lp_up2);
1775 CL45_RD_OVER_CL22(bp, params->port,
1778 MDIO_TX0_TX_DRIVER, &tx_driver);
1780 /* bits [10:7] at lp_up2, positioned at [15:12] */
1781 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1782 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1783 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1785 if ((lp_up2 != 0) &&
1786 (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
1787 /* replace tx_driver bits [15:12] */
1788 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1789 tx_driver |= lp_up2;
1790 CL45_WR_OVER_CL22(bp, params->port,
1793 MDIO_TX0_TX_DRIVER, tx_driver);
1797 static u8 bnx2x_emac_program(struct link_params *params,
1798 u32 line_speed, u32 duplex)
1800 struct bnx2x *bp = params->bp;
1801 u8 port = params->port;
1804 DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1805 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1807 (EMAC_MODE_25G_MODE |
1808 EMAC_MODE_PORT_MII_10M |
1809 EMAC_MODE_HALF_DUPLEX));
1810 switch (line_speed) {
1812 mode |= EMAC_MODE_PORT_MII_10M;
1816 mode |= EMAC_MODE_PORT_MII;
1820 mode |= EMAC_MODE_PORT_GMII;
1824 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1828 /* 10G not valid for EMAC */
1829 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1833 if (duplex == DUPLEX_HALF)
1834 mode |= EMAC_MODE_HALF_DUPLEX;
1836 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1839 bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1840 line_speed, params->hw_led_mode, params->chip_id);
1844 /*****************************************************************************/
1845 /* External Phy section */
1846 /*****************************************************************************/
1847 static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
1849 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1850 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
1852 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1853 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
1856 static void bnx2x_ext_phy_reset(struct link_params *params,
1857 struct link_vars *vars)
1859 struct bnx2x *bp = params->bp;
1861 u8 ext_phy_addr = ((params->ext_phy_config &
1862 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1863 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1864 DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1865 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1866 /* The PHY reset is controled by GPIO 1
1867 * Give it 1ms of reset pulse
1869 if (vars->phy_flags & PHY_XGXS_FLAG) {
1871 switch (ext_phy_type) {
1872 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1873 DP(NETIF_MSG_LINK, "XGXS Direct\n");
1876 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1877 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1878 DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1880 /* Restore normal power mode*/
1881 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1882 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1886 bnx2x_hw_reset(bp, params->port);
1888 bnx2x_cl45_write(bp, params->port,
1892 MDIO_PMA_REG_CTRL, 0xa040);
1894 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1895 /* Unset Low Power Mode and SW reset */
1896 /* Restore normal power mode*/
1897 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1898 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1901 DP(NETIF_MSG_LINK, "XGXS 8072\n");
1902 bnx2x_cl45_write(bp, params->port,
1909 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1912 emac_base = (params->port) ? GRCBASE_EMAC0 :
1915 /* Restore normal power mode*/
1916 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1917 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1920 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1921 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1924 DP(NETIF_MSG_LINK, "XGXS 8073\n");
1928 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1929 DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1931 /* Restore normal power mode*/
1932 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1933 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1937 bnx2x_hw_reset(bp, params->port);
1941 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
1942 DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
1946 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
1947 params->ext_phy_config);
1951 } else { /* SerDes */
1952 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
1953 switch (ext_phy_type) {
1954 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
1955 DP(NETIF_MSG_LINK, "SerDes Direct\n");
1958 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
1959 DP(NETIF_MSG_LINK, "SerDes 5482\n");
1960 bnx2x_hw_reset(bp, params->port);
1965 "BAD SerDes ext_phy_config 0x%x\n",
1966 params->ext_phy_config);
1972 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
1974 struct bnx2x *bp = params->bp;
1975 u8 port = params->port;
1976 u8 ext_phy_addr = ((params->ext_phy_config &
1977 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1978 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1979 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1980 u16 fw_ver1, fw_ver2;
1982 /* Need to wait 200ms after reset */
1984 /* Boot port from external ROM
1985 * Set ser_boot_ctl bit in the MISC_CTRL1 register
1987 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1989 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
1991 /* Reset internal microprocessor */
1992 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1994 MDIO_PMA_REG_GEN_CTRL,
1995 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
1996 /* set micro reset = 0 */
1997 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1999 MDIO_PMA_REG_GEN_CTRL,
2000 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2001 /* Reset internal microprocessor */
2002 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2004 MDIO_PMA_REG_GEN_CTRL,
2005 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2006 /* wait for 100ms for code download via SPI port */
2009 /* Clear ser_boot_ctl bit */
2010 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2012 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2016 /* Print the PHY FW version */
2017 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2019 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2020 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2022 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2023 DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2026 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2028 /* This is only required for 8073A1, version 102 only */
2030 struct bnx2x *bp = params->bp;
2031 u8 ext_phy_addr = ((params->ext_phy_config &
2032 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2033 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2036 /* Read 8073 HW revision*/
2037 bnx2x_cl45_read(bp, params->port,
2038 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2044 /* No need to workaround in 8073 A1 */
2048 bnx2x_cl45_read(bp, params->port,
2049 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2052 MDIO_PMA_REG_ROM_VER2, &val);
2054 /* SNR should be applied only for version 0x102 */
2061 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2063 struct bnx2x *bp = params->bp;
2064 u8 ext_phy_addr = ((params->ext_phy_config &
2065 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2066 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2067 u16 val, cnt, cnt1 ;
2069 bnx2x_cl45_read(bp, params->port,
2070 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2076 /* No need to workaround in 8073 A1 */
2079 /* XAUI workaround in 8073 A0: */
2081 /* After loading the boot ROM and restarting Autoneg,
2082 poll Dev1, Reg $C820: */
2084 for (cnt = 0; cnt < 1000; cnt++) {
2085 bnx2x_cl45_read(bp, params->port,
2086 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2090 /* If bit [14] = 0 or bit [13] = 0, continue on with
2091 system initialization (XAUI work-around not required,
2092 as these bits indicate 2.5G or 1G link up). */
2093 if (!(val & (1<<14)) || !(val & (1<<13))) {
2094 DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2096 } else if (!(val & (1<<15))) {
2097 DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2098 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2099 it's MSB (bit 15) goes to 1 (indicating that the
2100 XAUI workaround has completed),
2101 then continue on with system initialization.*/
2102 for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2103 bnx2x_cl45_read(bp, params->port,
2104 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2108 if (val & (1<<15)) {
2110 "XAUI workaround has completed\n");
2119 DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2124 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2127 u16 fw_ver1, fw_ver2;
2128 /* Boot port from external ROM */
2130 bnx2x_cl45_write(bp, port,
2131 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2134 MDIO_PMA_REG_GEN_CTRL,
2137 /* ucode reboot and rst */
2138 bnx2x_cl45_write(bp, port,
2139 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2142 MDIO_PMA_REG_GEN_CTRL,
2145 bnx2x_cl45_write(bp, port,
2146 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2149 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2151 /* Reset internal microprocessor */
2152 bnx2x_cl45_write(bp, port,
2153 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2156 MDIO_PMA_REG_GEN_CTRL,
2157 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2159 /* Release srst bit */
2160 bnx2x_cl45_write(bp, port,
2161 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2164 MDIO_PMA_REG_GEN_CTRL,
2165 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2167 /* wait for 100ms for code download via SPI port */
2170 /* Clear ser_boot_ctl bit */
2171 bnx2x_cl45_write(bp, port,
2172 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2175 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2177 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2180 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2181 bnx2x_cl45_read(bp, port,
2182 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2185 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2186 DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2190 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2192 struct bnx2x *bp = params->bp;
2193 u8 port = params->port;
2194 u8 ext_phy_addr = ((params->ext_phy_config &
2195 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2196 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2197 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2199 /* Force KR or KX */
2200 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2204 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2206 MDIO_PMA_REG_10G_CTRL2,
2208 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2210 MDIO_PMA_REG_BCM_CTRL,
2212 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2217 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2219 struct bnx2x *bp = params->bp;
2220 u8 port = params->port;
2222 u8 ext_phy_addr = ((params->ext_phy_config &
2223 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2224 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2225 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2227 bnx2x_cl45_read(bp, params->port,
2228 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2234 /* Mustn't set low power mode in 8073 A0 */
2238 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2239 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2241 MDIO_XS_PLL_SEQUENCER, &val);
2243 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2244 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2247 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2248 MDIO_XS_DEVAD, 0x805E, 0x1077);
2249 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2250 MDIO_XS_DEVAD, 0x805D, 0x0000);
2251 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2252 MDIO_XS_DEVAD, 0x805C, 0x030B);
2253 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2254 MDIO_XS_DEVAD, 0x805B, 0x1240);
2255 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2256 MDIO_XS_DEVAD, 0x805A, 0x2490);
2259 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2260 MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2261 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2262 MDIO_XS_DEVAD, 0x80A6, 0x9041);
2263 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2264 MDIO_XS_DEVAD, 0x80A5, 0x4640);
2267 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2268 MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2269 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2270 MDIO_XS_DEVAD, 0x80FD, 0x9249);
2271 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2272 MDIO_XS_DEVAD, 0x80FC, 0x2015);
2274 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
2275 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2277 MDIO_XS_PLL_SEQUENCER, &val);
2279 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2280 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2283 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
2284 struct link_vars *vars)
2287 struct bnx2x *bp = params->bp;
2289 u8 ext_phy_addr = ((params->ext_phy_config &
2290 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2291 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2292 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2294 bnx2x_cl45_read(bp, params->port,
2298 MDIO_AN_REG_CL37_FC_LD, &cl37_val);
2300 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2301 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2303 if ((vars->ieee_fc &
2304 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
2305 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
2306 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
2308 if ((vars->ieee_fc &
2309 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2310 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2311 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2313 if ((vars->ieee_fc &
2314 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2315 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2316 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2319 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
2321 bnx2x_cl45_write(bp, params->port,
2325 MDIO_AN_REG_CL37_FC_LD, cl37_val);
2329 static void bnx2x_ext_phy_set_pause(struct link_params *params,
2330 struct link_vars *vars)
2332 struct bnx2x *bp = params->bp;
2334 u8 ext_phy_addr = ((params->ext_phy_config &
2335 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2336 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2337 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2339 /* read modify write pause advertizing */
2340 bnx2x_cl45_read(bp, params->port,
2344 MDIO_AN_REG_ADV_PAUSE, &val);
2346 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2348 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2350 if ((vars->ieee_fc &
2351 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2352 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2353 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2355 if ((vars->ieee_fc &
2356 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2357 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2359 MDIO_AN_REG_ADV_PAUSE_PAUSE;
2362 "Ext phy AN advertize 0x%x\n", val);
2363 bnx2x_cl45_write(bp, params->port,
2367 MDIO_AN_REG_ADV_PAUSE, val);
2371 static void bnx2x_init_internal_phy(struct link_params *params,
2372 struct link_vars *vars)
2374 struct bnx2x *bp = params->bp;
2375 u8 port = params->port;
2376 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2379 rx_eq = ((params->serdes_config &
2380 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2381 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2383 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2384 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2385 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2386 CL45_WR_OVER_CL22(bp, port,
2389 MDIO_RX0_RX_EQ_BOOST,
2391 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2392 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2395 /* forced speed requested? */
2396 if (vars->line_speed != SPEED_AUTO_NEG) {
2397 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2399 /* disable autoneg */
2400 bnx2x_set_autoneg(params, vars);
2402 /* program speed and duplex */
2403 bnx2x_program_serdes(params, vars);
2405 } else { /* AN_mode */
2406 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2409 bnx2x_set_brcm_cl37_advertisment(params);
2411 /* program duplex & pause advertisement (for aneg) */
2412 bnx2x_set_ieee_aneg_advertisment(params,
2415 /* enable autoneg */
2416 bnx2x_set_autoneg(params, vars);
2418 /* enable and restart AN */
2419 bnx2x_restart_autoneg(params);
2422 } else { /* SGMII mode */
2423 DP(NETIF_MSG_LINK, "SGMII\n");
2425 bnx2x_initialize_sgmii_process(params, vars);
2429 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2431 struct bnx2x *bp = params->bp;
2438 if (vars->phy_flags & PHY_XGXS_FLAG) {
2439 ext_phy_addr = ((params->ext_phy_config &
2440 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2441 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2443 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2444 /* Make sure that the soft reset is off (expect for the 8072:
2445 * due to the lock, it will be done inside the specific
2448 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
2449 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
2450 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
2451 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
2452 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
2453 /* Wait for soft reset to get cleared upto 1 sec */
2454 for (cnt = 0; cnt < 1000; cnt++) {
2455 bnx2x_cl45_read(bp, params->port,
2459 MDIO_PMA_REG_CTRL, &ctrl);
2460 if (!(ctrl & (1<<15)))
2464 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
2468 switch (ext_phy_type) {
2469 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2472 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2473 DP(NETIF_MSG_LINK, "XGXS 8705\n");
2475 bnx2x_cl45_write(bp, params->port,
2479 MDIO_PMA_REG_MISC_CTRL,
2481 bnx2x_cl45_write(bp, params->port,
2485 MDIO_PMA_REG_PHY_IDENTIFIER,
2487 bnx2x_cl45_write(bp, params->port,
2491 MDIO_PMA_REG_CMU_PLL_BYPASS,
2493 bnx2x_cl45_write(bp, params->port,
2497 MDIO_WIS_REG_LASI_CNTL, 0x1);
2500 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2501 DP(NETIF_MSG_LINK, "XGXS 8706\n");
2505 /* First enable LASI */
2506 bnx2x_cl45_write(bp, params->port,
2510 MDIO_PMA_REG_RX_ALARM_CTRL,
2512 bnx2x_cl45_write(bp, params->port,
2516 MDIO_PMA_REG_LASI_CTRL, 0x0004);
2518 if (params->req_line_speed == SPEED_10000) {
2519 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
2521 bnx2x_cl45_write(bp, params->port,
2525 MDIO_PMA_REG_DIGITAL_CTRL,
2528 /* Force 1Gbps using autoneg with 1G
2531 /* Allow CL37 through CL73 */
2532 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
2533 bnx2x_cl45_write(bp, params->port,
2537 MDIO_AN_REG_CL37_CL73,
2540 /* Enable Full-Duplex advertisment on CL37 */
2541 bnx2x_cl45_write(bp, params->port,
2545 MDIO_AN_REG_CL37_FC_LP,
2547 /* Enable CL37 AN */
2548 bnx2x_cl45_write(bp, params->port,
2552 MDIO_AN_REG_CL37_AN,
2555 bnx2x_cl45_write(bp, params->port,
2559 MDIO_AN_REG_ADV, (1<<5));
2561 /* Enable clause 73 AN */
2562 bnx2x_cl45_write(bp, params->port,
2573 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2574 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2577 u16 rx_alarm_ctrl_val;
2580 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2581 rx_alarm_ctrl_val = 0x400;
2582 lasi_ctrl_val = 0x0004;
2584 rx_alarm_ctrl_val = (1<<2);
2585 lasi_ctrl_val = 0x0004;
2589 bnx2x_cl45_write(bp, params->port,
2593 MDIO_PMA_REG_RX_ALARM_CTRL,
2596 bnx2x_cl45_write(bp, params->port,
2600 MDIO_PMA_REG_LASI_CTRL,
2603 bnx2x_8073_set_pause_cl37(params, vars);
2606 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
2607 bnx2x_bcm8072_external_rom_boot(params);
2610 /* In case of 8073 with long xaui lines,
2611 don't set the 8073 xaui low power*/
2612 bnx2x_bcm8073_set_xaui_low_power_mode(params);
2615 bnx2x_cl45_read(bp, params->port,
2622 bnx2x_cl45_read(bp, params->port,
2626 MDIO_PMA_REG_RX_ALARM, &tmp1);
2628 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
2631 /* If this is forced speed, set to KR or KX
2632 * (all other are not supported)
2634 if (params->loopback_mode == LOOPBACK_EXT) {
2635 bnx2x_bcm807x_force_10G(params);
2637 "Forced speed 10G on 807X\n");
2640 bnx2x_cl45_write(bp, params->port,
2641 ext_phy_type, ext_phy_addr,
2643 MDIO_PMA_REG_BCM_CTRL,
2646 if (params->req_line_speed != SPEED_AUTO_NEG) {
2647 if (params->req_line_speed == SPEED_10000) {
2649 } else if (params->req_line_speed ==
2652 /* Note that 2.5G works only
2653 when used with 1G advertisment */
2659 if (params->speed_cap_mask &
2660 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2663 /* Note that 2.5G works only when
2664 used with 1G advertisment */
2665 if (params->speed_cap_mask &
2666 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
2667 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
2670 "807x autoneg val = 0x%x\n", val);
2673 bnx2x_cl45_write(bp, params->port,
2677 MDIO_AN_REG_ADV, val);
2680 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2682 bnx2x_cl45_read(bp, params->port,
2688 if (((params->speed_cap_mask &
2689 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
2690 (params->req_line_speed ==
2692 (params->req_line_speed ==
2695 /* Allow 2.5G for A1 and above */
2696 bnx2x_cl45_read(bp, params->port,
2697 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2701 DP(NETIF_MSG_LINK, "Add 2.5G\n");
2707 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
2711 bnx2x_cl45_write(bp, params->port,
2718 /* Add support for CL37 (passive mode) II */
2720 bnx2x_cl45_read(bp, params->port,
2724 MDIO_AN_REG_CL37_FC_LD,
2727 bnx2x_cl45_write(bp, params->port,
2731 MDIO_AN_REG_CL37_FC_LD, (tmp1 |
2732 ((params->req_duplex == DUPLEX_FULL) ?
2735 /* Add support for CL37 (passive mode) III */
2736 bnx2x_cl45_write(bp, params->port,
2740 MDIO_AN_REG_CL37_AN, 0x1000);
2743 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2744 /* The SNR will improve about 2db by changing
2745 BW and FEE main tap. Rest commands are executed
2747 /*Change FFE main cursor to 5 in EDC register*/
2748 if (bnx2x_8073_is_snr_needed(params))
2749 bnx2x_cl45_write(bp, params->port,
2753 MDIO_PMA_REG_EDC_FFE_MAIN,
2756 /* Enable FEC (Forware Error Correction)
2757 Request in the AN */
2758 bnx2x_cl45_read(bp, params->port,
2762 MDIO_AN_REG_ADV2, &tmp1);
2766 bnx2x_cl45_write(bp, params->port,
2770 MDIO_AN_REG_ADV2, tmp1);
2774 bnx2x_ext_phy_set_pause(params, vars);
2776 /* Restart autoneg */
2778 bnx2x_cl45_write(bp, params->port,
2782 MDIO_AN_REG_CTRL, 0x1200);
2783 DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
2784 "Advertise 1G=%x, 10G=%x\n",
2785 ((val & (1<<5)) > 0),
2786 ((val & (1<<7)) > 0));
2789 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
2791 "Setting the SFX7101 LASI indication\n");
2793 bnx2x_cl45_write(bp, params->port,
2797 MDIO_PMA_REG_LASI_CTRL, 0x1);
2799 "Setting the SFX7101 LED to blink on traffic\n");
2800 bnx2x_cl45_write(bp, params->port,
2804 MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
2806 bnx2x_ext_phy_set_pause(params, vars);
2807 /* Restart autoneg */
2808 bnx2x_cl45_read(bp, params->port,
2812 MDIO_AN_REG_CTRL, &val);
2814 bnx2x_cl45_write(bp, params->port,
2818 MDIO_AN_REG_CTRL, val);
2820 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2822 "XGXS PHY Failure detected 0x%x\n",
2823 params->ext_phy_config);
2827 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
2828 params->ext_phy_config);
2833 } else { /* SerDes */
2835 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2836 switch (ext_phy_type) {
2837 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
2838 DP(NETIF_MSG_LINK, "SerDes Direct\n");
2841 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
2842 DP(NETIF_MSG_LINK, "SerDes 5482\n");
2846 DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
2847 params->ext_phy_config);
2855 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2856 struct link_vars *vars)
2858 struct bnx2x *bp = params->bp;
2862 u16 rx_sd, pcs_status;
2863 u8 ext_phy_link_up = 0;
2864 u8 port = params->port;
2865 if (vars->phy_flags & PHY_XGXS_FLAG) {
2866 ext_phy_addr = ((params->ext_phy_config &
2867 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2868 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2870 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2871 switch (ext_phy_type) {
2872 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2873 DP(NETIF_MSG_LINK, "XGXS Direct\n");
2874 ext_phy_link_up = 1;
2877 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2878 DP(NETIF_MSG_LINK, "XGXS 8705\n");
2879 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2882 MDIO_WIS_REG_LASI_STATUS, &val1);
2883 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2885 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2888 MDIO_WIS_REG_LASI_STATUS, &val1);
2889 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2891 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2894 MDIO_PMA_REG_RX_SD, &rx_sd);
2895 DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
2896 ext_phy_link_up = (rx_sd & 0x1);
2897 if (ext_phy_link_up)
2898 vars->line_speed = SPEED_10000;
2901 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2902 DP(NETIF_MSG_LINK, "XGXS 8706\n");
2903 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2906 MDIO_PMA_REG_LASI_STATUS, &val1);
2907 DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2909 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2912 MDIO_PMA_REG_LASI_STATUS, &val1);
2913 DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2915 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2918 MDIO_PMA_REG_RX_SD, &rx_sd);
2919 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2922 MDIO_PCS_REG_STATUS, &pcs_status);
2924 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2927 MDIO_AN_REG_LINK_STATUS, &val2);
2928 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2931 MDIO_AN_REG_LINK_STATUS, &val2);
2933 DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
2934 " pcs_status 0x%x 1Gbps link_status 0x%x\n",
2935 rx_sd, pcs_status, val2);
2936 /* link is up if both bit 0 of pmd_rx_sd and
2937 * bit 0 of pcs_status are set, or if the autoneg bit
2940 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
2942 if (ext_phy_link_up) {
2944 vars->line_speed = SPEED_1000;
2946 vars->line_speed = SPEED_10000;
2949 /* clear LASI indication*/
2950 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2953 MDIO_PMA_REG_RX_ALARM, &val2);
2956 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2957 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2959 u16 link_status = 0;
2960 u16 an1000_status = 0;
2962 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2963 bnx2x_cl45_read(bp, params->port,
2967 MDIO_PCS_REG_LASI_STATUS, &val1);
2968 bnx2x_cl45_read(bp, params->port,
2972 MDIO_PCS_REG_LASI_STATUS, &val2);
2974 "870x LASI status 0x%x->0x%x\n",
2978 /* In 8073, port1 is directed through emac0 and
2979 * port0 is directed through emac1
2981 bnx2x_cl45_read(bp, params->port,
2985 MDIO_PMA_REG_LASI_STATUS, &val1);
2988 "8703 LASI status 0x%x\n",
2992 /* clear the interrupt LASI status register */
2993 bnx2x_cl45_read(bp, params->port,
2997 MDIO_PCS_REG_STATUS, &val2);
2998 bnx2x_cl45_read(bp, params->port,
3002 MDIO_PCS_REG_STATUS, &val1);
3003 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
3006 bnx2x_cl45_read(bp, params->port,
3013 /* Check the LASI */
3014 bnx2x_cl45_read(bp, params->port,
3018 MDIO_PMA_REG_RX_ALARM, &val2);
3020 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
3022 /* Check the link status */
3023 bnx2x_cl45_read(bp, params->port,
3027 MDIO_PCS_REG_STATUS, &val2);
3028 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
3030 bnx2x_cl45_read(bp, params->port,
3034 MDIO_PMA_REG_STATUS, &val2);
3035 bnx2x_cl45_read(bp, params->port,
3039 MDIO_PMA_REG_STATUS, &val1);
3040 ext_phy_link_up = ((val1 & 4) == 4);
3041 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
3043 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3045 if (ext_phy_link_up &&
3046 ((params->req_line_speed !=
3048 if (bnx2x_bcm8073_xaui_wa(params)
3050 ext_phy_link_up = 0;
3054 bnx2x_cl45_read(bp, params->port,
3060 bnx2x_cl45_read(bp, params->port,
3067 /* Check the link status on 1.1.2 */
3068 bnx2x_cl45_read(bp, params->port,
3072 MDIO_PMA_REG_STATUS, &val2);
3073 bnx2x_cl45_read(bp, params->port,
3077 MDIO_PMA_REG_STATUS, &val1);
3078 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3079 "an_link_status=0x%x\n",
3080 val2, val1, an1000_status);
3082 ext_phy_link_up = (((val1 & 4) == 4) ||
3083 (an1000_status & (1<<1)));
3084 if (ext_phy_link_up &&
3085 bnx2x_8073_is_snr_needed(params)) {
3086 /* The SNR will improve about 2dbby
3087 changing the BW and FEE main tap.*/
3089 /* The 1st write to change FFE main
3090 tap is set before restart AN */
3091 /* Change PLL Bandwidth in EDC
3093 bnx2x_cl45_write(bp, port, ext_phy_type,
3096 MDIO_PMA_REG_PLL_BANDWIDTH,
3099 /* Change CDR Bandwidth in EDC
3101 bnx2x_cl45_write(bp, port, ext_phy_type,
3104 MDIO_PMA_REG_CDR_BANDWIDTH,
3109 bnx2x_cl45_read(bp, params->port,
3116 /* Bits 0..2 --> speed detected,
3117 bits 13..15--> link is down */
3118 if ((link_status & (1<<2)) &&
3119 (!(link_status & (1<<15)))) {
3120 ext_phy_link_up = 1;
3121 vars->line_speed = SPEED_10000;
3123 "port %x: External link"
3124 " up in 10G\n", params->port);
3125 } else if ((link_status & (1<<1)) &&
3126 (!(link_status & (1<<14)))) {
3127 ext_phy_link_up = 1;
3128 vars->line_speed = SPEED_2500;
3130 "port %x: External link"
3131 " up in 2.5G\n", params->port);
3132 } else if ((link_status & (1<<0)) &&
3133 (!(link_status & (1<<13)))) {
3134 ext_phy_link_up = 1;
3135 vars->line_speed = SPEED_1000;
3137 "port %x: External link"
3138 " up in 1G\n", params->port);
3140 ext_phy_link_up = 0;
3142 "port %x: External link"
3143 " is down\n", params->port);
3146 /* See if 1G link is up for the 8072 */
3147 bnx2x_cl45_read(bp, params->port,
3153 bnx2x_cl45_read(bp, params->port,
3159 if (an1000_status & (1<<1)) {
3160 ext_phy_link_up = 1;
3161 vars->line_speed = SPEED_1000;
3163 "port %x: External link"
3164 " up in 1G\n", params->port);
3165 } else if (ext_phy_link_up) {
3166 ext_phy_link_up = 1;
3167 vars->line_speed = SPEED_10000;
3169 "port %x: External link"
3170 " up in 10G\n", params->port);
3177 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3178 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3181 MDIO_PMA_REG_LASI_STATUS, &val2);
3182 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3185 MDIO_PMA_REG_LASI_STATUS, &val1);
3187 "10G-base-T LASI status 0x%x->0x%x\n",
3189 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3192 MDIO_PMA_REG_STATUS, &val2);
3193 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3196 MDIO_PMA_REG_STATUS, &val1);
3198 "10G-base-T PMA status 0x%x->0x%x\n",
3200 ext_phy_link_up = ((val1 & 4) == 4);
3202 * print the AN outcome of the SFX7101 PHY
3204 if (ext_phy_link_up) {
3205 bnx2x_cl45_read(bp, params->port,
3209 MDIO_AN_REG_MASTER_STATUS,
3211 vars->line_speed = SPEED_10000;
3213 "SFX7101 AN status 0x%x->Master=%x\n",
3220 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3221 params->ext_phy_config);
3222 ext_phy_link_up = 0;
3226 } else { /* SerDes */
3227 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3228 switch (ext_phy_type) {
3229 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3230 DP(NETIF_MSG_LINK, "SerDes Direct\n");
3231 ext_phy_link_up = 1;
3234 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3235 DP(NETIF_MSG_LINK, "SerDes 5482\n");
3236 ext_phy_link_up = 1;
3241 "BAD SerDes ext_phy_config 0x%x\n",
3242 params->ext_phy_config);
3243 ext_phy_link_up = 0;
3248 return ext_phy_link_up;
3251 static void bnx2x_link_int_enable(struct link_params *params)
3253 u8 port = params->port;
3256 struct bnx2x *bp = params->bp;
3257 /* setting the status to report on link up
3258 for either XGXS or SerDes */
3260 if (params->switch_cfg == SWITCH_CFG_10G) {
3261 mask = (NIG_MASK_XGXS0_LINK10G |
3262 NIG_MASK_XGXS0_LINK_STATUS);
3263 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
3264 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3265 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3266 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3268 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
3269 mask |= NIG_MASK_MI_INT;
3270 DP(NETIF_MSG_LINK, "enabled external phy int\n");
3273 } else { /* SerDes */
3274 mask = NIG_MASK_SERDES0_LINK_STATUS;
3275 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
3276 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3277 if ((ext_phy_type !=
3278 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
3280 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
3281 mask |= NIG_MASK_MI_INT;
3282 DP(NETIF_MSG_LINK, "enabled external phy int\n");
3286 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3288 DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
3289 (params->switch_cfg == SWITCH_CFG_10G),
3290 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
3292 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
3293 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
3294 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
3295 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
3296 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
3297 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
3298 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
3305 static void bnx2x_link_int_ack(struct link_params *params,
3306 struct link_vars *vars, u8 is_10g)
3308 struct bnx2x *bp = params->bp;
3309 u8 port = params->port;
3311 /* first reset all status
3312 * we assume only one line will be change at a time */
3313 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3314 (NIG_STATUS_XGXS0_LINK10G |
3315 NIG_STATUS_XGXS0_LINK_STATUS |
3316 NIG_STATUS_SERDES0_LINK_STATUS));
3317 if (vars->phy_link_up) {
3319 /* Disable the 10G link interrupt
3320 * by writing 1 to the status register
3322 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
3324 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3325 NIG_STATUS_XGXS0_LINK10G);
3327 } else if (params->switch_cfg == SWITCH_CFG_10G) {
3328 /* Disable the link interrupt
3329 * by writing 1 to the relevant lane
3330 * in the status register
3332 u32 ser_lane = ((params->lane_config &
3333 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3334 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3336 DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
3338 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3340 NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
3342 } else { /* SerDes */
3343 DP(NETIF_MSG_LINK, "SerDes phy link up\n");
3344 /* Disable the link interrupt
3345 * by writing 1 to the status register
3348 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3349 NIG_STATUS_SERDES0_LINK_STATUS);
3352 } else { /* link_down */
3356 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
3359 u32 mask = 0xf0000000;
3363 /* Need more then 10chars for this format */
3370 digit = ((num & mask) >> shift);
3372 *str_ptr = digit + '0';
3374 *str_ptr = digit - 0xa + 'a';
3387 static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
3392 /* Enable EMAC0 in to enable MDIO */
3393 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
3394 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
3397 /* take ext phy out of reset */
3399 MISC_REGISTERS_GPIO_2,
3400 MISC_REGISTERS_GPIO_HIGH,
3404 MISC_REGISTERS_GPIO_1,
3405 MISC_REGISTERS_GPIO_HIGH,
3411 for (cnt = 0; cnt < 1000; cnt++) {
3413 bnx2x_cl45_read(bp, port,
3419 if (!(ctrl & (1<<15))) {
3420 DP(NETIF_MSG_LINK, "Reset completed\n\n");
3426 static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
3428 /* put sf to reset */
3430 MISC_REGISTERS_GPIO_1,
3431 MISC_REGISTERS_GPIO_LOW,
3434 MISC_REGISTERS_GPIO_2,
3435 MISC_REGISTERS_GPIO_LOW,
3439 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3440 u8 *version, u16 len)
3442 struct bnx2x *bp = params->bp;
3443 u32 ext_phy_type = 0;
3445 u8 ext_phy_addr = 0 ;
3449 if (version == NULL || params == NULL)
3452 /* reset the returned value to zero */
3453 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3454 ext_phy_addr = ((params->ext_phy_config &
3455 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3456 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3458 switch (ext_phy_type) {
3459 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3464 /* Take ext phy out of reset */
3466 bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3472 bnx2x_cl45_read(bp, params->port,
3476 MDIO_PMA_REG_7101_VER1, &val);
3477 version[2] = (val & 0xFF);
3478 version[3] = ((val & 0xFF00)>>8);
3480 bnx2x_cl45_read(bp, params->port,
3483 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2,
3485 version[0] = (val & 0xFF);
3486 version[1] = ((val & 0xFF00)>>8);
3490 bnx2x_turn_off_sf(bp, params->port);
3492 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3493 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3495 /* Take ext phy out of reset */
3497 bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3500 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3503 MDIO_PMA_REG_ROM_VER1, &val);
3505 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3508 MDIO_PMA_REG_ROM_VER2, &val);
3510 status = bnx2x_format_ver(ver_num, version, len);
3513 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3514 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3516 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3519 MDIO_PMA_REG_ROM_VER1, &val);
3521 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3524 MDIO_PMA_REG_ROM_VER2, &val);
3526 status = bnx2x_format_ver(ver_num, version, len);
3529 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3532 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
3533 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
3534 " type is FAILURE!\n");
3544 static void bnx2x_set_xgxs_loopback(struct link_params *params,
3545 struct link_vars *vars,
3548 u8 port = params->port;
3549 struct bnx2x *bp = params->bp;
3554 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
3556 /* change the uni_phy_addr in the nig */
3557 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
3560 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
3562 bnx2x_cl45_write(bp, port, 0,
3565 (MDIO_REG_BANK_AER_BLOCK +
3566 (MDIO_AER_BLOCK_AER_REG & 0xf)),
3569 bnx2x_cl45_write(bp, port, 0,
3572 (MDIO_REG_BANK_CL73_IEEEB0 +
3573 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
3576 /* set aer mmd back */
3577 bnx2x_set_aer_mmd(params, vars);
3580 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
3586 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
3588 CL45_RD_OVER_CL22(bp, port,
3590 MDIO_REG_BANK_COMBO_IEEE0,
3591 MDIO_COMBO_IEEE0_MII_CONTROL,
3594 CL45_WR_OVER_CL22(bp, port,
3596 MDIO_REG_BANK_COMBO_IEEE0,
3597 MDIO_COMBO_IEEE0_MII_CONTROL,
3599 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
3604 static void bnx2x_ext_phy_loopback(struct link_params *params)
3606 struct bnx2x *bp = params->bp;
3610 if (params->switch_cfg == SWITCH_CFG_10G) {
3611 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3612 /* CL37 Autoneg Enabled */
3613 ext_phy_addr = ((params->ext_phy_config &
3614 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3615 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3616 switch (ext_phy_type) {
3617 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3618 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
3620 "ext_phy_loopback: We should not get here\n");
3622 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3623 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
3625 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3626 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
3628 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3629 /* SFX7101_XGXS_TEST1 */
3630 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3633 MDIO_XS_SFX7101_XGXS_TEST1,
3636 "ext_phy_loopback: set ext phy loopback\n");
3638 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3641 } /* switch external PHY type */
3644 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3645 ext_phy_addr = (params->ext_phy_config &
3646 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
3647 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
3653 *------------------------------------------------------------------------
3654 * bnx2x_override_led_value -
3656 * Override the led value of the requsted led
3658 *------------------------------------------------------------------------
3660 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
3661 u32 led_idx, u32 value)
3665 /* If port 0 then use EMAC0, else use EMAC1*/
3666 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3669 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
3670 port, led_idx, value);
3673 case 0: /* 10MB led */
3674 /* Read the current value of the LED register in
3676 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3677 /* Set the OVERRIDE bit to 1 */
3678 reg_val |= EMAC_LED_OVERRIDE;
3679 /* If value is 1, set the 10M_OVERRIDE bit,
3680 otherwise reset it.*/
3681 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
3682 (reg_val & ~EMAC_LED_10MB_OVERRIDE);
3683 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3685 case 1: /*100MB led */
3686 /*Read the current value of the LED register in
3688 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3689 /* Set the OVERRIDE bit to 1 */
3690 reg_val |= EMAC_LED_OVERRIDE;
3691 /* If value is 1, set the 100M_OVERRIDE bit,
3692 otherwise reset it.*/
3693 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
3694 (reg_val & ~EMAC_LED_100MB_OVERRIDE);
3695 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3697 case 2: /* 1000MB led */
3698 /* Read the current value of the LED register in the
3700 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3701 /* Set the OVERRIDE bit to 1 */
3702 reg_val |= EMAC_LED_OVERRIDE;
3703 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
3705 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
3706 (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
3707 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3709 case 3: /* 2500MB led */
3710 /* Read the current value of the LED register in the
3712 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3713 /* Set the OVERRIDE bit to 1 */
3714 reg_val |= EMAC_LED_OVERRIDE;
3715 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
3717 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
3718 (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
3719 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3721 case 4: /*10G led */
3723 REG_WR(bp, NIG_REG_LED_10G_P0,
3726 REG_WR(bp, NIG_REG_LED_10G_P1,
3730 case 5: /* TRAFFIC led */
3731 /* Find if the traffic control is via BMAC or EMAC */
3733 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
3735 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
3737 /* Override the traffic led in the EMAC:*/
3739 /* Read the current value of the LED register in
3741 reg_val = REG_RD(bp, emac_base +
3743 /* Set the TRAFFIC_OVERRIDE bit to 1 */
3744 reg_val |= EMAC_LED_OVERRIDE;
3745 /* If value is 1, set the TRAFFIC bit, otherwise
3747 reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
3748 (reg_val & ~EMAC_LED_TRAFFIC);
3749 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3750 } else { /* Override the traffic led in the BMAC: */
3751 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3753 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
3759 "bnx2x_override_led_value() unknown led index %d "
3760 "(should be 0-5)\n", led_idx);
3768 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
3769 u16 hw_led_mode, u32 chip_id)
3773 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3774 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
3775 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
3776 speed, hw_led_mode);
3779 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
3780 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
3781 SHARED_HW_CFG_LED_MAC1);
3783 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3784 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
3788 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
3789 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
3791 /* Set blinking rate to ~15.9Hz */
3792 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
3793 LED_BLINK_RATE_VAL);
3794 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
3796 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3797 EMAC_WR(bp, EMAC_REG_EMAC_LED,
3798 (tmp & (~EMAC_LED_OVERRIDE)));
3800 if (!CHIP_IS_E1H(bp) &&
3801 ((speed == SPEED_2500) ||
3802 (speed == SPEED_1000) ||
3803 (speed == SPEED_100) ||
3804 (speed == SPEED_10))) {
3805 /* On Everest 1 Ax chip versions for speeds less than
3806 10G LED scheme is different */
3807 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3809 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
3811 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
3818 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
3826 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
3828 struct bnx2x *bp = params->bp;
3831 CL45_RD_OVER_CL22(bp, params->port,
3833 MDIO_REG_BANK_GP_STATUS,
3834 MDIO_GP_STATUS_TOP_AN_STATUS1,
3836 /* link is up only if both local phy and external phy are up */
3837 if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
3838 bnx2x_ext_phy_is_link_up(params, vars))
3844 static u8 bnx2x_link_initialize(struct link_params *params,
3845 struct link_vars *vars)
3847 struct bnx2x *bp = params->bp;
3848 u8 port = params->port;
3851 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3852 /* Activate the external PHY */
3853 bnx2x_ext_phy_reset(params, vars);
3855 bnx2x_set_aer_mmd(params, vars);
3857 if (vars->phy_flags & PHY_XGXS_FLAG)
3858 bnx2x_set_master_ln(params);
3860 rc = bnx2x_reset_unicore(params);
3861 /* reset the SerDes and wait for reset bit return low */
3865 bnx2x_set_aer_mmd(params, vars);
3867 /* setting the masterLn_def again after the reset */
3868 if (vars->phy_flags & PHY_XGXS_FLAG) {
3869 bnx2x_set_master_ln(params);
3870 bnx2x_set_swap_lanes(params);
3873 if (vars->phy_flags & PHY_XGXS_FLAG) {
3874 if (params->req_line_speed &&
3875 ((params->req_line_speed == SPEED_100) ||
3876 (params->req_line_speed == SPEED_10))) {
3877 vars->phy_flags |= PHY_SGMII_FLAG;
3879 vars->phy_flags &= ~PHY_SGMII_FLAG;
3882 /* In case of external phy existance, the line speed would be the
3883 line speed linked up by the external phy. In case it is direct only,
3884 then the line_speed during initialization will be equal to the
3886 vars->line_speed = params->req_line_speed;
3888 bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
3890 /* init ext phy and enable link state int */
3891 non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
3892 (params->loopback_mode == LOOPBACK_XGXS_10) ||
3893 (params->loopback_mode == LOOPBACK_EXT_PHY));
3896 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705)) {
3897 if (params->req_line_speed == SPEED_AUTO_NEG)
3898 bnx2x_set_parallel_detection(params, vars->phy_flags);
3899 bnx2x_init_internal_phy(params, vars);
3903 rc |= bnx2x_ext_phy_init(params, vars);
3905 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3906 (NIG_STATUS_XGXS0_LINK10G |
3907 NIG_STATUS_XGXS0_LINK_STATUS |
3908 NIG_STATUS_SERDES0_LINK_STATUS));
3915 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
3917 struct bnx2x *bp = params->bp;
3920 DP(NETIF_MSG_LINK, "Phy Initialization started \n");
3921 DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
3922 params->req_line_speed, params->req_flow_ctrl);
3923 vars->link_status = 0;
3924 vars->phy_link_up = 0;
3926 vars->line_speed = 0;
3927 vars->duplex = DUPLEX_FULL;
3928 vars->flow_ctrl = FLOW_CTRL_NONE;
3929 vars->mac_type = MAC_TYPE_NONE;
3931 if (params->switch_cfg == SWITCH_CFG_1G)
3932 vars->phy_flags = PHY_SERDES_FLAG;
3934 vars->phy_flags = PHY_XGXS_FLAG;
3937 /* disable attentions */
3938 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
3939 (NIG_MASK_XGXS0_LINK_STATUS |
3940 NIG_MASK_XGXS0_LINK10G |
3941 NIG_MASK_SERDES0_LINK_STATUS |
3944 bnx2x_emac_init(params, vars);
3946 if (CHIP_REV_IS_FPGA(bp)) {
3948 vars->line_speed = SPEED_10000;
3949 vars->duplex = DUPLEX_FULL;
3950 vars->flow_ctrl = FLOW_CTRL_NONE;
3951 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3952 /* enable on E1.5 FPGA */
3953 if (CHIP_IS_E1H(bp)) {
3955 (FLOW_CTRL_TX | FLOW_CTRL_RX);
3956 vars->link_status |=
3957 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
3958 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
3961 bnx2x_emac_enable(params, vars, 0);
3962 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3964 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3965 + params->port*4, 0);
3967 /* update shared memory */
3968 bnx2x_update_mng(params, vars->link_status);
3973 if (CHIP_REV_IS_EMUL(bp)) {
3976 vars->line_speed = SPEED_10000;
3977 vars->duplex = DUPLEX_FULL;
3978 vars->flow_ctrl = FLOW_CTRL_NONE;
3979 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3981 bnx2x_bmac_enable(params, vars, 0);
3983 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3985 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3986 + params->port*4, 0);
3988 /* update shared memory */
3989 bnx2x_update_mng(params, vars->link_status);
3994 if (params->loopback_mode == LOOPBACK_BMAC) {
3996 vars->line_speed = SPEED_10000;
3997 vars->duplex = DUPLEX_FULL;
3998 vars->flow_ctrl = FLOW_CTRL_NONE;
3999 vars->mac_type = MAC_TYPE_BMAC;
4001 vars->phy_flags = PHY_XGXS_FLAG;
4003 bnx2x_phy_deassert(params, vars->phy_flags);
4004 /* set bmac loopback */
4005 bnx2x_bmac_enable(params, vars, 1);
4007 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4009 } else if (params->loopback_mode == LOOPBACK_EMAC) {
4011 vars->line_speed = SPEED_1000;
4012 vars->duplex = DUPLEX_FULL;
4013 vars->flow_ctrl = FLOW_CTRL_NONE;
4014 vars->mac_type = MAC_TYPE_EMAC;
4016 vars->phy_flags = PHY_XGXS_FLAG;
4018 bnx2x_phy_deassert(params, vars->phy_flags);
4019 /* set bmac loopback */
4020 bnx2x_emac_enable(params, vars, 1);
4021 bnx2x_emac_program(params, vars->line_speed,
4023 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4025 } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
4026 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
4028 vars->line_speed = SPEED_10000;
4029 vars->duplex = DUPLEX_FULL;
4030 vars->flow_ctrl = FLOW_CTRL_NONE;
4032 vars->phy_flags = PHY_XGXS_FLAG;
4035 NIG_REG_XGXS0_CTRL_PHY_ADDR+
4037 params->phy_addr = (u8)val;
4039 bnx2x_phy_deassert(params, vars->phy_flags);
4040 bnx2x_link_initialize(params, vars);
4042 vars->mac_type = MAC_TYPE_BMAC;
4044 bnx2x_bmac_enable(params, vars, 0);
4046 if (params->loopback_mode == LOOPBACK_XGXS_10) {
4047 /* set 10G XGXS loopback */
4048 bnx2x_set_xgxs_loopback(params, vars, 1);
4050 /* set external phy loopback */
4051 bnx2x_ext_phy_loopback(params);
4053 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4059 bnx2x_phy_deassert(params, vars->phy_flags);
4060 switch (params->switch_cfg) {
4062 vars->phy_flags |= PHY_SERDES_FLAG;
4063 if ((params->ext_phy_config &
4064 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
4065 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
4071 NIG_REG_SERDES0_CTRL_PHY_ADDR+
4074 params->phy_addr = (u8)val;
4077 case SWITCH_CFG_10G:
4078 vars->phy_flags |= PHY_XGXS_FLAG;
4080 NIG_REG_XGXS0_CTRL_PHY_ADDR+
4082 params->phy_addr = (u8)val;
4086 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
4091 bnx2x_link_initialize(params, vars);
4093 bnx2x_link_int_enable(params);
4098 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
4101 struct bnx2x *bp = params->bp;
4102 u32 ext_phy_config = params->ext_phy_config;
4103 u16 hw_led_mode = params->hw_led_mode;
4104 u32 chip_id = params->chip_id;
4105 u8 port = params->port;
4106 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4107 /* disable attentions */
4109 vars->link_status = 0;
4110 bnx2x_update_mng(params, vars->link_status);
4111 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4112 (NIG_MASK_XGXS0_LINK_STATUS |
4113 NIG_MASK_XGXS0_LINK10G |
4114 NIG_MASK_SERDES0_LINK_STATUS |
4117 /* activate nig drain */
4118 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4120 /* disable nig egress interface */
4121 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4122 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4124 /* Stop BigMac rx */
4125 bnx2x_bmac_rx_disable(bp, port);
4128 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4131 /* The PHY reset is controled by GPIO 1
4132 * Hold it as vars low
4134 /* clear link led */
4135 bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4136 if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
4137 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
4138 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
4141 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4142 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4145 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4146 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4149 DP(NETIF_MSG_LINK, "reset external PHY\n");
4150 } else if (ext_phy_type ==
4151 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4152 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4155 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4156 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4160 /* reset the SerDes/XGXS */
4161 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4162 (0x1ff << (port*16)));
4165 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4166 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4168 /* disable nig ingress interface */
4169 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4170 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4171 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4172 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4177 static u8 bnx2x_update_link_down(struct link_params *params,
4178 struct link_vars *vars)
4180 struct bnx2x *bp = params->bp;
4181 u8 port = params->port;
4182 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4183 bnx2x_set_led(bp, port, LED_MODE_OFF,
4184 0, params->hw_led_mode,
4187 /* indicate no mac active */
4188 vars->mac_type = MAC_TYPE_NONE;
4190 /* update shared memory */
4191 vars->link_status = 0;
4192 vars->line_speed = 0;
4193 bnx2x_update_mng(params, vars->link_status);
4195 /* activate nig drain */
4196 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4199 bnx2x_bmac_rx_disable(bp, params->port);
4200 REG_WR(bp, GRCBASE_MISC +
4201 MISC_REGISTERS_RESET_REG_2_CLEAR,
4202 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4206 static u8 bnx2x_update_link_up(struct link_params *params,
4207 struct link_vars *vars,
4208 u8 link_10g, u32 gp_status)
4210 struct bnx2x *bp = params->bp;
4211 u8 port = params->port;
4213 vars->link_status |= LINK_STATUS_LINK_UP;
4215 bnx2x_bmac_enable(params, vars, 0);
4216 bnx2x_set_led(bp, port, LED_MODE_OPER,
4217 SPEED_10000, params->hw_led_mode,
4221 bnx2x_emac_enable(params, vars, 0);
4222 rc = bnx2x_emac_program(params, vars->line_speed,
4226 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4227 if (!(vars->phy_flags &
4229 bnx2x_set_sgmii_tx_driver(params);
4234 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4238 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4240 /* update shared memory */
4241 bnx2x_update_mng(params, vars->link_status);
4244 /* This function should called upon link interrupt */
4245 /* In case vars->link_up, driver needs to
4248 3. Update the shared memory
4252 1. Update shared memory
4257 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4259 struct bnx2x *bp = params->bp;
4260 u8 port = params->port;
4263 u8 ext_phy_link_up, rc = 0;
4266 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
4268 (vars->phy_flags & PHY_XGXS_FLAG),
4269 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4271 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4272 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4273 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4274 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
4276 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4277 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4278 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4280 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4282 /* Check external link change only for non-direct */
4283 ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
4285 /* Read gp_status */
4286 CL45_RD_OVER_CL22(bp, port, params->phy_addr,
4287 MDIO_REG_BANK_GP_STATUS,
4288 MDIO_GP_STATUS_TOP_AN_STATUS1,
4291 rc = bnx2x_link_settings_status(params, vars, gp_status);
4295 /* anything 10 and over uses the bmac */
4296 link_10g = ((vars->line_speed == SPEED_10000) ||
4297 (vars->line_speed == SPEED_12000) ||
4298 (vars->line_speed == SPEED_12500) ||
4299 (vars->line_speed == SPEED_13000) ||
4300 (vars->line_speed == SPEED_15000) ||
4301 (vars->line_speed == SPEED_16000));
4303 bnx2x_link_int_ack(params, vars, link_10g);
4305 /* In case external phy link is up, and internal link is down
4306 ( not initialized yet probably after link initialization, it needs
4308 Note that after link down-up as result of cable plug,
4309 the xgxs link would probably become up again without the need to
4312 if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4313 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
4314 (ext_phy_link_up && !vars->phy_link_up))
4315 bnx2x_init_internal_phy(params, vars);
4317 /* link is up only if both local phy and external phy are up */
4318 vars->link_up = (ext_phy_link_up && vars->phy_link_up);
4321 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
4323 rc = bnx2x_update_link_down(params, vars);
4328 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4330 u8 ext_phy_addr[PORT_MAX];
4334 /* PART1 - Reset both phys */
4335 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4336 /* Extract the ext phy address for the port */
4337 u32 ext_phy_config = REG_RD(bp, shmem_base +
4338 offsetof(struct shmem_region,
4339 dev_info.port_hw_config[port].external_phy_config));
4341 /* disable attentions */
4342 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4343 (NIG_MASK_XGXS0_LINK_STATUS |
4344 NIG_MASK_XGXS0_LINK10G |
4345 NIG_MASK_SERDES0_LINK_STATUS |
4348 ext_phy_addr[port] =
4350 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4351 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4353 /* Need to take the phy out of low power mode in order
4354 to write to access its registers */
4355 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4356 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
4359 bnx2x_cl45_write(bp, port,
4360 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4367 /* Add delay of 150ms after reset */
4370 /* PART2 - Download firmware to both phys */
4371 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4374 bnx2x_bcm8073_external_rom_boot(bp, port,
4375 ext_phy_addr[port]);
4377 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4380 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
4383 "bnx2x_8073_common_init_phy port %x "
4384 "fw Download failed\n", port);
4388 /* Only set bit 10 = 1 (Tx power down) */
4389 bnx2x_cl45_read(bp, port,
4390 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4393 MDIO_PMA_REG_TX_POWER_DOWN, &val);
4395 /* Phase1 of TX_POWER_DOWN reset */
4396 bnx2x_cl45_write(bp, port,
4397 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4400 MDIO_PMA_REG_TX_POWER_DOWN,
4404 /* Toggle Transmitter: Power down and then up with 600ms
4408 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
4409 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4410 /* Phase2 of POWER_DOWN_RESET*/
4411 /* Release bit 10 (Release Tx power down) */
4412 bnx2x_cl45_read(bp, port,
4413 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4416 MDIO_PMA_REG_TX_POWER_DOWN, &val);
4418 bnx2x_cl45_write(bp, port,
4419 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4422 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
4425 /* Read modify write the SPI-ROM version select register */
4426 bnx2x_cl45_read(bp, port,
4427 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4430 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
4431 bnx2x_cl45_write(bp, port,
4432 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4435 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
4437 /* set GPIO2 back to LOW */
4438 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4439 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
4445 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4450 DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n");
4452 /* Read the ext_phy_type for arbitrary port(0) */
4453 ext_phy_type = XGXS_EXT_PHY_TYPE(
4454 REG_RD(bp, shmem_base +
4455 offsetof(struct shmem_region,
4456 dev_info.port_hw_config[0].external_phy_config)));
4458 switch (ext_phy_type) {
4459 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4461 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
4466 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
4476 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
4480 bnx2x_cl45_read(bp, port,
4481 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4484 MDIO_PMA_REG_7101_RESET, &val);
4486 for (cnt = 0; cnt < 10; cnt++) {
4488 /* Writes a self-clearing reset */
4489 bnx2x_cl45_write(bp, port,
4490 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4493 MDIO_PMA_REG_7101_RESET,
4495 /* Wait for clear */
4496 bnx2x_cl45_read(bp, port,
4497 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4500 MDIO_PMA_REG_7101_RESET, &val);
4502 if ((val & (1<<15)) == 0)
4506 #define RESERVED_SIZE 256
4507 /* max application is 160K bytes - data at end of RAM */
4508 #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
4510 /* Header is 14 bytes */
4511 #define HEADER_SIZE 14
4512 #define DATA_OFFSET HEADER_SIZE
4514 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
4515 bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
4518 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
4520 /* Programs an image to DSP's flash via the SPI port*/
4521 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
4523 char data[], u32 size)
4525 const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
4526 /* Doesn't include last trans!*/
4527 const u16 last_trans_size = size%4; /* Num bytes on last trans */
4528 u16 trans_cnt, byte_cnt;
4531 u16 code_started = 0;
4532 u16 image_revision1, image_revision2;
4535 DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
4537 if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
4538 /* This very often will be the case, because the image is built
4539 with 160Kbytes size whereas the total image size must actually
4540 be 160Kbytes-RESERVED_SIZE */
4541 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
4542 "truncated to %d bytes\n", size, MAX_APP_SIZE);
4543 size = MAX_APP_SIZE+HEADER_SIZE;
4545 DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
4546 DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]);
4547 /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
4548 and issuing a reset.*/
4550 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4551 MISC_REGISTERS_GPIO_HIGH, port);
4553 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4556 for (cnt = 0; cnt < 100; cnt++)
4559 /* Make sure we can access the DSP
4560 And it's in the correct mode (waiting for download) */
4562 bnx2x_cl45_read(bp, port,
4563 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4566 MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
4568 if (tmp != 0x000A) {
4569 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
4570 "Expected 0x000A, read 0x%04X\n", tmp);
4571 DP(NETIF_MSG_LINK, "Download failed\n");
4575 /* Mux the SPI interface away from the internal processor */
4576 bnx2x_cl45_write(bp, port,
4577 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4580 MDIO_PCS_REG_7101_SPI_MUX, 1);
4582 /* Reset the SPI port */
4583 bnx2x_cl45_write(bp, port,
4584 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4587 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4588 bnx2x_cl45_write(bp, port,
4589 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4592 MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
4593 (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
4594 bnx2x_cl45_write(bp, port,
4595 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4598 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4600 /* Erase the flash */
4601 bnx2x_cl45_write(bp, port,
4602 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4605 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4606 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4608 bnx2x_cl45_write(bp, port,
4609 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4612 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4615 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4616 bnx2x_cl45_write(bp, port,
4617 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4620 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4621 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
4623 bnx2x_cl45_write(bp, port,
4624 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4627 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4629 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4631 /* Wait 10 seconds, the maximum time for the erase to complete */
4632 DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
4633 for (cnt = 0; cnt < 1000; cnt++)
4636 DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
4638 for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
4639 bnx2x_cl45_write(bp, port,
4640 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4643 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4644 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4646 bnx2x_cl45_write(bp, port,
4647 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4650 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4652 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4654 bnx2x_cl45_write(bp, port,
4655 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4658 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4659 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4661 /* Bits 23-16 of address */
4662 bnx2x_cl45_write(bp, port,
4663 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4666 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4668 /* Bits 15-8 of address */
4669 bnx2x_cl45_write(bp, port,
4670 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4673 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4676 /* Bits 7-0 of address */
4677 bnx2x_cl45_write(bp, port,
4678 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4681 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4685 while (byte_cnt < 4 && data_index < size) {
4686 bnx2x_cl45_write(bp, port,
4687 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4690 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4691 data[data_index++]);
4695 bnx2x_cl45_write(bp, port,
4696 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4699 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4702 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4703 msleep(5); /* Wait 5 ms minimum between transs */
4705 /* Let the user know something's going on.*/
4706 /* a pacifier ever 4K */
4707 if ((data_index % 1023) == 0)
4708 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4711 DP(NETIF_MSG_LINK, "\n");
4712 /* Transfer the last block if there is data remaining */
4713 if (last_trans_size) {
4714 bnx2x_cl45_write(bp, port,
4715 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4718 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4719 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4721 bnx2x_cl45_write(bp, port,
4722 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4725 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4728 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4730 bnx2x_cl45_write(bp, port,
4731 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4734 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4735 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4737 /* Bits 23-16 of address */
4738 bnx2x_cl45_write(bp, port,
4739 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4742 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4744 /* Bits 15-8 of address */
4745 bnx2x_cl45_write(bp, port,
4746 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4749 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4752 /* Bits 7-0 of address */
4753 bnx2x_cl45_write(bp, port,
4754 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4757 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4761 while (byte_cnt < last_trans_size && data_index < size) {
4762 /* Bits 7-0 of address */
4763 bnx2x_cl45_write(bp, port,
4764 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4767 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4768 data[data_index++]);
4772 bnx2x_cl45_write(bp, port,
4773 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4776 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4779 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4782 /* DSP Remove Download Mode */
4783 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4784 MISC_REGISTERS_GPIO_LOW, port);
4786 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4788 /* wait 0.5 sec to allow it to run */
4789 for (cnt = 0; cnt < 100; cnt++)
4792 bnx2x_hw_reset(bp, port);
4794 for (cnt = 0; cnt < 100; cnt++)
4797 /* Check that the code is started. In case the download
4798 checksum failed, the code won't be started. */
4799 bnx2x_cl45_read(bp, port,
4800 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4803 MDIO_PCS_REG_7101_DSP_ACCESS,
4806 code_started = (tmp & (1<<4));
4807 if (!code_started) {
4808 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
4812 /* Verify that the file revision is now equal to the image
4813 revision within the DSP */
4814 bnx2x_cl45_read(bp, port,
4815 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4818 MDIO_PMA_REG_7101_VER1,
4821 bnx2x_cl45_read(bp, port,
4822 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4825 MDIO_PMA_REG_7101_VER2,
4828 if (data[0x14e] != (image_revision2&0xFF) ||
4829 data[0x14f] != ((image_revision2&0xFF00)>>8) ||
4830 data[0x150] != (image_revision1&0xFF) ||
4831 data[0x151] != ((image_revision1&0xFF00)>>8)) {
4832 DP(NETIF_MSG_LINK, "Download failed.\n");
4835 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4839 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
4840 u8 driver_loaded, char data[], u32 size)
4845 ext_phy_addr = ((ext_phy_config &
4846 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4847 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4849 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4851 switch (ext_phy_type) {
4852 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4853 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4854 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4855 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4857 "Flash download not supported for this ext phy\n");
4860 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4861 /* Take ext phy out of reset */
4863 bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
4864 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
4867 bnx2x_turn_off_sf(bp, port);
4869 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4870 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4871 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4873 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");