1 /* Copyright 2008 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 vars->phy_flags |= PHY_SGMII_FLAG;
3890 vars->phy_flags &= ~PHY_SGMII_FLAG;
3893 /* In case of external phy existance, the line speed would be the
3894 line speed linked up by the external phy. In case it is direct only,
3895 then the line_speed during initialization will be equal to the
3897 vars->line_speed = params->req_line_speed;
3899 bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
3901 /* init ext phy and enable link state int */
3902 non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
3903 (params->loopback_mode == LOOPBACK_XGXS_10) ||
3904 (params->loopback_mode == LOOPBACK_EXT_PHY));
3907 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705)) {
3908 if (params->req_line_speed == SPEED_AUTO_NEG)
3909 bnx2x_set_parallel_detection(params, vars->phy_flags);
3910 bnx2x_init_internal_phy(params, vars);
3914 rc |= bnx2x_ext_phy_init(params, vars);
3916 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3917 (NIG_STATUS_XGXS0_LINK10G |
3918 NIG_STATUS_XGXS0_LINK_STATUS |
3919 NIG_STATUS_SERDES0_LINK_STATUS));
3926 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
3928 struct bnx2x *bp = params->bp;
3931 DP(NETIF_MSG_LINK, "Phy Initialization started \n");
3932 DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
3933 params->req_line_speed, params->req_flow_ctrl);
3934 vars->link_status = 0;
3935 vars->phy_link_up = 0;
3937 vars->line_speed = 0;
3938 vars->duplex = DUPLEX_FULL;
3939 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3940 vars->mac_type = MAC_TYPE_NONE;
3942 if (params->switch_cfg == SWITCH_CFG_1G)
3943 vars->phy_flags = PHY_SERDES_FLAG;
3945 vars->phy_flags = PHY_XGXS_FLAG;
3948 /* disable attentions */
3949 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
3950 (NIG_MASK_XGXS0_LINK_STATUS |
3951 NIG_MASK_XGXS0_LINK10G |
3952 NIG_MASK_SERDES0_LINK_STATUS |
3955 bnx2x_emac_init(params, vars);
3957 if (CHIP_REV_IS_FPGA(bp)) {
3959 vars->line_speed = SPEED_10000;
3960 vars->duplex = DUPLEX_FULL;
3961 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3962 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3963 /* enable on E1.5 FPGA */
3964 if (CHIP_IS_E1H(bp)) {
3966 (BNX2X_FLOW_CTRL_TX | BNX2X_FLOW_CTRL_RX);
3967 vars->link_status |=
3968 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
3969 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
3972 bnx2x_emac_enable(params, vars, 0);
3973 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3975 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3976 + params->port*4, 0);
3978 /* update shared memory */
3979 bnx2x_update_mng(params, vars->link_status);
3984 if (CHIP_REV_IS_EMUL(bp)) {
3987 vars->line_speed = SPEED_10000;
3988 vars->duplex = DUPLEX_FULL;
3989 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3990 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3992 bnx2x_bmac_enable(params, vars, 0);
3994 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3996 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3997 + params->port*4, 0);
3999 /* update shared memory */
4000 bnx2x_update_mng(params, vars->link_status);
4005 if (params->loopback_mode == LOOPBACK_BMAC) {
4007 vars->line_speed = SPEED_10000;
4008 vars->duplex = DUPLEX_FULL;
4009 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4010 vars->mac_type = MAC_TYPE_BMAC;
4012 vars->phy_flags = PHY_XGXS_FLAG;
4014 bnx2x_phy_deassert(params, vars->phy_flags);
4015 /* set bmac loopback */
4016 bnx2x_bmac_enable(params, vars, 1);
4018 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4020 } else if (params->loopback_mode == LOOPBACK_EMAC) {
4022 vars->line_speed = SPEED_1000;
4023 vars->duplex = DUPLEX_FULL;
4024 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4025 vars->mac_type = MAC_TYPE_EMAC;
4027 vars->phy_flags = PHY_XGXS_FLAG;
4029 bnx2x_phy_deassert(params, vars->phy_flags);
4030 /* set bmac loopback */
4031 bnx2x_emac_enable(params, vars, 1);
4032 bnx2x_emac_program(params, vars->line_speed,
4034 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4036 } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
4037 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
4039 vars->line_speed = SPEED_10000;
4040 vars->duplex = DUPLEX_FULL;
4041 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4043 vars->phy_flags = PHY_XGXS_FLAG;
4046 NIG_REG_XGXS0_CTRL_PHY_ADDR+
4048 params->phy_addr = (u8)val;
4050 bnx2x_phy_deassert(params, vars->phy_flags);
4051 bnx2x_link_initialize(params, vars);
4053 vars->mac_type = MAC_TYPE_BMAC;
4055 bnx2x_bmac_enable(params, vars, 0);
4057 if (params->loopback_mode == LOOPBACK_XGXS_10) {
4058 /* set 10G XGXS loopback */
4059 bnx2x_set_xgxs_loopback(params, vars, 1);
4061 /* set external phy loopback */
4062 bnx2x_ext_phy_loopback(params);
4064 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4070 bnx2x_phy_deassert(params, vars->phy_flags);
4071 switch (params->switch_cfg) {
4073 vars->phy_flags |= PHY_SERDES_FLAG;
4074 if ((params->ext_phy_config &
4075 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
4076 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
4082 NIG_REG_SERDES0_CTRL_PHY_ADDR+
4085 params->phy_addr = (u8)val;
4088 case SWITCH_CFG_10G:
4089 vars->phy_flags |= PHY_XGXS_FLAG;
4091 NIG_REG_XGXS0_CTRL_PHY_ADDR+
4093 params->phy_addr = (u8)val;
4097 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
4102 bnx2x_link_initialize(params, vars);
4104 bnx2x_link_int_enable(params);
4109 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
4112 struct bnx2x *bp = params->bp;
4113 u32 ext_phy_config = params->ext_phy_config;
4114 u16 hw_led_mode = params->hw_led_mode;
4115 u32 chip_id = params->chip_id;
4116 u8 port = params->port;
4117 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4118 /* disable attentions */
4120 vars->link_status = 0;
4121 bnx2x_update_mng(params, vars->link_status);
4122 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4123 (NIG_MASK_XGXS0_LINK_STATUS |
4124 NIG_MASK_XGXS0_LINK10G |
4125 NIG_MASK_SERDES0_LINK_STATUS |
4128 /* activate nig drain */
4129 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4131 /* disable nig egress interface */
4132 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4133 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4135 /* Stop BigMac rx */
4136 bnx2x_bmac_rx_disable(bp, port);
4139 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4142 /* The PHY reset is controled by GPIO 1
4143 * Hold it as vars low
4145 /* clear link led */
4146 bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4147 if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
4148 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
4149 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
4152 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4153 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4156 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4157 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4160 DP(NETIF_MSG_LINK, "reset external PHY\n");
4161 } else if (ext_phy_type ==
4162 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4163 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4166 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4167 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4171 /* reset the SerDes/XGXS */
4172 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4173 (0x1ff << (port*16)));
4176 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4177 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4179 /* disable nig ingress interface */
4180 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4181 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4182 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4183 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4188 static u8 bnx2x_update_link_down(struct link_params *params,
4189 struct link_vars *vars)
4191 struct bnx2x *bp = params->bp;
4192 u8 port = params->port;
4193 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4194 bnx2x_set_led(bp, port, LED_MODE_OFF,
4195 0, params->hw_led_mode,
4198 /* indicate no mac active */
4199 vars->mac_type = MAC_TYPE_NONE;
4201 /* update shared memory */
4202 vars->link_status = 0;
4203 vars->line_speed = 0;
4204 bnx2x_update_mng(params, vars->link_status);
4206 /* activate nig drain */
4207 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4210 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4215 bnx2x_bmac_rx_disable(bp, params->port);
4216 REG_WR(bp, GRCBASE_MISC +
4217 MISC_REGISTERS_RESET_REG_2_CLEAR,
4218 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4222 static u8 bnx2x_update_link_up(struct link_params *params,
4223 struct link_vars *vars,
4224 u8 link_10g, u32 gp_status)
4226 struct bnx2x *bp = params->bp;
4227 u8 port = params->port;
4229 vars->link_status |= LINK_STATUS_LINK_UP;
4231 bnx2x_bmac_enable(params, vars, 0);
4232 bnx2x_set_led(bp, port, LED_MODE_OPER,
4233 SPEED_10000, params->hw_led_mode,
4237 bnx2x_emac_enable(params, vars, 0);
4238 rc = bnx2x_emac_program(params, vars->line_speed,
4242 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4243 if (!(vars->phy_flags &
4245 bnx2x_set_sgmii_tx_driver(params);
4250 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4254 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4256 /* update shared memory */
4257 bnx2x_update_mng(params, vars->link_status);
4261 /* This function should called upon link interrupt */
4262 /* In case vars->link_up, driver needs to
4265 3. Update the shared memory
4269 1. Update shared memory
4274 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4276 struct bnx2x *bp = params->bp;
4277 u8 port = params->port;
4280 u8 ext_phy_link_up, rc = 0;
4283 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
4285 (vars->phy_flags & PHY_XGXS_FLAG),
4286 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4288 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4289 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4290 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4291 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
4293 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4294 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4295 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4298 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4300 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4302 /* Check external link change only for non-direct */
4303 ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
4305 /* Read gp_status */
4306 CL45_RD_OVER_CL22(bp, port, params->phy_addr,
4307 MDIO_REG_BANK_GP_STATUS,
4308 MDIO_GP_STATUS_TOP_AN_STATUS1,
4311 rc = bnx2x_link_settings_status(params, vars, gp_status);
4315 /* anything 10 and over uses the bmac */
4316 link_10g = ((vars->line_speed == SPEED_10000) ||
4317 (vars->line_speed == SPEED_12000) ||
4318 (vars->line_speed == SPEED_12500) ||
4319 (vars->line_speed == SPEED_13000) ||
4320 (vars->line_speed == SPEED_15000) ||
4321 (vars->line_speed == SPEED_16000));
4323 bnx2x_link_int_ack(params, vars, link_10g);
4325 /* In case external phy link is up, and internal link is down
4326 ( not initialized yet probably after link initialization, it needs
4328 Note that after link down-up as result of cable plug,
4329 the xgxs link would probably become up again without the need to
4332 if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4333 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
4334 (ext_phy_link_up && !vars->phy_link_up))
4335 bnx2x_init_internal_phy(params, vars);
4337 /* link is up only if both local phy and external phy are up */
4338 vars->link_up = (ext_phy_link_up && vars->phy_link_up);
4341 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
4343 rc = bnx2x_update_link_down(params, vars);
4348 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4350 u8 ext_phy_addr[PORT_MAX];
4354 /* PART1 - Reset both phys */
4355 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4356 /* Extract the ext phy address for the port */
4357 u32 ext_phy_config = REG_RD(bp, shmem_base +
4358 offsetof(struct shmem_region,
4359 dev_info.port_hw_config[port].external_phy_config));
4361 /* disable attentions */
4362 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4363 (NIG_MASK_XGXS0_LINK_STATUS |
4364 NIG_MASK_XGXS0_LINK10G |
4365 NIG_MASK_SERDES0_LINK_STATUS |
4368 ext_phy_addr[port] =
4370 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4371 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4373 /* Need to take the phy out of low power mode in order
4374 to write to access its registers */
4375 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4376 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
4379 bnx2x_cl45_write(bp, port,
4380 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4387 /* Add delay of 150ms after reset */
4390 /* PART2 - Download firmware to both phys */
4391 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4394 bnx2x_bcm8073_external_rom_boot(bp, port,
4395 ext_phy_addr[port]);
4397 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4400 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
4403 "bnx2x_8073_common_init_phy port %x "
4404 "fw Download failed\n", port);
4408 /* Only set bit 10 = 1 (Tx power down) */
4409 bnx2x_cl45_read(bp, port,
4410 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4413 MDIO_PMA_REG_TX_POWER_DOWN, &val);
4415 /* Phase1 of TX_POWER_DOWN reset */
4416 bnx2x_cl45_write(bp, port,
4417 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4420 MDIO_PMA_REG_TX_POWER_DOWN,
4424 /* Toggle Transmitter: Power down and then up with 600ms
4428 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
4429 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4430 /* Phase2 of POWER_DOWN_RESET*/
4431 /* Release bit 10 (Release Tx power down) */
4432 bnx2x_cl45_read(bp, port,
4433 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4436 MDIO_PMA_REG_TX_POWER_DOWN, &val);
4438 bnx2x_cl45_write(bp, port,
4439 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4442 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
4445 /* Read modify write the SPI-ROM version select register */
4446 bnx2x_cl45_read(bp, port,
4447 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4450 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
4451 bnx2x_cl45_write(bp, port,
4452 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4455 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
4457 /* set GPIO2 back to LOW */
4458 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4459 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
4465 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4470 DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n");
4472 /* Read the ext_phy_type for arbitrary port(0) */
4473 ext_phy_type = XGXS_EXT_PHY_TYPE(
4474 REG_RD(bp, shmem_base +
4475 offsetof(struct shmem_region,
4476 dev_info.port_hw_config[0].external_phy_config)));
4478 switch (ext_phy_type) {
4479 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4481 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
4486 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
4496 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
4500 bnx2x_cl45_read(bp, port,
4501 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4504 MDIO_PMA_REG_7101_RESET, &val);
4506 for (cnt = 0; cnt < 10; cnt++) {
4508 /* Writes a self-clearing reset */
4509 bnx2x_cl45_write(bp, port,
4510 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4513 MDIO_PMA_REG_7101_RESET,
4515 /* Wait for clear */
4516 bnx2x_cl45_read(bp, port,
4517 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4520 MDIO_PMA_REG_7101_RESET, &val);
4522 if ((val & (1<<15)) == 0)
4526 #define RESERVED_SIZE 256
4527 /* max application is 160K bytes - data at end of RAM */
4528 #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
4530 /* Header is 14 bytes */
4531 #define HEADER_SIZE 14
4532 #define DATA_OFFSET HEADER_SIZE
4534 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
4535 bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
4538 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
4540 /* Programs an image to DSP's flash via the SPI port*/
4541 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
4543 char data[], u32 size)
4545 const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
4546 /* Doesn't include last trans!*/
4547 const u16 last_trans_size = size%4; /* Num bytes on last trans */
4548 u16 trans_cnt, byte_cnt;
4551 u16 code_started = 0;
4552 u16 image_revision1, image_revision2;
4555 DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
4557 if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
4558 /* This very often will be the case, because the image is built
4559 with 160Kbytes size whereas the total image size must actually
4560 be 160Kbytes-RESERVED_SIZE */
4561 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
4562 "truncated to %d bytes\n", size, MAX_APP_SIZE);
4563 size = MAX_APP_SIZE+HEADER_SIZE;
4565 DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
4566 DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]);
4567 /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
4568 and issuing a reset.*/
4570 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4571 MISC_REGISTERS_GPIO_HIGH, port);
4573 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4576 for (cnt = 0; cnt < 100; cnt++)
4579 /* Make sure we can access the DSP
4580 And it's in the correct mode (waiting for download) */
4582 bnx2x_cl45_read(bp, port,
4583 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4586 MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
4588 if (tmp != 0x000A) {
4589 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
4590 "Expected 0x000A, read 0x%04X\n", tmp);
4591 DP(NETIF_MSG_LINK, "Download failed\n");
4595 /* Mux the SPI interface away from the internal processor */
4596 bnx2x_cl45_write(bp, port,
4597 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4600 MDIO_PCS_REG_7101_SPI_MUX, 1);
4602 /* Reset the SPI port */
4603 bnx2x_cl45_write(bp, port,
4604 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4607 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4608 bnx2x_cl45_write(bp, port,
4609 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4612 MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
4613 (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
4614 bnx2x_cl45_write(bp, port,
4615 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4618 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4620 /* Erase the flash */
4621 bnx2x_cl45_write(bp, port,
4622 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4625 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4626 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4628 bnx2x_cl45_write(bp, port,
4629 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4632 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4635 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4636 bnx2x_cl45_write(bp, port,
4637 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4640 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4641 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
4643 bnx2x_cl45_write(bp, port,
4644 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4647 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4649 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4651 /* Wait 10 seconds, the maximum time for the erase to complete */
4652 DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
4653 for (cnt = 0; cnt < 1000; cnt++)
4656 DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
4658 for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
4659 bnx2x_cl45_write(bp, port,
4660 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4663 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4664 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4666 bnx2x_cl45_write(bp, port,
4667 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4670 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4672 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4674 bnx2x_cl45_write(bp, port,
4675 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4678 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4679 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4681 /* Bits 23-16 of address */
4682 bnx2x_cl45_write(bp, port,
4683 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4686 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4688 /* Bits 15-8 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,
4696 /* Bits 7-0 of address */
4697 bnx2x_cl45_write(bp, port,
4698 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4701 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4705 while (byte_cnt < 4 && data_index < size) {
4706 bnx2x_cl45_write(bp, port,
4707 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4710 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4711 data[data_index++]);
4715 bnx2x_cl45_write(bp, port,
4716 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4719 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4722 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4723 msleep(5); /* Wait 5 ms minimum between transs */
4725 /* Let the user know something's going on.*/
4726 /* a pacifier ever 4K */
4727 if ((data_index % 1023) == 0)
4728 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4731 DP(NETIF_MSG_LINK, "\n");
4732 /* Transfer the last block if there is data remaining */
4733 if (last_trans_size) {
4734 bnx2x_cl45_write(bp, port,
4735 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4738 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4739 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4741 bnx2x_cl45_write(bp, port,
4742 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4745 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4748 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4750 bnx2x_cl45_write(bp, port,
4751 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4754 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4755 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4757 /* Bits 23-16 of address */
4758 bnx2x_cl45_write(bp, port,
4759 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4762 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4764 /* Bits 15-8 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,
4772 /* Bits 7-0 of address */
4773 bnx2x_cl45_write(bp, port,
4774 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4777 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4781 while (byte_cnt < last_trans_size && data_index < size) {
4782 /* Bits 7-0 of address */
4783 bnx2x_cl45_write(bp, port,
4784 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4787 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4788 data[data_index++]);
4792 bnx2x_cl45_write(bp, port,
4793 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4796 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4799 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4802 /* DSP Remove Download Mode */
4803 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4804 MISC_REGISTERS_GPIO_LOW, port);
4806 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4808 /* wait 0.5 sec to allow it to run */
4809 for (cnt = 0; cnt < 100; cnt++)
4812 bnx2x_hw_reset(bp, port);
4814 for (cnt = 0; cnt < 100; cnt++)
4817 /* Check that the code is started. In case the download
4818 checksum failed, the code won't be started. */
4819 bnx2x_cl45_read(bp, port,
4820 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4823 MDIO_PCS_REG_7101_DSP_ACCESS,
4826 code_started = (tmp & (1<<4));
4827 if (!code_started) {
4828 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
4832 /* Verify that the file revision is now equal to the image
4833 revision within the DSP */
4834 bnx2x_cl45_read(bp, port,
4835 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4838 MDIO_PMA_REG_7101_VER1,
4841 bnx2x_cl45_read(bp, port,
4842 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4845 MDIO_PMA_REG_7101_VER2,
4848 if (data[0x14e] != (image_revision2&0xFF) ||
4849 data[0x14f] != ((image_revision2&0xFF00)>>8) ||
4850 data[0x150] != (image_revision1&0xFF) ||
4851 data[0x151] != ((image_revision1&0xFF00)>>8)) {
4852 DP(NETIF_MSG_LINK, "Download failed.\n");
4855 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4859 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
4860 u8 driver_loaded, char data[], u32 size)
4865 ext_phy_addr = ((ext_phy_config &
4866 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4867 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4869 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4871 switch (ext_phy_type) {
4872 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4873 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4874 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4875 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4877 "Flash download not supported for this ext phy\n");
4880 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4881 /* Take ext phy out of reset */
4883 bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
4884 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
4887 bnx2x_turn_off_sf(bp, port);
4889 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4890 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4891 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4893 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");