bnx2x: Saving PHY FW version
[linux-2.6/mini2440.git] / drivers / net / bnx2x_link.c
blobffa412f63c9639bfe51fde90acc2f11473a4f3b5
1 /* Copyright 2008-2009 Broadcom Corporation
3 * Unless you and Broadcom execute a separate written software license
4 * agreement governing use of this software, this software is licensed to you
5 * under the terms of the GNU General Public License version 2, available
6 * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
8 * Notwithstanding the above, under no circumstances may you combine this
9 * software in any way with any other Broadcom software provided under a
10 * license other than the GPL, without Broadcom's express prior written
11 * consent.
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"
29 #include "bnx2x.h"
31 /********************************************************/
32 #define SUPPORT_CL73 0 /* Currently no */
33 #define ETH_HLEN 14
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 /* */
143 #define SFP_EEPROM_CON_TYPE_ADDR 0x2
144 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
145 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
147 #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
148 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
149 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
150 #define SFP_EEPROM_VENDOR_NAME_ADDR 0x14
151 #define SFP_EEPROM_VENDOR_NAME_SIZE 16
152 #define SFP_EEPROM_OPTIONS_ADDR 0x40
153 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
154 #define SFP_EEPROM_OPTIONS_SIZE 2
156 #define SFP_MODULE_TYPE_UNKNOWN 0x0
157 #define SFP_MODULE_TYPE_LC 0x1
158 #define SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE 0x2
159 #define SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE 0x3
161 #define SFP_LIMITING_MODE_VALUE 0x0044
162 /**********************************************************/
163 /* INTERFACE */
164 /**********************************************************/
165 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
166 bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
167 DEFAULT_PHY_DEV_ADDR, \
168 (_bank + (_addr & 0xf)), \
169 _val)
171 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
172 bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
173 DEFAULT_PHY_DEV_ADDR, \
174 (_bank + (_addr & 0xf)), \
175 _val)
177 static void bnx2x_set_phy_mdio(struct link_params *params)
179 struct bnx2x *bp = params->bp;
180 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
181 params->port*0x18, 0);
182 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
183 DEFAULT_PHY_DEV_ADDR);
186 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
188 u32 val = REG_RD(bp, reg);
190 val |= bits;
191 REG_WR(bp, reg, val);
192 return val;
195 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
197 u32 val = REG_RD(bp, reg);
199 val &= ~bits;
200 REG_WR(bp, reg, val);
201 return val;
204 static void bnx2x_emac_init(struct link_params *params,
205 struct link_vars *vars)
207 /* reset and unreset the emac core */
208 struct bnx2x *bp = params->bp;
209 u8 port = params->port;
210 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
211 u32 val;
212 u16 timeout;
214 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
215 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
216 udelay(5);
217 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
218 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
220 /* init emac - use read-modify-write */
221 /* self clear reset */
222 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
223 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
225 timeout = 200;
226 do {
227 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
228 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
229 if (!timeout) {
230 DP(NETIF_MSG_LINK, "EMAC timeout!\n");
231 return;
233 timeout--;
234 } while (val & EMAC_MODE_RESET);
236 /* Set mac address */
237 val = ((params->mac_addr[0] << 8) |
238 params->mac_addr[1]);
239 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
241 val = ((params->mac_addr[2] << 24) |
242 (params->mac_addr[3] << 16) |
243 (params->mac_addr[4] << 8) |
244 params->mac_addr[5]);
245 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
248 static u8 bnx2x_emac_enable(struct link_params *params,
249 struct link_vars *vars, u8 lb)
251 struct bnx2x *bp = params->bp;
252 u8 port = params->port;
253 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
254 u32 val;
256 DP(NETIF_MSG_LINK, "enabling EMAC\n");
258 /* enable emac and not bmac */
259 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
261 /* for paladium */
262 if (CHIP_REV_IS_EMUL(bp)) {
263 /* Use lane 1 (of lanes 0-3) */
264 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
265 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
266 port*4, 1);
268 /* for fpga */
269 else
271 if (CHIP_REV_IS_FPGA(bp)) {
272 /* Use lane 1 (of lanes 0-3) */
273 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
275 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
276 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
278 } else
279 /* ASIC */
280 if (vars->phy_flags & PHY_XGXS_FLAG) {
281 u32 ser_lane = ((params->lane_config &
282 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
283 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
285 DP(NETIF_MSG_LINK, "XGXS\n");
286 /* select the master lanes (out of 0-3) */
287 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
288 port*4, ser_lane);
289 /* select XGXS */
290 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
291 port*4, 1);
293 } else { /* SerDes */
294 DP(NETIF_MSG_LINK, "SerDes\n");
295 /* select SerDes */
296 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
297 port*4, 0);
300 /* enable emac */
301 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
303 if (CHIP_REV_IS_SLOW(bp)) {
304 /* config GMII mode */
305 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
306 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
307 (val | EMAC_MODE_PORT_GMII));
308 } else { /* ASIC */
309 /* pause enable/disable */
310 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
311 EMAC_RX_MODE_FLOW_EN);
312 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
313 bnx2x_bits_en(bp, emac_base +
314 EMAC_REG_EMAC_RX_MODE,
315 EMAC_RX_MODE_FLOW_EN);
317 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
318 (EMAC_TX_MODE_EXT_PAUSE_EN |
319 EMAC_TX_MODE_FLOW_EN));
320 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
321 bnx2x_bits_en(bp, emac_base +
322 EMAC_REG_EMAC_TX_MODE,
323 (EMAC_TX_MODE_EXT_PAUSE_EN |
324 EMAC_TX_MODE_FLOW_EN));
327 /* KEEP_VLAN_TAG, promiscuous */
328 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
329 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
330 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
332 /* Set Loopback */
333 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
334 if (lb)
335 val |= 0x810;
336 else
337 val &= ~0x810;
338 EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
340 /* enable emac */
341 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
343 /* enable emac for jumbo packets */
344 EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
345 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
346 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
348 /* strip CRC */
349 REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
351 /* disable the NIG in/out to the bmac */
352 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
353 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
354 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
356 /* enable the NIG in/out to the emac */
357 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
358 val = 0;
359 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
360 val = 1;
362 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
363 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
365 if (CHIP_REV_IS_EMUL(bp)) {
366 /* take the BigMac out of reset */
367 REG_WR(bp,
368 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
369 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
371 /* enable access for bmac registers */
372 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
375 vars->mac_type = MAC_TYPE_EMAC;
376 return 0;
381 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
382 u8 is_lb)
384 struct bnx2x *bp = params->bp;
385 u8 port = params->port;
386 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
387 NIG_REG_INGRESS_BMAC0_MEM;
388 u32 wb_data[2];
389 u32 val;
391 DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
392 /* reset and unreset the BigMac */
393 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
394 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
395 msleep(1);
397 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
398 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
400 /* enable access for bmac registers */
401 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
403 /* XGXS control */
404 wb_data[0] = 0x3c;
405 wb_data[1] = 0;
406 REG_WR_DMAE(bp, bmac_addr +
407 BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
408 wb_data, 2);
410 /* tx MAC SA */
411 wb_data[0] = ((params->mac_addr[2] << 24) |
412 (params->mac_addr[3] << 16) |
413 (params->mac_addr[4] << 8) |
414 params->mac_addr[5]);
415 wb_data[1] = ((params->mac_addr[0] << 8) |
416 params->mac_addr[1]);
417 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
418 wb_data, 2);
420 /* tx control */
421 val = 0xc0;
422 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
423 val |= 0x800000;
424 wb_data[0] = val;
425 wb_data[1] = 0;
426 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
427 wb_data, 2);
429 /* mac control */
430 val = 0x3;
431 if (is_lb) {
432 val |= 0x4;
433 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
435 wb_data[0] = val;
436 wb_data[1] = 0;
437 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
438 wb_data, 2);
441 /* set rx mtu */
442 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
443 wb_data[1] = 0;
444 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
445 wb_data, 2);
447 /* rx control set to don't strip crc */
448 val = 0x14;
449 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
450 val |= 0x20;
451 wb_data[0] = val;
452 wb_data[1] = 0;
453 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
454 wb_data, 2);
456 /* set tx mtu */
457 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
458 wb_data[1] = 0;
459 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
460 wb_data, 2);
462 /* set cnt max size */
463 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
464 wb_data[1] = 0;
465 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
466 wb_data, 2);
468 /* configure safc */
469 wb_data[0] = 0x1000200;
470 wb_data[1] = 0;
471 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
472 wb_data, 2);
473 /* fix for emulation */
474 if (CHIP_REV_IS_EMUL(bp)) {
475 wb_data[0] = 0xf000;
476 wb_data[1] = 0;
477 REG_WR_DMAE(bp,
478 bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
479 wb_data, 2);
482 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
483 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
484 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
485 val = 0;
486 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
487 val = 1;
488 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
489 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
490 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
491 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
492 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
493 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
495 vars->mac_type = MAC_TYPE_BMAC;
496 return 0;
499 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
501 struct bnx2x *bp = params->bp;
502 u32 val;
504 if (phy_flags & PHY_XGXS_FLAG) {
505 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
506 val = XGXS_RESET_BITS;
508 } else { /* SerDes */
509 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
510 val = SERDES_RESET_BITS;
513 val = val << (params->port*16);
515 /* reset and unreset the SerDes/XGXS */
516 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
517 val);
518 udelay(500);
519 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
520 val);
521 bnx2x_set_phy_mdio(params);
524 void bnx2x_link_status_update(struct link_params *params,
525 struct link_vars *vars)
527 struct bnx2x *bp = params->bp;
528 u8 link_10g;
529 u8 port = params->port;
531 if (params->switch_cfg == SWITCH_CFG_1G)
532 vars->phy_flags = PHY_SERDES_FLAG;
533 else
534 vars->phy_flags = PHY_XGXS_FLAG;
535 vars->link_status = REG_RD(bp, params->shmem_base +
536 offsetof(struct shmem_region,
537 port_mb[port].link_status));
539 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
541 if (vars->link_up) {
542 DP(NETIF_MSG_LINK, "phy link up\n");
544 vars->phy_link_up = 1;
545 vars->duplex = DUPLEX_FULL;
546 switch (vars->link_status &
547 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
548 case LINK_10THD:
549 vars->duplex = DUPLEX_HALF;
550 /* fall thru */
551 case LINK_10TFD:
552 vars->line_speed = SPEED_10;
553 break;
555 case LINK_100TXHD:
556 vars->duplex = DUPLEX_HALF;
557 /* fall thru */
558 case LINK_100T4:
559 case LINK_100TXFD:
560 vars->line_speed = SPEED_100;
561 break;
563 case LINK_1000THD:
564 vars->duplex = DUPLEX_HALF;
565 /* fall thru */
566 case LINK_1000TFD:
567 vars->line_speed = SPEED_1000;
568 break;
570 case LINK_2500THD:
571 vars->duplex = DUPLEX_HALF;
572 /* fall thru */
573 case LINK_2500TFD:
574 vars->line_speed = SPEED_2500;
575 break;
577 case LINK_10GTFD:
578 vars->line_speed = SPEED_10000;
579 break;
581 case LINK_12GTFD:
582 vars->line_speed = SPEED_12000;
583 break;
585 case LINK_12_5GTFD:
586 vars->line_speed = SPEED_12500;
587 break;
589 case LINK_13GTFD:
590 vars->line_speed = SPEED_13000;
591 break;
593 case LINK_15GTFD:
594 vars->line_speed = SPEED_15000;
595 break;
597 case LINK_16GTFD:
598 vars->line_speed = SPEED_16000;
599 break;
601 default:
602 break;
605 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
606 vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
607 else
608 vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
610 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
611 vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
612 else
613 vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
615 if (vars->phy_flags & PHY_XGXS_FLAG) {
616 if (vars->line_speed &&
617 ((vars->line_speed == SPEED_10) ||
618 (vars->line_speed == SPEED_100))) {
619 vars->phy_flags |= PHY_SGMII_FLAG;
620 } else {
621 vars->phy_flags &= ~PHY_SGMII_FLAG;
625 /* anything 10 and over uses the bmac */
626 link_10g = ((vars->line_speed == SPEED_10000) ||
627 (vars->line_speed == SPEED_12000) ||
628 (vars->line_speed == SPEED_12500) ||
629 (vars->line_speed == SPEED_13000) ||
630 (vars->line_speed == SPEED_15000) ||
631 (vars->line_speed == SPEED_16000));
632 if (link_10g)
633 vars->mac_type = MAC_TYPE_BMAC;
634 else
635 vars->mac_type = MAC_TYPE_EMAC;
637 } else { /* link down */
638 DP(NETIF_MSG_LINK, "phy link down\n");
640 vars->phy_link_up = 0;
642 vars->line_speed = 0;
643 vars->duplex = DUPLEX_FULL;
644 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
646 /* indicate no mac active */
647 vars->mac_type = MAC_TYPE_NONE;
650 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
651 vars->link_status, vars->phy_link_up);
652 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
653 vars->line_speed, vars->duplex, vars->flow_ctrl);
656 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
658 struct bnx2x *bp = params->bp;
659 REG_WR(bp, params->shmem_base +
660 offsetof(struct shmem_region,
661 port_mb[params->port].link_status),
662 link_status);
665 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
667 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
668 NIG_REG_INGRESS_BMAC0_MEM;
669 u32 wb_data[2];
670 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
672 /* Only if the bmac is out of reset */
673 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
674 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
675 nig_bmac_enable) {
677 /* Clear Rx Enable bit in BMAC_CONTROL register */
678 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
679 wb_data, 2);
680 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
681 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
682 wb_data, 2);
684 msleep(1);
688 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
689 u32 line_speed)
691 struct bnx2x *bp = params->bp;
692 u8 port = params->port;
693 u32 init_crd, crd;
694 u32 count = 1000;
696 /* disable port */
697 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
699 /* wait for init credit */
700 init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
701 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
702 DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
704 while ((init_crd != crd) && count) {
705 msleep(5);
707 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
708 count--;
710 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
711 if (init_crd != crd) {
712 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
713 init_crd, crd);
714 return -EINVAL;
717 if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
718 line_speed == SPEED_10 ||
719 line_speed == SPEED_100 ||
720 line_speed == SPEED_1000 ||
721 line_speed == SPEED_2500) {
722 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
723 /* update threshold */
724 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
725 /* update init credit */
726 init_crd = 778; /* (800-18-4) */
728 } else {
729 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
730 ETH_OVREHEAD)/16;
731 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
732 /* update threshold */
733 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
734 /* update init credit */
735 switch (line_speed) {
736 case SPEED_10000:
737 init_crd = thresh + 553 - 22;
738 break;
740 case SPEED_12000:
741 init_crd = thresh + 664 - 22;
742 break;
744 case SPEED_13000:
745 init_crd = thresh + 742 - 22;
746 break;
748 case SPEED_16000:
749 init_crd = thresh + 778 - 22;
750 break;
751 default:
752 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
753 line_speed);
754 return -EINVAL;
755 break;
758 REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
759 DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
760 line_speed, init_crd);
762 /* probe the credit changes */
763 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
764 msleep(5);
765 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
767 /* enable port */
768 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
769 return 0;
772 static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
774 u32 emac_base;
775 switch (ext_phy_type) {
776 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
777 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
778 /* All MDC/MDIO is directed through single EMAC */
779 if (REG_RD(bp, NIG_REG_PORT_SWAP))
780 emac_base = GRCBASE_EMAC0;
781 else
782 emac_base = GRCBASE_EMAC1;
783 break;
784 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
785 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
786 break;
787 default:
788 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
789 break;
791 return emac_base;
795 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
796 u8 phy_addr, u8 devad, u16 reg, u16 val)
798 u32 tmp, saved_mode;
799 u8 i, rc = 0;
800 u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
802 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
803 * (a value of 49==0x31) and make sure that the AUTO poll is off
806 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
807 tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
808 EMAC_MDIO_MODE_CLOCK_CNT);
809 tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
810 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
811 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
812 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
813 udelay(40);
815 /* address */
817 tmp = ((phy_addr << 21) | (devad << 16) | reg |
818 EMAC_MDIO_COMM_COMMAND_ADDRESS |
819 EMAC_MDIO_COMM_START_BUSY);
820 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
822 for (i = 0; i < 50; i++) {
823 udelay(10);
825 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
826 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
827 udelay(5);
828 break;
831 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
832 DP(NETIF_MSG_LINK, "write phy register failed\n");
833 rc = -EFAULT;
834 } else {
835 /* data */
836 tmp = ((phy_addr << 21) | (devad << 16) | val |
837 EMAC_MDIO_COMM_COMMAND_WRITE_45 |
838 EMAC_MDIO_COMM_START_BUSY);
839 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
841 for (i = 0; i < 50; i++) {
842 udelay(10);
844 tmp = REG_RD(bp, mdio_ctrl +
845 EMAC_REG_EMAC_MDIO_COMM);
846 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
847 udelay(5);
848 break;
851 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
852 DP(NETIF_MSG_LINK, "write phy register failed\n");
853 rc = -EFAULT;
857 /* Restore the saved mode */
858 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
860 return rc;
863 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
864 u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
866 u32 val, saved_mode;
867 u16 i;
868 u8 rc = 0;
870 u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
871 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
872 * (a value of 49==0x31) and make sure that the AUTO poll is off
875 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
876 val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
877 EMAC_MDIO_MODE_CLOCK_CNT));
878 val |= (EMAC_MDIO_MODE_CLAUSE_45 |
879 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
880 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
881 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
882 udelay(40);
884 /* address */
885 val = ((phy_addr << 21) | (devad << 16) | reg |
886 EMAC_MDIO_COMM_COMMAND_ADDRESS |
887 EMAC_MDIO_COMM_START_BUSY);
888 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
890 for (i = 0; i < 50; i++) {
891 udelay(10);
893 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
894 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
895 udelay(5);
896 break;
899 if (val & EMAC_MDIO_COMM_START_BUSY) {
900 DP(NETIF_MSG_LINK, "read phy register failed\n");
902 *ret_val = 0;
903 rc = -EFAULT;
905 } else {
906 /* data */
907 val = ((phy_addr << 21) | (devad << 16) |
908 EMAC_MDIO_COMM_COMMAND_READ_45 |
909 EMAC_MDIO_COMM_START_BUSY);
910 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
912 for (i = 0; i < 50; i++) {
913 udelay(10);
915 val = REG_RD(bp, mdio_ctrl +
916 EMAC_REG_EMAC_MDIO_COMM);
917 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
918 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
919 break;
922 if (val & EMAC_MDIO_COMM_START_BUSY) {
923 DP(NETIF_MSG_LINK, "read phy register failed\n");
925 *ret_val = 0;
926 rc = -EFAULT;
930 /* Restore the saved mode */
931 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
933 return rc;
936 static void bnx2x_set_aer_mmd(struct link_params *params,
937 struct link_vars *vars)
939 struct bnx2x *bp = params->bp;
940 u32 ser_lane;
941 u16 offset;
943 ser_lane = ((params->lane_config &
944 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
945 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
947 offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
948 (params->phy_addr + ser_lane) : 0;
950 CL45_WR_OVER_CL22(bp, params->port,
951 params->phy_addr,
952 MDIO_REG_BANK_AER_BLOCK,
953 MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
956 static void bnx2x_set_master_ln(struct link_params *params)
958 struct bnx2x *bp = params->bp;
959 u16 new_master_ln, ser_lane;
960 ser_lane = ((params->lane_config &
961 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
962 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
964 /* set the master_ln for AN */
965 CL45_RD_OVER_CL22(bp, params->port,
966 params->phy_addr,
967 MDIO_REG_BANK_XGXS_BLOCK2,
968 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
969 &new_master_ln);
971 CL45_WR_OVER_CL22(bp, params->port,
972 params->phy_addr,
973 MDIO_REG_BANK_XGXS_BLOCK2 ,
974 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
975 (new_master_ln | ser_lane));
978 static u8 bnx2x_reset_unicore(struct link_params *params)
980 struct bnx2x *bp = params->bp;
981 u16 mii_control;
982 u16 i;
984 CL45_RD_OVER_CL22(bp, params->port,
985 params->phy_addr,
986 MDIO_REG_BANK_COMBO_IEEE0,
987 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
989 /* reset the unicore */
990 CL45_WR_OVER_CL22(bp, params->port,
991 params->phy_addr,
992 MDIO_REG_BANK_COMBO_IEEE0,
993 MDIO_COMBO_IEEE0_MII_CONTROL,
994 (mii_control |
995 MDIO_COMBO_IEEO_MII_CONTROL_RESET));
997 /* wait for the reset to self clear */
998 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
999 udelay(5);
1001 /* the reset erased the previous bank value */
1002 CL45_RD_OVER_CL22(bp, params->port,
1003 params->phy_addr,
1004 MDIO_REG_BANK_COMBO_IEEE0,
1005 MDIO_COMBO_IEEE0_MII_CONTROL,
1006 &mii_control);
1008 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1009 udelay(5);
1010 return 0;
1014 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1015 return -EINVAL;
1019 static void bnx2x_set_swap_lanes(struct link_params *params)
1021 struct bnx2x *bp = params->bp;
1022 /* Each two bits represents a lane number:
1023 No swap is 0123 => 0x1b no need to enable the swap */
1024 u16 ser_lane, rx_lane_swap, tx_lane_swap;
1026 ser_lane = ((params->lane_config &
1027 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1028 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1029 rx_lane_swap = ((params->lane_config &
1030 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1031 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1032 tx_lane_swap = ((params->lane_config &
1033 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1034 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1036 if (rx_lane_swap != 0x1b) {
1037 CL45_WR_OVER_CL22(bp, params->port,
1038 params->phy_addr,
1039 MDIO_REG_BANK_XGXS_BLOCK2,
1040 MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1041 (rx_lane_swap |
1042 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1043 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1044 } else {
1045 CL45_WR_OVER_CL22(bp, params->port,
1046 params->phy_addr,
1047 MDIO_REG_BANK_XGXS_BLOCK2,
1048 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1051 if (tx_lane_swap != 0x1b) {
1052 CL45_WR_OVER_CL22(bp, params->port,
1053 params->phy_addr,
1054 MDIO_REG_BANK_XGXS_BLOCK2,
1055 MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1056 (tx_lane_swap |
1057 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1058 } else {
1059 CL45_WR_OVER_CL22(bp, params->port,
1060 params->phy_addr,
1061 MDIO_REG_BANK_XGXS_BLOCK2,
1062 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1066 static void bnx2x_set_parallel_detection(struct link_params *params,
1067 u8 phy_flags)
1069 struct bnx2x *bp = params->bp;
1070 u16 control2;
1072 CL45_RD_OVER_CL22(bp, params->port,
1073 params->phy_addr,
1074 MDIO_REG_BANK_SERDES_DIGITAL,
1075 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1076 &control2);
1079 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1082 CL45_WR_OVER_CL22(bp, params->port,
1083 params->phy_addr,
1084 MDIO_REG_BANK_SERDES_DIGITAL,
1085 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1086 control2);
1088 if (phy_flags & PHY_XGXS_FLAG) {
1089 DP(NETIF_MSG_LINK, "XGXS\n");
1091 CL45_WR_OVER_CL22(bp, params->port,
1092 params->phy_addr,
1093 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1094 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1095 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1097 CL45_RD_OVER_CL22(bp, params->port,
1098 params->phy_addr,
1099 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1100 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1101 &control2);
1104 control2 |=
1105 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1107 CL45_WR_OVER_CL22(bp, params->port,
1108 params->phy_addr,
1109 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1110 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1111 control2);
1113 /* Disable parallel detection of HiG */
1114 CL45_WR_OVER_CL22(bp, params->port,
1115 params->phy_addr,
1116 MDIO_REG_BANK_XGXS_BLOCK2,
1117 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1118 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1119 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1123 static void bnx2x_set_autoneg(struct link_params *params,
1124 struct link_vars *vars)
1126 struct bnx2x *bp = params->bp;
1127 u16 reg_val;
1129 /* CL37 Autoneg */
1131 CL45_RD_OVER_CL22(bp, params->port,
1132 params->phy_addr,
1133 MDIO_REG_BANK_COMBO_IEEE0,
1134 MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1136 /* CL37 Autoneg Enabled */
1137 if (vars->line_speed == SPEED_AUTO_NEG)
1138 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1139 else /* CL37 Autoneg Disabled */
1140 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1141 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1143 CL45_WR_OVER_CL22(bp, params->port,
1144 params->phy_addr,
1145 MDIO_REG_BANK_COMBO_IEEE0,
1146 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1148 /* Enable/Disable Autodetection */
1150 CL45_RD_OVER_CL22(bp, params->port,
1151 params->phy_addr,
1152 MDIO_REG_BANK_SERDES_DIGITAL,
1153 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1154 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1155 if (vars->line_speed == SPEED_AUTO_NEG)
1156 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1157 else
1158 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1160 CL45_WR_OVER_CL22(bp, params->port,
1161 params->phy_addr,
1162 MDIO_REG_BANK_SERDES_DIGITAL,
1163 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1165 /* Enable TetonII and BAM autoneg */
1166 CL45_RD_OVER_CL22(bp, params->port,
1167 params->phy_addr,
1168 MDIO_REG_BANK_BAM_NEXT_PAGE,
1169 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1170 &reg_val);
1171 if (vars->line_speed == SPEED_AUTO_NEG) {
1172 /* Enable BAM aneg Mode and TetonII aneg Mode */
1173 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1174 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1175 } else {
1176 /* TetonII and BAM Autoneg Disabled */
1177 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1178 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1180 CL45_WR_OVER_CL22(bp, params->port,
1181 params->phy_addr,
1182 MDIO_REG_BANK_BAM_NEXT_PAGE,
1183 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1184 reg_val);
1186 /* Enable Clause 73 Aneg */
1187 if ((vars->line_speed == SPEED_AUTO_NEG) &&
1188 (SUPPORT_CL73)) {
1189 /* Enable BAM Station Manager */
1191 CL45_WR_OVER_CL22(bp, params->port,
1192 params->phy_addr,
1193 MDIO_REG_BANK_CL73_USERB0,
1194 MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1195 (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1196 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1197 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
1199 /* Merge CL73 and CL37 aneg resolution */
1200 CL45_RD_OVER_CL22(bp, params->port,
1201 params->phy_addr,
1202 MDIO_REG_BANK_CL73_USERB0,
1203 MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1204 &reg_val);
1206 CL45_WR_OVER_CL22(bp, params->port,
1207 params->phy_addr,
1208 MDIO_REG_BANK_CL73_USERB0,
1209 MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1210 (reg_val |
1211 MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
1213 /* Set the CL73 AN speed */
1215 CL45_RD_OVER_CL22(bp, params->port,
1216 params->phy_addr,
1217 MDIO_REG_BANK_CL73_IEEEB1,
1218 MDIO_CL73_IEEEB1_AN_ADV2, &reg_val);
1219 /* In the SerDes we support only the 1G.
1220 In the XGXS we support the 10G KX4
1221 but we currently do not support the KR */
1222 if (vars->phy_flags & PHY_XGXS_FLAG) {
1223 DP(NETIF_MSG_LINK, "XGXS\n");
1224 /* 10G KX4 */
1225 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1226 } else {
1227 DP(NETIF_MSG_LINK, "SerDes\n");
1228 /* 1000M KX */
1229 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1231 CL45_WR_OVER_CL22(bp, params->port,
1232 params->phy_addr,
1233 MDIO_REG_BANK_CL73_IEEEB1,
1234 MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
1236 /* CL73 Autoneg Enabled */
1237 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
1238 } else {
1239 /* CL73 Autoneg Disabled */
1240 reg_val = 0;
1242 CL45_WR_OVER_CL22(bp, params->port,
1243 params->phy_addr,
1244 MDIO_REG_BANK_CL73_IEEEB0,
1245 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1248 /* program SerDes, forced speed */
1249 static void bnx2x_program_serdes(struct link_params *params,
1250 struct link_vars *vars)
1252 struct bnx2x *bp = params->bp;
1253 u16 reg_val;
1255 /* program duplex, disable autoneg */
1257 CL45_RD_OVER_CL22(bp, params->port,
1258 params->phy_addr,
1259 MDIO_REG_BANK_COMBO_IEEE0,
1260 MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1261 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1262 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
1263 if (params->req_duplex == DUPLEX_FULL)
1264 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1265 CL45_WR_OVER_CL22(bp, params->port,
1266 params->phy_addr,
1267 MDIO_REG_BANK_COMBO_IEEE0,
1268 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1270 /* program speed
1271 - needed only if the speed is greater than 1G (2.5G or 10G) */
1272 CL45_RD_OVER_CL22(bp, params->port,
1273 params->phy_addr,
1274 MDIO_REG_BANK_SERDES_DIGITAL,
1275 MDIO_SERDES_DIGITAL_MISC1, &reg_val);
1276 /* clearing the speed value before setting the right speed */
1277 DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1279 reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1280 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1282 if (!((vars->line_speed == SPEED_1000) ||
1283 (vars->line_speed == SPEED_100) ||
1284 (vars->line_speed == SPEED_10))) {
1286 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1287 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1288 if (vars->line_speed == SPEED_10000)
1289 reg_val |=
1290 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1291 if (vars->line_speed == SPEED_13000)
1292 reg_val |=
1293 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1296 CL45_WR_OVER_CL22(bp, params->port,
1297 params->phy_addr,
1298 MDIO_REG_BANK_SERDES_DIGITAL,
1299 MDIO_SERDES_DIGITAL_MISC1, reg_val);
1303 static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1305 struct bnx2x *bp = params->bp;
1306 u16 val = 0;
1308 /* configure the 48 bits for BAM AN */
1310 /* set extended capabilities */
1311 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1312 val |= MDIO_OVER_1G_UP1_2_5G;
1313 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1314 val |= MDIO_OVER_1G_UP1_10G;
1315 CL45_WR_OVER_CL22(bp, params->port,
1316 params->phy_addr,
1317 MDIO_REG_BANK_OVER_1G,
1318 MDIO_OVER_1G_UP1, val);
1320 CL45_WR_OVER_CL22(bp, params->port,
1321 params->phy_addr,
1322 MDIO_REG_BANK_OVER_1G,
1323 MDIO_OVER_1G_UP3, 0);
1326 static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
1328 *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1329 /* resolve pause mode and advertisement
1330 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1332 switch (params->req_flow_ctrl) {
1333 case BNX2X_FLOW_CTRL_AUTO:
1334 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
1335 *ieee_fc |=
1336 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1337 } else {
1338 *ieee_fc |=
1339 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1341 break;
1342 case BNX2X_FLOW_CTRL_TX:
1343 *ieee_fc |=
1344 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1345 break;
1347 case BNX2X_FLOW_CTRL_RX:
1348 case BNX2X_FLOW_CTRL_BOTH:
1349 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1350 break;
1352 case BNX2X_FLOW_CTRL_NONE:
1353 default:
1354 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1355 break;
1359 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1360 u32 ieee_fc)
1362 struct bnx2x *bp = params->bp;
1363 /* for AN, we are always publishing full duplex */
1365 CL45_WR_OVER_CL22(bp, params->port,
1366 params->phy_addr,
1367 MDIO_REG_BANK_COMBO_IEEE0,
1368 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
1371 static void bnx2x_restart_autoneg(struct link_params *params)
1373 struct bnx2x *bp = params->bp;
1374 DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1375 if (SUPPORT_CL73) {
1376 /* enable and restart clause 73 aneg */
1377 u16 an_ctrl;
1379 CL45_RD_OVER_CL22(bp, params->port,
1380 params->phy_addr,
1381 MDIO_REG_BANK_CL73_IEEEB0,
1382 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1383 &an_ctrl);
1384 CL45_WR_OVER_CL22(bp, params->port,
1385 params->phy_addr,
1386 MDIO_REG_BANK_CL73_IEEEB0,
1387 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1388 (an_ctrl |
1389 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1390 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1392 } else {
1393 /* Enable and restart BAM/CL37 aneg */
1394 u16 mii_control;
1396 CL45_RD_OVER_CL22(bp, params->port,
1397 params->phy_addr,
1398 MDIO_REG_BANK_COMBO_IEEE0,
1399 MDIO_COMBO_IEEE0_MII_CONTROL,
1400 &mii_control);
1401 DP(NETIF_MSG_LINK,
1402 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1403 mii_control);
1404 CL45_WR_OVER_CL22(bp, params->port,
1405 params->phy_addr,
1406 MDIO_REG_BANK_COMBO_IEEE0,
1407 MDIO_COMBO_IEEE0_MII_CONTROL,
1408 (mii_control |
1409 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1410 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1414 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1415 struct link_vars *vars)
1417 struct bnx2x *bp = params->bp;
1418 u16 control1;
1420 /* in SGMII mode, the unicore is always slave */
1422 CL45_RD_OVER_CL22(bp, params->port,
1423 params->phy_addr,
1424 MDIO_REG_BANK_SERDES_DIGITAL,
1425 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1426 &control1);
1427 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1428 /* set sgmii mode (and not fiber) */
1429 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1430 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1431 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1432 CL45_WR_OVER_CL22(bp, params->port,
1433 params->phy_addr,
1434 MDIO_REG_BANK_SERDES_DIGITAL,
1435 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1436 control1);
1438 /* if forced speed */
1439 if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1440 /* set speed, disable autoneg */
1441 u16 mii_control;
1443 CL45_RD_OVER_CL22(bp, params->port,
1444 params->phy_addr,
1445 MDIO_REG_BANK_COMBO_IEEE0,
1446 MDIO_COMBO_IEEE0_MII_CONTROL,
1447 &mii_control);
1448 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1449 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1450 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1452 switch (vars->line_speed) {
1453 case SPEED_100:
1454 mii_control |=
1455 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1456 break;
1457 case SPEED_1000:
1458 mii_control |=
1459 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1460 break;
1461 case SPEED_10:
1462 /* there is nothing to set for 10M */
1463 break;
1464 default:
1465 /* invalid speed for SGMII */
1466 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1467 vars->line_speed);
1468 break;
1471 /* setting the full duplex */
1472 if (params->req_duplex == DUPLEX_FULL)
1473 mii_control |=
1474 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1475 CL45_WR_OVER_CL22(bp, params->port,
1476 params->phy_addr,
1477 MDIO_REG_BANK_COMBO_IEEE0,
1478 MDIO_COMBO_IEEE0_MII_CONTROL,
1479 mii_control);
1481 } else { /* AN mode */
1482 /* enable and restart AN */
1483 bnx2x_restart_autoneg(params);
1489 * link management
1492 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1493 { /* LD LP */
1494 switch (pause_result) { /* ASYM P ASYM P */
1495 case 0xb: /* 1 0 1 1 */
1496 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
1497 break;
1499 case 0xe: /* 1 1 1 0 */
1500 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
1501 break;
1503 case 0x5: /* 0 1 0 1 */
1504 case 0x7: /* 0 1 1 1 */
1505 case 0xd: /* 1 1 0 1 */
1506 case 0xf: /* 1 1 1 1 */
1507 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
1508 break;
1510 default:
1511 break;
1515 static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1516 struct link_vars *vars)
1518 struct bnx2x *bp = params->bp;
1519 u8 ext_phy_addr;
1520 u16 ld_pause; /* local */
1521 u16 lp_pause; /* link partner */
1522 u16 an_complete; /* AN complete */
1523 u16 pause_result;
1524 u8 ret = 0;
1525 u32 ext_phy_type;
1526 u8 port = params->port;
1527 ext_phy_addr = ((params->ext_phy_config &
1528 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1529 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1531 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1532 /* read twice */
1534 bnx2x_cl45_read(bp, port,
1535 ext_phy_type,
1536 ext_phy_addr,
1537 MDIO_AN_DEVAD,
1538 MDIO_AN_REG_STATUS, &an_complete);
1539 bnx2x_cl45_read(bp, port,
1540 ext_phy_type,
1541 ext_phy_addr,
1542 MDIO_AN_DEVAD,
1543 MDIO_AN_REG_STATUS, &an_complete);
1545 if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1546 ret = 1;
1547 bnx2x_cl45_read(bp, port,
1548 ext_phy_type,
1549 ext_phy_addr,
1550 MDIO_AN_DEVAD,
1551 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1552 bnx2x_cl45_read(bp, port,
1553 ext_phy_type,
1554 ext_phy_addr,
1555 MDIO_AN_DEVAD,
1556 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1557 pause_result = (ld_pause &
1558 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1559 pause_result |= (lp_pause &
1560 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1561 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1562 pause_result);
1563 bnx2x_pause_resolve(vars, pause_result);
1564 if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
1565 ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1566 bnx2x_cl45_read(bp, port,
1567 ext_phy_type,
1568 ext_phy_addr,
1569 MDIO_AN_DEVAD,
1570 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1572 bnx2x_cl45_read(bp, port,
1573 ext_phy_type,
1574 ext_phy_addr,
1575 MDIO_AN_DEVAD,
1576 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1577 pause_result = (ld_pause &
1578 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1579 pause_result |= (lp_pause &
1580 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1582 bnx2x_pause_resolve(vars, pause_result);
1583 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1584 pause_result);
1587 return ret;
1591 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1592 struct link_vars *vars,
1593 u32 gp_status)
1595 struct bnx2x *bp = params->bp;
1596 u16 ld_pause; /* local driver */
1597 u16 lp_pause; /* link partner */
1598 u16 pause_result;
1600 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1602 /* resolve from gp_status in case of AN complete and not sgmii */
1603 if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1604 (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1605 (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1606 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1607 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1608 CL45_RD_OVER_CL22(bp, params->port,
1609 params->phy_addr,
1610 MDIO_REG_BANK_COMBO_IEEE0,
1611 MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1612 &ld_pause);
1613 CL45_RD_OVER_CL22(bp, params->port,
1614 params->phy_addr,
1615 MDIO_REG_BANK_COMBO_IEEE0,
1616 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1617 &lp_pause);
1618 pause_result = (ld_pause &
1619 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1620 pause_result |= (lp_pause &
1621 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1622 DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1623 bnx2x_pause_resolve(vars, pause_result);
1624 } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1625 (bnx2x_ext_phy_resove_fc(params, vars))) {
1626 return;
1627 } else {
1628 if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
1629 vars->flow_ctrl = params->req_fc_auto_adv;
1630 else
1631 vars->flow_ctrl = params->req_flow_ctrl;
1633 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1637 static u8 bnx2x_link_settings_status(struct link_params *params,
1638 struct link_vars *vars,
1639 u32 gp_status)
1641 struct bnx2x *bp = params->bp;
1642 u16 new_line_speed;
1643 u8 rc = 0;
1644 vars->link_status = 0;
1646 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1647 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1648 gp_status);
1650 vars->phy_link_up = 1;
1651 vars->link_status |= LINK_STATUS_LINK_UP;
1653 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1654 vars->duplex = DUPLEX_FULL;
1655 else
1656 vars->duplex = DUPLEX_HALF;
1658 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1660 switch (gp_status & GP_STATUS_SPEED_MASK) {
1661 case GP_STATUS_10M:
1662 new_line_speed = SPEED_10;
1663 if (vars->duplex == DUPLEX_FULL)
1664 vars->link_status |= LINK_10TFD;
1665 else
1666 vars->link_status |= LINK_10THD;
1667 break;
1669 case GP_STATUS_100M:
1670 new_line_speed = SPEED_100;
1671 if (vars->duplex == DUPLEX_FULL)
1672 vars->link_status |= LINK_100TXFD;
1673 else
1674 vars->link_status |= LINK_100TXHD;
1675 break;
1677 case GP_STATUS_1G:
1678 case GP_STATUS_1G_KX:
1679 new_line_speed = SPEED_1000;
1680 if (vars->duplex == DUPLEX_FULL)
1681 vars->link_status |= LINK_1000TFD;
1682 else
1683 vars->link_status |= LINK_1000THD;
1684 break;
1686 case GP_STATUS_2_5G:
1687 new_line_speed = SPEED_2500;
1688 if (vars->duplex == DUPLEX_FULL)
1689 vars->link_status |= LINK_2500TFD;
1690 else
1691 vars->link_status |= LINK_2500THD;
1692 break;
1694 case GP_STATUS_5G:
1695 case GP_STATUS_6G:
1696 DP(NETIF_MSG_LINK,
1697 "link speed unsupported gp_status 0x%x\n",
1698 gp_status);
1699 return -EINVAL;
1700 break;
1701 case GP_STATUS_10G_KX4:
1702 case GP_STATUS_10G_HIG:
1703 case GP_STATUS_10G_CX4:
1704 new_line_speed = SPEED_10000;
1705 vars->link_status |= LINK_10GTFD;
1706 break;
1708 case GP_STATUS_12G_HIG:
1709 new_line_speed = SPEED_12000;
1710 vars->link_status |= LINK_12GTFD;
1711 break;
1713 case GP_STATUS_12_5G:
1714 new_line_speed = SPEED_12500;
1715 vars->link_status |= LINK_12_5GTFD;
1716 break;
1718 case GP_STATUS_13G:
1719 new_line_speed = SPEED_13000;
1720 vars->link_status |= LINK_13GTFD;
1721 break;
1723 case GP_STATUS_15G:
1724 new_line_speed = SPEED_15000;
1725 vars->link_status |= LINK_15GTFD;
1726 break;
1728 case GP_STATUS_16G:
1729 new_line_speed = SPEED_16000;
1730 vars->link_status |= LINK_16GTFD;
1731 break;
1733 default:
1734 DP(NETIF_MSG_LINK,
1735 "link speed unsupported gp_status 0x%x\n",
1736 gp_status);
1737 return -EINVAL;
1738 break;
1741 /* Upon link speed change set the NIG into drain mode.
1742 Comes to deals with possible FIFO glitch due to clk change
1743 when speed is decreased without link down indicator */
1744 if (new_line_speed != vars->line_speed) {
1745 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
1746 + params->port*4, 0);
1747 msleep(1);
1749 vars->line_speed = new_line_speed;
1750 vars->link_status |= LINK_STATUS_SERDES_LINK;
1752 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1753 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1754 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1755 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1756 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
1757 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1758 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
1759 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1760 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481))) {
1761 vars->autoneg = AUTO_NEG_ENABLED;
1763 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1764 vars->autoneg |= AUTO_NEG_COMPLETE;
1765 vars->link_status |=
1766 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1769 vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1770 vars->link_status |=
1771 LINK_STATUS_PARALLEL_DETECTION_USED;
1774 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1775 vars->link_status |=
1776 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1778 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1779 vars->link_status |=
1780 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1782 } else { /* link_down */
1783 DP(NETIF_MSG_LINK, "phy link down\n");
1785 vars->phy_link_up = 0;
1787 vars->duplex = DUPLEX_FULL;
1788 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1789 vars->autoneg = AUTO_NEG_DISABLED;
1790 vars->mac_type = MAC_TYPE_NONE;
1793 DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x \n",
1794 gp_status, vars->phy_link_up, vars->line_speed);
1795 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x"
1796 " autoneg 0x%x\n",
1797 vars->duplex,
1798 vars->flow_ctrl, vars->autoneg);
1799 DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1801 return rc;
1804 static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
1806 struct bnx2x *bp = params->bp;
1807 u16 lp_up2;
1808 u16 tx_driver;
1810 /* read precomp */
1812 CL45_RD_OVER_CL22(bp, params->port,
1813 params->phy_addr,
1814 MDIO_REG_BANK_OVER_1G,
1815 MDIO_OVER_1G_LP_UP2, &lp_up2);
1817 CL45_RD_OVER_CL22(bp, params->port,
1818 params->phy_addr,
1819 MDIO_REG_BANK_TX0,
1820 MDIO_TX0_TX_DRIVER, &tx_driver);
1822 /* bits [10:7] at lp_up2, positioned at [15:12] */
1823 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1824 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1825 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1827 if ((lp_up2 != 0) &&
1828 (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
1829 /* replace tx_driver bits [15:12] */
1830 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1831 tx_driver |= lp_up2;
1832 CL45_WR_OVER_CL22(bp, params->port,
1833 params->phy_addr,
1834 MDIO_REG_BANK_TX0,
1835 MDIO_TX0_TX_DRIVER, tx_driver);
1839 static u8 bnx2x_emac_program(struct link_params *params,
1840 u32 line_speed, u32 duplex)
1842 struct bnx2x *bp = params->bp;
1843 u8 port = params->port;
1844 u16 mode = 0;
1846 DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1847 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1848 EMAC_REG_EMAC_MODE,
1849 (EMAC_MODE_25G_MODE |
1850 EMAC_MODE_PORT_MII_10M |
1851 EMAC_MODE_HALF_DUPLEX));
1852 switch (line_speed) {
1853 case SPEED_10:
1854 mode |= EMAC_MODE_PORT_MII_10M;
1855 break;
1857 case SPEED_100:
1858 mode |= EMAC_MODE_PORT_MII;
1859 break;
1861 case SPEED_1000:
1862 mode |= EMAC_MODE_PORT_GMII;
1863 break;
1865 case SPEED_2500:
1866 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1867 break;
1869 default:
1870 /* 10G not valid for EMAC */
1871 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1872 return -EINVAL;
1875 if (duplex == DUPLEX_HALF)
1876 mode |= EMAC_MODE_HALF_DUPLEX;
1877 bnx2x_bits_en(bp,
1878 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1879 mode);
1881 bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1882 line_speed, params->hw_led_mode, params->chip_id);
1883 return 0;
1886 /*****************************************************************************/
1887 /* External Phy section */
1888 /*****************************************************************************/
1889 static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
1891 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1892 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
1893 msleep(1);
1894 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1895 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
1898 static void bnx2x_ext_phy_reset(struct link_params *params,
1899 struct link_vars *vars)
1901 struct bnx2x *bp = params->bp;
1902 u32 ext_phy_type;
1903 u8 ext_phy_addr = ((params->ext_phy_config &
1904 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1905 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1906 DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1907 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1908 /* The PHY reset is controled by GPIO 1
1909 * Give it 1ms of reset pulse
1911 if (vars->phy_flags & PHY_XGXS_FLAG) {
1913 switch (ext_phy_type) {
1914 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1915 DP(NETIF_MSG_LINK, "XGXS Direct\n");
1916 break;
1918 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1919 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1920 DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1922 /* Restore normal power mode*/
1923 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1924 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1925 params->port);
1927 /* HW reset */
1928 bnx2x_hw_reset(bp, params->port);
1930 bnx2x_cl45_write(bp, params->port,
1931 ext_phy_type,
1932 ext_phy_addr,
1933 MDIO_PMA_DEVAD,
1934 MDIO_PMA_REG_CTRL, 0xa040);
1935 break;
1936 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
1938 /* Restore normal power mode*/
1939 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1940 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1941 params->port);
1943 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1944 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1945 params->port);
1947 bnx2x_cl45_write(bp, params->port,
1948 ext_phy_type,
1949 ext_phy_addr,
1950 MDIO_PMA_DEVAD,
1951 MDIO_PMA_REG_CTRL,
1952 1<<15);
1954 break;
1955 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1956 /* Unset Low Power Mode and SW reset */
1957 /* Restore normal power mode*/
1958 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1959 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1960 params->port);
1962 DP(NETIF_MSG_LINK, "XGXS 8072\n");
1963 bnx2x_cl45_write(bp, params->port,
1964 ext_phy_type,
1965 ext_phy_addr,
1966 MDIO_PMA_DEVAD,
1967 MDIO_PMA_REG_CTRL,
1968 1<<15);
1969 break;
1970 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1972 u16 emac_base;
1973 emac_base = (params->port) ? GRCBASE_EMAC0 :
1974 GRCBASE_EMAC1;
1976 /* Restore normal power mode*/
1977 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1978 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1979 params->port);
1981 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1982 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1983 params->port);
1985 DP(NETIF_MSG_LINK, "XGXS 8073\n");
1987 break;
1989 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1990 DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1992 /* Restore normal power mode*/
1993 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1994 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1995 params->port);
1997 /* HW reset */
1998 bnx2x_hw_reset(bp, params->port);
2000 break;
2002 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
2004 /* Restore normal power mode*/
2005 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2006 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2007 params->port);
2009 /* HW reset */
2010 bnx2x_hw_reset(bp, params->port);
2012 bnx2x_cl45_write(bp, params->port,
2013 ext_phy_type,
2014 ext_phy_addr,
2015 MDIO_PMA_DEVAD,
2016 MDIO_PMA_REG_CTRL,
2017 1<<15);
2018 break;
2019 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2020 DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
2021 break;
2023 default:
2024 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
2025 params->ext_phy_config);
2026 break;
2029 } else { /* SerDes */
2030 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2031 switch (ext_phy_type) {
2032 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
2033 DP(NETIF_MSG_LINK, "SerDes Direct\n");
2034 break;
2036 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
2037 DP(NETIF_MSG_LINK, "SerDes 5482\n");
2038 bnx2x_hw_reset(bp, params->port);
2039 break;
2041 default:
2042 DP(NETIF_MSG_LINK,
2043 "BAD SerDes ext_phy_config 0x%x\n",
2044 params->ext_phy_config);
2045 break;
2051 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
2052 u32 shmem_base, u32 spirom_ver)
2054 DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x\n",
2055 (u16)(spirom_ver>>16), (u16)spirom_ver);
2056 REG_WR(bp, shmem_base +
2057 offsetof(struct shmem_region,
2058 port_mb[port].ext_phy_fw_version),
2059 spirom_ver);
2062 static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
2063 u32 ext_phy_type, u8 ext_phy_addr,
2064 u32 shmem_base)
2066 u16 fw_ver1, fw_ver2;
2067 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2068 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2069 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2070 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2071 bnx2x_save_spirom_version(bp, port, shmem_base,
2072 (u32)(fw_ver1<<16 | fw_ver2));
2075 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
2077 struct bnx2x *bp = params->bp;
2078 u8 port = params->port;
2079 u8 ext_phy_addr = ((params->ext_phy_config &
2080 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2081 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2082 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2084 /* Need to wait 200ms after reset */
2085 msleep(200);
2086 /* Boot port from external ROM
2087 * Set ser_boot_ctl bit in the MISC_CTRL1 register
2089 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2090 MDIO_PMA_DEVAD,
2091 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2093 /* Reset internal microprocessor */
2094 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2095 MDIO_PMA_DEVAD,
2096 MDIO_PMA_REG_GEN_CTRL,
2097 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2098 /* set micro reset = 0 */
2099 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2100 MDIO_PMA_DEVAD,
2101 MDIO_PMA_REG_GEN_CTRL,
2102 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2103 /* Reset internal microprocessor */
2104 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2105 MDIO_PMA_DEVAD,
2106 MDIO_PMA_REG_GEN_CTRL,
2107 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2108 /* wait for 100ms for code download via SPI port */
2109 msleep(100);
2111 /* Clear ser_boot_ctl bit */
2112 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2113 MDIO_PMA_DEVAD,
2114 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2115 /* Wait 100ms */
2116 msleep(100);
2118 bnx2x_save_bcm_spirom_ver(bp, port,
2119 ext_phy_type,
2120 ext_phy_addr,
2121 params->shmem_base);
2124 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2126 /* This is only required for 8073A1, version 102 only */
2128 struct bnx2x *bp = params->bp;
2129 u8 ext_phy_addr = ((params->ext_phy_config &
2130 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2131 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2132 u16 val;
2134 /* Read 8073 HW revision*/
2135 bnx2x_cl45_read(bp, params->port,
2136 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2137 ext_phy_addr,
2138 MDIO_PMA_DEVAD,
2139 0xc801, &val);
2141 if (val != 1) {
2142 /* No need to workaround in 8073 A1 */
2143 return 0;
2146 bnx2x_cl45_read(bp, params->port,
2147 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2148 ext_phy_addr,
2149 MDIO_PMA_DEVAD,
2150 MDIO_PMA_REG_ROM_VER2, &val);
2152 /* SNR should be applied only for version 0x102 */
2153 if (val != 0x102)
2154 return 0;
2156 return 1;
2159 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2161 struct bnx2x *bp = params->bp;
2162 u8 ext_phy_addr = ((params->ext_phy_config &
2163 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2164 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2165 u16 val, cnt, cnt1 ;
2167 bnx2x_cl45_read(bp, params->port,
2168 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2169 ext_phy_addr,
2170 MDIO_PMA_DEVAD,
2171 0xc801, &val);
2173 if (val > 0) {
2174 /* No need to workaround in 8073 A1 */
2175 return 0;
2177 /* XAUI workaround in 8073 A0: */
2179 /* After loading the boot ROM and restarting Autoneg,
2180 poll Dev1, Reg $C820: */
2182 for (cnt = 0; cnt < 1000; cnt++) {
2183 bnx2x_cl45_read(bp, params->port,
2184 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2185 ext_phy_addr,
2186 MDIO_PMA_DEVAD,
2187 0xc820, &val);
2188 /* If bit [14] = 0 or bit [13] = 0, continue on with
2189 system initialization (XAUI work-around not required,
2190 as these bits indicate 2.5G or 1G link up). */
2191 if (!(val & (1<<14)) || !(val & (1<<13))) {
2192 DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2193 return 0;
2194 } else if (!(val & (1<<15))) {
2195 DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2196 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2197 it's MSB (bit 15) goes to 1 (indicating that the
2198 XAUI workaround has completed),
2199 then continue on with system initialization.*/
2200 for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2201 bnx2x_cl45_read(bp, params->port,
2202 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2203 ext_phy_addr,
2204 MDIO_PMA_DEVAD,
2205 0xc841, &val);
2206 if (val & (1<<15)) {
2207 DP(NETIF_MSG_LINK,
2208 "XAUI workaround has completed\n");
2209 return 0;
2211 msleep(3);
2213 break;
2215 msleep(3);
2217 DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2218 return -EINVAL;
2222 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2223 u8 ext_phy_addr, u32 shmem_base)
2225 /* Boot port from external ROM */
2226 /* EDC grst */
2227 bnx2x_cl45_write(bp, port,
2228 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2229 ext_phy_addr,
2230 MDIO_PMA_DEVAD,
2231 MDIO_PMA_REG_GEN_CTRL,
2232 0x0001);
2234 /* ucode reboot and rst */
2235 bnx2x_cl45_write(bp, port,
2236 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2237 ext_phy_addr,
2238 MDIO_PMA_DEVAD,
2239 MDIO_PMA_REG_GEN_CTRL,
2240 0x008c);
2242 bnx2x_cl45_write(bp, port,
2243 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2244 ext_phy_addr,
2245 MDIO_PMA_DEVAD,
2246 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2248 /* Reset internal microprocessor */
2249 bnx2x_cl45_write(bp, port,
2250 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2251 ext_phy_addr,
2252 MDIO_PMA_DEVAD,
2253 MDIO_PMA_REG_GEN_CTRL,
2254 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2256 /* Release srst bit */
2257 bnx2x_cl45_write(bp, port,
2258 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2259 ext_phy_addr,
2260 MDIO_PMA_DEVAD,
2261 MDIO_PMA_REG_GEN_CTRL,
2262 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2264 /* wait for 100ms for code download via SPI port */
2265 msleep(100);
2267 /* Clear ser_boot_ctl bit */
2268 bnx2x_cl45_write(bp, port,
2269 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2270 ext_phy_addr,
2271 MDIO_PMA_DEVAD,
2272 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2274 bnx2x_save_bcm_spirom_ver(bp, port,
2275 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2276 ext_phy_addr,
2277 shmem_base);
2280 static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
2282 struct bnx2x *bp = params->bp;
2283 u8 port = params->port;
2284 u8 ext_phy_addr = ((params->ext_phy_config &
2285 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2286 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2287 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2289 /* Need to wait 100ms after reset */
2290 msleep(100);
2292 /* Set serial boot control for external load */
2293 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2294 MDIO_PMA_DEVAD,
2295 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2297 /* Micro controller re-boot */
2298 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2299 MDIO_PMA_DEVAD,
2300 MDIO_PMA_REG_GEN_CTRL,
2301 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2303 /* Set soft reset */
2304 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2305 MDIO_PMA_DEVAD,
2306 MDIO_PMA_REG_GEN_CTRL,
2307 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2309 /* Clear soft reset.
2310 Will automatically reset micro-controller re-boot */
2311 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2312 MDIO_PMA_DEVAD,
2313 MDIO_PMA_REG_GEN_CTRL,
2314 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2316 /* wait for 100ms for microcode load */
2317 msleep(100);
2319 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
2320 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2321 MDIO_PMA_DEVAD,
2322 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2324 msleep(200);
2325 bnx2x_save_bcm_spirom_ver(bp, port,
2326 ext_phy_type,
2327 ext_phy_addr,
2328 params->shmem_base);
2331 static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port,
2332 u8 ext_phy_addr, u8 tx_en)
2334 u16 val;
2335 DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
2336 tx_en, port);
2337 /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
2338 bnx2x_cl45_read(bp, port,
2339 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2340 ext_phy_addr,
2341 MDIO_PMA_DEVAD,
2342 MDIO_PMA_REG_PHY_IDENTIFIER,
2343 &val);
2345 if (tx_en)
2346 val &= ~(1<<15);
2347 else
2348 val |= (1<<15);
2350 bnx2x_cl45_write(bp, port,
2351 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2352 ext_phy_addr,
2353 MDIO_PMA_DEVAD,
2354 MDIO_PMA_REG_PHY_IDENTIFIER,
2355 val);
2359 static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
2360 u8 byte_cnt, u8 *o_buf) {
2361 struct bnx2x *bp = params->bp;
2362 u16 val, i;
2363 u8 port = params->port;
2364 u8 ext_phy_addr = ((params->ext_phy_config &
2365 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2366 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2367 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2368 if (byte_cnt > 16) {
2369 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2370 " is limited to 0xf\n");
2371 return -EINVAL;
2373 /* Set the read command byte count */
2374 bnx2x_cl45_write(bp, port,
2375 ext_phy_type,
2376 ext_phy_addr,
2377 MDIO_PMA_DEVAD,
2378 MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT,
2379 (byte_cnt | 0xa000));
2381 /* Set the read command address */
2382 bnx2x_cl45_write(bp, port,
2383 ext_phy_type,
2384 ext_phy_addr,
2385 MDIO_PMA_DEVAD,
2386 MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR,
2387 addr);
2389 /* Activate read command */
2390 bnx2x_cl45_write(bp, port,
2391 ext_phy_type,
2392 ext_phy_addr,
2393 MDIO_PMA_DEVAD,
2394 MDIO_PMA_REG_8726_TWO_WIRE_CTRL,
2395 0x2c0f);
2397 /* Wait up to 500us for command complete status */
2398 for (i = 0; i < 100; i++) {
2399 bnx2x_cl45_read(bp, port,
2400 ext_phy_type,
2401 ext_phy_addr,
2402 MDIO_PMA_DEVAD,
2403 MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2404 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2405 MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE)
2406 break;
2407 udelay(5);
2410 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) !=
2411 MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE) {
2412 DP(NETIF_MSG_LINK,
2413 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2414 (val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK));
2415 return -EINVAL;
2418 /* Read the buffer */
2419 for (i = 0; i < byte_cnt; i++) {
2420 bnx2x_cl45_read(bp, port,
2421 ext_phy_type,
2422 ext_phy_addr,
2423 MDIO_PMA_DEVAD,
2424 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2425 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
2428 for (i = 0; i < 100; i++) {
2429 bnx2x_cl45_read(bp, port,
2430 ext_phy_type,
2431 ext_phy_addr,
2432 MDIO_PMA_DEVAD,
2433 MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2434 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2435 MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE)
2436 return 0;;
2437 msleep(1);
2439 return -EINVAL;
2443 static u8 bnx2x_get_sfp_module_type(struct link_params *params,
2444 u8 *module_type)
2446 struct bnx2x *bp = params->bp;
2447 u8 val;
2448 *module_type = SFP_MODULE_TYPE_UNKNOWN;
2450 /* First check for copper cable */
2451 if (bnx2x_read_sfp_module_eeprom(params,
2452 SFP_EEPROM_CON_TYPE_ADDR,
2454 &val) != 0) {
2455 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM");
2456 return -EINVAL;
2459 switch (val) {
2460 case SFP_EEPROM_CON_TYPE_VAL_COPPER:
2462 u8 copper_module_type;
2463 /* Check if its active cable( includes SFP+ module)
2464 of passive cable*/
2465 if (bnx2x_read_sfp_module_eeprom(params,
2466 SFP_EEPROM_FC_TX_TECH_ADDR,
2468 &copper_module_type) !=
2469 0) {
2470 DP(NETIF_MSG_LINK,
2471 "Failed to read copper-cable-type"
2472 " from SFP+ EEPROM\n");
2473 return -EINVAL;
2476 if (copper_module_type &
2477 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
2478 DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
2479 *module_type = SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE;
2480 } else if (copper_module_type &
2481 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
2482 DP(NETIF_MSG_LINK, "Passive Copper"
2483 " cable detected\n");
2484 *module_type =
2485 SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE;
2486 } else {
2487 DP(NETIF_MSG_LINK, "Unknown copper-cable-"
2488 "type 0x%x !!!\n", copper_module_type);
2489 return -EINVAL;
2491 break;
2493 case SFP_EEPROM_CON_TYPE_VAL_LC:
2494 DP(NETIF_MSG_LINK, "Optic module detected\n");
2495 *module_type = SFP_MODULE_TYPE_LC;
2496 break;
2498 default:
2499 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
2500 val);
2501 return -EINVAL;
2503 return 0;
2507 /* This function read the relevant field from the module ( SFP+ ),
2508 and verify it is compliant with this board */
2509 static u8 bnx2x_verify_sfp_module(struct link_params *params,
2510 u8 module_type)
2512 struct bnx2x *bp = params->bp;
2513 u8 *str_p, *tmp_buf;
2514 u16 i;
2516 #define COMPLIANCE_STR_CNT 6
2517 u8 *compliance_str[] = {"Broadcom", "JDSU", "Molex Inc", "PICOLIGHT",
2518 "FINISAR CORP. ", "Amphenol"};
2519 u8 buf[SFP_EEPROM_VENDOR_NAME_SIZE];
2520 /* Passive Copper cables are allowed to participate,
2521 since the module is hardwired to the copper cable */
2523 if (!(params->feature_config_flags &
2524 FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2525 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
2526 return 0;
2529 if (module_type != SFP_MODULE_TYPE_LC) {
2530 DP(NETIF_MSG_LINK, "No need to verify copper cable\n");
2531 return 0;
2534 /* In case of non copper cable or Active copper cable,
2535 verify that the SFP+ module is compliant with this board*/
2536 if (bnx2x_read_sfp_module_eeprom(params,
2537 SFP_EEPROM_VENDOR_NAME_ADDR,
2538 SFP_EEPROM_VENDOR_NAME_SIZE,
2539 buf) != 0) {
2540 DP(NETIF_MSG_LINK, "Failed to read Vendor-Name from"
2541 " module EEPROM\n");
2542 return -EINVAL;
2544 for (i = 0; i < COMPLIANCE_STR_CNT; i++) {
2545 str_p = compliance_str[i];
2546 tmp_buf = buf;
2547 while (*str_p) {
2548 if ((u8)(*tmp_buf) != (u8)(*str_p))
2549 break;
2550 str_p++;
2551 tmp_buf++;
2554 if (!(*str_p)) {
2555 DP(NETIF_MSG_LINK, "SFP+ Module verified, "
2556 "index=%x\n", i);
2557 return 0;
2560 DP(NETIF_MSG_LINK, "Incompliant SFP+ module. Disable module !!!\n");
2561 return -EINVAL;
2565 static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
2566 u8 module_type)
2568 struct bnx2x *bp = params->bp;
2569 u8 port = params->port;
2570 u8 options[SFP_EEPROM_OPTIONS_SIZE];
2571 u8 limiting_mode;
2572 u8 ext_phy_addr = ((params->ext_phy_config &
2573 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2574 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2576 if (bnx2x_read_sfp_module_eeprom(params,
2577 SFP_EEPROM_OPTIONS_ADDR,
2578 SFP_EEPROM_OPTIONS_SIZE,
2579 options) != 0) {
2580 DP(NETIF_MSG_LINK, "Failed to read Option field from"
2581 " module EEPROM\n");
2582 return -EINVAL;
2584 limiting_mode = !(options[0] &
2585 SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK);
2586 if (limiting_mode &&
2587 (module_type != SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE)) {
2588 DP(NETIF_MSG_LINK,
2589 "Module options = 0x%x.Setting LIMITING MODE\n",
2590 options[0]);
2591 bnx2x_cl45_write(bp, port,
2592 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2593 ext_phy_addr,
2594 MDIO_PMA_DEVAD,
2595 MDIO_PMA_REG_ROM_VER2,
2596 SFP_LIMITING_MODE_VALUE);
2597 } else { /* LRM mode ( default )*/
2598 u16 cur_limiting_mode;
2599 DP(NETIF_MSG_LINK, "Module options = 0x%x.Setting LRM MODE\n",
2600 options[0]);
2602 bnx2x_cl45_read(bp, port,
2603 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2604 ext_phy_addr,
2605 MDIO_PMA_DEVAD,
2606 MDIO_PMA_REG_ROM_VER2,
2607 &cur_limiting_mode);
2609 /* Changing to LRM mode takes quite few seconds.
2610 So do it only if current mode is limiting
2611 ( default is LRM )*/
2612 if (cur_limiting_mode != SFP_LIMITING_MODE_VALUE)
2613 return 0;
2615 bnx2x_cl45_write(bp, port,
2616 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2617 ext_phy_addr,
2618 MDIO_PMA_DEVAD,
2619 MDIO_PMA_REG_LRM_MODE,
2621 bnx2x_cl45_write(bp, port,
2622 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2623 ext_phy_addr,
2624 MDIO_PMA_DEVAD,
2625 MDIO_PMA_REG_ROM_VER2,
2626 0x128);
2627 bnx2x_cl45_write(bp, port,
2628 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2629 ext_phy_addr,
2630 MDIO_PMA_DEVAD,
2631 MDIO_PMA_REG_MISC_CTRL0,
2632 0x4008);
2633 bnx2x_cl45_write(bp, port,
2634 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2635 ext_phy_addr,
2636 MDIO_PMA_DEVAD,
2637 MDIO_PMA_REG_LRM_MODE,
2638 0xaaaa);
2640 return 0;
2643 static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
2645 u8 val;
2646 struct bnx2x *bp = params->bp;
2647 u16 timeout;
2648 /* Initialization time after hot-plug may take up to 300ms for some
2649 phys type ( e.g. JDSU ) */
2650 for (timeout = 0; timeout < 60; timeout++) {
2651 if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
2652 == 0) {
2653 DP(NETIF_MSG_LINK, "SFP+ module initialization "
2654 "took %d ms\n", timeout * 5);
2655 return 0;
2657 msleep(5);
2659 return -EINVAL;
2662 static u8 bnx2x_sfp_module_detection(struct link_params *params)
2664 struct bnx2x *bp = params->bp;
2665 u8 module_type;
2666 u8 ext_phy_addr = ((params->ext_phy_config &
2667 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2668 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2669 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2671 if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
2672 DP(NETIF_MSG_LINK, "Module detection is not required "
2673 "for this phy\n");
2674 return 0;
2677 DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
2678 params->port);
2680 if (bnx2x_get_sfp_module_type(params,
2681 &module_type) != 0) {
2682 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
2683 if (!(params->feature_config_flags &
2684 FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2685 /* In case module detection is disabled, it trys to
2686 link up. The issue that can happen here is LRM /
2687 LIMITING mode which set according to the module-type*/
2688 DP(NETIF_MSG_LINK, "Unable to read module-type."
2689 "Probably due to Bit Stretching."
2690 " Proceeding...\n");
2691 } else {
2692 return -EINVAL;
2694 } else if (bnx2x_verify_sfp_module(params, module_type) !=
2695 0) {
2696 /* check SFP+ module compatibility */
2697 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
2698 /* Turn on fault module-detected led */
2699 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2700 MISC_REGISTERS_GPIO_HIGH,
2701 params->port);
2702 return -EINVAL;
2705 /* Turn off fault module-detected led */
2706 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2707 MISC_REGISTERS_GPIO_LOW,
2708 params->port);
2710 /* Check and set limiting mode / LRM mode */
2711 if (bnx2x_bcm8726_set_limiting_mode(params, module_type)
2712 != 0) {
2713 DP(NETIF_MSG_LINK, "Setting limiting mode failed!!\n");
2714 return -EINVAL;
2717 /* Enable transmit for this module */
2718 bnx2x_bcm8726_set_transmitter(bp, params->port,
2719 ext_phy_addr, 1);
2720 return 0;
2723 void bnx2x_handle_module_detect_int(struct link_params *params)
2725 struct bnx2x *bp = params->bp;
2726 u32 gpio_val;
2727 u8 port = params->port;
2728 /* Set valid module led off */
2729 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2730 MISC_REGISTERS_GPIO_HIGH,
2731 params->port);
2733 /* Get current gpio val refelecting module plugged in / out*/
2734 gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
2736 /* Call the handling function in case module is detected */
2737 if (gpio_val == 0) {
2739 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2740 MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
2741 port);
2743 if (bnx2x_wait_for_sfp_module_initialized(params)
2744 == 0)
2745 bnx2x_sfp_module_detection(params);
2746 else
2747 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
2748 } else {
2749 u8 ext_phy_addr = ((params->ext_phy_config &
2750 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2751 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2752 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2753 MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
2754 port);
2755 /* Module was plugged out. */
2756 /* Disable transmit for this module */
2757 bnx2x_bcm8726_set_transmitter(bp, params->port,
2758 ext_phy_addr, 0);
2762 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2764 struct bnx2x *bp = params->bp;
2765 u8 port = params->port;
2766 u8 ext_phy_addr = ((params->ext_phy_config &
2767 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2768 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2769 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2771 /* Force KR or KX */
2772 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2773 MDIO_PMA_DEVAD,
2774 MDIO_PMA_REG_CTRL,
2775 0x2040);
2776 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2777 MDIO_PMA_DEVAD,
2778 MDIO_PMA_REG_10G_CTRL2,
2779 0x000b);
2780 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2781 MDIO_PMA_DEVAD,
2782 MDIO_PMA_REG_BCM_CTRL,
2783 0x0000);
2784 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2785 MDIO_AN_DEVAD,
2786 MDIO_AN_REG_CTRL,
2787 0x0000);
2789 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2791 struct bnx2x *bp = params->bp;
2792 u8 port = params->port;
2793 u16 val;
2794 u8 ext_phy_addr = ((params->ext_phy_config &
2795 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2796 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2797 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2799 bnx2x_cl45_read(bp, params->port,
2800 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2801 ext_phy_addr,
2802 MDIO_PMA_DEVAD,
2803 0xc801, &val);
2805 if (val == 0) {
2806 /* Mustn't set low power mode in 8073 A0 */
2807 return;
2810 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2811 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2812 MDIO_XS_DEVAD,
2813 MDIO_XS_PLL_SEQUENCER, &val);
2814 val &= ~(1<<13);
2815 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2816 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2818 /* PLL controls */
2819 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2820 MDIO_XS_DEVAD, 0x805E, 0x1077);
2821 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2822 MDIO_XS_DEVAD, 0x805D, 0x0000);
2823 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2824 MDIO_XS_DEVAD, 0x805C, 0x030B);
2825 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2826 MDIO_XS_DEVAD, 0x805B, 0x1240);
2827 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2828 MDIO_XS_DEVAD, 0x805A, 0x2490);
2830 /* Tx Controls */
2831 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2832 MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2833 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2834 MDIO_XS_DEVAD, 0x80A6, 0x9041);
2835 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2836 MDIO_XS_DEVAD, 0x80A5, 0x4640);
2838 /* Rx Controls */
2839 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2840 MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2841 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2842 MDIO_XS_DEVAD, 0x80FD, 0x9249);
2843 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2844 MDIO_XS_DEVAD, 0x80FC, 0x2015);
2846 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
2847 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2848 MDIO_XS_DEVAD,
2849 MDIO_XS_PLL_SEQUENCER, &val);
2850 val |= (1<<13);
2851 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2852 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2855 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
2856 struct link_vars *vars)
2859 struct bnx2x *bp = params->bp;
2860 u16 cl37_val;
2861 u8 ext_phy_addr = ((params->ext_phy_config &
2862 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2863 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2864 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2866 bnx2x_cl45_read(bp, params->port,
2867 ext_phy_type,
2868 ext_phy_addr,
2869 MDIO_AN_DEVAD,
2870 MDIO_AN_REG_CL37_FC_LD, &cl37_val);
2872 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2873 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2875 if ((vars->ieee_fc &
2876 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
2877 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
2878 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
2880 if ((vars->ieee_fc &
2881 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2882 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2883 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2885 if ((vars->ieee_fc &
2886 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2887 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2888 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2890 DP(NETIF_MSG_LINK,
2891 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
2893 bnx2x_cl45_write(bp, params->port,
2894 ext_phy_type,
2895 ext_phy_addr,
2896 MDIO_AN_DEVAD,
2897 MDIO_AN_REG_CL37_FC_LD, cl37_val);
2898 msleep(500);
2901 static void bnx2x_ext_phy_set_pause(struct link_params *params,
2902 struct link_vars *vars)
2904 struct bnx2x *bp = params->bp;
2905 u16 val;
2906 u8 ext_phy_addr = ((params->ext_phy_config &
2907 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2908 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2909 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2911 /* read modify write pause advertizing */
2912 bnx2x_cl45_read(bp, params->port,
2913 ext_phy_type,
2914 ext_phy_addr,
2915 MDIO_AN_DEVAD,
2916 MDIO_AN_REG_ADV_PAUSE, &val);
2918 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2920 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2922 if ((vars->ieee_fc &
2923 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2924 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2925 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2927 if ((vars->ieee_fc &
2928 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2929 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2930 val |=
2931 MDIO_AN_REG_ADV_PAUSE_PAUSE;
2933 DP(NETIF_MSG_LINK,
2934 "Ext phy AN advertize 0x%x\n", val);
2935 bnx2x_cl45_write(bp, params->port,
2936 ext_phy_type,
2937 ext_phy_addr,
2938 MDIO_AN_DEVAD,
2939 MDIO_AN_REG_ADV_PAUSE, val);
2943 static void bnx2x_init_internal_phy(struct link_params *params,
2944 struct link_vars *vars)
2946 struct bnx2x *bp = params->bp;
2947 u8 port = params->port;
2948 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2949 u16 bank, rx_eq;
2951 rx_eq = ((params->serdes_config &
2952 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2953 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2955 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2956 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2957 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2958 CL45_WR_OVER_CL22(bp, port,
2959 params->phy_addr,
2960 bank ,
2961 MDIO_RX0_RX_EQ_BOOST,
2962 ((rx_eq &
2963 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2964 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2967 /* forced speed requested? */
2968 if (vars->line_speed != SPEED_AUTO_NEG) {
2969 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2971 /* disable autoneg */
2972 bnx2x_set_autoneg(params, vars);
2974 /* program speed and duplex */
2975 bnx2x_program_serdes(params, vars);
2977 } else { /* AN_mode */
2978 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2980 /* AN enabled */
2981 bnx2x_set_brcm_cl37_advertisment(params);
2983 /* program duplex & pause advertisement (for aneg) */
2984 bnx2x_set_ieee_aneg_advertisment(params,
2985 vars->ieee_fc);
2987 /* enable autoneg */
2988 bnx2x_set_autoneg(params, vars);
2990 /* enable and restart AN */
2991 bnx2x_restart_autoneg(params);
2994 } else { /* SGMII mode */
2995 DP(NETIF_MSG_LINK, "SGMII\n");
2997 bnx2x_initialize_sgmii_process(params, vars);
3001 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
3003 struct bnx2x *bp = params->bp;
3004 u32 ext_phy_type;
3005 u8 ext_phy_addr;
3006 u16 cnt;
3007 u16 ctrl = 0;
3008 u16 val = 0;
3009 u8 rc = 0;
3010 if (vars->phy_flags & PHY_XGXS_FLAG) {
3011 ext_phy_addr = ((params->ext_phy_config &
3012 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3013 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3015 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3016 /* Make sure that the soft reset is off (expect for the 8072:
3017 * due to the lock, it will be done inside the specific
3018 * handling)
3020 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3021 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3022 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
3023 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
3024 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
3025 /* Wait for soft reset to get cleared upto 1 sec */
3026 for (cnt = 0; cnt < 1000; cnt++) {
3027 bnx2x_cl45_read(bp, params->port,
3028 ext_phy_type,
3029 ext_phy_addr,
3030 MDIO_PMA_DEVAD,
3031 MDIO_PMA_REG_CTRL, &ctrl);
3032 if (!(ctrl & (1<<15)))
3033 break;
3034 msleep(1);
3036 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
3037 ctrl, cnt);
3040 switch (ext_phy_type) {
3041 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3042 break;
3044 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3045 DP(NETIF_MSG_LINK, "XGXS 8705\n");
3047 bnx2x_cl45_write(bp, params->port,
3048 ext_phy_type,
3049 ext_phy_addr,
3050 MDIO_PMA_DEVAD,
3051 MDIO_PMA_REG_MISC_CTRL,
3052 0x8288);
3053 bnx2x_cl45_write(bp, params->port,
3054 ext_phy_type,
3055 ext_phy_addr,
3056 MDIO_PMA_DEVAD,
3057 MDIO_PMA_REG_PHY_IDENTIFIER,
3058 0x7fbf);
3059 bnx2x_cl45_write(bp, params->port,
3060 ext_phy_type,
3061 ext_phy_addr,
3062 MDIO_PMA_DEVAD,
3063 MDIO_PMA_REG_CMU_PLL_BYPASS,
3064 0x0100);
3065 bnx2x_cl45_write(bp, params->port,
3066 ext_phy_type,
3067 ext_phy_addr,
3068 MDIO_WIS_DEVAD,
3069 MDIO_WIS_REG_LASI_CNTL, 0x1);
3071 bnx2x_save_bcm_spirom_ver(bp, params->port,
3072 ext_phy_type,
3073 ext_phy_addr,
3074 params->shmem_base);
3075 break;
3077 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3078 /* Wait until fw is loaded */
3079 for (cnt = 0; cnt < 100; cnt++) {
3080 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3081 ext_phy_addr, MDIO_PMA_DEVAD,
3082 MDIO_PMA_REG_ROM_VER1, &val);
3083 if (val)
3084 break;
3085 msleep(10);
3087 DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
3088 "after %d ms\n", cnt);
3089 /* Force speed */
3090 /* First enable LASI */
3091 bnx2x_cl45_write(bp, params->port,
3092 ext_phy_type,
3093 ext_phy_addr,
3094 MDIO_PMA_DEVAD,
3095 MDIO_PMA_REG_RX_ALARM_CTRL,
3096 0x0400);
3097 bnx2x_cl45_write(bp, params->port,
3098 ext_phy_type,
3099 ext_phy_addr,
3100 MDIO_PMA_DEVAD,
3101 MDIO_PMA_REG_LASI_CTRL, 0x0004);
3103 if (params->req_line_speed == SPEED_10000) {
3104 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
3106 bnx2x_cl45_write(bp, params->port,
3107 ext_phy_type,
3108 ext_phy_addr,
3109 MDIO_PMA_DEVAD,
3110 MDIO_PMA_REG_DIGITAL_CTRL,
3111 0x400);
3112 } else {
3113 /* Force 1Gbps using autoneg with 1G
3114 advertisment */
3116 /* Allow CL37 through CL73 */
3117 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
3118 bnx2x_cl45_write(bp, params->port,
3119 ext_phy_type,
3120 ext_phy_addr,
3121 MDIO_AN_DEVAD,
3122 MDIO_AN_REG_CL37_CL73,
3123 0x040c);
3125 /* Enable Full-Duplex advertisment on CL37 */
3126 bnx2x_cl45_write(bp, params->port,
3127 ext_phy_type,
3128 ext_phy_addr,
3129 MDIO_AN_DEVAD,
3130 MDIO_AN_REG_CL37_FC_LP,
3131 0x0020);
3132 /* Enable CL37 AN */
3133 bnx2x_cl45_write(bp, params->port,
3134 ext_phy_type,
3135 ext_phy_addr,
3136 MDIO_AN_DEVAD,
3137 MDIO_AN_REG_CL37_AN,
3138 0x1000);
3139 /* 1G support */
3140 bnx2x_cl45_write(bp, params->port,
3141 ext_phy_type,
3142 ext_phy_addr,
3143 MDIO_AN_DEVAD,
3144 MDIO_AN_REG_ADV, (1<<5));
3146 /* Enable clause 73 AN */
3147 bnx2x_cl45_write(bp, params->port,
3148 ext_phy_type,
3149 ext_phy_addr,
3150 MDIO_AN_DEVAD,
3151 MDIO_AN_REG_CTRL,
3152 0x1200);
3155 bnx2x_save_bcm_spirom_ver(bp, params->port,
3156 ext_phy_type,
3157 ext_phy_addr,
3158 params->shmem_base);
3159 break;
3160 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3161 DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3162 bnx2x_bcm8726_external_rom_boot(params);
3164 /* Need to call module detected on initialization since
3165 the module detection triggered by actual module
3166 insertion might occur before driver is loaded, and when
3167 driver is loaded, it reset all registers, including the
3168 transmitter */
3169 bnx2x_sfp_module_detection(params);
3170 if (params->req_line_speed == SPEED_1000) {
3171 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3172 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3173 ext_phy_addr, MDIO_PMA_DEVAD,
3174 MDIO_PMA_REG_CTRL, 0x40);
3175 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3176 ext_phy_addr, MDIO_PMA_DEVAD,
3177 MDIO_PMA_REG_10G_CTRL2, 0xD);
3178 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3179 ext_phy_addr, MDIO_PMA_DEVAD,
3180 MDIO_PMA_REG_LASI_CTRL, 0x5);
3181 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3182 ext_phy_addr, MDIO_PMA_DEVAD,
3183 MDIO_PMA_REG_RX_ALARM_CTRL,
3184 0x400);
3185 } else if ((params->req_line_speed ==
3186 SPEED_AUTO_NEG) &&
3187 ((params->speed_cap_mask &
3188 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3189 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
3190 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3191 ext_phy_addr, MDIO_AN_DEVAD,
3192 MDIO_AN_REG_ADV, 0x20);
3193 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3194 ext_phy_addr, MDIO_AN_DEVAD,
3195 MDIO_AN_REG_CL37_CL73, 0x040c);
3196 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3197 ext_phy_addr, MDIO_AN_DEVAD,
3198 MDIO_AN_REG_CL37_FC_LD, 0x0020);
3199 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3200 ext_phy_addr, MDIO_AN_DEVAD,
3201 MDIO_AN_REG_CL37_AN, 0x1000);
3202 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3203 ext_phy_addr, MDIO_AN_DEVAD,
3204 MDIO_AN_REG_CTRL, 0x1200);
3206 /* Enable RX-ALARM control to receive
3207 interrupt for 1G speed change */
3208 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3209 ext_phy_addr, MDIO_PMA_DEVAD,
3210 MDIO_PMA_REG_LASI_CTRL, 0x4);
3211 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3212 ext_phy_addr, MDIO_PMA_DEVAD,
3213 MDIO_PMA_REG_RX_ALARM_CTRL,
3214 0x400);
3216 } else { /* Default 10G. Set only LASI control */
3217 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3218 ext_phy_addr, MDIO_PMA_DEVAD,
3219 MDIO_PMA_REG_LASI_CTRL, 1);
3221 break;
3222 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3223 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3225 u16 tmp1;
3226 u16 rx_alarm_ctrl_val;
3227 u16 lasi_ctrl_val;
3228 if (ext_phy_type ==
3229 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3230 rx_alarm_ctrl_val = 0x400;
3231 lasi_ctrl_val = 0x0004;
3232 } else {
3233 rx_alarm_ctrl_val = (1<<2);
3234 lasi_ctrl_val = 0x0004;
3237 /* enable LASI */
3238 bnx2x_cl45_write(bp, params->port,
3239 ext_phy_type,
3240 ext_phy_addr,
3241 MDIO_PMA_DEVAD,
3242 MDIO_PMA_REG_RX_ALARM_CTRL,
3243 rx_alarm_ctrl_val);
3245 bnx2x_cl45_write(bp, params->port,
3246 ext_phy_type,
3247 ext_phy_addr,
3248 MDIO_PMA_DEVAD,
3249 MDIO_PMA_REG_LASI_CTRL,
3250 lasi_ctrl_val);
3252 bnx2x_8073_set_pause_cl37(params, vars);
3254 if (ext_phy_type ==
3255 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
3256 bnx2x_bcm8072_external_rom_boot(params);
3257 } else {
3259 /* In case of 8073 with long xaui lines,
3260 don't set the 8073 xaui low power*/
3261 bnx2x_bcm8073_set_xaui_low_power_mode(params);
3264 bnx2x_cl45_read(bp, params->port,
3265 ext_phy_type,
3266 ext_phy_addr,
3267 MDIO_PMA_DEVAD,
3268 0xca13,
3269 &tmp1);
3271 bnx2x_cl45_read(bp, params->port,
3272 ext_phy_type,
3273 ext_phy_addr,
3274 MDIO_PMA_DEVAD,
3275 MDIO_PMA_REG_RX_ALARM, &tmp1);
3277 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
3278 "0x%x\n", tmp1);
3280 /* If this is forced speed, set to KR or KX
3281 * (all other are not supported)
3283 if (params->loopback_mode == LOOPBACK_EXT) {
3284 bnx2x_bcm807x_force_10G(params);
3285 DP(NETIF_MSG_LINK,
3286 "Forced speed 10G on 807X\n");
3287 break;
3288 } else {
3289 bnx2x_cl45_write(bp, params->port,
3290 ext_phy_type, ext_phy_addr,
3291 MDIO_PMA_DEVAD,
3292 MDIO_PMA_REG_BCM_CTRL,
3293 0x0002);
3295 if (params->req_line_speed != SPEED_AUTO_NEG) {
3296 if (params->req_line_speed == SPEED_10000) {
3297 val = (1<<7);
3298 } else if (params->req_line_speed ==
3299 SPEED_2500) {
3300 val = (1<<5);
3301 /* Note that 2.5G works only
3302 when used with 1G advertisment */
3303 } else
3304 val = (1<<5);
3305 } else {
3307 val = 0;
3308 if (params->speed_cap_mask &
3309 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3310 val |= (1<<7);
3312 /* Note that 2.5G works only when
3313 used with 1G advertisment */
3314 if (params->speed_cap_mask &
3315 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
3316 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
3317 val |= (1<<5);
3318 DP(NETIF_MSG_LINK,
3319 "807x autoneg val = 0x%x\n", val);
3322 bnx2x_cl45_write(bp, params->port,
3323 ext_phy_type,
3324 ext_phy_addr,
3325 MDIO_AN_DEVAD,
3326 MDIO_AN_REG_ADV, val);
3328 if (ext_phy_type ==
3329 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3331 bnx2x_cl45_read(bp, params->port,
3332 ext_phy_type,
3333 ext_phy_addr,
3334 MDIO_AN_DEVAD,
3335 0x8329, &tmp1);
3337 if (((params->speed_cap_mask &
3338 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
3339 (params->req_line_speed ==
3340 SPEED_AUTO_NEG)) ||
3341 (params->req_line_speed ==
3342 SPEED_2500)) {
3343 u16 phy_ver;
3344 /* Allow 2.5G for A1 and above */
3345 bnx2x_cl45_read(bp, params->port,
3346 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
3347 ext_phy_addr,
3348 MDIO_PMA_DEVAD,
3349 0xc801, &phy_ver);
3350 DP(NETIF_MSG_LINK, "Add 2.5G\n");
3351 if (phy_ver > 0)
3352 tmp1 |= 1;
3353 else
3354 tmp1 &= 0xfffe;
3355 } else {
3356 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
3357 tmp1 &= 0xfffe;
3360 bnx2x_cl45_write(bp, params->port,
3361 ext_phy_type,
3362 ext_phy_addr,
3363 MDIO_AN_DEVAD,
3364 0x8329, tmp1);
3367 /* Add support for CL37 (passive mode) II */
3369 bnx2x_cl45_read(bp, params->port,
3370 ext_phy_type,
3371 ext_phy_addr,
3372 MDIO_AN_DEVAD,
3373 MDIO_AN_REG_CL37_FC_LD,
3374 &tmp1);
3376 bnx2x_cl45_write(bp, params->port,
3377 ext_phy_type,
3378 ext_phy_addr,
3379 MDIO_AN_DEVAD,
3380 MDIO_AN_REG_CL37_FC_LD, (tmp1 |
3381 ((params->req_duplex == DUPLEX_FULL) ?
3382 0x20 : 0x40)));
3384 /* Add support for CL37 (passive mode) III */
3385 bnx2x_cl45_write(bp, params->port,
3386 ext_phy_type,
3387 ext_phy_addr,
3388 MDIO_AN_DEVAD,
3389 MDIO_AN_REG_CL37_AN, 0x1000);
3391 if (ext_phy_type ==
3392 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3393 /* The SNR will improve about 2db by changing
3394 BW and FEE main tap. Rest commands are executed
3395 after link is up*/
3396 /*Change FFE main cursor to 5 in EDC register*/
3397 if (bnx2x_8073_is_snr_needed(params))
3398 bnx2x_cl45_write(bp, params->port,
3399 ext_phy_type,
3400 ext_phy_addr,
3401 MDIO_PMA_DEVAD,
3402 MDIO_PMA_REG_EDC_FFE_MAIN,
3403 0xFB0C);
3405 /* Enable FEC (Forware Error Correction)
3406 Request in the AN */
3407 bnx2x_cl45_read(bp, params->port,
3408 ext_phy_type,
3409 ext_phy_addr,
3410 MDIO_AN_DEVAD,
3411 MDIO_AN_REG_ADV2, &tmp1);
3413 tmp1 |= (1<<15);
3415 bnx2x_cl45_write(bp, params->port,
3416 ext_phy_type,
3417 ext_phy_addr,
3418 MDIO_AN_DEVAD,
3419 MDIO_AN_REG_ADV2, tmp1);
3423 bnx2x_ext_phy_set_pause(params, vars);
3425 /* Restart autoneg */
3426 msleep(500);
3427 bnx2x_cl45_write(bp, params->port,
3428 ext_phy_type,
3429 ext_phy_addr,
3430 MDIO_AN_DEVAD,
3431 MDIO_AN_REG_CTRL, 0x1200);
3432 DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
3433 "Advertise 1G=%x, 10G=%x\n",
3434 ((val & (1<<5)) > 0),
3435 ((val & (1<<7)) > 0));
3436 break;
3438 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3440 u16 fw_ver1, fw_ver2;
3441 DP(NETIF_MSG_LINK,
3442 "Setting the SFX7101 LASI indication\n");
3444 bnx2x_cl45_write(bp, params->port,
3445 ext_phy_type,
3446 ext_phy_addr,
3447 MDIO_PMA_DEVAD,
3448 MDIO_PMA_REG_LASI_CTRL, 0x1);
3449 DP(NETIF_MSG_LINK,
3450 "Setting the SFX7101 LED to blink on traffic\n");
3451 bnx2x_cl45_write(bp, params->port,
3452 ext_phy_type,
3453 ext_phy_addr,
3454 MDIO_PMA_DEVAD,
3455 MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
3457 bnx2x_ext_phy_set_pause(params, vars);
3458 /* Restart autoneg */
3459 bnx2x_cl45_read(bp, params->port,
3460 ext_phy_type,
3461 ext_phy_addr,
3462 MDIO_AN_DEVAD,
3463 MDIO_AN_REG_CTRL, &val);
3464 val |= 0x200;
3465 bnx2x_cl45_write(bp, params->port,
3466 ext_phy_type,
3467 ext_phy_addr,
3468 MDIO_AN_DEVAD,
3469 MDIO_AN_REG_CTRL, val);
3471 /* Save spirom version */
3472 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3473 ext_phy_addr, MDIO_PMA_DEVAD,
3474 MDIO_PMA_REG_7101_VER1, &fw_ver1);
3476 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3477 ext_phy_addr, MDIO_PMA_DEVAD,
3478 MDIO_PMA_REG_7101_VER2, &fw_ver2);
3480 bnx2x_save_spirom_version(params->bp, params->port,
3481 params->shmem_base,
3482 (u32)(fw_ver1<<16 | fw_ver2));
3484 break;
3486 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
3487 DP(NETIF_MSG_LINK,
3488 "Setting the BCM8481 LASI control\n");
3490 bnx2x_cl45_write(bp, params->port,
3491 ext_phy_type,
3492 ext_phy_addr,
3493 MDIO_PMA_DEVAD,
3494 MDIO_PMA_REG_LASI_CTRL, 0x1);
3496 /* Restart autoneg */
3497 bnx2x_cl45_read(bp, params->port,
3498 ext_phy_type,
3499 ext_phy_addr,
3500 MDIO_AN_DEVAD,
3501 MDIO_AN_REG_CTRL, &val);
3502 val |= 0x200;
3503 bnx2x_cl45_write(bp, params->port,
3504 ext_phy_type,
3505 ext_phy_addr,
3506 MDIO_AN_DEVAD,
3507 MDIO_AN_REG_CTRL, val);
3509 bnx2x_save_bcm_spirom_ver(bp, params->port,
3510 ext_phy_type,
3511 ext_phy_addr,
3512 params->shmem_base);
3514 break;
3515 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
3516 DP(NETIF_MSG_LINK,
3517 "XGXS PHY Failure detected 0x%x\n",
3518 params->ext_phy_config);
3519 rc = -EINVAL;
3520 break;
3521 default:
3522 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3523 params->ext_phy_config);
3524 rc = -EINVAL;
3525 break;
3528 } else { /* SerDes */
3530 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3531 switch (ext_phy_type) {
3532 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3533 DP(NETIF_MSG_LINK, "SerDes Direct\n");
3534 break;
3536 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3537 DP(NETIF_MSG_LINK, "SerDes 5482\n");
3538 break;
3540 default:
3541 DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
3542 params->ext_phy_config);
3543 break;
3546 return rc;
3550 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
3551 struct link_vars *vars)
3553 struct bnx2x *bp = params->bp;
3554 u32 ext_phy_type;
3555 u8 ext_phy_addr;
3556 u16 val1 = 0, val2;
3557 u16 rx_sd, pcs_status;
3558 u8 ext_phy_link_up = 0;
3559 u8 port = params->port;
3560 if (vars->phy_flags & PHY_XGXS_FLAG) {
3561 ext_phy_addr = ((params->ext_phy_config &
3562 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3563 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3565 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3566 switch (ext_phy_type) {
3567 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3568 DP(NETIF_MSG_LINK, "XGXS Direct\n");
3569 ext_phy_link_up = 1;
3570 break;
3572 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3573 DP(NETIF_MSG_LINK, "XGXS 8705\n");
3574 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3575 ext_phy_addr,
3576 MDIO_WIS_DEVAD,
3577 MDIO_WIS_REG_LASI_STATUS, &val1);
3578 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3580 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3581 ext_phy_addr,
3582 MDIO_WIS_DEVAD,
3583 MDIO_WIS_REG_LASI_STATUS, &val1);
3584 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3586 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3587 ext_phy_addr,
3588 MDIO_PMA_DEVAD,
3589 MDIO_PMA_REG_RX_SD, &rx_sd);
3590 DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
3591 ext_phy_link_up = (rx_sd & 0x1);
3592 if (ext_phy_link_up)
3593 vars->line_speed = SPEED_10000;
3594 break;
3596 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3597 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3598 DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
3599 /* Clear RX Alarm*/
3600 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3601 ext_phy_addr,
3602 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
3603 &val2);
3604 /* clear LASI indication*/
3605 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3606 ext_phy_addr,
3607 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
3608 &val1);
3609 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3610 ext_phy_addr,
3611 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
3612 &val2);
3613 DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
3614 "0x%x\n", val1, val2);
3616 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3617 ext_phy_addr,
3618 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
3619 &rx_sd);
3620 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3621 ext_phy_addr,
3622 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
3623 &pcs_status);
3624 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3625 ext_phy_addr,
3626 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
3627 &val2);
3628 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3629 ext_phy_addr,
3630 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
3631 &val2);
3633 DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
3634 " pcs_status 0x%x 1Gbps link_status 0x%x\n",
3635 rx_sd, pcs_status, val2);
3636 /* link is up if both bit 0 of pmd_rx_sd and
3637 * bit 0 of pcs_status are set, or if the autoneg bit
3638 1 is set
3640 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
3641 (val2 & (1<<1)));
3642 if (ext_phy_link_up) {
3643 if (ext_phy_type ==
3644 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
3645 /* If transmitter is disabled,
3646 ignore false link up indication */
3647 bnx2x_cl45_read(bp, params->port,
3648 ext_phy_type,
3649 ext_phy_addr,
3650 MDIO_PMA_DEVAD,
3651 MDIO_PMA_REG_PHY_IDENTIFIER,
3652 &val1);
3653 if (val1 & (1<<15)) {
3654 DP(NETIF_MSG_LINK, "Tx is "
3655 "disabled\n");
3656 ext_phy_link_up = 0;
3657 break;
3661 if (val2 & (1<<1))
3662 vars->line_speed = SPEED_1000;
3663 else
3664 vars->line_speed = SPEED_10000;
3667 break;
3668 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3669 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3671 u16 link_status = 0;
3672 u16 an1000_status = 0;
3673 if (ext_phy_type ==
3674 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3675 bnx2x_cl45_read(bp, params->port,
3676 ext_phy_type,
3677 ext_phy_addr,
3678 MDIO_PCS_DEVAD,
3679 MDIO_PCS_REG_LASI_STATUS, &val1);
3680 bnx2x_cl45_read(bp, params->port,
3681 ext_phy_type,
3682 ext_phy_addr,
3683 MDIO_PCS_DEVAD,
3684 MDIO_PCS_REG_LASI_STATUS, &val2);
3685 DP(NETIF_MSG_LINK,
3686 "870x LASI status 0x%x->0x%x\n",
3687 val1, val2);
3689 } else {
3690 /* In 8073, port1 is directed through emac0 and
3691 * port0 is directed through emac1
3693 bnx2x_cl45_read(bp, params->port,
3694 ext_phy_type,
3695 ext_phy_addr,
3696 MDIO_PMA_DEVAD,
3697 MDIO_PMA_REG_LASI_STATUS, &val1);
3699 DP(NETIF_MSG_LINK,
3700 "8703 LASI status 0x%x\n",
3701 val1);
3704 /* clear the interrupt LASI status register */
3705 bnx2x_cl45_read(bp, params->port,
3706 ext_phy_type,
3707 ext_phy_addr,
3708 MDIO_PCS_DEVAD,
3709 MDIO_PCS_REG_STATUS, &val2);
3710 bnx2x_cl45_read(bp, params->port,
3711 ext_phy_type,
3712 ext_phy_addr,
3713 MDIO_PCS_DEVAD,
3714 MDIO_PCS_REG_STATUS, &val1);
3715 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
3716 val2, val1);
3717 /* Clear MSG-OUT */
3718 bnx2x_cl45_read(bp, params->port,
3719 ext_phy_type,
3720 ext_phy_addr,
3721 MDIO_PMA_DEVAD,
3722 0xca13,
3723 &val1);
3725 /* Check the LASI */
3726 bnx2x_cl45_read(bp, params->port,
3727 ext_phy_type,
3728 ext_phy_addr,
3729 MDIO_PMA_DEVAD,
3730 MDIO_PMA_REG_RX_ALARM, &val2);
3732 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
3734 /* Check the link status */
3735 bnx2x_cl45_read(bp, params->port,
3736 ext_phy_type,
3737 ext_phy_addr,
3738 MDIO_PCS_DEVAD,
3739 MDIO_PCS_REG_STATUS, &val2);
3740 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
3742 bnx2x_cl45_read(bp, params->port,
3743 ext_phy_type,
3744 ext_phy_addr,
3745 MDIO_PMA_DEVAD,
3746 MDIO_PMA_REG_STATUS, &val2);
3747 bnx2x_cl45_read(bp, params->port,
3748 ext_phy_type,
3749 ext_phy_addr,
3750 MDIO_PMA_DEVAD,
3751 MDIO_PMA_REG_STATUS, &val1);
3752 ext_phy_link_up = ((val1 & 4) == 4);
3753 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
3754 if (ext_phy_type ==
3755 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3757 if (ext_phy_link_up &&
3758 ((params->req_line_speed !=
3759 SPEED_10000))) {
3760 if (bnx2x_bcm8073_xaui_wa(params)
3761 != 0) {
3762 ext_phy_link_up = 0;
3763 break;
3766 bnx2x_cl45_read(bp, params->port,
3767 ext_phy_type,
3768 ext_phy_addr,
3769 MDIO_AN_DEVAD,
3770 0x8304,
3771 &an1000_status);
3772 bnx2x_cl45_read(bp, params->port,
3773 ext_phy_type,
3774 ext_phy_addr,
3775 MDIO_AN_DEVAD,
3776 0x8304,
3777 &an1000_status);
3779 /* Check the link status on 1.1.2 */
3780 bnx2x_cl45_read(bp, params->port,
3781 ext_phy_type,
3782 ext_phy_addr,
3783 MDIO_PMA_DEVAD,
3784 MDIO_PMA_REG_STATUS, &val2);
3785 bnx2x_cl45_read(bp, params->port,
3786 ext_phy_type,
3787 ext_phy_addr,
3788 MDIO_PMA_DEVAD,
3789 MDIO_PMA_REG_STATUS, &val1);
3790 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3791 "an_link_status=0x%x\n",
3792 val2, val1, an1000_status);
3794 ext_phy_link_up = (((val1 & 4) == 4) ||
3795 (an1000_status & (1<<1)));
3796 if (ext_phy_link_up &&
3797 bnx2x_8073_is_snr_needed(params)) {
3798 /* The SNR will improve about 2dbby
3799 changing the BW and FEE main tap.*/
3801 /* The 1st write to change FFE main
3802 tap is set before restart AN */
3803 /* Change PLL Bandwidth in EDC
3804 register */
3805 bnx2x_cl45_write(bp, port, ext_phy_type,
3806 ext_phy_addr,
3807 MDIO_PMA_DEVAD,
3808 MDIO_PMA_REG_PLL_BANDWIDTH,
3809 0x26BC);
3811 /* Change CDR Bandwidth in EDC
3812 register */
3813 bnx2x_cl45_write(bp, port, ext_phy_type,
3814 ext_phy_addr,
3815 MDIO_PMA_DEVAD,
3816 MDIO_PMA_REG_CDR_BANDWIDTH,
3817 0x0333);
3821 bnx2x_cl45_read(bp, params->port,
3822 ext_phy_type,
3823 ext_phy_addr,
3824 MDIO_PMA_DEVAD,
3825 0xc820,
3826 &link_status);
3828 /* Bits 0..2 --> speed detected,
3829 bits 13..15--> link is down */
3830 if ((link_status & (1<<2)) &&
3831 (!(link_status & (1<<15)))) {
3832 ext_phy_link_up = 1;
3833 vars->line_speed = SPEED_10000;
3834 DP(NETIF_MSG_LINK,
3835 "port %x: External link"
3836 " up in 10G\n", params->port);
3837 } else if ((link_status & (1<<1)) &&
3838 (!(link_status & (1<<14)))) {
3839 ext_phy_link_up = 1;
3840 vars->line_speed = SPEED_2500;
3841 DP(NETIF_MSG_LINK,
3842 "port %x: External link"
3843 " up in 2.5G\n", params->port);
3844 } else if ((link_status & (1<<0)) &&
3845 (!(link_status & (1<<13)))) {
3846 ext_phy_link_up = 1;
3847 vars->line_speed = SPEED_1000;
3848 DP(NETIF_MSG_LINK,
3849 "port %x: External link"
3850 " up in 1G\n", params->port);
3851 } else {
3852 ext_phy_link_up = 0;
3853 DP(NETIF_MSG_LINK,
3854 "port %x: External link"
3855 " is down\n", params->port);
3857 } else {
3858 /* See if 1G link is up for the 8072 */
3859 bnx2x_cl45_read(bp, params->port,
3860 ext_phy_type,
3861 ext_phy_addr,
3862 MDIO_AN_DEVAD,
3863 0x8304,
3864 &an1000_status);
3865 bnx2x_cl45_read(bp, params->port,
3866 ext_phy_type,
3867 ext_phy_addr,
3868 MDIO_AN_DEVAD,
3869 0x8304,
3870 &an1000_status);
3871 if (an1000_status & (1<<1)) {
3872 ext_phy_link_up = 1;
3873 vars->line_speed = SPEED_1000;
3874 DP(NETIF_MSG_LINK,
3875 "port %x: External link"
3876 " up in 1G\n", params->port);
3877 } else if (ext_phy_link_up) {
3878 ext_phy_link_up = 1;
3879 vars->line_speed = SPEED_10000;
3880 DP(NETIF_MSG_LINK,
3881 "port %x: External link"
3882 " up in 10G\n", params->port);
3887 break;
3889 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3890 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3891 ext_phy_addr,
3892 MDIO_PMA_DEVAD,
3893 MDIO_PMA_REG_LASI_STATUS, &val2);
3894 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3895 ext_phy_addr,
3896 MDIO_PMA_DEVAD,
3897 MDIO_PMA_REG_LASI_STATUS, &val1);
3898 DP(NETIF_MSG_LINK,
3899 "10G-base-T LASI status 0x%x->0x%x\n",
3900 val2, val1);
3901 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3902 ext_phy_addr,
3903 MDIO_PMA_DEVAD,
3904 MDIO_PMA_REG_STATUS, &val2);
3905 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3906 ext_phy_addr,
3907 MDIO_PMA_DEVAD,
3908 MDIO_PMA_REG_STATUS, &val1);
3909 DP(NETIF_MSG_LINK,
3910 "10G-base-T PMA status 0x%x->0x%x\n",
3911 val2, val1);
3912 ext_phy_link_up = ((val1 & 4) == 4);
3913 /* if link is up
3914 * print the AN outcome of the SFX7101 PHY
3916 if (ext_phy_link_up) {
3917 bnx2x_cl45_read(bp, params->port,
3918 ext_phy_type,
3919 ext_phy_addr,
3920 MDIO_AN_DEVAD,
3921 MDIO_AN_REG_MASTER_STATUS,
3922 &val2);
3923 vars->line_speed = SPEED_10000;
3924 DP(NETIF_MSG_LINK,
3925 "SFX7101 AN status 0x%x->Master=%x\n",
3926 val2,
3927 (val2 & (1<<14)));
3929 break;
3930 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
3931 /* Clear LASI interrupt */
3932 bnx2x_cl45_read(bp, params->port,
3933 ext_phy_type,
3934 ext_phy_addr,
3935 MDIO_PMA_DEVAD,
3936 MDIO_PMA_REG_LASI_STATUS, &val1);
3937 DP(NETIF_MSG_LINK, "8481 LASI status reg = 0x%x\n",
3938 val1);
3940 /* Check 10G-BaseT link status */
3941 /* Check Global PMD signal ok */
3942 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3943 ext_phy_addr,
3944 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
3945 &rx_sd);
3946 /* Check PCS block lock */
3947 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3948 ext_phy_addr,
3949 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
3950 &pcs_status);
3951 DP(NETIF_MSG_LINK, "8481 1.a = 0x%x, 1.20 = 0x%x\n",
3952 rx_sd, pcs_status);
3953 if (rx_sd & pcs_status & 0x1) {
3954 vars->line_speed = SPEED_10000;
3955 ext_phy_link_up = 1;
3956 } else {
3958 /* Check 1000-BaseT link status */
3959 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3960 ext_phy_addr,
3961 MDIO_AN_DEVAD, 0xFFE1,
3962 &val1);
3964 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3965 ext_phy_addr,
3966 MDIO_AN_DEVAD, 0xFFE1,
3967 &val2);
3968 DP(NETIF_MSG_LINK, "8481 7.FFE1 ="
3969 "0x%x-->0x%x\n", val1, val2);
3970 if (val2 & (1<<2)) {
3971 vars->line_speed = SPEED_1000;
3972 ext_phy_link_up = 1;
3976 break;
3977 default:
3978 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3979 params->ext_phy_config);
3980 ext_phy_link_up = 0;
3981 break;
3984 } else { /* SerDes */
3985 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3986 switch (ext_phy_type) {
3987 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3988 DP(NETIF_MSG_LINK, "SerDes Direct\n");
3989 ext_phy_link_up = 1;
3990 break;
3992 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3993 DP(NETIF_MSG_LINK, "SerDes 5482\n");
3994 ext_phy_link_up = 1;
3995 break;
3997 default:
3998 DP(NETIF_MSG_LINK,
3999 "BAD SerDes ext_phy_config 0x%x\n",
4000 params->ext_phy_config);
4001 ext_phy_link_up = 0;
4002 break;
4006 return ext_phy_link_up;
4009 static void bnx2x_link_int_enable(struct link_params *params)
4011 u8 port = params->port;
4012 u32 ext_phy_type;
4013 u32 mask;
4014 struct bnx2x *bp = params->bp;
4015 /* setting the status to report on link up
4016 for either XGXS or SerDes */
4018 if (params->switch_cfg == SWITCH_CFG_10G) {
4019 mask = (NIG_MASK_XGXS0_LINK10G |
4020 NIG_MASK_XGXS0_LINK_STATUS);
4021 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
4022 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4023 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
4024 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
4025 (ext_phy_type !=
4026 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
4027 mask |= NIG_MASK_MI_INT;
4028 DP(NETIF_MSG_LINK, "enabled external phy int\n");
4031 } else { /* SerDes */
4032 mask = NIG_MASK_SERDES0_LINK_STATUS;
4033 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
4034 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4035 if ((ext_phy_type !=
4036 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4037 (ext_phy_type !=
4038 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
4039 mask |= NIG_MASK_MI_INT;
4040 DP(NETIF_MSG_LINK, "enabled external phy int\n");
4043 bnx2x_bits_en(bp,
4044 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4045 mask);
4046 DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
4047 (params->switch_cfg == SWITCH_CFG_10G),
4048 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4050 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
4051 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4052 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4053 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
4054 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4055 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4056 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4061 * link management
4063 static void bnx2x_link_int_ack(struct link_params *params,
4064 struct link_vars *vars, u8 is_10g)
4066 struct bnx2x *bp = params->bp;
4067 u8 port = params->port;
4069 /* first reset all status
4070 * we assume only one line will be change at a time */
4071 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4072 (NIG_STATUS_XGXS0_LINK10G |
4073 NIG_STATUS_XGXS0_LINK_STATUS |
4074 NIG_STATUS_SERDES0_LINK_STATUS));
4075 if (vars->phy_link_up) {
4076 if (is_10g) {
4077 /* Disable the 10G link interrupt
4078 * by writing 1 to the status register
4080 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
4081 bnx2x_bits_en(bp,
4082 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4083 NIG_STATUS_XGXS0_LINK10G);
4085 } else if (params->switch_cfg == SWITCH_CFG_10G) {
4086 /* Disable the link interrupt
4087 * by writing 1 to the relevant lane
4088 * in the status register
4090 u32 ser_lane = ((params->lane_config &
4091 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4092 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4094 DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
4095 bnx2x_bits_en(bp,
4096 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4097 ((1 << ser_lane) <<
4098 NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
4100 } else { /* SerDes */
4101 DP(NETIF_MSG_LINK, "SerDes phy link up\n");
4102 /* Disable the link interrupt
4103 * by writing 1 to the status register
4105 bnx2x_bits_en(bp,
4106 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4107 NIG_STATUS_SERDES0_LINK_STATUS);
4110 } else { /* link_down */
4114 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
4116 u8 *str_ptr = str;
4117 u32 mask = 0xf0000000;
4118 u8 shift = 8*4;
4119 u8 digit;
4120 if (len < 10) {
4121 /* Need more than 10chars for this format */
4122 *str_ptr = '\0';
4123 return -EINVAL;
4125 while (shift > 0) {
4127 shift -= 4;
4128 digit = ((num & mask) >> shift);
4129 if (digit < 0xa)
4130 *str_ptr = digit + '0';
4131 else
4132 *str_ptr = digit - 0xa + 'a';
4133 str_ptr++;
4134 mask = mask >> 4;
4135 if (shift == 4*4) {
4136 *str_ptr = ':';
4137 str_ptr++;
4140 *str_ptr = '\0';
4141 return 0;
4145 static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
4146 u32 ext_phy_type)
4148 u32 cnt = 0;
4149 u16 ctrl = 0;
4150 /* Enable EMAC0 in to enable MDIO */
4151 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
4152 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
4153 msleep(5);
4155 /* take ext phy out of reset */
4156 bnx2x_set_gpio(bp,
4157 MISC_REGISTERS_GPIO_2,
4158 MISC_REGISTERS_GPIO_HIGH,
4159 port);
4161 bnx2x_set_gpio(bp,
4162 MISC_REGISTERS_GPIO_1,
4163 MISC_REGISTERS_GPIO_HIGH,
4164 port);
4166 /* wait for 5ms */
4167 msleep(5);
4169 for (cnt = 0; cnt < 1000; cnt++) {
4170 msleep(1);
4171 bnx2x_cl45_read(bp, port,
4172 ext_phy_type,
4173 ext_phy_addr,
4174 MDIO_PMA_DEVAD,
4175 MDIO_PMA_REG_CTRL,
4176 &ctrl);
4177 if (!(ctrl & (1<<15))) {
4178 DP(NETIF_MSG_LINK, "Reset completed\n\n");
4179 break;
4184 static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
4186 /* put sf to reset */
4187 bnx2x_set_gpio(bp,
4188 MISC_REGISTERS_GPIO_1,
4189 MISC_REGISTERS_GPIO_LOW,
4190 port);
4191 bnx2x_set_gpio(bp,
4192 MISC_REGISTERS_GPIO_2,
4193 MISC_REGISTERS_GPIO_LOW,
4194 port);
4197 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
4198 u8 *version, u16 len)
4200 struct bnx2x *bp = params->bp;
4201 u32 ext_phy_type = 0;
4202 u32 spirom_ver = 0;
4203 u8 status = 0 ;
4205 if (version == NULL || params == NULL)
4206 return -EINVAL;
4208 spirom_ver = REG_RD(bp, params->shmem_base +
4209 offsetof(struct shmem_region,
4210 port_mb[params->port].ext_phy_fw_version));
4212 /* reset the returned value to zero */
4213 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4214 switch (ext_phy_type) {
4215 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4217 if (len < 5)
4218 return -EINVAL;
4220 version[0] = (spirom_ver & 0xFF);
4221 version[1] = (spirom_ver & 0xFF00) >> 8;
4222 version[2] = (spirom_ver & 0xFF0000) >> 16;
4223 version[3] = (spirom_ver & 0xFF000000) >> 24;
4224 version[4] = '\0';
4226 break;
4227 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4228 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4229 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4230 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4231 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4232 status = bnx2x_format_ver(spirom_ver, version, len);
4233 break;
4234 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4235 break;
4237 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4238 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
4239 " type is FAILURE!\n");
4240 status = -EINVAL;
4241 break;
4243 default:
4244 break;
4246 return status;
4249 static void bnx2x_set_xgxs_loopback(struct link_params *params,
4250 struct link_vars *vars,
4251 u8 is_10g)
4253 u8 port = params->port;
4254 struct bnx2x *bp = params->bp;
4256 if (is_10g) {
4257 u32 md_devad;
4259 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
4261 /* change the uni_phy_addr in the nig */
4262 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
4263 port*0x18));
4265 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
4267 bnx2x_cl45_write(bp, port, 0,
4268 params->phy_addr,
4270 (MDIO_REG_BANK_AER_BLOCK +
4271 (MDIO_AER_BLOCK_AER_REG & 0xf)),
4272 0x2800);
4274 bnx2x_cl45_write(bp, port, 0,
4275 params->phy_addr,
4277 (MDIO_REG_BANK_CL73_IEEEB0 +
4278 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
4279 0x6041);
4280 msleep(200);
4281 /* set aer mmd back */
4282 bnx2x_set_aer_mmd(params, vars);
4284 /* and md_devad */
4285 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
4286 md_devad);
4288 } else {
4289 u16 mii_control;
4291 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
4293 CL45_RD_OVER_CL22(bp, port,
4294 params->phy_addr,
4295 MDIO_REG_BANK_COMBO_IEEE0,
4296 MDIO_COMBO_IEEE0_MII_CONTROL,
4297 &mii_control);
4299 CL45_WR_OVER_CL22(bp, port,
4300 params->phy_addr,
4301 MDIO_REG_BANK_COMBO_IEEE0,
4302 MDIO_COMBO_IEEE0_MII_CONTROL,
4303 (mii_control |
4304 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
4309 static void bnx2x_ext_phy_loopback(struct link_params *params)
4311 struct bnx2x *bp = params->bp;
4312 u8 ext_phy_addr;
4313 u32 ext_phy_type;
4315 if (params->switch_cfg == SWITCH_CFG_10G) {
4316 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4317 /* CL37 Autoneg Enabled */
4318 ext_phy_addr = ((params->ext_phy_config &
4319 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4320 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4321 switch (ext_phy_type) {
4322 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4323 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4324 DP(NETIF_MSG_LINK,
4325 "ext_phy_loopback: We should not get here\n");
4326 break;
4327 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4328 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
4329 break;
4330 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4331 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
4332 break;
4333 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4334 DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
4335 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4336 ext_phy_addr,
4337 MDIO_PMA_DEVAD,
4338 MDIO_PMA_REG_CTRL,
4339 0x0001);
4340 break;
4341 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4342 /* SFX7101_XGXS_TEST1 */
4343 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4344 ext_phy_addr,
4345 MDIO_XS_DEVAD,
4346 MDIO_XS_SFX7101_XGXS_TEST1,
4347 0x100);
4348 DP(NETIF_MSG_LINK,
4349 "ext_phy_loopback: set ext phy loopback\n");
4350 break;
4351 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4353 break;
4354 } /* switch external PHY type */
4355 } else {
4356 /* serdes */
4357 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4358 ext_phy_addr = (params->ext_phy_config &
4359 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
4360 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
4366 *------------------------------------------------------------------------
4367 * bnx2x_override_led_value -
4369 * Override the led value of the requsted led
4371 *------------------------------------------------------------------------
4373 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
4374 u32 led_idx, u32 value)
4376 u32 reg_val;
4378 /* If port 0 then use EMAC0, else use EMAC1*/
4379 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4381 DP(NETIF_MSG_LINK,
4382 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
4383 port, led_idx, value);
4385 switch (led_idx) {
4386 case 0: /* 10MB led */
4387 /* Read the current value of the LED register in
4388 the EMAC block */
4389 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4390 /* Set the OVERRIDE bit to 1 */
4391 reg_val |= EMAC_LED_OVERRIDE;
4392 /* If value is 1, set the 10M_OVERRIDE bit,
4393 otherwise reset it.*/
4394 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
4395 (reg_val & ~EMAC_LED_10MB_OVERRIDE);
4396 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4397 break;
4398 case 1: /*100MB led */
4399 /*Read the current value of the LED register in
4400 the EMAC block */
4401 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4402 /* Set the OVERRIDE bit to 1 */
4403 reg_val |= EMAC_LED_OVERRIDE;
4404 /* If value is 1, set the 100M_OVERRIDE bit,
4405 otherwise reset it.*/
4406 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
4407 (reg_val & ~EMAC_LED_100MB_OVERRIDE);
4408 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4409 break;
4410 case 2: /* 1000MB led */
4411 /* Read the current value of the LED register in the
4412 EMAC block */
4413 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4414 /* Set the OVERRIDE bit to 1 */
4415 reg_val |= EMAC_LED_OVERRIDE;
4416 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
4417 reset it. */
4418 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
4419 (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
4420 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4421 break;
4422 case 3: /* 2500MB led */
4423 /* Read the current value of the LED register in the
4424 EMAC block*/
4425 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4426 /* Set the OVERRIDE bit to 1 */
4427 reg_val |= EMAC_LED_OVERRIDE;
4428 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
4429 reset it.*/
4430 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
4431 (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
4432 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4433 break;
4434 case 4: /*10G led */
4435 if (port == 0) {
4436 REG_WR(bp, NIG_REG_LED_10G_P0,
4437 value);
4438 } else {
4439 REG_WR(bp, NIG_REG_LED_10G_P1,
4440 value);
4442 break;
4443 case 5: /* TRAFFIC led */
4444 /* Find if the traffic control is via BMAC or EMAC */
4445 if (port == 0)
4446 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
4447 else
4448 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
4450 /* Override the traffic led in the EMAC:*/
4451 if (reg_val == 1) {
4452 /* Read the current value of the LED register in
4453 the EMAC block */
4454 reg_val = REG_RD(bp, emac_base +
4455 EMAC_REG_EMAC_LED);
4456 /* Set the TRAFFIC_OVERRIDE bit to 1 */
4457 reg_val |= EMAC_LED_OVERRIDE;
4458 /* If value is 1, set the TRAFFIC bit, otherwise
4459 reset it.*/
4460 reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
4461 (reg_val & ~EMAC_LED_TRAFFIC);
4462 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4463 } else { /* Override the traffic led in the BMAC: */
4464 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4465 + port*4, 1);
4466 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
4467 value);
4469 break;
4470 default:
4471 DP(NETIF_MSG_LINK,
4472 "bnx2x_override_led_value() unknown led index %d "
4473 "(should be 0-5)\n", led_idx);
4474 return -EINVAL;
4477 return 0;
4481 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
4482 u16 hw_led_mode, u32 chip_id)
4484 u8 rc = 0;
4485 u32 tmp;
4486 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4487 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
4488 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
4489 speed, hw_led_mode);
4490 switch (mode) {
4491 case LED_MODE_OFF:
4492 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
4493 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
4494 SHARED_HW_CFG_LED_MAC1);
4496 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4497 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
4498 break;
4500 case LED_MODE_OPER:
4501 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
4502 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
4503 port*4, 0);
4504 /* Set blinking rate to ~15.9Hz */
4505 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
4506 LED_BLINK_RATE_VAL);
4507 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
4508 port*4, 1);
4509 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4510 EMAC_WR(bp, EMAC_REG_EMAC_LED,
4511 (tmp & (~EMAC_LED_OVERRIDE)));
4513 if (!CHIP_IS_E1H(bp) &&
4514 ((speed == SPEED_2500) ||
4515 (speed == SPEED_1000) ||
4516 (speed == SPEED_100) ||
4517 (speed == SPEED_10))) {
4518 /* On Everest 1 Ax chip versions for speeds less than
4519 10G LED scheme is different */
4520 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4521 + port*4, 1);
4522 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
4523 port*4, 0);
4524 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
4525 port*4, 1);
4527 break;
4529 default:
4530 rc = -EINVAL;
4531 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
4532 mode);
4533 break;
4535 return rc;
4539 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
4541 struct bnx2x *bp = params->bp;
4542 u16 gp_status = 0;
4544 CL45_RD_OVER_CL22(bp, params->port,
4545 params->phy_addr,
4546 MDIO_REG_BANK_GP_STATUS,
4547 MDIO_GP_STATUS_TOP_AN_STATUS1,
4548 &gp_status);
4549 /* link is up only if both local phy and external phy are up */
4550 if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
4551 bnx2x_ext_phy_is_link_up(params, vars))
4552 return 0;
4554 return -ESRCH;
4557 static u8 bnx2x_link_initialize(struct link_params *params,
4558 struct link_vars *vars)
4560 struct bnx2x *bp = params->bp;
4561 u8 port = params->port;
4562 u8 rc = 0;
4563 u8 non_ext_phy;
4564 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4565 /* Activate the external PHY */
4566 bnx2x_ext_phy_reset(params, vars);
4568 bnx2x_set_aer_mmd(params, vars);
4570 if (vars->phy_flags & PHY_XGXS_FLAG)
4571 bnx2x_set_master_ln(params);
4573 rc = bnx2x_reset_unicore(params);
4574 /* reset the SerDes and wait for reset bit return low */
4575 if (rc != 0)
4576 return rc;
4578 bnx2x_set_aer_mmd(params, vars);
4580 /* setting the masterLn_def again after the reset */
4581 if (vars->phy_flags & PHY_XGXS_FLAG) {
4582 bnx2x_set_master_ln(params);
4583 bnx2x_set_swap_lanes(params);
4586 if (vars->phy_flags & PHY_XGXS_FLAG) {
4587 if ((params->req_line_speed &&
4588 ((params->req_line_speed == SPEED_100) ||
4589 (params->req_line_speed == SPEED_10))) ||
4590 (!params->req_line_speed &&
4591 (params->speed_cap_mask >=
4592 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
4593 (params->speed_cap_mask <
4594 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4595 )) {
4596 vars->phy_flags |= PHY_SGMII_FLAG;
4597 } else {
4598 vars->phy_flags &= ~PHY_SGMII_FLAG;
4601 /* In case of external phy existance, the line speed would be the
4602 line speed linked up by the external phy. In case it is direct only,
4603 then the line_speed during initialization will be equal to the
4604 req_line_speed*/
4605 vars->line_speed = params->req_line_speed;
4607 bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
4609 /* init ext phy and enable link state int */
4610 non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
4611 (params->loopback_mode == LOOPBACK_XGXS_10) ||
4612 (params->loopback_mode == LOOPBACK_EXT_PHY));
4614 if (non_ext_phy ||
4615 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
4616 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
4617 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481)) {
4618 if (params->req_line_speed == SPEED_AUTO_NEG)
4619 bnx2x_set_parallel_detection(params, vars->phy_flags);
4620 bnx2x_init_internal_phy(params, vars);
4623 if (!non_ext_phy)
4624 rc |= bnx2x_ext_phy_init(params, vars);
4626 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4627 (NIG_STATUS_XGXS0_LINK10G |
4628 NIG_STATUS_XGXS0_LINK_STATUS |
4629 NIG_STATUS_SERDES0_LINK_STATUS));
4631 return rc;
4636 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
4638 struct bnx2x *bp = params->bp;
4640 u32 val;
4641 DP(NETIF_MSG_LINK, "Phy Initialization started \n");
4642 DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
4643 params->req_line_speed, params->req_flow_ctrl);
4644 vars->link_status = 0;
4645 vars->phy_link_up = 0;
4646 vars->link_up = 0;
4647 vars->line_speed = 0;
4648 vars->duplex = DUPLEX_FULL;
4649 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4650 vars->mac_type = MAC_TYPE_NONE;
4652 if (params->switch_cfg == SWITCH_CFG_1G)
4653 vars->phy_flags = PHY_SERDES_FLAG;
4654 else
4655 vars->phy_flags = PHY_XGXS_FLAG;
4658 /* disable attentions */
4659 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
4660 (NIG_MASK_XGXS0_LINK_STATUS |
4661 NIG_MASK_XGXS0_LINK10G |
4662 NIG_MASK_SERDES0_LINK_STATUS |
4663 NIG_MASK_MI_INT));
4665 bnx2x_emac_init(params, vars);
4667 if (CHIP_REV_IS_FPGA(bp)) {
4668 vars->link_up = 1;
4669 vars->line_speed = SPEED_10000;
4670 vars->duplex = DUPLEX_FULL;
4671 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4672 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
4673 /* enable on E1.5 FPGA */
4674 if (CHIP_IS_E1H(bp)) {
4675 vars->flow_ctrl |=
4676 (BNX2X_FLOW_CTRL_TX | BNX2X_FLOW_CTRL_RX);
4677 vars->link_status |=
4678 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
4679 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
4682 bnx2x_emac_enable(params, vars, 0);
4683 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4684 /* disable drain */
4685 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4686 + params->port*4, 0);
4688 /* update shared memory */
4689 bnx2x_update_mng(params, vars->link_status);
4691 return 0;
4693 } else
4694 if (CHIP_REV_IS_EMUL(bp)) {
4696 vars->link_up = 1;
4697 vars->line_speed = SPEED_10000;
4698 vars->duplex = DUPLEX_FULL;
4699 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4700 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
4702 bnx2x_bmac_enable(params, vars, 0);
4704 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4705 /* Disable drain */
4706 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4707 + params->port*4, 0);
4709 /* update shared memory */
4710 bnx2x_update_mng(params, vars->link_status);
4712 return 0;
4714 } else
4715 if (params->loopback_mode == LOOPBACK_BMAC) {
4716 vars->link_up = 1;
4717 vars->line_speed = SPEED_10000;
4718 vars->duplex = DUPLEX_FULL;
4719 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4720 vars->mac_type = MAC_TYPE_BMAC;
4722 vars->phy_flags = PHY_XGXS_FLAG;
4724 bnx2x_phy_deassert(params, vars->phy_flags);
4725 /* set bmac loopback */
4726 bnx2x_bmac_enable(params, vars, 1);
4728 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4729 params->port*4, 0);
4730 } else if (params->loopback_mode == LOOPBACK_EMAC) {
4731 vars->link_up = 1;
4732 vars->line_speed = SPEED_1000;
4733 vars->duplex = DUPLEX_FULL;
4734 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4735 vars->mac_type = MAC_TYPE_EMAC;
4737 vars->phy_flags = PHY_XGXS_FLAG;
4739 bnx2x_phy_deassert(params, vars->phy_flags);
4740 /* set bmac loopback */
4741 bnx2x_emac_enable(params, vars, 1);
4742 bnx2x_emac_program(params, vars->line_speed,
4743 vars->duplex);
4744 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4745 params->port*4, 0);
4746 } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
4747 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
4748 vars->link_up = 1;
4749 vars->line_speed = SPEED_10000;
4750 vars->duplex = DUPLEX_FULL;
4751 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4753 vars->phy_flags = PHY_XGXS_FLAG;
4755 val = REG_RD(bp,
4756 NIG_REG_XGXS0_CTRL_PHY_ADDR+
4757 params->port*0x18);
4758 params->phy_addr = (u8)val;
4760 bnx2x_phy_deassert(params, vars->phy_flags);
4761 bnx2x_link_initialize(params, vars);
4763 vars->mac_type = MAC_TYPE_BMAC;
4765 bnx2x_bmac_enable(params, vars, 0);
4767 if (params->loopback_mode == LOOPBACK_XGXS_10) {
4768 /* set 10G XGXS loopback */
4769 bnx2x_set_xgxs_loopback(params, vars, 1);
4770 } else {
4771 /* set external phy loopback */
4772 bnx2x_ext_phy_loopback(params);
4774 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4775 params->port*4, 0);
4776 } else
4777 /* No loopback */
4780 bnx2x_phy_deassert(params, vars->phy_flags);
4781 switch (params->switch_cfg) {
4782 case SWITCH_CFG_1G:
4783 vars->phy_flags |= PHY_SERDES_FLAG;
4784 if ((params->ext_phy_config &
4785 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
4786 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
4787 vars->phy_flags |=
4788 PHY_SGMII_FLAG;
4791 val = REG_RD(bp,
4792 NIG_REG_SERDES0_CTRL_PHY_ADDR+
4793 params->port*0x10);
4795 params->phy_addr = (u8)val;
4797 break;
4798 case SWITCH_CFG_10G:
4799 vars->phy_flags |= PHY_XGXS_FLAG;
4800 val = REG_RD(bp,
4801 NIG_REG_XGXS0_CTRL_PHY_ADDR+
4802 params->port*0x18);
4803 params->phy_addr = (u8)val;
4805 break;
4806 default:
4807 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
4808 return -EINVAL;
4809 break;
4812 bnx2x_link_initialize(params, vars);
4813 msleep(30);
4814 bnx2x_link_int_enable(params);
4816 return 0;
4819 static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
4821 DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
4823 /* Set serial boot control for external load */
4824 bnx2x_cl45_write(bp, port,
4825 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
4826 MDIO_PMA_DEVAD,
4827 MDIO_PMA_REG_GEN_CTRL, 0x0001);
4829 /* Disable Transmitter */
4830 bnx2x_bcm8726_set_transmitter(bp, port, ext_phy_addr, 0);
4834 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
4835 u8 reset_ext_phy)
4838 struct bnx2x *bp = params->bp;
4839 u32 ext_phy_config = params->ext_phy_config;
4840 u16 hw_led_mode = params->hw_led_mode;
4841 u32 chip_id = params->chip_id;
4842 u8 port = params->port;
4843 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4844 /* disable attentions */
4846 vars->link_status = 0;
4847 bnx2x_update_mng(params, vars->link_status);
4848 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4849 (NIG_MASK_XGXS0_LINK_STATUS |
4850 NIG_MASK_XGXS0_LINK10G |
4851 NIG_MASK_SERDES0_LINK_STATUS |
4852 NIG_MASK_MI_INT));
4854 /* activate nig drain */
4855 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4857 /* disable nig egress interface */
4858 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4859 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4861 /* Stop BigMac rx */
4862 bnx2x_bmac_rx_disable(bp, port);
4864 /* disable emac */
4865 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4867 msleep(10);
4868 /* The PHY reset is controled by GPIO 1
4869 * Hold it as vars low
4871 /* clear link led */
4872 bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4873 if (reset_ext_phy) {
4874 switch (ext_phy_type) {
4875 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4876 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4877 break;
4878 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4879 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4880 "low power mode\n",
4881 port);
4882 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4883 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4884 port);
4885 break;
4886 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4888 u8 ext_phy_addr = ((params->ext_phy_config &
4889 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4890 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4891 /* Set soft reset */
4892 bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
4893 break;
4895 default:
4896 /* HW reset */
4897 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4898 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4899 port);
4900 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4901 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4902 port);
4903 DP(NETIF_MSG_LINK, "reset external PHY\n");
4906 /* reset the SerDes/XGXS */
4907 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4908 (0x1ff << (port*16)));
4910 /* reset BigMac */
4911 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4912 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4914 /* disable nig ingress interface */
4915 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4916 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4917 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4918 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4919 vars->link_up = 0;
4920 return 0;
4923 static u8 bnx2x_update_link_down(struct link_params *params,
4924 struct link_vars *vars)
4926 struct bnx2x *bp = params->bp;
4927 u8 port = params->port;
4928 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4929 bnx2x_set_led(bp, port, LED_MODE_OFF,
4930 0, params->hw_led_mode,
4931 params->chip_id);
4933 /* indicate no mac active */
4934 vars->mac_type = MAC_TYPE_NONE;
4936 /* update shared memory */
4937 vars->link_status = 0;
4938 vars->line_speed = 0;
4939 bnx2x_update_mng(params, vars->link_status);
4941 /* activate nig drain */
4942 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4944 /* disable emac */
4945 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4947 msleep(10);
4949 /* reset BigMac */
4950 bnx2x_bmac_rx_disable(bp, params->port);
4951 REG_WR(bp, GRCBASE_MISC +
4952 MISC_REGISTERS_RESET_REG_2_CLEAR,
4953 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4954 return 0;
4957 static u8 bnx2x_update_link_up(struct link_params *params,
4958 struct link_vars *vars,
4959 u8 link_10g, u32 gp_status)
4961 struct bnx2x *bp = params->bp;
4962 u8 port = params->port;
4963 u8 rc = 0;
4964 vars->link_status |= LINK_STATUS_LINK_UP;
4965 if (link_10g) {
4966 bnx2x_bmac_enable(params, vars, 0);
4967 bnx2x_set_led(bp, port, LED_MODE_OPER,
4968 SPEED_10000, params->hw_led_mode,
4969 params->chip_id);
4971 } else {
4972 bnx2x_emac_enable(params, vars, 0);
4973 rc = bnx2x_emac_program(params, vars->line_speed,
4974 vars->duplex);
4976 /* AN complete? */
4977 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4978 if (!(vars->phy_flags &
4979 PHY_SGMII_FLAG))
4980 bnx2x_set_sgmii_tx_driver(params);
4984 /* PBF - link up */
4985 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4986 vars->line_speed);
4988 /* disable drain */
4989 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4991 /* update shared memory */
4992 bnx2x_update_mng(params, vars->link_status);
4993 msleep(20);
4994 return rc;
4996 /* This function should called upon link interrupt */
4997 /* In case vars->link_up, driver needs to
4998 1. Update the pbf
4999 2. Disable drain
5000 3. Update the shared memory
5001 4. Indicate link up
5002 5. Set LEDs
5003 Otherwise,
5004 1. Update shared memory
5005 2. Reset BigMac
5006 3. Report link down
5007 4. Unset LEDs
5009 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
5011 struct bnx2x *bp = params->bp;
5012 u8 port = params->port;
5013 u16 gp_status;
5014 u8 link_10g;
5015 u8 ext_phy_link_up, rc = 0;
5016 u32 ext_phy_type;
5018 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
5019 port,
5020 (vars->phy_flags & PHY_XGXS_FLAG),
5021 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5023 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
5024 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5025 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5026 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
5028 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5029 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5030 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5032 /* disable emac */
5033 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
5035 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5037 /* Check external link change only for non-direct */
5038 ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
5040 /* Read gp_status */
5041 CL45_RD_OVER_CL22(bp, port, params->phy_addr,
5042 MDIO_REG_BANK_GP_STATUS,
5043 MDIO_GP_STATUS_TOP_AN_STATUS1,
5044 &gp_status);
5046 rc = bnx2x_link_settings_status(params, vars, gp_status);
5047 if (rc != 0)
5048 return rc;
5050 /* anything 10 and over uses the bmac */
5051 link_10g = ((vars->line_speed == SPEED_10000) ||
5052 (vars->line_speed == SPEED_12000) ||
5053 (vars->line_speed == SPEED_12500) ||
5054 (vars->line_speed == SPEED_13000) ||
5055 (vars->line_speed == SPEED_15000) ||
5056 (vars->line_speed == SPEED_16000));
5058 bnx2x_link_int_ack(params, vars, link_10g);
5060 /* In case external phy link is up, and internal link is down
5061 ( not initialized yet probably after link initialization, it needs
5062 to be initialized.
5063 Note that after link down-up as result of cable plug,
5064 the xgxs link would probably become up again without the need to
5065 initialize it*/
5067 if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
5068 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
5069 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
5070 (ext_phy_link_up && !vars->phy_link_up))
5071 bnx2x_init_internal_phy(params, vars);
5073 /* link is up only if both local phy and external phy are up */
5074 vars->link_up = (ext_phy_link_up && vars->phy_link_up);
5076 if (vars->link_up)
5077 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
5078 else
5079 rc = bnx2x_update_link_down(params, vars);
5081 return rc;
5084 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5086 u8 ext_phy_addr[PORT_MAX];
5087 u16 val;
5088 s8 port;
5090 /* PART1 - Reset both phys */
5091 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5092 /* Extract the ext phy address for the port */
5093 u32 ext_phy_config = REG_RD(bp, shmem_base +
5094 offsetof(struct shmem_region,
5095 dev_info.port_hw_config[port].external_phy_config));
5097 /* disable attentions */
5098 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5099 (NIG_MASK_XGXS0_LINK_STATUS |
5100 NIG_MASK_XGXS0_LINK10G |
5101 NIG_MASK_SERDES0_LINK_STATUS |
5102 NIG_MASK_MI_INT));
5104 ext_phy_addr[port] =
5105 ((ext_phy_config &
5106 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5107 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5109 /* Need to take the phy out of low power mode in order
5110 to write to access its registers */
5111 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5112 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
5114 /* Reset the phy */
5115 bnx2x_cl45_write(bp, port,
5116 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5117 ext_phy_addr[port],
5118 MDIO_PMA_DEVAD,
5119 MDIO_PMA_REG_CTRL,
5120 1<<15);
5123 /* Add delay of 150ms after reset */
5124 msleep(150);
5126 /* PART2 - Download firmware to both phys */
5127 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5128 u16 fw_ver1;
5130 bnx2x_bcm8073_external_rom_boot(bp, port,
5131 ext_phy_addr[port], shmem_base);
5133 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5134 ext_phy_addr[port],
5135 MDIO_PMA_DEVAD,
5136 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
5137 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
5138 DP(NETIF_MSG_LINK,
5139 "bnx2x_8073_common_init_phy port %x:"
5140 "Download failed. fw version = 0x%x\n",
5141 port, fw_ver1);
5142 return -EINVAL;
5145 /* Only set bit 10 = 1 (Tx power down) */
5146 bnx2x_cl45_read(bp, port,
5147 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5148 ext_phy_addr[port],
5149 MDIO_PMA_DEVAD,
5150 MDIO_PMA_REG_TX_POWER_DOWN, &val);
5152 /* Phase1 of TX_POWER_DOWN reset */
5153 bnx2x_cl45_write(bp, port,
5154 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5155 ext_phy_addr[port],
5156 MDIO_PMA_DEVAD,
5157 MDIO_PMA_REG_TX_POWER_DOWN,
5158 (val | 1<<10));
5161 /* Toggle Transmitter: Power down and then up with 600ms
5162 delay between */
5163 msleep(600);
5165 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
5166 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5167 /* Phase2 of POWER_DOWN_RESET*/
5168 /* Release bit 10 (Release Tx power down) */
5169 bnx2x_cl45_read(bp, port,
5170 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5171 ext_phy_addr[port],
5172 MDIO_PMA_DEVAD,
5173 MDIO_PMA_REG_TX_POWER_DOWN, &val);
5175 bnx2x_cl45_write(bp, port,
5176 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5177 ext_phy_addr[port],
5178 MDIO_PMA_DEVAD,
5179 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
5180 msleep(15);
5182 /* Read modify write the SPI-ROM version select register */
5183 bnx2x_cl45_read(bp, port,
5184 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5185 ext_phy_addr[port],
5186 MDIO_PMA_DEVAD,
5187 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
5188 bnx2x_cl45_write(bp, port,
5189 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5190 ext_phy_addr[port],
5191 MDIO_PMA_DEVAD,
5192 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
5194 /* set GPIO2 back to LOW */
5195 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5196 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
5198 return 0;
5203 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5205 u8 ext_phy_addr;
5206 u32 val;
5207 s8 port;
5208 /* Use port1 because of the static port-swap */
5209 /* Enable the module detection interrupt */
5210 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
5211 val |= ((1<<MISC_REGISTERS_GPIO_3)|
5212 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
5213 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
5215 bnx2x_hw_reset(bp, 1);
5216 msleep(5);
5217 for (port = 0; port < PORT_MAX; port++) {
5218 /* Extract the ext phy address for the port */
5219 u32 ext_phy_config = REG_RD(bp, shmem_base +
5220 offsetof(struct shmem_region,
5221 dev_info.port_hw_config[port].external_phy_config));
5223 ext_phy_addr =
5224 ((ext_phy_config &
5225 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5226 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5227 DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
5228 ext_phy_addr);
5230 bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
5232 /* Set fault module detected LED on */
5233 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5234 MISC_REGISTERS_GPIO_HIGH,
5235 port);
5238 return 0;
5241 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5243 u8 rc = 0;
5244 u32 ext_phy_type;
5246 DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n");
5248 /* Read the ext_phy_type for arbitrary port(0) */
5249 ext_phy_type = XGXS_EXT_PHY_TYPE(
5250 REG_RD(bp, shmem_base +
5251 offsetof(struct shmem_region,
5252 dev_info.port_hw_config[0].external_phy_config)));
5254 switch (ext_phy_type) {
5255 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5257 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
5258 break;
5260 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5261 /* GPIO1 affects both ports, so there's need to pull
5262 it for single port alone */
5263 rc = bnx2x_8726_common_init_phy(bp, shmem_base);
5265 break;
5266 default:
5267 DP(NETIF_MSG_LINK,
5268 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
5269 ext_phy_type);
5270 break;
5273 return rc;
5278 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
5280 u16 val, cnt;
5282 bnx2x_cl45_read(bp, port,
5283 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5284 phy_addr,
5285 MDIO_PMA_DEVAD,
5286 MDIO_PMA_REG_7101_RESET, &val);
5288 for (cnt = 0; cnt < 10; cnt++) {
5289 msleep(50);
5290 /* Writes a self-clearing reset */
5291 bnx2x_cl45_write(bp, port,
5292 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5293 phy_addr,
5294 MDIO_PMA_DEVAD,
5295 MDIO_PMA_REG_7101_RESET,
5296 (val | (1<<15)));
5297 /* Wait for clear */
5298 bnx2x_cl45_read(bp, port,
5299 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5300 phy_addr,
5301 MDIO_PMA_DEVAD,
5302 MDIO_PMA_REG_7101_RESET, &val);
5304 if ((val & (1<<15)) == 0)
5305 break;
5308 #define RESERVED_SIZE 256
5309 /* max application is 160K bytes - data at end of RAM */
5310 #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
5312 /* Header is 14 bytes */
5313 #define HEADER_SIZE 14
5314 #define DATA_OFFSET HEADER_SIZE
5316 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
5317 bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
5318 ext_phy_addr, \
5319 MDIO_PCS_DEVAD, \
5320 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
5322 /* Programs an image to DSP's flash via the SPI port*/
5323 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
5324 u8 ext_phy_addr,
5325 char data[], u32 size)
5327 const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
5328 /* Doesn't include last trans!*/
5329 const u16 last_trans_size = size%4; /* Num bytes on last trans */
5330 u16 trans_cnt, byte_cnt;
5331 u32 data_index;
5332 u16 tmp;
5333 u16 code_started = 0;
5334 u16 image_revision1, image_revision2;
5335 u16 cnt;
5337 DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
5338 /* Going to flash*/
5339 if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
5340 /* This very often will be the case, because the image is built
5341 with 160Kbytes size whereas the total image size must actually
5342 be 160Kbytes-RESERVED_SIZE */
5343 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
5344 "truncated to %d bytes\n", size, MAX_APP_SIZE);
5345 size = MAX_APP_SIZE+HEADER_SIZE;
5347 DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
5348 DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]);
5349 /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
5350 and issuing a reset.*/
5352 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5353 MISC_REGISTERS_GPIO_HIGH, port);
5355 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
5357 /* wait 0.5 sec */
5358 for (cnt = 0; cnt < 100; cnt++)
5359 msleep(5);
5361 /* Make sure we can access the DSP
5362 And it's in the correct mode (waiting for download) */
5364 bnx2x_cl45_read(bp, port,
5365 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5366 ext_phy_addr,
5367 MDIO_PCS_DEVAD,
5368 MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
5370 if (tmp != 0x000A) {
5371 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
5372 "Expected 0x000A, read 0x%04X\n", tmp);
5373 DP(NETIF_MSG_LINK, "Download failed\n");
5374 return -EINVAL;
5377 /* Mux the SPI interface away from the internal processor */
5378 bnx2x_cl45_write(bp, port,
5379 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5380 ext_phy_addr,
5381 MDIO_PCS_DEVAD,
5382 MDIO_PCS_REG_7101_SPI_MUX, 1);
5384 /* Reset the SPI port */
5385 bnx2x_cl45_write(bp, port,
5386 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5387 ext_phy_addr,
5388 MDIO_PCS_DEVAD,
5389 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
5390 bnx2x_cl45_write(bp, port,
5391 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5392 ext_phy_addr,
5393 MDIO_PCS_DEVAD,
5394 MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
5395 (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
5396 bnx2x_cl45_write(bp, port,
5397 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5398 ext_phy_addr,
5399 MDIO_PCS_DEVAD,
5400 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
5402 /* Erase the flash */
5403 bnx2x_cl45_write(bp, port,
5404 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5405 ext_phy_addr,
5406 MDIO_PCS_DEVAD,
5407 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5408 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5410 bnx2x_cl45_write(bp, port,
5411 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5412 ext_phy_addr,
5413 MDIO_PCS_DEVAD,
5414 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5417 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5418 bnx2x_cl45_write(bp, port,
5419 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5420 ext_phy_addr,
5421 MDIO_PCS_DEVAD,
5422 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5423 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
5425 bnx2x_cl45_write(bp, port,
5426 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5427 ext_phy_addr,
5428 MDIO_PCS_DEVAD,
5429 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5431 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5433 /* Wait 10 seconds, the maximum time for the erase to complete */
5434 DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
5435 for (cnt = 0; cnt < 1000; cnt++)
5436 msleep(10);
5438 DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
5439 data_index = 0;
5440 for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
5441 bnx2x_cl45_write(bp, port,
5442 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5443 ext_phy_addr,
5444 MDIO_PCS_DEVAD,
5445 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5446 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5448 bnx2x_cl45_write(bp, port,
5449 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5450 ext_phy_addr,
5451 MDIO_PCS_DEVAD,
5452 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5454 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5456 bnx2x_cl45_write(bp, port,
5457 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5458 ext_phy_addr,
5459 MDIO_PCS_DEVAD,
5460 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5461 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
5463 /* Bits 23-16 of address */
5464 bnx2x_cl45_write(bp, port,
5465 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5466 ext_phy_addr,
5467 MDIO_PCS_DEVAD,
5468 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5469 (data_index>>16));
5470 /* Bits 15-8 of address */
5471 bnx2x_cl45_write(bp, port,
5472 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5473 ext_phy_addr,
5474 MDIO_PCS_DEVAD,
5475 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5476 (data_index>>8));
5478 /* Bits 7-0 of address */
5479 bnx2x_cl45_write(bp, port,
5480 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5481 ext_phy_addr,
5482 MDIO_PCS_DEVAD,
5483 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5484 ((u16)data_index));
5486 byte_cnt = 0;
5487 while (byte_cnt < 4 && data_index < size) {
5488 bnx2x_cl45_write(bp, port,
5489 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5490 ext_phy_addr,
5491 MDIO_PCS_DEVAD,
5492 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5493 data[data_index++]);
5494 byte_cnt++;
5497 bnx2x_cl45_write(bp, port,
5498 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5499 ext_phy_addr,
5500 MDIO_PCS_DEVAD,
5501 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5502 byte_cnt+4);
5504 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5505 msleep(5); /* Wait 5 ms minimum between transs */
5507 /* Let the user know something's going on.*/
5508 /* a pacifier ever 4K */
5509 if ((data_index % 1023) == 0)
5510 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
5513 DP(NETIF_MSG_LINK, "\n");
5514 /* Transfer the last block if there is data remaining */
5515 if (last_trans_size) {
5516 bnx2x_cl45_write(bp, port,
5517 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5518 ext_phy_addr,
5519 MDIO_PCS_DEVAD,
5520 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5521 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5523 bnx2x_cl45_write(bp, port,
5524 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5525 ext_phy_addr,
5526 MDIO_PCS_DEVAD,
5527 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5530 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5532 bnx2x_cl45_write(bp, port,
5533 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5534 ext_phy_addr,
5535 MDIO_PCS_DEVAD,
5536 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5537 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
5539 /* Bits 23-16 of address */
5540 bnx2x_cl45_write(bp, port,
5541 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5542 ext_phy_addr,
5543 MDIO_PCS_DEVAD,
5544 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5545 (data_index>>16));
5546 /* Bits 15-8 of address */
5547 bnx2x_cl45_write(bp, port,
5548 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5549 ext_phy_addr,
5550 MDIO_PCS_DEVAD,
5551 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5552 (data_index>>8));
5554 /* Bits 7-0 of address */
5555 bnx2x_cl45_write(bp, port,
5556 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5557 ext_phy_addr,
5558 MDIO_PCS_DEVAD,
5559 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5560 ((u16)data_index));
5562 byte_cnt = 0;
5563 while (byte_cnt < last_trans_size && data_index < size) {
5564 /* Bits 7-0 of address */
5565 bnx2x_cl45_write(bp, port,
5566 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5567 ext_phy_addr,
5568 MDIO_PCS_DEVAD,
5569 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5570 data[data_index++]);
5571 byte_cnt++;
5574 bnx2x_cl45_write(bp, port,
5575 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5576 ext_phy_addr,
5577 MDIO_PCS_DEVAD,
5578 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5579 byte_cnt+4);
5581 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5584 /* DSP Remove Download Mode */
5585 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5586 MISC_REGISTERS_GPIO_LOW, port);
5588 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
5590 /* wait 0.5 sec to allow it to run */
5591 for (cnt = 0; cnt < 100; cnt++)
5592 msleep(5);
5594 bnx2x_hw_reset(bp, port);
5596 for (cnt = 0; cnt < 100; cnt++)
5597 msleep(5);
5599 /* Check that the code is started. In case the download
5600 checksum failed, the code won't be started. */
5601 bnx2x_cl45_read(bp, port,
5602 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5603 ext_phy_addr,
5604 MDIO_PCS_DEVAD,
5605 MDIO_PCS_REG_7101_DSP_ACCESS,
5606 &tmp);
5608 code_started = (tmp & (1<<4));
5609 if (!code_started) {
5610 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
5611 return -EINVAL;
5614 /* Verify that the file revision is now equal to the image
5615 revision within the DSP */
5616 bnx2x_cl45_read(bp, port,
5617 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5618 ext_phy_addr,
5619 MDIO_PMA_DEVAD,
5620 MDIO_PMA_REG_7101_VER1,
5621 &image_revision1);
5623 bnx2x_cl45_read(bp, port,
5624 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5625 ext_phy_addr,
5626 MDIO_PMA_DEVAD,
5627 MDIO_PMA_REG_7101_VER2,
5628 &image_revision2);
5630 if (data[0x14e] != (image_revision2&0xFF) ||
5631 data[0x14f] != ((image_revision2&0xFF00)>>8) ||
5632 data[0x150] != (image_revision1&0xFF) ||
5633 data[0x151] != ((image_revision1&0xFF00)>>8)) {
5634 DP(NETIF_MSG_LINK, "Download failed.\n");
5635 return -EINVAL;
5637 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
5638 return 0;
5641 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
5642 u8 driver_loaded, char data[], u32 size)
5644 u8 rc = 0;
5645 u32 ext_phy_type;
5646 u8 ext_phy_addr;
5647 ext_phy_addr = ((ext_phy_config &
5648 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5649 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5651 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
5653 switch (ext_phy_type) {
5654 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5655 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5656 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5657 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5658 DP(NETIF_MSG_LINK,
5659 "Flash download not supported for this ext phy\n");
5660 rc = -EINVAL;
5661 break;
5662 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5663 /* Take ext phy out of reset */
5664 if (!driver_loaded)
5665 bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
5666 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
5667 data, size);
5668 if (!driver_loaded)
5669 bnx2x_turn_off_sf(bp, port);
5670 break;
5671 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5672 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
5673 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
5674 default:
5675 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");
5676 rc = -EINVAL;
5677 break;
5679 return rc;