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 +
300 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
302 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
305 if (CHIP_REV_IS_SLOW(bp)) {
306 /* config GMII mode */
307 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
308 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
309 (val | EMAC_MODE_PORT_GMII));
311 /* pause enable/disable */
312 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
313 EMAC_RX_MODE_FLOW_EN);
314 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
315 bnx2x_bits_en(bp, emac_base +
316 EMAC_REG_EMAC_RX_MODE,
317 EMAC_RX_MODE_FLOW_EN);
319 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
320 (EMAC_TX_MODE_EXT_PAUSE_EN |
321 EMAC_TX_MODE_FLOW_EN));
322 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
323 bnx2x_bits_en(bp, emac_base +
324 EMAC_REG_EMAC_TX_MODE,
325 (EMAC_TX_MODE_EXT_PAUSE_EN |
326 EMAC_TX_MODE_FLOW_EN));
329 /* KEEP_VLAN_TAG, promiscuous */
330 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
331 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
332 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
335 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
340 EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
343 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
345 /* enable emac for jumbo packets */
346 EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
347 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
348 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
351 REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
353 /* disable the NIG in/out to the bmac */
354 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
355 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
356 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
358 /* enable the NIG in/out to the emac */
359 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
361 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
364 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
365 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
367 if (CHIP_REV_IS_EMUL(bp)) {
368 /* take the BigMac out of reset */
370 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
371 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
373 /* enable access for bmac registers */
374 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
377 vars->mac_type = MAC_TYPE_EMAC;
383 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
386 struct bnx2x *bp = params->bp;
387 u8 port = params->port;
388 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
389 NIG_REG_INGRESS_BMAC0_MEM;
393 DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
394 /* reset and unreset the BigMac */
395 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
396 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
399 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
400 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
402 /* enable access for bmac registers */
403 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
408 REG_WR_DMAE(bp, bmac_addr +
409 BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
413 wb_data[0] = ((params->mac_addr[2] << 24) |
414 (params->mac_addr[3] << 16) |
415 (params->mac_addr[4] << 8) |
416 params->mac_addr[5]);
417 wb_data[1] = ((params->mac_addr[0] << 8) |
418 params->mac_addr[1]);
419 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
424 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
428 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
435 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
439 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
444 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
446 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
449 /* rx control set to don't strip crc */
451 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
455 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
459 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
461 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
464 /* set cnt max size */
465 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
467 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
471 wb_data[0] = 0x1000200;
473 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
475 /* fix for emulation */
476 if (CHIP_REV_IS_EMUL(bp)) {
480 bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
484 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
485 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
486 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
488 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
490 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
491 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
492 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
493 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
494 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
495 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
497 vars->mac_type = MAC_TYPE_BMAC;
501 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
503 struct bnx2x *bp = params->bp;
506 if (phy_flags & PHY_XGXS_FLAG) {
507 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
508 val = XGXS_RESET_BITS;
510 } else { /* SerDes */
511 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
512 val = SERDES_RESET_BITS;
515 val = val << (params->port*16);
517 /* reset and unreset the SerDes/XGXS */
518 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
521 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
523 bnx2x_set_phy_mdio(params);
526 void bnx2x_link_status_update(struct link_params *params,
527 struct link_vars *vars)
529 struct bnx2x *bp = params->bp;
531 u8 port = params->port;
533 if (params->switch_cfg == SWITCH_CFG_1G)
534 vars->phy_flags = PHY_SERDES_FLAG;
536 vars->phy_flags = PHY_XGXS_FLAG;
537 vars->link_status = REG_RD(bp, params->shmem_base +
538 offsetof(struct shmem_region,
539 port_mb[port].link_status));
541 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
544 DP(NETIF_MSG_LINK, "phy link up\n");
546 vars->phy_link_up = 1;
547 vars->duplex = DUPLEX_FULL;
548 switch (vars->link_status &
549 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
551 vars->duplex = DUPLEX_HALF;
554 vars->line_speed = SPEED_10;
558 vars->duplex = DUPLEX_HALF;
562 vars->line_speed = SPEED_100;
566 vars->duplex = DUPLEX_HALF;
569 vars->line_speed = SPEED_1000;
573 vars->duplex = DUPLEX_HALF;
576 vars->line_speed = SPEED_2500;
580 vars->line_speed = SPEED_10000;
584 vars->line_speed = SPEED_12000;
588 vars->line_speed = SPEED_12500;
592 vars->line_speed = SPEED_13000;
596 vars->line_speed = SPEED_15000;
600 vars->line_speed = SPEED_16000;
607 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
608 vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
610 vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
612 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
613 vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
615 vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
617 if (vars->phy_flags & PHY_XGXS_FLAG) {
618 if (vars->line_speed &&
619 ((vars->line_speed == SPEED_10) ||
620 (vars->line_speed == SPEED_100))) {
621 vars->phy_flags |= PHY_SGMII_FLAG;
623 vars->phy_flags &= ~PHY_SGMII_FLAG;
627 /* anything 10 and over uses the bmac */
628 link_10g = ((vars->line_speed == SPEED_10000) ||
629 (vars->line_speed == SPEED_12000) ||
630 (vars->line_speed == SPEED_12500) ||
631 (vars->line_speed == SPEED_13000) ||
632 (vars->line_speed == SPEED_15000) ||
633 (vars->line_speed == SPEED_16000));
635 vars->mac_type = MAC_TYPE_BMAC;
637 vars->mac_type = MAC_TYPE_EMAC;
639 } else { /* link down */
640 DP(NETIF_MSG_LINK, "phy link down\n");
642 vars->phy_link_up = 0;
644 vars->line_speed = 0;
645 vars->duplex = DUPLEX_FULL;
646 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
648 /* indicate no mac active */
649 vars->mac_type = MAC_TYPE_NONE;
652 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
653 vars->link_status, vars->phy_link_up);
654 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
655 vars->line_speed, vars->duplex, vars->flow_ctrl);
658 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
660 struct bnx2x *bp = params->bp;
661 REG_WR(bp, params->shmem_base +
662 offsetof(struct shmem_region,
663 port_mb[params->port].link_status),
667 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
669 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
670 NIG_REG_INGRESS_BMAC0_MEM;
672 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
674 /* Only if the bmac is out of reset */
675 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
676 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
679 /* Clear Rx Enable bit in BMAC_CONTROL register */
680 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
682 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
683 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
690 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
693 struct bnx2x *bp = params->bp;
694 u8 port = params->port;
699 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
701 /* wait for init credit */
702 init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
703 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
704 DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
706 while ((init_crd != crd) && count) {
709 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
712 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
713 if (init_crd != crd) {
714 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
719 if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
720 line_speed == SPEED_10 ||
721 line_speed == SPEED_100 ||
722 line_speed == SPEED_1000 ||
723 line_speed == SPEED_2500) {
724 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
725 /* update threshold */
726 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
727 /* update init credit */
728 init_crd = 778; /* (800-18-4) */
731 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
733 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
734 /* update threshold */
735 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
736 /* update init credit */
737 switch (line_speed) {
739 init_crd = thresh + 553 - 22;
743 init_crd = thresh + 664 - 22;
747 init_crd = thresh + 742 - 22;
751 init_crd = thresh + 778 - 22;
754 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
760 REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
761 DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
762 line_speed, init_crd);
764 /* probe the credit changes */
765 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
767 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
770 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
774 static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
777 switch (ext_phy_type) {
778 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
779 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
780 /* All MDC/MDIO is directed through single EMAC */
781 if (REG_RD(bp, NIG_REG_PORT_SWAP))
782 emac_base = GRCBASE_EMAC0;
784 emac_base = GRCBASE_EMAC1;
786 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
787 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
790 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
797 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
798 u8 phy_addr, u8 devad, u16 reg, u16 val)
802 u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
804 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
805 * (a value of 49==0x31) and make sure that the AUTO poll is off
808 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
809 tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
810 EMAC_MDIO_MODE_CLOCK_CNT);
811 tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
812 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
813 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
814 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
819 tmp = ((phy_addr << 21) | (devad << 16) | reg |
820 EMAC_MDIO_COMM_COMMAND_ADDRESS |
821 EMAC_MDIO_COMM_START_BUSY);
822 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
824 for (i = 0; i < 50; i++) {
827 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
828 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
833 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
834 DP(NETIF_MSG_LINK, "write phy register failed\n");
838 tmp = ((phy_addr << 21) | (devad << 16) | val |
839 EMAC_MDIO_COMM_COMMAND_WRITE_45 |
840 EMAC_MDIO_COMM_START_BUSY);
841 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
843 for (i = 0; i < 50; i++) {
846 tmp = REG_RD(bp, mdio_ctrl +
847 EMAC_REG_EMAC_MDIO_COMM);
848 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
853 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
854 DP(NETIF_MSG_LINK, "write phy register failed\n");
859 /* Restore the saved mode */
860 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
865 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
866 u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
872 u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
873 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
874 * (a value of 49==0x31) and make sure that the AUTO poll is off
877 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
878 val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
879 EMAC_MDIO_MODE_CLOCK_CNT));
880 val |= (EMAC_MDIO_MODE_CLAUSE_45 |
881 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
882 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
883 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
887 val = ((phy_addr << 21) | (devad << 16) | reg |
888 EMAC_MDIO_COMM_COMMAND_ADDRESS |
889 EMAC_MDIO_COMM_START_BUSY);
890 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
892 for (i = 0; i < 50; i++) {
895 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
896 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
901 if (val & EMAC_MDIO_COMM_START_BUSY) {
902 DP(NETIF_MSG_LINK, "read phy register failed\n");
909 val = ((phy_addr << 21) | (devad << 16) |
910 EMAC_MDIO_COMM_COMMAND_READ_45 |
911 EMAC_MDIO_COMM_START_BUSY);
912 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
914 for (i = 0; i < 50; i++) {
917 val = REG_RD(bp, mdio_ctrl +
918 EMAC_REG_EMAC_MDIO_COMM);
919 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
920 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
924 if (val & EMAC_MDIO_COMM_START_BUSY) {
925 DP(NETIF_MSG_LINK, "read phy register failed\n");
932 /* Restore the saved mode */
933 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
938 static void bnx2x_set_aer_mmd(struct link_params *params,
939 struct link_vars *vars)
941 struct bnx2x *bp = params->bp;
945 ser_lane = ((params->lane_config &
946 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
947 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
949 offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
950 (params->phy_addr + ser_lane) : 0;
952 CL45_WR_OVER_CL22(bp, params->port,
954 MDIO_REG_BANK_AER_BLOCK,
955 MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
958 static void bnx2x_set_master_ln(struct link_params *params)
960 struct bnx2x *bp = params->bp;
961 u16 new_master_ln, ser_lane;
962 ser_lane = ((params->lane_config &
963 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
964 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
966 /* set the master_ln for AN */
967 CL45_RD_OVER_CL22(bp, params->port,
969 MDIO_REG_BANK_XGXS_BLOCK2,
970 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
973 CL45_WR_OVER_CL22(bp, params->port,
975 MDIO_REG_BANK_XGXS_BLOCK2 ,
976 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
977 (new_master_ln | ser_lane));
980 static u8 bnx2x_reset_unicore(struct link_params *params)
982 struct bnx2x *bp = params->bp;
986 CL45_RD_OVER_CL22(bp, params->port,
988 MDIO_REG_BANK_COMBO_IEEE0,
989 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
991 /* reset the unicore */
992 CL45_WR_OVER_CL22(bp, params->port,
994 MDIO_REG_BANK_COMBO_IEEE0,
995 MDIO_COMBO_IEEE0_MII_CONTROL,
997 MDIO_COMBO_IEEO_MII_CONTROL_RESET));
999 /* wait for the reset to self clear */
1000 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
1003 /* the reset erased the previous bank value */
1004 CL45_RD_OVER_CL22(bp, params->port,
1006 MDIO_REG_BANK_COMBO_IEEE0,
1007 MDIO_COMBO_IEEE0_MII_CONTROL,
1010 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1016 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1021 static void bnx2x_set_swap_lanes(struct link_params *params)
1023 struct bnx2x *bp = params->bp;
1024 /* Each two bits represents a lane number:
1025 No swap is 0123 => 0x1b no need to enable the swap */
1026 u16 ser_lane, rx_lane_swap, tx_lane_swap;
1028 ser_lane = ((params->lane_config &
1029 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1030 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1031 rx_lane_swap = ((params->lane_config &
1032 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1033 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1034 tx_lane_swap = ((params->lane_config &
1035 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1036 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1038 if (rx_lane_swap != 0x1b) {
1039 CL45_WR_OVER_CL22(bp, params->port,
1041 MDIO_REG_BANK_XGXS_BLOCK2,
1042 MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1044 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1045 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1047 CL45_WR_OVER_CL22(bp, params->port,
1049 MDIO_REG_BANK_XGXS_BLOCK2,
1050 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1053 if (tx_lane_swap != 0x1b) {
1054 CL45_WR_OVER_CL22(bp, params->port,
1056 MDIO_REG_BANK_XGXS_BLOCK2,
1057 MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1059 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1061 CL45_WR_OVER_CL22(bp, params->port,
1063 MDIO_REG_BANK_XGXS_BLOCK2,
1064 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1068 static void bnx2x_set_parallel_detection(struct link_params *params,
1071 struct bnx2x *bp = params->bp;
1074 CL45_RD_OVER_CL22(bp, params->port,
1076 MDIO_REG_BANK_SERDES_DIGITAL,
1077 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1081 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1084 CL45_WR_OVER_CL22(bp, params->port,
1086 MDIO_REG_BANK_SERDES_DIGITAL,
1087 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1090 if (phy_flags & PHY_XGXS_FLAG) {
1091 DP(NETIF_MSG_LINK, "XGXS\n");
1093 CL45_WR_OVER_CL22(bp, params->port,
1095 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1096 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1097 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1099 CL45_RD_OVER_CL22(bp, params->port,
1101 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1102 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1107 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1109 CL45_WR_OVER_CL22(bp, params->port,
1111 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1112 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1115 /* Disable parallel detection of HiG */
1116 CL45_WR_OVER_CL22(bp, params->port,
1118 MDIO_REG_BANK_XGXS_BLOCK2,
1119 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1120 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1121 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1125 static void bnx2x_set_autoneg(struct link_params *params,
1126 struct link_vars *vars)
1128 struct bnx2x *bp = params->bp;
1133 CL45_RD_OVER_CL22(bp, params->port,
1135 MDIO_REG_BANK_COMBO_IEEE0,
1136 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
1138 /* CL37 Autoneg Enabled */
1139 if (vars->line_speed == SPEED_AUTO_NEG)
1140 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1141 else /* CL37 Autoneg Disabled */
1142 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1143 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1145 CL45_WR_OVER_CL22(bp, params->port,
1147 MDIO_REG_BANK_COMBO_IEEE0,
1148 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1150 /* Enable/Disable Autodetection */
1152 CL45_RD_OVER_CL22(bp, params->port,
1154 MDIO_REG_BANK_SERDES_DIGITAL,
1155 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val);
1156 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1157 if (vars->line_speed == SPEED_AUTO_NEG)
1158 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1160 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1162 CL45_WR_OVER_CL22(bp, params->port,
1164 MDIO_REG_BANK_SERDES_DIGITAL,
1165 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1167 /* Enable TetonII and BAM autoneg */
1168 CL45_RD_OVER_CL22(bp, params->port,
1170 MDIO_REG_BANK_BAM_NEXT_PAGE,
1171 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1173 if (vars->line_speed == SPEED_AUTO_NEG) {
1174 /* Enable BAM aneg Mode and TetonII aneg Mode */
1175 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1176 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1178 /* TetonII and BAM Autoneg Disabled */
1179 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1180 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1182 CL45_WR_OVER_CL22(bp, params->port,
1184 MDIO_REG_BANK_BAM_NEXT_PAGE,
1185 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1188 /* Enable Clause 73 Aneg */
1189 if ((vars->line_speed == SPEED_AUTO_NEG) &&
1191 /* Enable BAM Station Manager */
1193 CL45_WR_OVER_CL22(bp, params->port,
1195 MDIO_REG_BANK_CL73_USERB0,
1196 MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1197 (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1198 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1199 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
1201 /* Merge CL73 and CL37 aneg resolution */
1202 CL45_RD_OVER_CL22(bp, params->port,
1204 MDIO_REG_BANK_CL73_USERB0,
1205 MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1208 CL45_WR_OVER_CL22(bp, params->port,
1210 MDIO_REG_BANK_CL73_USERB0,
1211 MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1213 MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
1215 /* Set the CL73 AN speed */
1217 CL45_RD_OVER_CL22(bp, params->port,
1219 MDIO_REG_BANK_CL73_IEEEB1,
1220 MDIO_CL73_IEEEB1_AN_ADV2, ®_val);
1221 /* In the SerDes we support only the 1G.
1222 In the XGXS we support the 10G KX4
1223 but we currently do not support the KR */
1224 if (vars->phy_flags & PHY_XGXS_FLAG) {
1225 DP(NETIF_MSG_LINK, "XGXS\n");
1227 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1229 DP(NETIF_MSG_LINK, "SerDes\n");
1231 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1233 CL45_WR_OVER_CL22(bp, params->port,
1235 MDIO_REG_BANK_CL73_IEEEB1,
1236 MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
1238 /* CL73 Autoneg Enabled */
1239 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
1241 /* CL73 Autoneg Disabled */
1244 CL45_WR_OVER_CL22(bp, params->port,
1246 MDIO_REG_BANK_CL73_IEEEB0,
1247 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1250 /* program SerDes, forced speed */
1251 static void bnx2x_program_serdes(struct link_params *params,
1252 struct link_vars *vars)
1254 struct bnx2x *bp = params->bp;
1257 /* program duplex, disable autoneg */
1259 CL45_RD_OVER_CL22(bp, params->port,
1261 MDIO_REG_BANK_COMBO_IEEE0,
1262 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
1263 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1264 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
1265 if (params->req_duplex == DUPLEX_FULL)
1266 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1267 CL45_WR_OVER_CL22(bp, params->port,
1269 MDIO_REG_BANK_COMBO_IEEE0,
1270 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1273 - needed only if the speed is greater than 1G (2.5G or 10G) */
1274 CL45_RD_OVER_CL22(bp, params->port,
1276 MDIO_REG_BANK_SERDES_DIGITAL,
1277 MDIO_SERDES_DIGITAL_MISC1, ®_val);
1278 /* clearing the speed value before setting the right speed */
1279 DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1281 reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1282 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1284 if (!((vars->line_speed == SPEED_1000) ||
1285 (vars->line_speed == SPEED_100) ||
1286 (vars->line_speed == SPEED_10))) {
1288 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1289 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1290 if (vars->line_speed == SPEED_10000)
1292 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1293 if (vars->line_speed == SPEED_13000)
1295 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1298 CL45_WR_OVER_CL22(bp, params->port,
1300 MDIO_REG_BANK_SERDES_DIGITAL,
1301 MDIO_SERDES_DIGITAL_MISC1, reg_val);
1305 static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1307 struct bnx2x *bp = params->bp;
1310 /* configure the 48 bits for BAM AN */
1312 /* set extended capabilities */
1313 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1314 val |= MDIO_OVER_1G_UP1_2_5G;
1315 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1316 val |= MDIO_OVER_1G_UP1_10G;
1317 CL45_WR_OVER_CL22(bp, params->port,
1319 MDIO_REG_BANK_OVER_1G,
1320 MDIO_OVER_1G_UP1, val);
1322 CL45_WR_OVER_CL22(bp, params->port,
1324 MDIO_REG_BANK_OVER_1G,
1325 MDIO_OVER_1G_UP3, 0);
1328 static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
1330 *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1331 /* resolve pause mode and advertisement
1332 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1334 switch (params->req_flow_ctrl) {
1335 case BNX2X_FLOW_CTRL_AUTO:
1336 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
1338 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1341 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1344 case BNX2X_FLOW_CTRL_TX:
1346 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1349 case BNX2X_FLOW_CTRL_RX:
1350 case BNX2X_FLOW_CTRL_BOTH:
1351 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1354 case BNX2X_FLOW_CTRL_NONE:
1356 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1361 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1364 struct bnx2x *bp = params->bp;
1365 /* for AN, we are always publishing full duplex */
1367 CL45_WR_OVER_CL22(bp, params->port,
1369 MDIO_REG_BANK_COMBO_IEEE0,
1370 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
1373 static void bnx2x_restart_autoneg(struct link_params *params)
1375 struct bnx2x *bp = params->bp;
1376 DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1378 /* enable and restart clause 73 aneg */
1381 CL45_RD_OVER_CL22(bp, params->port,
1383 MDIO_REG_BANK_CL73_IEEEB0,
1384 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1386 CL45_WR_OVER_CL22(bp, params->port,
1388 MDIO_REG_BANK_CL73_IEEEB0,
1389 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1391 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1392 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1395 /* Enable and restart BAM/CL37 aneg */
1398 CL45_RD_OVER_CL22(bp, params->port,
1400 MDIO_REG_BANK_COMBO_IEEE0,
1401 MDIO_COMBO_IEEE0_MII_CONTROL,
1404 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1406 CL45_WR_OVER_CL22(bp, params->port,
1408 MDIO_REG_BANK_COMBO_IEEE0,
1409 MDIO_COMBO_IEEE0_MII_CONTROL,
1411 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1412 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1416 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1417 struct link_vars *vars)
1419 struct bnx2x *bp = params->bp;
1422 /* in SGMII mode, the unicore is always slave */
1424 CL45_RD_OVER_CL22(bp, params->port,
1426 MDIO_REG_BANK_SERDES_DIGITAL,
1427 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1429 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1430 /* set sgmii mode (and not fiber) */
1431 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1432 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1433 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1434 CL45_WR_OVER_CL22(bp, params->port,
1436 MDIO_REG_BANK_SERDES_DIGITAL,
1437 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1440 /* if forced speed */
1441 if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1442 /* set speed, disable autoneg */
1445 CL45_RD_OVER_CL22(bp, params->port,
1447 MDIO_REG_BANK_COMBO_IEEE0,
1448 MDIO_COMBO_IEEE0_MII_CONTROL,
1450 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1451 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1452 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1454 switch (vars->line_speed) {
1457 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1461 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1464 /* there is nothing to set for 10M */
1467 /* invalid speed for SGMII */
1468 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1473 /* setting the full duplex */
1474 if (params->req_duplex == DUPLEX_FULL)
1476 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1477 CL45_WR_OVER_CL22(bp, params->port,
1479 MDIO_REG_BANK_COMBO_IEEE0,
1480 MDIO_COMBO_IEEE0_MII_CONTROL,
1483 } else { /* AN mode */
1484 /* enable and restart AN */
1485 bnx2x_restart_autoneg(params);
1494 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1496 switch (pause_result) { /* ASYM P ASYM P */
1497 case 0xb: /* 1 0 1 1 */
1498 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
1501 case 0xe: /* 1 1 1 0 */
1502 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
1505 case 0x5: /* 0 1 0 1 */
1506 case 0x7: /* 0 1 1 1 */
1507 case 0xd: /* 1 1 0 1 */
1508 case 0xf: /* 1 1 1 1 */
1509 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
1517 static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1518 struct link_vars *vars)
1520 struct bnx2x *bp = params->bp;
1522 u16 ld_pause; /* local */
1523 u16 lp_pause; /* link partner */
1524 u16 an_complete; /* AN complete */
1528 u8 port = params->port;
1529 ext_phy_addr = ((params->ext_phy_config &
1530 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1531 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1533 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1536 bnx2x_cl45_read(bp, port,
1540 MDIO_AN_REG_STATUS, &an_complete);
1541 bnx2x_cl45_read(bp, port,
1545 MDIO_AN_REG_STATUS, &an_complete);
1547 if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1549 bnx2x_cl45_read(bp, port,
1553 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1554 bnx2x_cl45_read(bp, port,
1558 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1559 pause_result = (ld_pause &
1560 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1561 pause_result |= (lp_pause &
1562 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1563 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1565 bnx2x_pause_resolve(vars, pause_result);
1566 if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
1567 ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1568 bnx2x_cl45_read(bp, port,
1572 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1574 bnx2x_cl45_read(bp, port,
1578 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1579 pause_result = (ld_pause &
1580 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1581 pause_result |= (lp_pause &
1582 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1584 bnx2x_pause_resolve(vars, pause_result);
1585 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1593 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1594 struct link_vars *vars,
1597 struct bnx2x *bp = params->bp;
1598 u16 ld_pause; /* local driver */
1599 u16 lp_pause; /* link partner */
1602 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1604 /* resolve from gp_status in case of AN complete and not sgmii */
1605 if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1606 (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1607 (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1608 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1609 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1610 CL45_RD_OVER_CL22(bp, params->port,
1612 MDIO_REG_BANK_COMBO_IEEE0,
1613 MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1615 CL45_RD_OVER_CL22(bp, params->port,
1617 MDIO_REG_BANK_COMBO_IEEE0,
1618 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1620 pause_result = (ld_pause &
1621 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1622 pause_result |= (lp_pause &
1623 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1624 DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1625 bnx2x_pause_resolve(vars, pause_result);
1626 } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1627 (bnx2x_ext_phy_resove_fc(params, vars))) {
1630 if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
1631 vars->flow_ctrl = params->req_fc_auto_adv;
1633 vars->flow_ctrl = params->req_flow_ctrl;
1635 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1639 static u8 bnx2x_link_settings_status(struct link_params *params,
1640 struct link_vars *vars,
1643 struct bnx2x *bp = params->bp;
1646 vars->link_status = 0;
1648 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1649 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1652 vars->phy_link_up = 1;
1653 vars->link_status |= LINK_STATUS_LINK_UP;
1655 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1656 vars->duplex = DUPLEX_FULL;
1658 vars->duplex = DUPLEX_HALF;
1660 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1662 switch (gp_status & GP_STATUS_SPEED_MASK) {
1664 new_line_speed = SPEED_10;
1665 if (vars->duplex == DUPLEX_FULL)
1666 vars->link_status |= LINK_10TFD;
1668 vars->link_status |= LINK_10THD;
1671 case GP_STATUS_100M:
1672 new_line_speed = SPEED_100;
1673 if (vars->duplex == DUPLEX_FULL)
1674 vars->link_status |= LINK_100TXFD;
1676 vars->link_status |= LINK_100TXHD;
1680 case GP_STATUS_1G_KX:
1681 new_line_speed = SPEED_1000;
1682 if (vars->duplex == DUPLEX_FULL)
1683 vars->link_status |= LINK_1000TFD;
1685 vars->link_status |= LINK_1000THD;
1688 case GP_STATUS_2_5G:
1689 new_line_speed = SPEED_2500;
1690 if (vars->duplex == DUPLEX_FULL)
1691 vars->link_status |= LINK_2500TFD;
1693 vars->link_status |= LINK_2500THD;
1699 "link speed unsupported gp_status 0x%x\n",
1703 case GP_STATUS_10G_KX4:
1704 case GP_STATUS_10G_HIG:
1705 case GP_STATUS_10G_CX4:
1706 new_line_speed = SPEED_10000;
1707 vars->link_status |= LINK_10GTFD;
1710 case GP_STATUS_12G_HIG:
1711 new_line_speed = SPEED_12000;
1712 vars->link_status |= LINK_12GTFD;
1715 case GP_STATUS_12_5G:
1716 new_line_speed = SPEED_12500;
1717 vars->link_status |= LINK_12_5GTFD;
1721 new_line_speed = SPEED_13000;
1722 vars->link_status |= LINK_13GTFD;
1726 new_line_speed = SPEED_15000;
1727 vars->link_status |= LINK_15GTFD;
1731 new_line_speed = SPEED_16000;
1732 vars->link_status |= LINK_16GTFD;
1737 "link speed unsupported gp_status 0x%x\n",
1743 /* Upon link speed change set the NIG into drain mode.
1744 Comes to deals with possible FIFO glitch due to clk change
1745 when speed is decreased without link down indicator */
1746 if (new_line_speed != vars->line_speed) {
1747 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
1748 + params->port*4, 0);
1751 vars->line_speed = new_line_speed;
1752 vars->link_status |= LINK_STATUS_SERDES_LINK;
1754 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1755 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1756 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1757 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1758 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
1759 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1760 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
1761 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1762 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481))) {
1763 vars->autoneg = AUTO_NEG_ENABLED;
1765 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1766 vars->autoneg |= AUTO_NEG_COMPLETE;
1767 vars->link_status |=
1768 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1771 vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1772 vars->link_status |=
1773 LINK_STATUS_PARALLEL_DETECTION_USED;
1776 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1777 vars->link_status |=
1778 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1780 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1781 vars->link_status |=
1782 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1784 } else { /* link_down */
1785 DP(NETIF_MSG_LINK, "phy link down\n");
1787 vars->phy_link_up = 0;
1789 vars->duplex = DUPLEX_FULL;
1790 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1791 vars->autoneg = AUTO_NEG_DISABLED;
1792 vars->mac_type = MAC_TYPE_NONE;
1795 DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x \n",
1796 gp_status, vars->phy_link_up, vars->line_speed);
1797 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x"
1800 vars->flow_ctrl, vars->autoneg);
1801 DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1806 static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
1808 struct bnx2x *bp = params->bp;
1814 CL45_RD_OVER_CL22(bp, params->port,
1816 MDIO_REG_BANK_OVER_1G,
1817 MDIO_OVER_1G_LP_UP2, &lp_up2);
1819 CL45_RD_OVER_CL22(bp, params->port,
1822 MDIO_TX0_TX_DRIVER, &tx_driver);
1824 /* bits [10:7] at lp_up2, positioned at [15:12] */
1825 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1826 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1827 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1829 if ((lp_up2 != 0) &&
1830 (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
1831 /* replace tx_driver bits [15:12] */
1832 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1833 tx_driver |= lp_up2;
1834 CL45_WR_OVER_CL22(bp, params->port,
1837 MDIO_TX0_TX_DRIVER, tx_driver);
1841 static u8 bnx2x_emac_program(struct link_params *params,
1842 u32 line_speed, u32 duplex)
1844 struct bnx2x *bp = params->bp;
1845 u8 port = params->port;
1848 DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1849 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1851 (EMAC_MODE_25G_MODE |
1852 EMAC_MODE_PORT_MII_10M |
1853 EMAC_MODE_HALF_DUPLEX));
1854 switch (line_speed) {
1856 mode |= EMAC_MODE_PORT_MII_10M;
1860 mode |= EMAC_MODE_PORT_MII;
1864 mode |= EMAC_MODE_PORT_GMII;
1868 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1872 /* 10G not valid for EMAC */
1873 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1877 if (duplex == DUPLEX_HALF)
1878 mode |= EMAC_MODE_HALF_DUPLEX;
1880 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1883 bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1884 line_speed, params->hw_led_mode, params->chip_id);
1888 /*****************************************************************************/
1889 /* External Phy section */
1890 /*****************************************************************************/
1891 static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
1893 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1894 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
1896 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1897 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
1900 static void bnx2x_ext_phy_reset(struct link_params *params,
1901 struct link_vars *vars)
1903 struct bnx2x *bp = params->bp;
1905 u8 ext_phy_addr = ((params->ext_phy_config &
1906 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1907 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1908 DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1909 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1910 /* The PHY reset is controled by GPIO 1
1911 * Give it 1ms of reset pulse
1913 if (vars->phy_flags & PHY_XGXS_FLAG) {
1915 switch (ext_phy_type) {
1916 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1917 DP(NETIF_MSG_LINK, "XGXS Direct\n");
1920 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1921 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1922 DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1924 /* Restore normal power mode*/
1925 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1926 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1930 bnx2x_hw_reset(bp, params->port);
1932 bnx2x_cl45_write(bp, params->port,
1936 MDIO_PMA_REG_CTRL, 0xa040);
1938 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
1940 /* Restore normal power mode*/
1941 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1942 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1945 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1946 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1949 bnx2x_cl45_write(bp, params->port,
1957 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1958 /* Unset Low Power Mode and SW reset */
1959 /* Restore normal power mode*/
1960 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1961 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1964 DP(NETIF_MSG_LINK, "XGXS 8072\n");
1965 bnx2x_cl45_write(bp, params->port,
1972 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1975 emac_base = (params->port) ? GRCBASE_EMAC0 :
1978 /* Restore normal power mode*/
1979 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1980 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1983 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1984 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1987 DP(NETIF_MSG_LINK, "XGXS 8073\n");
1991 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1992 DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1994 /* Restore normal power mode*/
1995 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1996 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2000 bnx2x_hw_reset(bp, params->port);
2004 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
2006 /* Restore normal power mode*/
2007 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2008 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2012 bnx2x_hw_reset(bp, params->port);
2014 bnx2x_cl45_write(bp, params->port,
2021 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2022 DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
2026 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
2027 params->ext_phy_config);
2031 } else { /* SerDes */
2032 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2033 switch (ext_phy_type) {
2034 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
2035 DP(NETIF_MSG_LINK, "SerDes Direct\n");
2038 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
2039 DP(NETIF_MSG_LINK, "SerDes 5482\n");
2040 bnx2x_hw_reset(bp, params->port);
2045 "BAD SerDes ext_phy_config 0x%x\n",
2046 params->ext_phy_config);
2053 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
2054 u32 shmem_base, u32 spirom_ver)
2056 DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x\n",
2057 (u16)(spirom_ver>>16), (u16)spirom_ver);
2058 REG_WR(bp, shmem_base +
2059 offsetof(struct shmem_region,
2060 port_mb[port].ext_phy_fw_version),
2064 static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
2065 u32 ext_phy_type, u8 ext_phy_addr,
2068 u16 fw_ver1, fw_ver2;
2069 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2070 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2071 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2072 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2073 bnx2x_save_spirom_version(bp, port, shmem_base,
2074 (u32)(fw_ver1<<16 | fw_ver2));
2077 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
2079 struct bnx2x *bp = params->bp;
2080 u8 port = params->port;
2081 u8 ext_phy_addr = ((params->ext_phy_config &
2082 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2083 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2084 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2086 /* Need to wait 200ms after reset */
2088 /* Boot port from external ROM
2089 * Set ser_boot_ctl bit in the MISC_CTRL1 register
2091 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2093 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2095 /* Reset internal microprocessor */
2096 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2098 MDIO_PMA_REG_GEN_CTRL,
2099 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2100 /* set micro reset = 0 */
2101 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2103 MDIO_PMA_REG_GEN_CTRL,
2104 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2105 /* Reset internal microprocessor */
2106 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2108 MDIO_PMA_REG_GEN_CTRL,
2109 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2110 /* wait for 100ms for code download via SPI port */
2113 /* Clear ser_boot_ctl bit */
2114 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2116 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2120 bnx2x_save_bcm_spirom_ver(bp, port,
2123 params->shmem_base);
2126 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2128 /* This is only required for 8073A1, version 102 only */
2130 struct bnx2x *bp = params->bp;
2131 u8 ext_phy_addr = ((params->ext_phy_config &
2132 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2133 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2136 /* Read 8073 HW revision*/
2137 bnx2x_cl45_read(bp, params->port,
2138 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2144 /* No need to workaround in 8073 A1 */
2148 bnx2x_cl45_read(bp, params->port,
2149 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2152 MDIO_PMA_REG_ROM_VER2, &val);
2154 /* SNR should be applied only for version 0x102 */
2161 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2163 struct bnx2x *bp = params->bp;
2164 u8 ext_phy_addr = ((params->ext_phy_config &
2165 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2166 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2167 u16 val, cnt, cnt1 ;
2169 bnx2x_cl45_read(bp, params->port,
2170 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2176 /* No need to workaround in 8073 A1 */
2179 /* XAUI workaround in 8073 A0: */
2181 /* After loading the boot ROM and restarting Autoneg,
2182 poll Dev1, Reg $C820: */
2184 for (cnt = 0; cnt < 1000; cnt++) {
2185 bnx2x_cl45_read(bp, params->port,
2186 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2190 /* If bit [14] = 0 or bit [13] = 0, continue on with
2191 system initialization (XAUI work-around not required,
2192 as these bits indicate 2.5G or 1G link up). */
2193 if (!(val & (1<<14)) || !(val & (1<<13))) {
2194 DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2196 } else if (!(val & (1<<15))) {
2197 DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2198 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2199 it's MSB (bit 15) goes to 1 (indicating that the
2200 XAUI workaround has completed),
2201 then continue on with system initialization.*/
2202 for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2203 bnx2x_cl45_read(bp, params->port,
2204 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2208 if (val & (1<<15)) {
2210 "XAUI workaround has completed\n");
2219 DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2224 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2225 u8 ext_phy_addr, u32 shmem_base)
2227 /* Boot port from external ROM */
2229 bnx2x_cl45_write(bp, port,
2230 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2233 MDIO_PMA_REG_GEN_CTRL,
2236 /* ucode reboot and rst */
2237 bnx2x_cl45_write(bp, port,
2238 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2241 MDIO_PMA_REG_GEN_CTRL,
2244 bnx2x_cl45_write(bp, port,
2245 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2248 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2250 /* Reset internal microprocessor */
2251 bnx2x_cl45_write(bp, port,
2252 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2255 MDIO_PMA_REG_GEN_CTRL,
2256 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2258 /* Release srst bit */
2259 bnx2x_cl45_write(bp, port,
2260 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2263 MDIO_PMA_REG_GEN_CTRL,
2264 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2266 /* wait for 100ms for code download via SPI port */
2269 /* Clear ser_boot_ctl bit */
2270 bnx2x_cl45_write(bp, port,
2271 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2274 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2276 bnx2x_save_bcm_spirom_ver(bp, port,
2277 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2282 static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
2284 struct bnx2x *bp = params->bp;
2285 u8 port = params->port;
2286 u8 ext_phy_addr = ((params->ext_phy_config &
2287 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2288 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2289 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2291 /* Need to wait 100ms after reset */
2294 /* Set serial boot control for external load */
2295 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2297 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2299 /* Micro controller re-boot */
2300 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2302 MDIO_PMA_REG_GEN_CTRL,
2303 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2305 /* Set soft reset */
2306 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2308 MDIO_PMA_REG_GEN_CTRL,
2309 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2311 /* Clear soft reset.
2312 Will automatically reset micro-controller re-boot */
2313 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2315 MDIO_PMA_REG_GEN_CTRL,
2316 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2318 /* wait for 100ms for microcode load */
2321 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
2322 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2324 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2327 bnx2x_save_bcm_spirom_ver(bp, port,
2330 params->shmem_base);
2333 static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port,
2334 u8 ext_phy_addr, u8 tx_en)
2337 DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
2339 /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
2340 bnx2x_cl45_read(bp, port,
2341 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2344 MDIO_PMA_REG_PHY_IDENTIFIER,
2352 bnx2x_cl45_write(bp, port,
2353 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2356 MDIO_PMA_REG_PHY_IDENTIFIER,
2361 static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
2362 u8 byte_cnt, u8 *o_buf) {
2363 struct bnx2x *bp = params->bp;
2365 u8 port = params->port;
2366 u8 ext_phy_addr = ((params->ext_phy_config &
2367 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2368 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2369 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2370 if (byte_cnt > 16) {
2371 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2372 " is limited to 0xf\n");
2375 /* Set the read command byte count */
2376 bnx2x_cl45_write(bp, port,
2380 MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT,
2381 (byte_cnt | 0xa000));
2383 /* Set the read command address */
2384 bnx2x_cl45_write(bp, port,
2388 MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR,
2391 /* Activate read command */
2392 bnx2x_cl45_write(bp, port,
2396 MDIO_PMA_REG_8726_TWO_WIRE_CTRL,
2399 /* Wait up to 500us for command complete status */
2400 for (i = 0; i < 100; i++) {
2401 bnx2x_cl45_read(bp, port,
2405 MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2406 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2407 MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE)
2412 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) !=
2413 MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE) {
2415 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2416 (val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK));
2420 /* Read the buffer */
2421 for (i = 0; i < byte_cnt; i++) {
2422 bnx2x_cl45_read(bp, port,
2426 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2427 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
2430 for (i = 0; i < 100; i++) {
2431 bnx2x_cl45_read(bp, port,
2435 MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2436 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2437 MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE)
2445 static u8 bnx2x_get_sfp_module_type(struct link_params *params,
2448 struct bnx2x *bp = params->bp;
2450 *module_type = SFP_MODULE_TYPE_UNKNOWN;
2452 /* First check for copper cable */
2453 if (bnx2x_read_sfp_module_eeprom(params,
2454 SFP_EEPROM_CON_TYPE_ADDR,
2457 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM");
2462 case SFP_EEPROM_CON_TYPE_VAL_COPPER:
2464 u8 copper_module_type;
2465 /* Check if its active cable( includes SFP+ module)
2467 if (bnx2x_read_sfp_module_eeprom(params,
2468 SFP_EEPROM_FC_TX_TECH_ADDR,
2470 &copper_module_type) !=
2473 "Failed to read copper-cable-type"
2474 " from SFP+ EEPROM\n");
2478 if (copper_module_type &
2479 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
2480 DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
2481 *module_type = SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE;
2482 } else if (copper_module_type &
2483 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
2484 DP(NETIF_MSG_LINK, "Passive Copper"
2485 " cable detected\n");
2487 SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE;
2489 DP(NETIF_MSG_LINK, "Unknown copper-cable-"
2490 "type 0x%x !!!\n", copper_module_type);
2495 case SFP_EEPROM_CON_TYPE_VAL_LC:
2496 DP(NETIF_MSG_LINK, "Optic module detected\n");
2497 *module_type = SFP_MODULE_TYPE_LC;
2501 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
2509 /* This function read the relevant field from the module ( SFP+ ),
2510 and verify it is compliant with this board */
2511 static u8 bnx2x_verify_sfp_module(struct link_params *params,
2514 struct bnx2x *bp = params->bp;
2515 u8 *str_p, *tmp_buf;
2518 #define COMPLIANCE_STR_CNT 6
2519 u8 *compliance_str[] = {"Broadcom", "JDSU", "Molex Inc", "PICOLIGHT",
2520 "FINISAR CORP. ", "Amphenol"};
2521 u8 buf[SFP_EEPROM_VENDOR_NAME_SIZE];
2522 /* Passive Copper cables are allowed to participate,
2523 since the module is hardwired to the copper cable */
2525 if (!(params->feature_config_flags &
2526 FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2527 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
2531 if (module_type != SFP_MODULE_TYPE_LC) {
2532 DP(NETIF_MSG_LINK, "No need to verify copper cable\n");
2536 /* In case of non copper cable or Active copper cable,
2537 verify that the SFP+ module is compliant with this board*/
2538 if (bnx2x_read_sfp_module_eeprom(params,
2539 SFP_EEPROM_VENDOR_NAME_ADDR,
2540 SFP_EEPROM_VENDOR_NAME_SIZE,
2542 DP(NETIF_MSG_LINK, "Failed to read Vendor-Name from"
2543 " module EEPROM\n");
2546 for (i = 0; i < COMPLIANCE_STR_CNT; i++) {
2547 str_p = compliance_str[i];
2550 if ((u8)(*tmp_buf) != (u8)(*str_p))
2557 DP(NETIF_MSG_LINK, "SFP+ Module verified, "
2562 DP(NETIF_MSG_LINK, "Incompliant SFP+ module. Disable module !!!\n");
2567 static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
2570 struct bnx2x *bp = params->bp;
2571 u8 port = params->port;
2572 u8 options[SFP_EEPROM_OPTIONS_SIZE];
2574 u8 ext_phy_addr = ((params->ext_phy_config &
2575 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2576 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2578 if (bnx2x_read_sfp_module_eeprom(params,
2579 SFP_EEPROM_OPTIONS_ADDR,
2580 SFP_EEPROM_OPTIONS_SIZE,
2582 DP(NETIF_MSG_LINK, "Failed to read Option field from"
2583 " module EEPROM\n");
2586 limiting_mode = !(options[0] &
2587 SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK);
2588 if (limiting_mode &&
2589 (module_type != SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE)) {
2591 "Module options = 0x%x.Setting LIMITING MODE\n",
2593 bnx2x_cl45_write(bp, port,
2594 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2597 MDIO_PMA_REG_ROM_VER2,
2598 SFP_LIMITING_MODE_VALUE);
2599 } else { /* LRM mode ( default )*/
2600 u16 cur_limiting_mode;
2601 DP(NETIF_MSG_LINK, "Module options = 0x%x.Setting LRM MODE\n",
2604 bnx2x_cl45_read(bp, port,
2605 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2608 MDIO_PMA_REG_ROM_VER2,
2609 &cur_limiting_mode);
2611 /* Changing to LRM mode takes quite few seconds.
2612 So do it only if current mode is limiting
2613 ( default is LRM )*/
2614 if (cur_limiting_mode != SFP_LIMITING_MODE_VALUE)
2617 bnx2x_cl45_write(bp, port,
2618 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2621 MDIO_PMA_REG_LRM_MODE,
2623 bnx2x_cl45_write(bp, port,
2624 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2627 MDIO_PMA_REG_ROM_VER2,
2629 bnx2x_cl45_write(bp, port,
2630 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2633 MDIO_PMA_REG_MISC_CTRL0,
2635 bnx2x_cl45_write(bp, port,
2636 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2639 MDIO_PMA_REG_LRM_MODE,
2645 static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
2648 struct bnx2x *bp = params->bp;
2650 /* Initialization time after hot-plug may take up to 300ms for some
2651 phys type ( e.g. JDSU ) */
2652 for (timeout = 0; timeout < 60; timeout++) {
2653 if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
2655 DP(NETIF_MSG_LINK, "SFP+ module initialization "
2656 "took %d ms\n", timeout * 5);
2664 static u8 bnx2x_sfp_module_detection(struct link_params *params)
2666 struct bnx2x *bp = params->bp;
2668 u8 ext_phy_addr = ((params->ext_phy_config &
2669 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2670 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2671 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2673 if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
2674 DP(NETIF_MSG_LINK, "Module detection is not required "
2679 DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
2682 if (bnx2x_get_sfp_module_type(params,
2683 &module_type) != 0) {
2684 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
2685 if (!(params->feature_config_flags &
2686 FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2687 /* In case module detection is disabled, it trys to
2688 link up. The issue that can happen here is LRM /
2689 LIMITING mode which set according to the module-type*/
2690 DP(NETIF_MSG_LINK, "Unable to read module-type."
2691 "Probably due to Bit Stretching."
2692 " Proceeding...\n");
2696 } else if (bnx2x_verify_sfp_module(params, module_type) !=
2698 /* check SFP+ module compatibility */
2699 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
2700 /* Turn on fault module-detected led */
2701 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2702 MISC_REGISTERS_GPIO_HIGH,
2707 /* Turn off fault module-detected led */
2708 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2709 MISC_REGISTERS_GPIO_LOW,
2712 /* Check and set limiting mode / LRM mode */
2713 if (bnx2x_bcm8726_set_limiting_mode(params, module_type)
2715 DP(NETIF_MSG_LINK, "Setting limiting mode failed!!\n");
2719 /* Enable transmit for this module */
2720 bnx2x_bcm8726_set_transmitter(bp, params->port,
2725 void bnx2x_handle_module_detect_int(struct link_params *params)
2727 struct bnx2x *bp = params->bp;
2729 u8 port = params->port;
2730 /* Set valid module led off */
2731 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2732 MISC_REGISTERS_GPIO_HIGH,
2735 /* Get current gpio val refelecting module plugged in / out*/
2736 gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
2738 /* Call the handling function in case module is detected */
2739 if (gpio_val == 0) {
2741 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2742 MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
2745 if (bnx2x_wait_for_sfp_module_initialized(params)
2747 bnx2x_sfp_module_detection(params);
2749 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
2751 u8 ext_phy_addr = ((params->ext_phy_config &
2752 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2753 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2754 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2755 MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
2757 /* Module was plugged out. */
2758 /* Disable transmit for this module */
2759 bnx2x_bcm8726_set_transmitter(bp, params->port,
2764 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2766 struct bnx2x *bp = params->bp;
2767 u8 port = params->port;
2768 u8 ext_phy_addr = ((params->ext_phy_config &
2769 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2770 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2771 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2773 /* Force KR or KX */
2774 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2778 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2780 MDIO_PMA_REG_10G_CTRL2,
2782 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2784 MDIO_PMA_REG_BCM_CTRL,
2786 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2791 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2793 struct bnx2x *bp = params->bp;
2794 u8 port = params->port;
2796 u8 ext_phy_addr = ((params->ext_phy_config &
2797 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2798 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2799 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2801 bnx2x_cl45_read(bp, params->port,
2802 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2808 /* Mustn't set low power mode in 8073 A0 */
2812 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2813 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2815 MDIO_XS_PLL_SEQUENCER, &val);
2817 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2818 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2821 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2822 MDIO_XS_DEVAD, 0x805E, 0x1077);
2823 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2824 MDIO_XS_DEVAD, 0x805D, 0x0000);
2825 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2826 MDIO_XS_DEVAD, 0x805C, 0x030B);
2827 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2828 MDIO_XS_DEVAD, 0x805B, 0x1240);
2829 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2830 MDIO_XS_DEVAD, 0x805A, 0x2490);
2833 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2834 MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2835 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2836 MDIO_XS_DEVAD, 0x80A6, 0x9041);
2837 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2838 MDIO_XS_DEVAD, 0x80A5, 0x4640);
2841 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2842 MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2843 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2844 MDIO_XS_DEVAD, 0x80FD, 0x9249);
2845 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2846 MDIO_XS_DEVAD, 0x80FC, 0x2015);
2848 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
2849 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2851 MDIO_XS_PLL_SEQUENCER, &val);
2853 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2854 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2857 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
2858 struct link_vars *vars)
2861 struct bnx2x *bp = params->bp;
2863 u8 ext_phy_addr = ((params->ext_phy_config &
2864 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2865 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2866 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2868 bnx2x_cl45_read(bp, params->port,
2872 MDIO_AN_REG_CL37_FC_LD, &cl37_val);
2874 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2875 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2877 if ((vars->ieee_fc &
2878 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
2879 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
2880 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
2882 if ((vars->ieee_fc &
2883 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2884 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2885 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2887 if ((vars->ieee_fc &
2888 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2889 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2890 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2893 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
2895 bnx2x_cl45_write(bp, params->port,
2899 MDIO_AN_REG_CL37_FC_LD, cl37_val);
2903 static void bnx2x_ext_phy_set_pause(struct link_params *params,
2904 struct link_vars *vars)
2906 struct bnx2x *bp = params->bp;
2908 u8 ext_phy_addr = ((params->ext_phy_config &
2909 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2910 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2911 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2913 /* read modify write pause advertizing */
2914 bnx2x_cl45_read(bp, params->port,
2918 MDIO_AN_REG_ADV_PAUSE, &val);
2920 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2922 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2924 if ((vars->ieee_fc &
2925 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2926 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2927 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2929 if ((vars->ieee_fc &
2930 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2931 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2933 MDIO_AN_REG_ADV_PAUSE_PAUSE;
2936 "Ext phy AN advertize 0x%x\n", val);
2937 bnx2x_cl45_write(bp, params->port,
2941 MDIO_AN_REG_ADV_PAUSE, val);
2945 static void bnx2x_init_internal_phy(struct link_params *params,
2946 struct link_vars *vars)
2948 struct bnx2x *bp = params->bp;
2949 u8 port = params->port;
2950 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2953 rx_eq = ((params->serdes_config &
2954 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2955 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2957 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2958 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2959 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2960 CL45_WR_OVER_CL22(bp, port,
2963 MDIO_RX0_RX_EQ_BOOST,
2965 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2966 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2969 /* forced speed requested? */
2970 if (vars->line_speed != SPEED_AUTO_NEG) {
2971 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2973 /* disable autoneg */
2974 bnx2x_set_autoneg(params, vars);
2976 /* program speed and duplex */
2977 bnx2x_program_serdes(params, vars);
2979 } else { /* AN_mode */
2980 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2983 bnx2x_set_brcm_cl37_advertisment(params);
2985 /* program duplex & pause advertisement (for aneg) */
2986 bnx2x_set_ieee_aneg_advertisment(params,
2989 /* enable autoneg */
2990 bnx2x_set_autoneg(params, vars);
2992 /* enable and restart AN */
2993 bnx2x_restart_autoneg(params);
2996 } else { /* SGMII mode */
2997 DP(NETIF_MSG_LINK, "SGMII\n");
2999 bnx2x_initialize_sgmii_process(params, vars);
3003 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
3005 struct bnx2x *bp = params->bp;
3012 if (vars->phy_flags & PHY_XGXS_FLAG) {
3013 ext_phy_addr = ((params->ext_phy_config &
3014 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3015 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3017 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3018 /* Make sure that the soft reset is off (expect for the 8072:
3019 * due to the lock, it will be done inside the specific
3022 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3023 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3024 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
3025 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
3026 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
3027 /* Wait for soft reset to get cleared upto 1 sec */
3028 for (cnt = 0; cnt < 1000; cnt++) {
3029 bnx2x_cl45_read(bp, params->port,
3033 MDIO_PMA_REG_CTRL, &ctrl);
3034 if (!(ctrl & (1<<15)))
3038 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
3042 switch (ext_phy_type) {
3043 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3046 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3047 DP(NETIF_MSG_LINK, "XGXS 8705\n");
3049 bnx2x_cl45_write(bp, params->port,
3053 MDIO_PMA_REG_MISC_CTRL,
3055 bnx2x_cl45_write(bp, params->port,
3059 MDIO_PMA_REG_PHY_IDENTIFIER,
3061 bnx2x_cl45_write(bp, params->port,
3065 MDIO_PMA_REG_CMU_PLL_BYPASS,
3067 bnx2x_cl45_write(bp, params->port,
3071 MDIO_WIS_REG_LASI_CNTL, 0x1);
3073 bnx2x_save_bcm_spirom_ver(bp, params->port,
3076 params->shmem_base);
3079 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3080 /* Wait until fw is loaded */
3081 for (cnt = 0; cnt < 100; cnt++) {
3082 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3083 ext_phy_addr, MDIO_PMA_DEVAD,
3084 MDIO_PMA_REG_ROM_VER1, &val);
3089 DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
3090 "after %d ms\n", cnt);
3092 /* First enable LASI */
3093 bnx2x_cl45_write(bp, params->port,
3097 MDIO_PMA_REG_RX_ALARM_CTRL,
3099 bnx2x_cl45_write(bp, params->port,
3103 MDIO_PMA_REG_LASI_CTRL, 0x0004);
3105 if (params->req_line_speed == SPEED_10000) {
3106 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
3108 bnx2x_cl45_write(bp, params->port,
3112 MDIO_PMA_REG_DIGITAL_CTRL,
3115 /* Force 1Gbps using autoneg with 1G
3118 /* Allow CL37 through CL73 */
3119 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
3120 bnx2x_cl45_write(bp, params->port,
3124 MDIO_AN_REG_CL37_CL73,
3127 /* Enable Full-Duplex advertisment on CL37 */
3128 bnx2x_cl45_write(bp, params->port,
3132 MDIO_AN_REG_CL37_FC_LP,
3134 /* Enable CL37 AN */
3135 bnx2x_cl45_write(bp, params->port,
3139 MDIO_AN_REG_CL37_AN,
3142 bnx2x_cl45_write(bp, params->port,
3146 MDIO_AN_REG_ADV, (1<<5));
3148 /* Enable clause 73 AN */
3149 bnx2x_cl45_write(bp, params->port,
3157 bnx2x_save_bcm_spirom_ver(bp, params->port,
3160 params->shmem_base);
3162 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3163 DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3164 bnx2x_bcm8726_external_rom_boot(params);
3166 /* Need to call module detected on initialization since
3167 the module detection triggered by actual module
3168 insertion might occur before driver is loaded, and when
3169 driver is loaded, it reset all registers, including the
3171 bnx2x_sfp_module_detection(params);
3172 if (params->req_line_speed == SPEED_1000) {
3173 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3174 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3175 ext_phy_addr, MDIO_PMA_DEVAD,
3176 MDIO_PMA_REG_CTRL, 0x40);
3177 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3178 ext_phy_addr, MDIO_PMA_DEVAD,
3179 MDIO_PMA_REG_10G_CTRL2, 0xD);
3180 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3181 ext_phy_addr, MDIO_PMA_DEVAD,
3182 MDIO_PMA_REG_LASI_CTRL, 0x5);
3183 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3184 ext_phy_addr, MDIO_PMA_DEVAD,
3185 MDIO_PMA_REG_RX_ALARM_CTRL,
3187 } else if ((params->req_line_speed ==
3189 ((params->speed_cap_mask &
3190 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3191 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
3192 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3193 ext_phy_addr, MDIO_AN_DEVAD,
3194 MDIO_AN_REG_ADV, 0x20);
3195 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3196 ext_phy_addr, MDIO_AN_DEVAD,
3197 MDIO_AN_REG_CL37_CL73, 0x040c);
3198 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3199 ext_phy_addr, MDIO_AN_DEVAD,
3200 MDIO_AN_REG_CL37_FC_LD, 0x0020);
3201 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3202 ext_phy_addr, MDIO_AN_DEVAD,
3203 MDIO_AN_REG_CL37_AN, 0x1000);
3204 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3205 ext_phy_addr, MDIO_AN_DEVAD,
3206 MDIO_AN_REG_CTRL, 0x1200);
3208 /* Enable RX-ALARM control to receive
3209 interrupt for 1G speed change */
3210 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3211 ext_phy_addr, MDIO_PMA_DEVAD,
3212 MDIO_PMA_REG_LASI_CTRL, 0x4);
3213 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3214 ext_phy_addr, MDIO_PMA_DEVAD,
3215 MDIO_PMA_REG_RX_ALARM_CTRL,
3218 } else { /* Default 10G. Set only LASI control */
3219 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3220 ext_phy_addr, MDIO_PMA_DEVAD,
3221 MDIO_PMA_REG_LASI_CTRL, 1);
3224 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3225 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3228 u16 rx_alarm_ctrl_val;
3231 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3232 rx_alarm_ctrl_val = 0x400;
3233 lasi_ctrl_val = 0x0004;
3235 rx_alarm_ctrl_val = (1<<2);
3236 lasi_ctrl_val = 0x0004;
3240 bnx2x_cl45_write(bp, params->port,
3244 MDIO_PMA_REG_RX_ALARM_CTRL,
3247 bnx2x_cl45_write(bp, params->port,
3251 MDIO_PMA_REG_LASI_CTRL,
3254 bnx2x_8073_set_pause_cl37(params, vars);
3257 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
3258 bnx2x_bcm8072_external_rom_boot(params);
3261 /* In case of 8073 with long xaui lines,
3262 don't set the 8073 xaui low power*/
3263 bnx2x_bcm8073_set_xaui_low_power_mode(params);
3266 bnx2x_cl45_read(bp, params->port,
3273 bnx2x_cl45_read(bp, params->port,
3277 MDIO_PMA_REG_RX_ALARM, &tmp1);
3279 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
3282 /* If this is forced speed, set to KR or KX
3283 * (all other are not supported)
3285 if (params->loopback_mode == LOOPBACK_EXT) {
3286 bnx2x_bcm807x_force_10G(params);
3288 "Forced speed 10G on 807X\n");
3291 bnx2x_cl45_write(bp, params->port,
3292 ext_phy_type, ext_phy_addr,
3294 MDIO_PMA_REG_BCM_CTRL,
3297 if (params->req_line_speed != SPEED_AUTO_NEG) {
3298 if (params->req_line_speed == SPEED_10000) {
3300 } else if (params->req_line_speed ==
3303 /* Note that 2.5G works only
3304 when used with 1G advertisment */
3310 if (params->speed_cap_mask &
3311 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3314 /* Note that 2.5G works only when
3315 used with 1G advertisment */
3316 if (params->speed_cap_mask &
3317 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
3318 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
3321 "807x autoneg val = 0x%x\n", val);
3324 bnx2x_cl45_write(bp, params->port,
3328 MDIO_AN_REG_ADV, val);
3331 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3333 bnx2x_cl45_read(bp, params->port,
3339 if (((params->speed_cap_mask &
3340 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
3341 (params->req_line_speed ==
3343 (params->req_line_speed ==
3346 /* Allow 2.5G for A1 and above */
3347 bnx2x_cl45_read(bp, params->port,
3348 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
3352 DP(NETIF_MSG_LINK, "Add 2.5G\n");
3358 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
3362 bnx2x_cl45_write(bp, params->port,
3369 /* Add support for CL37 (passive mode) II */
3371 bnx2x_cl45_read(bp, params->port,
3375 MDIO_AN_REG_CL37_FC_LD,
3378 bnx2x_cl45_write(bp, params->port,
3382 MDIO_AN_REG_CL37_FC_LD, (tmp1 |
3383 ((params->req_duplex == DUPLEX_FULL) ?
3386 /* Add support for CL37 (passive mode) III */
3387 bnx2x_cl45_write(bp, params->port,
3391 MDIO_AN_REG_CL37_AN, 0x1000);
3394 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3395 /* The SNR will improve about 2db by changing
3396 BW and FEE main tap. Rest commands are executed
3398 /*Change FFE main cursor to 5 in EDC register*/
3399 if (bnx2x_8073_is_snr_needed(params))
3400 bnx2x_cl45_write(bp, params->port,
3404 MDIO_PMA_REG_EDC_FFE_MAIN,
3407 /* Enable FEC (Forware Error Correction)
3408 Request in the AN */
3409 bnx2x_cl45_read(bp, params->port,
3413 MDIO_AN_REG_ADV2, &tmp1);
3417 bnx2x_cl45_write(bp, params->port,
3421 MDIO_AN_REG_ADV2, tmp1);
3425 bnx2x_ext_phy_set_pause(params, vars);
3427 /* Restart autoneg */
3429 bnx2x_cl45_write(bp, params->port,
3433 MDIO_AN_REG_CTRL, 0x1200);
3434 DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
3435 "Advertise 1G=%x, 10G=%x\n",
3436 ((val & (1<<5)) > 0),
3437 ((val & (1<<7)) > 0));
3440 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3442 u16 fw_ver1, fw_ver2;
3444 "Setting the SFX7101 LASI indication\n");
3446 bnx2x_cl45_write(bp, params->port,
3450 MDIO_PMA_REG_LASI_CTRL, 0x1);
3452 "Setting the SFX7101 LED to blink on traffic\n");
3453 bnx2x_cl45_write(bp, params->port,
3457 MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
3459 bnx2x_ext_phy_set_pause(params, vars);
3460 /* Restart autoneg */
3461 bnx2x_cl45_read(bp, params->port,
3465 MDIO_AN_REG_CTRL, &val);
3467 bnx2x_cl45_write(bp, params->port,
3471 MDIO_AN_REG_CTRL, val);
3473 /* Save spirom version */
3474 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3475 ext_phy_addr, MDIO_PMA_DEVAD,
3476 MDIO_PMA_REG_7101_VER1, &fw_ver1);
3478 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3479 ext_phy_addr, MDIO_PMA_DEVAD,
3480 MDIO_PMA_REG_7101_VER2, &fw_ver2);
3482 bnx2x_save_spirom_version(params->bp, params->port,
3484 (u32)(fw_ver1<<16 | fw_ver2));
3488 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
3490 "Setting the BCM8481 LASI control\n");
3492 bnx2x_cl45_write(bp, params->port,
3496 MDIO_PMA_REG_LASI_CTRL, 0x1);
3498 /* Restart autoneg */
3499 bnx2x_cl45_read(bp, params->port,
3503 MDIO_AN_REG_CTRL, &val);
3505 bnx2x_cl45_write(bp, params->port,
3509 MDIO_AN_REG_CTRL, val);
3511 bnx2x_save_bcm_spirom_ver(bp, params->port,
3514 params->shmem_base);
3517 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
3519 "XGXS PHY Failure detected 0x%x\n",
3520 params->ext_phy_config);
3524 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3525 params->ext_phy_config);
3530 } else { /* SerDes */
3532 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3533 switch (ext_phy_type) {
3534 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3535 DP(NETIF_MSG_LINK, "SerDes Direct\n");
3538 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3539 DP(NETIF_MSG_LINK, "SerDes 5482\n");
3543 DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
3544 params->ext_phy_config);
3552 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
3553 struct link_vars *vars)
3555 struct bnx2x *bp = params->bp;
3559 u16 rx_sd, pcs_status;
3560 u8 ext_phy_link_up = 0;
3561 u8 port = params->port;
3562 if (vars->phy_flags & PHY_XGXS_FLAG) {
3563 ext_phy_addr = ((params->ext_phy_config &
3564 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3565 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3567 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3568 switch (ext_phy_type) {
3569 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3570 DP(NETIF_MSG_LINK, "XGXS Direct\n");
3571 ext_phy_link_up = 1;
3574 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3575 DP(NETIF_MSG_LINK, "XGXS 8705\n");
3576 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3579 MDIO_WIS_REG_LASI_STATUS, &val1);
3580 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3582 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3585 MDIO_WIS_REG_LASI_STATUS, &val1);
3586 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3588 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3591 MDIO_PMA_REG_RX_SD, &rx_sd);
3592 DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
3593 ext_phy_link_up = (rx_sd & 0x1);
3594 if (ext_phy_link_up)
3595 vars->line_speed = SPEED_10000;
3598 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3599 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3600 DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
3602 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3604 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
3606 /* clear LASI indication*/
3607 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3609 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
3611 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3613 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
3615 DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
3616 "0x%x\n", val1, val2);
3618 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3620 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
3622 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3624 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
3626 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3628 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
3630 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3632 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
3635 DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
3636 " pcs_status 0x%x 1Gbps link_status 0x%x\n",
3637 rx_sd, pcs_status, val2);
3638 /* link is up if both bit 0 of pmd_rx_sd and
3639 * bit 0 of pcs_status are set, or if the autoneg bit
3642 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
3644 if (ext_phy_link_up) {
3646 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
3647 /* If transmitter is disabled,
3648 ignore false link up indication */
3649 bnx2x_cl45_read(bp, params->port,
3653 MDIO_PMA_REG_PHY_IDENTIFIER,
3655 if (val1 & (1<<15)) {
3656 DP(NETIF_MSG_LINK, "Tx is "
3658 ext_phy_link_up = 0;
3664 vars->line_speed = SPEED_1000;
3666 vars->line_speed = SPEED_10000;
3670 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3671 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3673 u16 link_status = 0;
3674 u16 an1000_status = 0;
3676 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3677 bnx2x_cl45_read(bp, params->port,
3681 MDIO_PCS_REG_LASI_STATUS, &val1);
3682 bnx2x_cl45_read(bp, params->port,
3686 MDIO_PCS_REG_LASI_STATUS, &val2);
3688 "870x LASI status 0x%x->0x%x\n",
3692 /* In 8073, port1 is directed through emac0 and
3693 * port0 is directed through emac1
3695 bnx2x_cl45_read(bp, params->port,
3699 MDIO_PMA_REG_LASI_STATUS, &val1);
3702 "8703 LASI status 0x%x\n",
3706 /* clear the interrupt LASI status register */
3707 bnx2x_cl45_read(bp, params->port,
3711 MDIO_PCS_REG_STATUS, &val2);
3712 bnx2x_cl45_read(bp, params->port,
3716 MDIO_PCS_REG_STATUS, &val1);
3717 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
3720 bnx2x_cl45_read(bp, params->port,
3727 /* Check the LASI */
3728 bnx2x_cl45_read(bp, params->port,
3732 MDIO_PMA_REG_RX_ALARM, &val2);
3734 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
3736 /* Check the link status */
3737 bnx2x_cl45_read(bp, params->port,
3741 MDIO_PCS_REG_STATUS, &val2);
3742 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
3744 bnx2x_cl45_read(bp, params->port,
3748 MDIO_PMA_REG_STATUS, &val2);
3749 bnx2x_cl45_read(bp, params->port,
3753 MDIO_PMA_REG_STATUS, &val1);
3754 ext_phy_link_up = ((val1 & 4) == 4);
3755 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
3757 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3759 if (ext_phy_link_up &&
3760 ((params->req_line_speed !=
3762 if (bnx2x_bcm8073_xaui_wa(params)
3764 ext_phy_link_up = 0;
3768 bnx2x_cl45_read(bp, params->port,
3774 bnx2x_cl45_read(bp, params->port,
3781 /* Check the link status on 1.1.2 */
3782 bnx2x_cl45_read(bp, params->port,
3786 MDIO_PMA_REG_STATUS, &val2);
3787 bnx2x_cl45_read(bp, params->port,
3791 MDIO_PMA_REG_STATUS, &val1);
3792 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3793 "an_link_status=0x%x\n",
3794 val2, val1, an1000_status);
3796 ext_phy_link_up = (((val1 & 4) == 4) ||
3797 (an1000_status & (1<<1)));
3798 if (ext_phy_link_up &&
3799 bnx2x_8073_is_snr_needed(params)) {
3800 /* The SNR will improve about 2dbby
3801 changing the BW and FEE main tap.*/
3803 /* The 1st write to change FFE main
3804 tap is set before restart AN */
3805 /* Change PLL Bandwidth in EDC
3807 bnx2x_cl45_write(bp, port, ext_phy_type,
3810 MDIO_PMA_REG_PLL_BANDWIDTH,
3813 /* Change CDR Bandwidth in EDC
3815 bnx2x_cl45_write(bp, port, ext_phy_type,
3818 MDIO_PMA_REG_CDR_BANDWIDTH,
3823 bnx2x_cl45_read(bp, params->port,
3830 /* Bits 0..2 --> speed detected,
3831 bits 13..15--> link is down */
3832 if ((link_status & (1<<2)) &&
3833 (!(link_status & (1<<15)))) {
3834 ext_phy_link_up = 1;
3835 vars->line_speed = SPEED_10000;
3837 "port %x: External link"
3838 " up in 10G\n", params->port);
3839 } else if ((link_status & (1<<1)) &&
3840 (!(link_status & (1<<14)))) {
3841 ext_phy_link_up = 1;
3842 vars->line_speed = SPEED_2500;
3844 "port %x: External link"
3845 " up in 2.5G\n", params->port);
3846 } else if ((link_status & (1<<0)) &&
3847 (!(link_status & (1<<13)))) {
3848 ext_phy_link_up = 1;
3849 vars->line_speed = SPEED_1000;
3851 "port %x: External link"
3852 " up in 1G\n", params->port);
3854 ext_phy_link_up = 0;
3856 "port %x: External link"
3857 " is down\n", params->port);
3860 /* See if 1G link is up for the 8072 */
3861 bnx2x_cl45_read(bp, params->port,
3867 bnx2x_cl45_read(bp, params->port,
3873 if (an1000_status & (1<<1)) {
3874 ext_phy_link_up = 1;
3875 vars->line_speed = SPEED_1000;
3877 "port %x: External link"
3878 " up in 1G\n", params->port);
3879 } else if (ext_phy_link_up) {
3880 ext_phy_link_up = 1;
3881 vars->line_speed = SPEED_10000;
3883 "port %x: External link"
3884 " up in 10G\n", params->port);
3891 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3892 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3895 MDIO_PMA_REG_LASI_STATUS, &val2);
3896 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3899 MDIO_PMA_REG_LASI_STATUS, &val1);
3901 "10G-base-T LASI status 0x%x->0x%x\n",
3903 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3906 MDIO_PMA_REG_STATUS, &val2);
3907 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3910 MDIO_PMA_REG_STATUS, &val1);
3912 "10G-base-T PMA status 0x%x->0x%x\n",
3914 ext_phy_link_up = ((val1 & 4) == 4);
3916 * print the AN outcome of the SFX7101 PHY
3918 if (ext_phy_link_up) {
3919 bnx2x_cl45_read(bp, params->port,
3923 MDIO_AN_REG_MASTER_STATUS,
3925 vars->line_speed = SPEED_10000;
3927 "SFX7101 AN status 0x%x->Master=%x\n",
3932 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
3933 /* Clear LASI interrupt */
3934 bnx2x_cl45_read(bp, params->port,
3938 MDIO_PMA_REG_LASI_STATUS, &val1);
3939 DP(NETIF_MSG_LINK, "8481 LASI status reg = 0x%x\n",
3942 /* Check 10G-BaseT link status */
3943 /* Check Global PMD signal ok */
3944 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3946 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
3948 /* Check PCS block lock */
3949 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3951 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
3953 DP(NETIF_MSG_LINK, "8481 1.a = 0x%x, 1.20 = 0x%x\n",
3955 if (rx_sd & pcs_status & 0x1) {
3956 vars->line_speed = SPEED_10000;
3957 ext_phy_link_up = 1;
3960 /* Check 1000-BaseT link status */
3961 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3963 MDIO_AN_DEVAD, 0xFFE1,
3966 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3968 MDIO_AN_DEVAD, 0xFFE1,
3970 DP(NETIF_MSG_LINK, "8481 7.FFE1 ="
3971 "0x%x-->0x%x\n", val1, val2);
3972 if (val2 & (1<<2)) {
3973 vars->line_speed = SPEED_1000;
3974 ext_phy_link_up = 1;
3980 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3981 params->ext_phy_config);
3982 ext_phy_link_up = 0;
3986 } else { /* SerDes */
3987 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3988 switch (ext_phy_type) {
3989 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3990 DP(NETIF_MSG_LINK, "SerDes Direct\n");
3991 ext_phy_link_up = 1;
3994 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3995 DP(NETIF_MSG_LINK, "SerDes 5482\n");
3996 ext_phy_link_up = 1;
4001 "BAD SerDes ext_phy_config 0x%x\n",
4002 params->ext_phy_config);
4003 ext_phy_link_up = 0;
4008 return ext_phy_link_up;
4011 static void bnx2x_link_int_enable(struct link_params *params)
4013 u8 port = params->port;
4016 struct bnx2x *bp = params->bp;
4017 /* setting the status to report on link up
4018 for either XGXS or SerDes */
4020 if (params->switch_cfg == SWITCH_CFG_10G) {
4021 mask = (NIG_MASK_XGXS0_LINK10G |
4022 NIG_MASK_XGXS0_LINK_STATUS);
4023 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
4024 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4025 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
4026 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
4028 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
4029 mask |= NIG_MASK_MI_INT;
4030 DP(NETIF_MSG_LINK, "enabled external phy int\n");
4033 } else { /* SerDes */
4034 mask = NIG_MASK_SERDES0_LINK_STATUS;
4035 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
4036 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4037 if ((ext_phy_type !=
4038 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4040 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
4041 mask |= NIG_MASK_MI_INT;
4042 DP(NETIF_MSG_LINK, "enabled external phy int\n");
4046 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4048 DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
4049 (params->switch_cfg == SWITCH_CFG_10G),
4050 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4052 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
4053 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4054 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4055 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
4056 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4057 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4058 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4065 static void bnx2x_link_int_ack(struct link_params *params,
4066 struct link_vars *vars, u8 is_10g)
4068 struct bnx2x *bp = params->bp;
4069 u8 port = params->port;
4071 /* first reset all status
4072 * we assume only one line will be change at a time */
4073 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4074 (NIG_STATUS_XGXS0_LINK10G |
4075 NIG_STATUS_XGXS0_LINK_STATUS |
4076 NIG_STATUS_SERDES0_LINK_STATUS));
4077 if (vars->phy_link_up) {
4079 /* Disable the 10G link interrupt
4080 * by writing 1 to the status register
4082 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
4084 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4085 NIG_STATUS_XGXS0_LINK10G);
4087 } else if (params->switch_cfg == SWITCH_CFG_10G) {
4088 /* Disable the link interrupt
4089 * by writing 1 to the relevant lane
4090 * in the status register
4092 u32 ser_lane = ((params->lane_config &
4093 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4094 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4096 DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
4098 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4100 NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
4102 } else { /* SerDes */
4103 DP(NETIF_MSG_LINK, "SerDes phy link up\n");
4104 /* Disable the link interrupt
4105 * by writing 1 to the status register
4108 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4109 NIG_STATUS_SERDES0_LINK_STATUS);
4112 } else { /* link_down */
4116 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
4119 u32 mask = 0xf0000000;
4123 /* Need more than 10chars for this format */
4130 digit = ((num & mask) >> shift);
4132 *str_ptr = digit + '0';
4134 *str_ptr = digit - 0xa + 'a';
4147 static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
4152 /* Enable EMAC0 in to enable MDIO */
4153 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
4154 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
4157 /* take ext phy out of reset */
4159 MISC_REGISTERS_GPIO_2,
4160 MISC_REGISTERS_GPIO_HIGH,
4164 MISC_REGISTERS_GPIO_1,
4165 MISC_REGISTERS_GPIO_HIGH,
4171 for (cnt = 0; cnt < 1000; cnt++) {
4173 bnx2x_cl45_read(bp, port,
4179 if (!(ctrl & (1<<15))) {
4180 DP(NETIF_MSG_LINK, "Reset completed\n\n");
4186 static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
4188 /* put sf to reset */
4190 MISC_REGISTERS_GPIO_1,
4191 MISC_REGISTERS_GPIO_LOW,
4194 MISC_REGISTERS_GPIO_2,
4195 MISC_REGISTERS_GPIO_LOW,
4199 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
4200 u8 *version, u16 len)
4202 struct bnx2x *bp = params->bp;
4203 u32 ext_phy_type = 0;
4207 if (version == NULL || params == NULL)
4210 spirom_ver = REG_RD(bp, params->shmem_base +
4211 offsetof(struct shmem_region,
4212 port_mb[params->port].ext_phy_fw_version));
4214 /* reset the returned value to zero */
4215 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4216 switch (ext_phy_type) {
4217 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4222 version[0] = (spirom_ver & 0xFF);
4223 version[1] = (spirom_ver & 0xFF00) >> 8;
4224 version[2] = (spirom_ver & 0xFF0000) >> 16;
4225 version[3] = (spirom_ver & 0xFF000000) >> 24;
4229 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4230 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4231 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4232 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4233 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4234 status = bnx2x_format_ver(spirom_ver, version, len);
4236 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4239 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4240 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
4241 " type is FAILURE!\n");
4251 static void bnx2x_set_xgxs_loopback(struct link_params *params,
4252 struct link_vars *vars,
4255 u8 port = params->port;
4256 struct bnx2x *bp = params->bp;
4261 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
4263 /* change the uni_phy_addr in the nig */
4264 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
4267 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
4269 bnx2x_cl45_write(bp, port, 0,
4272 (MDIO_REG_BANK_AER_BLOCK +
4273 (MDIO_AER_BLOCK_AER_REG & 0xf)),
4276 bnx2x_cl45_write(bp, port, 0,
4279 (MDIO_REG_BANK_CL73_IEEEB0 +
4280 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
4283 /* set aer mmd back */
4284 bnx2x_set_aer_mmd(params, vars);
4287 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
4293 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
4295 CL45_RD_OVER_CL22(bp, port,
4297 MDIO_REG_BANK_COMBO_IEEE0,
4298 MDIO_COMBO_IEEE0_MII_CONTROL,
4301 CL45_WR_OVER_CL22(bp, port,
4303 MDIO_REG_BANK_COMBO_IEEE0,
4304 MDIO_COMBO_IEEE0_MII_CONTROL,
4306 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
4311 static void bnx2x_ext_phy_loopback(struct link_params *params)
4313 struct bnx2x *bp = params->bp;
4317 if (params->switch_cfg == SWITCH_CFG_10G) {
4318 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4319 /* CL37 Autoneg Enabled */
4320 ext_phy_addr = ((params->ext_phy_config &
4321 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4322 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4323 switch (ext_phy_type) {
4324 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4325 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4327 "ext_phy_loopback: We should not get here\n");
4329 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4330 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
4332 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4333 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
4335 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4336 DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
4337 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4343 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4344 /* SFX7101_XGXS_TEST1 */
4345 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4348 MDIO_XS_SFX7101_XGXS_TEST1,
4351 "ext_phy_loopback: set ext phy loopback\n");
4353 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4356 } /* switch external PHY type */
4359 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4360 ext_phy_addr = (params->ext_phy_config &
4361 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
4362 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
4368 *------------------------------------------------------------------------
4369 * bnx2x_override_led_value -
4371 * Override the led value of the requsted led
4373 *------------------------------------------------------------------------
4375 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
4376 u32 led_idx, u32 value)
4380 /* If port 0 then use EMAC0, else use EMAC1*/
4381 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4384 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
4385 port, led_idx, value);
4388 case 0: /* 10MB led */
4389 /* Read the current value of the LED register in
4391 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4392 /* Set the OVERRIDE bit to 1 */
4393 reg_val |= EMAC_LED_OVERRIDE;
4394 /* If value is 1, set the 10M_OVERRIDE bit,
4395 otherwise reset it.*/
4396 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
4397 (reg_val & ~EMAC_LED_10MB_OVERRIDE);
4398 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4400 case 1: /*100MB led */
4401 /*Read the current value of the LED register in
4403 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4404 /* Set the OVERRIDE bit to 1 */
4405 reg_val |= EMAC_LED_OVERRIDE;
4406 /* If value is 1, set the 100M_OVERRIDE bit,
4407 otherwise reset it.*/
4408 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
4409 (reg_val & ~EMAC_LED_100MB_OVERRIDE);
4410 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4412 case 2: /* 1000MB led */
4413 /* Read the current value of the LED register in the
4415 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4416 /* Set the OVERRIDE bit to 1 */
4417 reg_val |= EMAC_LED_OVERRIDE;
4418 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
4420 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
4421 (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
4422 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4424 case 3: /* 2500MB led */
4425 /* Read the current value of the LED register in the
4427 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4428 /* Set the OVERRIDE bit to 1 */
4429 reg_val |= EMAC_LED_OVERRIDE;
4430 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
4432 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
4433 (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
4434 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4436 case 4: /*10G led */
4438 REG_WR(bp, NIG_REG_LED_10G_P0,
4441 REG_WR(bp, NIG_REG_LED_10G_P1,
4445 case 5: /* TRAFFIC led */
4446 /* Find if the traffic control is via BMAC or EMAC */
4448 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
4450 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
4452 /* Override the traffic led in the EMAC:*/
4454 /* Read the current value of the LED register in
4456 reg_val = REG_RD(bp, emac_base +
4458 /* Set the TRAFFIC_OVERRIDE bit to 1 */
4459 reg_val |= EMAC_LED_OVERRIDE;
4460 /* If value is 1, set the TRAFFIC bit, otherwise
4462 reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
4463 (reg_val & ~EMAC_LED_TRAFFIC);
4464 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4465 } else { /* Override the traffic led in the BMAC: */
4466 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4468 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
4474 "bnx2x_override_led_value() unknown led index %d "
4475 "(should be 0-5)\n", led_idx);
4483 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
4484 u16 hw_led_mode, u32 chip_id)
4488 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4489 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
4490 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
4491 speed, hw_led_mode);
4494 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
4495 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
4496 SHARED_HW_CFG_LED_MAC1);
4498 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4499 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
4503 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
4504 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
4506 /* Set blinking rate to ~15.9Hz */
4507 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
4508 LED_BLINK_RATE_VAL);
4509 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
4511 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4512 EMAC_WR(bp, EMAC_REG_EMAC_LED,
4513 (tmp & (~EMAC_LED_OVERRIDE)));
4515 if (!CHIP_IS_E1H(bp) &&
4516 ((speed == SPEED_2500) ||
4517 (speed == SPEED_1000) ||
4518 (speed == SPEED_100) ||
4519 (speed == SPEED_10))) {
4520 /* On Everest 1 Ax chip versions for speeds less than
4521 10G LED scheme is different */
4522 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4524 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
4526 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
4533 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
4541 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
4543 struct bnx2x *bp = params->bp;
4546 CL45_RD_OVER_CL22(bp, params->port,
4548 MDIO_REG_BANK_GP_STATUS,
4549 MDIO_GP_STATUS_TOP_AN_STATUS1,
4551 /* link is up only if both local phy and external phy are up */
4552 if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
4553 bnx2x_ext_phy_is_link_up(params, vars))
4559 static u8 bnx2x_link_initialize(struct link_params *params,
4560 struct link_vars *vars)
4562 struct bnx2x *bp = params->bp;
4563 u8 port = params->port;
4566 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4567 /* Activate the external PHY */
4568 bnx2x_ext_phy_reset(params, vars);
4570 bnx2x_set_aer_mmd(params, vars);
4572 if (vars->phy_flags & PHY_XGXS_FLAG)
4573 bnx2x_set_master_ln(params);
4575 rc = bnx2x_reset_unicore(params);
4576 /* reset the SerDes and wait for reset bit return low */
4580 bnx2x_set_aer_mmd(params, vars);
4582 /* setting the masterLn_def again after the reset */
4583 if (vars->phy_flags & PHY_XGXS_FLAG) {
4584 bnx2x_set_master_ln(params);
4585 bnx2x_set_swap_lanes(params);
4588 if (vars->phy_flags & PHY_XGXS_FLAG) {
4589 if ((params->req_line_speed &&
4590 ((params->req_line_speed == SPEED_100) ||
4591 (params->req_line_speed == SPEED_10))) ||
4592 (!params->req_line_speed &&
4593 (params->speed_cap_mask >=
4594 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
4595 (params->speed_cap_mask <
4596 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4598 vars->phy_flags |= PHY_SGMII_FLAG;
4600 vars->phy_flags &= ~PHY_SGMII_FLAG;
4603 /* In case of external phy existance, the line speed would be the
4604 line speed linked up by the external phy. In case it is direct only,
4605 then the line_speed during initialization will be equal to the
4607 vars->line_speed = params->req_line_speed;
4609 bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
4611 /* init ext phy and enable link state int */
4612 non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
4613 (params->loopback_mode == LOOPBACK_XGXS_10) ||
4614 (params->loopback_mode == LOOPBACK_EXT_PHY));
4617 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
4618 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
4619 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481)) {
4620 if (params->req_line_speed == SPEED_AUTO_NEG)
4621 bnx2x_set_parallel_detection(params, vars->phy_flags);
4622 bnx2x_init_internal_phy(params, vars);
4626 rc |= bnx2x_ext_phy_init(params, vars);
4628 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4629 (NIG_STATUS_XGXS0_LINK10G |
4630 NIG_STATUS_XGXS0_LINK_STATUS |
4631 NIG_STATUS_SERDES0_LINK_STATUS));
4638 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
4640 struct bnx2x *bp = params->bp;
4643 DP(NETIF_MSG_LINK, "Phy Initialization started \n");
4644 DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
4645 params->req_line_speed, params->req_flow_ctrl);
4646 vars->link_status = 0;
4647 vars->phy_link_up = 0;
4649 vars->line_speed = 0;
4650 vars->duplex = DUPLEX_FULL;
4651 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4652 vars->mac_type = MAC_TYPE_NONE;
4654 if (params->switch_cfg == SWITCH_CFG_1G)
4655 vars->phy_flags = PHY_SERDES_FLAG;
4657 vars->phy_flags = PHY_XGXS_FLAG;
4660 /* disable attentions */
4661 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
4662 (NIG_MASK_XGXS0_LINK_STATUS |
4663 NIG_MASK_XGXS0_LINK10G |
4664 NIG_MASK_SERDES0_LINK_STATUS |
4667 bnx2x_emac_init(params, vars);
4669 if (CHIP_REV_IS_FPGA(bp)) {
4671 vars->line_speed = SPEED_10000;
4672 vars->duplex = DUPLEX_FULL;
4673 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4674 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
4675 /* enable on E1.5 FPGA */
4676 if (CHIP_IS_E1H(bp)) {
4678 (BNX2X_FLOW_CTRL_TX | BNX2X_FLOW_CTRL_RX);
4679 vars->link_status |=
4680 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
4681 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
4684 bnx2x_emac_enable(params, vars, 0);
4685 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4687 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4688 + params->port*4, 0);
4690 /* update shared memory */
4691 bnx2x_update_mng(params, vars->link_status);
4696 if (CHIP_REV_IS_EMUL(bp)) {
4699 vars->line_speed = SPEED_10000;
4700 vars->duplex = DUPLEX_FULL;
4701 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4702 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
4704 bnx2x_bmac_enable(params, vars, 0);
4706 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4708 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4709 + params->port*4, 0);
4711 /* update shared memory */
4712 bnx2x_update_mng(params, vars->link_status);
4717 if (params->loopback_mode == LOOPBACK_BMAC) {
4719 vars->line_speed = SPEED_10000;
4720 vars->duplex = DUPLEX_FULL;
4721 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4722 vars->mac_type = MAC_TYPE_BMAC;
4724 vars->phy_flags = PHY_XGXS_FLAG;
4726 bnx2x_phy_deassert(params, vars->phy_flags);
4727 /* set bmac loopback */
4728 bnx2x_bmac_enable(params, vars, 1);
4730 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4732 } else if (params->loopback_mode == LOOPBACK_EMAC) {
4734 vars->line_speed = SPEED_1000;
4735 vars->duplex = DUPLEX_FULL;
4736 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4737 vars->mac_type = MAC_TYPE_EMAC;
4739 vars->phy_flags = PHY_XGXS_FLAG;
4741 bnx2x_phy_deassert(params, vars->phy_flags);
4742 /* set bmac loopback */
4743 bnx2x_emac_enable(params, vars, 1);
4744 bnx2x_emac_program(params, vars->line_speed,
4746 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4748 } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
4749 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
4751 vars->line_speed = SPEED_10000;
4752 vars->duplex = DUPLEX_FULL;
4753 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4755 vars->phy_flags = PHY_XGXS_FLAG;
4758 NIG_REG_XGXS0_CTRL_PHY_ADDR+
4760 params->phy_addr = (u8)val;
4762 bnx2x_phy_deassert(params, vars->phy_flags);
4763 bnx2x_link_initialize(params, vars);
4765 vars->mac_type = MAC_TYPE_BMAC;
4767 bnx2x_bmac_enable(params, vars, 0);
4769 if (params->loopback_mode == LOOPBACK_XGXS_10) {
4770 /* set 10G XGXS loopback */
4771 bnx2x_set_xgxs_loopback(params, vars, 1);
4773 /* set external phy loopback */
4774 bnx2x_ext_phy_loopback(params);
4776 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4782 bnx2x_phy_deassert(params, vars->phy_flags);
4783 switch (params->switch_cfg) {
4785 vars->phy_flags |= PHY_SERDES_FLAG;
4786 if ((params->ext_phy_config &
4787 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
4788 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
4794 NIG_REG_SERDES0_CTRL_PHY_ADDR+
4797 params->phy_addr = (u8)val;
4800 case SWITCH_CFG_10G:
4801 vars->phy_flags |= PHY_XGXS_FLAG;
4803 NIG_REG_XGXS0_CTRL_PHY_ADDR+
4805 params->phy_addr = (u8)val;
4809 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
4814 bnx2x_link_initialize(params, vars);
4816 bnx2x_link_int_enable(params);
4821 static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
4823 DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
4825 /* Set serial boot control for external load */
4826 bnx2x_cl45_write(bp, port,
4827 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
4829 MDIO_PMA_REG_GEN_CTRL, 0x0001);
4831 /* Disable Transmitter */
4832 bnx2x_bcm8726_set_transmitter(bp, port, ext_phy_addr, 0);
4836 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
4840 struct bnx2x *bp = params->bp;
4841 u32 ext_phy_config = params->ext_phy_config;
4842 u16 hw_led_mode = params->hw_led_mode;
4843 u32 chip_id = params->chip_id;
4844 u8 port = params->port;
4845 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4846 /* disable attentions */
4848 vars->link_status = 0;
4849 bnx2x_update_mng(params, vars->link_status);
4850 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4851 (NIG_MASK_XGXS0_LINK_STATUS |
4852 NIG_MASK_XGXS0_LINK10G |
4853 NIG_MASK_SERDES0_LINK_STATUS |
4856 /* activate nig drain */
4857 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4859 /* disable nig egress interface */
4860 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4861 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4863 /* Stop BigMac rx */
4864 bnx2x_bmac_rx_disable(bp, port);
4867 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4870 /* The PHY reset is controled by GPIO 1
4871 * Hold it as vars low
4873 /* clear link led */
4874 bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4875 if (reset_ext_phy) {
4876 switch (ext_phy_type) {
4877 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4878 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4880 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4881 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4884 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4885 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4888 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4890 u8 ext_phy_addr = ((params->ext_phy_config &
4891 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4892 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4893 /* Set soft reset */
4894 bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
4899 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4900 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4902 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4903 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4905 DP(NETIF_MSG_LINK, "reset external PHY\n");
4908 /* reset the SerDes/XGXS */
4909 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4910 (0x1ff << (port*16)));
4913 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4914 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4916 /* disable nig ingress interface */
4917 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4918 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4919 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4920 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4925 static u8 bnx2x_update_link_down(struct link_params *params,
4926 struct link_vars *vars)
4928 struct bnx2x *bp = params->bp;
4929 u8 port = params->port;
4930 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4931 bnx2x_set_led(bp, port, LED_MODE_OFF,
4932 0, params->hw_led_mode,
4935 /* indicate no mac active */
4936 vars->mac_type = MAC_TYPE_NONE;
4938 /* update shared memory */
4939 vars->link_status = 0;
4940 vars->line_speed = 0;
4941 bnx2x_update_mng(params, vars->link_status);
4943 /* activate nig drain */
4944 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4947 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4952 bnx2x_bmac_rx_disable(bp, params->port);
4953 REG_WR(bp, GRCBASE_MISC +
4954 MISC_REGISTERS_RESET_REG_2_CLEAR,
4955 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4959 static u8 bnx2x_update_link_up(struct link_params *params,
4960 struct link_vars *vars,
4961 u8 link_10g, u32 gp_status)
4963 struct bnx2x *bp = params->bp;
4964 u8 port = params->port;
4966 vars->link_status |= LINK_STATUS_LINK_UP;
4968 bnx2x_bmac_enable(params, vars, 0);
4969 bnx2x_set_led(bp, port, LED_MODE_OPER,
4970 SPEED_10000, params->hw_led_mode,
4974 bnx2x_emac_enable(params, vars, 0);
4975 rc = bnx2x_emac_program(params, vars->line_speed,
4979 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4980 if (!(vars->phy_flags &
4982 bnx2x_set_sgmii_tx_driver(params);
4987 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4991 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4993 /* update shared memory */
4994 bnx2x_update_mng(params, vars->link_status);
4998 /* This function should called upon link interrupt */
4999 /* In case vars->link_up, driver needs to
5002 3. Update the shared memory
5006 1. Update shared memory
5011 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
5013 struct bnx2x *bp = params->bp;
5014 u8 port = params->port;
5017 u8 ext_phy_link_up, rc = 0;
5020 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
5022 (vars->phy_flags & PHY_XGXS_FLAG),
5023 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5025 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
5026 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5027 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5028 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
5030 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5031 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5032 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5035 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
5037 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5039 /* Check external link change only for non-direct */
5040 ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
5042 /* Read gp_status */
5043 CL45_RD_OVER_CL22(bp, port, params->phy_addr,
5044 MDIO_REG_BANK_GP_STATUS,
5045 MDIO_GP_STATUS_TOP_AN_STATUS1,
5048 rc = bnx2x_link_settings_status(params, vars, gp_status);
5052 /* anything 10 and over uses the bmac */
5053 link_10g = ((vars->line_speed == SPEED_10000) ||
5054 (vars->line_speed == SPEED_12000) ||
5055 (vars->line_speed == SPEED_12500) ||
5056 (vars->line_speed == SPEED_13000) ||
5057 (vars->line_speed == SPEED_15000) ||
5058 (vars->line_speed == SPEED_16000));
5060 bnx2x_link_int_ack(params, vars, link_10g);
5062 /* In case external phy link is up, and internal link is down
5063 ( not initialized yet probably after link initialization, it needs
5065 Note that after link down-up as result of cable plug,
5066 the xgxs link would probably become up again without the need to
5069 if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
5070 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
5071 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
5072 (ext_phy_link_up && !vars->phy_link_up))
5073 bnx2x_init_internal_phy(params, vars);
5075 /* link is up only if both local phy and external phy are up */
5076 vars->link_up = (ext_phy_link_up && vars->phy_link_up);
5079 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
5081 rc = bnx2x_update_link_down(params, vars);
5086 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5088 u8 ext_phy_addr[PORT_MAX];
5092 /* PART1 - Reset both phys */
5093 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5094 /* Extract the ext phy address for the port */
5095 u32 ext_phy_config = REG_RD(bp, shmem_base +
5096 offsetof(struct shmem_region,
5097 dev_info.port_hw_config[port].external_phy_config));
5099 /* disable attentions */
5100 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5101 (NIG_MASK_XGXS0_LINK_STATUS |
5102 NIG_MASK_XGXS0_LINK10G |
5103 NIG_MASK_SERDES0_LINK_STATUS |
5106 ext_phy_addr[port] =
5108 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5109 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5111 /* Need to take the phy out of low power mode in order
5112 to write to access its registers */
5113 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5114 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
5117 bnx2x_cl45_write(bp, port,
5118 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5125 /* Add delay of 150ms after reset */
5128 /* PART2 - Download firmware to both phys */
5129 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5132 bnx2x_bcm8073_external_rom_boot(bp, port,
5133 ext_phy_addr[port], shmem_base);
5135 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5138 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
5139 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
5141 "bnx2x_8073_common_init_phy port %x:"
5142 "Download failed. fw version = 0x%x\n",
5147 /* Only set bit 10 = 1 (Tx power down) */
5148 bnx2x_cl45_read(bp, port,
5149 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5152 MDIO_PMA_REG_TX_POWER_DOWN, &val);
5154 /* Phase1 of TX_POWER_DOWN reset */
5155 bnx2x_cl45_write(bp, port,
5156 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5159 MDIO_PMA_REG_TX_POWER_DOWN,
5163 /* Toggle Transmitter: Power down and then up with 600ms
5167 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
5168 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5169 /* Phase2 of POWER_DOWN_RESET*/
5170 /* Release bit 10 (Release Tx power down) */
5171 bnx2x_cl45_read(bp, port,
5172 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5175 MDIO_PMA_REG_TX_POWER_DOWN, &val);
5177 bnx2x_cl45_write(bp, port,
5178 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5181 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
5184 /* Read modify write the SPI-ROM version select register */
5185 bnx2x_cl45_read(bp, port,
5186 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5189 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
5190 bnx2x_cl45_write(bp, port,
5191 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5194 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
5196 /* set GPIO2 back to LOW */
5197 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5198 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
5205 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5210 /* Use port1 because of the static port-swap */
5211 /* Enable the module detection interrupt */
5212 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
5213 val |= ((1<<MISC_REGISTERS_GPIO_3)|
5214 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
5215 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
5217 bnx2x_hw_reset(bp, 1);
5219 for (port = 0; port < PORT_MAX; port++) {
5220 /* Extract the ext phy address for the port */
5221 u32 ext_phy_config = REG_RD(bp, shmem_base +
5222 offsetof(struct shmem_region,
5223 dev_info.port_hw_config[port].external_phy_config));
5227 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5228 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5229 DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
5232 bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
5234 /* Set fault module detected LED on */
5235 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5236 MISC_REGISTERS_GPIO_HIGH,
5243 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5248 DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n");
5250 /* Read the ext_phy_type for arbitrary port(0) */
5251 ext_phy_type = XGXS_EXT_PHY_TYPE(
5252 REG_RD(bp, shmem_base +
5253 offsetof(struct shmem_region,
5254 dev_info.port_hw_config[0].external_phy_config)));
5256 switch (ext_phy_type) {
5257 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5259 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
5262 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5263 /* GPIO1 affects both ports, so there's need to pull
5264 it for single port alone */
5265 rc = bnx2x_8726_common_init_phy(bp, shmem_base);
5270 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
5280 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
5284 bnx2x_cl45_read(bp, port,
5285 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5288 MDIO_PMA_REG_7101_RESET, &val);
5290 for (cnt = 0; cnt < 10; cnt++) {
5292 /* Writes a self-clearing reset */
5293 bnx2x_cl45_write(bp, port,
5294 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5297 MDIO_PMA_REG_7101_RESET,
5299 /* Wait for clear */
5300 bnx2x_cl45_read(bp, port,
5301 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5304 MDIO_PMA_REG_7101_RESET, &val);
5306 if ((val & (1<<15)) == 0)
5310 #define RESERVED_SIZE 256
5311 /* max application is 160K bytes - data at end of RAM */
5312 #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
5314 /* Header is 14 bytes */
5315 #define HEADER_SIZE 14
5316 #define DATA_OFFSET HEADER_SIZE
5318 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
5319 bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
5322 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
5324 /* Programs an image to DSP's flash via the SPI port*/
5325 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
5327 char data[], u32 size)
5329 const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
5330 /* Doesn't include last trans!*/
5331 const u16 last_trans_size = size%4; /* Num bytes on last trans */
5332 u16 trans_cnt, byte_cnt;
5335 u16 code_started = 0;
5336 u16 image_revision1, image_revision2;
5339 DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
5341 if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
5342 /* This very often will be the case, because the image is built
5343 with 160Kbytes size whereas the total image size must actually
5344 be 160Kbytes-RESERVED_SIZE */
5345 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
5346 "truncated to %d bytes\n", size, MAX_APP_SIZE);
5347 size = MAX_APP_SIZE+HEADER_SIZE;
5349 DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
5350 DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]);
5351 /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
5352 and issuing a reset.*/
5354 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5355 MISC_REGISTERS_GPIO_HIGH, port);
5357 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
5360 for (cnt = 0; cnt < 100; cnt++)
5363 /* Make sure we can access the DSP
5364 And it's in the correct mode (waiting for download) */
5366 bnx2x_cl45_read(bp, port,
5367 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5370 MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
5372 if (tmp != 0x000A) {
5373 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
5374 "Expected 0x000A, read 0x%04X\n", tmp);
5375 DP(NETIF_MSG_LINK, "Download failed\n");
5379 /* Mux the SPI interface away from the internal processor */
5380 bnx2x_cl45_write(bp, port,
5381 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5384 MDIO_PCS_REG_7101_SPI_MUX, 1);
5386 /* Reset the SPI port */
5387 bnx2x_cl45_write(bp, port,
5388 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5391 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
5392 bnx2x_cl45_write(bp, port,
5393 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5396 MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
5397 (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
5398 bnx2x_cl45_write(bp, port,
5399 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5402 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
5404 /* Erase the flash */
5405 bnx2x_cl45_write(bp, port,
5406 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5409 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5410 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5412 bnx2x_cl45_write(bp, port,
5413 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5416 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5419 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5420 bnx2x_cl45_write(bp, port,
5421 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5424 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5425 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
5427 bnx2x_cl45_write(bp, port,
5428 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5431 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5433 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5435 /* Wait 10 seconds, the maximum time for the erase to complete */
5436 DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
5437 for (cnt = 0; cnt < 1000; cnt++)
5440 DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
5442 for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
5443 bnx2x_cl45_write(bp, port,
5444 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5447 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5448 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5450 bnx2x_cl45_write(bp, port,
5451 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5454 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5456 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5458 bnx2x_cl45_write(bp, port,
5459 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5462 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5463 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
5465 /* Bits 23-16 of address */
5466 bnx2x_cl45_write(bp, port,
5467 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5470 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5472 /* Bits 15-8 of address */
5473 bnx2x_cl45_write(bp, port,
5474 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5477 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5480 /* Bits 7-0 of address */
5481 bnx2x_cl45_write(bp, port,
5482 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5485 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5489 while (byte_cnt < 4 && data_index < size) {
5490 bnx2x_cl45_write(bp, port,
5491 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5494 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5495 data[data_index++]);
5499 bnx2x_cl45_write(bp, port,
5500 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5503 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5506 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5507 msleep(5); /* Wait 5 ms minimum between transs */
5509 /* Let the user know something's going on.*/
5510 /* a pacifier ever 4K */
5511 if ((data_index % 1023) == 0)
5512 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
5515 DP(NETIF_MSG_LINK, "\n");
5516 /* Transfer the last block if there is data remaining */
5517 if (last_trans_size) {
5518 bnx2x_cl45_write(bp, port,
5519 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5522 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5523 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5525 bnx2x_cl45_write(bp, port,
5526 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5529 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5532 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5534 bnx2x_cl45_write(bp, port,
5535 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5538 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5539 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
5541 /* Bits 23-16 of address */
5542 bnx2x_cl45_write(bp, port,
5543 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5546 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5548 /* Bits 15-8 of address */
5549 bnx2x_cl45_write(bp, port,
5550 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5553 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5556 /* Bits 7-0 of address */
5557 bnx2x_cl45_write(bp, port,
5558 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5561 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5565 while (byte_cnt < last_trans_size && data_index < size) {
5566 /* Bits 7-0 of address */
5567 bnx2x_cl45_write(bp, port,
5568 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5571 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5572 data[data_index++]);
5576 bnx2x_cl45_write(bp, port,
5577 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5580 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5583 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5586 /* DSP Remove Download Mode */
5587 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5588 MISC_REGISTERS_GPIO_LOW, port);
5590 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
5592 /* wait 0.5 sec to allow it to run */
5593 for (cnt = 0; cnt < 100; cnt++)
5596 bnx2x_hw_reset(bp, port);
5598 for (cnt = 0; cnt < 100; cnt++)
5601 /* Check that the code is started. In case the download
5602 checksum failed, the code won't be started. */
5603 bnx2x_cl45_read(bp, port,
5604 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5607 MDIO_PCS_REG_7101_DSP_ACCESS,
5610 code_started = (tmp & (1<<4));
5611 if (!code_started) {
5612 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
5616 /* Verify that the file revision is now equal to the image
5617 revision within the DSP */
5618 bnx2x_cl45_read(bp, port,
5619 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5622 MDIO_PMA_REG_7101_VER1,
5625 bnx2x_cl45_read(bp, port,
5626 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5629 MDIO_PMA_REG_7101_VER2,
5632 if (data[0x14e] != (image_revision2&0xFF) ||
5633 data[0x14f] != ((image_revision2&0xFF00)>>8) ||
5634 data[0x150] != (image_revision1&0xFF) ||
5635 data[0x151] != ((image_revision1&0xFF00)>>8)) {
5636 DP(NETIF_MSG_LINK, "Download failed.\n");
5639 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
5643 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
5644 u8 driver_loaded, char data[], u32 size)
5649 ext_phy_addr = ((ext_phy_config &
5650 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5651 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5653 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
5655 switch (ext_phy_type) {
5656 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5657 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5658 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5659 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5661 "Flash download not supported for this ext phy\n");
5664 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5665 /* Take ext phy out of reset */
5667 bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
5668 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
5671 bnx2x_turn_off_sf(bp, port);
5673 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5674 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
5675 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
5677 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");