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>
27 /********************************************************/
29 #define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
30 #define ETH_MIN_PACKET_SIZE 60
31 #define ETH_MAX_PACKET_SIZE 1500
32 #define ETH_MAX_JUMBO_PACKET_SIZE 9600
33 #define MDIO_ACCESS_TIMEOUT 1000
34 #define BMAC_CONTROL_RX_ENABLE 2
36 /***********************************************************/
37 /* Shortcut definitions */
38 /***********************************************************/
40 #define NIG_STATUS_XGXS0_LINK10G \
41 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
42 #define NIG_STATUS_XGXS0_LINK_STATUS \
43 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
44 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
45 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
46 #define NIG_STATUS_SERDES0_LINK_STATUS \
47 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
48 #define NIG_MASK_MI_INT \
49 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
50 #define NIG_MASK_XGXS0_LINK10G \
51 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
52 #define NIG_MASK_XGXS0_LINK_STATUS \
53 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
54 #define NIG_MASK_SERDES0_LINK_STATUS \
55 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
57 #define MDIO_AN_CL73_OR_37_COMPLETE \
58 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
59 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
61 #define XGXS_RESET_BITS \
62 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
63 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
64 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
65 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
66 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
68 #define SERDES_RESET_BITS \
69 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
70 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
71 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
72 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
74 #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
75 #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
76 #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
77 #define AUTONEG_PARALLEL \
78 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
79 #define AUTONEG_SGMII_FIBER_AUTODET \
80 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
81 #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
83 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
84 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
85 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
86 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
87 #define GP_STATUS_SPEED_MASK \
88 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
89 #define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
90 #define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
91 #define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
92 #define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
93 #define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
94 #define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
95 #define GP_STATUS_10G_HIG \
96 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
97 #define GP_STATUS_10G_CX4 \
98 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
99 #define GP_STATUS_12G_HIG \
100 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
101 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
102 #define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
103 #define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
104 #define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
105 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
106 #define GP_STATUS_10G_KX4 \
107 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
109 #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
110 #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
111 #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
112 #define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
113 #define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
114 #define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
115 #define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
116 #define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
117 #define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
118 #define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
119 #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
120 #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
121 #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
122 #define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
123 #define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
124 #define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
125 #define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
126 #define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
127 #define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
128 #define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
129 #define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
130 #define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
131 #define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
133 #define PHY_XGXS_FLAG 0x1
134 #define PHY_SGMII_FLAG 0x2
135 #define PHY_SERDES_FLAG 0x4
138 #define SFP_EEPROM_CON_TYPE_ADDR 0x2
139 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
140 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
143 #define SFP_EEPROM_COMP_CODE_ADDR 0x3
144 #define SFP_EEPROM_COMP_CODE_SR_MASK (1<<4)
145 #define SFP_EEPROM_COMP_CODE_LR_MASK (1<<5)
146 #define SFP_EEPROM_COMP_CODE_LRM_MASK (1<<6)
148 #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
149 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
150 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
152 #define SFP_EEPROM_OPTIONS_ADDR 0x40
153 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
154 #define SFP_EEPROM_OPTIONS_SIZE 2
156 #define EDC_MODE_LINEAR 0x0022
157 #define EDC_MODE_LIMITING 0x0044
158 #define EDC_MODE_PASSIVE_DAC 0x0055
162 /**********************************************************/
164 /**********************************************************/
165 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
166 bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
167 DEFAULT_PHY_DEV_ADDR, \
168 (_bank + (_addr & 0xf)), \
171 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
172 bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
173 DEFAULT_PHY_DEV_ADDR, \
174 (_bank + (_addr & 0xf)), \
177 static void bnx2x_set_serdes_access(struct link_params *params)
179 struct bnx2x *bp = params->bp;
180 u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
182 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1);
183 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
185 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
188 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 0);
190 static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags)
192 struct bnx2x *bp = params->bp;
193 if (phy_flags & PHY_XGXS_FLAG) {
194 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
195 params->port*0x18, 0);
196 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
197 DEFAULT_PHY_DEV_ADDR);
199 bnx2x_set_serdes_access(params);
201 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
203 DEFAULT_PHY_DEV_ADDR);
207 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
209 u32 val = REG_RD(bp, reg);
212 REG_WR(bp, reg, val);
216 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
218 u32 val = REG_RD(bp, reg);
221 REG_WR(bp, reg, val);
225 static void bnx2x_emac_init(struct link_params *params,
226 struct link_vars *vars)
228 /* reset and unreset the emac core */
229 struct bnx2x *bp = params->bp;
230 u8 port = params->port;
231 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
235 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
236 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
238 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
239 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
241 /* init emac - use read-modify-write */
242 /* self clear reset */
243 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
244 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
248 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
249 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
251 DP(NETIF_MSG_LINK, "EMAC timeout!\n");
255 } while (val & EMAC_MODE_RESET);
257 /* Set mac address */
258 val = ((params->mac_addr[0] << 8) |
259 params->mac_addr[1]);
260 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
262 val = ((params->mac_addr[2] << 24) |
263 (params->mac_addr[3] << 16) |
264 (params->mac_addr[4] << 8) |
265 params->mac_addr[5]);
266 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
269 static u8 bnx2x_emac_enable(struct link_params *params,
270 struct link_vars *vars, u8 lb)
272 struct bnx2x *bp = params->bp;
273 u8 port = params->port;
274 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
277 DP(NETIF_MSG_LINK, "enabling EMAC\n");
279 /* enable emac and not bmac */
280 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
283 if (CHIP_REV_IS_EMUL(bp)) {
284 /* Use lane 1 (of lanes 0-3) */
285 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
286 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
292 if (CHIP_REV_IS_FPGA(bp)) {
293 /* Use lane 1 (of lanes 0-3) */
294 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
296 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
297 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
301 if (vars->phy_flags & PHY_XGXS_FLAG) {
302 u32 ser_lane = ((params->lane_config &
303 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
304 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
306 DP(NETIF_MSG_LINK, "XGXS\n");
307 /* select the master lanes (out of 0-3) */
308 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
311 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
314 } else { /* SerDes */
315 DP(NETIF_MSG_LINK, "SerDes\n");
317 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
321 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
323 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
326 if (CHIP_REV_IS_SLOW(bp)) {
327 /* config GMII mode */
328 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
329 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
330 (val | EMAC_MODE_PORT_GMII));
332 /* pause enable/disable */
333 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
334 EMAC_RX_MODE_FLOW_EN);
335 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
336 bnx2x_bits_en(bp, emac_base +
337 EMAC_REG_EMAC_RX_MODE,
338 EMAC_RX_MODE_FLOW_EN);
340 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
341 (EMAC_TX_MODE_EXT_PAUSE_EN |
342 EMAC_TX_MODE_FLOW_EN));
343 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
344 bnx2x_bits_en(bp, emac_base +
345 EMAC_REG_EMAC_TX_MODE,
346 (EMAC_TX_MODE_EXT_PAUSE_EN |
347 EMAC_TX_MODE_FLOW_EN));
350 /* KEEP_VLAN_TAG, promiscuous */
351 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
352 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
353 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
356 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
361 EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
364 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
366 /* enable emac for jumbo packets */
367 EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
368 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
369 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
372 REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
374 /* disable the NIG in/out to the bmac */
375 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
376 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
377 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
379 /* enable the NIG in/out to the emac */
380 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
382 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
385 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
386 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
388 if (CHIP_REV_IS_EMUL(bp)) {
389 /* take the BigMac out of reset */
391 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
392 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
394 /* enable access for bmac registers */
395 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
398 vars->mac_type = MAC_TYPE_EMAC;
404 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
407 struct bnx2x *bp = params->bp;
408 u8 port = params->port;
409 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
410 NIG_REG_INGRESS_BMAC0_MEM;
414 DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
415 /* reset and unreset the BigMac */
416 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
417 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
420 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
421 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
423 /* enable access for bmac registers */
424 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
429 REG_WR_DMAE(bp, bmac_addr +
430 BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
434 wb_data[0] = ((params->mac_addr[2] << 24) |
435 (params->mac_addr[3] << 16) |
436 (params->mac_addr[4] << 8) |
437 params->mac_addr[5]);
438 wb_data[1] = ((params->mac_addr[0] << 8) |
439 params->mac_addr[1]);
440 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
445 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
449 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
456 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
460 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
465 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
467 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
470 /* rx control set to don't strip crc */
472 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
476 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
480 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
482 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
485 /* set cnt max size */
486 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
488 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
492 wb_data[0] = 0x1000200;
494 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
496 /* fix for emulation */
497 if (CHIP_REV_IS_EMUL(bp)) {
501 bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
505 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
506 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
507 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
509 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
511 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
512 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
513 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
514 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
515 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
516 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
518 vars->mac_type = MAC_TYPE_BMAC;
522 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
524 struct bnx2x *bp = params->bp;
527 if (phy_flags & PHY_XGXS_FLAG) {
528 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
529 val = XGXS_RESET_BITS;
531 } else { /* SerDes */
532 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
533 val = SERDES_RESET_BITS;
536 val = val << (params->port*16);
538 /* reset and unreset the SerDes/XGXS */
539 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
542 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
544 bnx2x_set_phy_mdio(params, phy_flags);
547 void bnx2x_link_status_update(struct link_params *params,
548 struct link_vars *vars)
550 struct bnx2x *bp = params->bp;
552 u8 port = params->port;
554 if (params->switch_cfg == SWITCH_CFG_1G)
555 vars->phy_flags = PHY_SERDES_FLAG;
557 vars->phy_flags = PHY_XGXS_FLAG;
558 vars->link_status = REG_RD(bp, params->shmem_base +
559 offsetof(struct shmem_region,
560 port_mb[port].link_status));
562 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
565 DP(NETIF_MSG_LINK, "phy link up\n");
567 vars->phy_link_up = 1;
568 vars->duplex = DUPLEX_FULL;
569 switch (vars->link_status &
570 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
572 vars->duplex = DUPLEX_HALF;
575 vars->line_speed = SPEED_10;
579 vars->duplex = DUPLEX_HALF;
583 vars->line_speed = SPEED_100;
587 vars->duplex = DUPLEX_HALF;
590 vars->line_speed = SPEED_1000;
594 vars->duplex = DUPLEX_HALF;
597 vars->line_speed = SPEED_2500;
601 vars->line_speed = SPEED_10000;
605 vars->line_speed = SPEED_12000;
609 vars->line_speed = SPEED_12500;
613 vars->line_speed = SPEED_13000;
617 vars->line_speed = SPEED_15000;
621 vars->line_speed = SPEED_16000;
628 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
629 vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
631 vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
633 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
634 vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
636 vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
638 if (vars->phy_flags & PHY_XGXS_FLAG) {
639 if (vars->line_speed &&
640 ((vars->line_speed == SPEED_10) ||
641 (vars->line_speed == SPEED_100))) {
642 vars->phy_flags |= PHY_SGMII_FLAG;
644 vars->phy_flags &= ~PHY_SGMII_FLAG;
648 /* anything 10 and over uses the bmac */
649 link_10g = ((vars->line_speed == SPEED_10000) ||
650 (vars->line_speed == SPEED_12000) ||
651 (vars->line_speed == SPEED_12500) ||
652 (vars->line_speed == SPEED_13000) ||
653 (vars->line_speed == SPEED_15000) ||
654 (vars->line_speed == SPEED_16000));
656 vars->mac_type = MAC_TYPE_BMAC;
658 vars->mac_type = MAC_TYPE_EMAC;
660 } else { /* link down */
661 DP(NETIF_MSG_LINK, "phy link down\n");
663 vars->phy_link_up = 0;
665 vars->line_speed = 0;
666 vars->duplex = DUPLEX_FULL;
667 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
669 /* indicate no mac active */
670 vars->mac_type = MAC_TYPE_NONE;
673 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
674 vars->link_status, vars->phy_link_up);
675 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
676 vars->line_speed, vars->duplex, vars->flow_ctrl);
679 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
681 struct bnx2x *bp = params->bp;
682 REG_WR(bp, params->shmem_base +
683 offsetof(struct shmem_region,
684 port_mb[params->port].link_status),
688 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
690 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
691 NIG_REG_INGRESS_BMAC0_MEM;
693 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
695 /* Only if the bmac is out of reset */
696 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
697 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
700 /* Clear Rx Enable bit in BMAC_CONTROL register */
701 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
703 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
704 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
711 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
714 struct bnx2x *bp = params->bp;
715 u8 port = params->port;
720 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
722 /* wait for init credit */
723 init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
724 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
725 DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
727 while ((init_crd != crd) && count) {
730 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
733 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
734 if (init_crd != crd) {
735 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
740 if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
741 line_speed == SPEED_10 ||
742 line_speed == SPEED_100 ||
743 line_speed == SPEED_1000 ||
744 line_speed == SPEED_2500) {
745 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
746 /* update threshold */
747 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
748 /* update init credit */
749 init_crd = 778; /* (800-18-4) */
752 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
754 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
755 /* update threshold */
756 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
757 /* update init credit */
758 switch (line_speed) {
760 init_crd = thresh + 553 - 22;
764 init_crd = thresh + 664 - 22;
768 init_crd = thresh + 742 - 22;
772 init_crd = thresh + 778 - 22;
775 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
781 REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
782 DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
783 line_speed, init_crd);
785 /* probe the credit changes */
786 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
788 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
791 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
795 static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
798 switch (ext_phy_type) {
799 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
800 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
801 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
802 /* All MDC/MDIO is directed through single EMAC */
803 if (REG_RD(bp, NIG_REG_PORT_SWAP))
804 emac_base = GRCBASE_EMAC0;
806 emac_base = GRCBASE_EMAC1;
808 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
809 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
812 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
819 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
820 u8 phy_addr, u8 devad, u16 reg, u16 val)
824 u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
826 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
827 * (a value of 49==0x31) and make sure that the AUTO poll is off
830 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
831 tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
832 EMAC_MDIO_MODE_CLOCK_CNT);
833 tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
834 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
835 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
836 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
841 tmp = ((phy_addr << 21) | (devad << 16) | reg |
842 EMAC_MDIO_COMM_COMMAND_ADDRESS |
843 EMAC_MDIO_COMM_START_BUSY);
844 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
846 for (i = 0; i < 50; i++) {
849 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
850 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
855 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
856 DP(NETIF_MSG_LINK, "write phy register failed\n");
860 tmp = ((phy_addr << 21) | (devad << 16) | val |
861 EMAC_MDIO_COMM_COMMAND_WRITE_45 |
862 EMAC_MDIO_COMM_START_BUSY);
863 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
865 for (i = 0; i < 50; i++) {
868 tmp = REG_RD(bp, mdio_ctrl +
869 EMAC_REG_EMAC_MDIO_COMM);
870 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
875 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
876 DP(NETIF_MSG_LINK, "write phy register failed\n");
881 /* Restore the saved mode */
882 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
887 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
888 u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
894 u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
895 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
896 * (a value of 49==0x31) and make sure that the AUTO poll is off
899 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
900 val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
901 EMAC_MDIO_MODE_CLOCK_CNT));
902 val |= (EMAC_MDIO_MODE_CLAUSE_45 |
903 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
904 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
905 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
909 val = ((phy_addr << 21) | (devad << 16) | reg |
910 EMAC_MDIO_COMM_COMMAND_ADDRESS |
911 EMAC_MDIO_COMM_START_BUSY);
912 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
914 for (i = 0; i < 50; i++) {
917 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
918 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
923 if (val & EMAC_MDIO_COMM_START_BUSY) {
924 DP(NETIF_MSG_LINK, "read phy register failed\n");
931 val = ((phy_addr << 21) | (devad << 16) |
932 EMAC_MDIO_COMM_COMMAND_READ_45 |
933 EMAC_MDIO_COMM_START_BUSY);
934 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
936 for (i = 0; i < 50; i++) {
939 val = REG_RD(bp, mdio_ctrl +
940 EMAC_REG_EMAC_MDIO_COMM);
941 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
942 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
946 if (val & EMAC_MDIO_COMM_START_BUSY) {
947 DP(NETIF_MSG_LINK, "read phy register failed\n");
954 /* Restore the saved mode */
955 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
960 static void bnx2x_set_aer_mmd(struct link_params *params,
961 struct link_vars *vars)
963 struct bnx2x *bp = params->bp;
967 ser_lane = ((params->lane_config &
968 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
969 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
971 offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
972 (params->phy_addr + ser_lane) : 0;
974 CL45_WR_OVER_CL22(bp, params->port,
976 MDIO_REG_BANK_AER_BLOCK,
977 MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
980 static void bnx2x_set_master_ln(struct link_params *params)
982 struct bnx2x *bp = params->bp;
983 u16 new_master_ln, ser_lane;
984 ser_lane = ((params->lane_config &
985 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
986 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
988 /* set the master_ln for AN */
989 CL45_RD_OVER_CL22(bp, params->port,
991 MDIO_REG_BANK_XGXS_BLOCK2,
992 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
995 CL45_WR_OVER_CL22(bp, params->port,
997 MDIO_REG_BANK_XGXS_BLOCK2 ,
998 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
999 (new_master_ln | ser_lane));
1002 static u8 bnx2x_reset_unicore(struct link_params *params)
1004 struct bnx2x *bp = params->bp;
1008 CL45_RD_OVER_CL22(bp, params->port,
1010 MDIO_REG_BANK_COMBO_IEEE0,
1011 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
1013 /* reset the unicore */
1014 CL45_WR_OVER_CL22(bp, params->port,
1016 MDIO_REG_BANK_COMBO_IEEE0,
1017 MDIO_COMBO_IEEE0_MII_CONTROL,
1019 MDIO_COMBO_IEEO_MII_CONTROL_RESET));
1021 bnx2x_set_serdes_access(params);
1023 /* wait for the reset to self clear */
1024 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
1027 /* the reset erased the previous bank value */
1028 CL45_RD_OVER_CL22(bp, params->port,
1030 MDIO_REG_BANK_COMBO_IEEE0,
1031 MDIO_COMBO_IEEE0_MII_CONTROL,
1034 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1040 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1045 static void bnx2x_set_swap_lanes(struct link_params *params)
1047 struct bnx2x *bp = params->bp;
1048 /* Each two bits represents a lane number:
1049 No swap is 0123 => 0x1b no need to enable the swap */
1050 u16 ser_lane, rx_lane_swap, tx_lane_swap;
1052 ser_lane = ((params->lane_config &
1053 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1054 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1055 rx_lane_swap = ((params->lane_config &
1056 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1057 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1058 tx_lane_swap = ((params->lane_config &
1059 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1060 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1062 if (rx_lane_swap != 0x1b) {
1063 CL45_WR_OVER_CL22(bp, params->port,
1065 MDIO_REG_BANK_XGXS_BLOCK2,
1066 MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1068 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1069 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1071 CL45_WR_OVER_CL22(bp, params->port,
1073 MDIO_REG_BANK_XGXS_BLOCK2,
1074 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1077 if (tx_lane_swap != 0x1b) {
1078 CL45_WR_OVER_CL22(bp, params->port,
1080 MDIO_REG_BANK_XGXS_BLOCK2,
1081 MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1083 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1085 CL45_WR_OVER_CL22(bp, params->port,
1087 MDIO_REG_BANK_XGXS_BLOCK2,
1088 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1092 static void bnx2x_set_parallel_detection(struct link_params *params,
1095 struct bnx2x *bp = params->bp;
1098 CL45_RD_OVER_CL22(bp, params->port,
1100 MDIO_REG_BANK_SERDES_DIGITAL,
1101 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1105 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1108 CL45_WR_OVER_CL22(bp, params->port,
1110 MDIO_REG_BANK_SERDES_DIGITAL,
1111 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1114 if (phy_flags & PHY_XGXS_FLAG) {
1115 DP(NETIF_MSG_LINK, "XGXS\n");
1117 CL45_WR_OVER_CL22(bp, params->port,
1119 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1120 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1121 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1123 CL45_RD_OVER_CL22(bp, params->port,
1125 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1126 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1131 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1133 CL45_WR_OVER_CL22(bp, params->port,
1135 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1136 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1139 /* Disable parallel detection of HiG */
1140 CL45_WR_OVER_CL22(bp, params->port,
1142 MDIO_REG_BANK_XGXS_BLOCK2,
1143 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1144 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1145 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1149 static void bnx2x_set_autoneg(struct link_params *params,
1150 struct link_vars *vars)
1152 struct bnx2x *bp = params->bp;
1157 CL45_RD_OVER_CL22(bp, params->port,
1159 MDIO_REG_BANK_COMBO_IEEE0,
1160 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
1162 /* CL37 Autoneg Enabled */
1163 if (vars->line_speed == SPEED_AUTO_NEG)
1164 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1165 else /* CL37 Autoneg Disabled */
1166 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1167 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1169 CL45_WR_OVER_CL22(bp, params->port,
1171 MDIO_REG_BANK_COMBO_IEEE0,
1172 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1174 /* Enable/Disable Autodetection */
1176 CL45_RD_OVER_CL22(bp, params->port,
1178 MDIO_REG_BANK_SERDES_DIGITAL,
1179 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val);
1180 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1181 if (vars->line_speed == SPEED_AUTO_NEG)
1182 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1184 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1186 CL45_WR_OVER_CL22(bp, params->port,
1188 MDIO_REG_BANK_SERDES_DIGITAL,
1189 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1191 /* Enable TetonII and BAM autoneg */
1192 CL45_RD_OVER_CL22(bp, params->port,
1194 MDIO_REG_BANK_BAM_NEXT_PAGE,
1195 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1197 if (vars->line_speed == SPEED_AUTO_NEG) {
1198 /* Enable BAM aneg Mode and TetonII aneg Mode */
1199 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1200 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1202 /* TetonII and BAM Autoneg Disabled */
1203 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1204 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1206 CL45_WR_OVER_CL22(bp, params->port,
1208 MDIO_REG_BANK_BAM_NEXT_PAGE,
1209 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1212 /* CL73 Autoneg Disabled */
1215 CL45_WR_OVER_CL22(bp, params->port,
1217 MDIO_REG_BANK_CL73_IEEEB0,
1218 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1221 /* program SerDes, forced speed */
1222 static void bnx2x_program_serdes(struct link_params *params,
1223 struct link_vars *vars)
1225 struct bnx2x *bp = params->bp;
1228 /* program duplex, disable autoneg */
1230 CL45_RD_OVER_CL22(bp, params->port,
1232 MDIO_REG_BANK_COMBO_IEEE0,
1233 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
1234 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1235 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
1236 if (params->req_duplex == DUPLEX_FULL)
1237 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1238 CL45_WR_OVER_CL22(bp, params->port,
1240 MDIO_REG_BANK_COMBO_IEEE0,
1241 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1244 - needed only if the speed is greater than 1G (2.5G or 10G) */
1245 CL45_RD_OVER_CL22(bp, params->port,
1247 MDIO_REG_BANK_SERDES_DIGITAL,
1248 MDIO_SERDES_DIGITAL_MISC1, ®_val);
1249 /* clearing the speed value before setting the right speed */
1250 DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1252 reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1253 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1255 if (!((vars->line_speed == SPEED_1000) ||
1256 (vars->line_speed == SPEED_100) ||
1257 (vars->line_speed == SPEED_10))) {
1259 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1260 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1261 if (vars->line_speed == SPEED_10000)
1263 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1264 if (vars->line_speed == SPEED_13000)
1266 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1269 CL45_WR_OVER_CL22(bp, params->port,
1271 MDIO_REG_BANK_SERDES_DIGITAL,
1272 MDIO_SERDES_DIGITAL_MISC1, reg_val);
1276 static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1278 struct bnx2x *bp = params->bp;
1281 /* configure the 48 bits for BAM AN */
1283 /* set extended capabilities */
1284 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1285 val |= MDIO_OVER_1G_UP1_2_5G;
1286 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1287 val |= MDIO_OVER_1G_UP1_10G;
1288 CL45_WR_OVER_CL22(bp, params->port,
1290 MDIO_REG_BANK_OVER_1G,
1291 MDIO_OVER_1G_UP1, val);
1293 CL45_WR_OVER_CL22(bp, params->port,
1295 MDIO_REG_BANK_OVER_1G,
1296 MDIO_OVER_1G_UP3, 0);
1299 static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
1301 *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1302 /* resolve pause mode and advertisement
1303 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1305 switch (params->req_flow_ctrl) {
1306 case BNX2X_FLOW_CTRL_AUTO:
1307 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
1309 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1312 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1315 case BNX2X_FLOW_CTRL_TX:
1317 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1320 case BNX2X_FLOW_CTRL_RX:
1321 case BNX2X_FLOW_CTRL_BOTH:
1322 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1325 case BNX2X_FLOW_CTRL_NONE:
1327 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1332 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1335 struct bnx2x *bp = params->bp;
1336 /* for AN, we are always publishing full duplex */
1338 CL45_WR_OVER_CL22(bp, params->port,
1340 MDIO_REG_BANK_COMBO_IEEE0,
1341 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
1344 static void bnx2x_restart_autoneg(struct link_params *params)
1346 struct bnx2x *bp = params->bp;
1348 DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1349 /* Enable and restart BAM/CL37 aneg */
1351 CL45_RD_OVER_CL22(bp, params->port,
1353 MDIO_REG_BANK_COMBO_IEEE0,
1354 MDIO_COMBO_IEEE0_MII_CONTROL,
1357 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1359 CL45_WR_OVER_CL22(bp, params->port,
1361 MDIO_REG_BANK_COMBO_IEEE0,
1362 MDIO_COMBO_IEEE0_MII_CONTROL,
1364 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1365 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1368 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1369 struct link_vars *vars)
1371 struct bnx2x *bp = params->bp;
1374 /* in SGMII mode, the unicore is always slave */
1376 CL45_RD_OVER_CL22(bp, params->port,
1378 MDIO_REG_BANK_SERDES_DIGITAL,
1379 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1381 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1382 /* set sgmii mode (and not fiber) */
1383 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1384 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1385 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1386 CL45_WR_OVER_CL22(bp, params->port,
1388 MDIO_REG_BANK_SERDES_DIGITAL,
1389 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1392 /* if forced speed */
1393 if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1394 /* set speed, disable autoneg */
1397 CL45_RD_OVER_CL22(bp, params->port,
1399 MDIO_REG_BANK_COMBO_IEEE0,
1400 MDIO_COMBO_IEEE0_MII_CONTROL,
1402 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1403 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1404 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1406 switch (vars->line_speed) {
1409 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1413 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1416 /* there is nothing to set for 10M */
1419 /* invalid speed for SGMII */
1420 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1425 /* setting the full duplex */
1426 if (params->req_duplex == DUPLEX_FULL)
1428 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1429 CL45_WR_OVER_CL22(bp, params->port,
1431 MDIO_REG_BANK_COMBO_IEEE0,
1432 MDIO_COMBO_IEEE0_MII_CONTROL,
1435 } else { /* AN mode */
1436 /* enable and restart AN */
1437 bnx2x_restart_autoneg(params);
1446 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1448 switch (pause_result) { /* ASYM P ASYM P */
1449 case 0xb: /* 1 0 1 1 */
1450 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
1453 case 0xe: /* 1 1 1 0 */
1454 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
1457 case 0x5: /* 0 1 0 1 */
1458 case 0x7: /* 0 1 1 1 */
1459 case 0xd: /* 1 1 0 1 */
1460 case 0xf: /* 1 1 1 1 */
1461 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
1469 static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1470 struct link_vars *vars)
1472 struct bnx2x *bp = params->bp;
1474 u16 ld_pause; /* local */
1475 u16 lp_pause; /* link partner */
1476 u16 an_complete; /* AN complete */
1480 u8 port = params->port;
1481 ext_phy_addr = ((params->ext_phy_config &
1482 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1483 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1485 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1488 bnx2x_cl45_read(bp, port,
1492 MDIO_AN_REG_STATUS, &an_complete);
1493 bnx2x_cl45_read(bp, port,
1497 MDIO_AN_REG_STATUS, &an_complete);
1499 if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1501 bnx2x_cl45_read(bp, port,
1505 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1506 bnx2x_cl45_read(bp, port,
1510 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1511 pause_result = (ld_pause &
1512 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1513 pause_result |= (lp_pause &
1514 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1515 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1517 bnx2x_pause_resolve(vars, pause_result);
1518 if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
1519 ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1520 bnx2x_cl45_read(bp, port,
1524 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1526 bnx2x_cl45_read(bp, port,
1530 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1531 pause_result = (ld_pause &
1532 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1533 pause_result |= (lp_pause &
1534 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1536 bnx2x_pause_resolve(vars, pause_result);
1537 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1545 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1546 struct link_vars *vars,
1549 struct bnx2x *bp = params->bp;
1550 u16 ld_pause; /* local driver */
1551 u16 lp_pause; /* link partner */
1554 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1556 /* resolve from gp_status in case of AN complete and not sgmii */
1557 if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1558 (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1559 (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1560 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1561 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1562 CL45_RD_OVER_CL22(bp, params->port,
1564 MDIO_REG_BANK_COMBO_IEEE0,
1565 MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1567 CL45_RD_OVER_CL22(bp, params->port,
1569 MDIO_REG_BANK_COMBO_IEEE0,
1570 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1572 pause_result = (ld_pause &
1573 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1574 pause_result |= (lp_pause &
1575 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1576 DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1577 bnx2x_pause_resolve(vars, pause_result);
1578 } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1579 (bnx2x_ext_phy_resove_fc(params, vars))) {
1582 if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
1583 vars->flow_ctrl = params->req_fc_auto_adv;
1585 vars->flow_ctrl = params->req_flow_ctrl;
1587 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1591 static u8 bnx2x_link_settings_status(struct link_params *params,
1592 struct link_vars *vars,
1595 struct bnx2x *bp = params->bp;
1598 vars->link_status = 0;
1600 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1601 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1604 vars->phy_link_up = 1;
1605 vars->link_status |= LINK_STATUS_LINK_UP;
1607 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1608 vars->duplex = DUPLEX_FULL;
1610 vars->duplex = DUPLEX_HALF;
1612 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1614 switch (gp_status & GP_STATUS_SPEED_MASK) {
1616 new_line_speed = SPEED_10;
1617 if (vars->duplex == DUPLEX_FULL)
1618 vars->link_status |= LINK_10TFD;
1620 vars->link_status |= LINK_10THD;
1623 case GP_STATUS_100M:
1624 new_line_speed = SPEED_100;
1625 if (vars->duplex == DUPLEX_FULL)
1626 vars->link_status |= LINK_100TXFD;
1628 vars->link_status |= LINK_100TXHD;
1632 case GP_STATUS_1G_KX:
1633 new_line_speed = SPEED_1000;
1634 if (vars->duplex == DUPLEX_FULL)
1635 vars->link_status |= LINK_1000TFD;
1637 vars->link_status |= LINK_1000THD;
1640 case GP_STATUS_2_5G:
1641 new_line_speed = SPEED_2500;
1642 if (vars->duplex == DUPLEX_FULL)
1643 vars->link_status |= LINK_2500TFD;
1645 vars->link_status |= LINK_2500THD;
1651 "link speed unsupported gp_status 0x%x\n",
1655 case GP_STATUS_10G_KX4:
1656 case GP_STATUS_10G_HIG:
1657 case GP_STATUS_10G_CX4:
1658 new_line_speed = SPEED_10000;
1659 vars->link_status |= LINK_10GTFD;
1662 case GP_STATUS_12G_HIG:
1663 new_line_speed = SPEED_12000;
1664 vars->link_status |= LINK_12GTFD;
1667 case GP_STATUS_12_5G:
1668 new_line_speed = SPEED_12500;
1669 vars->link_status |= LINK_12_5GTFD;
1673 new_line_speed = SPEED_13000;
1674 vars->link_status |= LINK_13GTFD;
1678 new_line_speed = SPEED_15000;
1679 vars->link_status |= LINK_15GTFD;
1683 new_line_speed = SPEED_16000;
1684 vars->link_status |= LINK_16GTFD;
1689 "link speed unsupported gp_status 0x%x\n",
1695 /* Upon link speed change set the NIG into drain mode.
1696 Comes to deals with possible FIFO glitch due to clk change
1697 when speed is decreased without link down indicator */
1698 if (new_line_speed != vars->line_speed) {
1699 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
1700 + params->port*4, 0);
1703 vars->line_speed = new_line_speed;
1704 vars->link_status |= LINK_STATUS_SERDES_LINK;
1706 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1707 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1708 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1709 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1710 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
1711 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1712 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
1713 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1714 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481))) {
1715 vars->autoneg = AUTO_NEG_ENABLED;
1717 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1718 vars->autoneg |= AUTO_NEG_COMPLETE;
1719 vars->link_status |=
1720 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1723 vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1724 vars->link_status |=
1725 LINK_STATUS_PARALLEL_DETECTION_USED;
1728 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1729 vars->link_status |=
1730 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1732 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1733 vars->link_status |=
1734 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1736 } else { /* link_down */
1737 DP(NETIF_MSG_LINK, "phy link down\n");
1739 vars->phy_link_up = 0;
1741 vars->duplex = DUPLEX_FULL;
1742 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1743 vars->autoneg = AUTO_NEG_DISABLED;
1744 vars->mac_type = MAC_TYPE_NONE;
1747 DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x \n",
1748 gp_status, vars->phy_link_up, vars->line_speed);
1749 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x"
1752 vars->flow_ctrl, vars->autoneg);
1753 DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1758 static void bnx2x_set_gmii_tx_driver(struct link_params *params)
1760 struct bnx2x *bp = params->bp;
1766 CL45_RD_OVER_CL22(bp, params->port,
1768 MDIO_REG_BANK_OVER_1G,
1769 MDIO_OVER_1G_LP_UP2, &lp_up2);
1771 /* bits [10:7] at lp_up2, positioned at [15:12] */
1772 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1773 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1774 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1779 for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
1780 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
1781 CL45_RD_OVER_CL22(bp, params->port,
1784 MDIO_TX0_TX_DRIVER, &tx_driver);
1786 /* replace tx_driver bits [15:12] */
1788 (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
1789 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1790 tx_driver |= lp_up2;
1791 CL45_WR_OVER_CL22(bp, params->port,
1794 MDIO_TX0_TX_DRIVER, tx_driver);
1799 static u8 bnx2x_emac_program(struct link_params *params,
1800 u32 line_speed, u32 duplex)
1802 struct bnx2x *bp = params->bp;
1803 u8 port = params->port;
1806 DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1807 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1809 (EMAC_MODE_25G_MODE |
1810 EMAC_MODE_PORT_MII_10M |
1811 EMAC_MODE_HALF_DUPLEX));
1812 switch (line_speed) {
1814 mode |= EMAC_MODE_PORT_MII_10M;
1818 mode |= EMAC_MODE_PORT_MII;
1822 mode |= EMAC_MODE_PORT_GMII;
1826 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1830 /* 10G not valid for EMAC */
1831 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1835 if (duplex == DUPLEX_HALF)
1836 mode |= EMAC_MODE_HALF_DUPLEX;
1838 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1841 bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1842 line_speed, params->hw_led_mode, params->chip_id);
1846 /*****************************************************************************/
1847 /* External Phy section */
1848 /*****************************************************************************/
1849 static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
1851 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1852 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
1854 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1855 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
1858 static void bnx2x_ext_phy_reset(struct link_params *params,
1859 struct link_vars *vars)
1861 struct bnx2x *bp = params->bp;
1863 u8 ext_phy_addr = ((params->ext_phy_config &
1864 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1865 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1866 DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1867 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1868 /* The PHY reset is controled by GPIO 1
1869 * Give it 1ms of reset pulse
1871 if (vars->phy_flags & PHY_XGXS_FLAG) {
1873 switch (ext_phy_type) {
1874 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1875 DP(NETIF_MSG_LINK, "XGXS Direct\n");
1878 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1879 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1880 DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1882 /* Restore normal power mode*/
1883 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1884 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1888 bnx2x_hw_reset(bp, params->port);
1890 bnx2x_cl45_write(bp, params->port,
1894 MDIO_PMA_REG_CTRL, 0xa040);
1897 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
1900 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
1902 /* Restore normal power mode*/
1903 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1904 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1907 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1908 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1911 bnx2x_cl45_write(bp, params->port,
1919 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1920 /* Unset Low Power Mode and SW reset */
1921 /* Restore normal power mode*/
1922 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1923 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1926 DP(NETIF_MSG_LINK, "XGXS 8072\n");
1927 bnx2x_cl45_write(bp, params->port,
1934 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1937 /* Restore normal power mode*/
1938 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1939 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1942 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1943 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1946 DP(NETIF_MSG_LINK, "XGXS 8073\n");
1950 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1951 DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1953 /* Restore normal power mode*/
1954 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1955 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1959 bnx2x_hw_reset(bp, params->port);
1963 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
1965 /* Restore normal power mode*/
1966 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1967 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1971 bnx2x_hw_reset(bp, params->port);
1973 bnx2x_cl45_write(bp, params->port,
1980 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
1981 DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
1985 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
1986 params->ext_phy_config);
1990 } else { /* SerDes */
1991 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
1992 switch (ext_phy_type) {
1993 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
1994 DP(NETIF_MSG_LINK, "SerDes Direct\n");
1997 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
1998 DP(NETIF_MSG_LINK, "SerDes 5482\n");
1999 bnx2x_hw_reset(bp, params->port);
2004 "BAD SerDes ext_phy_config 0x%x\n",
2005 params->ext_phy_config);
2012 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
2013 u32 shmem_base, u32 spirom_ver)
2015 DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x\n",
2016 (u16)(spirom_ver>>16), (u16)spirom_ver);
2017 REG_WR(bp, shmem_base +
2018 offsetof(struct shmem_region,
2019 port_mb[port].ext_phy_fw_version),
2023 static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
2024 u32 ext_phy_type, u8 ext_phy_addr,
2027 u16 fw_ver1, fw_ver2;
2028 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2029 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2030 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2031 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2032 bnx2x_save_spirom_version(bp, port, shmem_base,
2033 (u32)(fw_ver1<<16 | fw_ver2));
2036 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
2038 struct bnx2x *bp = params->bp;
2039 u8 port = params->port;
2040 u8 ext_phy_addr = ((params->ext_phy_config &
2041 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2042 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2043 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2045 /* Need to wait 200ms after reset */
2047 /* Boot port from external ROM
2048 * Set ser_boot_ctl bit in the MISC_CTRL1 register
2050 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2052 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2054 /* Reset internal microprocessor */
2055 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2057 MDIO_PMA_REG_GEN_CTRL,
2058 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2059 /* set micro reset = 0 */
2060 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2062 MDIO_PMA_REG_GEN_CTRL,
2063 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2064 /* Reset internal microprocessor */
2065 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2067 MDIO_PMA_REG_GEN_CTRL,
2068 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2069 /* wait for 100ms for code download via SPI port */
2072 /* Clear ser_boot_ctl bit */
2073 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2075 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2079 bnx2x_save_bcm_spirom_ver(bp, port,
2082 params->shmem_base);
2085 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2087 /* This is only required for 8073A1, version 102 only */
2089 struct bnx2x *bp = params->bp;
2090 u8 ext_phy_addr = ((params->ext_phy_config &
2091 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2092 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2095 /* Read 8073 HW revision*/
2096 bnx2x_cl45_read(bp, params->port,
2097 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2100 MDIO_PMA_REG_8073_CHIP_REV, &val);
2103 /* No need to workaround in 8073 A1 */
2107 bnx2x_cl45_read(bp, params->port,
2108 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2111 MDIO_PMA_REG_ROM_VER2, &val);
2113 /* SNR should be applied only for version 0x102 */
2120 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2122 struct bnx2x *bp = params->bp;
2123 u8 ext_phy_addr = ((params->ext_phy_config &
2124 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2125 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2126 u16 val, cnt, cnt1 ;
2128 bnx2x_cl45_read(bp, params->port,
2129 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2132 MDIO_PMA_REG_8073_CHIP_REV, &val);
2135 /* No need to workaround in 8073 A1 */
2138 /* XAUI workaround in 8073 A0: */
2140 /* After loading the boot ROM and restarting Autoneg,
2141 poll Dev1, Reg $C820: */
2143 for (cnt = 0; cnt < 1000; cnt++) {
2144 bnx2x_cl45_read(bp, params->port,
2145 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2148 MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
2150 /* If bit [14] = 0 or bit [13] = 0, continue on with
2151 system initialization (XAUI work-around not required,
2152 as these bits indicate 2.5G or 1G link up). */
2153 if (!(val & (1<<14)) || !(val & (1<<13))) {
2154 DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2156 } else if (!(val & (1<<15))) {
2157 DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2158 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2159 it's MSB (bit 15) goes to 1 (indicating that the
2160 XAUI workaround has completed),
2161 then continue on with system initialization.*/
2162 for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2163 bnx2x_cl45_read(bp, params->port,
2164 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2167 MDIO_PMA_REG_8073_XAUI_WA, &val);
2168 if (val & (1<<15)) {
2170 "XAUI workaround has completed\n");
2179 DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2184 static void bnx2x_bcm8073_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
2189 /* Boot port from external ROM */
2191 bnx2x_cl45_write(bp, port,
2195 MDIO_PMA_REG_GEN_CTRL,
2198 /* ucode reboot and rst */
2199 bnx2x_cl45_write(bp, port,
2203 MDIO_PMA_REG_GEN_CTRL,
2206 bnx2x_cl45_write(bp, port,
2210 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2212 /* Reset internal microprocessor */
2213 bnx2x_cl45_write(bp, port,
2217 MDIO_PMA_REG_GEN_CTRL,
2218 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2220 /* Release srst bit */
2221 bnx2x_cl45_write(bp, port,
2225 MDIO_PMA_REG_GEN_CTRL,
2226 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2228 /* wait for 100ms for code download via SPI port */
2231 /* Clear ser_boot_ctl bit */
2232 bnx2x_cl45_write(bp, port,
2236 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2238 bnx2x_save_bcm_spirom_ver(bp, port,
2244 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2248 bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr,
2249 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2253 static void bnx2x_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
2257 bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr,
2258 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2263 static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
2265 struct bnx2x *bp = params->bp;
2266 u8 port = params->port;
2267 u8 ext_phy_addr = ((params->ext_phy_config &
2268 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2269 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2270 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2272 /* Need to wait 100ms after reset */
2275 /* Set serial boot control for external load */
2276 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2278 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2280 /* Micro controller re-boot */
2281 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2283 MDIO_PMA_REG_GEN_CTRL,
2284 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2286 /* Set soft reset */
2287 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2289 MDIO_PMA_REG_GEN_CTRL,
2290 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2292 /* Set PLL register value to be same like in P13 ver */
2293 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2295 MDIO_PMA_REG_PLL_CTRL,
2298 /* Clear soft reset.
2299 Will automatically reset micro-controller re-boot */
2300 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2302 MDIO_PMA_REG_GEN_CTRL,
2303 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2305 /* wait for 150ms for microcode load */
2308 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
2309 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2311 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2314 bnx2x_save_bcm_spirom_ver(bp, port,
2317 params->shmem_base);
2320 static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, u8 port,
2321 u32 ext_phy_type, u8 ext_phy_addr,
2325 DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
2327 /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
2328 bnx2x_cl45_read(bp, port,
2332 MDIO_PMA_REG_PHY_IDENTIFIER,
2340 bnx2x_cl45_write(bp, port,
2344 MDIO_PMA_REG_PHY_IDENTIFIER,
2348 static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params,
2349 u16 addr, u8 byte_cnt, u8 *o_buf)
2351 struct bnx2x *bp = params->bp;
2354 u8 port = params->port;
2355 u8 ext_phy_addr = ((params->ext_phy_config &
2356 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2357 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2358 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2359 if (byte_cnt > 16) {
2360 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2361 " is limited to 0xf\n");
2364 /* Set the read command byte count */
2365 bnx2x_cl45_write(bp, port,
2369 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
2370 (byte_cnt | 0xa000));
2372 /* Set the read command address */
2373 bnx2x_cl45_write(bp, port,
2377 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
2380 /* Activate read command */
2381 bnx2x_cl45_write(bp, port,
2385 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2388 /* Wait up to 500us for command complete status */
2389 for (i = 0; i < 100; i++) {
2390 bnx2x_cl45_read(bp, port,
2394 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2395 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2396 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
2401 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
2402 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
2404 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2405 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
2409 /* Read the buffer */
2410 for (i = 0; i < byte_cnt; i++) {
2411 bnx2x_cl45_read(bp, port,
2415 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2416 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
2419 for (i = 0; i < 100; i++) {
2420 bnx2x_cl45_read(bp, port,
2424 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2425 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2426 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
2433 static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
2434 u16 addr, u8 byte_cnt, u8 *o_buf)
2436 struct bnx2x *bp = params->bp;
2438 u8 port = params->port;
2439 u8 ext_phy_addr = ((params->ext_phy_config &
2440 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2441 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2442 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2444 if (byte_cnt > 16) {
2445 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2446 " is limited to 0xf\n");
2450 /* Need to read from 1.8000 to clear it */
2451 bnx2x_cl45_read(bp, port,
2452 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2455 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2458 /* Set the read command byte count */
2459 bnx2x_cl45_write(bp, port,
2463 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
2464 ((byte_cnt < 2) ? 2 : byte_cnt));
2466 /* Set the read command address */
2467 bnx2x_cl45_write(bp, port,
2471 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
2473 /* Set the destination address */
2474 bnx2x_cl45_write(bp, port,
2479 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
2481 /* Activate read command */
2482 bnx2x_cl45_write(bp, port,
2486 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2488 /* Wait appropriate time for two-wire command to finish before
2489 polling the status register */
2492 /* Wait up to 500us for command complete status */
2493 for (i = 0; i < 100; i++) {
2494 bnx2x_cl45_read(bp, port,
2498 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2499 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2500 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
2505 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
2506 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
2508 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2509 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
2513 /* Read the buffer */
2514 for (i = 0; i < byte_cnt; i++) {
2515 bnx2x_cl45_read(bp, port,
2519 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
2520 o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
2523 for (i = 0; i < 100; i++) {
2524 bnx2x_cl45_read(bp, port,
2528 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2529 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2530 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
2538 u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
2539 u8 byte_cnt, u8 *o_buf)
2541 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2543 if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
2544 return bnx2x_8726_read_sfp_module_eeprom(params, addr,
2546 else if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
2547 return bnx2x_8727_read_sfp_module_eeprom(params, addr,
2552 static u8 bnx2x_get_edc_mode(struct link_params *params,
2555 struct bnx2x *bp = params->bp;
2556 u8 val, check_limiting_mode = 0;
2557 *edc_mode = EDC_MODE_LIMITING;
2559 /* First check for copper cable */
2560 if (bnx2x_read_sfp_module_eeprom(params,
2561 SFP_EEPROM_CON_TYPE_ADDR,
2564 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
2569 case SFP_EEPROM_CON_TYPE_VAL_COPPER:
2571 u8 copper_module_type;
2572 /* Check if its active cable( includes SFP+ module)
2574 if (bnx2x_read_sfp_module_eeprom(params,
2575 SFP_EEPROM_FC_TX_TECH_ADDR,
2577 &copper_module_type) !=
2580 "Failed to read copper-cable-type"
2581 " from SFP+ EEPROM\n");
2585 if (copper_module_type &
2586 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
2587 DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
2588 check_limiting_mode = 1;
2589 } else if (copper_module_type &
2590 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
2591 DP(NETIF_MSG_LINK, "Passive Copper"
2592 " cable detected\n");
2594 EDC_MODE_PASSIVE_DAC;
2596 DP(NETIF_MSG_LINK, "Unknown copper-cable-"
2597 "type 0x%x !!!\n", copper_module_type);
2602 case SFP_EEPROM_CON_TYPE_VAL_LC:
2603 DP(NETIF_MSG_LINK, "Optic module detected\n");
2604 check_limiting_mode = 1;
2608 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
2613 if (check_limiting_mode) {
2614 u8 options[SFP_EEPROM_OPTIONS_SIZE];
2615 if (bnx2x_read_sfp_module_eeprom(params,
2616 SFP_EEPROM_OPTIONS_ADDR,
2617 SFP_EEPROM_OPTIONS_SIZE,
2619 DP(NETIF_MSG_LINK, "Failed to read Option"
2620 " field from module EEPROM\n");
2623 if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
2624 *edc_mode = EDC_MODE_LINEAR;
2626 *edc_mode = EDC_MODE_LIMITING;
2628 DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
2632 /* This function read the relevant field from the module ( SFP+ ),
2633 and verify it is compliant with this board */
2634 static u8 bnx2x_verify_sfp_module(struct link_params *params)
2636 struct bnx2x *bp = params->bp;
2639 char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
2640 char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
2642 val = REG_RD(bp, params->shmem_base +
2643 offsetof(struct shmem_region, dev_info.
2644 port_feature_config[params->port].config));
2645 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
2646 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
2647 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
2651 /* Ask the FW to validate the module */
2652 if (!(params->feature_config_flags &
2653 FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY)) {
2654 DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
2659 fw_resp = bnx2x_fw_command(bp, DRV_MSG_CODE_VRFY_OPT_MDL);
2660 if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
2661 DP(NETIF_MSG_LINK, "Approved module\n");
2665 /* format the warning message */
2666 if (bnx2x_read_sfp_module_eeprom(params,
2667 SFP_EEPROM_VENDOR_NAME_ADDR,
2668 SFP_EEPROM_VENDOR_NAME_SIZE,
2670 vendor_name[0] = '\0';
2672 vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
2673 if (bnx2x_read_sfp_module_eeprom(params,
2674 SFP_EEPROM_PART_NO_ADDR,
2675 SFP_EEPROM_PART_NO_SIZE,
2677 vendor_pn[0] = '\0';
2679 vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
2681 printk(KERN_INFO PFX "Warning: "
2682 "Unqualified SFP+ module "
2683 "detected on %s, Port %d from %s part number %s\n"
2684 , bp->dev->name, params->port,
2685 vendor_name, vendor_pn);
2689 static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
2692 struct bnx2x *bp = params->bp;
2693 u8 port = params->port;
2694 u8 ext_phy_addr = ((params->ext_phy_config &
2695 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2696 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2697 u16 cur_limiting_mode;
2699 bnx2x_cl45_read(bp, port,
2700 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2703 MDIO_PMA_REG_ROM_VER2,
2704 &cur_limiting_mode);
2705 DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
2708 if (edc_mode == EDC_MODE_LIMITING) {
2710 "Setting LIMITING MODE\n");
2711 bnx2x_cl45_write(bp, port,
2712 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2715 MDIO_PMA_REG_ROM_VER2,
2717 } else { /* LRM mode ( default )*/
2719 DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
2721 /* Changing to LRM mode takes quite few seconds.
2722 So do it only if current mode is limiting
2723 ( default is LRM )*/
2724 if (cur_limiting_mode != EDC_MODE_LIMITING)
2727 bnx2x_cl45_write(bp, port,
2728 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2731 MDIO_PMA_REG_LRM_MODE,
2733 bnx2x_cl45_write(bp, port,
2734 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2737 MDIO_PMA_REG_ROM_VER2,
2739 bnx2x_cl45_write(bp, port,
2740 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2743 MDIO_PMA_REG_MISC_CTRL0,
2745 bnx2x_cl45_write(bp, port,
2746 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2749 MDIO_PMA_REG_LRM_MODE,
2755 static u8 bnx2x_bcm8727_set_limiting_mode(struct link_params *params,
2758 struct bnx2x *bp = params->bp;
2759 u8 port = params->port;
2762 u8 ext_phy_addr = ((params->ext_phy_config &
2763 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2764 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2766 bnx2x_cl45_read(bp, port,
2767 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2770 MDIO_PMA_REG_PHY_IDENTIFIER,
2773 bnx2x_cl45_write(bp, port,
2774 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2777 MDIO_PMA_REG_PHY_IDENTIFIER,
2778 (phy_identifier & ~(1<<9)));
2780 bnx2x_cl45_read(bp, port,
2781 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2784 MDIO_PMA_REG_ROM_VER2,
2786 /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
2787 bnx2x_cl45_write(bp, port,
2788 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2791 MDIO_PMA_REG_ROM_VER2,
2792 (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
2794 bnx2x_cl45_write(bp, port,
2795 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2798 MDIO_PMA_REG_PHY_IDENTIFIER,
2799 (phy_identifier | (1<<9)));
2805 static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
2808 struct bnx2x *bp = params->bp;
2810 /* Initialization time after hot-plug may take up to 300ms for some
2811 phys type ( e.g. JDSU ) */
2812 for (timeout = 0; timeout < 60; timeout++) {
2813 if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
2815 DP(NETIF_MSG_LINK, "SFP+ module initialization "
2816 "took %d ms\n", timeout * 5);
2824 static void bnx2x_8727_power_module(struct bnx2x *bp,
2825 struct link_params *params,
2826 u8 ext_phy_addr, u8 is_power_up) {
2827 /* Make sure GPIOs are not using for LED mode */
2829 u8 port = params->port;
2831 * In the GPIO register, bit 4 is use to detemine if the GPIOs are
2832 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
2834 * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
2835 * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
2836 * where the 1st bit is the over-current(only input), and 2nd bit is
2837 * for power( only output )
2841 * In case of NOC feature is disabled and power is up, set GPIO control
2842 * as input to enable listening of over-current indication
2845 if (!(params->feature_config_flags &
2846 FEATURE_CONFIG_BCM8727_NOC) && is_power_up)
2850 * Set GPIO control to OUTPUT, and set the power bit
2851 * to according to the is_power_up
2853 val = ((!(is_power_up)) << 1);
2855 bnx2x_cl45_write(bp, port,
2856 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2859 MDIO_PMA_REG_8727_GPIO_CTRL,
2863 static u8 bnx2x_sfp_module_detection(struct link_params *params)
2865 struct bnx2x *bp = params->bp;
2868 u8 ext_phy_addr = ((params->ext_phy_config &
2869 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2870 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2871 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2872 u32 val = REG_RD(bp, params->shmem_base +
2873 offsetof(struct shmem_region, dev_info.
2874 port_feature_config[params->port].config));
2876 DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
2879 if (bnx2x_get_edc_mode(params, &edc_mode) != 0) {
2880 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
2882 } else if (bnx2x_verify_sfp_module(params) !=
2884 /* check SFP+ module compatibility */
2885 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
2887 /* Turn on fault module-detected led */
2888 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2889 MISC_REGISTERS_GPIO_HIGH,
2891 if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
2892 ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
2893 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) {
2894 /* Shutdown SFP+ module */
2895 DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
2896 bnx2x_8727_power_module(bp, params,
2901 /* Turn off fault module-detected led */
2902 DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n");
2903 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2904 MISC_REGISTERS_GPIO_LOW,
2908 /* power up the SFP module */
2909 if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
2910 bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
2912 /* Check and set limiting mode / LRM mode on 8726.
2913 On 8727 it is done automatically */
2914 if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
2915 bnx2x_bcm8726_set_limiting_mode(params, edc_mode);
2917 bnx2x_bcm8727_set_limiting_mode(params, edc_mode);
2919 * Enable transmit for this module if the module is approved, or
2920 * if unapproved modules should also enable the Tx laser
2923 (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
2924 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
2925 bnx2x_sfp_set_transmitter(bp, params->port,
2926 ext_phy_type, ext_phy_addr, 1);
2928 bnx2x_sfp_set_transmitter(bp, params->port,
2929 ext_phy_type, ext_phy_addr, 0);
2934 void bnx2x_handle_module_detect_int(struct link_params *params)
2936 struct bnx2x *bp = params->bp;
2938 u8 port = params->port;
2939 /* Set valid module led off */
2940 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2941 MISC_REGISTERS_GPIO_HIGH,
2944 /* Get current gpio val refelecting module plugged in / out*/
2945 gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
2947 /* Call the handling function in case module is detected */
2948 if (gpio_val == 0) {
2950 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2951 MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
2954 if (bnx2x_wait_for_sfp_module_initialized(params) ==
2956 bnx2x_sfp_module_detection(params);
2958 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
2960 u8 ext_phy_addr = ((params->ext_phy_config &
2961 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2962 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2964 XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2965 u32 val = REG_RD(bp, params->shmem_base +
2966 offsetof(struct shmem_region, dev_info.
2967 port_feature_config[params->port].
2970 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2971 MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
2973 /* Module was plugged out. */
2974 /* Disable transmit for this module */
2975 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
2976 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
2977 bnx2x_sfp_set_transmitter(bp, params->port,
2978 ext_phy_type, ext_phy_addr, 0);
2982 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2984 struct bnx2x *bp = params->bp;
2985 u8 port = params->port;
2986 u8 ext_phy_addr = ((params->ext_phy_config &
2987 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2988 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2989 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2991 /* Force KR or KX */
2992 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2996 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2998 MDIO_PMA_REG_10G_CTRL2,
3000 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3002 MDIO_PMA_REG_BCM_CTRL,
3004 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3009 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
3011 struct bnx2x *bp = params->bp;
3012 u8 port = params->port;
3014 u8 ext_phy_addr = ((params->ext_phy_config &
3015 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3016 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3017 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3019 bnx2x_cl45_read(bp, params->port,
3020 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
3023 MDIO_PMA_REG_8073_CHIP_REV, &val);
3026 /* Mustn't set low power mode in 8073 A0 */
3030 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
3031 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
3033 MDIO_XS_PLL_SEQUENCER, &val);
3035 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3036 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
3039 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3040 MDIO_XS_DEVAD, 0x805E, 0x1077);
3041 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3042 MDIO_XS_DEVAD, 0x805D, 0x0000);
3043 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3044 MDIO_XS_DEVAD, 0x805C, 0x030B);
3045 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3046 MDIO_XS_DEVAD, 0x805B, 0x1240);
3047 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3048 MDIO_XS_DEVAD, 0x805A, 0x2490);
3051 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3052 MDIO_XS_DEVAD, 0x80A7, 0x0C74);
3053 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3054 MDIO_XS_DEVAD, 0x80A6, 0x9041);
3055 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3056 MDIO_XS_DEVAD, 0x80A5, 0x4640);
3059 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3060 MDIO_XS_DEVAD, 0x80FE, 0x01C4);
3061 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3062 MDIO_XS_DEVAD, 0x80FD, 0x9249);
3063 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3064 MDIO_XS_DEVAD, 0x80FC, 0x2015);
3066 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
3067 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
3069 MDIO_XS_PLL_SEQUENCER, &val);
3071 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3072 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
3075 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
3076 struct link_vars *vars)
3079 struct bnx2x *bp = params->bp;
3081 u8 ext_phy_addr = ((params->ext_phy_config &
3082 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3083 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3084 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3086 bnx2x_cl45_read(bp, params->port,
3090 MDIO_AN_REG_CL37_FC_LD, &cl37_val);
3092 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3093 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3095 if ((vars->ieee_fc &
3096 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
3097 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
3098 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
3100 if ((vars->ieee_fc &
3101 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3102 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3103 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3105 if ((vars->ieee_fc &
3106 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3107 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3108 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3111 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
3113 bnx2x_cl45_write(bp, params->port,
3117 MDIO_AN_REG_CL37_FC_LD, cl37_val);
3121 static void bnx2x_ext_phy_set_pause(struct link_params *params,
3122 struct link_vars *vars)
3124 struct bnx2x *bp = params->bp;
3126 u8 ext_phy_addr = ((params->ext_phy_config &
3127 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3128 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3129 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3131 /* read modify write pause advertizing */
3132 bnx2x_cl45_read(bp, params->port,
3136 MDIO_AN_REG_ADV_PAUSE, &val);
3138 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3140 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3142 if ((vars->ieee_fc &
3143 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3144 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3145 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3147 if ((vars->ieee_fc &
3148 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3149 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3151 MDIO_AN_REG_ADV_PAUSE_PAUSE;
3154 "Ext phy AN advertize 0x%x\n", val);
3155 bnx2x_cl45_write(bp, params->port,
3159 MDIO_AN_REG_ADV_PAUSE, val);
3161 static void bnx2x_set_preemphasis(struct link_params *params)
3164 struct bnx2x *bp = params->bp;
3166 for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
3167 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
3168 CL45_WR_OVER_CL22(bp, params->port,
3171 MDIO_RX0_RX_EQ_BOOST,
3172 params->xgxs_config_rx[i]);
3175 for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
3176 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
3177 CL45_WR_OVER_CL22(bp, params->port,
3181 params->xgxs_config_tx[i]);
3185 static void bnx2x_init_internal_phy(struct link_params *params,
3186 struct link_vars *vars)
3188 struct bnx2x *bp = params->bp;
3189 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
3190 if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
3191 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3192 (params->feature_config_flags &
3193 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
3194 bnx2x_set_preemphasis(params);
3196 /* forced speed requested? */
3197 if (vars->line_speed != SPEED_AUTO_NEG) {
3198 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
3200 /* disable autoneg */
3201 bnx2x_set_autoneg(params, vars);
3203 /* program speed and duplex */
3204 bnx2x_program_serdes(params, vars);
3206 } else { /* AN_mode */
3207 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
3210 bnx2x_set_brcm_cl37_advertisment(params);
3212 /* program duplex & pause advertisement (for aneg) */
3213 bnx2x_set_ieee_aneg_advertisment(params,
3216 /* enable autoneg */
3217 bnx2x_set_autoneg(params, vars);
3219 /* enable and restart AN */
3220 bnx2x_restart_autoneg(params);
3223 } else { /* SGMII mode */
3224 DP(NETIF_MSG_LINK, "SGMII\n");
3226 bnx2x_initialize_sgmii_process(params, vars);
3230 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
3232 struct bnx2x *bp = params->bp;
3239 if (vars->phy_flags & PHY_XGXS_FLAG) {
3240 ext_phy_addr = ((params->ext_phy_config &
3241 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3242 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3244 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3245 /* Make sure that the soft reset is off (expect for the 8072:
3246 * due to the lock, it will be done inside the specific
3249 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3250 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3251 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
3252 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
3253 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
3254 /* Wait for soft reset to get cleared upto 1 sec */
3255 for (cnt = 0; cnt < 1000; cnt++) {
3256 bnx2x_cl45_read(bp, params->port,
3260 MDIO_PMA_REG_CTRL, &ctrl);
3261 if (!(ctrl & (1<<15)))
3265 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
3269 switch (ext_phy_type) {
3270 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3273 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3274 DP(NETIF_MSG_LINK, "XGXS 8705\n");
3276 bnx2x_cl45_write(bp, params->port,
3280 MDIO_PMA_REG_MISC_CTRL,
3282 bnx2x_cl45_write(bp, params->port,
3286 MDIO_PMA_REG_PHY_IDENTIFIER,
3288 bnx2x_cl45_write(bp, params->port,
3292 MDIO_PMA_REG_CMU_PLL_BYPASS,
3294 bnx2x_cl45_write(bp, params->port,
3298 MDIO_WIS_REG_LASI_CNTL, 0x1);
3300 /* BCM8705 doesn't have microcode, hence the 0 */
3301 bnx2x_save_spirom_version(bp, params->port,
3302 params->shmem_base, 0);
3305 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3306 /* Wait until fw is loaded */
3307 for (cnt = 0; cnt < 100; cnt++) {
3308 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3309 ext_phy_addr, MDIO_PMA_DEVAD,
3310 MDIO_PMA_REG_ROM_VER1, &val);
3315 DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
3316 "after %d ms\n", cnt);
3317 if ((params->feature_config_flags &
3318 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3321 for (i = 0; i < 4; i++) {
3322 reg = MDIO_XS_8706_REG_BANK_RX0 +
3323 i*(MDIO_XS_8706_REG_BANK_RX1 -
3324 MDIO_XS_8706_REG_BANK_RX0);
3325 bnx2x_cl45_read(bp, params->port,
3330 /* Clear first 3 bits of the control */
3332 /* Set control bits according to
3334 val |= (params->xgxs_config_rx[i] &
3336 DP(NETIF_MSG_LINK, "Setting RX"
3337 "Equalizer to BCM8706 reg 0x%x"
3338 " <-- val 0x%x\n", reg, val);
3339 bnx2x_cl45_write(bp, params->port,
3347 /* First enable LASI */
3348 bnx2x_cl45_write(bp, params->port,
3352 MDIO_PMA_REG_RX_ALARM_CTRL,
3354 bnx2x_cl45_write(bp, params->port,
3358 MDIO_PMA_REG_LASI_CTRL, 0x0004);
3360 if (params->req_line_speed == SPEED_10000) {
3361 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
3363 bnx2x_cl45_write(bp, params->port,
3367 MDIO_PMA_REG_DIGITAL_CTRL,
3370 /* Force 1Gbps using autoneg with 1G
3373 /* Allow CL37 through CL73 */
3374 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
3375 bnx2x_cl45_write(bp, params->port,
3379 MDIO_AN_REG_CL37_CL73,
3382 /* Enable Full-Duplex advertisment on CL37 */
3383 bnx2x_cl45_write(bp, params->port,
3387 MDIO_AN_REG_CL37_FC_LP,
3389 /* Enable CL37 AN */
3390 bnx2x_cl45_write(bp, params->port,
3394 MDIO_AN_REG_CL37_AN,
3397 bnx2x_cl45_write(bp, params->port,
3401 MDIO_AN_REG_ADV, (1<<5));
3403 /* Enable clause 73 AN */
3404 bnx2x_cl45_write(bp, params->port,
3412 bnx2x_save_bcm_spirom_ver(bp, params->port,
3415 params->shmem_base);
3417 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3418 DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3419 bnx2x_bcm8726_external_rom_boot(params);
3421 /* Need to call module detected on initialization since
3422 the module detection triggered by actual module
3423 insertion might occur before driver is loaded, and when
3424 driver is loaded, it reset all registers, including the
3426 bnx2x_sfp_module_detection(params);
3428 /* Set Flow control */
3429 bnx2x_ext_phy_set_pause(params, vars);
3430 if (params->req_line_speed == SPEED_1000) {
3431 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3432 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3433 ext_phy_addr, MDIO_PMA_DEVAD,
3434 MDIO_PMA_REG_CTRL, 0x40);
3435 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3436 ext_phy_addr, MDIO_PMA_DEVAD,
3437 MDIO_PMA_REG_10G_CTRL2, 0xD);
3438 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3439 ext_phy_addr, MDIO_PMA_DEVAD,
3440 MDIO_PMA_REG_LASI_CTRL, 0x5);
3441 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3442 ext_phy_addr, MDIO_PMA_DEVAD,
3443 MDIO_PMA_REG_RX_ALARM_CTRL,
3445 } else if ((params->req_line_speed ==
3447 ((params->speed_cap_mask &
3448 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3449 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
3450 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3451 ext_phy_addr, MDIO_AN_DEVAD,
3452 MDIO_AN_REG_ADV, 0x20);
3453 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3454 ext_phy_addr, MDIO_AN_DEVAD,
3455 MDIO_AN_REG_CL37_CL73, 0x040c);
3456 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3457 ext_phy_addr, MDIO_AN_DEVAD,
3458 MDIO_AN_REG_CL37_FC_LD, 0x0020);
3459 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3460 ext_phy_addr, MDIO_AN_DEVAD,
3461 MDIO_AN_REG_CL37_AN, 0x1000);
3462 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3463 ext_phy_addr, MDIO_AN_DEVAD,
3464 MDIO_AN_REG_CTRL, 0x1200);
3466 /* Enable RX-ALARM control to receive
3467 interrupt for 1G speed change */
3468 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3469 ext_phy_addr, MDIO_PMA_DEVAD,
3470 MDIO_PMA_REG_LASI_CTRL, 0x4);
3471 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3472 ext_phy_addr, MDIO_PMA_DEVAD,
3473 MDIO_PMA_REG_RX_ALARM_CTRL,
3476 } else { /* Default 10G. Set only LASI control */
3477 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3478 ext_phy_addr, MDIO_PMA_DEVAD,
3479 MDIO_PMA_REG_LASI_CTRL, 1);
3482 /* Set TX PreEmphasis if needed */
3483 if ((params->feature_config_flags &
3484 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3485 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
3487 params->xgxs_config_tx[0],
3488 params->xgxs_config_tx[1]);
3489 bnx2x_cl45_write(bp, params->port,
3493 MDIO_PMA_REG_8726_TX_CTRL1,
3494 params->xgxs_config_tx[0]);
3496 bnx2x_cl45_write(bp, params->port,
3500 MDIO_PMA_REG_8726_TX_CTRL2,
3501 params->xgxs_config_tx[1]);
3504 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3505 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3508 u16 rx_alarm_ctrl_val;
3511 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3512 rx_alarm_ctrl_val = 0x400;
3513 lasi_ctrl_val = 0x0004;
3515 rx_alarm_ctrl_val = (1<<2);
3516 lasi_ctrl_val = 0x0004;
3520 bnx2x_cl45_write(bp, params->port,
3524 MDIO_PMA_REG_RX_ALARM_CTRL,
3527 bnx2x_cl45_write(bp, params->port,
3531 MDIO_PMA_REG_LASI_CTRL,
3534 bnx2x_8073_set_pause_cl37(params, vars);
3537 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
3538 bnx2x_bcm8072_external_rom_boot(params);
3541 /* In case of 8073 with long xaui lines,
3542 don't set the 8073 xaui low power*/
3543 bnx2x_bcm8073_set_xaui_low_power_mode(params);
3546 bnx2x_cl45_read(bp, params->port,
3550 MDIO_PMA_REG_M8051_MSGOUT_REG,
3553 bnx2x_cl45_read(bp, params->port,
3557 MDIO_PMA_REG_RX_ALARM, &tmp1);
3559 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
3562 /* If this is forced speed, set to KR or KX
3563 * (all other are not supported)
3565 if (params->loopback_mode == LOOPBACK_EXT) {
3566 bnx2x_bcm807x_force_10G(params);
3568 "Forced speed 10G on 807X\n");
3571 bnx2x_cl45_write(bp, params->port,
3572 ext_phy_type, ext_phy_addr,
3574 MDIO_PMA_REG_BCM_CTRL,
3577 if (params->req_line_speed != SPEED_AUTO_NEG) {
3578 if (params->req_line_speed == SPEED_10000) {
3580 } else if (params->req_line_speed ==
3583 /* Note that 2.5G works only
3584 when used with 1G advertisment */
3590 if (params->speed_cap_mask &
3591 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3594 /* Note that 2.5G works only when
3595 used with 1G advertisment */
3596 if (params->speed_cap_mask &
3597 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
3598 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
3601 "807x autoneg val = 0x%x\n", val);
3604 bnx2x_cl45_write(bp, params->port,
3608 MDIO_AN_REG_ADV, val);
3611 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3613 bnx2x_cl45_read(bp, params->port,
3617 MDIO_AN_REG_8073_2_5G, &tmp1);
3619 if (((params->speed_cap_mask &
3620 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
3621 (params->req_line_speed ==
3623 (params->req_line_speed ==
3626 /* Allow 2.5G for A1 and above */
3627 bnx2x_cl45_read(bp, params->port,
3628 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
3631 MDIO_PMA_REG_8073_CHIP_REV, &phy_ver);
3632 DP(NETIF_MSG_LINK, "Add 2.5G\n");
3638 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
3642 bnx2x_cl45_write(bp, params->port,
3646 MDIO_AN_REG_8073_2_5G, tmp1);
3649 /* Add support for CL37 (passive mode) II */
3651 bnx2x_cl45_read(bp, params->port,
3655 MDIO_AN_REG_CL37_FC_LD,
3658 bnx2x_cl45_write(bp, params->port,
3662 MDIO_AN_REG_CL37_FC_LD, (tmp1 |
3663 ((params->req_duplex == DUPLEX_FULL) ?
3666 /* Add support for CL37 (passive mode) III */
3667 bnx2x_cl45_write(bp, params->port,
3671 MDIO_AN_REG_CL37_AN, 0x1000);
3674 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3675 /* The SNR will improve about 2db by changing
3676 BW and FEE main tap. Rest commands are executed
3678 /*Change FFE main cursor to 5 in EDC register*/
3679 if (bnx2x_8073_is_snr_needed(params))
3680 bnx2x_cl45_write(bp, params->port,
3684 MDIO_PMA_REG_EDC_FFE_MAIN,
3687 /* Enable FEC (Forware Error Correction)
3688 Request in the AN */
3689 bnx2x_cl45_read(bp, params->port,
3693 MDIO_AN_REG_ADV2, &tmp1);
3697 bnx2x_cl45_write(bp, params->port,
3701 MDIO_AN_REG_ADV2, tmp1);
3705 bnx2x_ext_phy_set_pause(params, vars);
3707 /* Restart autoneg */
3709 bnx2x_cl45_write(bp, params->port,
3713 MDIO_AN_REG_CTRL, 0x1200);
3714 DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
3715 "Advertise 1G=%x, 10G=%x\n",
3716 ((val & (1<<5)) > 0),
3717 ((val & (1<<7)) > 0));
3721 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
3724 u16 rx_alarm_ctrl_val;
3727 /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
3730 rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
3731 lasi_ctrl_val = 0x0004;
3733 DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
3735 bnx2x_cl45_write(bp, params->port,
3739 MDIO_PMA_REG_RX_ALARM_CTRL,
3742 bnx2x_cl45_write(bp, params->port,
3746 MDIO_PMA_REG_LASI_CTRL,
3749 /* Initially configure MOD_ABS to interrupt when
3750 module is presence( bit 8) */
3751 bnx2x_cl45_read(bp, params->port,
3755 MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
3756 /* Set EDC off by setting OPTXLOS signal input to low
3758 When the EDC is off it locks onto a reference clock and
3759 avoids becoming 'lost'.*/
3760 mod_abs &= ~((1<<8) | (1<<9));
3761 bnx2x_cl45_write(bp, params->port,
3765 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
3767 /* Make MOD_ABS give interrupt on change */
3768 bnx2x_cl45_read(bp, params->port,
3772 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
3775 bnx2x_cl45_write(bp, params->port,
3779 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
3782 /* Set 8727 GPIOs to input to allow reading from the
3783 8727 GPIO0 status which reflect SFP+ module
3786 bnx2x_cl45_read(bp, params->port,
3787 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3790 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
3792 val &= 0xff8f; /* Reset bits 4-6 */
3793 bnx2x_cl45_write(bp, params->port,
3794 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3797 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
3800 bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
3801 bnx2x_bcm8073_set_xaui_low_power_mode(params);
3803 bnx2x_cl45_read(bp, params->port,
3807 MDIO_PMA_REG_M8051_MSGOUT_REG,
3810 bnx2x_cl45_read(bp, params->port,
3814 MDIO_PMA_REG_RX_ALARM, &tmp1);
3816 /* Set option 1G speed */
3817 if (params->req_line_speed == SPEED_1000) {
3819 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3820 bnx2x_cl45_write(bp, params->port,
3824 MDIO_PMA_REG_CTRL, 0x40);
3825 bnx2x_cl45_write(bp, params->port,
3829 MDIO_PMA_REG_10G_CTRL2, 0xD);
3830 bnx2x_cl45_read(bp, params->port,
3834 MDIO_PMA_REG_10G_CTRL2, &tmp1);
3835 DP(NETIF_MSG_LINK, "1.7 = 0x%x \n", tmp1);
3837 } else if ((params->req_line_speed ==
3839 ((params->speed_cap_mask &
3840 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3842 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
3843 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3844 ext_phy_addr, MDIO_AN_DEVAD,
3845 MDIO_PMA_REG_8727_MISC_CTRL, 0);
3846 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3847 ext_phy_addr, MDIO_AN_DEVAD,
3848 MDIO_AN_REG_CL37_AN, 0x1300);
3850 /* Since the 8727 has only single reset pin,
3851 need to set the 10G registers although it is
3853 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3854 ext_phy_addr, MDIO_AN_DEVAD,
3855 MDIO_AN_REG_CTRL, 0x0020);
3856 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3857 ext_phy_addr, MDIO_AN_DEVAD,
3859 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3860 ext_phy_addr, MDIO_PMA_DEVAD,
3861 MDIO_PMA_REG_CTRL, 0x2040);
3862 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3863 ext_phy_addr, MDIO_PMA_DEVAD,
3864 MDIO_PMA_REG_10G_CTRL2, 0x0008);
3867 /* Set 2-wire transfer rate to 400Khz since 100Khz
3868 is not operational */
3869 bnx2x_cl45_write(bp, params->port,
3873 MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
3876 /* Set TX PreEmphasis if needed */
3877 if ((params->feature_config_flags &
3878 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3879 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
3881 params->xgxs_config_tx[0],
3882 params->xgxs_config_tx[1]);
3883 bnx2x_cl45_write(bp, params->port,
3887 MDIO_PMA_REG_8727_TX_CTRL1,
3888 params->xgxs_config_tx[0]);
3890 bnx2x_cl45_write(bp, params->port,
3894 MDIO_PMA_REG_8727_TX_CTRL2,
3895 params->xgxs_config_tx[1]);
3901 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3903 u16 fw_ver1, fw_ver2;
3905 "Setting the SFX7101 LASI indication\n");
3907 bnx2x_cl45_write(bp, params->port,
3911 MDIO_PMA_REG_LASI_CTRL, 0x1);
3913 "Setting the SFX7101 LED to blink on traffic\n");
3914 bnx2x_cl45_write(bp, params->port,
3918 MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
3920 bnx2x_ext_phy_set_pause(params, vars);
3921 /* Restart autoneg */
3922 bnx2x_cl45_read(bp, params->port,
3926 MDIO_AN_REG_CTRL, &val);
3928 bnx2x_cl45_write(bp, params->port,
3932 MDIO_AN_REG_CTRL, val);
3934 /* Save spirom version */
3935 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3936 ext_phy_addr, MDIO_PMA_DEVAD,
3937 MDIO_PMA_REG_7101_VER1, &fw_ver1);
3939 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3940 ext_phy_addr, MDIO_PMA_DEVAD,
3941 MDIO_PMA_REG_7101_VER2, &fw_ver2);
3943 bnx2x_save_spirom_version(params->bp, params->port,
3945 (u32)(fw_ver1<<16 | fw_ver2));
3949 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
3951 "Setting the BCM8481 LASI control\n");
3953 bnx2x_cl45_write(bp, params->port,
3957 MDIO_PMA_REG_LASI_CTRL, 0x1);
3959 /* Restart autoneg */
3960 bnx2x_cl45_read(bp, params->port,
3964 MDIO_AN_REG_CTRL, &val);
3966 bnx2x_cl45_write(bp, params->port,
3970 MDIO_AN_REG_CTRL, val);
3972 bnx2x_save_bcm_spirom_ver(bp, params->port,
3975 params->shmem_base);
3978 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
3980 "XGXS PHY Failure detected 0x%x\n",
3981 params->ext_phy_config);
3985 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3986 params->ext_phy_config);
3991 } else { /* SerDes */
3993 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3994 switch (ext_phy_type) {
3995 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3996 DP(NETIF_MSG_LINK, "SerDes Direct\n");
3999 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
4000 DP(NETIF_MSG_LINK, "SerDes 5482\n");
4004 DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
4005 params->ext_phy_config);
4012 static void bnx2x_8727_handle_mod_abs(struct link_params *params)
4014 struct bnx2x *bp = params->bp;
4015 u16 mod_abs, rx_alarm_status;
4016 u8 ext_phy_addr = ((params->ext_phy_config &
4017 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4018 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4019 u32 val = REG_RD(bp, params->shmem_base +
4020 offsetof(struct shmem_region, dev_info.
4021 port_feature_config[params->port].
4023 bnx2x_cl45_read(bp, params->port,
4024 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4027 MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
4028 if (mod_abs & (1<<8)) {
4030 /* Module is absent */
4031 DP(NETIF_MSG_LINK, "MOD_ABS indication "
4032 "show module is absent\n");
4034 /* 1. Set mod_abs to detect next module
4036 2. Set EDC off by setting OPTXLOS signal input to low
4038 When the EDC is off it locks onto a reference clock and
4039 avoids becoming 'lost'.*/
4040 mod_abs &= ~((1<<8)|(1<<9));
4041 bnx2x_cl45_write(bp, params->port,
4042 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4045 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4047 /* Clear RX alarm since it stays up as long as
4048 the mod_abs wasn't changed */
4049 bnx2x_cl45_read(bp, params->port,
4050 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4053 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4056 /* Module is present */
4057 DP(NETIF_MSG_LINK, "MOD_ABS indication "
4058 "show module is present\n");
4059 /* First thing, disable transmitter,
4060 and if the module is ok, the
4061 module_detection will enable it*/
4063 /* 1. Set mod_abs to detect next module
4064 absent event ( bit 8)
4065 2. Restore the default polarity of the OPRXLOS signal and
4066 this signal will then correctly indicate the presence or
4067 absence of the Rx signal. (bit 9) */
4068 mod_abs |= ((1<<8)|(1<<9));
4069 bnx2x_cl45_write(bp, params->port,
4070 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4073 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4075 /* Clear RX alarm since it stays up as long as
4076 the mod_abs wasn't changed. This is need to be done
4077 before calling the module detection, otherwise it will clear
4078 the link update alarm */
4079 bnx2x_cl45_read(bp, params->port,
4080 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4083 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4086 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
4087 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
4088 bnx2x_sfp_set_transmitter(bp, params->port,
4089 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4092 if (bnx2x_wait_for_sfp_module_initialized(params)
4094 bnx2x_sfp_module_detection(params);
4096 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
4099 DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
4101 /* No need to check link status in case of
4102 module plugged in/out */
4106 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
4107 struct link_vars *vars)
4109 struct bnx2x *bp = params->bp;
4113 u16 rx_sd, pcs_status;
4114 u8 ext_phy_link_up = 0;
4115 u8 port = params->port;
4116 if (vars->phy_flags & PHY_XGXS_FLAG) {
4117 ext_phy_addr = ((params->ext_phy_config &
4118 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4119 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4121 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4122 switch (ext_phy_type) {
4123 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4124 DP(NETIF_MSG_LINK, "XGXS Direct\n");
4125 ext_phy_link_up = 1;
4128 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4129 DP(NETIF_MSG_LINK, "XGXS 8705\n");
4130 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4133 MDIO_WIS_REG_LASI_STATUS, &val1);
4134 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4136 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4139 MDIO_WIS_REG_LASI_STATUS, &val1);
4140 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4142 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4145 MDIO_PMA_REG_RX_SD, &rx_sd);
4147 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4151 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4156 DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
4157 ext_phy_link_up = ((rx_sd & 0x1) && (val1 & (1<<9))
4158 && ((val1 & (1<<8)) == 0));
4159 if (ext_phy_link_up)
4160 vars->line_speed = SPEED_10000;
4163 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4164 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4165 DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
4167 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4169 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
4171 /* clear LASI indication*/
4172 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4174 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
4176 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4178 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
4180 DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
4181 "0x%x\n", val1, val2);
4183 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4185 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
4187 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4189 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
4191 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4193 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
4195 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4197 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
4200 DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
4201 " pcs_status 0x%x 1Gbps link_status 0x%x\n",
4202 rx_sd, pcs_status, val2);
4203 /* link is up if both bit 0 of pmd_rx_sd and
4204 * bit 0 of pcs_status are set, or if the autoneg bit
4207 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
4209 if (ext_phy_link_up) {
4211 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
4212 /* If transmitter is disabled,
4213 ignore false link up indication */
4214 bnx2x_cl45_read(bp, params->port,
4218 MDIO_PMA_REG_PHY_IDENTIFIER,
4220 if (val1 & (1<<15)) {
4221 DP(NETIF_MSG_LINK, "Tx is "
4223 ext_phy_link_up = 0;
4229 vars->line_speed = SPEED_1000;
4231 vars->line_speed = SPEED_10000;
4235 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
4237 u16 link_status = 0;
4238 u16 rx_alarm_status;
4239 /* Check the LASI */
4240 bnx2x_cl45_read(bp, params->port,
4244 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4246 DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
4249 bnx2x_cl45_read(bp, params->port,
4253 MDIO_PMA_REG_LASI_STATUS, &val1);
4256 "8727 LASI status 0x%x\n",
4260 bnx2x_cl45_read(bp, params->port,
4264 MDIO_PMA_REG_M8051_MSGOUT_REG,
4268 * If a module is present and there is need to check
4271 if (!(params->feature_config_flags &
4272 FEATURE_CONFIG_BCM8727_NOC) &&
4273 !(rx_alarm_status & (1<<5))) {
4274 /* Check over-current using 8727 GPIO0 input*/
4275 bnx2x_cl45_read(bp, params->port,
4279 MDIO_PMA_REG_8727_GPIO_CTRL,
4282 if ((val1 & (1<<8)) == 0) {
4283 DP(NETIF_MSG_LINK, "8727 Power fault"
4284 " has been detected on port"
4285 " %d\n", params->port);
4286 printk(KERN_ERR PFX "Error: Power"
4287 " fault on %s Port %d has"
4288 " been detected and the"
4289 " power to that SFP+ module"
4290 " has been removed to prevent"
4291 " failure of the card. Please"
4292 " remove the SFP+ module and"
4293 " restart the system to clear"
4295 , bp->dev->name, params->port);
4297 * Disable all RX_ALARMs except for
4300 bnx2x_cl45_write(bp, params->port,
4304 MDIO_PMA_REG_RX_ALARM_CTRL,
4307 bnx2x_cl45_read(bp, params->port,
4311 MDIO_PMA_REG_PHY_IDENTIFIER,
4313 /* Wait for module_absent_event */
4315 bnx2x_cl45_write(bp, params->port,
4319 MDIO_PMA_REG_PHY_IDENTIFIER,
4321 /* Clear RX alarm */
4322 bnx2x_cl45_read(bp, params->port,
4326 MDIO_PMA_REG_RX_ALARM,
4330 } /* Over current check */
4332 /* When module absent bit is set, check module */
4333 if (rx_alarm_status & (1<<5)) {
4334 bnx2x_8727_handle_mod_abs(params);
4335 /* Enable all mod_abs and link detection bits */
4336 bnx2x_cl45_write(bp, params->port,
4340 MDIO_PMA_REG_RX_ALARM_CTRL,
4344 /* If transmitter is disabled,
4345 ignore false link up indication */
4346 bnx2x_cl45_read(bp, params->port,
4350 MDIO_PMA_REG_PHY_IDENTIFIER,
4352 if (val1 & (1<<15)) {
4353 DP(NETIF_MSG_LINK, "Tx is disabled\n");
4354 ext_phy_link_up = 0;
4358 bnx2x_cl45_read(bp, params->port,
4362 MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
4365 /* Bits 0..2 --> speed detected,
4366 bits 13..15--> link is down */
4367 if ((link_status & (1<<2)) &&
4368 (!(link_status & (1<<15)))) {
4369 ext_phy_link_up = 1;
4370 vars->line_speed = SPEED_10000;
4371 } else if ((link_status & (1<<0)) &&
4372 (!(link_status & (1<<13)))) {
4373 ext_phy_link_up = 1;
4374 vars->line_speed = SPEED_1000;
4376 "port %x: External link"
4377 " up in 1G\n", params->port);
4379 ext_phy_link_up = 0;
4381 "port %x: External link"
4382 " is down\n", params->port);
4387 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4388 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4390 u16 link_status = 0;
4391 u16 an1000_status = 0;
4393 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
4394 bnx2x_cl45_read(bp, params->port,
4398 MDIO_PCS_REG_LASI_STATUS, &val1);
4399 bnx2x_cl45_read(bp, params->port,
4403 MDIO_PCS_REG_LASI_STATUS, &val2);
4405 "870x LASI status 0x%x->0x%x\n",
4409 /* In 8073, port1 is directed through emac0 and
4410 * port0 is directed through emac1
4412 bnx2x_cl45_read(bp, params->port,
4416 MDIO_PMA_REG_LASI_STATUS, &val1);
4419 "8703 LASI status 0x%x\n",
4423 /* clear the interrupt LASI status register */
4424 bnx2x_cl45_read(bp, params->port,
4428 MDIO_PCS_REG_STATUS, &val2);
4429 bnx2x_cl45_read(bp, params->port,
4433 MDIO_PCS_REG_STATUS, &val1);
4434 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
4437 bnx2x_cl45_read(bp, params->port,
4441 MDIO_PMA_REG_M8051_MSGOUT_REG,
4444 /* Check the LASI */
4445 bnx2x_cl45_read(bp, params->port,
4449 MDIO_PMA_REG_RX_ALARM, &val2);
4451 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
4453 /* Check the link status */
4454 bnx2x_cl45_read(bp, params->port,
4458 MDIO_PCS_REG_STATUS, &val2);
4459 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
4461 bnx2x_cl45_read(bp, params->port,
4465 MDIO_PMA_REG_STATUS, &val2);
4466 bnx2x_cl45_read(bp, params->port,
4470 MDIO_PMA_REG_STATUS, &val1);
4471 ext_phy_link_up = ((val1 & 4) == 4);
4472 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
4474 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4476 if (ext_phy_link_up &&
4477 ((params->req_line_speed !=
4479 if (bnx2x_bcm8073_xaui_wa(params)
4481 ext_phy_link_up = 0;
4485 bnx2x_cl45_read(bp, params->port,
4489 MDIO_AN_REG_LINK_STATUS,
4491 bnx2x_cl45_read(bp, params->port,
4495 MDIO_AN_REG_LINK_STATUS,
4498 /* Check the link status on 1.1.2 */
4499 bnx2x_cl45_read(bp, params->port,
4503 MDIO_PMA_REG_STATUS, &val2);
4504 bnx2x_cl45_read(bp, params->port,
4508 MDIO_PMA_REG_STATUS, &val1);
4509 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
4510 "an_link_status=0x%x\n",
4511 val2, val1, an1000_status);
4513 ext_phy_link_up = (((val1 & 4) == 4) ||
4514 (an1000_status & (1<<1)));
4515 if (ext_phy_link_up &&
4516 bnx2x_8073_is_snr_needed(params)) {
4517 /* The SNR will improve about 2dbby
4518 changing the BW and FEE main tap.*/
4520 /* The 1st write to change FFE main
4521 tap is set before restart AN */
4522 /* Change PLL Bandwidth in EDC
4524 bnx2x_cl45_write(bp, port, ext_phy_type,
4527 MDIO_PMA_REG_PLL_BANDWIDTH,
4530 /* Change CDR Bandwidth in EDC
4532 bnx2x_cl45_write(bp, port, ext_phy_type,
4535 MDIO_PMA_REG_CDR_BANDWIDTH,
4540 bnx2x_cl45_read(bp, params->port,
4544 MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
4547 /* Bits 0..2 --> speed detected,
4548 bits 13..15--> link is down */
4549 if ((link_status & (1<<2)) &&
4550 (!(link_status & (1<<15)))) {
4551 ext_phy_link_up = 1;
4552 vars->line_speed = SPEED_10000;
4554 "port %x: External link"
4555 " up in 10G\n", params->port);
4556 } else if ((link_status & (1<<1)) &&
4557 (!(link_status & (1<<14)))) {
4558 ext_phy_link_up = 1;
4559 vars->line_speed = SPEED_2500;
4561 "port %x: External link"
4562 " up in 2.5G\n", params->port);
4563 } else if ((link_status & (1<<0)) &&
4564 (!(link_status & (1<<13)))) {
4565 ext_phy_link_up = 1;
4566 vars->line_speed = SPEED_1000;
4568 "port %x: External link"
4569 " up in 1G\n", params->port);
4571 ext_phy_link_up = 0;
4573 "port %x: External link"
4574 " is down\n", params->port);
4577 /* See if 1G link is up for the 8072 */
4578 bnx2x_cl45_read(bp, params->port,
4582 MDIO_AN_REG_LINK_STATUS,
4584 bnx2x_cl45_read(bp, params->port,
4588 MDIO_AN_REG_LINK_STATUS,
4590 if (an1000_status & (1<<1)) {
4591 ext_phy_link_up = 1;
4592 vars->line_speed = SPEED_1000;
4594 "port %x: External link"
4595 " up in 1G\n", params->port);
4596 } else if (ext_phy_link_up) {
4597 ext_phy_link_up = 1;
4598 vars->line_speed = SPEED_10000;
4600 "port %x: External link"
4601 " up in 10G\n", params->port);
4608 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4609 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4612 MDIO_PMA_REG_LASI_STATUS, &val2);
4613 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4616 MDIO_PMA_REG_LASI_STATUS, &val1);
4618 "10G-base-T LASI status 0x%x->0x%x\n",
4620 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4623 MDIO_PMA_REG_STATUS, &val2);
4624 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4627 MDIO_PMA_REG_STATUS, &val1);
4629 "10G-base-T PMA status 0x%x->0x%x\n",
4631 ext_phy_link_up = ((val1 & 4) == 4);
4633 * print the AN outcome of the SFX7101 PHY
4635 if (ext_phy_link_up) {
4636 bnx2x_cl45_read(bp, params->port,
4640 MDIO_AN_REG_MASTER_STATUS,
4642 vars->line_speed = SPEED_10000;
4644 "SFX7101 AN status 0x%x->Master=%x\n",
4649 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
4650 /* Clear LASI interrupt */
4651 bnx2x_cl45_read(bp, params->port,
4655 MDIO_PMA_REG_LASI_STATUS, &val1);
4656 DP(NETIF_MSG_LINK, "8481 LASI status reg = 0x%x\n",
4659 /* Check 10G-BaseT link status */
4660 /* Check Global PMD signal ok */
4661 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4663 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
4665 /* Check PCS block lock */
4666 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4668 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
4670 DP(NETIF_MSG_LINK, "8481 1.a = 0x%x, 1.20 = 0x%x\n",
4672 if (rx_sd & pcs_status & 0x1) {
4673 vars->line_speed = SPEED_10000;
4674 ext_phy_link_up = 1;
4677 /* Check 1000-BaseT link status */
4678 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4680 MDIO_AN_DEVAD, 0xFFE1,
4683 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4685 MDIO_AN_DEVAD, 0xFFE1,
4687 DP(NETIF_MSG_LINK, "8481 7.FFE1 ="
4688 "0x%x-->0x%x\n", val1, val2);
4689 if (val2 & (1<<2)) {
4690 vars->line_speed = SPEED_1000;
4691 ext_phy_link_up = 1;
4697 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
4698 params->ext_phy_config);
4699 ext_phy_link_up = 0;
4703 } else { /* SerDes */
4704 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4705 switch (ext_phy_type) {
4706 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
4707 DP(NETIF_MSG_LINK, "SerDes Direct\n");
4708 ext_phy_link_up = 1;
4711 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
4712 DP(NETIF_MSG_LINK, "SerDes 5482\n");
4713 ext_phy_link_up = 1;
4718 "BAD SerDes ext_phy_config 0x%x\n",
4719 params->ext_phy_config);
4720 ext_phy_link_up = 0;
4725 return ext_phy_link_up;
4728 static void bnx2x_link_int_enable(struct link_params *params)
4730 u8 port = params->port;
4733 struct bnx2x *bp = params->bp;
4734 /* setting the status to report on link up
4735 for either XGXS or SerDes */
4737 if (params->switch_cfg == SWITCH_CFG_10G) {
4738 mask = (NIG_MASK_XGXS0_LINK10G |
4739 NIG_MASK_XGXS0_LINK_STATUS);
4740 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
4741 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4742 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
4743 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
4745 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
4746 mask |= NIG_MASK_MI_INT;
4747 DP(NETIF_MSG_LINK, "enabled external phy int\n");
4750 } else { /* SerDes */
4751 mask = NIG_MASK_SERDES0_LINK_STATUS;
4752 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
4753 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4754 if ((ext_phy_type !=
4755 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4757 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
4758 mask |= NIG_MASK_MI_INT;
4759 DP(NETIF_MSG_LINK, "enabled external phy int\n");
4763 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4765 DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
4766 (params->switch_cfg == SWITCH_CFG_10G),
4767 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4769 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
4770 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4771 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4772 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
4773 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4774 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4775 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4782 static void bnx2x_link_int_ack(struct link_params *params,
4783 struct link_vars *vars, u8 is_10g)
4785 struct bnx2x *bp = params->bp;
4786 u8 port = params->port;
4788 /* first reset all status
4789 * we assume only one line will be change at a time */
4790 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4791 (NIG_STATUS_XGXS0_LINK10G |
4792 NIG_STATUS_XGXS0_LINK_STATUS |
4793 NIG_STATUS_SERDES0_LINK_STATUS));
4794 if (vars->phy_link_up) {
4796 /* Disable the 10G link interrupt
4797 * by writing 1 to the status register
4799 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
4801 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4802 NIG_STATUS_XGXS0_LINK10G);
4804 } else if (params->switch_cfg == SWITCH_CFG_10G) {
4805 /* Disable the link interrupt
4806 * by writing 1 to the relevant lane
4807 * in the status register
4809 u32 ser_lane = ((params->lane_config &
4810 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4811 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4813 DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
4815 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4817 NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
4819 } else { /* SerDes */
4820 DP(NETIF_MSG_LINK, "SerDes phy link up\n");
4821 /* Disable the link interrupt
4822 * by writing 1 to the status register
4825 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4826 NIG_STATUS_SERDES0_LINK_STATUS);
4829 } else { /* link_down */
4833 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
4836 u32 mask = 0xf0000000;
4840 /* Need more than 10chars for this format */
4847 digit = ((num & mask) >> shift);
4849 *str_ptr = digit + '0';
4851 *str_ptr = digit - 0xa + 'a';
4864 static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
4869 /* Enable EMAC0 in to enable MDIO */
4870 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
4871 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
4874 /* take ext phy out of reset */
4876 MISC_REGISTERS_GPIO_2,
4877 MISC_REGISTERS_GPIO_HIGH,
4881 MISC_REGISTERS_GPIO_1,
4882 MISC_REGISTERS_GPIO_HIGH,
4888 for (cnt = 0; cnt < 1000; cnt++) {
4890 bnx2x_cl45_read(bp, port,
4896 if (!(ctrl & (1<<15))) {
4897 DP(NETIF_MSG_LINK, "Reset completed\n\n");
4903 static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
4905 /* put sf to reset */
4907 MISC_REGISTERS_GPIO_1,
4908 MISC_REGISTERS_GPIO_LOW,
4911 MISC_REGISTERS_GPIO_2,
4912 MISC_REGISTERS_GPIO_LOW,
4916 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
4917 u8 *version, u16 len)
4920 u32 ext_phy_type = 0;
4924 if (version == NULL || params == NULL)
4928 spirom_ver = REG_RD(bp, params->shmem_base +
4929 offsetof(struct shmem_region,
4930 port_mb[params->port].ext_phy_fw_version));
4932 /* reset the returned value to zero */
4933 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4934 switch (ext_phy_type) {
4935 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4940 version[0] = (spirom_ver & 0xFF);
4941 version[1] = (spirom_ver & 0xFF00) >> 8;
4942 version[2] = (spirom_ver & 0xFF0000) >> 16;
4943 version[3] = (spirom_ver & 0xFF000000) >> 24;
4947 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4948 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4949 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
4950 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4951 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4952 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4953 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
4954 status = bnx2x_format_ver(spirom_ver, version, len);
4956 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4959 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4960 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
4961 " type is FAILURE!\n");
4971 static void bnx2x_set_xgxs_loopback(struct link_params *params,
4972 struct link_vars *vars,
4975 u8 port = params->port;
4976 struct bnx2x *bp = params->bp;
4981 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
4983 /* change the uni_phy_addr in the nig */
4984 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
4987 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
4989 bnx2x_cl45_write(bp, port, 0,
4992 (MDIO_REG_BANK_AER_BLOCK +
4993 (MDIO_AER_BLOCK_AER_REG & 0xf)),
4996 bnx2x_cl45_write(bp, port, 0,
4999 (MDIO_REG_BANK_CL73_IEEEB0 +
5000 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
5003 /* set aer mmd back */
5004 bnx2x_set_aer_mmd(params, vars);
5007 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
5013 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
5015 CL45_RD_OVER_CL22(bp, port,
5017 MDIO_REG_BANK_COMBO_IEEE0,
5018 MDIO_COMBO_IEEE0_MII_CONTROL,
5021 CL45_WR_OVER_CL22(bp, port,
5023 MDIO_REG_BANK_COMBO_IEEE0,
5024 MDIO_COMBO_IEEE0_MII_CONTROL,
5026 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
5031 static void bnx2x_ext_phy_loopback(struct link_params *params)
5033 struct bnx2x *bp = params->bp;
5037 if (params->switch_cfg == SWITCH_CFG_10G) {
5038 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5039 /* CL37 Autoneg Enabled */
5040 ext_phy_addr = ((params->ext_phy_config &
5041 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5042 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5043 switch (ext_phy_type) {
5044 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5045 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
5047 "ext_phy_loopback: We should not get here\n");
5049 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5050 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
5052 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5053 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
5055 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5056 DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
5057 bnx2x_cl45_write(bp, params->port, ext_phy_type,
5063 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5064 /* SFX7101_XGXS_TEST1 */
5065 bnx2x_cl45_write(bp, params->port, ext_phy_type,
5068 MDIO_XS_SFX7101_XGXS_TEST1,
5071 "ext_phy_loopback: set ext phy loopback\n");
5073 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5076 } /* switch external PHY type */
5079 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
5080 ext_phy_addr = (params->ext_phy_config &
5081 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
5082 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
5088 *------------------------------------------------------------------------
5089 * bnx2x_override_led_value -
5091 * Override the led value of the requsted led
5093 *------------------------------------------------------------------------
5095 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
5096 u32 led_idx, u32 value)
5100 /* If port 0 then use EMAC0, else use EMAC1*/
5101 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5104 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
5105 port, led_idx, value);
5108 case 0: /* 10MB led */
5109 /* Read the current value of the LED register in
5111 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5112 /* Set the OVERRIDE bit to 1 */
5113 reg_val |= EMAC_LED_OVERRIDE;
5114 /* If value is 1, set the 10M_OVERRIDE bit,
5115 otherwise reset it.*/
5116 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
5117 (reg_val & ~EMAC_LED_10MB_OVERRIDE);
5118 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5120 case 1: /*100MB led */
5121 /*Read the current value of the LED register in
5123 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5124 /* Set the OVERRIDE bit to 1 */
5125 reg_val |= EMAC_LED_OVERRIDE;
5126 /* If value is 1, set the 100M_OVERRIDE bit,
5127 otherwise reset it.*/
5128 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
5129 (reg_val & ~EMAC_LED_100MB_OVERRIDE);
5130 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5132 case 2: /* 1000MB led */
5133 /* Read the current value of the LED register in the
5135 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5136 /* Set the OVERRIDE bit to 1 */
5137 reg_val |= EMAC_LED_OVERRIDE;
5138 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
5140 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
5141 (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
5142 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5144 case 3: /* 2500MB led */
5145 /* Read the current value of the LED register in the
5147 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5148 /* Set the OVERRIDE bit to 1 */
5149 reg_val |= EMAC_LED_OVERRIDE;
5150 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
5152 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
5153 (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
5154 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5156 case 4: /*10G led */
5158 REG_WR(bp, NIG_REG_LED_10G_P0,
5161 REG_WR(bp, NIG_REG_LED_10G_P1,
5165 case 5: /* TRAFFIC led */
5166 /* Find if the traffic control is via BMAC or EMAC */
5168 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
5170 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
5172 /* Override the traffic led in the EMAC:*/
5174 /* Read the current value of the LED register in
5176 reg_val = REG_RD(bp, emac_base +
5178 /* Set the TRAFFIC_OVERRIDE bit to 1 */
5179 reg_val |= EMAC_LED_OVERRIDE;
5180 /* If value is 1, set the TRAFFIC bit, otherwise
5182 reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
5183 (reg_val & ~EMAC_LED_TRAFFIC);
5184 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5185 } else { /* Override the traffic led in the BMAC: */
5186 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5188 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
5194 "bnx2x_override_led_value() unknown led index %d "
5195 "(should be 0-5)\n", led_idx);
5203 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
5204 u16 hw_led_mode, u32 chip_id)
5208 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5209 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
5210 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
5211 speed, hw_led_mode);
5214 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
5215 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
5216 SHARED_HW_CFG_LED_MAC1);
5218 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5219 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
5223 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
5224 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
5226 /* Set blinking rate to ~15.9Hz */
5227 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
5228 LED_BLINK_RATE_VAL);
5229 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
5231 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5232 EMAC_WR(bp, EMAC_REG_EMAC_LED,
5233 (tmp & (~EMAC_LED_OVERRIDE)));
5235 if (!CHIP_IS_E1H(bp) &&
5236 ((speed == SPEED_2500) ||
5237 (speed == SPEED_1000) ||
5238 (speed == SPEED_100) ||
5239 (speed == SPEED_10))) {
5240 /* On Everest 1 Ax chip versions for speeds less than
5241 10G LED scheme is different */
5242 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5244 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
5246 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
5253 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
5261 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
5263 struct bnx2x *bp = params->bp;
5266 CL45_RD_OVER_CL22(bp, params->port,
5268 MDIO_REG_BANK_GP_STATUS,
5269 MDIO_GP_STATUS_TOP_AN_STATUS1,
5271 /* link is up only if both local phy and external phy are up */
5272 if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
5273 bnx2x_ext_phy_is_link_up(params, vars))
5279 static u8 bnx2x_link_initialize(struct link_params *params,
5280 struct link_vars *vars)
5282 struct bnx2x *bp = params->bp;
5283 u8 port = params->port;
5286 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5287 /* Activate the external PHY */
5288 bnx2x_ext_phy_reset(params, vars);
5290 bnx2x_set_aer_mmd(params, vars);
5292 if (vars->phy_flags & PHY_XGXS_FLAG)
5293 bnx2x_set_master_ln(params);
5295 rc = bnx2x_reset_unicore(params);
5296 /* reset the SerDes and wait for reset bit return low */
5300 bnx2x_set_aer_mmd(params, vars);
5302 /* setting the masterLn_def again after the reset */
5303 if (vars->phy_flags & PHY_XGXS_FLAG) {
5304 bnx2x_set_master_ln(params);
5305 bnx2x_set_swap_lanes(params);
5308 if (vars->phy_flags & PHY_XGXS_FLAG) {
5309 if ((params->req_line_speed &&
5310 ((params->req_line_speed == SPEED_100) ||
5311 (params->req_line_speed == SPEED_10))) ||
5312 (!params->req_line_speed &&
5313 (params->speed_cap_mask >=
5314 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
5315 (params->speed_cap_mask <
5316 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
5318 vars->phy_flags |= PHY_SGMII_FLAG;
5320 vars->phy_flags &= ~PHY_SGMII_FLAG;
5323 /* In case of external phy existance, the line speed would be the
5324 line speed linked up by the external phy. In case it is direct only,
5325 then the line_speed during initialization will be equal to the
5327 vars->line_speed = params->req_line_speed;
5329 bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
5331 /* init ext phy and enable link state int */
5332 non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
5333 (params->loopback_mode == LOOPBACK_XGXS_10));
5336 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
5337 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
5338 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
5339 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
5340 if (params->req_line_speed == SPEED_AUTO_NEG)
5341 bnx2x_set_parallel_detection(params, vars->phy_flags);
5342 bnx2x_init_internal_phy(params, vars);
5346 rc |= bnx2x_ext_phy_init(params, vars);
5348 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5349 (NIG_STATUS_XGXS0_LINK10G |
5350 NIG_STATUS_XGXS0_LINK_STATUS |
5351 NIG_STATUS_SERDES0_LINK_STATUS));
5358 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
5360 struct bnx2x *bp = params->bp;
5363 DP(NETIF_MSG_LINK, "Phy Initialization started \n");
5364 DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
5365 params->req_line_speed, params->req_flow_ctrl);
5366 vars->link_status = 0;
5367 vars->phy_link_up = 0;
5369 vars->line_speed = 0;
5370 vars->duplex = DUPLEX_FULL;
5371 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5372 vars->mac_type = MAC_TYPE_NONE;
5374 if (params->switch_cfg == SWITCH_CFG_1G)
5375 vars->phy_flags = PHY_SERDES_FLAG;
5377 vars->phy_flags = PHY_XGXS_FLAG;
5380 /* disable attentions */
5381 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
5382 (NIG_MASK_XGXS0_LINK_STATUS |
5383 NIG_MASK_XGXS0_LINK10G |
5384 NIG_MASK_SERDES0_LINK_STATUS |
5387 bnx2x_emac_init(params, vars);
5389 if (CHIP_REV_IS_FPGA(bp)) {
5391 vars->line_speed = SPEED_10000;
5392 vars->duplex = DUPLEX_FULL;
5393 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5394 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
5395 /* enable on E1.5 FPGA */
5396 if (CHIP_IS_E1H(bp)) {
5398 (BNX2X_FLOW_CTRL_TX | BNX2X_FLOW_CTRL_RX);
5399 vars->link_status |=
5400 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
5401 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
5404 bnx2x_emac_enable(params, vars, 0);
5405 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
5407 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
5408 + params->port*4, 0);
5410 /* update shared memory */
5411 bnx2x_update_mng(params, vars->link_status);
5416 if (CHIP_REV_IS_EMUL(bp)) {
5419 vars->line_speed = SPEED_10000;
5420 vars->duplex = DUPLEX_FULL;
5421 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5422 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
5424 bnx2x_bmac_enable(params, vars, 0);
5426 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
5428 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
5429 + params->port*4, 0);
5431 /* update shared memory */
5432 bnx2x_update_mng(params, vars->link_status);
5437 if (params->loopback_mode == LOOPBACK_BMAC) {
5439 vars->line_speed = SPEED_10000;
5440 vars->duplex = DUPLEX_FULL;
5441 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5442 vars->mac_type = MAC_TYPE_BMAC;
5444 vars->phy_flags = PHY_XGXS_FLAG;
5446 bnx2x_phy_deassert(params, vars->phy_flags);
5447 /* set bmac loopback */
5448 bnx2x_bmac_enable(params, vars, 1);
5450 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
5452 } else if (params->loopback_mode == LOOPBACK_EMAC) {
5454 vars->line_speed = SPEED_1000;
5455 vars->duplex = DUPLEX_FULL;
5456 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5457 vars->mac_type = MAC_TYPE_EMAC;
5459 vars->phy_flags = PHY_XGXS_FLAG;
5461 bnx2x_phy_deassert(params, vars->phy_flags);
5462 /* set bmac loopback */
5463 bnx2x_emac_enable(params, vars, 1);
5464 bnx2x_emac_program(params, vars->line_speed,
5466 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
5468 } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
5469 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
5471 vars->line_speed = SPEED_10000;
5472 vars->duplex = DUPLEX_FULL;
5473 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5475 vars->phy_flags = PHY_XGXS_FLAG;
5478 NIG_REG_XGXS0_CTRL_PHY_ADDR+
5480 params->phy_addr = (u8)val;
5482 bnx2x_phy_deassert(params, vars->phy_flags);
5483 bnx2x_link_initialize(params, vars);
5485 vars->mac_type = MAC_TYPE_BMAC;
5487 bnx2x_bmac_enable(params, vars, 0);
5489 if (params->loopback_mode == LOOPBACK_XGXS_10) {
5490 /* set 10G XGXS loopback */
5491 bnx2x_set_xgxs_loopback(params, vars, 1);
5493 /* set external phy loopback */
5494 bnx2x_ext_phy_loopback(params);
5496 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
5499 bnx2x_set_led(bp, params->port, LED_MODE_OPER,
5500 vars->line_speed, params->hw_led_mode,
5507 bnx2x_phy_deassert(params, vars->phy_flags);
5508 switch (params->switch_cfg) {
5510 vars->phy_flags |= PHY_SERDES_FLAG;
5511 if ((params->ext_phy_config &
5512 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
5513 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
5519 NIG_REG_SERDES0_CTRL_PHY_ADDR+
5522 params->phy_addr = (u8)val;
5525 case SWITCH_CFG_10G:
5526 vars->phy_flags |= PHY_XGXS_FLAG;
5528 NIG_REG_XGXS0_CTRL_PHY_ADDR+
5530 params->phy_addr = (u8)val;
5534 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
5538 DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
5540 bnx2x_link_initialize(params, vars);
5542 bnx2x_link_int_enable(params);
5547 static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
5549 DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
5551 /* Set serial boot control for external load */
5552 bnx2x_cl45_write(bp, port,
5553 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
5555 MDIO_PMA_REG_GEN_CTRL, 0x0001);
5558 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
5562 struct bnx2x *bp = params->bp;
5563 u32 ext_phy_config = params->ext_phy_config;
5564 u16 hw_led_mode = params->hw_led_mode;
5565 u32 chip_id = params->chip_id;
5566 u8 port = params->port;
5567 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
5568 u32 val = REG_RD(bp, params->shmem_base +
5569 offsetof(struct shmem_region, dev_info.
5570 port_feature_config[params->port].
5573 /* disable attentions */
5575 vars->link_status = 0;
5576 bnx2x_update_mng(params, vars->link_status);
5577 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5578 (NIG_MASK_XGXS0_LINK_STATUS |
5579 NIG_MASK_XGXS0_LINK10G |
5580 NIG_MASK_SERDES0_LINK_STATUS |
5583 /* activate nig drain */
5584 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
5586 /* disable nig egress interface */
5587 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
5588 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
5590 /* Stop BigMac rx */
5591 bnx2x_bmac_rx_disable(bp, port);
5594 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
5597 /* The PHY reset is controled by GPIO 1
5598 * Hold it as vars low
5600 /* clear link led */
5601 bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
5602 if (reset_ext_phy) {
5603 switch (ext_phy_type) {
5604 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5605 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5608 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
5611 /* Disable Transmitter */
5612 u8 ext_phy_addr = ((params->ext_phy_config &
5613 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5614 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5615 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
5616 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
5617 bnx2x_sfp_set_transmitter(bp, port,
5618 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
5622 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5623 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
5626 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5627 MISC_REGISTERS_GPIO_OUTPUT_LOW,
5630 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5632 u8 ext_phy_addr = ((params->ext_phy_config &
5633 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5634 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5635 /* Set soft reset */
5636 bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
5641 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
5642 MISC_REGISTERS_GPIO_OUTPUT_LOW,
5644 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5645 MISC_REGISTERS_GPIO_OUTPUT_LOW,
5647 DP(NETIF_MSG_LINK, "reset external PHY\n");
5650 /* reset the SerDes/XGXS */
5651 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
5652 (0x1ff << (port*16)));
5655 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
5656 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
5658 /* disable nig ingress interface */
5659 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
5660 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
5661 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
5662 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
5667 static u8 bnx2x_update_link_down(struct link_params *params,
5668 struct link_vars *vars)
5670 struct bnx2x *bp = params->bp;
5671 u8 port = params->port;
5672 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
5673 bnx2x_set_led(bp, port, LED_MODE_OFF,
5674 0, params->hw_led_mode,
5677 /* indicate no mac active */
5678 vars->mac_type = MAC_TYPE_NONE;
5680 /* update shared memory */
5681 vars->link_status = 0;
5682 vars->line_speed = 0;
5683 bnx2x_update_mng(params, vars->link_status);
5685 /* activate nig drain */
5686 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
5689 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
5694 bnx2x_bmac_rx_disable(bp, params->port);
5695 REG_WR(bp, GRCBASE_MISC +
5696 MISC_REGISTERS_RESET_REG_2_CLEAR,
5697 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
5701 static u8 bnx2x_update_link_up(struct link_params *params,
5702 struct link_vars *vars,
5703 u8 link_10g, u32 gp_status)
5705 struct bnx2x *bp = params->bp;
5706 u8 port = params->port;
5708 vars->link_status |= LINK_STATUS_LINK_UP;
5710 bnx2x_bmac_enable(params, vars, 0);
5711 bnx2x_set_led(bp, port, LED_MODE_OPER,
5712 SPEED_10000, params->hw_led_mode,
5716 bnx2x_emac_enable(params, vars, 0);
5717 rc = bnx2x_emac_program(params, vars->line_speed,
5721 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
5722 if (!(vars->phy_flags &
5724 bnx2x_set_gmii_tx_driver(params);
5729 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
5733 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
5735 /* update shared memory */
5736 bnx2x_update_mng(params, vars->link_status);
5740 /* This function should called upon link interrupt */
5741 /* In case vars->link_up, driver needs to
5744 3. Update the shared memory
5748 1. Update shared memory
5753 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
5755 struct bnx2x *bp = params->bp;
5756 u8 port = params->port;
5759 u8 ext_phy_link_up, rc = 0;
5762 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
5764 (vars->phy_flags & PHY_XGXS_FLAG),
5765 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5767 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
5768 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5769 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5770 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
5772 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5773 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5774 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5777 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
5779 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5781 /* Check external link change only for non-direct */
5782 ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
5784 /* Read gp_status */
5785 CL45_RD_OVER_CL22(bp, port, params->phy_addr,
5786 MDIO_REG_BANK_GP_STATUS,
5787 MDIO_GP_STATUS_TOP_AN_STATUS1,
5790 rc = bnx2x_link_settings_status(params, vars, gp_status);
5794 /* anything 10 and over uses the bmac */
5795 link_10g = ((vars->line_speed == SPEED_10000) ||
5796 (vars->line_speed == SPEED_12000) ||
5797 (vars->line_speed == SPEED_12500) ||
5798 (vars->line_speed == SPEED_13000) ||
5799 (vars->line_speed == SPEED_15000) ||
5800 (vars->line_speed == SPEED_16000));
5802 bnx2x_link_int_ack(params, vars, link_10g);
5804 /* In case external phy link is up, and internal link is down
5805 ( not initialized yet probably after link initialization, it needs
5807 Note that after link down-up as result of cable plug,
5808 the xgxs link would probably become up again without the need to
5811 if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
5812 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
5813 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
5814 (ext_phy_link_up && !vars->phy_link_up))
5815 bnx2x_init_internal_phy(params, vars);
5817 /* link is up only if both local phy and external phy are up */
5818 vars->link_up = (ext_phy_link_up && vars->phy_link_up);
5821 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
5823 rc = bnx2x_update_link_down(params, vars);
5828 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5830 u8 ext_phy_addr[PORT_MAX];
5834 /* PART1 - Reset both phys */
5835 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5836 /* Extract the ext phy address for the port */
5837 u32 ext_phy_config = REG_RD(bp, shmem_base +
5838 offsetof(struct shmem_region,
5839 dev_info.port_hw_config[port].external_phy_config));
5841 /* disable attentions */
5842 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5843 (NIG_MASK_XGXS0_LINK_STATUS |
5844 NIG_MASK_XGXS0_LINK10G |
5845 NIG_MASK_SERDES0_LINK_STATUS |
5848 ext_phy_addr[port] =
5850 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5851 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5853 /* Need to take the phy out of low power mode in order
5854 to write to access its registers */
5855 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5856 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
5859 bnx2x_cl45_write(bp, port,
5860 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5867 /* Add delay of 150ms after reset */
5870 /* PART2 - Download firmware to both phys */
5871 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5874 bnx2x_bcm8073_external_rom_boot(bp, port,
5875 ext_phy_addr[port], shmem_base);
5877 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5880 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
5881 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
5883 "bnx2x_8073_common_init_phy port %x:"
5884 "Download failed. fw version = 0x%x\n",
5889 /* Only set bit 10 = 1 (Tx power down) */
5890 bnx2x_cl45_read(bp, port,
5891 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5894 MDIO_PMA_REG_TX_POWER_DOWN, &val);
5896 /* Phase1 of TX_POWER_DOWN reset */
5897 bnx2x_cl45_write(bp, port,
5898 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5901 MDIO_PMA_REG_TX_POWER_DOWN,
5905 /* Toggle Transmitter: Power down and then up with 600ms
5909 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
5910 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5911 /* Phase2 of POWER_DOWN_RESET */
5912 /* Release bit 10 (Release Tx power down) */
5913 bnx2x_cl45_read(bp, port,
5914 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5917 MDIO_PMA_REG_TX_POWER_DOWN, &val);
5919 bnx2x_cl45_write(bp, port,
5920 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5923 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
5926 /* Read modify write the SPI-ROM version select register */
5927 bnx2x_cl45_read(bp, port,
5928 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5931 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
5932 bnx2x_cl45_write(bp, port,
5933 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5936 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
5938 /* set GPIO2 back to LOW */
5939 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5940 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
5946 static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5948 u8 ext_phy_addr[PORT_MAX];
5950 u32 swap_val, swap_override;
5951 DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n");
5952 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
5953 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
5955 bnx2x_hw_reset(bp, 1 ^ (swap_val && swap_override));
5958 /* PART1 - Reset both phys */
5959 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5960 /* Extract the ext phy address for the port */
5961 u32 ext_phy_config = REG_RD(bp, shmem_base +
5962 offsetof(struct shmem_region,
5963 dev_info.port_hw_config[port].external_phy_config));
5965 /* disable attentions */
5966 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5967 (NIG_MASK_XGXS0_LINK_STATUS |
5968 NIG_MASK_XGXS0_LINK10G |
5969 NIG_MASK_SERDES0_LINK_STATUS |
5972 ext_phy_addr[port] = ((ext_phy_config &
5973 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5974 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5977 bnx2x_cl45_write(bp, port,
5978 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
5985 /* Add delay of 150ms after reset */
5988 /* PART2 - Download firmware to both phys */
5989 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5992 bnx2x_bcm8727_external_rom_boot(bp, port,
5993 ext_phy_addr[port], shmem_base);
5995 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
5998 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
5999 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
6001 "bnx2x_8073_common_init_phy port %x:"
6002 "Download failed. fw version = 0x%x\n",
6015 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6020 /* Use port1 because of the static port-swap */
6021 /* Enable the module detection interrupt */
6022 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
6023 val |= ((1<<MISC_REGISTERS_GPIO_3)|
6024 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
6025 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
6027 bnx2x_hw_reset(bp, 1);
6029 for (port = 0; port < PORT_MAX; port++) {
6030 /* Extract the ext phy address for the port */
6031 u32 ext_phy_config = REG_RD(bp, shmem_base +
6032 offsetof(struct shmem_region,
6033 dev_info.port_hw_config[port].external_phy_config));
6037 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
6038 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
6039 DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
6042 bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
6044 /* Set fault module detected LED on */
6045 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
6046 MISC_REGISTERS_GPIO_HIGH,
6053 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6058 DP(NETIF_MSG_LINK, "Begin common phy init\n");
6060 /* Read the ext_phy_type for arbitrary port(0) */
6061 ext_phy_type = XGXS_EXT_PHY_TYPE(
6062 REG_RD(bp, shmem_base +
6063 offsetof(struct shmem_region,
6064 dev_info.port_hw_config[0].external_phy_config)));
6066 switch (ext_phy_type) {
6067 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6069 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
6073 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6074 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
6075 rc = bnx2x_8727_common_init_phy(bp, shmem_base);
6078 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6079 /* GPIO1 affects both ports, so there's need to pull
6080 it for single port alone */
6081 rc = bnx2x_8726_common_init_phy(bp, shmem_base);
6086 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
6096 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
6100 bnx2x_cl45_read(bp, port,
6101 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6104 MDIO_PMA_REG_7101_RESET, &val);
6106 for (cnt = 0; cnt < 10; cnt++) {
6108 /* Writes a self-clearing reset */
6109 bnx2x_cl45_write(bp, port,
6110 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6113 MDIO_PMA_REG_7101_RESET,
6115 /* Wait for clear */
6116 bnx2x_cl45_read(bp, port,
6117 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6120 MDIO_PMA_REG_7101_RESET, &val);
6122 if ((val & (1<<15)) == 0)
6126 #define RESERVED_SIZE 256
6127 /* max application is 160K bytes - data at end of RAM */
6128 #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
6130 /* Header is 14 bytes */
6131 #define HEADER_SIZE 14
6132 #define DATA_OFFSET HEADER_SIZE
6134 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
6135 bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
6138 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
6140 /* Programs an image to DSP's flash via the SPI port*/
6141 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
6143 char data[], u32 size)
6145 const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
6146 /* Doesn't include last trans!*/
6147 const u16 last_trans_size = size%4; /* Num bytes on last trans */
6148 u16 trans_cnt, byte_cnt;
6151 u16 code_started = 0;
6152 u16 image_revision1, image_revision2;
6155 DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
6157 if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
6158 /* This very often will be the case, because the image is built
6159 with 160Kbytes size whereas the total image size must actually
6160 be 160Kbytes-RESERVED_SIZE */
6161 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
6162 "truncated to %d bytes\n", size, MAX_APP_SIZE);
6163 size = MAX_APP_SIZE+HEADER_SIZE;
6165 DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
6166 DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]);
6167 /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
6168 and issuing a reset.*/
6170 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
6171 MISC_REGISTERS_GPIO_HIGH, port);
6173 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
6176 for (cnt = 0; cnt < 100; cnt++)
6179 /* Make sure we can access the DSP
6180 And it's in the correct mode (waiting for download) */
6182 bnx2x_cl45_read(bp, port,
6183 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6186 MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
6188 if (tmp != 0x000A) {
6189 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
6190 "Expected 0x000A, read 0x%04X\n", tmp);
6191 DP(NETIF_MSG_LINK, "Download failed\n");
6195 /* Mux the SPI interface away from the internal processor */
6196 bnx2x_cl45_write(bp, port,
6197 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6200 MDIO_PCS_REG_7101_SPI_MUX, 1);
6202 /* Reset the SPI port */
6203 bnx2x_cl45_write(bp, port,
6204 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6207 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
6208 bnx2x_cl45_write(bp, port,
6209 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6212 MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
6213 (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
6214 bnx2x_cl45_write(bp, port,
6215 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6218 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
6220 /* Erase the flash */
6221 bnx2x_cl45_write(bp, port,
6222 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6225 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6226 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
6228 bnx2x_cl45_write(bp, port,
6229 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6232 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
6235 SPI_START_TRANSFER(bp, port, ext_phy_addr);
6236 bnx2x_cl45_write(bp, port,
6237 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6240 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6241 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
6243 bnx2x_cl45_write(bp, port,
6244 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6247 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
6249 SPI_START_TRANSFER(bp, port, ext_phy_addr);
6251 /* Wait 10 seconds, the maximum time for the erase to complete */
6252 DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
6253 for (cnt = 0; cnt < 1000; cnt++)
6256 DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
6258 for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
6259 bnx2x_cl45_write(bp, port,
6260 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6263 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6264 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
6266 bnx2x_cl45_write(bp, port,
6267 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6270 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
6272 SPI_START_TRANSFER(bp, port, ext_phy_addr);
6274 bnx2x_cl45_write(bp, port,
6275 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6278 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6279 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
6281 /* Bits 23-16 of address */
6282 bnx2x_cl45_write(bp, port,
6283 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6286 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6288 /* Bits 15-8 of address */
6289 bnx2x_cl45_write(bp, port,
6290 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6293 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6296 /* Bits 7-0 of address */
6297 bnx2x_cl45_write(bp, port,
6298 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6301 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6305 while (byte_cnt < 4 && data_index < size) {
6306 bnx2x_cl45_write(bp, port,
6307 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6310 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6311 data[data_index++]);
6315 bnx2x_cl45_write(bp, port,
6316 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6319 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
6322 SPI_START_TRANSFER(bp, port, ext_phy_addr);
6323 msleep(5); /* Wait 5 ms minimum between transs */
6325 /* Let the user know something's going on.*/
6326 /* a pacifier ever 4K */
6327 if ((data_index % 1023) == 0)
6328 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
6331 DP(NETIF_MSG_LINK, "\n");
6332 /* Transfer the last block if there is data remaining */
6333 if (last_trans_size) {
6334 bnx2x_cl45_write(bp, port,
6335 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6338 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6339 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
6341 bnx2x_cl45_write(bp, port,
6342 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6345 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
6348 SPI_START_TRANSFER(bp, port, ext_phy_addr);
6350 bnx2x_cl45_write(bp, port,
6351 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6354 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6355 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
6357 /* Bits 23-16 of address */
6358 bnx2x_cl45_write(bp, port,
6359 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6362 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6364 /* Bits 15-8 of address */
6365 bnx2x_cl45_write(bp, port,
6366 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6369 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6372 /* Bits 7-0 of address */
6373 bnx2x_cl45_write(bp, port,
6374 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6377 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6381 while (byte_cnt < last_trans_size && data_index < size) {
6382 /* Bits 7-0 of address */
6383 bnx2x_cl45_write(bp, port,
6384 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6387 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6388 data[data_index++]);
6392 bnx2x_cl45_write(bp, port,
6393 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6396 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
6399 SPI_START_TRANSFER(bp, port, ext_phy_addr);
6402 /* DSP Remove Download Mode */
6403 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
6404 MISC_REGISTERS_GPIO_LOW, port);
6406 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
6408 /* wait 0.5 sec to allow it to run */
6409 for (cnt = 0; cnt < 100; cnt++)
6412 bnx2x_hw_reset(bp, port);
6414 for (cnt = 0; cnt < 100; cnt++)
6417 /* Check that the code is started. In case the download
6418 checksum failed, the code won't be started. */
6419 bnx2x_cl45_read(bp, port,
6420 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6423 MDIO_PCS_REG_7101_DSP_ACCESS,
6426 code_started = (tmp & (1<<4));
6427 if (!code_started) {
6428 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
6432 /* Verify that the file revision is now equal to the image
6433 revision within the DSP */
6434 bnx2x_cl45_read(bp, port,
6435 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6438 MDIO_PMA_REG_7101_VER1,
6441 bnx2x_cl45_read(bp, port,
6442 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6445 MDIO_PMA_REG_7101_VER2,
6448 if (data[0x14e] != (image_revision2&0xFF) ||
6449 data[0x14f] != ((image_revision2&0xFF00)>>8) ||
6450 data[0x150] != (image_revision1&0xFF) ||
6451 data[0x151] != ((image_revision1&0xFF00)>>8)) {
6452 DP(NETIF_MSG_LINK, "Download failed.\n");
6455 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
6459 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
6460 u8 driver_loaded, char data[], u32 size)
6465 ext_phy_addr = ((ext_phy_config &
6466 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
6467 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
6469 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
6471 switch (ext_phy_type) {
6472 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
6473 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6474 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
6475 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
6477 "Flash download not supported for this ext phy\n");
6480 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
6481 /* Take ext phy out of reset */
6483 bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
6484 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
6487 bnx2x_turn_off_sf(bp, port);
6489 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
6490 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
6491 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
6493 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");