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 /********************************************************/
33 #define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
34 #define ETH_MIN_PACKET_SIZE 60
35 #define ETH_MAX_PACKET_SIZE 1500
36 #define ETH_MAX_JUMBO_PACKET_SIZE 9600
37 #define MDIO_ACCESS_TIMEOUT 1000
38 #define BMAC_CONTROL_RX_ENABLE 2
40 /***********************************************************/
41 /* Shortcut definitions */
42 /***********************************************************/
44 #define NIG_STATUS_XGXS0_LINK10G \
45 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
46 #define NIG_STATUS_XGXS0_LINK_STATUS \
47 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
48 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
49 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
50 #define NIG_STATUS_SERDES0_LINK_STATUS \
51 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
52 #define NIG_MASK_MI_INT \
53 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
54 #define NIG_MASK_XGXS0_LINK10G \
55 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
56 #define NIG_MASK_XGXS0_LINK_STATUS \
57 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
58 #define NIG_MASK_SERDES0_LINK_STATUS \
59 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
61 #define MDIO_AN_CL73_OR_37_COMPLETE \
62 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
63 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
65 #define XGXS_RESET_BITS \
66 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
67 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
68 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
69 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
70 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
72 #define SERDES_RESET_BITS \
73 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
74 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
75 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
76 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
78 #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
79 #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
80 #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
81 #define AUTONEG_PARALLEL \
82 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
83 #define AUTONEG_SGMII_FIBER_AUTODET \
84 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
85 #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
87 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
88 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
89 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
90 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
91 #define GP_STATUS_SPEED_MASK \
92 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
93 #define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
94 #define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
95 #define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
96 #define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
97 #define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
98 #define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
99 #define GP_STATUS_10G_HIG \
100 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
101 #define GP_STATUS_10G_CX4 \
102 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
103 #define GP_STATUS_12G_HIG \
104 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
105 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
106 #define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
107 #define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
108 #define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
109 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
110 #define GP_STATUS_10G_KX4 \
111 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
113 #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
114 #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
115 #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
116 #define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
117 #define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
118 #define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
119 #define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
120 #define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
121 #define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
122 #define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
123 #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
124 #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
125 #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
126 #define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
127 #define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
128 #define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
129 #define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
130 #define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
131 #define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
132 #define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
133 #define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
134 #define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
135 #define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
137 #define PHY_XGXS_FLAG 0x1
138 #define PHY_SGMII_FLAG 0x2
139 #define PHY_SERDES_FLAG 0x4
142 #define SFP_EEPROM_CON_TYPE_ADDR 0x2
143 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
144 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
146 #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
147 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
148 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
149 #define SFP_EEPROM_VENDOR_NAME_ADDR 0x14
150 #define SFP_EEPROM_VENDOR_NAME_SIZE 16
151 #define SFP_EEPROM_OPTIONS_ADDR 0x40
152 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
153 #define SFP_EEPROM_OPTIONS_SIZE 2
155 #define SFP_MODULE_TYPE_UNKNOWN 0x0
156 #define SFP_MODULE_TYPE_LC 0x1
157 #define SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE 0x2
158 #define SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE 0x3
160 #define SFP_LIMITING_MODE_VALUE 0x0044
161 /**********************************************************/
163 /**********************************************************/
164 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
165 bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
166 DEFAULT_PHY_DEV_ADDR, \
167 (_bank + (_addr & 0xf)), \
170 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
171 bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
172 DEFAULT_PHY_DEV_ADDR, \
173 (_bank + (_addr & 0xf)), \
176 static void bnx2x_set_serdes_access(struct link_params *params)
178 struct bnx2x *bp = params->bp;
179 u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
181 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1);
182 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
184 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
187 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 0);
189 static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags)
191 struct bnx2x *bp = params->bp;
192 if (phy_flags & PHY_XGXS_FLAG) {
193 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
194 params->port*0x18, 0);
195 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
196 DEFAULT_PHY_DEV_ADDR);
198 bnx2x_set_serdes_access(params);
200 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
202 DEFAULT_PHY_DEV_ADDR);
206 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
208 u32 val = REG_RD(bp, reg);
211 REG_WR(bp, reg, val);
215 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
217 u32 val = REG_RD(bp, reg);
220 REG_WR(bp, reg, val);
224 static void bnx2x_emac_init(struct link_params *params,
225 struct link_vars *vars)
227 /* reset and unreset the emac core */
228 struct bnx2x *bp = params->bp;
229 u8 port = params->port;
230 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
234 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
235 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
237 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
238 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
240 /* init emac - use read-modify-write */
241 /* self clear reset */
242 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
243 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
247 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
248 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
250 DP(NETIF_MSG_LINK, "EMAC timeout!\n");
254 } while (val & EMAC_MODE_RESET);
256 /* Set mac address */
257 val = ((params->mac_addr[0] << 8) |
258 params->mac_addr[1]);
259 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
261 val = ((params->mac_addr[2] << 24) |
262 (params->mac_addr[3] << 16) |
263 (params->mac_addr[4] << 8) |
264 params->mac_addr[5]);
265 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
268 static u8 bnx2x_emac_enable(struct link_params *params,
269 struct link_vars *vars, u8 lb)
271 struct bnx2x *bp = params->bp;
272 u8 port = params->port;
273 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
276 DP(NETIF_MSG_LINK, "enabling EMAC\n");
278 /* enable emac and not bmac */
279 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
282 if (CHIP_REV_IS_EMUL(bp)) {
283 /* Use lane 1 (of lanes 0-3) */
284 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
285 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
291 if (CHIP_REV_IS_FPGA(bp)) {
292 /* Use lane 1 (of lanes 0-3) */
293 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
295 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
296 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
300 if (vars->phy_flags & PHY_XGXS_FLAG) {
301 u32 ser_lane = ((params->lane_config &
302 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
303 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
305 DP(NETIF_MSG_LINK, "XGXS\n");
306 /* select the master lanes (out of 0-3) */
307 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
310 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
313 } else { /* SerDes */
314 DP(NETIF_MSG_LINK, "SerDes\n");
316 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
320 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
322 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
325 if (CHIP_REV_IS_SLOW(bp)) {
326 /* config GMII mode */
327 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
328 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
329 (val | EMAC_MODE_PORT_GMII));
331 /* pause enable/disable */
332 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
333 EMAC_RX_MODE_FLOW_EN);
334 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
335 bnx2x_bits_en(bp, emac_base +
336 EMAC_REG_EMAC_RX_MODE,
337 EMAC_RX_MODE_FLOW_EN);
339 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
340 (EMAC_TX_MODE_EXT_PAUSE_EN |
341 EMAC_TX_MODE_FLOW_EN));
342 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
343 bnx2x_bits_en(bp, emac_base +
344 EMAC_REG_EMAC_TX_MODE,
345 (EMAC_TX_MODE_EXT_PAUSE_EN |
346 EMAC_TX_MODE_FLOW_EN));
349 /* KEEP_VLAN_TAG, promiscuous */
350 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
351 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
352 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
355 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
360 EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
363 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
365 /* enable emac for jumbo packets */
366 EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
367 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
368 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
371 REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
373 /* disable the NIG in/out to the bmac */
374 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
375 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
376 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
378 /* enable the NIG in/out to the emac */
379 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
381 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
384 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
385 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
387 if (CHIP_REV_IS_EMUL(bp)) {
388 /* take the BigMac out of reset */
390 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
391 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
393 /* enable access for bmac registers */
394 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
397 vars->mac_type = MAC_TYPE_EMAC;
403 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
406 struct bnx2x *bp = params->bp;
407 u8 port = params->port;
408 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
409 NIG_REG_INGRESS_BMAC0_MEM;
413 DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
414 /* reset and unreset the BigMac */
415 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
416 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
419 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
420 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
422 /* enable access for bmac registers */
423 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
428 REG_WR_DMAE(bp, bmac_addr +
429 BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
433 wb_data[0] = ((params->mac_addr[2] << 24) |
434 (params->mac_addr[3] << 16) |
435 (params->mac_addr[4] << 8) |
436 params->mac_addr[5]);
437 wb_data[1] = ((params->mac_addr[0] << 8) |
438 params->mac_addr[1]);
439 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
444 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
448 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
455 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
459 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
464 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
466 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
469 /* rx control set to don't strip crc */
471 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
475 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
479 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
481 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
484 /* set cnt max size */
485 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
487 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
491 wb_data[0] = 0x1000200;
493 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
495 /* fix for emulation */
496 if (CHIP_REV_IS_EMUL(bp)) {
500 bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
504 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
505 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
506 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
508 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
510 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
511 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
512 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
513 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
514 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
515 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
517 vars->mac_type = MAC_TYPE_BMAC;
521 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
523 struct bnx2x *bp = params->bp;
526 if (phy_flags & PHY_XGXS_FLAG) {
527 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
528 val = XGXS_RESET_BITS;
530 } else { /* SerDes */
531 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
532 val = SERDES_RESET_BITS;
535 val = val << (params->port*16);
537 /* reset and unreset the SerDes/XGXS */
538 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
541 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
543 bnx2x_set_phy_mdio(params, phy_flags);
546 void bnx2x_link_status_update(struct link_params *params,
547 struct link_vars *vars)
549 struct bnx2x *bp = params->bp;
551 u8 port = params->port;
553 if (params->switch_cfg == SWITCH_CFG_1G)
554 vars->phy_flags = PHY_SERDES_FLAG;
556 vars->phy_flags = PHY_XGXS_FLAG;
557 vars->link_status = REG_RD(bp, params->shmem_base +
558 offsetof(struct shmem_region,
559 port_mb[port].link_status));
561 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
564 DP(NETIF_MSG_LINK, "phy link up\n");
566 vars->phy_link_up = 1;
567 vars->duplex = DUPLEX_FULL;
568 switch (vars->link_status &
569 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
571 vars->duplex = DUPLEX_HALF;
574 vars->line_speed = SPEED_10;
578 vars->duplex = DUPLEX_HALF;
582 vars->line_speed = SPEED_100;
586 vars->duplex = DUPLEX_HALF;
589 vars->line_speed = SPEED_1000;
593 vars->duplex = DUPLEX_HALF;
596 vars->line_speed = SPEED_2500;
600 vars->line_speed = SPEED_10000;
604 vars->line_speed = SPEED_12000;
608 vars->line_speed = SPEED_12500;
612 vars->line_speed = SPEED_13000;
616 vars->line_speed = SPEED_15000;
620 vars->line_speed = SPEED_16000;
627 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
628 vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
630 vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
632 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
633 vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
635 vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
637 if (vars->phy_flags & PHY_XGXS_FLAG) {
638 if (vars->line_speed &&
639 ((vars->line_speed == SPEED_10) ||
640 (vars->line_speed == SPEED_100))) {
641 vars->phy_flags |= PHY_SGMII_FLAG;
643 vars->phy_flags &= ~PHY_SGMII_FLAG;
647 /* anything 10 and over uses the bmac */
648 link_10g = ((vars->line_speed == SPEED_10000) ||
649 (vars->line_speed == SPEED_12000) ||
650 (vars->line_speed == SPEED_12500) ||
651 (vars->line_speed == SPEED_13000) ||
652 (vars->line_speed == SPEED_15000) ||
653 (vars->line_speed == SPEED_16000));
655 vars->mac_type = MAC_TYPE_BMAC;
657 vars->mac_type = MAC_TYPE_EMAC;
659 } else { /* link down */
660 DP(NETIF_MSG_LINK, "phy link down\n");
662 vars->phy_link_up = 0;
664 vars->line_speed = 0;
665 vars->duplex = DUPLEX_FULL;
666 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
668 /* indicate no mac active */
669 vars->mac_type = MAC_TYPE_NONE;
672 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
673 vars->link_status, vars->phy_link_up);
674 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
675 vars->line_speed, vars->duplex, vars->flow_ctrl);
678 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
680 struct bnx2x *bp = params->bp;
681 REG_WR(bp, params->shmem_base +
682 offsetof(struct shmem_region,
683 port_mb[params->port].link_status),
687 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
689 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
690 NIG_REG_INGRESS_BMAC0_MEM;
692 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
694 /* Only if the bmac is out of reset */
695 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
696 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
699 /* Clear Rx Enable bit in BMAC_CONTROL register */
700 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
702 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
703 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
710 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
713 struct bnx2x *bp = params->bp;
714 u8 port = params->port;
719 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
721 /* wait for init credit */
722 init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
723 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
724 DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
726 while ((init_crd != crd) && count) {
729 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
732 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
733 if (init_crd != crd) {
734 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
739 if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
740 line_speed == SPEED_10 ||
741 line_speed == SPEED_100 ||
742 line_speed == SPEED_1000 ||
743 line_speed == SPEED_2500) {
744 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
745 /* update threshold */
746 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
747 /* update init credit */
748 init_crd = 778; /* (800-18-4) */
751 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
753 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
754 /* update threshold */
755 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
756 /* update init credit */
757 switch (line_speed) {
759 init_crd = thresh + 553 - 22;
763 init_crd = thresh + 664 - 22;
767 init_crd = thresh + 742 - 22;
771 init_crd = thresh + 778 - 22;
774 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
780 REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
781 DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
782 line_speed, init_crd);
784 /* probe the credit changes */
785 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
787 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
790 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
794 static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
797 switch (ext_phy_type) {
798 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
799 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
800 /* All MDC/MDIO is directed through single EMAC */
801 if (REG_RD(bp, NIG_REG_PORT_SWAP))
802 emac_base = GRCBASE_EMAC0;
804 emac_base = GRCBASE_EMAC1;
806 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
807 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
810 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
817 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
818 u8 phy_addr, u8 devad, u16 reg, u16 val)
822 u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
824 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
825 * (a value of 49==0x31) and make sure that the AUTO poll is off
828 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
829 tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
830 EMAC_MDIO_MODE_CLOCK_CNT);
831 tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
832 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
833 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
834 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
839 tmp = ((phy_addr << 21) | (devad << 16) | reg |
840 EMAC_MDIO_COMM_COMMAND_ADDRESS |
841 EMAC_MDIO_COMM_START_BUSY);
842 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
844 for (i = 0; i < 50; i++) {
847 tmp = REG_RD(bp, mdio_ctrl + 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");
858 tmp = ((phy_addr << 21) | (devad << 16) | val |
859 EMAC_MDIO_COMM_COMMAND_WRITE_45 |
860 EMAC_MDIO_COMM_START_BUSY);
861 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
863 for (i = 0; i < 50; i++) {
866 tmp = REG_RD(bp, mdio_ctrl +
867 EMAC_REG_EMAC_MDIO_COMM);
868 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
873 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
874 DP(NETIF_MSG_LINK, "write phy register failed\n");
879 /* Restore the saved mode */
880 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
885 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
886 u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
892 u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
893 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
894 * (a value of 49==0x31) and make sure that the AUTO poll is off
897 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
898 val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
899 EMAC_MDIO_MODE_CLOCK_CNT));
900 val |= (EMAC_MDIO_MODE_CLAUSE_45 |
901 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
902 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
903 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
907 val = ((phy_addr << 21) | (devad << 16) | reg |
908 EMAC_MDIO_COMM_COMMAND_ADDRESS |
909 EMAC_MDIO_COMM_START_BUSY);
910 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
912 for (i = 0; i < 50; i++) {
915 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
916 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
921 if (val & EMAC_MDIO_COMM_START_BUSY) {
922 DP(NETIF_MSG_LINK, "read phy register failed\n");
929 val = ((phy_addr << 21) | (devad << 16) |
930 EMAC_MDIO_COMM_COMMAND_READ_45 |
931 EMAC_MDIO_COMM_START_BUSY);
932 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
934 for (i = 0; i < 50; i++) {
937 val = REG_RD(bp, mdio_ctrl +
938 EMAC_REG_EMAC_MDIO_COMM);
939 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
940 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
944 if (val & EMAC_MDIO_COMM_START_BUSY) {
945 DP(NETIF_MSG_LINK, "read phy register failed\n");
952 /* Restore the saved mode */
953 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
958 static void bnx2x_set_aer_mmd(struct link_params *params,
959 struct link_vars *vars)
961 struct bnx2x *bp = params->bp;
965 ser_lane = ((params->lane_config &
966 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
967 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
969 offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
970 (params->phy_addr + ser_lane) : 0;
972 CL45_WR_OVER_CL22(bp, params->port,
974 MDIO_REG_BANK_AER_BLOCK,
975 MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
978 static void bnx2x_set_master_ln(struct link_params *params)
980 struct bnx2x *bp = params->bp;
981 u16 new_master_ln, ser_lane;
982 ser_lane = ((params->lane_config &
983 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
984 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
986 /* set the master_ln for AN */
987 CL45_RD_OVER_CL22(bp, params->port,
989 MDIO_REG_BANK_XGXS_BLOCK2,
990 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
993 CL45_WR_OVER_CL22(bp, params->port,
995 MDIO_REG_BANK_XGXS_BLOCK2 ,
996 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
997 (new_master_ln | ser_lane));
1000 static u8 bnx2x_reset_unicore(struct link_params *params)
1002 struct bnx2x *bp = params->bp;
1006 CL45_RD_OVER_CL22(bp, params->port,
1008 MDIO_REG_BANK_COMBO_IEEE0,
1009 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
1011 /* reset the unicore */
1012 CL45_WR_OVER_CL22(bp, params->port,
1014 MDIO_REG_BANK_COMBO_IEEE0,
1015 MDIO_COMBO_IEEE0_MII_CONTROL,
1017 MDIO_COMBO_IEEO_MII_CONTROL_RESET));
1019 bnx2x_set_serdes_access(params);
1021 /* wait for the reset to self clear */
1022 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
1025 /* the reset erased the previous bank value */
1026 CL45_RD_OVER_CL22(bp, params->port,
1028 MDIO_REG_BANK_COMBO_IEEE0,
1029 MDIO_COMBO_IEEE0_MII_CONTROL,
1032 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1038 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1043 static void bnx2x_set_swap_lanes(struct link_params *params)
1045 struct bnx2x *bp = params->bp;
1046 /* Each two bits represents a lane number:
1047 No swap is 0123 => 0x1b no need to enable the swap */
1048 u16 ser_lane, rx_lane_swap, tx_lane_swap;
1050 ser_lane = ((params->lane_config &
1051 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1052 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1053 rx_lane_swap = ((params->lane_config &
1054 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1055 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1056 tx_lane_swap = ((params->lane_config &
1057 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1058 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1060 if (rx_lane_swap != 0x1b) {
1061 CL45_WR_OVER_CL22(bp, params->port,
1063 MDIO_REG_BANK_XGXS_BLOCK2,
1064 MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1066 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1067 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1069 CL45_WR_OVER_CL22(bp, params->port,
1071 MDIO_REG_BANK_XGXS_BLOCK2,
1072 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1075 if (tx_lane_swap != 0x1b) {
1076 CL45_WR_OVER_CL22(bp, params->port,
1078 MDIO_REG_BANK_XGXS_BLOCK2,
1079 MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1081 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1083 CL45_WR_OVER_CL22(bp, params->port,
1085 MDIO_REG_BANK_XGXS_BLOCK2,
1086 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1090 static void bnx2x_set_parallel_detection(struct link_params *params,
1093 struct bnx2x *bp = params->bp;
1096 CL45_RD_OVER_CL22(bp, params->port,
1098 MDIO_REG_BANK_SERDES_DIGITAL,
1099 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1103 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1106 CL45_WR_OVER_CL22(bp, params->port,
1108 MDIO_REG_BANK_SERDES_DIGITAL,
1109 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1112 if (phy_flags & PHY_XGXS_FLAG) {
1113 DP(NETIF_MSG_LINK, "XGXS\n");
1115 CL45_WR_OVER_CL22(bp, params->port,
1117 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1118 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1119 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1121 CL45_RD_OVER_CL22(bp, params->port,
1123 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1124 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1129 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1131 CL45_WR_OVER_CL22(bp, params->port,
1133 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1134 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1137 /* Disable parallel detection of HiG */
1138 CL45_WR_OVER_CL22(bp, params->port,
1140 MDIO_REG_BANK_XGXS_BLOCK2,
1141 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1142 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1143 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1147 static void bnx2x_set_autoneg(struct link_params *params,
1148 struct link_vars *vars)
1150 struct bnx2x *bp = params->bp;
1155 CL45_RD_OVER_CL22(bp, params->port,
1157 MDIO_REG_BANK_COMBO_IEEE0,
1158 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
1160 /* CL37 Autoneg Enabled */
1161 if (vars->line_speed == SPEED_AUTO_NEG)
1162 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1163 else /* CL37 Autoneg Disabled */
1164 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1165 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1167 CL45_WR_OVER_CL22(bp, params->port,
1169 MDIO_REG_BANK_COMBO_IEEE0,
1170 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1172 /* Enable/Disable Autodetection */
1174 CL45_RD_OVER_CL22(bp, params->port,
1176 MDIO_REG_BANK_SERDES_DIGITAL,
1177 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val);
1178 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1179 if (vars->line_speed == SPEED_AUTO_NEG)
1180 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1182 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1184 CL45_WR_OVER_CL22(bp, params->port,
1186 MDIO_REG_BANK_SERDES_DIGITAL,
1187 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1189 /* Enable TetonII and BAM autoneg */
1190 CL45_RD_OVER_CL22(bp, params->port,
1192 MDIO_REG_BANK_BAM_NEXT_PAGE,
1193 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1195 if (vars->line_speed == SPEED_AUTO_NEG) {
1196 /* Enable BAM aneg Mode and TetonII aneg Mode */
1197 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1198 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1200 /* TetonII and BAM Autoneg Disabled */
1201 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1202 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1204 CL45_WR_OVER_CL22(bp, params->port,
1206 MDIO_REG_BANK_BAM_NEXT_PAGE,
1207 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1210 /* CL73 Autoneg Disabled */
1213 CL45_WR_OVER_CL22(bp, params->port,
1215 MDIO_REG_BANK_CL73_IEEEB0,
1216 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1219 /* program SerDes, forced speed */
1220 static void bnx2x_program_serdes(struct link_params *params,
1221 struct link_vars *vars)
1223 struct bnx2x *bp = params->bp;
1226 /* program duplex, disable autoneg */
1228 CL45_RD_OVER_CL22(bp, params->port,
1230 MDIO_REG_BANK_COMBO_IEEE0,
1231 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
1232 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1233 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
1234 if (params->req_duplex == DUPLEX_FULL)
1235 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1236 CL45_WR_OVER_CL22(bp, params->port,
1238 MDIO_REG_BANK_COMBO_IEEE0,
1239 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1242 - needed only if the speed is greater than 1G (2.5G or 10G) */
1243 CL45_RD_OVER_CL22(bp, params->port,
1245 MDIO_REG_BANK_SERDES_DIGITAL,
1246 MDIO_SERDES_DIGITAL_MISC1, ®_val);
1247 /* clearing the speed value before setting the right speed */
1248 DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1250 reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1251 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1253 if (!((vars->line_speed == SPEED_1000) ||
1254 (vars->line_speed == SPEED_100) ||
1255 (vars->line_speed == SPEED_10))) {
1257 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1258 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1259 if (vars->line_speed == SPEED_10000)
1261 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1262 if (vars->line_speed == SPEED_13000)
1264 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1267 CL45_WR_OVER_CL22(bp, params->port,
1269 MDIO_REG_BANK_SERDES_DIGITAL,
1270 MDIO_SERDES_DIGITAL_MISC1, reg_val);
1274 static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1276 struct bnx2x *bp = params->bp;
1279 /* configure the 48 bits for BAM AN */
1281 /* set extended capabilities */
1282 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1283 val |= MDIO_OVER_1G_UP1_2_5G;
1284 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1285 val |= MDIO_OVER_1G_UP1_10G;
1286 CL45_WR_OVER_CL22(bp, params->port,
1288 MDIO_REG_BANK_OVER_1G,
1289 MDIO_OVER_1G_UP1, val);
1291 CL45_WR_OVER_CL22(bp, params->port,
1293 MDIO_REG_BANK_OVER_1G,
1294 MDIO_OVER_1G_UP3, 0);
1297 static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
1299 *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1300 /* resolve pause mode and advertisement
1301 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1303 switch (params->req_flow_ctrl) {
1304 case BNX2X_FLOW_CTRL_AUTO:
1305 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
1307 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1310 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1313 case BNX2X_FLOW_CTRL_TX:
1315 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1318 case BNX2X_FLOW_CTRL_RX:
1319 case BNX2X_FLOW_CTRL_BOTH:
1320 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1323 case BNX2X_FLOW_CTRL_NONE:
1325 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1330 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1333 struct bnx2x *bp = params->bp;
1334 /* for AN, we are always publishing full duplex */
1336 CL45_WR_OVER_CL22(bp, params->port,
1338 MDIO_REG_BANK_COMBO_IEEE0,
1339 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
1342 static void bnx2x_restart_autoneg(struct link_params *params)
1344 struct bnx2x *bp = params->bp;
1346 DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1347 /* Enable and restart BAM/CL37 aneg */
1349 CL45_RD_OVER_CL22(bp, params->port,
1351 MDIO_REG_BANK_COMBO_IEEE0,
1352 MDIO_COMBO_IEEE0_MII_CONTROL,
1355 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1357 CL45_WR_OVER_CL22(bp, params->port,
1359 MDIO_REG_BANK_COMBO_IEEE0,
1360 MDIO_COMBO_IEEE0_MII_CONTROL,
1362 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1363 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1366 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1367 struct link_vars *vars)
1369 struct bnx2x *bp = params->bp;
1372 /* in SGMII mode, the unicore is always slave */
1374 CL45_RD_OVER_CL22(bp, params->port,
1376 MDIO_REG_BANK_SERDES_DIGITAL,
1377 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1379 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1380 /* set sgmii mode (and not fiber) */
1381 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1382 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1383 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1384 CL45_WR_OVER_CL22(bp, params->port,
1386 MDIO_REG_BANK_SERDES_DIGITAL,
1387 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1390 /* if forced speed */
1391 if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1392 /* set speed, disable autoneg */
1395 CL45_RD_OVER_CL22(bp, params->port,
1397 MDIO_REG_BANK_COMBO_IEEE0,
1398 MDIO_COMBO_IEEE0_MII_CONTROL,
1400 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1401 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1402 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1404 switch (vars->line_speed) {
1407 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1411 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1414 /* there is nothing to set for 10M */
1417 /* invalid speed for SGMII */
1418 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1423 /* setting the full duplex */
1424 if (params->req_duplex == DUPLEX_FULL)
1426 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1427 CL45_WR_OVER_CL22(bp, params->port,
1429 MDIO_REG_BANK_COMBO_IEEE0,
1430 MDIO_COMBO_IEEE0_MII_CONTROL,
1433 } else { /* AN mode */
1434 /* enable and restart AN */
1435 bnx2x_restart_autoneg(params);
1444 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1446 switch (pause_result) { /* ASYM P ASYM P */
1447 case 0xb: /* 1 0 1 1 */
1448 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
1451 case 0xe: /* 1 1 1 0 */
1452 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
1455 case 0x5: /* 0 1 0 1 */
1456 case 0x7: /* 0 1 1 1 */
1457 case 0xd: /* 1 1 0 1 */
1458 case 0xf: /* 1 1 1 1 */
1459 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
1467 static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1468 struct link_vars *vars)
1470 struct bnx2x *bp = params->bp;
1472 u16 ld_pause; /* local */
1473 u16 lp_pause; /* link partner */
1474 u16 an_complete; /* AN complete */
1478 u8 port = params->port;
1479 ext_phy_addr = ((params->ext_phy_config &
1480 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1481 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1483 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1486 bnx2x_cl45_read(bp, port,
1490 MDIO_AN_REG_STATUS, &an_complete);
1491 bnx2x_cl45_read(bp, port,
1495 MDIO_AN_REG_STATUS, &an_complete);
1497 if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1499 bnx2x_cl45_read(bp, port,
1503 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1504 bnx2x_cl45_read(bp, port,
1508 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1509 pause_result = (ld_pause &
1510 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1511 pause_result |= (lp_pause &
1512 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1513 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1515 bnx2x_pause_resolve(vars, pause_result);
1516 if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
1517 ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1518 bnx2x_cl45_read(bp, port,
1522 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1524 bnx2x_cl45_read(bp, port,
1528 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1529 pause_result = (ld_pause &
1530 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1531 pause_result |= (lp_pause &
1532 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1534 bnx2x_pause_resolve(vars, pause_result);
1535 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1543 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1544 struct link_vars *vars,
1547 struct bnx2x *bp = params->bp;
1548 u16 ld_pause; /* local driver */
1549 u16 lp_pause; /* link partner */
1552 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1554 /* resolve from gp_status in case of AN complete and not sgmii */
1555 if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1556 (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1557 (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1558 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1559 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1560 CL45_RD_OVER_CL22(bp, params->port,
1562 MDIO_REG_BANK_COMBO_IEEE0,
1563 MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1565 CL45_RD_OVER_CL22(bp, params->port,
1567 MDIO_REG_BANK_COMBO_IEEE0,
1568 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1570 pause_result = (ld_pause &
1571 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1572 pause_result |= (lp_pause &
1573 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1574 DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1575 bnx2x_pause_resolve(vars, pause_result);
1576 } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1577 (bnx2x_ext_phy_resove_fc(params, vars))) {
1580 if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
1581 vars->flow_ctrl = params->req_fc_auto_adv;
1583 vars->flow_ctrl = params->req_flow_ctrl;
1585 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1589 static u8 bnx2x_link_settings_status(struct link_params *params,
1590 struct link_vars *vars,
1593 struct bnx2x *bp = params->bp;
1596 vars->link_status = 0;
1598 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1599 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1602 vars->phy_link_up = 1;
1603 vars->link_status |= LINK_STATUS_LINK_UP;
1605 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1606 vars->duplex = DUPLEX_FULL;
1608 vars->duplex = DUPLEX_HALF;
1610 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1612 switch (gp_status & GP_STATUS_SPEED_MASK) {
1614 new_line_speed = SPEED_10;
1615 if (vars->duplex == DUPLEX_FULL)
1616 vars->link_status |= LINK_10TFD;
1618 vars->link_status |= LINK_10THD;
1621 case GP_STATUS_100M:
1622 new_line_speed = SPEED_100;
1623 if (vars->duplex == DUPLEX_FULL)
1624 vars->link_status |= LINK_100TXFD;
1626 vars->link_status |= LINK_100TXHD;
1630 case GP_STATUS_1G_KX:
1631 new_line_speed = SPEED_1000;
1632 if (vars->duplex == DUPLEX_FULL)
1633 vars->link_status |= LINK_1000TFD;
1635 vars->link_status |= LINK_1000THD;
1638 case GP_STATUS_2_5G:
1639 new_line_speed = SPEED_2500;
1640 if (vars->duplex == DUPLEX_FULL)
1641 vars->link_status |= LINK_2500TFD;
1643 vars->link_status |= LINK_2500THD;
1649 "link speed unsupported gp_status 0x%x\n",
1653 case GP_STATUS_10G_KX4:
1654 case GP_STATUS_10G_HIG:
1655 case GP_STATUS_10G_CX4:
1656 new_line_speed = SPEED_10000;
1657 vars->link_status |= LINK_10GTFD;
1660 case GP_STATUS_12G_HIG:
1661 new_line_speed = SPEED_12000;
1662 vars->link_status |= LINK_12GTFD;
1665 case GP_STATUS_12_5G:
1666 new_line_speed = SPEED_12500;
1667 vars->link_status |= LINK_12_5GTFD;
1671 new_line_speed = SPEED_13000;
1672 vars->link_status |= LINK_13GTFD;
1676 new_line_speed = SPEED_15000;
1677 vars->link_status |= LINK_15GTFD;
1681 new_line_speed = SPEED_16000;
1682 vars->link_status |= LINK_16GTFD;
1687 "link speed unsupported gp_status 0x%x\n",
1693 /* Upon link speed change set the NIG into drain mode.
1694 Comes to deals with possible FIFO glitch due to clk change
1695 when speed is decreased without link down indicator */
1696 if (new_line_speed != vars->line_speed) {
1697 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
1698 + params->port*4, 0);
1701 vars->line_speed = new_line_speed;
1702 vars->link_status |= LINK_STATUS_SERDES_LINK;
1704 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1705 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1706 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1707 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1708 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
1709 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1710 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
1711 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1712 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481))) {
1713 vars->autoneg = AUTO_NEG_ENABLED;
1715 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1716 vars->autoneg |= AUTO_NEG_COMPLETE;
1717 vars->link_status |=
1718 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1721 vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1722 vars->link_status |=
1723 LINK_STATUS_PARALLEL_DETECTION_USED;
1726 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1727 vars->link_status |=
1728 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1730 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1731 vars->link_status |=
1732 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1734 } else { /* link_down */
1735 DP(NETIF_MSG_LINK, "phy link down\n");
1737 vars->phy_link_up = 0;
1739 vars->duplex = DUPLEX_FULL;
1740 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1741 vars->autoneg = AUTO_NEG_DISABLED;
1742 vars->mac_type = MAC_TYPE_NONE;
1745 DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x \n",
1746 gp_status, vars->phy_link_up, vars->line_speed);
1747 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x"
1750 vars->flow_ctrl, vars->autoneg);
1751 DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1756 static void bnx2x_set_gmii_tx_driver(struct link_params *params)
1758 struct bnx2x *bp = params->bp;
1764 CL45_RD_OVER_CL22(bp, params->port,
1766 MDIO_REG_BANK_OVER_1G,
1767 MDIO_OVER_1G_LP_UP2, &lp_up2);
1769 CL45_RD_OVER_CL22(bp, params->port,
1772 MDIO_TX0_TX_DRIVER, &tx_driver);
1774 /* bits [10:7] at lp_up2, positioned at [15:12] */
1775 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1776 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1777 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1779 if ((lp_up2 != 0) &&
1780 (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
1781 /* replace tx_driver bits [15:12] */
1782 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1783 tx_driver |= lp_up2;
1784 CL45_WR_OVER_CL22(bp, params->port,
1787 MDIO_TX0_TX_DRIVER, tx_driver);
1791 static u8 bnx2x_emac_program(struct link_params *params,
1792 u32 line_speed, u32 duplex)
1794 struct bnx2x *bp = params->bp;
1795 u8 port = params->port;
1798 DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1799 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1801 (EMAC_MODE_25G_MODE |
1802 EMAC_MODE_PORT_MII_10M |
1803 EMAC_MODE_HALF_DUPLEX));
1804 switch (line_speed) {
1806 mode |= EMAC_MODE_PORT_MII_10M;
1810 mode |= EMAC_MODE_PORT_MII;
1814 mode |= EMAC_MODE_PORT_GMII;
1818 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1822 /* 10G not valid for EMAC */
1823 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1827 if (duplex == DUPLEX_HALF)
1828 mode |= EMAC_MODE_HALF_DUPLEX;
1830 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1833 bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1834 line_speed, params->hw_led_mode, params->chip_id);
1838 /*****************************************************************************/
1839 /* External Phy section */
1840 /*****************************************************************************/
1841 static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
1843 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1844 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
1846 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1847 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
1850 static void bnx2x_ext_phy_reset(struct link_params *params,
1851 struct link_vars *vars)
1853 struct bnx2x *bp = params->bp;
1855 u8 ext_phy_addr = ((params->ext_phy_config &
1856 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1857 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1858 DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1859 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1860 /* The PHY reset is controled by GPIO 1
1861 * Give it 1ms of reset pulse
1863 if (vars->phy_flags & PHY_XGXS_FLAG) {
1865 switch (ext_phy_type) {
1866 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1867 DP(NETIF_MSG_LINK, "XGXS Direct\n");
1870 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1871 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1872 DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1874 /* Restore normal power mode*/
1875 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1876 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1880 bnx2x_hw_reset(bp, params->port);
1882 bnx2x_cl45_write(bp, params->port,
1886 MDIO_PMA_REG_CTRL, 0xa040);
1888 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
1890 /* Restore normal power mode*/
1891 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1892 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1895 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1896 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1899 bnx2x_cl45_write(bp, params->port,
1907 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1908 /* Unset Low Power Mode and SW reset */
1909 /* Restore normal power mode*/
1910 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1911 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1914 DP(NETIF_MSG_LINK, "XGXS 8072\n");
1915 bnx2x_cl45_write(bp, params->port,
1922 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1925 emac_base = (params->port) ? GRCBASE_EMAC0 :
1928 /* Restore normal power mode*/
1929 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1930 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1933 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1934 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1937 DP(NETIF_MSG_LINK, "XGXS 8073\n");
1941 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1942 DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1944 /* Restore normal power mode*/
1945 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1946 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1950 bnx2x_hw_reset(bp, params->port);
1954 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
1956 /* Restore normal power mode*/
1957 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1958 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1962 bnx2x_hw_reset(bp, params->port);
1964 bnx2x_cl45_write(bp, params->port,
1971 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
1972 DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
1976 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
1977 params->ext_phy_config);
1981 } else { /* SerDes */
1982 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
1983 switch (ext_phy_type) {
1984 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
1985 DP(NETIF_MSG_LINK, "SerDes Direct\n");
1988 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
1989 DP(NETIF_MSG_LINK, "SerDes 5482\n");
1990 bnx2x_hw_reset(bp, params->port);
1995 "BAD SerDes ext_phy_config 0x%x\n",
1996 params->ext_phy_config);
2003 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
2004 u32 shmem_base, u32 spirom_ver)
2006 DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x\n",
2007 (u16)(spirom_ver>>16), (u16)spirom_ver);
2008 REG_WR(bp, shmem_base +
2009 offsetof(struct shmem_region,
2010 port_mb[port].ext_phy_fw_version),
2014 static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
2015 u32 ext_phy_type, u8 ext_phy_addr,
2018 u16 fw_ver1, fw_ver2;
2019 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2020 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2021 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2022 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2023 bnx2x_save_spirom_version(bp, port, shmem_base,
2024 (u32)(fw_ver1<<16 | fw_ver2));
2027 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
2029 struct bnx2x *bp = params->bp;
2030 u8 port = params->port;
2031 u8 ext_phy_addr = ((params->ext_phy_config &
2032 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2033 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2034 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2036 /* Need to wait 200ms after reset */
2038 /* Boot port from external ROM
2039 * Set ser_boot_ctl bit in the MISC_CTRL1 register
2041 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2043 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2045 /* Reset internal microprocessor */
2046 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2048 MDIO_PMA_REG_GEN_CTRL,
2049 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2050 /* set micro reset = 0 */
2051 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2053 MDIO_PMA_REG_GEN_CTRL,
2054 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2055 /* Reset internal microprocessor */
2056 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2058 MDIO_PMA_REG_GEN_CTRL,
2059 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2060 /* wait for 100ms for code download via SPI port */
2063 /* Clear ser_boot_ctl bit */
2064 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2066 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2070 bnx2x_save_bcm_spirom_ver(bp, port,
2073 params->shmem_base);
2076 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2078 /* This is only required for 8073A1, version 102 only */
2080 struct bnx2x *bp = params->bp;
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);
2086 /* Read 8073 HW revision*/
2087 bnx2x_cl45_read(bp, params->port,
2088 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2094 /* No need to workaround in 8073 A1 */
2098 bnx2x_cl45_read(bp, params->port,
2099 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2102 MDIO_PMA_REG_ROM_VER2, &val);
2104 /* SNR should be applied only for version 0x102 */
2111 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2113 struct bnx2x *bp = params->bp;
2114 u8 ext_phy_addr = ((params->ext_phy_config &
2115 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2116 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2117 u16 val, cnt, cnt1 ;
2119 bnx2x_cl45_read(bp, params->port,
2120 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2126 /* No need to workaround in 8073 A1 */
2129 /* XAUI workaround in 8073 A0: */
2131 /* After loading the boot ROM and restarting Autoneg,
2132 poll Dev1, Reg $C820: */
2134 for (cnt = 0; cnt < 1000; cnt++) {
2135 bnx2x_cl45_read(bp, params->port,
2136 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2140 /* If bit [14] = 0 or bit [13] = 0, continue on with
2141 system initialization (XAUI work-around not required,
2142 as these bits indicate 2.5G or 1G link up). */
2143 if (!(val & (1<<14)) || !(val & (1<<13))) {
2144 DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2146 } else if (!(val & (1<<15))) {
2147 DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2148 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2149 it's MSB (bit 15) goes to 1 (indicating that the
2150 XAUI workaround has completed),
2151 then continue on with system initialization.*/
2152 for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2153 bnx2x_cl45_read(bp, params->port,
2154 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2158 if (val & (1<<15)) {
2160 "XAUI workaround has completed\n");
2169 DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2174 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2175 u8 ext_phy_addr, u32 shmem_base)
2177 /* Boot port from external ROM */
2179 bnx2x_cl45_write(bp, port,
2180 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2183 MDIO_PMA_REG_GEN_CTRL,
2186 /* ucode reboot and rst */
2187 bnx2x_cl45_write(bp, port,
2188 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2191 MDIO_PMA_REG_GEN_CTRL,
2194 bnx2x_cl45_write(bp, port,
2195 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2198 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2200 /* Reset internal microprocessor */
2201 bnx2x_cl45_write(bp, port,
2202 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2205 MDIO_PMA_REG_GEN_CTRL,
2206 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2208 /* Release srst bit */
2209 bnx2x_cl45_write(bp, port,
2210 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2213 MDIO_PMA_REG_GEN_CTRL,
2214 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2216 /* wait for 100ms for code download via SPI port */
2219 /* Clear ser_boot_ctl bit */
2220 bnx2x_cl45_write(bp, port,
2221 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2224 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2226 bnx2x_save_bcm_spirom_ver(bp, port,
2227 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2232 static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
2234 struct bnx2x *bp = params->bp;
2235 u8 port = params->port;
2236 u8 ext_phy_addr = ((params->ext_phy_config &
2237 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2238 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2239 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2241 /* Need to wait 100ms after reset */
2244 /* Set serial boot control for external load */
2245 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2247 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2249 /* Micro controller re-boot */
2250 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2252 MDIO_PMA_REG_GEN_CTRL,
2253 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2255 /* Set soft reset */
2256 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2258 MDIO_PMA_REG_GEN_CTRL,
2259 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2261 /* Clear soft reset.
2262 Will automatically reset micro-controller re-boot */
2263 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2265 MDIO_PMA_REG_GEN_CTRL,
2266 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2268 /* wait for 100ms for microcode load */
2271 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
2272 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2274 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2277 bnx2x_save_bcm_spirom_ver(bp, port,
2280 params->shmem_base);
2283 static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port,
2284 u8 ext_phy_addr, u8 tx_en)
2287 DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
2289 /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
2290 bnx2x_cl45_read(bp, port,
2291 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2294 MDIO_PMA_REG_PHY_IDENTIFIER,
2302 bnx2x_cl45_write(bp, port,
2303 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2306 MDIO_PMA_REG_PHY_IDENTIFIER,
2311 static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
2312 u8 byte_cnt, u8 *o_buf) {
2313 struct bnx2x *bp = params->bp;
2315 u8 port = params->port;
2316 u8 ext_phy_addr = ((params->ext_phy_config &
2317 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2318 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2319 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2320 if (byte_cnt > 16) {
2321 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2322 " is limited to 0xf\n");
2325 /* Set the read command byte count */
2326 bnx2x_cl45_write(bp, port,
2330 MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT,
2331 (byte_cnt | 0xa000));
2333 /* Set the read command address */
2334 bnx2x_cl45_write(bp, port,
2338 MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR,
2341 /* Activate read command */
2342 bnx2x_cl45_write(bp, port,
2346 MDIO_PMA_REG_8726_TWO_WIRE_CTRL,
2349 /* Wait up to 500us for command complete status */
2350 for (i = 0; i < 100; i++) {
2351 bnx2x_cl45_read(bp, port,
2355 MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2356 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2357 MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE)
2362 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) !=
2363 MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE) {
2365 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2366 (val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK));
2370 /* Read the buffer */
2371 for (i = 0; i < byte_cnt; i++) {
2372 bnx2x_cl45_read(bp, port,
2376 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2377 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
2380 for (i = 0; i < 100; i++) {
2381 bnx2x_cl45_read(bp, port,
2385 MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2386 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2387 MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE)
2395 static u8 bnx2x_get_sfp_module_type(struct link_params *params,
2398 struct bnx2x *bp = params->bp;
2400 *module_type = SFP_MODULE_TYPE_UNKNOWN;
2402 /* First check for copper cable */
2403 if (bnx2x_read_sfp_module_eeprom(params,
2404 SFP_EEPROM_CON_TYPE_ADDR,
2407 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM");
2412 case SFP_EEPROM_CON_TYPE_VAL_COPPER:
2414 u8 copper_module_type;
2415 /* Check if its active cable( includes SFP+ module)
2417 if (bnx2x_read_sfp_module_eeprom(params,
2418 SFP_EEPROM_FC_TX_TECH_ADDR,
2420 &copper_module_type) !=
2423 "Failed to read copper-cable-type"
2424 " from SFP+ EEPROM\n");
2428 if (copper_module_type &
2429 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
2430 DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
2431 *module_type = SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE;
2432 } else if (copper_module_type &
2433 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
2434 DP(NETIF_MSG_LINK, "Passive Copper"
2435 " cable detected\n");
2437 SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE;
2439 DP(NETIF_MSG_LINK, "Unknown copper-cable-"
2440 "type 0x%x !!!\n", copper_module_type);
2445 case SFP_EEPROM_CON_TYPE_VAL_LC:
2446 DP(NETIF_MSG_LINK, "Optic module detected\n");
2447 *module_type = SFP_MODULE_TYPE_LC;
2451 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
2459 /* This function read the relevant field from the module ( SFP+ ),
2460 and verify it is compliant with this board */
2461 static u8 bnx2x_verify_sfp_module(struct link_params *params,
2464 struct bnx2x *bp = params->bp;
2465 u8 *str_p, *tmp_buf;
2468 #define COMPLIANCE_STR_CNT 6
2469 u8 *compliance_str[] = {"Broadcom", "JDSU", "Molex Inc", "PICOLIGHT",
2470 "FINISAR CORP. ", "Amphenol"};
2471 u8 buf[SFP_EEPROM_VENDOR_NAME_SIZE];
2472 /* Passive Copper cables are allowed to participate,
2473 since the module is hardwired to the copper cable */
2475 if (!(params->feature_config_flags &
2476 FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2477 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
2481 if (module_type != SFP_MODULE_TYPE_LC) {
2482 DP(NETIF_MSG_LINK, "No need to verify copper cable\n");
2486 /* In case of non copper cable or Active copper cable,
2487 verify that the SFP+ module is compliant with this board*/
2488 if (bnx2x_read_sfp_module_eeprom(params,
2489 SFP_EEPROM_VENDOR_NAME_ADDR,
2490 SFP_EEPROM_VENDOR_NAME_SIZE,
2492 DP(NETIF_MSG_LINK, "Failed to read Vendor-Name from"
2493 " module EEPROM\n");
2496 for (i = 0; i < COMPLIANCE_STR_CNT; i++) {
2497 str_p = compliance_str[i];
2500 if ((u8)(*tmp_buf) != (u8)(*str_p))
2507 DP(NETIF_MSG_LINK, "SFP+ Module verified, "
2512 DP(NETIF_MSG_LINK, "Incompliant SFP+ module. Disable module !!!\n");
2517 static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
2520 struct bnx2x *bp = params->bp;
2521 u8 port = params->port;
2522 u8 options[SFP_EEPROM_OPTIONS_SIZE];
2524 u8 ext_phy_addr = ((params->ext_phy_config &
2525 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2526 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2528 if (bnx2x_read_sfp_module_eeprom(params,
2529 SFP_EEPROM_OPTIONS_ADDR,
2530 SFP_EEPROM_OPTIONS_SIZE,
2532 DP(NETIF_MSG_LINK, "Failed to read Option field from"
2533 " module EEPROM\n");
2536 limiting_mode = !(options[0] &
2537 SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK);
2538 if (limiting_mode &&
2539 (module_type != SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE)) {
2541 "Module options = 0x%x.Setting LIMITING MODE\n",
2543 bnx2x_cl45_write(bp, port,
2544 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2547 MDIO_PMA_REG_ROM_VER2,
2548 SFP_LIMITING_MODE_VALUE);
2549 } else { /* LRM mode ( default )*/
2550 u16 cur_limiting_mode;
2551 DP(NETIF_MSG_LINK, "Module options = 0x%x.Setting LRM MODE\n",
2554 bnx2x_cl45_read(bp, port,
2555 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2558 MDIO_PMA_REG_ROM_VER2,
2559 &cur_limiting_mode);
2561 /* Changing to LRM mode takes quite few seconds.
2562 So do it only if current mode is limiting
2563 ( default is LRM )*/
2564 if (cur_limiting_mode != SFP_LIMITING_MODE_VALUE)
2567 bnx2x_cl45_write(bp, port,
2568 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2571 MDIO_PMA_REG_LRM_MODE,
2573 bnx2x_cl45_write(bp, port,
2574 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2577 MDIO_PMA_REG_ROM_VER2,
2579 bnx2x_cl45_write(bp, port,
2580 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2583 MDIO_PMA_REG_MISC_CTRL0,
2585 bnx2x_cl45_write(bp, port,
2586 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2589 MDIO_PMA_REG_LRM_MODE,
2595 static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
2598 struct bnx2x *bp = params->bp;
2600 /* Initialization time after hot-plug may take up to 300ms for some
2601 phys type ( e.g. JDSU ) */
2602 for (timeout = 0; timeout < 60; timeout++) {
2603 if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
2605 DP(NETIF_MSG_LINK, "SFP+ module initialization "
2606 "took %d ms\n", timeout * 5);
2614 static u8 bnx2x_sfp_module_detection(struct link_params *params)
2616 struct bnx2x *bp = params->bp;
2618 u8 ext_phy_addr = ((params->ext_phy_config &
2619 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2620 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2621 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2623 if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
2624 DP(NETIF_MSG_LINK, "Module detection is not required "
2629 DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
2632 if (bnx2x_get_sfp_module_type(params,
2633 &module_type) != 0) {
2634 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
2635 if (!(params->feature_config_flags &
2636 FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2637 /* In case module detection is disabled, it trys to
2638 link up. The issue that can happen here is LRM /
2639 LIMITING mode which set according to the module-type*/
2640 DP(NETIF_MSG_LINK, "Unable to read module-type."
2641 "Probably due to Bit Stretching."
2642 " Proceeding...\n");
2646 } else if (bnx2x_verify_sfp_module(params, module_type) !=
2648 /* check SFP+ module compatibility */
2649 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
2650 /* Turn on fault module-detected led */
2651 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2652 MISC_REGISTERS_GPIO_HIGH,
2657 /* Turn off fault module-detected led */
2658 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2659 MISC_REGISTERS_GPIO_LOW,
2662 /* Check and set limiting mode / LRM mode */
2663 if (bnx2x_bcm8726_set_limiting_mode(params, module_type)
2665 DP(NETIF_MSG_LINK, "Setting limiting mode failed!!\n");
2669 /* Enable transmit for this module */
2670 bnx2x_bcm8726_set_transmitter(bp, params->port,
2675 void bnx2x_handle_module_detect_int(struct link_params *params)
2677 struct bnx2x *bp = params->bp;
2679 u8 port = params->port;
2680 /* Set valid module led off */
2681 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2682 MISC_REGISTERS_GPIO_HIGH,
2685 /* Get current gpio val refelecting module plugged in / out*/
2686 gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
2688 /* Call the handling function in case module is detected */
2689 if (gpio_val == 0) {
2691 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2692 MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
2695 if (bnx2x_wait_for_sfp_module_initialized(params)
2697 bnx2x_sfp_module_detection(params);
2699 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
2701 u8 ext_phy_addr = ((params->ext_phy_config &
2702 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2703 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2704 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2705 MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
2707 /* Module was plugged out. */
2708 /* Disable transmit for this module */
2709 bnx2x_bcm8726_set_transmitter(bp, params->port,
2714 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2716 struct bnx2x *bp = params->bp;
2717 u8 port = params->port;
2718 u8 ext_phy_addr = ((params->ext_phy_config &
2719 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2720 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2721 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2723 /* Force KR or KX */
2724 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2728 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2730 MDIO_PMA_REG_10G_CTRL2,
2732 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2734 MDIO_PMA_REG_BCM_CTRL,
2736 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2741 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2743 struct bnx2x *bp = params->bp;
2744 u8 port = params->port;
2746 u8 ext_phy_addr = ((params->ext_phy_config &
2747 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2748 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2749 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2751 bnx2x_cl45_read(bp, params->port,
2752 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2758 /* Mustn't set low power mode in 8073 A0 */
2762 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2763 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2765 MDIO_XS_PLL_SEQUENCER, &val);
2767 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2768 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2771 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2772 MDIO_XS_DEVAD, 0x805E, 0x1077);
2773 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2774 MDIO_XS_DEVAD, 0x805D, 0x0000);
2775 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2776 MDIO_XS_DEVAD, 0x805C, 0x030B);
2777 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2778 MDIO_XS_DEVAD, 0x805B, 0x1240);
2779 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2780 MDIO_XS_DEVAD, 0x805A, 0x2490);
2783 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2784 MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2785 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2786 MDIO_XS_DEVAD, 0x80A6, 0x9041);
2787 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2788 MDIO_XS_DEVAD, 0x80A5, 0x4640);
2791 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2792 MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2793 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2794 MDIO_XS_DEVAD, 0x80FD, 0x9249);
2795 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2796 MDIO_XS_DEVAD, 0x80FC, 0x2015);
2798 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
2799 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2801 MDIO_XS_PLL_SEQUENCER, &val);
2803 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2804 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2807 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
2808 struct link_vars *vars)
2811 struct bnx2x *bp = params->bp;
2813 u8 ext_phy_addr = ((params->ext_phy_config &
2814 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2815 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2816 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2818 bnx2x_cl45_read(bp, params->port,
2822 MDIO_AN_REG_CL37_FC_LD, &cl37_val);
2824 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2825 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2827 if ((vars->ieee_fc &
2828 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
2829 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
2830 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
2832 if ((vars->ieee_fc &
2833 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2834 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2835 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2837 if ((vars->ieee_fc &
2838 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2839 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2840 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2843 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
2845 bnx2x_cl45_write(bp, params->port,
2849 MDIO_AN_REG_CL37_FC_LD, cl37_val);
2853 static void bnx2x_ext_phy_set_pause(struct link_params *params,
2854 struct link_vars *vars)
2856 struct bnx2x *bp = params->bp;
2858 u8 ext_phy_addr = ((params->ext_phy_config &
2859 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2860 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2861 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2863 /* read modify write pause advertizing */
2864 bnx2x_cl45_read(bp, params->port,
2868 MDIO_AN_REG_ADV_PAUSE, &val);
2870 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2872 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2874 if ((vars->ieee_fc &
2875 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2876 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2877 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2879 if ((vars->ieee_fc &
2880 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2881 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2883 MDIO_AN_REG_ADV_PAUSE_PAUSE;
2886 "Ext phy AN advertize 0x%x\n", val);
2887 bnx2x_cl45_write(bp, params->port,
2891 MDIO_AN_REG_ADV_PAUSE, val);
2895 static void bnx2x_init_internal_phy(struct link_params *params,
2896 struct link_vars *vars)
2898 struct bnx2x *bp = params->bp;
2899 u8 port = params->port;
2900 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2903 rx_eq = ((params->serdes_config &
2904 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2905 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2907 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2908 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2909 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2910 CL45_WR_OVER_CL22(bp, port,
2913 MDIO_RX0_RX_EQ_BOOST,
2915 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2916 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2919 /* forced speed requested? */
2920 if (vars->line_speed != SPEED_AUTO_NEG) {
2921 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2923 /* disable autoneg */
2924 bnx2x_set_autoneg(params, vars);
2926 /* program speed and duplex */
2927 bnx2x_program_serdes(params, vars);
2929 } else { /* AN_mode */
2930 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2933 bnx2x_set_brcm_cl37_advertisment(params);
2935 /* program duplex & pause advertisement (for aneg) */
2936 bnx2x_set_ieee_aneg_advertisment(params,
2939 /* enable autoneg */
2940 bnx2x_set_autoneg(params, vars);
2942 /* enable and restart AN */
2943 bnx2x_restart_autoneg(params);
2946 } else { /* SGMII mode */
2947 DP(NETIF_MSG_LINK, "SGMII\n");
2949 bnx2x_initialize_sgmii_process(params, vars);
2953 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2955 struct bnx2x *bp = params->bp;
2962 if (vars->phy_flags & PHY_XGXS_FLAG) {
2963 ext_phy_addr = ((params->ext_phy_config &
2964 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2965 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2967 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2968 /* Make sure that the soft reset is off (expect for the 8072:
2969 * due to the lock, it will be done inside the specific
2972 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
2973 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
2974 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
2975 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
2976 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
2977 /* Wait for soft reset to get cleared upto 1 sec */
2978 for (cnt = 0; cnt < 1000; cnt++) {
2979 bnx2x_cl45_read(bp, params->port,
2983 MDIO_PMA_REG_CTRL, &ctrl);
2984 if (!(ctrl & (1<<15)))
2988 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
2992 switch (ext_phy_type) {
2993 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2996 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2997 DP(NETIF_MSG_LINK, "XGXS 8705\n");
2999 bnx2x_cl45_write(bp, params->port,
3003 MDIO_PMA_REG_MISC_CTRL,
3005 bnx2x_cl45_write(bp, params->port,
3009 MDIO_PMA_REG_PHY_IDENTIFIER,
3011 bnx2x_cl45_write(bp, params->port,
3015 MDIO_PMA_REG_CMU_PLL_BYPASS,
3017 bnx2x_cl45_write(bp, params->port,
3021 MDIO_WIS_REG_LASI_CNTL, 0x1);
3023 bnx2x_save_bcm_spirom_ver(bp, params->port,
3026 params->shmem_base);
3029 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3030 /* Wait until fw is loaded */
3031 for (cnt = 0; cnt < 100; cnt++) {
3032 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3033 ext_phy_addr, MDIO_PMA_DEVAD,
3034 MDIO_PMA_REG_ROM_VER1, &val);
3039 DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
3040 "after %d ms\n", cnt);
3042 /* First enable LASI */
3043 bnx2x_cl45_write(bp, params->port,
3047 MDIO_PMA_REG_RX_ALARM_CTRL,
3049 bnx2x_cl45_write(bp, params->port,
3053 MDIO_PMA_REG_LASI_CTRL, 0x0004);
3055 if (params->req_line_speed == SPEED_10000) {
3056 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
3058 bnx2x_cl45_write(bp, params->port,
3062 MDIO_PMA_REG_DIGITAL_CTRL,
3065 /* Force 1Gbps using autoneg with 1G
3068 /* Allow CL37 through CL73 */
3069 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
3070 bnx2x_cl45_write(bp, params->port,
3074 MDIO_AN_REG_CL37_CL73,
3077 /* Enable Full-Duplex advertisment on CL37 */
3078 bnx2x_cl45_write(bp, params->port,
3082 MDIO_AN_REG_CL37_FC_LP,
3084 /* Enable CL37 AN */
3085 bnx2x_cl45_write(bp, params->port,
3089 MDIO_AN_REG_CL37_AN,
3092 bnx2x_cl45_write(bp, params->port,
3096 MDIO_AN_REG_ADV, (1<<5));
3098 /* Enable clause 73 AN */
3099 bnx2x_cl45_write(bp, params->port,
3107 bnx2x_save_bcm_spirom_ver(bp, params->port,
3110 params->shmem_base);
3112 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3113 DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3114 bnx2x_bcm8726_external_rom_boot(params);
3116 /* Need to call module detected on initialization since
3117 the module detection triggered by actual module
3118 insertion might occur before driver is loaded, and when
3119 driver is loaded, it reset all registers, including the
3121 bnx2x_sfp_module_detection(params);
3122 if (params->req_line_speed == SPEED_1000) {
3123 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3124 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3125 ext_phy_addr, MDIO_PMA_DEVAD,
3126 MDIO_PMA_REG_CTRL, 0x40);
3127 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3128 ext_phy_addr, MDIO_PMA_DEVAD,
3129 MDIO_PMA_REG_10G_CTRL2, 0xD);
3130 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3131 ext_phy_addr, MDIO_PMA_DEVAD,
3132 MDIO_PMA_REG_LASI_CTRL, 0x5);
3133 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3134 ext_phy_addr, MDIO_PMA_DEVAD,
3135 MDIO_PMA_REG_RX_ALARM_CTRL,
3137 } else if ((params->req_line_speed ==
3139 ((params->speed_cap_mask &
3140 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3141 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
3142 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3143 ext_phy_addr, MDIO_AN_DEVAD,
3144 MDIO_AN_REG_ADV, 0x20);
3145 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3146 ext_phy_addr, MDIO_AN_DEVAD,
3147 MDIO_AN_REG_CL37_CL73, 0x040c);
3148 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3149 ext_phy_addr, MDIO_AN_DEVAD,
3150 MDIO_AN_REG_CL37_FC_LD, 0x0020);
3151 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3152 ext_phy_addr, MDIO_AN_DEVAD,
3153 MDIO_AN_REG_CL37_AN, 0x1000);
3154 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3155 ext_phy_addr, MDIO_AN_DEVAD,
3156 MDIO_AN_REG_CTRL, 0x1200);
3158 /* Enable RX-ALARM control to receive
3159 interrupt for 1G speed change */
3160 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3161 ext_phy_addr, MDIO_PMA_DEVAD,
3162 MDIO_PMA_REG_LASI_CTRL, 0x4);
3163 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3164 ext_phy_addr, MDIO_PMA_DEVAD,
3165 MDIO_PMA_REG_RX_ALARM_CTRL,
3168 } else { /* Default 10G. Set only LASI control */
3169 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3170 ext_phy_addr, MDIO_PMA_DEVAD,
3171 MDIO_PMA_REG_LASI_CTRL, 1);
3174 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3175 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3178 u16 rx_alarm_ctrl_val;
3181 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3182 rx_alarm_ctrl_val = 0x400;
3183 lasi_ctrl_val = 0x0004;
3185 rx_alarm_ctrl_val = (1<<2);
3186 lasi_ctrl_val = 0x0004;
3190 bnx2x_cl45_write(bp, params->port,
3194 MDIO_PMA_REG_RX_ALARM_CTRL,
3197 bnx2x_cl45_write(bp, params->port,
3201 MDIO_PMA_REG_LASI_CTRL,
3204 bnx2x_8073_set_pause_cl37(params, vars);
3207 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
3208 bnx2x_bcm8072_external_rom_boot(params);
3211 /* In case of 8073 with long xaui lines,
3212 don't set the 8073 xaui low power*/
3213 bnx2x_bcm8073_set_xaui_low_power_mode(params);
3216 bnx2x_cl45_read(bp, params->port,
3223 bnx2x_cl45_read(bp, params->port,
3227 MDIO_PMA_REG_RX_ALARM, &tmp1);
3229 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
3232 /* If this is forced speed, set to KR or KX
3233 * (all other are not supported)
3235 if (params->loopback_mode == LOOPBACK_EXT) {
3236 bnx2x_bcm807x_force_10G(params);
3238 "Forced speed 10G on 807X\n");
3241 bnx2x_cl45_write(bp, params->port,
3242 ext_phy_type, ext_phy_addr,
3244 MDIO_PMA_REG_BCM_CTRL,
3247 if (params->req_line_speed != SPEED_AUTO_NEG) {
3248 if (params->req_line_speed == SPEED_10000) {
3250 } else if (params->req_line_speed ==
3253 /* Note that 2.5G works only
3254 when used with 1G advertisment */
3260 if (params->speed_cap_mask &
3261 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3264 /* Note that 2.5G works only when
3265 used with 1G advertisment */
3266 if (params->speed_cap_mask &
3267 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
3268 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
3271 "807x autoneg val = 0x%x\n", val);
3274 bnx2x_cl45_write(bp, params->port,
3278 MDIO_AN_REG_ADV, val);
3281 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3283 bnx2x_cl45_read(bp, params->port,
3289 if (((params->speed_cap_mask &
3290 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
3291 (params->req_line_speed ==
3293 (params->req_line_speed ==
3296 /* Allow 2.5G for A1 and above */
3297 bnx2x_cl45_read(bp, params->port,
3298 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
3302 DP(NETIF_MSG_LINK, "Add 2.5G\n");
3308 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
3312 bnx2x_cl45_write(bp, params->port,
3319 /* Add support for CL37 (passive mode) II */
3321 bnx2x_cl45_read(bp, params->port,
3325 MDIO_AN_REG_CL37_FC_LD,
3328 bnx2x_cl45_write(bp, params->port,
3332 MDIO_AN_REG_CL37_FC_LD, (tmp1 |
3333 ((params->req_duplex == DUPLEX_FULL) ?
3336 /* Add support for CL37 (passive mode) III */
3337 bnx2x_cl45_write(bp, params->port,
3341 MDIO_AN_REG_CL37_AN, 0x1000);
3344 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3345 /* The SNR will improve about 2db by changing
3346 BW and FEE main tap. Rest commands are executed
3348 /*Change FFE main cursor to 5 in EDC register*/
3349 if (bnx2x_8073_is_snr_needed(params))
3350 bnx2x_cl45_write(bp, params->port,
3354 MDIO_PMA_REG_EDC_FFE_MAIN,
3357 /* Enable FEC (Forware Error Correction)
3358 Request in the AN */
3359 bnx2x_cl45_read(bp, params->port,
3363 MDIO_AN_REG_ADV2, &tmp1);
3367 bnx2x_cl45_write(bp, params->port,
3371 MDIO_AN_REG_ADV2, tmp1);
3375 bnx2x_ext_phy_set_pause(params, vars);
3377 /* Restart autoneg */
3379 bnx2x_cl45_write(bp, params->port,
3383 MDIO_AN_REG_CTRL, 0x1200);
3384 DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
3385 "Advertise 1G=%x, 10G=%x\n",
3386 ((val & (1<<5)) > 0),
3387 ((val & (1<<7)) > 0));
3390 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3392 u16 fw_ver1, fw_ver2;
3394 "Setting the SFX7101 LASI indication\n");
3396 bnx2x_cl45_write(bp, params->port,
3400 MDIO_PMA_REG_LASI_CTRL, 0x1);
3402 "Setting the SFX7101 LED to blink on traffic\n");
3403 bnx2x_cl45_write(bp, params->port,
3407 MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
3409 bnx2x_ext_phy_set_pause(params, vars);
3410 /* Restart autoneg */
3411 bnx2x_cl45_read(bp, params->port,
3415 MDIO_AN_REG_CTRL, &val);
3417 bnx2x_cl45_write(bp, params->port,
3421 MDIO_AN_REG_CTRL, val);
3423 /* Save spirom version */
3424 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3425 ext_phy_addr, MDIO_PMA_DEVAD,
3426 MDIO_PMA_REG_7101_VER1, &fw_ver1);
3428 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3429 ext_phy_addr, MDIO_PMA_DEVAD,
3430 MDIO_PMA_REG_7101_VER2, &fw_ver2);
3432 bnx2x_save_spirom_version(params->bp, params->port,
3434 (u32)(fw_ver1<<16 | fw_ver2));
3438 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
3440 "Setting the BCM8481 LASI control\n");
3442 bnx2x_cl45_write(bp, params->port,
3446 MDIO_PMA_REG_LASI_CTRL, 0x1);
3448 /* Restart autoneg */
3449 bnx2x_cl45_read(bp, params->port,
3453 MDIO_AN_REG_CTRL, &val);
3455 bnx2x_cl45_write(bp, params->port,
3459 MDIO_AN_REG_CTRL, val);
3461 bnx2x_save_bcm_spirom_ver(bp, params->port,
3464 params->shmem_base);
3467 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
3469 "XGXS PHY Failure detected 0x%x\n",
3470 params->ext_phy_config);
3474 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3475 params->ext_phy_config);
3480 } else { /* SerDes */
3482 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3483 switch (ext_phy_type) {
3484 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3485 DP(NETIF_MSG_LINK, "SerDes Direct\n");
3488 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3489 DP(NETIF_MSG_LINK, "SerDes 5482\n");
3493 DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
3494 params->ext_phy_config);
3502 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
3503 struct link_vars *vars)
3505 struct bnx2x *bp = params->bp;
3509 u16 rx_sd, pcs_status;
3510 u8 ext_phy_link_up = 0;
3511 u8 port = params->port;
3512 if (vars->phy_flags & PHY_XGXS_FLAG) {
3513 ext_phy_addr = ((params->ext_phy_config &
3514 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3515 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3517 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3518 switch (ext_phy_type) {
3519 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3520 DP(NETIF_MSG_LINK, "XGXS Direct\n");
3521 ext_phy_link_up = 1;
3524 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3525 DP(NETIF_MSG_LINK, "XGXS 8705\n");
3526 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3529 MDIO_WIS_REG_LASI_STATUS, &val1);
3530 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3532 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3535 MDIO_WIS_REG_LASI_STATUS, &val1);
3536 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3538 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3541 MDIO_PMA_REG_RX_SD, &rx_sd);
3542 DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
3543 ext_phy_link_up = (rx_sd & 0x1);
3544 if (ext_phy_link_up)
3545 vars->line_speed = SPEED_10000;
3548 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3549 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3550 DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
3552 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3554 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
3556 /* clear LASI indication*/
3557 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3559 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
3561 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3563 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
3565 DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
3566 "0x%x\n", val1, val2);
3568 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3570 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
3572 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3574 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
3576 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3578 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
3580 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3582 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
3585 DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
3586 " pcs_status 0x%x 1Gbps link_status 0x%x\n",
3587 rx_sd, pcs_status, val2);
3588 /* link is up if both bit 0 of pmd_rx_sd and
3589 * bit 0 of pcs_status are set, or if the autoneg bit
3592 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
3594 if (ext_phy_link_up) {
3596 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
3597 /* If transmitter is disabled,
3598 ignore false link up indication */
3599 bnx2x_cl45_read(bp, params->port,
3603 MDIO_PMA_REG_PHY_IDENTIFIER,
3605 if (val1 & (1<<15)) {
3606 DP(NETIF_MSG_LINK, "Tx is "
3608 ext_phy_link_up = 0;
3614 vars->line_speed = SPEED_1000;
3616 vars->line_speed = SPEED_10000;
3620 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3621 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3623 u16 link_status = 0;
3624 u16 an1000_status = 0;
3626 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3627 bnx2x_cl45_read(bp, params->port,
3631 MDIO_PCS_REG_LASI_STATUS, &val1);
3632 bnx2x_cl45_read(bp, params->port,
3636 MDIO_PCS_REG_LASI_STATUS, &val2);
3638 "870x LASI status 0x%x->0x%x\n",
3642 /* In 8073, port1 is directed through emac0 and
3643 * port0 is directed through emac1
3645 bnx2x_cl45_read(bp, params->port,
3649 MDIO_PMA_REG_LASI_STATUS, &val1);
3652 "8703 LASI status 0x%x\n",
3656 /* clear the interrupt LASI status register */
3657 bnx2x_cl45_read(bp, params->port,
3661 MDIO_PCS_REG_STATUS, &val2);
3662 bnx2x_cl45_read(bp, params->port,
3666 MDIO_PCS_REG_STATUS, &val1);
3667 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
3670 bnx2x_cl45_read(bp, params->port,
3677 /* Check the LASI */
3678 bnx2x_cl45_read(bp, params->port,
3682 MDIO_PMA_REG_RX_ALARM, &val2);
3684 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
3686 /* Check the link status */
3687 bnx2x_cl45_read(bp, params->port,
3691 MDIO_PCS_REG_STATUS, &val2);
3692 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
3694 bnx2x_cl45_read(bp, params->port,
3698 MDIO_PMA_REG_STATUS, &val2);
3699 bnx2x_cl45_read(bp, params->port,
3703 MDIO_PMA_REG_STATUS, &val1);
3704 ext_phy_link_up = ((val1 & 4) == 4);
3705 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
3707 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3709 if (ext_phy_link_up &&
3710 ((params->req_line_speed !=
3712 if (bnx2x_bcm8073_xaui_wa(params)
3714 ext_phy_link_up = 0;
3718 bnx2x_cl45_read(bp, params->port,
3724 bnx2x_cl45_read(bp, params->port,
3731 /* Check the link status on 1.1.2 */
3732 bnx2x_cl45_read(bp, params->port,
3736 MDIO_PMA_REG_STATUS, &val2);
3737 bnx2x_cl45_read(bp, params->port,
3741 MDIO_PMA_REG_STATUS, &val1);
3742 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3743 "an_link_status=0x%x\n",
3744 val2, val1, an1000_status);
3746 ext_phy_link_up = (((val1 & 4) == 4) ||
3747 (an1000_status & (1<<1)));
3748 if (ext_phy_link_up &&
3749 bnx2x_8073_is_snr_needed(params)) {
3750 /* The SNR will improve about 2dbby
3751 changing the BW and FEE main tap.*/
3753 /* The 1st write to change FFE main
3754 tap is set before restart AN */
3755 /* Change PLL Bandwidth in EDC
3757 bnx2x_cl45_write(bp, port, ext_phy_type,
3760 MDIO_PMA_REG_PLL_BANDWIDTH,
3763 /* Change CDR Bandwidth in EDC
3765 bnx2x_cl45_write(bp, port, ext_phy_type,
3768 MDIO_PMA_REG_CDR_BANDWIDTH,
3773 bnx2x_cl45_read(bp, params->port,
3780 /* Bits 0..2 --> speed detected,
3781 bits 13..15--> link is down */
3782 if ((link_status & (1<<2)) &&
3783 (!(link_status & (1<<15)))) {
3784 ext_phy_link_up = 1;
3785 vars->line_speed = SPEED_10000;
3787 "port %x: External link"
3788 " up in 10G\n", params->port);
3789 } else if ((link_status & (1<<1)) &&
3790 (!(link_status & (1<<14)))) {
3791 ext_phy_link_up = 1;
3792 vars->line_speed = SPEED_2500;
3794 "port %x: External link"
3795 " up in 2.5G\n", params->port);
3796 } else if ((link_status & (1<<0)) &&
3797 (!(link_status & (1<<13)))) {
3798 ext_phy_link_up = 1;
3799 vars->line_speed = SPEED_1000;
3801 "port %x: External link"
3802 " up in 1G\n", params->port);
3804 ext_phy_link_up = 0;
3806 "port %x: External link"
3807 " is down\n", params->port);
3810 /* See if 1G link is up for the 8072 */
3811 bnx2x_cl45_read(bp, params->port,
3817 bnx2x_cl45_read(bp, params->port,
3823 if (an1000_status & (1<<1)) {
3824 ext_phy_link_up = 1;
3825 vars->line_speed = SPEED_1000;
3827 "port %x: External link"
3828 " up in 1G\n", params->port);
3829 } else if (ext_phy_link_up) {
3830 ext_phy_link_up = 1;
3831 vars->line_speed = SPEED_10000;
3833 "port %x: External link"
3834 " up in 10G\n", params->port);
3841 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3842 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3845 MDIO_PMA_REG_LASI_STATUS, &val2);
3846 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3849 MDIO_PMA_REG_LASI_STATUS, &val1);
3851 "10G-base-T LASI status 0x%x->0x%x\n",
3853 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3856 MDIO_PMA_REG_STATUS, &val2);
3857 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3860 MDIO_PMA_REG_STATUS, &val1);
3862 "10G-base-T PMA status 0x%x->0x%x\n",
3864 ext_phy_link_up = ((val1 & 4) == 4);
3866 * print the AN outcome of the SFX7101 PHY
3868 if (ext_phy_link_up) {
3869 bnx2x_cl45_read(bp, params->port,
3873 MDIO_AN_REG_MASTER_STATUS,
3875 vars->line_speed = SPEED_10000;
3877 "SFX7101 AN status 0x%x->Master=%x\n",
3882 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
3883 /* Clear LASI interrupt */
3884 bnx2x_cl45_read(bp, params->port,
3888 MDIO_PMA_REG_LASI_STATUS, &val1);
3889 DP(NETIF_MSG_LINK, "8481 LASI status reg = 0x%x\n",
3892 /* Check 10G-BaseT link status */
3893 /* Check Global PMD signal ok */
3894 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3896 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
3898 /* Check PCS block lock */
3899 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3901 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
3903 DP(NETIF_MSG_LINK, "8481 1.a = 0x%x, 1.20 = 0x%x\n",
3905 if (rx_sd & pcs_status & 0x1) {
3906 vars->line_speed = SPEED_10000;
3907 ext_phy_link_up = 1;
3910 /* Check 1000-BaseT link status */
3911 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3913 MDIO_AN_DEVAD, 0xFFE1,
3916 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3918 MDIO_AN_DEVAD, 0xFFE1,
3920 DP(NETIF_MSG_LINK, "8481 7.FFE1 ="
3921 "0x%x-->0x%x\n", val1, val2);
3922 if (val2 & (1<<2)) {
3923 vars->line_speed = SPEED_1000;
3924 ext_phy_link_up = 1;
3930 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3931 params->ext_phy_config);
3932 ext_phy_link_up = 0;
3936 } else { /* SerDes */
3937 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3938 switch (ext_phy_type) {
3939 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3940 DP(NETIF_MSG_LINK, "SerDes Direct\n");
3941 ext_phy_link_up = 1;
3944 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3945 DP(NETIF_MSG_LINK, "SerDes 5482\n");
3946 ext_phy_link_up = 1;
3951 "BAD SerDes ext_phy_config 0x%x\n",
3952 params->ext_phy_config);
3953 ext_phy_link_up = 0;
3958 return ext_phy_link_up;
3961 static void bnx2x_link_int_enable(struct link_params *params)
3963 u8 port = params->port;
3966 struct bnx2x *bp = params->bp;
3967 /* setting the status to report on link up
3968 for either XGXS or SerDes */
3970 if (params->switch_cfg == SWITCH_CFG_10G) {
3971 mask = (NIG_MASK_XGXS0_LINK10G |
3972 NIG_MASK_XGXS0_LINK_STATUS);
3973 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
3974 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3975 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3976 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3978 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
3979 mask |= NIG_MASK_MI_INT;
3980 DP(NETIF_MSG_LINK, "enabled external phy int\n");
3983 } else { /* SerDes */
3984 mask = NIG_MASK_SERDES0_LINK_STATUS;
3985 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
3986 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3987 if ((ext_phy_type !=
3988 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
3990 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
3991 mask |= NIG_MASK_MI_INT;
3992 DP(NETIF_MSG_LINK, "enabled external phy int\n");
3996 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3998 DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
3999 (params->switch_cfg == SWITCH_CFG_10G),
4000 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4002 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
4003 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4004 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4005 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
4006 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4007 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4008 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4015 static void bnx2x_link_int_ack(struct link_params *params,
4016 struct link_vars *vars, u8 is_10g)
4018 struct bnx2x *bp = params->bp;
4019 u8 port = params->port;
4021 /* first reset all status
4022 * we assume only one line will be change at a time */
4023 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4024 (NIG_STATUS_XGXS0_LINK10G |
4025 NIG_STATUS_XGXS0_LINK_STATUS |
4026 NIG_STATUS_SERDES0_LINK_STATUS));
4027 if (vars->phy_link_up) {
4029 /* Disable the 10G link interrupt
4030 * by writing 1 to the status register
4032 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
4034 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4035 NIG_STATUS_XGXS0_LINK10G);
4037 } else if (params->switch_cfg == SWITCH_CFG_10G) {
4038 /* Disable the link interrupt
4039 * by writing 1 to the relevant lane
4040 * in the status register
4042 u32 ser_lane = ((params->lane_config &
4043 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4044 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4046 DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
4048 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4050 NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
4052 } else { /* SerDes */
4053 DP(NETIF_MSG_LINK, "SerDes phy link up\n");
4054 /* Disable the link interrupt
4055 * by writing 1 to the status register
4058 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4059 NIG_STATUS_SERDES0_LINK_STATUS);
4062 } else { /* link_down */
4066 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
4069 u32 mask = 0xf0000000;
4073 /* Need more than 10chars for this format */
4080 digit = ((num & mask) >> shift);
4082 *str_ptr = digit + '0';
4084 *str_ptr = digit - 0xa + 'a';
4097 static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
4102 /* Enable EMAC0 in to enable MDIO */
4103 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
4104 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
4107 /* take ext phy out of reset */
4109 MISC_REGISTERS_GPIO_2,
4110 MISC_REGISTERS_GPIO_HIGH,
4114 MISC_REGISTERS_GPIO_1,
4115 MISC_REGISTERS_GPIO_HIGH,
4121 for (cnt = 0; cnt < 1000; cnt++) {
4123 bnx2x_cl45_read(bp, port,
4129 if (!(ctrl & (1<<15))) {
4130 DP(NETIF_MSG_LINK, "Reset completed\n\n");
4136 static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
4138 /* put sf to reset */
4140 MISC_REGISTERS_GPIO_1,
4141 MISC_REGISTERS_GPIO_LOW,
4144 MISC_REGISTERS_GPIO_2,
4145 MISC_REGISTERS_GPIO_LOW,
4149 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
4150 u8 *version, u16 len)
4152 struct bnx2x *bp = params->bp;
4153 u32 ext_phy_type = 0;
4157 if (version == NULL || params == NULL)
4160 spirom_ver = REG_RD(bp, params->shmem_base +
4161 offsetof(struct shmem_region,
4162 port_mb[params->port].ext_phy_fw_version));
4164 /* reset the returned value to zero */
4165 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4166 switch (ext_phy_type) {
4167 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4172 version[0] = (spirom_ver & 0xFF);
4173 version[1] = (spirom_ver & 0xFF00) >> 8;
4174 version[2] = (spirom_ver & 0xFF0000) >> 16;
4175 version[3] = (spirom_ver & 0xFF000000) >> 24;
4179 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4180 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4181 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4182 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4183 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4184 status = bnx2x_format_ver(spirom_ver, version, len);
4186 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4189 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4190 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
4191 " type is FAILURE!\n");
4201 static void bnx2x_set_xgxs_loopback(struct link_params *params,
4202 struct link_vars *vars,
4205 u8 port = params->port;
4206 struct bnx2x *bp = params->bp;
4211 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
4213 /* change the uni_phy_addr in the nig */
4214 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
4217 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
4219 bnx2x_cl45_write(bp, port, 0,
4222 (MDIO_REG_BANK_AER_BLOCK +
4223 (MDIO_AER_BLOCK_AER_REG & 0xf)),
4226 bnx2x_cl45_write(bp, port, 0,
4229 (MDIO_REG_BANK_CL73_IEEEB0 +
4230 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
4233 /* set aer mmd back */
4234 bnx2x_set_aer_mmd(params, vars);
4237 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
4243 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
4245 CL45_RD_OVER_CL22(bp, port,
4247 MDIO_REG_BANK_COMBO_IEEE0,
4248 MDIO_COMBO_IEEE0_MII_CONTROL,
4251 CL45_WR_OVER_CL22(bp, port,
4253 MDIO_REG_BANK_COMBO_IEEE0,
4254 MDIO_COMBO_IEEE0_MII_CONTROL,
4256 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
4261 static void bnx2x_ext_phy_loopback(struct link_params *params)
4263 struct bnx2x *bp = params->bp;
4267 if (params->switch_cfg == SWITCH_CFG_10G) {
4268 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4269 /* CL37 Autoneg Enabled */
4270 ext_phy_addr = ((params->ext_phy_config &
4271 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4272 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4273 switch (ext_phy_type) {
4274 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4275 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4277 "ext_phy_loopback: We should not get here\n");
4279 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4280 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
4282 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4283 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
4285 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4286 DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
4287 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4293 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4294 /* SFX7101_XGXS_TEST1 */
4295 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4298 MDIO_XS_SFX7101_XGXS_TEST1,
4301 "ext_phy_loopback: set ext phy loopback\n");
4303 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4306 } /* switch external PHY type */
4309 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4310 ext_phy_addr = (params->ext_phy_config &
4311 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
4312 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
4318 *------------------------------------------------------------------------
4319 * bnx2x_override_led_value -
4321 * Override the led value of the requsted led
4323 *------------------------------------------------------------------------
4325 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
4326 u32 led_idx, u32 value)
4330 /* If port 0 then use EMAC0, else use EMAC1*/
4331 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4334 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
4335 port, led_idx, value);
4338 case 0: /* 10MB led */
4339 /* Read the current value of the LED register in
4341 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4342 /* Set the OVERRIDE bit to 1 */
4343 reg_val |= EMAC_LED_OVERRIDE;
4344 /* If value is 1, set the 10M_OVERRIDE bit,
4345 otherwise reset it.*/
4346 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
4347 (reg_val & ~EMAC_LED_10MB_OVERRIDE);
4348 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4350 case 1: /*100MB led */
4351 /*Read the current value of the LED register in
4353 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4354 /* Set the OVERRIDE bit to 1 */
4355 reg_val |= EMAC_LED_OVERRIDE;
4356 /* If value is 1, set the 100M_OVERRIDE bit,
4357 otherwise reset it.*/
4358 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
4359 (reg_val & ~EMAC_LED_100MB_OVERRIDE);
4360 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4362 case 2: /* 1000MB led */
4363 /* Read the current value of the LED register in the
4365 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4366 /* Set the OVERRIDE bit to 1 */
4367 reg_val |= EMAC_LED_OVERRIDE;
4368 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
4370 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
4371 (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
4372 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4374 case 3: /* 2500MB led */
4375 /* Read the current value of the LED register in the
4377 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4378 /* Set the OVERRIDE bit to 1 */
4379 reg_val |= EMAC_LED_OVERRIDE;
4380 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
4382 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
4383 (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
4384 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4386 case 4: /*10G led */
4388 REG_WR(bp, NIG_REG_LED_10G_P0,
4391 REG_WR(bp, NIG_REG_LED_10G_P1,
4395 case 5: /* TRAFFIC led */
4396 /* Find if the traffic control is via BMAC or EMAC */
4398 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
4400 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
4402 /* Override the traffic led in the EMAC:*/
4404 /* Read the current value of the LED register in
4406 reg_val = REG_RD(bp, emac_base +
4408 /* Set the TRAFFIC_OVERRIDE bit to 1 */
4409 reg_val |= EMAC_LED_OVERRIDE;
4410 /* If value is 1, set the TRAFFIC bit, otherwise
4412 reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
4413 (reg_val & ~EMAC_LED_TRAFFIC);
4414 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4415 } else { /* Override the traffic led in the BMAC: */
4416 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4418 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
4424 "bnx2x_override_led_value() unknown led index %d "
4425 "(should be 0-5)\n", led_idx);
4433 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
4434 u16 hw_led_mode, u32 chip_id)
4438 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4439 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
4440 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
4441 speed, hw_led_mode);
4444 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
4445 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
4446 SHARED_HW_CFG_LED_MAC1);
4448 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4449 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
4453 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
4454 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
4456 /* Set blinking rate to ~15.9Hz */
4457 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
4458 LED_BLINK_RATE_VAL);
4459 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
4461 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4462 EMAC_WR(bp, EMAC_REG_EMAC_LED,
4463 (tmp & (~EMAC_LED_OVERRIDE)));
4465 if (!CHIP_IS_E1H(bp) &&
4466 ((speed == SPEED_2500) ||
4467 (speed == SPEED_1000) ||
4468 (speed == SPEED_100) ||
4469 (speed == SPEED_10))) {
4470 /* On Everest 1 Ax chip versions for speeds less than
4471 10G LED scheme is different */
4472 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4474 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
4476 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
4483 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
4491 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
4493 struct bnx2x *bp = params->bp;
4496 CL45_RD_OVER_CL22(bp, params->port,
4498 MDIO_REG_BANK_GP_STATUS,
4499 MDIO_GP_STATUS_TOP_AN_STATUS1,
4501 /* link is up only if both local phy and external phy are up */
4502 if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
4503 bnx2x_ext_phy_is_link_up(params, vars))
4509 static u8 bnx2x_link_initialize(struct link_params *params,
4510 struct link_vars *vars)
4512 struct bnx2x *bp = params->bp;
4513 u8 port = params->port;
4516 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4517 /* Activate the external PHY */
4518 bnx2x_ext_phy_reset(params, vars);
4520 bnx2x_set_aer_mmd(params, vars);
4522 if (vars->phy_flags & PHY_XGXS_FLAG)
4523 bnx2x_set_master_ln(params);
4525 rc = bnx2x_reset_unicore(params);
4526 /* reset the SerDes and wait for reset bit return low */
4530 bnx2x_set_aer_mmd(params, vars);
4532 /* setting the masterLn_def again after the reset */
4533 if (vars->phy_flags & PHY_XGXS_FLAG) {
4534 bnx2x_set_master_ln(params);
4535 bnx2x_set_swap_lanes(params);
4538 if (vars->phy_flags & PHY_XGXS_FLAG) {
4539 if ((params->req_line_speed &&
4540 ((params->req_line_speed == SPEED_100) ||
4541 (params->req_line_speed == SPEED_10))) ||
4542 (!params->req_line_speed &&
4543 (params->speed_cap_mask >=
4544 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
4545 (params->speed_cap_mask <
4546 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4548 vars->phy_flags |= PHY_SGMII_FLAG;
4550 vars->phy_flags &= ~PHY_SGMII_FLAG;
4553 /* In case of external phy existance, the line speed would be the
4554 line speed linked up by the external phy. In case it is direct only,
4555 then the line_speed during initialization will be equal to the
4557 vars->line_speed = params->req_line_speed;
4559 bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
4561 /* init ext phy and enable link state int */
4562 non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
4563 (params->loopback_mode == LOOPBACK_XGXS_10) ||
4564 (params->loopback_mode == LOOPBACK_EXT_PHY));
4567 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
4568 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
4569 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481)) {
4570 if (params->req_line_speed == SPEED_AUTO_NEG)
4571 bnx2x_set_parallel_detection(params, vars->phy_flags);
4572 bnx2x_init_internal_phy(params, vars);
4576 rc |= bnx2x_ext_phy_init(params, vars);
4578 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4579 (NIG_STATUS_XGXS0_LINK10G |
4580 NIG_STATUS_XGXS0_LINK_STATUS |
4581 NIG_STATUS_SERDES0_LINK_STATUS));
4588 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
4590 struct bnx2x *bp = params->bp;
4593 DP(NETIF_MSG_LINK, "Phy Initialization started \n");
4594 DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
4595 params->req_line_speed, params->req_flow_ctrl);
4596 vars->link_status = 0;
4597 vars->phy_link_up = 0;
4599 vars->line_speed = 0;
4600 vars->duplex = DUPLEX_FULL;
4601 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4602 vars->mac_type = MAC_TYPE_NONE;
4604 if (params->switch_cfg == SWITCH_CFG_1G)
4605 vars->phy_flags = PHY_SERDES_FLAG;
4607 vars->phy_flags = PHY_XGXS_FLAG;
4610 /* disable attentions */
4611 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
4612 (NIG_MASK_XGXS0_LINK_STATUS |
4613 NIG_MASK_XGXS0_LINK10G |
4614 NIG_MASK_SERDES0_LINK_STATUS |
4617 bnx2x_emac_init(params, vars);
4619 if (CHIP_REV_IS_FPGA(bp)) {
4621 vars->line_speed = SPEED_10000;
4622 vars->duplex = DUPLEX_FULL;
4623 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4624 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
4625 /* enable on E1.5 FPGA */
4626 if (CHIP_IS_E1H(bp)) {
4628 (BNX2X_FLOW_CTRL_TX | BNX2X_FLOW_CTRL_RX);
4629 vars->link_status |=
4630 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
4631 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
4634 bnx2x_emac_enable(params, vars, 0);
4635 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4637 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4638 + params->port*4, 0);
4640 /* update shared memory */
4641 bnx2x_update_mng(params, vars->link_status);
4646 if (CHIP_REV_IS_EMUL(bp)) {
4649 vars->line_speed = SPEED_10000;
4650 vars->duplex = DUPLEX_FULL;
4651 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4652 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
4654 bnx2x_bmac_enable(params, vars, 0);
4656 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4658 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4659 + params->port*4, 0);
4661 /* update shared memory */
4662 bnx2x_update_mng(params, vars->link_status);
4667 if (params->loopback_mode == LOOPBACK_BMAC) {
4669 vars->line_speed = SPEED_10000;
4670 vars->duplex = DUPLEX_FULL;
4671 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4672 vars->mac_type = MAC_TYPE_BMAC;
4674 vars->phy_flags = PHY_XGXS_FLAG;
4676 bnx2x_phy_deassert(params, vars->phy_flags);
4677 /* set bmac loopback */
4678 bnx2x_bmac_enable(params, vars, 1);
4680 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4682 } else if (params->loopback_mode == LOOPBACK_EMAC) {
4684 vars->line_speed = SPEED_1000;
4685 vars->duplex = DUPLEX_FULL;
4686 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4687 vars->mac_type = MAC_TYPE_EMAC;
4689 vars->phy_flags = PHY_XGXS_FLAG;
4691 bnx2x_phy_deassert(params, vars->phy_flags);
4692 /* set bmac loopback */
4693 bnx2x_emac_enable(params, vars, 1);
4694 bnx2x_emac_program(params, vars->line_speed,
4696 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4698 } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
4699 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
4701 vars->line_speed = SPEED_10000;
4702 vars->duplex = DUPLEX_FULL;
4703 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4705 vars->phy_flags = PHY_XGXS_FLAG;
4708 NIG_REG_XGXS0_CTRL_PHY_ADDR+
4710 params->phy_addr = (u8)val;
4712 bnx2x_phy_deassert(params, vars->phy_flags);
4713 bnx2x_link_initialize(params, vars);
4715 vars->mac_type = MAC_TYPE_BMAC;
4717 bnx2x_bmac_enable(params, vars, 0);
4719 if (params->loopback_mode == LOOPBACK_XGXS_10) {
4720 /* set 10G XGXS loopback */
4721 bnx2x_set_xgxs_loopback(params, vars, 1);
4723 /* set external phy loopback */
4724 bnx2x_ext_phy_loopback(params);
4726 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4732 bnx2x_phy_deassert(params, vars->phy_flags);
4733 switch (params->switch_cfg) {
4735 vars->phy_flags |= PHY_SERDES_FLAG;
4736 if ((params->ext_phy_config &
4737 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
4738 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
4744 NIG_REG_SERDES0_CTRL_PHY_ADDR+
4747 params->phy_addr = (u8)val;
4750 case SWITCH_CFG_10G:
4751 vars->phy_flags |= PHY_XGXS_FLAG;
4753 NIG_REG_XGXS0_CTRL_PHY_ADDR+
4755 params->phy_addr = (u8)val;
4759 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
4764 bnx2x_link_initialize(params, vars);
4766 bnx2x_link_int_enable(params);
4771 static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
4773 DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
4775 /* Set serial boot control for external load */
4776 bnx2x_cl45_write(bp, port,
4777 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
4779 MDIO_PMA_REG_GEN_CTRL, 0x0001);
4781 /* Disable Transmitter */
4782 bnx2x_bcm8726_set_transmitter(bp, port, ext_phy_addr, 0);
4786 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
4790 struct bnx2x *bp = params->bp;
4791 u32 ext_phy_config = params->ext_phy_config;
4792 u16 hw_led_mode = params->hw_led_mode;
4793 u32 chip_id = params->chip_id;
4794 u8 port = params->port;
4795 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4796 /* disable attentions */
4798 vars->link_status = 0;
4799 bnx2x_update_mng(params, vars->link_status);
4800 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4801 (NIG_MASK_XGXS0_LINK_STATUS |
4802 NIG_MASK_XGXS0_LINK10G |
4803 NIG_MASK_SERDES0_LINK_STATUS |
4806 /* activate nig drain */
4807 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4809 /* disable nig egress interface */
4810 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4811 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4813 /* Stop BigMac rx */
4814 bnx2x_bmac_rx_disable(bp, port);
4817 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4820 /* The PHY reset is controled by GPIO 1
4821 * Hold it as vars low
4823 /* clear link led */
4824 bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4825 if (reset_ext_phy) {
4826 switch (ext_phy_type) {
4827 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4828 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4830 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4831 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4834 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4835 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4838 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4840 u8 ext_phy_addr = ((params->ext_phy_config &
4841 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4842 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4843 /* Set soft reset */
4844 bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
4849 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4850 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4852 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4853 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4855 DP(NETIF_MSG_LINK, "reset external PHY\n");
4858 /* reset the SerDes/XGXS */
4859 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4860 (0x1ff << (port*16)));
4863 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4864 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4866 /* disable nig ingress interface */
4867 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4868 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4869 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4870 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4875 static u8 bnx2x_update_link_down(struct link_params *params,
4876 struct link_vars *vars)
4878 struct bnx2x *bp = params->bp;
4879 u8 port = params->port;
4880 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4881 bnx2x_set_led(bp, port, LED_MODE_OFF,
4882 0, params->hw_led_mode,
4885 /* indicate no mac active */
4886 vars->mac_type = MAC_TYPE_NONE;
4888 /* update shared memory */
4889 vars->link_status = 0;
4890 vars->line_speed = 0;
4891 bnx2x_update_mng(params, vars->link_status);
4893 /* activate nig drain */
4894 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4897 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4902 bnx2x_bmac_rx_disable(bp, params->port);
4903 REG_WR(bp, GRCBASE_MISC +
4904 MISC_REGISTERS_RESET_REG_2_CLEAR,
4905 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4909 static u8 bnx2x_update_link_up(struct link_params *params,
4910 struct link_vars *vars,
4911 u8 link_10g, u32 gp_status)
4913 struct bnx2x *bp = params->bp;
4914 u8 port = params->port;
4916 vars->link_status |= LINK_STATUS_LINK_UP;
4918 bnx2x_bmac_enable(params, vars, 0);
4919 bnx2x_set_led(bp, port, LED_MODE_OPER,
4920 SPEED_10000, params->hw_led_mode,
4924 bnx2x_emac_enable(params, vars, 0);
4925 rc = bnx2x_emac_program(params, vars->line_speed,
4929 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4930 if (!(vars->phy_flags &
4932 bnx2x_set_gmii_tx_driver(params);
4937 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4941 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4943 /* update shared memory */
4944 bnx2x_update_mng(params, vars->link_status);
4948 /* This function should called upon link interrupt */
4949 /* In case vars->link_up, driver needs to
4952 3. Update the shared memory
4956 1. Update shared memory
4961 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4963 struct bnx2x *bp = params->bp;
4964 u8 port = params->port;
4967 u8 ext_phy_link_up, rc = 0;
4970 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
4972 (vars->phy_flags & PHY_XGXS_FLAG),
4973 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4975 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4976 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4977 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4978 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
4980 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4981 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4982 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4985 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4987 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4989 /* Check external link change only for non-direct */
4990 ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
4992 /* Read gp_status */
4993 CL45_RD_OVER_CL22(bp, port, params->phy_addr,
4994 MDIO_REG_BANK_GP_STATUS,
4995 MDIO_GP_STATUS_TOP_AN_STATUS1,
4998 rc = bnx2x_link_settings_status(params, vars, gp_status);
5002 /* anything 10 and over uses the bmac */
5003 link_10g = ((vars->line_speed == SPEED_10000) ||
5004 (vars->line_speed == SPEED_12000) ||
5005 (vars->line_speed == SPEED_12500) ||
5006 (vars->line_speed == SPEED_13000) ||
5007 (vars->line_speed == SPEED_15000) ||
5008 (vars->line_speed == SPEED_16000));
5010 bnx2x_link_int_ack(params, vars, link_10g);
5012 /* In case external phy link is up, and internal link is down
5013 ( not initialized yet probably after link initialization, it needs
5015 Note that after link down-up as result of cable plug,
5016 the xgxs link would probably become up again without the need to
5019 if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
5020 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
5021 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
5022 (ext_phy_link_up && !vars->phy_link_up))
5023 bnx2x_init_internal_phy(params, vars);
5025 /* link is up only if both local phy and external phy are up */
5026 vars->link_up = (ext_phy_link_up && vars->phy_link_up);
5029 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
5031 rc = bnx2x_update_link_down(params, vars);
5036 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5038 u8 ext_phy_addr[PORT_MAX];
5042 /* PART1 - Reset both phys */
5043 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5044 /* Extract the ext phy address for the port */
5045 u32 ext_phy_config = REG_RD(bp, shmem_base +
5046 offsetof(struct shmem_region,
5047 dev_info.port_hw_config[port].external_phy_config));
5049 /* disable attentions */
5050 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5051 (NIG_MASK_XGXS0_LINK_STATUS |
5052 NIG_MASK_XGXS0_LINK10G |
5053 NIG_MASK_SERDES0_LINK_STATUS |
5056 ext_phy_addr[port] =
5058 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5059 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5061 /* Need to take the phy out of low power mode in order
5062 to write to access its registers */
5063 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5064 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
5067 bnx2x_cl45_write(bp, port,
5068 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5075 /* Add delay of 150ms after reset */
5078 /* PART2 - Download firmware to both phys */
5079 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5082 bnx2x_bcm8073_external_rom_boot(bp, port,
5083 ext_phy_addr[port], shmem_base);
5085 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5088 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
5089 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
5091 "bnx2x_8073_common_init_phy port %x:"
5092 "Download failed. fw version = 0x%x\n",
5097 /* Only set bit 10 = 1 (Tx power down) */
5098 bnx2x_cl45_read(bp, port,
5099 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5102 MDIO_PMA_REG_TX_POWER_DOWN, &val);
5104 /* Phase1 of TX_POWER_DOWN reset */
5105 bnx2x_cl45_write(bp, port,
5106 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5109 MDIO_PMA_REG_TX_POWER_DOWN,
5113 /* Toggle Transmitter: Power down and then up with 600ms
5117 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
5118 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5119 /* Phase2 of POWER_DOWN_RESET*/
5120 /* Release bit 10 (Release Tx power down) */
5121 bnx2x_cl45_read(bp, port,
5122 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5125 MDIO_PMA_REG_TX_POWER_DOWN, &val);
5127 bnx2x_cl45_write(bp, port,
5128 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5131 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
5134 /* Read modify write the SPI-ROM version select register */
5135 bnx2x_cl45_read(bp, port,
5136 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5139 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
5140 bnx2x_cl45_write(bp, port,
5141 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5144 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
5146 /* set GPIO2 back to LOW */
5147 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5148 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
5155 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5160 /* Use port1 because of the static port-swap */
5161 /* Enable the module detection interrupt */
5162 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
5163 val |= ((1<<MISC_REGISTERS_GPIO_3)|
5164 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
5165 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
5167 bnx2x_hw_reset(bp, 1);
5169 for (port = 0; port < PORT_MAX; port++) {
5170 /* Extract the ext phy address for the port */
5171 u32 ext_phy_config = REG_RD(bp, shmem_base +
5172 offsetof(struct shmem_region,
5173 dev_info.port_hw_config[port].external_phy_config));
5177 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5178 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5179 DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
5182 bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
5184 /* Set fault module detected LED on */
5185 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5186 MISC_REGISTERS_GPIO_HIGH,
5193 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5198 DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n");
5200 /* Read the ext_phy_type for arbitrary port(0) */
5201 ext_phy_type = XGXS_EXT_PHY_TYPE(
5202 REG_RD(bp, shmem_base +
5203 offsetof(struct shmem_region,
5204 dev_info.port_hw_config[0].external_phy_config)));
5206 switch (ext_phy_type) {
5207 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5209 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
5212 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5213 /* GPIO1 affects both ports, so there's need to pull
5214 it for single port alone */
5215 rc = bnx2x_8726_common_init_phy(bp, shmem_base);
5220 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
5230 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
5234 bnx2x_cl45_read(bp, port,
5235 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5238 MDIO_PMA_REG_7101_RESET, &val);
5240 for (cnt = 0; cnt < 10; cnt++) {
5242 /* Writes a self-clearing reset */
5243 bnx2x_cl45_write(bp, port,
5244 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5247 MDIO_PMA_REG_7101_RESET,
5249 /* Wait for clear */
5250 bnx2x_cl45_read(bp, port,
5251 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5254 MDIO_PMA_REG_7101_RESET, &val);
5256 if ((val & (1<<15)) == 0)
5260 #define RESERVED_SIZE 256
5261 /* max application is 160K bytes - data at end of RAM */
5262 #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
5264 /* Header is 14 bytes */
5265 #define HEADER_SIZE 14
5266 #define DATA_OFFSET HEADER_SIZE
5268 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
5269 bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
5272 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
5274 /* Programs an image to DSP's flash via the SPI port*/
5275 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
5277 char data[], u32 size)
5279 const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
5280 /* Doesn't include last trans!*/
5281 const u16 last_trans_size = size%4; /* Num bytes on last trans */
5282 u16 trans_cnt, byte_cnt;
5285 u16 code_started = 0;
5286 u16 image_revision1, image_revision2;
5289 DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
5291 if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
5292 /* This very often will be the case, because the image is built
5293 with 160Kbytes size whereas the total image size must actually
5294 be 160Kbytes-RESERVED_SIZE */
5295 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
5296 "truncated to %d bytes\n", size, MAX_APP_SIZE);
5297 size = MAX_APP_SIZE+HEADER_SIZE;
5299 DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
5300 DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]);
5301 /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
5302 and issuing a reset.*/
5304 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5305 MISC_REGISTERS_GPIO_HIGH, port);
5307 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
5310 for (cnt = 0; cnt < 100; cnt++)
5313 /* Make sure we can access the DSP
5314 And it's in the correct mode (waiting for download) */
5316 bnx2x_cl45_read(bp, port,
5317 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5320 MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
5322 if (tmp != 0x000A) {
5323 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
5324 "Expected 0x000A, read 0x%04X\n", tmp);
5325 DP(NETIF_MSG_LINK, "Download failed\n");
5329 /* Mux the SPI interface away from the internal processor */
5330 bnx2x_cl45_write(bp, port,
5331 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5334 MDIO_PCS_REG_7101_SPI_MUX, 1);
5336 /* Reset the SPI port */
5337 bnx2x_cl45_write(bp, port,
5338 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5341 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
5342 bnx2x_cl45_write(bp, port,
5343 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5346 MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
5347 (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
5348 bnx2x_cl45_write(bp, port,
5349 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5352 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
5354 /* Erase the flash */
5355 bnx2x_cl45_write(bp, port,
5356 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5359 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5360 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5362 bnx2x_cl45_write(bp, port,
5363 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5366 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5369 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5370 bnx2x_cl45_write(bp, port,
5371 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5374 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5375 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
5377 bnx2x_cl45_write(bp, port,
5378 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5381 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5383 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5385 /* Wait 10 seconds, the maximum time for the erase to complete */
5386 DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
5387 for (cnt = 0; cnt < 1000; cnt++)
5390 DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
5392 for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
5393 bnx2x_cl45_write(bp, port,
5394 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5397 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5398 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5400 bnx2x_cl45_write(bp, port,
5401 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5404 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5406 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5408 bnx2x_cl45_write(bp, port,
5409 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5412 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5413 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
5415 /* Bits 23-16 of address */
5416 bnx2x_cl45_write(bp, port,
5417 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5420 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5422 /* Bits 15-8 of address */
5423 bnx2x_cl45_write(bp, port,
5424 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5427 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5430 /* Bits 7-0 of address */
5431 bnx2x_cl45_write(bp, port,
5432 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5435 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5439 while (byte_cnt < 4 && data_index < size) {
5440 bnx2x_cl45_write(bp, port,
5441 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5444 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5445 data[data_index++]);
5449 bnx2x_cl45_write(bp, port,
5450 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5453 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5456 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5457 msleep(5); /* Wait 5 ms minimum between transs */
5459 /* Let the user know something's going on.*/
5460 /* a pacifier ever 4K */
5461 if ((data_index % 1023) == 0)
5462 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
5465 DP(NETIF_MSG_LINK, "\n");
5466 /* Transfer the last block if there is data remaining */
5467 if (last_trans_size) {
5468 bnx2x_cl45_write(bp, port,
5469 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5472 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5473 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5475 bnx2x_cl45_write(bp, port,
5476 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5479 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5482 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5484 bnx2x_cl45_write(bp, port,
5485 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5488 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5489 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
5491 /* Bits 23-16 of address */
5492 bnx2x_cl45_write(bp, port,
5493 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5496 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5498 /* Bits 15-8 of address */
5499 bnx2x_cl45_write(bp, port,
5500 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5503 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5506 /* Bits 7-0 of address */
5507 bnx2x_cl45_write(bp, port,
5508 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5511 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5515 while (byte_cnt < last_trans_size && data_index < size) {
5516 /* Bits 7-0 of address */
5517 bnx2x_cl45_write(bp, port,
5518 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5521 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5522 data[data_index++]);
5526 bnx2x_cl45_write(bp, port,
5527 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5530 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5533 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5536 /* DSP Remove Download Mode */
5537 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5538 MISC_REGISTERS_GPIO_LOW, port);
5540 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
5542 /* wait 0.5 sec to allow it to run */
5543 for (cnt = 0; cnt < 100; cnt++)
5546 bnx2x_hw_reset(bp, port);
5548 for (cnt = 0; cnt < 100; cnt++)
5551 /* Check that the code is started. In case the download
5552 checksum failed, the code won't be started. */
5553 bnx2x_cl45_read(bp, port,
5554 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5557 MDIO_PCS_REG_7101_DSP_ACCESS,
5560 code_started = (tmp & (1<<4));
5561 if (!code_started) {
5562 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
5566 /* Verify that the file revision is now equal to the image
5567 revision within the DSP */
5568 bnx2x_cl45_read(bp, port,
5569 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5572 MDIO_PMA_REG_7101_VER1,
5575 bnx2x_cl45_read(bp, port,
5576 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5579 MDIO_PMA_REG_7101_VER2,
5582 if (data[0x14e] != (image_revision2&0xFF) ||
5583 data[0x14f] != ((image_revision2&0xFF00)>>8) ||
5584 data[0x150] != (image_revision1&0xFF) ||
5585 data[0x151] != ((image_revision1&0xFF00)>>8)) {
5586 DP(NETIF_MSG_LINK, "Download failed.\n");
5589 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
5593 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
5594 u8 driver_loaded, char data[], u32 size)
5599 ext_phy_addr = ((ext_phy_config &
5600 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5601 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5603 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
5605 switch (ext_phy_type) {
5606 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5607 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5608 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5609 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5611 "Flash download not supported for this ext phy\n");
5614 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5615 /* Take ext phy out of reset */
5617 bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
5618 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
5621 bnx2x_turn_off_sf(bp, port);
5623 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5624 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
5625 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
5627 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");