1 /* Copyright 2008-2009 Broadcom Corporation
3 * Unless you and Broadcom execute a separate written software license
4 * agreement governing use of this software, this software is licensed to you
5 * under the terms of the GNU General Public License version 2, available
6 * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
8 * Notwithstanding the above, under no circumstances may you combine this
9 * software in any way with any other Broadcom software provided under a
10 * license other than the GPL, without Broadcom's express prior written
13 * Written by Yaniv Rosner
17 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/pci.h>
20 #include <linux/netdevice.h>
21 #include <linux/delay.h>
22 #include <linux/ethtool.h>
23 #include <linux/mutex.h>
25 #include "bnx2x_reg.h"
26 #include "bnx2x_fw_defs.h"
27 #include "bnx2x_hsi.h"
28 #include "bnx2x_link.h"
31 /********************************************************/
32 #define SUPPORT_CL73 0 /* Currently no */
34 #define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
35 #define ETH_MIN_PACKET_SIZE 60
36 #define ETH_MAX_PACKET_SIZE 1500
37 #define ETH_MAX_JUMBO_PACKET_SIZE 9600
38 #define MDIO_ACCESS_TIMEOUT 1000
39 #define BMAC_CONTROL_RX_ENABLE 2
41 /***********************************************************/
42 /* Shortcut definitions */
43 /***********************************************************/
45 #define NIG_STATUS_XGXS0_LINK10G \
46 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
47 #define NIG_STATUS_XGXS0_LINK_STATUS \
48 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
49 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
50 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
51 #define NIG_STATUS_SERDES0_LINK_STATUS \
52 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
53 #define NIG_MASK_MI_INT \
54 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
55 #define NIG_MASK_XGXS0_LINK10G \
56 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
57 #define NIG_MASK_XGXS0_LINK_STATUS \
58 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
59 #define NIG_MASK_SERDES0_LINK_STATUS \
60 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
62 #define MDIO_AN_CL73_OR_37_COMPLETE \
63 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
64 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
66 #define XGXS_RESET_BITS \
67 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
68 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
69 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
70 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
71 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
73 #define SERDES_RESET_BITS \
74 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
75 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
76 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
77 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
79 #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
80 #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
81 #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
82 #define AUTONEG_PARALLEL \
83 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
84 #define AUTONEG_SGMII_FIBER_AUTODET \
85 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
86 #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
88 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
89 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
90 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
91 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
92 #define GP_STATUS_SPEED_MASK \
93 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
94 #define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
95 #define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
96 #define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
97 #define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
98 #define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
99 #define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
100 #define GP_STATUS_10G_HIG \
101 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
102 #define GP_STATUS_10G_CX4 \
103 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
104 #define GP_STATUS_12G_HIG \
105 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
106 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
107 #define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
108 #define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
109 #define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
110 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
111 #define GP_STATUS_10G_KX4 \
112 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
114 #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
115 #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
116 #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
117 #define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
118 #define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
119 #define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
120 #define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
121 #define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
122 #define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
123 #define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
124 #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
125 #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
126 #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
127 #define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
128 #define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
129 #define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
130 #define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
131 #define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
132 #define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
133 #define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
134 #define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
135 #define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
136 #define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
138 #define PHY_XGXS_FLAG 0x1
139 #define PHY_SGMII_FLAG 0x2
140 #define PHY_SERDES_FLAG 0x4
143 #define SFP_EEPROM_CON_TYPE_ADDR 0x2
144 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
145 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
147 #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
148 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
149 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
150 #define SFP_EEPROM_VENDOR_NAME_ADDR 0x14
151 #define SFP_EEPROM_VENDOR_NAME_SIZE 16
152 #define SFP_EEPROM_OPTIONS_ADDR 0x40
153 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
154 #define SFP_EEPROM_OPTIONS_SIZE 2
156 #define SFP_MODULE_TYPE_UNKNOWN 0x0
157 #define SFP_MODULE_TYPE_LC 0x1
158 #define SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE 0x2
159 #define SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE 0x3
161 #define SFP_LIMITING_MODE_VALUE 0x0044
162 /**********************************************************/
164 /**********************************************************/
165 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
166 bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
167 DEFAULT_PHY_DEV_ADDR, \
168 (_bank + (_addr & 0xf)), \
171 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
172 bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
173 DEFAULT_PHY_DEV_ADDR, \
174 (_bank + (_addr & 0xf)), \
177 static void bnx2x_set_phy_mdio(struct link_params *params)
179 struct bnx2x *bp = params->bp;
180 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
181 params->port*0x18, 0);
182 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
183 DEFAULT_PHY_DEV_ADDR);
186 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
188 u32 val = REG_RD(bp, reg);
191 REG_WR(bp, reg, val);
195 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
197 u32 val = REG_RD(bp, reg);
200 REG_WR(bp, reg, val);
204 static void bnx2x_emac_init(struct link_params *params,
205 struct link_vars *vars)
207 /* reset and unreset the emac core */
208 struct bnx2x *bp = params->bp;
209 u8 port = params->port;
210 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
214 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
215 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
217 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
218 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
220 /* init emac - use read-modify-write */
221 /* self clear reset */
222 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
223 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
227 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
228 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
230 DP(NETIF_MSG_LINK, "EMAC timeout!\n");
234 } while (val & EMAC_MODE_RESET);
236 /* Set mac address */
237 val = ((params->mac_addr[0] << 8) |
238 params->mac_addr[1]);
239 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
241 val = ((params->mac_addr[2] << 24) |
242 (params->mac_addr[3] << 16) |
243 (params->mac_addr[4] << 8) |
244 params->mac_addr[5]);
245 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
248 static u8 bnx2x_emac_enable(struct link_params *params,
249 struct link_vars *vars, u8 lb)
251 struct bnx2x *bp = params->bp;
252 u8 port = params->port;
253 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
256 DP(NETIF_MSG_LINK, "enabling EMAC\n");
258 /* enable emac and not bmac */
259 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
262 if (CHIP_REV_IS_EMUL(bp)) {
263 /* Use lane 1 (of lanes 0-3) */
264 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
265 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
271 if (CHIP_REV_IS_FPGA(bp)) {
272 /* Use lane 1 (of lanes 0-3) */
273 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
275 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
276 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
280 if (vars->phy_flags & PHY_XGXS_FLAG) {
281 u32 ser_lane = ((params->lane_config &
282 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
283 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
285 DP(NETIF_MSG_LINK, "XGXS\n");
286 /* select the master lanes (out of 0-3) */
287 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
290 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
293 } else { /* SerDes */
294 DP(NETIF_MSG_LINK, "SerDes\n");
296 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
301 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
303 if (CHIP_REV_IS_SLOW(bp)) {
304 /* config GMII mode */
305 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
306 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
307 (val | EMAC_MODE_PORT_GMII));
309 /* pause enable/disable */
310 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
311 EMAC_RX_MODE_FLOW_EN);
312 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
313 bnx2x_bits_en(bp, emac_base +
314 EMAC_REG_EMAC_RX_MODE,
315 EMAC_RX_MODE_FLOW_EN);
317 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
318 (EMAC_TX_MODE_EXT_PAUSE_EN |
319 EMAC_TX_MODE_FLOW_EN));
320 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
321 bnx2x_bits_en(bp, emac_base +
322 EMAC_REG_EMAC_TX_MODE,
323 (EMAC_TX_MODE_EXT_PAUSE_EN |
324 EMAC_TX_MODE_FLOW_EN));
327 /* KEEP_VLAN_TAG, promiscuous */
328 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
329 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
330 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
333 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
338 EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
341 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
343 /* enable emac for jumbo packets */
344 EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
345 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
346 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
349 REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
351 /* disable the NIG in/out to the bmac */
352 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
353 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
354 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
356 /* enable the NIG in/out to the emac */
357 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
359 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
362 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
363 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
365 if (CHIP_REV_IS_EMUL(bp)) {
366 /* take the BigMac out of reset */
368 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
369 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
371 /* enable access for bmac registers */
372 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
375 vars->mac_type = MAC_TYPE_EMAC;
381 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
384 struct bnx2x *bp = params->bp;
385 u8 port = params->port;
386 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
387 NIG_REG_INGRESS_BMAC0_MEM;
391 DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
392 /* reset and unreset the BigMac */
393 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
394 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
397 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
398 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
400 /* enable access for bmac registers */
401 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
406 REG_WR_DMAE(bp, bmac_addr +
407 BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
411 wb_data[0] = ((params->mac_addr[2] << 24) |
412 (params->mac_addr[3] << 16) |
413 (params->mac_addr[4] << 8) |
414 params->mac_addr[5]);
415 wb_data[1] = ((params->mac_addr[0] << 8) |
416 params->mac_addr[1]);
417 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
422 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
426 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
433 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
437 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
442 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
444 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
447 /* rx control set to don't strip crc */
449 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
453 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
457 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
459 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
462 /* set cnt max size */
463 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
465 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
469 wb_data[0] = 0x1000200;
471 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
473 /* fix for emulation */
474 if (CHIP_REV_IS_EMUL(bp)) {
478 bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
482 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
483 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
484 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
486 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
488 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
489 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
490 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
491 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
492 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
493 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
495 vars->mac_type = MAC_TYPE_BMAC;
499 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
501 struct bnx2x *bp = params->bp;
504 if (phy_flags & PHY_XGXS_FLAG) {
505 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
506 val = XGXS_RESET_BITS;
508 } else { /* SerDes */
509 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
510 val = SERDES_RESET_BITS;
513 val = val << (params->port*16);
515 /* reset and unreset the SerDes/XGXS */
516 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
519 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
521 bnx2x_set_phy_mdio(params);
524 void bnx2x_link_status_update(struct link_params *params,
525 struct link_vars *vars)
527 struct bnx2x *bp = params->bp;
529 u8 port = params->port;
531 if (params->switch_cfg == SWITCH_CFG_1G)
532 vars->phy_flags = PHY_SERDES_FLAG;
534 vars->phy_flags = PHY_XGXS_FLAG;
535 vars->link_status = REG_RD(bp, params->shmem_base +
536 offsetof(struct shmem_region,
537 port_mb[port].link_status));
539 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
542 DP(NETIF_MSG_LINK, "phy link up\n");
544 vars->phy_link_up = 1;
545 vars->duplex = DUPLEX_FULL;
546 switch (vars->link_status &
547 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
549 vars->duplex = DUPLEX_HALF;
552 vars->line_speed = SPEED_10;
556 vars->duplex = DUPLEX_HALF;
560 vars->line_speed = SPEED_100;
564 vars->duplex = DUPLEX_HALF;
567 vars->line_speed = SPEED_1000;
571 vars->duplex = DUPLEX_HALF;
574 vars->line_speed = SPEED_2500;
578 vars->line_speed = SPEED_10000;
582 vars->line_speed = SPEED_12000;
586 vars->line_speed = SPEED_12500;
590 vars->line_speed = SPEED_13000;
594 vars->line_speed = SPEED_15000;
598 vars->line_speed = SPEED_16000;
605 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
606 vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
608 vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
610 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
611 vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
613 vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
615 if (vars->phy_flags & PHY_XGXS_FLAG) {
616 if (vars->line_speed &&
617 ((vars->line_speed == SPEED_10) ||
618 (vars->line_speed == SPEED_100))) {
619 vars->phy_flags |= PHY_SGMII_FLAG;
621 vars->phy_flags &= ~PHY_SGMII_FLAG;
625 /* anything 10 and over uses the bmac */
626 link_10g = ((vars->line_speed == SPEED_10000) ||
627 (vars->line_speed == SPEED_12000) ||
628 (vars->line_speed == SPEED_12500) ||
629 (vars->line_speed == SPEED_13000) ||
630 (vars->line_speed == SPEED_15000) ||
631 (vars->line_speed == SPEED_16000));
633 vars->mac_type = MAC_TYPE_BMAC;
635 vars->mac_type = MAC_TYPE_EMAC;
637 } else { /* link down */
638 DP(NETIF_MSG_LINK, "phy link down\n");
640 vars->phy_link_up = 0;
642 vars->line_speed = 0;
643 vars->duplex = DUPLEX_FULL;
644 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
646 /* indicate no mac active */
647 vars->mac_type = MAC_TYPE_NONE;
650 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
651 vars->link_status, vars->phy_link_up);
652 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
653 vars->line_speed, vars->duplex, vars->flow_ctrl);
656 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
658 struct bnx2x *bp = params->bp;
659 REG_WR(bp, params->shmem_base +
660 offsetof(struct shmem_region,
661 port_mb[params->port].link_status),
665 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
667 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
668 NIG_REG_INGRESS_BMAC0_MEM;
670 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
672 /* Only if the bmac is out of reset */
673 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
674 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
677 /* Clear Rx Enable bit in BMAC_CONTROL register */
678 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
680 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
681 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
688 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
691 struct bnx2x *bp = params->bp;
692 u8 port = params->port;
697 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
699 /* wait for init credit */
700 init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
701 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
702 DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
704 while ((init_crd != crd) && count) {
707 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
710 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
711 if (init_crd != crd) {
712 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
717 if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
718 line_speed == SPEED_10 ||
719 line_speed == SPEED_100 ||
720 line_speed == SPEED_1000 ||
721 line_speed == SPEED_2500) {
722 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
723 /* update threshold */
724 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
725 /* update init credit */
726 init_crd = 778; /* (800-18-4) */
729 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
731 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
732 /* update threshold */
733 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
734 /* update init credit */
735 switch (line_speed) {
737 init_crd = thresh + 553 - 22;
741 init_crd = thresh + 664 - 22;
745 init_crd = thresh + 742 - 22;
749 init_crd = thresh + 778 - 22;
752 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
758 REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
759 DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
760 line_speed, init_crd);
762 /* probe the credit changes */
763 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
765 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
768 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
772 static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
775 switch (ext_phy_type) {
776 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
777 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
778 /* All MDC/MDIO is directed through single EMAC */
779 if (REG_RD(bp, NIG_REG_PORT_SWAP))
780 emac_base = GRCBASE_EMAC0;
782 emac_base = GRCBASE_EMAC1;
784 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
785 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
788 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
795 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
796 u8 phy_addr, u8 devad, u16 reg, u16 val)
800 u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
802 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
803 * (a value of 49==0x31) and make sure that the AUTO poll is off
806 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
807 tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
808 EMAC_MDIO_MODE_CLOCK_CNT);
809 tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
810 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
811 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
812 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
817 tmp = ((phy_addr << 21) | (devad << 16) | reg |
818 EMAC_MDIO_COMM_COMMAND_ADDRESS |
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 + EMAC_REG_EMAC_MDIO_COMM);
826 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
831 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
832 DP(NETIF_MSG_LINK, "write phy register failed\n");
836 tmp = ((phy_addr << 21) | (devad << 16) | val |
837 EMAC_MDIO_COMM_COMMAND_WRITE_45 |
838 EMAC_MDIO_COMM_START_BUSY);
839 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
841 for (i = 0; i < 50; i++) {
844 tmp = REG_RD(bp, mdio_ctrl +
845 EMAC_REG_EMAC_MDIO_COMM);
846 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
851 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
852 DP(NETIF_MSG_LINK, "write phy register failed\n");
857 /* Restore the saved mode */
858 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
863 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
864 u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
870 u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
871 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
872 * (a value of 49==0x31) and make sure that the AUTO poll is off
875 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
876 val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
877 EMAC_MDIO_MODE_CLOCK_CNT));
878 val |= (EMAC_MDIO_MODE_CLAUSE_45 |
879 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
880 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
881 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
885 val = ((phy_addr << 21) | (devad << 16) | reg |
886 EMAC_MDIO_COMM_COMMAND_ADDRESS |
887 EMAC_MDIO_COMM_START_BUSY);
888 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
890 for (i = 0; i < 50; i++) {
893 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
894 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
899 if (val & EMAC_MDIO_COMM_START_BUSY) {
900 DP(NETIF_MSG_LINK, "read phy register failed\n");
907 val = ((phy_addr << 21) | (devad << 16) |
908 EMAC_MDIO_COMM_COMMAND_READ_45 |
909 EMAC_MDIO_COMM_START_BUSY);
910 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
912 for (i = 0; i < 50; i++) {
915 val = REG_RD(bp, mdio_ctrl +
916 EMAC_REG_EMAC_MDIO_COMM);
917 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
918 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
922 if (val & EMAC_MDIO_COMM_START_BUSY) {
923 DP(NETIF_MSG_LINK, "read phy register failed\n");
930 /* Restore the saved mode */
931 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
936 static void bnx2x_set_aer_mmd(struct link_params *params,
937 struct link_vars *vars)
939 struct bnx2x *bp = params->bp;
943 ser_lane = ((params->lane_config &
944 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
945 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
947 offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
948 (params->phy_addr + ser_lane) : 0;
950 CL45_WR_OVER_CL22(bp, params->port,
952 MDIO_REG_BANK_AER_BLOCK,
953 MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
956 static void bnx2x_set_master_ln(struct link_params *params)
958 struct bnx2x *bp = params->bp;
959 u16 new_master_ln, ser_lane;
960 ser_lane = ((params->lane_config &
961 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
962 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
964 /* set the master_ln for AN */
965 CL45_RD_OVER_CL22(bp, params->port,
967 MDIO_REG_BANK_XGXS_BLOCK2,
968 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
971 CL45_WR_OVER_CL22(bp, params->port,
973 MDIO_REG_BANK_XGXS_BLOCK2 ,
974 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
975 (new_master_ln | ser_lane));
978 static u8 bnx2x_reset_unicore(struct link_params *params)
980 struct bnx2x *bp = params->bp;
984 CL45_RD_OVER_CL22(bp, params->port,
986 MDIO_REG_BANK_COMBO_IEEE0,
987 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
989 /* reset the unicore */
990 CL45_WR_OVER_CL22(bp, params->port,
992 MDIO_REG_BANK_COMBO_IEEE0,
993 MDIO_COMBO_IEEE0_MII_CONTROL,
995 MDIO_COMBO_IEEO_MII_CONTROL_RESET));
997 /* wait for the reset to self clear */
998 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
1001 /* the reset erased the previous bank value */
1002 CL45_RD_OVER_CL22(bp, params->port,
1004 MDIO_REG_BANK_COMBO_IEEE0,
1005 MDIO_COMBO_IEEE0_MII_CONTROL,
1008 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1014 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1019 static void bnx2x_set_swap_lanes(struct link_params *params)
1021 struct bnx2x *bp = params->bp;
1022 /* Each two bits represents a lane number:
1023 No swap is 0123 => 0x1b no need to enable the swap */
1024 u16 ser_lane, rx_lane_swap, tx_lane_swap;
1026 ser_lane = ((params->lane_config &
1027 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1028 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1029 rx_lane_swap = ((params->lane_config &
1030 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1031 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1032 tx_lane_swap = ((params->lane_config &
1033 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1034 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1036 if (rx_lane_swap != 0x1b) {
1037 CL45_WR_OVER_CL22(bp, params->port,
1039 MDIO_REG_BANK_XGXS_BLOCK2,
1040 MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1042 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1043 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1045 CL45_WR_OVER_CL22(bp, params->port,
1047 MDIO_REG_BANK_XGXS_BLOCK2,
1048 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1051 if (tx_lane_swap != 0x1b) {
1052 CL45_WR_OVER_CL22(bp, params->port,
1054 MDIO_REG_BANK_XGXS_BLOCK2,
1055 MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1057 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1059 CL45_WR_OVER_CL22(bp, params->port,
1061 MDIO_REG_BANK_XGXS_BLOCK2,
1062 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1066 static void bnx2x_set_parallel_detection(struct link_params *params,
1069 struct bnx2x *bp = params->bp;
1072 CL45_RD_OVER_CL22(bp, params->port,
1074 MDIO_REG_BANK_SERDES_DIGITAL,
1075 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1079 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1082 CL45_WR_OVER_CL22(bp, params->port,
1084 MDIO_REG_BANK_SERDES_DIGITAL,
1085 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1088 if (phy_flags & PHY_XGXS_FLAG) {
1089 DP(NETIF_MSG_LINK, "XGXS\n");
1091 CL45_WR_OVER_CL22(bp, params->port,
1093 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1094 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1095 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1097 CL45_RD_OVER_CL22(bp, params->port,
1099 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1100 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1105 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1107 CL45_WR_OVER_CL22(bp, params->port,
1109 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1110 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1113 /* Disable parallel detection of HiG */
1114 CL45_WR_OVER_CL22(bp, params->port,
1116 MDIO_REG_BANK_XGXS_BLOCK2,
1117 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1118 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1119 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1123 static void bnx2x_set_autoneg(struct link_params *params,
1124 struct link_vars *vars)
1126 struct bnx2x *bp = params->bp;
1131 CL45_RD_OVER_CL22(bp, params->port,
1133 MDIO_REG_BANK_COMBO_IEEE0,
1134 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
1136 /* CL37 Autoneg Enabled */
1137 if (vars->line_speed == SPEED_AUTO_NEG)
1138 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1139 else /* CL37 Autoneg Disabled */
1140 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1141 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1143 CL45_WR_OVER_CL22(bp, params->port,
1145 MDIO_REG_BANK_COMBO_IEEE0,
1146 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1148 /* Enable/Disable Autodetection */
1150 CL45_RD_OVER_CL22(bp, params->port,
1152 MDIO_REG_BANK_SERDES_DIGITAL,
1153 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val);
1154 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1155 if (vars->line_speed == SPEED_AUTO_NEG)
1156 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1158 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1160 CL45_WR_OVER_CL22(bp, params->port,
1162 MDIO_REG_BANK_SERDES_DIGITAL,
1163 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1165 /* Enable TetonII and BAM autoneg */
1166 CL45_RD_OVER_CL22(bp, params->port,
1168 MDIO_REG_BANK_BAM_NEXT_PAGE,
1169 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1171 if (vars->line_speed == SPEED_AUTO_NEG) {
1172 /* Enable BAM aneg Mode and TetonII aneg Mode */
1173 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1174 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1176 /* TetonII and BAM Autoneg Disabled */
1177 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1178 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1180 CL45_WR_OVER_CL22(bp, params->port,
1182 MDIO_REG_BANK_BAM_NEXT_PAGE,
1183 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1186 /* Enable Clause 73 Aneg */
1187 if ((vars->line_speed == SPEED_AUTO_NEG) &&
1189 /* Enable BAM Station Manager */
1191 CL45_WR_OVER_CL22(bp, params->port,
1193 MDIO_REG_BANK_CL73_USERB0,
1194 MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1195 (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1196 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1197 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
1199 /* Merge CL73 and CL37 aneg resolution */
1200 CL45_RD_OVER_CL22(bp, params->port,
1202 MDIO_REG_BANK_CL73_USERB0,
1203 MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1206 CL45_WR_OVER_CL22(bp, params->port,
1208 MDIO_REG_BANK_CL73_USERB0,
1209 MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1211 MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
1213 /* Set the CL73 AN speed */
1215 CL45_RD_OVER_CL22(bp, params->port,
1217 MDIO_REG_BANK_CL73_IEEEB1,
1218 MDIO_CL73_IEEEB1_AN_ADV2, ®_val);
1219 /* In the SerDes we support only the 1G.
1220 In the XGXS we support the 10G KX4
1221 but we currently do not support the KR */
1222 if (vars->phy_flags & PHY_XGXS_FLAG) {
1223 DP(NETIF_MSG_LINK, "XGXS\n");
1225 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1227 DP(NETIF_MSG_LINK, "SerDes\n");
1229 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1231 CL45_WR_OVER_CL22(bp, params->port,
1233 MDIO_REG_BANK_CL73_IEEEB1,
1234 MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
1236 /* CL73 Autoneg Enabled */
1237 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
1239 /* CL73 Autoneg Disabled */
1242 CL45_WR_OVER_CL22(bp, params->port,
1244 MDIO_REG_BANK_CL73_IEEEB0,
1245 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1248 /* program SerDes, forced speed */
1249 static void bnx2x_program_serdes(struct link_params *params,
1250 struct link_vars *vars)
1252 struct bnx2x *bp = params->bp;
1255 /* program duplex, disable autoneg */
1257 CL45_RD_OVER_CL22(bp, params->port,
1259 MDIO_REG_BANK_COMBO_IEEE0,
1260 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
1261 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1262 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
1263 if (params->req_duplex == DUPLEX_FULL)
1264 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1265 CL45_WR_OVER_CL22(bp, params->port,
1267 MDIO_REG_BANK_COMBO_IEEE0,
1268 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1271 - needed only if the speed is greater than 1G (2.5G or 10G) */
1272 CL45_RD_OVER_CL22(bp, params->port,
1274 MDIO_REG_BANK_SERDES_DIGITAL,
1275 MDIO_SERDES_DIGITAL_MISC1, ®_val);
1276 /* clearing the speed value before setting the right speed */
1277 DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1279 reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1280 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1282 if (!((vars->line_speed == SPEED_1000) ||
1283 (vars->line_speed == SPEED_100) ||
1284 (vars->line_speed == SPEED_10))) {
1286 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1287 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1288 if (vars->line_speed == SPEED_10000)
1290 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1291 if (vars->line_speed == SPEED_13000)
1293 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1296 CL45_WR_OVER_CL22(bp, params->port,
1298 MDIO_REG_BANK_SERDES_DIGITAL,
1299 MDIO_SERDES_DIGITAL_MISC1, reg_val);
1303 static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1305 struct bnx2x *bp = params->bp;
1308 /* configure the 48 bits for BAM AN */
1310 /* set extended capabilities */
1311 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1312 val |= MDIO_OVER_1G_UP1_2_5G;
1313 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1314 val |= MDIO_OVER_1G_UP1_10G;
1315 CL45_WR_OVER_CL22(bp, params->port,
1317 MDIO_REG_BANK_OVER_1G,
1318 MDIO_OVER_1G_UP1, val);
1320 CL45_WR_OVER_CL22(bp, params->port,
1322 MDIO_REG_BANK_OVER_1G,
1323 MDIO_OVER_1G_UP3, 0);
1326 static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
1328 *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1329 /* resolve pause mode and advertisement
1330 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1332 switch (params->req_flow_ctrl) {
1333 case BNX2X_FLOW_CTRL_AUTO:
1334 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
1336 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1339 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1342 case BNX2X_FLOW_CTRL_TX:
1344 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1347 case BNX2X_FLOW_CTRL_RX:
1348 case BNX2X_FLOW_CTRL_BOTH:
1349 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1352 case BNX2X_FLOW_CTRL_NONE:
1354 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1359 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1362 struct bnx2x *bp = params->bp;
1363 /* for AN, we are always publishing full duplex */
1365 CL45_WR_OVER_CL22(bp, params->port,
1367 MDIO_REG_BANK_COMBO_IEEE0,
1368 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
1371 static void bnx2x_restart_autoneg(struct link_params *params)
1373 struct bnx2x *bp = params->bp;
1374 DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1376 /* enable and restart clause 73 aneg */
1379 CL45_RD_OVER_CL22(bp, params->port,
1381 MDIO_REG_BANK_CL73_IEEEB0,
1382 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1384 CL45_WR_OVER_CL22(bp, params->port,
1386 MDIO_REG_BANK_CL73_IEEEB0,
1387 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1389 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1390 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1393 /* Enable and restart BAM/CL37 aneg */
1396 CL45_RD_OVER_CL22(bp, params->port,
1398 MDIO_REG_BANK_COMBO_IEEE0,
1399 MDIO_COMBO_IEEE0_MII_CONTROL,
1402 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1404 CL45_WR_OVER_CL22(bp, params->port,
1406 MDIO_REG_BANK_COMBO_IEEE0,
1407 MDIO_COMBO_IEEE0_MII_CONTROL,
1409 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1410 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1414 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1415 struct link_vars *vars)
1417 struct bnx2x *bp = params->bp;
1420 /* in SGMII mode, the unicore is always slave */
1422 CL45_RD_OVER_CL22(bp, params->port,
1424 MDIO_REG_BANK_SERDES_DIGITAL,
1425 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1427 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1428 /* set sgmii mode (and not fiber) */
1429 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1430 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1431 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1432 CL45_WR_OVER_CL22(bp, params->port,
1434 MDIO_REG_BANK_SERDES_DIGITAL,
1435 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1438 /* if forced speed */
1439 if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1440 /* set speed, disable autoneg */
1443 CL45_RD_OVER_CL22(bp, params->port,
1445 MDIO_REG_BANK_COMBO_IEEE0,
1446 MDIO_COMBO_IEEE0_MII_CONTROL,
1448 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1449 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1450 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1452 switch (vars->line_speed) {
1455 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1459 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1462 /* there is nothing to set for 10M */
1465 /* invalid speed for SGMII */
1466 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1471 /* setting the full duplex */
1472 if (params->req_duplex == DUPLEX_FULL)
1474 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1475 CL45_WR_OVER_CL22(bp, params->port,
1477 MDIO_REG_BANK_COMBO_IEEE0,
1478 MDIO_COMBO_IEEE0_MII_CONTROL,
1481 } else { /* AN mode */
1482 /* enable and restart AN */
1483 bnx2x_restart_autoneg(params);
1492 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1494 switch (pause_result) { /* ASYM P ASYM P */
1495 case 0xb: /* 1 0 1 1 */
1496 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
1499 case 0xe: /* 1 1 1 0 */
1500 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
1503 case 0x5: /* 0 1 0 1 */
1504 case 0x7: /* 0 1 1 1 */
1505 case 0xd: /* 1 1 0 1 */
1506 case 0xf: /* 1 1 1 1 */
1507 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
1515 static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1516 struct link_vars *vars)
1518 struct bnx2x *bp = params->bp;
1520 u16 ld_pause; /* local */
1521 u16 lp_pause; /* link partner */
1522 u16 an_complete; /* AN complete */
1526 u8 port = params->port;
1527 ext_phy_addr = ((params->ext_phy_config &
1528 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1529 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1531 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1534 bnx2x_cl45_read(bp, port,
1538 MDIO_AN_REG_STATUS, &an_complete);
1539 bnx2x_cl45_read(bp, port,
1543 MDIO_AN_REG_STATUS, &an_complete);
1545 if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1547 bnx2x_cl45_read(bp, port,
1551 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1552 bnx2x_cl45_read(bp, port,
1556 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1557 pause_result = (ld_pause &
1558 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1559 pause_result |= (lp_pause &
1560 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1561 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1563 bnx2x_pause_resolve(vars, pause_result);
1564 if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
1565 ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1566 bnx2x_cl45_read(bp, port,
1570 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1572 bnx2x_cl45_read(bp, port,
1576 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1577 pause_result = (ld_pause &
1578 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1579 pause_result |= (lp_pause &
1580 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1582 bnx2x_pause_resolve(vars, pause_result);
1583 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1591 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1592 struct link_vars *vars,
1595 struct bnx2x *bp = params->bp;
1596 u16 ld_pause; /* local driver */
1597 u16 lp_pause; /* link partner */
1600 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1602 /* resolve from gp_status in case of AN complete and not sgmii */
1603 if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1604 (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1605 (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1606 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1607 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1608 CL45_RD_OVER_CL22(bp, params->port,
1610 MDIO_REG_BANK_COMBO_IEEE0,
1611 MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1613 CL45_RD_OVER_CL22(bp, params->port,
1615 MDIO_REG_BANK_COMBO_IEEE0,
1616 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1618 pause_result = (ld_pause &
1619 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1620 pause_result |= (lp_pause &
1621 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1622 DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1623 bnx2x_pause_resolve(vars, pause_result);
1624 } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1625 (bnx2x_ext_phy_resove_fc(params, vars))) {
1628 if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
1629 vars->flow_ctrl = params->req_fc_auto_adv;
1631 vars->flow_ctrl = params->req_flow_ctrl;
1633 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1637 static u8 bnx2x_link_settings_status(struct link_params *params,
1638 struct link_vars *vars,
1641 struct bnx2x *bp = params->bp;
1644 vars->link_status = 0;
1646 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1647 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1650 vars->phy_link_up = 1;
1651 vars->link_status |= LINK_STATUS_LINK_UP;
1653 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1654 vars->duplex = DUPLEX_FULL;
1656 vars->duplex = DUPLEX_HALF;
1658 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1660 switch (gp_status & GP_STATUS_SPEED_MASK) {
1662 new_line_speed = SPEED_10;
1663 if (vars->duplex == DUPLEX_FULL)
1664 vars->link_status |= LINK_10TFD;
1666 vars->link_status |= LINK_10THD;
1669 case GP_STATUS_100M:
1670 new_line_speed = SPEED_100;
1671 if (vars->duplex == DUPLEX_FULL)
1672 vars->link_status |= LINK_100TXFD;
1674 vars->link_status |= LINK_100TXHD;
1678 case GP_STATUS_1G_KX:
1679 new_line_speed = SPEED_1000;
1680 if (vars->duplex == DUPLEX_FULL)
1681 vars->link_status |= LINK_1000TFD;
1683 vars->link_status |= LINK_1000THD;
1686 case GP_STATUS_2_5G:
1687 new_line_speed = SPEED_2500;
1688 if (vars->duplex == DUPLEX_FULL)
1689 vars->link_status |= LINK_2500TFD;
1691 vars->link_status |= LINK_2500THD;
1697 "link speed unsupported gp_status 0x%x\n",
1701 case GP_STATUS_10G_KX4:
1702 case GP_STATUS_10G_HIG:
1703 case GP_STATUS_10G_CX4:
1704 new_line_speed = SPEED_10000;
1705 vars->link_status |= LINK_10GTFD;
1708 case GP_STATUS_12G_HIG:
1709 new_line_speed = SPEED_12000;
1710 vars->link_status |= LINK_12GTFD;
1713 case GP_STATUS_12_5G:
1714 new_line_speed = SPEED_12500;
1715 vars->link_status |= LINK_12_5GTFD;
1719 new_line_speed = SPEED_13000;
1720 vars->link_status |= LINK_13GTFD;
1724 new_line_speed = SPEED_15000;
1725 vars->link_status |= LINK_15GTFD;
1729 new_line_speed = SPEED_16000;
1730 vars->link_status |= LINK_16GTFD;
1735 "link speed unsupported gp_status 0x%x\n",
1741 /* Upon link speed change set the NIG into drain mode.
1742 Comes to deals with possible FIFO glitch due to clk change
1743 when speed is decreased without link down indicator */
1744 if (new_line_speed != vars->line_speed) {
1745 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
1746 + params->port*4, 0);
1749 vars->line_speed = new_line_speed;
1750 vars->link_status |= LINK_STATUS_SERDES_LINK;
1752 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1753 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1754 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1755 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1756 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
1757 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1758 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) {
1759 vars->autoneg = AUTO_NEG_ENABLED;
1761 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1762 vars->autoneg |= AUTO_NEG_COMPLETE;
1763 vars->link_status |=
1764 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1767 vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1768 vars->link_status |=
1769 LINK_STATUS_PARALLEL_DETECTION_USED;
1772 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1773 vars->link_status |=
1774 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1776 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1777 vars->link_status |=
1778 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1780 } else { /* link_down */
1781 DP(NETIF_MSG_LINK, "phy link down\n");
1783 vars->phy_link_up = 0;
1785 vars->duplex = DUPLEX_FULL;
1786 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1787 vars->autoneg = AUTO_NEG_DISABLED;
1788 vars->mac_type = MAC_TYPE_NONE;
1791 DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x \n",
1792 gp_status, vars->phy_link_up, vars->line_speed);
1793 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x"
1796 vars->flow_ctrl, vars->autoneg);
1797 DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1802 static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
1804 struct bnx2x *bp = params->bp;
1810 CL45_RD_OVER_CL22(bp, params->port,
1812 MDIO_REG_BANK_OVER_1G,
1813 MDIO_OVER_1G_LP_UP2, &lp_up2);
1815 CL45_RD_OVER_CL22(bp, params->port,
1818 MDIO_TX0_TX_DRIVER, &tx_driver);
1820 /* bits [10:7] at lp_up2, positioned at [15:12] */
1821 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1822 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1823 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1825 if ((lp_up2 != 0) &&
1826 (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
1827 /* replace tx_driver bits [15:12] */
1828 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1829 tx_driver |= lp_up2;
1830 CL45_WR_OVER_CL22(bp, params->port,
1833 MDIO_TX0_TX_DRIVER, tx_driver);
1837 static u8 bnx2x_emac_program(struct link_params *params,
1838 u32 line_speed, u32 duplex)
1840 struct bnx2x *bp = params->bp;
1841 u8 port = params->port;
1844 DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1845 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1847 (EMAC_MODE_25G_MODE |
1848 EMAC_MODE_PORT_MII_10M |
1849 EMAC_MODE_HALF_DUPLEX));
1850 switch (line_speed) {
1852 mode |= EMAC_MODE_PORT_MII_10M;
1856 mode |= EMAC_MODE_PORT_MII;
1860 mode |= EMAC_MODE_PORT_GMII;
1864 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1868 /* 10G not valid for EMAC */
1869 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1873 if (duplex == DUPLEX_HALF)
1874 mode |= EMAC_MODE_HALF_DUPLEX;
1876 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1879 bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1880 line_speed, params->hw_led_mode, params->chip_id);
1884 /*****************************************************************************/
1885 /* External Phy section */
1886 /*****************************************************************************/
1887 static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
1889 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1890 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
1892 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1893 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
1896 static void bnx2x_ext_phy_reset(struct link_params *params,
1897 struct link_vars *vars)
1899 struct bnx2x *bp = params->bp;
1901 u8 ext_phy_addr = ((params->ext_phy_config &
1902 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1903 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1904 DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1905 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1906 /* The PHY reset is controled by GPIO 1
1907 * Give it 1ms of reset pulse
1909 if (vars->phy_flags & PHY_XGXS_FLAG) {
1911 switch (ext_phy_type) {
1912 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1913 DP(NETIF_MSG_LINK, "XGXS Direct\n");
1916 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1917 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1918 DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1920 /* Restore normal power mode*/
1921 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1922 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1926 bnx2x_hw_reset(bp, params->port);
1928 bnx2x_cl45_write(bp, params->port,
1932 MDIO_PMA_REG_CTRL, 0xa040);
1934 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
1936 /* Restore normal power mode*/
1937 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1938 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1941 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1942 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1945 bnx2x_cl45_write(bp, params->port,
1953 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1954 /* Unset Low Power Mode and SW reset */
1955 /* Restore normal power mode*/
1956 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1957 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1960 DP(NETIF_MSG_LINK, "XGXS 8072\n");
1961 bnx2x_cl45_write(bp, params->port,
1968 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1971 emac_base = (params->port) ? GRCBASE_EMAC0 :
1974 /* Restore normal power mode*/
1975 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1976 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1979 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1980 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1983 DP(NETIF_MSG_LINK, "XGXS 8073\n");
1987 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1988 DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1990 /* Restore normal power mode*/
1991 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1992 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1996 bnx2x_hw_reset(bp, params->port);
2000 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2001 DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
2005 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
2006 params->ext_phy_config);
2010 } else { /* SerDes */
2011 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2012 switch (ext_phy_type) {
2013 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
2014 DP(NETIF_MSG_LINK, "SerDes Direct\n");
2017 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
2018 DP(NETIF_MSG_LINK, "SerDes 5482\n");
2019 bnx2x_hw_reset(bp, params->port);
2024 "BAD SerDes ext_phy_config 0x%x\n",
2025 params->ext_phy_config);
2031 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
2033 struct bnx2x *bp = params->bp;
2034 u8 port = params->port;
2035 u8 ext_phy_addr = ((params->ext_phy_config &
2036 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2037 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2038 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2039 u16 fw_ver1, fw_ver2;
2041 /* Need to wait 200ms after reset */
2043 /* Boot port from external ROM
2044 * Set ser_boot_ctl bit in the MISC_CTRL1 register
2046 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2048 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2050 /* Reset internal microprocessor */
2051 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2053 MDIO_PMA_REG_GEN_CTRL,
2054 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2055 /* set micro reset = 0 */
2056 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2058 MDIO_PMA_REG_GEN_CTRL,
2059 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2060 /* Reset internal microprocessor */
2061 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2063 MDIO_PMA_REG_GEN_CTRL,
2064 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2065 /* wait for 100ms for code download via SPI port */
2068 /* Clear ser_boot_ctl bit */
2069 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2071 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2075 /* Print the PHY FW version */
2076 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2078 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2079 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2081 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2082 DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2085 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2087 /* This is only required for 8073A1, version 102 only */
2089 struct bnx2x *bp = params->bp;
2090 u8 ext_phy_addr = ((params->ext_phy_config &
2091 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2092 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2095 /* Read 8073 HW revision*/
2096 bnx2x_cl45_read(bp, params->port,
2097 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2103 /* No need to workaround in 8073 A1 */
2107 bnx2x_cl45_read(bp, params->port,
2108 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2111 MDIO_PMA_REG_ROM_VER2, &val);
2113 /* SNR should be applied only for version 0x102 */
2120 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2122 struct bnx2x *bp = params->bp;
2123 u8 ext_phy_addr = ((params->ext_phy_config &
2124 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2125 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2126 u16 val, cnt, cnt1 ;
2128 bnx2x_cl45_read(bp, params->port,
2129 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2135 /* No need to workaround in 8073 A1 */
2138 /* XAUI workaround in 8073 A0: */
2140 /* After loading the boot ROM and restarting Autoneg,
2141 poll Dev1, Reg $C820: */
2143 for (cnt = 0; cnt < 1000; cnt++) {
2144 bnx2x_cl45_read(bp, params->port,
2145 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2149 /* If bit [14] = 0 or bit [13] = 0, continue on with
2150 system initialization (XAUI work-around not required,
2151 as these bits indicate 2.5G or 1G link up). */
2152 if (!(val & (1<<14)) || !(val & (1<<13))) {
2153 DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2155 } else if (!(val & (1<<15))) {
2156 DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2157 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2158 it's MSB (bit 15) goes to 1 (indicating that the
2159 XAUI workaround has completed),
2160 then continue on with system initialization.*/
2161 for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2162 bnx2x_cl45_read(bp, params->port,
2163 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2167 if (val & (1<<15)) {
2169 "XAUI workaround has completed\n");
2178 DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2183 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2186 u16 fw_ver1, fw_ver2;
2187 /* Boot port from external ROM */
2189 bnx2x_cl45_write(bp, port,
2190 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2193 MDIO_PMA_REG_GEN_CTRL,
2196 /* ucode reboot and rst */
2197 bnx2x_cl45_write(bp, port,
2198 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2201 MDIO_PMA_REG_GEN_CTRL,
2204 bnx2x_cl45_write(bp, port,
2205 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2208 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2210 /* Reset internal microprocessor */
2211 bnx2x_cl45_write(bp, port,
2212 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2215 MDIO_PMA_REG_GEN_CTRL,
2216 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2218 /* Release srst bit */
2219 bnx2x_cl45_write(bp, port,
2220 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2223 MDIO_PMA_REG_GEN_CTRL,
2224 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2226 /* wait for 100ms for code download via SPI port */
2229 /* Clear ser_boot_ctl bit */
2230 bnx2x_cl45_write(bp, port,
2231 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2234 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2236 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2239 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2240 bnx2x_cl45_read(bp, port,
2241 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2244 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2245 DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2249 static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
2251 struct bnx2x *bp = params->bp;
2252 u8 port = params->port;
2253 u8 ext_phy_addr = ((params->ext_phy_config &
2254 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2255 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2256 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2258 /* Need to wait 100ms after reset */
2261 /* Set serial boot control for external load */
2262 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2264 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2266 /* Micro controller re-boot */
2267 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2269 MDIO_PMA_REG_GEN_CTRL,
2270 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2272 /* Set soft reset */
2273 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2275 MDIO_PMA_REG_GEN_CTRL,
2276 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2278 /* Clear soft reset.
2279 Will automatically reset micro-controller re-boot */
2280 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2282 MDIO_PMA_REG_GEN_CTRL,
2283 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2285 /* wait for 100ms for microcode load */
2288 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
2289 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2291 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2296 static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port,
2297 u8 ext_phy_addr, u8 tx_en)
2300 DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
2302 /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
2303 bnx2x_cl45_read(bp, port,
2304 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2307 MDIO_PMA_REG_PHY_IDENTIFIER,
2315 bnx2x_cl45_write(bp, port,
2316 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2319 MDIO_PMA_REG_PHY_IDENTIFIER,
2324 static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
2325 u8 byte_cnt, u8 *o_buf) {
2326 struct bnx2x *bp = params->bp;
2328 u8 port = params->port;
2329 u8 ext_phy_addr = ((params->ext_phy_config &
2330 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2331 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2332 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2333 if (byte_cnt > 16) {
2334 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2335 " is limited to 0xf\n");
2338 /* Set the read command byte count */
2339 bnx2x_cl45_write(bp, port,
2343 MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT,
2344 (byte_cnt | 0xa000));
2346 /* Set the read command address */
2347 bnx2x_cl45_write(bp, port,
2351 MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR,
2354 /* Activate read command */
2355 bnx2x_cl45_write(bp, port,
2359 MDIO_PMA_REG_8726_TWO_WIRE_CTRL,
2362 /* Wait up to 500us for command complete status */
2363 for (i = 0; i < 100; i++) {
2364 bnx2x_cl45_read(bp, port,
2368 MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2369 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2370 MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE)
2375 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) !=
2376 MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE) {
2378 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2379 (val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK));
2383 /* Read the buffer */
2384 for (i = 0; i < byte_cnt; i++) {
2385 bnx2x_cl45_read(bp, port,
2389 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2390 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
2393 for (i = 0; i < 100; i++) {
2394 bnx2x_cl45_read(bp, port,
2398 MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2399 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2400 MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE)
2408 static u8 bnx2x_get_sfp_module_type(struct link_params *params,
2411 struct bnx2x *bp = params->bp;
2413 *module_type = SFP_MODULE_TYPE_UNKNOWN;
2415 /* First check for copper cable */
2416 if (bnx2x_read_sfp_module_eeprom(params,
2417 SFP_EEPROM_CON_TYPE_ADDR,
2420 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM");
2425 case SFP_EEPROM_CON_TYPE_VAL_COPPER:
2427 u8 copper_module_type;
2428 /* Check if its active cable( includes SFP+ module)
2430 if (bnx2x_read_sfp_module_eeprom(params,
2431 SFP_EEPROM_FC_TX_TECH_ADDR,
2433 &copper_module_type) !=
2436 "Failed to read copper-cable-type"
2437 " from SFP+ EEPROM\n");
2441 if (copper_module_type &
2442 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
2443 DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
2444 *module_type = SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE;
2445 } else if (copper_module_type &
2446 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
2447 DP(NETIF_MSG_LINK, "Passive Copper"
2448 " cable detected\n");
2450 SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE;
2452 DP(NETIF_MSG_LINK, "Unknown copper-cable-"
2453 "type 0x%x !!!\n", copper_module_type);
2458 case SFP_EEPROM_CON_TYPE_VAL_LC:
2459 DP(NETIF_MSG_LINK, "Optic module detected\n");
2460 *module_type = SFP_MODULE_TYPE_LC;
2464 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
2472 /* This function read the relevant field from the module ( SFP+ ),
2473 and verify it is compliant with this board */
2474 static u8 bnx2x_verify_sfp_module(struct link_params *params,
2477 struct bnx2x *bp = params->bp;
2478 u8 *str_p, *tmp_buf;
2481 #define COMPLIANCE_STR_CNT 6
2482 u8 *compliance_str[] = {"Broadcom", "JDSU", "Molex Inc", "PICOLIGHT",
2483 "FINISAR CORP. ", "Amphenol"};
2484 u8 buf[SFP_EEPROM_VENDOR_NAME_SIZE];
2485 /* Passive Copper cables are allowed to participate,
2486 since the module is hardwired to the copper cable */
2488 if (!(params->feature_config_flags &
2489 FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2490 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
2494 if (module_type != SFP_MODULE_TYPE_LC) {
2495 DP(NETIF_MSG_LINK, "No need to verify copper cable\n");
2499 /* In case of non copper cable or Active copper cable,
2500 verify that the SFP+ module is compliant with this board*/
2501 if (bnx2x_read_sfp_module_eeprom(params,
2502 SFP_EEPROM_VENDOR_NAME_ADDR,
2503 SFP_EEPROM_VENDOR_NAME_SIZE,
2505 DP(NETIF_MSG_LINK, "Failed to read Vendor-Name from"
2506 " module EEPROM\n");
2509 for (i = 0; i < COMPLIANCE_STR_CNT; i++) {
2510 str_p = compliance_str[i];
2513 if ((u8)(*tmp_buf) != (u8)(*str_p))
2520 DP(NETIF_MSG_LINK, "SFP+ Module verified, "
2525 DP(NETIF_MSG_LINK, "Incompliant SFP+ module. Disable module !!!\n");
2530 static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
2533 struct bnx2x *bp = params->bp;
2534 u8 port = params->port;
2535 u8 options[SFP_EEPROM_OPTIONS_SIZE];
2537 u8 ext_phy_addr = ((params->ext_phy_config &
2538 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2539 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2541 if (bnx2x_read_sfp_module_eeprom(params,
2542 SFP_EEPROM_OPTIONS_ADDR,
2543 SFP_EEPROM_OPTIONS_SIZE,
2545 DP(NETIF_MSG_LINK, "Failed to read Option field from"
2546 " module EEPROM\n");
2549 limiting_mode = !(options[0] &
2550 SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK);
2551 if (limiting_mode &&
2552 (module_type != SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE)) {
2554 "Module options = 0x%x.Setting LIMITING MODE\n",
2556 bnx2x_cl45_write(bp, port,
2557 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2560 MDIO_PMA_REG_ROM_VER2,
2561 SFP_LIMITING_MODE_VALUE);
2562 } else { /* LRM mode ( default )*/
2563 u16 cur_limiting_mode;
2564 DP(NETIF_MSG_LINK, "Module options = 0x%x.Setting LRM MODE\n",
2567 bnx2x_cl45_read(bp, port,
2568 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2571 MDIO_PMA_REG_ROM_VER2,
2572 &cur_limiting_mode);
2574 /* Changing to LRM mode takes quite few seconds.
2575 So do it only if current mode is limiting
2576 ( default is LRM )*/
2577 if (cur_limiting_mode != SFP_LIMITING_MODE_VALUE)
2580 bnx2x_cl45_write(bp, port,
2581 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2584 MDIO_PMA_REG_LRM_MODE,
2586 bnx2x_cl45_write(bp, port,
2587 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2590 MDIO_PMA_REG_ROM_VER2,
2592 bnx2x_cl45_write(bp, port,
2593 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2596 MDIO_PMA_REG_MISC_CTRL0,
2598 bnx2x_cl45_write(bp, port,
2599 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2602 MDIO_PMA_REG_LRM_MODE,
2608 static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
2611 struct bnx2x *bp = params->bp;
2613 /* Initialization time after hot-plug may take up to 300ms for some
2614 phys type ( e.g. JDSU ) */
2615 for (timeout = 0; timeout < 60; timeout++) {
2616 if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
2618 DP(NETIF_MSG_LINK, "SFP+ module initialization "
2619 "took %d ms\n", timeout * 5);
2627 static u8 bnx2x_sfp_module_detection(struct link_params *params)
2629 struct bnx2x *bp = params->bp;
2631 u8 ext_phy_addr = ((params->ext_phy_config &
2632 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2633 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2634 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2636 if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
2637 DP(NETIF_MSG_LINK, "Module detection is not required "
2642 DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
2645 if (bnx2x_get_sfp_module_type(params,
2646 &module_type) != 0) {
2647 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
2648 if (!(params->feature_config_flags &
2649 FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2650 /* In case module detection is disabled, it trys to
2651 link up. The issue that can happen here is LRM /
2652 LIMITING mode which set according to the module-type*/
2653 DP(NETIF_MSG_LINK, "Unable to read module-type."
2654 "Probably due to Bit Stretching."
2655 " Proceeding...\n");
2659 } else if (bnx2x_verify_sfp_module(params, module_type) !=
2661 /* check SFP+ module compatibility */
2662 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
2663 /* Turn on fault module-detected led */
2664 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2665 MISC_REGISTERS_GPIO_HIGH,
2670 /* Turn off fault module-detected led */
2671 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2672 MISC_REGISTERS_GPIO_LOW,
2675 /* Check and set limiting mode / LRM mode */
2676 if (bnx2x_bcm8726_set_limiting_mode(params, module_type)
2678 DP(NETIF_MSG_LINK, "Setting limiting mode failed!!\n");
2682 /* Enable transmit for this module */
2683 bnx2x_bcm8726_set_transmitter(bp, params->port,
2688 void bnx2x_handle_module_detect_int(struct link_params *params)
2690 struct bnx2x *bp = params->bp;
2692 u8 port = params->port;
2693 /* Set valid module led off */
2694 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2695 MISC_REGISTERS_GPIO_HIGH,
2698 /* Get current gpio val refelecting module plugged in / out*/
2699 gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
2701 /* Call the handling function in case module is detected */
2702 if (gpio_val == 0) {
2704 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2705 MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
2708 if (bnx2x_wait_for_sfp_module_initialized(params)
2710 bnx2x_sfp_module_detection(params);
2712 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
2714 u8 ext_phy_addr = ((params->ext_phy_config &
2715 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2716 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2717 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2718 MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
2720 /* Module was plugged out. */
2721 /* Disable transmit for this module */
2722 bnx2x_bcm8726_set_transmitter(bp, params->port,
2727 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2729 struct bnx2x *bp = params->bp;
2730 u8 port = params->port;
2731 u8 ext_phy_addr = ((params->ext_phy_config &
2732 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2733 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2734 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2736 /* Force KR or KX */
2737 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2741 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2743 MDIO_PMA_REG_10G_CTRL2,
2745 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2747 MDIO_PMA_REG_BCM_CTRL,
2749 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2754 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2756 struct bnx2x *bp = params->bp;
2757 u8 port = params->port;
2759 u8 ext_phy_addr = ((params->ext_phy_config &
2760 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2761 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2762 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2764 bnx2x_cl45_read(bp, params->port,
2765 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2771 /* Mustn't set low power mode in 8073 A0 */
2775 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2776 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2778 MDIO_XS_PLL_SEQUENCER, &val);
2780 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2781 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2784 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2785 MDIO_XS_DEVAD, 0x805E, 0x1077);
2786 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2787 MDIO_XS_DEVAD, 0x805D, 0x0000);
2788 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2789 MDIO_XS_DEVAD, 0x805C, 0x030B);
2790 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2791 MDIO_XS_DEVAD, 0x805B, 0x1240);
2792 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2793 MDIO_XS_DEVAD, 0x805A, 0x2490);
2796 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2797 MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2798 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2799 MDIO_XS_DEVAD, 0x80A6, 0x9041);
2800 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2801 MDIO_XS_DEVAD, 0x80A5, 0x4640);
2804 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2805 MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2806 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2807 MDIO_XS_DEVAD, 0x80FD, 0x9249);
2808 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2809 MDIO_XS_DEVAD, 0x80FC, 0x2015);
2811 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
2812 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2814 MDIO_XS_PLL_SEQUENCER, &val);
2816 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2817 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2820 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
2821 struct link_vars *vars)
2824 struct bnx2x *bp = params->bp;
2826 u8 ext_phy_addr = ((params->ext_phy_config &
2827 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2828 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2829 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2831 bnx2x_cl45_read(bp, params->port,
2835 MDIO_AN_REG_CL37_FC_LD, &cl37_val);
2837 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2838 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2840 if ((vars->ieee_fc &
2841 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
2842 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
2843 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
2845 if ((vars->ieee_fc &
2846 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2847 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2848 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2850 if ((vars->ieee_fc &
2851 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2852 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2853 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2856 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
2858 bnx2x_cl45_write(bp, params->port,
2862 MDIO_AN_REG_CL37_FC_LD, cl37_val);
2866 static void bnx2x_ext_phy_set_pause(struct link_params *params,
2867 struct link_vars *vars)
2869 struct bnx2x *bp = params->bp;
2871 u8 ext_phy_addr = ((params->ext_phy_config &
2872 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2873 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2874 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2876 /* read modify write pause advertizing */
2877 bnx2x_cl45_read(bp, params->port,
2881 MDIO_AN_REG_ADV_PAUSE, &val);
2883 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2885 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2887 if ((vars->ieee_fc &
2888 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2889 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2890 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2892 if ((vars->ieee_fc &
2893 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2894 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2896 MDIO_AN_REG_ADV_PAUSE_PAUSE;
2899 "Ext phy AN advertize 0x%x\n", val);
2900 bnx2x_cl45_write(bp, params->port,
2904 MDIO_AN_REG_ADV_PAUSE, val);
2908 static void bnx2x_init_internal_phy(struct link_params *params,
2909 struct link_vars *vars)
2911 struct bnx2x *bp = params->bp;
2912 u8 port = params->port;
2913 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2916 rx_eq = ((params->serdes_config &
2917 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2918 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2920 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2921 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2922 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2923 CL45_WR_OVER_CL22(bp, port,
2926 MDIO_RX0_RX_EQ_BOOST,
2928 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2929 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2932 /* forced speed requested? */
2933 if (vars->line_speed != SPEED_AUTO_NEG) {
2934 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2936 /* disable autoneg */
2937 bnx2x_set_autoneg(params, vars);
2939 /* program speed and duplex */
2940 bnx2x_program_serdes(params, vars);
2942 } else { /* AN_mode */
2943 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2946 bnx2x_set_brcm_cl37_advertisment(params);
2948 /* program duplex & pause advertisement (for aneg) */
2949 bnx2x_set_ieee_aneg_advertisment(params,
2952 /* enable autoneg */
2953 bnx2x_set_autoneg(params, vars);
2955 /* enable and restart AN */
2956 bnx2x_restart_autoneg(params);
2959 } else { /* SGMII mode */
2960 DP(NETIF_MSG_LINK, "SGMII\n");
2962 bnx2x_initialize_sgmii_process(params, vars);
2966 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2968 struct bnx2x *bp = params->bp;
2975 if (vars->phy_flags & PHY_XGXS_FLAG) {
2976 ext_phy_addr = ((params->ext_phy_config &
2977 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2978 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2980 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2981 /* Make sure that the soft reset is off (expect for the 8072:
2982 * due to the lock, it will be done inside the specific
2985 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
2986 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
2987 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
2988 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
2989 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
2990 /* Wait for soft reset to get cleared upto 1 sec */
2991 for (cnt = 0; cnt < 1000; cnt++) {
2992 bnx2x_cl45_read(bp, params->port,
2996 MDIO_PMA_REG_CTRL, &ctrl);
2997 if (!(ctrl & (1<<15)))
3001 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
3005 switch (ext_phy_type) {
3006 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3009 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3010 DP(NETIF_MSG_LINK, "XGXS 8705\n");
3012 bnx2x_cl45_write(bp, params->port,
3016 MDIO_PMA_REG_MISC_CTRL,
3018 bnx2x_cl45_write(bp, params->port,
3022 MDIO_PMA_REG_PHY_IDENTIFIER,
3024 bnx2x_cl45_write(bp, params->port,
3028 MDIO_PMA_REG_CMU_PLL_BYPASS,
3030 bnx2x_cl45_write(bp, params->port,
3034 MDIO_WIS_REG_LASI_CNTL, 0x1);
3037 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3038 DP(NETIF_MSG_LINK, "XGXS 8706\n");
3042 /* First enable LASI */
3043 bnx2x_cl45_write(bp, params->port,
3047 MDIO_PMA_REG_RX_ALARM_CTRL,
3049 bnx2x_cl45_write(bp, params->port,
3053 MDIO_PMA_REG_LASI_CTRL, 0x0004);
3055 if (params->req_line_speed == SPEED_10000) {
3056 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
3058 bnx2x_cl45_write(bp, params->port,
3062 MDIO_PMA_REG_DIGITAL_CTRL,
3065 /* Force 1Gbps using autoneg with 1G
3068 /* Allow CL37 through CL73 */
3069 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
3070 bnx2x_cl45_write(bp, params->port,
3074 MDIO_AN_REG_CL37_CL73,
3077 /* Enable Full-Duplex advertisment on CL37 */
3078 bnx2x_cl45_write(bp, params->port,
3082 MDIO_AN_REG_CL37_FC_LP,
3084 /* Enable CL37 AN */
3085 bnx2x_cl45_write(bp, params->port,
3089 MDIO_AN_REG_CL37_AN,
3092 bnx2x_cl45_write(bp, params->port,
3096 MDIO_AN_REG_ADV, (1<<5));
3098 /* Enable clause 73 AN */
3099 bnx2x_cl45_write(bp, params->port,
3109 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3110 DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3111 bnx2x_bcm8726_external_rom_boot(params);
3113 /* Need to call module detected on initialization since
3114 the module detection triggered by actual module
3115 insertion might occur before driver is loaded, and when
3116 driver is loaded, it reset all registers, including the
3118 bnx2x_sfp_module_detection(params);
3119 if (params->req_line_speed == SPEED_1000) {
3120 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3121 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3122 ext_phy_addr, MDIO_PMA_DEVAD,
3123 MDIO_PMA_REG_CTRL, 0x40);
3124 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3125 ext_phy_addr, MDIO_PMA_DEVAD,
3126 MDIO_PMA_REG_10G_CTRL2, 0xD);
3127 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3128 ext_phy_addr, MDIO_PMA_DEVAD,
3129 MDIO_PMA_REG_LASI_CTRL, 0x5);
3130 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3131 ext_phy_addr, MDIO_PMA_DEVAD,
3132 MDIO_PMA_REG_RX_ALARM_CTRL,
3134 } else if ((params->req_line_speed ==
3136 ((params->speed_cap_mask &
3137 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3138 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
3139 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3140 ext_phy_addr, MDIO_AN_DEVAD,
3141 MDIO_AN_REG_ADV, 0x20);
3142 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3143 ext_phy_addr, MDIO_AN_DEVAD,
3144 MDIO_AN_REG_CL37_CL73, 0x040c);
3145 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3146 ext_phy_addr, MDIO_AN_DEVAD,
3147 MDIO_AN_REG_CL37_FC_LD, 0x0020);
3148 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3149 ext_phy_addr, MDIO_AN_DEVAD,
3150 MDIO_AN_REG_CL37_AN, 0x1000);
3151 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3152 ext_phy_addr, MDIO_AN_DEVAD,
3153 MDIO_AN_REG_CTRL, 0x1200);
3155 /* Enable RX-ALARM control to receive
3156 interrupt for 1G speed change */
3157 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3158 ext_phy_addr, MDIO_PMA_DEVAD,
3159 MDIO_PMA_REG_LASI_CTRL, 0x4);
3160 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3161 ext_phy_addr, MDIO_PMA_DEVAD,
3162 MDIO_PMA_REG_RX_ALARM_CTRL,
3165 } else { /* Default 10G. Set only LASI control */
3166 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3167 ext_phy_addr, MDIO_PMA_DEVAD,
3168 MDIO_PMA_REG_LASI_CTRL, 1);
3171 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3172 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3175 u16 rx_alarm_ctrl_val;
3178 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3179 rx_alarm_ctrl_val = 0x400;
3180 lasi_ctrl_val = 0x0004;
3182 rx_alarm_ctrl_val = (1<<2);
3183 lasi_ctrl_val = 0x0004;
3187 bnx2x_cl45_write(bp, params->port,
3191 MDIO_PMA_REG_RX_ALARM_CTRL,
3194 bnx2x_cl45_write(bp, params->port,
3198 MDIO_PMA_REG_LASI_CTRL,
3201 bnx2x_8073_set_pause_cl37(params, vars);
3204 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
3205 bnx2x_bcm8072_external_rom_boot(params);
3208 /* In case of 8073 with long xaui lines,
3209 don't set the 8073 xaui low power*/
3210 bnx2x_bcm8073_set_xaui_low_power_mode(params);
3213 bnx2x_cl45_read(bp, params->port,
3220 bnx2x_cl45_read(bp, params->port,
3224 MDIO_PMA_REG_RX_ALARM, &tmp1);
3226 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
3229 /* If this is forced speed, set to KR or KX
3230 * (all other are not supported)
3232 if (params->loopback_mode == LOOPBACK_EXT) {
3233 bnx2x_bcm807x_force_10G(params);
3235 "Forced speed 10G on 807X\n");
3238 bnx2x_cl45_write(bp, params->port,
3239 ext_phy_type, ext_phy_addr,
3241 MDIO_PMA_REG_BCM_CTRL,
3244 if (params->req_line_speed != SPEED_AUTO_NEG) {
3245 if (params->req_line_speed == SPEED_10000) {
3247 } else if (params->req_line_speed ==
3250 /* Note that 2.5G works only
3251 when used with 1G advertisment */
3257 if (params->speed_cap_mask &
3258 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3261 /* Note that 2.5G works only when
3262 used with 1G advertisment */
3263 if (params->speed_cap_mask &
3264 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
3265 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
3268 "807x autoneg val = 0x%x\n", val);
3271 bnx2x_cl45_write(bp, params->port,
3275 MDIO_AN_REG_ADV, val);
3278 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3280 bnx2x_cl45_read(bp, params->port,
3286 if (((params->speed_cap_mask &
3287 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
3288 (params->req_line_speed ==
3290 (params->req_line_speed ==
3293 /* Allow 2.5G for A1 and above */
3294 bnx2x_cl45_read(bp, params->port,
3295 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
3299 DP(NETIF_MSG_LINK, "Add 2.5G\n");
3305 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
3309 bnx2x_cl45_write(bp, params->port,
3316 /* Add support for CL37 (passive mode) II */
3318 bnx2x_cl45_read(bp, params->port,
3322 MDIO_AN_REG_CL37_FC_LD,
3325 bnx2x_cl45_write(bp, params->port,
3329 MDIO_AN_REG_CL37_FC_LD, (tmp1 |
3330 ((params->req_duplex == DUPLEX_FULL) ?
3333 /* Add support for CL37 (passive mode) III */
3334 bnx2x_cl45_write(bp, params->port,
3338 MDIO_AN_REG_CL37_AN, 0x1000);
3341 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3342 /* The SNR will improve about 2db by changing
3343 BW and FEE main tap. Rest commands are executed
3345 /*Change FFE main cursor to 5 in EDC register*/
3346 if (bnx2x_8073_is_snr_needed(params))
3347 bnx2x_cl45_write(bp, params->port,
3351 MDIO_PMA_REG_EDC_FFE_MAIN,
3354 /* Enable FEC (Forware Error Correction)
3355 Request in the AN */
3356 bnx2x_cl45_read(bp, params->port,
3360 MDIO_AN_REG_ADV2, &tmp1);
3364 bnx2x_cl45_write(bp, params->port,
3368 MDIO_AN_REG_ADV2, tmp1);
3372 bnx2x_ext_phy_set_pause(params, vars);
3374 /* Restart autoneg */
3376 bnx2x_cl45_write(bp, params->port,
3380 MDIO_AN_REG_CTRL, 0x1200);
3381 DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
3382 "Advertise 1G=%x, 10G=%x\n",
3383 ((val & (1<<5)) > 0),
3384 ((val & (1<<7)) > 0));
3387 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3389 "Setting the SFX7101 LASI indication\n");
3391 bnx2x_cl45_write(bp, params->port,
3395 MDIO_PMA_REG_LASI_CTRL, 0x1);
3397 "Setting the SFX7101 LED to blink on traffic\n");
3398 bnx2x_cl45_write(bp, params->port,
3402 MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
3404 bnx2x_ext_phy_set_pause(params, vars);
3405 /* Restart autoneg */
3406 bnx2x_cl45_read(bp, params->port,
3410 MDIO_AN_REG_CTRL, &val);
3412 bnx2x_cl45_write(bp, params->port,
3416 MDIO_AN_REG_CTRL, val);
3418 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
3420 "XGXS PHY Failure detected 0x%x\n",
3421 params->ext_phy_config);
3425 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3426 params->ext_phy_config);
3431 } else { /* SerDes */
3433 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3434 switch (ext_phy_type) {
3435 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3436 DP(NETIF_MSG_LINK, "SerDes Direct\n");
3439 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3440 DP(NETIF_MSG_LINK, "SerDes 5482\n");
3444 DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
3445 params->ext_phy_config);
3453 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
3454 struct link_vars *vars)
3456 struct bnx2x *bp = params->bp;
3460 u16 rx_sd, pcs_status;
3461 u8 ext_phy_link_up = 0;
3462 u8 port = params->port;
3463 if (vars->phy_flags & PHY_XGXS_FLAG) {
3464 ext_phy_addr = ((params->ext_phy_config &
3465 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3466 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3468 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3469 switch (ext_phy_type) {
3470 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3471 DP(NETIF_MSG_LINK, "XGXS Direct\n");
3472 ext_phy_link_up = 1;
3475 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3476 DP(NETIF_MSG_LINK, "XGXS 8705\n");
3477 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3480 MDIO_WIS_REG_LASI_STATUS, &val1);
3481 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3483 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3486 MDIO_WIS_REG_LASI_STATUS, &val1);
3487 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3489 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3492 MDIO_PMA_REG_RX_SD, &rx_sd);
3493 DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
3494 ext_phy_link_up = (rx_sd & 0x1);
3495 if (ext_phy_link_up)
3496 vars->line_speed = SPEED_10000;
3499 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3500 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3501 DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
3503 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3505 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
3507 /* clear LASI indication*/
3508 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3510 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
3512 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3514 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
3516 DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
3517 "0x%x\n", val1, val2);
3519 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3521 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
3523 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3525 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
3527 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3529 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
3531 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3533 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
3536 DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
3537 " pcs_status 0x%x 1Gbps link_status 0x%x\n",
3538 rx_sd, pcs_status, val2);
3539 /* link is up if both bit 0 of pmd_rx_sd and
3540 * bit 0 of pcs_status are set, or if the autoneg bit
3543 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
3545 if (ext_phy_link_up) {
3547 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
3548 /* If transmitter is disabled,
3549 ignore false link up indication */
3550 bnx2x_cl45_read(bp, params->port,
3554 MDIO_PMA_REG_PHY_IDENTIFIER,
3556 if (val1 & (1<<15)) {
3557 DP(NETIF_MSG_LINK, "Tx is "
3559 ext_phy_link_up = 0;
3565 vars->line_speed = SPEED_1000;
3567 vars->line_speed = SPEED_10000;
3571 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3572 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3574 u16 link_status = 0;
3575 u16 an1000_status = 0;
3577 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3578 bnx2x_cl45_read(bp, params->port,
3582 MDIO_PCS_REG_LASI_STATUS, &val1);
3583 bnx2x_cl45_read(bp, params->port,
3587 MDIO_PCS_REG_LASI_STATUS, &val2);
3589 "870x LASI status 0x%x->0x%x\n",
3593 /* In 8073, port1 is directed through emac0 and
3594 * port0 is directed through emac1
3596 bnx2x_cl45_read(bp, params->port,
3600 MDIO_PMA_REG_LASI_STATUS, &val1);
3603 "8703 LASI status 0x%x\n",
3607 /* clear the interrupt LASI status register */
3608 bnx2x_cl45_read(bp, params->port,
3612 MDIO_PCS_REG_STATUS, &val2);
3613 bnx2x_cl45_read(bp, params->port,
3617 MDIO_PCS_REG_STATUS, &val1);
3618 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
3621 bnx2x_cl45_read(bp, params->port,
3628 /* Check the LASI */
3629 bnx2x_cl45_read(bp, params->port,
3633 MDIO_PMA_REG_RX_ALARM, &val2);
3635 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
3637 /* Check the link status */
3638 bnx2x_cl45_read(bp, params->port,
3642 MDIO_PCS_REG_STATUS, &val2);
3643 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
3645 bnx2x_cl45_read(bp, params->port,
3649 MDIO_PMA_REG_STATUS, &val2);
3650 bnx2x_cl45_read(bp, params->port,
3654 MDIO_PMA_REG_STATUS, &val1);
3655 ext_phy_link_up = ((val1 & 4) == 4);
3656 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
3658 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3660 if (ext_phy_link_up &&
3661 ((params->req_line_speed !=
3663 if (bnx2x_bcm8073_xaui_wa(params)
3665 ext_phy_link_up = 0;
3669 bnx2x_cl45_read(bp, params->port,
3675 bnx2x_cl45_read(bp, params->port,
3682 /* Check the link status on 1.1.2 */
3683 bnx2x_cl45_read(bp, params->port,
3687 MDIO_PMA_REG_STATUS, &val2);
3688 bnx2x_cl45_read(bp, params->port,
3692 MDIO_PMA_REG_STATUS, &val1);
3693 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3694 "an_link_status=0x%x\n",
3695 val2, val1, an1000_status);
3697 ext_phy_link_up = (((val1 & 4) == 4) ||
3698 (an1000_status & (1<<1)));
3699 if (ext_phy_link_up &&
3700 bnx2x_8073_is_snr_needed(params)) {
3701 /* The SNR will improve about 2dbby
3702 changing the BW and FEE main tap.*/
3704 /* The 1st write to change FFE main
3705 tap is set before restart AN */
3706 /* Change PLL Bandwidth in EDC
3708 bnx2x_cl45_write(bp, port, ext_phy_type,
3711 MDIO_PMA_REG_PLL_BANDWIDTH,
3714 /* Change CDR Bandwidth in EDC
3716 bnx2x_cl45_write(bp, port, ext_phy_type,
3719 MDIO_PMA_REG_CDR_BANDWIDTH,
3724 bnx2x_cl45_read(bp, params->port,
3731 /* Bits 0..2 --> speed detected,
3732 bits 13..15--> link is down */
3733 if ((link_status & (1<<2)) &&
3734 (!(link_status & (1<<15)))) {
3735 ext_phy_link_up = 1;
3736 vars->line_speed = SPEED_10000;
3738 "port %x: External link"
3739 " up in 10G\n", params->port);
3740 } else if ((link_status & (1<<1)) &&
3741 (!(link_status & (1<<14)))) {
3742 ext_phy_link_up = 1;
3743 vars->line_speed = SPEED_2500;
3745 "port %x: External link"
3746 " up in 2.5G\n", params->port);
3747 } else if ((link_status & (1<<0)) &&
3748 (!(link_status & (1<<13)))) {
3749 ext_phy_link_up = 1;
3750 vars->line_speed = SPEED_1000;
3752 "port %x: External link"
3753 " up in 1G\n", params->port);
3755 ext_phy_link_up = 0;
3757 "port %x: External link"
3758 " is down\n", params->port);
3761 /* See if 1G link is up for the 8072 */
3762 bnx2x_cl45_read(bp, params->port,
3768 bnx2x_cl45_read(bp, params->port,
3774 if (an1000_status & (1<<1)) {
3775 ext_phy_link_up = 1;
3776 vars->line_speed = SPEED_1000;
3778 "port %x: External link"
3779 " up in 1G\n", params->port);
3780 } else if (ext_phy_link_up) {
3781 ext_phy_link_up = 1;
3782 vars->line_speed = SPEED_10000;
3784 "port %x: External link"
3785 " up in 10G\n", params->port);
3792 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3793 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3796 MDIO_PMA_REG_LASI_STATUS, &val2);
3797 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3800 MDIO_PMA_REG_LASI_STATUS, &val1);
3802 "10G-base-T LASI status 0x%x->0x%x\n",
3804 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3807 MDIO_PMA_REG_STATUS, &val2);
3808 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3811 MDIO_PMA_REG_STATUS, &val1);
3813 "10G-base-T PMA status 0x%x->0x%x\n",
3815 ext_phy_link_up = ((val1 & 4) == 4);
3817 * print the AN outcome of the SFX7101 PHY
3819 if (ext_phy_link_up) {
3820 bnx2x_cl45_read(bp, params->port,
3824 MDIO_AN_REG_MASTER_STATUS,
3826 vars->line_speed = SPEED_10000;
3828 "SFX7101 AN status 0x%x->Master=%x\n",
3835 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3836 params->ext_phy_config);
3837 ext_phy_link_up = 0;
3841 } else { /* SerDes */
3842 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3843 switch (ext_phy_type) {
3844 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3845 DP(NETIF_MSG_LINK, "SerDes Direct\n");
3846 ext_phy_link_up = 1;
3849 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3850 DP(NETIF_MSG_LINK, "SerDes 5482\n");
3851 ext_phy_link_up = 1;
3856 "BAD SerDes ext_phy_config 0x%x\n",
3857 params->ext_phy_config);
3858 ext_phy_link_up = 0;
3863 return ext_phy_link_up;
3866 static void bnx2x_link_int_enable(struct link_params *params)
3868 u8 port = params->port;
3871 struct bnx2x *bp = params->bp;
3872 /* setting the status to report on link up
3873 for either XGXS or SerDes */
3875 if (params->switch_cfg == SWITCH_CFG_10G) {
3876 mask = (NIG_MASK_XGXS0_LINK10G |
3877 NIG_MASK_XGXS0_LINK_STATUS);
3878 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
3879 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3880 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3881 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3883 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
3884 mask |= NIG_MASK_MI_INT;
3885 DP(NETIF_MSG_LINK, "enabled external phy int\n");
3888 } else { /* SerDes */
3889 mask = NIG_MASK_SERDES0_LINK_STATUS;
3890 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
3891 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3892 if ((ext_phy_type !=
3893 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
3895 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
3896 mask |= NIG_MASK_MI_INT;
3897 DP(NETIF_MSG_LINK, "enabled external phy int\n");
3901 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3903 DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
3904 (params->switch_cfg == SWITCH_CFG_10G),
3905 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
3907 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
3908 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
3909 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
3910 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
3911 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
3912 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
3913 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
3920 static void bnx2x_link_int_ack(struct link_params *params,
3921 struct link_vars *vars, u8 is_10g)
3923 struct bnx2x *bp = params->bp;
3924 u8 port = params->port;
3926 /* first reset all status
3927 * we assume only one line will be change at a time */
3928 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3929 (NIG_STATUS_XGXS0_LINK10G |
3930 NIG_STATUS_XGXS0_LINK_STATUS |
3931 NIG_STATUS_SERDES0_LINK_STATUS));
3932 if (vars->phy_link_up) {
3934 /* Disable the 10G link interrupt
3935 * by writing 1 to the status register
3937 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
3939 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3940 NIG_STATUS_XGXS0_LINK10G);
3942 } else if (params->switch_cfg == SWITCH_CFG_10G) {
3943 /* Disable the link interrupt
3944 * by writing 1 to the relevant lane
3945 * in the status register
3947 u32 ser_lane = ((params->lane_config &
3948 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3949 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3951 DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
3953 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3955 NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
3957 } else { /* SerDes */
3958 DP(NETIF_MSG_LINK, "SerDes phy link up\n");
3959 /* Disable the link interrupt
3960 * by writing 1 to the status register
3963 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3964 NIG_STATUS_SERDES0_LINK_STATUS);
3967 } else { /* link_down */
3971 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
3974 u32 mask = 0xf0000000;
3978 /* Need more than 10chars for this format */
3985 digit = ((num & mask) >> shift);
3987 *str_ptr = digit + '0';
3989 *str_ptr = digit - 0xa + 'a';
4002 static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
4007 /* Enable EMAC0 in to enable MDIO */
4008 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
4009 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
4012 /* take ext phy out of reset */
4014 MISC_REGISTERS_GPIO_2,
4015 MISC_REGISTERS_GPIO_HIGH,
4019 MISC_REGISTERS_GPIO_1,
4020 MISC_REGISTERS_GPIO_HIGH,
4026 for (cnt = 0; cnt < 1000; cnt++) {
4028 bnx2x_cl45_read(bp, port,
4034 if (!(ctrl & (1<<15))) {
4035 DP(NETIF_MSG_LINK, "Reset completed\n\n");
4041 static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
4043 /* put sf to reset */
4045 MISC_REGISTERS_GPIO_1,
4046 MISC_REGISTERS_GPIO_LOW,
4049 MISC_REGISTERS_GPIO_2,
4050 MISC_REGISTERS_GPIO_LOW,
4054 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
4055 u8 *version, u16 len)
4057 struct bnx2x *bp = params->bp;
4058 u32 ext_phy_type = 0;
4060 u8 ext_phy_addr = 0 ;
4064 if (version == NULL || params == NULL)
4067 /* reset the returned value to zero */
4068 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4069 ext_phy_addr = ((params->ext_phy_config &
4070 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4071 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4073 switch (ext_phy_type) {
4074 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4079 /* Take ext phy out of reset */
4081 bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
4087 bnx2x_cl45_read(bp, params->port,
4091 MDIO_PMA_REG_7101_VER1, &val);
4092 version[2] = (val & 0xFF);
4093 version[3] = ((val & 0xFF00)>>8);
4095 bnx2x_cl45_read(bp, params->port,
4098 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2,
4100 version[0] = (val & 0xFF);
4101 version[1] = ((val & 0xFF00)>>8);
4105 bnx2x_turn_off_sf(bp, params->port);
4107 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4108 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4110 /* Take ext phy out of reset */
4112 bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
4115 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4118 MDIO_PMA_REG_ROM_VER1, &val);
4120 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4123 MDIO_PMA_REG_ROM_VER2, &val);
4125 status = bnx2x_format_ver(ver_num, version, len);
4128 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4129 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4130 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4131 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4134 MDIO_PMA_REG_ROM_VER1, &val);
4136 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4139 MDIO_PMA_REG_ROM_VER2, &val);
4141 status = bnx2x_format_ver(ver_num, version, len);
4144 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4147 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4148 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
4149 " type is FAILURE!\n");
4159 static void bnx2x_set_xgxs_loopback(struct link_params *params,
4160 struct link_vars *vars,
4163 u8 port = params->port;
4164 struct bnx2x *bp = params->bp;
4169 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
4171 /* change the uni_phy_addr in the nig */
4172 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
4175 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
4177 bnx2x_cl45_write(bp, port, 0,
4180 (MDIO_REG_BANK_AER_BLOCK +
4181 (MDIO_AER_BLOCK_AER_REG & 0xf)),
4184 bnx2x_cl45_write(bp, port, 0,
4187 (MDIO_REG_BANK_CL73_IEEEB0 +
4188 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
4191 /* set aer mmd back */
4192 bnx2x_set_aer_mmd(params, vars);
4195 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
4201 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
4203 CL45_RD_OVER_CL22(bp, port,
4205 MDIO_REG_BANK_COMBO_IEEE0,
4206 MDIO_COMBO_IEEE0_MII_CONTROL,
4209 CL45_WR_OVER_CL22(bp, port,
4211 MDIO_REG_BANK_COMBO_IEEE0,
4212 MDIO_COMBO_IEEE0_MII_CONTROL,
4214 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
4219 static void bnx2x_ext_phy_loopback(struct link_params *params)
4221 struct bnx2x *bp = params->bp;
4225 if (params->switch_cfg == SWITCH_CFG_10G) {
4226 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4227 /* CL37 Autoneg Enabled */
4228 ext_phy_addr = ((params->ext_phy_config &
4229 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4230 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4231 switch (ext_phy_type) {
4232 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4233 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4235 "ext_phy_loopback: We should not get here\n");
4237 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4238 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
4240 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4241 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
4243 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4244 DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
4245 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4251 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4252 /* SFX7101_XGXS_TEST1 */
4253 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4256 MDIO_XS_SFX7101_XGXS_TEST1,
4259 "ext_phy_loopback: set ext phy loopback\n");
4261 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4264 } /* switch external PHY type */
4267 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4268 ext_phy_addr = (params->ext_phy_config &
4269 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
4270 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
4276 *------------------------------------------------------------------------
4277 * bnx2x_override_led_value -
4279 * Override the led value of the requsted led
4281 *------------------------------------------------------------------------
4283 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
4284 u32 led_idx, u32 value)
4288 /* If port 0 then use EMAC0, else use EMAC1*/
4289 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4292 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
4293 port, led_idx, value);
4296 case 0: /* 10MB led */
4297 /* Read the current value of the LED register in
4299 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4300 /* Set the OVERRIDE bit to 1 */
4301 reg_val |= EMAC_LED_OVERRIDE;
4302 /* If value is 1, set the 10M_OVERRIDE bit,
4303 otherwise reset it.*/
4304 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
4305 (reg_val & ~EMAC_LED_10MB_OVERRIDE);
4306 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4308 case 1: /*100MB led */
4309 /*Read the current value of the LED register in
4311 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4312 /* Set the OVERRIDE bit to 1 */
4313 reg_val |= EMAC_LED_OVERRIDE;
4314 /* If value is 1, set the 100M_OVERRIDE bit,
4315 otherwise reset it.*/
4316 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
4317 (reg_val & ~EMAC_LED_100MB_OVERRIDE);
4318 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4320 case 2: /* 1000MB led */
4321 /* Read the current value of the LED register in the
4323 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4324 /* Set the OVERRIDE bit to 1 */
4325 reg_val |= EMAC_LED_OVERRIDE;
4326 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
4328 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
4329 (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
4330 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4332 case 3: /* 2500MB led */
4333 /* Read the current value of the LED register in the
4335 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4336 /* Set the OVERRIDE bit to 1 */
4337 reg_val |= EMAC_LED_OVERRIDE;
4338 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
4340 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
4341 (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
4342 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4344 case 4: /*10G led */
4346 REG_WR(bp, NIG_REG_LED_10G_P0,
4349 REG_WR(bp, NIG_REG_LED_10G_P1,
4353 case 5: /* TRAFFIC led */
4354 /* Find if the traffic control is via BMAC or EMAC */
4356 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
4358 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
4360 /* Override the traffic led in the EMAC:*/
4362 /* Read the current value of the LED register in
4364 reg_val = REG_RD(bp, emac_base +
4366 /* Set the TRAFFIC_OVERRIDE bit to 1 */
4367 reg_val |= EMAC_LED_OVERRIDE;
4368 /* If value is 1, set the TRAFFIC bit, otherwise
4370 reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
4371 (reg_val & ~EMAC_LED_TRAFFIC);
4372 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4373 } else { /* Override the traffic led in the BMAC: */
4374 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4376 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
4382 "bnx2x_override_led_value() unknown led index %d "
4383 "(should be 0-5)\n", led_idx);
4391 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
4392 u16 hw_led_mode, u32 chip_id)
4396 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4397 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
4398 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
4399 speed, hw_led_mode);
4402 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
4403 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
4404 SHARED_HW_CFG_LED_MAC1);
4406 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4407 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
4411 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
4412 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
4414 /* Set blinking rate to ~15.9Hz */
4415 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
4416 LED_BLINK_RATE_VAL);
4417 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
4419 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4420 EMAC_WR(bp, EMAC_REG_EMAC_LED,
4421 (tmp & (~EMAC_LED_OVERRIDE)));
4423 if (!CHIP_IS_E1H(bp) &&
4424 ((speed == SPEED_2500) ||
4425 (speed == SPEED_1000) ||
4426 (speed == SPEED_100) ||
4427 (speed == SPEED_10))) {
4428 /* On Everest 1 Ax chip versions for speeds less than
4429 10G LED scheme is different */
4430 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4432 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
4434 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
4441 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
4449 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
4451 struct bnx2x *bp = params->bp;
4454 CL45_RD_OVER_CL22(bp, params->port,
4456 MDIO_REG_BANK_GP_STATUS,
4457 MDIO_GP_STATUS_TOP_AN_STATUS1,
4459 /* link is up only if both local phy and external phy are up */
4460 if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
4461 bnx2x_ext_phy_is_link_up(params, vars))
4467 static u8 bnx2x_link_initialize(struct link_params *params,
4468 struct link_vars *vars)
4470 struct bnx2x *bp = params->bp;
4471 u8 port = params->port;
4474 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4475 /* Activate the external PHY */
4476 bnx2x_ext_phy_reset(params, vars);
4478 bnx2x_set_aer_mmd(params, vars);
4480 if (vars->phy_flags & PHY_XGXS_FLAG)
4481 bnx2x_set_master_ln(params);
4483 rc = bnx2x_reset_unicore(params);
4484 /* reset the SerDes and wait for reset bit return low */
4488 bnx2x_set_aer_mmd(params, vars);
4490 /* setting the masterLn_def again after the reset */
4491 if (vars->phy_flags & PHY_XGXS_FLAG) {
4492 bnx2x_set_master_ln(params);
4493 bnx2x_set_swap_lanes(params);
4496 if (vars->phy_flags & PHY_XGXS_FLAG) {
4497 if ((params->req_line_speed &&
4498 ((params->req_line_speed == SPEED_100) ||
4499 (params->req_line_speed == SPEED_10))) ||
4500 (!params->req_line_speed &&
4501 (params->speed_cap_mask >=
4502 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
4503 (params->speed_cap_mask <
4504 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4506 vars->phy_flags |= PHY_SGMII_FLAG;
4508 vars->phy_flags &= ~PHY_SGMII_FLAG;
4511 /* In case of external phy existance, the line speed would be the
4512 line speed linked up by the external phy. In case it is direct only,
4513 then the line_speed during initialization will be equal to the
4515 vars->line_speed = params->req_line_speed;
4517 bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
4519 /* init ext phy and enable link state int */
4520 non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
4521 (params->loopback_mode == LOOPBACK_XGXS_10) ||
4522 (params->loopback_mode == LOOPBACK_EXT_PHY));
4525 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
4526 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)) {
4527 if (params->req_line_speed == SPEED_AUTO_NEG)
4528 bnx2x_set_parallel_detection(params, vars->phy_flags);
4529 bnx2x_init_internal_phy(params, vars);
4533 rc |= bnx2x_ext_phy_init(params, vars);
4535 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4536 (NIG_STATUS_XGXS0_LINK10G |
4537 NIG_STATUS_XGXS0_LINK_STATUS |
4538 NIG_STATUS_SERDES0_LINK_STATUS));
4545 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
4547 struct bnx2x *bp = params->bp;
4550 DP(NETIF_MSG_LINK, "Phy Initialization started \n");
4551 DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
4552 params->req_line_speed, params->req_flow_ctrl);
4553 vars->link_status = 0;
4554 vars->phy_link_up = 0;
4556 vars->line_speed = 0;
4557 vars->duplex = DUPLEX_FULL;
4558 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4559 vars->mac_type = MAC_TYPE_NONE;
4561 if (params->switch_cfg == SWITCH_CFG_1G)
4562 vars->phy_flags = PHY_SERDES_FLAG;
4564 vars->phy_flags = PHY_XGXS_FLAG;
4567 /* disable attentions */
4568 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
4569 (NIG_MASK_XGXS0_LINK_STATUS |
4570 NIG_MASK_XGXS0_LINK10G |
4571 NIG_MASK_SERDES0_LINK_STATUS |
4574 bnx2x_emac_init(params, vars);
4576 if (CHIP_REV_IS_FPGA(bp)) {
4578 vars->line_speed = SPEED_10000;
4579 vars->duplex = DUPLEX_FULL;
4580 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4581 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
4582 /* enable on E1.5 FPGA */
4583 if (CHIP_IS_E1H(bp)) {
4585 (BNX2X_FLOW_CTRL_TX | BNX2X_FLOW_CTRL_RX);
4586 vars->link_status |=
4587 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
4588 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
4591 bnx2x_emac_enable(params, vars, 0);
4592 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4594 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4595 + params->port*4, 0);
4597 /* update shared memory */
4598 bnx2x_update_mng(params, vars->link_status);
4603 if (CHIP_REV_IS_EMUL(bp)) {
4606 vars->line_speed = SPEED_10000;
4607 vars->duplex = DUPLEX_FULL;
4608 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4609 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
4611 bnx2x_bmac_enable(params, vars, 0);
4613 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4615 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4616 + params->port*4, 0);
4618 /* update shared memory */
4619 bnx2x_update_mng(params, vars->link_status);
4624 if (params->loopback_mode == LOOPBACK_BMAC) {
4626 vars->line_speed = SPEED_10000;
4627 vars->duplex = DUPLEX_FULL;
4628 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4629 vars->mac_type = MAC_TYPE_BMAC;
4631 vars->phy_flags = PHY_XGXS_FLAG;
4633 bnx2x_phy_deassert(params, vars->phy_flags);
4634 /* set bmac loopback */
4635 bnx2x_bmac_enable(params, vars, 1);
4637 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4639 } else if (params->loopback_mode == LOOPBACK_EMAC) {
4641 vars->line_speed = SPEED_1000;
4642 vars->duplex = DUPLEX_FULL;
4643 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4644 vars->mac_type = MAC_TYPE_EMAC;
4646 vars->phy_flags = PHY_XGXS_FLAG;
4648 bnx2x_phy_deassert(params, vars->phy_flags);
4649 /* set bmac loopback */
4650 bnx2x_emac_enable(params, vars, 1);
4651 bnx2x_emac_program(params, vars->line_speed,
4653 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4655 } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
4656 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
4658 vars->line_speed = SPEED_10000;
4659 vars->duplex = DUPLEX_FULL;
4660 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4662 vars->phy_flags = PHY_XGXS_FLAG;
4665 NIG_REG_XGXS0_CTRL_PHY_ADDR+
4667 params->phy_addr = (u8)val;
4669 bnx2x_phy_deassert(params, vars->phy_flags);
4670 bnx2x_link_initialize(params, vars);
4672 vars->mac_type = MAC_TYPE_BMAC;
4674 bnx2x_bmac_enable(params, vars, 0);
4676 if (params->loopback_mode == LOOPBACK_XGXS_10) {
4677 /* set 10G XGXS loopback */
4678 bnx2x_set_xgxs_loopback(params, vars, 1);
4680 /* set external phy loopback */
4681 bnx2x_ext_phy_loopback(params);
4683 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4689 bnx2x_phy_deassert(params, vars->phy_flags);
4690 switch (params->switch_cfg) {
4692 vars->phy_flags |= PHY_SERDES_FLAG;
4693 if ((params->ext_phy_config &
4694 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
4695 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
4701 NIG_REG_SERDES0_CTRL_PHY_ADDR+
4704 params->phy_addr = (u8)val;
4707 case SWITCH_CFG_10G:
4708 vars->phy_flags |= PHY_XGXS_FLAG;
4710 NIG_REG_XGXS0_CTRL_PHY_ADDR+
4712 params->phy_addr = (u8)val;
4716 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
4721 bnx2x_link_initialize(params, vars);
4723 bnx2x_link_int_enable(params);
4728 static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
4730 DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
4732 /* Set serial boot control for external load */
4733 bnx2x_cl45_write(bp, port,
4734 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
4736 MDIO_PMA_REG_GEN_CTRL, 0x0001);
4738 /* Disable Transmitter */
4739 bnx2x_bcm8726_set_transmitter(bp, port, ext_phy_addr, 0);
4743 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
4747 struct bnx2x *bp = params->bp;
4748 u32 ext_phy_config = params->ext_phy_config;
4749 u16 hw_led_mode = params->hw_led_mode;
4750 u32 chip_id = params->chip_id;
4751 u8 port = params->port;
4752 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4753 /* disable attentions */
4755 vars->link_status = 0;
4756 bnx2x_update_mng(params, vars->link_status);
4757 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4758 (NIG_MASK_XGXS0_LINK_STATUS |
4759 NIG_MASK_XGXS0_LINK10G |
4760 NIG_MASK_SERDES0_LINK_STATUS |
4763 /* activate nig drain */
4764 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4766 /* disable nig egress interface */
4767 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4768 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4770 /* Stop BigMac rx */
4771 bnx2x_bmac_rx_disable(bp, port);
4774 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4777 /* The PHY reset is controled by GPIO 1
4778 * Hold it as vars low
4780 /* clear link led */
4781 bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4782 if (reset_ext_phy) {
4783 switch (ext_phy_type) {
4784 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4785 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4787 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4788 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4791 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4792 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4795 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4797 u8 ext_phy_addr = ((params->ext_phy_config &
4798 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4799 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4800 /* Set soft reset */
4801 bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
4806 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4807 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4809 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4810 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4812 DP(NETIF_MSG_LINK, "reset external PHY\n");
4815 /* reset the SerDes/XGXS */
4816 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4817 (0x1ff << (port*16)));
4820 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4821 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4823 /* disable nig ingress interface */
4824 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4825 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4826 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4827 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4832 static u8 bnx2x_update_link_down(struct link_params *params,
4833 struct link_vars *vars)
4835 struct bnx2x *bp = params->bp;
4836 u8 port = params->port;
4837 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4838 bnx2x_set_led(bp, port, LED_MODE_OFF,
4839 0, params->hw_led_mode,
4842 /* indicate no mac active */
4843 vars->mac_type = MAC_TYPE_NONE;
4845 /* update shared memory */
4846 vars->link_status = 0;
4847 vars->line_speed = 0;
4848 bnx2x_update_mng(params, vars->link_status);
4850 /* activate nig drain */
4851 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4854 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4859 bnx2x_bmac_rx_disable(bp, params->port);
4860 REG_WR(bp, GRCBASE_MISC +
4861 MISC_REGISTERS_RESET_REG_2_CLEAR,
4862 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4866 static u8 bnx2x_update_link_up(struct link_params *params,
4867 struct link_vars *vars,
4868 u8 link_10g, u32 gp_status)
4870 struct bnx2x *bp = params->bp;
4871 u8 port = params->port;
4873 vars->link_status |= LINK_STATUS_LINK_UP;
4875 bnx2x_bmac_enable(params, vars, 0);
4876 bnx2x_set_led(bp, port, LED_MODE_OPER,
4877 SPEED_10000, params->hw_led_mode,
4881 bnx2x_emac_enable(params, vars, 0);
4882 rc = bnx2x_emac_program(params, vars->line_speed,
4886 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4887 if (!(vars->phy_flags &
4889 bnx2x_set_sgmii_tx_driver(params);
4894 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4898 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4900 /* update shared memory */
4901 bnx2x_update_mng(params, vars->link_status);
4905 /* This function should called upon link interrupt */
4906 /* In case vars->link_up, driver needs to
4909 3. Update the shared memory
4913 1. Update shared memory
4918 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4920 struct bnx2x *bp = params->bp;
4921 u8 port = params->port;
4924 u8 ext_phy_link_up, rc = 0;
4927 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
4929 (vars->phy_flags & PHY_XGXS_FLAG),
4930 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4932 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4933 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4934 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4935 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
4937 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4938 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4939 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4942 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4944 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4946 /* Check external link change only for non-direct */
4947 ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
4949 /* Read gp_status */
4950 CL45_RD_OVER_CL22(bp, port, params->phy_addr,
4951 MDIO_REG_BANK_GP_STATUS,
4952 MDIO_GP_STATUS_TOP_AN_STATUS1,
4955 rc = bnx2x_link_settings_status(params, vars, gp_status);
4959 /* anything 10 and over uses the bmac */
4960 link_10g = ((vars->line_speed == SPEED_10000) ||
4961 (vars->line_speed == SPEED_12000) ||
4962 (vars->line_speed == SPEED_12500) ||
4963 (vars->line_speed == SPEED_13000) ||
4964 (vars->line_speed == SPEED_15000) ||
4965 (vars->line_speed == SPEED_16000));
4967 bnx2x_link_int_ack(params, vars, link_10g);
4969 /* In case external phy link is up, and internal link is down
4970 ( not initialized yet probably after link initialization, it needs
4972 Note that after link down-up as result of cable plug,
4973 the xgxs link would probably become up again without the need to
4976 if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4977 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
4978 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
4979 (ext_phy_link_up && !vars->phy_link_up))
4980 bnx2x_init_internal_phy(params, vars);
4982 /* link is up only if both local phy and external phy are up */
4983 vars->link_up = (ext_phy_link_up && vars->phy_link_up);
4986 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
4988 rc = bnx2x_update_link_down(params, vars);
4993 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4995 u8 ext_phy_addr[PORT_MAX];
4999 /* PART1 - Reset both phys */
5000 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5001 /* Extract the ext phy address for the port */
5002 u32 ext_phy_config = REG_RD(bp, shmem_base +
5003 offsetof(struct shmem_region,
5004 dev_info.port_hw_config[port].external_phy_config));
5006 /* disable attentions */
5007 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5008 (NIG_MASK_XGXS0_LINK_STATUS |
5009 NIG_MASK_XGXS0_LINK10G |
5010 NIG_MASK_SERDES0_LINK_STATUS |
5013 ext_phy_addr[port] =
5015 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5016 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5018 /* Need to take the phy out of low power mode in order
5019 to write to access its registers */
5020 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5021 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
5024 bnx2x_cl45_write(bp, port,
5025 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5032 /* Add delay of 150ms after reset */
5035 /* PART2 - Download firmware to both phys */
5036 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5039 bnx2x_bcm8073_external_rom_boot(bp, port,
5040 ext_phy_addr[port]);
5042 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5045 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
5046 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
5048 "bnx2x_8073_common_init_phy port %x:"
5049 "Download failed. fw version = 0x%x\n",
5054 /* Only set bit 10 = 1 (Tx power down) */
5055 bnx2x_cl45_read(bp, port,
5056 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5059 MDIO_PMA_REG_TX_POWER_DOWN, &val);
5061 /* Phase1 of TX_POWER_DOWN reset */
5062 bnx2x_cl45_write(bp, port,
5063 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5066 MDIO_PMA_REG_TX_POWER_DOWN,
5070 /* Toggle Transmitter: Power down and then up with 600ms
5074 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
5075 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5076 /* Phase2 of POWER_DOWN_RESET*/
5077 /* Release bit 10 (Release Tx power down) */
5078 bnx2x_cl45_read(bp, port,
5079 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5082 MDIO_PMA_REG_TX_POWER_DOWN, &val);
5084 bnx2x_cl45_write(bp, port,
5085 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5088 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
5091 /* Read modify write the SPI-ROM version select register */
5092 bnx2x_cl45_read(bp, port,
5093 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5096 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
5097 bnx2x_cl45_write(bp, port,
5098 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5101 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
5103 /* set GPIO2 back to LOW */
5104 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5105 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
5112 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5117 /* Use port1 because of the static port-swap */
5118 /* Enable the module detection interrupt */
5119 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
5120 val |= ((1<<MISC_REGISTERS_GPIO_3)|
5121 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
5122 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
5124 bnx2x_hw_reset(bp, 1);
5126 for (port = 0; port < PORT_MAX; port++) {
5127 /* Extract the ext phy address for the port */
5128 u32 ext_phy_config = REG_RD(bp, shmem_base +
5129 offsetof(struct shmem_region,
5130 dev_info.port_hw_config[port].external_phy_config));
5134 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5135 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5136 DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
5139 bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
5141 /* Set fault module detected LED on */
5142 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5143 MISC_REGISTERS_GPIO_HIGH,
5150 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5155 DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n");
5157 /* Read the ext_phy_type for arbitrary port(0) */
5158 ext_phy_type = XGXS_EXT_PHY_TYPE(
5159 REG_RD(bp, shmem_base +
5160 offsetof(struct shmem_region,
5161 dev_info.port_hw_config[0].external_phy_config)));
5163 switch (ext_phy_type) {
5164 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5166 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
5169 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5170 /* GPIO1 affects both ports, so there's need to pull
5171 it for single port alone */
5172 rc = bnx2x_8726_common_init_phy(bp, shmem_base);
5177 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
5187 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
5191 bnx2x_cl45_read(bp, port,
5192 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5195 MDIO_PMA_REG_7101_RESET, &val);
5197 for (cnt = 0; cnt < 10; cnt++) {
5199 /* Writes a self-clearing reset */
5200 bnx2x_cl45_write(bp, port,
5201 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5204 MDIO_PMA_REG_7101_RESET,
5206 /* Wait for clear */
5207 bnx2x_cl45_read(bp, port,
5208 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5211 MDIO_PMA_REG_7101_RESET, &val);
5213 if ((val & (1<<15)) == 0)
5217 #define RESERVED_SIZE 256
5218 /* max application is 160K bytes - data at end of RAM */
5219 #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
5221 /* Header is 14 bytes */
5222 #define HEADER_SIZE 14
5223 #define DATA_OFFSET HEADER_SIZE
5225 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
5226 bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
5229 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
5231 /* Programs an image to DSP's flash via the SPI port*/
5232 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
5234 char data[], u32 size)
5236 const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
5237 /* Doesn't include last trans!*/
5238 const u16 last_trans_size = size%4; /* Num bytes on last trans */
5239 u16 trans_cnt, byte_cnt;
5242 u16 code_started = 0;
5243 u16 image_revision1, image_revision2;
5246 DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
5248 if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
5249 /* This very often will be the case, because the image is built
5250 with 160Kbytes size whereas the total image size must actually
5251 be 160Kbytes-RESERVED_SIZE */
5252 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
5253 "truncated to %d bytes\n", size, MAX_APP_SIZE);
5254 size = MAX_APP_SIZE+HEADER_SIZE;
5256 DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
5257 DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]);
5258 /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
5259 and issuing a reset.*/
5261 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5262 MISC_REGISTERS_GPIO_HIGH, port);
5264 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
5267 for (cnt = 0; cnt < 100; cnt++)
5270 /* Make sure we can access the DSP
5271 And it's in the correct mode (waiting for download) */
5273 bnx2x_cl45_read(bp, port,
5274 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5277 MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
5279 if (tmp != 0x000A) {
5280 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
5281 "Expected 0x000A, read 0x%04X\n", tmp);
5282 DP(NETIF_MSG_LINK, "Download failed\n");
5286 /* Mux the SPI interface away from the internal processor */
5287 bnx2x_cl45_write(bp, port,
5288 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5291 MDIO_PCS_REG_7101_SPI_MUX, 1);
5293 /* Reset the SPI port */
5294 bnx2x_cl45_write(bp, port,
5295 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5298 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
5299 bnx2x_cl45_write(bp, port,
5300 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5303 MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
5304 (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
5305 bnx2x_cl45_write(bp, port,
5306 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5309 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
5311 /* Erase the flash */
5312 bnx2x_cl45_write(bp, port,
5313 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5316 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5317 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5319 bnx2x_cl45_write(bp, port,
5320 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5323 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5326 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5327 bnx2x_cl45_write(bp, port,
5328 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5331 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5332 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
5334 bnx2x_cl45_write(bp, port,
5335 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5338 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5340 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5342 /* Wait 10 seconds, the maximum time for the erase to complete */
5343 DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
5344 for (cnt = 0; cnt < 1000; cnt++)
5347 DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
5349 for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
5350 bnx2x_cl45_write(bp, port,
5351 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5354 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5355 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5357 bnx2x_cl45_write(bp, port,
5358 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5361 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5363 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5365 bnx2x_cl45_write(bp, port,
5366 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5369 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5370 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
5372 /* Bits 23-16 of address */
5373 bnx2x_cl45_write(bp, port,
5374 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5377 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5379 /* Bits 15-8 of address */
5380 bnx2x_cl45_write(bp, port,
5381 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5384 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5387 /* Bits 7-0 of address */
5388 bnx2x_cl45_write(bp, port,
5389 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5392 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5396 while (byte_cnt < 4 && data_index < size) {
5397 bnx2x_cl45_write(bp, port,
5398 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5401 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5402 data[data_index++]);
5406 bnx2x_cl45_write(bp, port,
5407 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5410 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5413 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5414 msleep(5); /* Wait 5 ms minimum between transs */
5416 /* Let the user know something's going on.*/
5417 /* a pacifier ever 4K */
5418 if ((data_index % 1023) == 0)
5419 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
5422 DP(NETIF_MSG_LINK, "\n");
5423 /* Transfer the last block if there is data remaining */
5424 if (last_trans_size) {
5425 bnx2x_cl45_write(bp, port,
5426 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5429 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5430 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5432 bnx2x_cl45_write(bp, port,
5433 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5436 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5439 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5441 bnx2x_cl45_write(bp, port,
5442 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5445 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5446 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
5448 /* Bits 23-16 of address */
5449 bnx2x_cl45_write(bp, port,
5450 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5453 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5455 /* Bits 15-8 of address */
5456 bnx2x_cl45_write(bp, port,
5457 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5460 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5463 /* Bits 7-0 of address */
5464 bnx2x_cl45_write(bp, port,
5465 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5468 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5472 while (byte_cnt < last_trans_size && data_index < size) {
5473 /* Bits 7-0 of address */
5474 bnx2x_cl45_write(bp, port,
5475 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5478 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5479 data[data_index++]);
5483 bnx2x_cl45_write(bp, port,
5484 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5487 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5490 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5493 /* DSP Remove Download Mode */
5494 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5495 MISC_REGISTERS_GPIO_LOW, port);
5497 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
5499 /* wait 0.5 sec to allow it to run */
5500 for (cnt = 0; cnt < 100; cnt++)
5503 bnx2x_hw_reset(bp, port);
5505 for (cnt = 0; cnt < 100; cnt++)
5508 /* Check that the code is started. In case the download
5509 checksum failed, the code won't be started. */
5510 bnx2x_cl45_read(bp, port,
5511 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5514 MDIO_PCS_REG_7101_DSP_ACCESS,
5517 code_started = (tmp & (1<<4));
5518 if (!code_started) {
5519 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
5523 /* Verify that the file revision is now equal to the image
5524 revision within the DSP */
5525 bnx2x_cl45_read(bp, port,
5526 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5529 MDIO_PMA_REG_7101_VER1,
5532 bnx2x_cl45_read(bp, port,
5533 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5536 MDIO_PMA_REG_7101_VER2,
5539 if (data[0x14e] != (image_revision2&0xFF) ||
5540 data[0x14f] != ((image_revision2&0xFF00)>>8) ||
5541 data[0x150] != (image_revision1&0xFF) ||
5542 data[0x151] != ((image_revision1&0xFF00)>>8)) {
5543 DP(NETIF_MSG_LINK, "Download failed.\n");
5546 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
5550 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
5551 u8 driver_loaded, char data[], u32 size)
5556 ext_phy_addr = ((ext_phy_config &
5557 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5558 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5560 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
5562 switch (ext_phy_type) {
5563 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5564 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5565 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5566 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5568 "Flash download not supported for this ext phy\n");
5571 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5572 /* Take ext phy out of reset */
5574 bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
5575 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
5578 bnx2x_turn_off_sf(bp, port);
5580 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5581 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
5582 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
5584 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");