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 /***********************************************************/
49 /* Shortcut definitions */
50 /***********************************************************/
52 #define NIG_LATCH_BC_ENABLE_MI_INT 0
54 #define NIG_STATUS_EMAC0_MI_INT \
55 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
56 #define NIG_STATUS_XGXS0_LINK10G \
57 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
58 #define NIG_STATUS_XGXS0_LINK_STATUS \
59 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
60 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
61 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
62 #define NIG_STATUS_SERDES0_LINK_STATUS \
63 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
64 #define NIG_MASK_MI_INT \
65 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
66 #define NIG_MASK_XGXS0_LINK10G \
67 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
68 #define NIG_MASK_XGXS0_LINK_STATUS \
69 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
70 #define NIG_MASK_SERDES0_LINK_STATUS \
71 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
73 #define MDIO_AN_CL73_OR_37_COMPLETE \
74 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
75 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
77 #define XGXS_RESET_BITS \
78 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
79 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
80 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
81 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
82 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
84 #define SERDES_RESET_BITS \
85 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
86 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
87 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
88 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
90 #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
91 #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
92 #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
93 #define AUTONEG_PARALLEL \
94 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
95 #define AUTONEG_SGMII_FIBER_AUTODET \
96 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
97 #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
99 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
100 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
101 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
102 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
103 #define GP_STATUS_SPEED_MASK \
104 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
105 #define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
106 #define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
107 #define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
108 #define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
109 #define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
110 #define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
111 #define GP_STATUS_10G_HIG \
112 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
113 #define GP_STATUS_10G_CX4 \
114 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
115 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
116 #define GP_STATUS_10G_KX4 \
117 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
118 #define GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR
119 #define GP_STATUS_10G_XFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI
120 #define GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS
121 #define GP_STATUS_10G_SFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI
122 #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
123 #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
124 #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
125 #define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
126 #define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
127 #define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
128 #define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
129 #define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
130 #define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
131 #define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
132 #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
133 #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
134 #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
135 #define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
136 #define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
141 #define SFP_EEPROM_CON_TYPE_ADDR 0x2
142 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
143 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
146 #define SFP_EEPROM_COMP_CODE_ADDR 0x3
147 #define SFP_EEPROM_COMP_CODE_SR_MASK (1<<4)
148 #define SFP_EEPROM_COMP_CODE_LR_MASK (1<<5)
149 #define SFP_EEPROM_COMP_CODE_LRM_MASK (1<<6)
151 #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
152 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
153 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
155 #define SFP_EEPROM_OPTIONS_ADDR 0x40
156 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
157 #define SFP_EEPROM_OPTIONS_SIZE 2
159 #define EDC_MODE_LINEAR 0x0022
160 #define EDC_MODE_LIMITING 0x0044
161 #define EDC_MODE_PASSIVE_DAC 0x0055
164 /* BRB thresholds for E2*/
165 #define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE 170
166 #define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0
168 #define PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE 250
169 #define PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0
171 #define PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE 10
172 #define PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 90
174 #define PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE 50
175 #define PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE 250
177 /* BRB thresholds for E3A0 */
178 #define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE 290
179 #define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0
181 #define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE 410
182 #define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0
184 #define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE 10
185 #define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 170
187 #define PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE 50
188 #define PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE 410
191 /* BRB thresholds for E3B0 2 port mode*/
192 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE 1025
193 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0
195 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE 1025
196 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0
198 #define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE 10
199 #define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 1025
201 #define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE 50
202 #define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE 1025
205 #define PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR 1025
206 #define PFC_E3B0_2P_BRB_FULL_LB_XON_THR 1025
208 /* Lossy +Lossless GUARANTIED == GUART */
209 #define PFC_E3B0_2P_MIX_PAUSE_LB_GUART 284
210 /* Lossless +Lossless*/
211 #define PFC_E3B0_2P_PAUSE_LB_GUART 236
213 #define PFC_E3B0_2P_NON_PAUSE_LB_GUART 342
216 #define PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART 284
217 /* Lossless +Lossless*/
218 #define PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART 236
220 #define PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART 336
221 #define PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST 80
223 #define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART 0
224 #define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST 0
226 /* BRB thresholds for E3B0 4 port mode */
227 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE 304
228 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0
230 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE 384
231 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0
233 #define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE 10
234 #define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 304
236 #define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE 50
237 #define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE 384
241 #define PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR 304
242 #define PFC_E3B0_4P_BRB_FULL_LB_XON_THR 384
243 #define PFC_E3B0_4P_LB_GUART 120
245 #define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART 120
246 #define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST 80
248 #define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART 80
249 #define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST 120
251 #define DCBX_INVALID_COS (0xFF)
253 #define ETS_BW_LIMIT_CREDIT_UPPER_BOUND (0x5000)
254 #define ETS_BW_LIMIT_CREDIT_WEIGHT (0x5000)
255 #define ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS (1360)
256 #define ETS_E3B0_NIG_MIN_W_VAL_20GBPS (2720)
257 #define ETS_E3B0_PBF_MIN_W_VAL (10000)
259 #define MAX_PACKET_SIZE (9700)
260 #define WC_UC_TIMEOUT 100
262 /**********************************************************/
264 /**********************************************************/
266 #define CL22_WR_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
267 bnx2x_cl45_write(_bp, _phy, \
268 (_phy)->def_md_devad, \
269 (_bank + (_addr & 0xf)), \
272 #define CL22_RD_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
273 bnx2x_cl45_read(_bp, _phy, \
274 (_phy)->def_md_devad, \
275 (_bank + (_addr & 0xf)), \
278 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
280 u32 val = REG_RD(bp, reg);
283 REG_WR(bp, reg, val);
287 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
289 u32 val = REG_RD(bp, reg);
292 REG_WR(bp, reg, val);
296 /******************************************************************/
297 /* EPIO/GPIO section */
298 /******************************************************************/
299 static void bnx2x_set_epio(struct bnx2x *bp, u32 epio_pin, u32 en)
301 u32 epio_mask, gp_output, gp_oenable;
305 DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to set\n", epio_pin);
308 DP(NETIF_MSG_LINK, "Setting EPIO pin %d to %d\n", epio_pin, en);
309 epio_mask = 1 << epio_pin;
310 /* Set this EPIO to output */
311 gp_output = REG_RD(bp, MCP_REG_MCPR_GP_OUTPUTS);
313 gp_output |= epio_mask;
315 gp_output &= ~epio_mask;
317 REG_WR(bp, MCP_REG_MCPR_GP_OUTPUTS, gp_output);
319 /* Set the value for this EPIO */
320 gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE);
321 REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask);
324 static void bnx2x_set_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 val)
326 if (pin_cfg == PIN_CFG_NA)
328 if (pin_cfg >= PIN_CFG_EPIO0) {
329 bnx2x_set_epio(bp, pin_cfg - PIN_CFG_EPIO0, val);
331 u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
332 u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
333 bnx2x_set_gpio(bp, gpio_num, (u8)val, gpio_port);
337 /******************************************************************/
339 /******************************************************************/
340 static void bnx2x_ets_e2e3a0_disabled(struct link_params *params)
342 /* ETS disabled configuration*/
343 struct bnx2x *bp = params->bp;
345 DP(NETIF_MSG_LINK, "ETS E2E3 disabled configuration\n");
348 * mapping between entry priority to client number (0,1,2 -debug and
349 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
351 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
352 * cos1-100 cos0-011 dbg1-010 dbg0-001 MCP-000
355 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
357 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
358 * as strict. Bits 0,1,2 - debug and management entries, 3 -
359 * COS0 entry, 4 - COS1 entry.
360 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
361 * bit4 bit3 bit2 bit1 bit0
362 * MCP and debug are strict
365 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
366 /* defines which entries (clients) are subjected to WFQ arbitration */
367 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
369 * For strict priority entries defines the number of consecutive
370 * slots for the highest priority.
372 REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
374 * mapping between the CREDIT_WEIGHT registers and actual client
377 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
378 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
379 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
381 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
382 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
383 REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
384 /* ETS mode disable */
385 REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
387 * If ETS mode is enabled (there is no strict priority) defines a WFQ
388 * weight for COS0/COS1.
390 REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
391 REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710);
392 /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
393 REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680);
394 REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680);
395 /* Defines the number of consecutive slots for the strict priority */
396 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
398 /******************************************************************************
400 * Getting min_w_val will be set according to line speed .
402 ******************************************************************************/
403 static u32 bnx2x_ets_get_min_w_val_nig(const struct link_vars *vars)
406 /* Calculate min_w_val.*/
408 if (SPEED_20000 == vars->line_speed)
409 min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
411 min_w_val = ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS;
413 min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
415 * If the link isn't up (static configuration for example ) The
416 * link will be according to 20GBPS.
420 /******************************************************************************
422 * Getting credit upper bound form min_w_val.
424 ******************************************************************************/
425 static u32 bnx2x_ets_get_credit_upper_bound(const u32 min_w_val)
427 const u32 credit_upper_bound = (u32)MAXVAL((150 * min_w_val),
429 return credit_upper_bound;
431 /******************************************************************************
433 * Set credit upper bound for NIG.
435 ******************************************************************************/
436 static void bnx2x_ets_e3b0_set_credit_upper_bound_nig(
437 const struct link_params *params,
440 struct bnx2x *bp = params->bp;
441 const u8 port = params->port;
442 const u32 credit_upper_bound =
443 bnx2x_ets_get_credit_upper_bound(min_w_val);
445 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_0 :
446 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, credit_upper_bound);
447 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_1 :
448 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, credit_upper_bound);
449 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_2 :
450 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_2, credit_upper_bound);
451 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_3 :
452 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_3, credit_upper_bound);
453 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_4 :
454 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_4, credit_upper_bound);
455 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_5 :
456 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_5, credit_upper_bound);
459 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_6,
461 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_7,
463 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_8,
467 /******************************************************************************
469 * Will return the NIG ETS registers to init values.Except
470 * credit_upper_bound.
471 * That isn't used in this configuration (No WFQ is enabled) and will be
472 * configured acording to spec
474 ******************************************************************************/
475 static void bnx2x_ets_e3b0_nig_disabled(const struct link_params *params,
476 const struct link_vars *vars)
478 struct bnx2x *bp = params->bp;
479 const u8 port = params->port;
480 const u32 min_w_val = bnx2x_ets_get_min_w_val_nig(vars);
482 * mapping between entry priority to client number (0,1,2 -debug and
483 * management clients, 3 - COS0 client, 4 - COS1, ... 8 -
484 * COS5)(HIGHEST) 4bits client num.TODO_ETS - Should be done by
485 * reset value or init tool
488 REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB, 0x543210);
489 REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB, 0x0);
491 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, 0x76543210);
492 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, 0x8);
495 * For strict priority entries defines the number of consecutive
496 * slots for the highest priority.
498 /* TODO_ETS - Should be done by reset value or init tool */
499 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS :
500 NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
502 * mapping between the CREDIT_WEIGHT registers and actual client
505 /* TODO_ETS - Should be done by reset value or init tool */
508 REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB, 0x210543);
509 REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x0);
512 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_LSB,
514 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x5);
518 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
519 * as strict. Bits 0,1,2 - debug and management entries, 3 -
520 * COS0 entry, 4 - COS1 entry.
521 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
522 * bit4 bit3 bit2 bit1 bit0
523 * MCP and debug are strict
526 REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT, 0x3f);
528 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1ff);
529 /* defines which entries (clients) are subjected to WFQ arbitration */
530 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
531 NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
534 * Please notice the register address are note continuous and a
535 * for here is note appropriate.In 2 port mode port0 only COS0-5
536 * can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4
537 * port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT
538 * are never used for WFQ
540 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
541 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0x0);
542 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
543 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0x0);
544 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
545 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2, 0x0);
546 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_3 :
547 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3, 0x0);
548 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_4 :
549 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4, 0x0);
550 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_5 :
551 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5, 0x0);
553 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_6, 0x0);
554 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_7, 0x0);
555 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_8, 0x0);
558 bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val);
560 /******************************************************************************
562 * Set credit upper bound for PBF.
564 ******************************************************************************/
565 static void bnx2x_ets_e3b0_set_credit_upper_bound_pbf(
566 const struct link_params *params,
569 struct bnx2x *bp = params->bp;
570 const u32 credit_upper_bound =
571 bnx2x_ets_get_credit_upper_bound(min_w_val);
572 const u8 port = params->port;
573 u32 base_upper_bound = 0;
577 * In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4
578 * port mode port1 has COS0-2 that can be used for WFQ.
581 base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P0;
582 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0;
584 base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P1;
585 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1;
588 for (i = 0; i < max_cos; i++)
589 REG_WR(bp, base_upper_bound + (i << 2), credit_upper_bound);
592 /******************************************************************************
594 * Will return the PBF ETS registers to init values.Except
595 * credit_upper_bound.
596 * That isn't used in this configuration (No WFQ is enabled) and will be
597 * configured acording to spec
599 ******************************************************************************/
600 static void bnx2x_ets_e3b0_pbf_disabled(const struct link_params *params)
602 struct bnx2x *bp = params->bp;
603 const u8 port = params->port;
604 const u32 min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL;
610 * mapping between entry priority to client number 0 - COS0
611 * client, 2 - COS1, ... 5 - COS5)(HIGHEST) 4bits client num.
612 * TODO_ETS - Should be done by reset value or init tool
615 /* 0x688 (|011|0 10|00 1|000) */
616 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , 0x688);
618 /* (10 1|100 |011|0 10|00 1|000) */
619 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , 0x2C688);
621 /* TODO_ETS - Should be done by reset value or init tool */
623 /* 0x688 (|011|0 10|00 1|000)*/
624 REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P1, 0x688);
626 /* 0x2C688 (10 1|100 |011|0 10|00 1|000) */
627 REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P0, 0x2C688);
629 REG_WR(bp, (port) ? PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P1 :
630 PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P0 , 0x100);
633 REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
634 PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , 0);
636 REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
637 PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0 , 0);
639 * In 2 port mode port0 has COS0-5 that can be used for WFQ.
640 * In 4 port mode port1 has COS0-2 that can be used for WFQ.
643 base_weight = PBF_REG_COS0_WEIGHT_P0;
644 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0;
646 base_weight = PBF_REG_COS0_WEIGHT_P1;
647 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1;
650 for (i = 0; i < max_cos; i++)
651 REG_WR(bp, base_weight + (0x4 * i), 0);
653 bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
655 /******************************************************************************
657 * E3B0 disable will return basicly the values to init values.
659 ******************************************************************************/
660 static int bnx2x_ets_e3b0_disabled(const struct link_params *params,
661 const struct link_vars *vars)
663 struct bnx2x *bp = params->bp;
665 if (!CHIP_IS_E3B0(bp)) {
666 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_disabled the chip isn't E3B0"
671 bnx2x_ets_e3b0_nig_disabled(params, vars);
673 bnx2x_ets_e3b0_pbf_disabled(params);
678 /******************************************************************************
680 * Disable will return basicly the values to init values.
682 ******************************************************************************/
683 int bnx2x_ets_disabled(struct link_params *params,
684 struct link_vars *vars)
686 struct bnx2x *bp = params->bp;
687 int bnx2x_status = 0;
689 if ((CHIP_IS_E2(bp)) || (CHIP_IS_E3A0(bp)))
690 bnx2x_ets_e2e3a0_disabled(params);
691 else if (CHIP_IS_E3B0(bp))
692 bnx2x_status = bnx2x_ets_e3b0_disabled(params, vars);
694 DP(NETIF_MSG_LINK, "bnx2x_ets_disabled - chip not supported\n");
701 /******************************************************************************
703 * Set the COS mappimg to SP and BW until this point all the COS are not
705 ******************************************************************************/
706 static int bnx2x_ets_e3b0_cli_map(const struct link_params *params,
707 const struct bnx2x_ets_params *ets_params,
708 const u8 cos_sp_bitmap,
709 const u8 cos_bw_bitmap)
711 struct bnx2x *bp = params->bp;
712 const u8 port = params->port;
713 const u8 nig_cli_sp_bitmap = 0x7 | (cos_sp_bitmap << 3);
714 const u8 pbf_cli_sp_bitmap = cos_sp_bitmap;
715 const u8 nig_cli_subject2wfq_bitmap = cos_bw_bitmap << 3;
716 const u8 pbf_cli_subject2wfq_bitmap = cos_bw_bitmap;
718 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT :
719 NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, nig_cli_sp_bitmap);
721 REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
722 PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , pbf_cli_sp_bitmap);
724 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
725 NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ,
726 nig_cli_subject2wfq_bitmap);
728 REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
729 PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0,
730 pbf_cli_subject2wfq_bitmap);
735 /******************************************************************************
737 * This function is needed because NIG ARB_CREDIT_WEIGHT_X are
738 * not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
739 ******************************************************************************/
740 static int bnx2x_ets_e3b0_set_cos_bw(struct bnx2x *bp,
742 const u32 min_w_val_nig,
743 const u32 min_w_val_pbf,
748 u32 nig_reg_adress_crd_weight = 0;
749 u32 pbf_reg_adress_crd_weight = 0;
750 /* Calculate and set BW for this COS*/
751 const u32 cos_bw_nig = (bw * min_w_val_nig) / total_bw;
752 const u32 cos_bw_pbf = (bw * min_w_val_pbf) / total_bw;
756 nig_reg_adress_crd_weight =
757 (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
758 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0;
759 pbf_reg_adress_crd_weight = (port) ?
760 PBF_REG_COS0_WEIGHT_P1 : PBF_REG_COS0_WEIGHT_P0;
763 nig_reg_adress_crd_weight = (port) ?
764 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
765 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1;
766 pbf_reg_adress_crd_weight = (port) ?
767 PBF_REG_COS1_WEIGHT_P1 : PBF_REG_COS1_WEIGHT_P0;
770 nig_reg_adress_crd_weight = (port) ?
771 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
772 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2;
774 pbf_reg_adress_crd_weight = (port) ?
775 PBF_REG_COS2_WEIGHT_P1 : PBF_REG_COS2_WEIGHT_P0;
780 nig_reg_adress_crd_weight =
781 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3;
782 pbf_reg_adress_crd_weight =
783 PBF_REG_COS3_WEIGHT_P0;
788 nig_reg_adress_crd_weight =
789 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4;
790 pbf_reg_adress_crd_weight = PBF_REG_COS4_WEIGHT_P0;
795 nig_reg_adress_crd_weight =
796 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5;
797 pbf_reg_adress_crd_weight = PBF_REG_COS5_WEIGHT_P0;
801 REG_WR(bp, nig_reg_adress_crd_weight, cos_bw_nig);
803 REG_WR(bp, pbf_reg_adress_crd_weight, cos_bw_pbf);
807 /******************************************************************************
809 * Calculate the total BW.A value of 0 isn't legal.
811 ******************************************************************************/
812 static int bnx2x_ets_e3b0_get_total_bw(
813 const struct link_params *params,
814 const struct bnx2x_ets_params *ets_params,
817 struct bnx2x *bp = params->bp;
821 /* Calculate total BW requested */
822 for (cos_idx = 0; cos_idx < ets_params->num_of_cos; cos_idx++) {
823 if (bnx2x_cos_state_bw == ets_params->cos[cos_idx].state) {
825 if (0 == ets_params->cos[cos_idx].params.bw_params.bw) {
826 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config BW"
831 ets_params->cos[cos_idx].params.bw_params.bw;
835 /*Check taotl BW is valid */
836 if ((100 != *total_bw) || (0 == *total_bw)) {
837 if (0 == *total_bw) {
838 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config toatl BW"
842 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config toatl BW should be"
845 * We can handle a case whre the BW isn't 100 this can happen
846 * if the TC are joined.
852 /******************************************************************************
854 * Invalidate all the sp_pri_to_cos.
856 ******************************************************************************/
857 static void bnx2x_ets_e3b0_sp_pri_to_cos_init(u8 *sp_pri_to_cos)
860 for (pri = 0; pri < DCBX_MAX_NUM_COS; pri++)
861 sp_pri_to_cos[pri] = DCBX_INVALID_COS;
863 /******************************************************************************
865 * Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
866 * according to sp_pri_to_cos.
868 ******************************************************************************/
869 static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,
870 u8 *sp_pri_to_cos, const u8 pri,
873 struct bnx2x *bp = params->bp;
874 const u8 port = params->port;
875 const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
876 DCBX_E3B0_MAX_NUM_COS_PORT0;
878 if (DCBX_INVALID_COS != sp_pri_to_cos[pri]) {
879 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
880 "parameter There can't be two COS's with"
881 "the same strict pri\n");
885 if (pri > max_num_of_cos) {
886 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid"
887 "parameter Illegal strict priority\n");
891 sp_pri_to_cos[pri] = cos_entry;
896 /******************************************************************************
898 * Returns the correct value according to COS and priority in
899 * the sp_pri_cli register.
901 ******************************************************************************/
902 static u64 bnx2x_e3b0_sp_get_pri_cli_reg(const u8 cos, const u8 cos_offset,
908 pri_cli_nig = ((u64)(cos + cos_offset)) << (entry_size *
909 (pri_set + pri_offset));
913 /******************************************************************************
915 * Returns the correct value according to COS and priority in the
916 * sp_pri_cli register for NIG.
918 ******************************************************************************/
919 static u64 bnx2x_e3b0_sp_get_pri_cli_reg_nig(const u8 cos, const u8 pri_set)
921 /* MCP Dbg0 and dbg1 are always with higher strict pri*/
922 const u8 nig_cos_offset = 3;
923 const u8 nig_pri_offset = 3;
925 return bnx2x_e3b0_sp_get_pri_cli_reg(cos, nig_cos_offset, pri_set,
929 /******************************************************************************
931 * Returns the correct value according to COS and priority in the
932 * sp_pri_cli register for PBF.
934 ******************************************************************************/
935 static u64 bnx2x_e3b0_sp_get_pri_cli_reg_pbf(const u8 cos, const u8 pri_set)
937 const u8 pbf_cos_offset = 0;
938 const u8 pbf_pri_offset = 0;
940 return bnx2x_e3b0_sp_get_pri_cli_reg(cos, pbf_cos_offset, pri_set,
945 /******************************************************************************
947 * Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
948 * according to sp_pri_to_cos.(which COS has higher priority)
950 ******************************************************************************/
951 static int bnx2x_ets_e3b0_sp_set_pri_cli_reg(const struct link_params *params,
954 struct bnx2x *bp = params->bp;
956 const u8 port = params->port;
957 /* MCP Dbg0 and dbg1 are always with higher strict pri*/
958 u64 pri_cli_nig = 0x210;
959 u32 pri_cli_pbf = 0x0;
962 const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
963 DCBX_E3B0_MAX_NUM_COS_PORT0;
965 u8 cos_bit_to_set = (1 << max_num_of_cos) - 1;
967 /* Set all the strict priority first */
968 for (i = 0; i < max_num_of_cos; i++) {
969 if (DCBX_INVALID_COS != sp_pri_to_cos[i]) {
970 if (DCBX_MAX_NUM_COS <= sp_pri_to_cos[i]) {
972 "bnx2x_ets_e3b0_sp_set_pri_cli_reg "
973 "invalid cos entry\n");
977 pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
978 sp_pri_to_cos[i], pri_set);
980 pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
981 sp_pri_to_cos[i], pri_set);
982 pri_bitmask = 1 << sp_pri_to_cos[i];
983 /* COS is used remove it from bitmap.*/
984 if (0 == (pri_bitmask & cos_bit_to_set)) {
986 "bnx2x_ets_e3b0_sp_set_pri_cli_reg "
987 "invalid There can't be two COS's with"
988 " the same strict pri\n");
991 cos_bit_to_set &= ~pri_bitmask;
996 /* Set all the Non strict priority i= COS*/
997 for (i = 0; i < max_num_of_cos; i++) {
998 pri_bitmask = 1 << i;
999 /* Check if COS was already used for SP */
1000 if (pri_bitmask & cos_bit_to_set) {
1001 /* COS wasn't used for SP */
1002 pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
1005 pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
1007 /* COS is used remove it from bitmap.*/
1008 cos_bit_to_set &= ~pri_bitmask;
1013 if (pri_set != max_num_of_cos) {
1014 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_set_pri_cli_reg not all "
1015 "entries were set\n");
1020 /* Only 6 usable clients*/
1021 REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB,
1024 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , pri_cli_pbf);
1026 /* Only 9 usable clients*/
1027 const u32 pri_cli_nig_lsb = (u32) (pri_cli_nig);
1028 const u32 pri_cli_nig_msb = (u32) ((pri_cli_nig >> 32) & 0xF);
1030 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB,
1032 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB,
1035 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , pri_cli_pbf);
1040 /******************************************************************************
1042 * Configure the COS to ETS according to BW and SP settings.
1043 ******************************************************************************/
1044 int bnx2x_ets_e3b0_config(const struct link_params *params,
1045 const struct link_vars *vars,
1046 const struct bnx2x_ets_params *ets_params)
1048 struct bnx2x *bp = params->bp;
1049 int bnx2x_status = 0;
1050 const u8 port = params->port;
1052 const u32 min_w_val_nig = bnx2x_ets_get_min_w_val_nig(vars);
1053 const u32 min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL;
1054 u8 cos_bw_bitmap = 0;
1055 u8 cos_sp_bitmap = 0;
1056 u8 sp_pri_to_cos[DCBX_MAX_NUM_COS] = {0};
1057 const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
1058 DCBX_E3B0_MAX_NUM_COS_PORT0;
1061 if (!CHIP_IS_E3B0(bp)) {
1062 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_disabled the chip isn't E3B0"
1067 if ((ets_params->num_of_cos > max_num_of_cos)) {
1068 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config the number of COS "
1069 "isn't supported\n");
1073 /* Prepare sp strict priority parameters*/
1074 bnx2x_ets_e3b0_sp_pri_to_cos_init(sp_pri_to_cos);
1076 /* Prepare BW parameters*/
1077 bnx2x_status = bnx2x_ets_e3b0_get_total_bw(params, ets_params,
1079 if (0 != bnx2x_status) {
1080 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config get_total_bw failed "
1086 * Upper bound is set according to current link speed (min_w_val
1087 * should be the same for upper bound and COS credit val).
1089 bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val_nig);
1090 bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
1093 for (cos_entry = 0; cos_entry < ets_params->num_of_cos; cos_entry++) {
1094 if (bnx2x_cos_state_bw == ets_params->cos[cos_entry].state) {
1095 cos_bw_bitmap |= (1 << cos_entry);
1097 * The function also sets the BW in HW(not the mappin
1100 bnx2x_status = bnx2x_ets_e3b0_set_cos_bw(
1101 bp, cos_entry, min_w_val_nig, min_w_val_pbf,
1103 ets_params->cos[cos_entry].params.bw_params.bw,
1105 } else if (bnx2x_cos_state_strict ==
1106 ets_params->cos[cos_entry].state){
1107 cos_sp_bitmap |= (1 << cos_entry);
1109 bnx2x_status = bnx2x_ets_e3b0_sp_pri_to_cos_set(
1112 ets_params->cos[cos_entry].params.sp_params.pri,
1116 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_config cos state not"
1120 if (0 != bnx2x_status) {
1121 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_config set cos bw "
1123 return bnx2x_status;
1127 /* Set SP register (which COS has higher priority) */
1128 bnx2x_status = bnx2x_ets_e3b0_sp_set_pri_cli_reg(params,
1131 if (0 != bnx2x_status) {
1132 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config set_pri_cli_reg "
1134 return bnx2x_status;
1137 /* Set client mapping of BW and strict */
1138 bnx2x_status = bnx2x_ets_e3b0_cli_map(params, ets_params,
1142 if (0 != bnx2x_status) {
1143 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config SP failed\n");
1144 return bnx2x_status;
1148 static void bnx2x_ets_bw_limit_common(const struct link_params *params)
1150 /* ETS disabled configuration */
1151 struct bnx2x *bp = params->bp;
1152 DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
1154 * defines which entries (clients) are subjected to WFQ arbitration
1158 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
1160 * mapping between the ARB_CREDIT_WEIGHT registers and actual
1161 * client numbers (WEIGHT_0 does not actually have to represent
1163 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
1164 * cos1-001 cos0-000 dbg1-100 dbg0-011 MCP-010
1166 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
1168 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
1169 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1170 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
1171 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1173 /* ETS mode enabled*/
1174 REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
1176 /* Defines the number of consecutive slots for the strict priority */
1177 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
1179 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
1180 * as strict. Bits 0,1,2 - debug and management entries, 3 - COS0
1181 * entry, 4 - COS1 entry.
1182 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1183 * bit4 bit3 bit2 bit1 bit0
1184 * MCP and debug are strict
1186 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
1188 /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
1189 REG_WR(bp, PBF_REG_COS0_UPPER_BOUND,
1190 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1191 REG_WR(bp, PBF_REG_COS1_UPPER_BOUND,
1192 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1195 void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
1198 /* ETS disabled configuration*/
1199 struct bnx2x *bp = params->bp;
1200 const u32 total_bw = cos0_bw + cos1_bw;
1201 u32 cos0_credit_weight = 0;
1202 u32 cos1_credit_weight = 0;
1204 DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
1206 if ((0 == total_bw) ||
1209 DP(NETIF_MSG_LINK, "Total BW can't be zero\n");
1213 cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
1215 cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
1218 bnx2x_ets_bw_limit_common(params);
1220 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
1221 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
1223 REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
1224 REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
1227 int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
1229 /* ETS disabled configuration*/
1230 struct bnx2x *bp = params->bp;
1233 DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
1235 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
1236 * as strict. Bits 0,1,2 - debug and management entries,
1237 * 3 - COS0 entry, 4 - COS1 entry.
1238 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1239 * bit4 bit3 bit2 bit1 bit0
1240 * MCP and debug are strict
1242 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
1244 * For strict priority entries defines the number of consecutive slots
1245 * for the highest priority.
1247 REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
1248 /* ETS mode disable */
1249 REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
1250 /* Defines the number of consecutive slots for the strict priority */
1251 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
1253 /* Defines the number of consecutive slots for the strict priority */
1254 REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
1257 * mapping between entry priority to client number (0,1,2 -debug and
1258 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
1260 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
1261 * dbg0-010 dbg1-001 cos1-100 cos0-011 MCP-000
1262 * dbg0-010 dbg1-001 cos0-011 cos1-100 MCP-000
1264 val = (0 == strict_cos) ? 0x2318 : 0x22E0;
1265 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
1269 /******************************************************************/
1271 /******************************************************************/
1273 static void bnx2x_update_pfc_xmac(struct link_params *params,
1274 struct link_vars *vars,
1277 struct bnx2x *bp = params->bp;
1279 u32 pause_val, pfc0_val, pfc1_val;
1281 /* XMAC base adrr */
1282 xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1284 /* Initialize pause and pfc registers */
1285 pause_val = 0x18000;
1286 pfc0_val = 0xFFFF8000;
1289 /* No PFC support */
1290 if (!(params->feature_config_flags &
1291 FEATURE_CONFIG_PFC_ENABLED)) {
1294 * RX flow control - Process pause frame in receive direction
1296 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1297 pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN;
1300 * TX flow control - Send pause packet when buffer is full
1302 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1303 pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN;
1304 } else {/* PFC support */
1305 pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN |
1306 XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN |
1307 XMAC_PFC_CTRL_HI_REG_RX_PFC_EN |
1308 XMAC_PFC_CTRL_HI_REG_TX_PFC_EN;
1311 /* Write pause and PFC registers */
1312 REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
1313 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
1314 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
1320 static void bnx2x_bmac2_get_pfc_stat(struct link_params *params,
1321 u32 pfc_frames_sent[2],
1322 u32 pfc_frames_received[2])
1324 /* Read pfc statistic */
1325 struct bnx2x *bp = params->bp;
1326 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1327 NIG_REG_INGRESS_BMAC0_MEM;
1329 DP(NETIF_MSG_LINK, "pfc statistic read from BMAC\n");
1331 REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_STAT_GTPP,
1332 pfc_frames_sent, 2);
1334 REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_STAT_GRPP,
1335 pfc_frames_received, 2);
1338 static void bnx2x_emac_get_pfc_stat(struct link_params *params,
1339 u32 pfc_frames_sent[2],
1340 u32 pfc_frames_received[2])
1342 /* Read pfc statistic */
1343 struct bnx2x *bp = params->bp;
1344 u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1348 DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n");
1350 /* PFC received frames */
1351 val_xoff = REG_RD(bp, emac_base +
1352 EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
1353 val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
1354 val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
1355 val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
1357 pfc_frames_received[0] = val_xon + val_xoff;
1359 /* PFC received sent */
1360 val_xoff = REG_RD(bp, emac_base +
1361 EMAC_REG_RX_PFC_STATS_XOFF_SENT);
1362 val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
1363 val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
1364 val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
1366 pfc_frames_sent[0] = val_xon + val_xoff;
1369 void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
1370 u32 pfc_frames_sent[2],
1371 u32 pfc_frames_received[2])
1373 /* Read pfc statistic */
1374 struct bnx2x *bp = params->bp;
1376 DP(NETIF_MSG_LINK, "pfc statistic\n");
1381 val = REG_RD(bp, MISC_REG_RESET_REG_2);
1382 if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
1384 DP(NETIF_MSG_LINK, "About to read stats from EMAC\n");
1385 bnx2x_emac_get_pfc_stat(params, pfc_frames_sent,
1386 pfc_frames_received);
1388 DP(NETIF_MSG_LINK, "About to read stats from BMAC\n");
1389 bnx2x_bmac2_get_pfc_stat(params, pfc_frames_sent,
1390 pfc_frames_received);
1393 /******************************************************************/
1394 /* MAC/PBF section */
1395 /******************************************************************/
1396 static void bnx2x_set_mdio_clk(struct bnx2x *bp, u32 chip_id, u8 port)
1398 u32 mode, emac_base;
1400 * Set clause 45 mode, slow down the MDIO clock to 2.5MHz
1401 * (a value of 49==0x31) and make sure that the AUTO poll is off
1405 emac_base = GRCBASE_EMAC0;
1407 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1408 mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
1409 mode &= ~(EMAC_MDIO_MODE_AUTO_POLL |
1410 EMAC_MDIO_MODE_CLOCK_CNT);
1411 if (USES_WARPCORE(bp))
1412 mode |= (74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
1414 mode |= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
1416 mode |= (EMAC_MDIO_MODE_CLAUSE_45);
1417 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, mode);
1422 static void bnx2x_emac_init(struct link_params *params,
1423 struct link_vars *vars)
1425 /* reset and unreset the emac core */
1426 struct bnx2x *bp = params->bp;
1427 u8 port = params->port;
1428 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1432 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1433 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1435 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1436 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1438 /* init emac - use read-modify-write */
1439 /* self clear reset */
1440 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1441 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
1445 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1446 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
1448 DP(NETIF_MSG_LINK, "EMAC timeout!\n");
1452 } while (val & EMAC_MODE_RESET);
1453 bnx2x_set_mdio_clk(bp, params->chip_id, port);
1454 /* Set mac address */
1455 val = ((params->mac_addr[0] << 8) |
1456 params->mac_addr[1]);
1457 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
1459 val = ((params->mac_addr[2] << 24) |
1460 (params->mac_addr[3] << 16) |
1461 (params->mac_addr[4] << 8) |
1462 params->mac_addr[5]);
1463 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
1466 static void bnx2x_set_xumac_nig(struct link_params *params,
1470 struct bnx2x *bp = params->bp;
1472 REG_WR(bp, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN,
1474 REG_WR(bp, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN,
1476 REG_WR(bp, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN :
1477 NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
1480 static void bnx2x_umac_enable(struct link_params *params,
1481 struct link_vars *vars, u8 lb)
1484 u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
1485 struct bnx2x *bp = params->bp;
1487 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1488 (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
1489 usleep_range(1000, 1000);
1491 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1492 (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
1494 DP(NETIF_MSG_LINK, "enabling UMAC\n");
1497 * This register determines on which events the MAC will assert
1498 * error on the i/f to the NIG along w/ EOP.
1502 * BD REG_WR(bp, NIG_REG_P0_MAC_RSV_ERR_MASK +
1503 * params->port*0x14, 0xfffff.
1505 /* This register opens the gate for the UMAC despite its name */
1506 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
1508 val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN |
1509 UMAC_COMMAND_CONFIG_REG_PAD_EN |
1510 UMAC_COMMAND_CONFIG_REG_SW_RESET |
1511 UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK;
1512 switch (vars->line_speed) {
1526 DP(NETIF_MSG_LINK, "Invalid speed for UMAC %d\n",
1530 REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1533 /* Enable RX and TX */
1534 val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN;
1535 val |= UMAC_COMMAND_CONFIG_REG_TX_ENA |
1536 UMAC_COMMAND_CONFIG_REG_RX_ENA;
1537 REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1540 /* Remove SW Reset */
1541 val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET;
1543 /* Check loopback mode */
1545 val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA;
1546 REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1549 * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
1550 * length used by the MAC receive logic to check frames.
1552 REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
1553 bnx2x_set_xumac_nig(params,
1554 ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
1555 vars->mac_type = MAC_TYPE_UMAC;
1559 static u8 bnx2x_is_4_port_mode(struct bnx2x *bp)
1561 u32 port4mode_ovwr_val;
1562 /* Check 4-port override enabled */
1563 port4mode_ovwr_val = REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR);
1564 if (port4mode_ovwr_val & (1<<0)) {
1565 /* Return 4-port mode override value */
1566 return ((port4mode_ovwr_val & (1<<1)) == (1<<1));
1568 /* Return 4-port mode from input pin */
1569 return (u8)REG_RD(bp, MISC_REG_PORT4MODE_EN);
1572 /* Define the XMAC mode */
1573 static void bnx2x_xmac_init(struct bnx2x *bp, u32 max_speed)
1575 u32 is_port4mode = bnx2x_is_4_port_mode(bp);
1578 * In 4-port mode, need to set the mode only once, so if XMAC is
1579 * already out of reset, it means the mode has already been set,
1580 * and it must not* reset the XMAC again, since it controls both
1584 if (is_port4mode && (REG_RD(bp, MISC_REG_RESET_REG_2) &
1585 MISC_REGISTERS_RESET_REG_2_XMAC)) {
1586 DP(NETIF_MSG_LINK, "XMAC already out of reset"
1587 " in 4-port mode\n");
1592 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1593 MISC_REGISTERS_RESET_REG_2_XMAC);
1594 usleep_range(1000, 1000);
1596 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1597 MISC_REGISTERS_RESET_REG_2_XMAC);
1599 DP(NETIF_MSG_LINK, "Init XMAC to 2 ports x 10G per path\n");
1601 /* Set the number of ports on the system side to up to 2 */
1602 REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 1);
1604 /* Set the number of ports on the Warp Core to 10G */
1605 REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
1607 /* Set the number of ports on the system side to 1 */
1608 REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 0);
1609 if (max_speed == SPEED_10000) {
1610 DP(NETIF_MSG_LINK, "Init XMAC to 10G x 1"
1611 " port per path\n");
1612 /* Set the number of ports on the Warp Core to 10G */
1613 REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
1615 DP(NETIF_MSG_LINK, "Init XMAC to 20G x 2 ports"
1617 /* Set the number of ports on the Warp Core to 20G */
1618 REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 1);
1622 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1623 MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
1624 usleep_range(1000, 1000);
1626 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1627 MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
1631 static void bnx2x_xmac_disable(struct link_params *params)
1633 u8 port = params->port;
1634 struct bnx2x *bp = params->bp;
1635 u32 xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1637 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
1638 MISC_REGISTERS_RESET_REG_2_XMAC) {
1639 DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port);
1640 REG_WR(bp, xmac_base + XMAC_REG_CTRL, 0);
1641 usleep_range(1000, 1000);
1642 bnx2x_set_xumac_nig(params, 0, 0);
1643 REG_WR(bp, xmac_base + XMAC_REG_CTRL,
1644 XMAC_CTRL_REG_SOFT_RESET);
1648 static int bnx2x_xmac_enable(struct link_params *params,
1649 struct link_vars *vars, u8 lb)
1652 struct bnx2x *bp = params->bp;
1653 DP(NETIF_MSG_LINK, "enabling XMAC\n");
1655 xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1657 bnx2x_xmac_init(bp, vars->line_speed);
1660 * This register determines on which events the MAC will assert
1661 * error on the i/f to the NIG along w/ EOP.
1665 * This register tells the NIG whether to send traffic to UMAC
1668 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0);
1670 /* Set Max packet size */
1671 REG_WR(bp, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710);
1673 /* CRC append for Tx packets */
1674 REG_WR(bp, xmac_base + XMAC_REG_TX_CTRL, 0xC800);
1677 bnx2x_update_pfc_xmac(params, vars, 0);
1679 /* Enable TX and RX */
1680 val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
1682 /* Check loopback mode */
1684 val |= XMAC_CTRL_REG_CORE_LOCAL_LPBK;
1685 REG_WR(bp, xmac_base + XMAC_REG_CTRL, val);
1686 bnx2x_set_xumac_nig(params,
1687 ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
1689 vars->mac_type = MAC_TYPE_XMAC;
1693 static int bnx2x_emac_enable(struct link_params *params,
1694 struct link_vars *vars, u8 lb)
1696 struct bnx2x *bp = params->bp;
1697 u8 port = params->port;
1698 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1701 DP(NETIF_MSG_LINK, "enabling EMAC\n");
1703 /* enable emac and not bmac */
1704 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
1707 if (vars->phy_flags & PHY_XGXS_FLAG) {
1708 u32 ser_lane = ((params->lane_config &
1709 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1710 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1712 DP(NETIF_MSG_LINK, "XGXS\n");
1713 /* select the master lanes (out of 0-3) */
1714 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane);
1716 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
1718 } else { /* SerDes */
1719 DP(NETIF_MSG_LINK, "SerDes\n");
1721 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
1724 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
1725 EMAC_RX_MODE_RESET);
1726 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1727 EMAC_TX_MODE_RESET);
1729 if (CHIP_REV_IS_SLOW(bp)) {
1730 /* config GMII mode */
1731 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1732 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII));
1734 /* pause enable/disable */
1735 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
1736 EMAC_RX_MODE_FLOW_EN);
1738 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1739 (EMAC_TX_MODE_EXT_PAUSE_EN |
1740 EMAC_TX_MODE_FLOW_EN));
1741 if (!(params->feature_config_flags &
1742 FEATURE_CONFIG_PFC_ENABLED)) {
1743 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1744 bnx2x_bits_en(bp, emac_base +
1745 EMAC_REG_EMAC_RX_MODE,
1746 EMAC_RX_MODE_FLOW_EN);
1748 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1749 bnx2x_bits_en(bp, emac_base +
1750 EMAC_REG_EMAC_TX_MODE,
1751 (EMAC_TX_MODE_EXT_PAUSE_EN |
1752 EMAC_TX_MODE_FLOW_EN));
1754 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1755 EMAC_TX_MODE_FLOW_EN);
1758 /* KEEP_VLAN_TAG, promiscuous */
1759 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
1760 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
1763 * Setting this bit causes MAC control frames (except for pause
1764 * frames) to be passed on for processing. This setting has no
1765 * affect on the operation of the pause frames. This bit effects
1766 * all packets regardless of RX Parser packet sorting logic.
1767 * Turn the PFC off to make sure we are in Xon state before
1770 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
1771 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
1772 DP(NETIF_MSG_LINK, "PFC is enabled\n");
1773 /* Enable PFC again */
1774 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
1775 EMAC_REG_RX_PFC_MODE_RX_EN |
1776 EMAC_REG_RX_PFC_MODE_TX_EN |
1777 EMAC_REG_RX_PFC_MODE_PRIORITIES);
1779 EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
1781 EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
1783 EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
1784 val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
1786 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
1789 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1794 EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
1797 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
1799 /* enable emac for jumbo packets */
1800 EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
1801 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
1802 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
1805 REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
1807 /* disable the NIG in/out to the bmac */
1808 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
1809 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
1810 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
1812 /* enable the NIG in/out to the emac */
1813 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
1815 if ((params->feature_config_flags &
1816 FEATURE_CONFIG_PFC_ENABLED) ||
1817 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1820 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
1821 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
1823 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
1825 vars->mac_type = MAC_TYPE_EMAC;
1829 static void bnx2x_update_pfc_bmac1(struct link_params *params,
1830 struct link_vars *vars)
1833 struct bnx2x *bp = params->bp;
1834 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1835 NIG_REG_INGRESS_BMAC0_MEM;
1838 if ((!(params->feature_config_flags &
1839 FEATURE_CONFIG_PFC_ENABLED)) &&
1840 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1841 /* Enable BigMAC to react on received Pause packets */
1845 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
1849 if (!(params->feature_config_flags &
1850 FEATURE_CONFIG_PFC_ENABLED) &&
1851 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1855 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
1858 static void bnx2x_update_pfc_bmac2(struct link_params *params,
1859 struct link_vars *vars,
1863 * Set rx control: Strip CRC and enable BigMAC to relay
1864 * control packets to the system as well
1867 struct bnx2x *bp = params->bp;
1868 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1869 NIG_REG_INGRESS_BMAC0_MEM;
1872 if ((!(params->feature_config_flags &
1873 FEATURE_CONFIG_PFC_ENABLED)) &&
1874 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1875 /* Enable BigMAC to react on received Pause packets */
1879 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
1884 if (!(params->feature_config_flags &
1885 FEATURE_CONFIG_PFC_ENABLED) &&
1886 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1890 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
1892 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
1893 DP(NETIF_MSG_LINK, "PFC is enabled\n");
1894 /* Enable PFC RX & TX & STATS and set 8 COS */
1896 wb_data[0] |= (1<<0); /* RX */
1897 wb_data[0] |= (1<<1); /* TX */
1898 wb_data[0] |= (1<<2); /* Force initial Xon */
1899 wb_data[0] |= (1<<3); /* 8 cos */
1900 wb_data[0] |= (1<<5); /* STATS */
1902 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
1904 /* Clear the force Xon */
1905 wb_data[0] &= ~(1<<2);
1907 DP(NETIF_MSG_LINK, "PFC is disabled\n");
1908 /* disable PFC RX & TX & STATS and set 8 COS */
1913 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
1916 * Set Time (based unit is 512 bit time) between automatic
1917 * re-sending of PP packets amd enable automatic re-send of
1918 * Per-Priroity Packet as long as pp_gen is asserted and
1919 * pp_disable is low.
1922 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
1923 val |= (1<<16); /* enable automatic re-send */
1927 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
1931 val = 0x3; /* Enable RX and TX */
1933 val |= 0x4; /* Local loopback */
1934 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
1936 /* When PFC enabled, Pass pause frames towards the NIG. */
1937 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
1938 val |= ((1<<6)|(1<<5));
1942 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
1946 /* PFC BRB internal port configuration params */
1947 struct bnx2x_pfc_brb_threshold_val {
1954 struct bnx2x_pfc_brb_e3b0_val {
1955 u32 full_lb_xoff_th;
1956 u32 full_lb_xon_threshold;
1958 u32 mac_0_class_t_guarantied;
1959 u32 mac_0_class_t_guarantied_hyst;
1960 u32 mac_1_class_t_guarantied;
1961 u32 mac_1_class_t_guarantied_hyst;
1964 struct bnx2x_pfc_brb_th_val {
1965 struct bnx2x_pfc_brb_threshold_val pauseable_th;
1966 struct bnx2x_pfc_brb_threshold_val non_pauseable_th;
1968 static int bnx2x_pfc_brb_get_config_params(
1969 struct link_params *params,
1970 struct bnx2x_pfc_brb_th_val *config_val)
1972 struct bnx2x *bp = params->bp;
1973 DP(NETIF_MSG_LINK, "Setting PFC BRB configuration\n");
1974 if (CHIP_IS_E2(bp)) {
1975 config_val->pauseable_th.pause_xoff =
1976 PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
1977 config_val->pauseable_th.pause_xon =
1978 PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE;
1979 config_val->pauseable_th.full_xoff =
1980 PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE;
1981 config_val->pauseable_th.full_xon =
1982 PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE;
1984 config_val->non_pauseable_th.pause_xoff =
1985 PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
1986 config_val->non_pauseable_th.pause_xon =
1987 PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
1988 config_val->non_pauseable_th.full_xoff =
1989 PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
1990 config_val->non_pauseable_th.full_xon =
1991 PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE;
1992 } else if (CHIP_IS_E3A0(bp)) {
1993 config_val->pauseable_th.pause_xoff =
1994 PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
1995 config_val->pauseable_th.pause_xon =
1996 PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE;
1997 config_val->pauseable_th.full_xoff =
1998 PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE;
1999 config_val->pauseable_th.full_xon =
2000 PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE;
2002 config_val->non_pauseable_th.pause_xoff =
2003 PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2004 config_val->non_pauseable_th.pause_xon =
2005 PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2006 config_val->non_pauseable_th.full_xoff =
2007 PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2008 config_val->non_pauseable_th.full_xon =
2009 PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2010 } else if (CHIP_IS_E3B0(bp)) {
2011 if (params->phy[INT_PHY].flags &
2012 FLAGS_4_PORT_MODE) {
2013 config_val->pauseable_th.pause_xoff =
2014 PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2015 config_val->pauseable_th.pause_xon =
2016 PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE;
2017 config_val->pauseable_th.full_xoff =
2018 PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE;
2019 config_val->pauseable_th.full_xon =
2020 PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE;
2022 config_val->non_pauseable_th.pause_xoff =
2023 PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2024 config_val->non_pauseable_th.pause_xon =
2025 PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2026 config_val->non_pauseable_th.full_xoff =
2027 PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2028 config_val->non_pauseable_th.full_xon =
2029 PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2031 config_val->pauseable_th.pause_xoff =
2032 PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2033 config_val->pauseable_th.pause_xon =
2034 PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE;
2035 config_val->pauseable_th.full_xoff =
2036 PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE;
2037 config_val->pauseable_th.full_xon =
2038 PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE;
2040 config_val->non_pauseable_th.pause_xoff =
2041 PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2042 config_val->non_pauseable_th.pause_xon =
2043 PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2044 config_val->non_pauseable_th.full_xoff =
2045 PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2046 config_val->non_pauseable_th.full_xon =
2047 PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2056 static void bnx2x_pfc_brb_get_e3b0_config_params(struct link_params *params,
2057 struct bnx2x_pfc_brb_e3b0_val
2062 if (params->phy[INT_PHY].flags & FLAGS_4_PORT_MODE) {
2063 e3b0_val->full_lb_xoff_th =
2064 PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR;
2065 e3b0_val->full_lb_xon_threshold =
2066 PFC_E3B0_4P_BRB_FULL_LB_XON_THR;
2067 e3b0_val->lb_guarantied =
2068 PFC_E3B0_4P_LB_GUART;
2069 e3b0_val->mac_0_class_t_guarantied =
2070 PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART;
2071 e3b0_val->mac_0_class_t_guarantied_hyst =
2072 PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST;
2073 e3b0_val->mac_1_class_t_guarantied =
2074 PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART;
2075 e3b0_val->mac_1_class_t_guarantied_hyst =
2076 PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST;
2078 e3b0_val->full_lb_xoff_th =
2079 PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR;
2080 e3b0_val->full_lb_xon_threshold =
2081 PFC_E3B0_2P_BRB_FULL_LB_XON_THR;
2082 e3b0_val->mac_0_class_t_guarantied_hyst =
2083 PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST;
2084 e3b0_val->mac_1_class_t_guarantied =
2085 PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART;
2086 e3b0_val->mac_1_class_t_guarantied_hyst =
2087 PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST;
2089 if (cos0_pauseable != cos1_pauseable) {
2090 /* nonpauseable= Lossy + pauseable = Lossless*/
2091 e3b0_val->lb_guarantied =
2092 PFC_E3B0_2P_MIX_PAUSE_LB_GUART;
2093 e3b0_val->mac_0_class_t_guarantied =
2094 PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART;
2095 } else if (cos0_pauseable) {
2096 /* Lossless +Lossless*/
2097 e3b0_val->lb_guarantied =
2098 PFC_E3B0_2P_PAUSE_LB_GUART;
2099 e3b0_val->mac_0_class_t_guarantied =
2100 PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART;
2103 e3b0_val->lb_guarantied =
2104 PFC_E3B0_2P_NON_PAUSE_LB_GUART;
2105 e3b0_val->mac_0_class_t_guarantied =
2106 PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART;
2110 static int bnx2x_update_pfc_brb(struct link_params *params,
2111 struct link_vars *vars,
2112 struct bnx2x_nig_brb_pfc_port_params
2115 struct bnx2x *bp = params->bp;
2116 struct bnx2x_pfc_brb_th_val config_val = { {0} };
2117 struct bnx2x_pfc_brb_threshold_val *reg_th_config =
2118 &config_val.pauseable_th;
2119 struct bnx2x_pfc_brb_e3b0_val e3b0_val = {0};
2120 int set_pfc = params->feature_config_flags &
2121 FEATURE_CONFIG_PFC_ENABLED;
2122 int bnx2x_status = 0;
2123 u8 port = params->port;
2125 /* default - pause configuration */
2126 reg_th_config = &config_val.pauseable_th;
2127 bnx2x_status = bnx2x_pfc_brb_get_config_params(params, &config_val);
2128 if (0 != bnx2x_status)
2129 return bnx2x_status;
2131 if (set_pfc && pfc_params)
2133 if (!pfc_params->cos0_pauseable)
2134 reg_th_config = &config_val.non_pauseable_th;
2136 * The number of free blocks below which the pause signal to class 0
2137 * of MAC #n is asserted. n=0,1
2139 REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XOFF_THRESHOLD_1 :
2140 BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 ,
2141 reg_th_config->pause_xoff);
2143 * The number of free blocks above which the pause signal to class 0
2144 * of MAC #n is de-asserted. n=0,1
2146 REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XON_THRESHOLD_1 :
2147 BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , reg_th_config->pause_xon);
2149 * The number of free blocks below which the full signal to class 0
2150 * of MAC #n is asserted. n=0,1
2152 REG_WR(bp, (port) ? BRB1_REG_FULL_0_XOFF_THRESHOLD_1 :
2153 BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , reg_th_config->full_xoff);
2155 * The number of free blocks above which the full signal to class 0
2156 * of MAC #n is de-asserted. n=0,1
2158 REG_WR(bp, (port) ? BRB1_REG_FULL_0_XON_THRESHOLD_1 :
2159 BRB1_REG_FULL_0_XON_THRESHOLD_0 , reg_th_config->full_xon);
2161 if (set_pfc && pfc_params) {
2163 if (pfc_params->cos1_pauseable)
2164 reg_th_config = &config_val.pauseable_th;
2166 reg_th_config = &config_val.non_pauseable_th;
2168 * The number of free blocks below which the pause signal to
2169 * class 1 of MAC #n is asserted. n=0,1
2171 REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XOFF_THRESHOLD_1 :
2172 BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0,
2173 reg_th_config->pause_xoff);
2175 * The number of free blocks above which the pause signal to
2176 * class 1 of MAC #n is de-asserted. n=0,1
2178 REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XON_THRESHOLD_1 :
2179 BRB1_REG_PAUSE_1_XON_THRESHOLD_0,
2180 reg_th_config->pause_xon);
2182 * The number of free blocks below which the full signal to
2183 * class 1 of MAC #n is asserted. n=0,1
2185 REG_WR(bp, (port) ? BRB1_REG_FULL_1_XOFF_THRESHOLD_1 :
2186 BRB1_REG_FULL_1_XOFF_THRESHOLD_0,
2187 reg_th_config->full_xoff);
2189 * The number of free blocks above which the full signal to
2190 * class 1 of MAC #n is de-asserted. n=0,1
2192 REG_WR(bp, (port) ? BRB1_REG_FULL_1_XON_THRESHOLD_1 :
2193 BRB1_REG_FULL_1_XON_THRESHOLD_0,
2194 reg_th_config->full_xon);
2197 if (CHIP_IS_E3B0(bp)) {
2198 /*Should be done by init tool */
2200 * BRB_empty_for_dup = BRB1_REG_BRB_EMPTY_THRESHOLD
2206 * The hysteresis on the guarantied buffer space for the Lb port
2207 * before signaling XON.
2209 REG_WR(bp, BRB1_REG_LB_GUARANTIED_HYST, 80);
2211 bnx2x_pfc_brb_get_e3b0_config_params(
2214 pfc_params->cos0_pauseable,
2215 pfc_params->cos1_pauseable);
2217 * The number of free blocks below which the full signal to the
2218 * LB port is asserted.
2220 REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD,
2221 e3b0_val.full_lb_xoff_th);
2223 * The number of free blocks above which the full signal to the
2224 * LB port is de-asserted.
2226 REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD,
2227 e3b0_val.full_lb_xon_threshold);
2229 * The number of blocks guarantied for the MAC #n port. n=0,1
2232 /*The number of blocks guarantied for the LB port.*/
2233 REG_WR(bp, BRB1_REG_LB_GUARANTIED,
2234 e3b0_val.lb_guarantied);
2237 * The number of blocks guarantied for the MAC #n port.
2239 REG_WR(bp, BRB1_REG_MAC_GUARANTIED_0,
2240 2 * e3b0_val.mac_0_class_t_guarantied);
2241 REG_WR(bp, BRB1_REG_MAC_GUARANTIED_1,
2242 2 * e3b0_val.mac_1_class_t_guarantied);
2244 * The number of blocks guarantied for class #t in MAC0. t=0,1
2246 REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED,
2247 e3b0_val.mac_0_class_t_guarantied);
2248 REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED,
2249 e3b0_val.mac_0_class_t_guarantied);
2251 * The hysteresis on the guarantied buffer space for class in
2254 REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED_HYST,
2255 e3b0_val.mac_0_class_t_guarantied_hyst);
2256 REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED_HYST,
2257 e3b0_val.mac_0_class_t_guarantied_hyst);
2260 * The number of blocks guarantied for class #t in MAC1.t=0,1
2262 REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED,
2263 e3b0_val.mac_1_class_t_guarantied);
2264 REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED,
2265 e3b0_val.mac_1_class_t_guarantied);
2267 * The hysteresis on the guarantied buffer space for class #t
2270 REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED_HYST,
2271 e3b0_val.mac_1_class_t_guarantied_hyst);
2272 REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED_HYST,
2273 e3b0_val.mac_1_class_t_guarantied_hyst);
2279 return bnx2x_status;
2282 /******************************************************************************
2284 * This function is needed because NIG ARB_CREDIT_WEIGHT_X are
2285 * not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
2286 ******************************************************************************/
2287 int bnx2x_pfc_nig_rx_priority_mask(struct bnx2x *bp,
2289 u32 priority_mask, u8 port)
2291 u32 nig_reg_rx_priority_mask_add = 0;
2293 switch (cos_entry) {
2295 nig_reg_rx_priority_mask_add = (port) ?
2296 NIG_REG_P1_RX_COS0_PRIORITY_MASK :
2297 NIG_REG_P0_RX_COS0_PRIORITY_MASK;
2300 nig_reg_rx_priority_mask_add = (port) ?
2301 NIG_REG_P1_RX_COS1_PRIORITY_MASK :
2302 NIG_REG_P0_RX_COS1_PRIORITY_MASK;
2305 nig_reg_rx_priority_mask_add = (port) ?
2306 NIG_REG_P1_RX_COS2_PRIORITY_MASK :
2307 NIG_REG_P0_RX_COS2_PRIORITY_MASK;
2312 nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK;
2317 nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK;
2322 nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK;
2326 REG_WR(bp, nig_reg_rx_priority_mask_add, priority_mask);
2330 static void bnx2x_update_pfc_nig(struct link_params *params,
2331 struct link_vars *vars,
2332 struct bnx2x_nig_brb_pfc_port_params *nig_params)
2334 u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
2335 u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0;
2336 u32 pkt_priority_to_cos = 0;
2337 struct bnx2x *bp = params->bp;
2338 u8 port = params->port;
2340 int set_pfc = params->feature_config_flags &
2341 FEATURE_CONFIG_PFC_ENABLED;
2342 DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
2345 * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
2346 * MAC control frames (that are not pause packets)
2347 * will be forwarded to the XCM.
2349 xcm_mask = REG_RD(bp,
2350 port ? NIG_REG_LLH1_XCM_MASK :
2351 NIG_REG_LLH0_XCM_MASK);
2353 * nig params will override non PFC params, since it's possible to
2354 * do transition from PFC to SAFC
2364 xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2365 NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2367 p0_hwpfc_enable = 1;
2370 llfc_out_en = nig_params->llfc_out_en;
2371 llfc_enable = nig_params->llfc_enable;
2372 pause_enable = nig_params->pause_enable;
2373 } else /*defaul non PFC mode - PAUSE */
2376 xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2377 NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2382 REG_WR(bp, port ? NIG_REG_BRB1_PAUSE_IN_EN :
2383 NIG_REG_BRB0_PAUSE_IN_EN, pause_enable);
2384 REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
2385 NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
2386 REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
2387 NIG_REG_LLFC_ENABLE_0, llfc_enable);
2388 REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
2389 NIG_REG_PAUSE_ENABLE_0, pause_enable);
2391 REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
2392 NIG_REG_PPP_ENABLE_0, ppp_enable);
2394 REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
2395 NIG_REG_LLH0_XCM_MASK, xcm_mask);
2397 REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
2399 /* output enable for RX_XCM # IF */
2400 REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en);
2402 /* HW PFC TX enable */
2403 REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable);
2407 pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
2409 for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++)
2410 bnx2x_pfc_nig_rx_priority_mask(bp, i,
2411 nig_params->rx_cos_priority_mask[i], port);
2413 REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
2414 NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
2415 nig_params->llfc_high_priority_classes);
2417 REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
2418 NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
2419 nig_params->llfc_low_priority_classes);
2421 REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
2422 NIG_REG_P0_PKT_PRIORITY_TO_COS,
2423 pkt_priority_to_cos);
2426 int bnx2x_update_pfc(struct link_params *params,
2427 struct link_vars *vars,
2428 struct bnx2x_nig_brb_pfc_port_params *pfc_params)
2431 * The PFC and pause are orthogonal to one another, meaning when
2432 * PFC is enabled, the pause are disabled, and when PFC is
2433 * disabled, pause are set according to the pause result.
2436 struct bnx2x *bp = params->bp;
2437 int bnx2x_status = 0;
2438 u8 bmac_loopback = (params->loopback_mode == LOOPBACK_BMAC);
2439 /* update NIG params */
2440 bnx2x_update_pfc_nig(params, vars, pfc_params);
2442 /* update BRB params */
2443 bnx2x_status = bnx2x_update_pfc_brb(params, vars, pfc_params);
2444 if (0 != bnx2x_status)
2445 return bnx2x_status;
2448 return bnx2x_status;
2450 DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
2452 bnx2x_update_pfc_xmac(params, vars, 0);
2454 val = REG_RD(bp, MISC_REG_RESET_REG_2);
2456 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
2458 DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
2459 bnx2x_emac_enable(params, vars, 0);
2460 return bnx2x_status;
2464 bnx2x_update_pfc_bmac2(params, vars, bmac_loopback);
2466 bnx2x_update_pfc_bmac1(params, vars);
2469 if ((params->feature_config_flags &
2470 FEATURE_CONFIG_PFC_ENABLED) ||
2471 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
2473 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
2475 return bnx2x_status;
2479 static int bnx2x_bmac1_enable(struct link_params *params,
2480 struct link_vars *vars,
2483 struct bnx2x *bp = params->bp;
2484 u8 port = params->port;
2485 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2486 NIG_REG_INGRESS_BMAC0_MEM;
2490 DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
2495 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
2499 wb_data[0] = ((params->mac_addr[2] << 24) |
2500 (params->mac_addr[3] << 16) |
2501 (params->mac_addr[4] << 8) |
2502 params->mac_addr[5]);
2503 wb_data[1] = ((params->mac_addr[0] << 8) |
2504 params->mac_addr[1]);
2505 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
2511 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
2515 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
2518 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2520 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
2522 bnx2x_update_pfc_bmac1(params, vars);
2525 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2527 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
2529 /* set cnt max size */
2530 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2532 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2534 /* configure safc */
2535 wb_data[0] = 0x1000200;
2537 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
2543 static int bnx2x_bmac2_enable(struct link_params *params,
2544 struct link_vars *vars,
2547 struct bnx2x *bp = params->bp;
2548 u8 port = params->port;
2549 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2550 NIG_REG_INGRESS_BMAC0_MEM;
2553 DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
2557 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2560 /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
2563 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
2569 wb_data[0] = ((params->mac_addr[2] << 24) |
2570 (params->mac_addr[3] << 16) |
2571 (params->mac_addr[4] << 8) |
2572 params->mac_addr[5]);
2573 wb_data[1] = ((params->mac_addr[0] << 8) |
2574 params->mac_addr[1]);
2575 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
2580 /* Configure SAFC */
2581 wb_data[0] = 0x1000200;
2583 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
2588 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2590 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
2594 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2596 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
2598 /* set cnt max size */
2599 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
2601 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2603 bnx2x_update_pfc_bmac2(params, vars, is_lb);
2608 static int bnx2x_bmac_enable(struct link_params *params,
2609 struct link_vars *vars,
2613 u8 port = params->port;
2614 struct bnx2x *bp = params->bp;
2616 /* reset and unreset the BigMac */
2617 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2618 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2621 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2622 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2624 /* enable access for bmac registers */
2625 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
2627 /* Enable BMAC according to BMAC type*/
2629 rc = bnx2x_bmac2_enable(params, vars, is_lb);
2631 rc = bnx2x_bmac1_enable(params, vars, is_lb);
2632 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
2633 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
2634 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
2636 if ((params->feature_config_flags &
2637 FEATURE_CONFIG_PFC_ENABLED) ||
2638 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
2640 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
2641 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
2642 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
2643 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
2644 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
2645 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
2647 vars->mac_type = MAC_TYPE_BMAC;
2652 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
2654 struct bnx2x *bp = params->bp;
2656 REG_WR(bp, params->shmem_base +
2657 offsetof(struct shmem_region,
2658 port_mb[params->port].link_status), link_status);
2661 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
2663 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2664 NIG_REG_INGRESS_BMAC0_MEM;
2666 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
2668 /* Only if the bmac is out of reset */
2669 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
2670 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
2673 if (CHIP_IS_E2(bp)) {
2674 /* Clear Rx Enable bit in BMAC_CONTROL register */
2675 REG_RD_DMAE(bp, bmac_addr +
2676 BIGMAC2_REGISTER_BMAC_CONTROL,
2678 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
2679 REG_WR_DMAE(bp, bmac_addr +
2680 BIGMAC2_REGISTER_BMAC_CONTROL,
2683 /* Clear Rx Enable bit in BMAC_CONTROL register */
2684 REG_RD_DMAE(bp, bmac_addr +
2685 BIGMAC_REGISTER_BMAC_CONTROL,
2687 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
2688 REG_WR_DMAE(bp, bmac_addr +
2689 BIGMAC_REGISTER_BMAC_CONTROL,
2696 static int bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
2699 struct bnx2x *bp = params->bp;
2700 u8 port = params->port;
2705 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
2707 /* wait for init credit */
2708 init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
2709 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2710 DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
2712 while ((init_crd != crd) && count) {
2715 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2718 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2719 if (init_crd != crd) {
2720 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
2725 if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
2726 line_speed == SPEED_10 ||
2727 line_speed == SPEED_100 ||
2728 line_speed == SPEED_1000 ||
2729 line_speed == SPEED_2500) {
2730 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
2731 /* update threshold */
2732 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
2733 /* update init credit */
2734 init_crd = 778; /* (800-18-4) */
2737 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
2739 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
2740 /* update threshold */
2741 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
2742 /* update init credit */
2743 switch (line_speed) {
2745 init_crd = thresh + 553 - 22;
2748 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2753 REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
2754 DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
2755 line_speed, init_crd);
2757 /* probe the credit changes */
2758 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
2760 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
2763 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
2768 * bnx2x_get_emac_base - retrive emac base address
2770 * @bp: driver handle
2771 * @mdc_mdio_access: access type
2774 * This function selects the MDC/MDIO access (through emac0 or
2775 * emac1) depend on the mdc_mdio_access, port, port swapped. Each
2776 * phy has a default access mode, which could also be overridden
2777 * by nvram configuration. This parameter, whether this is the
2778 * default phy configuration, or the nvram overrun
2779 * configuration, is passed here as mdc_mdio_access and selects
2780 * the emac_base for the CL45 read/writes operations
2782 static u32 bnx2x_get_emac_base(struct bnx2x *bp,
2783 u32 mdc_mdio_access, u8 port)
2786 switch (mdc_mdio_access) {
2787 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
2789 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
2790 if (REG_RD(bp, NIG_REG_PORT_SWAP))
2791 emac_base = GRCBASE_EMAC1;
2793 emac_base = GRCBASE_EMAC0;
2795 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
2796 if (REG_RD(bp, NIG_REG_PORT_SWAP))
2797 emac_base = GRCBASE_EMAC0;
2799 emac_base = GRCBASE_EMAC1;
2801 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
2802 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2804 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
2805 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
2814 /******************************************************************/
2815 /* CL22 access functions */
2816 /******************************************************************/
2817 static int bnx2x_cl22_write(struct bnx2x *bp,
2818 struct bnx2x_phy *phy,
2824 /* Switch to CL22 */
2825 mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
2826 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
2827 mode & ~EMAC_MDIO_MODE_CLAUSE_45);
2830 tmp = ((phy->addr << 21) | (reg << 16) | val |
2831 EMAC_MDIO_COMM_COMMAND_WRITE_22 |
2832 EMAC_MDIO_COMM_START_BUSY);
2833 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2835 for (i = 0; i < 50; i++) {
2838 tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2839 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2844 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2845 DP(NETIF_MSG_LINK, "write phy register failed\n");
2848 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
2852 static int bnx2x_cl22_read(struct bnx2x *bp,
2853 struct bnx2x_phy *phy,
2854 u16 reg, u16 *ret_val)
2860 /* Switch to CL22 */
2861 mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
2862 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
2863 mode & ~EMAC_MDIO_MODE_CLAUSE_45);
2866 val = ((phy->addr << 21) | (reg << 16) |
2867 EMAC_MDIO_COMM_COMMAND_READ_22 |
2868 EMAC_MDIO_COMM_START_BUSY);
2869 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2871 for (i = 0; i < 50; i++) {
2874 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2875 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2876 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
2881 if (val & EMAC_MDIO_COMM_START_BUSY) {
2882 DP(NETIF_MSG_LINK, "read phy register failed\n");
2887 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
2891 /******************************************************************/
2892 /* CL45 access functions */
2893 /******************************************************************/
2894 static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
2895 u8 devad, u16 reg, u16 *ret_val)
2902 val = ((phy->addr << 21) | (devad << 16) | reg |
2903 EMAC_MDIO_COMM_COMMAND_ADDRESS |
2904 EMAC_MDIO_COMM_START_BUSY);
2905 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2907 for (i = 0; i < 50; i++) {
2910 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2911 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2916 if (val & EMAC_MDIO_COMM_START_BUSY) {
2917 DP(NETIF_MSG_LINK, "read phy register failed\n");
2918 netdev_err(bp->dev, "MDC/MDIO access timeout\n");
2923 val = ((phy->addr << 21) | (devad << 16) |
2924 EMAC_MDIO_COMM_COMMAND_READ_45 |
2925 EMAC_MDIO_COMM_START_BUSY);
2926 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2928 for (i = 0; i < 50; i++) {
2931 val = REG_RD(bp, phy->mdio_ctrl +
2932 EMAC_REG_EMAC_MDIO_COMM);
2933 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2934 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
2938 if (val & EMAC_MDIO_COMM_START_BUSY) {
2939 DP(NETIF_MSG_LINK, "read phy register failed\n");
2940 netdev_err(bp->dev, "MDC/MDIO access timeout\n");
2945 /* Work around for E3 A0 */
2946 if (phy->flags & FLAGS_MDC_MDIO_WA) {
2947 phy->flags ^= FLAGS_DUMMY_READ;
2948 if (phy->flags & FLAGS_DUMMY_READ) {
2950 bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
2957 static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
2958 u8 devad, u16 reg, u16 val)
2966 tmp = ((phy->addr << 21) | (devad << 16) | reg |
2967 EMAC_MDIO_COMM_COMMAND_ADDRESS |
2968 EMAC_MDIO_COMM_START_BUSY);
2969 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2971 for (i = 0; i < 50; i++) {
2974 tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2975 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2980 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2981 DP(NETIF_MSG_LINK, "write phy register failed\n");
2982 netdev_err(bp->dev, "MDC/MDIO access timeout\n");
2987 tmp = ((phy->addr << 21) | (devad << 16) | val |
2988 EMAC_MDIO_COMM_COMMAND_WRITE_45 |
2989 EMAC_MDIO_COMM_START_BUSY);
2990 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2992 for (i = 0; i < 50; i++) {
2995 tmp = REG_RD(bp, phy->mdio_ctrl +
2996 EMAC_REG_EMAC_MDIO_COMM);
2997 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3002 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3003 DP(NETIF_MSG_LINK, "write phy register failed\n");
3004 netdev_err(bp->dev, "MDC/MDIO access timeout\n");
3008 /* Work around for E3 A0 */
3009 if (phy->flags & FLAGS_MDC_MDIO_WA) {
3010 phy->flags ^= FLAGS_DUMMY_READ;
3011 if (phy->flags & FLAGS_DUMMY_READ) {
3013 bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
3021 /******************************************************************/
3022 /* BSC access functions from E3 */
3023 /******************************************************************/
3024 static void bnx2x_bsc_module_sel(struct link_params *params)
3027 u32 board_cfg, sfp_ctrl;
3028 u32 i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH];
3029 struct bnx2x *bp = params->bp;
3030 u8 port = params->port;
3031 /* Read I2C output PINs */
3032 board_cfg = REG_RD(bp, params->shmem_base +
3033 offsetof(struct shmem_region,
3034 dev_info.shared_hw_config.board));
3035 i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK;
3036 i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >>
3037 SHARED_HW_CFG_E3_I2C_MUX1_SHIFT;
3039 /* Read I2C output value */
3040 sfp_ctrl = REG_RD(bp, params->shmem_base +
3041 offsetof(struct shmem_region,
3042 dev_info.port_hw_config[port].e3_cmn_pin_cfg));
3043 i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0;
3044 i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0;
3045 DP(NETIF_MSG_LINK, "Setting BSC switch\n");
3046 for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++)
3047 bnx2x_set_cfg_pin(bp, i2c_pins[idx], i2c_val[idx]);
3050 static int bnx2x_bsc_read(struct link_params *params,
3051 struct bnx2x_phy *phy,
3060 struct bnx2x *bp = params->bp;
3062 if ((sl_devid != 0xa0) && (sl_devid != 0xa2)) {
3063 DP(NETIF_MSG_LINK, "invalid sl_devid 0x%x\n", sl_devid);
3067 if (xfer_cnt > 16) {
3068 DP(NETIF_MSG_LINK, "invalid xfer_cnt %d. Max is 16 bytes\n",
3072 bnx2x_bsc_module_sel(params);
3074 xfer_cnt = 16 - lc_addr;
3076 /* enable the engine */
3077 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3078 val |= MCPR_IMC_COMMAND_ENABLE;
3079 REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3081 /* program slave device ID */
3082 val = (sl_devid << 16) | sl_addr;
3083 REG_WR(bp, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val);
3085 /* start xfer with 0 byte to update the address pointer ???*/
3086 val = (MCPR_IMC_COMMAND_ENABLE) |
3087 (MCPR_IMC_COMMAND_WRITE_OP <<
3088 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3089 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0);
3090 REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3092 /* poll for completion */
3094 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3095 while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3097 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3099 DP(NETIF_MSG_LINK, "wr 0 byte timed out after %d try\n",
3108 /* start xfer with read op */
3109 val = (MCPR_IMC_COMMAND_ENABLE) |
3110 (MCPR_IMC_COMMAND_READ_OP <<
3111 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3112 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) |
3114 REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3116 /* poll for completion */
3118 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3119 while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3121 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3123 DP(NETIF_MSG_LINK, "rd op timed out after %d try\n", i);
3131 for (i = (lc_addr >> 2); i < 4; i++) {
3132 data_array[i] = REG_RD(bp, (MCP_REG_MCPR_IMC_DATAREG0 + i*4));
3134 data_array[i] = ((data_array[i] & 0x000000ff) << 24) |
3135 ((data_array[i] & 0x0000ff00) << 8) |
3136 ((data_array[i] & 0x00ff0000) >> 8) |
3137 ((data_array[i] & 0xff000000) >> 24);
3143 static void bnx2x_cl45_read_or_write(struct bnx2x *bp, struct bnx2x_phy *phy,
3144 u8 devad, u16 reg, u16 or_val)
3147 bnx2x_cl45_read(bp, phy, devad, reg, &val);
3148 bnx2x_cl45_write(bp, phy, devad, reg, val | or_val);
3151 int bnx2x_phy_read(struct link_params *params, u8 phy_addr,
3152 u8 devad, u16 reg, u16 *ret_val)
3156 * Probe for the phy according to the given phy_addr, and execute
3157 * the read request on it
3159 for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
3160 if (params->phy[phy_index].addr == phy_addr) {
3161 return bnx2x_cl45_read(params->bp,
3162 ¶ms->phy[phy_index], devad,
3169 int bnx2x_phy_write(struct link_params *params, u8 phy_addr,
3170 u8 devad, u16 reg, u16 val)
3174 * Probe for the phy according to the given phy_addr, and execute
3175 * the write request on it
3177 for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
3178 if (params->phy[phy_index].addr == phy_addr) {
3179 return bnx2x_cl45_write(params->bp,
3180 ¶ms->phy[phy_index], devad,
3186 static u8 bnx2x_get_warpcore_lane(struct bnx2x_phy *phy,
3187 struct link_params *params)
3190 struct bnx2x *bp = params->bp;
3191 u32 path_swap, path_swap_ovr;
3195 port = params->port;
3197 if (bnx2x_is_4_port_mode(bp)) {
3198 u32 port_swap, port_swap_ovr;
3200 /*figure out path swap value */
3201 path_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR);
3202 if (path_swap_ovr & 0x1)
3203 path_swap = (path_swap_ovr & 0x2);
3205 path_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP);
3210 /*figure out port swap value */
3211 port_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR);
3212 if (port_swap_ovr & 0x1)
3213 port_swap = (port_swap_ovr & 0x2);
3215 port_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP);
3220 lane = (port<<1) + path;
3221 } else { /* two port mode - no port swap */
3223 /*figure out path swap value */
3225 REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP_OVWR);
3226 if (path_swap_ovr & 0x1) {
3227 path_swap = (path_swap_ovr & 0x2);
3230 REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP);
3240 static void bnx2x_set_aer_mmd(struct link_params *params,
3241 struct bnx2x_phy *phy)
3244 u16 offset, aer_val;
3245 struct bnx2x *bp = params->bp;
3246 ser_lane = ((params->lane_config &
3247 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3248 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3250 offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
3251 (phy->addr + ser_lane) : 0;
3253 if (USES_WARPCORE(bp)) {
3254 aer_val = bnx2x_get_warpcore_lane(phy, params);
3256 * In Dual-lane mode, two lanes are joined together,
3257 * so in order to configure them, the AER broadcast method is
3259 * 0x200 is the broadcast address for lanes 0,1
3260 * 0x201 is the broadcast address for lanes 2,3
3262 if (phy->flags & FLAGS_WC_DUAL_MODE)
3263 aer_val = (aer_val >> 1) | 0x200;
3264 } else if (CHIP_IS_E2(bp))
3265 aer_val = 0x3800 + offset - 1;
3267 aer_val = 0x3800 + offset;
3268 DP(NETIF_MSG_LINK, "Set AER to 0x%x\n", aer_val);
3269 CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
3270 MDIO_AER_BLOCK_AER_REG, aer_val);
3274 /******************************************************************/
3275 /* Internal phy section */
3276 /******************************************************************/
3278 static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
3280 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3283 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
3284 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
3286 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
3289 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
3292 static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
3296 DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
3298 val = SERDES_RESET_BITS << (port*16);
3300 /* reset and unreset the SerDes/XGXS */
3301 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3303 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3305 bnx2x_set_serdes_access(bp, port);
3307 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + port*0x10,
3308 DEFAULT_PHY_DEV_ADDR);
3311 static void bnx2x_xgxs_deassert(struct link_params *params)
3313 struct bnx2x *bp = params->bp;
3316 DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
3317 port = params->port;
3319 val = XGXS_RESET_BITS << (port*16);
3321 /* reset and unreset the SerDes/XGXS */
3322 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3324 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3326 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0);
3327 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
3328 params->phy[INT_PHY].def_md_devad);
3331 static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
3332 struct link_params *params, u16 *ieee_fc)
3334 struct bnx2x *bp = params->bp;
3335 *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
3337 * resolve pause mode and advertisement Please refer to Table
3338 * 28B-3 of the 802.3ab-1999 spec
3341 switch (phy->req_flow_ctrl) {
3342 case BNX2X_FLOW_CTRL_AUTO:
3343 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH)
3344 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3347 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3350 case BNX2X_FLOW_CTRL_TX:
3351 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3354 case BNX2X_FLOW_CTRL_RX:
3355 case BNX2X_FLOW_CTRL_BOTH:
3356 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3359 case BNX2X_FLOW_CTRL_NONE:
3361 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
3364 DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
3367 static void set_phy_vars(struct link_params *params,
3368 struct link_vars *vars)
3370 struct bnx2x *bp = params->bp;
3371 u8 actual_phy_idx, phy_index, link_cfg_idx;
3372 u8 phy_config_swapped = params->multi_phy_config &
3373 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
3374 for (phy_index = INT_PHY; phy_index < params->num_phys;
3376 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
3377 actual_phy_idx = phy_index;
3378 if (phy_config_swapped) {
3379 if (phy_index == EXT_PHY1)
3380 actual_phy_idx = EXT_PHY2;
3381 else if (phy_index == EXT_PHY2)
3382 actual_phy_idx = EXT_PHY1;
3384 params->phy[actual_phy_idx].req_flow_ctrl =
3385 params->req_flow_ctrl[link_cfg_idx];
3387 params->phy[actual_phy_idx].req_line_speed =
3388 params->req_line_speed[link_cfg_idx];
3390 params->phy[actual_phy_idx].speed_cap_mask =
3391 params->speed_cap_mask[link_cfg_idx];
3393 params->phy[actual_phy_idx].req_duplex =
3394 params->req_duplex[link_cfg_idx];
3396 if (params->req_line_speed[link_cfg_idx] ==
3398 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
3400 DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
3401 " speed_cap_mask %x\n",
3402 params->phy[actual_phy_idx].req_flow_ctrl,
3403 params->phy[actual_phy_idx].req_line_speed,
3404 params->phy[actual_phy_idx].speed_cap_mask);
3408 static void bnx2x_ext_phy_set_pause(struct link_params *params,
3409 struct bnx2x_phy *phy,
3410 struct link_vars *vars)
3413 struct bnx2x *bp = params->bp;
3414 /* read modify write pause advertizing */
3415 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
3417 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3419 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3420 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
3421 if ((vars->ieee_fc &
3422 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3423 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3424 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3426 if ((vars->ieee_fc &
3427 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3428 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3429 val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
3431 DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
3432 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
3435 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
3437 switch (pause_result) { /* ASYM P ASYM P */
3438 case 0xb: /* 1 0 1 1 */
3439 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
3442 case 0xe: /* 1 1 1 0 */
3443 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
3446 case 0x5: /* 0 1 0 1 */
3447 case 0x7: /* 0 1 1 1 */
3448 case 0xd: /* 1 1 0 1 */
3449 case 0xf: /* 1 1 1 1 */
3450 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
3456 if (pause_result & (1<<0))
3457 vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
3458 if (pause_result & (1<<1))
3459 vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
3462 static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
3463 struct link_params *params,
3464 struct link_vars *vars)
3466 struct bnx2x *bp = params->bp;
3467 u16 ld_pause; /* local */
3468 u16 lp_pause; /* link partner */
3473 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3475 if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
3476 vars->flow_ctrl = phy->req_flow_ctrl;
3477 else if (phy->req_line_speed != SPEED_AUTO_NEG)
3478 vars->flow_ctrl = params->req_fc_auto_adv;
3479 else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
3481 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616) {
3482 bnx2x_cl22_read(bp, phy,
3484 bnx2x_cl22_read(bp, phy,
3487 bnx2x_cl45_read(bp, phy,
3489 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3490 bnx2x_cl45_read(bp, phy,
3492 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3494 pause_result = (ld_pause &
3495 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
3496 pause_result |= (lp_pause &
3497 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
3498 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
3500 bnx2x_pause_resolve(vars, pause_result);
3504 /******************************************************************/
3505 /* Warpcore section */
3506 /******************************************************************/
3507 /* The init_internal_warpcore should mirror the xgxs,
3508 * i.e. reset the lane (if needed), set aer for the
3509 * init configuration, and set/clear SGMII flag. Internal
3510 * phy init is done purely in phy_init stage.
3512 static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
3513 struct link_params *params,
3514 struct link_vars *vars) {
3515 u16 val16 = 0, lane;
3516 struct bnx2x *bp = params->bp;
3517 DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n");
3518 /* Check adding advertisement for 1G KX */
3519 if (((vars->line_speed == SPEED_AUTO_NEG) &&
3520 (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
3521 (vars->line_speed == SPEED_1000)) {
3525 /* Enable CL37 1G Parallel Detect */
3526 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3527 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &sd_digital);
3528 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3529 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3530 (sd_digital | 0x1));
3532 DP(NETIF_MSG_LINK, "Advertize 1G\n");
3534 if (((vars->line_speed == SPEED_AUTO_NEG) &&
3535 (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
3536 (vars->line_speed == SPEED_10000)) {
3537 /* Check adding advertisement for 10G KR */
3539 /* Enable 10G Parallel Detect */
3540 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3541 MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
3543 DP(NETIF_MSG_LINK, "Advertize 10G\n");
3546 /* Set Transmit PMD settings */
3547 lane = bnx2x_get_warpcore_lane(phy, params);
3548 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3549 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3550 ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3551 (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3552 (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
3553 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3554 MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
3556 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3557 MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL,
3559 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3560 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3563 /* Advertised speeds */
3564 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3565 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16);
3567 /* Advertise pause */
3568 bnx2x_ext_phy_set_pause(params, phy, vars);
3570 /* Enable Autoneg */
3571 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3572 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1000);
3574 /* Over 1G - AN local device user page 1 */
3575 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3576 MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
3578 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3579 MDIO_WC_REG_DIGITAL5_MISC7, &val16);
3581 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3582 MDIO_WC_REG_DIGITAL5_MISC7, val16 | 0x100);
3585 static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy,
3586 struct link_params *params,
3587 struct link_vars *vars)
3589 struct bnx2x *bp = params->bp;
3592 /* Disable Autoneg */
3593 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3594 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7);
3596 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3597 MDIO_WC_REG_PAR_DET_10G_CTRL, 0);
3599 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3600 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0x3f00);
3602 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3603 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0);
3605 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3606 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
3608 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3609 MDIO_WC_REG_DIGITAL3_UP1, 0x1);
3611 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3612 MDIO_WC_REG_DIGITAL5_MISC7, 0xa);
3614 /* Disable CL36 PCS Tx */
3615 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3616 MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0);
3618 /* Double Wide Single Data Rate @ pll rate */
3619 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3620 MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF);
3622 /* Leave cl72 training enable, needed for KR */
3623 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3624 MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150,
3627 /* Leave CL72 enabled */
3628 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3629 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3631 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3632 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3635 /* Set speed via PMA/PMD register */
3636 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3637 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
3639 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3640 MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
3642 /*Enable encoded forced speed */
3643 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3644 MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
3646 /* Turn TX scramble payload only the 64/66 scrambler */
3647 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3648 MDIO_WC_REG_TX66_CONTROL, 0x9);
3650 /* Turn RX scramble payload only the 64/66 scrambler */
3651 bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3652 MDIO_WC_REG_RX66_CONTROL, 0xF9);
3654 /* set and clear loopback to cause a reset to 64/66 decoder */
3655 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3656 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000);
3657 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3658 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
3662 static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
3663 struct link_params *params,
3666 struct bnx2x *bp = params->bp;
3667 u16 misc1_val, tap_val, tx_driver_val, lane, val;
3668 /* Hold rxSeqStart */
3669 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3670 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
3671 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3672 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val | 0x8000));
3674 /* Hold tx_fifo_reset */
3675 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3676 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
3677 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3678 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, (val | 0x1));
3680 /* Disable CL73 AN */
3681 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
3683 /* Disable 100FX Enable and Auto-Detect */
3684 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3685 MDIO_WC_REG_FX100_CTRL1, &val);
3686 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3687 MDIO_WC_REG_FX100_CTRL1, (val & 0xFFFA));
3689 /* Disable 100FX Idle detect */
3690 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3691 MDIO_WC_REG_FX100_CTRL3, &val);
3692 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3693 MDIO_WC_REG_FX100_CTRL3, (val | 0x0080));
3695 /* Set Block address to Remote PHY & Clear forced_speed[5] */
3696 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3697 MDIO_WC_REG_DIGITAL4_MISC3, &val);
3698 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3699 MDIO_WC_REG_DIGITAL4_MISC3, (val & 0xFF7F));
3701 /* Turn off auto-detect & fiber mode */
3702 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3703 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
3704 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3705 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3708 /* Set filter_force_link, disable_false_link and parallel_detect */
3709 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3710 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val);
3711 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3712 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3713 ((val | 0x0006) & 0xFFFE));
3716 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3717 MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val);
3719 misc1_val &= ~(0x1f);
3723 tap_val = ((0x08 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3724 (0x37 << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3725 (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
3727 ((0x00 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3728 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3729 (0x03 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
3733 tap_val = ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3734 (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3735 (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
3737 ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3738 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3739 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
3741 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3742 MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
3744 /* Set Transmit PMD settings */
3745 lane = bnx2x_get_warpcore_lane(phy, params);
3746 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3747 MDIO_WC_REG_TX_FIR_TAP,
3748 tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE);
3749 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3750 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3753 /* Enable fiber mode, enable and invert sig_det */
3754 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3755 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
3756 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3757 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, val | 0xd);
3759 /* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
3760 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3761 MDIO_WC_REG_DIGITAL4_MISC3, &val);
3762 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3763 MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080);
3765 /* 10G XFI Full Duplex */
3766 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3767 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
3769 /* Release tx_fifo_reset */
3770 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3771 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
3772 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3773 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, val & 0xFFFE);
3775 /* Release rxSeqStart */
3776 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3777 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
3778 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3779 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val & 0x7FFF));
3782 static void bnx2x_warpcore_set_20G_KR2(struct bnx2x *bp,
3783 struct bnx2x_phy *phy)
3785 DP(NETIF_MSG_LINK, "KR2 still not supported !!!\n");
3788 static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp,
3789 struct bnx2x_phy *phy,
3792 /* Rx0 anaRxControl1G */
3793 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3794 MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90);
3796 /* Rx2 anaRxControl1G */
3797 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3798 MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90);
3800 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3801 MDIO_WC_REG_RX66_SCW0, 0xE070);
3803 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3804 MDIO_WC_REG_RX66_SCW1, 0xC0D0);
3806 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3807 MDIO_WC_REG_RX66_SCW2, 0xA0B0);
3809 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3810 MDIO_WC_REG_RX66_SCW3, 0x8090);
3812 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3813 MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0);
3815 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3816 MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0);
3818 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3819 MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0);
3821 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3822 MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0);
3824 /* Serdes Digital Misc1 */
3825 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3826 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008);
3828 /* Serdes Digital4 Misc3 */
3829 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3830 MDIO_WC_REG_DIGITAL4_MISC3, 0x8088);
3832 /* Set Transmit PMD settings */
3833 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3834 MDIO_WC_REG_TX_FIR_TAP,
3835 ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3836 (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3837 (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET) |
3838 MDIO_WC_REG_TX_FIR_TAP_ENABLE));
3839 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3840 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3841 ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3842 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3843 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
3846 static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
3847 struct link_params *params,
3850 struct bnx2x *bp = params->bp;
3851 u16 val16, digctrl_kx1, digctrl_kx2;
3854 lane = bnx2x_get_warpcore_lane(phy, params);
3856 /* Clear XFI clock comp in non-10G single lane mode. */
3857 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3858 MDIO_WC_REG_RX66_CONTROL, &val16);
3859 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3860 MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13));
3862 if (phy->req_line_speed == SPEED_AUTO_NEG) {
3864 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3865 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3866 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3867 MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
3869 DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n");
3871 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3872 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3874 switch (phy->req_line_speed) {
3884 DP(NETIF_MSG_LINK, "Speed not supported: 0x%x"
3885 "\n", phy->req_line_speed);
3889 if (phy->req_duplex == DUPLEX_FULL)
3892 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3893 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16);
3895 DP(NETIF_MSG_LINK, "set SGMII force speed %d\n",
3896 phy->req_line_speed);
3897 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3898 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3899 DP(NETIF_MSG_LINK, " (readback) %x\n", val16);
3902 /* SGMII Slave mode and disable signal detect */
3903 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3904 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1);
3908 digctrl_kx1 &= 0xff4a;
3910 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3911 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3914 /* Turn off parallel detect */
3915 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3916 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2);
3917 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3918 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3919 (digctrl_kx2 & ~(1<<2)));
3921 /* Re-enable parallel detect */
3922 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3923 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3924 (digctrl_kx2 | (1<<2)));
3926 /* Enable autodet */
3927 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3928 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3929 (digctrl_kx1 | 0x10));
3932 static void bnx2x_warpcore_reset_lane(struct bnx2x *bp,
3933 struct bnx2x_phy *phy,
3937 /* Take lane out of reset after configuration is finished */
3938 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3939 MDIO_WC_REG_DIGITAL5_MISC6, &val);
3944 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3945 MDIO_WC_REG_DIGITAL5_MISC6, val);
3946 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3947 MDIO_WC_REG_DIGITAL5_MISC6, &val);
3951 /* Clear SFI/XFI link settings registers */
3952 static void bnx2x_warpcore_clear_regs(struct bnx2x_phy *phy,
3953 struct link_params *params,
3956 struct bnx2x *bp = params->bp;
3959 /* Set XFI clock comp as default. */
3960 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3961 MDIO_WC_REG_RX66_CONTROL, &val16);
3962 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3963 MDIO_WC_REG_RX66_CONTROL, val16 | (3<<13));
3965 bnx2x_warpcore_reset_lane(bp, phy, 1);
3966 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
3967 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3968 MDIO_WC_REG_FX100_CTRL1, 0x014a);
3969 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3970 MDIO_WC_REG_FX100_CTRL3, 0x0800);
3971 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3972 MDIO_WC_REG_DIGITAL4_MISC3, 0x8008);
3973 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3974 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x0195);
3975 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3976 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x0007);
3977 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3978 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x0002);
3979 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3980 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000);
3981 lane = bnx2x_get_warpcore_lane(phy, params);
3982 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3983 MDIO_WC_REG_TX_FIR_TAP, 0x0000);
3984 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3985 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990);
3986 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3987 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
3988 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3989 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140);
3990 bnx2x_warpcore_reset_lane(bp, phy, 0);
3993 static int bnx2x_get_mod_abs_int_cfg(struct bnx2x *bp,
3995 u32 shmem_base, u8 port,
3996 u8 *gpio_num, u8 *gpio_port)
4001 if (CHIP_IS_E3(bp)) {
4002 cfg_pin = (REG_RD(bp, shmem_base +
4003 offsetof(struct shmem_region,
4004 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4005 PORT_HW_CFG_E3_MOD_ABS_MASK) >>
4006 PORT_HW_CFG_E3_MOD_ABS_SHIFT;
4009 * Should not happen. This function called upon interrupt
4010 * triggered by GPIO ( since EPIO can only generate interrupts
4012 * So if this function was called and none of the GPIOs was set,
4013 * it means the shit hit the fan.
4015 if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
4016 (cfg_pin > PIN_CFG_GPIO3_P1)) {
4017 DP(NETIF_MSG_LINK, "ERROR: Invalid cfg pin %x for "
4018 "module detect indication\n",
4023 *gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
4024 *gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
4026 *gpio_num = MISC_REGISTERS_GPIO_3;
4029 DP(NETIF_MSG_LINK, "MOD_ABS int GPIO%d_P%d\n", *gpio_num, *gpio_port);
4033 static int bnx2x_is_sfp_module_plugged(struct bnx2x_phy *phy,
4034 struct link_params *params)
4036 struct bnx2x *bp = params->bp;
4037 u8 gpio_num, gpio_port;
4039 if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id,
4040 params->shmem_base, params->port,
4041 &gpio_num, &gpio_port) != 0)
4043 gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
4045 /* Call the handling function in case module is detected */
4052 static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
4053 struct link_params *params,
4054 struct link_vars *vars)
4056 struct bnx2x *bp = params->bp;
4059 u16 lane = bnx2x_get_warpcore_lane(phy, params);
4060 serdes_net_if = (REG_RD(bp, params->shmem_base +
4061 offsetof(struct shmem_region, dev_info.
4062 port_hw_config[params->port].default_cfg)) &
4063 PORT_HW_CFG_NET_SERDES_IF_MASK);
4064 DP(NETIF_MSG_LINK, "Begin Warpcore init, link_speed %d, "
4065 "serdes_net_if = 0x%x\n",
4066 vars->line_speed, serdes_net_if);
4067 bnx2x_set_aer_mmd(params, phy);
4069 vars->phy_flags |= PHY_XGXS_FLAG;
4070 if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
4071 (phy->req_line_speed &&
4072 ((phy->req_line_speed == SPEED_100) ||
4073 (phy->req_line_speed == SPEED_10)))) {
4074 vars->phy_flags |= PHY_SGMII_FLAG;
4075 DP(NETIF_MSG_LINK, "Setting SGMII mode\n");
4076 bnx2x_warpcore_clear_regs(phy, params, lane);
4077 bnx2x_warpcore_set_sgmii_speed(phy, params, 0);
4079 switch (serdes_net_if) {
4080 case PORT_HW_CFG_NET_SERDES_IF_KR:
4081 /* Enable KR Auto Neg */
4082 if (params->loopback_mode == LOOPBACK_NONE)
4083 bnx2x_warpcore_enable_AN_KR(phy, params, vars);
4085 DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n");
4086 bnx2x_warpcore_set_10G_KR(phy, params, vars);
4090 case PORT_HW_CFG_NET_SERDES_IF_XFI:
4091 bnx2x_warpcore_clear_regs(phy, params, lane);
4092 if (vars->line_speed == SPEED_10000) {
4093 DP(NETIF_MSG_LINK, "Setting 10G XFI\n");
4094 bnx2x_warpcore_set_10G_XFI(phy, params, 1);
4096 if (SINGLE_MEDIA_DIRECT(params)) {
4097 DP(NETIF_MSG_LINK, "1G Fiber\n");
4100 DP(NETIF_MSG_LINK, "10/100/1G SGMII\n");
4103 bnx2x_warpcore_set_sgmii_speed(phy,
4110 case PORT_HW_CFG_NET_SERDES_IF_SFI:
4112 bnx2x_warpcore_clear_regs(phy, params, lane);
4113 if (vars->line_speed == SPEED_10000) {
4114 DP(NETIF_MSG_LINK, "Setting 10G SFI\n");
4115 bnx2x_warpcore_set_10G_XFI(phy, params, 0);
4116 } else if (vars->line_speed == SPEED_1000) {
4117 DP(NETIF_MSG_LINK, "Setting 1G Fiber\n");
4118 bnx2x_warpcore_set_sgmii_speed(phy, params, 1);
4120 /* Issue Module detection */
4121 if (bnx2x_is_sfp_module_plugged(phy, params))
4122 bnx2x_sfp_module_detection(phy, params);
4125 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
4126 if (vars->line_speed != SPEED_20000) {
4127 DP(NETIF_MSG_LINK, "Speed not supported yet\n");
4130 DP(NETIF_MSG_LINK, "Setting 20G DXGXS\n");
4131 bnx2x_warpcore_set_20G_DXGXS(bp, phy, lane);
4132 /* Issue Module detection */
4134 bnx2x_sfp_module_detection(phy, params);
4137 case PORT_HW_CFG_NET_SERDES_IF_KR2:
4138 if (vars->line_speed != SPEED_20000) {
4139 DP(NETIF_MSG_LINK, "Speed not supported yet\n");
4142 DP(NETIF_MSG_LINK, "Setting 20G KR2\n");
4143 bnx2x_warpcore_set_20G_KR2(bp, phy);
4147 DP(NETIF_MSG_LINK, "Unsupported Serdes Net Interface "
4148 "0x%x\n", serdes_net_if);
4153 /* Take lane out of reset after configuration is finished */
4154 bnx2x_warpcore_reset_lane(bp, phy, 0);
4155 DP(NETIF_MSG_LINK, "Exit config init\n");
4158 static void bnx2x_sfp_e3_set_transmitter(struct link_params *params,
4159 struct bnx2x_phy *phy,
4162 struct bnx2x *bp = params->bp;
4164 u8 port = params->port;
4166 cfg_pin = REG_RD(bp, params->shmem_base +
4167 offsetof(struct shmem_region,
4168 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4169 PORT_HW_CFG_TX_LASER_MASK;
4170 /* Set the !tx_en since this pin is DISABLE_TX_LASER */
4171 DP(NETIF_MSG_LINK, "Setting WC TX to %d\n", tx_en);
4172 /* For 20G, the expected pin to be used is 3 pins after the current */
4174 bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1);
4175 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
4176 bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1);
4179 static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy,
4180 struct link_params *params)
4182 struct bnx2x *bp = params->bp;
4184 bnx2x_sfp_e3_set_transmitter(params, phy, 0);
4185 bnx2x_set_mdio_clk(bp, params->chip_id, params->port);
4186 bnx2x_set_aer_mmd(params, phy);
4187 /* Global register */
4188 bnx2x_warpcore_reset_lane(bp, phy, 1);
4190 /* Clear loopback settings (if any) */
4192 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4193 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4194 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4195 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 &
4198 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4199 MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
4200 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4201 MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 & 0xfffe);
4203 /* Update those 1-copy registers */
4204 CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4205 MDIO_AER_BLOCK_AER_REG, 0);
4206 /* Enable 1G MDIO (1-copy) */
4207 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4208 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4210 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4211 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4214 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4215 MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
4216 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4217 MDIO_WC_REG_XGXSBLK1_LANECTRL2,
4222 static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy,
4223 struct link_params *params)
4225 struct bnx2x *bp = params->bp;
4228 DP(NETIF_MSG_LINK, "Setting Warpcore loopback type %x, speed %d\n",
4229 params->loopback_mode, phy->req_line_speed);
4231 if (phy->req_line_speed < SPEED_10000) {
4234 /* Update those 1-copy registers */
4235 CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4236 MDIO_AER_BLOCK_AER_REG, 0);
4237 /* Enable 1G MDIO (1-copy) */
4238 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4239 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4241 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4242 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4244 /* Set 1G loopback based on lane (1-copy) */
4245 lane = bnx2x_get_warpcore_lane(phy, params);
4246 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4247 MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
4248 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4249 MDIO_WC_REG_XGXSBLK1_LANECTRL2,
4252 /* Switch back to 4-copy registers */
4253 bnx2x_set_aer_mmd(params, phy);
4254 /* Global loopback, not recommended. */
4255 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4256 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4257 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4258 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 |
4262 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4263 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4264 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4265 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 |
4268 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4269 MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
4270 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4271 MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 | 0x1);
4276 void bnx2x_link_status_update(struct link_params *params,
4277 struct link_vars *vars)
4279 struct bnx2x *bp = params->bp;
4281 u8 port = params->port;
4282 u32 sync_offset, media_types;
4283 /* Update PHY configuration */
4284 set_phy_vars(params, vars);
4286 vars->link_status = REG_RD(bp, params->shmem_base +
4287 offsetof(struct shmem_region,
4288 port_mb[port].link_status));
4290 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
4291 vars->phy_flags = PHY_XGXS_FLAG;
4292 if (vars->link_up) {
4293 DP(NETIF_MSG_LINK, "phy link up\n");
4295 vars->phy_link_up = 1;
4296 vars->duplex = DUPLEX_FULL;
4297 switch (vars->link_status &
4298 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
4300 vars->duplex = DUPLEX_HALF;
4303 vars->line_speed = SPEED_10;
4307 vars->duplex = DUPLEX_HALF;
4311 vars->line_speed = SPEED_100;
4315 vars->duplex = DUPLEX_HALF;
4318 vars->line_speed = SPEED_1000;
4322 vars->duplex = DUPLEX_HALF;
4325 vars->line_speed = SPEED_2500;
4329 vars->line_speed = SPEED_10000;
4332 vars->line_speed = SPEED_20000;
4337 vars->flow_ctrl = 0;
4338 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
4339 vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
4341 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
4342 vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
4344 if (!vars->flow_ctrl)
4345 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4347 if (vars->line_speed &&
4348 ((vars->line_speed == SPEED_10) ||
4349 (vars->line_speed == SPEED_100))) {
4350 vars->phy_flags |= PHY_SGMII_FLAG;
4352 vars->phy_flags &= ~PHY_SGMII_FLAG;
4354 if (vars->line_speed &&
4355 USES_WARPCORE(bp) &&
4356 (vars->line_speed == SPEED_1000))
4357 vars->phy_flags |= PHY_SGMII_FLAG;
4358 /* anything 10 and over uses the bmac */
4359 link_10g_plus = (vars->line_speed >= SPEED_10000);
4361 if (link_10g_plus) {
4362 if (USES_WARPCORE(bp))
4363 vars->mac_type = MAC_TYPE_XMAC;
4365 vars->mac_type = MAC_TYPE_BMAC;
4367 if (USES_WARPCORE(bp))
4368 vars->mac_type = MAC_TYPE_UMAC;
4370 vars->mac_type = MAC_TYPE_EMAC;
4372 } else { /* link down */
4373 DP(NETIF_MSG_LINK, "phy link down\n");
4375 vars->phy_link_up = 0;
4377 vars->line_speed = 0;
4378 vars->duplex = DUPLEX_FULL;
4379 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4381 /* indicate no mac active */
4382 vars->mac_type = MAC_TYPE_NONE;
4385 /* Sync media type */
4386 sync_offset = params->shmem_base +
4387 offsetof(struct shmem_region,
4388 dev_info.port_hw_config[port].media_type);
4389 media_types = REG_RD(bp, sync_offset);
4391 params->phy[INT_PHY].media_type =
4392 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
4393 PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
4394 params->phy[EXT_PHY1].media_type =
4395 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
4396 PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
4397 params->phy[EXT_PHY2].media_type =
4398 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
4399 PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
4400 DP(NETIF_MSG_LINK, "media_types = 0x%x\n", media_types);
4402 /* Sync AEU offset */
4403 sync_offset = params->shmem_base +
4404 offsetof(struct shmem_region,
4405 dev_info.port_hw_config[port].aeu_int_mask);
4407 vars->aeu_int_mask = REG_RD(bp, sync_offset);
4409 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x int_mask 0x%x\n",
4410 vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
4411 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
4412 vars->line_speed, vars->duplex, vars->flow_ctrl);
4416 static void bnx2x_set_master_ln(struct link_params *params,
4417 struct bnx2x_phy *phy)
4419 struct bnx2x *bp = params->bp;
4420 u16 new_master_ln, ser_lane;
4421 ser_lane = ((params->lane_config &
4422 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4423 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4425 /* set the master_ln for AN */
4426 CL22_RD_OVER_CL45(bp, phy,
4427 MDIO_REG_BANK_XGXS_BLOCK2,
4428 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4431 CL22_WR_OVER_CL45(bp, phy,
4432 MDIO_REG_BANK_XGXS_BLOCK2 ,
4433 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4434 (new_master_ln | ser_lane));
4437 static int bnx2x_reset_unicore(struct link_params *params,
4438 struct bnx2x_phy *phy,
4441 struct bnx2x *bp = params->bp;
4444 CL22_RD_OVER_CL45(bp, phy,
4445 MDIO_REG_BANK_COMBO_IEEE0,
4446 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
4448 /* reset the unicore */
4449 CL22_WR_OVER_CL45(bp, phy,
4450 MDIO_REG_BANK_COMBO_IEEE0,
4451 MDIO_COMBO_IEEE0_MII_CONTROL,
4453 MDIO_COMBO_IEEO_MII_CONTROL_RESET));
4455 bnx2x_set_serdes_access(bp, params->port);
4457 /* wait for the reset to self clear */
4458 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
4461 /* the reset erased the previous bank value */
4462 CL22_RD_OVER_CL45(bp, phy,
4463 MDIO_REG_BANK_COMBO_IEEE0,
4464 MDIO_COMBO_IEEE0_MII_CONTROL,
4467 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
4473 netdev_err(bp->dev, "Warning: PHY was not initialized,"
4476 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
4481 static void bnx2x_set_swap_lanes(struct link_params *params,
4482 struct bnx2x_phy *phy)
4484 struct bnx2x *bp = params->bp;
4486 * Each two bits represents a lane number:
4487 * No swap is 0123 => 0x1b no need to enable the swap
4489 u16 ser_lane, rx_lane_swap, tx_lane_swap;
4491 ser_lane = ((params->lane_config &
4492 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4493 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4494 rx_lane_swap = ((params->lane_config &
4495 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
4496 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
4497 tx_lane_swap = ((params->lane_config &
4498 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
4499 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
4501 if (rx_lane_swap != 0x1b) {
4502 CL22_WR_OVER_CL45(bp, phy,
4503 MDIO_REG_BANK_XGXS_BLOCK2,
4504 MDIO_XGXS_BLOCK2_RX_LN_SWAP,
4506 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
4507 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
4509 CL22_WR_OVER_CL45(bp, phy,
4510 MDIO_REG_BANK_XGXS_BLOCK2,
4511 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
4514 if (tx_lane_swap != 0x1b) {
4515 CL22_WR_OVER_CL45(bp, phy,
4516 MDIO_REG_BANK_XGXS_BLOCK2,
4517 MDIO_XGXS_BLOCK2_TX_LN_SWAP,
4519 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
4521 CL22_WR_OVER_CL45(bp, phy,
4522 MDIO_REG_BANK_XGXS_BLOCK2,
4523 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
4527 static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
4528 struct link_params *params)
4530 struct bnx2x *bp = params->bp;
4532 CL22_RD_OVER_CL45(bp, phy,
4533 MDIO_REG_BANK_SERDES_DIGITAL,
4534 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
4536 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4537 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
4539 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
4540 DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
4541 phy->speed_cap_mask, control2);
4542 CL22_WR_OVER_CL45(bp, phy,
4543 MDIO_REG_BANK_SERDES_DIGITAL,
4544 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
4547 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
4548 (phy->speed_cap_mask &
4549 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
4550 DP(NETIF_MSG_LINK, "XGXS\n");
4552 CL22_WR_OVER_CL45(bp, phy,
4553 MDIO_REG_BANK_10G_PARALLEL_DETECT,
4554 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
4555 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
4557 CL22_RD_OVER_CL45(bp, phy,
4558 MDIO_REG_BANK_10G_PARALLEL_DETECT,
4559 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4564 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
4566 CL22_WR_OVER_CL45(bp, phy,
4567 MDIO_REG_BANK_10G_PARALLEL_DETECT,
4568 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4571 /* Disable parallel detection of HiG */
4572 CL22_WR_OVER_CL45(bp, phy,
4573 MDIO_REG_BANK_XGXS_BLOCK2,
4574 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
4575 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
4576 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
4580 static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
4581 struct link_params *params,
4582 struct link_vars *vars,
4585 struct bnx2x *bp = params->bp;
4589 CL22_RD_OVER_CL45(bp, phy,
4590 MDIO_REG_BANK_COMBO_IEEE0,
4591 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
4593 /* CL37 Autoneg Enabled */
4594 if (vars->line_speed == SPEED_AUTO_NEG)
4595 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
4596 else /* CL37 Autoneg Disabled */
4597 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4598 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
4600 CL22_WR_OVER_CL45(bp, phy,
4601 MDIO_REG_BANK_COMBO_IEEE0,
4602 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
4604 /* Enable/Disable Autodetection */
4606 CL22_RD_OVER_CL45(bp, phy,
4607 MDIO_REG_BANK_SERDES_DIGITAL,
4608 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val);
4609 reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
4610 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
4611 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
4612 if (vars->line_speed == SPEED_AUTO_NEG)
4613 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4615 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4617 CL22_WR_OVER_CL45(bp, phy,
4618 MDIO_REG_BANK_SERDES_DIGITAL,
4619 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
4621 /* Enable TetonII and BAM autoneg */
4622 CL22_RD_OVER_CL45(bp, phy,
4623 MDIO_REG_BANK_BAM_NEXT_PAGE,
4624 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
4626 if (vars->line_speed == SPEED_AUTO_NEG) {
4627 /* Enable BAM aneg Mode and TetonII aneg Mode */
4628 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4629 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4631 /* TetonII and BAM Autoneg Disabled */
4632 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4633 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4635 CL22_WR_OVER_CL45(bp, phy,
4636 MDIO_REG_BANK_BAM_NEXT_PAGE,
4637 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
4641 /* Enable Cl73 FSM status bits */
4642 CL22_WR_OVER_CL45(bp, phy,
4643 MDIO_REG_BANK_CL73_USERB0,
4644 MDIO_CL73_USERB0_CL73_UCTRL,
4647 /* Enable BAM Station Manager*/
4648 CL22_WR_OVER_CL45(bp, phy,
4649 MDIO_REG_BANK_CL73_USERB0,
4650 MDIO_CL73_USERB0_CL73_BAM_CTRL1,
4651 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
4652 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
4653 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
4655 /* Advertise CL73 link speeds */
4656 CL22_RD_OVER_CL45(bp, phy,
4657 MDIO_REG_BANK_CL73_IEEEB1,
4658 MDIO_CL73_IEEEB1_AN_ADV2,
4660 if (phy->speed_cap_mask &
4661 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4662 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
4663 if (phy->speed_cap_mask &
4664 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4665 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
4667 CL22_WR_OVER_CL45(bp, phy,
4668 MDIO_REG_BANK_CL73_IEEEB1,
4669 MDIO_CL73_IEEEB1_AN_ADV2,
4672 /* CL73 Autoneg Enabled */
4673 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
4675 } else /* CL73 Autoneg Disabled */
4678 CL22_WR_OVER_CL45(bp, phy,
4679 MDIO_REG_BANK_CL73_IEEEB0,
4680 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
4683 /* program SerDes, forced speed */
4684 static void bnx2x_program_serdes(struct bnx2x_phy *phy,
4685 struct link_params *params,
4686 struct link_vars *vars)
4688 struct bnx2x *bp = params->bp;
4691 /* program duplex, disable autoneg and sgmii*/
4692 CL22_RD_OVER_CL45(bp, phy,
4693 MDIO_REG_BANK_COMBO_IEEE0,
4694 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
4695 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
4696 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4697 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
4698 if (phy->req_duplex == DUPLEX_FULL)
4699 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
4700 CL22_WR_OVER_CL45(bp, phy,
4701 MDIO_REG_BANK_COMBO_IEEE0,
4702 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
4706 * - needed only if the speed is greater than 1G (2.5G or 10G)
4708 CL22_RD_OVER_CL45(bp, phy,
4709 MDIO_REG_BANK_SERDES_DIGITAL,
4710 MDIO_SERDES_DIGITAL_MISC1, ®_val);
4711 /* clearing the speed value before setting the right speed */
4712 DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
4714 reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
4715 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
4717 if (!((vars->line_speed == SPEED_1000) ||
4718 (vars->line_speed == SPEED_100) ||
4719 (vars->line_speed == SPEED_10))) {
4721 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
4722 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
4723 if (vars->line_speed == SPEED_10000)
4725 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
4728 CL22_WR_OVER_CL45(bp, phy,
4729 MDIO_REG_BANK_SERDES_DIGITAL,
4730 MDIO_SERDES_DIGITAL_MISC1, reg_val);
4734 static void bnx2x_set_brcm_cl37_advertisement(struct bnx2x_phy *phy,
4735 struct link_params *params)
4737 struct bnx2x *bp = params->bp;
4740 /* configure the 48 bits for BAM AN */
4742 /* set extended capabilities */
4743 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
4744 val |= MDIO_OVER_1G_UP1_2_5G;
4745 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4746 val |= MDIO_OVER_1G_UP1_10G;
4747 CL22_WR_OVER_CL45(bp, phy,
4748 MDIO_REG_BANK_OVER_1G,
4749 MDIO_OVER_1G_UP1, val);
4751 CL22_WR_OVER_CL45(bp, phy,
4752 MDIO_REG_BANK_OVER_1G,
4753 MDIO_OVER_1G_UP3, 0x400);
4756 static void bnx2x_set_ieee_aneg_advertisement(struct bnx2x_phy *phy,
4757 struct link_params *params,
4760 struct bnx2x *bp = params->bp;
4762 /* for AN, we are always publishing full duplex */
4764 CL22_WR_OVER_CL45(bp, phy,
4765 MDIO_REG_BANK_COMBO_IEEE0,
4766 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
4767 CL22_RD_OVER_CL45(bp, phy,
4768 MDIO_REG_BANK_CL73_IEEEB1,
4769 MDIO_CL73_IEEEB1_AN_ADV1, &val);
4770 val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
4771 val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
4772 CL22_WR_OVER_CL45(bp, phy,
4773 MDIO_REG_BANK_CL73_IEEEB1,
4774 MDIO_CL73_IEEEB1_AN_ADV1, val);
4777 static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
4778 struct link_params *params,
4781 struct bnx2x *bp = params->bp;
4784 DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
4785 /* Enable and restart BAM/CL37 aneg */
4788 CL22_RD_OVER_CL45(bp, phy,
4789 MDIO_REG_BANK_CL73_IEEEB0,
4790 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
4793 CL22_WR_OVER_CL45(bp, phy,
4794 MDIO_REG_BANK_CL73_IEEEB0,
4795 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
4797 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
4798 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
4801 CL22_RD_OVER_CL45(bp, phy,
4802 MDIO_REG_BANK_COMBO_IEEE0,
4803 MDIO_COMBO_IEEE0_MII_CONTROL,
4806 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
4808 CL22_WR_OVER_CL45(bp, phy,
4809 MDIO_REG_BANK_COMBO_IEEE0,
4810 MDIO_COMBO_IEEE0_MII_CONTROL,
4812 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4813 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
4817 static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
4818 struct link_params *params,
4819 struct link_vars *vars)
4821 struct bnx2x *bp = params->bp;
4824 /* in SGMII mode, the unicore is always slave */
4826 CL22_RD_OVER_CL45(bp, phy,
4827 MDIO_REG_BANK_SERDES_DIGITAL,
4828 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
4830 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
4831 /* set sgmii mode (and not fiber) */
4832 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
4833 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
4834 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
4835 CL22_WR_OVER_CL45(bp, phy,
4836 MDIO_REG_BANK_SERDES_DIGITAL,
4837 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
4840 /* if forced speed */
4841 if (!(vars->line_speed == SPEED_AUTO_NEG)) {
4842 /* set speed, disable autoneg */
4845 CL22_RD_OVER_CL45(bp, phy,
4846 MDIO_REG_BANK_COMBO_IEEE0,
4847 MDIO_COMBO_IEEE0_MII_CONTROL,
4849 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4850 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
4851 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
4853 switch (vars->line_speed) {
4856 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
4860 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
4863 /* there is nothing to set for 10M */
4866 /* invalid speed for SGMII */
4867 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
4872 /* setting the full duplex */
4873 if (phy->req_duplex == DUPLEX_FULL)
4875 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
4876 CL22_WR_OVER_CL45(bp, phy,
4877 MDIO_REG_BANK_COMBO_IEEE0,
4878 MDIO_COMBO_IEEE0_MII_CONTROL,
4881 } else { /* AN mode */
4882 /* enable and restart AN */
4883 bnx2x_restart_autoneg(phy, params, 0);
4892 static int bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
4893 struct link_params *params)
4895 struct bnx2x *bp = params->bp;
4896 u16 pd_10g, status2_1000x;
4897 if (phy->req_line_speed != SPEED_AUTO_NEG)
4899 CL22_RD_OVER_CL45(bp, phy,
4900 MDIO_REG_BANK_SERDES_DIGITAL,
4901 MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
4903 CL22_RD_OVER_CL45(bp, phy,
4904 MDIO_REG_BANK_SERDES_DIGITAL,
4905 MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
4907 if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
4908 DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
4913 CL22_RD_OVER_CL45(bp, phy,
4914 MDIO_REG_BANK_10G_PARALLEL_DETECT,
4915 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
4918 if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
4919 DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
4926 static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
4927 struct link_params *params,
4928 struct link_vars *vars,
4931 struct bnx2x *bp = params->bp;
4932 u16 ld_pause; /* local driver */
4933 u16 lp_pause; /* link partner */
4936 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4938 /* resolve from gp_status in case of AN complete and not sgmii */
4939 if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
4940 vars->flow_ctrl = phy->req_flow_ctrl;
4941 else if (phy->req_line_speed != SPEED_AUTO_NEG)
4942 vars->flow_ctrl = params->req_fc_auto_adv;
4943 else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
4944 (!(vars->phy_flags & PHY_SGMII_FLAG))) {
4945 if (bnx2x_direct_parallel_detect_used(phy, params)) {
4946 vars->flow_ctrl = params->req_fc_auto_adv;
4950 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
4951 MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
4952 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
4953 MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
4955 CL22_RD_OVER_CL45(bp, phy,
4956 MDIO_REG_BANK_CL73_IEEEB1,
4957 MDIO_CL73_IEEEB1_AN_ADV1,
4959 CL22_RD_OVER_CL45(bp, phy,
4960 MDIO_REG_BANK_CL73_IEEEB1,
4961 MDIO_CL73_IEEEB1_AN_LP_ADV1,
4963 pause_result = (ld_pause &
4964 MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
4966 pause_result |= (lp_pause &
4967 MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
4969 DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
4972 CL22_RD_OVER_CL45(bp, phy,
4973 MDIO_REG_BANK_COMBO_IEEE0,
4974 MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
4976 CL22_RD_OVER_CL45(bp, phy,
4977 MDIO_REG_BANK_COMBO_IEEE0,
4978 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
4980 pause_result = (ld_pause &
4981 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
4982 pause_result |= (lp_pause &
4983 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
4984 DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
4987 bnx2x_pause_resolve(vars, pause_result);
4989 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
4992 static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
4993 struct link_params *params)
4995 struct bnx2x *bp = params->bp;
4996 u16 rx_status, ustat_val, cl37_fsm_received;
4997 DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
4998 /* Step 1: Make sure signal is detected */
4999 CL22_RD_OVER_CL45(bp, phy,
5003 if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
5004 (MDIO_RX0_RX_STATUS_SIGDET)) {
5005 DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
5006 "rx_status(0x80b0) = 0x%x\n", rx_status);
5007 CL22_WR_OVER_CL45(bp, phy,
5008 MDIO_REG_BANK_CL73_IEEEB0,
5009 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5010 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
5013 /* Step 2: Check CL73 state machine */
5014 CL22_RD_OVER_CL45(bp, phy,
5015 MDIO_REG_BANK_CL73_USERB0,
5016 MDIO_CL73_USERB0_CL73_USTAT1,
5019 (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5020 MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
5021 (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5022 MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
5023 DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
5024 "ustat_val(0x8371) = 0x%x\n", ustat_val);
5028 * Step 3: Check CL37 Message Pages received to indicate LP
5029 * supports only CL37
5031 CL22_RD_OVER_CL45(bp, phy,
5032 MDIO_REG_BANK_REMOTE_PHY,
5033 MDIO_REMOTE_PHY_MISC_RX_STATUS,
5034 &cl37_fsm_received);
5035 if ((cl37_fsm_received &
5036 (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5037 MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
5038 (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5039 MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
5040 DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
5041 "misc_rx_status(0x8330) = 0x%x\n",
5046 * The combined cl37/cl73 fsm state information indicating that
5047 * we are connected to a device which does not support cl73, but
5048 * does support cl37 BAM. In this case we disable cl73 and
5049 * restart cl37 auto-neg
5053 CL22_WR_OVER_CL45(bp, phy,
5054 MDIO_REG_BANK_CL73_IEEEB0,
5055 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5057 /* Restart CL37 autoneg */
5058 bnx2x_restart_autoneg(phy, params, 0);
5059 DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
5062 static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
5063 struct link_params *params,
5064 struct link_vars *vars,
5067 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
5068 vars->link_status |=
5069 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5071 if (bnx2x_direct_parallel_detect_used(phy, params))
5072 vars->link_status |=
5073 LINK_STATUS_PARALLEL_DETECTION_USED;
5075 static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,
5076 struct link_params *params,
5077 struct link_vars *vars,
5082 struct bnx2x *bp = params->bp;
5083 if (phy->req_line_speed == SPEED_AUTO_NEG)
5084 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
5086 DP(NETIF_MSG_LINK, "phy link up\n");
5088 vars->phy_link_up = 1;
5089 vars->link_status |= LINK_STATUS_LINK_UP;
5091 switch (speed_mask) {
5093 vars->line_speed = SPEED_10;
5094 if (vars->duplex == DUPLEX_FULL)
5095 vars->link_status |= LINK_10TFD;
5097 vars->link_status |= LINK_10THD;
5100 case GP_STATUS_100M:
5101 vars->line_speed = SPEED_100;
5102 if (vars->duplex == DUPLEX_FULL)
5103 vars->link_status |= LINK_100TXFD;
5105 vars->link_status |= LINK_100TXHD;
5109 case GP_STATUS_1G_KX:
5110 vars->line_speed = SPEED_1000;
5111 if (vars->duplex == DUPLEX_FULL)
5112 vars->link_status |= LINK_1000TFD;
5114 vars->link_status |= LINK_1000THD;
5117 case GP_STATUS_2_5G:
5118 vars->line_speed = SPEED_2500;
5119 if (vars->duplex == DUPLEX_FULL)
5120 vars->link_status |= LINK_2500TFD;
5122 vars->link_status |= LINK_2500THD;
5128 "link speed unsupported gp_status 0x%x\n",
5132 case GP_STATUS_10G_KX4:
5133 case GP_STATUS_10G_HIG:
5134 case GP_STATUS_10G_CX4:
5135 case GP_STATUS_10G_KR:
5136 case GP_STATUS_10G_SFI:
5137 case GP_STATUS_10G_XFI:
5138 vars->line_speed = SPEED_10000;
5139 vars->link_status |= LINK_10GTFD;
5141 case GP_STATUS_20G_DXGXS:
5142 vars->line_speed = SPEED_20000;
5143 vars->link_status |= LINK_20GTFD;
5147 "link speed unsupported gp_status 0x%x\n",
5151 } else { /* link_down */
5152 DP(NETIF_MSG_LINK, "phy link down\n");
5154 vars->phy_link_up = 0;
5156 vars->duplex = DUPLEX_FULL;
5157 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5158 vars->mac_type = MAC_TYPE_NONE;
5160 DP(NETIF_MSG_LINK, " phy_link_up %x line_speed %d\n",
5161 vars->phy_link_up, vars->line_speed);
5165 static int bnx2x_link_settings_status(struct bnx2x_phy *phy,
5166 struct link_params *params,
5167 struct link_vars *vars)
5170 struct bnx2x *bp = params->bp;
5172 u16 gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask;
5175 /* Read gp_status */
5176 CL22_RD_OVER_CL45(bp, phy,
5177 MDIO_REG_BANK_GP_STATUS,
5178 MDIO_GP_STATUS_TOP_AN_STATUS1,
5180 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
5181 duplex = DUPLEX_FULL;
5182 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)
5184 speed_mask = gp_status & GP_STATUS_SPEED_MASK;
5185 DP(NETIF_MSG_LINK, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x\n",
5186 gp_status, link_up, speed_mask);
5187 rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
5192 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
5193 if (SINGLE_MEDIA_DIRECT(params)) {
5194 bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
5195 if (phy->req_line_speed == SPEED_AUTO_NEG)
5196 bnx2x_xgxs_an_resolve(phy, params, vars,
5199 } else { /* link_down */
5200 if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
5201 SINGLE_MEDIA_DIRECT(params)) {
5202 /* Check signal is detected */
5203 bnx2x_check_fallback_to_cl37(phy, params);
5207 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n",
5208 vars->duplex, vars->flow_ctrl, vars->link_status);
5212 static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy,
5213 struct link_params *params,
5214 struct link_vars *vars)
5217 struct bnx2x *bp = params->bp;
5220 u16 gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL;
5222 lane = bnx2x_get_warpcore_lane(phy, params);
5223 /* Read gp_status */
5224 if (phy->req_line_speed > SPEED_10000) {
5226 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5228 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5230 DP(NETIF_MSG_LINK, "PCS RX link status = 0x%x-->0x%x\n",
5231 temp_link_up, link_up);
5234 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5236 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5237 MDIO_WC_REG_GP2_STATUS_GP_2_1, &gp_status1);
5238 DP(NETIF_MSG_LINK, "0x81d1 = 0x%x\n", gp_status1);
5239 /* Check for either KR or generic link up. */
5240 gp_status1 = ((gp_status1 >> 8) & 0xf) |
5241 ((gp_status1 >> 12) & 0xf);
5242 link_up = gp_status1 & (1 << lane);
5243 if (link_up && SINGLE_MEDIA_DIRECT(params)) {
5245 if (phy->req_line_speed == SPEED_AUTO_NEG) {
5246 /* Check Autoneg complete */
5247 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5248 MDIO_WC_REG_GP2_STATUS_GP_2_4,
5250 if (gp_status4 & ((1<<12)<<lane))
5251 vars->link_status |=
5252 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5254 /* Check parallel detect used */
5255 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5256 MDIO_WC_REG_PAR_DET_10G_STATUS,
5259 vars->link_status |=
5260 LINK_STATUS_PARALLEL_DETECTION_USED;
5262 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5267 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5268 MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed);
5270 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5271 MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed);
5273 DP(NETIF_MSG_LINK, "lane %d gp_speed 0x%x\n", lane, gp_speed);
5275 if ((lane & 1) == 0)
5280 rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed,
5283 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n",
5284 vars->duplex, vars->flow_ctrl, vars->link_status);
5287 static void bnx2x_set_gmii_tx_driver(struct link_params *params)
5289 struct bnx2x *bp = params->bp;
5290 struct bnx2x_phy *phy = ¶ms->phy[INT_PHY];
5296 CL22_RD_OVER_CL45(bp, phy,
5297 MDIO_REG_BANK_OVER_1G,
5298 MDIO_OVER_1G_LP_UP2, &lp_up2);
5300 /* bits [10:7] at lp_up2, positioned at [15:12] */
5301 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
5302 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
5303 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
5308 for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
5309 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
5310 CL22_RD_OVER_CL45(bp, phy,
5312 MDIO_TX0_TX_DRIVER, &tx_driver);
5314 /* replace tx_driver bits [15:12] */
5316 (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
5317 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
5318 tx_driver |= lp_up2;
5319 CL22_WR_OVER_CL45(bp, phy,
5321 MDIO_TX0_TX_DRIVER, tx_driver);
5326 static int bnx2x_emac_program(struct link_params *params,
5327 struct link_vars *vars)
5329 struct bnx2x *bp = params->bp;
5330 u8 port = params->port;
5333 DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
5334 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
5336 (EMAC_MODE_25G_MODE |
5337 EMAC_MODE_PORT_MII_10M |
5338 EMAC_MODE_HALF_DUPLEX));
5339 switch (vars->line_speed) {
5341 mode |= EMAC_MODE_PORT_MII_10M;
5345 mode |= EMAC_MODE_PORT_MII;
5349 mode |= EMAC_MODE_PORT_GMII;
5353 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
5357 /* 10G not valid for EMAC */
5358 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
5363 if (vars->duplex == DUPLEX_HALF)
5364 mode |= EMAC_MODE_HALF_DUPLEX;
5366 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
5369 bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
5373 static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
5374 struct link_params *params)
5378 struct bnx2x *bp = params->bp;
5380 for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
5381 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
5382 CL22_WR_OVER_CL45(bp, phy,
5384 MDIO_RX0_RX_EQ_BOOST,
5385 phy->rx_preemphasis[i]);
5388 for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
5389 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
5390 CL22_WR_OVER_CL45(bp, phy,
5393 phy->tx_preemphasis[i]);
5397 static void bnx2x_xgxs_config_init(struct bnx2x_phy *phy,
5398 struct link_params *params,
5399 struct link_vars *vars)
5401 struct bnx2x *bp = params->bp;
5402 u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
5403 (params->loopback_mode == LOOPBACK_XGXS));
5404 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
5405 if (SINGLE_MEDIA_DIRECT(params) &&
5406 (params->feature_config_flags &
5407 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
5408 bnx2x_set_preemphasis(phy, params);
5410 /* forced speed requested? */
5411 if (vars->line_speed != SPEED_AUTO_NEG ||
5412 (SINGLE_MEDIA_DIRECT(params) &&
5413 params->loopback_mode == LOOPBACK_EXT)) {
5414 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
5416 /* disable autoneg */
5417 bnx2x_set_autoneg(phy, params, vars, 0);
5419 /* program speed and duplex */
5420 bnx2x_program_serdes(phy, params, vars);
5422 } else { /* AN_mode */
5423 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
5426 bnx2x_set_brcm_cl37_advertisement(phy, params);
5428 /* program duplex & pause advertisement (for aneg) */
5429 bnx2x_set_ieee_aneg_advertisement(phy, params,
5432 /* enable autoneg */
5433 bnx2x_set_autoneg(phy, params, vars, enable_cl73);
5435 /* enable and restart AN */
5436 bnx2x_restart_autoneg(phy, params, enable_cl73);
5439 } else { /* SGMII mode */
5440 DP(NETIF_MSG_LINK, "SGMII\n");
5442 bnx2x_initialize_sgmii_process(phy, params, vars);
5446 static int bnx2x_prepare_xgxs(struct bnx2x_phy *phy,
5447 struct link_params *params,
5448 struct link_vars *vars)
5451 vars->phy_flags |= PHY_XGXS_FLAG;
5452 if ((phy->req_line_speed &&
5453 ((phy->req_line_speed == SPEED_100) ||
5454 (phy->req_line_speed == SPEED_10))) ||
5455 (!phy->req_line_speed &&
5456 (phy->speed_cap_mask >=
5457 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
5458 (phy->speed_cap_mask <
5459 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
5460 (phy->type == PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD))
5461 vars->phy_flags |= PHY_SGMII_FLAG;
5463 vars->phy_flags &= ~PHY_SGMII_FLAG;
5465 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
5466 bnx2x_set_aer_mmd(params, phy);
5467 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
5468 bnx2x_set_master_ln(params, phy);
5470 rc = bnx2x_reset_unicore(params, phy, 0);
5471 /* reset the SerDes and wait for reset bit return low */
5475 bnx2x_set_aer_mmd(params, phy);
5476 /* setting the masterLn_def again after the reset */
5477 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
5478 bnx2x_set_master_ln(params, phy);
5479 bnx2x_set_swap_lanes(params, phy);
5485 static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
5486 struct bnx2x_phy *phy,
5487 struct link_params *params)
5490 /* Wait for soft reset to get cleared up to 1 sec */
5491 for (cnt = 0; cnt < 1000; cnt++) {
5492 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616)
5493 bnx2x_cl22_read(bp, phy,
5494 MDIO_PMA_REG_CTRL, &ctrl);
5496 bnx2x_cl45_read(bp, phy,
5498 MDIO_PMA_REG_CTRL, &ctrl);
5499 if (!(ctrl & (1<<15)))
5505 netdev_err(bp->dev, "Warning: PHY was not initialized,"
5508 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
5512 static void bnx2x_link_int_enable(struct link_params *params)
5514 u8 port = params->port;
5516 struct bnx2x *bp = params->bp;
5518 /* Setting the status to report on link up for either XGXS or SerDes */
5519 if (CHIP_IS_E3(bp)) {
5520 mask = NIG_MASK_XGXS0_LINK_STATUS;
5521 if (!(SINGLE_MEDIA_DIRECT(params)))
5522 mask |= NIG_MASK_MI_INT;
5523 } else if (params->switch_cfg == SWITCH_CFG_10G) {
5524 mask = (NIG_MASK_XGXS0_LINK10G |
5525 NIG_MASK_XGXS0_LINK_STATUS);
5526 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
5527 if (!(SINGLE_MEDIA_DIRECT(params)) &&
5528 params->phy[INT_PHY].type !=
5529 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
5530 mask |= NIG_MASK_MI_INT;
5531 DP(NETIF_MSG_LINK, "enabled external phy int\n");
5534 } else { /* SerDes */
5535 mask = NIG_MASK_SERDES0_LINK_STATUS;
5536 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
5537 if (!(SINGLE_MEDIA_DIRECT(params)) &&
5538 params->phy[INT_PHY].type !=
5539 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
5540 mask |= NIG_MASK_MI_INT;
5541 DP(NETIF_MSG_LINK, "enabled external phy int\n");
5545 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5548 DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
5549 (params->switch_cfg == SWITCH_CFG_10G),
5550 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5551 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
5552 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5553 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5554 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
5555 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5556 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5557 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5560 static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port,
5563 u32 latch_status = 0;
5566 * Disable the MI INT ( external phy int ) by writing 1 to the
5567 * status register. Link down indication is high-active-signal,
5568 * so in this case we need to write the status to clear the XOR
5570 /* Read Latched signals */
5571 latch_status = REG_RD(bp,
5572 NIG_REG_LATCH_STATUS_0 + port*8);
5573 DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status);
5574 /* Handle only those with latched-signal=up.*/
5577 NIG_REG_STATUS_INTERRUPT_PORT0
5579 NIG_STATUS_EMAC0_MI_INT);
5582 NIG_REG_STATUS_INTERRUPT_PORT0
5584 NIG_STATUS_EMAC0_MI_INT);
5586 if (latch_status & 1) {
5588 /* For all latched-signal=up : Re-Arm Latch signals */
5589 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
5590 (latch_status & 0xfffe) | (latch_status & 1));
5592 /* For all latched-signal=up,Write original_signal to status */
5595 static void bnx2x_link_int_ack(struct link_params *params,
5596 struct link_vars *vars, u8 is_10g_plus)
5598 struct bnx2x *bp = params->bp;
5599 u8 port = params->port;
5602 * First reset all status we assume only one line will be
5605 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5606 (NIG_STATUS_XGXS0_LINK10G |
5607 NIG_STATUS_XGXS0_LINK_STATUS |
5608 NIG_STATUS_SERDES0_LINK_STATUS));
5609 if (vars->phy_link_up) {
5610 if (USES_WARPCORE(bp))
5611 mask = NIG_STATUS_XGXS0_LINK_STATUS;
5614 mask = NIG_STATUS_XGXS0_LINK10G;
5615 else if (params->switch_cfg == SWITCH_CFG_10G) {
5617 * Disable the link interrupt by writing 1 to
5618 * the relevant lane in the status register
5621 ((params->lane_config &
5622 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
5623 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
5624 mask = ((1 << ser_lane) <<
5625 NIG_STATUS_XGXS0_LINK_STATUS_SIZE);
5627 mask = NIG_STATUS_SERDES0_LINK_STATUS;
5629 DP(NETIF_MSG_LINK, "Ack link up interrupt with mask 0x%x\n",
5632 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5637 static int bnx2x_format_ver(u32 num, u8 *str, u16 *len)
5640 u32 mask = 0xf0000000;
5643 u8 remove_leading_zeros = 1;
5645 /* Need more than 10chars for this format */
5653 digit = ((num & mask) >> shift);
5654 if (digit == 0 && remove_leading_zeros) {
5657 } else if (digit < 0xa)
5658 *str_ptr = digit + '0';
5660 *str_ptr = digit - 0xa + 'a';
5661 remove_leading_zeros = 0;
5669 remove_leading_zeros = 1;
5676 static int bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
5683 int bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
5684 u8 *version, u16 len)
5689 u8 *ver_p = version;
5690 u16 remain_len = len;
5691 if (version == NULL || params == NULL)
5695 /* Extract first external phy*/
5697 spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
5699 if (params->phy[EXT_PHY1].format_fw_ver) {
5700 status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
5703 ver_p += (len - remain_len);
5705 if ((params->num_phys == MAX_PHYS) &&
5706 (params->phy[EXT_PHY2].ver_addr != 0)) {
5707 spirom_ver = REG_RD(bp, params->phy[EXT_PHY2].ver_addr);
5708 if (params->phy[EXT_PHY2].format_fw_ver) {
5712 status |= params->phy[EXT_PHY2].format_fw_ver(
5716 ver_p = version + (len - remain_len);
5723 static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
5724 struct link_params *params)
5726 u8 port = params->port;
5727 struct bnx2x *bp = params->bp;
5729 if (phy->req_line_speed != SPEED_1000) {
5732 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
5734 if (!CHIP_IS_E3(bp)) {
5735 /* change the uni_phy_addr in the nig */
5736 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
5739 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
5743 bnx2x_cl45_write(bp, phy,
5745 (MDIO_REG_BANK_AER_BLOCK +
5746 (MDIO_AER_BLOCK_AER_REG & 0xf)),
5749 bnx2x_cl45_write(bp, phy,
5751 (MDIO_REG_BANK_CL73_IEEEB0 +
5752 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
5755 /* set aer mmd back */
5756 bnx2x_set_aer_mmd(params, phy);
5758 if (!CHIP_IS_E3(bp)) {
5760 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
5765 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
5766 bnx2x_cl45_read(bp, phy, 5,
5767 (MDIO_REG_BANK_COMBO_IEEE0 +
5768 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
5770 bnx2x_cl45_write(bp, phy, 5,
5771 (MDIO_REG_BANK_COMBO_IEEE0 +
5772 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
5774 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
5778 int bnx2x_set_led(struct link_params *params,
5779 struct link_vars *vars, u8 mode, u32 speed)
5781 u8 port = params->port;
5782 u16 hw_led_mode = params->hw_led_mode;
5786 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5787 struct bnx2x *bp = params->bp;
5788 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
5789 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
5790 speed, hw_led_mode);
5792 for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) {
5793 if (params->phy[phy_idx].set_link_led) {
5794 params->phy[phy_idx].set_link_led(
5795 ¶ms->phy[phy_idx], params, mode);
5800 case LED_MODE_FRONT_PANEL_OFF:
5802 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
5803 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
5804 SHARED_HW_CFG_LED_MAC1);
5806 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5807 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
5812 * For all other phys, OPER mode is same as ON, so in case
5813 * link is down, do nothing
5818 if (((params->phy[EXT_PHY1].type ==
5819 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) ||
5820 (params->phy[EXT_PHY1].type ==
5821 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722)) &&
5822 CHIP_IS_E2(bp) && params->num_phys == 2) {
5824 * This is a work-around for E2+8727 Configurations
5826 if (mode == LED_MODE_ON ||
5827 speed == SPEED_10000){
5828 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
5829 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
5831 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5832 EMAC_WR(bp, EMAC_REG_EMAC_LED,
5833 (tmp | EMAC_LED_OVERRIDE));
5836 } else if (SINGLE_MEDIA_DIRECT(params) &&
5840 * This is a work-around for HW issue found when link
5843 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
5844 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
5846 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
5849 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
5850 /* Set blinking rate to ~15.9Hz */
5851 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
5852 LED_BLINK_RATE_VAL);
5853 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
5855 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5856 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp & (~EMAC_LED_OVERRIDE)));
5858 if (CHIP_IS_E1(bp) &&
5859 ((speed == SPEED_2500) ||
5860 (speed == SPEED_1000) ||
5861 (speed == SPEED_100) ||
5862 (speed == SPEED_10))) {
5864 * On Everest 1 Ax chip versions for speeds less than
5865 * 10G LED scheme is different
5867 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5869 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
5871 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
5878 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
5887 * This function comes to reflect the actual link state read DIRECTLY from the
5890 int bnx2x_test_link(struct link_params *params, struct link_vars *vars,
5893 struct bnx2x *bp = params->bp;
5894 u16 gp_status = 0, phy_index = 0;
5895 u8 ext_phy_link_up = 0, serdes_phy_type;
5896 struct link_vars temp_vars;
5897 struct bnx2x_phy *int_phy = ¶ms->phy[INT_PHY];
5899 if (CHIP_IS_E3(bp)) {
5901 if (params->req_line_speed[LINK_CONFIG_IDX(INT_PHY)]
5903 /* Check 20G link */
5904 bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
5906 bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
5910 /* Check 10G link and below*/
5911 u8 lane = bnx2x_get_warpcore_lane(int_phy, params);
5912 bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
5913 MDIO_WC_REG_GP2_STATUS_GP_2_1,
5915 gp_status = ((gp_status >> 8) & 0xf) |
5916 ((gp_status >> 12) & 0xf);
5917 link_up = gp_status & (1 << lane);
5922 CL22_RD_OVER_CL45(bp, int_phy,
5923 MDIO_REG_BANK_GP_STATUS,
5924 MDIO_GP_STATUS_TOP_AN_STATUS1,
5926 /* link is up only if both local phy and external phy are up */
5927 if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
5930 /* In XGXS loopback mode, do not check external PHY */
5931 if (params->loopback_mode == LOOPBACK_XGXS)
5934 switch (params->num_phys) {
5936 /* No external PHY */
5939 ext_phy_link_up = params->phy[EXT_PHY1].read_status(
5940 ¶ms->phy[EXT_PHY1],
5941 params, &temp_vars);
5943 case 3: /* Dual Media */
5944 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
5946 serdes_phy_type = ((params->phy[phy_index].media_type ==
5947 ETH_PHY_SFP_FIBER) ||
5948 (params->phy[phy_index].media_type ==
5949 ETH_PHY_XFP_FIBER) ||
5950 (params->phy[phy_index].media_type ==
5951 ETH_PHY_DA_TWINAX));
5953 if (is_serdes != serdes_phy_type)
5955 if (params->phy[phy_index].read_status) {
5957 params->phy[phy_index].read_status(
5958 ¶ms->phy[phy_index],
5959 params, &temp_vars);
5964 if (ext_phy_link_up)
5969 static int bnx2x_link_initialize(struct link_params *params,
5970 struct link_vars *vars)
5973 u8 phy_index, non_ext_phy;
5974 struct bnx2x *bp = params->bp;
5976 * In case of external phy existence, the line speed would be the
5977 * line speed linked up by the external phy. In case it is direct
5978 * only, then the line_speed during initialization will be
5979 * equal to the req_line_speed
5981 vars->line_speed = params->phy[INT_PHY].req_line_speed;
5984 * Initialize the internal phy in case this is a direct board
5985 * (no external phys), or this board has external phy which requires
5988 if (!USES_WARPCORE(bp))
5989 bnx2x_prepare_xgxs(¶ms->phy[INT_PHY], params, vars);
5990 /* init ext phy and enable link state int */
5991 non_ext_phy = (SINGLE_MEDIA_DIRECT(params) ||
5992 (params->loopback_mode == LOOPBACK_XGXS));
5995 (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) ||
5996 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
5997 struct bnx2x_phy *phy = ¶ms->phy[INT_PHY];
5998 if (vars->line_speed == SPEED_AUTO_NEG &&
6001 bnx2x_set_parallel_detection(phy, params);
6002 if (params->phy[INT_PHY].config_init)
6003 params->phy[INT_PHY].config_init(phy,
6008 /* Init external phy*/
6010 if (params->phy[INT_PHY].supported &
6012 vars->link_status |= LINK_STATUS_SERDES_LINK;
6014 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6017 * No need to initialize second phy in case of first
6018 * phy only selection. In case of second phy, we do
6019 * need to initialize the first phy, since they are
6022 if (params->phy[phy_index].supported &
6024 vars->link_status |= LINK_STATUS_SERDES_LINK;
6026 if (phy_index == EXT_PHY2 &&
6027 (bnx2x_phy_selection(params) ==
6028 PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
6029 DP(NETIF_MSG_LINK, "Not initializing"
6033 params->phy[phy_index].config_init(
6034 ¶ms->phy[phy_index],
6038 /* Reset the interrupt indication after phy was initialized */
6039 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
6041 (NIG_STATUS_XGXS0_LINK10G |
6042 NIG_STATUS_XGXS0_LINK_STATUS |
6043 NIG_STATUS_SERDES0_LINK_STATUS |
6045 bnx2x_update_mng(params, vars->link_status);
6049 static void bnx2x_int_link_reset(struct bnx2x_phy *phy,
6050 struct link_params *params)
6052 /* reset the SerDes/XGXS */
6053 REG_WR(params->bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
6054 (0x1ff << (params->port*16)));
6057 static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
6058 struct link_params *params)
6060 struct bnx2x *bp = params->bp;
6064 gpio_port = BP_PATH(bp);
6066 gpio_port = params->port;
6067 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6068 MISC_REGISTERS_GPIO_OUTPUT_LOW,
6070 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6071 MISC_REGISTERS_GPIO_OUTPUT_LOW,
6073 DP(NETIF_MSG_LINK, "reset external PHY\n");
6076 static int bnx2x_update_link_down(struct link_params *params,
6077 struct link_vars *vars)
6079 struct bnx2x *bp = params->bp;
6080 u8 port = params->port;
6082 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
6083 bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
6085 /* indicate no mac active */
6086 vars->mac_type = MAC_TYPE_NONE;
6088 /* update shared memory */
6089 vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK |
6090 LINK_STATUS_LINK_UP |
6091 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE |
6092 LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK |
6093 LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK |
6094 LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK);
6095 vars->line_speed = 0;
6096 bnx2x_update_mng(params, vars->link_status);
6098 /* activate nig drain */
6099 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6102 if (!CHIP_IS_E3(bp))
6103 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6106 /* reset BigMac/Xmac */
6107 if (CHIP_IS_E1x(bp) ||
6109 bnx2x_bmac_rx_disable(bp, params->port);
6110 REG_WR(bp, GRCBASE_MISC +
6111 MISC_REGISTERS_RESET_REG_2_CLEAR,
6112 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6115 bnx2x_xmac_disable(params);
6120 static int bnx2x_update_link_up(struct link_params *params,
6121 struct link_vars *vars,
6124 struct bnx2x *bp = params->bp;
6125 u8 port = params->port;
6128 vars->link_status |= LINK_STATUS_LINK_UP;
6130 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
6131 vars->link_status |=
6132 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
6134 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
6135 vars->link_status |=
6136 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
6137 if (USES_WARPCORE(bp)) {
6139 bnx2x_xmac_enable(params, vars, 0);
6141 bnx2x_umac_enable(params, vars, 0);
6142 bnx2x_set_led(params, vars,
6143 LED_MODE_OPER, vars->line_speed);
6145 if ((CHIP_IS_E1x(bp) ||
6148 bnx2x_bmac_enable(params, vars, 0);
6150 bnx2x_set_led(params, vars,
6151 LED_MODE_OPER, SPEED_10000);
6153 rc = bnx2x_emac_program(params, vars);
6154 bnx2x_emac_enable(params, vars, 0);
6157 if ((vars->link_status &
6158 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
6159 && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
6160 SINGLE_MEDIA_DIRECT(params))
6161 bnx2x_set_gmii_tx_driver(params);
6166 if (CHIP_IS_E1x(bp))
6167 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
6171 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
6173 /* update shared memory */
6174 bnx2x_update_mng(params, vars->link_status);
6179 * The bnx2x_link_update function should be called upon link
6181 * Link is considered up as follows:
6182 * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
6184 * - SINGLE_MEDIA - The link between the 577xx and the external
6185 * phy (XGXS) need to up as well as the external link of the
6187 * - DUAL_MEDIA - The link between the 577xx and the first
6188 * external phy needs to be up, and at least one of the 2
6189 * external phy link must be up.
6191 int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
6193 struct bnx2x *bp = params->bp;
6194 struct link_vars phy_vars[MAX_PHYS];
6195 u8 port = params->port;
6196 u8 link_10g_plus, phy_index;
6197 u8 ext_phy_link_up = 0, cur_link_up;
6200 u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
6201 u8 active_external_phy = INT_PHY;
6203 for (phy_index = INT_PHY; phy_index < params->num_phys;
6205 phy_vars[phy_index].flow_ctrl = 0;
6206 phy_vars[phy_index].link_status = 0;
6207 phy_vars[phy_index].line_speed = 0;
6208 phy_vars[phy_index].duplex = DUPLEX_FULL;
6209 phy_vars[phy_index].phy_link_up = 0;
6210 phy_vars[phy_index].link_up = 0;
6211 phy_vars[phy_index].fault_detected = 0;
6214 if (USES_WARPCORE(bp))
6215 bnx2x_set_aer_mmd(params, ¶ms->phy[INT_PHY]);
6217 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
6218 port, (vars->phy_flags & PHY_XGXS_FLAG),
6219 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
6221 is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
6223 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
6224 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
6226 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
6228 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
6229 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
6230 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
6233 if (!CHIP_IS_E3(bp))
6234 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6238 * Check external link change only for external phys, and apply
6239 * priority selection between them in case the link on both phys
6240 * is up. Note that instead of the common vars, a temporary
6241 * vars argument is used since each phy may have different link/
6242 * speed/duplex result
6244 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6246 struct bnx2x_phy *phy = ¶ms->phy[phy_index];
6247 if (!phy->read_status)
6249 /* Read link status and params of this ext phy */
6250 cur_link_up = phy->read_status(phy, params,
6251 &phy_vars[phy_index]);
6253 DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
6256 DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
6261 if (!ext_phy_link_up) {
6262 ext_phy_link_up = 1;
6263 active_external_phy = phy_index;
6265 switch (bnx2x_phy_selection(params)) {
6266 case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
6267 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
6269 * In this option, the first PHY makes sure to pass the
6270 * traffic through itself only.
6271 * Its not clear how to reset the link on the second phy
6273 active_external_phy = EXT_PHY1;
6275 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
6277 * In this option, the first PHY makes sure to pass the
6278 * traffic through the second PHY.
6280 active_external_phy = EXT_PHY2;
6284 * Link indication on both PHYs with the following cases
6286 * - FIRST_PHY means that second phy wasn't initialized,
6287 * hence its link is expected to be down
6288 * - SECOND_PHY means that first phy should not be able
6289 * to link up by itself (using configuration)
6290 * - DEFAULT should be overriden during initialiazation
6292 DP(NETIF_MSG_LINK, "Invalid link indication"
6293 "mpc=0x%x. DISABLING LINK !!!\n",
6294 params->multi_phy_config);
6295 ext_phy_link_up = 0;
6300 prev_line_speed = vars->line_speed;
6303 * Read the status of the internal phy. In case of
6304 * DIRECT_SINGLE_MEDIA board, this link is the external link,
6305 * otherwise this is the link between the 577xx and the first
6308 if (params->phy[INT_PHY].read_status)
6309 params->phy[INT_PHY].read_status(
6310 ¶ms->phy[INT_PHY],
6313 * The INT_PHY flow control reside in the vars. This include the
6314 * case where the speed or flow control are not set to AUTO.
6315 * Otherwise, the active external phy flow control result is set
6316 * to the vars. The ext_phy_line_speed is needed to check if the
6317 * speed is different between the internal phy and external phy.
6318 * This case may be result of intermediate link speed change.
6320 if (active_external_phy > INT_PHY) {
6321 vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
6323 * Link speed is taken from the XGXS. AN and FC result from
6326 vars->link_status |= phy_vars[active_external_phy].link_status;
6329 * if active_external_phy is first PHY and link is up - disable
6330 * disable TX on second external PHY
6332 if (active_external_phy == EXT_PHY1) {
6333 if (params->phy[EXT_PHY2].phy_specific_func) {
6334 DP(NETIF_MSG_LINK, "Disabling TX on"
6336 params->phy[EXT_PHY2].phy_specific_func(
6337 ¶ms->phy[EXT_PHY2],
6338 params, DISABLE_TX);
6342 ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
6343 vars->duplex = phy_vars[active_external_phy].duplex;
6344 if (params->phy[active_external_phy].supported &
6346 vars->link_status |= LINK_STATUS_SERDES_LINK;
6348 vars->link_status &= ~LINK_STATUS_SERDES_LINK;
6349 DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
6350 active_external_phy);
6353 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6355 if (params->phy[phy_index].flags &
6356 FLAGS_REARM_LATCH_SIGNAL) {
6357 bnx2x_rearm_latch_signal(bp, port,
6359 active_external_phy);
6363 DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
6364 " ext_phy_line_speed = %d\n", vars->flow_ctrl,
6365 vars->link_status, ext_phy_line_speed);
6367 * Upon link speed change set the NIG into drain mode. Comes to
6368 * deals with possible FIFO glitch due to clk change when speed
6369 * is decreased without link down indicator
6372 if (vars->phy_link_up) {
6373 if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
6374 (ext_phy_line_speed != vars->line_speed)) {
6375 DP(NETIF_MSG_LINK, "Internal link speed %d is"
6376 " different than the external"
6377 " link speed %d\n", vars->line_speed,
6378 ext_phy_line_speed);
6379 vars->phy_link_up = 0;
6380 } else if (prev_line_speed != vars->line_speed) {
6381 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4,
6387 /* anything 10 and over uses the bmac */
6388 link_10g_plus = (vars->line_speed >= SPEED_10000);
6390 bnx2x_link_int_ack(params, vars, link_10g_plus);
6393 * In case external phy link is up, and internal link is down
6394 * (not initialized yet probably after link initialization, it
6395 * needs to be initialized.
6396 * Note that after link down-up as result of cable plug, the xgxs
6397 * link would probably become up again without the need
6400 if (!(SINGLE_MEDIA_DIRECT(params))) {
6401 DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
6402 " init_preceding = %d\n", ext_phy_link_up,
6404 params->phy[EXT_PHY1].flags &
6405 FLAGS_INIT_XGXS_FIRST);
6406 if (!(params->phy[EXT_PHY1].flags &
6407 FLAGS_INIT_XGXS_FIRST)
6408 && ext_phy_link_up && !vars->phy_link_up) {
6409 vars->line_speed = ext_phy_line_speed;
6410 if (vars->line_speed < SPEED_1000)
6411 vars->phy_flags |= PHY_SGMII_FLAG;
6413 vars->phy_flags &= ~PHY_SGMII_FLAG;
6415 if (params->phy[INT_PHY].config_init)
6416 params->phy[INT_PHY].config_init(
6417 ¶ms->phy[INT_PHY], params,
6422 * Link is up only if both local phy and external phy (in case of
6423 * non-direct board) are up and no fault detected on active PHY.
6425 vars->link_up = (vars->phy_link_up &&
6427 SINGLE_MEDIA_DIRECT(params)) &&
6428 (phy_vars[active_external_phy].fault_detected == 0));
6431 rc = bnx2x_update_link_up(params, vars, link_10g_plus);
6433 rc = bnx2x_update_link_down(params, vars);
6439 /*****************************************************************************/
6440 /* External Phy section */
6441 /*****************************************************************************/
6442 void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
6444 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6445 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
6447 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6448 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
6451 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
6452 u32 spirom_ver, u32 ver_addr)
6454 DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
6455 (u16)(spirom_ver>>16), (u16)spirom_ver, port);
6458 REG_WR(bp, ver_addr, spirom_ver);
6461 static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp,
6462 struct bnx2x_phy *phy,
6465 u16 fw_ver1, fw_ver2;
6467 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
6468 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6469 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
6470 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
6471 bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2),
6475 static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp,
6476 struct bnx2x_phy *phy,
6477 struct link_vars *vars)
6480 bnx2x_cl45_read(bp, phy,
6482 MDIO_AN_REG_STATUS, &val);
6483 bnx2x_cl45_read(bp, phy,
6485 MDIO_AN_REG_STATUS, &val);
6487 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6488 if ((val & (1<<0)) == 0)
6489 vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
6492 /******************************************************************/
6493 /* common BCM8073/BCM8727 PHY SECTION */
6494 /******************************************************************/
6495 static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
6496 struct link_params *params,
6497 struct link_vars *vars)
6499 struct bnx2x *bp = params->bp;
6500 if (phy->req_line_speed == SPEED_10 ||
6501 phy->req_line_speed == SPEED_100) {
6502 vars->flow_ctrl = phy->req_flow_ctrl;
6506 if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
6507 (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) {
6509 u16 ld_pause; /* local */
6510 u16 lp_pause; /* link partner */
6511 bnx2x_cl45_read(bp, phy,
6513 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
6515 bnx2x_cl45_read(bp, phy,
6517 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
6518 pause_result = (ld_pause &
6519 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
6520 pause_result |= (lp_pause &
6521 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
6523 bnx2x_pause_resolve(vars, pause_result);
6524 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
6528 static int bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
6529 struct bnx2x_phy *phy,
6533 u16 fw_ver1, fw_msgout;
6536 /* Boot port from external ROM */
6538 bnx2x_cl45_write(bp, phy,
6540 MDIO_PMA_REG_GEN_CTRL,
6543 /* ucode reboot and rst */
6544 bnx2x_cl45_write(bp, phy,
6546 MDIO_PMA_REG_GEN_CTRL,
6549 bnx2x_cl45_write(bp, phy,
6551 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
6553 /* Reset internal microprocessor */
6554 bnx2x_cl45_write(bp, phy,
6556 MDIO_PMA_REG_GEN_CTRL,
6557 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
6559 /* Release srst bit */
6560 bnx2x_cl45_write(bp, phy,
6562 MDIO_PMA_REG_GEN_CTRL,
6563 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
6565 /* Delay 100ms per the PHY specifications */
6568 /* 8073 sometimes taking longer to download */
6573 "bnx2x_8073_8727_external_rom_boot port %x:"
6574 "Download failed. fw version = 0x%x\n",
6580 bnx2x_cl45_read(bp, phy,
6582 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6583 bnx2x_cl45_read(bp, phy,
6585 MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
6588 } while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
6589 ((fw_msgout & 0xff) != 0x03 && (phy->type ==
6590 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)));
6592 /* Clear ser_boot_ctl bit */
6593 bnx2x_cl45_write(bp, phy,
6595 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
6596 bnx2x_save_bcm_spirom_ver(bp, phy, port);
6599 "bnx2x_8073_8727_external_rom_boot port %x:"
6600 "Download complete. fw version = 0x%x\n",
6606 /******************************************************************/
6607 /* BCM8073 PHY SECTION */
6608 /******************************************************************/
6609 static int bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
6611 /* This is only required for 8073A1, version 102 only */
6614 /* Read 8073 HW revision*/
6615 bnx2x_cl45_read(bp, phy,
6617 MDIO_PMA_REG_8073_CHIP_REV, &val);
6620 /* No need to workaround in 8073 A1 */
6624 bnx2x_cl45_read(bp, phy,
6626 MDIO_PMA_REG_ROM_VER2, &val);
6628 /* SNR should be applied only for version 0x102 */
6635 static int bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
6637 u16 val, cnt, cnt1 ;
6639 bnx2x_cl45_read(bp, phy,
6641 MDIO_PMA_REG_8073_CHIP_REV, &val);
6644 /* No need to workaround in 8073 A1 */
6647 /* XAUI workaround in 8073 A0: */
6650 * After loading the boot ROM and restarting Autoneg, poll
6654 for (cnt = 0; cnt < 1000; cnt++) {
6655 bnx2x_cl45_read(bp, phy,
6657 MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
6660 * If bit [14] = 0 or bit [13] = 0, continue on with
6661 * system initialization (XAUI work-around not required, as
6662 * these bits indicate 2.5G or 1G link up).
6664 if (!(val & (1<<14)) || !(val & (1<<13))) {
6665 DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
6667 } else if (!(val & (1<<15))) {
6668 DP(NETIF_MSG_LINK, "bit 15 went off\n");
6670 * If bit 15 is 0, then poll Dev1, Reg $C841 until it's
6671 * MSB (bit15) goes to 1 (indicating that the XAUI
6672 * workaround has completed), then continue on with
6673 * system initialization.
6675 for (cnt1 = 0; cnt1 < 1000; cnt1++) {
6676 bnx2x_cl45_read(bp, phy,
6678 MDIO_PMA_REG_8073_XAUI_WA, &val);
6679 if (val & (1<<15)) {
6681 "XAUI workaround has completed\n");
6690 DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
6694 static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy)
6696 /* Force KR or KX */
6697 bnx2x_cl45_write(bp, phy,
6698 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
6699 bnx2x_cl45_write(bp, phy,
6700 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
6701 bnx2x_cl45_write(bp, phy,
6702 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
6703 bnx2x_cl45_write(bp, phy,
6704 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
6707 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
6708 struct bnx2x_phy *phy,
6709 struct link_vars *vars)
6712 struct bnx2x *bp = params->bp;
6713 bnx2x_cl45_read(bp, phy,
6714 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
6716 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
6717 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
6718 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
6719 if ((vars->ieee_fc &
6720 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
6721 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
6722 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
6724 if ((vars->ieee_fc &
6725 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
6726 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
6727 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
6729 if ((vars->ieee_fc &
6730 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
6731 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
6732 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
6735 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
6737 bnx2x_cl45_write(bp, phy,
6738 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
6742 static int bnx2x_8073_config_init(struct bnx2x_phy *phy,
6743 struct link_params *params,
6744 struct link_vars *vars)
6746 struct bnx2x *bp = params->bp;
6749 DP(NETIF_MSG_LINK, "Init 8073\n");
6752 gpio_port = BP_PATH(bp);
6754 gpio_port = params->port;
6755 /* Restore normal power mode*/
6756 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6757 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
6759 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6760 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
6763 bnx2x_cl45_write(bp, phy,
6764 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2));
6765 bnx2x_cl45_write(bp, phy,
6766 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004);
6768 bnx2x_8073_set_pause_cl37(params, phy, vars);
6770 bnx2x_cl45_read(bp, phy,
6771 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
6773 bnx2x_cl45_read(bp, phy,
6774 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
6776 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
6778 /* Swap polarity if required - Must be done only in non-1G mode */
6779 if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
6780 /* Configure the 8073 to swap _P and _N of the KR lines */
6781 DP(NETIF_MSG_LINK, "Swapping polarity for the 8073\n");
6782 /* 10G Rx/Tx and 1G Tx signal polarity swap */
6783 bnx2x_cl45_read(bp, phy,
6785 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
6786 bnx2x_cl45_write(bp, phy,
6788 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
6793 /* Enable CL37 BAM */
6794 if (REG_RD(bp, params->shmem_base +
6795 offsetof(struct shmem_region, dev_info.
6796 port_hw_config[params->port].default_cfg)) &
6797 PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
6799 bnx2x_cl45_read(bp, phy,
6801 MDIO_AN_REG_8073_BAM, &val);
6802 bnx2x_cl45_write(bp, phy,
6804 MDIO_AN_REG_8073_BAM, val | 1);
6805 DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
6807 if (params->loopback_mode == LOOPBACK_EXT) {
6808 bnx2x_807x_force_10G(bp, phy);
6809 DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
6812 bnx2x_cl45_write(bp, phy,
6813 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
6815 if (phy->req_line_speed != SPEED_AUTO_NEG) {
6816 if (phy->req_line_speed == SPEED_10000) {
6818 } else if (phy->req_line_speed == SPEED_2500) {
6821 * Note that 2.5G works only when used with 1G
6828 if (phy->speed_cap_mask &
6829 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
6832 /* Note that 2.5G works only when used with 1G advertisement */
6833 if (phy->speed_cap_mask &
6834 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
6835 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
6837 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
6840 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
6841 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
6843 if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
6844 (phy->req_line_speed == SPEED_AUTO_NEG)) ||
6845 (phy->req_line_speed == SPEED_2500)) {
6847 /* Allow 2.5G for A1 and above */
6848 bnx2x_cl45_read(bp, phy,
6849 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
6851 DP(NETIF_MSG_LINK, "Add 2.5G\n");
6857 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
6861 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
6862 /* Add support for CL37 (passive mode) II */
6864 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
6865 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
6866 (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
6869 /* Add support for CL37 (passive mode) III */
6870 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
6873 * The SNR will improve about 2db by changing BW and FEE main
6874 * tap. Rest commands are executed after link is up
6875 * Change FFE main cursor to 5 in EDC register
6877 if (bnx2x_8073_is_snr_needed(bp, phy))
6878 bnx2x_cl45_write(bp, phy,
6879 MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
6882 /* Enable FEC (Forware Error Correction) Request in the AN */
6883 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
6885 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
6887 bnx2x_ext_phy_set_pause(params, phy, vars);
6889 /* Restart autoneg */
6891 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
6892 DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
6893 ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
6897 static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
6898 struct link_params *params,
6899 struct link_vars *vars)
6901 struct bnx2x *bp = params->bp;
6904 u16 link_status = 0;
6905 u16 an1000_status = 0;
6907 bnx2x_cl45_read(bp, phy,
6908 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
6910 DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
6912 /* clear the interrupt LASI status register */
6913 bnx2x_cl45_read(bp, phy,
6914 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
6915 bnx2x_cl45_read(bp, phy,
6916 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
6917 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
6919 bnx2x_cl45_read(bp, phy,
6920 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
6922 /* Check the LASI */
6923 bnx2x_cl45_read(bp, phy,
6924 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
6926 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
6928 /* Check the link status */
6929 bnx2x_cl45_read(bp, phy,
6930 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
6931 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
6933 bnx2x_cl45_read(bp, phy,
6934 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
6935 bnx2x_cl45_read(bp, phy,
6936 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
6937 link_up = ((val1 & 4) == 4);
6938 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
6941 ((phy->req_line_speed != SPEED_10000))) {
6942 if (bnx2x_8073_xaui_wa(bp, phy) != 0)
6945 bnx2x_cl45_read(bp, phy,
6946 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
6947 bnx2x_cl45_read(bp, phy,
6948 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
6950 /* Check the link status on 1.1.2 */
6951 bnx2x_cl45_read(bp, phy,
6952 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
6953 bnx2x_cl45_read(bp, phy,
6954 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
6955 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
6956 "an_link_status=0x%x\n", val2, val1, an1000_status);
6958 link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
6959 if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
6961 * The SNR will improve about 2dbby changing the BW and FEE main
6962 * tap. The 1st write to change FFE main tap is set before
6963 * restart AN. Change PLL Bandwidth in EDC register
6965 bnx2x_cl45_write(bp, phy,
6966 MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
6969 /* Change CDR Bandwidth in EDC register */
6970 bnx2x_cl45_write(bp, phy,
6971 MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
6974 bnx2x_cl45_read(bp, phy,
6975 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
6978 /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
6979 if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
6981 vars->line_speed = SPEED_10000;
6982 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
6984 } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
6986 vars->line_speed = SPEED_2500;
6987 DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
6989 } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
6991 vars->line_speed = SPEED_1000;
6992 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
6996 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
7001 /* Swap polarity if required */
7002 if (params->lane_config &
7003 PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
7004 /* Configure the 8073 to swap P and N of the KR lines */
7005 bnx2x_cl45_read(bp, phy,
7007 MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
7009 * Set bit 3 to invert Rx in 1G mode and clear this bit
7010 * when it`s in 10G mode.
7012 if (vars->line_speed == SPEED_1000) {
7013 DP(NETIF_MSG_LINK, "Swapping 1G polarity for"
7019 bnx2x_cl45_write(bp, phy,
7021 MDIO_XS_REG_8073_RX_CTRL_PCIE,
7024 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
7025 bnx2x_8073_resolve_fc(phy, params, vars);
7026 vars->duplex = DUPLEX_FULL;
7031 static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
7032 struct link_params *params)
7034 struct bnx2x *bp = params->bp;
7037 gpio_port = BP_PATH(bp);
7039 gpio_port = params->port;
7040 DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
7042 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7043 MISC_REGISTERS_GPIO_OUTPUT_LOW,
7047 /******************************************************************/
7048 /* BCM8705 PHY SECTION */
7049 /******************************************************************/
7050 static int bnx2x_8705_config_init(struct bnx2x_phy *phy,
7051 struct link_params *params,
7052 struct link_vars *vars)
7054 struct bnx2x *bp = params->bp;
7055 DP(NETIF_MSG_LINK, "init 8705\n");
7056 /* Restore normal power mode*/
7057 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7058 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
7060 bnx2x_ext_phy_hw_reset(bp, params->port);
7061 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
7062 bnx2x_wait_reset_complete(bp, phy, params);
7064 bnx2x_cl45_write(bp, phy,
7065 MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
7066 bnx2x_cl45_write(bp, phy,
7067 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
7068 bnx2x_cl45_write(bp, phy,
7069 MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
7070 bnx2x_cl45_write(bp, phy,
7071 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
7072 /* BCM8705 doesn't have microcode, hence the 0 */
7073 bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
7077 static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
7078 struct link_params *params,
7079 struct link_vars *vars)
7083 struct bnx2x *bp = params->bp;
7084 DP(NETIF_MSG_LINK, "read status 8705\n");
7085 bnx2x_cl45_read(bp, phy,
7086 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
7087 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
7089 bnx2x_cl45_read(bp, phy,
7090 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
7091 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
7093 bnx2x_cl45_read(bp, phy,
7094 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
7096 bnx2x_cl45_read(bp, phy,
7097 MDIO_PMA_DEVAD, 0xc809, &val1);
7098 bnx2x_cl45_read(bp, phy,
7099 MDIO_PMA_DEVAD, 0xc809, &val1);
7101 DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
7102 link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
7104 vars->line_speed = SPEED_10000;
7105 bnx2x_ext_phy_resolve_fc(phy, params, vars);
7110 /******************************************************************/
7111 /* SFP+ module Section */
7112 /******************************************************************/
7113 static u8 bnx2x_get_gpio_port(struct link_params *params)
7116 u32 swap_val, swap_override;
7117 struct bnx2x *bp = params->bp;
7119 gpio_port = BP_PATH(bp);
7121 gpio_port = params->port;
7122 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
7123 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
7124 return gpio_port ^ (swap_val && swap_override);
7127 static void bnx2x_sfp_e1e2_set_transmitter(struct link_params *params,
7128 struct bnx2x_phy *phy,
7132 u8 port = params->port;
7133 struct bnx2x *bp = params->bp;
7136 /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
7137 tx_en_mode = REG_RD(bp, params->shmem_base +
7138 offsetof(struct shmem_region,
7139 dev_info.port_hw_config[port].sfp_ctrl)) &
7140 PORT_HW_CFG_TX_LASER_MASK;
7141 DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x "
7142 "mode = %x\n", tx_en, port, tx_en_mode);
7143 switch (tx_en_mode) {
7144 case PORT_HW_CFG_TX_LASER_MDIO:
7146 bnx2x_cl45_read(bp, phy,
7148 MDIO_PMA_REG_PHY_IDENTIFIER,
7156 bnx2x_cl45_write(bp, phy,
7158 MDIO_PMA_REG_PHY_IDENTIFIER,
7161 case PORT_HW_CFG_TX_LASER_GPIO0:
7162 case PORT_HW_CFG_TX_LASER_GPIO1:
7163 case PORT_HW_CFG_TX_LASER_GPIO2:
7164 case PORT_HW_CFG_TX_LASER_GPIO3:
7167 u8 gpio_port, gpio_mode;
7169 gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH;
7171 gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW;
7173 gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0;
7174 gpio_port = bnx2x_get_gpio_port(params);
7175 bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
7179 DP(NETIF_MSG_LINK, "Invalid TX_LASER_MDIO 0x%x\n", tx_en_mode);
7184 static void bnx2x_sfp_set_transmitter(struct link_params *params,
7185 struct bnx2x_phy *phy,
7188 struct bnx2x *bp = params->bp;
7189 DP(NETIF_MSG_LINK, "Setting SFP+ transmitter to %d\n", tx_en);
7191 bnx2x_sfp_e3_set_transmitter(params, phy, tx_en);
7193 bnx2x_sfp_e1e2_set_transmitter(params, phy, tx_en);
7196 static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7197 struct link_params *params,
7198 u16 addr, u8 byte_cnt, u8 *o_buf)
7200 struct bnx2x *bp = params->bp;
7203 if (byte_cnt > 16) {
7204 DP(NETIF_MSG_LINK, "Reading from eeprom is"
7205 " is limited to 0xf\n");
7208 /* Set the read command byte count */
7209 bnx2x_cl45_write(bp, phy,
7210 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
7211 (byte_cnt | 0xa000));
7213 /* Set the read command address */
7214 bnx2x_cl45_write(bp, phy,
7215 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
7218 /* Activate read command */
7219 bnx2x_cl45_write(bp, phy,
7220 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7223 /* Wait up to 500us for command complete status */
7224 for (i = 0; i < 100; i++) {
7225 bnx2x_cl45_read(bp, phy,
7227 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7228 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7229 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
7234 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
7235 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
7237 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
7238 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
7242 /* Read the buffer */
7243 for (i = 0; i < byte_cnt; i++) {
7244 bnx2x_cl45_read(bp, phy,
7246 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
7247 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
7250 for (i = 0; i < 100; i++) {
7251 bnx2x_cl45_read(bp, phy,
7253 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7254 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7255 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
7262 static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7263 struct link_params *params,
7264 u16 addr, u8 byte_cnt,
7268 u8 i, j = 0, cnt = 0;
7271 struct bnx2x *bp = params->bp;
7272 /*DP(NETIF_MSG_LINK, "bnx2x_direct_read_sfp_module_eeprom:"
7273 " addr %d, cnt %d\n",
7275 if (byte_cnt > 16) {
7276 DP(NETIF_MSG_LINK, "Reading from eeprom is"
7277 " is limited to 16 bytes\n");
7281 /* 4 byte aligned address */
7282 addr32 = addr & (~0x3);
7284 rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt,
7286 } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT));
7289 for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) {
7290 o_buf[j] = *((u8 *)data_array + i);
7298 static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7299 struct link_params *params,
7300 u16 addr, u8 byte_cnt, u8 *o_buf)
7302 struct bnx2x *bp = params->bp;
7305 if (byte_cnt > 16) {
7306 DP(NETIF_MSG_LINK, "Reading from eeprom is"
7307 " is limited to 0xf\n");
7311 /* Need to read from 1.8000 to clear it */
7312 bnx2x_cl45_read(bp, phy,
7314 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7317 /* Set the read command byte count */
7318 bnx2x_cl45_write(bp, phy,
7320 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
7321 ((byte_cnt < 2) ? 2 : byte_cnt));
7323 /* Set the read command address */
7324 bnx2x_cl45_write(bp, phy,
7326 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
7328 /* Set the destination address */
7329 bnx2x_cl45_write(bp, phy,
7332 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
7334 /* Activate read command */
7335 bnx2x_cl45_write(bp, phy,
7337 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7340 * Wait appropriate time for two-wire command to finish before
7341 * polling the status register
7345 /* Wait up to 500us for command complete status */
7346 for (i = 0; i < 100; i++) {
7347 bnx2x_cl45_read(bp, phy,
7349 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7350 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7351 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
7356 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
7357 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
7359 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
7360 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
7364 /* Read the buffer */
7365 for (i = 0; i < byte_cnt; i++) {
7366 bnx2x_cl45_read(bp, phy,
7368 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
7369 o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
7372 for (i = 0; i < 100; i++) {
7373 bnx2x_cl45_read(bp, phy,
7375 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7376 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7377 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
7385 int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7386 struct link_params *params, u16 addr,
7387 u8 byte_cnt, u8 *o_buf)
7390 switch (phy->type) {
7391 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7392 rc = bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
7395 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7396 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
7397 rc = bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
7400 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
7401 rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr,
7408 static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
7409 struct link_params *params,
7412 struct bnx2x *bp = params->bp;
7413 u32 sync_offset = 0, phy_idx, media_types;
7414 u8 val, check_limiting_mode = 0;
7415 *edc_mode = EDC_MODE_LIMITING;
7417 phy->media_type = ETH_PHY_UNSPECIFIED;
7418 /* First check for copper cable */
7419 if (bnx2x_read_sfp_module_eeprom(phy,
7421 SFP_EEPROM_CON_TYPE_ADDR,
7424 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
7429 case SFP_EEPROM_CON_TYPE_VAL_COPPER:
7431 u8 copper_module_type;
7432 phy->media_type = ETH_PHY_DA_TWINAX;
7434 * Check if its active cable (includes SFP+ module)
7437 if (bnx2x_read_sfp_module_eeprom(phy,
7439 SFP_EEPROM_FC_TX_TECH_ADDR,
7441 &copper_module_type) != 0) {
7443 "Failed to read copper-cable-type"
7444 " from SFP+ EEPROM\n");
7448 if (copper_module_type &
7449 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
7450 DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
7451 check_limiting_mode = 1;
7452 } else if (copper_module_type &
7453 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
7454 DP(NETIF_MSG_LINK, "Passive Copper"
7455 " cable detected\n");
7457 EDC_MODE_PASSIVE_DAC;
7459 DP(NETIF_MSG_LINK, "Unknown copper-cable-"
7460 "type 0x%x !!!\n", copper_module_type);
7465 case SFP_EEPROM_CON_TYPE_VAL_LC:
7466 phy->media_type = ETH_PHY_SFP_FIBER;
7467 DP(NETIF_MSG_LINK, "Optic module detected\n");
7468 check_limiting_mode = 1;
7471 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
7475 sync_offset = params->shmem_base +
7476 offsetof(struct shmem_region,
7477 dev_info.port_hw_config[params->port].media_type);
7478 media_types = REG_RD(bp, sync_offset);
7479 /* Update media type for non-PMF sync */
7480 for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
7481 if (&(params->phy[phy_idx]) == phy) {
7482 media_types &= ~(PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
7483 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
7484 media_types |= ((phy->media_type &
7485 PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
7486 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
7490 REG_WR(bp, sync_offset, media_types);
7491 if (check_limiting_mode) {
7492 u8 options[SFP_EEPROM_OPTIONS_SIZE];
7493 if (bnx2x_read_sfp_module_eeprom(phy,
7495 SFP_EEPROM_OPTIONS_ADDR,
7496 SFP_EEPROM_OPTIONS_SIZE,
7498 DP(NETIF_MSG_LINK, "Failed to read Option"
7499 " field from module EEPROM\n");
7502 if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
7503 *edc_mode = EDC_MODE_LINEAR;
7505 *edc_mode = EDC_MODE_LIMITING;
7507 DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
7511 * This function read the relevant field from the module (SFP+), and verify it
7512 * is compliant with this board
7514 static int bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
7515 struct link_params *params)
7517 struct bnx2x *bp = params->bp;
7519 u32 fw_resp, fw_cmd_param;
7520 char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
7521 char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
7522 phy->flags &= ~FLAGS_SFP_NOT_APPROVED;
7523 val = REG_RD(bp, params->shmem_base +
7524 offsetof(struct shmem_region, dev_info.
7525 port_feature_config[params->port].config));
7526 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
7527 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
7528 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
7532 if (params->feature_config_flags &
7533 FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
7534 /* Use specific phy request */
7535 cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
7536 } else if (params->feature_config_flags &
7537 FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
7538 /* Use first phy request only in case of non-dual media*/
7539 if (DUAL_MEDIA(params)) {
7540 DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
7544 cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
7546 /* No support in OPT MDL detection */
7547 DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
7552 fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
7553 fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param);
7554 if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
7555 DP(NETIF_MSG_LINK, "Approved module\n");
7559 /* format the warning message */
7560 if (bnx2x_read_sfp_module_eeprom(phy,
7562 SFP_EEPROM_VENDOR_NAME_ADDR,
7563 SFP_EEPROM_VENDOR_NAME_SIZE,
7565 vendor_name[0] = '\0';
7567 vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
7568 if (bnx2x_read_sfp_module_eeprom(phy,
7570 SFP_EEPROM_PART_NO_ADDR,
7571 SFP_EEPROM_PART_NO_SIZE,
7573 vendor_pn[0] = '\0';
7575 vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
7577 netdev_err(bp->dev, "Warning: Unqualified SFP+ module detected,"
7578 " Port %d from %s part number %s\n",
7579 params->port, vendor_name, vendor_pn);
7580 phy->flags |= FLAGS_SFP_NOT_APPROVED;
7584 static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
7585 struct link_params *params)
7589 struct bnx2x *bp = params->bp;
7592 * Initialization time after hot-plug may take up to 300ms for
7593 * some phys type ( e.g. JDSU )
7596 for (timeout = 0; timeout < 60; timeout++) {
7597 if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
7599 DP(NETIF_MSG_LINK, "SFP+ module initialization "
7600 "took %d ms\n", timeout * 5);
7608 static void bnx2x_8727_power_module(struct bnx2x *bp,
7609 struct bnx2x_phy *phy,
7611 /* Make sure GPIOs are not using for LED mode */
7614 * In the GPIO register, bit 4 is use to determine if the GPIOs are
7615 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
7617 * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0
7618 * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1
7619 * where the 1st bit is the over-current(only input), and 2nd bit is
7620 * for power( only output )
7622 * In case of NOC feature is disabled and power is up, set GPIO control
7623 * as input to enable listening of over-current indication
7625 if (phy->flags & FLAGS_NOC)
7631 * Set GPIO control to OUTPUT, and set the power bit
7632 * to according to the is_power_up
7636 bnx2x_cl45_write(bp, phy,
7638 MDIO_PMA_REG_8727_GPIO_CTRL,
7642 static int bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
7643 struct bnx2x_phy *phy,
7646 u16 cur_limiting_mode;
7648 bnx2x_cl45_read(bp, phy,
7650 MDIO_PMA_REG_ROM_VER2,
7651 &cur_limiting_mode);
7652 DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
7655 if (edc_mode == EDC_MODE_LIMITING) {
7656 DP(NETIF_MSG_LINK, "Setting LIMITING MODE\n");
7657 bnx2x_cl45_write(bp, phy,
7659 MDIO_PMA_REG_ROM_VER2,
7661 } else { /* LRM mode ( default )*/
7663 DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
7666 * Changing to LRM mode takes quite few seconds. So do it only
7667 * if current mode is limiting (default is LRM)
7669 if (cur_limiting_mode != EDC_MODE_LIMITING)
7672 bnx2x_cl45_write(bp, phy,
7674 MDIO_PMA_REG_LRM_MODE,
7676 bnx2x_cl45_write(bp, phy,
7678 MDIO_PMA_REG_ROM_VER2,
7680 bnx2x_cl45_write(bp, phy,
7682 MDIO_PMA_REG_MISC_CTRL0,
7684 bnx2x_cl45_write(bp, phy,
7686 MDIO_PMA_REG_LRM_MODE,
7692 static int bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
7693 struct bnx2x_phy *phy,
7698 bnx2x_cl45_read(bp, phy,
7700 MDIO_PMA_REG_PHY_IDENTIFIER,
7703 bnx2x_cl45_write(bp, phy,
7705 MDIO_PMA_REG_PHY_IDENTIFIER,
7706 (phy_identifier & ~(1<<9)));
7708 bnx2x_cl45_read(bp, phy,
7710 MDIO_PMA_REG_ROM_VER2,
7712 /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
7713 bnx2x_cl45_write(bp, phy,
7715 MDIO_PMA_REG_ROM_VER2,
7716 (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
7718 bnx2x_cl45_write(bp, phy,
7720 MDIO_PMA_REG_PHY_IDENTIFIER,
7721 (phy_identifier | (1<<9)));
7726 static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
7727 struct link_params *params,
7730 struct bnx2x *bp = params->bp;
7734 bnx2x_sfp_set_transmitter(params, phy, 0);
7737 if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
7738 bnx2x_sfp_set_transmitter(params, phy, 1);
7741 DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
7747 static void bnx2x_set_e1e2_module_fault_led(struct link_params *params,
7750 struct bnx2x *bp = params->bp;
7752 u32 fault_led_gpio = REG_RD(bp, params->shmem_base +
7753 offsetof(struct shmem_region,
7754 dev_info.port_hw_config[params->port].sfp_ctrl)) &
7755 PORT_HW_CFG_FAULT_MODULE_LED_MASK;
7756 switch (fault_led_gpio) {
7757 case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED:
7759 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0:
7760 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1:
7761 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2:
7762 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3:
7764 u8 gpio_port = bnx2x_get_gpio_port(params);
7765 u16 gpio_pin = fault_led_gpio -
7766 PORT_HW_CFG_FAULT_MODULE_LED_GPIO0;
7767 DP(NETIF_MSG_LINK, "Set fault module-detected led "
7768 "pin %x port %x mode %x\n",
7769 gpio_pin, gpio_port, gpio_mode);
7770 bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
7774 DP(NETIF_MSG_LINK, "Error: Invalid fault led mode 0x%x\n",
7779 static void bnx2x_set_e3_module_fault_led(struct link_params *params,
7783 u8 port = params->port;
7784 struct bnx2x *bp = params->bp;
7785 pin_cfg = (REG_RD(bp, params->shmem_base +
7786 offsetof(struct shmem_region,
7787 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
7788 PORT_HW_CFG_E3_FAULT_MDL_LED_MASK) >>
7789 PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT;
7790 DP(NETIF_MSG_LINK, "Setting Fault LED to %d using pin cfg %d\n",
7791 gpio_mode, pin_cfg);
7792 bnx2x_set_cfg_pin(bp, pin_cfg, gpio_mode);
7795 static void bnx2x_set_sfp_module_fault_led(struct link_params *params,
7798 struct bnx2x *bp = params->bp;
7799 DP(NETIF_MSG_LINK, "Setting SFP+ module fault LED to %d\n", gpio_mode);
7800 if (CHIP_IS_E3(bp)) {
7802 * Low ==> if SFP+ module is supported otherwise
7803 * High ==> if SFP+ module is not on the approved vendor list
7805 bnx2x_set_e3_module_fault_led(params, gpio_mode);
7807 bnx2x_set_e1e2_module_fault_led(params, gpio_mode);
7810 static void bnx2x_warpcore_power_module(struct link_params *params,
7811 struct bnx2x_phy *phy,
7815 struct bnx2x *bp = params->bp;
7817 pin_cfg = (REG_RD(bp, params->shmem_base +
7818 offsetof(struct shmem_region,
7819 dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
7820 PORT_HW_CFG_E3_PWR_DIS_MASK) >>
7821 PORT_HW_CFG_E3_PWR_DIS_SHIFT;
7822 DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n",
7825 * Low ==> corresponding SFP+ module is powered
7826 * high ==> the SFP+ module is powered down
7828 bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1);
7831 static void bnx2x_power_sfp_module(struct link_params *params,
7832 struct bnx2x_phy *phy,
7835 struct bnx2x *bp = params->bp;
7836 DP(NETIF_MSG_LINK, "Setting SFP+ power to %x\n", power);
7838 switch (phy->type) {
7839 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7840 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
7841 bnx2x_8727_power_module(params->bp, phy, power);
7843 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
7844 bnx2x_warpcore_power_module(params, phy, power);
7850 static void bnx2x_warpcore_set_limiting_mode(struct link_params *params,
7851 struct bnx2x_phy *phy,
7855 u16 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
7856 struct bnx2x *bp = params->bp;
7858 u8 lane = bnx2x_get_warpcore_lane(phy, params);
7859 /* This is a global register which controls all lanes */
7860 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
7861 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
7862 val &= ~(0xf << (lane << 2));
7865 case EDC_MODE_LINEAR:
7866 case EDC_MODE_LIMITING:
7867 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
7869 case EDC_MODE_PASSIVE_DAC:
7870 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC;
7876 val |= (mode << (lane << 2));
7877 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
7878 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, val);
7880 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
7881 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
7886 static void bnx2x_set_limiting_mode(struct link_params *params,
7887 struct bnx2x_phy *phy,
7890 switch (phy->type) {
7891 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7892 bnx2x_8726_set_limiting_mode(params->bp, phy, edc_mode);
7894 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7895 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
7896 bnx2x_8727_set_limiting_mode(params->bp, phy, edc_mode);
7898 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
7899 bnx2x_warpcore_set_limiting_mode(params, phy, edc_mode);
7904 int bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
7905 struct link_params *params)
7907 struct bnx2x *bp = params->bp;
7911 u32 val = REG_RD(bp, params->shmem_base +
7912 offsetof(struct shmem_region, dev_info.
7913 port_feature_config[params->port].config));
7915 DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
7917 /* Power up module */
7918 bnx2x_power_sfp_module(params, phy, 1);
7919 if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
7920 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
7922 } else if (bnx2x_verify_sfp_module(phy, params) != 0) {
7923 /* check SFP+ module compatibility */
7924 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
7926 /* Turn on fault module-detected led */
7927 bnx2x_set_sfp_module_fault_led(params,
7928 MISC_REGISTERS_GPIO_HIGH);
7930 /* Check if need to power down the SFP+ module */
7931 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
7932 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN) {
7933 DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
7934 bnx2x_power_sfp_module(params, phy, 0);
7938 /* Turn off fault module-detected led */
7939 bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
7943 * Check and set limiting mode / LRM mode on 8726. On 8727 it
7944 * is done automatically
7946 bnx2x_set_limiting_mode(params, phy, edc_mode);
7949 * Enable transmit for this module if the module is approved, or
7950 * if unapproved modules should also enable the Tx laser
7953 (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
7954 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
7955 bnx2x_sfp_set_transmitter(params, phy, 1);
7957 bnx2x_sfp_set_transmitter(params, phy, 0);
7962 void bnx2x_handle_module_detect_int(struct link_params *params)
7964 struct bnx2x *bp = params->bp;
7965 struct bnx2x_phy *phy;
7967 u8 gpio_num, gpio_port;
7969 phy = ¶ms->phy[INT_PHY];
7971 phy = ¶ms->phy[EXT_PHY1];
7973 if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id, params->shmem_base,
7974 params->port, &gpio_num, &gpio_port) ==
7976 DP(NETIF_MSG_LINK, "Failed to get MOD_ABS interrupt config\n");
7980 /* Set valid module led off */
7981 bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH);
7983 /* Get current gpio val reflecting module plugged in / out*/
7984 gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
7986 /* Call the handling function in case module is detected */
7987 if (gpio_val == 0) {
7988 bnx2x_power_sfp_module(params, phy, 1);
7989 bnx2x_set_gpio_int(bp, gpio_num,
7990 MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
7992 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
7993 bnx2x_sfp_module_detection(phy, params);
7995 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
7997 u32 val = REG_RD(bp, params->shmem_base +
7998 offsetof(struct shmem_region, dev_info.
7999 port_feature_config[params->port].
8002 bnx2x_set_gpio_int(bp, gpio_num,
8003 MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
8006 * Module was plugged out.
8007 * Disable transmit for this module
8009 phy->media_type = ETH_PHY_NOT_PRESENT;
8010 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8011 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
8012 bnx2x_sfp_set_transmitter(params, phy, 0);
8016 /******************************************************************/
8017 /* Used by 8706 and 8727 */
8018 /******************************************************************/
8019 static void bnx2x_sfp_mask_fault(struct bnx2x *bp,
8020 struct bnx2x_phy *phy,
8021 u16 alarm_status_offset,
8022 u16 alarm_ctrl_offset)
8024 u16 alarm_status, val;
8025 bnx2x_cl45_read(bp, phy,
8026 MDIO_PMA_DEVAD, alarm_status_offset,
8028 bnx2x_cl45_read(bp, phy,
8029 MDIO_PMA_DEVAD, alarm_status_offset,
8031 /* Mask or enable the fault event. */
8032 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, &val);
8033 if (alarm_status & (1<<0))
8037 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, val);
8039 /******************************************************************/
8040 /* common BCM8706/BCM8726 PHY SECTION */
8041 /******************************************************************/
8042 static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
8043 struct link_params *params,
8044 struct link_vars *vars)
8047 u16 val1, val2, rx_sd, pcs_status;
8048 struct bnx2x *bp = params->bp;
8049 DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
8051 bnx2x_cl45_read(bp, phy,
8052 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
8054 bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_REG_TX_ALARM,
8055 MDIO_PMA_REG_TX_ALARM_CTRL);
8057 /* clear LASI indication*/
8058 bnx2x_cl45_read(bp, phy,
8059 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
8060 bnx2x_cl45_read(bp, phy,
8061 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
8062 DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
8064 bnx2x_cl45_read(bp, phy,
8065 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
8066 bnx2x_cl45_read(bp, phy,
8067 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
8068 bnx2x_cl45_read(bp, phy,
8069 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
8070 bnx2x_cl45_read(bp, phy,
8071 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
8073 DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
8074 " link_status 0x%x\n", rx_sd, pcs_status, val2);
8076 * link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
8077 * are set, or if the autoneg bit 1 is set
8079 link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
8082 vars->line_speed = SPEED_1000;
8084 vars->line_speed = SPEED_10000;
8085 bnx2x_ext_phy_resolve_fc(phy, params, vars);
8086 vars->duplex = DUPLEX_FULL;
8089 /* Capture 10G link fault. Read twice to clear stale value. */
8090 if (vars->line_speed == SPEED_10000) {
8091 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
8092 MDIO_PMA_REG_TX_ALARM, &val1);
8093 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
8094 MDIO_PMA_REG_TX_ALARM, &val1);
8096 vars->fault_detected = 1;
8102 /******************************************************************/
8103 /* BCM8706 PHY SECTION */
8104 /******************************************************************/
8105 static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
8106 struct link_params *params,
8107 struct link_vars *vars)
8111 struct bnx2x *bp = params->bp;
8112 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
8113 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
8115 bnx2x_ext_phy_hw_reset(bp, params->port);
8116 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
8117 bnx2x_wait_reset_complete(bp, phy, params);
8119 /* Wait until fw is loaded */
8120 for (cnt = 0; cnt < 100; cnt++) {
8121 bnx2x_cl45_read(bp, phy,
8122 MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
8127 DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt);
8128 if ((params->feature_config_flags &
8129 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
8132 for (i = 0; i < 4; i++) {
8133 reg = MDIO_XS_8706_REG_BANK_RX0 +
8134 i*(MDIO_XS_8706_REG_BANK_RX1 -
8135 MDIO_XS_8706_REG_BANK_RX0);
8136 bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val);
8137 /* Clear first 3 bits of the control */
8139 /* Set control bits according to configuration */
8140 val |= (phy->rx_preemphasis[i] & 0x7);
8141 DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706"
8142 " reg 0x%x <-- val 0x%x\n", reg, val);
8143 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val);
8147 if (phy->req_line_speed == SPEED_10000) {
8148 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
8150 bnx2x_cl45_write(bp, phy,
8152 MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
8153 bnx2x_cl45_write(bp, phy,
8154 MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_ALARM_CTRL,
8156 /* Arm LASI for link and Tx fault. */
8157 bnx2x_cl45_write(bp, phy,
8158 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 3);
8160 /* Force 1Gbps using autoneg with 1G advertisement */
8162 /* Allow CL37 through CL73 */
8163 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
8164 bnx2x_cl45_write(bp, phy,
8165 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
8167 /* Enable Full-Duplex advertisement on CL37 */
8168 bnx2x_cl45_write(bp, phy,
8169 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
8170 /* Enable CL37 AN */
8171 bnx2x_cl45_write(bp, phy,
8172 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8174 bnx2x_cl45_write(bp, phy,
8175 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
8177 /* Enable clause 73 AN */
8178 bnx2x_cl45_write(bp, phy,
8179 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
8180 bnx2x_cl45_write(bp, phy,
8181 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
8183 bnx2x_cl45_write(bp, phy,
8184 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
8187 bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
8190 * If TX Laser is controlled by GPIO_0, do not let PHY go into low
8191 * power mode, if TX Laser is disabled
8194 tx_en_mode = REG_RD(bp, params->shmem_base +
8195 offsetof(struct shmem_region,
8196 dev_info.port_hw_config[params->port].sfp_ctrl))
8197 & PORT_HW_CFG_TX_LASER_MASK;
8199 if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
8200 DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
8201 bnx2x_cl45_read(bp, phy,
8202 MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1);
8204 bnx2x_cl45_write(bp, phy,
8205 MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1);
8211 static int bnx2x_8706_read_status(struct bnx2x_phy *phy,
8212 struct link_params *params,
8213 struct link_vars *vars)
8215 return bnx2x_8706_8726_read_status(phy, params, vars);
8218 /******************************************************************/
8219 /* BCM8726 PHY SECTION */
8220 /******************************************************************/
8221 static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
8222 struct link_params *params)
8224 struct bnx2x *bp = params->bp;
8225 DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
8226 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
8229 static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
8230 struct link_params *params)
8232 struct bnx2x *bp = params->bp;
8233 /* Need to wait 100ms after reset */
8236 /* Micro controller re-boot */
8237 bnx2x_cl45_write(bp, phy,
8238 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
8240 /* Set soft reset */
8241 bnx2x_cl45_write(bp, phy,
8243 MDIO_PMA_REG_GEN_CTRL,
8244 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
8246 bnx2x_cl45_write(bp, phy,
8248 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
8250 bnx2x_cl45_write(bp, phy,
8252 MDIO_PMA_REG_GEN_CTRL,
8253 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
8255 /* wait for 150ms for microcode load */
8258 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
8259 bnx2x_cl45_write(bp, phy,
8261 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
8264 bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
8267 static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
8268 struct link_params *params,
8269 struct link_vars *vars)
8271 struct bnx2x *bp = params->bp;
8273 u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
8275 bnx2x_cl45_read(bp, phy,
8276 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
8278 if (val1 & (1<<15)) {
8279 DP(NETIF_MSG_LINK, "Tx is disabled\n");
8281 vars->line_speed = 0;
8288 static int bnx2x_8726_config_init(struct bnx2x_phy *phy,
8289 struct link_params *params,
8290 struct link_vars *vars)
8292 struct bnx2x *bp = params->bp;
8293 DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
8295 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
8296 bnx2x_wait_reset_complete(bp, phy, params);
8298 bnx2x_8726_external_rom_boot(phy, params);
8301 * Need to call module detected on initialization since the module
8302 * detection triggered by actual module insertion might occur before
8303 * driver is loaded, and when driver is loaded, it reset all
8304 * registers, including the transmitter
8306 bnx2x_sfp_module_detection(phy, params);
8308 if (phy->req_line_speed == SPEED_1000) {
8309 DP(NETIF_MSG_LINK, "Setting 1G force\n");
8310 bnx2x_cl45_write(bp, phy,
8311 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
8312 bnx2x_cl45_write(bp, phy,
8313 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
8314 bnx2x_cl45_write(bp, phy,
8315 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5);
8316 bnx2x_cl45_write(bp, phy,
8317 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
8319 } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
8320 (phy->speed_cap_mask &
8321 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
8322 ((phy->speed_cap_mask &
8323 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
8324 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
8325 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
8326 /* Set Flow control */
8327 bnx2x_ext_phy_set_pause(params, phy, vars);
8328 bnx2x_cl45_write(bp, phy,
8329 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
8330 bnx2x_cl45_write(bp, phy,
8331 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
8332 bnx2x_cl45_write(bp, phy,
8333 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
8334 bnx2x_cl45_write(bp, phy,
8335 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8336 bnx2x_cl45_write(bp, phy,
8337 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
8339 * Enable RX-ALARM control to receive interrupt for 1G speed
8342 bnx2x_cl45_write(bp, phy,
8343 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4);
8344 bnx2x_cl45_write(bp, phy,
8345 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
8348 } else { /* Default 10G. Set only LASI control */
8349 bnx2x_cl45_write(bp, phy,
8350 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
8353 /* Set TX PreEmphasis if needed */
8354 if ((params->feature_config_flags &
8355 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
8356 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
8358 phy->tx_preemphasis[0],
8359 phy->tx_preemphasis[1]);
8360 bnx2x_cl45_write(bp, phy,
8362 MDIO_PMA_REG_8726_TX_CTRL1,
8363 phy->tx_preemphasis[0]);
8365 bnx2x_cl45_write(bp, phy,
8367 MDIO_PMA_REG_8726_TX_CTRL2,
8368 phy->tx_preemphasis[1]);
8375 static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
8376 struct link_params *params)
8378 struct bnx2x *bp = params->bp;
8379 DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
8380 /* Set serial boot control for external load */
8381 bnx2x_cl45_write(bp, phy,
8383 MDIO_PMA_REG_GEN_CTRL, 0x0001);
8386 /******************************************************************/
8387 /* BCM8727 PHY SECTION */
8388 /******************************************************************/
8390 static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy,
8391 struct link_params *params, u8 mode)
8393 struct bnx2x *bp = params->bp;
8394 u16 led_mode_bitmask = 0;
8395 u16 gpio_pins_bitmask = 0;
8397 /* Only NOC flavor requires to set the LED specifically */
8398 if (!(phy->flags & FLAGS_NOC))
8401 case LED_MODE_FRONT_PANEL_OFF:
8403 led_mode_bitmask = 0;
8404 gpio_pins_bitmask = 0x03;
8407 led_mode_bitmask = 0;
8408 gpio_pins_bitmask = 0x02;
8411 led_mode_bitmask = 0x60;
8412 gpio_pins_bitmask = 0x11;
8415 bnx2x_cl45_read(bp, phy,
8417 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
8420 val |= led_mode_bitmask;
8421 bnx2x_cl45_write(bp, phy,
8423 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
8425 bnx2x_cl45_read(bp, phy,
8427 MDIO_PMA_REG_8727_GPIO_CTRL,
8430 val |= gpio_pins_bitmask;
8431 bnx2x_cl45_write(bp, phy,
8433 MDIO_PMA_REG_8727_GPIO_CTRL,
8436 static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
8437 struct link_params *params) {
8438 u32 swap_val, swap_override;
8441 * The PHY reset is controlled by GPIO 1. Fake the port number
8442 * to cancel the swap done in set_gpio()
8444 struct bnx2x *bp = params->bp;
8445 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
8446 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
8447 port = (swap_val && swap_override) ^ 1;
8448 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
8449 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
8452 static int bnx2x_8727_config_init(struct bnx2x_phy *phy,
8453 struct link_params *params,
8454 struct link_vars *vars)
8457 u16 tmp1, val, mod_abs, tmp2;
8458 u16 rx_alarm_ctrl_val;
8460 struct bnx2x *bp = params->bp;
8461 /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
8463 bnx2x_wait_reset_complete(bp, phy, params);
8464 rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
8465 /* Should be 0x6 to enable XS on Tx side. */
8466 lasi_ctrl_val = 0x0006;
8468 DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
8470 bnx2x_cl45_write(bp, phy,
8471 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
8473 bnx2x_cl45_write(bp, phy,
8474 MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_ALARM_CTRL,
8476 bnx2x_cl45_write(bp, phy,
8477 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val);
8480 * Initially configure MOD_ABS to interrupt when module is
8483 bnx2x_cl45_read(bp, phy,
8484 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
8486 * Set EDC off by setting OPTXLOS signal input to low (bit 9).
8487 * When the EDC is off it locks onto a reference clock and avoids
8491 if (!(phy->flags & FLAGS_NOC))
8493 bnx2x_cl45_write(bp, phy,
8494 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
8497 /* Make MOD_ABS give interrupt on change */
8498 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
8501 if (phy->flags & FLAGS_NOC)
8505 * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
8506 * status which reflect SFP+ module over-current
8508 if (!(phy->flags & FLAGS_NOC))
8509 val &= 0xff8f; /* Reset bits 4-6 */
8510 bnx2x_cl45_write(bp, phy,
8511 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val);
8513 bnx2x_8727_power_module(bp, phy, 1);
8515 bnx2x_cl45_read(bp, phy,
8516 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
8518 bnx2x_cl45_read(bp, phy,
8519 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
8521 /* Set option 1G speed */
8522 if (phy->req_line_speed == SPEED_1000) {
8523 DP(NETIF_MSG_LINK, "Setting 1G force\n");
8524 bnx2x_cl45_write(bp, phy,
8525 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
8526 bnx2x_cl45_write(bp, phy,
8527 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
8528 bnx2x_cl45_read(bp, phy,
8529 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
8530 DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
8532 * Power down the XAUI until link is up in case of dual-media
8535 if (DUAL_MEDIA(params)) {
8536 bnx2x_cl45_read(bp, phy,
8538 MDIO_PMA_REG_8727_PCS_GP, &val);
8540 bnx2x_cl45_write(bp, phy,
8542 MDIO_PMA_REG_8727_PCS_GP, val);
8544 } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
8545 ((phy->speed_cap_mask &
8546 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
8547 ((phy->speed_cap_mask &
8548 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
8549 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
8551 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
8552 bnx2x_cl45_write(bp, phy,
8553 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
8554 bnx2x_cl45_write(bp, phy,
8555 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
8558 * Since the 8727 has only single reset pin, need to set the 10G
8559 * registers although it is default
8561 bnx2x_cl45_write(bp, phy,
8562 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
8564 bnx2x_cl45_write(bp, phy,
8565 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
8566 bnx2x_cl45_write(bp, phy,
8567 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
8568 bnx2x_cl45_write(bp, phy,
8569 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
8574 * Set 2-wire transfer rate of SFP+ module EEPROM
8575 * to 100Khz since some DACs(direct attached cables) do
8576 * not work at 400Khz.
8578 bnx2x_cl45_write(bp, phy,
8579 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
8582 /* Set TX PreEmphasis if needed */
8583 if ((params->feature_config_flags &
8584 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
8585 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
8586 phy->tx_preemphasis[0],
8587 phy->tx_preemphasis[1]);
8588 bnx2x_cl45_write(bp, phy,
8589 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
8590 phy->tx_preemphasis[0]);
8592 bnx2x_cl45_write(bp, phy,
8593 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
8594 phy->tx_preemphasis[1]);
8598 * If TX Laser is controlled by GPIO_0, do not let PHY go into low
8599 * power mode, if TX Laser is disabled
8601 tx_en_mode = REG_RD(bp, params->shmem_base +
8602 offsetof(struct shmem_region,
8603 dev_info.port_hw_config[params->port].sfp_ctrl))
8604 & PORT_HW_CFG_TX_LASER_MASK;
8606 if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
8608 DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
8609 bnx2x_cl45_read(bp, phy,
8610 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2);
8613 bnx2x_cl45_write(bp, phy,
8614 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
8620 static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
8621 struct link_params *params)
8623 struct bnx2x *bp = params->bp;
8624 u16 mod_abs, rx_alarm_status;
8625 u32 val = REG_RD(bp, params->shmem_base +
8626 offsetof(struct shmem_region, dev_info.
8627 port_feature_config[params->port].
8629 bnx2x_cl45_read(bp, phy,
8631 MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
8632 if (mod_abs & (1<<8)) {
8634 /* Module is absent */
8635 DP(NETIF_MSG_LINK, "MOD_ABS indication "
8636 "show module is absent\n");
8637 phy->media_type = ETH_PHY_NOT_PRESENT;
8639 * 1. Set mod_abs to detect next module
8641 * 2. Set EDC off by setting OPTXLOS signal input to low
8643 * When the EDC is off it locks onto a reference clock and
8644 * avoids becoming 'lost'.
8647 if (!(phy->flags & FLAGS_NOC))
8649 bnx2x_cl45_write(bp, phy,
8651 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
8654 * Clear RX alarm since it stays up as long as
8655 * the mod_abs wasn't changed
8657 bnx2x_cl45_read(bp, phy,
8659 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
8662 /* Module is present */
8663 DP(NETIF_MSG_LINK, "MOD_ABS indication "
8664 "show module is present\n");
8666 * First disable transmitter, and if the module is ok, the
8667 * module_detection will enable it
8668 * 1. Set mod_abs to detect next module absent event ( bit 8)
8669 * 2. Restore the default polarity of the OPRXLOS signal and
8670 * this signal will then correctly indicate the presence or
8671 * absence of the Rx signal. (bit 9)
8674 if (!(phy->flags & FLAGS_NOC))
8676 bnx2x_cl45_write(bp, phy,
8678 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
8681 * Clear RX alarm since it stays up as long as the mod_abs
8682 * wasn't changed. This is need to be done before calling the
8683 * module detection, otherwise it will clear* the link update
8686 bnx2x_cl45_read(bp, phy,
8688 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
8691 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8692 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
8693 bnx2x_sfp_set_transmitter(params, phy, 0);
8695 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
8696 bnx2x_sfp_module_detection(phy, params);
8698 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
8701 DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
8703 /* No need to check link status in case of module plugged in/out */
8706 static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
8707 struct link_params *params,
8708 struct link_vars *vars)
8711 struct bnx2x *bp = params->bp;
8712 u8 link_up = 0, oc_port = params->port;
8713 u16 link_status = 0;
8714 u16 rx_alarm_status, lasi_ctrl, val1;
8716 /* If PHY is not initialized, do not check link status */
8717 bnx2x_cl45_read(bp, phy,
8718 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
8723 /* Check the LASI on Rx */
8724 bnx2x_cl45_read(bp, phy,
8725 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
8727 vars->line_speed = 0;
8728 DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status);
8730 bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_REG_TX_ALARM,
8731 MDIO_PMA_REG_TX_ALARM_CTRL);
8733 bnx2x_cl45_read(bp, phy,
8734 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
8736 DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
8739 bnx2x_cl45_read(bp, phy,
8740 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
8743 * If a module is present and there is need to check
8746 if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
8747 /* Check over-current using 8727 GPIO0 input*/
8748 bnx2x_cl45_read(bp, phy,
8749 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
8752 if ((val1 & (1<<8)) == 0) {
8753 if (!CHIP_IS_E1x(bp))
8754 oc_port = BP_PATH(bp) + (params->port << 1);
8755 DP(NETIF_MSG_LINK, "8727 Power fault has been detected"
8756 " on port %d\n", oc_port);
8757 netdev_err(bp->dev, "Error: Power fault on Port %d has"
8758 " been detected and the power to "
8759 "that SFP+ module has been removed"
8760 " to prevent failure of the card."
8761 " Please remove the SFP+ module and"
8762 " restart the system to clear this"
8765 /* Disable all RX_ALARMs except for mod_abs */
8766 bnx2x_cl45_write(bp, phy,
8768 MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5));
8770 bnx2x_cl45_read(bp, phy,
8772 MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
8773 /* Wait for module_absent_event */
8775 bnx2x_cl45_write(bp, phy,
8777 MDIO_PMA_REG_PHY_IDENTIFIER, val1);
8778 /* Clear RX alarm */
8779 bnx2x_cl45_read(bp, phy,
8781 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
8784 } /* Over current check */
8786 /* When module absent bit is set, check module */
8787 if (rx_alarm_status & (1<<5)) {
8788 bnx2x_8727_handle_mod_abs(phy, params);
8789 /* Enable all mod_abs and link detection bits */
8790 bnx2x_cl45_write(bp, phy,
8791 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
8794 DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n");
8795 bnx2x_8727_specific_func(phy, params, ENABLE_TX);
8796 /* If transmitter is disabled, ignore false link up indication */
8797 bnx2x_cl45_read(bp, phy,
8798 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
8799 if (val1 & (1<<15)) {
8800 DP(NETIF_MSG_LINK, "Tx is disabled\n");
8804 bnx2x_cl45_read(bp, phy,
8806 MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
8809 * Bits 0..2 --> speed detected,
8810 * Bits 13..15--> link is down
8812 if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
8814 vars->line_speed = SPEED_10000;
8815 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
8817 } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
8819 vars->line_speed = SPEED_1000;
8820 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
8824 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
8828 /* Capture 10G link fault. */
8829 if (vars->line_speed == SPEED_10000) {
8830 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
8831 MDIO_PMA_REG_TX_ALARM, &val1);
8833 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
8834 MDIO_PMA_REG_TX_ALARM, &val1);
8836 if (val1 & (1<<0)) {
8837 vars->fault_detected = 1;
8842 bnx2x_ext_phy_resolve_fc(phy, params, vars);
8843 vars->duplex = DUPLEX_FULL;
8844 DP(NETIF_MSG_LINK, "duplex = 0x%x\n", vars->duplex);
8847 if ((DUAL_MEDIA(params)) &&
8848 (phy->req_line_speed == SPEED_1000)) {
8849 bnx2x_cl45_read(bp, phy,
8851 MDIO_PMA_REG_8727_PCS_GP, &val1);
8853 * In case of dual-media board and 1G, power up the XAUI side,
8854 * otherwise power it down. For 10G it is done automatically
8860 bnx2x_cl45_write(bp, phy,
8862 MDIO_PMA_REG_8727_PCS_GP, val1);
8867 static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
8868 struct link_params *params)
8870 struct bnx2x *bp = params->bp;
8871 /* Disable Transmitter */
8872 bnx2x_sfp_set_transmitter(params, phy, 0);
8874 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0);
8878 /******************************************************************/
8879 /* BCM8481/BCM84823/BCM84833 PHY SECTION */
8880 /******************************************************************/
8881 static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
8882 struct link_params *params)
8884 u16 val, fw_ver1, fw_ver2, cnt;
8886 struct bnx2x *bp = params->bp;
8888 port = params->port;
8890 /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
8891 /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
8892 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
8893 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
8894 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
8895 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
8896 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
8898 for (cnt = 0; cnt < 100; cnt++) {
8899 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
8905 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n");
8906 bnx2x_save_spirom_version(bp, port, 0,
8912 /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
8913 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
8914 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
8915 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
8916 for (cnt = 0; cnt < 100; cnt++) {
8917 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
8923 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n");
8924 bnx2x_save_spirom_version(bp, port, 0,
8929 /* lower 16 bits of the register SPI_FW_STATUS */
8930 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
8931 /* upper 16 bits of register SPI_FW_STATUS */
8932 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
8934 bnx2x_save_spirom_version(bp, port, (fw_ver2<<16) | fw_ver1,
8938 static void bnx2x_848xx_set_led(struct bnx2x *bp,
8939 struct bnx2x_phy *phy)
8943 /* PHYC_CTL_LED_CTL */
8944 bnx2x_cl45_read(bp, phy,
8946 MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
8950 bnx2x_cl45_write(bp, phy,
8952 MDIO_PMA_REG_8481_LINK_SIGNAL, val);
8954 bnx2x_cl45_write(bp, phy,
8956 MDIO_PMA_REG_8481_LED1_MASK,
8959 bnx2x_cl45_write(bp, phy,
8961 MDIO_PMA_REG_8481_LED2_MASK,
8964 /* Select activity source by Tx and Rx, as suggested by PHY AE */
8965 bnx2x_cl45_write(bp, phy,
8967 MDIO_PMA_REG_8481_LED3_MASK,
8970 /* Select the closest activity blink rate to that in 10/100/1000 */
8971 bnx2x_cl45_write(bp, phy,
8973 MDIO_PMA_REG_8481_LED3_BLINK,
8976 bnx2x_cl45_read(bp, phy,
8978 MDIO_PMA_REG_84823_CTL_LED_CTL_1, &val);
8979 val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/
8981 bnx2x_cl45_write(bp, phy,
8983 MDIO_PMA_REG_84823_CTL_LED_CTL_1, val);
8985 /* 'Interrupt Mask' */
8986 bnx2x_cl45_write(bp, phy,
8991 static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
8992 struct link_params *params,
8993 struct link_vars *vars)
8995 struct bnx2x *bp = params->bp;
8996 u16 autoneg_val, an_1000_val, an_10_100_val;
8997 u16 tmp_req_line_speed;
8999 tmp_req_line_speed = phy->req_line_speed;
9000 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
9001 if (phy->req_line_speed == SPEED_10000)
9002 phy->req_line_speed = SPEED_AUTO_NEG;
9005 * This phy uses the NIG latch mechanism since link indication
9006 * arrives through its LED4 and not via its LASI signal, so we
9007 * get steady signal instead of clear on read
9009 bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
9010 1 << NIG_LATCH_BC_ENABLE_MI_INT);
9012 bnx2x_cl45_write(bp, phy,
9013 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
9015 bnx2x_848xx_set_led(bp, phy);
9017 /* set 1000 speed advertisement */
9018 bnx2x_cl45_read(bp, phy,
9019 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
9022 bnx2x_ext_phy_set_pause(params, phy, vars);
9023 bnx2x_cl45_read(bp, phy,
9025 MDIO_AN_REG_8481_LEGACY_AN_ADV,
9027 bnx2x_cl45_read(bp, phy,
9028 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
9030 /* Disable forced speed */
9031 autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
9032 an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
9034 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9035 (phy->speed_cap_mask &
9036 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
9037 (phy->req_line_speed == SPEED_1000)) {
9038 an_1000_val |= (1<<8);
9039 autoneg_val |= (1<<9 | 1<<12);
9040 if (phy->req_duplex == DUPLEX_FULL)
9041 an_1000_val |= (1<<9);
9042 DP(NETIF_MSG_LINK, "Advertising 1G\n");
9044 an_1000_val &= ~((1<<8) | (1<<9));
9046 bnx2x_cl45_write(bp, phy,
9047 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
9050 /* set 10 speed advertisement */
9051 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9052 (phy->speed_cap_mask &
9053 (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
9054 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
9055 an_10_100_val |= (1<<7);
9056 /* Enable autoneg and restart autoneg for legacy speeds */
9057 autoneg_val |= (1<<9 | 1<<12);
9059 if (phy->req_duplex == DUPLEX_FULL)
9060 an_10_100_val |= (1<<8);
9061 DP(NETIF_MSG_LINK, "Advertising 100M\n");
9063 /* set 10 speed advertisement */
9064 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9065 (phy->speed_cap_mask &
9066 (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
9067 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
9068 an_10_100_val |= (1<<5);
9069 autoneg_val |= (1<<9 | 1<<12);
9070 if (phy->req_duplex == DUPLEX_FULL)
9071 an_10_100_val |= (1<<6);
9072 DP(NETIF_MSG_LINK, "Advertising 10M\n");
9075 /* Only 10/100 are allowed to work in FORCE mode */
9076 if (phy->req_line_speed == SPEED_100) {
9077 autoneg_val |= (1<<13);
9078 /* Enabled AUTO-MDIX when autoneg is disabled */
9079 bnx2x_cl45_write(bp, phy,
9080 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
9081 (1<<15 | 1<<9 | 7<<0));
9082 DP(NETIF_MSG_LINK, "Setting 100M force\n");
9084 if (phy->req_line_speed == SPEED_10) {
9085 /* Enabled AUTO-MDIX when autoneg is disabled */
9086 bnx2x_cl45_write(bp, phy,
9087 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
9088 (1<<15 | 1<<9 | 7<<0));
9089 DP(NETIF_MSG_LINK, "Setting 10M force\n");
9092 bnx2x_cl45_write(bp, phy,
9093 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
9096 if (phy->req_duplex == DUPLEX_FULL)
9097 autoneg_val |= (1<<8);
9099 bnx2x_cl45_write(bp, phy,
9101 MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
9103 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9104 (phy->speed_cap_mask &
9105 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
9106 (phy->req_line_speed == SPEED_10000)) {
9107 DP(NETIF_MSG_LINK, "Advertising 10G\n");
9108 /* Restart autoneg for 10G*/
9110 bnx2x_cl45_write(bp, phy,
9111 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
9113 } else if (phy->req_line_speed != SPEED_10 &&
9114 phy->req_line_speed != SPEED_100) {
9115 bnx2x_cl45_write(bp, phy,
9117 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
9120 /* Save spirom version */
9121 bnx2x_save_848xx_spirom_version(phy, params);
9123 phy->req_line_speed = tmp_req_line_speed;
9128 static int bnx2x_8481_config_init(struct bnx2x_phy *phy,
9129 struct link_params *params,
9130 struct link_vars *vars)
9132 struct bnx2x *bp = params->bp;
9133 /* Restore normal power mode*/
9134 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
9135 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
9138 bnx2x_ext_phy_hw_reset(bp, params->port);
9139 bnx2x_wait_reset_complete(bp, phy, params);
9141 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
9142 return bnx2x_848xx_cmn_config_init(phy, params, vars);
9146 #define PHY84833_HDSHK_WAIT 300
9147 static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy,
9148 struct link_params *params,
9149 struct link_vars *vars)
9154 struct bnx2x *bp = params->bp;
9158 /* Write CMD_OPEN_OVERRIDE to STATUS reg */
9159 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9160 MDIO_84833_TOP_CFG_SCRATCH_REG2,
9161 PHY84833_CMD_OPEN_OVERRIDE);
9162 for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
9163 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9164 MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
9165 if (val == PHY84833_CMD_OPEN_FOR_CMDS)
9169 if (idx >= PHY84833_HDSHK_WAIT) {
9170 DP(NETIF_MSG_LINK, "Pairswap: FW not ready.\n");
9174 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9175 MDIO_84833_TOP_CFG_SCRATCH_REG4,
9177 /* Issue pair swap command */
9178 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9179 MDIO_84833_TOP_CFG_SCRATCH_REG0,
9180 PHY84833_DIAG_CMD_PAIR_SWAP_CHANGE);
9181 for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
9182 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9183 MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
9184 if ((val == PHY84833_CMD_COMPLETE_PASS) ||
9185 (val == PHY84833_CMD_COMPLETE_ERROR))
9189 if ((idx >= PHY84833_HDSHK_WAIT) ||
9190 (val == PHY84833_CMD_COMPLETE_ERROR)) {
9191 DP(NETIF_MSG_LINK, "Pairswap: override failed.\n");
9194 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9195 MDIO_84833_TOP_CFG_SCRATCH_REG2,
9196 PHY84833_CMD_CLEAR_COMPLETE);
9197 DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data);
9202 static int bnx2x_84833_common_init_phy(struct bnx2x *bp,
9203 u32 shmem_base_path[],
9209 if (CHIP_IS_E3(bp)) {
9210 /* Assume that these will be GPIOs, not EPIOs. */
9211 for (idx = 0; idx < 2; idx++) {
9212 /* Map config param to register bit. */
9213 reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] +
9214 offsetof(struct shmem_region,
9215 dev_info.port_hw_config[0].e3_cmn_pin_cfg));
9216 reset_pin[idx] = (reset_pin[idx] &
9217 PORT_HW_CFG_E3_PHY_RESET_MASK) >>
9218 PORT_HW_CFG_E3_PHY_RESET_SHIFT;
9219 reset_pin[idx] -= PIN_CFG_GPIO0_P0;
9220 reset_pin[idx] = (1 << reset_pin[idx]);
9222 reset_gpios = (u8)(reset_pin[0] | reset_pin[1]);
9224 /* E2, look from diff place of shmem. */
9225 for (idx = 0; idx < 2; idx++) {
9226 reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] +
9227 offsetof(struct shmem_region,
9228 dev_info.port_hw_config[0].default_cfg));
9229 reset_pin[idx] &= PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK;
9230 reset_pin[idx] -= PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0;
9231 reset_pin[idx] >>= PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT;
9232 reset_pin[idx] = (1 << reset_pin[idx]);
9234 reset_gpios = (u8)(reset_pin[0] | reset_pin[1]);
9237 bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
9239 bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH);
9241 DP(NETIF_MSG_LINK, "84833 reset pulse on pin values 0x%x\n",
9247 static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
9248 struct link_params *params,
9249 struct link_vars *vars)
9251 struct bnx2x *bp = params->bp;
9252 u8 port, initialize = 1;
9255 u32 actual_phy_selection, cms_enable;
9260 if (!(CHIP_IS_E1(bp)))
9263 port = params->port;
9265 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
9266 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
9267 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
9270 bnx2x_cl45_write(bp, phy,
9272 MDIO_PMA_REG_CTRL, 0x8000);
9275 bnx2x_wait_reset_complete(bp, phy, params);
9276 /* Wait for GPHY to come out of reset */
9279 /* Bring PHY out of super isolate mode */
9280 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
9281 bnx2x_cl45_read(bp, phy,
9283 MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
9284 val &= ~MDIO_84833_SUPER_ISOLATE;
9285 bnx2x_cl45_write(bp, phy,
9287 MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
9288 bnx2x_wait_reset_complete(bp, phy, params);
9291 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
9292 bnx2x_84833_pair_swap_cfg(phy, params, vars);
9295 * BCM84823 requires that XGXS links up first @ 10G for normal behavior
9297 temp = vars->line_speed;
9298 vars->line_speed = SPEED_10000;
9299 bnx2x_set_autoneg(¶ms->phy[INT_PHY], params, vars, 0);
9300 bnx2x_program_serdes(¶ms->phy[INT_PHY], params, vars);
9301 vars->line_speed = temp;
9303 /* Set dual-media configuration according to configuration */
9305 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9306 MDIO_CTL_REG_84823_MEDIA, &val);
9307 val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
9308 MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
9309 MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
9310 MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
9311 MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
9313 if (CHIP_IS_E3(bp)) {
9314 val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
9315 MDIO_CTL_REG_84823_MEDIA_LINE_MASK);
9317 val |= (MDIO_CTL_REG_84823_CTRL_MAC_XFI |
9318 MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L);
9321 actual_phy_selection = bnx2x_phy_selection(params);
9323 switch (actual_phy_selection) {
9324 case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
9325 /* Do nothing. Essentially this is like the priority copper */
9327 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
9328 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
9330 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
9331 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
9333 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
9334 /* Do nothing here. The first PHY won't be initialized at all */
9336 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
9337 val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
9341 if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000)
9342 val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
9344 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9345 MDIO_CTL_REG_84823_MEDIA, val);
9346 DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
9347 params->multi_phy_config, val);
9350 rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
9352 bnx2x_save_848xx_spirom_version(phy, params);
9353 cms_enable = REG_RD(bp, params->shmem_base +
9354 offsetof(struct shmem_region,
9355 dev_info.port_hw_config[params->port].default_cfg)) &
9356 PORT_HW_CFG_ENABLE_CMS_MASK;
9358 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9359 MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
9361 val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
9363 val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
9364 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9365 MDIO_CTL_REG_84823_USER_CTRL_REG, val);
9371 static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
9372 struct link_params *params,
9373 struct link_vars *vars)
9375 struct bnx2x *bp = params->bp;
9376 u16 val, val1, val2;
9380 /* Check 10G-BaseT link status */
9381 /* Check PMD signal ok */
9382 bnx2x_cl45_read(bp, phy,
9383 MDIO_AN_DEVAD, 0xFFFA, &val1);
9384 bnx2x_cl45_read(bp, phy,
9385 MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
9387 DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
9389 /* Check link 10G */
9390 if (val2 & (1<<11)) {
9391 vars->line_speed = SPEED_10000;
9392 vars->duplex = DUPLEX_FULL;
9394 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
9395 } else { /* Check Legacy speed link */
9396 u16 legacy_status, legacy_speed;
9398 /* Enable expansion register 0x42 (Operation mode status) */
9399 bnx2x_cl45_write(bp, phy,
9401 MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
9403 /* Get legacy speed operation status */
9404 bnx2x_cl45_read(bp, phy,
9406 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
9409 DP(NETIF_MSG_LINK, "Legacy speed status"
9410 " = 0x%x\n", legacy_status);
9411 link_up = ((legacy_status & (1<<11)) == (1<<11));
9413 legacy_speed = (legacy_status & (3<<9));
9414 if (legacy_speed == (0<<9))
9415 vars->line_speed = SPEED_10;
9416 else if (legacy_speed == (1<<9))
9417 vars->line_speed = SPEED_100;
9418 else if (legacy_speed == (2<<9))
9419 vars->line_speed = SPEED_1000;
9420 else /* Should not happen */
9421 vars->line_speed = 0;
9423 if (legacy_status & (1<<8))
9424 vars->duplex = DUPLEX_FULL;
9426 vars->duplex = DUPLEX_HALF;
9428 DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
9429 " is_duplex_full= %d\n", vars->line_speed,
9430 (vars->duplex == DUPLEX_FULL));
9431 /* Check legacy speed AN resolution */
9432 bnx2x_cl45_read(bp, phy,
9434 MDIO_AN_REG_8481_LEGACY_MII_STATUS,
9437 vars->link_status |=
9438 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
9439 bnx2x_cl45_read(bp, phy,
9441 MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
9443 if ((val & (1<<0)) == 0)
9444 vars->link_status |=
9445 LINK_STATUS_PARALLEL_DETECTION_USED;
9449 DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n",
9451 bnx2x_ext_phy_resolve_fc(phy, params, vars);
9458 static int bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
9462 spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
9463 status = bnx2x_format_ver(spirom_ver, str, len);
9467 static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
9468 struct link_params *params)
9470 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
9471 MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
9472 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
9473 MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
9476 static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
9477 struct link_params *params)
9479 bnx2x_cl45_write(params->bp, phy,
9480 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
9481 bnx2x_cl45_write(params->bp, phy,
9482 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
9485 static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
9486 struct link_params *params)
9488 struct bnx2x *bp = params->bp;
9492 if (!(CHIP_IS_E1(bp)))
9495 port = params->port;
9497 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
9498 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
9499 MISC_REGISTERS_GPIO_OUTPUT_LOW,
9502 bnx2x_cl45_read(bp, phy,
9505 /* Put to low power mode on newer FW */
9506 if ((val16 & 0x303f) > 0x1009)
9507 bnx2x_cl45_write(bp, phy,
9509 MDIO_PMA_REG_CTRL, 0x800);
9513 static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
9514 struct link_params *params, u8 mode)
9516 struct bnx2x *bp = params->bp;
9520 if (!(CHIP_IS_E1(bp)))
9523 port = params->port;
9528 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", port);
9530 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
9531 SHARED_HW_CFG_LED_EXTPHY1) {
9534 bnx2x_cl45_write(bp, phy,
9536 MDIO_PMA_REG_8481_LED1_MASK,
9539 bnx2x_cl45_write(bp, phy,
9541 MDIO_PMA_REG_8481_LED2_MASK,
9544 bnx2x_cl45_write(bp, phy,
9546 MDIO_PMA_REG_8481_LED3_MASK,
9549 bnx2x_cl45_write(bp, phy,
9551 MDIO_PMA_REG_8481_LED5_MASK,
9555 bnx2x_cl45_write(bp, phy,
9557 MDIO_PMA_REG_8481_LED1_MASK,
9561 case LED_MODE_FRONT_PANEL_OFF:
9563 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
9566 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
9567 SHARED_HW_CFG_LED_EXTPHY1) {
9570 bnx2x_cl45_write(bp, phy,
9572 MDIO_PMA_REG_8481_LED1_MASK,
9575 bnx2x_cl45_write(bp, phy,
9577 MDIO_PMA_REG_8481_LED2_MASK,
9580 bnx2x_cl45_write(bp, phy,
9582 MDIO_PMA_REG_8481_LED3_MASK,
9585 bnx2x_cl45_write(bp, phy,
9587 MDIO_PMA_REG_8481_LED5_MASK,
9591 bnx2x_cl45_write(bp, phy,
9593 MDIO_PMA_REG_8481_LED1_MASK,
9599 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", port);
9601 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
9602 SHARED_HW_CFG_LED_EXTPHY1) {
9603 /* Set control reg */
9604 bnx2x_cl45_read(bp, phy,
9606 MDIO_PMA_REG_8481_LINK_SIGNAL,
9611 bnx2x_cl45_write(bp, phy,
9613 MDIO_PMA_REG_8481_LINK_SIGNAL,
9617 bnx2x_cl45_write(bp, phy,
9619 MDIO_PMA_REG_8481_LED1_MASK,
9622 bnx2x_cl45_write(bp, phy,
9624 MDIO_PMA_REG_8481_LED2_MASK,
9627 bnx2x_cl45_write(bp, phy,
9629 MDIO_PMA_REG_8481_LED3_MASK,
9632 bnx2x_cl45_write(bp, phy,
9634 MDIO_PMA_REG_8481_LED5_MASK,
9637 bnx2x_cl45_write(bp, phy,
9639 MDIO_PMA_REG_8481_LED1_MASK,
9646 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", port);
9648 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
9649 SHARED_HW_CFG_LED_EXTPHY1) {
9651 /* Set control reg */
9652 bnx2x_cl45_read(bp, phy,
9654 MDIO_PMA_REG_8481_LINK_SIGNAL,
9658 MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
9659 >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) {
9660 DP(NETIF_MSG_LINK, "Setting LINK_SIGNAL\n");
9661 bnx2x_cl45_write(bp, phy,
9663 MDIO_PMA_REG_8481_LINK_SIGNAL,
9668 bnx2x_cl45_write(bp, phy,
9670 MDIO_PMA_REG_8481_LED1_MASK,
9673 bnx2x_cl45_write(bp, phy,
9675 MDIO_PMA_REG_8481_LED2_MASK,
9678 bnx2x_cl45_write(bp, phy,
9680 MDIO_PMA_REG_8481_LED3_MASK,
9683 bnx2x_cl45_write(bp, phy,
9685 MDIO_PMA_REG_8481_LED5_MASK,
9689 bnx2x_cl45_write(bp, phy,
9691 MDIO_PMA_REG_8481_LED1_MASK,
9694 /* Tell LED3 to blink on source */
9695 bnx2x_cl45_read(bp, phy,
9697 MDIO_PMA_REG_8481_LINK_SIGNAL,
9700 val |= (1<<6); /* A83B[8:6]= 1 */
9701 bnx2x_cl45_write(bp, phy,
9703 MDIO_PMA_REG_8481_LINK_SIGNAL,
9710 * This is a workaround for E3+84833 until autoneg
9711 * restart is fixed in f/w
9713 if (CHIP_IS_E3(bp)) {
9714 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
9715 MDIO_WC_REG_GP2_STATUS_GP_2_1, &val);
9719 /******************************************************************/
9720 /* 54616S PHY SECTION */
9721 /******************************************************************/
9722 static int bnx2x_54616s_config_init(struct bnx2x_phy *phy,
9723 struct link_params *params,
9724 struct link_vars *vars)
9726 struct bnx2x *bp = params->bp;
9728 u16 autoneg_val, an_1000_val, an_10_100_val, fc_val, temp;
9731 DP(NETIF_MSG_LINK, "54616S cfg init\n");
9732 usleep_range(1000, 1000);
9734 /* This works with E3 only, no need to check the chip
9735 before determining the port. */
9736 port = params->port;
9738 cfg_pin = (REG_RD(bp, params->shmem_base +
9739 offsetof(struct shmem_region,
9740 dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
9741 PORT_HW_CFG_E3_PHY_RESET_MASK) >>
9742 PORT_HW_CFG_E3_PHY_RESET_SHIFT;
9744 /* Drive pin high to bring the GPHY out of reset. */
9745 bnx2x_set_cfg_pin(bp, cfg_pin, 1);
9747 /* wait for GPHY to reset */
9751 bnx2x_cl22_write(bp, phy,
9752 MDIO_PMA_REG_CTRL, 0x8000);
9753 bnx2x_wait_reset_complete(bp, phy, params);
9755 /*wait for GPHY to reset */
9758 /* Configure LED4: set to INTR (0x6). */
9759 /* Accessing shadow register 0xe. */
9760 bnx2x_cl22_write(bp, phy,
9761 MDIO_REG_GPHY_SHADOW,
9762 MDIO_REG_GPHY_SHADOW_LED_SEL2);
9763 bnx2x_cl22_read(bp, phy,
9764 MDIO_REG_GPHY_SHADOW,
9766 temp &= ~(0xf << 4);
9768 bnx2x_cl22_write(bp, phy,
9769 MDIO_REG_GPHY_SHADOW,
9770 MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
9771 /* Configure INTR based on link status change. */
9772 bnx2x_cl22_write(bp, phy,
9774 ~MDIO_REG_INTR_MASK_LINK_STATUS);
9776 /* Flip the signal detect polarity (set 0x1c.0x1e[8]). */
9777 bnx2x_cl22_write(bp, phy,
9778 MDIO_REG_GPHY_SHADOW,
9779 MDIO_REG_GPHY_SHADOW_AUTO_DET_MED);
9780 bnx2x_cl22_read(bp, phy,
9781 MDIO_REG_GPHY_SHADOW,
9783 temp |= MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD;
9784 bnx2x_cl22_write(bp, phy,
9785 MDIO_REG_GPHY_SHADOW,
9786 MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
9789 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
9790 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
9792 if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
9793 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC)
9794 fc_val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
9796 if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
9797 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
9798 fc_val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
9800 /* read all advertisement */
9801 bnx2x_cl22_read(bp, phy,
9805 bnx2x_cl22_read(bp, phy,
9809 bnx2x_cl22_read(bp, phy,
9813 /* Disable forced speed */
9814 autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
9815 an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8) | (1<<10) |
9818 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9819 (phy->speed_cap_mask &
9820 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
9821 (phy->req_line_speed == SPEED_1000)) {
9822 an_1000_val |= (1<<8);
9823 autoneg_val |= (1<<9 | 1<<12);
9824 if (phy->req_duplex == DUPLEX_FULL)
9825 an_1000_val |= (1<<9);
9826 DP(NETIF_MSG_LINK, "Advertising 1G\n");
9828 an_1000_val &= ~((1<<8) | (1<<9));
9830 bnx2x_cl22_write(bp, phy,
9833 bnx2x_cl22_read(bp, phy,
9837 /* set 100 speed advertisement */
9838 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9839 (phy->speed_cap_mask &
9840 (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
9841 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
9842 an_10_100_val |= (1<<7);
9843 /* Enable autoneg and restart autoneg for legacy speeds */
9844 autoneg_val |= (1<<9 | 1<<12);
9846 if (phy->req_duplex == DUPLEX_FULL)
9847 an_10_100_val |= (1<<8);
9848 DP(NETIF_MSG_LINK, "Advertising 100M\n");
9851 /* set 10 speed advertisement */
9852 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9853 (phy->speed_cap_mask &
9854 (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
9855 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
9856 an_10_100_val |= (1<<5);
9857 autoneg_val |= (1<<9 | 1<<12);
9858 if (phy->req_duplex == DUPLEX_FULL)
9859 an_10_100_val |= (1<<6);
9860 DP(NETIF_MSG_LINK, "Advertising 10M\n");
9863 /* Only 10/100 are allowed to work in FORCE mode */
9864 if (phy->req_line_speed == SPEED_100) {
9865 autoneg_val |= (1<<13);
9866 /* Enabled AUTO-MDIX when autoneg is disabled */
9867 bnx2x_cl22_write(bp, phy,
9869 (1<<15 | 1<<9 | 7<<0));
9870 DP(NETIF_MSG_LINK, "Setting 100M force\n");
9872 if (phy->req_line_speed == SPEED_10) {
9873 /* Enabled AUTO-MDIX when autoneg is disabled */
9874 bnx2x_cl22_write(bp, phy,
9876 (1<<15 | 1<<9 | 7<<0));
9877 DP(NETIF_MSG_LINK, "Setting 10M force\n");
9880 bnx2x_cl22_write(bp, phy,
9882 an_10_100_val | fc_val);
9884 if (phy->req_duplex == DUPLEX_FULL)
9885 autoneg_val |= (1<<8);
9887 bnx2x_cl22_write(bp, phy,
9888 MDIO_PMA_REG_CTRL, autoneg_val);
9893 static void bnx2x_54616s_set_link_led(struct bnx2x_phy *phy,
9894 struct link_params *params, u8 mode)
9896 struct bnx2x *bp = params->bp;
9897 DP(NETIF_MSG_LINK, "54616S set link led (mode=%x)\n", mode);
9899 case LED_MODE_FRONT_PANEL_OFF:
9909 static void bnx2x_54616s_link_reset(struct bnx2x_phy *phy,
9910 struct link_params *params)
9912 struct bnx2x *bp = params->bp;
9916 /* This works with E3 only, no need to check the chip
9917 before determining the port. */
9918 port = params->port;
9919 cfg_pin = (REG_RD(bp, params->shmem_base +
9920 offsetof(struct shmem_region,
9921 dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
9922 PORT_HW_CFG_E3_PHY_RESET_MASK) >>
9923 PORT_HW_CFG_E3_PHY_RESET_SHIFT;
9925 /* Drive pin low to put GPHY in reset. */
9926 bnx2x_set_cfg_pin(bp, cfg_pin, 0);
9929 static u8 bnx2x_54616s_read_status(struct bnx2x_phy *phy,
9930 struct link_params *params,
9931 struct link_vars *vars)
9933 struct bnx2x *bp = params->bp;
9936 u16 legacy_status, legacy_speed;
9938 /* Get speed operation status */
9939 bnx2x_cl22_read(bp, phy,
9942 DP(NETIF_MSG_LINK, "54616S read_status: 0x%x\n", legacy_status);
9944 /* Read status to clear the PHY interrupt. */
9945 bnx2x_cl22_read(bp, phy,
9946 MDIO_REG_INTR_STATUS,
9949 link_up = ((legacy_status & (1<<2)) == (1<<2));
9952 legacy_speed = (legacy_status & (7<<8));
9953 if (legacy_speed == (7<<8)) {
9954 vars->line_speed = SPEED_1000;
9955 vars->duplex = DUPLEX_FULL;
9956 } else if (legacy_speed == (6<<8)) {
9957 vars->line_speed = SPEED_1000;
9958 vars->duplex = DUPLEX_HALF;
9959 } else if (legacy_speed == (5<<8)) {
9960 vars->line_speed = SPEED_100;
9961 vars->duplex = DUPLEX_FULL;
9963 /* Omitting 100Base-T4 for now */
9964 else if (legacy_speed == (3<<8)) {
9965 vars->line_speed = SPEED_100;
9966 vars->duplex = DUPLEX_HALF;
9967 } else if (legacy_speed == (2<<8)) {
9968 vars->line_speed = SPEED_10;
9969 vars->duplex = DUPLEX_FULL;
9970 } else if (legacy_speed == (1<<8)) {
9971 vars->line_speed = SPEED_10;
9972 vars->duplex = DUPLEX_HALF;
9973 } else /* Should not happen */
9974 vars->line_speed = 0;
9976 DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
9977 " is_duplex_full= %d\n", vars->line_speed,
9978 (vars->duplex == DUPLEX_FULL));
9980 /* Check legacy speed AN resolution */
9981 bnx2x_cl22_read(bp, phy,
9985 vars->link_status |=
9986 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
9987 bnx2x_cl22_read(bp, phy,
9990 if ((val & (1<<0)) == 0)
9991 vars->link_status |=
9992 LINK_STATUS_PARALLEL_DETECTION_USED;
9994 DP(NETIF_MSG_LINK, "BCM54616S: link speed is %d\n",
9996 bnx2x_ext_phy_resolve_fc(phy, params, vars);
10001 static void bnx2x_54616s_config_loopback(struct bnx2x_phy *phy,
10002 struct link_params *params)
10004 struct bnx2x *bp = params->bp;
10006 u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
10008 DP(NETIF_MSG_LINK, "2PMA/PMD ext_phy_loopback: 54616s\n");
10010 /* Enable master/slave manual mmode and set to master */
10011 /* mii write 9 [bits set 11 12] */
10012 bnx2x_cl22_write(bp, phy, 0x09, 3<<11);
10014 /* forced 1G and disable autoneg */
10015 /* set val [mii read 0] */
10016 /* set val [expr $val & [bits clear 6 12 13]] */
10017 /* set val [expr $val | [bits set 6 8]] */
10018 /* mii write 0 $val */
10019 bnx2x_cl22_read(bp, phy, 0x00, &val);
10020 val &= ~((1<<6) | (1<<12) | (1<<13));
10021 val |= (1<<6) | (1<<8);
10022 bnx2x_cl22_write(bp, phy, 0x00, val);
10024 /* Set external loopback and Tx using 6dB coding */
10025 /* mii write 0x18 7 */
10026 /* set val [mii read 0x18] */
10027 /* mii write 0x18 [expr $val | [bits set 10 15]] */
10028 bnx2x_cl22_write(bp, phy, 0x18, 7);
10029 bnx2x_cl22_read(bp, phy, 0x18, &val);
10030 bnx2x_cl22_write(bp, phy, 0x18, val | (1<<10) | (1<<15));
10032 /* This register opens the gate for the UMAC despite its name */
10033 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
10036 * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
10037 * length used by the MAC receive logic to check frames.
10039 REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
10042 /******************************************************************/
10043 /* SFX7101 PHY SECTION */
10044 /******************************************************************/
10045 static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
10046 struct link_params *params)
10048 struct bnx2x *bp = params->bp;
10049 /* SFX7101_XGXS_TEST1 */
10050 bnx2x_cl45_write(bp, phy,
10051 MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
10054 static int bnx2x_7101_config_init(struct bnx2x_phy *phy,
10055 struct link_params *params,
10056 struct link_vars *vars)
10058 u16 fw_ver1, fw_ver2, val;
10059 struct bnx2x *bp = params->bp;
10060 DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
10062 /* Restore normal power mode*/
10063 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
10064 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
10066 bnx2x_ext_phy_hw_reset(bp, params->port);
10067 bnx2x_wait_reset_complete(bp, phy, params);
10069 bnx2x_cl45_write(bp, phy,
10070 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1);
10071 DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
10072 bnx2x_cl45_write(bp, phy,
10073 MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
10075 bnx2x_ext_phy_set_pause(params, phy, vars);
10076 /* Restart autoneg */
10077 bnx2x_cl45_read(bp, phy,
10078 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
10080 bnx2x_cl45_write(bp, phy,
10081 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
10083 /* Save spirom version */
10084 bnx2x_cl45_read(bp, phy,
10085 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
10087 bnx2x_cl45_read(bp, phy,
10088 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
10089 bnx2x_save_spirom_version(bp, params->port,
10090 (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
10094 static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
10095 struct link_params *params,
10096 struct link_vars *vars)
10098 struct bnx2x *bp = params->bp;
10101 bnx2x_cl45_read(bp, phy,
10102 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
10103 bnx2x_cl45_read(bp, phy,
10104 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
10105 DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
10107 bnx2x_cl45_read(bp, phy,
10108 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
10109 bnx2x_cl45_read(bp, phy,
10110 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
10111 DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
10113 link_up = ((val1 & 4) == 4);
10114 /* if link is up print the AN outcome of the SFX7101 PHY */
10116 bnx2x_cl45_read(bp, phy,
10117 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
10119 vars->line_speed = SPEED_10000;
10120 vars->duplex = DUPLEX_FULL;
10121 DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
10122 val2, (val2 & (1<<14)));
10123 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
10124 bnx2x_ext_phy_resolve_fc(phy, params, vars);
10129 static int bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
10133 str[0] = (spirom_ver & 0xFF);
10134 str[1] = (spirom_ver & 0xFF00) >> 8;
10135 str[2] = (spirom_ver & 0xFF0000) >> 16;
10136 str[3] = (spirom_ver & 0xFF000000) >> 24;
10142 void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
10146 bnx2x_cl45_read(bp, phy,
10148 MDIO_PMA_REG_7101_RESET, &val);
10150 for (cnt = 0; cnt < 10; cnt++) {
10152 /* Writes a self-clearing reset */
10153 bnx2x_cl45_write(bp, phy,
10155 MDIO_PMA_REG_7101_RESET,
10157 /* Wait for clear */
10158 bnx2x_cl45_read(bp, phy,
10160 MDIO_PMA_REG_7101_RESET, &val);
10162 if ((val & (1<<15)) == 0)
10167 static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
10168 struct link_params *params) {
10169 /* Low power mode is controlled by GPIO 2 */
10170 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
10171 MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
10172 /* The PHY reset is controlled by GPIO 1 */
10173 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
10174 MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
10177 static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy,
10178 struct link_params *params, u8 mode)
10181 struct bnx2x *bp = params->bp;
10183 case LED_MODE_FRONT_PANEL_OFF:
10190 case LED_MODE_OPER:
10194 bnx2x_cl45_write(bp, phy,
10196 MDIO_PMA_REG_7107_LINK_LED_CNTL,
10200 /******************************************************************/
10201 /* STATIC PHY DECLARATION */
10202 /******************************************************************/
10204 static struct bnx2x_phy phy_null = {
10205 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
10208 .flags = FLAGS_INIT_XGXS_FIRST,
10209 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10210 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10213 .media_type = ETH_PHY_NOT_PRESENT,
10215 .req_flow_ctrl = 0,
10216 .req_line_speed = 0,
10217 .speed_cap_mask = 0,
10220 .config_init = (config_init_t)NULL,
10221 .read_status = (read_status_t)NULL,
10222 .link_reset = (link_reset_t)NULL,
10223 .config_loopback = (config_loopback_t)NULL,
10224 .format_fw_ver = (format_fw_ver_t)NULL,
10225 .hw_reset = (hw_reset_t)NULL,
10226 .set_link_led = (set_link_led_t)NULL,
10227 .phy_specific_func = (phy_specific_func_t)NULL
10230 static struct bnx2x_phy phy_serdes = {
10231 .type = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
10235 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10236 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10238 .supported = (SUPPORTED_10baseT_Half |
10239 SUPPORTED_10baseT_Full |
10240 SUPPORTED_100baseT_Half |
10241 SUPPORTED_100baseT_Full |
10242 SUPPORTED_1000baseT_Full |
10243 SUPPORTED_2500baseX_Full |
10245 SUPPORTED_Autoneg |
10247 SUPPORTED_Asym_Pause),
10248 .media_type = ETH_PHY_BASE_T,
10250 .req_flow_ctrl = 0,
10251 .req_line_speed = 0,
10252 .speed_cap_mask = 0,
10255 .config_init = (config_init_t)bnx2x_xgxs_config_init,
10256 .read_status = (read_status_t)bnx2x_link_settings_status,
10257 .link_reset = (link_reset_t)bnx2x_int_link_reset,
10258 .config_loopback = (config_loopback_t)NULL,
10259 .format_fw_ver = (format_fw_ver_t)NULL,
10260 .hw_reset = (hw_reset_t)NULL,
10261 .set_link_led = (set_link_led_t)NULL,
10262 .phy_specific_func = (phy_specific_func_t)NULL
10265 static struct bnx2x_phy phy_xgxs = {
10266 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
10270 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10271 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10273 .supported = (SUPPORTED_10baseT_Half |
10274 SUPPORTED_10baseT_Full |
10275 SUPPORTED_100baseT_Half |
10276 SUPPORTED_100baseT_Full |
10277 SUPPORTED_1000baseT_Full |
10278 SUPPORTED_2500baseX_Full |
10279 SUPPORTED_10000baseT_Full |
10281 SUPPORTED_Autoneg |
10283 SUPPORTED_Asym_Pause),
10284 .media_type = ETH_PHY_CX4,
10286 .req_flow_ctrl = 0,
10287 .req_line_speed = 0,
10288 .speed_cap_mask = 0,
10291 .config_init = (config_init_t)bnx2x_xgxs_config_init,
10292 .read_status = (read_status_t)bnx2x_link_settings_status,
10293 .link_reset = (link_reset_t)bnx2x_int_link_reset,
10294 .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
10295 .format_fw_ver = (format_fw_ver_t)NULL,
10296 .hw_reset = (hw_reset_t)NULL,
10297 .set_link_led = (set_link_led_t)NULL,
10298 .phy_specific_func = (phy_specific_func_t)NULL
10300 static struct bnx2x_phy phy_warpcore = {
10301 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
10304 .flags = FLAGS_HW_LOCK_REQUIRED,
10305 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10306 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10308 .supported = (SUPPORTED_10baseT_Half |
10309 SUPPORTED_10baseT_Full |
10310 SUPPORTED_100baseT_Half |
10311 SUPPORTED_100baseT_Full |
10312 SUPPORTED_1000baseT_Full |
10313 SUPPORTED_10000baseT_Full |
10314 SUPPORTED_20000baseKR2_Full |
10315 SUPPORTED_20000baseMLD2_Full |
10317 SUPPORTED_Autoneg |
10319 SUPPORTED_Asym_Pause),
10320 .media_type = ETH_PHY_UNSPECIFIED,
10322 .req_flow_ctrl = 0,
10323 .req_line_speed = 0,
10324 .speed_cap_mask = 0,
10325 /* req_duplex = */0,
10327 .config_init = (config_init_t)bnx2x_warpcore_config_init,
10328 .read_status = (read_status_t)bnx2x_warpcore_read_status,
10329 .link_reset = (link_reset_t)bnx2x_warpcore_link_reset,
10330 .config_loopback = (config_loopback_t)bnx2x_set_warpcore_loopback,
10331 .format_fw_ver = (format_fw_ver_t)NULL,
10332 .hw_reset = (hw_reset_t)NULL,
10333 .set_link_led = (set_link_led_t)NULL,
10334 .phy_specific_func = (phy_specific_func_t)NULL
10338 static struct bnx2x_phy phy_7101 = {
10339 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
10342 .flags = FLAGS_FAN_FAILURE_DET_REQ,
10343 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10344 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10346 .supported = (SUPPORTED_10000baseT_Full |
10348 SUPPORTED_Autoneg |
10350 SUPPORTED_Asym_Pause),
10351 .media_type = ETH_PHY_BASE_T,
10353 .req_flow_ctrl = 0,
10354 .req_line_speed = 0,
10355 .speed_cap_mask = 0,
10358 .config_init = (config_init_t)bnx2x_7101_config_init,
10359 .read_status = (read_status_t)bnx2x_7101_read_status,
10360 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
10361 .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
10362 .format_fw_ver = (format_fw_ver_t)bnx2x_7101_format_ver,
10363 .hw_reset = (hw_reset_t)bnx2x_7101_hw_reset,
10364 .set_link_led = (set_link_led_t)bnx2x_7101_set_link_led,
10365 .phy_specific_func = (phy_specific_func_t)NULL
10367 static struct bnx2x_phy phy_8073 = {
10368 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
10371 .flags = FLAGS_HW_LOCK_REQUIRED,
10372 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10373 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10375 .supported = (SUPPORTED_10000baseT_Full |
10376 SUPPORTED_2500baseX_Full |
10377 SUPPORTED_1000baseT_Full |
10379 SUPPORTED_Autoneg |
10381 SUPPORTED_Asym_Pause),
10382 .media_type = ETH_PHY_KR,
10384 .req_flow_ctrl = 0,
10385 .req_line_speed = 0,
10386 .speed_cap_mask = 0,
10389 .config_init = (config_init_t)bnx2x_8073_config_init,
10390 .read_status = (read_status_t)bnx2x_8073_read_status,
10391 .link_reset = (link_reset_t)bnx2x_8073_link_reset,
10392 .config_loopback = (config_loopback_t)NULL,
10393 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
10394 .hw_reset = (hw_reset_t)NULL,
10395 .set_link_led = (set_link_led_t)NULL,
10396 .phy_specific_func = (phy_specific_func_t)NULL
10398 static struct bnx2x_phy phy_8705 = {
10399 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
10402 .flags = FLAGS_INIT_XGXS_FIRST,
10403 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10404 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10406 .supported = (SUPPORTED_10000baseT_Full |
10409 SUPPORTED_Asym_Pause),
10410 .media_type = ETH_PHY_XFP_FIBER,
10412 .req_flow_ctrl = 0,
10413 .req_line_speed = 0,
10414 .speed_cap_mask = 0,
10417 .config_init = (config_init_t)bnx2x_8705_config_init,
10418 .read_status = (read_status_t)bnx2x_8705_read_status,
10419 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
10420 .config_loopback = (config_loopback_t)NULL,
10421 .format_fw_ver = (format_fw_ver_t)bnx2x_null_format_ver,
10422 .hw_reset = (hw_reset_t)NULL,
10423 .set_link_led = (set_link_led_t)NULL,
10424 .phy_specific_func = (phy_specific_func_t)NULL
10426 static struct bnx2x_phy phy_8706 = {
10427 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
10430 .flags = FLAGS_INIT_XGXS_FIRST,
10431 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10432 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10434 .supported = (SUPPORTED_10000baseT_Full |
10435 SUPPORTED_1000baseT_Full |
10438 SUPPORTED_Asym_Pause),
10439 .media_type = ETH_PHY_SFP_FIBER,
10441 .req_flow_ctrl = 0,
10442 .req_line_speed = 0,
10443 .speed_cap_mask = 0,
10446 .config_init = (config_init_t)bnx2x_8706_config_init,
10447 .read_status = (read_status_t)bnx2x_8706_read_status,
10448 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
10449 .config_loopback = (config_loopback_t)NULL,
10450 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
10451 .hw_reset = (hw_reset_t)NULL,
10452 .set_link_led = (set_link_led_t)NULL,
10453 .phy_specific_func = (phy_specific_func_t)NULL
10456 static struct bnx2x_phy phy_8726 = {
10457 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
10460 .flags = (FLAGS_HW_LOCK_REQUIRED |
10461 FLAGS_INIT_XGXS_FIRST),
10462 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10463 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10465 .supported = (SUPPORTED_10000baseT_Full |
10466 SUPPORTED_1000baseT_Full |
10467 SUPPORTED_Autoneg |
10470 SUPPORTED_Asym_Pause),
10471 .media_type = ETH_PHY_NOT_PRESENT,
10473 .req_flow_ctrl = 0,
10474 .req_line_speed = 0,
10475 .speed_cap_mask = 0,
10478 .config_init = (config_init_t)bnx2x_8726_config_init,
10479 .read_status = (read_status_t)bnx2x_8726_read_status,
10480 .link_reset = (link_reset_t)bnx2x_8726_link_reset,
10481 .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
10482 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
10483 .hw_reset = (hw_reset_t)NULL,
10484 .set_link_led = (set_link_led_t)NULL,
10485 .phy_specific_func = (phy_specific_func_t)NULL
10488 static struct bnx2x_phy phy_8727 = {
10489 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
10492 .flags = FLAGS_FAN_FAILURE_DET_REQ,
10493 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10494 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10496 .supported = (SUPPORTED_10000baseT_Full |
10497 SUPPORTED_1000baseT_Full |
10500 SUPPORTED_Asym_Pause),
10501 .media_type = ETH_PHY_NOT_PRESENT,
10503 .req_flow_ctrl = 0,
10504 .req_line_speed = 0,
10505 .speed_cap_mask = 0,
10508 .config_init = (config_init_t)bnx2x_8727_config_init,
10509 .read_status = (read_status_t)bnx2x_8727_read_status,
10510 .link_reset = (link_reset_t)bnx2x_8727_link_reset,
10511 .config_loopback = (config_loopback_t)NULL,
10512 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
10513 .hw_reset = (hw_reset_t)bnx2x_8727_hw_reset,
10514 .set_link_led = (set_link_led_t)bnx2x_8727_set_link_led,
10515 .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func
10517 static struct bnx2x_phy phy_8481 = {
10518 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
10521 .flags = FLAGS_FAN_FAILURE_DET_REQ |
10522 FLAGS_REARM_LATCH_SIGNAL,
10523 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10524 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10526 .supported = (SUPPORTED_10baseT_Half |
10527 SUPPORTED_10baseT_Full |
10528 SUPPORTED_100baseT_Half |
10529 SUPPORTED_100baseT_Full |
10530 SUPPORTED_1000baseT_Full |
10531 SUPPORTED_10000baseT_Full |
10533 SUPPORTED_Autoneg |
10535 SUPPORTED_Asym_Pause),
10536 .media_type = ETH_PHY_BASE_T,
10538 .req_flow_ctrl = 0,
10539 .req_line_speed = 0,
10540 .speed_cap_mask = 0,
10543 .config_init = (config_init_t)bnx2x_8481_config_init,
10544 .read_status = (read_status_t)bnx2x_848xx_read_status,
10545 .link_reset = (link_reset_t)bnx2x_8481_link_reset,
10546 .config_loopback = (config_loopback_t)NULL,
10547 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
10548 .hw_reset = (hw_reset_t)bnx2x_8481_hw_reset,
10549 .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
10550 .phy_specific_func = (phy_specific_func_t)NULL
10553 static struct bnx2x_phy phy_84823 = {
10554 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
10557 .flags = FLAGS_FAN_FAILURE_DET_REQ |
10558 FLAGS_REARM_LATCH_SIGNAL,
10559 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10560 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10562 .supported = (SUPPORTED_10baseT_Half |
10563 SUPPORTED_10baseT_Full |
10564 SUPPORTED_100baseT_Half |
10565 SUPPORTED_100baseT_Full |
10566 SUPPORTED_1000baseT_Full |
10567 SUPPORTED_10000baseT_Full |
10569 SUPPORTED_Autoneg |
10571 SUPPORTED_Asym_Pause),
10572 .media_type = ETH_PHY_BASE_T,
10574 .req_flow_ctrl = 0,
10575 .req_line_speed = 0,
10576 .speed_cap_mask = 0,
10579 .config_init = (config_init_t)bnx2x_848x3_config_init,
10580 .read_status = (read_status_t)bnx2x_848xx_read_status,
10581 .link_reset = (link_reset_t)bnx2x_848x3_link_reset,
10582 .config_loopback = (config_loopback_t)NULL,
10583 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
10584 .hw_reset = (hw_reset_t)NULL,
10585 .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
10586 .phy_specific_func = (phy_specific_func_t)NULL
10589 static struct bnx2x_phy phy_84833 = {
10590 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833,
10593 .flags = FLAGS_FAN_FAILURE_DET_REQ |
10594 FLAGS_REARM_LATCH_SIGNAL,
10595 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10596 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10598 .supported = (SUPPORTED_10baseT_Half |
10599 SUPPORTED_10baseT_Full |
10600 SUPPORTED_100baseT_Half |
10601 SUPPORTED_100baseT_Full |
10602 SUPPORTED_1000baseT_Full |
10603 SUPPORTED_10000baseT_Full |
10605 SUPPORTED_Autoneg |
10607 SUPPORTED_Asym_Pause),
10608 .media_type = ETH_PHY_BASE_T,
10610 .req_flow_ctrl = 0,
10611 .req_line_speed = 0,
10612 .speed_cap_mask = 0,
10615 .config_init = (config_init_t)bnx2x_848x3_config_init,
10616 .read_status = (read_status_t)bnx2x_848xx_read_status,
10617 .link_reset = (link_reset_t)bnx2x_848x3_link_reset,
10618 .config_loopback = (config_loopback_t)NULL,
10619 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
10620 .hw_reset = (hw_reset_t)NULL,
10621 .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
10622 .phy_specific_func = (phy_specific_func_t)NULL
10625 static struct bnx2x_phy phy_54616s = {
10626 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616,
10629 .flags = FLAGS_INIT_XGXS_FIRST,
10630 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10631 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10633 .supported = (SUPPORTED_10baseT_Half |
10634 SUPPORTED_10baseT_Full |
10635 SUPPORTED_100baseT_Half |
10636 SUPPORTED_100baseT_Full |
10637 SUPPORTED_1000baseT_Full |
10639 SUPPORTED_Autoneg |
10641 SUPPORTED_Asym_Pause),
10642 .media_type = ETH_PHY_BASE_T,
10644 .req_flow_ctrl = 0,
10645 .req_line_speed = 0,
10646 .speed_cap_mask = 0,
10647 /* req_duplex = */0,
10649 .config_init = (config_init_t)bnx2x_54616s_config_init,
10650 .read_status = (read_status_t)bnx2x_54616s_read_status,
10651 .link_reset = (link_reset_t)bnx2x_54616s_link_reset,
10652 .config_loopback = (config_loopback_t)bnx2x_54616s_config_loopback,
10653 .format_fw_ver = (format_fw_ver_t)NULL,
10654 .hw_reset = (hw_reset_t)NULL,
10655 .set_link_led = (set_link_led_t)bnx2x_54616s_set_link_led,
10656 .phy_specific_func = (phy_specific_func_t)NULL
10658 /*****************************************************************/
10660 /* Populate the phy according. Main function: bnx2x_populate_phy */
10662 /*****************************************************************/
10664 static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
10665 struct bnx2x_phy *phy, u8 port,
10668 /* Get the 4 lanes xgxs config rx and tx */
10669 u32 rx = 0, tx = 0, i;
10670 for (i = 0; i < 2; i++) {
10672 * INT_PHY and EXT_PHY1 share the same value location in the
10673 * shmem. When num_phys is greater than 1, than this value
10674 * applies only to EXT_PHY1
10676 if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
10677 rx = REG_RD(bp, shmem_base +
10678 offsetof(struct shmem_region,
10679 dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
10681 tx = REG_RD(bp, shmem_base +
10682 offsetof(struct shmem_region,
10683 dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
10685 rx = REG_RD(bp, shmem_base +
10686 offsetof(struct shmem_region,
10687 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
10689 tx = REG_RD(bp, shmem_base +
10690 offsetof(struct shmem_region,
10691 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
10694 phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
10695 phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
10697 phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
10698 phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
10702 static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
10703 u8 phy_index, u8 port)
10705 u32 ext_phy_config = 0;
10706 switch (phy_index) {
10708 ext_phy_config = REG_RD(bp, shmem_base +
10709 offsetof(struct shmem_region,
10710 dev_info.port_hw_config[port].external_phy_config));
10713 ext_phy_config = REG_RD(bp, shmem_base +
10714 offsetof(struct shmem_region,
10715 dev_info.port_hw_config[port].external_phy_config2));
10718 DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
10722 return ext_phy_config;
10724 static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
10725 struct bnx2x_phy *phy)
10729 u32 switch_cfg = (REG_RD(bp, shmem_base +
10730 offsetof(struct shmem_region,
10731 dev_info.port_feature_config[port].link_config)) &
10732 PORT_FEATURE_CONNECTED_SWITCH_MASK);
10733 chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16;
10734 DP(NETIF_MSG_LINK, ":chip_id = 0x%x\n", chip_id);
10735 if (USES_WARPCORE(bp)) {
10737 phy_addr = REG_RD(bp,
10738 MISC_REG_WC0_CTRL_PHY_ADDR);
10739 *phy = phy_warpcore;
10740 if (REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR) == 0x3)
10741 phy->flags |= FLAGS_4_PORT_MODE;
10743 phy->flags &= ~FLAGS_4_PORT_MODE;
10744 /* Check Dual mode */
10745 serdes_net_if = (REG_RD(bp, shmem_base +
10746 offsetof(struct shmem_region, dev_info.
10747 port_hw_config[port].default_cfg)) &
10748 PORT_HW_CFG_NET_SERDES_IF_MASK);
10750 * Set the appropriate supported and flags indications per
10751 * interface type of the chip
10753 switch (serdes_net_if) {
10754 case PORT_HW_CFG_NET_SERDES_IF_SGMII:
10755 phy->supported &= (SUPPORTED_10baseT_Half |
10756 SUPPORTED_10baseT_Full |
10757 SUPPORTED_100baseT_Half |
10758 SUPPORTED_100baseT_Full |
10759 SUPPORTED_1000baseT_Full |
10761 SUPPORTED_Autoneg |
10763 SUPPORTED_Asym_Pause);
10764 phy->media_type = ETH_PHY_BASE_T;
10766 case PORT_HW_CFG_NET_SERDES_IF_XFI:
10767 phy->media_type = ETH_PHY_XFP_FIBER;
10769 case PORT_HW_CFG_NET_SERDES_IF_SFI:
10770 phy->supported &= (SUPPORTED_1000baseT_Full |
10771 SUPPORTED_10000baseT_Full |
10774 SUPPORTED_Asym_Pause);
10775 phy->media_type = ETH_PHY_SFP_FIBER;
10777 case PORT_HW_CFG_NET_SERDES_IF_KR:
10778 phy->media_type = ETH_PHY_KR;
10779 phy->supported &= (SUPPORTED_1000baseT_Full |
10780 SUPPORTED_10000baseT_Full |
10782 SUPPORTED_Autoneg |
10784 SUPPORTED_Asym_Pause);
10786 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
10787 phy->media_type = ETH_PHY_KR;
10788 phy->flags |= FLAGS_WC_DUAL_MODE;
10789 phy->supported &= (SUPPORTED_20000baseMLD2_Full |
10792 SUPPORTED_Asym_Pause);
10794 case PORT_HW_CFG_NET_SERDES_IF_KR2:
10795 phy->media_type = ETH_PHY_KR;
10796 phy->flags |= FLAGS_WC_DUAL_MODE;
10797 phy->supported &= (SUPPORTED_20000baseKR2_Full |
10800 SUPPORTED_Asym_Pause);
10803 DP(NETIF_MSG_LINK, "Unknown WC interface type 0x%x\n",
10809 * Enable MDC/MDIO work-around for E3 A0 since free running MDC
10810 * was not set as expected. For B0, ECO will be enabled so there
10811 * won't be an issue there
10813 if (CHIP_REV(bp) == CHIP_REV_Ax)
10814 phy->flags |= FLAGS_MDC_MDIO_WA;
10816 switch (switch_cfg) {
10817 case SWITCH_CFG_1G:
10818 phy_addr = REG_RD(bp,
10819 NIG_REG_SERDES0_CTRL_PHY_ADDR +
10823 case SWITCH_CFG_10G:
10824 phy_addr = REG_RD(bp,
10825 NIG_REG_XGXS0_CTRL_PHY_ADDR +
10830 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
10834 phy->addr = (u8)phy_addr;
10835 phy->mdio_ctrl = bnx2x_get_emac_base(bp,
10836 SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
10838 if (CHIP_IS_E2(bp))
10839 phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
10841 phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
10843 DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
10844 port, phy->addr, phy->mdio_ctrl);
10846 bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
10850 static int bnx2x_populate_ext_phy(struct bnx2x *bp,
10855 struct bnx2x_phy *phy)
10857 u32 ext_phy_config, phy_type, config2;
10858 u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
10859 ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
10861 phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
10862 /* Select the phy type */
10863 switch (phy_type) {
10864 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
10865 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
10868 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
10871 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
10874 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
10875 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
10878 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
10879 /* BCM8727_NOC => BCM8727 no over current */
10880 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
10882 phy->flags |= FLAGS_NOC;
10884 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
10885 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
10886 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
10889 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
10892 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
10895 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
10898 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616:
10901 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
10904 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
10912 phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
10913 bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
10916 * The shmem address of the phy version is located on different
10917 * structures. In case this structure is too old, do not set
10920 config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region,
10921 dev_info.shared_hw_config.config2));
10922 if (phy_index == EXT_PHY1) {
10923 phy->ver_addr = shmem_base + offsetof(struct shmem_region,
10924 port_mb[port].ext_phy_fw_version);
10926 /* Check specific mdc mdio settings */
10927 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
10928 mdc_mdio_access = config2 &
10929 SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
10931 u32 size = REG_RD(bp, shmem2_base);
10934 offsetof(struct shmem2_region, ext_phy_fw_version2)) {
10935 phy->ver_addr = shmem2_base +
10936 offsetof(struct shmem2_region,
10937 ext_phy_fw_version2[port]);
10939 /* Check specific mdc mdio settings */
10940 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
10941 mdc_mdio_access = (config2 &
10942 SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
10943 (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
10944 SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
10946 phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
10949 * In case mdc/mdio_access of the external phy is different than the
10950 * mdc/mdio access of the XGXS, a HW lock must be taken in each access
10951 * to prevent one port interfere with another port's CL45 operations.
10953 if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH)
10954 phy->flags |= FLAGS_HW_LOCK_REQUIRED;
10955 DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n",
10956 phy_type, port, phy_index);
10957 DP(NETIF_MSG_LINK, " addr=0x%x, mdio_ctl=0x%x\n",
10958 phy->addr, phy->mdio_ctrl);
10962 static int bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
10963 u32 shmem2_base, u8 port, struct bnx2x_phy *phy)
10966 phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
10967 if (phy_index == INT_PHY)
10968 return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
10969 status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
10974 static void bnx2x_phy_def_cfg(struct link_params *params,
10975 struct bnx2x_phy *phy,
10978 struct bnx2x *bp = params->bp;
10980 /* Populate the default phy configuration for MF mode */
10981 if (phy_index == EXT_PHY2) {
10982 link_config = REG_RD(bp, params->shmem_base +
10983 offsetof(struct shmem_region, dev_info.
10984 port_feature_config[params->port].link_config2));
10985 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
10986 offsetof(struct shmem_region,
10988 port_hw_config[params->port].speed_capability_mask2));
10990 link_config = REG_RD(bp, params->shmem_base +
10991 offsetof(struct shmem_region, dev_info.
10992 port_feature_config[params->port].link_config));
10993 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
10994 offsetof(struct shmem_region,
10996 port_hw_config[params->port].speed_capability_mask));
10998 DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask"
10999 " 0x%x\n", phy_index, link_config, phy->speed_cap_mask);
11001 phy->req_duplex = DUPLEX_FULL;
11002 switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) {
11003 case PORT_FEATURE_LINK_SPEED_10M_HALF:
11004 phy->req_duplex = DUPLEX_HALF;
11005 case PORT_FEATURE_LINK_SPEED_10M_FULL:
11006 phy->req_line_speed = SPEED_10;
11008 case PORT_FEATURE_LINK_SPEED_100M_HALF:
11009 phy->req_duplex = DUPLEX_HALF;
11010 case PORT_FEATURE_LINK_SPEED_100M_FULL:
11011 phy->req_line_speed = SPEED_100;
11013 case PORT_FEATURE_LINK_SPEED_1G:
11014 phy->req_line_speed = SPEED_1000;
11016 case PORT_FEATURE_LINK_SPEED_2_5G:
11017 phy->req_line_speed = SPEED_2500;
11019 case PORT_FEATURE_LINK_SPEED_10G_CX4:
11020 phy->req_line_speed = SPEED_10000;
11023 phy->req_line_speed = SPEED_AUTO_NEG;
11027 switch (link_config & PORT_FEATURE_FLOW_CONTROL_MASK) {
11028 case PORT_FEATURE_FLOW_CONTROL_AUTO:
11029 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
11031 case PORT_FEATURE_FLOW_CONTROL_TX:
11032 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
11034 case PORT_FEATURE_FLOW_CONTROL_RX:
11035 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
11037 case PORT_FEATURE_FLOW_CONTROL_BOTH:
11038 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
11041 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11046 u32 bnx2x_phy_selection(struct link_params *params)
11048 u32 phy_config_swapped, prio_cfg;
11049 u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
11051 phy_config_swapped = params->multi_phy_config &
11052 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
11054 prio_cfg = params->multi_phy_config &
11055 PORT_HW_CFG_PHY_SELECTION_MASK;
11057 if (phy_config_swapped) {
11058 switch (prio_cfg) {
11059 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
11060 return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
11062 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
11063 return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
11065 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
11066 return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
11068 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
11069 return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
11073 return_cfg = prio_cfg;
11079 int bnx2x_phy_probe(struct link_params *params)
11081 u8 phy_index, actual_phy_idx, link_cfg_idx;
11082 u32 phy_config_swapped, sync_offset, media_types;
11083 struct bnx2x *bp = params->bp;
11084 struct bnx2x_phy *phy;
11085 params->num_phys = 0;
11086 DP(NETIF_MSG_LINK, "Begin phy probe\n");
11087 phy_config_swapped = params->multi_phy_config &
11088 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
11090 for (phy_index = INT_PHY; phy_index < MAX_PHYS;
11092 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
11093 actual_phy_idx = phy_index;
11094 if (phy_config_swapped) {
11095 if (phy_index == EXT_PHY1)
11096 actual_phy_idx = EXT_PHY2;
11097 else if (phy_index == EXT_PHY2)
11098 actual_phy_idx = EXT_PHY1;
11100 DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x,"
11101 " actual_phy_idx %x\n", phy_config_swapped,
11102 phy_index, actual_phy_idx);
11103 phy = ¶ms->phy[actual_phy_idx];
11104 if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
11105 params->shmem2_base, params->port,
11107 params->num_phys = 0;
11108 DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
11110 for (phy_index = INT_PHY;
11111 phy_index < MAX_PHYS;
11116 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
11119 sync_offset = params->shmem_base +
11120 offsetof(struct shmem_region,
11121 dev_info.port_hw_config[params->port].media_type);
11122 media_types = REG_RD(bp, sync_offset);
11125 * Update media type for non-PMF sync only for the first time
11126 * In case the media type changes afterwards, it will be updated
11127 * using the update_status function
11129 if ((media_types & (PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
11130 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
11131 actual_phy_idx))) == 0) {
11132 media_types |= ((phy->media_type &
11133 PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
11134 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
11137 REG_WR(bp, sync_offset, media_types);
11139 bnx2x_phy_def_cfg(params, phy, phy_index);
11140 params->num_phys++;
11143 DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
11147 void bnx2x_init_bmac_loopback(struct link_params *params,
11148 struct link_vars *vars)
11150 struct bnx2x *bp = params->bp;
11152 vars->line_speed = SPEED_10000;
11153 vars->duplex = DUPLEX_FULL;
11154 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11155 vars->mac_type = MAC_TYPE_BMAC;
11157 vars->phy_flags = PHY_XGXS_FLAG;
11159 bnx2x_xgxs_deassert(params);
11161 /* set bmac loopback */
11162 bnx2x_bmac_enable(params, vars, 1);
11164 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11167 void bnx2x_init_emac_loopback(struct link_params *params,
11168 struct link_vars *vars)
11170 struct bnx2x *bp = params->bp;
11172 vars->line_speed = SPEED_1000;
11173 vars->duplex = DUPLEX_FULL;
11174 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11175 vars->mac_type = MAC_TYPE_EMAC;
11177 vars->phy_flags = PHY_XGXS_FLAG;
11179 bnx2x_xgxs_deassert(params);
11180 /* set bmac loopback */
11181 bnx2x_emac_enable(params, vars, 1);
11182 bnx2x_emac_program(params, vars);
11183 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11186 void bnx2x_init_xmac_loopback(struct link_params *params,
11187 struct link_vars *vars)
11189 struct bnx2x *bp = params->bp;
11191 if (!params->req_line_speed[0])
11192 vars->line_speed = SPEED_10000;
11194 vars->line_speed = params->req_line_speed[0];
11195 vars->duplex = DUPLEX_FULL;
11196 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11197 vars->mac_type = MAC_TYPE_XMAC;
11198 vars->phy_flags = PHY_XGXS_FLAG;
11200 * Set WC to loopback mode since link is required to provide clock
11201 * to the XMAC in 20G mode
11203 if (vars->line_speed == SPEED_20000) {
11204 bnx2x_set_aer_mmd(params, ¶ms->phy[0]);
11205 bnx2x_warpcore_reset_lane(bp, ¶ms->phy[0], 0);
11206 params->phy[INT_PHY].config_loopback(
11207 ¶ms->phy[INT_PHY],
11210 bnx2x_xmac_enable(params, vars, 1);
11211 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11214 void bnx2x_init_umac_loopback(struct link_params *params,
11215 struct link_vars *vars)
11217 struct bnx2x *bp = params->bp;
11219 vars->line_speed = SPEED_1000;
11220 vars->duplex = DUPLEX_FULL;
11221 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11222 vars->mac_type = MAC_TYPE_UMAC;
11223 vars->phy_flags = PHY_XGXS_FLAG;
11224 bnx2x_umac_enable(params, vars, 1);
11226 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11229 void bnx2x_init_xgxs_loopback(struct link_params *params,
11230 struct link_vars *vars)
11232 struct bnx2x *bp = params->bp;
11234 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11235 vars->duplex = DUPLEX_FULL;
11236 if (params->req_line_speed[0] == SPEED_1000)
11237 vars->line_speed = SPEED_1000;
11239 vars->line_speed = SPEED_10000;
11241 if (!USES_WARPCORE(bp))
11242 bnx2x_xgxs_deassert(params);
11243 bnx2x_link_initialize(params, vars);
11245 if (params->req_line_speed[0] == SPEED_1000) {
11246 if (USES_WARPCORE(bp))
11247 bnx2x_umac_enable(params, vars, 0);
11249 bnx2x_emac_program(params, vars);
11250 bnx2x_emac_enable(params, vars, 0);
11253 if (USES_WARPCORE(bp))
11254 bnx2x_xmac_enable(params, vars, 0);
11256 bnx2x_bmac_enable(params, vars, 0);
11259 if (params->loopback_mode == LOOPBACK_XGXS) {
11260 /* set 10G XGXS loopback */
11261 params->phy[INT_PHY].config_loopback(
11262 ¶ms->phy[INT_PHY],
11266 /* set external phy loopback */
11268 for (phy_index = EXT_PHY1;
11269 phy_index < params->num_phys; phy_index++) {
11270 if (params->phy[phy_index].config_loopback)
11271 params->phy[phy_index].config_loopback(
11272 ¶ms->phy[phy_index],
11276 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11278 bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
11281 int bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
11283 struct bnx2x *bp = params->bp;
11284 DP(NETIF_MSG_LINK, "Phy Initialization started\n");
11285 DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n",
11286 params->req_line_speed[0], params->req_flow_ctrl[0]);
11287 DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n",
11288 params->req_line_speed[1], params->req_flow_ctrl[1]);
11289 vars->link_status = 0;
11290 vars->phy_link_up = 0;
11292 vars->line_speed = 0;
11293 vars->duplex = DUPLEX_FULL;
11294 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11295 vars->mac_type = MAC_TYPE_NONE;
11296 vars->phy_flags = 0;
11298 /* disable attentions */
11299 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
11300 (NIG_MASK_XGXS0_LINK_STATUS |
11301 NIG_MASK_XGXS0_LINK10G |
11302 NIG_MASK_SERDES0_LINK_STATUS |
11305 bnx2x_emac_init(params, vars);
11307 if (params->num_phys == 0) {
11308 DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
11311 set_phy_vars(params, vars);
11313 DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
11314 switch (params->loopback_mode) {
11315 case LOOPBACK_BMAC:
11316 bnx2x_init_bmac_loopback(params, vars);
11318 case LOOPBACK_EMAC:
11319 bnx2x_init_emac_loopback(params, vars);
11321 case LOOPBACK_XMAC:
11322 bnx2x_init_xmac_loopback(params, vars);
11324 case LOOPBACK_UMAC:
11325 bnx2x_init_umac_loopback(params, vars);
11327 case LOOPBACK_XGXS:
11328 case LOOPBACK_EXT_PHY:
11329 bnx2x_init_xgxs_loopback(params, vars);
11332 if (!CHIP_IS_E3(bp)) {
11333 if (params->switch_cfg == SWITCH_CFG_10G)
11334 bnx2x_xgxs_deassert(params);
11336 bnx2x_serdes_deassert(bp, params->port);
11338 bnx2x_link_initialize(params, vars);
11340 bnx2x_link_int_enable(params);
11346 int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
11349 struct bnx2x *bp = params->bp;
11350 u8 phy_index, port = params->port, clear_latch_ind = 0;
11351 DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
11352 /* disable attentions */
11353 vars->link_status = 0;
11354 bnx2x_update_mng(params, vars->link_status);
11355 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
11356 (NIG_MASK_XGXS0_LINK_STATUS |
11357 NIG_MASK_XGXS0_LINK10G |
11358 NIG_MASK_SERDES0_LINK_STATUS |
11361 /* activate nig drain */
11362 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
11364 /* disable nig egress interface */
11365 if (!CHIP_IS_E3(bp)) {
11366 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
11367 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
11370 /* Stop BigMac rx */
11371 if (!CHIP_IS_E3(bp))
11372 bnx2x_bmac_rx_disable(bp, port);
11374 bnx2x_xmac_disable(params);
11376 if (!CHIP_IS_E3(bp))
11377 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
11380 /* The PHY reset is controlled by GPIO 1
11381 * Hold it as vars low
11383 /* clear link led */
11384 bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
11386 if (reset_ext_phy) {
11387 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
11389 if (params->phy[phy_index].link_reset)
11390 params->phy[phy_index].link_reset(
11391 ¶ms->phy[phy_index],
11393 if (params->phy[phy_index].flags &
11394 FLAGS_REARM_LATCH_SIGNAL)
11395 clear_latch_ind = 1;
11399 if (clear_latch_ind) {
11400 /* Clear latching indication */
11401 bnx2x_rearm_latch_signal(bp, port, 0);
11402 bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4,
11403 1 << NIG_LATCH_BC_ENABLE_MI_INT);
11405 if (params->phy[INT_PHY].link_reset)
11406 params->phy[INT_PHY].link_reset(
11407 ¶ms->phy[INT_PHY], params);
11409 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
11410 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
11412 /* disable nig ingress interface */
11413 if (!CHIP_IS_E3(bp)) {
11414 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
11415 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
11418 vars->phy_flags = 0;
11422 /****************************************************************************/
11423 /* Common function */
11424 /****************************************************************************/
11425 static int bnx2x_8073_common_init_phy(struct bnx2x *bp,
11426 u32 shmem_base_path[],
11427 u32 shmem2_base_path[], u8 phy_index,
11430 struct bnx2x_phy phy[PORT_MAX];
11431 struct bnx2x_phy *phy_blk[PORT_MAX];
11434 s8 port_of_path = 0;
11435 u32 swap_val, swap_override;
11436 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
11437 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
11438 port ^= (swap_val && swap_override);
11439 bnx2x_ext_phy_hw_reset(bp, port);
11440 /* PART1 - Reset both phys */
11441 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
11442 u32 shmem_base, shmem2_base;
11443 /* In E2, same phy is using for port0 of the two paths */
11444 if (CHIP_IS_E1x(bp)) {
11445 shmem_base = shmem_base_path[0];
11446 shmem2_base = shmem2_base_path[0];
11447 port_of_path = port;
11449 shmem_base = shmem_base_path[port];
11450 shmem2_base = shmem2_base_path[port];
11454 /* Extract the ext phy address for the port */
11455 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
11456 port_of_path, &phy[port]) !=
11458 DP(NETIF_MSG_LINK, "populate_phy failed\n");
11461 /* disable attentions */
11462 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
11464 (NIG_MASK_XGXS0_LINK_STATUS |
11465 NIG_MASK_XGXS0_LINK10G |
11466 NIG_MASK_SERDES0_LINK_STATUS |
11469 /* Need to take the phy out of low power mode in order
11470 to write to access its registers */
11471 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
11472 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
11475 /* Reset the phy */
11476 bnx2x_cl45_write(bp, &phy[port],
11482 /* Add delay of 150ms after reset */
11485 if (phy[PORT_0].addr & 0x1) {
11486 phy_blk[PORT_0] = &(phy[PORT_1]);
11487 phy_blk[PORT_1] = &(phy[PORT_0]);
11489 phy_blk[PORT_0] = &(phy[PORT_0]);
11490 phy_blk[PORT_1] = &(phy[PORT_1]);
11493 /* PART2 - Download firmware to both phys */
11494 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
11495 if (CHIP_IS_E1x(bp))
11496 port_of_path = port;
11500 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
11501 phy_blk[port]->addr);
11502 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
11506 /* Only set bit 10 = 1 (Tx power down) */
11507 bnx2x_cl45_read(bp, phy_blk[port],
11509 MDIO_PMA_REG_TX_POWER_DOWN, &val);
11511 /* Phase1 of TX_POWER_DOWN reset */
11512 bnx2x_cl45_write(bp, phy_blk[port],
11514 MDIO_PMA_REG_TX_POWER_DOWN,
11519 * Toggle Transmitter: Power down and then up with 600ms delay
11524 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
11525 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
11526 /* Phase2 of POWER_DOWN_RESET */
11527 /* Release bit 10 (Release Tx power down) */
11528 bnx2x_cl45_read(bp, phy_blk[port],
11530 MDIO_PMA_REG_TX_POWER_DOWN, &val);
11532 bnx2x_cl45_write(bp, phy_blk[port],
11534 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
11537 /* Read modify write the SPI-ROM version select register */
11538 bnx2x_cl45_read(bp, phy_blk[port],
11540 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
11541 bnx2x_cl45_write(bp, phy_blk[port],
11543 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
11545 /* set GPIO2 back to LOW */
11546 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
11547 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
11551 static int bnx2x_8726_common_init_phy(struct bnx2x *bp,
11552 u32 shmem_base_path[],
11553 u32 shmem2_base_path[], u8 phy_index,
11558 struct bnx2x_phy phy;
11559 /* Use port1 because of the static port-swap */
11560 /* Enable the module detection interrupt */
11561 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
11562 val |= ((1<<MISC_REGISTERS_GPIO_3)|
11563 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
11564 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
11566 bnx2x_ext_phy_hw_reset(bp, 0);
11568 for (port = 0; port < PORT_MAX; port++) {
11569 u32 shmem_base, shmem2_base;
11571 /* In E2, same phy is using for port0 of the two paths */
11572 if (CHIP_IS_E1x(bp)) {
11573 shmem_base = shmem_base_path[0];
11574 shmem2_base = shmem2_base_path[0];
11576 shmem_base = shmem_base_path[port];
11577 shmem2_base = shmem2_base_path[port];
11579 /* Extract the ext phy address for the port */
11580 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
11583 DP(NETIF_MSG_LINK, "populate phy failed\n");
11588 bnx2x_cl45_write(bp, &phy,
11589 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
11592 /* Set fault module detected LED on */
11593 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
11594 MISC_REGISTERS_GPIO_HIGH,
11600 static void bnx2x_get_ext_phy_reset_gpio(struct bnx2x *bp, u32 shmem_base,
11601 u8 *io_gpio, u8 *io_port)
11604 u32 phy_gpio_reset = REG_RD(bp, shmem_base +
11605 offsetof(struct shmem_region,
11606 dev_info.port_hw_config[PORT_0].default_cfg));
11607 switch (phy_gpio_reset) {
11608 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0:
11612 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0:
11616 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0:
11620 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0:
11624 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1:
11628 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1:
11632 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1:
11636 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1:
11641 /* Don't override the io_gpio and io_port */
11646 static int bnx2x_8727_common_init_phy(struct bnx2x *bp,
11647 u32 shmem_base_path[],
11648 u32 shmem2_base_path[], u8 phy_index,
11651 s8 port, reset_gpio;
11652 u32 swap_val, swap_override;
11653 struct bnx2x_phy phy[PORT_MAX];
11654 struct bnx2x_phy *phy_blk[PORT_MAX];
11656 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
11657 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
11659 reset_gpio = MISC_REGISTERS_GPIO_1;
11663 * Retrieve the reset gpio/port which control the reset.
11664 * Default is GPIO1, PORT1
11666 bnx2x_get_ext_phy_reset_gpio(bp, shmem_base_path[0],
11667 (u8 *)&reset_gpio, (u8 *)&port);
11669 /* Calculate the port based on port swap */
11670 port ^= (swap_val && swap_override);
11672 /* Initiate PHY reset*/
11673 bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW,
11676 bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH,
11681 /* PART1 - Reset both phys */
11682 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
11683 u32 shmem_base, shmem2_base;
11685 /* In E2, same phy is using for port0 of the two paths */
11686 if (CHIP_IS_E1x(bp)) {
11687 shmem_base = shmem_base_path[0];
11688 shmem2_base = shmem2_base_path[0];
11689 port_of_path = port;
11691 shmem_base = shmem_base_path[port];
11692 shmem2_base = shmem2_base_path[port];
11696 /* Extract the ext phy address for the port */
11697 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
11698 port_of_path, &phy[port]) !=
11700 DP(NETIF_MSG_LINK, "populate phy failed\n");
11703 /* disable attentions */
11704 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
11706 (NIG_MASK_XGXS0_LINK_STATUS |
11707 NIG_MASK_XGXS0_LINK10G |
11708 NIG_MASK_SERDES0_LINK_STATUS |
11712 /* Reset the phy */
11713 bnx2x_cl45_write(bp, &phy[port],
11714 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
11717 /* Add delay of 150ms after reset */
11719 if (phy[PORT_0].addr & 0x1) {
11720 phy_blk[PORT_0] = &(phy[PORT_1]);
11721 phy_blk[PORT_1] = &(phy[PORT_0]);
11723 phy_blk[PORT_0] = &(phy[PORT_0]);
11724 phy_blk[PORT_1] = &(phy[PORT_1]);
11726 /* PART2 - Download firmware to both phys */
11727 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
11728 if (CHIP_IS_E1x(bp))
11729 port_of_path = port;
11732 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
11733 phy_blk[port]->addr);
11734 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
11742 static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
11743 u32 shmem2_base_path[], u8 phy_index,
11744 u32 ext_phy_type, u32 chip_id)
11748 switch (ext_phy_type) {
11749 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
11750 rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
11752 phy_index, chip_id);
11754 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
11755 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
11756 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
11757 rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
11759 phy_index, chip_id);
11762 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
11764 * GPIO1 affects both ports, so there's need to pull
11765 * it for single port alone
11767 rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
11769 phy_index, chip_id);
11771 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
11773 * GPIO3's are linked, and so both need to be toggled
11774 * to obtain required 2us pulse.
11776 rc = bnx2x_84833_common_init_phy(bp, shmem_base_path, chip_id);
11778 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
11783 "ext_phy 0x%x common init not required\n",
11789 netdev_err(bp->dev, "Warning: PHY was not initialized,"
11795 int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
11796 u32 shmem2_base_path[], u32 chip_id)
11801 u32 ext_phy_type, ext_phy_config;
11802 bnx2x_set_mdio_clk(bp, chip_id, PORT_0);
11803 bnx2x_set_mdio_clk(bp, chip_id, PORT_1);
11804 DP(NETIF_MSG_LINK, "Begin common phy init\n");
11805 if (CHIP_IS_E3(bp)) {
11807 val = REG_RD(bp, MISC_REG_GEN_PURP_HWG);
11808 REG_WR(bp, MISC_REG_GEN_PURP_HWG, val | 1);
11810 /* Check if common init was already done */
11811 phy_ver = REG_RD(bp, shmem_base_path[0] +
11812 offsetof(struct shmem_region,
11813 port_mb[PORT_0].ext_phy_fw_version));
11815 DP(NETIF_MSG_LINK, "Not doing common init; phy ver is 0x%x\n",
11820 /* Read the ext_phy_type for arbitrary port(0) */
11821 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
11823 ext_phy_config = bnx2x_get_ext_phy_config(bp,
11824 shmem_base_path[0],
11826 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
11827 rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
11829 phy_index, ext_phy_type,
11835 u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
11838 struct bnx2x_phy phy;
11839 for (phy_index = INT_PHY; phy_index < MAX_PHYS;
11841 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
11843 DP(NETIF_MSG_LINK, "populate phy failed\n");
11847 if (phy.flags & FLAGS_HW_LOCK_REQUIRED)
11853 u8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
11858 u8 phy_index, fan_failure_det_req = 0;
11859 struct bnx2x_phy phy;
11860 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
11862 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
11865 DP(NETIF_MSG_LINK, "populate phy failed\n");
11868 fan_failure_det_req |= (phy.flags &
11869 FLAGS_FAN_FAILURE_DET_REQ);
11871 return fan_failure_det_req;
11874 void bnx2x_hw_reset_phy(struct link_params *params)
11877 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
11879 if (params->phy[phy_index].hw_reset) {
11880 params->phy[phy_index].hw_reset(
11881 ¶ms->phy[phy_index],
11883 params->phy[phy_index] = phy_null;
11888 void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars,
11889 u32 chip_id, u32 shmem_base, u32 shmem2_base,
11892 u8 gpio_num = 0xff, gpio_port = 0xff, phy_index;
11894 u32 offset, aeu_mask, swap_val, swap_override, sync_offset;
11895 if (CHIP_IS_E3(bp)) {
11896 if (bnx2x_get_mod_abs_int_cfg(bp, chip_id,
11903 struct bnx2x_phy phy;
11904 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
11906 if (bnx2x_populate_phy(bp, phy_index, shmem_base,
11907 shmem2_base, port, &phy)
11909 DP(NETIF_MSG_LINK, "populate phy failed\n");
11912 if (phy.type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
11913 gpio_num = MISC_REGISTERS_GPIO_3;
11920 if (gpio_num == 0xff)
11923 /* Set GPIO3 to trigger SFP+ module insertion/removal */
11924 bnx2x_set_gpio(bp, gpio_num, MISC_REGISTERS_GPIO_INPUT_HI_Z, gpio_port);
11926 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
11927 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
11928 gpio_port ^= (swap_val && swap_override);
11930 vars->aeu_int_mask = AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 <<
11931 (gpio_num + (gpio_port << 2));
11933 sync_offset = shmem_base +
11934 offsetof(struct shmem_region,
11935 dev_info.port_hw_config[port].aeu_int_mask);
11936 REG_WR(bp, sync_offset, vars->aeu_int_mask);
11938 DP(NETIF_MSG_LINK, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x\n",
11939 gpio_num, gpio_port, vars->aeu_int_mask);
11942 offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
11944 offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
11946 /* Open appropriate AEU for interrupts */
11947 aeu_mask = REG_RD(bp, offset);
11948 aeu_mask |= vars->aeu_int_mask;
11949 REG_WR(bp, offset, aeu_mask);
11951 /* Enable the GPIO to trigger interrupt */
11952 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
11953 val |= 1 << (gpio_num + (gpio_port << 2));
11954 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);