1 /* Copyright 2008-2011 Broadcom Corporation
3 * Unless you and Broadcom execute a separate written software license
4 * agreement governing use of this software, this software is licensed to you
5 * under the terms of the GNU General Public License version 2, available
6 * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
8 * Notwithstanding the above, under no circumstances may you combine this
9 * software in any way with any other Broadcom software provided under a
10 * license other than the GPL, without Broadcom's express prior written
13 * Written by Yaniv Rosner
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/pci.h>
22 #include <linux/netdevice.h>
23 #include <linux/delay.h>
24 #include <linux/ethtool.h>
25 #include <linux/mutex.h>
28 #include "bnx2x_cmn.h"
31 /********************************************************/
33 /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
34 #define ETH_OVREHEAD (ETH_HLEN + 8 + 8)
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 #define I2C_SWITCH_WIDTH 2
44 #define I2C_WA_RETRY_CNT 3
45 #define MCPR_IMC_COMMAND_READ_OP 1
46 #define MCPR_IMC_COMMAND_WRITE_OP 2
48 /* LED Blink rate that will achieve ~15.9Hz */
49 #define LED_BLINK_RATE_VAL_E3 354
50 #define LED_BLINK_RATE_VAL_E1X_E2 480
51 /***********************************************************/
52 /* Shortcut definitions */
53 /***********************************************************/
55 #define NIG_LATCH_BC_ENABLE_MI_INT 0
57 #define NIG_STATUS_EMAC0_MI_INT \
58 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
59 #define NIG_STATUS_XGXS0_LINK10G \
60 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
61 #define NIG_STATUS_XGXS0_LINK_STATUS \
62 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
63 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
64 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
65 #define NIG_STATUS_SERDES0_LINK_STATUS \
66 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
67 #define NIG_MASK_MI_INT \
68 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
69 #define NIG_MASK_XGXS0_LINK10G \
70 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
71 #define NIG_MASK_XGXS0_LINK_STATUS \
72 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
73 #define NIG_MASK_SERDES0_LINK_STATUS \
74 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
76 #define MDIO_AN_CL73_OR_37_COMPLETE \
77 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
78 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
80 #define XGXS_RESET_BITS \
81 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
82 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
83 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
84 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
85 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
87 #define SERDES_RESET_BITS \
88 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
89 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
90 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
91 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
93 #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
94 #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
95 #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
96 #define AUTONEG_PARALLEL \
97 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
98 #define AUTONEG_SGMII_FIBER_AUTODET \
99 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
100 #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
102 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
103 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
104 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
105 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
106 #define GP_STATUS_SPEED_MASK \
107 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
108 #define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
109 #define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
110 #define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
111 #define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
112 #define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
113 #define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
114 #define GP_STATUS_10G_HIG \
115 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
116 #define GP_STATUS_10G_CX4 \
117 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
118 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
119 #define GP_STATUS_10G_KX4 \
120 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
121 #define GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR
122 #define GP_STATUS_10G_XFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI
123 #define GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS
124 #define GP_STATUS_10G_SFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI
125 #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
126 #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
127 #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
128 #define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
129 #define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
130 #define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
131 #define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
132 #define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
133 #define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
134 #define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
135 #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
136 #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
137 #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
138 #define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
139 #define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
144 #define SFP_EEPROM_CON_TYPE_ADDR 0x2
145 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
146 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
149 #define SFP_EEPROM_COMP_CODE_ADDR 0x3
150 #define SFP_EEPROM_COMP_CODE_SR_MASK (1<<4)
151 #define SFP_EEPROM_COMP_CODE_LR_MASK (1<<5)
152 #define SFP_EEPROM_COMP_CODE_LRM_MASK (1<<6)
154 #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
155 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
156 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
158 #define SFP_EEPROM_OPTIONS_ADDR 0x40
159 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
160 #define SFP_EEPROM_OPTIONS_SIZE 2
162 #define EDC_MODE_LINEAR 0x0022
163 #define EDC_MODE_LIMITING 0x0044
164 #define EDC_MODE_PASSIVE_DAC 0x0055
167 /* BRB thresholds for E2*/
168 #define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE 170
169 #define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0
171 #define PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE 250
172 #define PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0
174 #define PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE 10
175 #define PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 90
177 #define PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE 50
178 #define PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE 250
180 /* BRB thresholds for E3A0 */
181 #define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE 290
182 #define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0
184 #define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE 410
185 #define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0
187 #define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE 10
188 #define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 170
190 #define PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE 50
191 #define PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE 410
194 /* BRB thresholds for E3B0 2 port mode*/
195 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE 1025
196 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0
198 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE 1025
199 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0
201 #define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE 10
202 #define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 1025
204 #define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE 50
205 #define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE 1025
208 #define PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR 1025
209 #define PFC_E3B0_2P_BRB_FULL_LB_XON_THR 1025
211 /* Lossy +Lossless GUARANTIED == GUART */
212 #define PFC_E3B0_2P_MIX_PAUSE_LB_GUART 284
213 /* Lossless +Lossless*/
214 #define PFC_E3B0_2P_PAUSE_LB_GUART 236
216 #define PFC_E3B0_2P_NON_PAUSE_LB_GUART 342
219 #define PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART 284
220 /* Lossless +Lossless*/
221 #define PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART 236
223 #define PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART 336
224 #define PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST 80
226 #define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART 0
227 #define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST 0
229 /* BRB thresholds for E3B0 4 port mode */
230 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE 304
231 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0
233 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE 384
234 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0
236 #define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE 10
237 #define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 304
239 #define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE 50
240 #define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE 384
244 #define PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR 304
245 #define PFC_E3B0_4P_BRB_FULL_LB_XON_THR 384
246 #define PFC_E3B0_4P_LB_GUART 120
248 #define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART 120
249 #define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST 80
251 #define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART 80
252 #define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST 120
254 #define DCBX_INVALID_COS (0xFF)
256 #define ETS_BW_LIMIT_CREDIT_UPPER_BOUND (0x5000)
257 #define ETS_BW_LIMIT_CREDIT_WEIGHT (0x5000)
258 #define ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS (1360)
259 #define ETS_E3B0_NIG_MIN_W_VAL_20GBPS (2720)
260 #define ETS_E3B0_PBF_MIN_W_VAL (10000)
262 #define MAX_PACKET_SIZE (9700)
263 #define WC_UC_TIMEOUT 100
264 #define MAX_KR_LINK_RETRY 4
266 /**********************************************************/
268 /**********************************************************/
270 #define CL22_WR_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
271 bnx2x_cl45_write(_bp, _phy, \
272 (_phy)->def_md_devad, \
273 (_bank + (_addr & 0xf)), \
276 #define CL22_RD_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
277 bnx2x_cl45_read(_bp, _phy, \
278 (_phy)->def_md_devad, \
279 (_bank + (_addr & 0xf)), \
282 static u32
bnx2x_bits_en(struct bnx2x
*bp
, u32 reg
, u32 bits
)
284 u32 val
= REG_RD(bp
, reg
);
287 REG_WR(bp
, reg
, val
);
291 static u32
bnx2x_bits_dis(struct bnx2x
*bp
, u32 reg
, u32 bits
)
293 u32 val
= REG_RD(bp
, reg
);
296 REG_WR(bp
, reg
, val
);
300 /******************************************************************/
301 /* EPIO/GPIO section */
302 /******************************************************************/
303 static void bnx2x_get_epio(struct bnx2x
*bp
, u32 epio_pin
, u32
*en
)
305 u32 epio_mask
, gp_oenable
;
309 DP(NETIF_MSG_LINK
, "Invalid EPIO pin %d to get\n", epio_pin
);
313 epio_mask
= 1 << epio_pin
;
314 /* Set this EPIO to output */
315 gp_oenable
= REG_RD(bp
, MCP_REG_MCPR_GP_OENABLE
);
316 REG_WR(bp
, MCP_REG_MCPR_GP_OENABLE
, gp_oenable
& ~epio_mask
);
318 *en
= (REG_RD(bp
, MCP_REG_MCPR_GP_INPUTS
) & epio_mask
) >> epio_pin
;
320 static void bnx2x_set_epio(struct bnx2x
*bp
, u32 epio_pin
, u32 en
)
322 u32 epio_mask
, gp_output
, gp_oenable
;
326 DP(NETIF_MSG_LINK
, "Invalid EPIO pin %d to set\n", epio_pin
);
329 DP(NETIF_MSG_LINK
, "Setting EPIO pin %d to %d\n", epio_pin
, en
);
330 epio_mask
= 1 << epio_pin
;
331 /* Set this EPIO to output */
332 gp_output
= REG_RD(bp
, MCP_REG_MCPR_GP_OUTPUTS
);
334 gp_output
|= epio_mask
;
336 gp_output
&= ~epio_mask
;
338 REG_WR(bp
, MCP_REG_MCPR_GP_OUTPUTS
, gp_output
);
340 /* Set the value for this EPIO */
341 gp_oenable
= REG_RD(bp
, MCP_REG_MCPR_GP_OENABLE
);
342 REG_WR(bp
, MCP_REG_MCPR_GP_OENABLE
, gp_oenable
| epio_mask
);
345 static void bnx2x_set_cfg_pin(struct bnx2x
*bp
, u32 pin_cfg
, u32 val
)
347 if (pin_cfg
== PIN_CFG_NA
)
349 if (pin_cfg
>= PIN_CFG_EPIO0
) {
350 bnx2x_set_epio(bp
, pin_cfg
- PIN_CFG_EPIO0
, val
);
352 u8 gpio_num
= (pin_cfg
- PIN_CFG_GPIO0_P0
) & 0x3;
353 u8 gpio_port
= (pin_cfg
- PIN_CFG_GPIO0_P0
) >> 2;
354 bnx2x_set_gpio(bp
, gpio_num
, (u8
)val
, gpio_port
);
358 static u32
bnx2x_get_cfg_pin(struct bnx2x
*bp
, u32 pin_cfg
, u32
*val
)
360 if (pin_cfg
== PIN_CFG_NA
)
362 if (pin_cfg
>= PIN_CFG_EPIO0
) {
363 bnx2x_get_epio(bp
, pin_cfg
- PIN_CFG_EPIO0
, val
);
365 u8 gpio_num
= (pin_cfg
- PIN_CFG_GPIO0_P0
) & 0x3;
366 u8 gpio_port
= (pin_cfg
- PIN_CFG_GPIO0_P0
) >> 2;
367 *val
= bnx2x_get_gpio(bp
, gpio_num
, gpio_port
);
372 /******************************************************************/
374 /******************************************************************/
375 static void bnx2x_ets_e2e3a0_disabled(struct link_params
*params
)
377 /* ETS disabled configuration*/
378 struct bnx2x
*bp
= params
->bp
;
380 DP(NETIF_MSG_LINK
, "ETS E2E3 disabled configuration\n");
383 * mapping between entry priority to client number (0,1,2 -debug and
384 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
386 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
387 * cos1-100 cos0-011 dbg1-010 dbg0-001 MCP-000
390 REG_WR(bp
, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT
, 0x4688);
392 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
393 * as strict. Bits 0,1,2 - debug and management entries, 3 -
394 * COS0 entry, 4 - COS1 entry.
395 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
396 * bit4 bit3 bit2 bit1 bit0
397 * MCP and debug are strict
400 REG_WR(bp
, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT
, 0x7);
401 /* defines which entries (clients) are subjected to WFQ arbitration */
402 REG_WR(bp
, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ
, 0);
404 * For strict priority entries defines the number of consecutive
405 * slots for the highest priority.
407 REG_WR(bp
, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS
, 0x100);
409 * mapping between the CREDIT_WEIGHT registers and actual client
412 REG_WR(bp
, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP
, 0);
413 REG_WR(bp
, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0
, 0);
414 REG_WR(bp
, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1
, 0);
416 REG_WR(bp
, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0
, 0);
417 REG_WR(bp
, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1
, 0);
418 REG_WR(bp
, PBF_REG_HIGH_PRIORITY_COS_NUM
, 0);
419 /* ETS mode disable */
420 REG_WR(bp
, PBF_REG_ETS_ENABLED
, 0);
422 * If ETS mode is enabled (there is no strict priority) defines a WFQ
423 * weight for COS0/COS1.
425 REG_WR(bp
, PBF_REG_COS0_WEIGHT
, 0x2710);
426 REG_WR(bp
, PBF_REG_COS1_WEIGHT
, 0x2710);
427 /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
428 REG_WR(bp
, PBF_REG_COS0_UPPER_BOUND
, 0x989680);
429 REG_WR(bp
, PBF_REG_COS1_UPPER_BOUND
, 0x989680);
430 /* Defines the number of consecutive slots for the strict priority */
431 REG_WR(bp
, PBF_REG_NUM_STRICT_ARB_SLOTS
, 0);
433 /******************************************************************************
435 * Getting min_w_val will be set according to line speed .
437 ******************************************************************************/
438 static u32
bnx2x_ets_get_min_w_val_nig(const struct link_vars
*vars
)
441 /* Calculate min_w_val.*/
443 if (SPEED_20000
== vars
->line_speed
)
444 min_w_val
= ETS_E3B0_NIG_MIN_W_VAL_20GBPS
;
446 min_w_val
= ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS
;
448 min_w_val
= ETS_E3B0_NIG_MIN_W_VAL_20GBPS
;
450 * If the link isn't up (static configuration for example ) The
451 * link will be according to 20GBPS.
455 /******************************************************************************
457 * Getting credit upper bound form min_w_val.
459 ******************************************************************************/
460 static u32
bnx2x_ets_get_credit_upper_bound(const u32 min_w_val
)
462 const u32 credit_upper_bound
= (u32
)MAXVAL((150 * min_w_val
),
464 return credit_upper_bound
;
466 /******************************************************************************
468 * Set credit upper bound for NIG.
470 ******************************************************************************/
471 static void bnx2x_ets_e3b0_set_credit_upper_bound_nig(
472 const struct link_params
*params
,
475 struct bnx2x
*bp
= params
->bp
;
476 const u8 port
= params
->port
;
477 const u32 credit_upper_bound
=
478 bnx2x_ets_get_credit_upper_bound(min_w_val
);
480 REG_WR(bp
, (port
) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_0
:
481 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0
, credit_upper_bound
);
482 REG_WR(bp
, (port
) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_1
:
483 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1
, credit_upper_bound
);
484 REG_WR(bp
, (port
) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_2
:
485 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_2
, credit_upper_bound
);
486 REG_WR(bp
, (port
) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_3
:
487 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_3
, credit_upper_bound
);
488 REG_WR(bp
, (port
) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_4
:
489 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_4
, credit_upper_bound
);
490 REG_WR(bp
, (port
) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_5
:
491 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_5
, credit_upper_bound
);
494 REG_WR(bp
, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_6
,
496 REG_WR(bp
, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_7
,
498 REG_WR(bp
, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_8
,
502 /******************************************************************************
504 * Will return the NIG ETS registers to init values.Except
505 * credit_upper_bound.
506 * That isn't used in this configuration (No WFQ is enabled) and will be
507 * configured acording to spec
509 ******************************************************************************/
510 static void bnx2x_ets_e3b0_nig_disabled(const struct link_params
*params
,
511 const struct link_vars
*vars
)
513 struct bnx2x
*bp
= params
->bp
;
514 const u8 port
= params
->port
;
515 const u32 min_w_val
= bnx2x_ets_get_min_w_val_nig(vars
);
517 * mapping between entry priority to client number (0,1,2 -debug and
518 * management clients, 3 - COS0 client, 4 - COS1, ... 8 -
519 * COS5)(HIGHEST) 4bits client num.TODO_ETS - Should be done by
520 * reset value or init tool
523 REG_WR(bp
, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB
, 0x543210);
524 REG_WR(bp
, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB
, 0x0);
526 REG_WR(bp
, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB
, 0x76543210);
527 REG_WR(bp
, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB
, 0x8);
530 * For strict priority entries defines the number of consecutive
531 * slots for the highest priority.
533 /* TODO_ETS - Should be done by reset value or init tool */
534 REG_WR(bp
, (port
) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS
:
535 NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS
, 0x100);
537 * mapping between the CREDIT_WEIGHT registers and actual client
540 /* TODO_ETS - Should be done by reset value or init tool */
543 REG_WR(bp
, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB
, 0x210543);
544 REG_WR(bp
, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_MSB
, 0x0);
547 REG_WR(bp
, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_LSB
,
549 REG_WR(bp
, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB
, 0x5);
553 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
554 * as strict. Bits 0,1,2 - debug and management entries, 3 -
555 * COS0 entry, 4 - COS1 entry.
556 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
557 * bit4 bit3 bit2 bit1 bit0
558 * MCP and debug are strict
561 REG_WR(bp
, NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT
, 0x3f);
563 REG_WR(bp
, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT
, 0x1ff);
564 /* defines which entries (clients) are subjected to WFQ arbitration */
565 REG_WR(bp
, (port
) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ
:
566 NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ
, 0);
569 * Please notice the register address are note continuous and a
570 * for here is note appropriate.In 2 port mode port0 only COS0-5
571 * can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4
572 * port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT
573 * are never used for WFQ
575 REG_WR(bp
, (port
) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0
:
576 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0
, 0x0);
577 REG_WR(bp
, (port
) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1
:
578 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1
, 0x0);
579 REG_WR(bp
, (port
) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2
:
580 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2
, 0x0);
581 REG_WR(bp
, (port
) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_3
:
582 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3
, 0x0);
583 REG_WR(bp
, (port
) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_4
:
584 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4
, 0x0);
585 REG_WR(bp
, (port
) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_5
:
586 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5
, 0x0);
588 REG_WR(bp
, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_6
, 0x0);
589 REG_WR(bp
, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_7
, 0x0);
590 REG_WR(bp
, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_8
, 0x0);
593 bnx2x_ets_e3b0_set_credit_upper_bound_nig(params
, min_w_val
);
595 /******************************************************************************
597 * Set credit upper bound for PBF.
599 ******************************************************************************/
600 static void bnx2x_ets_e3b0_set_credit_upper_bound_pbf(
601 const struct link_params
*params
,
604 struct bnx2x
*bp
= params
->bp
;
605 const u32 credit_upper_bound
=
606 bnx2x_ets_get_credit_upper_bound(min_w_val
);
607 const u8 port
= params
->port
;
608 u32 base_upper_bound
= 0;
612 * In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4
613 * port mode port1 has COS0-2 that can be used for WFQ.
616 base_upper_bound
= PBF_REG_COS0_UPPER_BOUND_P0
;
617 max_cos
= DCBX_E3B0_MAX_NUM_COS_PORT0
;
619 base_upper_bound
= PBF_REG_COS0_UPPER_BOUND_P1
;
620 max_cos
= DCBX_E3B0_MAX_NUM_COS_PORT1
;
623 for (i
= 0; i
< max_cos
; i
++)
624 REG_WR(bp
, base_upper_bound
+ (i
<< 2), credit_upper_bound
);
627 /******************************************************************************
629 * Will return the PBF ETS registers to init values.Except
630 * credit_upper_bound.
631 * That isn't used in this configuration (No WFQ is enabled) and will be
632 * configured acording to spec
634 ******************************************************************************/
635 static void bnx2x_ets_e3b0_pbf_disabled(const struct link_params
*params
)
637 struct bnx2x
*bp
= params
->bp
;
638 const u8 port
= params
->port
;
639 const u32 min_w_val_pbf
= ETS_E3B0_PBF_MIN_W_VAL
;
645 * mapping between entry priority to client number 0 - COS0
646 * client, 2 - COS1, ... 5 - COS5)(HIGHEST) 4bits client num.
647 * TODO_ETS - Should be done by reset value or init tool
650 /* 0x688 (|011|0 10|00 1|000) */
651 REG_WR(bp
, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1
, 0x688);
653 /* (10 1|100 |011|0 10|00 1|000) */
654 REG_WR(bp
, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0
, 0x2C688);
656 /* TODO_ETS - Should be done by reset value or init tool */
658 /* 0x688 (|011|0 10|00 1|000)*/
659 REG_WR(bp
, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P1
, 0x688);
661 /* 0x2C688 (10 1|100 |011|0 10|00 1|000) */
662 REG_WR(bp
, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P0
, 0x2C688);
664 REG_WR(bp
, (port
) ? PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P1
:
665 PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P0
, 0x100);
668 REG_WR(bp
, (port
) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1
:
669 PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0
, 0);
671 REG_WR(bp
, (port
) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1
:
672 PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0
, 0);
674 * In 2 port mode port0 has COS0-5 that can be used for WFQ.
675 * In 4 port mode port1 has COS0-2 that can be used for WFQ.
678 base_weight
= PBF_REG_COS0_WEIGHT_P0
;
679 max_cos
= DCBX_E3B0_MAX_NUM_COS_PORT0
;
681 base_weight
= PBF_REG_COS0_WEIGHT_P1
;
682 max_cos
= DCBX_E3B0_MAX_NUM_COS_PORT1
;
685 for (i
= 0; i
< max_cos
; i
++)
686 REG_WR(bp
, base_weight
+ (0x4 * i
), 0);
688 bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params
, min_w_val_pbf
);
690 /******************************************************************************
692 * E3B0 disable will return basicly the values to init values.
694 ******************************************************************************/
695 static int bnx2x_ets_e3b0_disabled(const struct link_params
*params
,
696 const struct link_vars
*vars
)
698 struct bnx2x
*bp
= params
->bp
;
700 if (!CHIP_IS_E3B0(bp
)) {
702 "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
706 bnx2x_ets_e3b0_nig_disabled(params
, vars
);
708 bnx2x_ets_e3b0_pbf_disabled(params
);
713 /******************************************************************************
715 * Disable will return basicly the values to init values.
717 ******************************************************************************/
718 int bnx2x_ets_disabled(struct link_params
*params
,
719 struct link_vars
*vars
)
721 struct bnx2x
*bp
= params
->bp
;
722 int bnx2x_status
= 0;
724 if ((CHIP_IS_E2(bp
)) || (CHIP_IS_E3A0(bp
)))
725 bnx2x_ets_e2e3a0_disabled(params
);
726 else if (CHIP_IS_E3B0(bp
))
727 bnx2x_status
= bnx2x_ets_e3b0_disabled(params
, vars
);
729 DP(NETIF_MSG_LINK
, "bnx2x_ets_disabled - chip not supported\n");
736 /******************************************************************************
738 * Set the COS mappimg to SP and BW until this point all the COS are not
740 ******************************************************************************/
741 static int bnx2x_ets_e3b0_cli_map(const struct link_params
*params
,
742 const struct bnx2x_ets_params
*ets_params
,
743 const u8 cos_sp_bitmap
,
744 const u8 cos_bw_bitmap
)
746 struct bnx2x
*bp
= params
->bp
;
747 const u8 port
= params
->port
;
748 const u8 nig_cli_sp_bitmap
= 0x7 | (cos_sp_bitmap
<< 3);
749 const u8 pbf_cli_sp_bitmap
= cos_sp_bitmap
;
750 const u8 nig_cli_subject2wfq_bitmap
= cos_bw_bitmap
<< 3;
751 const u8 pbf_cli_subject2wfq_bitmap
= cos_bw_bitmap
;
753 REG_WR(bp
, (port
) ? NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT
:
754 NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT
, nig_cli_sp_bitmap
);
756 REG_WR(bp
, (port
) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1
:
757 PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0
, pbf_cli_sp_bitmap
);
759 REG_WR(bp
, (port
) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ
:
760 NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ
,
761 nig_cli_subject2wfq_bitmap
);
763 REG_WR(bp
, (port
) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1
:
764 PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0
,
765 pbf_cli_subject2wfq_bitmap
);
770 /******************************************************************************
772 * This function is needed because NIG ARB_CREDIT_WEIGHT_X are
773 * not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
774 ******************************************************************************/
775 static int bnx2x_ets_e3b0_set_cos_bw(struct bnx2x
*bp
,
777 const u32 min_w_val_nig
,
778 const u32 min_w_val_pbf
,
783 u32 nig_reg_adress_crd_weight
= 0;
784 u32 pbf_reg_adress_crd_weight
= 0;
785 /* Calculate and set BW for this COS - use 1 instead of 0 for BW */
786 const u32 cos_bw_nig
= ((bw
? bw
: 1) * min_w_val_nig
) / total_bw
;
787 const u32 cos_bw_pbf
= ((bw
? bw
: 1) * min_w_val_pbf
) / total_bw
;
791 nig_reg_adress_crd_weight
=
792 (port
) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0
:
793 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0
;
794 pbf_reg_adress_crd_weight
= (port
) ?
795 PBF_REG_COS0_WEIGHT_P1
: PBF_REG_COS0_WEIGHT_P0
;
798 nig_reg_adress_crd_weight
= (port
) ?
799 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1
:
800 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1
;
801 pbf_reg_adress_crd_weight
= (port
) ?
802 PBF_REG_COS1_WEIGHT_P1
: PBF_REG_COS1_WEIGHT_P0
;
805 nig_reg_adress_crd_weight
= (port
) ?
806 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2
:
807 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2
;
809 pbf_reg_adress_crd_weight
= (port
) ?
810 PBF_REG_COS2_WEIGHT_P1
: PBF_REG_COS2_WEIGHT_P0
;
815 nig_reg_adress_crd_weight
=
816 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3
;
817 pbf_reg_adress_crd_weight
=
818 PBF_REG_COS3_WEIGHT_P0
;
823 nig_reg_adress_crd_weight
=
824 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4
;
825 pbf_reg_adress_crd_weight
= PBF_REG_COS4_WEIGHT_P0
;
830 nig_reg_adress_crd_weight
=
831 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5
;
832 pbf_reg_adress_crd_weight
= PBF_REG_COS5_WEIGHT_P0
;
836 REG_WR(bp
, nig_reg_adress_crd_weight
, cos_bw_nig
);
838 REG_WR(bp
, pbf_reg_adress_crd_weight
, cos_bw_pbf
);
842 /******************************************************************************
844 * Calculate the total BW.A value of 0 isn't legal.
846 ******************************************************************************/
847 static int bnx2x_ets_e3b0_get_total_bw(
848 const struct link_params
*params
,
849 const struct bnx2x_ets_params
*ets_params
,
852 struct bnx2x
*bp
= params
->bp
;
856 /* Calculate total BW requested */
857 for (cos_idx
= 0; cos_idx
< ets_params
->num_of_cos
; cos_idx
++) {
858 if (bnx2x_cos_state_bw
== ets_params
->cos
[cos_idx
].state
) {
860 ets_params
->cos
[cos_idx
].params
.bw_params
.bw
;
864 /* Check total BW is valid */
865 if ((100 != *total_bw
) || (0 == *total_bw
)) {
866 if (0 == *total_bw
) {
868 "bnx2x_ets_E3B0_config toatl BW shouldn't be 0\n");
872 "bnx2x_ets_E3B0_config toatl BW should be 100\n");
874 * We can handle a case whre the BW isn't 100 this can happen
875 * if the TC are joined.
881 /******************************************************************************
883 * Invalidate all the sp_pri_to_cos.
885 ******************************************************************************/
886 static void bnx2x_ets_e3b0_sp_pri_to_cos_init(u8
*sp_pri_to_cos
)
889 for (pri
= 0; pri
< DCBX_MAX_NUM_COS
; pri
++)
890 sp_pri_to_cos
[pri
] = DCBX_INVALID_COS
;
892 /******************************************************************************
894 * Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
895 * according to sp_pri_to_cos.
897 ******************************************************************************/
898 static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params
*params
,
899 u8
*sp_pri_to_cos
, const u8 pri
,
902 struct bnx2x
*bp
= params
->bp
;
903 const u8 port
= params
->port
;
904 const u8 max_num_of_cos
= (port
) ? DCBX_E3B0_MAX_NUM_COS_PORT1
:
905 DCBX_E3B0_MAX_NUM_COS_PORT0
;
907 if (DCBX_INVALID_COS
!= sp_pri_to_cos
[pri
]) {
908 DP(NETIF_MSG_LINK
, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
909 "parameter There can't be two COS's with "
910 "the same strict pri\n");
914 if (pri
> max_num_of_cos
) {
915 DP(NETIF_MSG_LINK
, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
916 "parameter Illegal strict priority\n");
920 sp_pri_to_cos
[pri
] = cos_entry
;
925 /******************************************************************************
927 * Returns the correct value according to COS and priority in
928 * the sp_pri_cli register.
930 ******************************************************************************/
931 static u64
bnx2x_e3b0_sp_get_pri_cli_reg(const u8 cos
, const u8 cos_offset
,
937 pri_cli_nig
= ((u64
)(cos
+ cos_offset
)) << (entry_size
*
938 (pri_set
+ pri_offset
));
942 /******************************************************************************
944 * Returns the correct value according to COS and priority in the
945 * sp_pri_cli register for NIG.
947 ******************************************************************************/
948 static u64
bnx2x_e3b0_sp_get_pri_cli_reg_nig(const u8 cos
, const u8 pri_set
)
950 /* MCP Dbg0 and dbg1 are always with higher strict pri*/
951 const u8 nig_cos_offset
= 3;
952 const u8 nig_pri_offset
= 3;
954 return bnx2x_e3b0_sp_get_pri_cli_reg(cos
, nig_cos_offset
, pri_set
,
958 /******************************************************************************
960 * Returns the correct value according to COS and priority in the
961 * sp_pri_cli register for PBF.
963 ******************************************************************************/
964 static u64
bnx2x_e3b0_sp_get_pri_cli_reg_pbf(const u8 cos
, const u8 pri_set
)
966 const u8 pbf_cos_offset
= 0;
967 const u8 pbf_pri_offset
= 0;
969 return bnx2x_e3b0_sp_get_pri_cli_reg(cos
, pbf_cos_offset
, pri_set
,
974 /******************************************************************************
976 * Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
977 * according to sp_pri_to_cos.(which COS has higher priority)
979 ******************************************************************************/
980 static int bnx2x_ets_e3b0_sp_set_pri_cli_reg(const struct link_params
*params
,
983 struct bnx2x
*bp
= params
->bp
;
985 const u8 port
= params
->port
;
986 /* MCP Dbg0 and dbg1 are always with higher strict pri*/
987 u64 pri_cli_nig
= 0x210;
988 u32 pri_cli_pbf
= 0x0;
991 const u8 max_num_of_cos
= (port
) ? DCBX_E3B0_MAX_NUM_COS_PORT1
:
992 DCBX_E3B0_MAX_NUM_COS_PORT0
;
994 u8 cos_bit_to_set
= (1 << max_num_of_cos
) - 1;
996 /* Set all the strict priority first */
997 for (i
= 0; i
< max_num_of_cos
; i
++) {
998 if (DCBX_INVALID_COS
!= sp_pri_to_cos
[i
]) {
999 if (DCBX_MAX_NUM_COS
<= sp_pri_to_cos
[i
]) {
1001 "bnx2x_ets_e3b0_sp_set_pri_cli_reg "
1002 "invalid cos entry\n");
1006 pri_cli_nig
|= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
1007 sp_pri_to_cos
[i
], pri_set
);
1009 pri_cli_pbf
|= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
1010 sp_pri_to_cos
[i
], pri_set
);
1011 pri_bitmask
= 1 << sp_pri_to_cos
[i
];
1012 /* COS is used remove it from bitmap.*/
1013 if (0 == (pri_bitmask
& cos_bit_to_set
)) {
1015 "bnx2x_ets_e3b0_sp_set_pri_cli_reg "
1016 "invalid There can't be two COS's with"
1017 " the same strict pri\n");
1020 cos_bit_to_set
&= ~pri_bitmask
;
1025 /* Set all the Non strict priority i= COS*/
1026 for (i
= 0; i
< max_num_of_cos
; i
++) {
1027 pri_bitmask
= 1 << i
;
1028 /* Check if COS was already used for SP */
1029 if (pri_bitmask
& cos_bit_to_set
) {
1030 /* COS wasn't used for SP */
1031 pri_cli_nig
|= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
1034 pri_cli_pbf
|= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
1036 /* COS is used remove it from bitmap.*/
1037 cos_bit_to_set
&= ~pri_bitmask
;
1042 if (pri_set
!= max_num_of_cos
) {
1043 DP(NETIF_MSG_LINK
, "bnx2x_ets_e3b0_sp_set_pri_cli_reg not all "
1044 "entries were set\n");
1049 /* Only 6 usable clients*/
1050 REG_WR(bp
, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB
,
1053 REG_WR(bp
, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1
, pri_cli_pbf
);
1055 /* Only 9 usable clients*/
1056 const u32 pri_cli_nig_lsb
= (u32
) (pri_cli_nig
);
1057 const u32 pri_cli_nig_msb
= (u32
) ((pri_cli_nig
>> 32) & 0xF);
1059 REG_WR(bp
, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB
,
1061 REG_WR(bp
, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB
,
1064 REG_WR(bp
, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0
, pri_cli_pbf
);
1069 /******************************************************************************
1071 * Configure the COS to ETS according to BW and SP settings.
1072 ******************************************************************************/
1073 int bnx2x_ets_e3b0_config(const struct link_params
*params
,
1074 const struct link_vars
*vars
,
1075 const struct bnx2x_ets_params
*ets_params
)
1077 struct bnx2x
*bp
= params
->bp
;
1078 int bnx2x_status
= 0;
1079 const u8 port
= params
->port
;
1081 const u32 min_w_val_nig
= bnx2x_ets_get_min_w_val_nig(vars
);
1082 const u32 min_w_val_pbf
= ETS_E3B0_PBF_MIN_W_VAL
;
1083 u8 cos_bw_bitmap
= 0;
1084 u8 cos_sp_bitmap
= 0;
1085 u8 sp_pri_to_cos
[DCBX_MAX_NUM_COS
] = {0};
1086 const u8 max_num_of_cos
= (port
) ? DCBX_E3B0_MAX_NUM_COS_PORT1
:
1087 DCBX_E3B0_MAX_NUM_COS_PORT0
;
1090 if (!CHIP_IS_E3B0(bp
)) {
1092 "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
1096 if ((ets_params
->num_of_cos
> max_num_of_cos
)) {
1097 DP(NETIF_MSG_LINK
, "bnx2x_ets_E3B0_config the number of COS "
1098 "isn't supported\n");
1102 /* Prepare sp strict priority parameters*/
1103 bnx2x_ets_e3b0_sp_pri_to_cos_init(sp_pri_to_cos
);
1105 /* Prepare BW parameters*/
1106 bnx2x_status
= bnx2x_ets_e3b0_get_total_bw(params
, ets_params
,
1108 if (0 != bnx2x_status
) {
1110 "bnx2x_ets_E3B0_config get_total_bw failed\n");
1115 * Upper bound is set according to current link speed (min_w_val
1116 * should be the same for upper bound and COS credit val).
1118 bnx2x_ets_e3b0_set_credit_upper_bound_nig(params
, min_w_val_nig
);
1119 bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params
, min_w_val_pbf
);
1122 for (cos_entry
= 0; cos_entry
< ets_params
->num_of_cos
; cos_entry
++) {
1123 if (bnx2x_cos_state_bw
== ets_params
->cos
[cos_entry
].state
) {
1124 cos_bw_bitmap
|= (1 << cos_entry
);
1126 * The function also sets the BW in HW(not the mappin
1129 bnx2x_status
= bnx2x_ets_e3b0_set_cos_bw(
1130 bp
, cos_entry
, min_w_val_nig
, min_w_val_pbf
,
1132 ets_params
->cos
[cos_entry
].params
.bw_params
.bw
,
1134 } else if (bnx2x_cos_state_strict
==
1135 ets_params
->cos
[cos_entry
].state
){
1136 cos_sp_bitmap
|= (1 << cos_entry
);
1138 bnx2x_status
= bnx2x_ets_e3b0_sp_pri_to_cos_set(
1141 ets_params
->cos
[cos_entry
].params
.sp_params
.pri
,
1146 "bnx2x_ets_e3b0_config cos state not valid\n");
1149 if (0 != bnx2x_status
) {
1151 "bnx2x_ets_e3b0_config set cos bw failed\n");
1152 return bnx2x_status
;
1156 /* Set SP register (which COS has higher priority) */
1157 bnx2x_status
= bnx2x_ets_e3b0_sp_set_pri_cli_reg(params
,
1160 if (0 != bnx2x_status
) {
1162 "bnx2x_ets_E3B0_config set_pri_cli_reg failed\n");
1163 return bnx2x_status
;
1166 /* Set client mapping of BW and strict */
1167 bnx2x_status
= bnx2x_ets_e3b0_cli_map(params
, ets_params
,
1171 if (0 != bnx2x_status
) {
1172 DP(NETIF_MSG_LINK
, "bnx2x_ets_E3B0_config SP failed\n");
1173 return bnx2x_status
;
1177 static void bnx2x_ets_bw_limit_common(const struct link_params
*params
)
1179 /* ETS disabled configuration */
1180 struct bnx2x
*bp
= params
->bp
;
1181 DP(NETIF_MSG_LINK
, "ETS enabled BW limit configuration\n");
1183 * defines which entries (clients) are subjected to WFQ arbitration
1187 REG_WR(bp
, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ
, 0x18);
1189 * mapping between the ARB_CREDIT_WEIGHT registers and actual
1190 * client numbers (WEIGHT_0 does not actually have to represent
1192 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
1193 * cos1-001 cos0-000 dbg1-100 dbg0-011 MCP-010
1195 REG_WR(bp
, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP
, 0x111A);
1197 REG_WR(bp
, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0
,
1198 ETS_BW_LIMIT_CREDIT_UPPER_BOUND
);
1199 REG_WR(bp
, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1
,
1200 ETS_BW_LIMIT_CREDIT_UPPER_BOUND
);
1202 /* ETS mode enabled*/
1203 REG_WR(bp
, PBF_REG_ETS_ENABLED
, 1);
1205 /* Defines the number of consecutive slots for the strict priority */
1206 REG_WR(bp
, PBF_REG_NUM_STRICT_ARB_SLOTS
, 0);
1208 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
1209 * as strict. Bits 0,1,2 - debug and management entries, 3 - COS0
1210 * entry, 4 - COS1 entry.
1211 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1212 * bit4 bit3 bit2 bit1 bit0
1213 * MCP and debug are strict
1215 REG_WR(bp
, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT
, 0x7);
1217 /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
1218 REG_WR(bp
, PBF_REG_COS0_UPPER_BOUND
,
1219 ETS_BW_LIMIT_CREDIT_UPPER_BOUND
);
1220 REG_WR(bp
, PBF_REG_COS1_UPPER_BOUND
,
1221 ETS_BW_LIMIT_CREDIT_UPPER_BOUND
);
1224 void bnx2x_ets_bw_limit(const struct link_params
*params
, const u32 cos0_bw
,
1227 /* ETS disabled configuration*/
1228 struct bnx2x
*bp
= params
->bp
;
1229 const u32 total_bw
= cos0_bw
+ cos1_bw
;
1230 u32 cos0_credit_weight
= 0;
1231 u32 cos1_credit_weight
= 0;
1233 DP(NETIF_MSG_LINK
, "ETS enabled BW limit configuration\n");
1235 if ((0 == total_bw
) ||
1238 DP(NETIF_MSG_LINK
, "Total BW can't be zero\n");
1242 cos0_credit_weight
= (cos0_bw
* ETS_BW_LIMIT_CREDIT_WEIGHT
)/
1244 cos1_credit_weight
= (cos1_bw
* ETS_BW_LIMIT_CREDIT_WEIGHT
)/
1247 bnx2x_ets_bw_limit_common(params
);
1249 REG_WR(bp
, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0
, cos0_credit_weight
);
1250 REG_WR(bp
, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1
, cos1_credit_weight
);
1252 REG_WR(bp
, PBF_REG_COS0_WEIGHT
, cos0_credit_weight
);
1253 REG_WR(bp
, PBF_REG_COS1_WEIGHT
, cos1_credit_weight
);
1256 int bnx2x_ets_strict(const struct link_params
*params
, const u8 strict_cos
)
1258 /* ETS disabled configuration*/
1259 struct bnx2x
*bp
= params
->bp
;
1262 DP(NETIF_MSG_LINK
, "ETS enabled strict configuration\n");
1264 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
1265 * as strict. Bits 0,1,2 - debug and management entries,
1266 * 3 - COS0 entry, 4 - COS1 entry.
1267 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1268 * bit4 bit3 bit2 bit1 bit0
1269 * MCP and debug are strict
1271 REG_WR(bp
, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT
, 0x1F);
1273 * For strict priority entries defines the number of consecutive slots
1274 * for the highest priority.
1276 REG_WR(bp
, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS
, 0x100);
1277 /* ETS mode disable */
1278 REG_WR(bp
, PBF_REG_ETS_ENABLED
, 0);
1279 /* Defines the number of consecutive slots for the strict priority */
1280 REG_WR(bp
, PBF_REG_NUM_STRICT_ARB_SLOTS
, 0x100);
1282 /* Defines the number of consecutive slots for the strict priority */
1283 REG_WR(bp
, PBF_REG_HIGH_PRIORITY_COS_NUM
, strict_cos
);
1286 * mapping between entry priority to client number (0,1,2 -debug and
1287 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
1289 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
1290 * dbg0-010 dbg1-001 cos1-100 cos0-011 MCP-000
1291 * dbg0-010 dbg1-001 cos0-011 cos1-100 MCP-000
1293 val
= (0 == strict_cos
) ? 0x2318 : 0x22E0;
1294 REG_WR(bp
, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT
, val
);
1298 /******************************************************************/
1300 /******************************************************************/
1302 static void bnx2x_update_pfc_xmac(struct link_params
*params
,
1303 struct link_vars
*vars
,
1306 struct bnx2x
*bp
= params
->bp
;
1308 u32 pause_val
, pfc0_val
, pfc1_val
;
1310 /* XMAC base adrr */
1311 xmac_base
= (params
->port
) ? GRCBASE_XMAC1
: GRCBASE_XMAC0
;
1313 /* Initialize pause and pfc registers */
1314 pause_val
= 0x18000;
1315 pfc0_val
= 0xFFFF8000;
1318 /* No PFC support */
1319 if (!(params
->feature_config_flags
&
1320 FEATURE_CONFIG_PFC_ENABLED
)) {
1323 * RX flow control - Process pause frame in receive direction
1325 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_RX
)
1326 pause_val
|= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN
;
1329 * TX flow control - Send pause packet when buffer is full
1331 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
)
1332 pause_val
|= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN
;
1333 } else {/* PFC support */
1334 pfc1_val
|= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN
|
1335 XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN
|
1336 XMAC_PFC_CTRL_HI_REG_RX_PFC_EN
|
1337 XMAC_PFC_CTRL_HI_REG_TX_PFC_EN
;
1340 /* Write pause and PFC registers */
1341 REG_WR(bp
, xmac_base
+ XMAC_REG_PAUSE_CTRL
, pause_val
);
1342 REG_WR(bp
, xmac_base
+ XMAC_REG_PFC_CTRL
, pfc0_val
);
1343 REG_WR(bp
, xmac_base
+ XMAC_REG_PFC_CTRL_HI
, pfc1_val
);
1346 /* Set MAC address for source TX Pause/PFC frames */
1347 REG_WR(bp
, xmac_base
+ XMAC_REG_CTRL_SA_LO
,
1348 ((params
->mac_addr
[2] << 24) |
1349 (params
->mac_addr
[3] << 16) |
1350 (params
->mac_addr
[4] << 8) |
1351 (params
->mac_addr
[5])));
1352 REG_WR(bp
, xmac_base
+ XMAC_REG_CTRL_SA_HI
,
1353 ((params
->mac_addr
[0] << 8) |
1354 (params
->mac_addr
[1])));
1360 static void bnx2x_emac_get_pfc_stat(struct link_params
*params
,
1361 u32 pfc_frames_sent
[2],
1362 u32 pfc_frames_received
[2])
1364 /* Read pfc statistic */
1365 struct bnx2x
*bp
= params
->bp
;
1366 u32 emac_base
= params
->port
? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
1370 DP(NETIF_MSG_LINK
, "pfc statistic read from EMAC\n");
1372 /* PFC received frames */
1373 val_xoff
= REG_RD(bp
, emac_base
+
1374 EMAC_REG_RX_PFC_STATS_XOFF_RCVD
);
1375 val_xoff
&= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT
;
1376 val_xon
= REG_RD(bp
, emac_base
+ EMAC_REG_RX_PFC_STATS_XON_RCVD
);
1377 val_xon
&= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT
;
1379 pfc_frames_received
[0] = val_xon
+ val_xoff
;
1381 /* PFC received sent */
1382 val_xoff
= REG_RD(bp
, emac_base
+
1383 EMAC_REG_RX_PFC_STATS_XOFF_SENT
);
1384 val_xoff
&= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT
;
1385 val_xon
= REG_RD(bp
, emac_base
+ EMAC_REG_RX_PFC_STATS_XON_SENT
);
1386 val_xon
&= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT
;
1388 pfc_frames_sent
[0] = val_xon
+ val_xoff
;
1391 /* Read pfc statistic*/
1392 void bnx2x_pfc_statistic(struct link_params
*params
, struct link_vars
*vars
,
1393 u32 pfc_frames_sent
[2],
1394 u32 pfc_frames_received
[2])
1396 /* Read pfc statistic */
1397 struct bnx2x
*bp
= params
->bp
;
1399 DP(NETIF_MSG_LINK
, "pfc statistic\n");
1404 if (MAC_TYPE_EMAC
== vars
->mac_type
) {
1405 DP(NETIF_MSG_LINK
, "About to read PFC stats from EMAC\n");
1406 bnx2x_emac_get_pfc_stat(params
, pfc_frames_sent
,
1407 pfc_frames_received
);
1410 /******************************************************************/
1411 /* MAC/PBF section */
1412 /******************************************************************/
1413 static void bnx2x_set_mdio_clk(struct bnx2x
*bp
, u32 chip_id
, u8 port
)
1415 u32 mode
, emac_base
;
1417 * Set clause 45 mode, slow down the MDIO clock to 2.5MHz
1418 * (a value of 49==0x31) and make sure that the AUTO poll is off
1422 emac_base
= GRCBASE_EMAC0
;
1424 emac_base
= (port
) ? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
1425 mode
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MDIO_MODE
);
1426 mode
&= ~(EMAC_MDIO_MODE_AUTO_POLL
|
1427 EMAC_MDIO_MODE_CLOCK_CNT
);
1428 if (USES_WARPCORE(bp
))
1429 mode
|= (74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT
);
1431 mode
|= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT
);
1433 mode
|= (EMAC_MDIO_MODE_CLAUSE_45
);
1434 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_MDIO_MODE
, mode
);
1439 static void bnx2x_emac_init(struct link_params
*params
,
1440 struct link_vars
*vars
)
1442 /* reset and unreset the emac core */
1443 struct bnx2x
*bp
= params
->bp
;
1444 u8 port
= params
->port
;
1445 u32 emac_base
= port
? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
1449 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
1450 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE
<< port
));
1452 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
1453 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE
<< port
));
1455 /* init emac - use read-modify-write */
1456 /* self clear reset */
1457 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
1458 EMAC_WR(bp
, EMAC_REG_EMAC_MODE
, (val
| EMAC_MODE_RESET
));
1462 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
1463 DP(NETIF_MSG_LINK
, "EMAC reset reg is %u\n", val
);
1465 DP(NETIF_MSG_LINK
, "EMAC timeout!\n");
1469 } while (val
& EMAC_MODE_RESET
);
1470 bnx2x_set_mdio_clk(bp
, params
->chip_id
, port
);
1471 /* Set mac address */
1472 val
= ((params
->mac_addr
[0] << 8) |
1473 params
->mac_addr
[1]);
1474 EMAC_WR(bp
, EMAC_REG_EMAC_MAC_MATCH
, val
);
1476 val
= ((params
->mac_addr
[2] << 24) |
1477 (params
->mac_addr
[3] << 16) |
1478 (params
->mac_addr
[4] << 8) |
1479 params
->mac_addr
[5]);
1480 EMAC_WR(bp
, EMAC_REG_EMAC_MAC_MATCH
+ 4, val
);
1483 static void bnx2x_set_xumac_nig(struct link_params
*params
,
1487 struct bnx2x
*bp
= params
->bp
;
1489 REG_WR(bp
, params
->port
? NIG_REG_P1_MAC_IN_EN
: NIG_REG_P0_MAC_IN_EN
,
1491 REG_WR(bp
, params
->port
? NIG_REG_P1_MAC_OUT_EN
: NIG_REG_P0_MAC_OUT_EN
,
1493 REG_WR(bp
, params
->port
? NIG_REG_P1_MAC_PAUSE_OUT_EN
:
1494 NIG_REG_P0_MAC_PAUSE_OUT_EN
, tx_pause_en
);
1497 static void bnx2x_umac_disable(struct link_params
*params
)
1499 u32 umac_base
= params
->port
? GRCBASE_UMAC1
: GRCBASE_UMAC0
;
1500 struct bnx2x
*bp
= params
->bp
;
1501 if (!(REG_RD(bp
, MISC_REG_RESET_REG_2
) &
1502 (MISC_REGISTERS_RESET_REG_2_UMAC0
<< params
->port
)))
1505 /* Disable RX and TX */
1506 REG_WR(bp
, umac_base
+ UMAC_REG_COMMAND_CONFIG
, 0);
1509 static void bnx2x_umac_enable(struct link_params
*params
,
1510 struct link_vars
*vars
, u8 lb
)
1513 u32 umac_base
= params
->port
? GRCBASE_UMAC1
: GRCBASE_UMAC0
;
1514 struct bnx2x
*bp
= params
->bp
;
1516 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
1517 (MISC_REGISTERS_RESET_REG_2_UMAC0
<< params
->port
));
1518 usleep_range(1000, 1000);
1520 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
1521 (MISC_REGISTERS_RESET_REG_2_UMAC0
<< params
->port
));
1523 DP(NETIF_MSG_LINK
, "enabling UMAC\n");
1526 * This register determines on which events the MAC will assert
1527 * error on the i/f to the NIG along w/ EOP.
1531 * BD REG_WR(bp, NIG_REG_P0_MAC_RSV_ERR_MASK +
1532 * params->port*0x14, 0xfffff.
1534 /* This register opens the gate for the UMAC despite its name */
1535 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_PORT
+ params
->port
*4, 1);
1537 val
= UMAC_COMMAND_CONFIG_REG_PROMIS_EN
|
1538 UMAC_COMMAND_CONFIG_REG_PAD_EN
|
1539 UMAC_COMMAND_CONFIG_REG_SW_RESET
|
1540 UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK
;
1541 switch (vars
->line_speed
) {
1555 DP(NETIF_MSG_LINK
, "Invalid speed for UMAC %d\n",
1559 if (!(vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
))
1560 val
|= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE
;
1562 if (!(vars
->flow_ctrl
& BNX2X_FLOW_CTRL_RX
))
1563 val
|= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE
;
1565 REG_WR(bp
, umac_base
+ UMAC_REG_COMMAND_CONFIG
, val
);
1568 /* Set MAC address for source TX Pause/PFC frames (under SW reset) */
1569 REG_WR(bp
, umac_base
+ UMAC_REG_MAC_ADDR0
,
1570 ((params
->mac_addr
[2] << 24) |
1571 (params
->mac_addr
[3] << 16) |
1572 (params
->mac_addr
[4] << 8) |
1573 (params
->mac_addr
[5])));
1574 REG_WR(bp
, umac_base
+ UMAC_REG_MAC_ADDR1
,
1575 ((params
->mac_addr
[0] << 8) |
1576 (params
->mac_addr
[1])));
1578 /* Enable RX and TX */
1579 val
&= ~UMAC_COMMAND_CONFIG_REG_PAD_EN
;
1580 val
|= UMAC_COMMAND_CONFIG_REG_TX_ENA
|
1581 UMAC_COMMAND_CONFIG_REG_RX_ENA
;
1582 REG_WR(bp
, umac_base
+ UMAC_REG_COMMAND_CONFIG
, val
);
1585 /* Remove SW Reset */
1586 val
&= ~UMAC_COMMAND_CONFIG_REG_SW_RESET
;
1588 /* Check loopback mode */
1590 val
|= UMAC_COMMAND_CONFIG_REG_LOOP_ENA
;
1591 REG_WR(bp
, umac_base
+ UMAC_REG_COMMAND_CONFIG
, val
);
1594 * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
1595 * length used by the MAC receive logic to check frames.
1597 REG_WR(bp
, umac_base
+ UMAC_REG_MAXFR
, 0x2710);
1598 bnx2x_set_xumac_nig(params
,
1599 ((vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
) != 0), 1);
1600 vars
->mac_type
= MAC_TYPE_UMAC
;
1604 static u8
bnx2x_is_4_port_mode(struct bnx2x
*bp
)
1606 u32 port4mode_ovwr_val
;
1607 /* Check 4-port override enabled */
1608 port4mode_ovwr_val
= REG_RD(bp
, MISC_REG_PORT4MODE_EN_OVWR
);
1609 if (port4mode_ovwr_val
& (1<<0)) {
1610 /* Return 4-port mode override value */
1611 return ((port4mode_ovwr_val
& (1<<1)) == (1<<1));
1613 /* Return 4-port mode from input pin */
1614 return (u8
)REG_RD(bp
, MISC_REG_PORT4MODE_EN
);
1617 /* Define the XMAC mode */
1618 static void bnx2x_xmac_init(struct link_params
*params
, u32 max_speed
)
1620 struct bnx2x
*bp
= params
->bp
;
1621 u32 is_port4mode
= bnx2x_is_4_port_mode(bp
);
1624 * In 4-port mode, need to set the mode only once, so if XMAC is
1625 * already out of reset, it means the mode has already been set,
1626 * and it must not* reset the XMAC again, since it controls both
1630 if ((CHIP_NUM(bp
) == CHIP_NUM_57840
) &&
1631 (REG_RD(bp
, MISC_REG_RESET_REG_2
) &
1632 MISC_REGISTERS_RESET_REG_2_XMAC
)) {
1634 "XMAC already out of reset in 4-port mode\n");
1639 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
1640 MISC_REGISTERS_RESET_REG_2_XMAC
);
1641 usleep_range(1000, 1000);
1643 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
1644 MISC_REGISTERS_RESET_REG_2_XMAC
);
1646 DP(NETIF_MSG_LINK
, "Init XMAC to 2 ports x 10G per path\n");
1648 /* Set the number of ports on the system side to up to 2 */
1649 REG_WR(bp
, MISC_REG_XMAC_CORE_PORT_MODE
, 1);
1651 /* Set the number of ports on the Warp Core to 10G */
1652 REG_WR(bp
, MISC_REG_XMAC_PHY_PORT_MODE
, 3);
1654 /* Set the number of ports on the system side to 1 */
1655 REG_WR(bp
, MISC_REG_XMAC_CORE_PORT_MODE
, 0);
1656 if (max_speed
== SPEED_10000
) {
1658 "Init XMAC to 10G x 1 port per path\n");
1659 /* Set the number of ports on the Warp Core to 10G */
1660 REG_WR(bp
, MISC_REG_XMAC_PHY_PORT_MODE
, 3);
1663 "Init XMAC to 20G x 2 ports per path\n");
1664 /* Set the number of ports on the Warp Core to 20G */
1665 REG_WR(bp
, MISC_REG_XMAC_PHY_PORT_MODE
, 1);
1669 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
1670 MISC_REGISTERS_RESET_REG_2_XMAC_SOFT
);
1671 usleep_range(1000, 1000);
1673 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
1674 MISC_REGISTERS_RESET_REG_2_XMAC_SOFT
);
1678 static void bnx2x_xmac_disable(struct link_params
*params
)
1680 u8 port
= params
->port
;
1681 struct bnx2x
*bp
= params
->bp
;
1682 u32 pfc_ctrl
, xmac_base
= (port
) ? GRCBASE_XMAC1
: GRCBASE_XMAC0
;
1684 if (REG_RD(bp
, MISC_REG_RESET_REG_2
) &
1685 MISC_REGISTERS_RESET_REG_2_XMAC
) {
1687 * Send an indication to change the state in the NIG back to XON
1688 * Clearing this bit enables the next set of this bit to get
1691 pfc_ctrl
= REG_RD(bp
, xmac_base
+ XMAC_REG_PFC_CTRL_HI
);
1692 REG_WR(bp
, xmac_base
+ XMAC_REG_PFC_CTRL_HI
,
1693 (pfc_ctrl
& ~(1<<1)));
1694 REG_WR(bp
, xmac_base
+ XMAC_REG_PFC_CTRL_HI
,
1695 (pfc_ctrl
| (1<<1)));
1696 DP(NETIF_MSG_LINK
, "Disable XMAC on port %x\n", port
);
1697 REG_WR(bp
, xmac_base
+ XMAC_REG_CTRL
, 0);
1701 static int bnx2x_xmac_enable(struct link_params
*params
,
1702 struct link_vars
*vars
, u8 lb
)
1705 struct bnx2x
*bp
= params
->bp
;
1706 DP(NETIF_MSG_LINK
, "enabling XMAC\n");
1708 xmac_base
= (params
->port
) ? GRCBASE_XMAC1
: GRCBASE_XMAC0
;
1710 bnx2x_xmac_init(params
, vars
->line_speed
);
1713 * This register determines on which events the MAC will assert
1714 * error on the i/f to the NIG along w/ EOP.
1718 * This register tells the NIG whether to send traffic to UMAC
1721 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_PORT
+ params
->port
*4, 0);
1723 /* Set Max packet size */
1724 REG_WR(bp
, xmac_base
+ XMAC_REG_RX_MAX_SIZE
, 0x2710);
1726 /* CRC append for Tx packets */
1727 REG_WR(bp
, xmac_base
+ XMAC_REG_TX_CTRL
, 0xC800);
1730 bnx2x_update_pfc_xmac(params
, vars
, 0);
1732 /* Enable TX and RX */
1733 val
= XMAC_CTRL_REG_TX_EN
| XMAC_CTRL_REG_RX_EN
;
1735 /* Check loopback mode */
1737 val
|= XMAC_CTRL_REG_LINE_LOCAL_LPBK
;
1738 REG_WR(bp
, xmac_base
+ XMAC_REG_CTRL
, val
);
1739 bnx2x_set_xumac_nig(params
,
1740 ((vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
) != 0), 1);
1742 vars
->mac_type
= MAC_TYPE_XMAC
;
1746 static int bnx2x_emac_enable(struct link_params
*params
,
1747 struct link_vars
*vars
, u8 lb
)
1749 struct bnx2x
*bp
= params
->bp
;
1750 u8 port
= params
->port
;
1751 u32 emac_base
= port
? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
1754 DP(NETIF_MSG_LINK
, "enabling EMAC\n");
1757 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
1758 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
1760 /* enable emac and not bmac */
1761 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_PORT
+ port
*4, 1);
1764 if (vars
->phy_flags
& PHY_XGXS_FLAG
) {
1765 u32 ser_lane
= ((params
->lane_config
&
1766 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
1767 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
1769 DP(NETIF_MSG_LINK
, "XGXS\n");
1770 /* select the master lanes (out of 0-3) */
1771 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+ port
*4, ser_lane
);
1773 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+ port
*4, 1);
1775 } else { /* SerDes */
1776 DP(NETIF_MSG_LINK
, "SerDes\n");
1778 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+ port
*4, 0);
1781 bnx2x_bits_en(bp
, emac_base
+ EMAC_REG_EMAC_RX_MODE
,
1782 EMAC_RX_MODE_RESET
);
1783 bnx2x_bits_en(bp
, emac_base
+ EMAC_REG_EMAC_TX_MODE
,
1784 EMAC_TX_MODE_RESET
);
1786 if (CHIP_REV_IS_SLOW(bp
)) {
1787 /* config GMII mode */
1788 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
1789 EMAC_WR(bp
, EMAC_REG_EMAC_MODE
, (val
| EMAC_MODE_PORT_GMII
));
1791 /* pause enable/disable */
1792 bnx2x_bits_dis(bp
, emac_base
+ EMAC_REG_EMAC_RX_MODE
,
1793 EMAC_RX_MODE_FLOW_EN
);
1795 bnx2x_bits_dis(bp
, emac_base
+ EMAC_REG_EMAC_TX_MODE
,
1796 (EMAC_TX_MODE_EXT_PAUSE_EN
|
1797 EMAC_TX_MODE_FLOW_EN
));
1798 if (!(params
->feature_config_flags
&
1799 FEATURE_CONFIG_PFC_ENABLED
)) {
1800 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_RX
)
1801 bnx2x_bits_en(bp
, emac_base
+
1802 EMAC_REG_EMAC_RX_MODE
,
1803 EMAC_RX_MODE_FLOW_EN
);
1805 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
)
1806 bnx2x_bits_en(bp
, emac_base
+
1807 EMAC_REG_EMAC_TX_MODE
,
1808 (EMAC_TX_MODE_EXT_PAUSE_EN
|
1809 EMAC_TX_MODE_FLOW_EN
));
1811 bnx2x_bits_en(bp
, emac_base
+ EMAC_REG_EMAC_TX_MODE
,
1812 EMAC_TX_MODE_FLOW_EN
);
1815 /* KEEP_VLAN_TAG, promiscuous */
1816 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_RX_MODE
);
1817 val
|= EMAC_RX_MODE_KEEP_VLAN_TAG
| EMAC_RX_MODE_PROMISCUOUS
;
1820 * Setting this bit causes MAC control frames (except for pause
1821 * frames) to be passed on for processing. This setting has no
1822 * affect on the operation of the pause frames. This bit effects
1823 * all packets regardless of RX Parser packet sorting logic.
1824 * Turn the PFC off to make sure we are in Xon state before
1827 EMAC_WR(bp
, EMAC_REG_RX_PFC_MODE
, 0);
1828 if (params
->feature_config_flags
& FEATURE_CONFIG_PFC_ENABLED
) {
1829 DP(NETIF_MSG_LINK
, "PFC is enabled\n");
1830 /* Enable PFC again */
1831 EMAC_WR(bp
, EMAC_REG_RX_PFC_MODE
,
1832 EMAC_REG_RX_PFC_MODE_RX_EN
|
1833 EMAC_REG_RX_PFC_MODE_TX_EN
|
1834 EMAC_REG_RX_PFC_MODE_PRIORITIES
);
1836 EMAC_WR(bp
, EMAC_REG_RX_PFC_PARAM
,
1838 EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT
) |
1840 EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT
)));
1841 val
|= EMAC_RX_MODE_KEEP_MAC_CONTROL
;
1843 EMAC_WR(bp
, EMAC_REG_EMAC_RX_MODE
, val
);
1846 val
= REG_RD(bp
, emac_base
+ EMAC_REG_EMAC_MODE
);
1851 EMAC_WR(bp
, EMAC_REG_EMAC_MODE
, val
);
1854 REG_WR(bp
, NIG_REG_NIG_EMAC0_EN
+ port
*4, 1);
1856 /* enable emac for jumbo packets */
1857 EMAC_WR(bp
, EMAC_REG_EMAC_RX_MTU_SIZE
,
1858 (EMAC_RX_MTU_SIZE_JUMBO_ENA
|
1859 (ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
)));
1862 REG_WR(bp
, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC
+ port
*4, 0x1);
1864 /* disable the NIG in/out to the bmac */
1865 REG_WR(bp
, NIG_REG_BMAC0_IN_EN
+ port
*4, 0x0);
1866 REG_WR(bp
, NIG_REG_BMAC0_PAUSE_OUT_EN
+ port
*4, 0x0);
1867 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0x0);
1869 /* enable the NIG in/out to the emac */
1870 REG_WR(bp
, NIG_REG_EMAC0_IN_EN
+ port
*4, 0x1);
1872 if ((params
->feature_config_flags
&
1873 FEATURE_CONFIG_PFC_ENABLED
) ||
1874 (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
))
1877 REG_WR(bp
, NIG_REG_EMAC0_PAUSE_OUT_EN
+ port
*4, val
);
1878 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0x1);
1880 REG_WR(bp
, NIG_REG_BMAC0_REGS_OUT_EN
+ port
*4, 0x0);
1882 vars
->mac_type
= MAC_TYPE_EMAC
;
1886 static void bnx2x_update_pfc_bmac1(struct link_params
*params
,
1887 struct link_vars
*vars
)
1890 struct bnx2x
*bp
= params
->bp
;
1891 u32 bmac_addr
= params
->port
? NIG_REG_INGRESS_BMAC1_MEM
:
1892 NIG_REG_INGRESS_BMAC0_MEM
;
1895 if ((!(params
->feature_config_flags
&
1896 FEATURE_CONFIG_PFC_ENABLED
)) &&
1897 (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_RX
))
1898 /* Enable BigMAC to react on received Pause packets */
1902 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_RX_CONTROL
, wb_data
, 2);
1906 if (!(params
->feature_config_flags
&
1907 FEATURE_CONFIG_PFC_ENABLED
) &&
1908 (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
))
1912 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_TX_CONTROL
, wb_data
, 2);
1915 static void bnx2x_update_pfc_bmac2(struct link_params
*params
,
1916 struct link_vars
*vars
,
1920 * Set rx control: Strip CRC and enable BigMAC to relay
1921 * control packets to the system as well
1924 struct bnx2x
*bp
= params
->bp
;
1925 u32 bmac_addr
= params
->port
? NIG_REG_INGRESS_BMAC1_MEM
:
1926 NIG_REG_INGRESS_BMAC0_MEM
;
1929 if ((!(params
->feature_config_flags
&
1930 FEATURE_CONFIG_PFC_ENABLED
)) &&
1931 (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_RX
))
1932 /* Enable BigMAC to react on received Pause packets */
1936 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC2_REGISTER_RX_CONTROL
, wb_data
, 2);
1941 if (!(params
->feature_config_flags
&
1942 FEATURE_CONFIG_PFC_ENABLED
) &&
1943 (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
))
1947 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC2_REGISTER_TX_CONTROL
, wb_data
, 2);
1949 if (params
->feature_config_flags
& FEATURE_CONFIG_PFC_ENABLED
) {
1950 DP(NETIF_MSG_LINK
, "PFC is enabled\n");
1951 /* Enable PFC RX & TX & STATS and set 8 COS */
1953 wb_data
[0] |= (1<<0); /* RX */
1954 wb_data
[0] |= (1<<1); /* TX */
1955 wb_data
[0] |= (1<<2); /* Force initial Xon */
1956 wb_data
[0] |= (1<<3); /* 8 cos */
1957 wb_data
[0] |= (1<<5); /* STATS */
1959 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC2_REGISTER_PFC_CONTROL
,
1961 /* Clear the force Xon */
1962 wb_data
[0] &= ~(1<<2);
1964 DP(NETIF_MSG_LINK
, "PFC is disabled\n");
1965 /* disable PFC RX & TX & STATS and set 8 COS */
1970 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC2_REGISTER_PFC_CONTROL
, wb_data
, 2);
1973 * Set Time (based unit is 512 bit time) between automatic
1974 * re-sending of PP packets amd enable automatic re-send of
1975 * Per-Priroity Packet as long as pp_gen is asserted and
1976 * pp_disable is low.
1979 if (params
->feature_config_flags
& FEATURE_CONFIG_PFC_ENABLED
)
1980 val
|= (1<<16); /* enable automatic re-send */
1984 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC2_REGISTER_TX_PAUSE_CONTROL
,
1988 val
= 0x3; /* Enable RX and TX */
1990 val
|= 0x4; /* Local loopback */
1991 DP(NETIF_MSG_LINK
, "enable bmac loopback\n");
1993 /* When PFC enabled, Pass pause frames towards the NIG. */
1994 if (params
->feature_config_flags
& FEATURE_CONFIG_PFC_ENABLED
)
1995 val
|= ((1<<6)|(1<<5));
1999 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC2_REGISTER_BMAC_CONTROL
, wb_data
, 2);
2003 /* PFC BRB internal port configuration params */
2004 struct bnx2x_pfc_brb_threshold_val
{
2011 struct bnx2x_pfc_brb_e3b0_val
{
2012 u32 full_lb_xoff_th
;
2013 u32 full_lb_xon_threshold
;
2015 u32 mac_0_class_t_guarantied
;
2016 u32 mac_0_class_t_guarantied_hyst
;
2017 u32 mac_1_class_t_guarantied
;
2018 u32 mac_1_class_t_guarantied_hyst
;
2021 struct bnx2x_pfc_brb_th_val
{
2022 struct bnx2x_pfc_brb_threshold_val pauseable_th
;
2023 struct bnx2x_pfc_brb_threshold_val non_pauseable_th
;
2025 static int bnx2x_pfc_brb_get_config_params(
2026 struct link_params
*params
,
2027 struct bnx2x_pfc_brb_th_val
*config_val
)
2029 struct bnx2x
*bp
= params
->bp
;
2030 DP(NETIF_MSG_LINK
, "Setting PFC BRB configuration\n");
2031 if (CHIP_IS_E2(bp
)) {
2032 config_val
->pauseable_th
.pause_xoff
=
2033 PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE
;
2034 config_val
->pauseable_th
.pause_xon
=
2035 PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE
;
2036 config_val
->pauseable_th
.full_xoff
=
2037 PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE
;
2038 config_val
->pauseable_th
.full_xon
=
2039 PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE
;
2041 config_val
->non_pauseable_th
.pause_xoff
=
2042 PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE
;
2043 config_val
->non_pauseable_th
.pause_xon
=
2044 PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE
;
2045 config_val
->non_pauseable_th
.full_xoff
=
2046 PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE
;
2047 config_val
->non_pauseable_th
.full_xon
=
2048 PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE
;
2049 } else if (CHIP_IS_E3A0(bp
)) {
2050 config_val
->pauseable_th
.pause_xoff
=
2051 PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE
;
2052 config_val
->pauseable_th
.pause_xon
=
2053 PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE
;
2054 config_val
->pauseable_th
.full_xoff
=
2055 PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE
;
2056 config_val
->pauseable_th
.full_xon
=
2057 PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE
;
2059 config_val
->non_pauseable_th
.pause_xoff
=
2060 PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE
;
2061 config_val
->non_pauseable_th
.pause_xon
=
2062 PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE
;
2063 config_val
->non_pauseable_th
.full_xoff
=
2064 PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE
;
2065 config_val
->non_pauseable_th
.full_xon
=
2066 PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE
;
2067 } else if (CHIP_IS_E3B0(bp
)) {
2068 if (params
->phy
[INT_PHY
].flags
&
2069 FLAGS_4_PORT_MODE
) {
2070 config_val
->pauseable_th
.pause_xoff
=
2071 PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE
;
2072 config_val
->pauseable_th
.pause_xon
=
2073 PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE
;
2074 config_val
->pauseable_th
.full_xoff
=
2075 PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE
;
2076 config_val
->pauseable_th
.full_xon
=
2077 PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE
;
2079 config_val
->non_pauseable_th
.pause_xoff
=
2080 PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE
;
2081 config_val
->non_pauseable_th
.pause_xon
=
2082 PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE
;
2083 config_val
->non_pauseable_th
.full_xoff
=
2084 PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE
;
2085 config_val
->non_pauseable_th
.full_xon
=
2086 PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE
;
2088 config_val
->pauseable_th
.pause_xoff
=
2089 PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE
;
2090 config_val
->pauseable_th
.pause_xon
=
2091 PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE
;
2092 config_val
->pauseable_th
.full_xoff
=
2093 PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE
;
2094 config_val
->pauseable_th
.full_xon
=
2095 PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE
;
2097 config_val
->non_pauseable_th
.pause_xoff
=
2098 PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE
;
2099 config_val
->non_pauseable_th
.pause_xon
=
2100 PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE
;
2101 config_val
->non_pauseable_th
.full_xoff
=
2102 PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE
;
2103 config_val
->non_pauseable_th
.full_xon
=
2104 PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE
;
2113 static void bnx2x_pfc_brb_get_e3b0_config_params(struct link_params
*params
,
2114 struct bnx2x_pfc_brb_e3b0_val
2119 if (params
->phy
[INT_PHY
].flags
& FLAGS_4_PORT_MODE
) {
2120 e3b0_val
->full_lb_xoff_th
=
2121 PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR
;
2122 e3b0_val
->full_lb_xon_threshold
=
2123 PFC_E3B0_4P_BRB_FULL_LB_XON_THR
;
2124 e3b0_val
->lb_guarantied
=
2125 PFC_E3B0_4P_LB_GUART
;
2126 e3b0_val
->mac_0_class_t_guarantied
=
2127 PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART
;
2128 e3b0_val
->mac_0_class_t_guarantied_hyst
=
2129 PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST
;
2130 e3b0_val
->mac_1_class_t_guarantied
=
2131 PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART
;
2132 e3b0_val
->mac_1_class_t_guarantied_hyst
=
2133 PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST
;
2135 e3b0_val
->full_lb_xoff_th
=
2136 PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR
;
2137 e3b0_val
->full_lb_xon_threshold
=
2138 PFC_E3B0_2P_BRB_FULL_LB_XON_THR
;
2139 e3b0_val
->mac_0_class_t_guarantied_hyst
=
2140 PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST
;
2141 e3b0_val
->mac_1_class_t_guarantied
=
2142 PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART
;
2143 e3b0_val
->mac_1_class_t_guarantied_hyst
=
2144 PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST
;
2146 if (cos0_pauseable
!= cos1_pauseable
) {
2147 /* nonpauseable= Lossy + pauseable = Lossless*/
2148 e3b0_val
->lb_guarantied
=
2149 PFC_E3B0_2P_MIX_PAUSE_LB_GUART
;
2150 e3b0_val
->mac_0_class_t_guarantied
=
2151 PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART
;
2152 } else if (cos0_pauseable
) {
2153 /* Lossless +Lossless*/
2154 e3b0_val
->lb_guarantied
=
2155 PFC_E3B0_2P_PAUSE_LB_GUART
;
2156 e3b0_val
->mac_0_class_t_guarantied
=
2157 PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART
;
2160 e3b0_val
->lb_guarantied
=
2161 PFC_E3B0_2P_NON_PAUSE_LB_GUART
;
2162 e3b0_val
->mac_0_class_t_guarantied
=
2163 PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART
;
2167 static int bnx2x_update_pfc_brb(struct link_params
*params
,
2168 struct link_vars
*vars
,
2169 struct bnx2x_nig_brb_pfc_port_params
2172 struct bnx2x
*bp
= params
->bp
;
2173 struct bnx2x_pfc_brb_th_val config_val
= { {0} };
2174 struct bnx2x_pfc_brb_threshold_val
*reg_th_config
=
2175 &config_val
.pauseable_th
;
2176 struct bnx2x_pfc_brb_e3b0_val e3b0_val
= {0};
2177 int set_pfc
= params
->feature_config_flags
&
2178 FEATURE_CONFIG_PFC_ENABLED
;
2179 int bnx2x_status
= 0;
2180 u8 port
= params
->port
;
2182 /* default - pause configuration */
2183 reg_th_config
= &config_val
.pauseable_th
;
2184 bnx2x_status
= bnx2x_pfc_brb_get_config_params(params
, &config_val
);
2185 if (0 != bnx2x_status
)
2186 return bnx2x_status
;
2188 if (set_pfc
&& pfc_params
)
2190 if (!pfc_params
->cos0_pauseable
)
2191 reg_th_config
= &config_val
.non_pauseable_th
;
2193 * The number of free blocks below which the pause signal to class 0
2194 * of MAC #n is asserted. n=0,1
2196 REG_WR(bp
, (port
) ? BRB1_REG_PAUSE_0_XOFF_THRESHOLD_1
:
2197 BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0
,
2198 reg_th_config
->pause_xoff
);
2200 * The number of free blocks above which the pause signal to class 0
2201 * of MAC #n is de-asserted. n=0,1
2203 REG_WR(bp
, (port
) ? BRB1_REG_PAUSE_0_XON_THRESHOLD_1
:
2204 BRB1_REG_PAUSE_0_XON_THRESHOLD_0
, reg_th_config
->pause_xon
);
2206 * The number of free blocks below which the full signal to class 0
2207 * of MAC #n is asserted. n=0,1
2209 REG_WR(bp
, (port
) ? BRB1_REG_FULL_0_XOFF_THRESHOLD_1
:
2210 BRB1_REG_FULL_0_XOFF_THRESHOLD_0
, reg_th_config
->full_xoff
);
2212 * The number of free blocks above which the full signal to class 0
2213 * of MAC #n is de-asserted. n=0,1
2215 REG_WR(bp
, (port
) ? BRB1_REG_FULL_0_XON_THRESHOLD_1
:
2216 BRB1_REG_FULL_0_XON_THRESHOLD_0
, reg_th_config
->full_xon
);
2218 if (set_pfc
&& pfc_params
) {
2220 if (pfc_params
->cos1_pauseable
)
2221 reg_th_config
= &config_val
.pauseable_th
;
2223 reg_th_config
= &config_val
.non_pauseable_th
;
2225 * The number of free blocks below which the pause signal to
2226 * class 1 of MAC #n is asserted. n=0,1
2228 REG_WR(bp
, (port
) ? BRB1_REG_PAUSE_1_XOFF_THRESHOLD_1
:
2229 BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0
,
2230 reg_th_config
->pause_xoff
);
2232 * The number of free blocks above which the pause signal to
2233 * class 1 of MAC #n is de-asserted. n=0,1
2235 REG_WR(bp
, (port
) ? BRB1_REG_PAUSE_1_XON_THRESHOLD_1
:
2236 BRB1_REG_PAUSE_1_XON_THRESHOLD_0
,
2237 reg_th_config
->pause_xon
);
2239 * The number of free blocks below which the full signal to
2240 * class 1 of MAC #n is asserted. n=0,1
2242 REG_WR(bp
, (port
) ? BRB1_REG_FULL_1_XOFF_THRESHOLD_1
:
2243 BRB1_REG_FULL_1_XOFF_THRESHOLD_0
,
2244 reg_th_config
->full_xoff
);
2246 * The number of free blocks above which the full signal to
2247 * class 1 of MAC #n is de-asserted. n=0,1
2249 REG_WR(bp
, (port
) ? BRB1_REG_FULL_1_XON_THRESHOLD_1
:
2250 BRB1_REG_FULL_1_XON_THRESHOLD_0
,
2251 reg_th_config
->full_xon
);
2254 if (CHIP_IS_E3B0(bp
)) {
2255 /*Should be done by init tool */
2257 * BRB_empty_for_dup = BRB1_REG_BRB_EMPTY_THRESHOLD
2263 * The hysteresis on the guarantied buffer space for the Lb port
2264 * before signaling XON.
2266 REG_WR(bp
, BRB1_REG_LB_GUARANTIED_HYST
, 80);
2268 bnx2x_pfc_brb_get_e3b0_config_params(
2271 pfc_params
->cos0_pauseable
,
2272 pfc_params
->cos1_pauseable
);
2274 * The number of free blocks below which the full signal to the
2275 * LB port is asserted.
2277 REG_WR(bp
, BRB1_REG_FULL_LB_XOFF_THRESHOLD
,
2278 e3b0_val
.full_lb_xoff_th
);
2280 * The number of free blocks above which the full signal to the
2281 * LB port is de-asserted.
2283 REG_WR(bp
, BRB1_REG_FULL_LB_XON_THRESHOLD
,
2284 e3b0_val
.full_lb_xon_threshold
);
2286 * The number of blocks guarantied for the MAC #n port. n=0,1
2289 /*The number of blocks guarantied for the LB port.*/
2290 REG_WR(bp
, BRB1_REG_LB_GUARANTIED
,
2291 e3b0_val
.lb_guarantied
);
2294 * The number of blocks guarantied for the MAC #n port.
2296 REG_WR(bp
, BRB1_REG_MAC_GUARANTIED_0
,
2297 2 * e3b0_val
.mac_0_class_t_guarantied
);
2298 REG_WR(bp
, BRB1_REG_MAC_GUARANTIED_1
,
2299 2 * e3b0_val
.mac_1_class_t_guarantied
);
2301 * The number of blocks guarantied for class #t in MAC0. t=0,1
2303 REG_WR(bp
, BRB1_REG_MAC_0_CLASS_0_GUARANTIED
,
2304 e3b0_val
.mac_0_class_t_guarantied
);
2305 REG_WR(bp
, BRB1_REG_MAC_0_CLASS_1_GUARANTIED
,
2306 e3b0_val
.mac_0_class_t_guarantied
);
2308 * The hysteresis on the guarantied buffer space for class in
2311 REG_WR(bp
, BRB1_REG_MAC_0_CLASS_0_GUARANTIED_HYST
,
2312 e3b0_val
.mac_0_class_t_guarantied_hyst
);
2313 REG_WR(bp
, BRB1_REG_MAC_0_CLASS_1_GUARANTIED_HYST
,
2314 e3b0_val
.mac_0_class_t_guarantied_hyst
);
2317 * The number of blocks guarantied for class #t in MAC1.t=0,1
2319 REG_WR(bp
, BRB1_REG_MAC_1_CLASS_0_GUARANTIED
,
2320 e3b0_val
.mac_1_class_t_guarantied
);
2321 REG_WR(bp
, BRB1_REG_MAC_1_CLASS_1_GUARANTIED
,
2322 e3b0_val
.mac_1_class_t_guarantied
);
2324 * The hysteresis on the guarantied buffer space for class #t
2327 REG_WR(bp
, BRB1_REG_MAC_1_CLASS_0_GUARANTIED_HYST
,
2328 e3b0_val
.mac_1_class_t_guarantied_hyst
);
2329 REG_WR(bp
, BRB1_REG_MAC_1_CLASS_1_GUARANTIED_HYST
,
2330 e3b0_val
.mac_1_class_t_guarantied_hyst
);
2336 return bnx2x_status
;
2339 /******************************************************************************
2341 * This function is needed because NIG ARB_CREDIT_WEIGHT_X are
2342 * not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
2343 ******************************************************************************/
2344 int bnx2x_pfc_nig_rx_priority_mask(struct bnx2x
*bp
,
2346 u32 priority_mask
, u8 port
)
2348 u32 nig_reg_rx_priority_mask_add
= 0;
2350 switch (cos_entry
) {
2352 nig_reg_rx_priority_mask_add
= (port
) ?
2353 NIG_REG_P1_RX_COS0_PRIORITY_MASK
:
2354 NIG_REG_P0_RX_COS0_PRIORITY_MASK
;
2357 nig_reg_rx_priority_mask_add
= (port
) ?
2358 NIG_REG_P1_RX_COS1_PRIORITY_MASK
:
2359 NIG_REG_P0_RX_COS1_PRIORITY_MASK
;
2362 nig_reg_rx_priority_mask_add
= (port
) ?
2363 NIG_REG_P1_RX_COS2_PRIORITY_MASK
:
2364 NIG_REG_P0_RX_COS2_PRIORITY_MASK
;
2369 nig_reg_rx_priority_mask_add
= NIG_REG_P0_RX_COS3_PRIORITY_MASK
;
2374 nig_reg_rx_priority_mask_add
= NIG_REG_P0_RX_COS4_PRIORITY_MASK
;
2379 nig_reg_rx_priority_mask_add
= NIG_REG_P0_RX_COS5_PRIORITY_MASK
;
2383 REG_WR(bp
, nig_reg_rx_priority_mask_add
, priority_mask
);
2387 static void bnx2x_update_mng(struct link_params
*params
, u32 link_status
)
2389 struct bnx2x
*bp
= params
->bp
;
2391 REG_WR(bp
, params
->shmem_base
+
2392 offsetof(struct shmem_region
,
2393 port_mb
[params
->port
].link_status
), link_status
);
2396 static void bnx2x_update_pfc_nig(struct link_params
*params
,
2397 struct link_vars
*vars
,
2398 struct bnx2x_nig_brb_pfc_port_params
*nig_params
)
2400 u32 xcm_mask
= 0, ppp_enable
= 0, pause_enable
= 0, llfc_out_en
= 0;
2401 u32 llfc_enable
= 0, xcm0_out_en
= 0, p0_hwpfc_enable
= 0;
2402 u32 pkt_priority_to_cos
= 0;
2403 struct bnx2x
*bp
= params
->bp
;
2404 u8 port
= params
->port
;
2406 int set_pfc
= params
->feature_config_flags
&
2407 FEATURE_CONFIG_PFC_ENABLED
;
2408 DP(NETIF_MSG_LINK
, "updating pfc nig parameters\n");
2411 * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
2412 * MAC control frames (that are not pause packets)
2413 * will be forwarded to the XCM.
2415 xcm_mask
= REG_RD(bp
,
2416 port
? NIG_REG_LLH1_XCM_MASK
:
2417 NIG_REG_LLH0_XCM_MASK
);
2419 * nig params will override non PFC params, since it's possible to
2420 * do transition from PFC to SAFC
2430 xcm_mask
&= ~(port
? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN
:
2431 NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN
);
2433 p0_hwpfc_enable
= 1;
2436 llfc_out_en
= nig_params
->llfc_out_en
;
2437 llfc_enable
= nig_params
->llfc_enable
;
2438 pause_enable
= nig_params
->pause_enable
;
2439 } else /*defaul non PFC mode - PAUSE */
2442 xcm_mask
|= (port
? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN
:
2443 NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN
);
2448 REG_WR(bp
, port
? NIG_REG_BRB1_PAUSE_IN_EN
:
2449 NIG_REG_BRB0_PAUSE_IN_EN
, pause_enable
);
2450 REG_WR(bp
, port
? NIG_REG_LLFC_OUT_EN_1
:
2451 NIG_REG_LLFC_OUT_EN_0
, llfc_out_en
);
2452 REG_WR(bp
, port
? NIG_REG_LLFC_ENABLE_1
:
2453 NIG_REG_LLFC_ENABLE_0
, llfc_enable
);
2454 REG_WR(bp
, port
? NIG_REG_PAUSE_ENABLE_1
:
2455 NIG_REG_PAUSE_ENABLE_0
, pause_enable
);
2457 REG_WR(bp
, port
? NIG_REG_PPP_ENABLE_1
:
2458 NIG_REG_PPP_ENABLE_0
, ppp_enable
);
2460 REG_WR(bp
, port
? NIG_REG_LLH1_XCM_MASK
:
2461 NIG_REG_LLH0_XCM_MASK
, xcm_mask
);
2463 REG_WR(bp
, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0
, 0x7);
2465 /* output enable for RX_XCM # IF */
2466 REG_WR(bp
, NIG_REG_XCM0_OUT_EN
, xcm0_out_en
);
2468 /* HW PFC TX enable */
2469 REG_WR(bp
, NIG_REG_P0_HWPFC_ENABLE
, p0_hwpfc_enable
);
2473 pkt_priority_to_cos
= nig_params
->pkt_priority_to_cos
;
2475 for (i
= 0; i
< nig_params
->num_of_rx_cos_priority_mask
; i
++)
2476 bnx2x_pfc_nig_rx_priority_mask(bp
, i
,
2477 nig_params
->rx_cos_priority_mask
[i
], port
);
2479 REG_WR(bp
, port
? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1
:
2480 NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0
,
2481 nig_params
->llfc_high_priority_classes
);
2483 REG_WR(bp
, port
? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1
:
2484 NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0
,
2485 nig_params
->llfc_low_priority_classes
);
2487 REG_WR(bp
, port
? NIG_REG_P1_PKT_PRIORITY_TO_COS
:
2488 NIG_REG_P0_PKT_PRIORITY_TO_COS
,
2489 pkt_priority_to_cos
);
2492 int bnx2x_update_pfc(struct link_params
*params
,
2493 struct link_vars
*vars
,
2494 struct bnx2x_nig_brb_pfc_port_params
*pfc_params
)
2497 * The PFC and pause are orthogonal to one another, meaning when
2498 * PFC is enabled, the pause are disabled, and when PFC is
2499 * disabled, pause are set according to the pause result.
2502 struct bnx2x
*bp
= params
->bp
;
2503 int bnx2x_status
= 0;
2504 u8 bmac_loopback
= (params
->loopback_mode
== LOOPBACK_BMAC
);
2506 if (params
->feature_config_flags
& FEATURE_CONFIG_PFC_ENABLED
)
2507 vars
->link_status
|= LINK_STATUS_PFC_ENABLED
;
2509 vars
->link_status
&= ~LINK_STATUS_PFC_ENABLED
;
2511 bnx2x_update_mng(params
, vars
->link_status
);
2513 /* update NIG params */
2514 bnx2x_update_pfc_nig(params
, vars
, pfc_params
);
2516 /* update BRB params */
2517 bnx2x_status
= bnx2x_update_pfc_brb(params
, vars
, pfc_params
);
2518 if (0 != bnx2x_status
)
2519 return bnx2x_status
;
2522 return bnx2x_status
;
2524 DP(NETIF_MSG_LINK
, "About to update PFC in BMAC\n");
2526 bnx2x_update_pfc_xmac(params
, vars
, 0);
2528 val
= REG_RD(bp
, MISC_REG_RESET_REG_2
);
2530 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< params
->port
))
2532 DP(NETIF_MSG_LINK
, "About to update PFC in EMAC\n");
2533 bnx2x_emac_enable(params
, vars
, 0);
2534 return bnx2x_status
;
2538 bnx2x_update_pfc_bmac2(params
, vars
, bmac_loopback
);
2540 bnx2x_update_pfc_bmac1(params
, vars
);
2543 if ((params
->feature_config_flags
&
2544 FEATURE_CONFIG_PFC_ENABLED
) ||
2545 (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
))
2547 REG_WR(bp
, NIG_REG_BMAC0_PAUSE_OUT_EN
+ params
->port
*4, val
);
2549 return bnx2x_status
;
2553 static int bnx2x_bmac1_enable(struct link_params
*params
,
2554 struct link_vars
*vars
,
2557 struct bnx2x
*bp
= params
->bp
;
2558 u8 port
= params
->port
;
2559 u32 bmac_addr
= port
? NIG_REG_INGRESS_BMAC1_MEM
:
2560 NIG_REG_INGRESS_BMAC0_MEM
;
2564 DP(NETIF_MSG_LINK
, "Enabling BigMAC1\n");
2569 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_BMAC_XGXS_CONTROL
,
2573 wb_data
[0] = ((params
->mac_addr
[2] << 24) |
2574 (params
->mac_addr
[3] << 16) |
2575 (params
->mac_addr
[4] << 8) |
2576 params
->mac_addr
[5]);
2577 wb_data
[1] = ((params
->mac_addr
[0] << 8) |
2578 params
->mac_addr
[1]);
2579 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_TX_SOURCE_ADDR
, wb_data
, 2);
2585 DP(NETIF_MSG_LINK
, "enable bmac loopback\n");
2589 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_BMAC_CONTROL
, wb_data
, 2);
2592 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
2594 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_RX_MAX_SIZE
, wb_data
, 2);
2596 bnx2x_update_pfc_bmac1(params
, vars
);
2599 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
2601 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_TX_MAX_SIZE
, wb_data
, 2);
2603 /* set cnt max size */
2604 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
2606 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_CNT_MAX_SIZE
, wb_data
, 2);
2608 /* configure safc */
2609 wb_data
[0] = 0x1000200;
2611 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC_REGISTER_RX_LLFC_MSG_FLDS
,
2617 static int bnx2x_bmac2_enable(struct link_params
*params
,
2618 struct link_vars
*vars
,
2621 struct bnx2x
*bp
= params
->bp
;
2622 u8 port
= params
->port
;
2623 u32 bmac_addr
= port
? NIG_REG_INGRESS_BMAC1_MEM
:
2624 NIG_REG_INGRESS_BMAC0_MEM
;
2627 DP(NETIF_MSG_LINK
, "Enabling BigMAC2\n");
2631 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC2_REGISTER_BMAC_CONTROL
, wb_data
, 2);
2634 /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
2637 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC2_REGISTER_BMAC_XGXS_CONTROL
,
2643 wb_data
[0] = ((params
->mac_addr
[2] << 24) |
2644 (params
->mac_addr
[3] << 16) |
2645 (params
->mac_addr
[4] << 8) |
2646 params
->mac_addr
[5]);
2647 wb_data
[1] = ((params
->mac_addr
[0] << 8) |
2648 params
->mac_addr
[1]);
2649 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC2_REGISTER_TX_SOURCE_ADDR
,
2654 /* Configure SAFC */
2655 wb_data
[0] = 0x1000200;
2657 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS
,
2662 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
2664 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC2_REGISTER_RX_MAX_SIZE
, wb_data
, 2);
2668 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
;
2670 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC2_REGISTER_TX_MAX_SIZE
, wb_data
, 2);
2672 /* set cnt max size */
2673 wb_data
[0] = ETH_MAX_JUMBO_PACKET_SIZE
+ ETH_OVREHEAD
- 2;
2675 REG_WR_DMAE(bp
, bmac_addr
+ BIGMAC2_REGISTER_CNT_MAX_SIZE
, wb_data
, 2);
2677 bnx2x_update_pfc_bmac2(params
, vars
, is_lb
);
2682 static int bnx2x_bmac_enable(struct link_params
*params
,
2683 struct link_vars
*vars
,
2687 u8 port
= params
->port
;
2688 struct bnx2x
*bp
= params
->bp
;
2690 /* reset and unreset the BigMac */
2691 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
2692 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
2695 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_SET
,
2696 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
2698 /* enable access for bmac registers */
2699 REG_WR(bp
, NIG_REG_BMAC0_REGS_OUT_EN
+ port
*4, 0x1);
2701 /* Enable BMAC according to BMAC type*/
2703 rc
= bnx2x_bmac2_enable(params
, vars
, is_lb
);
2705 rc
= bnx2x_bmac1_enable(params
, vars
, is_lb
);
2706 REG_WR(bp
, NIG_REG_XGXS_SERDES0_MODE_SEL
+ port
*4, 0x1);
2707 REG_WR(bp
, NIG_REG_XGXS_LANE_SEL_P0
+ port
*4, 0x0);
2708 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_PORT
+ port
*4, 0x0);
2710 if ((params
->feature_config_flags
&
2711 FEATURE_CONFIG_PFC_ENABLED
) ||
2712 (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
))
2714 REG_WR(bp
, NIG_REG_BMAC0_PAUSE_OUT_EN
+ port
*4, val
);
2715 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0x0);
2716 REG_WR(bp
, NIG_REG_EMAC0_IN_EN
+ port
*4, 0x0);
2717 REG_WR(bp
, NIG_REG_EMAC0_PAUSE_OUT_EN
+ port
*4, 0x0);
2718 REG_WR(bp
, NIG_REG_BMAC0_IN_EN
+ port
*4, 0x1);
2719 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0x1);
2721 vars
->mac_type
= MAC_TYPE_BMAC
;
2725 static void bnx2x_bmac_rx_disable(struct bnx2x
*bp
, u8 port
)
2727 u32 bmac_addr
= port
? NIG_REG_INGRESS_BMAC1_MEM
:
2728 NIG_REG_INGRESS_BMAC0_MEM
;
2730 u32 nig_bmac_enable
= REG_RD(bp
, NIG_REG_BMAC0_REGS_OUT_EN
+ port
*4);
2732 /* Only if the bmac is out of reset */
2733 if (REG_RD(bp
, MISC_REG_RESET_REG_2
) &
2734 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
) &&
2737 if (CHIP_IS_E2(bp
)) {
2738 /* Clear Rx Enable bit in BMAC_CONTROL register */
2739 REG_RD_DMAE(bp
, bmac_addr
+
2740 BIGMAC2_REGISTER_BMAC_CONTROL
,
2742 wb_data
[0] &= ~BMAC_CONTROL_RX_ENABLE
;
2743 REG_WR_DMAE(bp
, bmac_addr
+
2744 BIGMAC2_REGISTER_BMAC_CONTROL
,
2747 /* Clear Rx Enable bit in BMAC_CONTROL register */
2748 REG_RD_DMAE(bp
, bmac_addr
+
2749 BIGMAC_REGISTER_BMAC_CONTROL
,
2751 wb_data
[0] &= ~BMAC_CONTROL_RX_ENABLE
;
2752 REG_WR_DMAE(bp
, bmac_addr
+
2753 BIGMAC_REGISTER_BMAC_CONTROL
,
2760 static int bnx2x_pbf_update(struct link_params
*params
, u32 flow_ctrl
,
2763 struct bnx2x
*bp
= params
->bp
;
2764 u8 port
= params
->port
;
2769 REG_WR(bp
, PBF_REG_DISABLE_NEW_TASK_PROC_P0
+ port
*4, 0x1);
2771 /* wait for init credit */
2772 init_crd
= REG_RD(bp
, PBF_REG_P0_INIT_CRD
+ port
*4);
2773 crd
= REG_RD(bp
, PBF_REG_P0_CREDIT
+ port
*8);
2774 DP(NETIF_MSG_LINK
, "init_crd 0x%x crd 0x%x\n", init_crd
, crd
);
2776 while ((init_crd
!= crd
) && count
) {
2779 crd
= REG_RD(bp
, PBF_REG_P0_CREDIT
+ port
*8);
2782 crd
= REG_RD(bp
, PBF_REG_P0_CREDIT
+ port
*8);
2783 if (init_crd
!= crd
) {
2784 DP(NETIF_MSG_LINK
, "BUG! init_crd 0x%x != crd 0x%x\n",
2789 if (flow_ctrl
& BNX2X_FLOW_CTRL_RX
||
2790 line_speed
== SPEED_10
||
2791 line_speed
== SPEED_100
||
2792 line_speed
== SPEED_1000
||
2793 line_speed
== SPEED_2500
) {
2794 REG_WR(bp
, PBF_REG_P0_PAUSE_ENABLE
+ port
*4, 1);
2795 /* update threshold */
2796 REG_WR(bp
, PBF_REG_P0_ARB_THRSH
+ port
*4, 0);
2797 /* update init credit */
2798 init_crd
= 778; /* (800-18-4) */
2801 u32 thresh
= (ETH_MAX_JUMBO_PACKET_SIZE
+
2803 REG_WR(bp
, PBF_REG_P0_PAUSE_ENABLE
+ port
*4, 0);
2804 /* update threshold */
2805 REG_WR(bp
, PBF_REG_P0_ARB_THRSH
+ port
*4, thresh
);
2806 /* update init credit */
2807 switch (line_speed
) {
2809 init_crd
= thresh
+ 553 - 22;
2812 DP(NETIF_MSG_LINK
, "Invalid line_speed 0x%x\n",
2817 REG_WR(bp
, PBF_REG_P0_INIT_CRD
+ port
*4, init_crd
);
2818 DP(NETIF_MSG_LINK
, "PBF updated to speed %d credit %d\n",
2819 line_speed
, init_crd
);
2821 /* probe the credit changes */
2822 REG_WR(bp
, PBF_REG_INIT_P0
+ port
*4, 0x1);
2824 REG_WR(bp
, PBF_REG_INIT_P0
+ port
*4, 0x0);
2827 REG_WR(bp
, PBF_REG_DISABLE_NEW_TASK_PROC_P0
+ port
*4, 0x0);
2832 * bnx2x_get_emac_base - retrive emac base address
2834 * @bp: driver handle
2835 * @mdc_mdio_access: access type
2838 * This function selects the MDC/MDIO access (through emac0 or
2839 * emac1) depend on the mdc_mdio_access, port, port swapped. Each
2840 * phy has a default access mode, which could also be overridden
2841 * by nvram configuration. This parameter, whether this is the
2842 * default phy configuration, or the nvram overrun
2843 * configuration, is passed here as mdc_mdio_access and selects
2844 * the emac_base for the CL45 read/writes operations
2846 static u32
bnx2x_get_emac_base(struct bnx2x
*bp
,
2847 u32 mdc_mdio_access
, u8 port
)
2850 switch (mdc_mdio_access
) {
2851 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE
:
2853 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0
:
2854 if (REG_RD(bp
, NIG_REG_PORT_SWAP
))
2855 emac_base
= GRCBASE_EMAC1
;
2857 emac_base
= GRCBASE_EMAC0
;
2859 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1
:
2860 if (REG_RD(bp
, NIG_REG_PORT_SWAP
))
2861 emac_base
= GRCBASE_EMAC0
;
2863 emac_base
= GRCBASE_EMAC1
;
2865 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH
:
2866 emac_base
= (port
) ? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
2868 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED
:
2869 emac_base
= (port
) ? GRCBASE_EMAC0
: GRCBASE_EMAC1
;
2878 /******************************************************************/
2879 /* CL22 access functions */
2880 /******************************************************************/
2881 static int bnx2x_cl22_write(struct bnx2x
*bp
,
2882 struct bnx2x_phy
*phy
,
2888 /* Switch to CL22 */
2889 mode
= REG_RD(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
2890 REG_WR(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
,
2891 mode
& ~EMAC_MDIO_MODE_CLAUSE_45
);
2894 tmp
= ((phy
->addr
<< 21) | (reg
<< 16) | val
|
2895 EMAC_MDIO_COMM_COMMAND_WRITE_22
|
2896 EMAC_MDIO_COMM_START_BUSY
);
2897 REG_WR(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, tmp
);
2899 for (i
= 0; i
< 50; i
++) {
2902 tmp
= REG_RD(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
);
2903 if (!(tmp
& EMAC_MDIO_COMM_START_BUSY
)) {
2908 if (tmp
& EMAC_MDIO_COMM_START_BUSY
) {
2909 DP(NETIF_MSG_LINK
, "write phy register failed\n");
2912 REG_WR(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, mode
);
2916 static int bnx2x_cl22_read(struct bnx2x
*bp
,
2917 struct bnx2x_phy
*phy
,
2918 u16 reg
, u16
*ret_val
)
2924 /* Switch to CL22 */
2925 mode
= REG_RD(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
);
2926 REG_WR(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
,
2927 mode
& ~EMAC_MDIO_MODE_CLAUSE_45
);
2930 val
= ((phy
->addr
<< 21) | (reg
<< 16) |
2931 EMAC_MDIO_COMM_COMMAND_READ_22
|
2932 EMAC_MDIO_COMM_START_BUSY
);
2933 REG_WR(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, val
);
2935 for (i
= 0; i
< 50; i
++) {
2938 val
= REG_RD(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
);
2939 if (!(val
& EMAC_MDIO_COMM_START_BUSY
)) {
2940 *ret_val
= (u16
)(val
& EMAC_MDIO_COMM_DATA
);
2945 if (val
& EMAC_MDIO_COMM_START_BUSY
) {
2946 DP(NETIF_MSG_LINK
, "read phy register failed\n");
2951 REG_WR(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_MODE
, mode
);
2955 /******************************************************************/
2956 /* CL45 access functions */
2957 /******************************************************************/
2958 static int bnx2x_cl45_read(struct bnx2x
*bp
, struct bnx2x_phy
*phy
,
2959 u8 devad
, u16 reg
, u16
*ret_val
)
2964 if (phy
->flags
& FLAGS_MDC_MDIO_WA_B0
)
2965 bnx2x_bits_en(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_STATUS
,
2966 EMAC_MDIO_STATUS_10MB
);
2968 val
= ((phy
->addr
<< 21) | (devad
<< 16) | reg
|
2969 EMAC_MDIO_COMM_COMMAND_ADDRESS
|
2970 EMAC_MDIO_COMM_START_BUSY
);
2971 REG_WR(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, val
);
2973 for (i
= 0; i
< 50; i
++) {
2976 val
= REG_RD(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
);
2977 if (!(val
& EMAC_MDIO_COMM_START_BUSY
)) {
2982 if (val
& EMAC_MDIO_COMM_START_BUSY
) {
2983 DP(NETIF_MSG_LINK
, "read phy register failed\n");
2984 netdev_err(bp
->dev
, "MDC/MDIO access timeout\n");
2989 val
= ((phy
->addr
<< 21) | (devad
<< 16) |
2990 EMAC_MDIO_COMM_COMMAND_READ_45
|
2991 EMAC_MDIO_COMM_START_BUSY
);
2992 REG_WR(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, val
);
2994 for (i
= 0; i
< 50; i
++) {
2997 val
= REG_RD(bp
, phy
->mdio_ctrl
+
2998 EMAC_REG_EMAC_MDIO_COMM
);
2999 if (!(val
& EMAC_MDIO_COMM_START_BUSY
)) {
3000 *ret_val
= (u16
)(val
& EMAC_MDIO_COMM_DATA
);
3004 if (val
& EMAC_MDIO_COMM_START_BUSY
) {
3005 DP(NETIF_MSG_LINK
, "read phy register failed\n");
3006 netdev_err(bp
->dev
, "MDC/MDIO access timeout\n");
3011 /* Work around for E3 A0 */
3012 if (phy
->flags
& FLAGS_MDC_MDIO_WA
) {
3013 phy
->flags
^= FLAGS_DUMMY_READ
;
3014 if (phy
->flags
& FLAGS_DUMMY_READ
) {
3016 bnx2x_cl45_read(bp
, phy
, devad
, 0xf, &temp_val
);
3020 if (phy
->flags
& FLAGS_MDC_MDIO_WA_B0
)
3021 bnx2x_bits_dis(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_STATUS
,
3022 EMAC_MDIO_STATUS_10MB
);
3026 static int bnx2x_cl45_write(struct bnx2x
*bp
, struct bnx2x_phy
*phy
,
3027 u8 devad
, u16 reg
, u16 val
)
3032 if (phy
->flags
& FLAGS_MDC_MDIO_WA_B0
)
3033 bnx2x_bits_en(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_STATUS
,
3034 EMAC_MDIO_STATUS_10MB
);
3038 tmp
= ((phy
->addr
<< 21) | (devad
<< 16) | reg
|
3039 EMAC_MDIO_COMM_COMMAND_ADDRESS
|
3040 EMAC_MDIO_COMM_START_BUSY
);
3041 REG_WR(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, tmp
);
3043 for (i
= 0; i
< 50; i
++) {
3046 tmp
= REG_RD(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
);
3047 if (!(tmp
& EMAC_MDIO_COMM_START_BUSY
)) {
3052 if (tmp
& EMAC_MDIO_COMM_START_BUSY
) {
3053 DP(NETIF_MSG_LINK
, "write phy register failed\n");
3054 netdev_err(bp
->dev
, "MDC/MDIO access timeout\n");
3059 tmp
= ((phy
->addr
<< 21) | (devad
<< 16) | val
|
3060 EMAC_MDIO_COMM_COMMAND_WRITE_45
|
3061 EMAC_MDIO_COMM_START_BUSY
);
3062 REG_WR(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_COMM
, tmp
);
3064 for (i
= 0; i
< 50; i
++) {
3067 tmp
= REG_RD(bp
, phy
->mdio_ctrl
+
3068 EMAC_REG_EMAC_MDIO_COMM
);
3069 if (!(tmp
& EMAC_MDIO_COMM_START_BUSY
)) {
3074 if (tmp
& EMAC_MDIO_COMM_START_BUSY
) {
3075 DP(NETIF_MSG_LINK
, "write phy register failed\n");
3076 netdev_err(bp
->dev
, "MDC/MDIO access timeout\n");
3080 /* Work around for E3 A0 */
3081 if (phy
->flags
& FLAGS_MDC_MDIO_WA
) {
3082 phy
->flags
^= FLAGS_DUMMY_READ
;
3083 if (phy
->flags
& FLAGS_DUMMY_READ
) {
3085 bnx2x_cl45_read(bp
, phy
, devad
, 0xf, &temp_val
);
3088 if (phy
->flags
& FLAGS_MDC_MDIO_WA_B0
)
3089 bnx2x_bits_dis(bp
, phy
->mdio_ctrl
+ EMAC_REG_EMAC_MDIO_STATUS
,
3090 EMAC_MDIO_STATUS_10MB
);
3095 /******************************************************************/
3096 /* BSC access functions from E3 */
3097 /******************************************************************/
3098 static void bnx2x_bsc_module_sel(struct link_params
*params
)
3101 u32 board_cfg
, sfp_ctrl
;
3102 u32 i2c_pins
[I2C_SWITCH_WIDTH
], i2c_val
[I2C_SWITCH_WIDTH
];
3103 struct bnx2x
*bp
= params
->bp
;
3104 u8 port
= params
->port
;
3105 /* Read I2C output PINs */
3106 board_cfg
= REG_RD(bp
, params
->shmem_base
+
3107 offsetof(struct shmem_region
,
3108 dev_info
.shared_hw_config
.board
));
3109 i2c_pins
[I2C_BSC0
] = board_cfg
& SHARED_HW_CFG_E3_I2C_MUX0_MASK
;
3110 i2c_pins
[I2C_BSC1
] = (board_cfg
& SHARED_HW_CFG_E3_I2C_MUX1_MASK
) >>
3111 SHARED_HW_CFG_E3_I2C_MUX1_SHIFT
;
3113 /* Read I2C output value */
3114 sfp_ctrl
= REG_RD(bp
, params
->shmem_base
+
3115 offsetof(struct shmem_region
,
3116 dev_info
.port_hw_config
[port
].e3_cmn_pin_cfg
));
3117 i2c_val
[I2C_BSC0
] = (sfp_ctrl
& PORT_HW_CFG_E3_I2C_MUX0_MASK
) > 0;
3118 i2c_val
[I2C_BSC1
] = (sfp_ctrl
& PORT_HW_CFG_E3_I2C_MUX1_MASK
) > 0;
3119 DP(NETIF_MSG_LINK
, "Setting BSC switch\n");
3120 for (idx
= 0; idx
< I2C_SWITCH_WIDTH
; idx
++)
3121 bnx2x_set_cfg_pin(bp
, i2c_pins
[idx
], i2c_val
[idx
]);
3124 static int bnx2x_bsc_read(struct link_params
*params
,
3125 struct bnx2x_phy
*phy
,
3134 struct bnx2x
*bp
= params
->bp
;
3136 if ((sl_devid
!= 0xa0) && (sl_devid
!= 0xa2)) {
3137 DP(NETIF_MSG_LINK
, "invalid sl_devid 0x%x\n", sl_devid
);
3141 if (xfer_cnt
> 16) {
3142 DP(NETIF_MSG_LINK
, "invalid xfer_cnt %d. Max is 16 bytes\n",
3146 bnx2x_bsc_module_sel(params
);
3148 xfer_cnt
= 16 - lc_addr
;
3150 /* enable the engine */
3151 val
= REG_RD(bp
, MCP_REG_MCPR_IMC_COMMAND
);
3152 val
|= MCPR_IMC_COMMAND_ENABLE
;
3153 REG_WR(bp
, MCP_REG_MCPR_IMC_COMMAND
, val
);
3155 /* program slave device ID */
3156 val
= (sl_devid
<< 16) | sl_addr
;
3157 REG_WR(bp
, MCP_REG_MCPR_IMC_SLAVE_CONTROL
, val
);
3159 /* start xfer with 0 byte to update the address pointer ???*/
3160 val
= (MCPR_IMC_COMMAND_ENABLE
) |
3161 (MCPR_IMC_COMMAND_WRITE_OP
<<
3162 MCPR_IMC_COMMAND_OPERATION_BITSHIFT
) |
3163 (lc_addr
<< MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT
) | (0);
3164 REG_WR(bp
, MCP_REG_MCPR_IMC_COMMAND
, val
);
3166 /* poll for completion */
3168 val
= REG_RD(bp
, MCP_REG_MCPR_IMC_COMMAND
);
3169 while (((val
>> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT
) & 0x3) != 1) {
3171 val
= REG_RD(bp
, MCP_REG_MCPR_IMC_COMMAND
);
3173 DP(NETIF_MSG_LINK
, "wr 0 byte timed out after %d try\n",
3182 /* start xfer with read op */
3183 val
= (MCPR_IMC_COMMAND_ENABLE
) |
3184 (MCPR_IMC_COMMAND_READ_OP
<<
3185 MCPR_IMC_COMMAND_OPERATION_BITSHIFT
) |
3186 (lc_addr
<< MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT
) |
3188 REG_WR(bp
, MCP_REG_MCPR_IMC_COMMAND
, val
);
3190 /* poll for completion */
3192 val
= REG_RD(bp
, MCP_REG_MCPR_IMC_COMMAND
);
3193 while (((val
>> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT
) & 0x3) != 1) {
3195 val
= REG_RD(bp
, MCP_REG_MCPR_IMC_COMMAND
);
3197 DP(NETIF_MSG_LINK
, "rd op timed out after %d try\n", i
);
3205 for (i
= (lc_addr
>> 2); i
< 4; i
++) {
3206 data_array
[i
] = REG_RD(bp
, (MCP_REG_MCPR_IMC_DATAREG0
+ i
*4));
3208 data_array
[i
] = ((data_array
[i
] & 0x000000ff) << 24) |
3209 ((data_array
[i
] & 0x0000ff00) << 8) |
3210 ((data_array
[i
] & 0x00ff0000) >> 8) |
3211 ((data_array
[i
] & 0xff000000) >> 24);
3217 static void bnx2x_cl45_read_or_write(struct bnx2x
*bp
, struct bnx2x_phy
*phy
,
3218 u8 devad
, u16 reg
, u16 or_val
)
3221 bnx2x_cl45_read(bp
, phy
, devad
, reg
, &val
);
3222 bnx2x_cl45_write(bp
, phy
, devad
, reg
, val
| or_val
);
3225 int bnx2x_phy_read(struct link_params
*params
, u8 phy_addr
,
3226 u8 devad
, u16 reg
, u16
*ret_val
)
3230 * Probe for the phy according to the given phy_addr, and execute
3231 * the read request on it
3233 for (phy_index
= 0; phy_index
< params
->num_phys
; phy_index
++) {
3234 if (params
->phy
[phy_index
].addr
== phy_addr
) {
3235 return bnx2x_cl45_read(params
->bp
,
3236 ¶ms
->phy
[phy_index
], devad
,
3243 int bnx2x_phy_write(struct link_params
*params
, u8 phy_addr
,
3244 u8 devad
, u16 reg
, u16 val
)
3248 * Probe for the phy according to the given phy_addr, and execute
3249 * the write request on it
3251 for (phy_index
= 0; phy_index
< params
->num_phys
; phy_index
++) {
3252 if (params
->phy
[phy_index
].addr
== phy_addr
) {
3253 return bnx2x_cl45_write(params
->bp
,
3254 ¶ms
->phy
[phy_index
], devad
,
3260 static u8
bnx2x_get_warpcore_lane(struct bnx2x_phy
*phy
,
3261 struct link_params
*params
)
3264 struct bnx2x
*bp
= params
->bp
;
3265 u32 path_swap
, path_swap_ovr
;
3269 port
= params
->port
;
3271 if (bnx2x_is_4_port_mode(bp
)) {
3272 u32 port_swap
, port_swap_ovr
;
3274 /*figure out path swap value */
3275 path_swap_ovr
= REG_RD(bp
, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR
);
3276 if (path_swap_ovr
& 0x1)
3277 path_swap
= (path_swap_ovr
& 0x2);
3279 path_swap
= REG_RD(bp
, MISC_REG_FOUR_PORT_PATH_SWAP
);
3284 /*figure out port swap value */
3285 port_swap_ovr
= REG_RD(bp
, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR
);
3286 if (port_swap_ovr
& 0x1)
3287 port_swap
= (port_swap_ovr
& 0x2);
3289 port_swap
= REG_RD(bp
, MISC_REG_FOUR_PORT_PORT_SWAP
);
3294 lane
= (port
<<1) + path
;
3295 } else { /* two port mode - no port swap */
3297 /*figure out path swap value */
3299 REG_RD(bp
, MISC_REG_TWO_PORT_PATH_SWAP_OVWR
);
3300 if (path_swap_ovr
& 0x1) {
3301 path_swap
= (path_swap_ovr
& 0x2);
3304 REG_RD(bp
, MISC_REG_TWO_PORT_PATH_SWAP
);
3314 static void bnx2x_set_aer_mmd(struct link_params
*params
,
3315 struct bnx2x_phy
*phy
)
3318 u16 offset
, aer_val
;
3319 struct bnx2x
*bp
= params
->bp
;
3320 ser_lane
= ((params
->lane_config
&
3321 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
3322 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
3324 offset
= (phy
->type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) ?
3325 (phy
->addr
+ ser_lane
) : 0;
3327 if (USES_WARPCORE(bp
)) {
3328 aer_val
= bnx2x_get_warpcore_lane(phy
, params
);
3330 * In Dual-lane mode, two lanes are joined together,
3331 * so in order to configure them, the AER broadcast method is
3333 * 0x200 is the broadcast address for lanes 0,1
3334 * 0x201 is the broadcast address for lanes 2,3
3336 if (phy
->flags
& FLAGS_WC_DUAL_MODE
)
3337 aer_val
= (aer_val
>> 1) | 0x200;
3338 } else if (CHIP_IS_E2(bp
))
3339 aer_val
= 0x3800 + offset
- 1;
3341 aer_val
= 0x3800 + offset
;
3342 DP(NETIF_MSG_LINK
, "Set AER to 0x%x\n", aer_val
);
3343 CL22_WR_OVER_CL45(bp
, phy
, MDIO_REG_BANK_AER_BLOCK
,
3344 MDIO_AER_BLOCK_AER_REG
, aer_val
);
3348 /******************************************************************/
3349 /* Internal phy section */
3350 /******************************************************************/
3352 static void bnx2x_set_serdes_access(struct bnx2x
*bp
, u8 port
)
3354 u32 emac_base
= (port
) ? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
3357 REG_WR(bp
, NIG_REG_SERDES0_CTRL_MD_ST
+ port
*0x10, 1);
3358 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_MDIO_COMM
, 0x245f8000);
3360 REG_WR(bp
, emac_base
+ EMAC_REG_EMAC_MDIO_COMM
, 0x245d000f);
3363 REG_WR(bp
, NIG_REG_SERDES0_CTRL_MD_ST
+ port
*0x10, 0);
3366 static void bnx2x_serdes_deassert(struct bnx2x
*bp
, u8 port
)
3370 DP(NETIF_MSG_LINK
, "bnx2x_serdes_deassert\n");
3372 val
= SERDES_RESET_BITS
<< (port
*16);
3374 /* reset and unreset the SerDes/XGXS */
3375 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_CLEAR
, val
);
3377 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_SET
, val
);
3379 bnx2x_set_serdes_access(bp
, port
);
3381 REG_WR(bp
, NIG_REG_SERDES0_CTRL_MD_DEVAD
+ port
*0x10,
3382 DEFAULT_PHY_DEV_ADDR
);
3385 static void bnx2x_xgxs_deassert(struct link_params
*params
)
3387 struct bnx2x
*bp
= params
->bp
;
3390 DP(NETIF_MSG_LINK
, "bnx2x_xgxs_deassert\n");
3391 port
= params
->port
;
3393 val
= XGXS_RESET_BITS
<< (port
*16);
3395 /* reset and unreset the SerDes/XGXS */
3396 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_CLEAR
, val
);
3398 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_SET
, val
);
3400 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_ST
+ port
*0x18, 0);
3401 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_DEVAD
+ port
*0x18,
3402 params
->phy
[INT_PHY
].def_md_devad
);
3405 static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy
*phy
,
3406 struct link_params
*params
, u16
*ieee_fc
)
3408 struct bnx2x
*bp
= params
->bp
;
3409 *ieee_fc
= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX
;
3411 * resolve pause mode and advertisement Please refer to Table
3412 * 28B-3 of the 802.3ab-1999 spec
3415 switch (phy
->req_flow_ctrl
) {
3416 case BNX2X_FLOW_CTRL_AUTO
:
3417 if (params
->req_fc_auto_adv
== BNX2X_FLOW_CTRL_BOTH
)
3418 *ieee_fc
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
3421 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
;
3424 case BNX2X_FLOW_CTRL_TX
:
3425 *ieee_fc
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
;
3428 case BNX2X_FLOW_CTRL_RX
:
3429 case BNX2X_FLOW_CTRL_BOTH
:
3430 *ieee_fc
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
3433 case BNX2X_FLOW_CTRL_NONE
:
3435 *ieee_fc
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE
;
3438 DP(NETIF_MSG_LINK
, "ieee_fc = 0x%x\n", *ieee_fc
);
3441 static void set_phy_vars(struct link_params
*params
,
3442 struct link_vars
*vars
)
3444 struct bnx2x
*bp
= params
->bp
;
3445 u8 actual_phy_idx
, phy_index
, link_cfg_idx
;
3446 u8 phy_config_swapped
= params
->multi_phy_config
&
3447 PORT_HW_CFG_PHY_SWAPPED_ENABLED
;
3448 for (phy_index
= INT_PHY
; phy_index
< params
->num_phys
;
3450 link_cfg_idx
= LINK_CONFIG_IDX(phy_index
);
3451 actual_phy_idx
= phy_index
;
3452 if (phy_config_swapped
) {
3453 if (phy_index
== EXT_PHY1
)
3454 actual_phy_idx
= EXT_PHY2
;
3455 else if (phy_index
== EXT_PHY2
)
3456 actual_phy_idx
= EXT_PHY1
;
3458 params
->phy
[actual_phy_idx
].req_flow_ctrl
=
3459 params
->req_flow_ctrl
[link_cfg_idx
];
3461 params
->phy
[actual_phy_idx
].req_line_speed
=
3462 params
->req_line_speed
[link_cfg_idx
];
3464 params
->phy
[actual_phy_idx
].speed_cap_mask
=
3465 params
->speed_cap_mask
[link_cfg_idx
];
3467 params
->phy
[actual_phy_idx
].req_duplex
=
3468 params
->req_duplex
[link_cfg_idx
];
3470 if (params
->req_line_speed
[link_cfg_idx
] ==
3472 vars
->link_status
|= LINK_STATUS_AUTO_NEGOTIATE_ENABLED
;
3474 DP(NETIF_MSG_LINK
, "req_flow_ctrl %x, req_line_speed %x,"
3475 " speed_cap_mask %x\n",
3476 params
->phy
[actual_phy_idx
].req_flow_ctrl
,
3477 params
->phy
[actual_phy_idx
].req_line_speed
,
3478 params
->phy
[actual_phy_idx
].speed_cap_mask
);
3482 static void bnx2x_ext_phy_set_pause(struct link_params
*params
,
3483 struct bnx2x_phy
*phy
,
3484 struct link_vars
*vars
)
3487 struct bnx2x
*bp
= params
->bp
;
3488 /* read modify write pause advertizing */
3489 bnx2x_cl45_read(bp
, phy
, MDIO_AN_DEVAD
, MDIO_AN_REG_ADV_PAUSE
, &val
);
3491 val
&= ~MDIO_AN_REG_ADV_PAUSE_BOTH
;
3493 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3494 bnx2x_calc_ieee_aneg_adv(phy
, params
, &vars
->ieee_fc
);
3495 if ((vars
->ieee_fc
&
3496 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) ==
3497 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) {
3498 val
|= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC
;
3500 if ((vars
->ieee_fc
&
3501 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) ==
3502 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) {
3503 val
|= MDIO_AN_REG_ADV_PAUSE_PAUSE
;
3505 DP(NETIF_MSG_LINK
, "Ext phy AN advertize 0x%x\n", val
);
3506 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
, MDIO_AN_REG_ADV_PAUSE
, val
);
3509 static void bnx2x_pause_resolve(struct link_vars
*vars
, u32 pause_result
)
3511 switch (pause_result
) { /* ASYM P ASYM P */
3512 case 0xb: /* 1 0 1 1 */
3513 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_TX
;
3516 case 0xe: /* 1 1 1 0 */
3517 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_RX
;
3520 case 0x5: /* 0 1 0 1 */
3521 case 0x7: /* 0 1 1 1 */
3522 case 0xd: /* 1 1 0 1 */
3523 case 0xf: /* 1 1 1 1 */
3524 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_BOTH
;
3530 if (pause_result
& (1<<0))
3531 vars
->link_status
|= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE
;
3532 if (pause_result
& (1<<1))
3533 vars
->link_status
|= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE
;
3536 static u8
bnx2x_ext_phy_resolve_fc(struct bnx2x_phy
*phy
,
3537 struct link_params
*params
,
3538 struct link_vars
*vars
)
3540 struct bnx2x
*bp
= params
->bp
;
3541 u16 ld_pause
; /* local */
3542 u16 lp_pause
; /* link partner */
3547 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
3549 if (phy
->req_flow_ctrl
!= BNX2X_FLOW_CTRL_AUTO
)
3550 vars
->flow_ctrl
= phy
->req_flow_ctrl
;
3551 else if (phy
->req_line_speed
!= SPEED_AUTO_NEG
)
3552 vars
->flow_ctrl
= params
->req_fc_auto_adv
;
3553 else if (vars
->link_status
& LINK_STATUS_AUTO_NEGOTIATE_COMPLETE
) {
3555 if (phy
->type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE
) {
3556 bnx2x_cl22_read(bp
, phy
,
3558 bnx2x_cl22_read(bp
, phy
,
3561 bnx2x_cl45_read(bp
, phy
,
3563 MDIO_AN_REG_ADV_PAUSE
, &ld_pause
);
3564 bnx2x_cl45_read(bp
, phy
,
3566 MDIO_AN_REG_LP_AUTO_NEG
, &lp_pause
);
3568 pause_result
= (ld_pause
&
3569 MDIO_AN_REG_ADV_PAUSE_MASK
) >> 8;
3570 pause_result
|= (lp_pause
&
3571 MDIO_AN_REG_ADV_PAUSE_MASK
) >> 10;
3572 DP(NETIF_MSG_LINK
, "Ext PHY pause result 0x%x\n",
3574 bnx2x_pause_resolve(vars
, pause_result
);
3578 /******************************************************************/
3579 /* Warpcore section */
3580 /******************************************************************/
3581 /* The init_internal_warpcore should mirror the xgxs,
3582 * i.e. reset the lane (if needed), set aer for the
3583 * init configuration, and set/clear SGMII flag. Internal
3584 * phy init is done purely in phy_init stage.
3586 static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy
*phy
,
3587 struct link_params
*params
,
3588 struct link_vars
*vars
) {
3589 u16 val16
= 0, lane
, bam37
= 0;
3590 struct bnx2x
*bp
= params
->bp
;
3591 DP(NETIF_MSG_LINK
, "Enable Auto Negotiation for KR\n");
3593 /* Disable Autoneg: re-enable it after adv is done. */
3594 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
,
3595 MDIO_WC_REG_IEEE0BLK_MIICNTL
, 0);
3597 /* Check adding advertisement for 1G KX */
3598 if (((vars
->line_speed
== SPEED_AUTO_NEG
) &&
3599 (phy
->speed_cap_mask
& PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
)) ||
3600 (vars
->line_speed
== SPEED_1000
)) {
3604 /* Enable CL37 1G Parallel Detect */
3605 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3606 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2
, &sd_digital
);
3607 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3608 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2
,
3609 (sd_digital
| 0x1));
3611 DP(NETIF_MSG_LINK
, "Advertize 1G\n");
3613 if (((vars
->line_speed
== SPEED_AUTO_NEG
) &&
3614 (phy
->speed_cap_mask
& PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)) ||
3615 (vars
->line_speed
== SPEED_10000
)) {
3616 /* Check adding advertisement for 10G KR */
3618 /* Enable 10G Parallel Detect */
3619 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
,
3620 MDIO_WC_REG_PAR_DET_10G_CTRL
, 1);
3622 DP(NETIF_MSG_LINK
, "Advertize 10G\n");
3625 /* Set Transmit PMD settings */
3626 lane
= bnx2x_get_warpcore_lane(phy
, params
);
3627 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3628 MDIO_WC_REG_TX0_TX_DRIVER
+ 0x10*lane
,
3629 ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET
) |
3630 (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET
) |
3631 (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET
)));
3632 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3633 MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL
,
3635 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3636 MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL
,
3639 /* Advertised speeds */
3640 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
,
3641 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1
, val16
);
3643 /* Advertised and set FEC (Forward Error Correction) */
3644 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
,
3645 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2
,
3646 (MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY
|
3647 MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ
));
3649 /* Enable CL37 BAM */
3650 if (REG_RD(bp
, params
->shmem_base
+
3651 offsetof(struct shmem_region
, dev_info
.
3652 port_hw_config
[params
->port
].default_cfg
)) &
3653 PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED
) {
3654 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3655 MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL
, &bam37
);
3656 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3657 MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL
, bam37
| 1);
3658 DP(NETIF_MSG_LINK
, "Enable CL37 BAM on KR\n");
3661 /* Advertise pause */
3662 bnx2x_ext_phy_set_pause(params
, phy
, vars
);
3664 vars
->rx_tx_asic_rst
= MAX_KR_LINK_RETRY
;
3666 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3667 MDIO_WC_REG_DIGITAL5_MISC7
, &val16
);
3669 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3670 MDIO_WC_REG_DIGITAL5_MISC7
, val16
| 0x100);
3672 /* Over 1G - AN local device user page 1 */
3673 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3674 MDIO_WC_REG_DIGITAL3_UP1
, 0x1f);
3676 /* Enable Autoneg */
3677 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
,
3678 MDIO_WC_REG_IEEE0BLK_MIICNTL
, 0x1000);
3682 static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy
*phy
,
3683 struct link_params
*params
,
3684 struct link_vars
*vars
)
3686 struct bnx2x
*bp
= params
->bp
;
3689 /* Disable Autoneg */
3690 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3691 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2
, 0x7);
3693 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
,
3694 MDIO_WC_REG_PAR_DET_10G_CTRL
, 0);
3696 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3697 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL
, 0x3f00);
3699 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
,
3700 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1
, 0);
3702 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
,
3703 MDIO_WC_REG_IEEE0BLK_MIICNTL
, 0x0);
3705 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3706 MDIO_WC_REG_DIGITAL3_UP1
, 0x1);
3708 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3709 MDIO_WC_REG_DIGITAL5_MISC7
, 0xa);
3711 /* Disable CL36 PCS Tx */
3712 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3713 MDIO_WC_REG_XGXSBLK1_LANECTRL0
, 0x0);
3715 /* Double Wide Single Data Rate @ pll rate */
3716 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3717 MDIO_WC_REG_XGXSBLK1_LANECTRL1
, 0xFFFF);
3719 /* Leave cl72 training enable, needed for KR */
3720 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
,
3721 MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150
,
3724 /* Leave CL72 enabled */
3725 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3726 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL
,
3728 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3729 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL
,
3732 /* Set speed via PMA/PMD register */
3733 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
,
3734 MDIO_WC_REG_IEEE0BLK_MIICNTL
, 0x2040);
3736 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
,
3737 MDIO_WC_REG_IEEE0BLK_AUTONEGNP
, 0xB);
3739 /*Enable encoded forced speed */
3740 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3741 MDIO_WC_REG_SERDESDIGITAL_MISC2
, 0x30);
3743 /* Turn TX scramble payload only the 64/66 scrambler */
3744 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3745 MDIO_WC_REG_TX66_CONTROL
, 0x9);
3747 /* Turn RX scramble payload only the 64/66 scrambler */
3748 bnx2x_cl45_read_or_write(bp
, phy
, MDIO_WC_DEVAD
,
3749 MDIO_WC_REG_RX66_CONTROL
, 0xF9);
3751 /* set and clear loopback to cause a reset to 64/66 decoder */
3752 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3753 MDIO_WC_REG_IEEE0BLK_MIICNTL
, 0x4000);
3754 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3755 MDIO_WC_REG_IEEE0BLK_MIICNTL
, 0x0);
3759 static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy
*phy
,
3760 struct link_params
*params
,
3763 struct bnx2x
*bp
= params
->bp
;
3764 u16 misc1_val
, tap_val
, tx_driver_val
, lane
, val
;
3765 /* Hold rxSeqStart */
3766 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3767 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0
, &val
);
3768 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3769 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0
, (val
| 0x8000));
3771 /* Hold tx_fifo_reset */
3772 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3773 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3
, &val
);
3774 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3775 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3
, (val
| 0x1));
3777 /* Disable CL73 AN */
3778 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
, MDIO_AN_REG_CTRL
, 0);
3780 /* Disable 100FX Enable and Auto-Detect */
3781 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3782 MDIO_WC_REG_FX100_CTRL1
, &val
);
3783 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3784 MDIO_WC_REG_FX100_CTRL1
, (val
& 0xFFFA));
3786 /* Disable 100FX Idle detect */
3787 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3788 MDIO_WC_REG_FX100_CTRL3
, &val
);
3789 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3790 MDIO_WC_REG_FX100_CTRL3
, (val
| 0x0080));
3792 /* Set Block address to Remote PHY & Clear forced_speed[5] */
3793 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3794 MDIO_WC_REG_DIGITAL4_MISC3
, &val
);
3795 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3796 MDIO_WC_REG_DIGITAL4_MISC3
, (val
& 0xFF7F));
3798 /* Turn off auto-detect & fiber mode */
3799 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3800 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1
, &val
);
3801 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3802 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1
,
3805 /* Set filter_force_link, disable_false_link and parallel_detect */
3806 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3807 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2
, &val
);
3808 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3809 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2
,
3810 ((val
| 0x0006) & 0xFFFE));
3813 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3814 MDIO_WC_REG_SERDESDIGITAL_MISC1
, &misc1_val
);
3816 misc1_val
&= ~(0x1f);
3820 tap_val
= ((0x08 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET
) |
3821 (0x37 << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET
) |
3822 (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET
));
3824 ((0x00 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET
) |
3825 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET
) |
3826 (0x03 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET
));
3830 tap_val
= ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET
) |
3831 (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET
) |
3832 (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET
));
3834 ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET
) |
3835 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET
) |
3836 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET
));
3838 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3839 MDIO_WC_REG_SERDESDIGITAL_MISC1
, misc1_val
);
3841 /* Set Transmit PMD settings */
3842 lane
= bnx2x_get_warpcore_lane(phy
, params
);
3843 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3844 MDIO_WC_REG_TX_FIR_TAP
,
3845 tap_val
| MDIO_WC_REG_TX_FIR_TAP_ENABLE
);
3846 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3847 MDIO_WC_REG_TX0_TX_DRIVER
+ 0x10*lane
,
3850 /* Enable fiber mode, enable and invert sig_det */
3851 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3852 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1
, &val
);
3853 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3854 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1
, val
| 0xd);
3856 /* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
3857 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3858 MDIO_WC_REG_DIGITAL4_MISC3
, &val
);
3859 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3860 MDIO_WC_REG_DIGITAL4_MISC3
, val
| 0x8080);
3862 /* 10G XFI Full Duplex */
3863 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3864 MDIO_WC_REG_IEEE0BLK_MIICNTL
, 0x100);
3866 /* Release tx_fifo_reset */
3867 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3868 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3
, &val
);
3869 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3870 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3
, val
& 0xFFFE);
3872 /* Release rxSeqStart */
3873 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3874 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0
, &val
);
3875 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3876 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0
, (val
& 0x7FFF));
3879 static void bnx2x_warpcore_set_20G_KR2(struct bnx2x
*bp
,
3880 struct bnx2x_phy
*phy
)
3882 DP(NETIF_MSG_LINK
, "KR2 still not supported !!!\n");
3885 static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x
*bp
,
3886 struct bnx2x_phy
*phy
,
3889 /* Rx0 anaRxControl1G */
3890 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3891 MDIO_WC_REG_RX0_ANARXCONTROL1G
, 0x90);
3893 /* Rx2 anaRxControl1G */
3894 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3895 MDIO_WC_REG_RX2_ANARXCONTROL1G
, 0x90);
3897 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3898 MDIO_WC_REG_RX66_SCW0
, 0xE070);
3900 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3901 MDIO_WC_REG_RX66_SCW1
, 0xC0D0);
3903 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3904 MDIO_WC_REG_RX66_SCW2
, 0xA0B0);
3906 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3907 MDIO_WC_REG_RX66_SCW3
, 0x8090);
3909 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3910 MDIO_WC_REG_RX66_SCW0_MASK
, 0xF0F0);
3912 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3913 MDIO_WC_REG_RX66_SCW1_MASK
, 0xF0F0);
3915 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3916 MDIO_WC_REG_RX66_SCW2_MASK
, 0xF0F0);
3918 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3919 MDIO_WC_REG_RX66_SCW3_MASK
, 0xF0F0);
3921 /* Serdes Digital Misc1 */
3922 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3923 MDIO_WC_REG_SERDESDIGITAL_MISC1
, 0x6008);
3925 /* Serdes Digital4 Misc3 */
3926 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3927 MDIO_WC_REG_DIGITAL4_MISC3
, 0x8088);
3929 /* Set Transmit PMD settings */
3930 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3931 MDIO_WC_REG_TX_FIR_TAP
,
3932 ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET
) |
3933 (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET
) |
3934 (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET
) |
3935 MDIO_WC_REG_TX_FIR_TAP_ENABLE
));
3936 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3937 MDIO_WC_REG_TX0_TX_DRIVER
+ 0x10*lane
,
3938 ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET
) |
3939 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET
) |
3940 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET
)));
3943 static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy
*phy
,
3944 struct link_params
*params
,
3947 struct bnx2x
*bp
= params
->bp
;
3948 u16 val16
, digctrl_kx1
, digctrl_kx2
;
3951 lane
= bnx2x_get_warpcore_lane(phy
, params
);
3953 /* Clear XFI clock comp in non-10G single lane mode. */
3954 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3955 MDIO_WC_REG_RX66_CONTROL
, &val16
);
3956 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3957 MDIO_WC_REG_RX66_CONTROL
, val16
& ~(3<<13));
3959 if (phy
->req_line_speed
== SPEED_AUTO_NEG
) {
3961 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3962 MDIO_WC_REG_COMBO_IEEE0_MIICTRL
, &val16
);
3963 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3964 MDIO_WC_REG_COMBO_IEEE0_MIICTRL
,
3966 DP(NETIF_MSG_LINK
, "set SGMII AUTONEG\n");
3968 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3969 MDIO_WC_REG_COMBO_IEEE0_MIICTRL
, &val16
);
3971 switch (phy
->req_line_speed
) {
3982 "Speed not supported: 0x%x\n", phy
->req_line_speed
);
3986 if (phy
->req_duplex
== DUPLEX_FULL
)
3989 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
3990 MDIO_WC_REG_COMBO_IEEE0_MIICTRL
, val16
);
3992 DP(NETIF_MSG_LINK
, "set SGMII force speed %d\n",
3993 phy
->req_line_speed
);
3994 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
3995 MDIO_WC_REG_COMBO_IEEE0_MIICTRL
, &val16
);
3996 DP(NETIF_MSG_LINK
, " (readback) %x\n", val16
);
3999 /* SGMII Slave mode and disable signal detect */
4000 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
4001 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1
, &digctrl_kx1
);
4005 digctrl_kx1
&= 0xff4a;
4007 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4008 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1
,
4011 /* Turn off parallel detect */
4012 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
4013 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2
, &digctrl_kx2
);
4014 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4015 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2
,
4016 (digctrl_kx2
& ~(1<<2)));
4018 /* Re-enable parallel detect */
4019 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4020 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2
,
4021 (digctrl_kx2
| (1<<2)));
4023 /* Enable autodet */
4024 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4025 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1
,
4026 (digctrl_kx1
| 0x10));
4029 static void bnx2x_warpcore_reset_lane(struct bnx2x
*bp
,
4030 struct bnx2x_phy
*phy
,
4034 /* Take lane out of reset after configuration is finished */
4035 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
4036 MDIO_WC_REG_DIGITAL5_MISC6
, &val
);
4041 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4042 MDIO_WC_REG_DIGITAL5_MISC6
, val
);
4043 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
4044 MDIO_WC_REG_DIGITAL5_MISC6
, &val
);
4048 /* Clear SFI/XFI link settings registers */
4049 static void bnx2x_warpcore_clear_regs(struct bnx2x_phy
*phy
,
4050 struct link_params
*params
,
4053 struct bnx2x
*bp
= params
->bp
;
4056 /* Set XFI clock comp as default. */
4057 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
4058 MDIO_WC_REG_RX66_CONTROL
, &val16
);
4059 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4060 MDIO_WC_REG_RX66_CONTROL
, val16
| (3<<13));
4062 bnx2x_warpcore_reset_lane(bp
, phy
, 1);
4063 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
, MDIO_AN_REG_CTRL
, 0);
4064 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4065 MDIO_WC_REG_FX100_CTRL1
, 0x014a);
4066 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4067 MDIO_WC_REG_FX100_CTRL3
, 0x0800);
4068 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4069 MDIO_WC_REG_DIGITAL4_MISC3
, 0x8008);
4070 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4071 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1
, 0x0195);
4072 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4073 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2
, 0x0007);
4074 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4075 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3
, 0x0002);
4076 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4077 MDIO_WC_REG_SERDESDIGITAL_MISC1
, 0x6000);
4078 lane
= bnx2x_get_warpcore_lane(phy
, params
);
4079 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4080 MDIO_WC_REG_TX_FIR_TAP
, 0x0000);
4081 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4082 MDIO_WC_REG_TX0_TX_DRIVER
+ 0x10*lane
, 0x0990);
4083 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4084 MDIO_WC_REG_IEEE0BLK_MIICNTL
, 0x2040);
4085 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4086 MDIO_WC_REG_COMBO_IEEE0_MIICTRL
, 0x0140);
4087 bnx2x_warpcore_reset_lane(bp
, phy
, 0);
4090 static int bnx2x_get_mod_abs_int_cfg(struct bnx2x
*bp
,
4092 u32 shmem_base
, u8 port
,
4093 u8
*gpio_num
, u8
*gpio_port
)
4098 if (CHIP_IS_E3(bp
)) {
4099 cfg_pin
= (REG_RD(bp
, shmem_base
+
4100 offsetof(struct shmem_region
,
4101 dev_info
.port_hw_config
[port
].e3_sfp_ctrl
)) &
4102 PORT_HW_CFG_E3_MOD_ABS_MASK
) >>
4103 PORT_HW_CFG_E3_MOD_ABS_SHIFT
;
4106 * Should not happen. This function called upon interrupt
4107 * triggered by GPIO ( since EPIO can only generate interrupts
4109 * So if this function was called and none of the GPIOs was set,
4110 * it means the shit hit the fan.
4112 if ((cfg_pin
< PIN_CFG_GPIO0_P0
) ||
4113 (cfg_pin
> PIN_CFG_GPIO3_P1
)) {
4115 "ERROR: Invalid cfg pin %x for module detect indication\n",
4120 *gpio_num
= (cfg_pin
- PIN_CFG_GPIO0_P0
) & 0x3;
4121 *gpio_port
= (cfg_pin
- PIN_CFG_GPIO0_P0
) >> 2;
4123 *gpio_num
= MISC_REGISTERS_GPIO_3
;
4126 DP(NETIF_MSG_LINK
, "MOD_ABS int GPIO%d_P%d\n", *gpio_num
, *gpio_port
);
4130 static int bnx2x_is_sfp_module_plugged(struct bnx2x_phy
*phy
,
4131 struct link_params
*params
)
4133 struct bnx2x
*bp
= params
->bp
;
4134 u8 gpio_num
, gpio_port
;
4136 if (bnx2x_get_mod_abs_int_cfg(bp
, params
->chip_id
,
4137 params
->shmem_base
, params
->port
,
4138 &gpio_num
, &gpio_port
) != 0)
4140 gpio_val
= bnx2x_get_gpio(bp
, gpio_num
, gpio_port
);
4142 /* Call the handling function in case module is detected */
4148 static int bnx2x_warpcore_get_sigdet(struct bnx2x_phy
*phy
,
4149 struct link_params
*params
)
4151 u16 gp2_status_reg0
, lane
;
4152 struct bnx2x
*bp
= params
->bp
;
4154 lane
= bnx2x_get_warpcore_lane(phy
, params
);
4156 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
, MDIO_WC_REG_GP2_STATUS_GP_2_0
,
4159 return (gp2_status_reg0
>> (8+lane
)) & 0x1;
4162 static void bnx2x_warpcore_config_runtime(struct bnx2x_phy
*phy
,
4163 struct link_params
*params
,
4164 struct link_vars
*vars
)
4166 struct bnx2x
*bp
= params
->bp
;
4168 u16 gp_status1
= 0, lnkup
= 0, lnkup_kr
= 0;
4169 u16 lane
= bnx2x_get_warpcore_lane(phy
, params
);
4171 vars
->turn_to_run_wc_rt
= vars
->turn_to_run_wc_rt
? 0 : 1;
4173 if (!vars
->turn_to_run_wc_rt
)
4176 /* return if there is no link partner */
4177 if (!(bnx2x_warpcore_get_sigdet(phy
, params
))) {
4178 DP(NETIF_MSG_LINK
, "bnx2x_warpcore_get_sigdet false\n");
4182 if (vars
->rx_tx_asic_rst
) {
4183 serdes_net_if
= (REG_RD(bp
, params
->shmem_base
+
4184 offsetof(struct shmem_region
, dev_info
.
4185 port_hw_config
[params
->port
].default_cfg
)) &
4186 PORT_HW_CFG_NET_SERDES_IF_MASK
);
4188 switch (serdes_net_if
) {
4189 case PORT_HW_CFG_NET_SERDES_IF_KR
:
4190 /* Do we get link yet? */
4191 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
, 0x81d1,
4193 lnkup
= (gp_status1
>> (8+lane
)) & 0x1;/* 1G */
4195 lnkup_kr
= (gp_status1
>> (12+lane
)) & 0x1;
4198 "gp_status1 0x%x\n", gp_status1
);
4200 if (lnkup_kr
|| lnkup
) {
4201 vars
->rx_tx_asic_rst
= 0;
4203 "link up, rx_tx_asic_rst 0x%x\n",
4204 vars
->rx_tx_asic_rst
);
4206 /*reset the lane to see if link comes up.*/
4207 bnx2x_warpcore_reset_lane(bp
, phy
, 1);
4208 bnx2x_warpcore_reset_lane(bp
, phy
, 0);
4210 /* restart Autoneg */
4211 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
,
4212 MDIO_WC_REG_IEEE0BLK_MIICNTL
, 0x1200);
4214 vars
->rx_tx_asic_rst
--;
4215 DP(NETIF_MSG_LINK
, "0x%x retry left\n",
4216 vars
->rx_tx_asic_rst
);
4224 } /*params->rx_tx_asic_rst*/
4228 static void bnx2x_warpcore_config_init(struct bnx2x_phy
*phy
,
4229 struct link_params
*params
,
4230 struct link_vars
*vars
)
4232 struct bnx2x
*bp
= params
->bp
;
4235 u16 lane
= bnx2x_get_warpcore_lane(phy
, params
);
4236 serdes_net_if
= (REG_RD(bp
, params
->shmem_base
+
4237 offsetof(struct shmem_region
, dev_info
.
4238 port_hw_config
[params
->port
].default_cfg
)) &
4239 PORT_HW_CFG_NET_SERDES_IF_MASK
);
4240 DP(NETIF_MSG_LINK
, "Begin Warpcore init, link_speed %d, "
4241 "serdes_net_if = 0x%x\n",
4242 vars
->line_speed
, serdes_net_if
);
4243 bnx2x_set_aer_mmd(params
, phy
);
4245 vars
->phy_flags
|= PHY_XGXS_FLAG
;
4246 if ((serdes_net_if
== PORT_HW_CFG_NET_SERDES_IF_SGMII
) ||
4247 (phy
->req_line_speed
&&
4248 ((phy
->req_line_speed
== SPEED_100
) ||
4249 (phy
->req_line_speed
== SPEED_10
)))) {
4250 vars
->phy_flags
|= PHY_SGMII_FLAG
;
4251 DP(NETIF_MSG_LINK
, "Setting SGMII mode\n");
4252 bnx2x_warpcore_clear_regs(phy
, params
, lane
);
4253 bnx2x_warpcore_set_sgmii_speed(phy
, params
, 0);
4255 switch (serdes_net_if
) {
4256 case PORT_HW_CFG_NET_SERDES_IF_KR
:
4257 /* Enable KR Auto Neg */
4258 if (params
->loopback_mode
== LOOPBACK_NONE
)
4259 bnx2x_warpcore_enable_AN_KR(phy
, params
, vars
);
4261 DP(NETIF_MSG_LINK
, "Setting KR 10G-Force\n");
4262 bnx2x_warpcore_set_10G_KR(phy
, params
, vars
);
4266 case PORT_HW_CFG_NET_SERDES_IF_XFI
:
4267 bnx2x_warpcore_clear_regs(phy
, params
, lane
);
4268 if (vars
->line_speed
== SPEED_10000
) {
4269 DP(NETIF_MSG_LINK
, "Setting 10G XFI\n");
4270 bnx2x_warpcore_set_10G_XFI(phy
, params
, 1);
4272 if (SINGLE_MEDIA_DIRECT(params
)) {
4273 DP(NETIF_MSG_LINK
, "1G Fiber\n");
4276 DP(NETIF_MSG_LINK
, "10/100/1G SGMII\n");
4279 bnx2x_warpcore_set_sgmii_speed(phy
,
4286 case PORT_HW_CFG_NET_SERDES_IF_SFI
:
4288 bnx2x_warpcore_clear_regs(phy
, params
, lane
);
4289 if (vars
->line_speed
== SPEED_10000
) {
4290 DP(NETIF_MSG_LINK
, "Setting 10G SFI\n");
4291 bnx2x_warpcore_set_10G_XFI(phy
, params
, 0);
4292 } else if (vars
->line_speed
== SPEED_1000
) {
4293 DP(NETIF_MSG_LINK
, "Setting 1G Fiber\n");
4294 bnx2x_warpcore_set_sgmii_speed(phy
, params
, 1);
4296 /* Issue Module detection */
4297 if (bnx2x_is_sfp_module_plugged(phy
, params
))
4298 bnx2x_sfp_module_detection(phy
, params
);
4301 case PORT_HW_CFG_NET_SERDES_IF_DXGXS
:
4302 if (vars
->line_speed
!= SPEED_20000
) {
4303 DP(NETIF_MSG_LINK
, "Speed not supported yet\n");
4306 DP(NETIF_MSG_LINK
, "Setting 20G DXGXS\n");
4307 bnx2x_warpcore_set_20G_DXGXS(bp
, phy
, lane
);
4308 /* Issue Module detection */
4310 bnx2x_sfp_module_detection(phy
, params
);
4313 case PORT_HW_CFG_NET_SERDES_IF_KR2
:
4314 if (vars
->line_speed
!= SPEED_20000
) {
4315 DP(NETIF_MSG_LINK
, "Speed not supported yet\n");
4318 DP(NETIF_MSG_LINK
, "Setting 20G KR2\n");
4319 bnx2x_warpcore_set_20G_KR2(bp
, phy
);
4324 "Unsupported Serdes Net Interface 0x%x\n",
4330 /* Take lane out of reset after configuration is finished */
4331 bnx2x_warpcore_reset_lane(bp
, phy
, 0);
4332 DP(NETIF_MSG_LINK
, "Exit config init\n");
4335 static void bnx2x_sfp_e3_set_transmitter(struct link_params
*params
,
4336 struct bnx2x_phy
*phy
,
4339 struct bnx2x
*bp
= params
->bp
;
4341 u8 port
= params
->port
;
4343 cfg_pin
= REG_RD(bp
, params
->shmem_base
+
4344 offsetof(struct shmem_region
,
4345 dev_info
.port_hw_config
[port
].e3_sfp_ctrl
)) &
4346 PORT_HW_CFG_TX_LASER_MASK
;
4347 /* Set the !tx_en since this pin is DISABLE_TX_LASER */
4348 DP(NETIF_MSG_LINK
, "Setting WC TX to %d\n", tx_en
);
4349 /* For 20G, the expected pin to be used is 3 pins after the current */
4351 bnx2x_set_cfg_pin(bp
, cfg_pin
, tx_en
^ 1);
4352 if (phy
->speed_cap_mask
& PORT_HW_CFG_SPEED_CAPABILITY_D0_20G
)
4353 bnx2x_set_cfg_pin(bp
, cfg_pin
+ 3, tx_en
^ 1);
4356 static void bnx2x_warpcore_link_reset(struct bnx2x_phy
*phy
,
4357 struct link_params
*params
)
4359 struct bnx2x
*bp
= params
->bp
;
4361 bnx2x_sfp_e3_set_transmitter(params
, phy
, 0);
4362 bnx2x_set_mdio_clk(bp
, params
->chip_id
, params
->port
);
4363 bnx2x_set_aer_mmd(params
, phy
);
4364 /* Global register */
4365 bnx2x_warpcore_reset_lane(bp
, phy
, 1);
4367 /* Clear loopback settings (if any) */
4369 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
4370 MDIO_WC_REG_COMBO_IEEE0_MIICTRL
, &val16
);
4371 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4372 MDIO_WC_REG_COMBO_IEEE0_MIICTRL
, val16
&
4375 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
4376 MDIO_WC_REG_IEEE0BLK_MIICNTL
, &val16
);
4377 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4378 MDIO_WC_REG_IEEE0BLK_MIICNTL
, val16
& 0xfffe);
4380 /* Update those 1-copy registers */
4381 CL22_WR_OVER_CL45(bp
, phy
, MDIO_REG_BANK_AER_BLOCK
,
4382 MDIO_AER_BLOCK_AER_REG
, 0);
4383 /* Enable 1G MDIO (1-copy) */
4384 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
4385 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL
,
4387 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4388 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL
,
4391 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
4392 MDIO_WC_REG_XGXSBLK1_LANECTRL2
, &val16
);
4393 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4394 MDIO_WC_REG_XGXSBLK1_LANECTRL2
,
4399 static void bnx2x_set_warpcore_loopback(struct bnx2x_phy
*phy
,
4400 struct link_params
*params
)
4402 struct bnx2x
*bp
= params
->bp
;
4405 DP(NETIF_MSG_LINK
, "Setting Warpcore loopback type %x, speed %d\n",
4406 params
->loopback_mode
, phy
->req_line_speed
);
4408 if (phy
->req_line_speed
< SPEED_10000
) {
4411 /* Update those 1-copy registers */
4412 CL22_WR_OVER_CL45(bp
, phy
, MDIO_REG_BANK_AER_BLOCK
,
4413 MDIO_AER_BLOCK_AER_REG
, 0);
4414 /* Enable 1G MDIO (1-copy) */
4415 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
4416 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL
,
4418 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4419 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL
,
4421 /* Set 1G loopback based on lane (1-copy) */
4422 lane
= bnx2x_get_warpcore_lane(phy
, params
);
4423 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
4424 MDIO_WC_REG_XGXSBLK1_LANECTRL2
, &val16
);
4425 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4426 MDIO_WC_REG_XGXSBLK1_LANECTRL2
,
4429 /* Switch back to 4-copy registers */
4430 bnx2x_set_aer_mmd(params
, phy
);
4431 /* Global loopback, not recommended. */
4432 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
4433 MDIO_WC_REG_COMBO_IEEE0_MIICTRL
, &val16
);
4434 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4435 MDIO_WC_REG_COMBO_IEEE0_MIICTRL
, val16
|
4439 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
4440 MDIO_WC_REG_COMBO_IEEE0_MIICTRL
, &val16
);
4441 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4442 MDIO_WC_REG_COMBO_IEEE0_MIICTRL
, val16
|
4445 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
4446 MDIO_WC_REG_IEEE0BLK_MIICNTL
, &val16
);
4447 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
4448 MDIO_WC_REG_IEEE0BLK_MIICNTL
, val16
| 0x1);
4453 void bnx2x_link_status_update(struct link_params
*params
,
4454 struct link_vars
*vars
)
4456 struct bnx2x
*bp
= params
->bp
;
4458 u8 port
= params
->port
;
4459 u32 sync_offset
, media_types
;
4460 /* Update PHY configuration */
4461 set_phy_vars(params
, vars
);
4463 vars
->link_status
= REG_RD(bp
, params
->shmem_base
+
4464 offsetof(struct shmem_region
,
4465 port_mb
[port
].link_status
));
4467 vars
->link_up
= (vars
->link_status
& LINK_STATUS_LINK_UP
);
4468 vars
->phy_flags
= PHY_XGXS_FLAG
;
4469 if (vars
->link_status
& LINK_STATUS_PHYSICAL_LINK_FLAG
)
4470 vars
->phy_flags
|= PHY_PHYSICAL_LINK_FLAG
;
4472 if (vars
->link_up
) {
4473 DP(NETIF_MSG_LINK
, "phy link up\n");
4475 vars
->phy_link_up
= 1;
4476 vars
->duplex
= DUPLEX_FULL
;
4477 switch (vars
->link_status
&
4478 LINK_STATUS_SPEED_AND_DUPLEX_MASK
) {
4480 vars
->duplex
= DUPLEX_HALF
;
4483 vars
->line_speed
= SPEED_10
;
4487 vars
->duplex
= DUPLEX_HALF
;
4491 vars
->line_speed
= SPEED_100
;
4495 vars
->duplex
= DUPLEX_HALF
;
4498 vars
->line_speed
= SPEED_1000
;
4502 vars
->duplex
= DUPLEX_HALF
;
4505 vars
->line_speed
= SPEED_2500
;
4509 vars
->line_speed
= SPEED_10000
;
4512 vars
->line_speed
= SPEED_20000
;
4517 vars
->flow_ctrl
= 0;
4518 if (vars
->link_status
& LINK_STATUS_TX_FLOW_CONTROL_ENABLED
)
4519 vars
->flow_ctrl
|= BNX2X_FLOW_CTRL_TX
;
4521 if (vars
->link_status
& LINK_STATUS_RX_FLOW_CONTROL_ENABLED
)
4522 vars
->flow_ctrl
|= BNX2X_FLOW_CTRL_RX
;
4524 if (!vars
->flow_ctrl
)
4525 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
4527 if (vars
->line_speed
&&
4528 ((vars
->line_speed
== SPEED_10
) ||
4529 (vars
->line_speed
== SPEED_100
))) {
4530 vars
->phy_flags
|= PHY_SGMII_FLAG
;
4532 vars
->phy_flags
&= ~PHY_SGMII_FLAG
;
4534 if (vars
->line_speed
&&
4535 USES_WARPCORE(bp
) &&
4536 (vars
->line_speed
== SPEED_1000
))
4537 vars
->phy_flags
|= PHY_SGMII_FLAG
;
4538 /* anything 10 and over uses the bmac */
4539 link_10g_plus
= (vars
->line_speed
>= SPEED_10000
);
4541 if (link_10g_plus
) {
4542 if (USES_WARPCORE(bp
))
4543 vars
->mac_type
= MAC_TYPE_XMAC
;
4545 vars
->mac_type
= MAC_TYPE_BMAC
;
4547 if (USES_WARPCORE(bp
))
4548 vars
->mac_type
= MAC_TYPE_UMAC
;
4550 vars
->mac_type
= MAC_TYPE_EMAC
;
4552 } else { /* link down */
4553 DP(NETIF_MSG_LINK
, "phy link down\n");
4555 vars
->phy_link_up
= 0;
4557 vars
->line_speed
= 0;
4558 vars
->duplex
= DUPLEX_FULL
;
4559 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
4561 /* indicate no mac active */
4562 vars
->mac_type
= MAC_TYPE_NONE
;
4563 if (vars
->link_status
& LINK_STATUS_PHYSICAL_LINK_FLAG
)
4564 vars
->phy_flags
|= PHY_HALF_OPEN_CONN_FLAG
;
4567 /* Sync media type */
4568 sync_offset
= params
->shmem_base
+
4569 offsetof(struct shmem_region
,
4570 dev_info
.port_hw_config
[port
].media_type
);
4571 media_types
= REG_RD(bp
, sync_offset
);
4573 params
->phy
[INT_PHY
].media_type
=
4574 (media_types
& PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK
) >>
4575 PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT
;
4576 params
->phy
[EXT_PHY1
].media_type
=
4577 (media_types
& PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK
) >>
4578 PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT
;
4579 params
->phy
[EXT_PHY2
].media_type
=
4580 (media_types
& PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK
) >>
4581 PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT
;
4582 DP(NETIF_MSG_LINK
, "media_types = 0x%x\n", media_types
);
4584 /* Sync AEU offset */
4585 sync_offset
= params
->shmem_base
+
4586 offsetof(struct shmem_region
,
4587 dev_info
.port_hw_config
[port
].aeu_int_mask
);
4589 vars
->aeu_int_mask
= REG_RD(bp
, sync_offset
);
4591 /* Sync PFC status */
4592 if (vars
->link_status
& LINK_STATUS_PFC_ENABLED
)
4593 params
->feature_config_flags
|=
4594 FEATURE_CONFIG_PFC_ENABLED
;
4596 params
->feature_config_flags
&=
4597 ~FEATURE_CONFIG_PFC_ENABLED
;
4599 DP(NETIF_MSG_LINK
, "link_status 0x%x phy_link_up %x int_mask 0x%x\n",
4600 vars
->link_status
, vars
->phy_link_up
, vars
->aeu_int_mask
);
4601 DP(NETIF_MSG_LINK
, "line_speed %x duplex %x flow_ctrl 0x%x\n",
4602 vars
->line_speed
, vars
->duplex
, vars
->flow_ctrl
);
4606 static void bnx2x_set_master_ln(struct link_params
*params
,
4607 struct bnx2x_phy
*phy
)
4609 struct bnx2x
*bp
= params
->bp
;
4610 u16 new_master_ln
, ser_lane
;
4611 ser_lane
= ((params
->lane_config
&
4612 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
4613 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
4615 /* set the master_ln for AN */
4616 CL22_RD_OVER_CL45(bp
, phy
,
4617 MDIO_REG_BANK_XGXS_BLOCK2
,
4618 MDIO_XGXS_BLOCK2_TEST_MODE_LANE
,
4621 CL22_WR_OVER_CL45(bp
, phy
,
4622 MDIO_REG_BANK_XGXS_BLOCK2
,
4623 MDIO_XGXS_BLOCK2_TEST_MODE_LANE
,
4624 (new_master_ln
| ser_lane
));
4627 static int bnx2x_reset_unicore(struct link_params
*params
,
4628 struct bnx2x_phy
*phy
,
4631 struct bnx2x
*bp
= params
->bp
;
4634 CL22_RD_OVER_CL45(bp
, phy
,
4635 MDIO_REG_BANK_COMBO_IEEE0
,
4636 MDIO_COMBO_IEEE0_MII_CONTROL
, &mii_control
);
4638 /* reset the unicore */
4639 CL22_WR_OVER_CL45(bp
, phy
,
4640 MDIO_REG_BANK_COMBO_IEEE0
,
4641 MDIO_COMBO_IEEE0_MII_CONTROL
,
4643 MDIO_COMBO_IEEO_MII_CONTROL_RESET
));
4645 bnx2x_set_serdes_access(bp
, params
->port
);
4647 /* wait for the reset to self clear */
4648 for (i
= 0; i
< MDIO_ACCESS_TIMEOUT
; i
++) {
4651 /* the reset erased the previous bank value */
4652 CL22_RD_OVER_CL45(bp
, phy
,
4653 MDIO_REG_BANK_COMBO_IEEE0
,
4654 MDIO_COMBO_IEEE0_MII_CONTROL
,
4657 if (!(mii_control
& MDIO_COMBO_IEEO_MII_CONTROL_RESET
)) {
4663 netdev_err(bp
->dev
, "Warning: PHY was not initialized,"
4666 DP(NETIF_MSG_LINK
, "BUG! XGXS is still in reset!\n");
4671 static void bnx2x_set_swap_lanes(struct link_params
*params
,
4672 struct bnx2x_phy
*phy
)
4674 struct bnx2x
*bp
= params
->bp
;
4676 * Each two bits represents a lane number:
4677 * No swap is 0123 => 0x1b no need to enable the swap
4679 u16 ser_lane
, rx_lane_swap
, tx_lane_swap
;
4681 ser_lane
= ((params
->lane_config
&
4682 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
4683 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
4684 rx_lane_swap
= ((params
->lane_config
&
4685 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK
) >>
4686 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT
);
4687 tx_lane_swap
= ((params
->lane_config
&
4688 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK
) >>
4689 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT
);
4691 if (rx_lane_swap
!= 0x1b) {
4692 CL22_WR_OVER_CL45(bp
, phy
,
4693 MDIO_REG_BANK_XGXS_BLOCK2
,
4694 MDIO_XGXS_BLOCK2_RX_LN_SWAP
,
4696 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE
|
4697 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE
));
4699 CL22_WR_OVER_CL45(bp
, phy
,
4700 MDIO_REG_BANK_XGXS_BLOCK2
,
4701 MDIO_XGXS_BLOCK2_RX_LN_SWAP
, 0);
4704 if (tx_lane_swap
!= 0x1b) {
4705 CL22_WR_OVER_CL45(bp
, phy
,
4706 MDIO_REG_BANK_XGXS_BLOCK2
,
4707 MDIO_XGXS_BLOCK2_TX_LN_SWAP
,
4709 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE
));
4711 CL22_WR_OVER_CL45(bp
, phy
,
4712 MDIO_REG_BANK_XGXS_BLOCK2
,
4713 MDIO_XGXS_BLOCK2_TX_LN_SWAP
, 0);
4717 static void bnx2x_set_parallel_detection(struct bnx2x_phy
*phy
,
4718 struct link_params
*params
)
4720 struct bnx2x
*bp
= params
->bp
;
4722 CL22_RD_OVER_CL45(bp
, phy
,
4723 MDIO_REG_BANK_SERDES_DIGITAL
,
4724 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2
,
4726 if (phy
->speed_cap_mask
& PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
)
4727 control2
|= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN
;
4729 control2
&= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN
;
4730 DP(NETIF_MSG_LINK
, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
4731 phy
->speed_cap_mask
, control2
);
4732 CL22_WR_OVER_CL45(bp
, phy
,
4733 MDIO_REG_BANK_SERDES_DIGITAL
,
4734 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2
,
4737 if ((phy
->type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) &&
4738 (phy
->speed_cap_mask
&
4739 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)) {
4740 DP(NETIF_MSG_LINK
, "XGXS\n");
4742 CL22_WR_OVER_CL45(bp
, phy
,
4743 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
4744 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK
,
4745 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT
);
4747 CL22_RD_OVER_CL45(bp
, phy
,
4748 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
4749 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL
,
4754 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN
;
4756 CL22_WR_OVER_CL45(bp
, phy
,
4757 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
4758 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL
,
4761 /* Disable parallel detection of HiG */
4762 CL22_WR_OVER_CL45(bp
, phy
,
4763 MDIO_REG_BANK_XGXS_BLOCK2
,
4764 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G
,
4765 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS
|
4766 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS
);
4770 static void bnx2x_set_autoneg(struct bnx2x_phy
*phy
,
4771 struct link_params
*params
,
4772 struct link_vars
*vars
,
4775 struct bnx2x
*bp
= params
->bp
;
4779 CL22_RD_OVER_CL45(bp
, phy
,
4780 MDIO_REG_BANK_COMBO_IEEE0
,
4781 MDIO_COMBO_IEEE0_MII_CONTROL
, ®_val
);
4783 /* CL37 Autoneg Enabled */
4784 if (vars
->line_speed
== SPEED_AUTO_NEG
)
4785 reg_val
|= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
;
4786 else /* CL37 Autoneg Disabled */
4787 reg_val
&= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
|
4788 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN
);
4790 CL22_WR_OVER_CL45(bp
, phy
,
4791 MDIO_REG_BANK_COMBO_IEEE0
,
4792 MDIO_COMBO_IEEE0_MII_CONTROL
, reg_val
);
4794 /* Enable/Disable Autodetection */
4796 CL22_RD_OVER_CL45(bp
, phy
,
4797 MDIO_REG_BANK_SERDES_DIGITAL
,
4798 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
, ®_val
);
4799 reg_val
&= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN
|
4800 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT
);
4801 reg_val
|= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE
;
4802 if (vars
->line_speed
== SPEED_AUTO_NEG
)
4803 reg_val
|= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET
;
4805 reg_val
&= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET
;
4807 CL22_WR_OVER_CL45(bp
, phy
,
4808 MDIO_REG_BANK_SERDES_DIGITAL
,
4809 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
, reg_val
);
4811 /* Enable TetonII and BAM autoneg */
4812 CL22_RD_OVER_CL45(bp
, phy
,
4813 MDIO_REG_BANK_BAM_NEXT_PAGE
,
4814 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL
,
4816 if (vars
->line_speed
== SPEED_AUTO_NEG
) {
4817 /* Enable BAM aneg Mode and TetonII aneg Mode */
4818 reg_val
|= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE
|
4819 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN
);
4821 /* TetonII and BAM Autoneg Disabled */
4822 reg_val
&= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE
|
4823 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN
);
4825 CL22_WR_OVER_CL45(bp
, phy
,
4826 MDIO_REG_BANK_BAM_NEXT_PAGE
,
4827 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL
,
4831 /* Enable Cl73 FSM status bits */
4832 CL22_WR_OVER_CL45(bp
, phy
,
4833 MDIO_REG_BANK_CL73_USERB0
,
4834 MDIO_CL73_USERB0_CL73_UCTRL
,
4837 /* Enable BAM Station Manager*/
4838 CL22_WR_OVER_CL45(bp
, phy
,
4839 MDIO_REG_BANK_CL73_USERB0
,
4840 MDIO_CL73_USERB0_CL73_BAM_CTRL1
,
4841 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN
|
4842 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN
|
4843 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN
);
4845 /* Advertise CL73 link speeds */
4846 CL22_RD_OVER_CL45(bp
, phy
,
4847 MDIO_REG_BANK_CL73_IEEEB1
,
4848 MDIO_CL73_IEEEB1_AN_ADV2
,
4850 if (phy
->speed_cap_mask
&
4851 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)
4852 reg_val
|= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4
;
4853 if (phy
->speed_cap_mask
&
4854 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
)
4855 reg_val
|= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX
;
4857 CL22_WR_OVER_CL45(bp
, phy
,
4858 MDIO_REG_BANK_CL73_IEEEB1
,
4859 MDIO_CL73_IEEEB1_AN_ADV2
,
4862 /* CL73 Autoneg Enabled */
4863 reg_val
= MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN
;
4865 } else /* CL73 Autoneg Disabled */
4868 CL22_WR_OVER_CL45(bp
, phy
,
4869 MDIO_REG_BANK_CL73_IEEEB0
,
4870 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
, reg_val
);
4873 /* program SerDes, forced speed */
4874 static void bnx2x_program_serdes(struct bnx2x_phy
*phy
,
4875 struct link_params
*params
,
4876 struct link_vars
*vars
)
4878 struct bnx2x
*bp
= params
->bp
;
4881 /* program duplex, disable autoneg and sgmii*/
4882 CL22_RD_OVER_CL45(bp
, phy
,
4883 MDIO_REG_BANK_COMBO_IEEE0
,
4884 MDIO_COMBO_IEEE0_MII_CONTROL
, ®_val
);
4885 reg_val
&= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
|
4886 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
|
4887 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK
);
4888 if (phy
->req_duplex
== DUPLEX_FULL
)
4889 reg_val
|= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
;
4890 CL22_WR_OVER_CL45(bp
, phy
,
4891 MDIO_REG_BANK_COMBO_IEEE0
,
4892 MDIO_COMBO_IEEE0_MII_CONTROL
, reg_val
);
4896 * - needed only if the speed is greater than 1G (2.5G or 10G)
4898 CL22_RD_OVER_CL45(bp
, phy
,
4899 MDIO_REG_BANK_SERDES_DIGITAL
,
4900 MDIO_SERDES_DIGITAL_MISC1
, ®_val
);
4901 /* clearing the speed value before setting the right speed */
4902 DP(NETIF_MSG_LINK
, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val
);
4904 reg_val
&= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK
|
4905 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL
);
4907 if (!((vars
->line_speed
== SPEED_1000
) ||
4908 (vars
->line_speed
== SPEED_100
) ||
4909 (vars
->line_speed
== SPEED_10
))) {
4911 reg_val
|= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M
|
4912 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL
);
4913 if (vars
->line_speed
== SPEED_10000
)
4915 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4
;
4918 CL22_WR_OVER_CL45(bp
, phy
,
4919 MDIO_REG_BANK_SERDES_DIGITAL
,
4920 MDIO_SERDES_DIGITAL_MISC1
, reg_val
);
4924 static void bnx2x_set_brcm_cl37_advertisement(struct bnx2x_phy
*phy
,
4925 struct link_params
*params
)
4927 struct bnx2x
*bp
= params
->bp
;
4930 /* configure the 48 bits for BAM AN */
4932 /* set extended capabilities */
4933 if (phy
->speed_cap_mask
& PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G
)
4934 val
|= MDIO_OVER_1G_UP1_2_5G
;
4935 if (phy
->speed_cap_mask
& PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)
4936 val
|= MDIO_OVER_1G_UP1_10G
;
4937 CL22_WR_OVER_CL45(bp
, phy
,
4938 MDIO_REG_BANK_OVER_1G
,
4939 MDIO_OVER_1G_UP1
, val
);
4941 CL22_WR_OVER_CL45(bp
, phy
,
4942 MDIO_REG_BANK_OVER_1G
,
4943 MDIO_OVER_1G_UP3
, 0x400);
4946 static void bnx2x_set_ieee_aneg_advertisement(struct bnx2x_phy
*phy
,
4947 struct link_params
*params
,
4950 struct bnx2x
*bp
= params
->bp
;
4952 /* for AN, we are always publishing full duplex */
4954 CL22_WR_OVER_CL45(bp
, phy
,
4955 MDIO_REG_BANK_COMBO_IEEE0
,
4956 MDIO_COMBO_IEEE0_AUTO_NEG_ADV
, ieee_fc
);
4957 CL22_RD_OVER_CL45(bp
, phy
,
4958 MDIO_REG_BANK_CL73_IEEEB1
,
4959 MDIO_CL73_IEEEB1_AN_ADV1
, &val
);
4960 val
&= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH
;
4961 val
|= ((ieee_fc
<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK
);
4962 CL22_WR_OVER_CL45(bp
, phy
,
4963 MDIO_REG_BANK_CL73_IEEEB1
,
4964 MDIO_CL73_IEEEB1_AN_ADV1
, val
);
4967 static void bnx2x_restart_autoneg(struct bnx2x_phy
*phy
,
4968 struct link_params
*params
,
4971 struct bnx2x
*bp
= params
->bp
;
4974 DP(NETIF_MSG_LINK
, "bnx2x_restart_autoneg\n");
4975 /* Enable and restart BAM/CL37 aneg */
4978 CL22_RD_OVER_CL45(bp
, phy
,
4979 MDIO_REG_BANK_CL73_IEEEB0
,
4980 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
,
4983 CL22_WR_OVER_CL45(bp
, phy
,
4984 MDIO_REG_BANK_CL73_IEEEB0
,
4985 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
,
4987 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN
|
4988 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN
));
4991 CL22_RD_OVER_CL45(bp
, phy
,
4992 MDIO_REG_BANK_COMBO_IEEE0
,
4993 MDIO_COMBO_IEEE0_MII_CONTROL
,
4996 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
4998 CL22_WR_OVER_CL45(bp
, phy
,
4999 MDIO_REG_BANK_COMBO_IEEE0
,
5000 MDIO_COMBO_IEEE0_MII_CONTROL
,
5002 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
|
5003 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN
));
5007 static void bnx2x_initialize_sgmii_process(struct bnx2x_phy
*phy
,
5008 struct link_params
*params
,
5009 struct link_vars
*vars
)
5011 struct bnx2x
*bp
= params
->bp
;
5014 /* in SGMII mode, the unicore is always slave */
5016 CL22_RD_OVER_CL45(bp
, phy
,
5017 MDIO_REG_BANK_SERDES_DIGITAL
,
5018 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
,
5020 control1
|= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT
;
5021 /* set sgmii mode (and not fiber) */
5022 control1
&= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE
|
5023 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET
|
5024 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE
);
5025 CL22_WR_OVER_CL45(bp
, phy
,
5026 MDIO_REG_BANK_SERDES_DIGITAL
,
5027 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1
,
5030 /* if forced speed */
5031 if (!(vars
->line_speed
== SPEED_AUTO_NEG
)) {
5032 /* set speed, disable autoneg */
5035 CL22_RD_OVER_CL45(bp
, phy
,
5036 MDIO_REG_BANK_COMBO_IEEE0
,
5037 MDIO_COMBO_IEEE0_MII_CONTROL
,
5039 mii_control
&= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN
|
5040 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK
|
5041 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
);
5043 switch (vars
->line_speed
) {
5046 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100
;
5050 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000
;
5053 /* there is nothing to set for 10M */
5056 /* invalid speed for SGMII */
5057 DP(NETIF_MSG_LINK
, "Invalid line_speed 0x%x\n",
5062 /* setting the full duplex */
5063 if (phy
->req_duplex
== DUPLEX_FULL
)
5065 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX
;
5066 CL22_WR_OVER_CL45(bp
, phy
,
5067 MDIO_REG_BANK_COMBO_IEEE0
,
5068 MDIO_COMBO_IEEE0_MII_CONTROL
,
5071 } else { /* AN mode */
5072 /* enable and restart AN */
5073 bnx2x_restart_autoneg(phy
, params
, 0);
5082 static int bnx2x_direct_parallel_detect_used(struct bnx2x_phy
*phy
,
5083 struct link_params
*params
)
5085 struct bnx2x
*bp
= params
->bp
;
5086 u16 pd_10g
, status2_1000x
;
5087 if (phy
->req_line_speed
!= SPEED_AUTO_NEG
)
5089 CL22_RD_OVER_CL45(bp
, phy
,
5090 MDIO_REG_BANK_SERDES_DIGITAL
,
5091 MDIO_SERDES_DIGITAL_A_1000X_STATUS2
,
5093 CL22_RD_OVER_CL45(bp
, phy
,
5094 MDIO_REG_BANK_SERDES_DIGITAL
,
5095 MDIO_SERDES_DIGITAL_A_1000X_STATUS2
,
5097 if (status2_1000x
& MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED
) {
5098 DP(NETIF_MSG_LINK
, "1G parallel detect link on port %d\n",
5103 CL22_RD_OVER_CL45(bp
, phy
,
5104 MDIO_REG_BANK_10G_PARALLEL_DETECT
,
5105 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS
,
5108 if (pd_10g
& MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK
) {
5109 DP(NETIF_MSG_LINK
, "10G parallel detect link on port %d\n",
5116 static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy
*phy
,
5117 struct link_params
*params
,
5118 struct link_vars
*vars
,
5121 struct bnx2x
*bp
= params
->bp
;
5122 u16 ld_pause
; /* local driver */
5123 u16 lp_pause
; /* link partner */
5126 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
5128 /* resolve from gp_status in case of AN complete and not sgmii */
5129 if (phy
->req_flow_ctrl
!= BNX2X_FLOW_CTRL_AUTO
)
5130 vars
->flow_ctrl
= phy
->req_flow_ctrl
;
5131 else if (phy
->req_line_speed
!= SPEED_AUTO_NEG
)
5132 vars
->flow_ctrl
= params
->req_fc_auto_adv
;
5133 else if ((gp_status
& MDIO_AN_CL73_OR_37_COMPLETE
) &&
5134 (!(vars
->phy_flags
& PHY_SGMII_FLAG
))) {
5135 if (bnx2x_direct_parallel_detect_used(phy
, params
)) {
5136 vars
->flow_ctrl
= params
->req_fc_auto_adv
;
5140 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE
|
5141 MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE
)) ==
5142 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE
|
5143 MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE
)) {
5145 CL22_RD_OVER_CL45(bp
, phy
,
5146 MDIO_REG_BANK_CL73_IEEEB1
,
5147 MDIO_CL73_IEEEB1_AN_ADV1
,
5149 CL22_RD_OVER_CL45(bp
, phy
,
5150 MDIO_REG_BANK_CL73_IEEEB1
,
5151 MDIO_CL73_IEEEB1_AN_LP_ADV1
,
5153 pause_result
= (ld_pause
&
5154 MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK
)
5156 pause_result
|= (lp_pause
&
5157 MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK
)
5159 DP(NETIF_MSG_LINK
, "pause_result CL73 0x%x\n",
5162 CL22_RD_OVER_CL45(bp
, phy
,
5163 MDIO_REG_BANK_COMBO_IEEE0
,
5164 MDIO_COMBO_IEEE0_AUTO_NEG_ADV
,
5166 CL22_RD_OVER_CL45(bp
, phy
,
5167 MDIO_REG_BANK_COMBO_IEEE0
,
5168 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1
,
5170 pause_result
= (ld_pause
&
5171 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK
)>>5;
5172 pause_result
|= (lp_pause
&
5173 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK
)>>7;
5174 DP(NETIF_MSG_LINK
, "pause_result CL37 0x%x\n",
5177 bnx2x_pause_resolve(vars
, pause_result
);
5179 DP(NETIF_MSG_LINK
, "flow_ctrl 0x%x\n", vars
->flow_ctrl
);
5182 static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy
*phy
,
5183 struct link_params
*params
)
5185 struct bnx2x
*bp
= params
->bp
;
5186 u16 rx_status
, ustat_val
, cl37_fsm_received
;
5187 DP(NETIF_MSG_LINK
, "bnx2x_check_fallback_to_cl37\n");
5188 /* Step 1: Make sure signal is detected */
5189 CL22_RD_OVER_CL45(bp
, phy
,
5193 if ((rx_status
& MDIO_RX0_RX_STATUS_SIGDET
) !=
5194 (MDIO_RX0_RX_STATUS_SIGDET
)) {
5195 DP(NETIF_MSG_LINK
, "Signal is not detected. Restoring CL73."
5196 "rx_status(0x80b0) = 0x%x\n", rx_status
);
5197 CL22_WR_OVER_CL45(bp
, phy
,
5198 MDIO_REG_BANK_CL73_IEEEB0
,
5199 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
,
5200 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN
);
5203 /* Step 2: Check CL73 state machine */
5204 CL22_RD_OVER_CL45(bp
, phy
,
5205 MDIO_REG_BANK_CL73_USERB0
,
5206 MDIO_CL73_USERB0_CL73_USTAT1
,
5209 (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK
|
5210 MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37
)) !=
5211 (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK
|
5212 MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37
)) {
5213 DP(NETIF_MSG_LINK
, "CL73 state-machine is not stable. "
5214 "ustat_val(0x8371) = 0x%x\n", ustat_val
);
5218 * Step 3: Check CL37 Message Pages received to indicate LP
5219 * supports only CL37
5221 CL22_RD_OVER_CL45(bp
, phy
,
5222 MDIO_REG_BANK_REMOTE_PHY
,
5223 MDIO_REMOTE_PHY_MISC_RX_STATUS
,
5224 &cl37_fsm_received
);
5225 if ((cl37_fsm_received
&
5226 (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG
|
5227 MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG
)) !=
5228 (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG
|
5229 MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG
)) {
5230 DP(NETIF_MSG_LINK
, "No CL37 FSM were received. "
5231 "misc_rx_status(0x8330) = 0x%x\n",
5236 * The combined cl37/cl73 fsm state information indicating that
5237 * we are connected to a device which does not support cl73, but
5238 * does support cl37 BAM. In this case we disable cl73 and
5239 * restart cl37 auto-neg
5243 CL22_WR_OVER_CL45(bp
, phy
,
5244 MDIO_REG_BANK_CL73_IEEEB0
,
5245 MDIO_CL73_IEEEB0_CL73_AN_CONTROL
,
5247 /* Restart CL37 autoneg */
5248 bnx2x_restart_autoneg(phy
, params
, 0);
5249 DP(NETIF_MSG_LINK
, "Disabling CL73, and restarting CL37 autoneg\n");
5252 static void bnx2x_xgxs_an_resolve(struct bnx2x_phy
*phy
,
5253 struct link_params
*params
,
5254 struct link_vars
*vars
,
5257 if (gp_status
& MDIO_AN_CL73_OR_37_COMPLETE
)
5258 vars
->link_status
|=
5259 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE
;
5261 if (bnx2x_direct_parallel_detect_used(phy
, params
))
5262 vars
->link_status
|=
5263 LINK_STATUS_PARALLEL_DETECTION_USED
;
5265 static int bnx2x_get_link_speed_duplex(struct bnx2x_phy
*phy
,
5266 struct link_params
*params
,
5267 struct link_vars
*vars
,
5272 struct bnx2x
*bp
= params
->bp
;
5273 if (phy
->req_line_speed
== SPEED_AUTO_NEG
)
5274 vars
->link_status
|= LINK_STATUS_AUTO_NEGOTIATE_ENABLED
;
5276 DP(NETIF_MSG_LINK
, "phy link up\n");
5278 vars
->phy_link_up
= 1;
5279 vars
->link_status
|= LINK_STATUS_LINK_UP
;
5281 switch (speed_mask
) {
5283 vars
->line_speed
= SPEED_10
;
5284 if (vars
->duplex
== DUPLEX_FULL
)
5285 vars
->link_status
|= LINK_10TFD
;
5287 vars
->link_status
|= LINK_10THD
;
5290 case GP_STATUS_100M
:
5291 vars
->line_speed
= SPEED_100
;
5292 if (vars
->duplex
== DUPLEX_FULL
)
5293 vars
->link_status
|= LINK_100TXFD
;
5295 vars
->link_status
|= LINK_100TXHD
;
5299 case GP_STATUS_1G_KX
:
5300 vars
->line_speed
= SPEED_1000
;
5301 if (vars
->duplex
== DUPLEX_FULL
)
5302 vars
->link_status
|= LINK_1000TFD
;
5304 vars
->link_status
|= LINK_1000THD
;
5307 case GP_STATUS_2_5G
:
5308 vars
->line_speed
= SPEED_2500
;
5309 if (vars
->duplex
== DUPLEX_FULL
)
5310 vars
->link_status
|= LINK_2500TFD
;
5312 vars
->link_status
|= LINK_2500THD
;
5318 "link speed unsupported gp_status 0x%x\n",
5322 case GP_STATUS_10G_KX4
:
5323 case GP_STATUS_10G_HIG
:
5324 case GP_STATUS_10G_CX4
:
5325 case GP_STATUS_10G_KR
:
5326 case GP_STATUS_10G_SFI
:
5327 case GP_STATUS_10G_XFI
:
5328 vars
->line_speed
= SPEED_10000
;
5329 vars
->link_status
|= LINK_10GTFD
;
5331 case GP_STATUS_20G_DXGXS
:
5332 vars
->line_speed
= SPEED_20000
;
5333 vars
->link_status
|= LINK_20GTFD
;
5337 "link speed unsupported gp_status 0x%x\n",
5341 } else { /* link_down */
5342 DP(NETIF_MSG_LINK
, "phy link down\n");
5344 vars
->phy_link_up
= 0;
5346 vars
->duplex
= DUPLEX_FULL
;
5347 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
5348 vars
->mac_type
= MAC_TYPE_NONE
;
5350 DP(NETIF_MSG_LINK
, " phy_link_up %x line_speed %d\n",
5351 vars
->phy_link_up
, vars
->line_speed
);
5355 static int bnx2x_link_settings_status(struct bnx2x_phy
*phy
,
5356 struct link_params
*params
,
5357 struct link_vars
*vars
)
5360 struct bnx2x
*bp
= params
->bp
;
5362 u16 gp_status
, duplex
= DUPLEX_HALF
, link_up
= 0, speed_mask
;
5365 /* Read gp_status */
5366 CL22_RD_OVER_CL45(bp
, phy
,
5367 MDIO_REG_BANK_GP_STATUS
,
5368 MDIO_GP_STATUS_TOP_AN_STATUS1
,
5370 if (gp_status
& MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS
)
5371 duplex
= DUPLEX_FULL
;
5372 if (gp_status
& MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS
)
5374 speed_mask
= gp_status
& GP_STATUS_SPEED_MASK
;
5375 DP(NETIF_MSG_LINK
, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x\n",
5376 gp_status
, link_up
, speed_mask
);
5377 rc
= bnx2x_get_link_speed_duplex(phy
, params
, vars
, link_up
, speed_mask
,
5382 if (gp_status
& MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS
) {
5383 if (SINGLE_MEDIA_DIRECT(params
)) {
5384 bnx2x_flow_ctrl_resolve(phy
, params
, vars
, gp_status
);
5385 if (phy
->req_line_speed
== SPEED_AUTO_NEG
)
5386 bnx2x_xgxs_an_resolve(phy
, params
, vars
,
5389 } else { /* link_down */
5390 if ((phy
->req_line_speed
== SPEED_AUTO_NEG
) &&
5391 SINGLE_MEDIA_DIRECT(params
)) {
5392 /* Check signal is detected */
5393 bnx2x_check_fallback_to_cl37(phy
, params
);
5397 DP(NETIF_MSG_LINK
, "duplex %x flow_ctrl 0x%x link_status 0x%x\n",
5398 vars
->duplex
, vars
->flow_ctrl
, vars
->link_status
);
5402 static int bnx2x_warpcore_read_status(struct bnx2x_phy
*phy
,
5403 struct link_params
*params
,
5404 struct link_vars
*vars
)
5407 struct bnx2x
*bp
= params
->bp
;
5410 u16 gp_status1
, gp_speed
, link_up
, duplex
= DUPLEX_FULL
;
5412 lane
= bnx2x_get_warpcore_lane(phy
, params
);
5413 /* Read gp_status */
5414 if (phy
->req_line_speed
> SPEED_10000
) {
5416 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
5418 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
5420 DP(NETIF_MSG_LINK
, "PCS RX link status = 0x%x-->0x%x\n",
5421 temp_link_up
, link_up
);
5424 bnx2x_ext_phy_resolve_fc(phy
, params
, vars
);
5426 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
5427 MDIO_WC_REG_GP2_STATUS_GP_2_1
, &gp_status1
);
5428 DP(NETIF_MSG_LINK
, "0x81d1 = 0x%x\n", gp_status1
);
5429 /* Check for either KR or generic link up. */
5430 gp_status1
= ((gp_status1
>> 8) & 0xf) |
5431 ((gp_status1
>> 12) & 0xf);
5432 link_up
= gp_status1
& (1 << lane
);
5433 if (link_up
&& SINGLE_MEDIA_DIRECT(params
)) {
5435 if (phy
->req_line_speed
== SPEED_AUTO_NEG
) {
5436 /* Check Autoneg complete */
5437 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
5438 MDIO_WC_REG_GP2_STATUS_GP_2_4
,
5440 if (gp_status4
& ((1<<12)<<lane
))
5441 vars
->link_status
|=
5442 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE
;
5444 /* Check parallel detect used */
5445 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
5446 MDIO_WC_REG_PAR_DET_10G_STATUS
,
5449 vars
->link_status
|=
5450 LINK_STATUS_PARALLEL_DETECTION_USED
;
5452 bnx2x_ext_phy_resolve_fc(phy
, params
, vars
);
5457 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
5458 MDIO_WC_REG_GP2_STATUS_GP_2_2
, &gp_speed
);
5460 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
5461 MDIO_WC_REG_GP2_STATUS_GP_2_3
, &gp_speed
);
5463 DP(NETIF_MSG_LINK
, "lane %d gp_speed 0x%x\n", lane
, gp_speed
);
5465 if ((lane
& 1) == 0)
5470 rc
= bnx2x_get_link_speed_duplex(phy
, params
, vars
, link_up
, gp_speed
,
5473 DP(NETIF_MSG_LINK
, "duplex %x flow_ctrl 0x%x link_status 0x%x\n",
5474 vars
->duplex
, vars
->flow_ctrl
, vars
->link_status
);
5477 static void bnx2x_set_gmii_tx_driver(struct link_params
*params
)
5479 struct bnx2x
*bp
= params
->bp
;
5480 struct bnx2x_phy
*phy
= ¶ms
->phy
[INT_PHY
];
5486 CL22_RD_OVER_CL45(bp
, phy
,
5487 MDIO_REG_BANK_OVER_1G
,
5488 MDIO_OVER_1G_LP_UP2
, &lp_up2
);
5490 /* bits [10:7] at lp_up2, positioned at [15:12] */
5491 lp_up2
= (((lp_up2
& MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK
) >>
5492 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT
) <<
5493 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT
);
5498 for (bank
= MDIO_REG_BANK_TX0
; bank
<= MDIO_REG_BANK_TX3
;
5499 bank
+= (MDIO_REG_BANK_TX1
- MDIO_REG_BANK_TX0
)) {
5500 CL22_RD_OVER_CL45(bp
, phy
,
5502 MDIO_TX0_TX_DRIVER
, &tx_driver
);
5504 /* replace tx_driver bits [15:12] */
5506 (tx_driver
& MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK
)) {
5507 tx_driver
&= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK
;
5508 tx_driver
|= lp_up2
;
5509 CL22_WR_OVER_CL45(bp
, phy
,
5511 MDIO_TX0_TX_DRIVER
, tx_driver
);
5516 static int bnx2x_emac_program(struct link_params
*params
,
5517 struct link_vars
*vars
)
5519 struct bnx2x
*bp
= params
->bp
;
5520 u8 port
= params
->port
;
5523 DP(NETIF_MSG_LINK
, "setting link speed & duplex\n");
5524 bnx2x_bits_dis(bp
, GRCBASE_EMAC0
+ port
*0x400 +
5526 (EMAC_MODE_25G_MODE
|
5527 EMAC_MODE_PORT_MII_10M
|
5528 EMAC_MODE_HALF_DUPLEX
));
5529 switch (vars
->line_speed
) {
5531 mode
|= EMAC_MODE_PORT_MII_10M
;
5535 mode
|= EMAC_MODE_PORT_MII
;
5539 mode
|= EMAC_MODE_PORT_GMII
;
5543 mode
|= (EMAC_MODE_25G_MODE
| EMAC_MODE_PORT_GMII
);
5547 /* 10G not valid for EMAC */
5548 DP(NETIF_MSG_LINK
, "Invalid line_speed 0x%x\n",
5553 if (vars
->duplex
== DUPLEX_HALF
)
5554 mode
|= EMAC_MODE_HALF_DUPLEX
;
5556 GRCBASE_EMAC0
+ port
*0x400 + EMAC_REG_EMAC_MODE
,
5559 bnx2x_set_led(params
, vars
, LED_MODE_OPER
, vars
->line_speed
);
5563 static void bnx2x_set_preemphasis(struct bnx2x_phy
*phy
,
5564 struct link_params
*params
)
5568 struct bnx2x
*bp
= params
->bp
;
5570 for (bank
= MDIO_REG_BANK_RX0
, i
= 0; bank
<= MDIO_REG_BANK_RX3
;
5571 bank
+= (MDIO_REG_BANK_RX1
-MDIO_REG_BANK_RX0
), i
++) {
5572 CL22_WR_OVER_CL45(bp
, phy
,
5574 MDIO_RX0_RX_EQ_BOOST
,
5575 phy
->rx_preemphasis
[i
]);
5578 for (bank
= MDIO_REG_BANK_TX0
, i
= 0; bank
<= MDIO_REG_BANK_TX3
;
5579 bank
+= (MDIO_REG_BANK_TX1
- MDIO_REG_BANK_TX0
), i
++) {
5580 CL22_WR_OVER_CL45(bp
, phy
,
5583 phy
->tx_preemphasis
[i
]);
5587 static void bnx2x_xgxs_config_init(struct bnx2x_phy
*phy
,
5588 struct link_params
*params
,
5589 struct link_vars
*vars
)
5591 struct bnx2x
*bp
= params
->bp
;
5592 u8 enable_cl73
= (SINGLE_MEDIA_DIRECT(params
) ||
5593 (params
->loopback_mode
== LOOPBACK_XGXS
));
5594 if (!(vars
->phy_flags
& PHY_SGMII_FLAG
)) {
5595 if (SINGLE_MEDIA_DIRECT(params
) &&
5596 (params
->feature_config_flags
&
5597 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED
))
5598 bnx2x_set_preemphasis(phy
, params
);
5600 /* forced speed requested? */
5601 if (vars
->line_speed
!= SPEED_AUTO_NEG
||
5602 (SINGLE_MEDIA_DIRECT(params
) &&
5603 params
->loopback_mode
== LOOPBACK_EXT
)) {
5604 DP(NETIF_MSG_LINK
, "not SGMII, no AN\n");
5606 /* disable autoneg */
5607 bnx2x_set_autoneg(phy
, params
, vars
, 0);
5609 /* program speed and duplex */
5610 bnx2x_program_serdes(phy
, params
, vars
);
5612 } else { /* AN_mode */
5613 DP(NETIF_MSG_LINK
, "not SGMII, AN\n");
5616 bnx2x_set_brcm_cl37_advertisement(phy
, params
);
5618 /* program duplex & pause advertisement (for aneg) */
5619 bnx2x_set_ieee_aneg_advertisement(phy
, params
,
5622 /* enable autoneg */
5623 bnx2x_set_autoneg(phy
, params
, vars
, enable_cl73
);
5625 /* enable and restart AN */
5626 bnx2x_restart_autoneg(phy
, params
, enable_cl73
);
5629 } else { /* SGMII mode */
5630 DP(NETIF_MSG_LINK
, "SGMII\n");
5632 bnx2x_initialize_sgmii_process(phy
, params
, vars
);
5636 static int bnx2x_prepare_xgxs(struct bnx2x_phy
*phy
,
5637 struct link_params
*params
,
5638 struct link_vars
*vars
)
5641 vars
->phy_flags
|= PHY_XGXS_FLAG
;
5642 if ((phy
->req_line_speed
&&
5643 ((phy
->req_line_speed
== SPEED_100
) ||
5644 (phy
->req_line_speed
== SPEED_10
))) ||
5645 (!phy
->req_line_speed
&&
5646 (phy
->speed_cap_mask
>=
5647 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL
) &&
5648 (phy
->speed_cap_mask
<
5649 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
)) ||
5650 (phy
->type
== PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD
))
5651 vars
->phy_flags
|= PHY_SGMII_FLAG
;
5653 vars
->phy_flags
&= ~PHY_SGMII_FLAG
;
5655 bnx2x_calc_ieee_aneg_adv(phy
, params
, &vars
->ieee_fc
);
5656 bnx2x_set_aer_mmd(params
, phy
);
5657 if (phy
->type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
)
5658 bnx2x_set_master_ln(params
, phy
);
5660 rc
= bnx2x_reset_unicore(params
, phy
, 0);
5661 /* reset the SerDes and wait for reset bit return low */
5665 bnx2x_set_aer_mmd(params
, phy
);
5666 /* setting the masterLn_def again after the reset */
5667 if (phy
->type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
) {
5668 bnx2x_set_master_ln(params
, phy
);
5669 bnx2x_set_swap_lanes(params
, phy
);
5675 static u16
bnx2x_wait_reset_complete(struct bnx2x
*bp
,
5676 struct bnx2x_phy
*phy
,
5677 struct link_params
*params
)
5680 /* Wait for soft reset to get cleared up to 1 sec */
5681 for (cnt
= 0; cnt
< 1000; cnt
++) {
5682 if (phy
->type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE
)
5683 bnx2x_cl22_read(bp
, phy
,
5684 MDIO_PMA_REG_CTRL
, &ctrl
);
5686 bnx2x_cl45_read(bp
, phy
,
5688 MDIO_PMA_REG_CTRL
, &ctrl
);
5689 if (!(ctrl
& (1<<15)))
5695 netdev_err(bp
->dev
, "Warning: PHY was not initialized,"
5698 DP(NETIF_MSG_LINK
, "control reg 0x%x (after %d ms)\n", ctrl
, cnt
);
5702 static void bnx2x_link_int_enable(struct link_params
*params
)
5704 u8 port
= params
->port
;
5706 struct bnx2x
*bp
= params
->bp
;
5708 /* Setting the status to report on link up for either XGXS or SerDes */
5709 if (CHIP_IS_E3(bp
)) {
5710 mask
= NIG_MASK_XGXS0_LINK_STATUS
;
5711 if (!(SINGLE_MEDIA_DIRECT(params
)))
5712 mask
|= NIG_MASK_MI_INT
;
5713 } else if (params
->switch_cfg
== SWITCH_CFG_10G
) {
5714 mask
= (NIG_MASK_XGXS0_LINK10G
|
5715 NIG_MASK_XGXS0_LINK_STATUS
);
5716 DP(NETIF_MSG_LINK
, "enabled XGXS interrupt\n");
5717 if (!(SINGLE_MEDIA_DIRECT(params
)) &&
5718 params
->phy
[INT_PHY
].type
!=
5719 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
) {
5720 mask
|= NIG_MASK_MI_INT
;
5721 DP(NETIF_MSG_LINK
, "enabled external phy int\n");
5724 } else { /* SerDes */
5725 mask
= NIG_MASK_SERDES0_LINK_STATUS
;
5726 DP(NETIF_MSG_LINK
, "enabled SerDes interrupt\n");
5727 if (!(SINGLE_MEDIA_DIRECT(params
)) &&
5728 params
->phy
[INT_PHY
].type
!=
5729 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN
) {
5730 mask
|= NIG_MASK_MI_INT
;
5731 DP(NETIF_MSG_LINK
, "enabled external phy int\n");
5735 NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4,
5738 DP(NETIF_MSG_LINK
, "port %x, is_xgxs %x, int_status 0x%x\n", port
,
5739 (params
->switch_cfg
== SWITCH_CFG_10G
),
5740 REG_RD(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4));
5741 DP(NETIF_MSG_LINK
, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
5742 REG_RD(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4),
5743 REG_RD(bp
, NIG_REG_EMAC0_STATUS_MISC_MI_INT
+ port
*0x18),
5744 REG_RD(bp
, NIG_REG_SERDES0_STATUS_LINK_STATUS
+port
*0x3c));
5745 DP(NETIF_MSG_LINK
, " 10G %x, XGXS_LINK %x\n",
5746 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK10G
+ port
*0x68),
5747 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK_STATUS
+ port
*0x68));
5750 static void bnx2x_rearm_latch_signal(struct bnx2x
*bp
, u8 port
,
5753 u32 latch_status
= 0;
5756 * Disable the MI INT ( external phy int ) by writing 1 to the
5757 * status register. Link down indication is high-active-signal,
5758 * so in this case we need to write the status to clear the XOR
5760 /* Read Latched signals */
5761 latch_status
= REG_RD(bp
,
5762 NIG_REG_LATCH_STATUS_0
+ port
*8);
5763 DP(NETIF_MSG_LINK
, "latch_status = 0x%x\n", latch_status
);
5764 /* Handle only those with latched-signal=up.*/
5767 NIG_REG_STATUS_INTERRUPT_PORT0
5769 NIG_STATUS_EMAC0_MI_INT
);
5772 NIG_REG_STATUS_INTERRUPT_PORT0
5774 NIG_STATUS_EMAC0_MI_INT
);
5776 if (latch_status
& 1) {
5778 /* For all latched-signal=up : Re-Arm Latch signals */
5779 REG_WR(bp
, NIG_REG_LATCH_STATUS_0
+ port
*8,
5780 (latch_status
& 0xfffe) | (latch_status
& 1));
5782 /* For all latched-signal=up,Write original_signal to status */
5785 static void bnx2x_link_int_ack(struct link_params
*params
,
5786 struct link_vars
*vars
, u8 is_10g_plus
)
5788 struct bnx2x
*bp
= params
->bp
;
5789 u8 port
= params
->port
;
5792 * First reset all status we assume only one line will be
5795 bnx2x_bits_dis(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
5796 (NIG_STATUS_XGXS0_LINK10G
|
5797 NIG_STATUS_XGXS0_LINK_STATUS
|
5798 NIG_STATUS_SERDES0_LINK_STATUS
));
5799 if (vars
->phy_link_up
) {
5800 if (USES_WARPCORE(bp
))
5801 mask
= NIG_STATUS_XGXS0_LINK_STATUS
;
5804 mask
= NIG_STATUS_XGXS0_LINK10G
;
5805 else if (params
->switch_cfg
== SWITCH_CFG_10G
) {
5807 * Disable the link interrupt by writing 1 to
5808 * the relevant lane in the status register
5811 ((params
->lane_config
&
5812 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK
) >>
5813 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT
);
5814 mask
= ((1 << ser_lane
) <<
5815 NIG_STATUS_XGXS0_LINK_STATUS_SIZE
);
5817 mask
= NIG_STATUS_SERDES0_LINK_STATUS
;
5819 DP(NETIF_MSG_LINK
, "Ack link up interrupt with mask 0x%x\n",
5822 NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4,
5827 static int bnx2x_format_ver(u32 num
, u8
*str
, u16
*len
)
5830 u32 mask
= 0xf0000000;
5833 u8 remove_leading_zeros
= 1;
5835 /* Need more than 10chars for this format */
5843 digit
= ((num
& mask
) >> shift
);
5844 if (digit
== 0 && remove_leading_zeros
) {
5847 } else if (digit
< 0xa)
5848 *str_ptr
= digit
+ '0';
5850 *str_ptr
= digit
- 0xa + 'a';
5851 remove_leading_zeros
= 0;
5859 remove_leading_zeros
= 1;
5866 static int bnx2x_null_format_ver(u32 spirom_ver
, u8
*str
, u16
*len
)
5873 int bnx2x_get_ext_phy_fw_version(struct link_params
*params
, u8 driver_loaded
,
5874 u8
*version
, u16 len
)
5879 u8
*ver_p
= version
;
5880 u16 remain_len
= len
;
5881 if (version
== NULL
|| params
== NULL
)
5885 /* Extract first external phy*/
5887 spirom_ver
= REG_RD(bp
, params
->phy
[EXT_PHY1
].ver_addr
);
5889 if (params
->phy
[EXT_PHY1
].format_fw_ver
) {
5890 status
|= params
->phy
[EXT_PHY1
].format_fw_ver(spirom_ver
,
5893 ver_p
+= (len
- remain_len
);
5895 if ((params
->num_phys
== MAX_PHYS
) &&
5896 (params
->phy
[EXT_PHY2
].ver_addr
!= 0)) {
5897 spirom_ver
= REG_RD(bp
, params
->phy
[EXT_PHY2
].ver_addr
);
5898 if (params
->phy
[EXT_PHY2
].format_fw_ver
) {
5902 status
|= params
->phy
[EXT_PHY2
].format_fw_ver(
5906 ver_p
= version
+ (len
- remain_len
);
5913 static void bnx2x_set_xgxs_loopback(struct bnx2x_phy
*phy
,
5914 struct link_params
*params
)
5916 u8 port
= params
->port
;
5917 struct bnx2x
*bp
= params
->bp
;
5919 if (phy
->req_line_speed
!= SPEED_1000
) {
5922 DP(NETIF_MSG_LINK
, "XGXS 10G loopback enable\n");
5924 if (!CHIP_IS_E3(bp
)) {
5925 /* change the uni_phy_addr in the nig */
5926 md_devad
= REG_RD(bp
, (NIG_REG_XGXS0_CTRL_MD_DEVAD
+
5929 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_DEVAD
+ port
*0x18,
5933 bnx2x_cl45_write(bp
, phy
,
5935 (MDIO_REG_BANK_AER_BLOCK
+
5936 (MDIO_AER_BLOCK_AER_REG
& 0xf)),
5939 bnx2x_cl45_write(bp
, phy
,
5941 (MDIO_REG_BANK_CL73_IEEEB0
+
5942 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL
& 0xf)),
5945 /* set aer mmd back */
5946 bnx2x_set_aer_mmd(params
, phy
);
5948 if (!CHIP_IS_E3(bp
)) {
5950 REG_WR(bp
, NIG_REG_XGXS0_CTRL_MD_DEVAD
+ port
*0x18,
5955 DP(NETIF_MSG_LINK
, "XGXS 1G loopback enable\n");
5956 bnx2x_cl45_read(bp
, phy
, 5,
5957 (MDIO_REG_BANK_COMBO_IEEE0
+
5958 (MDIO_COMBO_IEEE0_MII_CONTROL
& 0xf)),
5960 bnx2x_cl45_write(bp
, phy
, 5,
5961 (MDIO_REG_BANK_COMBO_IEEE0
+
5962 (MDIO_COMBO_IEEE0_MII_CONTROL
& 0xf)),
5964 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK
);
5968 int bnx2x_set_led(struct link_params
*params
,
5969 struct link_vars
*vars
, u8 mode
, u32 speed
)
5971 u8 port
= params
->port
;
5972 u16 hw_led_mode
= params
->hw_led_mode
;
5976 u32 emac_base
= port
? GRCBASE_EMAC1
: GRCBASE_EMAC0
;
5977 struct bnx2x
*bp
= params
->bp
;
5978 DP(NETIF_MSG_LINK
, "bnx2x_set_led: port %x, mode %d\n", port
, mode
);
5979 DP(NETIF_MSG_LINK
, "speed 0x%x, hw_led_mode 0x%x\n",
5980 speed
, hw_led_mode
);
5982 for (phy_idx
= EXT_PHY1
; phy_idx
< MAX_PHYS
; phy_idx
++) {
5983 if (params
->phy
[phy_idx
].set_link_led
) {
5984 params
->phy
[phy_idx
].set_link_led(
5985 ¶ms
->phy
[phy_idx
], params
, mode
);
5990 case LED_MODE_FRONT_PANEL_OFF
:
5992 REG_WR(bp
, NIG_REG_LED_10G_P0
+ port
*4, 0);
5993 REG_WR(bp
, NIG_REG_LED_MODE_P0
+ port
*4,
5994 SHARED_HW_CFG_LED_MAC1
);
5996 tmp
= EMAC_RD(bp
, EMAC_REG_EMAC_LED
);
5997 if (params
->phy
[EXT_PHY1
].type
==
5998 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE
)
5999 EMAC_WR(bp
, EMAC_REG_EMAC_LED
, tmp
& 0xfff1);
6001 EMAC_WR(bp
, EMAC_REG_EMAC_LED
,
6002 (tmp
| EMAC_LED_OVERRIDE
));
6008 * For all other phys, OPER mode is same as ON, so in case
6009 * link is down, do nothing
6014 if (((params
->phy
[EXT_PHY1
].type
==
6015 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
) ||
6016 (params
->phy
[EXT_PHY1
].type
==
6017 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722
)) &&
6018 CHIP_IS_E2(bp
) && params
->num_phys
== 2) {
6020 * This is a work-around for E2+8727 Configurations
6022 if (mode
== LED_MODE_ON
||
6023 speed
== SPEED_10000
){
6024 REG_WR(bp
, NIG_REG_LED_MODE_P0
+ port
*4, 0);
6025 REG_WR(bp
, NIG_REG_LED_10G_P0
+ port
*4, 1);
6027 tmp
= EMAC_RD(bp
, EMAC_REG_EMAC_LED
);
6028 EMAC_WR(bp
, EMAC_REG_EMAC_LED
,
6029 (tmp
| EMAC_LED_OVERRIDE
));
6031 * return here without enabling traffic
6032 * LED blink and setting rate in ON mode.
6033 * In oper mode, enabling LED blink
6034 * and setting rate is needed.
6036 if (mode
== LED_MODE_ON
)
6039 } else if (SINGLE_MEDIA_DIRECT(params
)) {
6041 * This is a work-around for HW issue found when link
6044 if ((!CHIP_IS_E3(bp
)) ||
6046 mode
== LED_MODE_ON
))
6047 REG_WR(bp
, NIG_REG_LED_10G_P0
+ port
*4, 1);
6049 if (CHIP_IS_E1x(bp
) ||
6051 (mode
== LED_MODE_ON
))
6052 REG_WR(bp
, NIG_REG_LED_MODE_P0
+ port
*4, 0);
6054 REG_WR(bp
, NIG_REG_LED_MODE_P0
+ port
*4,
6056 } else if ((params
->phy
[EXT_PHY1
].type
==
6057 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE
) &&
6058 (mode
!= LED_MODE_OPER
)) {
6059 REG_WR(bp
, NIG_REG_LED_MODE_P0
+ port
*4, 0);
6060 tmp
= EMAC_RD(bp
, EMAC_REG_EMAC_LED
);
6061 EMAC_WR(bp
, EMAC_REG_EMAC_LED
, tmp
| 0x3);
6063 REG_WR(bp
, NIG_REG_LED_MODE_P0
+ port
*4,
6066 REG_WR(bp
, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
+ port
*4, 0);
6067 /* Set blinking rate to ~15.9Hz */
6069 REG_WR(bp
, NIG_REG_LED_CONTROL_BLINK_RATE_P0
+ port
*4,
6070 LED_BLINK_RATE_VAL_E3
);
6072 REG_WR(bp
, NIG_REG_LED_CONTROL_BLINK_RATE_P0
+ port
*4,
6073 LED_BLINK_RATE_VAL_E1X_E2
);
6074 REG_WR(bp
, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0
+
6076 if ((params
->phy
[EXT_PHY1
].type
!=
6077 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE
) &&
6078 (mode
!= LED_MODE_OPER
)) {
6079 tmp
= EMAC_RD(bp
, EMAC_REG_EMAC_LED
);
6080 EMAC_WR(bp
, EMAC_REG_EMAC_LED
,
6081 (tmp
& (~EMAC_LED_OVERRIDE
)));
6084 if (CHIP_IS_E1(bp
) &&
6085 ((speed
== SPEED_2500
) ||
6086 (speed
== SPEED_1000
) ||
6087 (speed
== SPEED_100
) ||
6088 (speed
== SPEED_10
))) {
6090 * On Everest 1 Ax chip versions for speeds less than
6091 * 10G LED scheme is different
6093 REG_WR(bp
, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
6095 REG_WR(bp
, NIG_REG_LED_CONTROL_TRAFFIC_P0
+
6097 REG_WR(bp
, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0
+
6104 DP(NETIF_MSG_LINK
, "bnx2x_set_led: Invalid led mode %d\n",
6113 * This function comes to reflect the actual link state read DIRECTLY from the
6116 int bnx2x_test_link(struct link_params
*params
, struct link_vars
*vars
,
6119 struct bnx2x
*bp
= params
->bp
;
6120 u16 gp_status
= 0, phy_index
= 0;
6121 u8 ext_phy_link_up
= 0, serdes_phy_type
;
6122 struct link_vars temp_vars
;
6123 struct bnx2x_phy
*int_phy
= ¶ms
->phy
[INT_PHY
];
6125 if (CHIP_IS_E3(bp
)) {
6127 if (params
->req_line_speed
[LINK_CONFIG_IDX(INT_PHY
)]
6129 /* Check 20G link */
6130 bnx2x_cl45_read(bp
, int_phy
, MDIO_WC_DEVAD
,
6132 bnx2x_cl45_read(bp
, int_phy
, MDIO_WC_DEVAD
,
6136 /* Check 10G link and below*/
6137 u8 lane
= bnx2x_get_warpcore_lane(int_phy
, params
);
6138 bnx2x_cl45_read(bp
, int_phy
, MDIO_WC_DEVAD
,
6139 MDIO_WC_REG_GP2_STATUS_GP_2_1
,
6141 gp_status
= ((gp_status
>> 8) & 0xf) |
6142 ((gp_status
>> 12) & 0xf);
6143 link_up
= gp_status
& (1 << lane
);
6148 CL22_RD_OVER_CL45(bp
, int_phy
,
6149 MDIO_REG_BANK_GP_STATUS
,
6150 MDIO_GP_STATUS_TOP_AN_STATUS1
,
6152 /* link is up only if both local phy and external phy are up */
6153 if (!(gp_status
& MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS
))
6156 /* In XGXS loopback mode, do not check external PHY */
6157 if (params
->loopback_mode
== LOOPBACK_XGXS
)
6160 switch (params
->num_phys
) {
6162 /* No external PHY */
6165 ext_phy_link_up
= params
->phy
[EXT_PHY1
].read_status(
6166 ¶ms
->phy
[EXT_PHY1
],
6167 params
, &temp_vars
);
6169 case 3: /* Dual Media */
6170 for (phy_index
= EXT_PHY1
; phy_index
< params
->num_phys
;
6172 serdes_phy_type
= ((params
->phy
[phy_index
].media_type
==
6173 ETH_PHY_SFP_FIBER
) ||
6174 (params
->phy
[phy_index
].media_type
==
6175 ETH_PHY_XFP_FIBER
) ||
6176 (params
->phy
[phy_index
].media_type
==
6177 ETH_PHY_DA_TWINAX
));
6179 if (is_serdes
!= serdes_phy_type
)
6181 if (params
->phy
[phy_index
].read_status
) {
6183 params
->phy
[phy_index
].read_status(
6184 ¶ms
->phy
[phy_index
],
6185 params
, &temp_vars
);
6190 if (ext_phy_link_up
)
6195 static int bnx2x_link_initialize(struct link_params
*params
,
6196 struct link_vars
*vars
)
6199 u8 phy_index
, non_ext_phy
;
6200 struct bnx2x
*bp
= params
->bp
;
6202 * In case of external phy existence, the line speed would be the
6203 * line speed linked up by the external phy. In case it is direct
6204 * only, then the line_speed during initialization will be
6205 * equal to the req_line_speed
6207 vars
->line_speed
= params
->phy
[INT_PHY
].req_line_speed
;
6210 * Initialize the internal phy in case this is a direct board
6211 * (no external phys), or this board has external phy which requires
6214 if (!USES_WARPCORE(bp
))
6215 bnx2x_prepare_xgxs(¶ms
->phy
[INT_PHY
], params
, vars
);
6216 /* init ext phy and enable link state int */
6217 non_ext_phy
= (SINGLE_MEDIA_DIRECT(params
) ||
6218 (params
->loopback_mode
== LOOPBACK_XGXS
));
6221 (params
->phy
[EXT_PHY1
].flags
& FLAGS_INIT_XGXS_FIRST
) ||
6222 (params
->loopback_mode
== LOOPBACK_EXT_PHY
)) {
6223 struct bnx2x_phy
*phy
= ¶ms
->phy
[INT_PHY
];
6224 if (vars
->line_speed
== SPEED_AUTO_NEG
&&
6227 bnx2x_set_parallel_detection(phy
, params
);
6228 if (params
->phy
[INT_PHY
].config_init
)
6229 params
->phy
[INT_PHY
].config_init(phy
,
6234 /* Init external phy*/
6236 if (params
->phy
[INT_PHY
].supported
&
6238 vars
->link_status
|= LINK_STATUS_SERDES_LINK
;
6240 for (phy_index
= EXT_PHY1
; phy_index
< params
->num_phys
;
6243 * No need to initialize second phy in case of first
6244 * phy only selection. In case of second phy, we do
6245 * need to initialize the first phy, since they are
6248 if (params
->phy
[phy_index
].supported
&
6250 vars
->link_status
|= LINK_STATUS_SERDES_LINK
;
6252 if (phy_index
== EXT_PHY2
&&
6253 (bnx2x_phy_selection(params
) ==
6254 PORT_HW_CFG_PHY_SELECTION_FIRST_PHY
)) {
6256 "Not initializing second phy\n");
6259 params
->phy
[phy_index
].config_init(
6260 ¶ms
->phy
[phy_index
],
6264 /* Reset the interrupt indication after phy was initialized */
6265 bnx2x_bits_dis(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+
6267 (NIG_STATUS_XGXS0_LINK10G
|
6268 NIG_STATUS_XGXS0_LINK_STATUS
|
6269 NIG_STATUS_SERDES0_LINK_STATUS
|
6271 bnx2x_update_mng(params
, vars
->link_status
);
6275 static void bnx2x_int_link_reset(struct bnx2x_phy
*phy
,
6276 struct link_params
*params
)
6278 /* reset the SerDes/XGXS */
6279 REG_WR(params
->bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_3_CLEAR
,
6280 (0x1ff << (params
->port
*16)));
6283 static void bnx2x_common_ext_link_reset(struct bnx2x_phy
*phy
,
6284 struct link_params
*params
)
6286 struct bnx2x
*bp
= params
->bp
;
6290 gpio_port
= BP_PATH(bp
);
6292 gpio_port
= params
->port
;
6293 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
6294 MISC_REGISTERS_GPIO_OUTPUT_LOW
,
6296 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
6297 MISC_REGISTERS_GPIO_OUTPUT_LOW
,
6299 DP(NETIF_MSG_LINK
, "reset external PHY\n");
6302 static int bnx2x_update_link_down(struct link_params
*params
,
6303 struct link_vars
*vars
)
6305 struct bnx2x
*bp
= params
->bp
;
6306 u8 port
= params
->port
;
6308 DP(NETIF_MSG_LINK
, "Port %x: Link is down\n", port
);
6309 bnx2x_set_led(params
, vars
, LED_MODE_OFF
, 0);
6310 vars
->phy_flags
&= ~PHY_PHYSICAL_LINK_FLAG
;
6311 /* indicate no mac active */
6312 vars
->mac_type
= MAC_TYPE_NONE
;
6314 /* update shared memory */
6315 vars
->link_status
&= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK
|
6316 LINK_STATUS_LINK_UP
|
6317 LINK_STATUS_PHYSICAL_LINK_FLAG
|
6318 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE
|
6319 LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK
|
6320 LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK
|
6321 LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK
);
6322 vars
->line_speed
= 0;
6323 bnx2x_update_mng(params
, vars
->link_status
);
6325 /* activate nig drain */
6326 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ port
*4, 1);
6329 if (!CHIP_IS_E3(bp
))
6330 REG_WR(bp
, NIG_REG_NIG_EMAC0_EN
+ port
*4, 0);
6333 /* reset BigMac/Xmac */
6334 if (CHIP_IS_E1x(bp
) ||
6336 bnx2x_bmac_rx_disable(bp
, params
->port
);
6337 REG_WR(bp
, GRCBASE_MISC
+
6338 MISC_REGISTERS_RESET_REG_2_CLEAR
,
6339 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
6341 if (CHIP_IS_E3(bp
)) {
6342 bnx2x_xmac_disable(params
);
6343 bnx2x_umac_disable(params
);
6349 static int bnx2x_update_link_up(struct link_params
*params
,
6350 struct link_vars
*vars
,
6353 struct bnx2x
*bp
= params
->bp
;
6354 u8 port
= params
->port
;
6357 vars
->link_status
|= (LINK_STATUS_LINK_UP
|
6358 LINK_STATUS_PHYSICAL_LINK_FLAG
);
6359 vars
->phy_flags
|= PHY_PHYSICAL_LINK_FLAG
;
6361 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_TX
)
6362 vars
->link_status
|=
6363 LINK_STATUS_TX_FLOW_CONTROL_ENABLED
;
6365 if (vars
->flow_ctrl
& BNX2X_FLOW_CTRL_RX
)
6366 vars
->link_status
|=
6367 LINK_STATUS_RX_FLOW_CONTROL_ENABLED
;
6368 if (USES_WARPCORE(bp
)) {
6370 if (bnx2x_xmac_enable(params
, vars
, 0) ==
6372 DP(NETIF_MSG_LINK
, "Found errors on XMAC\n");
6374 vars
->phy_flags
|= PHY_HALF_OPEN_CONN_FLAG
;
6375 vars
->link_status
&= ~LINK_STATUS_LINK_UP
;
6378 bnx2x_umac_enable(params
, vars
, 0);
6379 bnx2x_set_led(params
, vars
,
6380 LED_MODE_OPER
, vars
->line_speed
);
6382 if ((CHIP_IS_E1x(bp
) ||
6385 if (bnx2x_bmac_enable(params
, vars
, 0) ==
6387 DP(NETIF_MSG_LINK
, "Found errors on BMAC\n");
6389 vars
->phy_flags
|= PHY_HALF_OPEN_CONN_FLAG
;
6390 vars
->link_status
&= ~LINK_STATUS_LINK_UP
;
6393 bnx2x_set_led(params
, vars
,
6394 LED_MODE_OPER
, SPEED_10000
);
6396 rc
= bnx2x_emac_program(params
, vars
);
6397 bnx2x_emac_enable(params
, vars
, 0);
6400 if ((vars
->link_status
&
6401 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE
)
6402 && (!(vars
->phy_flags
& PHY_SGMII_FLAG
)) &&
6403 SINGLE_MEDIA_DIRECT(params
))
6404 bnx2x_set_gmii_tx_driver(params
);
6409 if (CHIP_IS_E1x(bp
))
6410 rc
|= bnx2x_pbf_update(params
, vars
->flow_ctrl
,
6414 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ port
*4, 0);
6416 /* update shared memory */
6417 bnx2x_update_mng(params
, vars
->link_status
);
6422 * The bnx2x_link_update function should be called upon link
6424 * Link is considered up as follows:
6425 * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
6427 * - SINGLE_MEDIA - The link between the 577xx and the external
6428 * phy (XGXS) need to up as well as the external link of the
6430 * - DUAL_MEDIA - The link between the 577xx and the first
6431 * external phy needs to be up, and at least one of the 2
6432 * external phy link must be up.
6434 int bnx2x_link_update(struct link_params
*params
, struct link_vars
*vars
)
6436 struct bnx2x
*bp
= params
->bp
;
6437 struct link_vars phy_vars
[MAX_PHYS
];
6438 u8 port
= params
->port
;
6439 u8 link_10g_plus
, phy_index
;
6440 u8 ext_phy_link_up
= 0, cur_link_up
;
6443 u16 ext_phy_line_speed
= 0, prev_line_speed
= vars
->line_speed
;
6444 u8 active_external_phy
= INT_PHY
;
6445 vars
->phy_flags
&= ~PHY_HALF_OPEN_CONN_FLAG
;
6446 for (phy_index
= INT_PHY
; phy_index
< params
->num_phys
;
6448 phy_vars
[phy_index
].flow_ctrl
= 0;
6449 phy_vars
[phy_index
].link_status
= 0;
6450 phy_vars
[phy_index
].line_speed
= 0;
6451 phy_vars
[phy_index
].duplex
= DUPLEX_FULL
;
6452 phy_vars
[phy_index
].phy_link_up
= 0;
6453 phy_vars
[phy_index
].link_up
= 0;
6454 phy_vars
[phy_index
].fault_detected
= 0;
6457 if (USES_WARPCORE(bp
))
6458 bnx2x_set_aer_mmd(params
, ¶ms
->phy
[INT_PHY
]);
6460 DP(NETIF_MSG_LINK
, "port %x, XGXS?%x, int_status 0x%x\n",
6461 port
, (vars
->phy_flags
& PHY_XGXS_FLAG
),
6462 REG_RD(bp
, NIG_REG_STATUS_INTERRUPT_PORT0
+ port
*4));
6464 is_mi_int
= (u8
)(REG_RD(bp
, NIG_REG_EMAC0_STATUS_MISC_MI_INT
+
6466 DP(NETIF_MSG_LINK
, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
6467 REG_RD(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4),
6469 REG_RD(bp
, NIG_REG_SERDES0_STATUS_LINK_STATUS
+ port
*0x3c));
6471 DP(NETIF_MSG_LINK
, " 10G %x, XGXS_LINK %x\n",
6472 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK10G
+ port
*0x68),
6473 REG_RD(bp
, NIG_REG_XGXS0_STATUS_LINK_STATUS
+ port
*0x68));
6476 if (!CHIP_IS_E3(bp
))
6477 REG_WR(bp
, NIG_REG_NIG_EMAC0_EN
+ port
*4, 0);
6481 * Check external link change only for external phys, and apply
6482 * priority selection between them in case the link on both phys
6483 * is up. Note that instead of the common vars, a temporary
6484 * vars argument is used since each phy may have different link/
6485 * speed/duplex result
6487 for (phy_index
= EXT_PHY1
; phy_index
< params
->num_phys
;
6489 struct bnx2x_phy
*phy
= ¶ms
->phy
[phy_index
];
6490 if (!phy
->read_status
)
6492 /* Read link status and params of this ext phy */
6493 cur_link_up
= phy
->read_status(phy
, params
,
6494 &phy_vars
[phy_index
]);
6496 DP(NETIF_MSG_LINK
, "phy in index %d link is up\n",
6499 DP(NETIF_MSG_LINK
, "phy in index %d link is down\n",
6504 if (!ext_phy_link_up
) {
6505 ext_phy_link_up
= 1;
6506 active_external_phy
= phy_index
;
6508 switch (bnx2x_phy_selection(params
)) {
6509 case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT
:
6510 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY
:
6512 * In this option, the first PHY makes sure to pass the
6513 * traffic through itself only.
6514 * Its not clear how to reset the link on the second phy
6516 active_external_phy
= EXT_PHY1
;
6518 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY
:
6520 * In this option, the first PHY makes sure to pass the
6521 * traffic through the second PHY.
6523 active_external_phy
= EXT_PHY2
;
6527 * Link indication on both PHYs with the following cases
6529 * - FIRST_PHY means that second phy wasn't initialized,
6530 * hence its link is expected to be down
6531 * - SECOND_PHY means that first phy should not be able
6532 * to link up by itself (using configuration)
6533 * - DEFAULT should be overriden during initialiazation
6535 DP(NETIF_MSG_LINK
, "Invalid link indication"
6536 "mpc=0x%x. DISABLING LINK !!!\n",
6537 params
->multi_phy_config
);
6538 ext_phy_link_up
= 0;
6543 prev_line_speed
= vars
->line_speed
;
6546 * Read the status of the internal phy. In case of
6547 * DIRECT_SINGLE_MEDIA board, this link is the external link,
6548 * otherwise this is the link between the 577xx and the first
6551 if (params
->phy
[INT_PHY
].read_status
)
6552 params
->phy
[INT_PHY
].read_status(
6553 ¶ms
->phy
[INT_PHY
],
6556 * The INT_PHY flow control reside in the vars. This include the
6557 * case where the speed or flow control are not set to AUTO.
6558 * Otherwise, the active external phy flow control result is set
6559 * to the vars. The ext_phy_line_speed is needed to check if the
6560 * speed is different between the internal phy and external phy.
6561 * This case may be result of intermediate link speed change.
6563 if (active_external_phy
> INT_PHY
) {
6564 vars
->flow_ctrl
= phy_vars
[active_external_phy
].flow_ctrl
;
6566 * Link speed is taken from the XGXS. AN and FC result from
6569 vars
->link_status
|= phy_vars
[active_external_phy
].link_status
;
6572 * if active_external_phy is first PHY and link is up - disable
6573 * disable TX on second external PHY
6575 if (active_external_phy
== EXT_PHY1
) {
6576 if (params
->phy
[EXT_PHY2
].phy_specific_func
) {
6578 "Disabling TX on EXT_PHY2\n");
6579 params
->phy
[EXT_PHY2
].phy_specific_func(
6580 ¶ms
->phy
[EXT_PHY2
],
6581 params
, DISABLE_TX
);
6585 ext_phy_line_speed
= phy_vars
[active_external_phy
].line_speed
;
6586 vars
->duplex
= phy_vars
[active_external_phy
].duplex
;
6587 if (params
->phy
[active_external_phy
].supported
&
6589 vars
->link_status
|= LINK_STATUS_SERDES_LINK
;
6591 vars
->link_status
&= ~LINK_STATUS_SERDES_LINK
;
6592 DP(NETIF_MSG_LINK
, "Active external phy selected: %x\n",
6593 active_external_phy
);
6596 for (phy_index
= EXT_PHY1
; phy_index
< params
->num_phys
;
6598 if (params
->phy
[phy_index
].flags
&
6599 FLAGS_REARM_LATCH_SIGNAL
) {
6600 bnx2x_rearm_latch_signal(bp
, port
,
6602 active_external_phy
);
6606 DP(NETIF_MSG_LINK
, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
6607 " ext_phy_line_speed = %d\n", vars
->flow_ctrl
,
6608 vars
->link_status
, ext_phy_line_speed
);
6610 * Upon link speed change set the NIG into drain mode. Comes to
6611 * deals with possible FIFO glitch due to clk change when speed
6612 * is decreased without link down indicator
6615 if (vars
->phy_link_up
) {
6616 if (!(SINGLE_MEDIA_DIRECT(params
)) && ext_phy_link_up
&&
6617 (ext_phy_line_speed
!= vars
->line_speed
)) {
6618 DP(NETIF_MSG_LINK
, "Internal link speed %d is"
6619 " different than the external"
6620 " link speed %d\n", vars
->line_speed
,
6621 ext_phy_line_speed
);
6622 vars
->phy_link_up
= 0;
6623 } else if (prev_line_speed
!= vars
->line_speed
) {
6624 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ params
->port
*4,
6630 /* anything 10 and over uses the bmac */
6631 link_10g_plus
= (vars
->line_speed
>= SPEED_10000
);
6633 bnx2x_link_int_ack(params
, vars
, link_10g_plus
);
6636 * In case external phy link is up, and internal link is down
6637 * (not initialized yet probably after link initialization, it
6638 * needs to be initialized.
6639 * Note that after link down-up as result of cable plug, the xgxs
6640 * link would probably become up again without the need
6643 if (!(SINGLE_MEDIA_DIRECT(params
))) {
6644 DP(NETIF_MSG_LINK
, "ext_phy_link_up = %d, int_link_up = %d,"
6645 " init_preceding = %d\n", ext_phy_link_up
,
6647 params
->phy
[EXT_PHY1
].flags
&
6648 FLAGS_INIT_XGXS_FIRST
);
6649 if (!(params
->phy
[EXT_PHY1
].flags
&
6650 FLAGS_INIT_XGXS_FIRST
)
6651 && ext_phy_link_up
&& !vars
->phy_link_up
) {
6652 vars
->line_speed
= ext_phy_line_speed
;
6653 if (vars
->line_speed
< SPEED_1000
)
6654 vars
->phy_flags
|= PHY_SGMII_FLAG
;
6656 vars
->phy_flags
&= ~PHY_SGMII_FLAG
;
6658 if (params
->phy
[INT_PHY
].config_init
)
6659 params
->phy
[INT_PHY
].config_init(
6660 ¶ms
->phy
[INT_PHY
], params
,
6665 * Link is up only if both local phy and external phy (in case of
6666 * non-direct board) are up and no fault detected on active PHY.
6668 vars
->link_up
= (vars
->phy_link_up
&&
6670 SINGLE_MEDIA_DIRECT(params
)) &&
6671 (phy_vars
[active_external_phy
].fault_detected
== 0));
6674 rc
= bnx2x_update_link_up(params
, vars
, link_10g_plus
);
6676 rc
= bnx2x_update_link_down(params
, vars
);
6682 /*****************************************************************************/
6683 /* External Phy section */
6684 /*****************************************************************************/
6685 void bnx2x_ext_phy_hw_reset(struct bnx2x
*bp
, u8 port
)
6687 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
6688 MISC_REGISTERS_GPIO_OUTPUT_LOW
, port
);
6690 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
6691 MISC_REGISTERS_GPIO_OUTPUT_HIGH
, port
);
6694 static void bnx2x_save_spirom_version(struct bnx2x
*bp
, u8 port
,
6695 u32 spirom_ver
, u32 ver_addr
)
6697 DP(NETIF_MSG_LINK
, "FW version 0x%x:0x%x for port %d\n",
6698 (u16
)(spirom_ver
>>16), (u16
)spirom_ver
, port
);
6701 REG_WR(bp
, ver_addr
, spirom_ver
);
6704 static void bnx2x_save_bcm_spirom_ver(struct bnx2x
*bp
,
6705 struct bnx2x_phy
*phy
,
6708 u16 fw_ver1
, fw_ver2
;
6710 bnx2x_cl45_read(bp
, phy
, MDIO_PMA_DEVAD
,
6711 MDIO_PMA_REG_ROM_VER1
, &fw_ver1
);
6712 bnx2x_cl45_read(bp
, phy
, MDIO_PMA_DEVAD
,
6713 MDIO_PMA_REG_ROM_VER2
, &fw_ver2
);
6714 bnx2x_save_spirom_version(bp
, port
, (u32
)(fw_ver1
<<16 | fw_ver2
),
6718 static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x
*bp
,
6719 struct bnx2x_phy
*phy
,
6720 struct link_vars
*vars
)
6723 bnx2x_cl45_read(bp
, phy
,
6725 MDIO_AN_REG_STATUS
, &val
);
6726 bnx2x_cl45_read(bp
, phy
,
6728 MDIO_AN_REG_STATUS
, &val
);
6730 vars
->link_status
|= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE
;
6731 if ((val
& (1<<0)) == 0)
6732 vars
->link_status
|= LINK_STATUS_PARALLEL_DETECTION_USED
;
6735 /******************************************************************/
6736 /* common BCM8073/BCM8727 PHY SECTION */
6737 /******************************************************************/
6738 static void bnx2x_8073_resolve_fc(struct bnx2x_phy
*phy
,
6739 struct link_params
*params
,
6740 struct link_vars
*vars
)
6742 struct bnx2x
*bp
= params
->bp
;
6743 if (phy
->req_line_speed
== SPEED_10
||
6744 phy
->req_line_speed
== SPEED_100
) {
6745 vars
->flow_ctrl
= phy
->req_flow_ctrl
;
6749 if (bnx2x_ext_phy_resolve_fc(phy
, params
, vars
) &&
6750 (vars
->flow_ctrl
== BNX2X_FLOW_CTRL_NONE
)) {
6752 u16 ld_pause
; /* local */
6753 u16 lp_pause
; /* link partner */
6754 bnx2x_cl45_read(bp
, phy
,
6756 MDIO_AN_REG_CL37_FC_LD
, &ld_pause
);
6758 bnx2x_cl45_read(bp
, phy
,
6760 MDIO_AN_REG_CL37_FC_LP
, &lp_pause
);
6761 pause_result
= (ld_pause
&
6762 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) >> 5;
6763 pause_result
|= (lp_pause
&
6764 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) >> 7;
6766 bnx2x_pause_resolve(vars
, pause_result
);
6767 DP(NETIF_MSG_LINK
, "Ext PHY CL37 pause result 0x%x\n",
6771 static int bnx2x_8073_8727_external_rom_boot(struct bnx2x
*bp
,
6772 struct bnx2x_phy
*phy
,
6776 u16 fw_ver1
, fw_msgout
;
6779 /* Boot port from external ROM */
6781 bnx2x_cl45_write(bp
, phy
,
6783 MDIO_PMA_REG_GEN_CTRL
,
6786 /* ucode reboot and rst */
6787 bnx2x_cl45_write(bp
, phy
,
6789 MDIO_PMA_REG_GEN_CTRL
,
6792 bnx2x_cl45_write(bp
, phy
,
6794 MDIO_PMA_REG_MISC_CTRL1
, 0x0001);
6796 /* Reset internal microprocessor */
6797 bnx2x_cl45_write(bp
, phy
,
6799 MDIO_PMA_REG_GEN_CTRL
,
6800 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET
);
6802 /* Release srst bit */
6803 bnx2x_cl45_write(bp
, phy
,
6805 MDIO_PMA_REG_GEN_CTRL
,
6806 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP
);
6808 /* Delay 100ms per the PHY specifications */
6811 /* 8073 sometimes taking longer to download */
6816 "bnx2x_8073_8727_external_rom_boot port %x:"
6817 "Download failed. fw version = 0x%x\n",
6823 bnx2x_cl45_read(bp
, phy
,
6825 MDIO_PMA_REG_ROM_VER1
, &fw_ver1
);
6826 bnx2x_cl45_read(bp
, phy
,
6828 MDIO_PMA_REG_M8051_MSGOUT_REG
, &fw_msgout
);
6831 } while (fw_ver1
== 0 || fw_ver1
== 0x4321 ||
6832 ((fw_msgout
& 0xff) != 0x03 && (phy
->type
==
6833 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
)));
6835 /* Clear ser_boot_ctl bit */
6836 bnx2x_cl45_write(bp
, phy
,
6838 MDIO_PMA_REG_MISC_CTRL1
, 0x0000);
6839 bnx2x_save_bcm_spirom_ver(bp
, phy
, port
);
6842 "bnx2x_8073_8727_external_rom_boot port %x:"
6843 "Download complete. fw version = 0x%x\n",
6849 /******************************************************************/
6850 /* BCM8073 PHY SECTION */
6851 /******************************************************************/
6852 static int bnx2x_8073_is_snr_needed(struct bnx2x
*bp
, struct bnx2x_phy
*phy
)
6854 /* This is only required for 8073A1, version 102 only */
6857 /* Read 8073 HW revision*/
6858 bnx2x_cl45_read(bp
, phy
,
6860 MDIO_PMA_REG_8073_CHIP_REV
, &val
);
6863 /* No need to workaround in 8073 A1 */
6867 bnx2x_cl45_read(bp
, phy
,
6869 MDIO_PMA_REG_ROM_VER2
, &val
);
6871 /* SNR should be applied only for version 0x102 */
6878 static int bnx2x_8073_xaui_wa(struct bnx2x
*bp
, struct bnx2x_phy
*phy
)
6880 u16 val
, cnt
, cnt1
;
6882 bnx2x_cl45_read(bp
, phy
,
6884 MDIO_PMA_REG_8073_CHIP_REV
, &val
);
6887 /* No need to workaround in 8073 A1 */
6890 /* XAUI workaround in 8073 A0: */
6893 * After loading the boot ROM and restarting Autoneg, poll
6897 for (cnt
= 0; cnt
< 1000; cnt
++) {
6898 bnx2x_cl45_read(bp
, phy
,
6900 MDIO_PMA_REG_8073_SPEED_LINK_STATUS
,
6903 * If bit [14] = 0 or bit [13] = 0, continue on with
6904 * system initialization (XAUI work-around not required, as
6905 * these bits indicate 2.5G or 1G link up).
6907 if (!(val
& (1<<14)) || !(val
& (1<<13))) {
6908 DP(NETIF_MSG_LINK
, "XAUI work-around not required\n");
6910 } else if (!(val
& (1<<15))) {
6911 DP(NETIF_MSG_LINK
, "bit 15 went off\n");
6913 * If bit 15 is 0, then poll Dev1, Reg $C841 until it's
6914 * MSB (bit15) goes to 1 (indicating that the XAUI
6915 * workaround has completed), then continue on with
6916 * system initialization.
6918 for (cnt1
= 0; cnt1
< 1000; cnt1
++) {
6919 bnx2x_cl45_read(bp
, phy
,
6921 MDIO_PMA_REG_8073_XAUI_WA
, &val
);
6922 if (val
& (1<<15)) {
6924 "XAUI workaround has completed\n");
6933 DP(NETIF_MSG_LINK
, "Warning: XAUI work-around timeout !!!\n");
6937 static void bnx2x_807x_force_10G(struct bnx2x
*bp
, struct bnx2x_phy
*phy
)
6939 /* Force KR or KX */
6940 bnx2x_cl45_write(bp
, phy
,
6941 MDIO_PMA_DEVAD
, MDIO_PMA_REG_CTRL
, 0x2040);
6942 bnx2x_cl45_write(bp
, phy
,
6943 MDIO_PMA_DEVAD
, MDIO_PMA_REG_10G_CTRL2
, 0x000b);
6944 bnx2x_cl45_write(bp
, phy
,
6945 MDIO_PMA_DEVAD
, MDIO_PMA_REG_BCM_CTRL
, 0x0000);
6946 bnx2x_cl45_write(bp
, phy
,
6947 MDIO_AN_DEVAD
, MDIO_AN_REG_CTRL
, 0x0000);
6950 static void bnx2x_8073_set_pause_cl37(struct link_params
*params
,
6951 struct bnx2x_phy
*phy
,
6952 struct link_vars
*vars
)
6955 struct bnx2x
*bp
= params
->bp
;
6956 bnx2x_cl45_read(bp
, phy
,
6957 MDIO_AN_DEVAD
, MDIO_AN_REG_CL37_FC_LD
, &cl37_val
);
6959 cl37_val
&= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
6960 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
6961 bnx2x_calc_ieee_aneg_adv(phy
, params
, &vars
->ieee_fc
);
6962 if ((vars
->ieee_fc
&
6963 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC
) ==
6964 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC
) {
6965 cl37_val
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC
;
6967 if ((vars
->ieee_fc
&
6968 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) ==
6969 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) {
6970 cl37_val
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
;
6972 if ((vars
->ieee_fc
&
6973 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) ==
6974 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) {
6975 cl37_val
|= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
;
6978 "Ext phy AN advertize cl37 0x%x\n", cl37_val
);
6980 bnx2x_cl45_write(bp
, phy
,
6981 MDIO_AN_DEVAD
, MDIO_AN_REG_CL37_FC_LD
, cl37_val
);
6985 static int bnx2x_8073_config_init(struct bnx2x_phy
*phy
,
6986 struct link_params
*params
,
6987 struct link_vars
*vars
)
6989 struct bnx2x
*bp
= params
->bp
;
6992 DP(NETIF_MSG_LINK
, "Init 8073\n");
6995 gpio_port
= BP_PATH(bp
);
6997 gpio_port
= params
->port
;
6998 /* Restore normal power mode*/
6999 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
7000 MISC_REGISTERS_GPIO_OUTPUT_HIGH
, gpio_port
);
7002 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
7003 MISC_REGISTERS_GPIO_OUTPUT_HIGH
, gpio_port
);
7006 bnx2x_cl45_write(bp
, phy
,
7007 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_RXCTRL
, (1<<2));
7008 bnx2x_cl45_write(bp
, phy
,
7009 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_CTRL
, 0x0004);
7011 bnx2x_8073_set_pause_cl37(params
, phy
, vars
);
7013 bnx2x_cl45_read(bp
, phy
,
7014 MDIO_PMA_DEVAD
, MDIO_PMA_REG_M8051_MSGOUT_REG
, &tmp1
);
7016 bnx2x_cl45_read(bp
, phy
,
7017 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_RXSTAT
, &tmp1
);
7019 DP(NETIF_MSG_LINK
, "Before rom RX_ALARM(port1): 0x%x\n", tmp1
);
7021 /* Swap polarity if required - Must be done only in non-1G mode */
7022 if (params
->lane_config
& PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED
) {
7023 /* Configure the 8073 to swap _P and _N of the KR lines */
7024 DP(NETIF_MSG_LINK
, "Swapping polarity for the 8073\n");
7025 /* 10G Rx/Tx and 1G Tx signal polarity swap */
7026 bnx2x_cl45_read(bp
, phy
,
7028 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL
, &val
);
7029 bnx2x_cl45_write(bp
, phy
,
7031 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL
,
7036 /* Enable CL37 BAM */
7037 if (REG_RD(bp
, params
->shmem_base
+
7038 offsetof(struct shmem_region
, dev_info
.
7039 port_hw_config
[params
->port
].default_cfg
)) &
7040 PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED
) {
7042 bnx2x_cl45_read(bp
, phy
,
7044 MDIO_AN_REG_8073_BAM
, &val
);
7045 bnx2x_cl45_write(bp
, phy
,
7047 MDIO_AN_REG_8073_BAM
, val
| 1);
7048 DP(NETIF_MSG_LINK
, "Enable CL37 BAM on KR\n");
7050 if (params
->loopback_mode
== LOOPBACK_EXT
) {
7051 bnx2x_807x_force_10G(bp
, phy
);
7052 DP(NETIF_MSG_LINK
, "Forced speed 10G on 807X\n");
7055 bnx2x_cl45_write(bp
, phy
,
7056 MDIO_PMA_DEVAD
, MDIO_PMA_REG_BCM_CTRL
, 0x0002);
7058 if (phy
->req_line_speed
!= SPEED_AUTO_NEG
) {
7059 if (phy
->req_line_speed
== SPEED_10000
) {
7061 } else if (phy
->req_line_speed
== SPEED_2500
) {
7064 * Note that 2.5G works only when used with 1G
7071 if (phy
->speed_cap_mask
&
7072 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)
7075 /* Note that 2.5G works only when used with 1G advertisement */
7076 if (phy
->speed_cap_mask
&
7077 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
|
7078 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G
))
7080 DP(NETIF_MSG_LINK
, "807x autoneg val = 0x%x\n", val
);
7083 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
, MDIO_AN_REG_ADV
, val
);
7084 bnx2x_cl45_read(bp
, phy
, MDIO_AN_DEVAD
, MDIO_AN_REG_8073_2_5G
, &tmp1
);
7086 if (((phy
->speed_cap_mask
& PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G
) &&
7087 (phy
->req_line_speed
== SPEED_AUTO_NEG
)) ||
7088 (phy
->req_line_speed
== SPEED_2500
)) {
7090 /* Allow 2.5G for A1 and above */
7091 bnx2x_cl45_read(bp
, phy
,
7092 MDIO_PMA_DEVAD
, MDIO_PMA_REG_8073_CHIP_REV
,
7094 DP(NETIF_MSG_LINK
, "Add 2.5G\n");
7100 DP(NETIF_MSG_LINK
, "Disable 2.5G\n");
7104 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
, MDIO_AN_REG_8073_2_5G
, tmp1
);
7105 /* Add support for CL37 (passive mode) II */
7107 bnx2x_cl45_read(bp
, phy
, MDIO_AN_DEVAD
, MDIO_AN_REG_CL37_FC_LD
, &tmp1
);
7108 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
, MDIO_AN_REG_CL37_FC_LD
,
7109 (tmp1
| ((phy
->req_duplex
== DUPLEX_FULL
) ?
7112 /* Add support for CL37 (passive mode) III */
7113 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
, MDIO_AN_REG_CL37_AN
, 0x1000);
7116 * The SNR will improve about 2db by changing BW and FEE main
7117 * tap. Rest commands are executed after link is up
7118 * Change FFE main cursor to 5 in EDC register
7120 if (bnx2x_8073_is_snr_needed(bp
, phy
))
7121 bnx2x_cl45_write(bp
, phy
,
7122 MDIO_PMA_DEVAD
, MDIO_PMA_REG_EDC_FFE_MAIN
,
7125 /* Enable FEC (Forware Error Correction) Request in the AN */
7126 bnx2x_cl45_read(bp
, phy
, MDIO_AN_DEVAD
, MDIO_AN_REG_ADV2
, &tmp1
);
7128 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
, MDIO_AN_REG_ADV2
, tmp1
);
7130 bnx2x_ext_phy_set_pause(params
, phy
, vars
);
7132 /* Restart autoneg */
7134 bnx2x_cl45_write(bp
, phy
, MDIO_AN_DEVAD
, MDIO_AN_REG_CTRL
, 0x1200);
7135 DP(NETIF_MSG_LINK
, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
7136 ((val
& (1<<5)) > 0), ((val
& (1<<7)) > 0));
7140 static u8
bnx2x_8073_read_status(struct bnx2x_phy
*phy
,
7141 struct link_params
*params
,
7142 struct link_vars
*vars
)
7144 struct bnx2x
*bp
= params
->bp
;
7147 u16 link_status
= 0;
7148 u16 an1000_status
= 0;
7150 bnx2x_cl45_read(bp
, phy
,
7151 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_STAT
, &val1
);
7153 DP(NETIF_MSG_LINK
, "8703 LASI status 0x%x\n", val1
);
7155 /* clear the interrupt LASI status register */
7156 bnx2x_cl45_read(bp
, phy
,
7157 MDIO_PCS_DEVAD
, MDIO_PCS_REG_STATUS
, &val2
);
7158 bnx2x_cl45_read(bp
, phy
,
7159 MDIO_PCS_DEVAD
, MDIO_PCS_REG_STATUS
, &val1
);
7160 DP(NETIF_MSG_LINK
, "807x PCS status 0x%x->0x%x\n", val2
, val1
);
7162 bnx2x_cl45_read(bp
, phy
,
7163 MDIO_PMA_DEVAD
, MDIO_PMA_REG_M8051_MSGOUT_REG
, &val1
);
7165 /* Check the LASI */
7166 bnx2x_cl45_read(bp
, phy
,
7167 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_RXSTAT
, &val2
);
7169 DP(NETIF_MSG_LINK
, "KR 0x9003 0x%x\n", val2
);
7171 /* Check the link status */
7172 bnx2x_cl45_read(bp
, phy
,
7173 MDIO_PCS_DEVAD
, MDIO_PCS_REG_STATUS
, &val2
);
7174 DP(NETIF_MSG_LINK
, "KR PCS status 0x%x\n", val2
);
7176 bnx2x_cl45_read(bp
, phy
,
7177 MDIO_PMA_DEVAD
, MDIO_PMA_REG_STATUS
, &val2
);
7178 bnx2x_cl45_read(bp
, phy
,
7179 MDIO_PMA_DEVAD
, MDIO_PMA_REG_STATUS
, &val1
);
7180 link_up
= ((val1
& 4) == 4);
7181 DP(NETIF_MSG_LINK
, "PMA_REG_STATUS=0x%x\n", val1
);
7184 ((phy
->req_line_speed
!= SPEED_10000
))) {
7185 if (bnx2x_8073_xaui_wa(bp
, phy
) != 0)
7188 bnx2x_cl45_read(bp
, phy
,
7189 MDIO_AN_DEVAD
, MDIO_AN_REG_LINK_STATUS
, &an1000_status
);
7190 bnx2x_cl45_read(bp
, phy
,
7191 MDIO_AN_DEVAD
, MDIO_AN_REG_LINK_STATUS
, &an1000_status
);
7193 /* Check the link status on 1.1.2 */
7194 bnx2x_cl45_read(bp
, phy
,
7195 MDIO_PMA_DEVAD
, MDIO_PMA_REG_STATUS
, &val2
);
7196 bnx2x_cl45_read(bp
, phy
,
7197 MDIO_PMA_DEVAD
, MDIO_PMA_REG_STATUS
, &val1
);
7198 DP(NETIF_MSG_LINK
, "KR PMA status 0x%x->0x%x,"
7199 "an_link_status=0x%x\n", val2
, val1
, an1000_status
);
7201 link_up
= (((val1
& 4) == 4) || (an1000_status
& (1<<1)));
7202 if (link_up
&& bnx2x_8073_is_snr_needed(bp
, phy
)) {
7204 * The SNR will improve about 2dbby changing the BW and FEE main
7205 * tap. The 1st write to change FFE main tap is set before
7206 * restart AN. Change PLL Bandwidth in EDC register
7208 bnx2x_cl45_write(bp
, phy
,
7209 MDIO_PMA_DEVAD
, MDIO_PMA_REG_PLL_BANDWIDTH
,
7212 /* Change CDR Bandwidth in EDC register */
7213 bnx2x_cl45_write(bp
, phy
,
7214 MDIO_PMA_DEVAD
, MDIO_PMA_REG_CDR_BANDWIDTH
,
7217 bnx2x_cl45_read(bp
, phy
,
7218 MDIO_PMA_DEVAD
, MDIO_PMA_REG_8073_SPEED_LINK_STATUS
,
7221 /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
7222 if ((link_status
& (1<<2)) && (!(link_status
& (1<<15)))) {
7224 vars
->line_speed
= SPEED_10000
;
7225 DP(NETIF_MSG_LINK
, "port %x: External link up in 10G\n",
7227 } else if ((link_status
& (1<<1)) && (!(link_status
& (1<<14)))) {
7229 vars
->line_speed
= SPEED_2500
;
7230 DP(NETIF_MSG_LINK
, "port %x: External link up in 2.5G\n",
7232 } else if ((link_status
& (1<<0)) && (!(link_status
& (1<<13)))) {
7234 vars
->line_speed
= SPEED_1000
;
7235 DP(NETIF_MSG_LINK
, "port %x: External link up in 1G\n",
7239 DP(NETIF_MSG_LINK
, "port %x: External link is down\n",
7244 /* Swap polarity if required */
7245 if (params
->lane_config
&
7246 PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED
) {
7247 /* Configure the 8073 to swap P and N of the KR lines */
7248 bnx2x_cl45_read(bp
, phy
,
7250 MDIO_XS_REG_8073_RX_CTRL_PCIE
, &val1
);
7252 * Set bit 3 to invert Rx in 1G mode and clear this bit
7253 * when it`s in 10G mode.
7255 if (vars
->line_speed
== SPEED_1000
) {
7256 DP(NETIF_MSG_LINK
, "Swapping 1G polarity for"
7262 bnx2x_cl45_write(bp
, phy
,
7264 MDIO_XS_REG_8073_RX_CTRL_PCIE
,
7267 bnx2x_ext_phy_10G_an_resolve(bp
, phy
, vars
);
7268 bnx2x_8073_resolve_fc(phy
, params
, vars
);
7269 vars
->duplex
= DUPLEX_FULL
;
7274 static void bnx2x_8073_link_reset(struct bnx2x_phy
*phy
,
7275 struct link_params
*params
)
7277 struct bnx2x
*bp
= params
->bp
;
7280 gpio_port
= BP_PATH(bp
);
7282 gpio_port
= params
->port
;
7283 DP(NETIF_MSG_LINK
, "Setting 8073 port %d into low power mode\n",
7285 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
7286 MISC_REGISTERS_GPIO_OUTPUT_LOW
,
7290 /******************************************************************/
7291 /* BCM8705 PHY SECTION */
7292 /******************************************************************/
7293 static int bnx2x_8705_config_init(struct bnx2x_phy
*phy
,
7294 struct link_params
*params
,
7295 struct link_vars
*vars
)
7297 struct bnx2x
*bp
= params
->bp
;
7298 DP(NETIF_MSG_LINK
, "init 8705\n");
7299 /* Restore normal power mode*/
7300 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
7301 MISC_REGISTERS_GPIO_OUTPUT_HIGH
, params
->port
);
7303 bnx2x_ext_phy_hw_reset(bp
, params
->port
);
7304 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
, MDIO_PMA_REG_CTRL
, 0xa040);
7305 bnx2x_wait_reset_complete(bp
, phy
, params
);
7307 bnx2x_cl45_write(bp
, phy
,
7308 MDIO_PMA_DEVAD
, MDIO_PMA_REG_MISC_CTRL
, 0x8288);
7309 bnx2x_cl45_write(bp
, phy
,
7310 MDIO_PMA_DEVAD
, MDIO_PMA_REG_PHY_IDENTIFIER
, 0x7fbf);
7311 bnx2x_cl45_write(bp
, phy
,
7312 MDIO_PMA_DEVAD
, MDIO_PMA_REG_CMU_PLL_BYPASS
, 0x0100);
7313 bnx2x_cl45_write(bp
, phy
,
7314 MDIO_WIS_DEVAD
, MDIO_WIS_REG_LASI_CNTL
, 0x1);
7315 /* BCM8705 doesn't have microcode, hence the 0 */
7316 bnx2x_save_spirom_version(bp
, params
->port
, params
->shmem_base
, 0);
7320 static u8
bnx2x_8705_read_status(struct bnx2x_phy
*phy
,
7321 struct link_params
*params
,
7322 struct link_vars
*vars
)
7326 struct bnx2x
*bp
= params
->bp
;
7327 DP(NETIF_MSG_LINK
, "read status 8705\n");
7328 bnx2x_cl45_read(bp
, phy
,
7329 MDIO_WIS_DEVAD
, MDIO_WIS_REG_LASI_STATUS
, &val1
);
7330 DP(NETIF_MSG_LINK
, "8705 LASI status 0x%x\n", val1
);
7332 bnx2x_cl45_read(bp
, phy
,
7333 MDIO_WIS_DEVAD
, MDIO_WIS_REG_LASI_STATUS
, &val1
);
7334 DP(NETIF_MSG_LINK
, "8705 LASI status 0x%x\n", val1
);
7336 bnx2x_cl45_read(bp
, phy
,
7337 MDIO_PMA_DEVAD
, MDIO_PMA_REG_RX_SD
, &rx_sd
);
7339 bnx2x_cl45_read(bp
, phy
,
7340 MDIO_PMA_DEVAD
, 0xc809, &val1
);
7341 bnx2x_cl45_read(bp
, phy
,
7342 MDIO_PMA_DEVAD
, 0xc809, &val1
);
7344 DP(NETIF_MSG_LINK
, "8705 1.c809 val=0x%x\n", val1
);
7345 link_up
= ((rx_sd
& 0x1) && (val1
& (1<<9)) && ((val1
& (1<<8)) == 0));
7347 vars
->line_speed
= SPEED_10000
;
7348 bnx2x_ext_phy_resolve_fc(phy
, params
, vars
);
7353 /******************************************************************/
7354 /* SFP+ module Section */
7355 /******************************************************************/
7356 static void bnx2x_set_disable_pmd_transmit(struct link_params
*params
,
7357 struct bnx2x_phy
*phy
,
7360 struct bnx2x
*bp
= params
->bp
;
7362 * Disable transmitter only for bootcodes which can enable it afterwards
7366 if (params
->feature_config_flags
&
7367 FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED
)
7368 DP(NETIF_MSG_LINK
, "Disabling PMD transmitter\n");
7370 DP(NETIF_MSG_LINK
, "NOT disabling PMD transmitter\n");
7374 DP(NETIF_MSG_LINK
, "Enabling PMD transmitter\n");
7375 bnx2x_cl45_write(bp
, phy
,
7377 MDIO_PMA_REG_TX_DISABLE
, pmd_dis
);
7380 static u8
bnx2x_get_gpio_port(struct link_params
*params
)
7383 u32 swap_val
, swap_override
;
7384 struct bnx2x
*bp
= params
->bp
;
7386 gpio_port
= BP_PATH(bp
);
7388 gpio_port
= params
->port
;
7389 swap_val
= REG_RD(bp
, NIG_REG_PORT_SWAP
);
7390 swap_override
= REG_RD(bp
, NIG_REG_STRAP_OVERRIDE
);
7391 return gpio_port
^ (swap_val
&& swap_override
);
7394 static void bnx2x_sfp_e1e2_set_transmitter(struct link_params
*params
,
7395 struct bnx2x_phy
*phy
,
7399 u8 port
= params
->port
;
7400 struct bnx2x
*bp
= params
->bp
;
7403 /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
7404 tx_en_mode
= REG_RD(bp
, params
->shmem_base
+
7405 offsetof(struct shmem_region
,
7406 dev_info
.port_hw_config
[port
].sfp_ctrl
)) &
7407 PORT_HW_CFG_TX_LASER_MASK
;
7408 DP(NETIF_MSG_LINK
, "Setting transmitter tx_en=%x for port %x "
7409 "mode = %x\n", tx_en
, port
, tx_en_mode
);
7410 switch (tx_en_mode
) {
7411 case PORT_HW_CFG_TX_LASER_MDIO
:
7413 bnx2x_cl45_read(bp
, phy
,
7415 MDIO_PMA_REG_PHY_IDENTIFIER
,
7423 bnx2x_cl45_write(bp
, phy
,
7425 MDIO_PMA_REG_PHY_IDENTIFIER
,
7428 case PORT_HW_CFG_TX_LASER_GPIO0
:
7429 case PORT_HW_CFG_TX_LASER_GPIO1
:
7430 case PORT_HW_CFG_TX_LASER_GPIO2
:
7431 case PORT_HW_CFG_TX_LASER_GPIO3
:
7434 u8 gpio_port
, gpio_mode
;
7436 gpio_mode
= MISC_REGISTERS_GPIO_OUTPUT_HIGH
;
7438 gpio_mode
= MISC_REGISTERS_GPIO_OUTPUT_LOW
;
7440 gpio_pin
= tx_en_mode
- PORT_HW_CFG_TX_LASER_GPIO0
;
7441 gpio_port
= bnx2x_get_gpio_port(params
);
7442 bnx2x_set_gpio(bp
, gpio_pin
, gpio_mode
, gpio_port
);
7446 DP(NETIF_MSG_LINK
, "Invalid TX_LASER_MDIO 0x%x\n", tx_en_mode
);
7451 static void bnx2x_sfp_set_transmitter(struct link_params
*params
,
7452 struct bnx2x_phy
*phy
,
7455 struct bnx2x
*bp
= params
->bp
;
7456 DP(NETIF_MSG_LINK
, "Setting SFP+ transmitter to %d\n", tx_en
);
7458 bnx2x_sfp_e3_set_transmitter(params
, phy
, tx_en
);
7460 bnx2x_sfp_e1e2_set_transmitter(params
, phy
, tx_en
);
7463 static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy
*phy
,
7464 struct link_params
*params
,
7465 u16 addr
, u8 byte_cnt
, u8
*o_buf
)
7467 struct bnx2x
*bp
= params
->bp
;
7470 if (byte_cnt
> 16) {
7472 "Reading from eeprom is limited to 0xf\n");
7475 /* Set the read command byte count */
7476 bnx2x_cl45_write(bp
, phy
,
7477 MDIO_PMA_DEVAD
, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT
,
7478 (byte_cnt
| 0xa000));
7480 /* Set the read command address */
7481 bnx2x_cl45_write(bp
, phy
,
7482 MDIO_PMA_DEVAD
, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR
,
7485 /* Activate read command */
7486 bnx2x_cl45_write(bp
, phy
,
7487 MDIO_PMA_DEVAD
, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL
,
7490 /* Wait up to 500us for command complete status */
7491 for (i
= 0; i
< 100; i
++) {
7492 bnx2x_cl45_read(bp
, phy
,
7494 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL
, &val
);
7495 if ((val
& MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK
) ==
7496 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE
)
7501 if ((val
& MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK
) !=
7502 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE
) {
7504 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
7505 (val
& MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK
));
7509 /* Read the buffer */
7510 for (i
= 0; i
< byte_cnt
; i
++) {
7511 bnx2x_cl45_read(bp
, phy
,
7513 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF
+ i
, &val
);
7514 o_buf
[i
] = (u8
)(val
& MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK
);
7517 for (i
= 0; i
< 100; i
++) {
7518 bnx2x_cl45_read(bp
, phy
,
7520 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL
, &val
);
7521 if ((val
& MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK
) ==
7522 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE
)
7529 static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy
*phy
,
7530 struct link_params
*params
,
7531 u16 addr
, u8 byte_cnt
,
7535 u8 i
, j
= 0, cnt
= 0;
7538 struct bnx2x
*bp
= params
->bp
;
7539 /*DP(NETIF_MSG_LINK, "bnx2x_direct_read_sfp_module_eeprom:"
7540 " addr %d, cnt %d\n",
7542 if (byte_cnt
> 16) {
7544 "Reading from eeprom is limited to 16 bytes\n");
7548 /* 4 byte aligned address */
7549 addr32
= addr
& (~0x3);
7551 rc
= bnx2x_bsc_read(params
, phy
, 0xa0, addr32
, 0, byte_cnt
,
7553 } while ((rc
!= 0) && (++cnt
< I2C_WA_RETRY_CNT
));
7556 for (i
= (addr
- addr32
); i
< byte_cnt
+ (addr
- addr32
); i
++) {
7557 o_buf
[j
] = *((u8
*)data_array
+ i
);
7565 static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy
*phy
,
7566 struct link_params
*params
,
7567 u16 addr
, u8 byte_cnt
, u8
*o_buf
)
7569 struct bnx2x
*bp
= params
->bp
;
7572 if (byte_cnt
> 16) {
7574 "Reading from eeprom is limited to 0xf\n");
7578 /* Need to read from 1.8000 to clear it */
7579 bnx2x_cl45_read(bp
, phy
,
7581 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL
,
7584 /* Set the read command byte count */
7585 bnx2x_cl45_write(bp
, phy
,
7587 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT
,
7588 ((byte_cnt
< 2) ? 2 : byte_cnt
));
7590 /* Set the read command address */
7591 bnx2x_cl45_write(bp
, phy
,
7593 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR
,
7595 /* Set the destination address */
7596 bnx2x_cl45_write(bp
, phy
,
7599 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF
);
7601 /* Activate read command */
7602 bnx2x_cl45_write(bp
, phy
,
7604 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL
,
7607 * Wait appropriate time for two-wire command to finish before
7608 * polling the status register
7612 /* Wait up to 500us for command complete status */
7613 for (i
= 0; i
< 100; i
++) {
7614 bnx2x_cl45_read(bp
, phy
,
7616 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL
, &val
);
7617 if ((val
& MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK
) ==
7618 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE
)
7623 if ((val
& MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK
) !=
7624 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE
) {
7626 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
7627 (val
& MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK
));
7631 /* Read the buffer */
7632 for (i
= 0; i
< byte_cnt
; i
++) {
7633 bnx2x_cl45_read(bp
, phy
,
7635 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF
+ i
, &val
);
7636 o_buf
[i
] = (u8
)(val
& MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK
);
7639 for (i
= 0; i
< 100; i
++) {
7640 bnx2x_cl45_read(bp
, phy
,
7642 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL
, &val
);
7643 if ((val
& MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK
) ==
7644 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE
)
7652 int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy
*phy
,
7653 struct link_params
*params
, u16 addr
,
7654 u8 byte_cnt
, u8
*o_buf
)
7657 switch (phy
->type
) {
7658 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
:
7659 rc
= bnx2x_8726_read_sfp_module_eeprom(phy
, params
, addr
,
7662 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
:
7663 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722
:
7664 rc
= bnx2x_8727_read_sfp_module_eeprom(phy
, params
, addr
,
7667 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
7668 rc
= bnx2x_warpcore_read_sfp_module_eeprom(phy
, params
, addr
,
7675 static int bnx2x_get_edc_mode(struct bnx2x_phy
*phy
,
7676 struct link_params
*params
,
7679 struct bnx2x
*bp
= params
->bp
;
7680 u32 sync_offset
= 0, phy_idx
, media_types
;
7681 u8 val
, check_limiting_mode
= 0;
7682 *edc_mode
= EDC_MODE_LIMITING
;
7684 phy
->media_type
= ETH_PHY_UNSPECIFIED
;
7685 /* First check for copper cable */
7686 if (bnx2x_read_sfp_module_eeprom(phy
,
7688 SFP_EEPROM_CON_TYPE_ADDR
,
7691 DP(NETIF_MSG_LINK
, "Failed to read from SFP+ module EEPROM\n");
7696 case SFP_EEPROM_CON_TYPE_VAL_COPPER
:
7698 u8 copper_module_type
;
7699 phy
->media_type
= ETH_PHY_DA_TWINAX
;
7701 * Check if its active cable (includes SFP+ module)
7704 if (bnx2x_read_sfp_module_eeprom(phy
,
7706 SFP_EEPROM_FC_TX_TECH_ADDR
,
7708 &copper_module_type
) != 0) {
7710 "Failed to read copper-cable-type"
7711 " from SFP+ EEPROM\n");
7715 if (copper_module_type
&
7716 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE
) {
7717 DP(NETIF_MSG_LINK
, "Active Copper cable detected\n");
7718 check_limiting_mode
= 1;
7719 } else if (copper_module_type
&
7720 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE
) {
7722 "Passive Copper cable detected\n");
7724 EDC_MODE_PASSIVE_DAC
;
7727 "Unknown copper-cable-type 0x%x !!!\n",
7728 copper_module_type
);
7733 case SFP_EEPROM_CON_TYPE_VAL_LC
:
7734 phy
->media_type
= ETH_PHY_SFP_FIBER
;
7735 DP(NETIF_MSG_LINK
, "Optic module detected\n");
7736 check_limiting_mode
= 1;
7739 DP(NETIF_MSG_LINK
, "Unable to determine module type 0x%x !!!\n",
7743 sync_offset
= params
->shmem_base
+
7744 offsetof(struct shmem_region
,
7745 dev_info
.port_hw_config
[params
->port
].media_type
);
7746 media_types
= REG_RD(bp
, sync_offset
);
7747 /* Update media type for non-PMF sync */
7748 for (phy_idx
= INT_PHY
; phy_idx
< MAX_PHYS
; phy_idx
++) {
7749 if (&(params
->phy
[phy_idx
]) == phy
) {
7750 media_types
&= ~(PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK
<<
7751 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT
* phy_idx
));
7752 media_types
|= ((phy
->media_type
&
7753 PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK
) <<
7754 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT
* phy_idx
));
7758 REG_WR(bp
, sync_offset
, media_types
);
7759 if (check_limiting_mode
) {
7760 u8 options
[SFP_EEPROM_OPTIONS_SIZE
];
7761 if (bnx2x_read_sfp_module_eeprom(phy
,
7763 SFP_EEPROM_OPTIONS_ADDR
,
7764 SFP_EEPROM_OPTIONS_SIZE
,
7767 "Failed to read Option field from module EEPROM\n");
7770 if ((options
[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK
))
7771 *edc_mode
= EDC_MODE_LINEAR
;
7773 *edc_mode
= EDC_MODE_LIMITING
;
7775 DP(NETIF_MSG_LINK
, "EDC mode is set to 0x%x\n", *edc_mode
);
7779 * This function read the relevant field from the module (SFP+), and verify it
7780 * is compliant with this board
7782 static int bnx2x_verify_sfp_module(struct bnx2x_phy
*phy
,
7783 struct link_params
*params
)
7785 struct bnx2x
*bp
= params
->bp
;
7787 u32 fw_resp
, fw_cmd_param
;
7788 char vendor_name
[SFP_EEPROM_VENDOR_NAME_SIZE
+1];
7789 char vendor_pn
[SFP_EEPROM_PART_NO_SIZE
+1];
7790 phy
->flags
&= ~FLAGS_SFP_NOT_APPROVED
;
7791 val
= REG_RD(bp
, params
->shmem_base
+
7792 offsetof(struct shmem_region
, dev_info
.
7793 port_feature_config
[params
->port
].config
));
7794 if ((val
& PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK
) ==
7795 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT
) {
7796 DP(NETIF_MSG_LINK
, "NOT enforcing module verification\n");
7800 if (params
->feature_config_flags
&
7801 FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY
) {
7802 /* Use specific phy request */
7803 cmd
= DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL
;
7804 } else if (params
->feature_config_flags
&
7805 FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY
) {
7806 /* Use first phy request only in case of non-dual media*/
7807 if (DUAL_MEDIA(params
)) {
7809 "FW does not support OPT MDL verification\n");
7812 cmd
= DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL
;
7814 /* No support in OPT MDL detection */
7816 "FW does not support OPT MDL verification\n");
7820 fw_cmd_param
= FW_PARAM_SET(phy
->addr
, phy
->type
, phy
->mdio_ctrl
);
7821 fw_resp
= bnx2x_fw_command(bp
, cmd
, fw_cmd_param
);
7822 if (fw_resp
== FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS
) {
7823 DP(NETIF_MSG_LINK
, "Approved module\n");
7827 /* format the warning message */
7828 if (bnx2x_read_sfp_module_eeprom(phy
,
7830 SFP_EEPROM_VENDOR_NAME_ADDR
,
7831 SFP_EEPROM_VENDOR_NAME_SIZE
,
7833 vendor_name
[0] = '\0';
7835 vendor_name
[SFP_EEPROM_VENDOR_NAME_SIZE
] = '\0';
7836 if (bnx2x_read_sfp_module_eeprom(phy
,
7838 SFP_EEPROM_PART_NO_ADDR
,
7839 SFP_EEPROM_PART_NO_SIZE
,
7841 vendor_pn
[0] = '\0';
7843 vendor_pn
[SFP_EEPROM_PART_NO_SIZE
] = '\0';
7845 netdev_err(bp
->dev
, "Warning: Unqualified SFP+ module detected,"
7846 " Port %d from %s part number %s\n",
7847 params
->port
, vendor_name
, vendor_pn
);
7848 phy
->flags
|= FLAGS_SFP_NOT_APPROVED
;
7852 static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy
*phy
,
7853 struct link_params
*params
)
7857 struct bnx2x
*bp
= params
->bp
;
7860 * Initialization time after hot-plug may take up to 300ms for
7861 * some phys type ( e.g. JDSU )
7864 for (timeout
= 0; timeout
< 60; timeout
++) {
7865 if (bnx2x_read_sfp_module_eeprom(phy
, params
, 1, 1, &val
)
7868 "SFP+ module initialization took %d ms\n",
7877 static void bnx2x_8727_power_module(struct bnx2x
*bp
,
7878 struct bnx2x_phy
*phy
,
7880 /* Make sure GPIOs are not using for LED mode */
7883 * In the GPIO register, bit 4 is use to determine if the GPIOs are
7884 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
7886 * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0
7887 * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1
7888 * where the 1st bit is the over-current(only input), and 2nd bit is
7889 * for power( only output )
7891 * In case of NOC feature is disabled and power is up, set GPIO control
7892 * as input to enable listening of over-current indication
7894 if (phy
->flags
& FLAGS_NOC
)
7900 * Set GPIO control to OUTPUT, and set the power bit
7901 * to according to the is_power_up
7905 bnx2x_cl45_write(bp
, phy
,
7907 MDIO_PMA_REG_8727_GPIO_CTRL
,
7911 static int bnx2x_8726_set_limiting_mode(struct bnx2x
*bp
,
7912 struct bnx2x_phy
*phy
,
7915 u16 cur_limiting_mode
;
7917 bnx2x_cl45_read(bp
, phy
,
7919 MDIO_PMA_REG_ROM_VER2
,
7920 &cur_limiting_mode
);
7921 DP(NETIF_MSG_LINK
, "Current Limiting mode is 0x%x\n",
7924 if (edc_mode
== EDC_MODE_LIMITING
) {
7925 DP(NETIF_MSG_LINK
, "Setting LIMITING MODE\n");
7926 bnx2x_cl45_write(bp
, phy
,
7928 MDIO_PMA_REG_ROM_VER2
,
7930 } else { /* LRM mode ( default )*/
7932 DP(NETIF_MSG_LINK
, "Setting LRM MODE\n");
7935 * Changing to LRM mode takes quite few seconds. So do it only
7936 * if current mode is limiting (default is LRM)
7938 if (cur_limiting_mode
!= EDC_MODE_LIMITING
)
7941 bnx2x_cl45_write(bp
, phy
,
7943 MDIO_PMA_REG_LRM_MODE
,
7945 bnx2x_cl45_write(bp
, phy
,
7947 MDIO_PMA_REG_ROM_VER2
,
7949 bnx2x_cl45_write(bp
, phy
,
7951 MDIO_PMA_REG_MISC_CTRL0
,
7953 bnx2x_cl45_write(bp
, phy
,
7955 MDIO_PMA_REG_LRM_MODE
,
7961 static int bnx2x_8727_set_limiting_mode(struct bnx2x
*bp
,
7962 struct bnx2x_phy
*phy
,
7967 bnx2x_cl45_read(bp
, phy
,
7969 MDIO_PMA_REG_PHY_IDENTIFIER
,
7972 bnx2x_cl45_write(bp
, phy
,
7974 MDIO_PMA_REG_PHY_IDENTIFIER
,
7975 (phy_identifier
& ~(1<<9)));
7977 bnx2x_cl45_read(bp
, phy
,
7979 MDIO_PMA_REG_ROM_VER2
,
7981 /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
7982 bnx2x_cl45_write(bp
, phy
,
7984 MDIO_PMA_REG_ROM_VER2
,
7985 (rom_ver2_val
& 0xff00) | (edc_mode
& 0x00ff));
7987 bnx2x_cl45_write(bp
, phy
,
7989 MDIO_PMA_REG_PHY_IDENTIFIER
,
7990 (phy_identifier
| (1<<9)));
7995 static void bnx2x_8727_specific_func(struct bnx2x_phy
*phy
,
7996 struct link_params
*params
,
7999 struct bnx2x
*bp
= params
->bp
;
8003 bnx2x_sfp_set_transmitter(params
, phy
, 0);
8006 if (!(phy
->flags
& FLAGS_SFP_NOT_APPROVED
))
8007 bnx2x_sfp_set_transmitter(params
, phy
, 1);
8010 DP(NETIF_MSG_LINK
, "Function 0x%x not supported by 8727\n",
8016 static void bnx2x_set_e1e2_module_fault_led(struct link_params
*params
,
8019 struct bnx2x
*bp
= params
->bp
;
8021 u32 fault_led_gpio
= REG_RD(bp
, params
->shmem_base
+
8022 offsetof(struct shmem_region
,
8023 dev_info
.port_hw_config
[params
->port
].sfp_ctrl
)) &
8024 PORT_HW_CFG_FAULT_MODULE_LED_MASK
;
8025 switch (fault_led_gpio
) {
8026 case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED
:
8028 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0
:
8029 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1
:
8030 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2
:
8031 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3
:
8033 u8 gpio_port
= bnx2x_get_gpio_port(params
);
8034 u16 gpio_pin
= fault_led_gpio
-
8035 PORT_HW_CFG_FAULT_MODULE_LED_GPIO0
;
8036 DP(NETIF_MSG_LINK
, "Set fault module-detected led "
8037 "pin %x port %x mode %x\n",
8038 gpio_pin
, gpio_port
, gpio_mode
);
8039 bnx2x_set_gpio(bp
, gpio_pin
, gpio_mode
, gpio_port
);
8043 DP(NETIF_MSG_LINK
, "Error: Invalid fault led mode 0x%x\n",
8048 static void bnx2x_set_e3_module_fault_led(struct link_params
*params
,
8052 u8 port
= params
->port
;
8053 struct bnx2x
*bp
= params
->bp
;
8054 pin_cfg
= (REG_RD(bp
, params
->shmem_base
+
8055 offsetof(struct shmem_region
,
8056 dev_info
.port_hw_config
[port
].e3_sfp_ctrl
)) &
8057 PORT_HW_CFG_E3_FAULT_MDL_LED_MASK
) >>
8058 PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT
;
8059 DP(NETIF_MSG_LINK
, "Setting Fault LED to %d using pin cfg %d\n",
8060 gpio_mode
, pin_cfg
);
8061 bnx2x_set_cfg_pin(bp
, pin_cfg
, gpio_mode
);
8064 static void bnx2x_set_sfp_module_fault_led(struct link_params
*params
,
8067 struct bnx2x
*bp
= params
->bp
;
8068 DP(NETIF_MSG_LINK
, "Setting SFP+ module fault LED to %d\n", gpio_mode
);
8069 if (CHIP_IS_E3(bp
)) {
8071 * Low ==> if SFP+ module is supported otherwise
8072 * High ==> if SFP+ module is not on the approved vendor list
8074 bnx2x_set_e3_module_fault_led(params
, gpio_mode
);
8076 bnx2x_set_e1e2_module_fault_led(params
, gpio_mode
);
8079 static void bnx2x_warpcore_power_module(struct link_params
*params
,
8080 struct bnx2x_phy
*phy
,
8084 struct bnx2x
*bp
= params
->bp
;
8086 pin_cfg
= (REG_RD(bp
, params
->shmem_base
+
8087 offsetof(struct shmem_region
,
8088 dev_info
.port_hw_config
[params
->port
].e3_sfp_ctrl
)) &
8089 PORT_HW_CFG_E3_PWR_DIS_MASK
) >>
8090 PORT_HW_CFG_E3_PWR_DIS_SHIFT
;
8092 if (pin_cfg
== PIN_CFG_NA
)
8094 DP(NETIF_MSG_LINK
, "Setting SFP+ module power to %d using pin cfg %d\n",
8097 * Low ==> corresponding SFP+ module is powered
8098 * high ==> the SFP+ module is powered down
8100 bnx2x_set_cfg_pin(bp
, pin_cfg
, power
^ 1);
8103 static void bnx2x_warpcore_hw_reset(struct bnx2x_phy
*phy
,
8104 struct link_params
*params
)
8106 bnx2x_warpcore_power_module(params
, phy
, 0);
8109 static void bnx2x_power_sfp_module(struct link_params
*params
,
8110 struct bnx2x_phy
*phy
,
8113 struct bnx2x
*bp
= params
->bp
;
8114 DP(NETIF_MSG_LINK
, "Setting SFP+ power to %x\n", power
);
8116 switch (phy
->type
) {
8117 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
:
8118 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722
:
8119 bnx2x_8727_power_module(params
->bp
, phy
, power
);
8121 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
8122 bnx2x_warpcore_power_module(params
, phy
, power
);
8128 static void bnx2x_warpcore_set_limiting_mode(struct link_params
*params
,
8129 struct bnx2x_phy
*phy
,
8133 u16 mode
= MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT
;
8134 struct bnx2x
*bp
= params
->bp
;
8136 u8 lane
= bnx2x_get_warpcore_lane(phy
, params
);
8137 /* This is a global register which controls all lanes */
8138 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
8139 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE
, &val
);
8140 val
&= ~(0xf << (lane
<< 2));
8143 case EDC_MODE_LINEAR
:
8144 case EDC_MODE_LIMITING
:
8145 mode
= MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT
;
8147 case EDC_MODE_PASSIVE_DAC
:
8148 mode
= MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC
;
8154 val
|= (mode
<< (lane
<< 2));
8155 bnx2x_cl45_write(bp
, phy
, MDIO_WC_DEVAD
,
8156 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE
, val
);
8158 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
8159 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE
, &val
);
8161 /* Restart microcode to re-read the new mode */
8162 bnx2x_warpcore_reset_lane(bp
, phy
, 1);
8163 bnx2x_warpcore_reset_lane(bp
, phy
, 0);
8167 static void bnx2x_set_limiting_mode(struct link_params
*params
,
8168 struct bnx2x_phy
*phy
,
8171 switch (phy
->type
) {
8172 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
:
8173 bnx2x_8726_set_limiting_mode(params
->bp
, phy
, edc_mode
);
8175 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
:
8176 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722
:
8177 bnx2x_8727_set_limiting_mode(params
->bp
, phy
, edc_mode
);
8179 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
:
8180 bnx2x_warpcore_set_limiting_mode(params
, phy
, edc_mode
);
8185 int bnx2x_sfp_module_detection(struct bnx2x_phy
*phy
,
8186 struct link_params
*params
)
8188 struct bnx2x
*bp
= params
->bp
;
8192 u32 val
= REG_RD(bp
, params
->shmem_base
+
8193 offsetof(struct shmem_region
, dev_info
.
8194 port_feature_config
[params
->port
].config
));
8196 DP(NETIF_MSG_LINK
, "SFP+ module plugged in/out detected on port %d\n",
8198 /* Power up module */
8199 bnx2x_power_sfp_module(params
, phy
, 1);
8200 if (bnx2x_get_edc_mode(phy
, params
, &edc_mode
) != 0) {
8201 DP(NETIF_MSG_LINK
, "Failed to get valid module type\n");
8203 } else if (bnx2x_verify_sfp_module(phy
, params
) != 0) {
8204 /* check SFP+ module compatibility */
8205 DP(NETIF_MSG_LINK
, "Module verification failed!!\n");
8207 /* Turn on fault module-detected led */
8208 bnx2x_set_sfp_module_fault_led(params
,
8209 MISC_REGISTERS_GPIO_HIGH
);
8211 /* Check if need to power down the SFP+ module */
8212 if ((val
& PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK
) ==
8213 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN
) {
8214 DP(NETIF_MSG_LINK
, "Shutdown SFP+ module!!\n");
8215 bnx2x_power_sfp_module(params
, phy
, 0);
8219 /* Turn off fault module-detected led */
8220 bnx2x_set_sfp_module_fault_led(params
, MISC_REGISTERS_GPIO_LOW
);
8224 * Check and set limiting mode / LRM mode on 8726. On 8727 it
8225 * is done automatically
8227 bnx2x_set_limiting_mode(params
, phy
, edc_mode
);
8230 * Enable transmit for this module if the module is approved, or
8231 * if unapproved modules should also enable the Tx laser
8234 (val
& PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK
) !=
8235 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER
)
8236 bnx2x_sfp_set_transmitter(params
, phy
, 1);
8238 bnx2x_sfp_set_transmitter(params
, phy
, 0);
8243 void bnx2x_handle_module_detect_int(struct link_params
*params
)
8245 struct bnx2x
*bp
= params
->bp
;
8246 struct bnx2x_phy
*phy
;
8248 u8 gpio_num
, gpio_port
;
8250 phy
= ¶ms
->phy
[INT_PHY
];
8252 phy
= ¶ms
->phy
[EXT_PHY1
];
8254 if (bnx2x_get_mod_abs_int_cfg(bp
, params
->chip_id
, params
->shmem_base
,
8255 params
->port
, &gpio_num
, &gpio_port
) ==
8257 DP(NETIF_MSG_LINK
, "Failed to get MOD_ABS interrupt config\n");
8261 /* Set valid module led off */
8262 bnx2x_set_sfp_module_fault_led(params
, MISC_REGISTERS_GPIO_HIGH
);
8264 /* Get current gpio val reflecting module plugged in / out*/
8265 gpio_val
= bnx2x_get_gpio(bp
, gpio_num
, gpio_port
);
8267 /* Call the handling function in case module is detected */
8268 if (gpio_val
== 0) {
8269 bnx2x_power_sfp_module(params
, phy
, 1);
8270 bnx2x_set_gpio_int(bp
, gpio_num
,
8271 MISC_REGISTERS_GPIO_INT_OUTPUT_CLR
,
8273 if (bnx2x_wait_for_sfp_module_initialized(phy
, params
) == 0)
8274 bnx2x_sfp_module_detection(phy
, params
);
8276 DP(NETIF_MSG_LINK
, "SFP+ module is not initialized\n");
8278 u32 val
= REG_RD(bp
, params
->shmem_base
+
8279 offsetof(struct shmem_region
, dev_info
.
8280 port_feature_config
[params
->port
].
8282 bnx2x_set_gpio_int(bp
, gpio_num
,
8283 MISC_REGISTERS_GPIO_INT_OUTPUT_SET
,
8286 * Module was plugged out.
8287 * Disable transmit for this module
8289 phy
->media_type
= ETH_PHY_NOT_PRESENT
;
8290 if (((val
& PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK
) ==
8291 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER
) ||
8293 bnx2x_sfp_set_transmitter(params
, phy
, 0);
8297 /******************************************************************/
8298 /* Used by 8706 and 8727 */
8299 /******************************************************************/
8300 static void bnx2x_sfp_mask_fault(struct bnx2x
*bp
,
8301 struct bnx2x_phy
*phy
,
8302 u16 alarm_status_offset
,
8303 u16 alarm_ctrl_offset
)
8305 u16 alarm_status
, val
;
8306 bnx2x_cl45_read(bp
, phy
,
8307 MDIO_PMA_DEVAD
, alarm_status_offset
,
8309 bnx2x_cl45_read(bp
, phy
,
8310 MDIO_PMA_DEVAD
, alarm_status_offset
,
8312 /* Mask or enable the fault event. */
8313 bnx2x_cl45_read(bp
, phy
, MDIO_PMA_DEVAD
, alarm_ctrl_offset
, &val
);
8314 if (alarm_status
& (1<<0))
8318 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
, alarm_ctrl_offset
, val
);
8320 /******************************************************************/
8321 /* common BCM8706/BCM8726 PHY SECTION */
8322 /******************************************************************/
8323 static u8
bnx2x_8706_8726_read_status(struct bnx2x_phy
*phy
,
8324 struct link_params
*params
,
8325 struct link_vars
*vars
)
8328 u16 val1
, val2
, rx_sd
, pcs_status
;
8329 struct bnx2x
*bp
= params
->bp
;
8330 DP(NETIF_MSG_LINK
, "XGXS 8706/8726\n");
8332 bnx2x_cl45_read(bp
, phy
,
8333 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_RXSTAT
, &val2
);
8335 bnx2x_sfp_mask_fault(bp
, phy
, MDIO_PMA_LASI_TXSTAT
,
8336 MDIO_PMA_LASI_TXCTRL
);
8338 /* clear LASI indication*/
8339 bnx2x_cl45_read(bp
, phy
,
8340 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_STAT
, &val1
);
8341 bnx2x_cl45_read(bp
, phy
,
8342 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_STAT
, &val2
);
8343 DP(NETIF_MSG_LINK
, "8706/8726 LASI status 0x%x--> 0x%x\n", val1
, val2
);
8345 bnx2x_cl45_read(bp
, phy
,
8346 MDIO_PMA_DEVAD
, MDIO_PMA_REG_RX_SD
, &rx_sd
);
8347 bnx2x_cl45_read(bp
, phy
,
8348 MDIO_PCS_DEVAD
, MDIO_PCS_REG_STATUS
, &pcs_status
);
8349 bnx2x_cl45_read(bp
, phy
,
8350 MDIO_AN_DEVAD
, MDIO_AN_REG_LINK_STATUS
, &val2
);
8351 bnx2x_cl45_read(bp
, phy
,
8352 MDIO_AN_DEVAD
, MDIO_AN_REG_LINK_STATUS
, &val2
);
8354 DP(NETIF_MSG_LINK
, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
8355 " link_status 0x%x\n", rx_sd
, pcs_status
, val2
);
8357 * link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
8358 * are set, or if the autoneg bit 1 is set
8360 link_up
= ((rx_sd
& pcs_status
& 0x1) || (val2
& (1<<1)));
8363 vars
->line_speed
= SPEED_1000
;
8365 vars
->line_speed
= SPEED_10000
;
8366 bnx2x_ext_phy_resolve_fc(phy
, params
, vars
);
8367 vars
->duplex
= DUPLEX_FULL
;
8370 /* Capture 10G link fault. Read twice to clear stale value. */
8371 if (vars
->line_speed
== SPEED_10000
) {
8372 bnx2x_cl45_read(bp
, phy
, MDIO_PMA_DEVAD
,
8373 MDIO_PMA_LASI_TXSTAT
, &val1
);
8374 bnx2x_cl45_read(bp
, phy
, MDIO_PMA_DEVAD
,
8375 MDIO_PMA_LASI_TXSTAT
, &val1
);
8377 vars
->fault_detected
= 1;
8383 /******************************************************************/
8384 /* BCM8706 PHY SECTION */
8385 /******************************************************************/
8386 static u8
bnx2x_8706_config_init(struct bnx2x_phy
*phy
,
8387 struct link_params
*params
,
8388 struct link_vars
*vars
)
8392 struct bnx2x
*bp
= params
->bp
;
8394 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
8395 MISC_REGISTERS_GPIO_OUTPUT_HIGH
, params
->port
);
8397 bnx2x_ext_phy_hw_reset(bp
, params
->port
);
8398 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
, MDIO_PMA_REG_CTRL
, 0xa040);
8399 bnx2x_wait_reset_complete(bp
, phy
, params
);
8401 /* Wait until fw is loaded */
8402 for (cnt
= 0; cnt
< 100; cnt
++) {
8403 bnx2x_cl45_read(bp
, phy
,
8404 MDIO_PMA_DEVAD
, MDIO_PMA_REG_ROM_VER1
, &val
);
8409 DP(NETIF_MSG_LINK
, "XGXS 8706 is initialized after %d ms\n", cnt
);
8410 if ((params
->feature_config_flags
&
8411 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED
)) {
8414 for (i
= 0; i
< 4; i
++) {
8415 reg
= MDIO_XS_8706_REG_BANK_RX0
+
8416 i
*(MDIO_XS_8706_REG_BANK_RX1
-
8417 MDIO_XS_8706_REG_BANK_RX0
);
8418 bnx2x_cl45_read(bp
, phy
, MDIO_XS_DEVAD
, reg
, &val
);
8419 /* Clear first 3 bits of the control */
8421 /* Set control bits according to configuration */
8422 val
|= (phy
->rx_preemphasis
[i
] & 0x7);
8423 DP(NETIF_MSG_LINK
, "Setting RX Equalizer to BCM8706"
8424 " reg 0x%x <-- val 0x%x\n", reg
, val
);
8425 bnx2x_cl45_write(bp
, phy
, MDIO_XS_DEVAD
, reg
, val
);
8429 if (phy
->req_line_speed
== SPEED_10000
) {
8430 DP(NETIF_MSG_LINK
, "XGXS 8706 force 10Gbps\n");
8432 bnx2x_cl45_write(bp
, phy
,
8434 MDIO_PMA_REG_DIGITAL_CTRL
, 0x400);
8435 bnx2x_cl45_write(bp
, phy
,
8436 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_TXCTRL
,
8438 /* Arm LASI for link and Tx fault. */
8439 bnx2x_cl45_write(bp
, phy
,
8440 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_CTRL
, 3);
8442 /* Force 1Gbps using autoneg with 1G advertisement */
8444 /* Allow CL37 through CL73 */
8445 DP(NETIF_MSG_LINK
, "XGXS 8706 AutoNeg\n");
8446 bnx2x_cl45_write(bp
, phy
,
8447 MDIO_AN_DEVAD
, MDIO_AN_REG_CL37_CL73
, 0x040c);
8449 /* Enable Full-Duplex advertisement on CL37 */
8450 bnx2x_cl45_write(bp
, phy
,
8451 MDIO_AN_DEVAD
, MDIO_AN_REG_CL37_FC_LP
, 0x0020);
8452 /* Enable CL37 AN */
8453 bnx2x_cl45_write(bp
, phy
,
8454 MDIO_AN_DEVAD
, MDIO_AN_REG_CL37_AN
, 0x1000);
8456 bnx2x_cl45_write(bp
, phy
,
8457 MDIO_AN_DEVAD
, MDIO_AN_REG_ADV
, (1<<5));
8459 /* Enable clause 73 AN */
8460 bnx2x_cl45_write(bp
, phy
,
8461 MDIO_AN_DEVAD
, MDIO_AN_REG_CTRL
, 0x1200);
8462 bnx2x_cl45_write(bp
, phy
,
8463 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_RXCTRL
,
8465 bnx2x_cl45_write(bp
, phy
,
8466 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_CTRL
,
8469 bnx2x_save_bcm_spirom_ver(bp
, phy
, params
->port
);
8472 * If TX Laser is controlled by GPIO_0, do not let PHY go into low
8473 * power mode, if TX Laser is disabled
8476 tx_en_mode
= REG_RD(bp
, params
->shmem_base
+
8477 offsetof(struct shmem_region
,
8478 dev_info
.port_hw_config
[params
->port
].sfp_ctrl
))
8479 & PORT_HW_CFG_TX_LASER_MASK
;
8481 if (tx_en_mode
== PORT_HW_CFG_TX_LASER_GPIO0
) {
8482 DP(NETIF_MSG_LINK
, "Enabling TXONOFF_PWRDN_DIS\n");
8483 bnx2x_cl45_read(bp
, phy
,
8484 MDIO_PMA_DEVAD
, MDIO_PMA_REG_DIGITAL_CTRL
, &tmp1
);
8486 bnx2x_cl45_write(bp
, phy
,
8487 MDIO_PMA_DEVAD
, MDIO_PMA_REG_DIGITAL_CTRL
, tmp1
);
8493 static int bnx2x_8706_read_status(struct bnx2x_phy
*phy
,
8494 struct link_params
*params
,
8495 struct link_vars
*vars
)
8497 return bnx2x_8706_8726_read_status(phy
, params
, vars
);
8500 /******************************************************************/
8501 /* BCM8726 PHY SECTION */
8502 /******************************************************************/
8503 static void bnx2x_8726_config_loopback(struct bnx2x_phy
*phy
,
8504 struct link_params
*params
)
8506 struct bnx2x
*bp
= params
->bp
;
8507 DP(NETIF_MSG_LINK
, "PMA/PMD ext_phy_loopback: 8726\n");
8508 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
, MDIO_PMA_REG_CTRL
, 0x0001);
8511 static void bnx2x_8726_external_rom_boot(struct bnx2x_phy
*phy
,
8512 struct link_params
*params
)
8514 struct bnx2x
*bp
= params
->bp
;
8515 /* Need to wait 100ms after reset */
8518 /* Micro controller re-boot */
8519 bnx2x_cl45_write(bp
, phy
,
8520 MDIO_PMA_DEVAD
, MDIO_PMA_REG_GEN_CTRL
, 0x018B);
8522 /* Set soft reset */
8523 bnx2x_cl45_write(bp
, phy
,
8525 MDIO_PMA_REG_GEN_CTRL
,
8526 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET
);
8528 bnx2x_cl45_write(bp
, phy
,
8530 MDIO_PMA_REG_MISC_CTRL1
, 0x0001);
8532 bnx2x_cl45_write(bp
, phy
,
8534 MDIO_PMA_REG_GEN_CTRL
,
8535 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP
);
8537 /* wait for 150ms for microcode load */
8540 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
8541 bnx2x_cl45_write(bp
, phy
,
8543 MDIO_PMA_REG_MISC_CTRL1
, 0x0000);
8546 bnx2x_save_bcm_spirom_ver(bp
, phy
, params
->port
);
8549 static u8
bnx2x_8726_read_status(struct bnx2x_phy
*phy
,
8550 struct link_params
*params
,
8551 struct link_vars
*vars
)
8553 struct bnx2x
*bp
= params
->bp
;
8555 u8 link_up
= bnx2x_8706_8726_read_status(phy
, params
, vars
);
8557 bnx2x_cl45_read(bp
, phy
,
8558 MDIO_PMA_DEVAD
, MDIO_PMA_REG_PHY_IDENTIFIER
,
8560 if (val1
& (1<<15)) {
8561 DP(NETIF_MSG_LINK
, "Tx is disabled\n");
8563 vars
->line_speed
= 0;
8570 static int bnx2x_8726_config_init(struct bnx2x_phy
*phy
,
8571 struct link_params
*params
,
8572 struct link_vars
*vars
)
8574 struct bnx2x
*bp
= params
->bp
;
8575 DP(NETIF_MSG_LINK
, "Initializing BCM8726\n");
8577 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
, MDIO_PMA_REG_CTRL
, 1<<15);
8578 bnx2x_wait_reset_complete(bp
, phy
, params
);
8580 bnx2x_8726_external_rom_boot(phy
, params
);
8583 * Need to call module detected on initialization since the module
8584 * detection triggered by actual module insertion might occur before
8585 * driver is loaded, and when driver is loaded, it reset all
8586 * registers, including the transmitter
8588 bnx2x_sfp_module_detection(phy
, params
);
8590 if (phy
->req_line_speed
== SPEED_1000
) {
8591 DP(NETIF_MSG_LINK
, "Setting 1G force\n");
8592 bnx2x_cl45_write(bp
, phy
,
8593 MDIO_PMA_DEVAD
, MDIO_PMA_REG_CTRL
, 0x40);
8594 bnx2x_cl45_write(bp
, phy
,
8595 MDIO_PMA_DEVAD
, MDIO_PMA_REG_10G_CTRL2
, 0xD);
8596 bnx2x_cl45_write(bp
, phy
,
8597 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_CTRL
, 0x5);
8598 bnx2x_cl45_write(bp
, phy
,
8599 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_RXCTRL
,
8601 } else if ((phy
->req_line_speed
== SPEED_AUTO_NEG
) &&
8602 (phy
->speed_cap_mask
&
8603 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
) &&
8604 ((phy
->speed_cap_mask
&
8605 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
) !=
8606 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)) {
8607 DP(NETIF_MSG_LINK
, "Setting 1G clause37\n");
8608 /* Set Flow control */
8609 bnx2x_ext_phy_set_pause(params
, phy
, vars
);
8610 bnx2x_cl45_write(bp
, phy
,
8611 MDIO_AN_DEVAD
, MDIO_AN_REG_ADV
, 0x20);
8612 bnx2x_cl45_write(bp
, phy
,
8613 MDIO_AN_DEVAD
, MDIO_AN_REG_CL37_CL73
, 0x040c);
8614 bnx2x_cl45_write(bp
, phy
,
8615 MDIO_AN_DEVAD
, MDIO_AN_REG_CL37_FC_LD
, 0x0020);
8616 bnx2x_cl45_write(bp
, phy
,
8617 MDIO_AN_DEVAD
, MDIO_AN_REG_CL37_AN
, 0x1000);
8618 bnx2x_cl45_write(bp
, phy
,
8619 MDIO_AN_DEVAD
, MDIO_AN_REG_CTRL
, 0x1200);
8621 * Enable RX-ALARM control to receive interrupt for 1G speed
8624 bnx2x_cl45_write(bp
, phy
,
8625 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_CTRL
, 0x4);
8626 bnx2x_cl45_write(bp
, phy
,
8627 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_RXCTRL
,
8630 } else { /* Default 10G. Set only LASI control */
8631 bnx2x_cl45_write(bp
, phy
,
8632 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_CTRL
, 1);
8635 /* Set TX PreEmphasis if needed */
8636 if ((params
->feature_config_flags
&
8637 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED
)) {
8639 "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
8640 phy
->tx_preemphasis
[0],
8641 phy
->tx_preemphasis
[1]);
8642 bnx2x_cl45_write(bp
, phy
,
8644 MDIO_PMA_REG_8726_TX_CTRL1
,
8645 phy
->tx_preemphasis
[0]);
8647 bnx2x_cl45_write(bp
, phy
,
8649 MDIO_PMA_REG_8726_TX_CTRL2
,
8650 phy
->tx_preemphasis
[1]);
8657 static void bnx2x_8726_link_reset(struct bnx2x_phy
*phy
,
8658 struct link_params
*params
)
8660 struct bnx2x
*bp
= params
->bp
;
8661 DP(NETIF_MSG_LINK
, "bnx2x_8726_link_reset port %d\n", params
->port
);
8662 /* Set serial boot control for external load */
8663 bnx2x_cl45_write(bp
, phy
,
8665 MDIO_PMA_REG_GEN_CTRL
, 0x0001);
8668 /******************************************************************/
8669 /* BCM8727 PHY SECTION */
8670 /******************************************************************/
8672 static void bnx2x_8727_set_link_led(struct bnx2x_phy
*phy
,
8673 struct link_params
*params
, u8 mode
)
8675 struct bnx2x
*bp
= params
->bp
;
8676 u16 led_mode_bitmask
= 0;
8677 u16 gpio_pins_bitmask
= 0;
8679 /* Only NOC flavor requires to set the LED specifically */
8680 if (!(phy
->flags
& FLAGS_NOC
))
8683 case LED_MODE_FRONT_PANEL_OFF
:
8685 led_mode_bitmask
= 0;
8686 gpio_pins_bitmask
= 0x03;
8689 led_mode_bitmask
= 0;
8690 gpio_pins_bitmask
= 0x02;
8693 led_mode_bitmask
= 0x60;
8694 gpio_pins_bitmask
= 0x11;
8697 bnx2x_cl45_read(bp
, phy
,
8699 MDIO_PMA_REG_8727_PCS_OPT_CTRL
,
8702 val
|= led_mode_bitmask
;
8703 bnx2x_cl45_write(bp
, phy
,
8705 MDIO_PMA_REG_8727_PCS_OPT_CTRL
,
8707 bnx2x_cl45_read(bp
, phy
,
8709 MDIO_PMA_REG_8727_GPIO_CTRL
,
8712 val
|= gpio_pins_bitmask
;
8713 bnx2x_cl45_write(bp
, phy
,
8715 MDIO_PMA_REG_8727_GPIO_CTRL
,
8718 static void bnx2x_8727_hw_reset(struct bnx2x_phy
*phy
,
8719 struct link_params
*params
) {
8720 u32 swap_val
, swap_override
;
8723 * The PHY reset is controlled by GPIO 1. Fake the port number
8724 * to cancel the swap done in set_gpio()
8726 struct bnx2x
*bp
= params
->bp
;
8727 swap_val
= REG_RD(bp
, NIG_REG_PORT_SWAP
);
8728 swap_override
= REG_RD(bp
, NIG_REG_STRAP_OVERRIDE
);
8729 port
= (swap_val
&& swap_override
) ^ 1;
8730 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_1
,
8731 MISC_REGISTERS_GPIO_OUTPUT_LOW
, port
);
8734 static int bnx2x_8727_config_init(struct bnx2x_phy
*phy
,
8735 struct link_params
*params
,
8736 struct link_vars
*vars
)
8739 u16 tmp1
, val
, mod_abs
, tmp2
;
8740 u16 rx_alarm_ctrl_val
;
8742 struct bnx2x
*bp
= params
->bp
;
8743 /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
8745 bnx2x_wait_reset_complete(bp
, phy
, params
);
8746 rx_alarm_ctrl_val
= (1<<2) | (1<<5) ;
8747 /* Should be 0x6 to enable XS on Tx side. */
8748 lasi_ctrl_val
= 0x0006;
8750 DP(NETIF_MSG_LINK
, "Initializing BCM8727\n");
8752 bnx2x_cl45_write(bp
, phy
,
8753 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_RXCTRL
,
8755 bnx2x_cl45_write(bp
, phy
,
8756 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_TXCTRL
,
8758 bnx2x_cl45_write(bp
, phy
,
8759 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_CTRL
, lasi_ctrl_val
);
8762 * Initially configure MOD_ABS to interrupt when module is
8765 bnx2x_cl45_read(bp
, phy
,
8766 MDIO_PMA_DEVAD
, MDIO_PMA_REG_PHY_IDENTIFIER
, &mod_abs
);
8768 * Set EDC off by setting OPTXLOS signal input to low (bit 9).
8769 * When the EDC is off it locks onto a reference clock and avoids
8773 if (!(phy
->flags
& FLAGS_NOC
))
8775 bnx2x_cl45_write(bp
, phy
,
8776 MDIO_PMA_DEVAD
, MDIO_PMA_REG_PHY_IDENTIFIER
, mod_abs
);
8779 /* Enable/Disable PHY transmitter output */
8780 bnx2x_set_disable_pmd_transmit(params
, phy
, 0);
8782 /* Make MOD_ABS give interrupt on change */
8783 bnx2x_cl45_read(bp
, phy
, MDIO_PMA_DEVAD
, MDIO_PMA_REG_8727_PCS_OPT_CTRL
,
8786 if (phy
->flags
& FLAGS_NOC
)
8790 * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
8791 * status which reflect SFP+ module over-current
8793 if (!(phy
->flags
& FLAGS_NOC
))
8794 val
&= 0xff8f; /* Reset bits 4-6 */
8795 bnx2x_cl45_write(bp
, phy
,
8796 MDIO_PMA_DEVAD
, MDIO_PMA_REG_8727_PCS_OPT_CTRL
, val
);
8798 bnx2x_8727_power_module(bp
, phy
, 1);
8800 bnx2x_cl45_read(bp
, phy
,
8801 MDIO_PMA_DEVAD
, MDIO_PMA_REG_M8051_MSGOUT_REG
, &tmp1
);
8803 bnx2x_cl45_read(bp
, phy
,
8804 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_RXSTAT
, &tmp1
);
8806 /* Set option 1G speed */
8807 if (phy
->req_line_speed
== SPEED_1000
) {
8808 DP(NETIF_MSG_LINK
, "Setting 1G force\n");
8809 bnx2x_cl45_write(bp
, phy
,
8810 MDIO_PMA_DEVAD
, MDIO_PMA_REG_CTRL
, 0x40);
8811 bnx2x_cl45_write(bp
, phy
,
8812 MDIO_PMA_DEVAD
, MDIO_PMA_REG_10G_CTRL2
, 0xD);
8813 bnx2x_cl45_read(bp
, phy
,
8814 MDIO_PMA_DEVAD
, MDIO_PMA_REG_10G_CTRL2
, &tmp1
);
8815 DP(NETIF_MSG_LINK
, "1.7 = 0x%x\n", tmp1
);
8817 * Power down the XAUI until link is up in case of dual-media
8820 if (DUAL_MEDIA(params
)) {
8821 bnx2x_cl45_read(bp
, phy
,
8823 MDIO_PMA_REG_8727_PCS_GP
, &val
);
8825 bnx2x_cl45_write(bp
, phy
,
8827 MDIO_PMA_REG_8727_PCS_GP
, val
);
8829 } else if ((phy
->req_line_speed
== SPEED_AUTO_NEG
) &&
8830 ((phy
->speed_cap_mask
&
8831 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
)) &&
8832 ((phy
->speed_cap_mask
&
8833 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
) !=
8834 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)) {
8836 DP(NETIF_MSG_LINK
, "Setting 1G clause37\n");
8837 bnx2x_cl45_write(bp
, phy
,
8838 MDIO_AN_DEVAD
, MDIO_AN_REG_8727_MISC_CTRL
, 0);
8839 bnx2x_cl45_write(bp
, phy
,
8840 MDIO_AN_DEVAD
, MDIO_AN_REG_CL37_AN
, 0x1300);
8843 * Since the 8727 has only single reset pin, need to set the 10G
8844 * registers although it is default
8846 bnx2x_cl45_write(bp
, phy
,
8847 MDIO_AN_DEVAD
, MDIO_AN_REG_8727_MISC_CTRL
,
8849 bnx2x_cl45_write(bp
, phy
,
8850 MDIO_AN_DEVAD
, MDIO_AN_REG_CL37_AN
, 0x0100);
8851 bnx2x_cl45_write(bp
, phy
,
8852 MDIO_PMA_DEVAD
, MDIO_PMA_REG_CTRL
, 0x2040);
8853 bnx2x_cl45_write(bp
, phy
,
8854 MDIO_PMA_DEVAD
, MDIO_PMA_REG_10G_CTRL2
,
8859 * Set 2-wire transfer rate of SFP+ module EEPROM
8860 * to 100Khz since some DACs(direct attached cables) do
8861 * not work at 400Khz.
8863 bnx2x_cl45_write(bp
, phy
,
8864 MDIO_PMA_DEVAD
, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR
,
8867 /* Set TX PreEmphasis if needed */
8868 if ((params
->feature_config_flags
&
8869 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED
)) {
8870 DP(NETIF_MSG_LINK
, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
8871 phy
->tx_preemphasis
[0],
8872 phy
->tx_preemphasis
[1]);
8873 bnx2x_cl45_write(bp
, phy
,
8874 MDIO_PMA_DEVAD
, MDIO_PMA_REG_8727_TX_CTRL1
,
8875 phy
->tx_preemphasis
[0]);
8877 bnx2x_cl45_write(bp
, phy
,
8878 MDIO_PMA_DEVAD
, MDIO_PMA_REG_8727_TX_CTRL2
,
8879 phy
->tx_preemphasis
[1]);
8883 * If TX Laser is controlled by GPIO_0, do not let PHY go into low
8884 * power mode, if TX Laser is disabled
8886 tx_en_mode
= REG_RD(bp
, params
->shmem_base
+
8887 offsetof(struct shmem_region
,
8888 dev_info
.port_hw_config
[params
->port
].sfp_ctrl
))
8889 & PORT_HW_CFG_TX_LASER_MASK
;
8891 if (tx_en_mode
== PORT_HW_CFG_TX_LASER_GPIO0
) {
8893 DP(NETIF_MSG_LINK
, "Enabling TXONOFF_PWRDN_DIS\n");
8894 bnx2x_cl45_read(bp
, phy
,
8895 MDIO_PMA_DEVAD
, MDIO_PMA_REG_8727_OPT_CFG_REG
, &tmp2
);
8898 bnx2x_cl45_write(bp
, phy
,
8899 MDIO_PMA_DEVAD
, MDIO_PMA_REG_8727_OPT_CFG_REG
, tmp2
);
8905 static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy
*phy
,
8906 struct link_params
*params
)
8908 struct bnx2x
*bp
= params
->bp
;
8909 u16 mod_abs
, rx_alarm_status
;
8910 u32 val
= REG_RD(bp
, params
->shmem_base
+
8911 offsetof(struct shmem_region
, dev_info
.
8912 port_feature_config
[params
->port
].
8914 bnx2x_cl45_read(bp
, phy
,
8916 MDIO_PMA_REG_PHY_IDENTIFIER
, &mod_abs
);
8917 if (mod_abs
& (1<<8)) {
8919 /* Module is absent */
8921 "MOD_ABS indication show module is absent\n");
8922 phy
->media_type
= ETH_PHY_NOT_PRESENT
;
8924 * 1. Set mod_abs to detect next module
8926 * 2. Set EDC off by setting OPTXLOS signal input to low
8928 * When the EDC is off it locks onto a reference clock and
8929 * avoids becoming 'lost'.
8932 if (!(phy
->flags
& FLAGS_NOC
))
8934 bnx2x_cl45_write(bp
, phy
,
8936 MDIO_PMA_REG_PHY_IDENTIFIER
, mod_abs
);
8939 * Clear RX alarm since it stays up as long as
8940 * the mod_abs wasn't changed
8942 bnx2x_cl45_read(bp
, phy
,
8944 MDIO_PMA_LASI_RXSTAT
, &rx_alarm_status
);
8947 /* Module is present */
8949 "MOD_ABS indication show module is present\n");
8951 * First disable transmitter, and if the module is ok, the
8952 * module_detection will enable it
8953 * 1. Set mod_abs to detect next module absent event ( bit 8)
8954 * 2. Restore the default polarity of the OPRXLOS signal and
8955 * this signal will then correctly indicate the presence or
8956 * absence of the Rx signal. (bit 9)
8959 if (!(phy
->flags
& FLAGS_NOC
))
8961 bnx2x_cl45_write(bp
, phy
,
8963 MDIO_PMA_REG_PHY_IDENTIFIER
, mod_abs
);
8966 * Clear RX alarm since it stays up as long as the mod_abs
8967 * wasn't changed. This is need to be done before calling the
8968 * module detection, otherwise it will clear* the link update
8971 bnx2x_cl45_read(bp
, phy
,
8973 MDIO_PMA_LASI_RXSTAT
, &rx_alarm_status
);
8976 if ((val
& PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK
) ==
8977 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER
)
8978 bnx2x_sfp_set_transmitter(params
, phy
, 0);
8980 if (bnx2x_wait_for_sfp_module_initialized(phy
, params
) == 0)
8981 bnx2x_sfp_module_detection(phy
, params
);
8983 DP(NETIF_MSG_LINK
, "SFP+ module is not initialized\n");
8986 DP(NETIF_MSG_LINK
, "8727 RX_ALARM_STATUS 0x%x\n",
8988 /* No need to check link status in case of module plugged in/out */
8991 static u8
bnx2x_8727_read_status(struct bnx2x_phy
*phy
,
8992 struct link_params
*params
,
8993 struct link_vars
*vars
)
8996 struct bnx2x
*bp
= params
->bp
;
8997 u8 link_up
= 0, oc_port
= params
->port
;
8998 u16 link_status
= 0;
8999 u16 rx_alarm_status
, lasi_ctrl
, val1
;
9001 /* If PHY is not initialized, do not check link status */
9002 bnx2x_cl45_read(bp
, phy
,
9003 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_CTRL
,
9008 /* Check the LASI on Rx */
9009 bnx2x_cl45_read(bp
, phy
,
9010 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_RXSTAT
,
9012 vars
->line_speed
= 0;
9013 DP(NETIF_MSG_LINK
, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status
);
9015 bnx2x_sfp_mask_fault(bp
, phy
, MDIO_PMA_LASI_TXSTAT
,
9016 MDIO_PMA_LASI_TXCTRL
);
9018 bnx2x_cl45_read(bp
, phy
,
9019 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_STAT
, &val1
);
9021 DP(NETIF_MSG_LINK
, "8727 LASI status 0x%x\n", val1
);
9024 bnx2x_cl45_read(bp
, phy
,
9025 MDIO_PMA_DEVAD
, MDIO_PMA_REG_M8051_MSGOUT_REG
, &val1
);
9028 * If a module is present and there is need to check
9031 if (!(phy
->flags
& FLAGS_NOC
) && !(rx_alarm_status
& (1<<5))) {
9032 /* Check over-current using 8727 GPIO0 input*/
9033 bnx2x_cl45_read(bp
, phy
,
9034 MDIO_PMA_DEVAD
, MDIO_PMA_REG_8727_GPIO_CTRL
,
9037 if ((val1
& (1<<8)) == 0) {
9038 if (!CHIP_IS_E1x(bp
))
9039 oc_port
= BP_PATH(bp
) + (params
->port
<< 1);
9041 "8727 Power fault has been detected on port %d\n",
9043 netdev_err(bp
->dev
, "Error: Power fault on Port %d has"
9044 " been detected and the power to "
9045 "that SFP+ module has been removed"
9046 " to prevent failure of the card."
9047 " Please remove the SFP+ module and"
9048 " restart the system to clear this"
9051 /* Disable all RX_ALARMs except for mod_abs */
9052 bnx2x_cl45_write(bp
, phy
,
9054 MDIO_PMA_LASI_RXCTRL
, (1<<5));
9056 bnx2x_cl45_read(bp
, phy
,
9058 MDIO_PMA_REG_PHY_IDENTIFIER
, &val1
);
9059 /* Wait for module_absent_event */
9061 bnx2x_cl45_write(bp
, phy
,
9063 MDIO_PMA_REG_PHY_IDENTIFIER
, val1
);
9064 /* Clear RX alarm */
9065 bnx2x_cl45_read(bp
, phy
,
9067 MDIO_PMA_LASI_RXSTAT
, &rx_alarm_status
);
9070 } /* Over current check */
9072 /* When module absent bit is set, check module */
9073 if (rx_alarm_status
& (1<<5)) {
9074 bnx2x_8727_handle_mod_abs(phy
, params
);
9075 /* Enable all mod_abs and link detection bits */
9076 bnx2x_cl45_write(bp
, phy
,
9077 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_RXCTRL
,
9080 DP(NETIF_MSG_LINK
, "Enabling 8727 TX laser if SFP is approved\n");
9081 bnx2x_8727_specific_func(phy
, params
, ENABLE_TX
);
9082 /* If transmitter is disabled, ignore false link up indication */
9083 bnx2x_cl45_read(bp
, phy
,
9084 MDIO_PMA_DEVAD
, MDIO_PMA_REG_PHY_IDENTIFIER
, &val1
);
9085 if (val1
& (1<<15)) {
9086 DP(NETIF_MSG_LINK
, "Tx is disabled\n");
9090 bnx2x_cl45_read(bp
, phy
,
9092 MDIO_PMA_REG_8073_SPEED_LINK_STATUS
, &link_status
);
9095 * Bits 0..2 --> speed detected,
9096 * Bits 13..15--> link is down
9098 if ((link_status
& (1<<2)) && (!(link_status
& (1<<15)))) {
9100 vars
->line_speed
= SPEED_10000
;
9101 DP(NETIF_MSG_LINK
, "port %x: External link up in 10G\n",
9103 } else if ((link_status
& (1<<0)) && (!(link_status
& (1<<13)))) {
9105 vars
->line_speed
= SPEED_1000
;
9106 DP(NETIF_MSG_LINK
, "port %x: External link up in 1G\n",
9110 DP(NETIF_MSG_LINK
, "port %x: External link is down\n",
9114 /* Capture 10G link fault. */
9115 if (vars
->line_speed
== SPEED_10000
) {
9116 bnx2x_cl45_read(bp
, phy
, MDIO_PMA_DEVAD
,
9117 MDIO_PMA_LASI_TXSTAT
, &val1
);
9119 bnx2x_cl45_read(bp
, phy
, MDIO_PMA_DEVAD
,
9120 MDIO_PMA_LASI_TXSTAT
, &val1
);
9122 if (val1
& (1<<0)) {
9123 vars
->fault_detected
= 1;
9128 bnx2x_ext_phy_resolve_fc(phy
, params
, vars
);
9129 vars
->duplex
= DUPLEX_FULL
;
9130 DP(NETIF_MSG_LINK
, "duplex = 0x%x\n", vars
->duplex
);
9133 if ((DUAL_MEDIA(params
)) &&
9134 (phy
->req_line_speed
== SPEED_1000
)) {
9135 bnx2x_cl45_read(bp
, phy
,
9137 MDIO_PMA_REG_8727_PCS_GP
, &val1
);
9139 * In case of dual-media board and 1G, power up the XAUI side,
9140 * otherwise power it down. For 10G it is done automatically
9146 bnx2x_cl45_write(bp
, phy
,
9148 MDIO_PMA_REG_8727_PCS_GP
, val1
);
9153 static void bnx2x_8727_link_reset(struct bnx2x_phy
*phy
,
9154 struct link_params
*params
)
9156 struct bnx2x
*bp
= params
->bp
;
9158 /* Enable/Disable PHY transmitter output */
9159 bnx2x_set_disable_pmd_transmit(params
, phy
, 1);
9161 /* Disable Transmitter */
9162 bnx2x_sfp_set_transmitter(params
, phy
, 0);
9164 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
, MDIO_PMA_LASI_CTRL
, 0);
9168 /******************************************************************/
9169 /* BCM8481/BCM84823/BCM84833 PHY SECTION */
9170 /******************************************************************/
9171 static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy
*phy
,
9172 struct link_params
*params
)
9174 u16 val
, fw_ver1
, fw_ver2
, cnt
;
9176 struct bnx2x
*bp
= params
->bp
;
9178 port
= params
->port
;
9180 /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
9181 /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
9182 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
, 0xA819, 0x0014);
9183 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
, 0xA81A, 0xc200);
9184 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
, 0xA81B, 0x0000);
9185 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
, 0xA81C, 0x0300);
9186 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
, 0xA817, 0x0009);
9188 for (cnt
= 0; cnt
< 100; cnt
++) {
9189 bnx2x_cl45_read(bp
, phy
, MDIO_PMA_DEVAD
, 0xA818, &val
);
9195 DP(NETIF_MSG_LINK
, "Unable to read 848xx phy fw version(1)\n");
9196 bnx2x_save_spirom_version(bp
, port
, 0,
9202 /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
9203 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
, 0xA819, 0x0000);
9204 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
, 0xA81A, 0xc200);
9205 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
, 0xA817, 0x000A);
9206 for (cnt
= 0; cnt
< 100; cnt
++) {
9207 bnx2x_cl45_read(bp
, phy
, MDIO_PMA_DEVAD
, 0xA818, &val
);
9213 DP(NETIF_MSG_LINK
, "Unable to read 848xx phy fw version(2)\n");
9214 bnx2x_save_spirom_version(bp
, port
, 0,
9219 /* lower 16 bits of the register SPI_FW_STATUS */
9220 bnx2x_cl45_read(bp
, phy
, MDIO_PMA_DEVAD
, 0xA81B, &fw_ver1
);
9221 /* upper 16 bits of register SPI_FW_STATUS */
9222 bnx2x_cl45_read(bp
, phy
, MDIO_PMA_DEVAD
, 0xA81C, &fw_ver2
);
9224 bnx2x_save_spirom_version(bp
, port
, (fw_ver2
<<16) | fw_ver1
,
9228 static void bnx2x_848xx_set_led(struct bnx2x
*bp
,
9229 struct bnx2x_phy
*phy
)
9233 /* PHYC_CTL_LED_CTL */
9234 bnx2x_cl45_read(bp
, phy
,
9236 MDIO_PMA_REG_8481_LINK_SIGNAL
, &val
);
9240 bnx2x_cl45_write(bp
, phy
,
9242 MDIO_PMA_REG_8481_LINK_SIGNAL
, val
);
9244 bnx2x_cl45_write(bp
, phy
,
9246 MDIO_PMA_REG_8481_LED1_MASK
,
9249 bnx2x_cl45_write(bp
, phy
,
9251 MDIO_PMA_REG_8481_LED2_MASK
,
9254 /* Select activity source by Tx and Rx, as suggested by PHY AE */
9255 bnx2x_cl45_write(bp
, phy
,
9257 MDIO_PMA_REG_8481_LED3_MASK
,
9260 /* Select the closest activity blink rate to that in 10/100/1000 */
9261 bnx2x_cl45_write(bp
, phy
,
9263 MDIO_PMA_REG_8481_LED3_BLINK
,
9266 bnx2x_cl45_read(bp
, phy
,
9268 MDIO_PMA_REG_84823_CTL_LED_CTL_1
, &val
);
9269 val
|= MDIO_PMA_REG_84823_LED3_STRETCH_EN
; /* stretch_en for LED3*/
9271 bnx2x_cl45_write(bp
, phy
,
9273 MDIO_PMA_REG_84823_CTL_LED_CTL_1
, val
);
9275 /* 'Interrupt Mask' */
9276 bnx2x_cl45_write(bp
, phy
,
9281 static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy
*phy
,
9282 struct link_params
*params
,
9283 struct link_vars
*vars
)
9285 struct bnx2x
*bp
= params
->bp
;
9286 u16 autoneg_val
, an_1000_val
, an_10_100_val
;
9287 u16 tmp_req_line_speed
;
9289 tmp_req_line_speed
= phy
->req_line_speed
;
9290 if (phy
->type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833
)
9291 if (phy
->req_line_speed
== SPEED_10000
)
9292 phy
->req_line_speed
= SPEED_AUTO_NEG
;
9295 * This phy uses the NIG latch mechanism since link indication
9296 * arrives through its LED4 and not via its LASI signal, so we
9297 * get steady signal instead of clear on read
9299 bnx2x_bits_en(bp
, NIG_REG_LATCH_BC_0
+ params
->port
*4,
9300 1 << NIG_LATCH_BC_ENABLE_MI_INT
);
9302 bnx2x_cl45_write(bp
, phy
,
9303 MDIO_PMA_DEVAD
, MDIO_PMA_REG_CTRL
, 0x0000);
9305 bnx2x_848xx_set_led(bp
, phy
);
9307 /* set 1000 speed advertisement */
9308 bnx2x_cl45_read(bp
, phy
,
9309 MDIO_AN_DEVAD
, MDIO_AN_REG_8481_1000T_CTRL
,
9312 bnx2x_ext_phy_set_pause(params
, phy
, vars
);
9313 bnx2x_cl45_read(bp
, phy
,
9315 MDIO_AN_REG_8481_LEGACY_AN_ADV
,
9317 bnx2x_cl45_read(bp
, phy
,
9318 MDIO_AN_DEVAD
, MDIO_AN_REG_8481_LEGACY_MII_CTRL
,
9320 /* Disable forced speed */
9321 autoneg_val
&= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
9322 an_10_100_val
&= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
9324 if (((phy
->req_line_speed
== SPEED_AUTO_NEG
) &&
9325 (phy
->speed_cap_mask
&
9326 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
)) ||
9327 (phy
->req_line_speed
== SPEED_1000
)) {
9328 an_1000_val
|= (1<<8);
9329 autoneg_val
|= (1<<9 | 1<<12);
9330 if (phy
->req_duplex
== DUPLEX_FULL
)
9331 an_1000_val
|= (1<<9);
9332 DP(NETIF_MSG_LINK
, "Advertising 1G\n");
9334 an_1000_val
&= ~((1<<8) | (1<<9));
9336 bnx2x_cl45_write(bp
, phy
,
9337 MDIO_AN_DEVAD
, MDIO_AN_REG_8481_1000T_CTRL
,
9340 /* set 100 speed advertisement */
9341 if (((phy
->req_line_speed
== SPEED_AUTO_NEG
) &&
9342 (phy
->speed_cap_mask
&
9343 (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL
|
9344 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF
)) &&
9346 (SUPPORTED_100baseT_Half
|
9347 SUPPORTED_100baseT_Full
)))) {
9348 an_10_100_val
|= (1<<7);
9349 /* Enable autoneg and restart autoneg for legacy speeds */
9350 autoneg_val
|= (1<<9 | 1<<12);
9352 if (phy
->req_duplex
== DUPLEX_FULL
)
9353 an_10_100_val
|= (1<<8);
9354 DP(NETIF_MSG_LINK
, "Advertising 100M\n");
9356 /* set 10 speed advertisement */
9357 if (((phy
->req_line_speed
== SPEED_AUTO_NEG
) &&
9358 (phy
->speed_cap_mask
&
9359 (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL
|
9360 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF
)) &&
9362 (SUPPORTED_10baseT_Half
|
9363 SUPPORTED_10baseT_Full
)))) {
9364 an_10_100_val
|= (1<<5);
9365 autoneg_val
|= (1<<9 | 1<<12);
9366 if (phy
->req_duplex
== DUPLEX_FULL
)
9367 an_10_100_val
|= (1<<6);
9368 DP(NETIF_MSG_LINK
, "Advertising 10M\n");
9371 /* Only 10/100 are allowed to work in FORCE mode */
9372 if ((phy
->req_line_speed
== SPEED_100
) &&
9374 (SUPPORTED_100baseT_Half
|
9375 SUPPORTED_100baseT_Full
))) {
9376 autoneg_val
|= (1<<13);
9377 /* Enabled AUTO-MDIX when autoneg is disabled */
9378 bnx2x_cl45_write(bp
, phy
,
9379 MDIO_AN_DEVAD
, MDIO_AN_REG_8481_AUX_CTRL
,
9380 (1<<15 | 1<<9 | 7<<0));
9381 DP(NETIF_MSG_LINK
, "Setting 100M force\n");
9383 if ((phy
->req_line_speed
== SPEED_10
) &&
9385 (SUPPORTED_10baseT_Half
|
9386 SUPPORTED_10baseT_Full
))) {
9387 /* Enabled AUTO-MDIX when autoneg is disabled */
9388 bnx2x_cl45_write(bp
, phy
,
9389 MDIO_AN_DEVAD
, MDIO_AN_REG_8481_AUX_CTRL
,
9390 (1<<15 | 1<<9 | 7<<0));
9391 DP(NETIF_MSG_LINK
, "Setting 10M force\n");
9394 bnx2x_cl45_write(bp
, phy
,
9395 MDIO_AN_DEVAD
, MDIO_AN_REG_8481_LEGACY_AN_ADV
,
9398 if (phy
->req_duplex
== DUPLEX_FULL
)
9399 autoneg_val
|= (1<<8);
9402 * Always write this if this is not 84833.
9403 * For 84833, write it only when it's a forced speed.
9405 if ((phy
->type
!= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833
) ||
9406 ((autoneg_val
& (1<<12)) == 0))
9407 bnx2x_cl45_write(bp
, phy
,
9409 MDIO_AN_REG_8481_LEGACY_MII_CTRL
, autoneg_val
);
9411 if (((phy
->req_line_speed
== SPEED_AUTO_NEG
) &&
9412 (phy
->speed_cap_mask
&
9413 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G
)) ||
9414 (phy
->req_line_speed
== SPEED_10000
)) {
9415 DP(NETIF_MSG_LINK
, "Advertising 10G\n");
9416 /* Restart autoneg for 10G*/
9418 bnx2x_cl45_write(bp
, phy
,
9419 MDIO_AN_DEVAD
, MDIO_AN_REG_CTRL
,
9422 bnx2x_cl45_write(bp
, phy
,
9424 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL
,
9427 /* Save spirom version */
9428 bnx2x_save_848xx_spirom_version(phy
, params
);
9430 phy
->req_line_speed
= tmp_req_line_speed
;
9435 static int bnx2x_8481_config_init(struct bnx2x_phy
*phy
,
9436 struct link_params
*params
,
9437 struct link_vars
*vars
)
9439 struct bnx2x
*bp
= params
->bp
;
9440 /* Restore normal power mode*/
9441 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
9442 MISC_REGISTERS_GPIO_OUTPUT_HIGH
, params
->port
);
9445 bnx2x_ext_phy_hw_reset(bp
, params
->port
);
9446 bnx2x_wait_reset_complete(bp
, phy
, params
);
9448 bnx2x_cl45_write(bp
, phy
, MDIO_PMA_DEVAD
, MDIO_PMA_REG_CTRL
, 1<<15);
9449 return bnx2x_848xx_cmn_config_init(phy
, params
, vars
);
9453 #define PHY84833_HDSHK_WAIT 300
9454 static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy
*phy
,
9455 struct link_params
*params
,
9456 struct link_vars
*vars
)
9462 struct bnx2x
*bp
= params
->bp
;
9465 /* Check for configuration. */
9466 pair_swap
= REG_RD(bp
, params
->shmem_base
+
9467 offsetof(struct shmem_region
,
9468 dev_info
.port_hw_config
[params
->port
].xgbt_phy_cfg
)) &
9469 PORT_HW_CFG_RJ45_PAIR_SWAP_MASK
;
9474 data
= (u16
)pair_swap
;
9476 /* Write CMD_OPEN_OVERRIDE to STATUS reg */
9477 bnx2x_cl45_write(bp
, phy
, MDIO_CTL_DEVAD
,
9478 MDIO_84833_TOP_CFG_SCRATCH_REG2
,
9479 PHY84833_CMD_OPEN_OVERRIDE
);
9480 for (idx
= 0; idx
< PHY84833_HDSHK_WAIT
; idx
++) {
9481 bnx2x_cl45_read(bp
, phy
, MDIO_CTL_DEVAD
,
9482 MDIO_84833_TOP_CFG_SCRATCH_REG2
, &val
);
9483 if (val
== PHY84833_CMD_OPEN_FOR_CMDS
)
9487 if (idx
>= PHY84833_HDSHK_WAIT
) {
9488 DP(NETIF_MSG_LINK
, "Pairswap: FW not ready.\n");
9492 bnx2x_cl45_write(bp
, phy
, MDIO_CTL_DEVAD
,
9493 MDIO_84833_TOP_CFG_SCRATCH_REG4
,
9495 /* Issue pair swap command */
9496 bnx2x_cl45_write(bp
, phy
, MDIO_CTL_DEVAD
,
9497 MDIO_84833_TOP_CFG_SCRATCH_REG0
,
9498 PHY84833_DIAG_CMD_PAIR_SWAP_CHANGE
);
9499 for (idx
= 0; idx
< PHY84833_HDSHK_WAIT
; idx
++) {
9500 bnx2x_cl45_read(bp
, phy
, MDIO_CTL_DEVAD
,
9501 MDIO_84833_TOP_CFG_SCRATCH_REG2
, &val
);
9502 if ((val
== PHY84833_CMD_COMPLETE_PASS
) ||
9503 (val
== PHY84833_CMD_COMPLETE_ERROR
))
9507 if ((idx
>= PHY84833_HDSHK_WAIT
) ||
9508 (val
== PHY84833_CMD_COMPLETE_ERROR
)) {
9509 DP(NETIF_MSG_LINK
, "Pairswap: override failed.\n");
9512 bnx2x_cl45_write(bp
, phy
, MDIO_CTL_DEVAD
,
9513 MDIO_84833_TOP_CFG_SCRATCH_REG2
,
9514 PHY84833_CMD_CLEAR_COMPLETE
);
9515 DP(NETIF_MSG_LINK
, "Pairswap OK, val=0x%x\n", data
);
9520 static u8
bnx2x_84833_get_reset_gpios(struct bnx2x
*bp
,
9521 u32 shmem_base_path
[],
9527 if (CHIP_IS_E3(bp
)) {
9528 /* Assume that these will be GPIOs, not EPIOs. */
9529 for (idx
= 0; idx
< 2; idx
++) {
9530 /* Map config param to register bit. */
9531 reset_pin
[idx
] = REG_RD(bp
, shmem_base_path
[idx
] +
9532 offsetof(struct shmem_region
,
9533 dev_info
.port_hw_config
[0].e3_cmn_pin_cfg
));
9534 reset_pin
[idx
] = (reset_pin
[idx
] &
9535 PORT_HW_CFG_E3_PHY_RESET_MASK
) >>
9536 PORT_HW_CFG_E3_PHY_RESET_SHIFT
;
9537 reset_pin
[idx
] -= PIN_CFG_GPIO0_P0
;
9538 reset_pin
[idx
] = (1 << reset_pin
[idx
]);
9540 reset_gpios
= (u8
)(reset_pin
[0] | reset_pin
[1]);
9542 /* E2, look from diff place of shmem. */
9543 for (idx
= 0; idx
< 2; idx
++) {
9544 reset_pin
[idx
] = REG_RD(bp
, shmem_base_path
[idx
] +
9545 offsetof(struct shmem_region
,
9546 dev_info
.port_hw_config
[0].default_cfg
));
9547 reset_pin
[idx
] &= PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK
;
9548 reset_pin
[idx
] -= PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0
;
9549 reset_pin
[idx
] >>= PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT
;
9550 reset_pin
[idx
] = (1 << reset_pin
[idx
]);
9552 reset_gpios
= (u8
)(reset_pin
[0] | reset_pin
[1]);
9558 static int bnx2x_84833_hw_reset_phy(struct bnx2x_phy
*phy
,
9559 struct link_params
*params
)
9561 struct bnx2x
*bp
= params
->bp
;
9563 u32 other_shmem_base_addr
= REG_RD(bp
, params
->shmem2_base
+
9564 offsetof(struct shmem2_region
,
9565 other_shmem_base_addr
));
9567 u32 shmem_base_path
[2];
9568 shmem_base_path
[0] = params
->shmem_base
;
9569 shmem_base_path
[1] = other_shmem_base_addr
;
9571 reset_gpios
= bnx2x_84833_get_reset_gpios(bp
, shmem_base_path
,
9574 bnx2x_set_mult_gpio(bp
, reset_gpios
, MISC_REGISTERS_GPIO_OUTPUT_LOW
);
9576 DP(NETIF_MSG_LINK
, "84833 hw reset on pin values 0x%x\n",
9582 static int bnx2x_84833_common_init_phy(struct bnx2x
*bp
,
9583 u32 shmem_base_path
[],
9588 reset_gpios
= bnx2x_84833_get_reset_gpios(bp
, shmem_base_path
, chip_id
);
9590 bnx2x_set_mult_gpio(bp
, reset_gpios
, MISC_REGISTERS_GPIO_OUTPUT_LOW
);
9592 bnx2x_set_mult_gpio(bp
, reset_gpios
, MISC_REGISTERS_GPIO_OUTPUT_HIGH
);
9594 DP(NETIF_MSG_LINK
, "84833 reset pulse on pin values 0x%x\n",
9600 #define PHY84833_CONSTANT_LATENCY 1193
9601 static int bnx2x_848x3_config_init(struct bnx2x_phy
*phy
,
9602 struct link_params
*params
,
9603 struct link_vars
*vars
)
9605 struct bnx2x
*bp
= params
->bp
;
9606 u8 port
, initialize
= 1;
9609 u32 actual_phy_selection
, cms_enable
, idx
;
9614 if (!(CHIP_IS_E1(bp
)))
9617 port
= params
->port
;
9619 if (phy
->type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823
) {
9620 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_3
,
9621 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
9625 bnx2x_cl45_write(bp
, phy
,
9627 MDIO_PMA_REG_CTRL
, 0x8000);
9628 /* Bring PHY out of super isolate mode */
9629 bnx2x_cl45_read(bp
, phy
,
9631 MDIO_84833_TOP_CFG_XGPHY_STRAP1
, &val
);
9632 val
&= ~MDIO_84833_SUPER_ISOLATE
;
9633 bnx2x_cl45_write(bp
, phy
,
9635 MDIO_84833_TOP_CFG_XGPHY_STRAP1
, val
);
9638 bnx2x_wait_reset_complete(bp
, phy
, params
);
9640 /* Wait for GPHY to come out of reset */
9643 if (phy
->type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833
)
9644 bnx2x_84833_pair_swap_cfg(phy
, params
, vars
);
9647 * BCM84823 requires that XGXS links up first @ 10G for normal behavior
9649 temp
= vars
->line_speed
;
9650 vars
->line_speed
= SPEED_10000
;
9651 bnx2x_set_autoneg(¶ms
->phy
[INT_PHY
], params
, vars
, 0);
9652 bnx2x_program_serdes(¶ms
->phy
[INT_PHY
], params
, vars
);
9653 vars
->line_speed
= temp
;
9655 /* Set dual-media configuration according to configuration */
9657 bnx2x_cl45_read(bp
, phy
, MDIO_CTL_DEVAD
,
9658 MDIO_CTL_REG_84823_MEDIA
, &val
);
9659 val
&= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK
|
9660 MDIO_CTL_REG_84823_MEDIA_LINE_MASK
|
9661 MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN
|
9662 MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK
|
9663 MDIO_CTL_REG_84823_MEDIA_FIBER_1G
);
9665 if (CHIP_IS_E3(bp
)) {
9666 val
&= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK
|
9667 MDIO_CTL_REG_84823_MEDIA_LINE_MASK
);
9669 val
|= (MDIO_CTL_REG_84823_CTRL_MAC_XFI
|
9670 MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L
);
9673 actual_phy_selection
= bnx2x_phy_selection(params
);
9675 switch (actual_phy_selection
) {
9676 case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT
:
9677 /* Do nothing. Essentially this is like the priority copper */
9679 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY
:
9680 val
|= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER
;
9682 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY
:
9683 val
|= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER
;
9685 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY
:
9686 /* Do nothing here. The first PHY won't be initialized at all */
9688 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY
:
9689 val
|= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN
;
9693 if (params
->phy
[EXT_PHY2
].req_line_speed
== SPEED_1000
)
9694 val
|= MDIO_CTL_REG_84823_MEDIA_FIBER_1G
;
9696 bnx2x_cl45_write(bp
, phy
, MDIO_CTL_DEVAD
,
9697 MDIO_CTL_REG_84823_MEDIA
, val
);
9698 DP(NETIF_MSG_LINK
, "Multi_phy config = 0x%x, Media control = 0x%x\n",
9699 params
->multi_phy_config
, val
);
9702 if (params
->feature_config_flags
&
9703 FEATURE_CONFIG_AUTOGREEEN_ENABLED
) {
9704 /* Ensure that f/w is ready */
9705 for (idx
= 0; idx
< PHY84833_HDSHK_WAIT
; idx
++) {
9706 bnx2x_cl45_read(bp
, phy
, MDIO_CTL_DEVAD
,
9707 MDIO_84833_TOP_CFG_SCRATCH_REG2
, &val
);
9708 if (val
== PHY84833_CMD_OPEN_FOR_CMDS
)
9710 usleep_range(1000, 1000);
9712 if (idx
>= PHY84833_HDSHK_WAIT
) {
9713 DP(NETIF_MSG_LINK
, "AutogrEEEn: FW not ready.\n");
9717 /* Select EEE mode */
9718 bnx2x_cl45_write(bp
, phy
, MDIO_CTL_DEVAD
,
9719 MDIO_84833_TOP_CFG_SCRATCH_REG3
,
9722 /* Set Idle and Latency */
9723 bnx2x_cl45_write(bp
, phy
, MDIO_CTL_DEVAD
,
9724 MDIO_84833_TOP_CFG_SCRATCH_REG4
,
9725 PHY84833_CONSTANT_LATENCY
+ 1);
9727 bnx2x_cl45_write(bp
, phy
, MDIO_CTL_DEVAD
,
9728 MDIO_84833_TOP_CFG_DATA3_REG
,
9729 PHY84833_CONSTANT_LATENCY
+ 1);
9731 bnx2x_cl45_write(bp
, phy
, MDIO_CTL_DEVAD
,
9732 MDIO_84833_TOP_CFG_DATA4_REG
,
9733 PHY84833_CONSTANT_LATENCY
);
9735 /* Send EEE instruction to command register */
9736 bnx2x_cl45_write(bp
, phy
, MDIO_CTL_DEVAD
,
9737 MDIO_84833_TOP_CFG_SCRATCH_REG0
,
9738 PHY84833_DIAG_CMD_SET_EEE_MODE
);
9740 /* Ensure that the command has completed */
9741 for (idx
= 0; idx
< PHY84833_HDSHK_WAIT
; idx
++) {
9742 bnx2x_cl45_read(bp
, phy
, MDIO_CTL_DEVAD
,
9743 MDIO_84833_TOP_CFG_SCRATCH_REG2
, &val
);
9744 if ((val
== PHY84833_CMD_COMPLETE_PASS
) ||
9745 (val
== PHY84833_CMD_COMPLETE_ERROR
))
9747 usleep_range(1000, 1000);
9749 if ((idx
>= PHY84833_HDSHK_WAIT
) ||
9750 (val
== PHY84833_CMD_COMPLETE_ERROR
)) {
9751 DP(NETIF_MSG_LINK
, "AutogrEEEn: command failed.\n");
9755 /* Reset command handler */
9756 bnx2x_cl45_write(bp
, phy
, MDIO_CTL_DEVAD
,
9757 MDIO_84833_TOP_CFG_SCRATCH_REG2
,
9758 PHY84833_CMD_CLEAR_COMPLETE
);
9762 rc
= bnx2x_848xx_cmn_config_init(phy
, params
, vars
);
9764 bnx2x_save_848xx_spirom_version(phy
, params
);
9765 /* 84833 PHY has a better feature and doesn't need to support this. */
9766 if (phy
->type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823
) {
9767 cms_enable
= REG_RD(bp
, params
->shmem_base
+
9768 offsetof(struct shmem_region
,
9769 dev_info
.port_hw_config
[params
->port
].default_cfg
)) &
9770 PORT_HW_CFG_ENABLE_CMS_MASK
;
9772 bnx2x_cl45_read(bp
, phy
, MDIO_CTL_DEVAD
,
9773 MDIO_CTL_REG_84823_USER_CTRL_REG
, &val
);
9775 val
|= MDIO_CTL_REG_84823_USER_CTRL_CMS
;
9777 val
&= ~MDIO_CTL_REG_84823_USER_CTRL_CMS
;
9778 bnx2x_cl45_write(bp
, phy
, MDIO_CTL_DEVAD
,
9779 MDIO_CTL_REG_84823_USER_CTRL_REG
, val
);
9785 static u8
bnx2x_848xx_read_status(struct bnx2x_phy
*phy
,
9786 struct link_params
*params
,
9787 struct link_vars
*vars
)
9789 struct bnx2x
*bp
= params
->bp
;
9790 u16 val
, val1
, val2
;
9794 /* Check 10G-BaseT link status */
9795 /* Check PMD signal ok */
9796 bnx2x_cl45_read(bp
, phy
,
9797 MDIO_AN_DEVAD
, 0xFFFA, &val1
);
9798 bnx2x_cl45_read(bp
, phy
,
9799 MDIO_PMA_DEVAD
, MDIO_PMA_REG_8481_PMD_SIGNAL
,
9801 DP(NETIF_MSG_LINK
, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2
);
9803 /* Check link 10G */
9804 if (val2
& (1<<11)) {
9805 vars
->line_speed
= SPEED_10000
;
9806 vars
->duplex
= DUPLEX_FULL
;
9808 bnx2x_ext_phy_10G_an_resolve(bp
, phy
, vars
);
9809 } else { /* Check Legacy speed link */
9810 u16 legacy_status
, legacy_speed
;
9812 /* Enable expansion register 0x42 (Operation mode status) */
9813 bnx2x_cl45_write(bp
, phy
,
9815 MDIO_AN_REG_8481_EXPANSION_REG_ACCESS
, 0xf42);
9817 /* Get legacy speed operation status */
9818 bnx2x_cl45_read(bp
, phy
,
9820 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW
,
9823 DP(NETIF_MSG_LINK
, "Legacy speed status = 0x%x\n",
9825 link_up
= ((legacy_status
& (1<<11)) == (1<<11));
9827 legacy_speed
= (legacy_status
& (3<<9));
9828 if (legacy_speed
== (0<<9))
9829 vars
->line_speed
= SPEED_10
;
9830 else if (legacy_speed
== (1<<9))
9831 vars
->line_speed
= SPEED_100
;
9832 else if (legacy_speed
== (2<<9))
9833 vars
->line_speed
= SPEED_1000
;
9834 else /* Should not happen */
9835 vars
->line_speed
= 0;
9837 if (legacy_status
& (1<<8))
9838 vars
->duplex
= DUPLEX_FULL
;
9840 vars
->duplex
= DUPLEX_HALF
;
9843 "Link is up in %dMbps, is_duplex_full= %d\n",
9845 (vars
->duplex
== DUPLEX_FULL
));
9846 /* Check legacy speed AN resolution */
9847 bnx2x_cl45_read(bp
, phy
,
9849 MDIO_AN_REG_8481_LEGACY_MII_STATUS
,
9852 vars
->link_status
|=
9853 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE
;
9854 bnx2x_cl45_read(bp
, phy
,
9856 MDIO_AN_REG_8481_LEGACY_AN_EXPANSION
,
9858 if ((val
& (1<<0)) == 0)
9859 vars
->link_status
|=
9860 LINK_STATUS_PARALLEL_DETECTION_USED
;
9864 DP(NETIF_MSG_LINK
, "BCM84823: link speed is %d\n",
9866 bnx2x_ext_phy_resolve_fc(phy
, params
, vars
);
9873 static int bnx2x_848xx_format_ver(u32 raw_ver
, u8
*str
, u16
*len
)
9877 spirom_ver
= ((raw_ver
& 0xF80) >> 7) << 16 | (raw_ver
& 0x7F);
9878 status
= bnx2x_format_ver(spirom_ver
, str
, len
);
9882 static void bnx2x_8481_hw_reset(struct bnx2x_phy
*phy
,
9883 struct link_params
*params
)
9885 bnx2x_set_gpio(params
->bp
, MISC_REGISTERS_GPIO_1
,
9886 MISC_REGISTERS_GPIO_OUTPUT_LOW
, 0);
9887 bnx2x_set_gpio(params
->bp
, MISC_REGISTERS_GPIO_1
,
9888 MISC_REGISTERS_GPIO_OUTPUT_LOW
, 1);
9891 static void bnx2x_8481_link_reset(struct bnx2x_phy
*phy
,
9892 struct link_params
*params
)
9894 bnx2x_cl45_write(params
->bp
, phy
,
9895 MDIO_AN_DEVAD
, MDIO_AN_REG_CTRL
, 0x0000);
9896 bnx2x_cl45_write(params
->bp
, phy
,
9897 MDIO_PMA_DEVAD
, MDIO_PMA_REG_CTRL
, 1);
9900 static void bnx2x_848x3_link_reset(struct bnx2x_phy
*phy
,
9901 struct link_params
*params
)
9903 struct bnx2x
*bp
= params
->bp
;
9907 if (!(CHIP_IS_E1(bp
)))
9910 port
= params
->port
;
9912 if (phy
->type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823
) {
9913 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_3
,
9914 MISC_REGISTERS_GPIO_OUTPUT_LOW
,
9917 bnx2x_cl45_read(bp
, phy
,
9920 bnx2x_cl45_write(bp
, phy
,
9922 MDIO_PMA_REG_CTRL
, 0x800);
9926 static void bnx2x_848xx_set_link_led(struct bnx2x_phy
*phy
,
9927 struct link_params
*params
, u8 mode
)
9929 struct bnx2x
*bp
= params
->bp
;
9933 if (!(CHIP_IS_E1(bp
)))
9936 port
= params
->port
;
9941 DP(NETIF_MSG_LINK
, "Port 0x%x: LED MODE OFF\n", port
);
9943 if ((params
->hw_led_mode
<< SHARED_HW_CFG_LED_MODE_SHIFT
) ==
9944 SHARED_HW_CFG_LED_EXTPHY1
) {
9947 bnx2x_cl45_write(bp
, phy
,
9949 MDIO_PMA_REG_8481_LED1_MASK
,
9952 bnx2x_cl45_write(bp
, phy
,
9954 MDIO_PMA_REG_8481_LED2_MASK
,
9957 bnx2x_cl45_write(bp
, phy
,
9959 MDIO_PMA_REG_8481_LED3_MASK
,
9962 bnx2x_cl45_write(bp
, phy
,
9964 MDIO_PMA_REG_8481_LED5_MASK
,
9968 bnx2x_cl45_write(bp
, phy
,
9970 MDIO_PMA_REG_8481_LED1_MASK
,
9974 case LED_MODE_FRONT_PANEL_OFF
:
9976 DP(NETIF_MSG_LINK
, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
9979 if ((params
->hw_led_mode
<< SHARED_HW_CFG_LED_MODE_SHIFT
) ==
9980 SHARED_HW_CFG_LED_EXTPHY1
) {
9983 bnx2x_cl45_write(bp
, phy
,
9985 MDIO_PMA_REG_8481_LED1_MASK
,
9988 bnx2x_cl45_write(bp
, phy
,
9990 MDIO_PMA_REG_8481_LED2_MASK
,
9993 bnx2x_cl45_write(bp
, phy
,
9995 MDIO_PMA_REG_8481_LED3_MASK
,
9998 bnx2x_cl45_write(bp
, phy
,
10000 MDIO_PMA_REG_8481_LED5_MASK
,
10004 bnx2x_cl45_write(bp
, phy
,
10006 MDIO_PMA_REG_8481_LED1_MASK
,
10012 DP(NETIF_MSG_LINK
, "Port 0x%x: LED MODE ON\n", port
);
10014 if ((params
->hw_led_mode
<< SHARED_HW_CFG_LED_MODE_SHIFT
) ==
10015 SHARED_HW_CFG_LED_EXTPHY1
) {
10016 /* Set control reg */
10017 bnx2x_cl45_read(bp
, phy
,
10019 MDIO_PMA_REG_8481_LINK_SIGNAL
,
10024 bnx2x_cl45_write(bp
, phy
,
10026 MDIO_PMA_REG_8481_LINK_SIGNAL
,
10029 /* Set LED masks */
10030 bnx2x_cl45_write(bp
, phy
,
10032 MDIO_PMA_REG_8481_LED1_MASK
,
10035 bnx2x_cl45_write(bp
, phy
,
10037 MDIO_PMA_REG_8481_LED2_MASK
,
10040 bnx2x_cl45_write(bp
, phy
,
10042 MDIO_PMA_REG_8481_LED3_MASK
,
10045 bnx2x_cl45_write(bp
, phy
,
10047 MDIO_PMA_REG_8481_LED5_MASK
,
10050 bnx2x_cl45_write(bp
, phy
,
10052 MDIO_PMA_REG_8481_LED1_MASK
,
10057 case LED_MODE_OPER
:
10059 DP(NETIF_MSG_LINK
, "Port 0x%x: LED MODE OPER\n", port
);
10061 if ((params
->hw_led_mode
<< SHARED_HW_CFG_LED_MODE_SHIFT
) ==
10062 SHARED_HW_CFG_LED_EXTPHY1
) {
10064 /* Set control reg */
10065 bnx2x_cl45_read(bp
, phy
,
10067 MDIO_PMA_REG_8481_LINK_SIGNAL
,
10071 MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK
)
10072 >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT
)) {
10073 DP(NETIF_MSG_LINK
, "Setting LINK_SIGNAL\n");
10074 bnx2x_cl45_write(bp
, phy
,
10076 MDIO_PMA_REG_8481_LINK_SIGNAL
,
10080 /* Set LED masks */
10081 bnx2x_cl45_write(bp
, phy
,
10083 MDIO_PMA_REG_8481_LED1_MASK
,
10086 bnx2x_cl45_write(bp
, phy
,
10088 MDIO_PMA_REG_8481_LED2_MASK
,
10091 bnx2x_cl45_write(bp
, phy
,
10093 MDIO_PMA_REG_8481_LED3_MASK
,
10096 bnx2x_cl45_write(bp
, phy
,
10098 MDIO_PMA_REG_8481_LED5_MASK
,
10102 bnx2x_cl45_write(bp
, phy
,
10104 MDIO_PMA_REG_8481_LED1_MASK
,
10107 /* Tell LED3 to blink on source */
10108 bnx2x_cl45_read(bp
, phy
,
10110 MDIO_PMA_REG_8481_LINK_SIGNAL
,
10113 val
|= (1<<6); /* A83B[8:6]= 1 */
10114 bnx2x_cl45_write(bp
, phy
,
10116 MDIO_PMA_REG_8481_LINK_SIGNAL
,
10123 * This is a workaround for E3+84833 until autoneg
10124 * restart is fixed in f/w
10126 if (CHIP_IS_E3(bp
)) {
10127 bnx2x_cl45_read(bp
, phy
, MDIO_WC_DEVAD
,
10128 MDIO_WC_REG_GP2_STATUS_GP_2_1
, &val
);
10132 /******************************************************************/
10133 /* 54618SE PHY SECTION */
10134 /******************************************************************/
10135 static int bnx2x_54618se_config_init(struct bnx2x_phy
*phy
,
10136 struct link_params
*params
,
10137 struct link_vars
*vars
)
10139 struct bnx2x
*bp
= params
->bp
;
10141 u16 autoneg_val
, an_1000_val
, an_10_100_val
, fc_val
, temp
;
10144 DP(NETIF_MSG_LINK
, "54618SE cfg init\n");
10145 usleep_range(1000, 1000);
10147 /* This works with E3 only, no need to check the chip
10148 before determining the port. */
10149 port
= params
->port
;
10151 cfg_pin
= (REG_RD(bp
, params
->shmem_base
+
10152 offsetof(struct shmem_region
,
10153 dev_info
.port_hw_config
[port
].e3_cmn_pin_cfg
)) &
10154 PORT_HW_CFG_E3_PHY_RESET_MASK
) >>
10155 PORT_HW_CFG_E3_PHY_RESET_SHIFT
;
10157 /* Drive pin high to bring the GPHY out of reset. */
10158 bnx2x_set_cfg_pin(bp
, cfg_pin
, 1);
10160 /* wait for GPHY to reset */
10164 bnx2x_cl22_write(bp
, phy
,
10165 MDIO_PMA_REG_CTRL
, 0x8000);
10166 bnx2x_wait_reset_complete(bp
, phy
, params
);
10168 /*wait for GPHY to reset */
10171 /* Configure LED4: set to INTR (0x6). */
10172 /* Accessing shadow register 0xe. */
10173 bnx2x_cl22_write(bp
, phy
,
10174 MDIO_REG_GPHY_SHADOW
,
10175 MDIO_REG_GPHY_SHADOW_LED_SEL2
);
10176 bnx2x_cl22_read(bp
, phy
,
10177 MDIO_REG_GPHY_SHADOW
,
10179 temp
&= ~(0xf << 4);
10180 temp
|= (0x6 << 4);
10181 bnx2x_cl22_write(bp
, phy
,
10182 MDIO_REG_GPHY_SHADOW
,
10183 MDIO_REG_GPHY_SHADOW_WR_ENA
| temp
);
10184 /* Configure INTR based on link status change. */
10185 bnx2x_cl22_write(bp
, phy
,
10186 MDIO_REG_INTR_MASK
,
10187 ~MDIO_REG_INTR_MASK_LINK_STATUS
);
10189 /* Flip the signal detect polarity (set 0x1c.0x1e[8]). */
10190 bnx2x_cl22_write(bp
, phy
,
10191 MDIO_REG_GPHY_SHADOW
,
10192 MDIO_REG_GPHY_SHADOW_AUTO_DET_MED
);
10193 bnx2x_cl22_read(bp
, phy
,
10194 MDIO_REG_GPHY_SHADOW
,
10196 temp
|= MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD
;
10197 bnx2x_cl22_write(bp
, phy
,
10198 MDIO_REG_GPHY_SHADOW
,
10199 MDIO_REG_GPHY_SHADOW_WR_ENA
| temp
);
10202 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
10203 bnx2x_calc_ieee_aneg_adv(phy
, params
, &vars
->ieee_fc
);
10205 if ((vars
->ieee_fc
& MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
) ==
10206 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC
)
10207 fc_val
|= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC
;
10209 if ((vars
->ieee_fc
& MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
) ==
10210 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH
)
10211 fc_val
|= MDIO_AN_REG_ADV_PAUSE_PAUSE
;
10213 /* read all advertisement */
10214 bnx2x_cl22_read(bp
, phy
,
10218 bnx2x_cl22_read(bp
, phy
,
10222 bnx2x_cl22_read(bp
, phy
,
10226 /* Disable forced speed */
10227 autoneg_val
&= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
10228 an_10_100_val
&= ~((1<<5) | (1<<6) | (1<<7) | (1<<8) | (1<<10) |
10231 if (((phy
->req_line_speed
== SPEED_AUTO_NEG
) &&
10232 (phy
->speed_cap_mask
&
10233 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G
)) ||
10234 (phy
->req_line_speed
== SPEED_1000
)) {
10235 an_1000_val
|= (1<<8);
10236 autoneg_val
|= (1<<9 | 1<<12);
10237 if (phy
->req_duplex
== DUPLEX_FULL
)
10238 an_1000_val
|= (1<<9);
10239 DP(NETIF_MSG_LINK
, "Advertising 1G\n");
10241 an_1000_val
&= ~((1<<8) | (1<<9));
10243 bnx2x_cl22_write(bp
, phy
,
10246 bnx2x_cl22_read(bp
, phy
,
10250 /* set 100 speed advertisement */
10251 if (((phy
->req_line_speed
== SPEED_AUTO_NEG
) &&
10252 (phy
->speed_cap_mask
&
10253 (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL
|
10254 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF
)))) {
10255 an_10_100_val
|= (1<<7);
10256 /* Enable autoneg and restart autoneg for legacy speeds */
10257 autoneg_val
|= (1<<9 | 1<<12);
10259 if (phy
->req_duplex
== DUPLEX_FULL
)
10260 an_10_100_val
|= (1<<8);
10261 DP(NETIF_MSG_LINK
, "Advertising 100M\n");
10264 /* set 10 speed advertisement */
10265 if (((phy
->req_line_speed
== SPEED_AUTO_NEG
) &&
10266 (phy
->speed_cap_mask
&
10267 (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL
|
10268 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF
)))) {
10269 an_10_100_val
|= (1<<5);
10270 autoneg_val
|= (1<<9 | 1<<12);
10271 if (phy
->req_duplex
== DUPLEX_FULL
)
10272 an_10_100_val
|= (1<<6);
10273 DP(NETIF_MSG_LINK
, "Advertising 10M\n");
10276 /* Only 10/100 are allowed to work in FORCE mode */
10277 if (phy
->req_line_speed
== SPEED_100
) {
10278 autoneg_val
|= (1<<13);
10279 /* Enabled AUTO-MDIX when autoneg is disabled */
10280 bnx2x_cl22_write(bp
, phy
,
10282 (1<<15 | 1<<9 | 7<<0));
10283 DP(NETIF_MSG_LINK
, "Setting 100M force\n");
10285 if (phy
->req_line_speed
== SPEED_10
) {
10286 /* Enabled AUTO-MDIX when autoneg is disabled */
10287 bnx2x_cl22_write(bp
, phy
,
10289 (1<<15 | 1<<9 | 7<<0));
10290 DP(NETIF_MSG_LINK
, "Setting 10M force\n");
10293 /* Check if we should turn on Auto-GrEEEn */
10294 bnx2x_cl22_read(bp
, phy
, MDIO_REG_GPHY_PHYID_LSB
, &temp
);
10295 if (temp
== MDIO_REG_GPHY_ID_54618SE
) {
10296 if (params
->feature_config_flags
&
10297 FEATURE_CONFIG_AUTOGREEEN_ENABLED
) {
10299 DP(NETIF_MSG_LINK
, "Enabling Auto-GrEEEn\n");
10302 DP(NETIF_MSG_LINK
, "Disabling Auto-GrEEEn\n");
10304 bnx2x_cl22_write(bp
, phy
,
10305 MDIO_REG_GPHY_CL45_ADDR_REG
, MDIO_AN_DEVAD
);
10306 bnx2x_cl22_write(bp
, phy
,
10307 MDIO_REG_GPHY_CL45_DATA_REG
,
10308 MDIO_REG_GPHY_EEE_ADV
);
10309 bnx2x_cl22_write(bp
, phy
,
10310 MDIO_REG_GPHY_CL45_ADDR_REG
,
10311 (0x1 << 14) | MDIO_AN_DEVAD
);
10312 bnx2x_cl22_write(bp
, phy
,
10313 MDIO_REG_GPHY_CL45_DATA_REG
,
10317 bnx2x_cl22_write(bp
, phy
,
10319 an_10_100_val
| fc_val
);
10321 if (phy
->req_duplex
== DUPLEX_FULL
)
10322 autoneg_val
|= (1<<8);
10324 bnx2x_cl22_write(bp
, phy
,
10325 MDIO_PMA_REG_CTRL
, autoneg_val
);
10330 static void bnx2x_54618se_link_reset(struct bnx2x_phy
*phy
,
10331 struct link_params
*params
)
10333 struct bnx2x
*bp
= params
->bp
;
10338 * In case of no EPIO routed to reset the GPHY, put it
10339 * in low power mode.
10341 bnx2x_cl22_write(bp
, phy
, MDIO_PMA_REG_CTRL
, 0x800);
10343 * This works with E3 only, no need to check the chip
10344 * before determining the port.
10346 port
= params
->port
;
10347 cfg_pin
= (REG_RD(bp
, params
->shmem_base
+
10348 offsetof(struct shmem_region
,
10349 dev_info
.port_hw_config
[port
].e3_cmn_pin_cfg
)) &
10350 PORT_HW_CFG_E3_PHY_RESET_MASK
) >>
10351 PORT_HW_CFG_E3_PHY_RESET_SHIFT
;
10353 /* Drive pin low to put GPHY in reset. */
10354 bnx2x_set_cfg_pin(bp
, cfg_pin
, 0);
10357 static u8
bnx2x_54618se_read_status(struct bnx2x_phy
*phy
,
10358 struct link_params
*params
,
10359 struct link_vars
*vars
)
10361 struct bnx2x
*bp
= params
->bp
;
10364 u16 legacy_status
, legacy_speed
;
10366 /* Get speed operation status */
10367 bnx2x_cl22_read(bp
, phy
,
10370 DP(NETIF_MSG_LINK
, "54618SE read_status: 0x%x\n", legacy_status
);
10372 /* Read status to clear the PHY interrupt. */
10373 bnx2x_cl22_read(bp
, phy
,
10374 MDIO_REG_INTR_STATUS
,
10377 link_up
= ((legacy_status
& (1<<2)) == (1<<2));
10380 legacy_speed
= (legacy_status
& (7<<8));
10381 if (legacy_speed
== (7<<8)) {
10382 vars
->line_speed
= SPEED_1000
;
10383 vars
->duplex
= DUPLEX_FULL
;
10384 } else if (legacy_speed
== (6<<8)) {
10385 vars
->line_speed
= SPEED_1000
;
10386 vars
->duplex
= DUPLEX_HALF
;
10387 } else if (legacy_speed
== (5<<8)) {
10388 vars
->line_speed
= SPEED_100
;
10389 vars
->duplex
= DUPLEX_FULL
;
10391 /* Omitting 100Base-T4 for now */
10392 else if (legacy_speed
== (3<<8)) {
10393 vars
->line_speed
= SPEED_100
;
10394 vars
->duplex
= DUPLEX_HALF
;
10395 } else if (legacy_speed
== (2<<8)) {
10396 vars
->line_speed
= SPEED_10
;
10397 vars
->duplex
= DUPLEX_FULL
;
10398 } else if (legacy_speed
== (1<<8)) {
10399 vars
->line_speed
= SPEED_10
;
10400 vars
->duplex
= DUPLEX_HALF
;
10401 } else /* Should not happen */
10402 vars
->line_speed
= 0;
10405 "Link is up in %dMbps, is_duplex_full= %d\n",
10407 (vars
->duplex
== DUPLEX_FULL
));
10409 /* Check legacy speed AN resolution */
10410 bnx2x_cl22_read(bp
, phy
,
10414 vars
->link_status
|=
10415 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE
;
10416 bnx2x_cl22_read(bp
, phy
,
10419 if ((val
& (1<<0)) == 0)
10420 vars
->link_status
|=
10421 LINK_STATUS_PARALLEL_DETECTION_USED
;
10423 DP(NETIF_MSG_LINK
, "BCM54618SE: link speed is %d\n",
10426 /* Report whether EEE is resolved. */
10427 bnx2x_cl22_read(bp
, phy
, MDIO_REG_GPHY_PHYID_LSB
, &val
);
10428 if (val
== MDIO_REG_GPHY_ID_54618SE
) {
10429 if (vars
->link_status
&
10430 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE
)
10433 bnx2x_cl22_write(bp
, phy
,
10434 MDIO_REG_GPHY_CL45_ADDR_REG
,
10436 bnx2x_cl22_write(bp
, phy
,
10437 MDIO_REG_GPHY_CL45_DATA_REG
,
10438 MDIO_REG_GPHY_EEE_RESOLVED
);
10439 bnx2x_cl22_write(bp
, phy
,
10440 MDIO_REG_GPHY_CL45_ADDR_REG
,
10441 (0x1 << 14) | MDIO_AN_DEVAD
);
10442 bnx2x_cl22_read(bp
, phy
,
10443 MDIO_REG_GPHY_CL45_DATA_REG
,
10446 DP(NETIF_MSG_LINK
, "EEE resolution: 0x%x\n", val
);
10449 bnx2x_ext_phy_resolve_fc(phy
, params
, vars
);
10454 static void bnx2x_54618se_config_loopback(struct bnx2x_phy
*phy
,
10455 struct link_params
*params
)
10457 struct bnx2x
*bp
= params
->bp
;
10459 u32 umac_base
= params
->port
? GRCBASE_UMAC1
: GRCBASE_UMAC0
;
10461 DP(NETIF_MSG_LINK
, "2PMA/PMD ext_phy_loopback: 54618se\n");
10463 /* Enable master/slave manual mmode and set to master */
10464 /* mii write 9 [bits set 11 12] */
10465 bnx2x_cl22_write(bp
, phy
, 0x09, 3<<11);
10467 /* forced 1G and disable autoneg */
10468 /* set val [mii read 0] */
10469 /* set val [expr $val & [bits clear 6 12 13]] */
10470 /* set val [expr $val | [bits set 6 8]] */
10471 /* mii write 0 $val */
10472 bnx2x_cl22_read(bp
, phy
, 0x00, &val
);
10473 val
&= ~((1<<6) | (1<<12) | (1<<13));
10474 val
|= (1<<6) | (1<<8);
10475 bnx2x_cl22_write(bp
, phy
, 0x00, val
);
10477 /* Set external loopback and Tx using 6dB coding */
10478 /* mii write 0x18 7 */
10479 /* set val [mii read 0x18] */
10480 /* mii write 0x18 [expr $val | [bits set 10 15]] */
10481 bnx2x_cl22_write(bp
, phy
, 0x18, 7);
10482 bnx2x_cl22_read(bp
, phy
, 0x18, &val
);
10483 bnx2x_cl22_write(bp
, phy
, 0x18, val
| (1<<10) | (1<<15));
10485 /* This register opens the gate for the UMAC despite its name */
10486 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_PORT
+ params
->port
*4, 1);
10489 * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
10490 * length used by the MAC receive logic to check frames.
10492 REG_WR(bp
, umac_base
+ UMAC_REG_MAXFR
, 0x2710);
10495 /******************************************************************/
10496 /* SFX7101 PHY SECTION */
10497 /******************************************************************/
10498 static void bnx2x_7101_config_loopback(struct bnx2x_phy
*phy
,
10499 struct link_params
*params
)
10501 struct bnx2x
*bp
= params
->bp
;
10502 /* SFX7101_XGXS_TEST1 */
10503 bnx2x_cl45_write(bp
, phy
,
10504 MDIO_XS_DEVAD
, MDIO_XS_SFX7101_XGXS_TEST1
, 0x100);
10507 static int bnx2x_7101_config_init(struct bnx2x_phy
*phy
,
10508 struct link_params
*params
,
10509 struct link_vars
*vars
)
10511 u16 fw_ver1
, fw_ver2
, val
;
10512 struct bnx2x
*bp
= params
->bp
;
10513 DP(NETIF_MSG_LINK
, "Setting the SFX7101 LASI indication\n");
10515 /* Restore normal power mode*/
10516 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
10517 MISC_REGISTERS_GPIO_OUTPUT_HIGH
, params
->port
);
10519 bnx2x_ext_phy_hw_reset(bp
, params
->port
);
10520 bnx2x_wait_reset_complete(bp
, phy
, params
);
10522 bnx2x_cl45_write(bp
, phy
,
10523 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_CTRL
, 0x1);
10524 DP(NETIF_MSG_LINK
, "Setting the SFX7101 LED to blink on traffic\n");
10525 bnx2x_cl45_write(bp
, phy
,
10526 MDIO_PMA_DEVAD
, MDIO_PMA_REG_7107_LED_CNTL
, (1<<3));
10528 bnx2x_ext_phy_set_pause(params
, phy
, vars
);
10529 /* Restart autoneg */
10530 bnx2x_cl45_read(bp
, phy
,
10531 MDIO_AN_DEVAD
, MDIO_AN_REG_CTRL
, &val
);
10533 bnx2x_cl45_write(bp
, phy
,
10534 MDIO_AN_DEVAD
, MDIO_AN_REG_CTRL
, val
);
10536 /* Save spirom version */
10537 bnx2x_cl45_read(bp
, phy
,
10538 MDIO_PMA_DEVAD
, MDIO_PMA_REG_7101_VER1
, &fw_ver1
);
10540 bnx2x_cl45_read(bp
, phy
,
10541 MDIO_PMA_DEVAD
, MDIO_PMA_REG_7101_VER2
, &fw_ver2
);
10542 bnx2x_save_spirom_version(bp
, params
->port
,
10543 (u32
)(fw_ver1
<<16 | fw_ver2
), phy
->ver_addr
);
10547 static u8
bnx2x_7101_read_status(struct bnx2x_phy
*phy
,
10548 struct link_params
*params
,
10549 struct link_vars
*vars
)
10551 struct bnx2x
*bp
= params
->bp
;
10554 bnx2x_cl45_read(bp
, phy
,
10555 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_STAT
, &val2
);
10556 bnx2x_cl45_read(bp
, phy
,
10557 MDIO_PMA_DEVAD
, MDIO_PMA_LASI_STAT
, &val1
);
10558 DP(NETIF_MSG_LINK
, "10G-base-T LASI status 0x%x->0x%x\n",
10560 bnx2x_cl45_read(bp
, phy
,
10561 MDIO_PMA_DEVAD
, MDIO_PMA_REG_STATUS
, &val2
);
10562 bnx2x_cl45_read(bp
, phy
,
10563 MDIO_PMA_DEVAD
, MDIO_PMA_REG_STATUS
, &val1
);
10564 DP(NETIF_MSG_LINK
, "10G-base-T PMA status 0x%x->0x%x\n",
10566 link_up
= ((val1
& 4) == 4);
10567 /* if link is up print the AN outcome of the SFX7101 PHY */
10569 bnx2x_cl45_read(bp
, phy
,
10570 MDIO_AN_DEVAD
, MDIO_AN_REG_MASTER_STATUS
,
10572 vars
->line_speed
= SPEED_10000
;
10573 vars
->duplex
= DUPLEX_FULL
;
10574 DP(NETIF_MSG_LINK
, "SFX7101 AN status 0x%x->Master=%x\n",
10575 val2
, (val2
& (1<<14)));
10576 bnx2x_ext_phy_10G_an_resolve(bp
, phy
, vars
);
10577 bnx2x_ext_phy_resolve_fc(phy
, params
, vars
);
10582 static int bnx2x_7101_format_ver(u32 spirom_ver
, u8
*str
, u16
*len
)
10586 str
[0] = (spirom_ver
& 0xFF);
10587 str
[1] = (spirom_ver
& 0xFF00) >> 8;
10588 str
[2] = (spirom_ver
& 0xFF0000) >> 16;
10589 str
[3] = (spirom_ver
& 0xFF000000) >> 24;
10595 void bnx2x_sfx7101_sp_sw_reset(struct bnx2x
*bp
, struct bnx2x_phy
*phy
)
10599 bnx2x_cl45_read(bp
, phy
,
10601 MDIO_PMA_REG_7101_RESET
, &val
);
10603 for (cnt
= 0; cnt
< 10; cnt
++) {
10605 /* Writes a self-clearing reset */
10606 bnx2x_cl45_write(bp
, phy
,
10608 MDIO_PMA_REG_7101_RESET
,
10610 /* Wait for clear */
10611 bnx2x_cl45_read(bp
, phy
,
10613 MDIO_PMA_REG_7101_RESET
, &val
);
10615 if ((val
& (1<<15)) == 0)
10620 static void bnx2x_7101_hw_reset(struct bnx2x_phy
*phy
,
10621 struct link_params
*params
) {
10622 /* Low power mode is controlled by GPIO 2 */
10623 bnx2x_set_gpio(params
->bp
, MISC_REGISTERS_GPIO_2
,
10624 MISC_REGISTERS_GPIO_OUTPUT_LOW
, params
->port
);
10625 /* The PHY reset is controlled by GPIO 1 */
10626 bnx2x_set_gpio(params
->bp
, MISC_REGISTERS_GPIO_1
,
10627 MISC_REGISTERS_GPIO_OUTPUT_LOW
, params
->port
);
10630 static void bnx2x_7101_set_link_led(struct bnx2x_phy
*phy
,
10631 struct link_params
*params
, u8 mode
)
10634 struct bnx2x
*bp
= params
->bp
;
10636 case LED_MODE_FRONT_PANEL_OFF
:
10643 case LED_MODE_OPER
:
10647 bnx2x_cl45_write(bp
, phy
,
10649 MDIO_PMA_REG_7107_LINK_LED_CNTL
,
10653 /******************************************************************/
10654 /* STATIC PHY DECLARATION */
10655 /******************************************************************/
10657 static struct bnx2x_phy phy_null
= {
10658 .type
= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
,
10661 .flags
= FLAGS_INIT_XGXS_FIRST
,
10662 .rx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10663 .tx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10666 .media_type
= ETH_PHY_NOT_PRESENT
,
10668 .req_flow_ctrl
= 0,
10669 .req_line_speed
= 0,
10670 .speed_cap_mask
= 0,
10673 .config_init
= (config_init_t
)NULL
,
10674 .read_status
= (read_status_t
)NULL
,
10675 .link_reset
= (link_reset_t
)NULL
,
10676 .config_loopback
= (config_loopback_t
)NULL
,
10677 .format_fw_ver
= (format_fw_ver_t
)NULL
,
10678 .hw_reset
= (hw_reset_t
)NULL
,
10679 .set_link_led
= (set_link_led_t
)NULL
,
10680 .phy_specific_func
= (phy_specific_func_t
)NULL
10683 static struct bnx2x_phy phy_serdes
= {
10684 .type
= PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT
,
10688 .rx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10689 .tx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10691 .supported
= (SUPPORTED_10baseT_Half
|
10692 SUPPORTED_10baseT_Full
|
10693 SUPPORTED_100baseT_Half
|
10694 SUPPORTED_100baseT_Full
|
10695 SUPPORTED_1000baseT_Full
|
10696 SUPPORTED_2500baseX_Full
|
10698 SUPPORTED_Autoneg
|
10700 SUPPORTED_Asym_Pause
),
10701 .media_type
= ETH_PHY_BASE_T
,
10703 .req_flow_ctrl
= 0,
10704 .req_line_speed
= 0,
10705 .speed_cap_mask
= 0,
10708 .config_init
= (config_init_t
)bnx2x_xgxs_config_init
,
10709 .read_status
= (read_status_t
)bnx2x_link_settings_status
,
10710 .link_reset
= (link_reset_t
)bnx2x_int_link_reset
,
10711 .config_loopback
= (config_loopback_t
)NULL
,
10712 .format_fw_ver
= (format_fw_ver_t
)NULL
,
10713 .hw_reset
= (hw_reset_t
)NULL
,
10714 .set_link_led
= (set_link_led_t
)NULL
,
10715 .phy_specific_func
= (phy_specific_func_t
)NULL
10718 static struct bnx2x_phy phy_xgxs
= {
10719 .type
= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
,
10723 .rx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10724 .tx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10726 .supported
= (SUPPORTED_10baseT_Half
|
10727 SUPPORTED_10baseT_Full
|
10728 SUPPORTED_100baseT_Half
|
10729 SUPPORTED_100baseT_Full
|
10730 SUPPORTED_1000baseT_Full
|
10731 SUPPORTED_2500baseX_Full
|
10732 SUPPORTED_10000baseT_Full
|
10734 SUPPORTED_Autoneg
|
10736 SUPPORTED_Asym_Pause
),
10737 .media_type
= ETH_PHY_CX4
,
10739 .req_flow_ctrl
= 0,
10740 .req_line_speed
= 0,
10741 .speed_cap_mask
= 0,
10744 .config_init
= (config_init_t
)bnx2x_xgxs_config_init
,
10745 .read_status
= (read_status_t
)bnx2x_link_settings_status
,
10746 .link_reset
= (link_reset_t
)bnx2x_int_link_reset
,
10747 .config_loopback
= (config_loopback_t
)bnx2x_set_xgxs_loopback
,
10748 .format_fw_ver
= (format_fw_ver_t
)NULL
,
10749 .hw_reset
= (hw_reset_t
)NULL
,
10750 .set_link_led
= (set_link_led_t
)NULL
,
10751 .phy_specific_func
= (phy_specific_func_t
)NULL
10753 static struct bnx2x_phy phy_warpcore
= {
10754 .type
= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT
,
10757 .flags
= FLAGS_HW_LOCK_REQUIRED
,
10758 .rx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10759 .tx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10761 .supported
= (SUPPORTED_10baseT_Half
|
10762 SUPPORTED_10baseT_Full
|
10763 SUPPORTED_100baseT_Half
|
10764 SUPPORTED_100baseT_Full
|
10765 SUPPORTED_1000baseT_Full
|
10766 SUPPORTED_10000baseT_Full
|
10767 SUPPORTED_20000baseKR2_Full
|
10768 SUPPORTED_20000baseMLD2_Full
|
10770 SUPPORTED_Autoneg
|
10772 SUPPORTED_Asym_Pause
),
10773 .media_type
= ETH_PHY_UNSPECIFIED
,
10775 .req_flow_ctrl
= 0,
10776 .req_line_speed
= 0,
10777 .speed_cap_mask
= 0,
10778 /* req_duplex = */0,
10780 .config_init
= (config_init_t
)bnx2x_warpcore_config_init
,
10781 .read_status
= (read_status_t
)bnx2x_warpcore_read_status
,
10782 .link_reset
= (link_reset_t
)bnx2x_warpcore_link_reset
,
10783 .config_loopback
= (config_loopback_t
)bnx2x_set_warpcore_loopback
,
10784 .format_fw_ver
= (format_fw_ver_t
)NULL
,
10785 .hw_reset
= (hw_reset_t
)bnx2x_warpcore_hw_reset
,
10786 .set_link_led
= (set_link_led_t
)NULL
,
10787 .phy_specific_func
= (phy_specific_func_t
)NULL
10791 static struct bnx2x_phy phy_7101
= {
10792 .type
= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
,
10795 .flags
= FLAGS_FAN_FAILURE_DET_REQ
,
10796 .rx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10797 .tx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10799 .supported
= (SUPPORTED_10000baseT_Full
|
10801 SUPPORTED_Autoneg
|
10803 SUPPORTED_Asym_Pause
),
10804 .media_type
= ETH_PHY_BASE_T
,
10806 .req_flow_ctrl
= 0,
10807 .req_line_speed
= 0,
10808 .speed_cap_mask
= 0,
10811 .config_init
= (config_init_t
)bnx2x_7101_config_init
,
10812 .read_status
= (read_status_t
)bnx2x_7101_read_status
,
10813 .link_reset
= (link_reset_t
)bnx2x_common_ext_link_reset
,
10814 .config_loopback
= (config_loopback_t
)bnx2x_7101_config_loopback
,
10815 .format_fw_ver
= (format_fw_ver_t
)bnx2x_7101_format_ver
,
10816 .hw_reset
= (hw_reset_t
)bnx2x_7101_hw_reset
,
10817 .set_link_led
= (set_link_led_t
)bnx2x_7101_set_link_led
,
10818 .phy_specific_func
= (phy_specific_func_t
)NULL
10820 static struct bnx2x_phy phy_8073
= {
10821 .type
= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
,
10824 .flags
= FLAGS_HW_LOCK_REQUIRED
,
10825 .rx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10826 .tx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10828 .supported
= (SUPPORTED_10000baseT_Full
|
10829 SUPPORTED_2500baseX_Full
|
10830 SUPPORTED_1000baseT_Full
|
10832 SUPPORTED_Autoneg
|
10834 SUPPORTED_Asym_Pause
),
10835 .media_type
= ETH_PHY_KR
,
10837 .req_flow_ctrl
= 0,
10838 .req_line_speed
= 0,
10839 .speed_cap_mask
= 0,
10842 .config_init
= (config_init_t
)bnx2x_8073_config_init
,
10843 .read_status
= (read_status_t
)bnx2x_8073_read_status
,
10844 .link_reset
= (link_reset_t
)bnx2x_8073_link_reset
,
10845 .config_loopback
= (config_loopback_t
)NULL
,
10846 .format_fw_ver
= (format_fw_ver_t
)bnx2x_format_ver
,
10847 .hw_reset
= (hw_reset_t
)NULL
,
10848 .set_link_led
= (set_link_led_t
)NULL
,
10849 .phy_specific_func
= (phy_specific_func_t
)NULL
10851 static struct bnx2x_phy phy_8705
= {
10852 .type
= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
,
10855 .flags
= FLAGS_INIT_XGXS_FIRST
,
10856 .rx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10857 .tx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10859 .supported
= (SUPPORTED_10000baseT_Full
|
10862 SUPPORTED_Asym_Pause
),
10863 .media_type
= ETH_PHY_XFP_FIBER
,
10865 .req_flow_ctrl
= 0,
10866 .req_line_speed
= 0,
10867 .speed_cap_mask
= 0,
10870 .config_init
= (config_init_t
)bnx2x_8705_config_init
,
10871 .read_status
= (read_status_t
)bnx2x_8705_read_status
,
10872 .link_reset
= (link_reset_t
)bnx2x_common_ext_link_reset
,
10873 .config_loopback
= (config_loopback_t
)NULL
,
10874 .format_fw_ver
= (format_fw_ver_t
)bnx2x_null_format_ver
,
10875 .hw_reset
= (hw_reset_t
)NULL
,
10876 .set_link_led
= (set_link_led_t
)NULL
,
10877 .phy_specific_func
= (phy_specific_func_t
)NULL
10879 static struct bnx2x_phy phy_8706
= {
10880 .type
= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
,
10883 .flags
= FLAGS_INIT_XGXS_FIRST
,
10884 .rx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10885 .tx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10887 .supported
= (SUPPORTED_10000baseT_Full
|
10888 SUPPORTED_1000baseT_Full
|
10891 SUPPORTED_Asym_Pause
),
10892 .media_type
= ETH_PHY_SFP_FIBER
,
10894 .req_flow_ctrl
= 0,
10895 .req_line_speed
= 0,
10896 .speed_cap_mask
= 0,
10899 .config_init
= (config_init_t
)bnx2x_8706_config_init
,
10900 .read_status
= (read_status_t
)bnx2x_8706_read_status
,
10901 .link_reset
= (link_reset_t
)bnx2x_common_ext_link_reset
,
10902 .config_loopback
= (config_loopback_t
)NULL
,
10903 .format_fw_ver
= (format_fw_ver_t
)bnx2x_format_ver
,
10904 .hw_reset
= (hw_reset_t
)NULL
,
10905 .set_link_led
= (set_link_led_t
)NULL
,
10906 .phy_specific_func
= (phy_specific_func_t
)NULL
10909 static struct bnx2x_phy phy_8726
= {
10910 .type
= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
,
10913 .flags
= (FLAGS_HW_LOCK_REQUIRED
|
10914 FLAGS_INIT_XGXS_FIRST
),
10915 .rx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10916 .tx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10918 .supported
= (SUPPORTED_10000baseT_Full
|
10919 SUPPORTED_1000baseT_Full
|
10920 SUPPORTED_Autoneg
|
10923 SUPPORTED_Asym_Pause
),
10924 .media_type
= ETH_PHY_NOT_PRESENT
,
10926 .req_flow_ctrl
= 0,
10927 .req_line_speed
= 0,
10928 .speed_cap_mask
= 0,
10931 .config_init
= (config_init_t
)bnx2x_8726_config_init
,
10932 .read_status
= (read_status_t
)bnx2x_8726_read_status
,
10933 .link_reset
= (link_reset_t
)bnx2x_8726_link_reset
,
10934 .config_loopback
= (config_loopback_t
)bnx2x_8726_config_loopback
,
10935 .format_fw_ver
= (format_fw_ver_t
)bnx2x_format_ver
,
10936 .hw_reset
= (hw_reset_t
)NULL
,
10937 .set_link_led
= (set_link_led_t
)NULL
,
10938 .phy_specific_func
= (phy_specific_func_t
)NULL
10941 static struct bnx2x_phy phy_8727
= {
10942 .type
= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
,
10945 .flags
= FLAGS_FAN_FAILURE_DET_REQ
,
10946 .rx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10947 .tx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10949 .supported
= (SUPPORTED_10000baseT_Full
|
10950 SUPPORTED_1000baseT_Full
|
10953 SUPPORTED_Asym_Pause
),
10954 .media_type
= ETH_PHY_NOT_PRESENT
,
10956 .req_flow_ctrl
= 0,
10957 .req_line_speed
= 0,
10958 .speed_cap_mask
= 0,
10961 .config_init
= (config_init_t
)bnx2x_8727_config_init
,
10962 .read_status
= (read_status_t
)bnx2x_8727_read_status
,
10963 .link_reset
= (link_reset_t
)bnx2x_8727_link_reset
,
10964 .config_loopback
= (config_loopback_t
)NULL
,
10965 .format_fw_ver
= (format_fw_ver_t
)bnx2x_format_ver
,
10966 .hw_reset
= (hw_reset_t
)bnx2x_8727_hw_reset
,
10967 .set_link_led
= (set_link_led_t
)bnx2x_8727_set_link_led
,
10968 .phy_specific_func
= (phy_specific_func_t
)bnx2x_8727_specific_func
10970 static struct bnx2x_phy phy_8481
= {
10971 .type
= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
,
10974 .flags
= FLAGS_FAN_FAILURE_DET_REQ
|
10975 FLAGS_REARM_LATCH_SIGNAL
,
10976 .rx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10977 .tx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
10979 .supported
= (SUPPORTED_10baseT_Half
|
10980 SUPPORTED_10baseT_Full
|
10981 SUPPORTED_100baseT_Half
|
10982 SUPPORTED_100baseT_Full
|
10983 SUPPORTED_1000baseT_Full
|
10984 SUPPORTED_10000baseT_Full
|
10986 SUPPORTED_Autoneg
|
10988 SUPPORTED_Asym_Pause
),
10989 .media_type
= ETH_PHY_BASE_T
,
10991 .req_flow_ctrl
= 0,
10992 .req_line_speed
= 0,
10993 .speed_cap_mask
= 0,
10996 .config_init
= (config_init_t
)bnx2x_8481_config_init
,
10997 .read_status
= (read_status_t
)bnx2x_848xx_read_status
,
10998 .link_reset
= (link_reset_t
)bnx2x_8481_link_reset
,
10999 .config_loopback
= (config_loopback_t
)NULL
,
11000 .format_fw_ver
= (format_fw_ver_t
)bnx2x_848xx_format_ver
,
11001 .hw_reset
= (hw_reset_t
)bnx2x_8481_hw_reset
,
11002 .set_link_led
= (set_link_led_t
)bnx2x_848xx_set_link_led
,
11003 .phy_specific_func
= (phy_specific_func_t
)NULL
11006 static struct bnx2x_phy phy_84823
= {
11007 .type
= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823
,
11010 .flags
= FLAGS_FAN_FAILURE_DET_REQ
|
11011 FLAGS_REARM_LATCH_SIGNAL
,
11012 .rx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
11013 .tx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
11015 .supported
= (SUPPORTED_10baseT_Half
|
11016 SUPPORTED_10baseT_Full
|
11017 SUPPORTED_100baseT_Half
|
11018 SUPPORTED_100baseT_Full
|
11019 SUPPORTED_1000baseT_Full
|
11020 SUPPORTED_10000baseT_Full
|
11022 SUPPORTED_Autoneg
|
11024 SUPPORTED_Asym_Pause
),
11025 .media_type
= ETH_PHY_BASE_T
,
11027 .req_flow_ctrl
= 0,
11028 .req_line_speed
= 0,
11029 .speed_cap_mask
= 0,
11032 .config_init
= (config_init_t
)bnx2x_848x3_config_init
,
11033 .read_status
= (read_status_t
)bnx2x_848xx_read_status
,
11034 .link_reset
= (link_reset_t
)bnx2x_848x3_link_reset
,
11035 .config_loopback
= (config_loopback_t
)NULL
,
11036 .format_fw_ver
= (format_fw_ver_t
)bnx2x_848xx_format_ver
,
11037 .hw_reset
= (hw_reset_t
)NULL
,
11038 .set_link_led
= (set_link_led_t
)bnx2x_848xx_set_link_led
,
11039 .phy_specific_func
= (phy_specific_func_t
)NULL
11042 static struct bnx2x_phy phy_84833
= {
11043 .type
= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833
,
11046 .flags
= FLAGS_FAN_FAILURE_DET_REQ
|
11047 FLAGS_REARM_LATCH_SIGNAL
,
11048 .rx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
11049 .tx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
11051 .supported
= (SUPPORTED_100baseT_Half
|
11052 SUPPORTED_100baseT_Full
|
11053 SUPPORTED_1000baseT_Full
|
11054 SUPPORTED_10000baseT_Full
|
11056 SUPPORTED_Autoneg
|
11058 SUPPORTED_Asym_Pause
),
11059 .media_type
= ETH_PHY_BASE_T
,
11061 .req_flow_ctrl
= 0,
11062 .req_line_speed
= 0,
11063 .speed_cap_mask
= 0,
11066 .config_init
= (config_init_t
)bnx2x_848x3_config_init
,
11067 .read_status
= (read_status_t
)bnx2x_848xx_read_status
,
11068 .link_reset
= (link_reset_t
)bnx2x_848x3_link_reset
,
11069 .config_loopback
= (config_loopback_t
)NULL
,
11070 .format_fw_ver
= (format_fw_ver_t
)bnx2x_848xx_format_ver
,
11071 .hw_reset
= (hw_reset_t
)bnx2x_84833_hw_reset_phy
,
11072 .set_link_led
= (set_link_led_t
)bnx2x_848xx_set_link_led
,
11073 .phy_specific_func
= (phy_specific_func_t
)NULL
11076 static struct bnx2x_phy phy_54618se
= {
11077 .type
= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE
,
11080 .flags
= FLAGS_INIT_XGXS_FIRST
,
11081 .rx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
11082 .tx_preemphasis
= {0xffff, 0xffff, 0xffff, 0xffff},
11084 .supported
= (SUPPORTED_10baseT_Half
|
11085 SUPPORTED_10baseT_Full
|
11086 SUPPORTED_100baseT_Half
|
11087 SUPPORTED_100baseT_Full
|
11088 SUPPORTED_1000baseT_Full
|
11090 SUPPORTED_Autoneg
|
11092 SUPPORTED_Asym_Pause
),
11093 .media_type
= ETH_PHY_BASE_T
,
11095 .req_flow_ctrl
= 0,
11096 .req_line_speed
= 0,
11097 .speed_cap_mask
= 0,
11098 /* req_duplex = */0,
11100 .config_init
= (config_init_t
)bnx2x_54618se_config_init
,
11101 .read_status
= (read_status_t
)bnx2x_54618se_read_status
,
11102 .link_reset
= (link_reset_t
)bnx2x_54618se_link_reset
,
11103 .config_loopback
= (config_loopback_t
)bnx2x_54618se_config_loopback
,
11104 .format_fw_ver
= (format_fw_ver_t
)NULL
,
11105 .hw_reset
= (hw_reset_t
)NULL
,
11106 .set_link_led
= (set_link_led_t
)NULL
,
11107 .phy_specific_func
= (phy_specific_func_t
)NULL
11109 /*****************************************************************/
11111 /* Populate the phy according. Main function: bnx2x_populate_phy */
11113 /*****************************************************************/
11115 static void bnx2x_populate_preemphasis(struct bnx2x
*bp
, u32 shmem_base
,
11116 struct bnx2x_phy
*phy
, u8 port
,
11119 /* Get the 4 lanes xgxs config rx and tx */
11120 u32 rx
= 0, tx
= 0, i
;
11121 for (i
= 0; i
< 2; i
++) {
11123 * INT_PHY and EXT_PHY1 share the same value location in the
11124 * shmem. When num_phys is greater than 1, than this value
11125 * applies only to EXT_PHY1
11127 if (phy_index
== INT_PHY
|| phy_index
== EXT_PHY1
) {
11128 rx
= REG_RD(bp
, shmem_base
+
11129 offsetof(struct shmem_region
,
11130 dev_info
.port_hw_config
[port
].xgxs_config_rx
[i
<<1]));
11132 tx
= REG_RD(bp
, shmem_base
+
11133 offsetof(struct shmem_region
,
11134 dev_info
.port_hw_config
[port
].xgxs_config_tx
[i
<<1]));
11136 rx
= REG_RD(bp
, shmem_base
+
11137 offsetof(struct shmem_region
,
11138 dev_info
.port_hw_config
[port
].xgxs_config2_rx
[i
<<1]));
11140 tx
= REG_RD(bp
, shmem_base
+
11141 offsetof(struct shmem_region
,
11142 dev_info
.port_hw_config
[port
].xgxs_config2_rx
[i
<<1]));
11145 phy
->rx_preemphasis
[i
<< 1] = ((rx
>>16) & 0xffff);
11146 phy
->rx_preemphasis
[(i
<< 1) + 1] = (rx
& 0xffff);
11148 phy
->tx_preemphasis
[i
<< 1] = ((tx
>>16) & 0xffff);
11149 phy
->tx_preemphasis
[(i
<< 1) + 1] = (tx
& 0xffff);
11153 static u32
bnx2x_get_ext_phy_config(struct bnx2x
*bp
, u32 shmem_base
,
11154 u8 phy_index
, u8 port
)
11156 u32 ext_phy_config
= 0;
11157 switch (phy_index
) {
11159 ext_phy_config
= REG_RD(bp
, shmem_base
+
11160 offsetof(struct shmem_region
,
11161 dev_info
.port_hw_config
[port
].external_phy_config
));
11164 ext_phy_config
= REG_RD(bp
, shmem_base
+
11165 offsetof(struct shmem_region
,
11166 dev_info
.port_hw_config
[port
].external_phy_config2
));
11169 DP(NETIF_MSG_LINK
, "Invalid phy_index %d\n", phy_index
);
11173 return ext_phy_config
;
11175 static int bnx2x_populate_int_phy(struct bnx2x
*bp
, u32 shmem_base
, u8 port
,
11176 struct bnx2x_phy
*phy
)
11180 u32 switch_cfg
= (REG_RD(bp
, shmem_base
+
11181 offsetof(struct shmem_region
,
11182 dev_info
.port_feature_config
[port
].link_config
)) &
11183 PORT_FEATURE_CONNECTED_SWITCH_MASK
);
11184 chip_id
= REG_RD(bp
, MISC_REG_CHIP_NUM
) << 16;
11185 DP(NETIF_MSG_LINK
, ":chip_id = 0x%x\n", chip_id
);
11186 if (USES_WARPCORE(bp
)) {
11188 phy_addr
= REG_RD(bp
,
11189 MISC_REG_WC0_CTRL_PHY_ADDR
);
11190 *phy
= phy_warpcore
;
11191 if (REG_RD(bp
, MISC_REG_PORT4MODE_EN_OVWR
) == 0x3)
11192 phy
->flags
|= FLAGS_4_PORT_MODE
;
11194 phy
->flags
&= ~FLAGS_4_PORT_MODE
;
11195 /* Check Dual mode */
11196 serdes_net_if
= (REG_RD(bp
, shmem_base
+
11197 offsetof(struct shmem_region
, dev_info
.
11198 port_hw_config
[port
].default_cfg
)) &
11199 PORT_HW_CFG_NET_SERDES_IF_MASK
);
11201 * Set the appropriate supported and flags indications per
11202 * interface type of the chip
11204 switch (serdes_net_if
) {
11205 case PORT_HW_CFG_NET_SERDES_IF_SGMII
:
11206 phy
->supported
&= (SUPPORTED_10baseT_Half
|
11207 SUPPORTED_10baseT_Full
|
11208 SUPPORTED_100baseT_Half
|
11209 SUPPORTED_100baseT_Full
|
11210 SUPPORTED_1000baseT_Full
|
11212 SUPPORTED_Autoneg
|
11214 SUPPORTED_Asym_Pause
);
11215 phy
->media_type
= ETH_PHY_BASE_T
;
11217 case PORT_HW_CFG_NET_SERDES_IF_XFI
:
11218 phy
->media_type
= ETH_PHY_XFP_FIBER
;
11220 case PORT_HW_CFG_NET_SERDES_IF_SFI
:
11221 phy
->supported
&= (SUPPORTED_1000baseT_Full
|
11222 SUPPORTED_10000baseT_Full
|
11225 SUPPORTED_Asym_Pause
);
11226 phy
->media_type
= ETH_PHY_SFP_FIBER
;
11228 case PORT_HW_CFG_NET_SERDES_IF_KR
:
11229 phy
->media_type
= ETH_PHY_KR
;
11230 phy
->supported
&= (SUPPORTED_1000baseT_Full
|
11231 SUPPORTED_10000baseT_Full
|
11233 SUPPORTED_Autoneg
|
11235 SUPPORTED_Asym_Pause
);
11237 case PORT_HW_CFG_NET_SERDES_IF_DXGXS
:
11238 phy
->media_type
= ETH_PHY_KR
;
11239 phy
->flags
|= FLAGS_WC_DUAL_MODE
;
11240 phy
->supported
&= (SUPPORTED_20000baseMLD2_Full
|
11243 SUPPORTED_Asym_Pause
);
11245 case PORT_HW_CFG_NET_SERDES_IF_KR2
:
11246 phy
->media_type
= ETH_PHY_KR
;
11247 phy
->flags
|= FLAGS_WC_DUAL_MODE
;
11248 phy
->supported
&= (SUPPORTED_20000baseKR2_Full
|
11251 SUPPORTED_Asym_Pause
);
11254 DP(NETIF_MSG_LINK
, "Unknown WC interface type 0x%x\n",
11260 * Enable MDC/MDIO work-around for E3 A0 since free running MDC
11261 * was not set as expected. For B0, ECO will be enabled so there
11262 * won't be an issue there
11264 if (CHIP_REV(bp
) == CHIP_REV_Ax
)
11265 phy
->flags
|= FLAGS_MDC_MDIO_WA
;
11267 phy
->flags
|= FLAGS_MDC_MDIO_WA_B0
;
11269 switch (switch_cfg
) {
11270 case SWITCH_CFG_1G
:
11271 phy_addr
= REG_RD(bp
,
11272 NIG_REG_SERDES0_CTRL_PHY_ADDR
+
11276 case SWITCH_CFG_10G
:
11277 phy_addr
= REG_RD(bp
,
11278 NIG_REG_XGXS0_CTRL_PHY_ADDR
+
11283 DP(NETIF_MSG_LINK
, "Invalid switch_cfg\n");
11287 phy
->addr
= (u8
)phy_addr
;
11288 phy
->mdio_ctrl
= bnx2x_get_emac_base(bp
,
11289 SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH
,
11291 if (CHIP_IS_E2(bp
))
11292 phy
->def_md_devad
= E2_DEFAULT_PHY_DEV_ADDR
;
11294 phy
->def_md_devad
= DEFAULT_PHY_DEV_ADDR
;
11296 DP(NETIF_MSG_LINK
, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
11297 port
, phy
->addr
, phy
->mdio_ctrl
);
11299 bnx2x_populate_preemphasis(bp
, shmem_base
, phy
, port
, INT_PHY
);
11303 static int bnx2x_populate_ext_phy(struct bnx2x
*bp
,
11308 struct bnx2x_phy
*phy
)
11310 u32 ext_phy_config
, phy_type
, config2
;
11311 u32 mdc_mdio_access
= SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH
;
11312 ext_phy_config
= bnx2x_get_ext_phy_config(bp
, shmem_base
,
11314 phy_type
= XGXS_EXT_PHY_TYPE(ext_phy_config
);
11315 /* Select the phy type */
11316 switch (phy_type
) {
11317 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
11318 mdc_mdio_access
= SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED
;
11321 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
:
11324 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
:
11327 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
:
11328 mdc_mdio_access
= SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1
;
11331 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC
:
11332 /* BCM8727_NOC => BCM8727 no over current */
11333 mdc_mdio_access
= SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1
;
11335 phy
->flags
|= FLAGS_NOC
;
11337 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722
:
11338 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
:
11339 mdc_mdio_access
= SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1
;
11342 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481
:
11345 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823
:
11348 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833
:
11351 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616
:
11352 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE
:
11353 *phy
= phy_54618se
;
11355 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101
:
11358 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
11366 phy
->addr
= XGXS_EXT_PHY_ADDR(ext_phy_config
);
11367 bnx2x_populate_preemphasis(bp
, shmem_base
, phy
, port
, phy_index
);
11370 * The shmem address of the phy version is located on different
11371 * structures. In case this structure is too old, do not set
11374 config2
= REG_RD(bp
, shmem_base
+ offsetof(struct shmem_region
,
11375 dev_info
.shared_hw_config
.config2
));
11376 if (phy_index
== EXT_PHY1
) {
11377 phy
->ver_addr
= shmem_base
+ offsetof(struct shmem_region
,
11378 port_mb
[port
].ext_phy_fw_version
);
11380 /* Check specific mdc mdio settings */
11381 if (config2
& SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK
)
11382 mdc_mdio_access
= config2
&
11383 SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK
;
11385 u32 size
= REG_RD(bp
, shmem2_base
);
11388 offsetof(struct shmem2_region
, ext_phy_fw_version2
)) {
11389 phy
->ver_addr
= shmem2_base
+
11390 offsetof(struct shmem2_region
,
11391 ext_phy_fw_version2
[port
]);
11393 /* Check specific mdc mdio settings */
11394 if (config2
& SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK
)
11395 mdc_mdio_access
= (config2
&
11396 SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK
) >>
11397 (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT
-
11398 SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT
);
11400 phy
->mdio_ctrl
= bnx2x_get_emac_base(bp
, mdc_mdio_access
, port
);
11403 * In case mdc/mdio_access of the external phy is different than the
11404 * mdc/mdio access of the XGXS, a HW lock must be taken in each access
11405 * to prevent one port interfere with another port's CL45 operations.
11407 if (mdc_mdio_access
!= SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH
)
11408 phy
->flags
|= FLAGS_HW_LOCK_REQUIRED
;
11409 DP(NETIF_MSG_LINK
, "phy_type 0x%x port %d found in index %d\n",
11410 phy_type
, port
, phy_index
);
11411 DP(NETIF_MSG_LINK
, " addr=0x%x, mdio_ctl=0x%x\n",
11412 phy
->addr
, phy
->mdio_ctrl
);
11416 static int bnx2x_populate_phy(struct bnx2x
*bp
, u8 phy_index
, u32 shmem_base
,
11417 u32 shmem2_base
, u8 port
, struct bnx2x_phy
*phy
)
11420 phy
->type
= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
;
11421 if (phy_index
== INT_PHY
)
11422 return bnx2x_populate_int_phy(bp
, shmem_base
, port
, phy
);
11423 status
= bnx2x_populate_ext_phy(bp
, phy_index
, shmem_base
, shmem2_base
,
11428 static void bnx2x_phy_def_cfg(struct link_params
*params
,
11429 struct bnx2x_phy
*phy
,
11432 struct bnx2x
*bp
= params
->bp
;
11434 /* Populate the default phy configuration for MF mode */
11435 if (phy_index
== EXT_PHY2
) {
11436 link_config
= REG_RD(bp
, params
->shmem_base
+
11437 offsetof(struct shmem_region
, dev_info
.
11438 port_feature_config
[params
->port
].link_config2
));
11439 phy
->speed_cap_mask
= REG_RD(bp
, params
->shmem_base
+
11440 offsetof(struct shmem_region
,
11442 port_hw_config
[params
->port
].speed_capability_mask2
));
11444 link_config
= REG_RD(bp
, params
->shmem_base
+
11445 offsetof(struct shmem_region
, dev_info
.
11446 port_feature_config
[params
->port
].link_config
));
11447 phy
->speed_cap_mask
= REG_RD(bp
, params
->shmem_base
+
11448 offsetof(struct shmem_region
,
11450 port_hw_config
[params
->port
].speed_capability_mask
));
11453 "Default config phy idx %x cfg 0x%x speed_cap_mask 0x%x\n",
11454 phy_index
, link_config
, phy
->speed_cap_mask
);
11456 phy
->req_duplex
= DUPLEX_FULL
;
11457 switch (link_config
& PORT_FEATURE_LINK_SPEED_MASK
) {
11458 case PORT_FEATURE_LINK_SPEED_10M_HALF
:
11459 phy
->req_duplex
= DUPLEX_HALF
;
11460 case PORT_FEATURE_LINK_SPEED_10M_FULL
:
11461 phy
->req_line_speed
= SPEED_10
;
11463 case PORT_FEATURE_LINK_SPEED_100M_HALF
:
11464 phy
->req_duplex
= DUPLEX_HALF
;
11465 case PORT_FEATURE_LINK_SPEED_100M_FULL
:
11466 phy
->req_line_speed
= SPEED_100
;
11468 case PORT_FEATURE_LINK_SPEED_1G
:
11469 phy
->req_line_speed
= SPEED_1000
;
11471 case PORT_FEATURE_LINK_SPEED_2_5G
:
11472 phy
->req_line_speed
= SPEED_2500
;
11474 case PORT_FEATURE_LINK_SPEED_10G_CX4
:
11475 phy
->req_line_speed
= SPEED_10000
;
11478 phy
->req_line_speed
= SPEED_AUTO_NEG
;
11482 switch (link_config
& PORT_FEATURE_FLOW_CONTROL_MASK
) {
11483 case PORT_FEATURE_FLOW_CONTROL_AUTO
:
11484 phy
->req_flow_ctrl
= BNX2X_FLOW_CTRL_AUTO
;
11486 case PORT_FEATURE_FLOW_CONTROL_TX
:
11487 phy
->req_flow_ctrl
= BNX2X_FLOW_CTRL_TX
;
11489 case PORT_FEATURE_FLOW_CONTROL_RX
:
11490 phy
->req_flow_ctrl
= BNX2X_FLOW_CTRL_RX
;
11492 case PORT_FEATURE_FLOW_CONTROL_BOTH
:
11493 phy
->req_flow_ctrl
= BNX2X_FLOW_CTRL_BOTH
;
11496 phy
->req_flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
11501 u32
bnx2x_phy_selection(struct link_params
*params
)
11503 u32 phy_config_swapped
, prio_cfg
;
11504 u32 return_cfg
= PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT
;
11506 phy_config_swapped
= params
->multi_phy_config
&
11507 PORT_HW_CFG_PHY_SWAPPED_ENABLED
;
11509 prio_cfg
= params
->multi_phy_config
&
11510 PORT_HW_CFG_PHY_SELECTION_MASK
;
11512 if (phy_config_swapped
) {
11513 switch (prio_cfg
) {
11514 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY
:
11515 return_cfg
= PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY
;
11517 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY
:
11518 return_cfg
= PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY
;
11520 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY
:
11521 return_cfg
= PORT_HW_CFG_PHY_SELECTION_FIRST_PHY
;
11523 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY
:
11524 return_cfg
= PORT_HW_CFG_PHY_SELECTION_SECOND_PHY
;
11528 return_cfg
= prio_cfg
;
11534 int bnx2x_phy_probe(struct link_params
*params
)
11536 u8 phy_index
, actual_phy_idx
, link_cfg_idx
;
11537 u32 phy_config_swapped
, sync_offset
, media_types
;
11538 struct bnx2x
*bp
= params
->bp
;
11539 struct bnx2x_phy
*phy
;
11540 params
->num_phys
= 0;
11541 DP(NETIF_MSG_LINK
, "Begin phy probe\n");
11542 phy_config_swapped
= params
->multi_phy_config
&
11543 PORT_HW_CFG_PHY_SWAPPED_ENABLED
;
11545 for (phy_index
= INT_PHY
; phy_index
< MAX_PHYS
;
11547 link_cfg_idx
= LINK_CONFIG_IDX(phy_index
);
11548 actual_phy_idx
= phy_index
;
11549 if (phy_config_swapped
) {
11550 if (phy_index
== EXT_PHY1
)
11551 actual_phy_idx
= EXT_PHY2
;
11552 else if (phy_index
== EXT_PHY2
)
11553 actual_phy_idx
= EXT_PHY1
;
11555 DP(NETIF_MSG_LINK
, "phy_config_swapped %x, phy_index %x,"
11556 " actual_phy_idx %x\n", phy_config_swapped
,
11557 phy_index
, actual_phy_idx
);
11558 phy
= ¶ms
->phy
[actual_phy_idx
];
11559 if (bnx2x_populate_phy(bp
, phy_index
, params
->shmem_base
,
11560 params
->shmem2_base
, params
->port
,
11562 params
->num_phys
= 0;
11563 DP(NETIF_MSG_LINK
, "phy probe failed in phy index %d\n",
11565 for (phy_index
= INT_PHY
;
11566 phy_index
< MAX_PHYS
;
11571 if (phy
->type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN
)
11574 sync_offset
= params
->shmem_base
+
11575 offsetof(struct shmem_region
,
11576 dev_info
.port_hw_config
[params
->port
].media_type
);
11577 media_types
= REG_RD(bp
, sync_offset
);
11580 * Update media type for non-PMF sync only for the first time
11581 * In case the media type changes afterwards, it will be updated
11582 * using the update_status function
11584 if ((media_types
& (PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK
<<
11585 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT
*
11586 actual_phy_idx
))) == 0) {
11587 media_types
|= ((phy
->media_type
&
11588 PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK
) <<
11589 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT
*
11592 REG_WR(bp
, sync_offset
, media_types
);
11594 bnx2x_phy_def_cfg(params
, phy
, phy_index
);
11595 params
->num_phys
++;
11598 DP(NETIF_MSG_LINK
, "End phy probe. #phys found %x\n", params
->num_phys
);
11602 void bnx2x_init_bmac_loopback(struct link_params
*params
,
11603 struct link_vars
*vars
)
11605 struct bnx2x
*bp
= params
->bp
;
11607 vars
->line_speed
= SPEED_10000
;
11608 vars
->duplex
= DUPLEX_FULL
;
11609 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
11610 vars
->mac_type
= MAC_TYPE_BMAC
;
11612 vars
->phy_flags
= PHY_XGXS_FLAG
;
11614 bnx2x_xgxs_deassert(params
);
11616 /* set bmac loopback */
11617 bnx2x_bmac_enable(params
, vars
, 1);
11619 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ params
->port
*4, 0);
11622 void bnx2x_init_emac_loopback(struct link_params
*params
,
11623 struct link_vars
*vars
)
11625 struct bnx2x
*bp
= params
->bp
;
11627 vars
->line_speed
= SPEED_1000
;
11628 vars
->duplex
= DUPLEX_FULL
;
11629 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
11630 vars
->mac_type
= MAC_TYPE_EMAC
;
11632 vars
->phy_flags
= PHY_XGXS_FLAG
;
11634 bnx2x_xgxs_deassert(params
);
11635 /* set bmac loopback */
11636 bnx2x_emac_enable(params
, vars
, 1);
11637 bnx2x_emac_program(params
, vars
);
11638 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ params
->port
*4, 0);
11641 void bnx2x_init_xmac_loopback(struct link_params
*params
,
11642 struct link_vars
*vars
)
11644 struct bnx2x
*bp
= params
->bp
;
11646 if (!params
->req_line_speed
[0])
11647 vars
->line_speed
= SPEED_10000
;
11649 vars
->line_speed
= params
->req_line_speed
[0];
11650 vars
->duplex
= DUPLEX_FULL
;
11651 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
11652 vars
->mac_type
= MAC_TYPE_XMAC
;
11653 vars
->phy_flags
= PHY_XGXS_FLAG
;
11655 * Set WC to loopback mode since link is required to provide clock
11656 * to the XMAC in 20G mode
11658 bnx2x_set_aer_mmd(params
, ¶ms
->phy
[0]);
11659 bnx2x_warpcore_reset_lane(bp
, ¶ms
->phy
[0], 0);
11660 params
->phy
[INT_PHY
].config_loopback(
11661 ¶ms
->phy
[INT_PHY
],
11664 bnx2x_xmac_enable(params
, vars
, 1);
11665 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ params
->port
*4, 0);
11668 void bnx2x_init_umac_loopback(struct link_params
*params
,
11669 struct link_vars
*vars
)
11671 struct bnx2x
*bp
= params
->bp
;
11673 vars
->line_speed
= SPEED_1000
;
11674 vars
->duplex
= DUPLEX_FULL
;
11675 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
11676 vars
->mac_type
= MAC_TYPE_UMAC
;
11677 vars
->phy_flags
= PHY_XGXS_FLAG
;
11678 bnx2x_umac_enable(params
, vars
, 1);
11680 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ params
->port
*4, 0);
11683 void bnx2x_init_xgxs_loopback(struct link_params
*params
,
11684 struct link_vars
*vars
)
11686 struct bnx2x
*bp
= params
->bp
;
11688 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
11689 vars
->duplex
= DUPLEX_FULL
;
11690 if (params
->req_line_speed
[0] == SPEED_1000
)
11691 vars
->line_speed
= SPEED_1000
;
11693 vars
->line_speed
= SPEED_10000
;
11695 if (!USES_WARPCORE(bp
))
11696 bnx2x_xgxs_deassert(params
);
11697 bnx2x_link_initialize(params
, vars
);
11699 if (params
->req_line_speed
[0] == SPEED_1000
) {
11700 if (USES_WARPCORE(bp
))
11701 bnx2x_umac_enable(params
, vars
, 0);
11703 bnx2x_emac_program(params
, vars
);
11704 bnx2x_emac_enable(params
, vars
, 0);
11707 if (USES_WARPCORE(bp
))
11708 bnx2x_xmac_enable(params
, vars
, 0);
11710 bnx2x_bmac_enable(params
, vars
, 0);
11713 if (params
->loopback_mode
== LOOPBACK_XGXS
) {
11714 /* set 10G XGXS loopback */
11715 params
->phy
[INT_PHY
].config_loopback(
11716 ¶ms
->phy
[INT_PHY
],
11720 /* set external phy loopback */
11722 for (phy_index
= EXT_PHY1
;
11723 phy_index
< params
->num_phys
; phy_index
++) {
11724 if (params
->phy
[phy_index
].config_loopback
)
11725 params
->phy
[phy_index
].config_loopback(
11726 ¶ms
->phy
[phy_index
],
11730 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ params
->port
*4, 0);
11732 bnx2x_set_led(params
, vars
, LED_MODE_OPER
, vars
->line_speed
);
11735 int bnx2x_phy_init(struct link_params
*params
, struct link_vars
*vars
)
11737 struct bnx2x
*bp
= params
->bp
;
11738 DP(NETIF_MSG_LINK
, "Phy Initialization started\n");
11739 DP(NETIF_MSG_LINK
, "(1) req_speed %d, req_flowctrl %d\n",
11740 params
->req_line_speed
[0], params
->req_flow_ctrl
[0]);
11741 DP(NETIF_MSG_LINK
, "(2) req_speed %d, req_flowctrl %d\n",
11742 params
->req_line_speed
[1], params
->req_flow_ctrl
[1]);
11743 vars
->link_status
= 0;
11744 vars
->phy_link_up
= 0;
11746 vars
->line_speed
= 0;
11747 vars
->duplex
= DUPLEX_FULL
;
11748 vars
->flow_ctrl
= BNX2X_FLOW_CTRL_NONE
;
11749 vars
->mac_type
= MAC_TYPE_NONE
;
11750 vars
->phy_flags
= 0;
11752 /* disable attentions */
11753 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ params
->port
*4,
11754 (NIG_MASK_XGXS0_LINK_STATUS
|
11755 NIG_MASK_XGXS0_LINK10G
|
11756 NIG_MASK_SERDES0_LINK_STATUS
|
11759 bnx2x_emac_init(params
, vars
);
11761 if (params
->num_phys
== 0) {
11762 DP(NETIF_MSG_LINK
, "No phy found for initialization !!\n");
11765 set_phy_vars(params
, vars
);
11767 DP(NETIF_MSG_LINK
, "Num of phys on board: %d\n", params
->num_phys
);
11768 switch (params
->loopback_mode
) {
11769 case LOOPBACK_BMAC
:
11770 bnx2x_init_bmac_loopback(params
, vars
);
11772 case LOOPBACK_EMAC
:
11773 bnx2x_init_emac_loopback(params
, vars
);
11775 case LOOPBACK_XMAC
:
11776 bnx2x_init_xmac_loopback(params
, vars
);
11778 case LOOPBACK_UMAC
:
11779 bnx2x_init_umac_loopback(params
, vars
);
11781 case LOOPBACK_XGXS
:
11782 case LOOPBACK_EXT_PHY
:
11783 bnx2x_init_xgxs_loopback(params
, vars
);
11786 if (!CHIP_IS_E3(bp
)) {
11787 if (params
->switch_cfg
== SWITCH_CFG_10G
)
11788 bnx2x_xgxs_deassert(params
);
11790 bnx2x_serdes_deassert(bp
, params
->port
);
11792 bnx2x_link_initialize(params
, vars
);
11794 bnx2x_link_int_enable(params
);
11800 int bnx2x_link_reset(struct link_params
*params
, struct link_vars
*vars
,
11803 struct bnx2x
*bp
= params
->bp
;
11804 u8 phy_index
, port
= params
->port
, clear_latch_ind
= 0;
11805 DP(NETIF_MSG_LINK
, "Resetting the link of port %d\n", port
);
11806 /* disable attentions */
11807 vars
->link_status
= 0;
11808 bnx2x_update_mng(params
, vars
->link_status
);
11809 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ port
*4,
11810 (NIG_MASK_XGXS0_LINK_STATUS
|
11811 NIG_MASK_XGXS0_LINK10G
|
11812 NIG_MASK_SERDES0_LINK_STATUS
|
11815 /* activate nig drain */
11816 REG_WR(bp
, NIG_REG_EGRESS_DRAIN0_MODE
+ port
*4, 1);
11818 /* disable nig egress interface */
11819 if (!CHIP_IS_E3(bp
)) {
11820 REG_WR(bp
, NIG_REG_BMAC0_OUT_EN
+ port
*4, 0);
11821 REG_WR(bp
, NIG_REG_EGRESS_EMAC0_OUT_EN
+ port
*4, 0);
11824 /* Stop BigMac rx */
11825 if (!CHIP_IS_E3(bp
))
11826 bnx2x_bmac_rx_disable(bp
, port
);
11828 bnx2x_xmac_disable(params
);
11829 bnx2x_umac_disable(params
);
11832 if (!CHIP_IS_E3(bp
))
11833 REG_WR(bp
, NIG_REG_NIG_EMAC0_EN
+ port
*4, 0);
11836 /* The PHY reset is controlled by GPIO 1
11837 * Hold it as vars low
11839 /* clear link led */
11840 bnx2x_set_led(params
, vars
, LED_MODE_OFF
, 0);
11842 if (reset_ext_phy
) {
11843 bnx2x_set_mdio_clk(bp
, params
->chip_id
, port
);
11844 for (phy_index
= EXT_PHY1
; phy_index
< params
->num_phys
;
11846 if (params
->phy
[phy_index
].link_reset
) {
11847 bnx2x_set_aer_mmd(params
,
11848 ¶ms
->phy
[phy_index
]);
11849 params
->phy
[phy_index
].link_reset(
11850 ¶ms
->phy
[phy_index
],
11853 if (params
->phy
[phy_index
].flags
&
11854 FLAGS_REARM_LATCH_SIGNAL
)
11855 clear_latch_ind
= 1;
11859 if (clear_latch_ind
) {
11860 /* Clear latching indication */
11861 bnx2x_rearm_latch_signal(bp
, port
, 0);
11862 bnx2x_bits_dis(bp
, NIG_REG_LATCH_BC_0
+ port
*4,
11863 1 << NIG_LATCH_BC_ENABLE_MI_INT
);
11865 if (params
->phy
[INT_PHY
].link_reset
)
11866 params
->phy
[INT_PHY
].link_reset(
11867 ¶ms
->phy
[INT_PHY
], params
);
11869 /* disable nig ingress interface */
11870 if (!CHIP_IS_E3(bp
)) {
11872 REG_WR(bp
, GRCBASE_MISC
+ MISC_REGISTERS_RESET_REG_2_CLEAR
,
11873 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< port
));
11874 REG_WR(bp
, NIG_REG_BMAC0_IN_EN
+ port
*4, 0);
11875 REG_WR(bp
, NIG_REG_EMAC0_IN_EN
+ port
*4, 0);
11877 u32 xmac_base
= (params
->port
) ? GRCBASE_XMAC1
: GRCBASE_XMAC0
;
11878 bnx2x_set_xumac_nig(params
, 0, 0);
11879 if (REG_RD(bp
, MISC_REG_RESET_REG_2
) &
11880 MISC_REGISTERS_RESET_REG_2_XMAC
)
11881 REG_WR(bp
, xmac_base
+ XMAC_REG_CTRL
,
11882 XMAC_CTRL_REG_SOFT_RESET
);
11885 vars
->phy_flags
= 0;
11889 /****************************************************************************/
11890 /* Common function */
11891 /****************************************************************************/
11892 static int bnx2x_8073_common_init_phy(struct bnx2x
*bp
,
11893 u32 shmem_base_path
[],
11894 u32 shmem2_base_path
[], u8 phy_index
,
11897 struct bnx2x_phy phy
[PORT_MAX
];
11898 struct bnx2x_phy
*phy_blk
[PORT_MAX
];
11901 s8 port_of_path
= 0;
11902 u32 swap_val
, swap_override
;
11903 swap_val
= REG_RD(bp
, NIG_REG_PORT_SWAP
);
11904 swap_override
= REG_RD(bp
, NIG_REG_STRAP_OVERRIDE
);
11905 port
^= (swap_val
&& swap_override
);
11906 bnx2x_ext_phy_hw_reset(bp
, port
);
11907 /* PART1 - Reset both phys */
11908 for (port
= PORT_MAX
- 1; port
>= PORT_0
; port
--) {
11909 u32 shmem_base
, shmem2_base
;
11910 /* In E2, same phy is using for port0 of the two paths */
11911 if (CHIP_IS_E1x(bp
)) {
11912 shmem_base
= shmem_base_path
[0];
11913 shmem2_base
= shmem2_base_path
[0];
11914 port_of_path
= port
;
11916 shmem_base
= shmem_base_path
[port
];
11917 shmem2_base
= shmem2_base_path
[port
];
11921 /* Extract the ext phy address for the port */
11922 if (bnx2x_populate_phy(bp
, phy_index
, shmem_base
, shmem2_base
,
11923 port_of_path
, &phy
[port
]) !=
11925 DP(NETIF_MSG_LINK
, "populate_phy failed\n");
11928 /* disable attentions */
11929 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+
11931 (NIG_MASK_XGXS0_LINK_STATUS
|
11932 NIG_MASK_XGXS0_LINK10G
|
11933 NIG_MASK_SERDES0_LINK_STATUS
|
11936 /* Need to take the phy out of low power mode in order
11937 to write to access its registers */
11938 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
11939 MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
11942 /* Reset the phy */
11943 bnx2x_cl45_write(bp
, &phy
[port
],
11949 /* Add delay of 150ms after reset */
11952 if (phy
[PORT_0
].addr
& 0x1) {
11953 phy_blk
[PORT_0
] = &(phy
[PORT_1
]);
11954 phy_blk
[PORT_1
] = &(phy
[PORT_0
]);
11956 phy_blk
[PORT_0
] = &(phy
[PORT_0
]);
11957 phy_blk
[PORT_1
] = &(phy
[PORT_1
]);
11960 /* PART2 - Download firmware to both phys */
11961 for (port
= PORT_MAX
- 1; port
>= PORT_0
; port
--) {
11962 if (CHIP_IS_E1x(bp
))
11963 port_of_path
= port
;
11967 DP(NETIF_MSG_LINK
, "Loading spirom for phy address 0x%x\n",
11968 phy_blk
[port
]->addr
);
11969 if (bnx2x_8073_8727_external_rom_boot(bp
, phy_blk
[port
],
11973 /* Only set bit 10 = 1 (Tx power down) */
11974 bnx2x_cl45_read(bp
, phy_blk
[port
],
11976 MDIO_PMA_REG_TX_POWER_DOWN
, &val
);
11978 /* Phase1 of TX_POWER_DOWN reset */
11979 bnx2x_cl45_write(bp
, phy_blk
[port
],
11981 MDIO_PMA_REG_TX_POWER_DOWN
,
11986 * Toggle Transmitter: Power down and then up with 600ms delay
11991 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
11992 for (port
= PORT_MAX
- 1; port
>= PORT_0
; port
--) {
11993 /* Phase2 of POWER_DOWN_RESET */
11994 /* Release bit 10 (Release Tx power down) */
11995 bnx2x_cl45_read(bp
, phy_blk
[port
],
11997 MDIO_PMA_REG_TX_POWER_DOWN
, &val
);
11999 bnx2x_cl45_write(bp
, phy_blk
[port
],
12001 MDIO_PMA_REG_TX_POWER_DOWN
, (val
& (~(1<<10))));
12004 /* Read modify write the SPI-ROM version select register */
12005 bnx2x_cl45_read(bp
, phy_blk
[port
],
12007 MDIO_PMA_REG_EDC_FFE_MAIN
, &val
);
12008 bnx2x_cl45_write(bp
, phy_blk
[port
],
12010 MDIO_PMA_REG_EDC_FFE_MAIN
, (val
| (1<<12)));
12012 /* set GPIO2 back to LOW */
12013 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_2
,
12014 MISC_REGISTERS_GPIO_OUTPUT_LOW
, port
);
12018 static int bnx2x_8726_common_init_phy(struct bnx2x
*bp
,
12019 u32 shmem_base_path
[],
12020 u32 shmem2_base_path
[], u8 phy_index
,
12025 struct bnx2x_phy phy
;
12026 /* Use port1 because of the static port-swap */
12027 /* Enable the module detection interrupt */
12028 val
= REG_RD(bp
, MISC_REG_GPIO_EVENT_EN
);
12029 val
|= ((1<<MISC_REGISTERS_GPIO_3
)|
12030 (1<<(MISC_REGISTERS_GPIO_3
+ MISC_REGISTERS_GPIO_PORT_SHIFT
)));
12031 REG_WR(bp
, MISC_REG_GPIO_EVENT_EN
, val
);
12033 bnx2x_ext_phy_hw_reset(bp
, 0);
12035 for (port
= 0; port
< PORT_MAX
; port
++) {
12036 u32 shmem_base
, shmem2_base
;
12038 /* In E2, same phy is using for port0 of the two paths */
12039 if (CHIP_IS_E1x(bp
)) {
12040 shmem_base
= shmem_base_path
[0];
12041 shmem2_base
= shmem2_base_path
[0];
12043 shmem_base
= shmem_base_path
[port
];
12044 shmem2_base
= shmem2_base_path
[port
];
12046 /* Extract the ext phy address for the port */
12047 if (bnx2x_populate_phy(bp
, phy_index
, shmem_base
, shmem2_base
,
12050 DP(NETIF_MSG_LINK
, "populate phy failed\n");
12055 bnx2x_cl45_write(bp
, &phy
,
12056 MDIO_PMA_DEVAD
, MDIO_PMA_REG_GEN_CTRL
, 0x0001);
12059 /* Set fault module detected LED on */
12060 bnx2x_set_gpio(bp
, MISC_REGISTERS_GPIO_0
,
12061 MISC_REGISTERS_GPIO_HIGH
,
12067 static void bnx2x_get_ext_phy_reset_gpio(struct bnx2x
*bp
, u32 shmem_base
,
12068 u8
*io_gpio
, u8
*io_port
)
12071 u32 phy_gpio_reset
= REG_RD(bp
, shmem_base
+
12072 offsetof(struct shmem_region
,
12073 dev_info
.port_hw_config
[PORT_0
].default_cfg
));
12074 switch (phy_gpio_reset
) {
12075 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0
:
12079 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0
:
12083 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0
:
12087 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0
:
12091 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1
:
12095 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1
:
12099 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1
:
12103 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1
:
12108 /* Don't override the io_gpio and io_port */
12113 static int bnx2x_8727_common_init_phy(struct bnx2x
*bp
,
12114 u32 shmem_base_path
[],
12115 u32 shmem2_base_path
[], u8 phy_index
,
12118 s8 port
, reset_gpio
;
12119 u32 swap_val
, swap_override
;
12120 struct bnx2x_phy phy
[PORT_MAX
];
12121 struct bnx2x_phy
*phy_blk
[PORT_MAX
];
12123 swap_val
= REG_RD(bp
, NIG_REG_PORT_SWAP
);
12124 swap_override
= REG_RD(bp
, NIG_REG_STRAP_OVERRIDE
);
12126 reset_gpio
= MISC_REGISTERS_GPIO_1
;
12130 * Retrieve the reset gpio/port which control the reset.
12131 * Default is GPIO1, PORT1
12133 bnx2x_get_ext_phy_reset_gpio(bp
, shmem_base_path
[0],
12134 (u8
*)&reset_gpio
, (u8
*)&port
);
12136 /* Calculate the port based on port swap */
12137 port
^= (swap_val
&& swap_override
);
12139 /* Initiate PHY reset*/
12140 bnx2x_set_gpio(bp
, reset_gpio
, MISC_REGISTERS_GPIO_OUTPUT_LOW
,
12143 bnx2x_set_gpio(bp
, reset_gpio
, MISC_REGISTERS_GPIO_OUTPUT_HIGH
,
12148 /* PART1 - Reset both phys */
12149 for (port
= PORT_MAX
- 1; port
>= PORT_0
; port
--) {
12150 u32 shmem_base
, shmem2_base
;
12152 /* In E2, same phy is using for port0 of the two paths */
12153 if (CHIP_IS_E1x(bp
)) {
12154 shmem_base
= shmem_base_path
[0];
12155 shmem2_base
= shmem2_base_path
[0];
12156 port_of_path
= port
;
12158 shmem_base
= shmem_base_path
[port
];
12159 shmem2_base
= shmem2_base_path
[port
];
12163 /* Extract the ext phy address for the port */
12164 if (bnx2x_populate_phy(bp
, phy_index
, shmem_base
, shmem2_base
,
12165 port_of_path
, &phy
[port
]) !=
12167 DP(NETIF_MSG_LINK
, "populate phy failed\n");
12170 /* disable attentions */
12171 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+
12173 (NIG_MASK_XGXS0_LINK_STATUS
|
12174 NIG_MASK_XGXS0_LINK10G
|
12175 NIG_MASK_SERDES0_LINK_STATUS
|
12179 /* Reset the phy */
12180 bnx2x_cl45_write(bp
, &phy
[port
],
12181 MDIO_PMA_DEVAD
, MDIO_PMA_REG_CTRL
, 1<<15);
12184 /* Add delay of 150ms after reset */
12186 if (phy
[PORT_0
].addr
& 0x1) {
12187 phy_blk
[PORT_0
] = &(phy
[PORT_1
]);
12188 phy_blk
[PORT_1
] = &(phy
[PORT_0
]);
12190 phy_blk
[PORT_0
] = &(phy
[PORT_0
]);
12191 phy_blk
[PORT_1
] = &(phy
[PORT_1
]);
12193 /* PART2 - Download firmware to both phys */
12194 for (port
= PORT_MAX
- 1; port
>= PORT_0
; port
--) {
12195 if (CHIP_IS_E1x(bp
))
12196 port_of_path
= port
;
12199 DP(NETIF_MSG_LINK
, "Loading spirom for phy address 0x%x\n",
12200 phy_blk
[port
]->addr
);
12201 if (bnx2x_8073_8727_external_rom_boot(bp
, phy_blk
[port
],
12204 /* Disable PHY transmitter output */
12205 bnx2x_cl45_write(bp
, phy_blk
[port
],
12207 MDIO_PMA_REG_TX_DISABLE
, 1);
12213 static int bnx2x_ext_phy_common_init(struct bnx2x
*bp
, u32 shmem_base_path
[],
12214 u32 shmem2_base_path
[], u8 phy_index
,
12215 u32 ext_phy_type
, u32 chip_id
)
12219 switch (ext_phy_type
) {
12220 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
:
12221 rc
= bnx2x_8073_common_init_phy(bp
, shmem_base_path
,
12223 phy_index
, chip_id
);
12225 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722
:
12226 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727
:
12227 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC
:
12228 rc
= bnx2x_8727_common_init_phy(bp
, shmem_base_path
,
12230 phy_index
, chip_id
);
12233 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
:
12235 * GPIO1 affects both ports, so there's need to pull
12236 * it for single port alone
12238 rc
= bnx2x_8726_common_init_phy(bp
, shmem_base_path
,
12240 phy_index
, chip_id
);
12242 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833
:
12244 * GPIO3's are linked, and so both need to be toggled
12245 * to obtain required 2us pulse.
12247 rc
= bnx2x_84833_common_init_phy(bp
, shmem_base_path
, chip_id
);
12249 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE
:
12254 "ext_phy 0x%x common init not required\n",
12260 netdev_err(bp
->dev
, "Warning: PHY was not initialized,"
12266 int bnx2x_common_init_phy(struct bnx2x
*bp
, u32 shmem_base_path
[],
12267 u32 shmem2_base_path
[], u32 chip_id
)
12272 u32 ext_phy_type
, ext_phy_config
;
12273 bnx2x_set_mdio_clk(bp
, chip_id
, PORT_0
);
12274 bnx2x_set_mdio_clk(bp
, chip_id
, PORT_1
);
12275 DP(NETIF_MSG_LINK
, "Begin common phy init\n");
12276 if (CHIP_IS_E3(bp
)) {
12278 val
= REG_RD(bp
, MISC_REG_GEN_PURP_HWG
);
12279 REG_WR(bp
, MISC_REG_GEN_PURP_HWG
, val
| 1);
12281 /* Check if common init was already done */
12282 phy_ver
= REG_RD(bp
, shmem_base_path
[0] +
12283 offsetof(struct shmem_region
,
12284 port_mb
[PORT_0
].ext_phy_fw_version
));
12286 DP(NETIF_MSG_LINK
, "Not doing common init; phy ver is 0x%x\n",
12291 /* Read the ext_phy_type for arbitrary port(0) */
12292 for (phy_index
= EXT_PHY1
; phy_index
< MAX_PHYS
;
12294 ext_phy_config
= bnx2x_get_ext_phy_config(bp
,
12295 shmem_base_path
[0],
12297 ext_phy_type
= XGXS_EXT_PHY_TYPE(ext_phy_config
);
12298 rc
|= bnx2x_ext_phy_common_init(bp
, shmem_base_path
,
12300 phy_index
, ext_phy_type
,
12306 static void bnx2x_check_over_curr(struct link_params
*params
,
12307 struct link_vars
*vars
)
12309 struct bnx2x
*bp
= params
->bp
;
12311 u8 port
= params
->port
;
12314 cfg_pin
= (REG_RD(bp
, params
->shmem_base
+
12315 offsetof(struct shmem_region
,
12316 dev_info
.port_hw_config
[port
].e3_cmn_pin_cfg1
)) &
12317 PORT_HW_CFG_E3_OVER_CURRENT_MASK
) >>
12318 PORT_HW_CFG_E3_OVER_CURRENT_SHIFT
;
12320 /* Ignore check if no external input PIN available */
12321 if (bnx2x_get_cfg_pin(bp
, cfg_pin
, &pin_val
) != 0)
12325 if ((vars
->phy_flags
& PHY_OVER_CURRENT_FLAG
) == 0) {
12326 netdev_err(bp
->dev
, "Error: Power fault on Port %d has"
12327 " been detected and the power to "
12328 "that SFP+ module has been removed"
12329 " to prevent failure of the card."
12330 " Please remove the SFP+ module and"
12331 " restart the system to clear this"
12334 vars
->phy_flags
|= PHY_OVER_CURRENT_FLAG
;
12337 vars
->phy_flags
&= ~PHY_OVER_CURRENT_FLAG
;
12340 static void bnx2x_analyze_link_error(struct link_params
*params
,
12341 struct link_vars
*vars
, u32 lss_status
)
12343 struct bnx2x
*bp
= params
->bp
;
12344 /* Compare new value with previous value */
12346 u32 half_open_conn
= (vars
->phy_flags
& PHY_HALF_OPEN_CONN_FLAG
) > 0;
12348 if ((lss_status
^ half_open_conn
) == 0)
12351 /* If values differ */
12352 DP(NETIF_MSG_LINK
, "Link changed:%x %x->%x\n", vars
->link_up
,
12353 half_open_conn
, lss_status
);
12356 * a. Update shmem->link_status accordingly
12357 * b. Update link_vars->link_up
12360 DP(NETIF_MSG_LINK
, "Remote Fault detected !!!\n");
12361 vars
->link_status
&= ~LINK_STATUS_LINK_UP
;
12363 vars
->phy_flags
|= PHY_HALF_OPEN_CONN_FLAG
;
12365 * Set LED mode to off since the PHY doesn't know about these
12368 led_mode
= LED_MODE_OFF
;
12370 DP(NETIF_MSG_LINK
, "Remote Fault cleared\n");
12371 vars
->link_status
|= LINK_STATUS_LINK_UP
;
12373 vars
->phy_flags
&= ~PHY_HALF_OPEN_CONN_FLAG
;
12374 led_mode
= LED_MODE_OPER
;
12376 /* Update the LED according to the link state */
12377 bnx2x_set_led(params
, vars
, led_mode
, SPEED_10000
);
12379 /* Update link status in the shared memory */
12380 bnx2x_update_mng(params
, vars
->link_status
);
12382 /* C. Trigger General Attention */
12383 vars
->periodic_flags
|= PERIODIC_FLAGS_LINK_EVENT
;
12384 bnx2x_notify_link_changed(bp
);
12387 /******************************************************************************
12389 * This function checks for half opened connection change indication.
12390 * When such change occurs, it calls the bnx2x_analyze_link_error
12391 * to check if Remote Fault is set or cleared. Reception of remote fault
12392 * status message in the MAC indicates that the peer's MAC has detected
12393 * a fault, for example, due to break in the TX side of fiber.
12395 ******************************************************************************/
12396 static void bnx2x_check_half_open_conn(struct link_params
*params
,
12397 struct link_vars
*vars
)
12399 struct bnx2x
*bp
= params
->bp
;
12400 u32 lss_status
= 0;
12402 /* In case link status is physically up @ 10G do */
12403 if ((vars
->phy_flags
& PHY_PHYSICAL_LINK_FLAG
) == 0)
12406 if (CHIP_IS_E3(bp
) &&
12407 (REG_RD(bp
, MISC_REG_RESET_REG_2
) &
12408 (MISC_REGISTERS_RESET_REG_2_XMAC
))) {
12409 /* Check E3 XMAC */
12411 * Note that link speed cannot be queried here, since it may be
12412 * zero while link is down. In case UMAC is active, LSS will
12413 * simply not be set
12415 mac_base
= (params
->port
) ? GRCBASE_XMAC1
: GRCBASE_XMAC0
;
12417 /* Clear stick bits (Requires rising edge) */
12418 REG_WR(bp
, mac_base
+ XMAC_REG_CLEAR_RX_LSS_STATUS
, 0);
12419 REG_WR(bp
, mac_base
+ XMAC_REG_CLEAR_RX_LSS_STATUS
,
12420 XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS
|
12421 XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS
);
12422 if (REG_RD(bp
, mac_base
+ XMAC_REG_RX_LSS_STATUS
))
12425 bnx2x_analyze_link_error(params
, vars
, lss_status
);
12426 } else if (REG_RD(bp
, MISC_REG_RESET_REG_2
) &
12427 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0
<< params
->port
)) {
12428 /* Check E1X / E2 BMAC */
12429 u32 lss_status_reg
;
12431 mac_base
= params
->port
? NIG_REG_INGRESS_BMAC1_MEM
:
12432 NIG_REG_INGRESS_BMAC0_MEM
;
12433 /* Read BIGMAC_REGISTER_RX_LSS_STATUS */
12434 if (CHIP_IS_E2(bp
))
12435 lss_status_reg
= BIGMAC2_REGISTER_RX_LSS_STAT
;
12437 lss_status_reg
= BIGMAC_REGISTER_RX_LSS_STATUS
;
12439 REG_RD_DMAE(bp
, mac_base
+ lss_status_reg
, wb_data
, 2);
12440 lss_status
= (wb_data
[0] > 0);
12442 bnx2x_analyze_link_error(params
, vars
, lss_status
);
12446 void bnx2x_period_func(struct link_params
*params
, struct link_vars
*vars
)
12448 struct bnx2x
*bp
= params
->bp
;
12450 for (phy_idx
= INT_PHY
; phy_idx
< MAX_PHYS
; phy_idx
++) {
12451 if (params
->phy
[phy_idx
].flags
& FLAGS_TX_ERROR_CHECK
) {
12452 bnx2x_set_aer_mmd(params
, ¶ms
->phy
[phy_idx
]);
12453 bnx2x_check_half_open_conn(params
, vars
);
12458 if (CHIP_IS_E3(bp
)) {
12459 struct bnx2x_phy
*phy
= ¶ms
->phy
[INT_PHY
];
12460 bnx2x_set_aer_mmd(params
, phy
);
12461 bnx2x_check_over_curr(params
, vars
);
12462 bnx2x_warpcore_config_runtime(phy
, params
, vars
);
12467 u8
bnx2x_hw_lock_required(struct bnx2x
*bp
, u32 shmem_base
, u32 shmem2_base
)
12470 struct bnx2x_phy phy
;
12471 for (phy_index
= INT_PHY
; phy_index
< MAX_PHYS
;
12473 if (bnx2x_populate_phy(bp
, phy_index
, shmem_base
, shmem2_base
,
12475 DP(NETIF_MSG_LINK
, "populate phy failed\n");
12479 if (phy
.flags
& FLAGS_HW_LOCK_REQUIRED
)
12485 u8
bnx2x_fan_failure_det_req(struct bnx2x
*bp
,
12490 u8 phy_index
, fan_failure_det_req
= 0;
12491 struct bnx2x_phy phy
;
12492 for (phy_index
= EXT_PHY1
; phy_index
< MAX_PHYS
;
12494 if (bnx2x_populate_phy(bp
, phy_index
, shmem_base
, shmem2_base
,
12497 DP(NETIF_MSG_LINK
, "populate phy failed\n");
12500 fan_failure_det_req
|= (phy
.flags
&
12501 FLAGS_FAN_FAILURE_DET_REQ
);
12503 return fan_failure_det_req
;
12506 void bnx2x_hw_reset_phy(struct link_params
*params
)
12509 struct bnx2x
*bp
= params
->bp
;
12510 bnx2x_update_mng(params
, 0);
12511 bnx2x_bits_dis(bp
, NIG_REG_MASK_INTERRUPT_PORT0
+ params
->port
*4,
12512 (NIG_MASK_XGXS0_LINK_STATUS
|
12513 NIG_MASK_XGXS0_LINK10G
|
12514 NIG_MASK_SERDES0_LINK_STATUS
|
12517 for (phy_index
= INT_PHY
; phy_index
< MAX_PHYS
;
12519 if (params
->phy
[phy_index
].hw_reset
) {
12520 params
->phy
[phy_index
].hw_reset(
12521 ¶ms
->phy
[phy_index
],
12523 params
->phy
[phy_index
] = phy_null
;
12528 void bnx2x_init_mod_abs_int(struct bnx2x
*bp
, struct link_vars
*vars
,
12529 u32 chip_id
, u32 shmem_base
, u32 shmem2_base
,
12532 u8 gpio_num
= 0xff, gpio_port
= 0xff, phy_index
;
12534 u32 offset
, aeu_mask
, swap_val
, swap_override
, sync_offset
;
12535 if (CHIP_IS_E3(bp
)) {
12536 if (bnx2x_get_mod_abs_int_cfg(bp
, chip_id
,
12543 struct bnx2x_phy phy
;
12544 for (phy_index
= EXT_PHY1
; phy_index
< MAX_PHYS
;
12546 if (bnx2x_populate_phy(bp
, phy_index
, shmem_base
,
12547 shmem2_base
, port
, &phy
)
12549 DP(NETIF_MSG_LINK
, "populate phy failed\n");
12552 if (phy
.type
== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
) {
12553 gpio_num
= MISC_REGISTERS_GPIO_3
;
12560 if (gpio_num
== 0xff)
12563 /* Set GPIO3 to trigger SFP+ module insertion/removal */
12564 bnx2x_set_gpio(bp
, gpio_num
, MISC_REGISTERS_GPIO_INPUT_HI_Z
, gpio_port
);
12566 swap_val
= REG_RD(bp
, NIG_REG_PORT_SWAP
);
12567 swap_override
= REG_RD(bp
, NIG_REG_STRAP_OVERRIDE
);
12568 gpio_port
^= (swap_val
&& swap_override
);
12570 vars
->aeu_int_mask
= AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0
<<
12571 (gpio_num
+ (gpio_port
<< 2));
12573 sync_offset
= shmem_base
+
12574 offsetof(struct shmem_region
,
12575 dev_info
.port_hw_config
[port
].aeu_int_mask
);
12576 REG_WR(bp
, sync_offset
, vars
->aeu_int_mask
);
12578 DP(NETIF_MSG_LINK
, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x\n",
12579 gpio_num
, gpio_port
, vars
->aeu_int_mask
);
12582 offset
= MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0
;
12584 offset
= MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0
;
12586 /* Open appropriate AEU for interrupts */
12587 aeu_mask
= REG_RD(bp
, offset
);
12588 aeu_mask
|= vars
->aeu_int_mask
;
12589 REG_WR(bp
, offset
, aeu_mask
);
12591 /* Enable the GPIO to trigger interrupt */
12592 val
= REG_RD(bp
, MISC_REG_GPIO_EVENT_EN
);
12593 val
|= 1 << (gpio_num
+ (gpio_port
<< 2));
12594 REG_WR(bp
, MISC_REG_GPIO_EVENT_EN
, val
);