1 /* Copyright 2008 Broadcom Corporation
3 * Unless you and Broadcom execute a separate written software license
4 * agreement governing use of this software, this software is licensed to you
5 * under the terms of the GNU General Public License version 2, available
6 * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
8 * Notwithstanding the above, under no circumstances may you combine this
9 * software in any way with any other Broadcom software provided under a
10 * license other than the GPL, without Broadcom's express prior written
13 * Written by Yaniv Rosner
17 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/pci.h>
20 #include <linux/netdevice.h>
21 #include <linux/delay.h>
22 #include <linux/ethtool.h>
23 #include <linux/mutex.h>
24 #include <linux/version.h>
26 #include "bnx2x_reg.h"
27 #include "bnx2x_fw_defs.h"
28 #include "bnx2x_hsi.h"
29 #include "bnx2x_link.h"
32 /********************************************************/
33 #define SUPPORT_CL73 0 /* Currently no */
35 #define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
36 #define ETH_MIN_PACKET_SIZE 60
37 #define ETH_MAX_PACKET_SIZE 1500
38 #define ETH_MAX_JUMBO_PACKET_SIZE 9600
39 #define MDIO_ACCESS_TIMEOUT 1000
40 #define BMAC_CONTROL_RX_ENABLE 2
41 #define MAX_MTU_SIZE 5000
43 /***********************************************************/
44 /* Shortcut definitions */
45 /***********************************************************/
47 #define NIG_STATUS_XGXS0_LINK10G \
48 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
49 #define NIG_STATUS_XGXS0_LINK_STATUS \
50 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
51 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
52 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
53 #define NIG_STATUS_SERDES0_LINK_STATUS \
54 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
55 #define NIG_MASK_MI_INT \
56 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
57 #define NIG_MASK_XGXS0_LINK10G \
58 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
59 #define NIG_MASK_XGXS0_LINK_STATUS \
60 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
61 #define NIG_MASK_SERDES0_LINK_STATUS \
62 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
64 #define MDIO_AN_CL73_OR_37_COMPLETE \
65 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
66 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
68 #define XGXS_RESET_BITS \
69 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
70 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
71 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
72 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
73 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
75 #define SERDES_RESET_BITS \
76 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
77 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
78 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
79 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
81 #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
82 #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
83 #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
84 #define AUTONEG_PARALLEL \
85 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
86 #define AUTONEG_SGMII_FIBER_AUTODET \
87 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
88 #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
90 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
91 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
92 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
93 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
94 #define GP_STATUS_SPEED_MASK \
95 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
96 #define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
97 #define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
98 #define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
99 #define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
100 #define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
101 #define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
102 #define GP_STATUS_10G_HIG \
103 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
104 #define GP_STATUS_10G_CX4 \
105 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
106 #define GP_STATUS_12G_HIG \
107 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
108 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
109 #define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
110 #define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
111 #define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
112 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
113 #define GP_STATUS_10G_KX4 \
114 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
116 #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
117 #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
118 #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
119 #define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
120 #define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
121 #define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
122 #define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
123 #define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
124 #define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
125 #define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
126 #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
127 #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
128 #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
129 #define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
130 #define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
131 #define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
132 #define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
133 #define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
134 #define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
135 #define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
136 #define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
137 #define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
138 #define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
140 #define PHY_XGXS_FLAG 0x1
141 #define PHY_SGMII_FLAG 0x2
142 #define PHY_SERDES_FLAG 0x4
144 /**********************************************************/
146 /**********************************************************/
147 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
148 bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
149 DEFAULT_PHY_DEV_ADDR, \
150 (_bank + (_addr & 0xf)), \
153 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
154 bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
155 DEFAULT_PHY_DEV_ADDR, \
156 (_bank + (_addr & 0xf)), \
159 static void bnx2x_set_phy_mdio(struct link_params *params)
161 struct bnx2x *bp = params->bp;
162 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
163 params->port*0x18, 0);
164 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
165 DEFAULT_PHY_DEV_ADDR);
168 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
170 u32 val = REG_RD(bp, reg);
173 REG_WR(bp, reg, val);
177 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
179 u32 val = REG_RD(bp, reg);
182 REG_WR(bp, reg, val);
186 static void bnx2x_emac_init(struct link_params *params,
187 struct link_vars *vars)
189 /* reset and unreset the emac core */
190 struct bnx2x *bp = params->bp;
191 u8 port = params->port;
192 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
196 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
197 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
199 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
200 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
202 /* init emac - use read-modify-write */
203 /* self clear reset */
204 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
205 EMAC_WR(EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
210 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
211 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
213 DP(NETIF_MSG_LINK, "EMAC timeout!\n");
217 }while (val & EMAC_MODE_RESET);
219 /* Set mac address */
220 val = ((params->mac_addr[0] << 8) |
221 params->mac_addr[1]);
222 EMAC_WR(EMAC_REG_EMAC_MAC_MATCH, val);
224 val = ((params->mac_addr[2] << 24) |
225 (params->mac_addr[3] << 16) |
226 (params->mac_addr[4] << 8) |
227 params->mac_addr[5]);
228 EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val);
231 static u8 bnx2x_emac_enable(struct link_params *params,
232 struct link_vars *vars, u8 lb)
234 struct bnx2x *bp = params->bp;
235 u8 port = params->port;
236 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
239 DP(NETIF_MSG_LINK, "enabling EMAC\n");
241 /* enable emac and not bmac */
242 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
245 if (CHIP_REV_IS_EMUL(bp)) {
246 /* Use lane 1 (of lanes 0-3) */
247 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
248 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
254 if (CHIP_REV_IS_FPGA(bp)) {
255 /* Use lane 1 (of lanes 0-3) */
256 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
258 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
259 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
263 if (vars->phy_flags & PHY_XGXS_FLAG) {
264 u32 ser_lane = ((params->lane_config &
265 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
266 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
268 DP(NETIF_MSG_LINK, "XGXS\n");
269 /* select the master lanes (out of 0-3) */
270 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
273 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
276 } else { /* SerDes */
277 DP(NETIF_MSG_LINK, "SerDes\n");
279 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
284 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
286 if (CHIP_REV_IS_SLOW(bp)) {
287 /* config GMII mode */
288 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
289 EMAC_WR(EMAC_REG_EMAC_MODE,
290 (val | EMAC_MODE_PORT_GMII));
292 /* pause enable/disable */
293 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
294 EMAC_RX_MODE_FLOW_EN);
295 if (vars->flow_ctrl & FLOW_CTRL_RX)
296 bnx2x_bits_en(bp, emac_base +
297 EMAC_REG_EMAC_RX_MODE,
298 EMAC_RX_MODE_FLOW_EN);
300 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
301 EMAC_TX_MODE_EXT_PAUSE_EN);
302 if (vars->flow_ctrl & FLOW_CTRL_TX)
303 bnx2x_bits_en(bp, emac_base +
304 EMAC_REG_EMAC_TX_MODE,
305 EMAC_TX_MODE_EXT_PAUSE_EN);
308 /* KEEP_VLAN_TAG, promiscuous */
309 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
310 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
311 EMAC_WR(EMAC_REG_EMAC_RX_MODE, val);
314 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
319 EMAC_WR(EMAC_REG_EMAC_MODE, val);
321 /* enable emac for jumbo packets */
322 EMAC_WR(EMAC_REG_EMAC_RX_MTU_SIZE,
323 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
324 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
327 REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
329 /* disable the NIG in/out to the bmac */
330 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
331 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
332 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
334 /* enable the NIG in/out to the emac */
335 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
337 if (vars->flow_ctrl & FLOW_CTRL_TX)
340 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
341 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
343 if (CHIP_REV_IS_EMUL(bp)) {
344 /* take the BigMac out of reset */
346 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
347 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
349 /* enable access for bmac registers */
350 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
353 vars->mac_type = MAC_TYPE_EMAC;
359 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
362 struct bnx2x *bp = params->bp;
363 u8 port = params->port;
364 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
365 NIG_REG_INGRESS_BMAC0_MEM;
369 DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
370 /* reset and unreset the BigMac */
371 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
372 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
375 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
376 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
378 /* enable access for bmac registers */
379 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
384 REG_WR_DMAE(bp, bmac_addr +
385 BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
389 wb_data[0] = ((params->mac_addr[2] << 24) |
390 (params->mac_addr[3] << 16) |
391 (params->mac_addr[4] << 8) |
392 params->mac_addr[5]);
393 wb_data[1] = ((params->mac_addr[0] << 8) |
394 params->mac_addr[1]);
395 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
400 if (vars->flow_ctrl & FLOW_CTRL_TX)
404 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
411 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
415 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
420 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
422 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
425 /* rx control set to don't strip crc */
427 if (vars->flow_ctrl & FLOW_CTRL_RX)
431 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
435 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
437 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
440 /* set cnt max size */
441 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
443 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
447 wb_data[0] = 0x1000200;
449 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
451 /* fix for emulation */
452 if (CHIP_REV_IS_EMUL(bp)) {
456 bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
460 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
461 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
462 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
464 if (vars->flow_ctrl & FLOW_CTRL_TX)
466 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
467 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
468 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
469 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
470 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
471 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
473 vars->mac_type = MAC_TYPE_BMAC;
477 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
479 struct bnx2x *bp = params->bp;
482 if (phy_flags & PHY_XGXS_FLAG) {
483 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
484 val = XGXS_RESET_BITS;
486 } else { /* SerDes */
487 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
488 val = SERDES_RESET_BITS;
491 val = val << (params->port*16);
493 /* reset and unreset the SerDes/XGXS */
494 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
497 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
499 bnx2x_set_phy_mdio(params);
502 void bnx2x_link_status_update(struct link_params *params,
503 struct link_vars *vars)
505 struct bnx2x *bp = params->bp;
507 u8 port = params->port;
509 if (params->switch_cfg == SWITCH_CFG_1G)
510 vars->phy_flags = PHY_SERDES_FLAG;
512 vars->phy_flags = PHY_XGXS_FLAG;
513 vars->link_status = REG_RD(bp, params->shmem_base +
514 offsetof(struct shmem_region,
515 port_mb[port].link_status));
517 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
520 DP(NETIF_MSG_LINK, "phy link up\n");
522 vars->phy_link_up = 1;
523 vars->duplex = DUPLEX_FULL;
524 switch (vars->link_status &
525 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
527 vars->duplex = DUPLEX_HALF;
530 vars->line_speed = SPEED_10;
534 vars->duplex = DUPLEX_HALF;
538 vars->line_speed = SPEED_100;
542 vars->duplex = DUPLEX_HALF;
545 vars->line_speed = SPEED_1000;
549 vars->duplex = DUPLEX_HALF;
552 vars->line_speed = SPEED_2500;
556 vars->line_speed = SPEED_10000;
560 vars->line_speed = SPEED_12000;
564 vars->line_speed = SPEED_12500;
568 vars->line_speed = SPEED_13000;
572 vars->line_speed = SPEED_15000;
576 vars->line_speed = SPEED_16000;
583 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
584 vars->flow_ctrl |= FLOW_CTRL_TX;
586 vars->flow_ctrl &= ~FLOW_CTRL_TX;
588 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
589 vars->flow_ctrl |= FLOW_CTRL_RX;
591 vars->flow_ctrl &= ~FLOW_CTRL_RX;
593 if (vars->phy_flags & PHY_XGXS_FLAG) {
594 if (params->req_line_speed &&
595 ((params->req_line_speed == SPEED_10) ||
596 (params->req_line_speed == SPEED_100))) {
597 vars->phy_flags |= PHY_SGMII_FLAG;
599 vars->phy_flags &= ~PHY_SGMII_FLAG;
603 /* anything 10 and over uses the bmac */
604 link_10g = ((vars->line_speed == SPEED_10000) ||
605 (vars->line_speed == SPEED_12000) ||
606 (vars->line_speed == SPEED_12500) ||
607 (vars->line_speed == SPEED_13000) ||
608 (vars->line_speed == SPEED_15000) ||
609 (vars->line_speed == SPEED_16000));
611 vars->mac_type = MAC_TYPE_BMAC;
613 vars->mac_type = MAC_TYPE_EMAC;
615 } else { /* link down */
616 DP(NETIF_MSG_LINK, "phy link down\n");
618 vars->phy_link_up = 0;
620 vars->line_speed = 0;
621 vars->duplex = DUPLEX_FULL;
622 vars->flow_ctrl = FLOW_CTRL_NONE;
624 /* indicate no mac active */
625 vars->mac_type = MAC_TYPE_NONE;
628 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
629 vars->link_status, vars->phy_link_up);
630 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
631 vars->line_speed, vars->duplex, vars->flow_ctrl);
634 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
636 struct bnx2x *bp = params->bp;
637 REG_WR(bp, params->shmem_base +
638 offsetof(struct shmem_region,
639 port_mb[params->port].link_status),
643 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
645 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
646 NIG_REG_INGRESS_BMAC0_MEM;
648 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
650 /* Only if the bmac is out of reset */
651 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
652 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
655 /* Clear Rx Enable bit in BMAC_CONTROL register */
656 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
658 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
659 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
666 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
669 struct bnx2x *bp = params->bp;
670 u8 port = params->port;
676 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
678 /* wait for init credit */
679 init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
680 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
681 DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
683 while ((init_crd != crd) && count) {
686 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
689 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
690 if (init_crd != crd) {
691 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
696 if (flow_ctrl & FLOW_CTRL_RX)
698 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, pause);
700 /* update threshold */
701 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
702 /* update init credit */
703 init_crd = 778; /* (800-18-4) */
706 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
709 /* update threshold */
710 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
711 /* update init credit */
712 switch (line_speed) {
716 init_crd = thresh + 55 - 22;
720 init_crd = thresh + 138 - 22;
724 init_crd = thresh + 553 - 22;
728 init_crd = thresh + 664 - 22;
732 init_crd = thresh + 742 - 22;
736 init_crd = thresh + 778 - 22;
739 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
745 REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
746 DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
747 line_speed, init_crd);
749 /* probe the credit changes */
750 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
752 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
755 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
759 static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port)
762 switch (ext_phy_type) {
763 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
764 emac_base = GRCBASE_EMAC0;
766 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
767 emac_base = (port) ? GRCBASE_EMAC0: GRCBASE_EMAC1;
770 emac_base = (port) ? GRCBASE_EMAC1: GRCBASE_EMAC0;
777 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
778 u8 phy_addr, u8 devad, u16 reg, u16 val)
782 u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
784 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
785 * (a value of 49==0x31) and make sure that the AUTO poll is off
787 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
788 tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
789 EMAC_MDIO_MODE_CLOCK_CNT);
790 tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
791 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
792 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
793 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
798 tmp = ((phy_addr << 21) | (devad << 16) | reg |
799 EMAC_MDIO_COMM_COMMAND_ADDRESS |
800 EMAC_MDIO_COMM_START_BUSY);
801 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
803 for (i = 0; i < 50; i++) {
806 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
807 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
812 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
813 DP(NETIF_MSG_LINK, "write phy register failed\n");
817 tmp = ((phy_addr << 21) | (devad << 16) | val |
818 EMAC_MDIO_COMM_COMMAND_WRITE_45 |
819 EMAC_MDIO_COMM_START_BUSY);
820 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
822 for (i = 0; i < 50; i++) {
825 tmp = REG_RD(bp, mdio_ctrl +
826 EMAC_REG_EMAC_MDIO_COMM);
827 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
832 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
833 DP(NETIF_MSG_LINK, "write phy register failed\n");
838 /* Restore the saved mode */
839 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
844 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
845 u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
851 u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
852 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
853 * (a value of 49==0x31) and make sure that the AUTO poll is off
855 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
856 val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
857 EMAC_MDIO_MODE_CLOCK_CNT));
858 val |= (EMAC_MDIO_MODE_CLAUSE_45 |
859 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
860 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
861 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
865 val = ((phy_addr << 21) | (devad << 16) | reg |
866 EMAC_MDIO_COMM_COMMAND_ADDRESS |
867 EMAC_MDIO_COMM_START_BUSY);
868 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
870 for (i = 0; i < 50; i++) {
873 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
874 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
879 if (val & EMAC_MDIO_COMM_START_BUSY) {
880 DP(NETIF_MSG_LINK, "read phy register failed\n");
887 val = ((phy_addr << 21) | (devad << 16) |
888 EMAC_MDIO_COMM_COMMAND_READ_45 |
889 EMAC_MDIO_COMM_START_BUSY);
890 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
892 for (i = 0; i < 50; i++) {
895 val = REG_RD(bp, mdio_ctrl +
896 EMAC_REG_EMAC_MDIO_COMM);
897 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
898 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
902 if (val & EMAC_MDIO_COMM_START_BUSY) {
903 DP(NETIF_MSG_LINK, "read phy register failed\n");
910 /* Restore the saved mode */
911 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
916 static void bnx2x_set_aer_mmd(struct link_params *params,
917 struct link_vars *vars)
919 struct bnx2x *bp = params->bp;
923 ser_lane = ((params->lane_config &
924 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
925 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
927 offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
928 (params->phy_addr + ser_lane) : 0;
930 CL45_WR_OVER_CL22(bp, params->port,
932 MDIO_REG_BANK_AER_BLOCK,
933 MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
936 static void bnx2x_set_master_ln(struct link_params *params)
938 struct bnx2x *bp = params->bp;
939 u16 new_master_ln, ser_lane;
940 ser_lane = ((params->lane_config &
941 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
942 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
944 /* set the master_ln for AN */
945 CL45_RD_OVER_CL22(bp, params->port,
947 MDIO_REG_BANK_XGXS_BLOCK2,
948 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
951 CL45_WR_OVER_CL22(bp, params->port,
953 MDIO_REG_BANK_XGXS_BLOCK2 ,
954 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
955 (new_master_ln | ser_lane));
958 static u8 bnx2x_reset_unicore(struct link_params *params)
960 struct bnx2x *bp = params->bp;
964 CL45_RD_OVER_CL22(bp, params->port,
966 MDIO_REG_BANK_COMBO_IEEE0,
967 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
969 /* reset the unicore */
970 CL45_WR_OVER_CL22(bp, params->port,
972 MDIO_REG_BANK_COMBO_IEEE0,
973 MDIO_COMBO_IEEE0_MII_CONTROL,
975 MDIO_COMBO_IEEO_MII_CONTROL_RESET));
977 /* wait for the reset to self clear */
978 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
981 /* the reset erased the previous bank value */
982 CL45_RD_OVER_CL22(bp, params->port,
984 MDIO_REG_BANK_COMBO_IEEE0,
985 MDIO_COMBO_IEEE0_MII_CONTROL,
988 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
994 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
999 static void bnx2x_set_swap_lanes(struct link_params *params)
1001 struct bnx2x *bp = params->bp;
1002 /* Each two bits represents a lane number:
1003 No swap is 0123 => 0x1b no need to enable the swap */
1004 u16 ser_lane, rx_lane_swap, tx_lane_swap;
1006 ser_lane = ((params->lane_config &
1007 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1008 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1009 rx_lane_swap = ((params->lane_config &
1010 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1011 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1012 tx_lane_swap = ((params->lane_config &
1013 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1014 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1016 if (rx_lane_swap != 0x1b) {
1017 CL45_WR_OVER_CL22(bp, params->port,
1019 MDIO_REG_BANK_XGXS_BLOCK2,
1020 MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1022 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1023 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1025 CL45_WR_OVER_CL22(bp, params->port,
1027 MDIO_REG_BANK_XGXS_BLOCK2,
1028 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1031 if (tx_lane_swap != 0x1b) {
1032 CL45_WR_OVER_CL22(bp, params->port,
1034 MDIO_REG_BANK_XGXS_BLOCK2,
1035 MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1037 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1039 CL45_WR_OVER_CL22(bp, params->port,
1041 MDIO_REG_BANK_XGXS_BLOCK2,
1042 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1046 static void bnx2x_set_parallel_detection(struct link_params *params,
1049 struct bnx2x *bp = params->bp;
1052 CL45_RD_OVER_CL22(bp, params->port,
1054 MDIO_REG_BANK_SERDES_DIGITAL,
1055 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1059 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1062 CL45_WR_OVER_CL22(bp, params->port,
1064 MDIO_REG_BANK_SERDES_DIGITAL,
1065 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1068 if (phy_flags & PHY_XGXS_FLAG) {
1069 DP(NETIF_MSG_LINK, "XGXS\n");
1071 CL45_WR_OVER_CL22(bp, params->port,
1073 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1074 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1075 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1077 CL45_RD_OVER_CL22(bp, params->port,
1079 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1080 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1085 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1087 CL45_WR_OVER_CL22(bp, params->port,
1089 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1090 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1093 /* Disable parallel detection of HiG */
1094 CL45_WR_OVER_CL22(bp, params->port,
1096 MDIO_REG_BANK_XGXS_BLOCK2,
1097 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1098 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1099 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1103 static void bnx2x_set_autoneg(struct link_params *params,
1104 struct link_vars *vars)
1106 struct bnx2x *bp = params->bp;
1111 CL45_RD_OVER_CL22(bp, params->port,
1113 MDIO_REG_BANK_COMBO_IEEE0,
1114 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
1116 /* CL37 Autoneg Enabled */
1117 if (params->req_line_speed == SPEED_AUTO_NEG)
1118 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1119 else /* CL37 Autoneg Disabled */
1120 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1121 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1123 CL45_WR_OVER_CL22(bp, params->port,
1125 MDIO_REG_BANK_COMBO_IEEE0,
1126 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1128 /* Enable/Disable Autodetection */
1130 CL45_RD_OVER_CL22(bp, params->port,
1132 MDIO_REG_BANK_SERDES_DIGITAL,
1133 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val);
1134 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1135 if (params->req_line_speed == SPEED_AUTO_NEG)
1136 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1138 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1140 CL45_WR_OVER_CL22(bp, params->port,
1142 MDIO_REG_BANK_SERDES_DIGITAL,
1143 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1145 /* Enable TetonII and BAM autoneg */
1146 CL45_RD_OVER_CL22(bp, params->port,
1148 MDIO_REG_BANK_BAM_NEXT_PAGE,
1149 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1151 if (params->req_line_speed == SPEED_AUTO_NEG) {
1152 /* Enable BAM aneg Mode and TetonII aneg Mode */
1153 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1154 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1156 /* TetonII and BAM Autoneg Disabled */
1157 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1158 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1160 CL45_WR_OVER_CL22(bp, params->port,
1162 MDIO_REG_BANK_BAM_NEXT_PAGE,
1163 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1166 /* Enable Clause 73 Aneg */
1167 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1169 /* Enable BAM Station Manager */
1171 CL45_WR_OVER_CL22(bp, params->port,
1173 MDIO_REG_BANK_CL73_USERB0,
1174 MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1175 (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1176 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1177 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
1179 /* Merge CL73 and CL37 aneg resolution */
1180 CL45_RD_OVER_CL22(bp, params->port,
1182 MDIO_REG_BANK_CL73_USERB0,
1183 MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1186 CL45_WR_OVER_CL22(bp, params->port,
1188 MDIO_REG_BANK_CL73_USERB0,
1189 MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1191 MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
1193 /* Set the CL73 AN speed */
1195 CL45_RD_OVER_CL22(bp, params->port,
1197 MDIO_REG_BANK_CL73_IEEEB1,
1198 MDIO_CL73_IEEEB1_AN_ADV2, ®_val);
1199 /* In the SerDes we support only the 1G.
1200 In the XGXS we support the 10G KX4
1201 but we currently do not support the KR */
1202 if (vars->phy_flags & PHY_XGXS_FLAG) {
1203 DP(NETIF_MSG_LINK, "XGXS\n");
1205 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1207 DP(NETIF_MSG_LINK, "SerDes\n");
1209 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1211 CL45_WR_OVER_CL22(bp, params->port,
1213 MDIO_REG_BANK_CL73_IEEEB1,
1214 MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
1216 /* CL73 Autoneg Enabled */
1217 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
1219 /* CL73 Autoneg Disabled */
1222 CL45_WR_OVER_CL22(bp, params->port,
1224 MDIO_REG_BANK_CL73_IEEEB0,
1225 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1228 /* program SerDes, forced speed */
1229 static void bnx2x_program_serdes(struct link_params *params)
1231 struct bnx2x *bp = params->bp;
1234 /* program duplex, disable autoneg */
1236 CL45_RD_OVER_CL22(bp, params->port,
1238 MDIO_REG_BANK_COMBO_IEEE0,
1239 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
1240 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1241 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
1242 if (params->req_duplex == DUPLEX_FULL)
1243 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1244 CL45_WR_OVER_CL22(bp, params->port,
1246 MDIO_REG_BANK_COMBO_IEEE0,
1247 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1250 - needed only if the speed is greater than 1G (2.5G or 10G) */
1251 if (!((params->req_line_speed == SPEED_1000) ||
1252 (params->req_line_speed == SPEED_100) ||
1253 (params->req_line_speed == SPEED_10))) {
1254 CL45_RD_OVER_CL22(bp, params->port,
1256 MDIO_REG_BANK_SERDES_DIGITAL,
1257 MDIO_SERDES_DIGITAL_MISC1, ®_val);
1258 /* clearing the speed value before setting the right speed */
1259 reg_val &= ~MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK;
1260 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1261 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1262 if (params->req_line_speed == SPEED_10000)
1264 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1265 if (params->req_line_speed == SPEED_13000)
1267 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1268 CL45_WR_OVER_CL22(bp, params->port,
1270 MDIO_REG_BANK_SERDES_DIGITAL,
1271 MDIO_SERDES_DIGITAL_MISC1, reg_val);
1275 static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1277 struct bnx2x *bp = params->bp;
1280 /* configure the 48 bits for BAM AN */
1282 /* set extended capabilities */
1283 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1284 val |= MDIO_OVER_1G_UP1_2_5G;
1285 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1286 val |= MDIO_OVER_1G_UP1_10G;
1287 CL45_WR_OVER_CL22(bp, params->port,
1289 MDIO_REG_BANK_OVER_1G,
1290 MDIO_OVER_1G_UP1, val);
1292 CL45_WR_OVER_CL22(bp, params->port,
1294 MDIO_REG_BANK_OVER_1G,
1295 MDIO_OVER_1G_UP3, 0);
1298 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1301 struct bnx2x *bp = params->bp;
1302 /* for AN, we are always publishing full duplex */
1303 u16 an_adv = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1305 /* resolve pause mode and advertisement
1306 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1308 switch (params->req_flow_ctrl) {
1309 case FLOW_CTRL_AUTO:
1310 if (params->mtu <= MAX_MTU_SIZE) {
1312 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1315 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1320 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1324 case FLOW_CTRL_BOTH:
1325 an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1328 case FLOW_CTRL_NONE:
1330 an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1336 CL45_WR_OVER_CL22(bp, params->port,
1338 MDIO_REG_BANK_COMBO_IEEE0,
1339 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, an_adv);
1342 static void bnx2x_restart_autoneg(struct link_params *params)
1344 struct bnx2x *bp = params->bp;
1345 DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1347 /* enable and restart clause 73 aneg */
1350 CL45_RD_OVER_CL22(bp, params->port,
1352 MDIO_REG_BANK_CL73_IEEEB0,
1353 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1355 CL45_WR_OVER_CL22(bp, params->port,
1357 MDIO_REG_BANK_CL73_IEEEB0,
1358 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1360 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1361 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1364 /* Enable and restart BAM/CL37 aneg */
1367 CL45_RD_OVER_CL22(bp, params->port,
1369 MDIO_REG_BANK_COMBO_IEEE0,
1370 MDIO_COMBO_IEEE0_MII_CONTROL,
1373 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1375 CL45_WR_OVER_CL22(bp, params->port,
1377 MDIO_REG_BANK_COMBO_IEEE0,
1378 MDIO_COMBO_IEEE0_MII_CONTROL,
1380 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1381 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1385 static void bnx2x_initialize_sgmii_process(struct link_params *params)
1387 struct bnx2x *bp = params->bp;
1390 /* in SGMII mode, the unicore is always slave */
1392 CL45_RD_OVER_CL22(bp, params->port,
1394 MDIO_REG_BANK_SERDES_DIGITAL,
1395 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1397 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1398 /* set sgmii mode (and not fiber) */
1399 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1400 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1401 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1402 CL45_WR_OVER_CL22(bp, params->port,
1404 MDIO_REG_BANK_SERDES_DIGITAL,
1405 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1408 /* if forced speed */
1409 if (!(params->req_line_speed == SPEED_AUTO_NEG)) {
1410 /* set speed, disable autoneg */
1413 CL45_RD_OVER_CL22(bp, params->port,
1415 MDIO_REG_BANK_COMBO_IEEE0,
1416 MDIO_COMBO_IEEE0_MII_CONTROL,
1418 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1419 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1420 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1422 switch (params->req_line_speed) {
1425 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1429 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1432 /* there is nothing to set for 10M */
1435 /* invalid speed for SGMII */
1436 DP(NETIF_MSG_LINK, "Invalid req_line_speed 0x%x\n",
1437 params->req_line_speed);
1441 /* setting the full duplex */
1442 if (params->req_duplex == DUPLEX_FULL)
1444 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1445 CL45_WR_OVER_CL22(bp, params->port,
1447 MDIO_REG_BANK_COMBO_IEEE0,
1448 MDIO_COMBO_IEEE0_MII_CONTROL,
1451 } else { /* AN mode */
1452 /* enable and restart AN */
1453 bnx2x_restart_autoneg(params);
1462 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1464 switch (pause_result) { /* ASYM P ASYM P */
1465 case 0xb: /* 1 0 1 1 */
1466 vars->flow_ctrl = FLOW_CTRL_TX;
1469 case 0xe: /* 1 1 1 0 */
1470 vars->flow_ctrl = FLOW_CTRL_RX;
1473 case 0x5: /* 0 1 0 1 */
1474 case 0x7: /* 0 1 1 1 */
1475 case 0xd: /* 1 1 0 1 */
1476 case 0xf: /* 1 1 1 1 */
1477 vars->flow_ctrl = FLOW_CTRL_BOTH;
1485 static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1486 struct link_vars *vars)
1488 struct bnx2x *bp = params->bp;
1490 u16 ld_pause; /* local */
1491 u16 lp_pause; /* link partner */
1492 u16 an_complete; /* AN complete */
1496 u8 port = params->port;
1497 ext_phy_addr = ((params->ext_phy_config &
1498 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1499 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1501 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1504 bnx2x_cl45_read(bp, port,
1508 MDIO_AN_REG_STATUS, &an_complete);
1509 bnx2x_cl45_read(bp, port,
1513 MDIO_AN_REG_STATUS, &an_complete);
1515 if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1517 bnx2x_cl45_read(bp, port,
1521 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1522 bnx2x_cl45_read(bp, port,
1526 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1527 pause_result = (ld_pause &
1528 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1529 pause_result |= (lp_pause &
1530 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1531 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1533 bnx2x_pause_resolve(vars, pause_result);
1539 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1540 struct link_vars *vars,
1543 struct bnx2x *bp = params->bp;
1544 u16 ld_pause; /* local driver */
1545 u16 lp_pause; /* link partner */
1548 vars->flow_ctrl = FLOW_CTRL_NONE;
1550 /* resolve from gp_status in case of AN complete and not sgmii */
1551 if ((params->req_flow_ctrl == FLOW_CTRL_AUTO) &&
1552 (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1553 (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1554 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1555 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1556 CL45_RD_OVER_CL22(bp, params->port,
1558 MDIO_REG_BANK_COMBO_IEEE0,
1559 MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1561 CL45_RD_OVER_CL22(bp, params->port,
1563 MDIO_REG_BANK_COMBO_IEEE0,
1564 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1566 pause_result = (ld_pause &
1567 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1568 pause_result |= (lp_pause &
1569 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1570 DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1571 bnx2x_pause_resolve(vars, pause_result);
1572 } else if ((params->req_flow_ctrl == FLOW_CTRL_AUTO) &&
1573 (bnx2x_ext_phy_resove_fc(params, vars))) {
1576 vars->flow_ctrl = params->req_flow_ctrl;
1577 if (vars->flow_ctrl == FLOW_CTRL_AUTO) {
1578 if (params->mtu <= MAX_MTU_SIZE)
1579 vars->flow_ctrl = FLOW_CTRL_BOTH;
1581 vars->flow_ctrl = FLOW_CTRL_TX;
1584 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1588 static u8 bnx2x_link_settings_status(struct link_params *params,
1589 struct link_vars *vars,
1592 struct bnx2x *bp = params->bp;
1594 vars->link_status = 0;
1596 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1597 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1600 vars->phy_link_up = 1;
1601 vars->link_status |= LINK_STATUS_LINK_UP;
1603 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1604 vars->duplex = DUPLEX_FULL;
1606 vars->duplex = DUPLEX_HALF;
1608 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1610 switch (gp_status & GP_STATUS_SPEED_MASK) {
1612 vars->line_speed = SPEED_10;
1613 if (vars->duplex == DUPLEX_FULL)
1614 vars->link_status |= LINK_10TFD;
1616 vars->link_status |= LINK_10THD;
1619 case GP_STATUS_100M:
1620 vars->line_speed = SPEED_100;
1621 if (vars->duplex == DUPLEX_FULL)
1622 vars->link_status |= LINK_100TXFD;
1624 vars->link_status |= LINK_100TXHD;
1628 case GP_STATUS_1G_KX:
1629 vars->line_speed = SPEED_1000;
1630 if (vars->duplex == DUPLEX_FULL)
1631 vars->link_status |= LINK_1000TFD;
1633 vars->link_status |= LINK_1000THD;
1636 case GP_STATUS_2_5G:
1637 vars->line_speed = SPEED_2500;
1638 if (vars->duplex == DUPLEX_FULL)
1639 vars->link_status |= LINK_2500TFD;
1641 vars->link_status |= LINK_2500THD;
1647 "link speed unsupported gp_status 0x%x\n",
1651 case GP_STATUS_10G_KX4:
1652 case GP_STATUS_10G_HIG:
1653 case GP_STATUS_10G_CX4:
1654 vars->line_speed = SPEED_10000;
1655 vars->link_status |= LINK_10GTFD;
1658 case GP_STATUS_12G_HIG:
1659 vars->line_speed = SPEED_12000;
1660 vars->link_status |= LINK_12GTFD;
1663 case GP_STATUS_12_5G:
1664 vars->line_speed = SPEED_12500;
1665 vars->link_status |= LINK_12_5GTFD;
1669 vars->line_speed = SPEED_13000;
1670 vars->link_status |= LINK_13GTFD;
1674 vars->line_speed = SPEED_15000;
1675 vars->link_status |= LINK_15GTFD;
1679 vars->line_speed = SPEED_16000;
1680 vars->link_status |= LINK_16GTFD;
1685 "link speed unsupported gp_status 0x%x\n",
1691 vars->link_status |= LINK_STATUS_SERDES_LINK;
1693 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1694 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1695 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1696 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1697 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) {
1698 vars->autoneg = AUTO_NEG_ENABLED;
1700 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1701 vars->autoneg |= AUTO_NEG_COMPLETE;
1702 vars->link_status |=
1703 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1706 vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1707 vars->link_status |=
1708 LINK_STATUS_PARALLEL_DETECTION_USED;
1711 if (vars->flow_ctrl & FLOW_CTRL_TX)
1712 vars->link_status |=
1713 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1715 if (vars->flow_ctrl & FLOW_CTRL_RX)
1716 vars->link_status |=
1717 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1719 } else { /* link_down */
1720 DP(NETIF_MSG_LINK, "phy link down\n");
1722 vars->phy_link_up = 0;
1724 vars->duplex = DUPLEX_FULL;
1725 vars->flow_ctrl = FLOW_CTRL_NONE;
1726 vars->autoneg = AUTO_NEG_DISABLED;
1727 vars->mac_type = MAC_TYPE_NONE;
1730 DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x \n",
1731 gp_status, vars->phy_link_up, vars->line_speed);
1732 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x"
1735 vars->flow_ctrl, vars->autoneg);
1736 DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1741 static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
1743 struct bnx2x *bp = params->bp;
1749 CL45_RD_OVER_CL22(bp, params->port,
1751 MDIO_REG_BANK_OVER_1G,
1752 MDIO_OVER_1G_LP_UP2, &lp_up2);
1754 CL45_RD_OVER_CL22(bp, params->port,
1757 MDIO_TX0_TX_DRIVER, &tx_driver);
1759 /* bits [10:7] at lp_up2, positioned at [15:12] */
1760 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1761 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1762 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1764 if ((lp_up2 != 0) &&
1765 (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
1766 /* replace tx_driver bits [15:12] */
1767 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1768 tx_driver |= lp_up2;
1769 CL45_WR_OVER_CL22(bp, params->port,
1772 MDIO_TX0_TX_DRIVER, tx_driver);
1776 static u8 bnx2x_emac_program(struct link_params *params,
1777 u32 line_speed, u32 duplex)
1779 struct bnx2x *bp = params->bp;
1780 u8 port = params->port;
1783 DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1784 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1786 (EMAC_MODE_25G_MODE |
1787 EMAC_MODE_PORT_MII_10M |
1788 EMAC_MODE_HALF_DUPLEX));
1789 switch (line_speed) {
1791 mode |= EMAC_MODE_PORT_MII_10M;
1795 mode |= EMAC_MODE_PORT_MII;
1799 mode |= EMAC_MODE_PORT_GMII;
1803 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1807 /* 10G not valid for EMAC */
1808 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1812 if (duplex == DUPLEX_HALF)
1813 mode |= EMAC_MODE_HALF_DUPLEX;
1815 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1818 bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1819 line_speed, params->hw_led_mode, params->chip_id);
1823 /*****************************************************************************/
1824 /* External Phy section */
1825 /*****************************************************************************/
1826 static void bnx2x_hw_reset(struct bnx2x *bp)
1828 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1829 MISC_REGISTERS_GPIO_OUTPUT_LOW);
1831 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1832 MISC_REGISTERS_GPIO_OUTPUT_HIGH);
1835 static void bnx2x_ext_phy_reset(struct link_params *params,
1836 struct link_vars *vars)
1838 struct bnx2x *bp = params->bp;
1840 u8 ext_phy_addr = ((params->ext_phy_config &
1841 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1842 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1843 DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1844 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1845 /* The PHY reset is controled by GPIO 1
1846 * Give it 1ms of reset pulse
1848 if (vars->phy_flags & PHY_XGXS_FLAG) {
1850 switch (ext_phy_type) {
1851 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1852 DP(NETIF_MSG_LINK, "XGXS Direct\n");
1855 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1856 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1857 DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1859 /* Restore normal power mode*/
1860 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1861 MISC_REGISTERS_GPIO_OUTPUT_HIGH);
1866 bnx2x_cl45_write(bp, params->port,
1870 MDIO_PMA_REG_CTRL, 0xa040);
1872 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1873 /* Unset Low Power Mode and SW reset */
1874 /* Restore normal power mode*/
1875 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1876 MISC_REGISTERS_GPIO_OUTPUT_HIGH);
1878 DP(NETIF_MSG_LINK, "XGXS 8072\n");
1879 bnx2x_cl45_write(bp, params->port,
1886 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1889 emac_base = (params->port) ? GRCBASE_EMAC0 :
1892 /* Restore normal power mode*/
1893 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1894 MISC_REGISTERS_GPIO_OUTPUT_HIGH);
1896 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1897 MISC_REGISTERS_GPIO_OUTPUT_HIGH);
1899 DP(NETIF_MSG_LINK, "XGXS 8073\n");
1900 bnx2x_cl45_write(bp,
1910 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1911 DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1913 /* Restore normal power mode*/
1914 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1915 MISC_REGISTERS_GPIO_OUTPUT_HIGH);
1922 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
1923 DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
1927 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
1928 params->ext_phy_config);
1932 } else { /* SerDes */
1933 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
1934 switch (ext_phy_type) {
1935 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
1936 DP(NETIF_MSG_LINK, "SerDes Direct\n");
1939 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
1940 DP(NETIF_MSG_LINK, "SerDes 5482\n");
1946 "BAD SerDes ext_phy_config 0x%x\n",
1947 params->ext_phy_config);
1953 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
1955 struct bnx2x *bp = params->bp;
1956 u8 port = params->port;
1957 u8 ext_phy_addr = ((params->ext_phy_config &
1958 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1959 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1960 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1961 u16 fw_ver1, fw_ver2;
1963 /* Need to wait 200ms after reset */
1965 /* Boot port from external ROM
1966 * Set ser_boot_ctl bit in the MISC_CTRL1 register
1968 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1970 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
1972 /* Reset internal microprocessor */
1973 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1975 MDIO_PMA_REG_GEN_CTRL,
1976 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
1977 /* set micro reset = 0 */
1978 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1980 MDIO_PMA_REG_GEN_CTRL,
1981 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
1982 /* Reset internal microprocessor */
1983 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1985 MDIO_PMA_REG_GEN_CTRL,
1986 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
1987 /* wait for 100ms for code download via SPI port */
1990 /* Clear ser_boot_ctl bit */
1991 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1993 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
1997 /* Print the PHY FW version */
1998 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2000 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2001 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2003 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2004 DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2007 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2009 /* This is only required for 8073A1, version 102 only */
2011 struct bnx2x *bp = params->bp;
2012 u8 ext_phy_addr = ((params->ext_phy_config &
2013 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2014 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2017 /* Read 8073 HW revision*/
2018 bnx2x_cl45_read(bp, params->port,
2019 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2025 /* No need to workaround in 8073 A1 */
2029 bnx2x_cl45_read(bp, params->port,
2030 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2033 MDIO_PMA_REG_ROM_VER2, &val);
2035 /* SNR should be applied only for version 0x102 */
2042 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2044 struct bnx2x *bp = params->bp;
2045 u8 ext_phy_addr = ((params->ext_phy_config &
2046 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2047 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2048 u16 val, cnt, cnt1 ;
2050 bnx2x_cl45_read(bp, params->port,
2051 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2057 /* No need to workaround in 8073 A1 */
2060 /* XAUI workaround in 8073 A0: */
2062 /* After loading the boot ROM and restarting Autoneg,
2063 poll Dev1, Reg $C820: */
2065 for (cnt = 0; cnt < 1000; cnt++) {
2066 bnx2x_cl45_read(bp, params->port,
2067 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2071 /* If bit [14] = 0 or bit [13] = 0, continue on with
2072 system initialization (XAUI work-around not required,
2073 as these bits indicate 2.5G or 1G link up). */
2074 if (!(val & (1<<14)) || !(val & (1<<13))) {
2075 DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2077 } else if (!(val & (1<<15))) {
2078 DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2079 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2080 it's MSB (bit 15) goes to 1 (indicating that the
2081 XAUI workaround has completed),
2082 then continue on with system initialization.*/
2083 for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2084 bnx2x_cl45_read(bp, params->port,
2085 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2089 if (val & (1<<15)) {
2091 "XAUI workaround has completed\n");
2100 DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2105 static void bnx2x_bcm8073_external_rom_boot(struct link_params *params)
2107 struct bnx2x *bp = params->bp;
2108 u8 port = params->port;
2109 u8 ext_phy_addr = ((params->ext_phy_config &
2110 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2111 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2112 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2113 u16 fw_ver1, fw_ver2, val;
2114 /* Need to wait 100ms after reset */
2116 /* Boot port from external ROM */
2118 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2120 MDIO_PMA_REG_GEN_CTRL,
2123 /* ucode reboot and rst */
2124 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2126 MDIO_PMA_REG_GEN_CTRL,
2129 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2131 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2133 /* Reset internal microprocessor */
2134 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2136 MDIO_PMA_REG_GEN_CTRL,
2137 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2139 /* Release srst bit */
2140 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2142 MDIO_PMA_REG_GEN_CTRL,
2143 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2145 /* wait for 100ms for code download via SPI port */
2148 /* Clear ser_boot_ctl bit */
2149 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2151 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2153 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2155 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2156 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2158 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2159 DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2161 /* Only set bit 10 = 1 (Tx power down) */
2162 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2164 MDIO_PMA_REG_TX_POWER_DOWN, &val);
2166 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2168 MDIO_PMA_REG_TX_POWER_DOWN, (val | 1<<10));
2171 /* Release bit 10 (Release Tx power down) */
2172 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2174 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
2178 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2180 struct bnx2x *bp = params->bp;
2181 u8 port = params->port;
2183 u8 ext_phy_addr = ((params->ext_phy_config &
2184 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2185 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2186 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2188 bnx2x_cl45_read(bp, params->port,
2189 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2195 /* Mustn't set low power mode in 8073 A0 */
2199 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2200 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2202 MDIO_XS_PLL_SEQUENCER, &val);
2204 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2205 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2208 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2209 MDIO_XS_DEVAD, 0x805E, 0x1077);
2210 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2211 MDIO_XS_DEVAD, 0x805D, 0x0000);
2212 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2213 MDIO_XS_DEVAD, 0x805C, 0x030B);
2214 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2215 MDIO_XS_DEVAD, 0x805B, 0x1240);
2216 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2217 MDIO_XS_DEVAD, 0x805A, 0x2490);
2220 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2221 MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2222 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2223 MDIO_XS_DEVAD, 0x80A6, 0x9041);
2224 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2225 MDIO_XS_DEVAD, 0x80A5, 0x4640);
2228 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2229 MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2230 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2231 MDIO_XS_DEVAD, 0x80FD, 0x9249);
2232 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2233 MDIO_XS_DEVAD, 0x80FC, 0x2015);
2235 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
2236 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2238 MDIO_XS_PLL_SEQUENCER, &val);
2240 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2241 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2243 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2245 struct bnx2x *bp = params->bp;
2246 u8 port = params->port;
2247 u8 ext_phy_addr = ((params->ext_phy_config &
2248 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2249 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2250 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2252 /* Force KR or KX */
2253 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2257 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2259 MDIO_PMA_REG_10G_CTRL2,
2261 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2263 MDIO_PMA_REG_BCM_CTRL,
2265 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2271 static void bnx2x_ext_phy_set_pause(struct link_params *params,
2272 struct link_vars *vars)
2274 struct bnx2x *bp = params->bp;
2276 u8 ext_phy_addr = ((params->ext_phy_config &
2277 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2278 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2279 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2281 /* read modify write pause advertizing */
2282 bnx2x_cl45_read(bp, params->port,
2286 MDIO_AN_REG_ADV_PAUSE, &val);
2288 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2289 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2292 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2293 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2296 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2298 MDIO_AN_REG_ADV_PAUSE_PAUSE;
2301 "Ext phy AN advertize 0x%x\n", val);
2302 bnx2x_cl45_write(bp, params->port,
2306 MDIO_AN_REG_ADV_PAUSE, val);
2310 static void bnx2x_init_internal_phy(struct link_params *params,
2311 struct link_vars *vars)
2313 struct bnx2x *bp = params->bp;
2314 u8 port = params->port;
2315 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2318 rx_eq = ((params->serdes_config &
2319 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2320 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2322 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2323 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2324 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2325 CL45_WR_OVER_CL22(bp, port,
2328 MDIO_RX0_RX_EQ_BOOST,
2330 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2331 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2334 /* forced speed requested? */
2335 if (vars->line_speed != SPEED_AUTO_NEG) {
2336 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2338 /* disable autoneg */
2339 bnx2x_set_autoneg(params, vars);
2341 /* program speed and duplex */
2342 bnx2x_program_serdes(params);
2344 } else { /* AN_mode */
2345 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2348 bnx2x_set_brcm_cl37_advertisment(params);
2350 /* program duplex & pause advertisement (for aneg) */
2351 bnx2x_set_ieee_aneg_advertisment(params,
2354 /* enable autoneg */
2355 bnx2x_set_autoneg(params, vars);
2357 /* enable and restart AN */
2358 bnx2x_restart_autoneg(params);
2361 } else { /* SGMII mode */
2362 DP(NETIF_MSG_LINK, "SGMII\n");
2364 bnx2x_initialize_sgmii_process(params);
2368 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2370 struct bnx2x *bp = params->bp;
2377 if (vars->phy_flags & PHY_XGXS_FLAG) {
2378 ext_phy_addr = ((params->ext_phy_config &
2379 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2380 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2382 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2383 /* Make sure that the soft reset is off (expect for the 8072:
2384 * due to the lock, it will be done inside the specific
2387 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
2388 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
2389 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
2390 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
2391 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
2392 /* Wait for soft reset to get cleared upto 1 sec */
2393 for (cnt = 0; cnt < 1000; cnt++) {
2394 bnx2x_cl45_read(bp, params->port,
2398 MDIO_PMA_REG_CTRL, &ctrl);
2399 if (!(ctrl & (1<<15)))
2403 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
2407 switch (ext_phy_type) {
2408 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2411 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2412 DP(NETIF_MSG_LINK, "XGXS 8705\n");
2414 bnx2x_cl45_write(bp, params->port,
2418 MDIO_PMA_REG_MISC_CTRL,
2420 bnx2x_cl45_write(bp, params->port,
2424 MDIO_PMA_REG_PHY_IDENTIFIER,
2426 bnx2x_cl45_write(bp, params->port,
2430 MDIO_PMA_REG_CMU_PLL_BYPASS,
2432 bnx2x_cl45_write(bp, params->port,
2436 MDIO_WIS_REG_LASI_CNTL, 0x1);
2439 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2440 DP(NETIF_MSG_LINK, "XGXS 8706\n");
2444 /* First enable LASI */
2445 bnx2x_cl45_write(bp, params->port,
2449 MDIO_PMA_REG_RX_ALARM_CTRL,
2451 bnx2x_cl45_write(bp, params->port,
2455 MDIO_PMA_REG_LASI_CTRL, 0x0004);
2457 if (params->req_line_speed == SPEED_10000) {
2458 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
2460 bnx2x_cl45_write(bp, params->port,
2464 MDIO_PMA_REG_DIGITAL_CTRL,
2467 /* Force 1Gbps using autoneg with 1G
2470 /* Allow CL37 through CL73 */
2471 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
2472 bnx2x_cl45_write(bp, params->port,
2476 MDIO_AN_REG_CL37_CL73,
2479 /* Enable Full-Duplex advertisment on CL37 */
2480 bnx2x_cl45_write(bp, params->port,
2484 MDIO_AN_REG_CL37_FD,
2486 /* Enable CL37 AN */
2487 bnx2x_cl45_write(bp, params->port,
2491 MDIO_AN_REG_CL37_AN,
2494 bnx2x_cl45_write(bp, params->port,
2498 MDIO_AN_REG_ADV, (1<<5));
2500 /* Enable clause 73 AN */
2501 bnx2x_cl45_write(bp, params->port,
2512 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2513 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2516 u16 rx_alarm_ctrl_val;
2519 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2520 rx_alarm_ctrl_val = 0x400;
2521 lasi_ctrl_val = 0x0004;
2523 /* In 8073, port1 is directed through emac0 and
2524 * port0 is directed through emac1
2526 rx_alarm_ctrl_val = (1<<2);
2527 /*lasi_ctrl_val = 0x0005;*/
2528 lasi_ctrl_val = 0x0004;
2531 /* Wait for soft reset to get cleared upto 1 sec */
2532 for (cnt = 0; cnt < 1000; cnt++) {
2533 bnx2x_cl45_read(bp, params->port,
2539 if (!(ctrl & (1<<15)))
2544 "807x control reg 0x%x (after %d ms)\n",
2548 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
2549 bnx2x_bcm8072_external_rom_boot(params);
2551 bnx2x_bcm8073_external_rom_boot(params);
2552 /* In case of 8073 with long xaui lines,
2553 don't set the 8073 xaui low power*/
2554 bnx2x_bcm8073_set_xaui_low_power_mode(params);
2558 bnx2x_cl45_write(bp, params->port,
2562 MDIO_PMA_REG_RX_ALARM_CTRL,
2565 bnx2x_cl45_write(bp, params->port,
2569 MDIO_PMA_REG_LASI_CTRL,
2572 bnx2x_cl45_read(bp, params->port,
2576 MDIO_PMA_REG_RX_ALARM, &tmp1);
2578 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
2581 /* If this is forced speed, set to KR or KX
2582 * (all other are not supported)
2584 if (!(params->req_line_speed == SPEED_AUTO_NEG)) {
2585 if (params->req_line_speed == SPEED_10000) {
2586 bnx2x_bcm807x_force_10G(params);
2588 "Forced speed 10G on 807X\n");
2590 } else if (params->req_line_speed ==
2593 /* Note that 2.5G works only
2594 when used with 1G advertisment */
2600 if (params->speed_cap_mask &
2601 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2604 if (params->speed_cap_mask &
2605 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
2607 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
2608 /*val = ((1<<5)|(1<<7));*/
2611 bnx2x_cl45_write(bp, params->port,
2615 MDIO_AN_REG_ADV, val);
2618 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2619 /* Disable 2.5Ghz */
2620 bnx2x_cl45_read(bp, params->port,
2625 /* SUPPORT_SPEED_CAPABILITY
2626 (Due to the nature of the link order, its not
2627 possible to enable 2.5G within the autoneg
2629 if (params->speed_cap_mask &
2630 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
2632 if (params->req_line_speed == SPEED_2500) {
2634 /* Allow 2.5G for A1 and above */
2635 bnx2x_cl45_read(bp, params->port,
2636 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2649 bnx2x_cl45_write(bp, params->port,
2655 /* Add support for CL37 (passive mode) I */
2656 bnx2x_cl45_write(bp, params->port,
2660 MDIO_AN_REG_CL37_CL73, 0x040c);
2661 /* Add support for CL37 (passive mode) II */
2662 bnx2x_cl45_write(bp, params->port,
2666 MDIO_AN_REG_CL37_FD, 0x20);
2667 /* Add support for CL37 (passive mode) III */
2668 bnx2x_cl45_write(bp, params->port,
2672 MDIO_AN_REG_CL37_AN, 0x1000);
2673 /* Restart autoneg */
2677 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2679 /* The SNR will improve about 2db by changing the
2680 BW and FEE main tap. Rest commands are executed
2682 /* Change FFE main cursor to 5 in EDC register */
2683 if (bnx2x_8073_is_snr_needed(params))
2684 bnx2x_cl45_write(bp, params->port,
2688 MDIO_PMA_REG_EDC_FFE_MAIN,
2691 /* Enable FEC (Forware Error Correction)
2692 Request in the AN */
2693 bnx2x_cl45_read(bp, params->port,
2697 MDIO_AN_REG_ADV2, &tmp1);
2701 bnx2x_cl45_write(bp, params->port,
2705 MDIO_AN_REG_ADV2, tmp1);
2708 bnx2x_ext_phy_set_pause(params, vars);
2710 bnx2x_cl45_write(bp, params->port,
2714 MDIO_AN_REG_CTRL, 0x1200);
2715 DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
2716 "Advertise 1G=%x, 10G=%x\n",
2717 ((val & (1<<5)) > 0),
2718 ((val & (1<<7)) > 0));
2721 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
2723 "Setting the SFX7101 LASI indication\n");
2725 bnx2x_cl45_write(bp, params->port,
2729 MDIO_PMA_REG_LASI_CTRL, 0x1);
2731 "Setting the SFX7101 LED to blink on traffic\n");
2732 bnx2x_cl45_write(bp, params->port,
2736 MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
2738 bnx2x_ext_phy_set_pause(params, vars);
2739 /* Restart autoneg */
2740 bnx2x_cl45_read(bp, params->port,
2744 MDIO_AN_REG_CTRL, &val);
2746 bnx2x_cl45_write(bp, params->port,
2750 MDIO_AN_REG_CTRL, val);
2752 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2754 "XGXS PHY Failure detected 0x%x\n",
2755 params->ext_phy_config);
2759 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
2760 params->ext_phy_config);
2765 } else { /* SerDes */
2767 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2768 switch (ext_phy_type) {
2769 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
2770 DP(NETIF_MSG_LINK, "SerDes Direct\n");
2773 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
2774 DP(NETIF_MSG_LINK, "SerDes 5482\n");
2778 DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
2779 params->ext_phy_config);
2787 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2788 struct link_vars *vars)
2790 struct bnx2x *bp = params->bp;
2794 u16 rx_sd, pcs_status;
2795 u8 ext_phy_link_up = 0;
2796 u8 port = params->port;
2797 if (vars->phy_flags & PHY_XGXS_FLAG) {
2798 ext_phy_addr = ((params->ext_phy_config &
2799 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2800 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2802 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2803 switch (ext_phy_type) {
2804 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2805 DP(NETIF_MSG_LINK, "XGXS Direct\n");
2806 ext_phy_link_up = 1;
2809 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2810 DP(NETIF_MSG_LINK, "XGXS 8705\n");
2811 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2814 MDIO_WIS_REG_LASI_STATUS, &val1);
2815 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2817 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2820 MDIO_WIS_REG_LASI_STATUS, &val1);
2821 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2823 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2826 MDIO_PMA_REG_RX_SD, &rx_sd);
2827 DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
2828 ext_phy_link_up = (rx_sd & 0x1);
2831 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2832 DP(NETIF_MSG_LINK, "XGXS 8706\n");
2833 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2836 MDIO_PMA_REG_LASI_STATUS, &val1);
2837 DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2839 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2842 MDIO_PMA_REG_LASI_STATUS, &val1);
2843 DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2845 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2848 MDIO_PMA_REG_RX_SD, &rx_sd);
2849 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2852 MDIO_PCS_REG_STATUS, &pcs_status);
2854 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2857 MDIO_AN_REG_LINK_STATUS, &val2);
2858 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2861 MDIO_AN_REG_LINK_STATUS, &val2);
2863 DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
2864 " pcs_status 0x%x 1Gbps link_status 0x%x\n",
2865 rx_sd, pcs_status, val2);
2866 /* link is up if both bit 0 of pmd_rx_sd and
2867 * bit 0 of pcs_status are set, or if the autoneg bit
2870 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
2872 if (ext_phy_link_up) {
2874 vars->line_speed = SPEED_1000;
2876 vars->line_speed = SPEED_10000;
2879 /* clear LASI indication*/
2880 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2883 MDIO_PMA_REG_RX_ALARM, &val2);
2886 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2887 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2890 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2891 bnx2x_cl45_read(bp, params->port,
2895 MDIO_PCS_REG_LASI_STATUS, &val1);
2896 bnx2x_cl45_read(bp, params->port,
2900 MDIO_PCS_REG_LASI_STATUS, &val2);
2902 "870x LASI status 0x%x->0x%x\n",
2906 /* In 8073, port1 is directed through emac0 and
2907 * port0 is directed through emac1
2909 bnx2x_cl45_read(bp, params->port,
2913 MDIO_PMA_REG_LASI_STATUS, &val1);
2915 bnx2x_cl45_read(bp, params->port,
2919 MDIO_PMA_REG_LASI_STATUS, &val2);
2921 "8703 LASI status 0x%x->0x%x\n",
2925 /* clear the interrupt LASI status register */
2926 bnx2x_cl45_read(bp, params->port,
2930 MDIO_PCS_REG_STATUS, &val2);
2931 bnx2x_cl45_read(bp, params->port,
2935 MDIO_PCS_REG_STATUS, &val1);
2936 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
2938 /* Check the LASI */
2939 bnx2x_cl45_read(bp, params->port,
2943 MDIO_PMA_REG_RX_ALARM, &val2);
2944 bnx2x_cl45_read(bp, params->port,
2948 MDIO_PMA_REG_RX_ALARM,
2950 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x->0x%x\n",
2952 /* Check the link status */
2953 bnx2x_cl45_read(bp, params->port,
2957 MDIO_PCS_REG_STATUS, &val2);
2958 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
2960 bnx2x_cl45_read(bp, params->port,
2964 MDIO_PMA_REG_STATUS, &val2);
2965 bnx2x_cl45_read(bp, params->port,
2969 MDIO_PMA_REG_STATUS, &val1);
2970 ext_phy_link_up = ((val1 & 4) == 4);
2971 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
2973 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2974 u16 an1000_status = 0;
2975 if (ext_phy_link_up &&
2977 (params->req_line_speed != SPEED_10000)
2979 if (bnx2x_bcm8073_xaui_wa(params)
2981 ext_phy_link_up = 0;
2984 bnx2x_cl45_read(bp, params->port,
2990 bnx2x_cl45_read(bp, params->port,
2997 /* Check the link status on 1.1.2 */
2998 bnx2x_cl45_read(bp, params->port,
3002 MDIO_PMA_REG_STATUS, &val2);
3003 bnx2x_cl45_read(bp, params->port,
3007 MDIO_PMA_REG_STATUS, &val1);
3008 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3009 "an_link_status=0x%x\n",
3010 val2, val1, an1000_status);
3012 ext_phy_link_up = (((val1 & 4) == 4) ||
3013 (an1000_status & (1<<1)));
3014 if (ext_phy_link_up &&
3015 bnx2x_8073_is_snr_needed(params)) {
3016 /* The SNR will improve about 2dbby
3017 changing the BW and FEE main tap.*/
3019 /* The 1st write to change FFE main
3020 tap is set before restart AN */
3021 /* Change PLL Bandwidth in EDC
3023 bnx2x_cl45_write(bp, port, ext_phy_type,
3026 MDIO_PMA_REG_PLL_BANDWIDTH,
3029 /* Change CDR Bandwidth in EDC
3031 bnx2x_cl45_write(bp, port, ext_phy_type,
3034 MDIO_PMA_REG_CDR_BANDWIDTH,
3041 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3042 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3045 MDIO_PMA_REG_LASI_STATUS, &val2);
3046 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3049 MDIO_PMA_REG_LASI_STATUS, &val1);
3051 "10G-base-T LASI status 0x%x->0x%x\n",
3053 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3056 MDIO_PMA_REG_STATUS, &val2);
3057 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3060 MDIO_PMA_REG_STATUS, &val1);
3062 "10G-base-T PMA status 0x%x->0x%x\n",
3064 ext_phy_link_up = ((val1 & 4) == 4);
3066 * print the AN outcome of the SFX7101 PHY
3068 if (ext_phy_link_up) {
3069 bnx2x_cl45_read(bp, params->port,
3073 MDIO_AN_REG_MASTER_STATUS,
3075 vars->line_speed = SPEED_10000;
3077 "SFX7101 AN status 0x%x->Master=%x\n",
3084 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3085 params->ext_phy_config);
3086 ext_phy_link_up = 0;
3090 } else { /* SerDes */
3091 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3092 switch (ext_phy_type) {
3093 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3094 DP(NETIF_MSG_LINK, "SerDes Direct\n");
3095 ext_phy_link_up = 1;
3098 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3099 DP(NETIF_MSG_LINK, "SerDes 5482\n");
3100 ext_phy_link_up = 1;
3105 "BAD SerDes ext_phy_config 0x%x\n",
3106 params->ext_phy_config);
3107 ext_phy_link_up = 0;
3112 return ext_phy_link_up;
3115 static void bnx2x_link_int_enable(struct link_params *params)
3117 u8 port = params->port;
3120 struct bnx2x *bp = params->bp;
3121 /* setting the status to report on link up
3122 for either XGXS or SerDes */
3124 if (params->switch_cfg == SWITCH_CFG_10G) {
3125 mask = (NIG_MASK_XGXS0_LINK10G |
3126 NIG_MASK_XGXS0_LINK_STATUS);
3127 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
3128 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3129 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3130 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3132 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
3133 mask |= NIG_MASK_MI_INT;
3134 DP(NETIF_MSG_LINK, "enabled external phy int\n");
3137 } else { /* SerDes */
3138 mask = NIG_MASK_SERDES0_LINK_STATUS;
3139 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
3140 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3141 if ((ext_phy_type !=
3142 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
3144 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
3145 mask |= NIG_MASK_MI_INT;
3146 DP(NETIF_MSG_LINK, "enabled external phy int\n");
3150 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3152 DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
3153 (params->switch_cfg == SWITCH_CFG_10G),
3154 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
3156 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
3157 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
3158 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
3159 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
3160 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
3161 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
3162 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
3169 static void bnx2x_link_int_ack(struct link_params *params,
3170 struct link_vars *vars, u16 is_10g)
3172 struct bnx2x *bp = params->bp;
3173 u8 port = params->port;
3175 /* first reset all status
3176 * we assume only one line will be change at a time */
3177 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3178 (NIG_STATUS_XGXS0_LINK10G |
3179 NIG_STATUS_XGXS0_LINK_STATUS |
3180 NIG_STATUS_SERDES0_LINK_STATUS));
3181 if (vars->phy_link_up) {
3183 /* Disable the 10G link interrupt
3184 * by writing 1 to the status register
3186 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
3188 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3189 NIG_STATUS_XGXS0_LINK10G);
3191 } else if (params->switch_cfg == SWITCH_CFG_10G) {
3192 /* Disable the link interrupt
3193 * by writing 1 to the relevant lane
3194 * in the status register
3196 u32 ser_lane = ((params->lane_config &
3197 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3198 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3200 DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
3202 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3204 NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
3206 } else { /* SerDes */
3207 DP(NETIF_MSG_LINK, "SerDes phy link up\n");
3208 /* Disable the link interrupt
3209 * by writing 1 to the status register
3212 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3213 NIG_STATUS_SERDES0_LINK_STATUS);
3216 } else { /* link_down */
3220 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
3223 u32 mask = 0xf0000000;
3227 /* Need more then 10chars for this format */
3234 digit = ((num & mask) >> shift);
3236 *str_ptr = digit + '0';
3238 *str_ptr = digit - 0xa + 'a';
3251 static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
3256 /* Enable EMAC0 in to enable MDIO */
3257 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
3258 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
3261 /* take ext phy out of reset */
3263 MISC_REGISTERS_GPIO_2,
3264 MISC_REGISTERS_GPIO_HIGH);
3267 MISC_REGISTERS_GPIO_1,
3268 MISC_REGISTERS_GPIO_HIGH);
3273 for (cnt = 0; cnt < 1000; cnt++) {
3275 bnx2x_cl45_read(bp, port,
3281 if (!(ctrl & (1<<15))) {
3282 DP(NETIF_MSG_LINK, "Reset completed\n\n");
3288 static void bnx2x_turn_off_sf(struct bnx2x *bp)
3290 /* put sf to reset */
3291 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, MISC_REGISTERS_GPIO_LOW);
3293 MISC_REGISTERS_GPIO_2,
3294 MISC_REGISTERS_GPIO_LOW);
3297 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3298 u8 *version, u16 len)
3300 struct bnx2x *bp = params->bp;
3301 u32 ext_phy_type = 0;
3303 u8 ext_phy_addr = 0 ;
3307 if (version == NULL || params == NULL)
3310 /* reset the returned value to zero */
3311 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3312 ext_phy_addr = ((params->ext_phy_config &
3313 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3314 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3316 switch (ext_phy_type) {
3317 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3322 /* Take ext phy out of reset */
3324 bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3330 bnx2x_cl45_read(bp, params->port,
3334 MDIO_PMA_REG_7101_VER1, &val);
3335 version[2] = (val & 0xFF);
3336 version[3] = ((val & 0xFF00)>>8);
3338 bnx2x_cl45_read(bp, params->port,
3341 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2,
3343 version[0] = (val & 0xFF);
3344 version[1] = ((val & 0xFF00)>>8);
3348 bnx2x_turn_off_sf(bp);
3350 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3351 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3353 /* Take ext phy out of reset */
3355 bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3358 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3361 MDIO_PMA_REG_ROM_VER1, &val);
3363 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3366 MDIO_PMA_REG_ROM_VER2, &val);
3368 status = bnx2x_format_ver(ver_num, version, len);
3371 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3372 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3374 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3377 MDIO_PMA_REG_ROM_VER1, &val);
3379 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3382 MDIO_PMA_REG_ROM_VER2, &val);
3384 status = bnx2x_format_ver(ver_num, version, len);
3387 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3390 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
3391 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
3392 " type is FAILURE!\n");
3402 static void bnx2x_set_xgxs_loopback(struct link_params *params,
3403 struct link_vars *vars,
3406 u8 port = params->port;
3407 struct bnx2x *bp = params->bp;
3412 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
3414 /* change the uni_phy_addr in the nig */
3415 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
3418 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
3420 bnx2x_cl45_write(bp, port, 0,
3423 (MDIO_REG_BANK_AER_BLOCK +
3424 (MDIO_AER_BLOCK_AER_REG & 0xf)),
3427 bnx2x_cl45_write(bp, port, 0,
3430 (MDIO_REG_BANK_CL73_IEEEB0 +
3431 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
3434 /* set aer mmd back */
3435 bnx2x_set_aer_mmd(params, vars);
3438 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
3444 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
3446 CL45_RD_OVER_CL22(bp, port,
3448 MDIO_REG_BANK_COMBO_IEEE0,
3449 MDIO_COMBO_IEEE0_MII_CONTROL,
3452 CL45_WR_OVER_CL22(bp, port,
3454 MDIO_REG_BANK_COMBO_IEEE0,
3455 MDIO_COMBO_IEEE0_MII_CONTROL,
3457 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
3462 static void bnx2x_ext_phy_loopback(struct link_params *params)
3464 struct bnx2x *bp = params->bp;
3468 if (params->switch_cfg == SWITCH_CFG_10G) {
3469 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3470 /* CL37 Autoneg Enabled */
3471 ext_phy_addr = ((params->ext_phy_config &
3472 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3473 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3474 switch (ext_phy_type) {
3475 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3476 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
3478 "ext_phy_loopback: We should not get here\n");
3480 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3481 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
3483 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3484 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
3486 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3487 /* SFX7101_XGXS_TEST1 */
3488 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3491 MDIO_XS_SFX7101_XGXS_TEST1,
3494 "ext_phy_loopback: set ext phy loopback\n");
3496 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3499 } /* switch external PHY type */
3502 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3503 ext_phy_addr = (params->ext_phy_config &
3504 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
3505 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
3511 *------------------------------------------------------------------------
3512 * bnx2x_override_led_value -
3514 * Override the led value of the requsted led
3516 *------------------------------------------------------------------------
3518 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
3519 u32 led_idx, u32 value)
3523 /* If port 0 then use EMAC0, else use EMAC1*/
3524 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3527 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
3528 port, led_idx, value);
3531 case 0: /* 10MB led */
3532 /* Read the current value of the LED register in
3534 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3535 /* Set the OVERRIDE bit to 1 */
3536 reg_val |= EMAC_LED_OVERRIDE;
3537 /* If value is 1, set the 10M_OVERRIDE bit,
3538 otherwise reset it.*/
3539 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
3540 (reg_val & ~EMAC_LED_10MB_OVERRIDE);
3541 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3543 case 1: /*100MB led */
3544 /*Read the current value of the LED register in
3546 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3547 /* Set the OVERRIDE bit to 1 */
3548 reg_val |= EMAC_LED_OVERRIDE;
3549 /* If value is 1, set the 100M_OVERRIDE bit,
3550 otherwise reset it.*/
3551 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
3552 (reg_val & ~EMAC_LED_100MB_OVERRIDE);
3553 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3555 case 2: /* 1000MB led */
3556 /* Read the current value of the LED register in the
3558 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3559 /* Set the OVERRIDE bit to 1 */
3560 reg_val |= EMAC_LED_OVERRIDE;
3561 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
3563 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
3564 (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
3565 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3567 case 3: /* 2500MB led */
3568 /* Read the current value of the LED register in the
3570 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3571 /* Set the OVERRIDE bit to 1 */
3572 reg_val |= EMAC_LED_OVERRIDE;
3573 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
3575 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
3576 (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
3577 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3579 case 4: /*10G led */
3581 REG_WR(bp, NIG_REG_LED_10G_P0,
3584 REG_WR(bp, NIG_REG_LED_10G_P1,
3588 case 5: /* TRAFFIC led */
3589 /* Find if the traffic control is via BMAC or EMAC */
3591 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
3593 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
3595 /* Override the traffic led in the EMAC:*/
3597 /* Read the current value of the LED register in
3599 reg_val = REG_RD(bp, emac_base +
3601 /* Set the TRAFFIC_OVERRIDE bit to 1 */
3602 reg_val |= EMAC_LED_OVERRIDE;
3603 /* If value is 1, set the TRAFFIC bit, otherwise
3605 reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
3606 (reg_val & ~EMAC_LED_TRAFFIC);
3607 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3608 } else { /* Override the traffic led in the BMAC: */
3609 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3611 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
3617 "bnx2x_override_led_value() unknown led index %d "
3618 "(should be 0-5)\n", led_idx);
3626 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
3627 u16 hw_led_mode, u32 chip_id)
3630 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
3631 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
3632 speed, hw_led_mode);
3635 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
3636 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
3637 SHARED_HW_CFG_LED_MAC1);
3641 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
3642 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
3644 /* Set blinking rate to ~15.9Hz */
3645 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
3646 LED_BLINK_RATE_VAL);
3647 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
3649 if (!CHIP_IS_E1H(bp) &&
3650 ((speed == SPEED_2500) ||
3651 (speed == SPEED_1000) ||
3652 (speed == SPEED_100) ||
3653 (speed == SPEED_10))) {
3654 /* On Everest 1 Ax chip versions for speeds less than
3655 10G LED scheme is different */
3656 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3658 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
3660 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
3667 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
3675 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
3677 struct bnx2x *bp = params->bp;
3680 CL45_RD_OVER_CL22(bp, params->port,
3682 MDIO_REG_BANK_GP_STATUS,
3683 MDIO_GP_STATUS_TOP_AN_STATUS1,
3685 /* link is up only if both local phy and external phy are up */
3686 if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
3687 bnx2x_ext_phy_is_link_up(params, vars))
3693 static u8 bnx2x_link_initialize(struct link_params *params,
3694 struct link_vars *vars)
3696 struct bnx2x *bp = params->bp;
3697 u8 port = params->port;
3700 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3701 /* Activate the external PHY */
3702 bnx2x_ext_phy_reset(params, vars);
3704 bnx2x_set_aer_mmd(params, vars);
3706 if (vars->phy_flags & PHY_XGXS_FLAG)
3707 bnx2x_set_master_ln(params);
3709 rc = bnx2x_reset_unicore(params);
3710 /* reset the SerDes and wait for reset bit return low */
3714 bnx2x_set_aer_mmd(params, vars);
3716 /* setting the masterLn_def again after the reset */
3717 if (vars->phy_flags & PHY_XGXS_FLAG) {
3718 bnx2x_set_master_ln(params);
3719 bnx2x_set_swap_lanes(params);
3722 if (vars->phy_flags & PHY_XGXS_FLAG) {
3723 if (params->req_line_speed &&
3724 ((params->req_line_speed == SPEED_100) ||
3725 (params->req_line_speed == SPEED_10))) {
3726 vars->phy_flags |= PHY_SGMII_FLAG;
3728 vars->phy_flags &= ~PHY_SGMII_FLAG;
3731 /* In case of external phy existance, the line speed would be the
3732 line speed linked up by the external phy. In case it is direct only,
3733 then the line_speed during initialization will be equal to the
3735 vars->line_speed = params->req_line_speed;
3737 bnx2x_set_ieee_aneg_advertisment(params, &vars->ieee_fc);
3739 /* init ext phy and enable link state int */
3740 non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
3741 (params->loopback_mode == LOOPBACK_XGXS_10) ||
3742 (params->loopback_mode == LOOPBACK_EXT_PHY));
3745 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705)) {
3746 if (params->req_line_speed == SPEED_AUTO_NEG)
3747 bnx2x_set_parallel_detection(params, vars->phy_flags);
3748 bnx2x_init_internal_phy(params, vars);
3752 rc |= bnx2x_ext_phy_init(params, vars);
3754 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3755 (NIG_STATUS_XGXS0_LINK10G |
3756 NIG_STATUS_XGXS0_LINK_STATUS |
3757 NIG_STATUS_SERDES0_LINK_STATUS));
3764 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
3766 struct bnx2x *bp = params->bp;
3769 DP(NETIF_MSG_LINK, "Phy Initialization started\n");
3770 DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
3771 params->req_line_speed, params->req_flow_ctrl);
3772 vars->link_status = 0;
3773 vars->phy_link_up = 0;
3775 vars->line_speed = 0;
3776 vars->duplex = DUPLEX_FULL;
3777 vars->flow_ctrl = FLOW_CTRL_NONE;
3778 vars->mac_type = MAC_TYPE_NONE;
3780 if (params->switch_cfg == SWITCH_CFG_1G)
3781 vars->phy_flags = PHY_SERDES_FLAG;
3783 vars->phy_flags = PHY_XGXS_FLAG;
3785 /* disable attentions */
3786 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
3787 (NIG_MASK_XGXS0_LINK_STATUS |
3788 NIG_MASK_XGXS0_LINK10G |
3789 NIG_MASK_SERDES0_LINK_STATUS |
3792 bnx2x_emac_init(params, vars);
3794 if (CHIP_REV_IS_FPGA(bp)) {
3796 vars->line_speed = SPEED_10000;
3797 vars->duplex = DUPLEX_FULL;
3798 vars->flow_ctrl = FLOW_CTRL_NONE;
3799 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3800 /* enable on E1.5 FPGA */
3801 if (CHIP_IS_E1H(bp)) {
3803 (FLOW_CTRL_TX | FLOW_CTRL_RX);
3804 vars->link_status |=
3805 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
3806 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
3809 bnx2x_emac_enable(params, vars, 0);
3810 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3812 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3813 + params->port*4, 0);
3815 /* update shared memory */
3816 bnx2x_update_mng(params, vars->link_status);
3821 if (CHIP_REV_IS_EMUL(bp)) {
3824 vars->line_speed = SPEED_10000;
3825 vars->duplex = DUPLEX_FULL;
3826 vars->flow_ctrl = FLOW_CTRL_NONE;
3827 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3829 bnx2x_bmac_enable(params, vars, 0);
3831 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3833 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3834 + params->port*4, 0);
3836 /* update shared memory */
3837 bnx2x_update_mng(params, vars->link_status);
3842 if (params->loopback_mode == LOOPBACK_BMAC) {
3844 vars->line_speed = SPEED_10000;
3845 vars->duplex = DUPLEX_FULL;
3846 vars->flow_ctrl = FLOW_CTRL_NONE;
3847 vars->mac_type = MAC_TYPE_BMAC;
3849 vars->phy_flags = PHY_XGXS_FLAG;
3851 bnx2x_phy_deassert(params, vars->phy_flags);
3852 /* set bmac loopback */
3853 bnx2x_bmac_enable(params, vars, 1);
3855 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
3857 } else if (params->loopback_mode == LOOPBACK_EMAC) {
3859 vars->line_speed = SPEED_1000;
3860 vars->duplex = DUPLEX_FULL;
3861 vars->flow_ctrl = FLOW_CTRL_NONE;
3862 vars->mac_type = MAC_TYPE_EMAC;
3864 vars->phy_flags = PHY_XGXS_FLAG;
3866 bnx2x_phy_deassert(params, vars->phy_flags);
3867 /* set bmac loopback */
3868 bnx2x_emac_enable(params, vars, 1);
3869 bnx2x_emac_program(params, vars->line_speed,
3871 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
3873 } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
3874 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
3876 vars->line_speed = SPEED_10000;
3877 vars->duplex = DUPLEX_FULL;
3878 vars->flow_ctrl = FLOW_CTRL_NONE;
3880 vars->phy_flags = PHY_XGXS_FLAG;
3883 NIG_REG_XGXS0_CTRL_PHY_ADDR+
3885 params->phy_addr = (u8)val;
3887 bnx2x_phy_deassert(params, vars->phy_flags);
3888 bnx2x_link_initialize(params, vars);
3890 vars->mac_type = MAC_TYPE_BMAC;
3892 bnx2x_bmac_enable(params, vars, 0);
3894 if (params->loopback_mode == LOOPBACK_XGXS_10) {
3895 /* set 10G XGXS loopback */
3896 bnx2x_set_xgxs_loopback(params, vars, 1);
3898 /* set external phy loopback */
3899 bnx2x_ext_phy_loopback(params);
3901 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
3907 bnx2x_phy_deassert(params, vars->phy_flags);
3908 switch (params->switch_cfg) {
3910 vars->phy_flags |= PHY_SERDES_FLAG;
3911 if ((params->ext_phy_config &
3912 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
3913 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
3919 NIG_REG_SERDES0_CTRL_PHY_ADDR+
3922 params->phy_addr = (u8)val;
3925 case SWITCH_CFG_10G:
3926 vars->phy_flags |= PHY_XGXS_FLAG;
3928 NIG_REG_XGXS0_CTRL_PHY_ADDR+
3930 params->phy_addr = (u8)val;
3934 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
3939 bnx2x_link_initialize(params, vars);
3941 bnx2x_link_int_enable(params);
3946 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
3949 struct bnx2x *bp = params->bp;
3950 u32 ext_phy_config = params->ext_phy_config;
3951 u16 hw_led_mode = params->hw_led_mode;
3952 u32 chip_id = params->chip_id;
3953 u8 port = params->port;
3954 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
3955 /* disable attentions */
3957 vars->link_status = 0;
3958 bnx2x_update_mng(params, vars->link_status);
3959 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3960 (NIG_MASK_XGXS0_LINK_STATUS |
3961 NIG_MASK_XGXS0_LINK10G |
3962 NIG_MASK_SERDES0_LINK_STATUS |
3965 /* activate nig drain */
3966 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
3968 /* disable nig egress interface */
3969 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
3970 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
3972 /* Stop BigMac rx */
3973 bnx2x_bmac_rx_disable(bp, port);
3976 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
3979 /* The PHY reset is controled by GPIO 1
3980 * Hold it as vars low
3982 /* clear link led */
3983 bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
3984 if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
3985 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
3986 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
3989 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3990 MISC_REGISTERS_GPIO_OUTPUT_LOW);
3992 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3993 MISC_REGISTERS_GPIO_OUTPUT_LOW);
3995 DP(NETIF_MSG_LINK, "reset external PHY\n");
3996 } else if (ext_phy_type ==
3997 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3998 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4001 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4002 MISC_REGISTERS_GPIO_OUTPUT_LOW);
4005 /* reset the SerDes/XGXS */
4006 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4007 (0x1ff << (port*16)));
4010 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4011 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4013 /* disable nig ingress interface */
4014 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4015 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4016 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4017 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4022 static u8 bnx2x_update_link_down(struct link_params *params,
4023 struct link_vars *vars)
4025 struct bnx2x *bp = params->bp;
4026 u8 port = params->port;
4027 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4028 bnx2x_set_led(bp, port, LED_MODE_OFF,
4029 0, params->hw_led_mode,
4032 /* indicate no mac active */
4033 vars->mac_type = MAC_TYPE_NONE;
4035 /* update shared memory */
4036 vars->link_status = 0;
4037 vars->line_speed = 0;
4038 bnx2x_update_mng(params, vars->link_status);
4040 /* activate nig drain */
4041 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4044 bnx2x_bmac_rx_disable(bp, params->port);
4045 REG_WR(bp, GRCBASE_MISC +
4046 MISC_REGISTERS_RESET_REG_2_CLEAR,
4047 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4051 static u8 bnx2x_update_link_up(struct link_params *params,
4052 struct link_vars *vars,
4053 u8 link_10g, u32 gp_status)
4055 struct bnx2x *bp = params->bp;
4056 u8 port = params->port;
4058 vars->link_status |= LINK_STATUS_LINK_UP;
4060 bnx2x_bmac_enable(params, vars, 0);
4061 bnx2x_set_led(bp, port, LED_MODE_OPER,
4062 SPEED_10000, params->hw_led_mode,
4066 bnx2x_emac_enable(params, vars, 0);
4067 rc = bnx2x_emac_program(params, vars->line_speed,
4071 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4072 if (!(vars->phy_flags &
4074 bnx2x_set_sgmii_tx_driver(params);
4079 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4083 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4085 /* update shared memory */
4086 bnx2x_update_mng(params, vars->link_status);
4089 /* This function should called upon link interrupt */
4090 /* In case vars->link_up, driver needs to
4093 3. Update the shared memory
4097 1. Update shared memory
4102 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4104 struct bnx2x *bp = params->bp;
4105 u8 port = params->port;
4108 u8 ext_phy_link_up, rc = 0;
4111 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
4113 (vars->phy_flags & PHY_XGXS_FLAG),
4114 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4116 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4117 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4118 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4119 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
4121 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4122 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4123 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4125 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4127 /* Check external link change only for non-direct */
4128 ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
4130 /* Read gp_status */
4131 CL45_RD_OVER_CL22(bp, port, params->phy_addr,
4132 MDIO_REG_BANK_GP_STATUS,
4133 MDIO_GP_STATUS_TOP_AN_STATUS1,
4136 rc = bnx2x_link_settings_status(params, vars, gp_status);
4140 /* anything 10 and over uses the bmac */
4141 link_10g = ((vars->line_speed == SPEED_10000) ||
4142 (vars->line_speed == SPEED_12000) ||
4143 (vars->line_speed == SPEED_12500) ||
4144 (vars->line_speed == SPEED_13000) ||
4145 (vars->line_speed == SPEED_15000) ||
4146 (vars->line_speed == SPEED_16000));
4148 bnx2x_link_int_ack(params, vars, link_10g);
4150 /* In case external phy link is up, and internal link is down
4151 ( not initialized yet probably after link initialization, it needs
4153 Note that after link down-up as result of cable plug,
4154 the xgxs link would probably become up again without the need to
4157 if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4158 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
4159 (ext_phy_link_up && !vars->phy_link_up))
4160 bnx2x_init_internal_phy(params, vars);
4162 /* link is up only if both local phy and external phy are up */
4163 vars->link_up = (ext_phy_link_up && vars->phy_link_up);
4166 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
4168 rc = bnx2x_update_link_down(params, vars);
4173 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
4177 bnx2x_cl45_read(bp, port,
4178 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4181 MDIO_PMA_REG_7101_RESET, &val);
4183 for (cnt = 0; cnt < 10; cnt++) {
4185 /* Writes a self-clearing reset */
4186 bnx2x_cl45_write(bp, port,
4187 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4190 MDIO_PMA_REG_7101_RESET,
4192 /* Wait for clear */
4193 bnx2x_cl45_read(bp, port,
4194 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4197 MDIO_PMA_REG_7101_RESET, &val);
4199 if ((val & (1<<15)) == 0)
4203 #define RESERVED_SIZE 256
4204 /* max application is 160K bytes - data at end of RAM */
4205 #define MAX_APP_SIZE 160*1024 - RESERVED_SIZE
4207 /* Header is 14 bytes */
4208 #define HEADER_SIZE 14
4209 #define DATA_OFFSET HEADER_SIZE
4211 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
4212 bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
4215 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
4217 /* Programs an image to DSP's flash via the SPI port*/
4218 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
4220 char data[], u32 size)
4222 const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
4223 /* Doesn't include last trans!*/
4224 const u16 last_trans_size = size%4; /* Num bytes on last trans */
4225 u16 trans_cnt, byte_cnt;
4228 u16 code_started = 0;
4229 u16 image_revision1, image_revision2;
4232 DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
4234 if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
4235 /* This very often will be the case, because the image is built
4236 with 160Kbytes size whereas the total image size must actually
4237 be 160Kbytes-RESERVED_SIZE */
4238 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
4239 "truncated to %d bytes\n", size, MAX_APP_SIZE);
4240 size = MAX_APP_SIZE+HEADER_SIZE;
4242 DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
4243 DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]);
4244 /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
4245 and issuing a reset.*/
4247 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4248 MISC_REGISTERS_GPIO_HIGH);
4250 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4253 for (cnt = 0; cnt < 100; cnt++)
4256 /* Make sure we can access the DSP
4257 And it's in the correct mode (waiting for download) */
4259 bnx2x_cl45_read(bp, port,
4260 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4263 MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
4265 if (tmp != 0x000A) {
4266 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
4267 "Expected 0x000A, read 0x%04X\n", tmp);
4268 DP(NETIF_MSG_LINK, "Download failed\n");
4272 /* Mux the SPI interface away from the internal processor */
4273 bnx2x_cl45_write(bp, port,
4274 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4277 MDIO_PCS_REG_7101_SPI_MUX, 1);
4279 /* Reset the SPI port */
4280 bnx2x_cl45_write(bp, port,
4281 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4284 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4285 bnx2x_cl45_write(bp, port,
4286 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4289 MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
4290 (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
4291 bnx2x_cl45_write(bp, port,
4292 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4295 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4297 /* Erase the flash */
4298 bnx2x_cl45_write(bp, port,
4299 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4302 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4303 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4305 bnx2x_cl45_write(bp, port,
4306 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4309 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4312 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4313 bnx2x_cl45_write(bp, port,
4314 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4317 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4318 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
4320 bnx2x_cl45_write(bp, port,
4321 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4324 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4326 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4328 /* Wait 10 seconds, the maximum time for the erase to complete */
4329 DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
4330 for (cnt = 0; cnt < 1000; cnt++)
4333 DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
4335 for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
4336 bnx2x_cl45_write(bp, port,
4337 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4340 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4341 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4343 bnx2x_cl45_write(bp, port,
4344 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4347 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4349 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4351 bnx2x_cl45_write(bp, port,
4352 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4355 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4356 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4358 /* Bits 23-16 of address */
4359 bnx2x_cl45_write(bp, port,
4360 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4363 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4365 /* Bits 15-8 of address */
4366 bnx2x_cl45_write(bp, port,
4367 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4370 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4373 /* Bits 7-0 of address */
4374 bnx2x_cl45_write(bp, port,
4375 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4378 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4382 while (byte_cnt < 4 && data_index < size) {
4383 bnx2x_cl45_write(bp, port,
4384 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4387 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4388 data[data_index++]);
4392 bnx2x_cl45_write(bp, port,
4393 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4396 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4399 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4400 msleep(5); /* Wait 5 ms minimum between transs */
4402 /* Let the user know something's going on.*/
4403 /* a pacifier ever 4K */
4404 if ((data_index % 1023) == 0)
4405 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4408 DP(NETIF_MSG_LINK, "\n");
4409 /* Transfer the last block if there is data remaining */
4410 if (last_trans_size) {
4411 bnx2x_cl45_write(bp, port,
4412 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4415 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4416 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4418 bnx2x_cl45_write(bp, port,
4419 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4422 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4425 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4427 bnx2x_cl45_write(bp, port,
4428 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4431 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4432 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4434 /* Bits 23-16 of address */
4435 bnx2x_cl45_write(bp, port,
4436 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4439 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4441 /* Bits 15-8 of address */
4442 bnx2x_cl45_write(bp, port,
4443 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4446 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4449 /* Bits 7-0 of address */
4450 bnx2x_cl45_write(bp, port,
4451 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4454 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4458 while (byte_cnt < last_trans_size && data_index < size) {
4459 /* Bits 7-0 of address */
4460 bnx2x_cl45_write(bp, port,
4461 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4464 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4465 data[data_index++]);
4469 bnx2x_cl45_write(bp, port,
4470 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4473 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4476 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4479 /* DSP Remove Download Mode */
4480 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, MISC_REGISTERS_GPIO_LOW);
4482 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4484 /* wait 0.5 sec to allow it to run */
4485 for (cnt = 0; cnt < 100; cnt++)
4490 for (cnt = 0; cnt < 100; cnt++)
4493 /* Check that the code is started. In case the download
4494 checksum failed, the code won't be started. */
4495 bnx2x_cl45_read(bp, port,
4496 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4499 MDIO_PCS_REG_7101_DSP_ACCESS,
4502 code_started = (tmp & (1<<4));
4503 if (!code_started) {
4504 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
4508 /* Verify that the file revision is now equal to the image
4509 revision within the DSP */
4510 bnx2x_cl45_read(bp, port,
4511 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4514 MDIO_PMA_REG_7101_VER1,
4517 bnx2x_cl45_read(bp, port,
4518 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4521 MDIO_PMA_REG_7101_VER2,
4524 if (data[0x14e] != (image_revision2&0xFF) ||
4525 data[0x14f] != ((image_revision2&0xFF00)>>8) ||
4526 data[0x150] != (image_revision1&0xFF) ||
4527 data[0x151] != ((image_revision1&0xFF00)>>8)) {
4528 DP(NETIF_MSG_LINK, "Download failed.\n");
4531 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4535 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
4536 u8 driver_loaded, char data[], u32 size)
4541 ext_phy_addr = ((ext_phy_config &
4542 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4543 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4545 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4547 switch (ext_phy_type) {
4548 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4549 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4550 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4551 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4553 "Flash download not supported for this ext phy\n");
4556 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4557 /* Take ext phy out of reset */
4559 bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
4560 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
4563 bnx2x_turn_off_sf(bp);
4565 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4566 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4567 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4569 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");