1 /* Copyright 2008-2009 Broadcom Corporation
3 * Unless you and Broadcom execute a separate written software license
4 * agreement governing use of this software, this software is licensed to you
5 * under the terms of the GNU General Public License version 2, available
6 * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
8 * Notwithstanding the above, under no circumstances may you combine this
9 * software in any way with any other Broadcom software provided under a
10 * license other than the GPL, without Broadcom's express prior written
13 * Written by Yaniv Rosner
17 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/pci.h>
20 #include <linux/netdevice.h>
21 #include <linux/delay.h>
22 #include <linux/ethtool.h>
23 #include <linux/mutex.h>
25 #include "bnx2x_reg.h"
26 #include "bnx2x_fw_defs.h"
27 #include "bnx2x_hsi.h"
28 #include "bnx2x_link.h"
31 /********************************************************/
32 #define SUPPORT_CL73 0 /* Currently no */
34 #define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
35 #define ETH_MIN_PACKET_SIZE 60
36 #define ETH_MAX_PACKET_SIZE 1500
37 #define ETH_MAX_JUMBO_PACKET_SIZE 9600
38 #define MDIO_ACCESS_TIMEOUT 1000
39 #define BMAC_CONTROL_RX_ENABLE 2
41 /***********************************************************/
42 /* Shortcut definitions */
43 /***********************************************************/
45 #define NIG_STATUS_XGXS0_LINK10G \
46 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
47 #define NIG_STATUS_XGXS0_LINK_STATUS \
48 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
49 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
50 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
51 #define NIG_STATUS_SERDES0_LINK_STATUS \
52 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
53 #define NIG_MASK_MI_INT \
54 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
55 #define NIG_MASK_XGXS0_LINK10G \
56 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
57 #define NIG_MASK_XGXS0_LINK_STATUS \
58 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
59 #define NIG_MASK_SERDES0_LINK_STATUS \
60 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
62 #define MDIO_AN_CL73_OR_37_COMPLETE \
63 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
64 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
66 #define XGXS_RESET_BITS \
67 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
68 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
69 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
70 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
71 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
73 #define SERDES_RESET_BITS \
74 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
75 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
76 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
77 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
79 #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
80 #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
81 #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
82 #define AUTONEG_PARALLEL \
83 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
84 #define AUTONEG_SGMII_FIBER_AUTODET \
85 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
86 #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
88 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
89 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
90 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
91 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
92 #define GP_STATUS_SPEED_MASK \
93 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
94 #define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
95 #define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
96 #define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
97 #define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
98 #define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
99 #define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
100 #define GP_STATUS_10G_HIG \
101 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
102 #define GP_STATUS_10G_CX4 \
103 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
104 #define GP_STATUS_12G_HIG \
105 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
106 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
107 #define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
108 #define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
109 #define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
110 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
111 #define GP_STATUS_10G_KX4 \
112 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
114 #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
115 #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
116 #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
117 #define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
118 #define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
119 #define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
120 #define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
121 #define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
122 #define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
123 #define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
124 #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
125 #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
126 #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
127 #define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
128 #define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
129 #define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
130 #define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
131 #define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
132 #define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
133 #define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
134 #define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
135 #define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
136 #define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
138 #define PHY_XGXS_FLAG 0x1
139 #define PHY_SGMII_FLAG 0x2
140 #define PHY_SERDES_FLAG 0x4
142 /**********************************************************/
144 /**********************************************************/
145 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
146 bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
147 DEFAULT_PHY_DEV_ADDR, \
148 (_bank + (_addr & 0xf)), \
151 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
152 bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
153 DEFAULT_PHY_DEV_ADDR, \
154 (_bank + (_addr & 0xf)), \
157 static void bnx2x_set_phy_mdio(struct link_params *params)
159 struct bnx2x *bp = params->bp;
160 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
161 params->port*0x18, 0);
162 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
163 DEFAULT_PHY_DEV_ADDR);
166 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
168 u32 val = REG_RD(bp, reg);
171 REG_WR(bp, reg, val);
175 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
177 u32 val = REG_RD(bp, reg);
180 REG_WR(bp, reg, val);
184 static void bnx2x_emac_init(struct link_params *params,
185 struct link_vars *vars)
187 /* reset and unreset the emac core */
188 struct bnx2x *bp = params->bp;
189 u8 port = params->port;
190 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
194 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
195 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
197 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
198 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
200 /* init emac - use read-modify-write */
201 /* self clear reset */
202 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
203 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
207 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
208 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
210 DP(NETIF_MSG_LINK, "EMAC timeout!\n");
214 } while (val & EMAC_MODE_RESET);
216 /* Set mac address */
217 val = ((params->mac_addr[0] << 8) |
218 params->mac_addr[1]);
219 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
221 val = ((params->mac_addr[2] << 24) |
222 (params->mac_addr[3] << 16) |
223 (params->mac_addr[4] << 8) |
224 params->mac_addr[5]);
225 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
228 static u8 bnx2x_emac_enable(struct link_params *params,
229 struct link_vars *vars, u8 lb)
231 struct bnx2x *bp = params->bp;
232 u8 port = params->port;
233 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
236 DP(NETIF_MSG_LINK, "enabling EMAC\n");
238 /* enable emac and not bmac */
239 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
242 if (CHIP_REV_IS_EMUL(bp)) {
243 /* Use lane 1 (of lanes 0-3) */
244 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
245 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
251 if (CHIP_REV_IS_FPGA(bp)) {
252 /* Use lane 1 (of lanes 0-3) */
253 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
255 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
256 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
260 if (vars->phy_flags & PHY_XGXS_FLAG) {
261 u32 ser_lane = ((params->lane_config &
262 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
263 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
265 DP(NETIF_MSG_LINK, "XGXS\n");
266 /* select the master lanes (out of 0-3) */
267 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
270 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
273 } else { /* SerDes */
274 DP(NETIF_MSG_LINK, "SerDes\n");
276 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
281 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
283 if (CHIP_REV_IS_SLOW(bp)) {
284 /* config GMII mode */
285 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
286 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
287 (val | EMAC_MODE_PORT_GMII));
289 /* pause enable/disable */
290 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
291 EMAC_RX_MODE_FLOW_EN);
292 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
293 bnx2x_bits_en(bp, emac_base +
294 EMAC_REG_EMAC_RX_MODE,
295 EMAC_RX_MODE_FLOW_EN);
297 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
298 (EMAC_TX_MODE_EXT_PAUSE_EN |
299 EMAC_TX_MODE_FLOW_EN));
300 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
301 bnx2x_bits_en(bp, emac_base +
302 EMAC_REG_EMAC_TX_MODE,
303 (EMAC_TX_MODE_EXT_PAUSE_EN |
304 EMAC_TX_MODE_FLOW_EN));
307 /* KEEP_VLAN_TAG, promiscuous */
308 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
309 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
310 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
313 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
318 EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
321 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
323 /* enable emac for jumbo packets */
324 EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
325 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
326 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
329 REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
331 /* disable the NIG in/out to the bmac */
332 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
333 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
334 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
336 /* enable the NIG in/out to the emac */
337 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
339 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
342 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
343 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
345 if (CHIP_REV_IS_EMUL(bp)) {
346 /* take the BigMac out of reset */
348 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
349 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
351 /* enable access for bmac registers */
352 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
355 vars->mac_type = MAC_TYPE_EMAC;
361 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
364 struct bnx2x *bp = params->bp;
365 u8 port = params->port;
366 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
367 NIG_REG_INGRESS_BMAC0_MEM;
371 DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
372 /* reset and unreset the BigMac */
373 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
374 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
377 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
378 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
380 /* enable access for bmac registers */
381 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
386 REG_WR_DMAE(bp, bmac_addr +
387 BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
391 wb_data[0] = ((params->mac_addr[2] << 24) |
392 (params->mac_addr[3] << 16) |
393 (params->mac_addr[4] << 8) |
394 params->mac_addr[5]);
395 wb_data[1] = ((params->mac_addr[0] << 8) |
396 params->mac_addr[1]);
397 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
402 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
406 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
413 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
417 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
422 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
424 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
427 /* rx control set to don't strip crc */
429 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
433 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
437 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
439 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
442 /* set cnt max size */
443 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
445 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
449 wb_data[0] = 0x1000200;
451 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
453 /* fix for emulation */
454 if (CHIP_REV_IS_EMUL(bp)) {
458 bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
462 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
463 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
464 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
466 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
468 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
469 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
470 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
471 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
472 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
473 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
475 vars->mac_type = MAC_TYPE_BMAC;
479 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
481 struct bnx2x *bp = params->bp;
484 if (phy_flags & PHY_XGXS_FLAG) {
485 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
486 val = XGXS_RESET_BITS;
488 } else { /* SerDes */
489 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
490 val = SERDES_RESET_BITS;
493 val = val << (params->port*16);
495 /* reset and unreset the SerDes/XGXS */
496 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
499 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
501 bnx2x_set_phy_mdio(params);
504 void bnx2x_link_status_update(struct link_params *params,
505 struct link_vars *vars)
507 struct bnx2x *bp = params->bp;
509 u8 port = params->port;
511 if (params->switch_cfg == SWITCH_CFG_1G)
512 vars->phy_flags = PHY_SERDES_FLAG;
514 vars->phy_flags = PHY_XGXS_FLAG;
515 vars->link_status = REG_RD(bp, params->shmem_base +
516 offsetof(struct shmem_region,
517 port_mb[port].link_status));
519 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
522 DP(NETIF_MSG_LINK, "phy link up\n");
524 vars->phy_link_up = 1;
525 vars->duplex = DUPLEX_FULL;
526 switch (vars->link_status &
527 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
529 vars->duplex = DUPLEX_HALF;
532 vars->line_speed = SPEED_10;
536 vars->duplex = DUPLEX_HALF;
540 vars->line_speed = SPEED_100;
544 vars->duplex = DUPLEX_HALF;
547 vars->line_speed = SPEED_1000;
551 vars->duplex = DUPLEX_HALF;
554 vars->line_speed = SPEED_2500;
558 vars->line_speed = SPEED_10000;
562 vars->line_speed = SPEED_12000;
566 vars->line_speed = SPEED_12500;
570 vars->line_speed = SPEED_13000;
574 vars->line_speed = SPEED_15000;
578 vars->line_speed = SPEED_16000;
585 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
586 vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
588 vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
590 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
591 vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
593 vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
595 if (vars->phy_flags & PHY_XGXS_FLAG) {
596 if (vars->line_speed &&
597 ((vars->line_speed == SPEED_10) ||
598 (vars->line_speed == SPEED_100))) {
599 vars->phy_flags |= PHY_SGMII_FLAG;
601 vars->phy_flags &= ~PHY_SGMII_FLAG;
605 /* anything 10 and over uses the bmac */
606 link_10g = ((vars->line_speed == SPEED_10000) ||
607 (vars->line_speed == SPEED_12000) ||
608 (vars->line_speed == SPEED_12500) ||
609 (vars->line_speed == SPEED_13000) ||
610 (vars->line_speed == SPEED_15000) ||
611 (vars->line_speed == SPEED_16000));
613 vars->mac_type = MAC_TYPE_BMAC;
615 vars->mac_type = MAC_TYPE_EMAC;
617 } else { /* link down */
618 DP(NETIF_MSG_LINK, "phy link down\n");
620 vars->phy_link_up = 0;
622 vars->line_speed = 0;
623 vars->duplex = DUPLEX_FULL;
624 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
626 /* indicate no mac active */
627 vars->mac_type = MAC_TYPE_NONE;
630 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
631 vars->link_status, vars->phy_link_up);
632 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
633 vars->line_speed, vars->duplex, vars->flow_ctrl);
636 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
638 struct bnx2x *bp = params->bp;
639 REG_WR(bp, params->shmem_base +
640 offsetof(struct shmem_region,
641 port_mb[params->port].link_status),
645 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
647 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
648 NIG_REG_INGRESS_BMAC0_MEM;
650 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
652 /* Only if the bmac is out of reset */
653 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
654 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
657 /* Clear Rx Enable bit in BMAC_CONTROL register */
658 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
660 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
661 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
668 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
671 struct bnx2x *bp = params->bp;
672 u8 port = params->port;
677 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
679 /* wait for init credit */
680 init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
681 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
682 DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
684 while ((init_crd != crd) && count) {
687 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
690 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
691 if (init_crd != crd) {
692 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
697 if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
698 line_speed == SPEED_10 ||
699 line_speed == SPEED_100 ||
700 line_speed == SPEED_1000 ||
701 line_speed == SPEED_2500) {
702 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
703 /* update threshold */
704 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
705 /* update init credit */
706 init_crd = 778; /* (800-18-4) */
709 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
711 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
712 /* update threshold */
713 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
714 /* update init credit */
715 switch (line_speed) {
717 init_crd = thresh + 553 - 22;
721 init_crd = thresh + 664 - 22;
725 init_crd = thresh + 742 - 22;
729 init_crd = thresh + 778 - 22;
732 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
738 REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
739 DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
740 line_speed, init_crd);
742 /* probe the credit changes */
743 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
745 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
748 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
752 static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port)
755 switch (ext_phy_type) {
756 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
757 emac_base = GRCBASE_EMAC0;
759 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
760 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
763 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
770 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
771 u8 phy_addr, u8 devad, u16 reg, u16 val)
775 u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
777 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
778 * (a value of 49==0x31) and make sure that the AUTO poll is off
780 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
781 tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
782 EMAC_MDIO_MODE_CLOCK_CNT);
783 tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
784 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
785 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
786 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
791 tmp = ((phy_addr << 21) | (devad << 16) | reg |
792 EMAC_MDIO_COMM_COMMAND_ADDRESS |
793 EMAC_MDIO_COMM_START_BUSY);
794 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
796 for (i = 0; i < 50; i++) {
799 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
800 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
805 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
806 DP(NETIF_MSG_LINK, "write phy register failed\n");
810 tmp = ((phy_addr << 21) | (devad << 16) | val |
811 EMAC_MDIO_COMM_COMMAND_WRITE_45 |
812 EMAC_MDIO_COMM_START_BUSY);
813 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
815 for (i = 0; i < 50; i++) {
818 tmp = REG_RD(bp, mdio_ctrl +
819 EMAC_REG_EMAC_MDIO_COMM);
820 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
825 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
826 DP(NETIF_MSG_LINK, "write phy register failed\n");
831 /* Restore the saved mode */
832 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
837 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
838 u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
844 u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
845 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
846 * (a value of 49==0x31) and make sure that the AUTO poll is off
848 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
849 val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
850 EMAC_MDIO_MODE_CLOCK_CNT));
851 val |= (EMAC_MDIO_MODE_CLAUSE_45 |
852 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
853 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
854 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
858 val = ((phy_addr << 21) | (devad << 16) | reg |
859 EMAC_MDIO_COMM_COMMAND_ADDRESS |
860 EMAC_MDIO_COMM_START_BUSY);
861 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
863 for (i = 0; i < 50; i++) {
866 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
867 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
872 if (val & EMAC_MDIO_COMM_START_BUSY) {
873 DP(NETIF_MSG_LINK, "read phy register failed\n");
880 val = ((phy_addr << 21) | (devad << 16) |
881 EMAC_MDIO_COMM_COMMAND_READ_45 |
882 EMAC_MDIO_COMM_START_BUSY);
883 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
885 for (i = 0; i < 50; i++) {
888 val = REG_RD(bp, mdio_ctrl +
889 EMAC_REG_EMAC_MDIO_COMM);
890 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
891 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
895 if (val & EMAC_MDIO_COMM_START_BUSY) {
896 DP(NETIF_MSG_LINK, "read phy register failed\n");
903 /* Restore the saved mode */
904 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
909 static void bnx2x_set_aer_mmd(struct link_params *params,
910 struct link_vars *vars)
912 struct bnx2x *bp = params->bp;
916 ser_lane = ((params->lane_config &
917 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
918 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
920 offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
921 (params->phy_addr + ser_lane) : 0;
923 CL45_WR_OVER_CL22(bp, params->port,
925 MDIO_REG_BANK_AER_BLOCK,
926 MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
929 static void bnx2x_set_master_ln(struct link_params *params)
931 struct bnx2x *bp = params->bp;
932 u16 new_master_ln, ser_lane;
933 ser_lane = ((params->lane_config &
934 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
935 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
937 /* set the master_ln for AN */
938 CL45_RD_OVER_CL22(bp, params->port,
940 MDIO_REG_BANK_XGXS_BLOCK2,
941 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
944 CL45_WR_OVER_CL22(bp, params->port,
946 MDIO_REG_BANK_XGXS_BLOCK2 ,
947 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
948 (new_master_ln | ser_lane));
951 static u8 bnx2x_reset_unicore(struct link_params *params)
953 struct bnx2x *bp = params->bp;
957 CL45_RD_OVER_CL22(bp, params->port,
959 MDIO_REG_BANK_COMBO_IEEE0,
960 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
962 /* reset the unicore */
963 CL45_WR_OVER_CL22(bp, params->port,
965 MDIO_REG_BANK_COMBO_IEEE0,
966 MDIO_COMBO_IEEE0_MII_CONTROL,
968 MDIO_COMBO_IEEO_MII_CONTROL_RESET));
970 /* wait for the reset to self clear */
971 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
974 /* the reset erased the previous bank value */
975 CL45_RD_OVER_CL22(bp, params->port,
977 MDIO_REG_BANK_COMBO_IEEE0,
978 MDIO_COMBO_IEEE0_MII_CONTROL,
981 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
987 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
992 static void bnx2x_set_swap_lanes(struct link_params *params)
994 struct bnx2x *bp = params->bp;
995 /* Each two bits represents a lane number:
996 No swap is 0123 => 0x1b no need to enable the swap */
997 u16 ser_lane, rx_lane_swap, tx_lane_swap;
999 ser_lane = ((params->lane_config &
1000 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1001 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1002 rx_lane_swap = ((params->lane_config &
1003 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1004 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1005 tx_lane_swap = ((params->lane_config &
1006 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1007 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1009 if (rx_lane_swap != 0x1b) {
1010 CL45_WR_OVER_CL22(bp, params->port,
1012 MDIO_REG_BANK_XGXS_BLOCK2,
1013 MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1015 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1016 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1018 CL45_WR_OVER_CL22(bp, params->port,
1020 MDIO_REG_BANK_XGXS_BLOCK2,
1021 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1024 if (tx_lane_swap != 0x1b) {
1025 CL45_WR_OVER_CL22(bp, params->port,
1027 MDIO_REG_BANK_XGXS_BLOCK2,
1028 MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1030 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1032 CL45_WR_OVER_CL22(bp, params->port,
1034 MDIO_REG_BANK_XGXS_BLOCK2,
1035 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1039 static void bnx2x_set_parallel_detection(struct link_params *params,
1042 struct bnx2x *bp = params->bp;
1045 CL45_RD_OVER_CL22(bp, params->port,
1047 MDIO_REG_BANK_SERDES_DIGITAL,
1048 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1052 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1055 CL45_WR_OVER_CL22(bp, params->port,
1057 MDIO_REG_BANK_SERDES_DIGITAL,
1058 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1061 if (phy_flags & PHY_XGXS_FLAG) {
1062 DP(NETIF_MSG_LINK, "XGXS\n");
1064 CL45_WR_OVER_CL22(bp, params->port,
1066 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1067 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1068 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1070 CL45_RD_OVER_CL22(bp, params->port,
1072 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1073 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1078 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1080 CL45_WR_OVER_CL22(bp, params->port,
1082 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1083 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1086 /* Disable parallel detection of HiG */
1087 CL45_WR_OVER_CL22(bp, params->port,
1089 MDIO_REG_BANK_XGXS_BLOCK2,
1090 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1091 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1092 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1096 static void bnx2x_set_autoneg(struct link_params *params,
1097 struct link_vars *vars)
1099 struct bnx2x *bp = params->bp;
1104 CL45_RD_OVER_CL22(bp, params->port,
1106 MDIO_REG_BANK_COMBO_IEEE0,
1107 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
1109 /* CL37 Autoneg Enabled */
1110 if (vars->line_speed == SPEED_AUTO_NEG)
1111 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1112 else /* CL37 Autoneg Disabled */
1113 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1114 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1116 CL45_WR_OVER_CL22(bp, params->port,
1118 MDIO_REG_BANK_COMBO_IEEE0,
1119 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1121 /* Enable/Disable Autodetection */
1123 CL45_RD_OVER_CL22(bp, params->port,
1125 MDIO_REG_BANK_SERDES_DIGITAL,
1126 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val);
1127 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1128 if (vars->line_speed == SPEED_AUTO_NEG)
1129 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1131 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1133 CL45_WR_OVER_CL22(bp, params->port,
1135 MDIO_REG_BANK_SERDES_DIGITAL,
1136 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1138 /* Enable TetonII and BAM autoneg */
1139 CL45_RD_OVER_CL22(bp, params->port,
1141 MDIO_REG_BANK_BAM_NEXT_PAGE,
1142 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1144 if (vars->line_speed == SPEED_AUTO_NEG) {
1145 /* Enable BAM aneg Mode and TetonII aneg Mode */
1146 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1147 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1149 /* TetonII and BAM Autoneg Disabled */
1150 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1151 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1153 CL45_WR_OVER_CL22(bp, params->port,
1155 MDIO_REG_BANK_BAM_NEXT_PAGE,
1156 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1159 /* Enable Clause 73 Aneg */
1160 if ((vars->line_speed == SPEED_AUTO_NEG) &&
1162 /* Enable BAM Station Manager */
1164 CL45_WR_OVER_CL22(bp, params->port,
1166 MDIO_REG_BANK_CL73_USERB0,
1167 MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1168 (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1169 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1170 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
1172 /* Merge CL73 and CL37 aneg resolution */
1173 CL45_RD_OVER_CL22(bp, params->port,
1175 MDIO_REG_BANK_CL73_USERB0,
1176 MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1179 CL45_WR_OVER_CL22(bp, params->port,
1181 MDIO_REG_BANK_CL73_USERB0,
1182 MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1184 MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
1186 /* Set the CL73 AN speed */
1188 CL45_RD_OVER_CL22(bp, params->port,
1190 MDIO_REG_BANK_CL73_IEEEB1,
1191 MDIO_CL73_IEEEB1_AN_ADV2, ®_val);
1192 /* In the SerDes we support only the 1G.
1193 In the XGXS we support the 10G KX4
1194 but we currently do not support the KR */
1195 if (vars->phy_flags & PHY_XGXS_FLAG) {
1196 DP(NETIF_MSG_LINK, "XGXS\n");
1198 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1200 DP(NETIF_MSG_LINK, "SerDes\n");
1202 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1204 CL45_WR_OVER_CL22(bp, params->port,
1206 MDIO_REG_BANK_CL73_IEEEB1,
1207 MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
1209 /* CL73 Autoneg Enabled */
1210 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
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;
1347 DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1349 /* enable and restart clause 73 aneg */
1352 CL45_RD_OVER_CL22(bp, params->port,
1354 MDIO_REG_BANK_CL73_IEEEB0,
1355 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1357 CL45_WR_OVER_CL22(bp, params->port,
1359 MDIO_REG_BANK_CL73_IEEEB0,
1360 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1362 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1363 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1366 /* Enable and restart BAM/CL37 aneg */
1369 CL45_RD_OVER_CL22(bp, params->port,
1371 MDIO_REG_BANK_COMBO_IEEE0,
1372 MDIO_COMBO_IEEE0_MII_CONTROL,
1375 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1377 CL45_WR_OVER_CL22(bp, params->port,
1379 MDIO_REG_BANK_COMBO_IEEE0,
1380 MDIO_COMBO_IEEE0_MII_CONTROL,
1382 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1383 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1387 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1388 struct link_vars *vars)
1390 struct bnx2x *bp = params->bp;
1393 /* in SGMII mode, the unicore is always slave */
1395 CL45_RD_OVER_CL22(bp, params->port,
1397 MDIO_REG_BANK_SERDES_DIGITAL,
1398 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1400 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1401 /* set sgmii mode (and not fiber) */
1402 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1403 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1404 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1405 CL45_WR_OVER_CL22(bp, params->port,
1407 MDIO_REG_BANK_SERDES_DIGITAL,
1408 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1411 /* if forced speed */
1412 if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1413 /* set speed, disable autoneg */
1416 CL45_RD_OVER_CL22(bp, params->port,
1418 MDIO_REG_BANK_COMBO_IEEE0,
1419 MDIO_COMBO_IEEE0_MII_CONTROL,
1421 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1422 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1423 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1425 switch (vars->line_speed) {
1428 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1432 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1435 /* there is nothing to set for 10M */
1438 /* invalid speed for SGMII */
1439 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1444 /* setting the full duplex */
1445 if (params->req_duplex == DUPLEX_FULL)
1447 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1448 CL45_WR_OVER_CL22(bp, params->port,
1450 MDIO_REG_BANK_COMBO_IEEE0,
1451 MDIO_COMBO_IEEE0_MII_CONTROL,
1454 } else { /* AN mode */
1455 /* enable and restart AN */
1456 bnx2x_restart_autoneg(params);
1465 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1467 switch (pause_result) { /* ASYM P ASYM P */
1468 case 0xb: /* 1 0 1 1 */
1469 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
1472 case 0xe: /* 1 1 1 0 */
1473 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
1476 case 0x5: /* 0 1 0 1 */
1477 case 0x7: /* 0 1 1 1 */
1478 case 0xd: /* 1 1 0 1 */
1479 case 0xf: /* 1 1 1 1 */
1480 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
1488 static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1489 struct link_vars *vars)
1491 struct bnx2x *bp = params->bp;
1493 u16 ld_pause; /* local */
1494 u16 lp_pause; /* link partner */
1495 u16 an_complete; /* AN complete */
1499 u8 port = params->port;
1500 ext_phy_addr = ((params->ext_phy_config &
1501 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1502 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1504 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1507 bnx2x_cl45_read(bp, port,
1511 MDIO_AN_REG_STATUS, &an_complete);
1512 bnx2x_cl45_read(bp, port,
1516 MDIO_AN_REG_STATUS, &an_complete);
1518 if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1520 bnx2x_cl45_read(bp, port,
1524 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1525 bnx2x_cl45_read(bp, port,
1529 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1530 pause_result = (ld_pause &
1531 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1532 pause_result |= (lp_pause &
1533 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1534 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1536 bnx2x_pause_resolve(vars, pause_result);
1537 if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
1538 ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1539 bnx2x_cl45_read(bp, port,
1543 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1545 bnx2x_cl45_read(bp, port,
1549 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1550 pause_result = (ld_pause &
1551 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1552 pause_result |= (lp_pause &
1553 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1555 bnx2x_pause_resolve(vars, pause_result);
1556 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1564 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1565 struct link_vars *vars,
1568 struct bnx2x *bp = params->bp;
1569 u16 ld_pause; /* local driver */
1570 u16 lp_pause; /* link partner */
1573 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1575 /* resolve from gp_status in case of AN complete and not sgmii */
1576 if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1577 (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1578 (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1579 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1580 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1581 CL45_RD_OVER_CL22(bp, params->port,
1583 MDIO_REG_BANK_COMBO_IEEE0,
1584 MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1586 CL45_RD_OVER_CL22(bp, params->port,
1588 MDIO_REG_BANK_COMBO_IEEE0,
1589 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1591 pause_result = (ld_pause &
1592 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1593 pause_result |= (lp_pause &
1594 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1595 DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1596 bnx2x_pause_resolve(vars, pause_result);
1597 } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1598 (bnx2x_ext_phy_resove_fc(params, vars))) {
1601 if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
1602 vars->flow_ctrl = params->req_fc_auto_adv;
1604 vars->flow_ctrl = params->req_flow_ctrl;
1606 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1610 static u8 bnx2x_link_settings_status(struct link_params *params,
1611 struct link_vars *vars,
1614 struct bnx2x *bp = params->bp;
1617 vars->link_status = 0;
1619 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1620 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1623 vars->phy_link_up = 1;
1624 vars->link_status |= LINK_STATUS_LINK_UP;
1626 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1627 vars->duplex = DUPLEX_FULL;
1629 vars->duplex = DUPLEX_HALF;
1631 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1633 switch (gp_status & GP_STATUS_SPEED_MASK) {
1635 new_line_speed = SPEED_10;
1636 if (vars->duplex == DUPLEX_FULL)
1637 vars->link_status |= LINK_10TFD;
1639 vars->link_status |= LINK_10THD;
1642 case GP_STATUS_100M:
1643 new_line_speed = SPEED_100;
1644 if (vars->duplex == DUPLEX_FULL)
1645 vars->link_status |= LINK_100TXFD;
1647 vars->link_status |= LINK_100TXHD;
1651 case GP_STATUS_1G_KX:
1652 new_line_speed = SPEED_1000;
1653 if (vars->duplex == DUPLEX_FULL)
1654 vars->link_status |= LINK_1000TFD;
1656 vars->link_status |= LINK_1000THD;
1659 case GP_STATUS_2_5G:
1660 new_line_speed = SPEED_2500;
1661 if (vars->duplex == DUPLEX_FULL)
1662 vars->link_status |= LINK_2500TFD;
1664 vars->link_status |= LINK_2500THD;
1670 "link speed unsupported gp_status 0x%x\n",
1674 case GP_STATUS_10G_KX4:
1675 case GP_STATUS_10G_HIG:
1676 case GP_STATUS_10G_CX4:
1677 new_line_speed = SPEED_10000;
1678 vars->link_status |= LINK_10GTFD;
1681 case GP_STATUS_12G_HIG:
1682 new_line_speed = SPEED_12000;
1683 vars->link_status |= LINK_12GTFD;
1686 case GP_STATUS_12_5G:
1687 new_line_speed = SPEED_12500;
1688 vars->link_status |= LINK_12_5GTFD;
1692 new_line_speed = SPEED_13000;
1693 vars->link_status |= LINK_13GTFD;
1697 new_line_speed = SPEED_15000;
1698 vars->link_status |= LINK_15GTFD;
1702 new_line_speed = SPEED_16000;
1703 vars->link_status |= LINK_16GTFD;
1708 "link speed unsupported gp_status 0x%x\n",
1714 /* Upon link speed change set the NIG into drain mode.
1715 Comes to deals with possible FIFO glitch due to clk change
1716 when speed is decreased without link down indicator */
1717 if (new_line_speed != vars->line_speed) {
1718 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
1719 + params->port*4, 0);
1722 vars->line_speed = new_line_speed;
1723 vars->link_status |= LINK_STATUS_SERDES_LINK;
1725 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1726 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1727 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1728 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1729 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) {
1730 vars->autoneg = AUTO_NEG_ENABLED;
1732 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1733 vars->autoneg |= AUTO_NEG_COMPLETE;
1734 vars->link_status |=
1735 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1738 vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1739 vars->link_status |=
1740 LINK_STATUS_PARALLEL_DETECTION_USED;
1743 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1744 vars->link_status |=
1745 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1747 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1748 vars->link_status |=
1749 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1751 } else { /* link_down */
1752 DP(NETIF_MSG_LINK, "phy link down\n");
1754 vars->phy_link_up = 0;
1756 vars->duplex = DUPLEX_FULL;
1757 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1758 vars->autoneg = AUTO_NEG_DISABLED;
1759 vars->mac_type = MAC_TYPE_NONE;
1762 DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x \n",
1763 gp_status, vars->phy_link_up, vars->line_speed);
1764 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x"
1767 vars->flow_ctrl, vars->autoneg);
1768 DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1773 static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
1775 struct bnx2x *bp = params->bp;
1781 CL45_RD_OVER_CL22(bp, params->port,
1783 MDIO_REG_BANK_OVER_1G,
1784 MDIO_OVER_1G_LP_UP2, &lp_up2);
1786 CL45_RD_OVER_CL22(bp, params->port,
1789 MDIO_TX0_TX_DRIVER, &tx_driver);
1791 /* bits [10:7] at lp_up2, positioned at [15:12] */
1792 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1793 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1794 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1796 if ((lp_up2 != 0) &&
1797 (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
1798 /* replace tx_driver bits [15:12] */
1799 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1800 tx_driver |= lp_up2;
1801 CL45_WR_OVER_CL22(bp, params->port,
1804 MDIO_TX0_TX_DRIVER, tx_driver);
1808 static u8 bnx2x_emac_program(struct link_params *params,
1809 u32 line_speed, u32 duplex)
1811 struct bnx2x *bp = params->bp;
1812 u8 port = params->port;
1815 DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1816 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1818 (EMAC_MODE_25G_MODE |
1819 EMAC_MODE_PORT_MII_10M |
1820 EMAC_MODE_HALF_DUPLEX));
1821 switch (line_speed) {
1823 mode |= EMAC_MODE_PORT_MII_10M;
1827 mode |= EMAC_MODE_PORT_MII;
1831 mode |= EMAC_MODE_PORT_GMII;
1835 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1839 /* 10G not valid for EMAC */
1840 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1844 if (duplex == DUPLEX_HALF)
1845 mode |= EMAC_MODE_HALF_DUPLEX;
1847 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1850 bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1851 line_speed, params->hw_led_mode, params->chip_id);
1855 /*****************************************************************************/
1856 /* External Phy section */
1857 /*****************************************************************************/
1858 static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
1860 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1861 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
1863 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1864 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
1867 static void bnx2x_ext_phy_reset(struct link_params *params,
1868 struct link_vars *vars)
1870 struct bnx2x *bp = params->bp;
1872 u8 ext_phy_addr = ((params->ext_phy_config &
1873 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1874 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1875 DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1876 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1877 /* The PHY reset is controled by GPIO 1
1878 * Give it 1ms of reset pulse
1880 if (vars->phy_flags & PHY_XGXS_FLAG) {
1882 switch (ext_phy_type) {
1883 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1884 DP(NETIF_MSG_LINK, "XGXS Direct\n");
1887 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1888 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1889 DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1891 /* Restore normal power mode*/
1892 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1893 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1897 bnx2x_hw_reset(bp, params->port);
1899 bnx2x_cl45_write(bp, params->port,
1903 MDIO_PMA_REG_CTRL, 0xa040);
1905 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1906 /* Unset Low Power Mode and SW reset */
1907 /* Restore normal power mode*/
1908 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1909 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1912 DP(NETIF_MSG_LINK, "XGXS 8072\n");
1913 bnx2x_cl45_write(bp, params->port,
1920 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1923 emac_base = (params->port) ? GRCBASE_EMAC0 :
1926 /* Restore normal power mode*/
1927 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1928 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1931 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1932 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1935 DP(NETIF_MSG_LINK, "XGXS 8073\n");
1939 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1940 DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1942 /* Restore normal power mode*/
1943 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1944 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1948 bnx2x_hw_reset(bp, params->port);
1952 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
1953 DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
1957 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
1958 params->ext_phy_config);
1962 } else { /* SerDes */
1963 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
1964 switch (ext_phy_type) {
1965 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
1966 DP(NETIF_MSG_LINK, "SerDes Direct\n");
1969 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
1970 DP(NETIF_MSG_LINK, "SerDes 5482\n");
1971 bnx2x_hw_reset(bp, params->port);
1976 "BAD SerDes ext_phy_config 0x%x\n",
1977 params->ext_phy_config);
1983 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
1985 struct bnx2x *bp = params->bp;
1986 u8 port = params->port;
1987 u8 ext_phy_addr = ((params->ext_phy_config &
1988 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1989 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1990 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1991 u16 fw_ver1, fw_ver2;
1993 /* Need to wait 200ms after reset */
1995 /* Boot port from external ROM
1996 * Set ser_boot_ctl bit in the MISC_CTRL1 register
1998 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2000 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2002 /* Reset internal microprocessor */
2003 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2005 MDIO_PMA_REG_GEN_CTRL,
2006 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2007 /* set micro reset = 0 */
2008 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2010 MDIO_PMA_REG_GEN_CTRL,
2011 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2012 /* Reset internal microprocessor */
2013 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2015 MDIO_PMA_REG_GEN_CTRL,
2016 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2017 /* wait for 100ms for code download via SPI port */
2020 /* Clear ser_boot_ctl bit */
2021 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2023 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2027 /* Print the PHY FW version */
2028 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2030 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2031 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2033 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2034 DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2037 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2039 /* This is only required for 8073A1, version 102 only */
2041 struct bnx2x *bp = params->bp;
2042 u8 ext_phy_addr = ((params->ext_phy_config &
2043 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2044 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2047 /* Read 8073 HW revision*/
2048 bnx2x_cl45_read(bp, params->port,
2049 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2055 /* No need to workaround in 8073 A1 */
2059 bnx2x_cl45_read(bp, params->port,
2060 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2063 MDIO_PMA_REG_ROM_VER2, &val);
2065 /* SNR should be applied only for version 0x102 */
2072 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2074 struct bnx2x *bp = params->bp;
2075 u8 ext_phy_addr = ((params->ext_phy_config &
2076 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2077 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2078 u16 val, cnt, cnt1 ;
2080 bnx2x_cl45_read(bp, params->port,
2081 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2087 /* No need to workaround in 8073 A1 */
2090 /* XAUI workaround in 8073 A0: */
2092 /* After loading the boot ROM and restarting Autoneg,
2093 poll Dev1, Reg $C820: */
2095 for (cnt = 0; cnt < 1000; cnt++) {
2096 bnx2x_cl45_read(bp, params->port,
2097 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2101 /* If bit [14] = 0 or bit [13] = 0, continue on with
2102 system initialization (XAUI work-around not required,
2103 as these bits indicate 2.5G or 1G link up). */
2104 if (!(val & (1<<14)) || !(val & (1<<13))) {
2105 DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2107 } else if (!(val & (1<<15))) {
2108 DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2109 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2110 it's MSB (bit 15) goes to 1 (indicating that the
2111 XAUI workaround has completed),
2112 then continue on with system initialization.*/
2113 for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2114 bnx2x_cl45_read(bp, params->port,
2115 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2119 if (val & (1<<15)) {
2121 "XAUI workaround has completed\n");
2130 DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2135 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2138 u16 fw_ver1, fw_ver2;
2139 /* Boot port from external ROM */
2141 bnx2x_cl45_write(bp, port,
2142 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2145 MDIO_PMA_REG_GEN_CTRL,
2148 /* ucode reboot and rst */
2149 bnx2x_cl45_write(bp, port,
2150 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2153 MDIO_PMA_REG_GEN_CTRL,
2156 bnx2x_cl45_write(bp, port,
2157 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2160 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2162 /* Reset internal microprocessor */
2163 bnx2x_cl45_write(bp, port,
2164 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2167 MDIO_PMA_REG_GEN_CTRL,
2168 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2170 /* Release srst bit */
2171 bnx2x_cl45_write(bp, port,
2172 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2175 MDIO_PMA_REG_GEN_CTRL,
2176 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2178 /* wait for 100ms for code download via SPI port */
2181 /* Clear ser_boot_ctl bit */
2182 bnx2x_cl45_write(bp, port,
2183 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2186 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2188 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2191 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2192 bnx2x_cl45_read(bp, port,
2193 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2196 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2197 DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2201 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2203 struct bnx2x *bp = params->bp;
2204 u8 port = params->port;
2205 u8 ext_phy_addr = ((params->ext_phy_config &
2206 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2207 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2208 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2210 /* Force KR or KX */
2211 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2215 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2217 MDIO_PMA_REG_10G_CTRL2,
2219 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2221 MDIO_PMA_REG_BCM_CTRL,
2223 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2228 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2230 struct bnx2x *bp = params->bp;
2231 u8 port = params->port;
2233 u8 ext_phy_addr = ((params->ext_phy_config &
2234 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2235 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2236 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2238 bnx2x_cl45_read(bp, params->port,
2239 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2245 /* Mustn't set low power mode in 8073 A0 */
2249 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2250 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2252 MDIO_XS_PLL_SEQUENCER, &val);
2254 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2255 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2258 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2259 MDIO_XS_DEVAD, 0x805E, 0x1077);
2260 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2261 MDIO_XS_DEVAD, 0x805D, 0x0000);
2262 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2263 MDIO_XS_DEVAD, 0x805C, 0x030B);
2264 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2265 MDIO_XS_DEVAD, 0x805B, 0x1240);
2266 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2267 MDIO_XS_DEVAD, 0x805A, 0x2490);
2270 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2271 MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2272 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2273 MDIO_XS_DEVAD, 0x80A6, 0x9041);
2274 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2275 MDIO_XS_DEVAD, 0x80A5, 0x4640);
2278 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2279 MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2280 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2281 MDIO_XS_DEVAD, 0x80FD, 0x9249);
2282 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2283 MDIO_XS_DEVAD, 0x80FC, 0x2015);
2285 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
2286 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2288 MDIO_XS_PLL_SEQUENCER, &val);
2290 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2291 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2294 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
2295 struct link_vars *vars)
2298 struct bnx2x *bp = params->bp;
2300 u8 ext_phy_addr = ((params->ext_phy_config &
2301 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2302 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2303 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2305 bnx2x_cl45_read(bp, params->port,
2309 MDIO_AN_REG_CL37_FC_LD, &cl37_val);
2311 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2312 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2314 if ((vars->ieee_fc &
2315 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
2316 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
2317 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
2319 if ((vars->ieee_fc &
2320 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2321 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2322 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2324 if ((vars->ieee_fc &
2325 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2326 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2327 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2330 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
2332 bnx2x_cl45_write(bp, params->port,
2336 MDIO_AN_REG_CL37_FC_LD, cl37_val);
2340 static void bnx2x_ext_phy_set_pause(struct link_params *params,
2341 struct link_vars *vars)
2343 struct bnx2x *bp = params->bp;
2345 u8 ext_phy_addr = ((params->ext_phy_config &
2346 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2347 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2348 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2350 /* read modify write pause advertizing */
2351 bnx2x_cl45_read(bp, params->port,
2355 MDIO_AN_REG_ADV_PAUSE, &val);
2357 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2359 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2361 if ((vars->ieee_fc &
2362 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2363 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2364 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2366 if ((vars->ieee_fc &
2367 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2368 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2370 MDIO_AN_REG_ADV_PAUSE_PAUSE;
2373 "Ext phy AN advertize 0x%x\n", val);
2374 bnx2x_cl45_write(bp, params->port,
2378 MDIO_AN_REG_ADV_PAUSE, val);
2382 static void bnx2x_init_internal_phy(struct link_params *params,
2383 struct link_vars *vars)
2385 struct bnx2x *bp = params->bp;
2386 u8 port = params->port;
2387 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2390 rx_eq = ((params->serdes_config &
2391 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2392 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2394 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2395 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2396 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2397 CL45_WR_OVER_CL22(bp, port,
2400 MDIO_RX0_RX_EQ_BOOST,
2402 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2403 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2406 /* forced speed requested? */
2407 if (vars->line_speed != SPEED_AUTO_NEG) {
2408 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2410 /* disable autoneg */
2411 bnx2x_set_autoneg(params, vars);
2413 /* program speed and duplex */
2414 bnx2x_program_serdes(params, vars);
2416 } else { /* AN_mode */
2417 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2420 bnx2x_set_brcm_cl37_advertisment(params);
2422 /* program duplex & pause advertisement (for aneg) */
2423 bnx2x_set_ieee_aneg_advertisment(params,
2426 /* enable autoneg */
2427 bnx2x_set_autoneg(params, vars);
2429 /* enable and restart AN */
2430 bnx2x_restart_autoneg(params);
2433 } else { /* SGMII mode */
2434 DP(NETIF_MSG_LINK, "SGMII\n");
2436 bnx2x_initialize_sgmii_process(params, vars);
2440 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2442 struct bnx2x *bp = params->bp;
2449 if (vars->phy_flags & PHY_XGXS_FLAG) {
2450 ext_phy_addr = ((params->ext_phy_config &
2451 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2452 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2454 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2455 /* Make sure that the soft reset is off (expect for the 8072:
2456 * due to the lock, it will be done inside the specific
2459 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
2460 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
2461 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
2462 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
2463 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
2464 /* Wait for soft reset to get cleared upto 1 sec */
2465 for (cnt = 0; cnt < 1000; cnt++) {
2466 bnx2x_cl45_read(bp, params->port,
2470 MDIO_PMA_REG_CTRL, &ctrl);
2471 if (!(ctrl & (1<<15)))
2475 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
2479 switch (ext_phy_type) {
2480 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2483 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2484 DP(NETIF_MSG_LINK, "XGXS 8705\n");
2486 bnx2x_cl45_write(bp, params->port,
2490 MDIO_PMA_REG_MISC_CTRL,
2492 bnx2x_cl45_write(bp, params->port,
2496 MDIO_PMA_REG_PHY_IDENTIFIER,
2498 bnx2x_cl45_write(bp, params->port,
2502 MDIO_PMA_REG_CMU_PLL_BYPASS,
2504 bnx2x_cl45_write(bp, params->port,
2508 MDIO_WIS_REG_LASI_CNTL, 0x1);
2511 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2512 DP(NETIF_MSG_LINK, "XGXS 8706\n");
2516 /* First enable LASI */
2517 bnx2x_cl45_write(bp, params->port,
2521 MDIO_PMA_REG_RX_ALARM_CTRL,
2523 bnx2x_cl45_write(bp, params->port,
2527 MDIO_PMA_REG_LASI_CTRL, 0x0004);
2529 if (params->req_line_speed == SPEED_10000) {
2530 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
2532 bnx2x_cl45_write(bp, params->port,
2536 MDIO_PMA_REG_DIGITAL_CTRL,
2539 /* Force 1Gbps using autoneg with 1G
2542 /* Allow CL37 through CL73 */
2543 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
2544 bnx2x_cl45_write(bp, params->port,
2548 MDIO_AN_REG_CL37_CL73,
2551 /* Enable Full-Duplex advertisment on CL37 */
2552 bnx2x_cl45_write(bp, params->port,
2556 MDIO_AN_REG_CL37_FC_LP,
2558 /* Enable CL37 AN */
2559 bnx2x_cl45_write(bp, params->port,
2563 MDIO_AN_REG_CL37_AN,
2566 bnx2x_cl45_write(bp, params->port,
2570 MDIO_AN_REG_ADV, (1<<5));
2572 /* Enable clause 73 AN */
2573 bnx2x_cl45_write(bp, params->port,
2584 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2585 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2588 u16 rx_alarm_ctrl_val;
2591 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2592 rx_alarm_ctrl_val = 0x400;
2593 lasi_ctrl_val = 0x0004;
2595 rx_alarm_ctrl_val = (1<<2);
2596 lasi_ctrl_val = 0x0004;
2600 bnx2x_cl45_write(bp, params->port,
2604 MDIO_PMA_REG_RX_ALARM_CTRL,
2607 bnx2x_cl45_write(bp, params->port,
2611 MDIO_PMA_REG_LASI_CTRL,
2614 bnx2x_8073_set_pause_cl37(params, vars);
2617 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
2618 bnx2x_bcm8072_external_rom_boot(params);
2621 /* In case of 8073 with long xaui lines,
2622 don't set the 8073 xaui low power*/
2623 bnx2x_bcm8073_set_xaui_low_power_mode(params);
2626 bnx2x_cl45_read(bp, params->port,
2633 bnx2x_cl45_read(bp, params->port,
2637 MDIO_PMA_REG_RX_ALARM, &tmp1);
2639 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
2642 /* If this is forced speed, set to KR or KX
2643 * (all other are not supported)
2645 if (params->loopback_mode == LOOPBACK_EXT) {
2646 bnx2x_bcm807x_force_10G(params);
2648 "Forced speed 10G on 807X\n");
2651 bnx2x_cl45_write(bp, params->port,
2652 ext_phy_type, ext_phy_addr,
2654 MDIO_PMA_REG_BCM_CTRL,
2657 if (params->req_line_speed != SPEED_AUTO_NEG) {
2658 if (params->req_line_speed == SPEED_10000) {
2660 } else if (params->req_line_speed ==
2663 /* Note that 2.5G works only
2664 when used with 1G advertisment */
2670 if (params->speed_cap_mask &
2671 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2674 /* Note that 2.5G works only when
2675 used with 1G advertisment */
2676 if (params->speed_cap_mask &
2677 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
2678 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
2681 "807x autoneg val = 0x%x\n", val);
2684 bnx2x_cl45_write(bp, params->port,
2688 MDIO_AN_REG_ADV, val);
2691 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2693 bnx2x_cl45_read(bp, params->port,
2699 if (((params->speed_cap_mask &
2700 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
2701 (params->req_line_speed ==
2703 (params->req_line_speed ==
2706 /* Allow 2.5G for A1 and above */
2707 bnx2x_cl45_read(bp, params->port,
2708 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2712 DP(NETIF_MSG_LINK, "Add 2.5G\n");
2718 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
2722 bnx2x_cl45_write(bp, params->port,
2729 /* Add support for CL37 (passive mode) II */
2731 bnx2x_cl45_read(bp, params->port,
2735 MDIO_AN_REG_CL37_FC_LD,
2738 bnx2x_cl45_write(bp, params->port,
2742 MDIO_AN_REG_CL37_FC_LD, (tmp1 |
2743 ((params->req_duplex == DUPLEX_FULL) ?
2746 /* Add support for CL37 (passive mode) III */
2747 bnx2x_cl45_write(bp, params->port,
2751 MDIO_AN_REG_CL37_AN, 0x1000);
2754 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2755 /* The SNR will improve about 2db by changing
2756 BW and FEE main tap. Rest commands are executed
2758 /*Change FFE main cursor to 5 in EDC register*/
2759 if (bnx2x_8073_is_snr_needed(params))
2760 bnx2x_cl45_write(bp, params->port,
2764 MDIO_PMA_REG_EDC_FFE_MAIN,
2767 /* Enable FEC (Forware Error Correction)
2768 Request in the AN */
2769 bnx2x_cl45_read(bp, params->port,
2773 MDIO_AN_REG_ADV2, &tmp1);
2777 bnx2x_cl45_write(bp, params->port,
2781 MDIO_AN_REG_ADV2, tmp1);
2785 bnx2x_ext_phy_set_pause(params, vars);
2787 /* Restart autoneg */
2789 bnx2x_cl45_write(bp, params->port,
2793 MDIO_AN_REG_CTRL, 0x1200);
2794 DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
2795 "Advertise 1G=%x, 10G=%x\n",
2796 ((val & (1<<5)) > 0),
2797 ((val & (1<<7)) > 0));
2800 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
2802 "Setting the SFX7101 LASI indication\n");
2804 bnx2x_cl45_write(bp, params->port,
2808 MDIO_PMA_REG_LASI_CTRL, 0x1);
2810 "Setting the SFX7101 LED to blink on traffic\n");
2811 bnx2x_cl45_write(bp, params->port,
2815 MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
2817 bnx2x_ext_phy_set_pause(params, vars);
2818 /* Restart autoneg */
2819 bnx2x_cl45_read(bp, params->port,
2823 MDIO_AN_REG_CTRL, &val);
2825 bnx2x_cl45_write(bp, params->port,
2829 MDIO_AN_REG_CTRL, val);
2831 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2833 "XGXS PHY Failure detected 0x%x\n",
2834 params->ext_phy_config);
2838 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
2839 params->ext_phy_config);
2844 } else { /* SerDes */
2846 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2847 switch (ext_phy_type) {
2848 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
2849 DP(NETIF_MSG_LINK, "SerDes Direct\n");
2852 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
2853 DP(NETIF_MSG_LINK, "SerDes 5482\n");
2857 DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
2858 params->ext_phy_config);
2866 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2867 struct link_vars *vars)
2869 struct bnx2x *bp = params->bp;
2873 u16 rx_sd, pcs_status;
2874 u8 ext_phy_link_up = 0;
2875 u8 port = params->port;
2876 if (vars->phy_flags & PHY_XGXS_FLAG) {
2877 ext_phy_addr = ((params->ext_phy_config &
2878 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2879 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2881 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2882 switch (ext_phy_type) {
2883 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2884 DP(NETIF_MSG_LINK, "XGXS Direct\n");
2885 ext_phy_link_up = 1;
2888 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2889 DP(NETIF_MSG_LINK, "XGXS 8705\n");
2890 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2893 MDIO_WIS_REG_LASI_STATUS, &val1);
2894 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2896 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2899 MDIO_WIS_REG_LASI_STATUS, &val1);
2900 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2902 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2905 MDIO_PMA_REG_RX_SD, &rx_sd);
2906 DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
2907 ext_phy_link_up = (rx_sd & 0x1);
2908 if (ext_phy_link_up)
2909 vars->line_speed = SPEED_10000;
2912 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2913 DP(NETIF_MSG_LINK, "XGXS 8706\n");
2914 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2917 MDIO_PMA_REG_LASI_STATUS, &val1);
2918 DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2920 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2923 MDIO_PMA_REG_LASI_STATUS, &val1);
2924 DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2926 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2929 MDIO_PMA_REG_RX_SD, &rx_sd);
2930 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2933 MDIO_PCS_REG_STATUS, &pcs_status);
2935 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2938 MDIO_AN_REG_LINK_STATUS, &val2);
2939 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2942 MDIO_AN_REG_LINK_STATUS, &val2);
2944 DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
2945 " pcs_status 0x%x 1Gbps link_status 0x%x\n",
2946 rx_sd, pcs_status, val2);
2947 /* link is up if both bit 0 of pmd_rx_sd and
2948 * bit 0 of pcs_status are set, or if the autoneg bit
2951 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
2953 if (ext_phy_link_up) {
2955 vars->line_speed = SPEED_1000;
2957 vars->line_speed = SPEED_10000;
2960 /* clear LASI indication*/
2961 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2964 MDIO_PMA_REG_RX_ALARM, &val2);
2967 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2968 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2970 u16 link_status = 0;
2971 u16 an1000_status = 0;
2973 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2974 bnx2x_cl45_read(bp, params->port,
2978 MDIO_PCS_REG_LASI_STATUS, &val1);
2979 bnx2x_cl45_read(bp, params->port,
2983 MDIO_PCS_REG_LASI_STATUS, &val2);
2985 "870x LASI status 0x%x->0x%x\n",
2989 /* In 8073, port1 is directed through emac0 and
2990 * port0 is directed through emac1
2992 bnx2x_cl45_read(bp, params->port,
2996 MDIO_PMA_REG_LASI_STATUS, &val1);
2999 "8703 LASI status 0x%x\n",
3003 /* clear the interrupt LASI status register */
3004 bnx2x_cl45_read(bp, params->port,
3008 MDIO_PCS_REG_STATUS, &val2);
3009 bnx2x_cl45_read(bp, params->port,
3013 MDIO_PCS_REG_STATUS, &val1);
3014 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
3017 bnx2x_cl45_read(bp, params->port,
3024 /* Check the LASI */
3025 bnx2x_cl45_read(bp, params->port,
3029 MDIO_PMA_REG_RX_ALARM, &val2);
3031 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
3033 /* Check the link status */
3034 bnx2x_cl45_read(bp, params->port,
3038 MDIO_PCS_REG_STATUS, &val2);
3039 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
3041 bnx2x_cl45_read(bp, params->port,
3045 MDIO_PMA_REG_STATUS, &val2);
3046 bnx2x_cl45_read(bp, params->port,
3050 MDIO_PMA_REG_STATUS, &val1);
3051 ext_phy_link_up = ((val1 & 4) == 4);
3052 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
3054 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3056 if (ext_phy_link_up &&
3057 ((params->req_line_speed !=
3059 if (bnx2x_bcm8073_xaui_wa(params)
3061 ext_phy_link_up = 0;
3065 bnx2x_cl45_read(bp, params->port,
3071 bnx2x_cl45_read(bp, params->port,
3078 /* Check the link status on 1.1.2 */
3079 bnx2x_cl45_read(bp, params->port,
3083 MDIO_PMA_REG_STATUS, &val2);
3084 bnx2x_cl45_read(bp, params->port,
3088 MDIO_PMA_REG_STATUS, &val1);
3089 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3090 "an_link_status=0x%x\n",
3091 val2, val1, an1000_status);
3093 ext_phy_link_up = (((val1 & 4) == 4) ||
3094 (an1000_status & (1<<1)));
3095 if (ext_phy_link_up &&
3096 bnx2x_8073_is_snr_needed(params)) {
3097 /* The SNR will improve about 2dbby
3098 changing the BW and FEE main tap.*/
3100 /* The 1st write to change FFE main
3101 tap is set before restart AN */
3102 /* Change PLL Bandwidth in EDC
3104 bnx2x_cl45_write(bp, port, ext_phy_type,
3107 MDIO_PMA_REG_PLL_BANDWIDTH,
3110 /* Change CDR Bandwidth in EDC
3112 bnx2x_cl45_write(bp, port, ext_phy_type,
3115 MDIO_PMA_REG_CDR_BANDWIDTH,
3120 bnx2x_cl45_read(bp, params->port,
3127 /* Bits 0..2 --> speed detected,
3128 bits 13..15--> link is down */
3129 if ((link_status & (1<<2)) &&
3130 (!(link_status & (1<<15)))) {
3131 ext_phy_link_up = 1;
3132 vars->line_speed = SPEED_10000;
3134 "port %x: External link"
3135 " up in 10G\n", params->port);
3136 } else if ((link_status & (1<<1)) &&
3137 (!(link_status & (1<<14)))) {
3138 ext_phy_link_up = 1;
3139 vars->line_speed = SPEED_2500;
3141 "port %x: External link"
3142 " up in 2.5G\n", params->port);
3143 } else if ((link_status & (1<<0)) &&
3144 (!(link_status & (1<<13)))) {
3145 ext_phy_link_up = 1;
3146 vars->line_speed = SPEED_1000;
3148 "port %x: External link"
3149 " up in 1G\n", params->port);
3151 ext_phy_link_up = 0;
3153 "port %x: External link"
3154 " is down\n", params->port);
3157 /* See if 1G link is up for the 8072 */
3158 bnx2x_cl45_read(bp, params->port,
3164 bnx2x_cl45_read(bp, params->port,
3170 if (an1000_status & (1<<1)) {
3171 ext_phy_link_up = 1;
3172 vars->line_speed = SPEED_1000;
3174 "port %x: External link"
3175 " up in 1G\n", params->port);
3176 } else if (ext_phy_link_up) {
3177 ext_phy_link_up = 1;
3178 vars->line_speed = SPEED_10000;
3180 "port %x: External link"
3181 " up in 10G\n", params->port);
3188 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3189 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3192 MDIO_PMA_REG_LASI_STATUS, &val2);
3193 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3196 MDIO_PMA_REG_LASI_STATUS, &val1);
3198 "10G-base-T LASI status 0x%x->0x%x\n",
3200 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3203 MDIO_PMA_REG_STATUS, &val2);
3204 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3207 MDIO_PMA_REG_STATUS, &val1);
3209 "10G-base-T PMA status 0x%x->0x%x\n",
3211 ext_phy_link_up = ((val1 & 4) == 4);
3213 * print the AN outcome of the SFX7101 PHY
3215 if (ext_phy_link_up) {
3216 bnx2x_cl45_read(bp, params->port,
3220 MDIO_AN_REG_MASTER_STATUS,
3222 vars->line_speed = SPEED_10000;
3224 "SFX7101 AN status 0x%x->Master=%x\n",
3231 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3232 params->ext_phy_config);
3233 ext_phy_link_up = 0;
3237 } else { /* SerDes */
3238 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3239 switch (ext_phy_type) {
3240 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3241 DP(NETIF_MSG_LINK, "SerDes Direct\n");
3242 ext_phy_link_up = 1;
3245 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3246 DP(NETIF_MSG_LINK, "SerDes 5482\n");
3247 ext_phy_link_up = 1;
3252 "BAD SerDes ext_phy_config 0x%x\n",
3253 params->ext_phy_config);
3254 ext_phy_link_up = 0;
3259 return ext_phy_link_up;
3262 static void bnx2x_link_int_enable(struct link_params *params)
3264 u8 port = params->port;
3267 struct bnx2x *bp = params->bp;
3268 /* setting the status to report on link up
3269 for either XGXS or SerDes */
3271 if (params->switch_cfg == SWITCH_CFG_10G) {
3272 mask = (NIG_MASK_XGXS0_LINK10G |
3273 NIG_MASK_XGXS0_LINK_STATUS);
3274 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
3275 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3276 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3277 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3279 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
3280 mask |= NIG_MASK_MI_INT;
3281 DP(NETIF_MSG_LINK, "enabled external phy int\n");
3284 } else { /* SerDes */
3285 mask = NIG_MASK_SERDES0_LINK_STATUS;
3286 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
3287 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3288 if ((ext_phy_type !=
3289 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
3291 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
3292 mask |= NIG_MASK_MI_INT;
3293 DP(NETIF_MSG_LINK, "enabled external phy int\n");
3297 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3299 DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
3300 (params->switch_cfg == SWITCH_CFG_10G),
3301 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
3303 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
3304 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
3305 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
3306 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
3307 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
3308 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
3309 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
3316 static void bnx2x_link_int_ack(struct link_params *params,
3317 struct link_vars *vars, u8 is_10g)
3319 struct bnx2x *bp = params->bp;
3320 u8 port = params->port;
3322 /* first reset all status
3323 * we assume only one line will be change at a time */
3324 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3325 (NIG_STATUS_XGXS0_LINK10G |
3326 NIG_STATUS_XGXS0_LINK_STATUS |
3327 NIG_STATUS_SERDES0_LINK_STATUS));
3328 if (vars->phy_link_up) {
3330 /* Disable the 10G link interrupt
3331 * by writing 1 to the status register
3333 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
3335 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3336 NIG_STATUS_XGXS0_LINK10G);
3338 } else if (params->switch_cfg == SWITCH_CFG_10G) {
3339 /* Disable the link interrupt
3340 * by writing 1 to the relevant lane
3341 * in the status register
3343 u32 ser_lane = ((params->lane_config &
3344 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3345 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3347 DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
3349 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3351 NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
3353 } else { /* SerDes */
3354 DP(NETIF_MSG_LINK, "SerDes phy link up\n");
3355 /* Disable the link interrupt
3356 * by writing 1 to the status register
3359 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3360 NIG_STATUS_SERDES0_LINK_STATUS);
3363 } else { /* link_down */
3367 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
3370 u32 mask = 0xf0000000;
3374 /* Need more than 10chars for this format */
3381 digit = ((num & mask) >> shift);
3383 *str_ptr = digit + '0';
3385 *str_ptr = digit - 0xa + 'a';
3398 static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
3403 /* Enable EMAC0 in to enable MDIO */
3404 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
3405 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
3408 /* take ext phy out of reset */
3410 MISC_REGISTERS_GPIO_2,
3411 MISC_REGISTERS_GPIO_HIGH,
3415 MISC_REGISTERS_GPIO_1,
3416 MISC_REGISTERS_GPIO_HIGH,
3422 for (cnt = 0; cnt < 1000; cnt++) {
3424 bnx2x_cl45_read(bp, port,
3430 if (!(ctrl & (1<<15))) {
3431 DP(NETIF_MSG_LINK, "Reset completed\n\n");
3437 static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
3439 /* put sf to reset */
3441 MISC_REGISTERS_GPIO_1,
3442 MISC_REGISTERS_GPIO_LOW,
3445 MISC_REGISTERS_GPIO_2,
3446 MISC_REGISTERS_GPIO_LOW,
3450 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3451 u8 *version, u16 len)
3453 struct bnx2x *bp = params->bp;
3454 u32 ext_phy_type = 0;
3456 u8 ext_phy_addr = 0 ;
3460 if (version == NULL || params == NULL)
3463 /* reset the returned value to zero */
3464 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3465 ext_phy_addr = ((params->ext_phy_config &
3466 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3467 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3469 switch (ext_phy_type) {
3470 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3475 /* Take ext phy out of reset */
3477 bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3483 bnx2x_cl45_read(bp, params->port,
3487 MDIO_PMA_REG_7101_VER1, &val);
3488 version[2] = (val & 0xFF);
3489 version[3] = ((val & 0xFF00)>>8);
3491 bnx2x_cl45_read(bp, params->port,
3494 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2,
3496 version[0] = (val & 0xFF);
3497 version[1] = ((val & 0xFF00)>>8);
3501 bnx2x_turn_off_sf(bp, params->port);
3503 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3504 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3506 /* Take ext phy out of reset */
3508 bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3511 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3514 MDIO_PMA_REG_ROM_VER1, &val);
3516 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3519 MDIO_PMA_REG_ROM_VER2, &val);
3521 status = bnx2x_format_ver(ver_num, version, len);
3524 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3525 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3527 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3530 MDIO_PMA_REG_ROM_VER1, &val);
3532 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3535 MDIO_PMA_REG_ROM_VER2, &val);
3537 status = bnx2x_format_ver(ver_num, version, len);
3540 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3543 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
3544 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
3545 " type is FAILURE!\n");
3555 static void bnx2x_set_xgxs_loopback(struct link_params *params,
3556 struct link_vars *vars,
3559 u8 port = params->port;
3560 struct bnx2x *bp = params->bp;
3565 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
3567 /* change the uni_phy_addr in the nig */
3568 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
3571 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
3573 bnx2x_cl45_write(bp, port, 0,
3576 (MDIO_REG_BANK_AER_BLOCK +
3577 (MDIO_AER_BLOCK_AER_REG & 0xf)),
3580 bnx2x_cl45_write(bp, port, 0,
3583 (MDIO_REG_BANK_CL73_IEEEB0 +
3584 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
3587 /* set aer mmd back */
3588 bnx2x_set_aer_mmd(params, vars);
3591 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
3597 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
3599 CL45_RD_OVER_CL22(bp, port,
3601 MDIO_REG_BANK_COMBO_IEEE0,
3602 MDIO_COMBO_IEEE0_MII_CONTROL,
3605 CL45_WR_OVER_CL22(bp, port,
3607 MDIO_REG_BANK_COMBO_IEEE0,
3608 MDIO_COMBO_IEEE0_MII_CONTROL,
3610 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
3615 static void bnx2x_ext_phy_loopback(struct link_params *params)
3617 struct bnx2x *bp = params->bp;
3621 if (params->switch_cfg == SWITCH_CFG_10G) {
3622 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3623 /* CL37 Autoneg Enabled */
3624 ext_phy_addr = ((params->ext_phy_config &
3625 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3626 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3627 switch (ext_phy_type) {
3628 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3629 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
3631 "ext_phy_loopback: We should not get here\n");
3633 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3634 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
3636 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3637 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
3639 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3640 /* SFX7101_XGXS_TEST1 */
3641 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3644 MDIO_XS_SFX7101_XGXS_TEST1,
3647 "ext_phy_loopback: set ext phy loopback\n");
3649 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3652 } /* switch external PHY type */
3655 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3656 ext_phy_addr = (params->ext_phy_config &
3657 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
3658 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
3664 *------------------------------------------------------------------------
3665 * bnx2x_override_led_value -
3667 * Override the led value of the requsted led
3669 *------------------------------------------------------------------------
3671 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
3672 u32 led_idx, u32 value)
3676 /* If port 0 then use EMAC0, else use EMAC1*/
3677 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3680 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
3681 port, led_idx, value);
3684 case 0: /* 10MB led */
3685 /* Read the current value of the LED register in
3687 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3688 /* Set the OVERRIDE bit to 1 */
3689 reg_val |= EMAC_LED_OVERRIDE;
3690 /* If value is 1, set the 10M_OVERRIDE bit,
3691 otherwise reset it.*/
3692 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
3693 (reg_val & ~EMAC_LED_10MB_OVERRIDE);
3694 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3696 case 1: /*100MB led */
3697 /*Read the current value of the LED register in
3699 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3700 /* Set the OVERRIDE bit to 1 */
3701 reg_val |= EMAC_LED_OVERRIDE;
3702 /* If value is 1, set the 100M_OVERRIDE bit,
3703 otherwise reset it.*/
3704 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
3705 (reg_val & ~EMAC_LED_100MB_OVERRIDE);
3706 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3708 case 2: /* 1000MB led */
3709 /* Read the current value of the LED register in the
3711 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3712 /* Set the OVERRIDE bit to 1 */
3713 reg_val |= EMAC_LED_OVERRIDE;
3714 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
3716 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
3717 (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
3718 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3720 case 3: /* 2500MB led */
3721 /* Read the current value of the LED register in the
3723 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3724 /* Set the OVERRIDE bit to 1 */
3725 reg_val |= EMAC_LED_OVERRIDE;
3726 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
3728 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
3729 (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
3730 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3732 case 4: /*10G led */
3734 REG_WR(bp, NIG_REG_LED_10G_P0,
3737 REG_WR(bp, NIG_REG_LED_10G_P1,
3741 case 5: /* TRAFFIC led */
3742 /* Find if the traffic control is via BMAC or EMAC */
3744 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
3746 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
3748 /* Override the traffic led in the EMAC:*/
3750 /* Read the current value of the LED register in
3752 reg_val = REG_RD(bp, emac_base +
3754 /* Set the TRAFFIC_OVERRIDE bit to 1 */
3755 reg_val |= EMAC_LED_OVERRIDE;
3756 /* If value is 1, set the TRAFFIC bit, otherwise
3758 reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
3759 (reg_val & ~EMAC_LED_TRAFFIC);
3760 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3761 } else { /* Override the traffic led in the BMAC: */
3762 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3764 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
3770 "bnx2x_override_led_value() unknown led index %d "
3771 "(should be 0-5)\n", led_idx);
3779 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
3780 u16 hw_led_mode, u32 chip_id)
3784 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3785 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
3786 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
3787 speed, hw_led_mode);
3790 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
3791 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
3792 SHARED_HW_CFG_LED_MAC1);
3794 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3795 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
3799 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
3800 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
3802 /* Set blinking rate to ~15.9Hz */
3803 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
3804 LED_BLINK_RATE_VAL);
3805 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
3807 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3808 EMAC_WR(bp, EMAC_REG_EMAC_LED,
3809 (tmp & (~EMAC_LED_OVERRIDE)));
3811 if (!CHIP_IS_E1H(bp) &&
3812 ((speed == SPEED_2500) ||
3813 (speed == SPEED_1000) ||
3814 (speed == SPEED_100) ||
3815 (speed == SPEED_10))) {
3816 /* On Everest 1 Ax chip versions for speeds less than
3817 10G LED scheme is different */
3818 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3820 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
3822 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
3829 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
3837 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
3839 struct bnx2x *bp = params->bp;
3842 CL45_RD_OVER_CL22(bp, params->port,
3844 MDIO_REG_BANK_GP_STATUS,
3845 MDIO_GP_STATUS_TOP_AN_STATUS1,
3847 /* link is up only if both local phy and external phy are up */
3848 if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
3849 bnx2x_ext_phy_is_link_up(params, vars))
3855 static u8 bnx2x_link_initialize(struct link_params *params,
3856 struct link_vars *vars)
3858 struct bnx2x *bp = params->bp;
3859 u8 port = params->port;
3862 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3863 /* Activate the external PHY */
3864 bnx2x_ext_phy_reset(params, vars);
3866 bnx2x_set_aer_mmd(params, vars);
3868 if (vars->phy_flags & PHY_XGXS_FLAG)
3869 bnx2x_set_master_ln(params);
3871 rc = bnx2x_reset_unicore(params);
3872 /* reset the SerDes and wait for reset bit return low */
3876 bnx2x_set_aer_mmd(params, vars);
3878 /* setting the masterLn_def again after the reset */
3879 if (vars->phy_flags & PHY_XGXS_FLAG) {
3880 bnx2x_set_master_ln(params);
3881 bnx2x_set_swap_lanes(params);
3884 if (vars->phy_flags & PHY_XGXS_FLAG) {
3885 if ((params->req_line_speed &&
3886 ((params->req_line_speed == SPEED_100) ||
3887 (params->req_line_speed == SPEED_10))) ||
3888 (!params->req_line_speed &&
3889 (params->speed_cap_mask >=
3890 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
3891 (params->speed_cap_mask <
3892 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
3894 vars->phy_flags |= PHY_SGMII_FLAG;
3896 vars->phy_flags &= ~PHY_SGMII_FLAG;
3899 /* In case of external phy existance, the line speed would be the
3900 line speed linked up by the external phy. In case it is direct only,
3901 then the line_speed during initialization will be equal to the
3903 vars->line_speed = params->req_line_speed;
3905 bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
3907 /* init ext phy and enable link state int */
3908 non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
3909 (params->loopback_mode == LOOPBACK_XGXS_10) ||
3910 (params->loopback_mode == LOOPBACK_EXT_PHY));
3913 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705)) {
3914 if (params->req_line_speed == SPEED_AUTO_NEG)
3915 bnx2x_set_parallel_detection(params, vars->phy_flags);
3916 bnx2x_init_internal_phy(params, vars);
3920 rc |= bnx2x_ext_phy_init(params, vars);
3922 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3923 (NIG_STATUS_XGXS0_LINK10G |
3924 NIG_STATUS_XGXS0_LINK_STATUS |
3925 NIG_STATUS_SERDES0_LINK_STATUS));
3932 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
3934 struct bnx2x *bp = params->bp;
3937 DP(NETIF_MSG_LINK, "Phy Initialization started \n");
3938 DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
3939 params->req_line_speed, params->req_flow_ctrl);
3940 vars->link_status = 0;
3941 vars->phy_link_up = 0;
3943 vars->line_speed = 0;
3944 vars->duplex = DUPLEX_FULL;
3945 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3946 vars->mac_type = MAC_TYPE_NONE;
3948 if (params->switch_cfg == SWITCH_CFG_1G)
3949 vars->phy_flags = PHY_SERDES_FLAG;
3951 vars->phy_flags = PHY_XGXS_FLAG;
3954 /* disable attentions */
3955 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
3956 (NIG_MASK_XGXS0_LINK_STATUS |
3957 NIG_MASK_XGXS0_LINK10G |
3958 NIG_MASK_SERDES0_LINK_STATUS |
3961 bnx2x_emac_init(params, vars);
3963 if (CHIP_REV_IS_FPGA(bp)) {
3965 vars->line_speed = SPEED_10000;
3966 vars->duplex = DUPLEX_FULL;
3967 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3968 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3969 /* enable on E1.5 FPGA */
3970 if (CHIP_IS_E1H(bp)) {
3972 (BNX2X_FLOW_CTRL_TX | BNX2X_FLOW_CTRL_RX);
3973 vars->link_status |=
3974 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
3975 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
3978 bnx2x_emac_enable(params, vars, 0);
3979 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3981 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3982 + params->port*4, 0);
3984 /* update shared memory */
3985 bnx2x_update_mng(params, vars->link_status);
3990 if (CHIP_REV_IS_EMUL(bp)) {
3993 vars->line_speed = SPEED_10000;
3994 vars->duplex = DUPLEX_FULL;
3995 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3996 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3998 bnx2x_bmac_enable(params, vars, 0);
4000 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4002 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4003 + params->port*4, 0);
4005 /* update shared memory */
4006 bnx2x_update_mng(params, vars->link_status);
4011 if (params->loopback_mode == LOOPBACK_BMAC) {
4013 vars->line_speed = SPEED_10000;
4014 vars->duplex = DUPLEX_FULL;
4015 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4016 vars->mac_type = MAC_TYPE_BMAC;
4018 vars->phy_flags = PHY_XGXS_FLAG;
4020 bnx2x_phy_deassert(params, vars->phy_flags);
4021 /* set bmac loopback */
4022 bnx2x_bmac_enable(params, vars, 1);
4024 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4026 } else if (params->loopback_mode == LOOPBACK_EMAC) {
4028 vars->line_speed = SPEED_1000;
4029 vars->duplex = DUPLEX_FULL;
4030 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4031 vars->mac_type = MAC_TYPE_EMAC;
4033 vars->phy_flags = PHY_XGXS_FLAG;
4035 bnx2x_phy_deassert(params, vars->phy_flags);
4036 /* set bmac loopback */
4037 bnx2x_emac_enable(params, vars, 1);
4038 bnx2x_emac_program(params, vars->line_speed,
4040 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4042 } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
4043 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
4045 vars->line_speed = SPEED_10000;
4046 vars->duplex = DUPLEX_FULL;
4047 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4049 vars->phy_flags = PHY_XGXS_FLAG;
4052 NIG_REG_XGXS0_CTRL_PHY_ADDR+
4054 params->phy_addr = (u8)val;
4056 bnx2x_phy_deassert(params, vars->phy_flags);
4057 bnx2x_link_initialize(params, vars);
4059 vars->mac_type = MAC_TYPE_BMAC;
4061 bnx2x_bmac_enable(params, vars, 0);
4063 if (params->loopback_mode == LOOPBACK_XGXS_10) {
4064 /* set 10G XGXS loopback */
4065 bnx2x_set_xgxs_loopback(params, vars, 1);
4067 /* set external phy loopback */
4068 bnx2x_ext_phy_loopback(params);
4070 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4076 bnx2x_phy_deassert(params, vars->phy_flags);
4077 switch (params->switch_cfg) {
4079 vars->phy_flags |= PHY_SERDES_FLAG;
4080 if ((params->ext_phy_config &
4081 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
4082 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
4088 NIG_REG_SERDES0_CTRL_PHY_ADDR+
4091 params->phy_addr = (u8)val;
4094 case SWITCH_CFG_10G:
4095 vars->phy_flags |= PHY_XGXS_FLAG;
4097 NIG_REG_XGXS0_CTRL_PHY_ADDR+
4099 params->phy_addr = (u8)val;
4103 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
4108 bnx2x_link_initialize(params, vars);
4110 bnx2x_link_int_enable(params);
4115 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
4118 struct bnx2x *bp = params->bp;
4119 u32 ext_phy_config = params->ext_phy_config;
4120 u16 hw_led_mode = params->hw_led_mode;
4121 u32 chip_id = params->chip_id;
4122 u8 port = params->port;
4123 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4124 /* disable attentions */
4126 vars->link_status = 0;
4127 bnx2x_update_mng(params, vars->link_status);
4128 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4129 (NIG_MASK_XGXS0_LINK_STATUS |
4130 NIG_MASK_XGXS0_LINK10G |
4131 NIG_MASK_SERDES0_LINK_STATUS |
4134 /* activate nig drain */
4135 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4137 /* disable nig egress interface */
4138 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4139 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4141 /* Stop BigMac rx */
4142 bnx2x_bmac_rx_disable(bp, port);
4145 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4148 /* The PHY reset is controled by GPIO 1
4149 * Hold it as vars low
4151 /* clear link led */
4152 bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4153 if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
4154 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
4155 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
4158 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4159 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4162 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4163 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4166 DP(NETIF_MSG_LINK, "reset external PHY\n");
4167 } else if (ext_phy_type ==
4168 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4169 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4172 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4173 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4177 /* reset the SerDes/XGXS */
4178 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4179 (0x1ff << (port*16)));
4182 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4183 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4185 /* disable nig ingress interface */
4186 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4187 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4188 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4189 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4194 static u8 bnx2x_update_link_down(struct link_params *params,
4195 struct link_vars *vars)
4197 struct bnx2x *bp = params->bp;
4198 u8 port = params->port;
4199 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4200 bnx2x_set_led(bp, port, LED_MODE_OFF,
4201 0, params->hw_led_mode,
4204 /* indicate no mac active */
4205 vars->mac_type = MAC_TYPE_NONE;
4207 /* update shared memory */
4208 vars->link_status = 0;
4209 vars->line_speed = 0;
4210 bnx2x_update_mng(params, vars->link_status);
4212 /* activate nig drain */
4213 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4216 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4221 bnx2x_bmac_rx_disable(bp, params->port);
4222 REG_WR(bp, GRCBASE_MISC +
4223 MISC_REGISTERS_RESET_REG_2_CLEAR,
4224 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4228 static u8 bnx2x_update_link_up(struct link_params *params,
4229 struct link_vars *vars,
4230 u8 link_10g, u32 gp_status)
4232 struct bnx2x *bp = params->bp;
4233 u8 port = params->port;
4235 vars->link_status |= LINK_STATUS_LINK_UP;
4237 bnx2x_bmac_enable(params, vars, 0);
4238 bnx2x_set_led(bp, port, LED_MODE_OPER,
4239 SPEED_10000, params->hw_led_mode,
4243 bnx2x_emac_enable(params, vars, 0);
4244 rc = bnx2x_emac_program(params, vars->line_speed,
4248 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4249 if (!(vars->phy_flags &
4251 bnx2x_set_sgmii_tx_driver(params);
4256 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4260 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4262 /* update shared memory */
4263 bnx2x_update_mng(params, vars->link_status);
4267 /* This function should called upon link interrupt */
4268 /* In case vars->link_up, driver needs to
4271 3. Update the shared memory
4275 1. Update shared memory
4280 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4282 struct bnx2x *bp = params->bp;
4283 u8 port = params->port;
4286 u8 ext_phy_link_up, rc = 0;
4289 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
4291 (vars->phy_flags & PHY_XGXS_FLAG),
4292 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4294 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4295 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4296 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4297 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
4299 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4300 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4301 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4304 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4306 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4308 /* Check external link change only for non-direct */
4309 ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
4311 /* Read gp_status */
4312 CL45_RD_OVER_CL22(bp, port, params->phy_addr,
4313 MDIO_REG_BANK_GP_STATUS,
4314 MDIO_GP_STATUS_TOP_AN_STATUS1,
4317 rc = bnx2x_link_settings_status(params, vars, gp_status);
4321 /* anything 10 and over uses the bmac */
4322 link_10g = ((vars->line_speed == SPEED_10000) ||
4323 (vars->line_speed == SPEED_12000) ||
4324 (vars->line_speed == SPEED_12500) ||
4325 (vars->line_speed == SPEED_13000) ||
4326 (vars->line_speed == SPEED_15000) ||
4327 (vars->line_speed == SPEED_16000));
4329 bnx2x_link_int_ack(params, vars, link_10g);
4331 /* In case external phy link is up, and internal link is down
4332 ( not initialized yet probably after link initialization, it needs
4334 Note that after link down-up as result of cable plug,
4335 the xgxs link would probably become up again without the need to
4338 if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4339 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
4340 (ext_phy_link_up && !vars->phy_link_up))
4341 bnx2x_init_internal_phy(params, vars);
4343 /* link is up only if both local phy and external phy are up */
4344 vars->link_up = (ext_phy_link_up && vars->phy_link_up);
4347 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
4349 rc = bnx2x_update_link_down(params, vars);
4354 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4356 u8 ext_phy_addr[PORT_MAX];
4360 /* PART1 - Reset both phys */
4361 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4362 /* Extract the ext phy address for the port */
4363 u32 ext_phy_config = REG_RD(bp, shmem_base +
4364 offsetof(struct shmem_region,
4365 dev_info.port_hw_config[port].external_phy_config));
4367 /* disable attentions */
4368 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4369 (NIG_MASK_XGXS0_LINK_STATUS |
4370 NIG_MASK_XGXS0_LINK10G |
4371 NIG_MASK_SERDES0_LINK_STATUS |
4374 ext_phy_addr[port] =
4376 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4377 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4379 /* Need to take the phy out of low power mode in order
4380 to write to access its registers */
4381 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4382 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
4385 bnx2x_cl45_write(bp, port,
4386 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4393 /* Add delay of 150ms after reset */
4396 /* PART2 - Download firmware to both phys */
4397 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4400 bnx2x_bcm8073_external_rom_boot(bp, port,
4401 ext_phy_addr[port]);
4403 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4406 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
4407 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
4409 "bnx2x_8073_common_init_phy port %x:"
4410 "Download failed. fw version = 0x%x\n",
4415 /* Only set bit 10 = 1 (Tx power down) */
4416 bnx2x_cl45_read(bp, port,
4417 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4420 MDIO_PMA_REG_TX_POWER_DOWN, &val);
4422 /* Phase1 of TX_POWER_DOWN reset */
4423 bnx2x_cl45_write(bp, port,
4424 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4427 MDIO_PMA_REG_TX_POWER_DOWN,
4431 /* Toggle Transmitter: Power down and then up with 600ms
4435 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
4436 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4437 /* Phase2 of POWER_DOWN_RESET*/
4438 /* Release bit 10 (Release Tx power down) */
4439 bnx2x_cl45_read(bp, port,
4440 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4443 MDIO_PMA_REG_TX_POWER_DOWN, &val);
4445 bnx2x_cl45_write(bp, port,
4446 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4449 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
4452 /* Read modify write the SPI-ROM version select register */
4453 bnx2x_cl45_read(bp, port,
4454 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4457 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
4458 bnx2x_cl45_write(bp, port,
4459 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4462 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
4464 /* set GPIO2 back to LOW */
4465 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4466 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
4472 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4477 DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n");
4479 /* Read the ext_phy_type for arbitrary port(0) */
4480 ext_phy_type = XGXS_EXT_PHY_TYPE(
4481 REG_RD(bp, shmem_base +
4482 offsetof(struct shmem_region,
4483 dev_info.port_hw_config[0].external_phy_config)));
4485 switch (ext_phy_type) {
4486 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4488 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
4493 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
4503 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
4507 bnx2x_cl45_read(bp, port,
4508 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4511 MDIO_PMA_REG_7101_RESET, &val);
4513 for (cnt = 0; cnt < 10; cnt++) {
4515 /* Writes a self-clearing reset */
4516 bnx2x_cl45_write(bp, port,
4517 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4520 MDIO_PMA_REG_7101_RESET,
4522 /* Wait for clear */
4523 bnx2x_cl45_read(bp, port,
4524 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4527 MDIO_PMA_REG_7101_RESET, &val);
4529 if ((val & (1<<15)) == 0)
4533 #define RESERVED_SIZE 256
4534 /* max application is 160K bytes - data at end of RAM */
4535 #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
4537 /* Header is 14 bytes */
4538 #define HEADER_SIZE 14
4539 #define DATA_OFFSET HEADER_SIZE
4541 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
4542 bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
4545 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
4547 /* Programs an image to DSP's flash via the SPI port*/
4548 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
4550 char data[], u32 size)
4552 const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
4553 /* Doesn't include last trans!*/
4554 const u16 last_trans_size = size%4; /* Num bytes on last trans */
4555 u16 trans_cnt, byte_cnt;
4558 u16 code_started = 0;
4559 u16 image_revision1, image_revision2;
4562 DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
4564 if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
4565 /* This very often will be the case, because the image is built
4566 with 160Kbytes size whereas the total image size must actually
4567 be 160Kbytes-RESERVED_SIZE */
4568 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
4569 "truncated to %d bytes\n", size, MAX_APP_SIZE);
4570 size = MAX_APP_SIZE+HEADER_SIZE;
4572 DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
4573 DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]);
4574 /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
4575 and issuing a reset.*/
4577 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4578 MISC_REGISTERS_GPIO_HIGH, port);
4580 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4583 for (cnt = 0; cnt < 100; cnt++)
4586 /* Make sure we can access the DSP
4587 And it's in the correct mode (waiting for download) */
4589 bnx2x_cl45_read(bp, port,
4590 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4593 MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
4595 if (tmp != 0x000A) {
4596 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
4597 "Expected 0x000A, read 0x%04X\n", tmp);
4598 DP(NETIF_MSG_LINK, "Download failed\n");
4602 /* Mux the SPI interface away from the internal processor */
4603 bnx2x_cl45_write(bp, port,
4604 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4607 MDIO_PCS_REG_7101_SPI_MUX, 1);
4609 /* Reset the SPI port */
4610 bnx2x_cl45_write(bp, port,
4611 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4614 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4615 bnx2x_cl45_write(bp, port,
4616 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4619 MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
4620 (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
4621 bnx2x_cl45_write(bp, port,
4622 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4625 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4627 /* Erase the flash */
4628 bnx2x_cl45_write(bp, port,
4629 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4632 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4633 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4635 bnx2x_cl45_write(bp, port,
4636 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4639 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4642 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4643 bnx2x_cl45_write(bp, port,
4644 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4647 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4648 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
4650 bnx2x_cl45_write(bp, port,
4651 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4654 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4656 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4658 /* Wait 10 seconds, the maximum time for the erase to complete */
4659 DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
4660 for (cnt = 0; cnt < 1000; cnt++)
4663 DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
4665 for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
4666 bnx2x_cl45_write(bp, port,
4667 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4670 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4671 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4673 bnx2x_cl45_write(bp, port,
4674 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4677 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4679 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4681 bnx2x_cl45_write(bp, port,
4682 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4685 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4686 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4688 /* Bits 23-16 of address */
4689 bnx2x_cl45_write(bp, port,
4690 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4693 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4695 /* Bits 15-8 of address */
4696 bnx2x_cl45_write(bp, port,
4697 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4700 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4703 /* Bits 7-0 of address */
4704 bnx2x_cl45_write(bp, port,
4705 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4708 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4712 while (byte_cnt < 4 && data_index < size) {
4713 bnx2x_cl45_write(bp, port,
4714 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4717 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4718 data[data_index++]);
4722 bnx2x_cl45_write(bp, port,
4723 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4726 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4729 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4730 msleep(5); /* Wait 5 ms minimum between transs */
4732 /* Let the user know something's going on.*/
4733 /* a pacifier ever 4K */
4734 if ((data_index % 1023) == 0)
4735 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4738 DP(NETIF_MSG_LINK, "\n");
4739 /* Transfer the last block if there is data remaining */
4740 if (last_trans_size) {
4741 bnx2x_cl45_write(bp, port,
4742 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4745 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4746 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4748 bnx2x_cl45_write(bp, port,
4749 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4752 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4755 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4757 bnx2x_cl45_write(bp, port,
4758 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4761 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4762 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4764 /* Bits 23-16 of address */
4765 bnx2x_cl45_write(bp, port,
4766 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4769 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4771 /* Bits 15-8 of address */
4772 bnx2x_cl45_write(bp, port,
4773 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4776 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4779 /* Bits 7-0 of address */
4780 bnx2x_cl45_write(bp, port,
4781 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4784 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4788 while (byte_cnt < last_trans_size && data_index < size) {
4789 /* Bits 7-0 of address */
4790 bnx2x_cl45_write(bp, port,
4791 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4794 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4795 data[data_index++]);
4799 bnx2x_cl45_write(bp, port,
4800 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4803 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4806 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4809 /* DSP Remove Download Mode */
4810 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4811 MISC_REGISTERS_GPIO_LOW, port);
4813 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4815 /* wait 0.5 sec to allow it to run */
4816 for (cnt = 0; cnt < 100; cnt++)
4819 bnx2x_hw_reset(bp, port);
4821 for (cnt = 0; cnt < 100; cnt++)
4824 /* Check that the code is started. In case the download
4825 checksum failed, the code won't be started. */
4826 bnx2x_cl45_read(bp, port,
4827 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4830 MDIO_PCS_REG_7101_DSP_ACCESS,
4833 code_started = (tmp & (1<<4));
4834 if (!code_started) {
4835 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
4839 /* Verify that the file revision is now equal to the image
4840 revision within the DSP */
4841 bnx2x_cl45_read(bp, port,
4842 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4845 MDIO_PMA_REG_7101_VER1,
4848 bnx2x_cl45_read(bp, port,
4849 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4852 MDIO_PMA_REG_7101_VER2,
4855 if (data[0x14e] != (image_revision2&0xFF) ||
4856 data[0x14f] != ((image_revision2&0xFF00)>>8) ||
4857 data[0x150] != (image_revision1&0xFF) ||
4858 data[0x151] != ((image_revision1&0xFF00)>>8)) {
4859 DP(NETIF_MSG_LINK, "Download failed.\n");
4862 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4866 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
4867 u8 driver_loaded, char data[], u32 size)
4872 ext_phy_addr = ((ext_phy_config &
4873 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4874 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4876 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4878 switch (ext_phy_type) {
4879 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4880 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4881 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4882 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4884 "Flash download not supported for this ext phy\n");
4887 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4888 /* Take ext phy out of reset */
4890 bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
4891 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
4894 bnx2x_turn_off_sf(bp, port);
4896 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4897 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4898 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4900 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");