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
138 #define SFP_EEPROM_CON_TYPE_ADDR 0x2
139 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
140 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
143 #define SFP_EEPROM_COMP_CODE_ADDR 0x3
144 #define SFP_EEPROM_COMP_CODE_SR_MASK (1<<4)
145 #define SFP_EEPROM_COMP_CODE_LR_MASK (1<<5)
146 #define SFP_EEPROM_COMP_CODE_LRM_MASK (1<<6)
148 #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
149 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
150 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
152 #define SFP_EEPROM_OPTIONS_ADDR 0x40
153 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
154 #define SFP_EEPROM_OPTIONS_SIZE 2
156 #define EDC_MODE_LINEAR 0x0022
157 #define EDC_MODE_LIMITING 0x0044
158 #define EDC_MODE_PASSIVE_DAC 0x0055
161 /* BRB thresholds for E2*/
162 #define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE 170
163 #define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0
165 #define PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE 250
166 #define PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0
168 #define PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE 10
169 #define PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 90
171 #define PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE 50
172 #define PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE 250
174 /* BRB thresholds for E3A0 */
175 #define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE 290
176 #define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0
178 #define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE 410
179 #define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0
181 #define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE 10
182 #define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 170
184 #define PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE 50
185 #define PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE 410
188 /* BRB thresholds for E3B0 2 port mode*/
189 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE 1025
190 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0
192 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE 1025
193 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0
195 #define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE 10
196 #define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 1025
198 #define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE 50
199 #define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE 1025
202 #define PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR 1025
203 #define PFC_E3B0_2P_BRB_FULL_LB_XON_THR 1025
205 /* Lossy +Lossless GUARANTIED == GUART */
206 #define PFC_E3B0_2P_MIX_PAUSE_LB_GUART 284
207 /* Lossless +Lossless*/
208 #define PFC_E3B0_2P_PAUSE_LB_GUART 236
210 #define PFC_E3B0_2P_NON_PAUSE_LB_GUART 342
213 #define PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART 284
214 /* Lossless +Lossless*/
215 #define PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART 236
217 #define PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART 336
218 #define PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST 80
220 #define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART 0
221 #define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST 0
223 /* BRB thresholds for E3B0 4 port mode */
224 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE 304
225 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0
227 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE 384
228 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0
230 #define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE 10
231 #define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 304
233 #define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE 50
234 #define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE 384
238 #define PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR 304
239 #define PFC_E3B0_4P_BRB_FULL_LB_XON_THR 384
240 #define PFC_E3B0_4P_LB_GUART 120
242 #define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART 120
243 #define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST 80
245 #define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART 80
246 #define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST 120
248 #define DCBX_INVALID_COS (0xFF)
250 #define ETS_BW_LIMIT_CREDIT_UPPER_BOUND (0x5000)
251 #define ETS_BW_LIMIT_CREDIT_WEIGHT (0x5000)
252 #define ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS (1360)
253 #define ETS_E3B0_NIG_MIN_W_VAL_20GBPS (2720)
254 #define ETS_E3B0_PBF_MIN_W_VAL (10000)
256 #define MAX_PACKET_SIZE (9700)
257 #define WC_UC_TIMEOUT 100
259 /**********************************************************/
261 /**********************************************************/
263 #define CL22_WR_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
264 bnx2x_cl45_write(_bp, _phy, \
265 (_phy)->def_md_devad, \
266 (_bank + (_addr & 0xf)), \
269 #define CL22_RD_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
270 bnx2x_cl45_read(_bp, _phy, \
271 (_phy)->def_md_devad, \
272 (_bank + (_addr & 0xf)), \
275 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
277 u32 val = REG_RD(bp, reg);
280 REG_WR(bp, reg, val);
284 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
286 u32 val = REG_RD(bp, reg);
289 REG_WR(bp, reg, val);
293 /******************************************************************/
294 /* EPIO/GPIO section */
295 /******************************************************************/
296 static void bnx2x_set_epio(struct bnx2x *bp, u32 epio_pin, u32 en)
298 u32 epio_mask, gp_output, gp_oenable;
302 DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to set\n", epio_pin);
305 DP(NETIF_MSG_LINK, "Setting EPIO pin %d to %d\n", epio_pin, en);
306 epio_mask = 1 << epio_pin;
307 /* Set this EPIO to output */
308 gp_output = REG_RD(bp, MCP_REG_MCPR_GP_OUTPUTS);
310 gp_output |= epio_mask;
312 gp_output &= ~epio_mask;
314 REG_WR(bp, MCP_REG_MCPR_GP_OUTPUTS, gp_output);
316 /* Set the value for this EPIO */
317 gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE);
318 REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask);
321 static void bnx2x_set_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 val)
323 if (pin_cfg == PIN_CFG_NA)
325 if (pin_cfg >= PIN_CFG_EPIO0) {
326 bnx2x_set_epio(bp, pin_cfg - PIN_CFG_EPIO0, val);
328 u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
329 u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
330 bnx2x_set_gpio(bp, gpio_num, (u8)val, gpio_port);
334 /******************************************************************/
336 /******************************************************************/
337 void bnx2x_ets_disabled(struct link_params *params)
339 /* ETS disabled configuration*/
340 struct bnx2x *bp = params->bp;
342 DP(NETIF_MSG_LINK, "ETS disabled configuration\n");
345 * mapping between entry priority to client number (0,1,2 -debug and
346 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
348 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
349 * cos1-100 cos0-011 dbg1-010 dbg0-001 MCP-000
352 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
354 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
355 * as strict. Bits 0,1,2 - debug and management entries, 3 -
356 * COS0 entry, 4 - COS1 entry.
357 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
358 * bit4 bit3 bit2 bit1 bit0
359 * MCP and debug are strict
362 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
363 /* defines which entries (clients) are subjected to WFQ arbitration */
364 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
366 * For strict priority entries defines the number of consecutive
367 * slots for the highest priority.
369 REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
371 * mapping between the CREDIT_WEIGHT registers and actual client
374 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
375 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
376 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
378 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
379 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
380 REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
381 /* ETS mode disable */
382 REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
384 * If ETS mode is enabled (there is no strict priority) defines a WFQ
385 * weight for COS0/COS1.
387 REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
388 REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710);
389 /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
390 REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680);
391 REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680);
392 /* Defines the number of consecutive slots for the strict priority */
393 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
396 static void bnx2x_ets_bw_limit_common(const struct link_params *params)
398 /* ETS disabled configuration */
399 struct bnx2x *bp = params->bp;
400 DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
402 * defines which entries (clients) are subjected to WFQ arbitration
406 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
408 * mapping between the ARB_CREDIT_WEIGHT registers and actual
409 * client numbers (WEIGHT_0 does not actually have to represent
411 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
412 * cos1-001 cos0-000 dbg1-100 dbg0-011 MCP-010
414 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
416 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
417 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
418 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
419 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
421 /* ETS mode enabled*/
422 REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
424 /* Defines the number of consecutive slots for the strict priority */
425 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
427 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
428 * as strict. Bits 0,1,2 - debug and management entries, 3 - COS0
429 * entry, 4 - COS1 entry.
430 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
431 * bit4 bit3 bit2 bit1 bit0
432 * MCP and debug are strict
434 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
436 /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
437 REG_WR(bp, PBF_REG_COS0_UPPER_BOUND,
438 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
439 REG_WR(bp, PBF_REG_COS1_UPPER_BOUND,
440 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
443 void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
446 /* ETS disabled configuration*/
447 struct bnx2x *bp = params->bp;
448 const u32 total_bw = cos0_bw + cos1_bw;
449 u32 cos0_credit_weight = 0;
450 u32 cos1_credit_weight = 0;
452 DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
454 if ((0 == total_bw) ||
457 DP(NETIF_MSG_LINK, "Total BW can't be zero\n");
461 cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
463 cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
466 bnx2x_ets_bw_limit_common(params);
468 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
469 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
471 REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
472 REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
475 int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
477 /* ETS disabled configuration*/
478 struct bnx2x *bp = params->bp;
481 DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
483 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
484 * as strict. Bits 0,1,2 - debug and management entries,
485 * 3 - COS0 entry, 4 - COS1 entry.
486 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
487 * bit4 bit3 bit2 bit1 bit0
488 * MCP and debug are strict
490 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
492 * For strict priority entries defines the number of consecutive slots
493 * for the highest priority.
495 REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
496 /* ETS mode disable */
497 REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
498 /* Defines the number of consecutive slots for the strict priority */
499 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
501 /* Defines the number of consecutive slots for the strict priority */
502 REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
505 * mapping between entry priority to client number (0,1,2 -debug and
506 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
508 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
509 * dbg0-010 dbg1-001 cos1-100 cos0-011 MCP-000
510 * dbg0-010 dbg1-001 cos0-011 cos1-100 MCP-000
512 val = (0 == strict_cos) ? 0x2318 : 0x22E0;
513 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
517 /******************************************************************/
519 /******************************************************************/
521 static void bnx2x_update_pfc_xmac(struct link_params *params,
522 struct link_vars *vars,
525 struct bnx2x *bp = params->bp;
527 u32 pause_val, pfc0_val, pfc1_val;
530 xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
532 /* Initialize pause and pfc registers */
534 pfc0_val = 0xFFFF8000;
538 if (!(params->feature_config_flags &
539 FEATURE_CONFIG_PFC_ENABLED)) {
542 * RX flow control - Process pause frame in receive direction
544 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
545 pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN;
548 * TX flow control - Send pause packet when buffer is full
550 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
551 pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN;
552 } else {/* PFC support */
553 pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN |
554 XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN |
555 XMAC_PFC_CTRL_HI_REG_RX_PFC_EN |
556 XMAC_PFC_CTRL_HI_REG_TX_PFC_EN;
559 /* Write pause and PFC registers */
560 REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
561 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
562 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
568 static void bnx2x_bmac2_get_pfc_stat(struct link_params *params,
569 u32 pfc_frames_sent[2],
570 u32 pfc_frames_received[2])
572 /* Read pfc statistic */
573 struct bnx2x *bp = params->bp;
574 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
575 NIG_REG_INGRESS_BMAC0_MEM;
577 DP(NETIF_MSG_LINK, "pfc statistic read from BMAC\n");
579 REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_STAT_GTPP,
582 REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_STAT_GRPP,
583 pfc_frames_received, 2);
586 static void bnx2x_emac_get_pfc_stat(struct link_params *params,
587 u32 pfc_frames_sent[2],
588 u32 pfc_frames_received[2])
590 /* Read pfc statistic */
591 struct bnx2x *bp = params->bp;
592 u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
596 DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n");
598 /* PFC received frames */
599 val_xoff = REG_RD(bp, emac_base +
600 EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
601 val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
602 val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
603 val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
605 pfc_frames_received[0] = val_xon + val_xoff;
607 /* PFC received sent */
608 val_xoff = REG_RD(bp, emac_base +
609 EMAC_REG_RX_PFC_STATS_XOFF_SENT);
610 val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
611 val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
612 val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
614 pfc_frames_sent[0] = val_xon + val_xoff;
617 void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
618 u32 pfc_frames_sent[2],
619 u32 pfc_frames_received[2])
621 /* Read pfc statistic */
622 struct bnx2x *bp = params->bp;
624 DP(NETIF_MSG_LINK, "pfc statistic\n");
629 val = REG_RD(bp, MISC_REG_RESET_REG_2);
630 if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
632 DP(NETIF_MSG_LINK, "About to read stats from EMAC\n");
633 bnx2x_emac_get_pfc_stat(params, pfc_frames_sent,
634 pfc_frames_received);
636 DP(NETIF_MSG_LINK, "About to read stats from BMAC\n");
637 bnx2x_bmac2_get_pfc_stat(params, pfc_frames_sent,
638 pfc_frames_received);
641 /******************************************************************/
642 /* MAC/PBF section */
643 /******************************************************************/
644 static void bnx2x_set_mdio_clk(struct bnx2x *bp, u32 chip_id, u8 port)
648 * Set clause 45 mode, slow down the MDIO clock to 2.5MHz
649 * (a value of 49==0x31) and make sure that the AUTO poll is off
653 emac_base = GRCBASE_EMAC0;
655 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
656 mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
657 mode &= ~(EMAC_MDIO_MODE_AUTO_POLL |
658 EMAC_MDIO_MODE_CLOCK_CNT);
659 if (USES_WARPCORE(bp))
660 mode |= (74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
662 mode |= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
664 mode |= (EMAC_MDIO_MODE_CLAUSE_45);
665 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, mode);
670 static void bnx2x_emac_init(struct link_params *params,
671 struct link_vars *vars)
673 /* reset and unreset the emac core */
674 struct bnx2x *bp = params->bp;
675 u8 port = params->port;
676 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
680 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
681 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
683 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
684 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
686 /* init emac - use read-modify-write */
687 /* self clear reset */
688 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
689 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
693 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
694 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
696 DP(NETIF_MSG_LINK, "EMAC timeout!\n");
700 } while (val & EMAC_MODE_RESET);
701 bnx2x_set_mdio_clk(bp, params->chip_id, port);
702 /* Set mac address */
703 val = ((params->mac_addr[0] << 8) |
704 params->mac_addr[1]);
705 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
707 val = ((params->mac_addr[2] << 24) |
708 (params->mac_addr[3] << 16) |
709 (params->mac_addr[4] << 8) |
710 params->mac_addr[5]);
711 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
714 static void bnx2x_set_xumac_nig(struct link_params *params,
718 struct bnx2x *bp = params->bp;
720 REG_WR(bp, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN,
722 REG_WR(bp, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN,
724 REG_WR(bp, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN :
725 NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
728 static void bnx2x_umac_enable(struct link_params *params,
729 struct link_vars *vars, u8 lb)
732 u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
733 struct bnx2x *bp = params->bp;
735 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
736 (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
737 usleep_range(1000, 1000);
739 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
740 (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
742 DP(NETIF_MSG_LINK, "enabling UMAC\n");
745 * This register determines on which events the MAC will assert
746 * error on the i/f to the NIG along w/ EOP.
750 * BD REG_WR(bp, NIG_REG_P0_MAC_RSV_ERR_MASK +
751 * params->port*0x14, 0xfffff.
753 /* This register opens the gate for the UMAC despite its name */
754 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
756 val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN |
757 UMAC_COMMAND_CONFIG_REG_PAD_EN |
758 UMAC_COMMAND_CONFIG_REG_SW_RESET |
759 UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK;
760 switch (vars->line_speed) {
774 DP(NETIF_MSG_LINK, "Invalid speed for UMAC %d\n",
778 REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
781 /* Enable RX and TX */
782 val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN;
783 val |= UMAC_COMMAND_CONFIG_REG_TX_ENA |
784 UMAC_COMMAND_CONFIG_REG_RX_ENA;
785 REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
788 /* Remove SW Reset */
789 val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET;
791 /* Check loopback mode */
793 val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA;
794 REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
797 * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
798 * length used by the MAC receive logic to check frames.
800 REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
801 bnx2x_set_xumac_nig(params,
802 ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
803 vars->mac_type = MAC_TYPE_UMAC;
807 static u8 bnx2x_is_4_port_mode(struct bnx2x *bp)
809 u32 port4mode_ovwr_val;
810 /* Check 4-port override enabled */
811 port4mode_ovwr_val = REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR);
812 if (port4mode_ovwr_val & (1<<0)) {
813 /* Return 4-port mode override value */
814 return ((port4mode_ovwr_val & (1<<1)) == (1<<1));
816 /* Return 4-port mode from input pin */
817 return (u8)REG_RD(bp, MISC_REG_PORT4MODE_EN);
820 /* Define the XMAC mode */
821 static void bnx2x_xmac_init(struct bnx2x *bp, u32 max_speed)
823 u32 is_port4mode = bnx2x_is_4_port_mode(bp);
826 * In 4-port mode, need to set the mode only once, so if XMAC is
827 * already out of reset, it means the mode has already been set,
828 * and it must not* reset the XMAC again, since it controls both
832 if (is_port4mode && (REG_RD(bp, MISC_REG_RESET_REG_2) &
833 MISC_REGISTERS_RESET_REG_2_XMAC)) {
834 DP(NETIF_MSG_LINK, "XMAC already out of reset"
835 " in 4-port mode\n");
840 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
841 MISC_REGISTERS_RESET_REG_2_XMAC);
842 usleep_range(1000, 1000);
844 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
845 MISC_REGISTERS_RESET_REG_2_XMAC);
847 DP(NETIF_MSG_LINK, "Init XMAC to 2 ports x 10G per path\n");
849 /* Set the number of ports on the system side to up to 2 */
850 REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 1);
852 /* Set the number of ports on the Warp Core to 10G */
853 REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
855 /* Set the number of ports on the system side to 1 */
856 REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 0);
857 if (max_speed == SPEED_10000) {
858 DP(NETIF_MSG_LINK, "Init XMAC to 10G x 1"
860 /* Set the number of ports on the Warp Core to 10G */
861 REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
863 DP(NETIF_MSG_LINK, "Init XMAC to 20G x 2 ports"
865 /* Set the number of ports on the Warp Core to 20G */
866 REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 1);
870 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
871 MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
872 usleep_range(1000, 1000);
874 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
875 MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
879 static void bnx2x_xmac_disable(struct link_params *params)
881 u8 port = params->port;
882 struct bnx2x *bp = params->bp;
883 u32 xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
885 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
886 MISC_REGISTERS_RESET_REG_2_XMAC) {
887 DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port);
888 REG_WR(bp, xmac_base + XMAC_REG_CTRL, 0);
889 usleep_range(1000, 1000);
890 bnx2x_set_xumac_nig(params, 0, 0);
891 REG_WR(bp, xmac_base + XMAC_REG_CTRL,
892 XMAC_CTRL_REG_SOFT_RESET);
896 static int bnx2x_xmac_enable(struct link_params *params,
897 struct link_vars *vars, u8 lb)
900 struct bnx2x *bp = params->bp;
901 DP(NETIF_MSG_LINK, "enabling XMAC\n");
903 xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
905 bnx2x_xmac_init(bp, vars->line_speed);
908 * This register determines on which events the MAC will assert
909 * error on the i/f to the NIG along w/ EOP.
913 * This register tells the NIG whether to send traffic to UMAC
916 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0);
918 /* Set Max packet size */
919 REG_WR(bp, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710);
921 /* CRC append for Tx packets */
922 REG_WR(bp, xmac_base + XMAC_REG_TX_CTRL, 0xC800);
925 bnx2x_update_pfc_xmac(params, vars, 0);
927 /* Enable TX and RX */
928 val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
930 /* Check loopback mode */
932 val |= XMAC_CTRL_REG_CORE_LOCAL_LPBK;
933 REG_WR(bp, xmac_base + XMAC_REG_CTRL, val);
934 bnx2x_set_xumac_nig(params,
935 ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
937 vars->mac_type = MAC_TYPE_XMAC;
941 static int bnx2x_emac_enable(struct link_params *params,
942 struct link_vars *vars, u8 lb)
944 struct bnx2x *bp = params->bp;
945 u8 port = params->port;
946 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
949 DP(NETIF_MSG_LINK, "enabling EMAC\n");
951 /* enable emac and not bmac */
952 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
955 if (vars->phy_flags & PHY_XGXS_FLAG) {
956 u32 ser_lane = ((params->lane_config &
957 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
958 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
960 DP(NETIF_MSG_LINK, "XGXS\n");
961 /* select the master lanes (out of 0-3) */
962 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane);
964 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
966 } else { /* SerDes */
967 DP(NETIF_MSG_LINK, "SerDes\n");
969 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
972 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
974 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
977 if (CHIP_REV_IS_SLOW(bp)) {
978 /* config GMII mode */
979 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
980 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII));
982 /* pause enable/disable */
983 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
984 EMAC_RX_MODE_FLOW_EN);
986 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
987 (EMAC_TX_MODE_EXT_PAUSE_EN |
988 EMAC_TX_MODE_FLOW_EN));
989 if (!(params->feature_config_flags &
990 FEATURE_CONFIG_PFC_ENABLED)) {
991 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
992 bnx2x_bits_en(bp, emac_base +
993 EMAC_REG_EMAC_RX_MODE,
994 EMAC_RX_MODE_FLOW_EN);
996 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
997 bnx2x_bits_en(bp, emac_base +
998 EMAC_REG_EMAC_TX_MODE,
999 (EMAC_TX_MODE_EXT_PAUSE_EN |
1000 EMAC_TX_MODE_FLOW_EN));
1002 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1003 EMAC_TX_MODE_FLOW_EN);
1006 /* KEEP_VLAN_TAG, promiscuous */
1007 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
1008 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
1011 * Setting this bit causes MAC control frames (except for pause
1012 * frames) to be passed on for processing. This setting has no
1013 * affect on the operation of the pause frames. This bit effects
1014 * all packets regardless of RX Parser packet sorting logic.
1015 * Turn the PFC off to make sure we are in Xon state before
1018 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
1019 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
1020 DP(NETIF_MSG_LINK, "PFC is enabled\n");
1021 /* Enable PFC again */
1022 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
1023 EMAC_REG_RX_PFC_MODE_RX_EN |
1024 EMAC_REG_RX_PFC_MODE_TX_EN |
1025 EMAC_REG_RX_PFC_MODE_PRIORITIES);
1027 EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
1029 EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
1031 EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
1032 val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
1034 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
1037 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1042 EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
1045 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
1047 /* enable emac for jumbo packets */
1048 EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
1049 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
1050 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
1053 REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
1055 /* disable the NIG in/out to the bmac */
1056 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
1057 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
1058 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
1060 /* enable the NIG in/out to the emac */
1061 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
1063 if ((params->feature_config_flags &
1064 FEATURE_CONFIG_PFC_ENABLED) ||
1065 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1068 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
1069 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
1071 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
1073 vars->mac_type = MAC_TYPE_EMAC;
1077 static void bnx2x_update_pfc_bmac1(struct link_params *params,
1078 struct link_vars *vars)
1081 struct bnx2x *bp = params->bp;
1082 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1083 NIG_REG_INGRESS_BMAC0_MEM;
1086 if ((!(params->feature_config_flags &
1087 FEATURE_CONFIG_PFC_ENABLED)) &&
1088 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1089 /* Enable BigMAC to react on received Pause packets */
1093 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
1097 if (!(params->feature_config_flags &
1098 FEATURE_CONFIG_PFC_ENABLED) &&
1099 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1103 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
1106 static void bnx2x_update_pfc_bmac2(struct link_params *params,
1107 struct link_vars *vars,
1111 * Set rx control: Strip CRC and enable BigMAC to relay
1112 * control packets to the system as well
1115 struct bnx2x *bp = params->bp;
1116 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1117 NIG_REG_INGRESS_BMAC0_MEM;
1120 if ((!(params->feature_config_flags &
1121 FEATURE_CONFIG_PFC_ENABLED)) &&
1122 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1123 /* Enable BigMAC to react on received Pause packets */
1127 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
1132 if (!(params->feature_config_flags &
1133 FEATURE_CONFIG_PFC_ENABLED) &&
1134 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1138 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
1140 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
1141 DP(NETIF_MSG_LINK, "PFC is enabled\n");
1142 /* Enable PFC RX & TX & STATS and set 8 COS */
1144 wb_data[0] |= (1<<0); /* RX */
1145 wb_data[0] |= (1<<1); /* TX */
1146 wb_data[0] |= (1<<2); /* Force initial Xon */
1147 wb_data[0] |= (1<<3); /* 8 cos */
1148 wb_data[0] |= (1<<5); /* STATS */
1150 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
1152 /* Clear the force Xon */
1153 wb_data[0] &= ~(1<<2);
1155 DP(NETIF_MSG_LINK, "PFC is disabled\n");
1156 /* disable PFC RX & TX & STATS and set 8 COS */
1161 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
1164 * Set Time (based unit is 512 bit time) between automatic
1165 * re-sending of PP packets amd enable automatic re-send of
1166 * Per-Priroity Packet as long as pp_gen is asserted and
1167 * pp_disable is low.
1170 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
1171 val |= (1<<16); /* enable automatic re-send */
1175 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
1179 val = 0x3; /* Enable RX and TX */
1181 val |= 0x4; /* Local loopback */
1182 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
1184 /* When PFC enabled, Pass pause frames towards the NIG. */
1185 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
1186 val |= ((1<<6)|(1<<5));
1190 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
1194 /* PFC BRB internal port configuration params */
1195 struct bnx2x_pfc_brb_threshold_val {
1202 struct bnx2x_pfc_brb_e3b0_val {
1203 u32 full_lb_xoff_th;
1204 u32 full_lb_xon_threshold;
1206 u32 mac_0_class_t_guarantied;
1207 u32 mac_0_class_t_guarantied_hyst;
1208 u32 mac_1_class_t_guarantied;
1209 u32 mac_1_class_t_guarantied_hyst;
1212 struct bnx2x_pfc_brb_th_val {
1213 struct bnx2x_pfc_brb_threshold_val pauseable_th;
1214 struct bnx2x_pfc_brb_threshold_val non_pauseable_th;
1216 static int bnx2x_pfc_brb_get_config_params(
1217 struct link_params *params,
1218 struct bnx2x_pfc_brb_th_val *config_val)
1220 struct bnx2x *bp = params->bp;
1221 DP(NETIF_MSG_LINK, "Setting PFC BRB configuration\n");
1222 if (CHIP_IS_E2(bp)) {
1223 config_val->pauseable_th.pause_xoff =
1224 PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
1225 config_val->pauseable_th.pause_xon =
1226 PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE;
1227 config_val->pauseable_th.full_xoff =
1228 PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE;
1229 config_val->pauseable_th.full_xon =
1230 PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE;
1232 config_val->non_pauseable_th.pause_xoff =
1233 PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
1234 config_val->non_pauseable_th.pause_xon =
1235 PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
1236 config_val->non_pauseable_th.full_xoff =
1237 PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
1238 config_val->non_pauseable_th.full_xon =
1239 PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE;
1240 } else if (CHIP_IS_E3A0(bp)) {
1241 config_val->pauseable_th.pause_xoff =
1242 PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
1243 config_val->pauseable_th.pause_xon =
1244 PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE;
1245 config_val->pauseable_th.full_xoff =
1246 PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE;
1247 config_val->pauseable_th.full_xon =
1248 PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE;
1250 config_val->non_pauseable_th.pause_xoff =
1251 PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
1252 config_val->non_pauseable_th.pause_xon =
1253 PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
1254 config_val->non_pauseable_th.full_xoff =
1255 PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
1256 config_val->non_pauseable_th.full_xon =
1257 PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE;
1258 } else if (CHIP_IS_E3B0(bp)) {
1259 if (params->phy[INT_PHY].flags &
1260 FLAGS_4_PORT_MODE) {
1261 config_val->pauseable_th.pause_xoff =
1262 PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
1263 config_val->pauseable_th.pause_xon =
1264 PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE;
1265 config_val->pauseable_th.full_xoff =
1266 PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE;
1267 config_val->pauseable_th.full_xon =
1268 PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE;
1270 config_val->non_pauseable_th.pause_xoff =
1271 PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
1272 config_val->non_pauseable_th.pause_xon =
1273 PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
1274 config_val->non_pauseable_th.full_xoff =
1275 PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
1276 config_val->non_pauseable_th.full_xon =
1277 PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
1279 config_val->pauseable_th.pause_xoff =
1280 PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
1281 config_val->pauseable_th.pause_xon =
1282 PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE;
1283 config_val->pauseable_th.full_xoff =
1284 PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE;
1285 config_val->pauseable_th.full_xon =
1286 PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE;
1288 config_val->non_pauseable_th.pause_xoff =
1289 PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
1290 config_val->non_pauseable_th.pause_xon =
1291 PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
1292 config_val->non_pauseable_th.full_xoff =
1293 PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
1294 config_val->non_pauseable_th.full_xon =
1295 PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
1304 static void bnx2x_pfc_brb_get_e3b0_config_params(struct link_params *params,
1305 struct bnx2x_pfc_brb_e3b0_val
1310 if (params->phy[INT_PHY].flags & FLAGS_4_PORT_MODE) {
1311 e3b0_val->full_lb_xoff_th =
1312 PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR;
1313 e3b0_val->full_lb_xon_threshold =
1314 PFC_E3B0_4P_BRB_FULL_LB_XON_THR;
1315 e3b0_val->lb_guarantied =
1316 PFC_E3B0_4P_LB_GUART;
1317 e3b0_val->mac_0_class_t_guarantied =
1318 PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART;
1319 e3b0_val->mac_0_class_t_guarantied_hyst =
1320 PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST;
1321 e3b0_val->mac_1_class_t_guarantied =
1322 PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART;
1323 e3b0_val->mac_1_class_t_guarantied_hyst =
1324 PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST;
1326 e3b0_val->full_lb_xoff_th =
1327 PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR;
1328 e3b0_val->full_lb_xon_threshold =
1329 PFC_E3B0_2P_BRB_FULL_LB_XON_THR;
1330 e3b0_val->mac_0_class_t_guarantied_hyst =
1331 PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST;
1332 e3b0_val->mac_1_class_t_guarantied =
1333 PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART;
1334 e3b0_val->mac_1_class_t_guarantied_hyst =
1335 PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST;
1337 if (cos0_pauseable != cos1_pauseable) {
1338 /* nonpauseable= Lossy + pauseable = Lossless*/
1339 e3b0_val->lb_guarantied =
1340 PFC_E3B0_2P_MIX_PAUSE_LB_GUART;
1341 e3b0_val->mac_0_class_t_guarantied =
1342 PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART;
1343 } else if (cos0_pauseable) {
1344 /* Lossless +Lossless*/
1345 e3b0_val->lb_guarantied =
1346 PFC_E3B0_2P_PAUSE_LB_GUART;
1347 e3b0_val->mac_0_class_t_guarantied =
1348 PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART;
1351 e3b0_val->lb_guarantied =
1352 PFC_E3B0_2P_NON_PAUSE_LB_GUART;
1353 e3b0_val->mac_0_class_t_guarantied =
1354 PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART;
1358 static int bnx2x_update_pfc_brb(struct link_params *params,
1359 struct link_vars *vars,
1360 struct bnx2x_nig_brb_pfc_port_params
1363 struct bnx2x *bp = params->bp;
1364 struct bnx2x_pfc_brb_th_val config_val = { {0} };
1365 struct bnx2x_pfc_brb_threshold_val *reg_th_config =
1366 &config_val.pauseable_th;
1367 struct bnx2x_pfc_brb_e3b0_val e3b0_val = {0};
1368 int set_pfc = params->feature_config_flags &
1369 FEATURE_CONFIG_PFC_ENABLED;
1370 int bnx2x_status = 0;
1371 u8 port = params->port;
1373 /* default - pause configuration */
1374 reg_th_config = &config_val.pauseable_th;
1375 bnx2x_status = bnx2x_pfc_brb_get_config_params(params, &config_val);
1376 if (0 != bnx2x_status)
1377 return bnx2x_status;
1379 if (set_pfc && pfc_params)
1381 if (!pfc_params->cos0_pauseable)
1382 reg_th_config = &config_val.non_pauseable_th;
1384 * The number of free blocks below which the pause signal to class 0
1385 * of MAC #n is asserted. n=0,1
1387 REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XOFF_THRESHOLD_1 :
1388 BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 ,
1389 reg_th_config->pause_xoff);
1391 * The number of free blocks above which the pause signal to class 0
1392 * of MAC #n is de-asserted. n=0,1
1394 REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XON_THRESHOLD_1 :
1395 BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , reg_th_config->pause_xon);
1397 * The number of free blocks below which the full signal to class 0
1398 * of MAC #n is asserted. n=0,1
1400 REG_WR(bp, (port) ? BRB1_REG_FULL_0_XOFF_THRESHOLD_1 :
1401 BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , reg_th_config->full_xoff);
1403 * The number of free blocks above which the full signal to class 0
1404 * of MAC #n is de-asserted. n=0,1
1406 REG_WR(bp, (port) ? BRB1_REG_FULL_0_XON_THRESHOLD_1 :
1407 BRB1_REG_FULL_0_XON_THRESHOLD_0 , reg_th_config->full_xon);
1409 if (set_pfc && pfc_params) {
1411 if (pfc_params->cos1_pauseable)
1412 reg_th_config = &config_val.pauseable_th;
1414 reg_th_config = &config_val.non_pauseable_th;
1416 * The number of free blocks below which the pause signal to
1417 * class 1 of MAC #n is asserted. n=0,1
1419 REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XOFF_THRESHOLD_1 :
1420 BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0,
1421 reg_th_config->pause_xoff);
1423 * The number of free blocks above which the pause signal to
1424 * class 1 of MAC #n is de-asserted. n=0,1
1426 REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XON_THRESHOLD_1 :
1427 BRB1_REG_PAUSE_1_XON_THRESHOLD_0,
1428 reg_th_config->pause_xon);
1430 * The number of free blocks below which the full signal to
1431 * class 1 of MAC #n is asserted. n=0,1
1433 REG_WR(bp, (port) ? BRB1_REG_FULL_1_XOFF_THRESHOLD_1 :
1434 BRB1_REG_FULL_1_XOFF_THRESHOLD_0,
1435 reg_th_config->full_xoff);
1437 * The number of free blocks above which the full signal to
1438 * class 1 of MAC #n is de-asserted. n=0,1
1440 REG_WR(bp, (port) ? BRB1_REG_FULL_1_XON_THRESHOLD_1 :
1441 BRB1_REG_FULL_1_XON_THRESHOLD_0,
1442 reg_th_config->full_xon);
1445 if (CHIP_IS_E3B0(bp)) {
1446 /*Should be done by init tool */
1448 * BRB_empty_for_dup = BRB1_REG_BRB_EMPTY_THRESHOLD
1454 * The hysteresis on the guarantied buffer space for the Lb port
1455 * before signaling XON.
1457 REG_WR(bp, BRB1_REG_LB_GUARANTIED_HYST, 80);
1459 bnx2x_pfc_brb_get_e3b0_config_params(
1462 pfc_params->cos0_pauseable,
1463 pfc_params->cos1_pauseable);
1465 * The number of free blocks below which the full signal to the
1466 * LB port is asserted.
1468 REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD,
1469 e3b0_val.full_lb_xoff_th);
1471 * The number of free blocks above which the full signal to the
1472 * LB port is de-asserted.
1474 REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD,
1475 e3b0_val.full_lb_xon_threshold);
1477 * The number of blocks guarantied for the MAC #n port. n=0,1
1480 /*The number of blocks guarantied for the LB port.*/
1481 REG_WR(bp, BRB1_REG_LB_GUARANTIED,
1482 e3b0_val.lb_guarantied);
1485 * The number of blocks guarantied for the MAC #n port.
1487 REG_WR(bp, BRB1_REG_MAC_GUARANTIED_0,
1488 2 * e3b0_val.mac_0_class_t_guarantied);
1489 REG_WR(bp, BRB1_REG_MAC_GUARANTIED_1,
1490 2 * e3b0_val.mac_1_class_t_guarantied);
1492 * The number of blocks guarantied for class #t in MAC0. t=0,1
1494 REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED,
1495 e3b0_val.mac_0_class_t_guarantied);
1496 REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED,
1497 e3b0_val.mac_0_class_t_guarantied);
1499 * The hysteresis on the guarantied buffer space for class in
1502 REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED_HYST,
1503 e3b0_val.mac_0_class_t_guarantied_hyst);
1504 REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED_HYST,
1505 e3b0_val.mac_0_class_t_guarantied_hyst);
1508 * The number of blocks guarantied for class #t in MAC1.t=0,1
1510 REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED,
1511 e3b0_val.mac_1_class_t_guarantied);
1512 REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED,
1513 e3b0_val.mac_1_class_t_guarantied);
1515 * The hysteresis on the guarantied buffer space for class #t
1518 REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED_HYST,
1519 e3b0_val.mac_1_class_t_guarantied_hyst);
1520 REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED_HYST,
1521 e3b0_val.mac_1_class_t_guarantied_hyst);
1527 return bnx2x_status;
1530 /******************************************************************************
1532 * This function is needed because NIG ARB_CREDIT_WEIGHT_X are
1533 * not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
1534 ******************************************************************************/
1535 int bnx2x_pfc_nig_rx_priority_mask(struct bnx2x *bp,
1537 u32 priority_mask, u8 port)
1539 u32 nig_reg_rx_priority_mask_add = 0;
1541 switch (cos_entry) {
1543 nig_reg_rx_priority_mask_add = (port) ?
1544 NIG_REG_P1_RX_COS0_PRIORITY_MASK :
1545 NIG_REG_P0_RX_COS0_PRIORITY_MASK;
1548 nig_reg_rx_priority_mask_add = (port) ?
1549 NIG_REG_P1_RX_COS1_PRIORITY_MASK :
1550 NIG_REG_P0_RX_COS1_PRIORITY_MASK;
1553 nig_reg_rx_priority_mask_add = (port) ?
1554 NIG_REG_P1_RX_COS2_PRIORITY_MASK :
1555 NIG_REG_P0_RX_COS2_PRIORITY_MASK;
1560 nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK;
1565 nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK;
1570 nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK;
1574 REG_WR(bp, nig_reg_rx_priority_mask_add, priority_mask);
1578 static void bnx2x_update_pfc_nig(struct link_params *params,
1579 struct link_vars *vars,
1580 struct bnx2x_nig_brb_pfc_port_params *nig_params)
1582 u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
1583 u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0;
1584 u32 pkt_priority_to_cos = 0;
1585 struct bnx2x *bp = params->bp;
1586 u8 port = params->port;
1588 int set_pfc = params->feature_config_flags &
1589 FEATURE_CONFIG_PFC_ENABLED;
1590 DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
1593 * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
1594 * MAC control frames (that are not pause packets)
1595 * will be forwarded to the XCM.
1597 xcm_mask = REG_RD(bp,
1598 port ? NIG_REG_LLH1_XCM_MASK :
1599 NIG_REG_LLH0_XCM_MASK);
1601 * nig params will override non PFC params, since it's possible to
1602 * do transition from PFC to SAFC
1612 xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
1613 NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
1615 p0_hwpfc_enable = 1;
1618 llfc_out_en = nig_params->llfc_out_en;
1619 llfc_enable = nig_params->llfc_enable;
1620 pause_enable = nig_params->pause_enable;
1621 } else /*defaul non PFC mode - PAUSE */
1624 xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
1625 NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
1630 REG_WR(bp, port ? NIG_REG_BRB1_PAUSE_IN_EN :
1631 NIG_REG_BRB0_PAUSE_IN_EN, pause_enable);
1632 REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
1633 NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
1634 REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
1635 NIG_REG_LLFC_ENABLE_0, llfc_enable);
1636 REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
1637 NIG_REG_PAUSE_ENABLE_0, pause_enable);
1639 REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
1640 NIG_REG_PPP_ENABLE_0, ppp_enable);
1642 REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
1643 NIG_REG_LLH0_XCM_MASK, xcm_mask);
1645 REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
1647 /* output enable for RX_XCM # IF */
1648 REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en);
1650 /* HW PFC TX enable */
1651 REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable);
1655 pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
1657 for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++)
1658 bnx2x_pfc_nig_rx_priority_mask(bp, i,
1659 nig_params->rx_cos_priority_mask[i], port);
1661 REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
1662 NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
1663 nig_params->llfc_high_priority_classes);
1665 REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
1666 NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
1667 nig_params->llfc_low_priority_classes);
1669 REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
1670 NIG_REG_P0_PKT_PRIORITY_TO_COS,
1671 pkt_priority_to_cos);
1674 int bnx2x_update_pfc(struct link_params *params,
1675 struct link_vars *vars,
1676 struct bnx2x_nig_brb_pfc_port_params *pfc_params)
1679 * The PFC and pause are orthogonal to one another, meaning when
1680 * PFC is enabled, the pause are disabled, and when PFC is
1681 * disabled, pause are set according to the pause result.
1684 struct bnx2x *bp = params->bp;
1685 int bnx2x_status = 0;
1686 u8 bmac_loopback = (params->loopback_mode == LOOPBACK_BMAC);
1687 /* update NIG params */
1688 bnx2x_update_pfc_nig(params, vars, pfc_params);
1690 /* update BRB params */
1691 bnx2x_status = bnx2x_update_pfc_brb(params, vars, pfc_params);
1692 if (0 != bnx2x_status)
1693 return bnx2x_status;
1696 return bnx2x_status;
1698 DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
1700 bnx2x_update_pfc_xmac(params, vars, 0);
1702 val = REG_RD(bp, MISC_REG_RESET_REG_2);
1704 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
1706 DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
1707 bnx2x_emac_enable(params, vars, 0);
1708 return bnx2x_status;
1712 bnx2x_update_pfc_bmac2(params, vars, bmac_loopback);
1714 bnx2x_update_pfc_bmac1(params, vars);
1717 if ((params->feature_config_flags &
1718 FEATURE_CONFIG_PFC_ENABLED) ||
1719 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1721 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
1723 return bnx2x_status;
1727 static int bnx2x_bmac1_enable(struct link_params *params,
1728 struct link_vars *vars,
1731 struct bnx2x *bp = params->bp;
1732 u8 port = params->port;
1733 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1734 NIG_REG_INGRESS_BMAC0_MEM;
1738 DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
1743 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
1747 wb_data[0] = ((params->mac_addr[2] << 24) |
1748 (params->mac_addr[3] << 16) |
1749 (params->mac_addr[4] << 8) |
1750 params->mac_addr[5]);
1751 wb_data[1] = ((params->mac_addr[0] << 8) |
1752 params->mac_addr[1]);
1753 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
1759 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
1763 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
1766 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1768 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
1770 bnx2x_update_pfc_bmac1(params, vars);
1773 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1775 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
1777 /* set cnt max size */
1778 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1780 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
1782 /* configure safc */
1783 wb_data[0] = 0x1000200;
1785 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
1791 static int bnx2x_bmac2_enable(struct link_params *params,
1792 struct link_vars *vars,
1795 struct bnx2x *bp = params->bp;
1796 u8 port = params->port;
1797 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1798 NIG_REG_INGRESS_BMAC0_MEM;
1801 DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
1805 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
1808 /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
1811 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
1817 wb_data[0] = ((params->mac_addr[2] << 24) |
1818 (params->mac_addr[3] << 16) |
1819 (params->mac_addr[4] << 8) |
1820 params->mac_addr[5]);
1821 wb_data[1] = ((params->mac_addr[0] << 8) |
1822 params->mac_addr[1]);
1823 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
1828 /* Configure SAFC */
1829 wb_data[0] = 0x1000200;
1831 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
1836 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1838 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
1842 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1844 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
1846 /* set cnt max size */
1847 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
1849 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
1851 bnx2x_update_pfc_bmac2(params, vars, is_lb);
1856 static int bnx2x_bmac_enable(struct link_params *params,
1857 struct link_vars *vars,
1861 u8 port = params->port;
1862 struct bnx2x *bp = params->bp;
1864 /* reset and unreset the BigMac */
1865 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1866 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1869 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1870 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1872 /* enable access for bmac registers */
1873 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
1875 /* Enable BMAC according to BMAC type*/
1877 rc = bnx2x_bmac2_enable(params, vars, is_lb);
1879 rc = bnx2x_bmac1_enable(params, vars, is_lb);
1880 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
1881 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
1882 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
1884 if ((params->feature_config_flags &
1885 FEATURE_CONFIG_PFC_ENABLED) ||
1886 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1888 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
1889 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
1890 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
1891 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
1892 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
1893 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
1895 vars->mac_type = MAC_TYPE_BMAC;
1900 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
1902 struct bnx2x *bp = params->bp;
1904 REG_WR(bp, params->shmem_base +
1905 offsetof(struct shmem_region,
1906 port_mb[params->port].link_status), link_status);
1909 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
1911 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1912 NIG_REG_INGRESS_BMAC0_MEM;
1914 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
1916 /* Only if the bmac is out of reset */
1917 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
1918 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
1921 if (CHIP_IS_E2(bp)) {
1922 /* Clear Rx Enable bit in BMAC_CONTROL register */
1923 REG_RD_DMAE(bp, bmac_addr +
1924 BIGMAC2_REGISTER_BMAC_CONTROL,
1926 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
1927 REG_WR_DMAE(bp, bmac_addr +
1928 BIGMAC2_REGISTER_BMAC_CONTROL,
1931 /* Clear Rx Enable bit in BMAC_CONTROL register */
1932 REG_RD_DMAE(bp, bmac_addr +
1933 BIGMAC_REGISTER_BMAC_CONTROL,
1935 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
1936 REG_WR_DMAE(bp, bmac_addr +
1937 BIGMAC_REGISTER_BMAC_CONTROL,
1944 static int bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
1947 struct bnx2x *bp = params->bp;
1948 u8 port = params->port;
1953 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
1955 /* wait for init credit */
1956 init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
1957 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
1958 DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
1960 while ((init_crd != crd) && count) {
1963 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
1966 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
1967 if (init_crd != crd) {
1968 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
1973 if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
1974 line_speed == SPEED_10 ||
1975 line_speed == SPEED_100 ||
1976 line_speed == SPEED_1000 ||
1977 line_speed == SPEED_2500) {
1978 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
1979 /* update threshold */
1980 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
1981 /* update init credit */
1982 init_crd = 778; /* (800-18-4) */
1985 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
1987 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
1988 /* update threshold */
1989 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
1990 /* update init credit */
1991 switch (line_speed) {
1993 init_crd = thresh + 553 - 22;
1996 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2001 REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
2002 DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
2003 line_speed, init_crd);
2005 /* probe the credit changes */
2006 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
2008 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
2011 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
2016 * bnx2x_get_emac_base - retrive emac base address
2018 * @bp: driver handle
2019 * @mdc_mdio_access: access type
2022 * This function selects the MDC/MDIO access (through emac0 or
2023 * emac1) depend on the mdc_mdio_access, port, port swapped. Each
2024 * phy has a default access mode, which could also be overridden
2025 * by nvram configuration. This parameter, whether this is the
2026 * default phy configuration, or the nvram overrun
2027 * configuration, is passed here as mdc_mdio_access and selects
2028 * the emac_base for the CL45 read/writes operations
2030 static u32 bnx2x_get_emac_base(struct bnx2x *bp,
2031 u32 mdc_mdio_access, u8 port)
2034 switch (mdc_mdio_access) {
2035 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
2037 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
2038 if (REG_RD(bp, NIG_REG_PORT_SWAP))
2039 emac_base = GRCBASE_EMAC1;
2041 emac_base = GRCBASE_EMAC0;
2043 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
2044 if (REG_RD(bp, NIG_REG_PORT_SWAP))
2045 emac_base = GRCBASE_EMAC0;
2047 emac_base = GRCBASE_EMAC1;
2049 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
2050 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2052 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
2053 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
2062 /******************************************************************/
2063 /* CL45 access functions */
2064 /******************************************************************/
2065 static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
2066 u8 devad, u16 reg, u16 *ret_val)
2073 val = ((phy->addr << 21) | (devad << 16) | reg |
2074 EMAC_MDIO_COMM_COMMAND_ADDRESS |
2075 EMAC_MDIO_COMM_START_BUSY);
2076 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2078 for (i = 0; i < 50; i++) {
2081 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2082 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2087 if (val & EMAC_MDIO_COMM_START_BUSY) {
2088 DP(NETIF_MSG_LINK, "read phy register failed\n");
2089 netdev_err(bp->dev, "MDC/MDIO access timeout\n");
2094 val = ((phy->addr << 21) | (devad << 16) |
2095 EMAC_MDIO_COMM_COMMAND_READ_45 |
2096 EMAC_MDIO_COMM_START_BUSY);
2097 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2099 for (i = 0; i < 50; i++) {
2102 val = REG_RD(bp, phy->mdio_ctrl +
2103 EMAC_REG_EMAC_MDIO_COMM);
2104 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2105 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
2109 if (val & EMAC_MDIO_COMM_START_BUSY) {
2110 DP(NETIF_MSG_LINK, "read phy register failed\n");
2111 netdev_err(bp->dev, "MDC/MDIO access timeout\n");
2116 /* Work around for E3 A0 */
2117 if (phy->flags & FLAGS_MDC_MDIO_WA) {
2118 phy->flags ^= FLAGS_DUMMY_READ;
2119 if (phy->flags & FLAGS_DUMMY_READ) {
2121 bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
2128 static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
2129 u8 devad, u16 reg, u16 val)
2137 tmp = ((phy->addr << 21) | (devad << 16) | reg |
2138 EMAC_MDIO_COMM_COMMAND_ADDRESS |
2139 EMAC_MDIO_COMM_START_BUSY);
2140 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2142 for (i = 0; i < 50; i++) {
2145 tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2146 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2151 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2152 DP(NETIF_MSG_LINK, "write phy register failed\n");
2153 netdev_err(bp->dev, "MDC/MDIO access timeout\n");
2158 tmp = ((phy->addr << 21) | (devad << 16) | val |
2159 EMAC_MDIO_COMM_COMMAND_WRITE_45 |
2160 EMAC_MDIO_COMM_START_BUSY);
2161 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2163 for (i = 0; i < 50; i++) {
2166 tmp = REG_RD(bp, phy->mdio_ctrl +
2167 EMAC_REG_EMAC_MDIO_COMM);
2168 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2173 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2174 DP(NETIF_MSG_LINK, "write phy register failed\n");
2175 netdev_err(bp->dev, "MDC/MDIO access timeout\n");
2179 /* Work around for E3 A0 */
2180 if (phy->flags & FLAGS_MDC_MDIO_WA) {
2181 phy->flags ^= FLAGS_DUMMY_READ;
2182 if (phy->flags & FLAGS_DUMMY_READ) {
2184 bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
2192 /******************************************************************/
2193 /* BSC access functions from E3 */
2194 /******************************************************************/
2195 static void bnx2x_bsc_module_sel(struct link_params *params)
2198 u32 board_cfg, sfp_ctrl;
2199 u32 i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH];
2200 struct bnx2x *bp = params->bp;
2201 u8 port = params->port;
2202 /* Read I2C output PINs */
2203 board_cfg = REG_RD(bp, params->shmem_base +
2204 offsetof(struct shmem_region,
2205 dev_info.shared_hw_config.board));
2206 i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK;
2207 i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >>
2208 SHARED_HW_CFG_E3_I2C_MUX1_SHIFT;
2210 /* Read I2C output value */
2211 sfp_ctrl = REG_RD(bp, params->shmem_base +
2212 offsetof(struct shmem_region,
2213 dev_info.port_hw_config[port].e3_cmn_pin_cfg));
2214 i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0;
2215 i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0;
2216 DP(NETIF_MSG_LINK, "Setting BSC switch\n");
2217 for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++)
2218 bnx2x_set_cfg_pin(bp, i2c_pins[idx], i2c_val[idx]);
2221 static int bnx2x_bsc_read(struct link_params *params,
2222 struct bnx2x_phy *phy,
2231 struct bnx2x *bp = params->bp;
2233 if ((sl_devid != 0xa0) && (sl_devid != 0xa2)) {
2234 DP(NETIF_MSG_LINK, "invalid sl_devid 0x%x\n", sl_devid);
2238 if (xfer_cnt > 16) {
2239 DP(NETIF_MSG_LINK, "invalid xfer_cnt %d. Max is 16 bytes\n",
2243 bnx2x_bsc_module_sel(params);
2245 xfer_cnt = 16 - lc_addr;
2247 /* enable the engine */
2248 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
2249 val |= MCPR_IMC_COMMAND_ENABLE;
2250 REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
2252 /* program slave device ID */
2253 val = (sl_devid << 16) | sl_addr;
2254 REG_WR(bp, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val);
2256 /* start xfer with 0 byte to update the address pointer ???*/
2257 val = (MCPR_IMC_COMMAND_ENABLE) |
2258 (MCPR_IMC_COMMAND_WRITE_OP <<
2259 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
2260 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0);
2261 REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
2263 /* poll for completion */
2265 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
2266 while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
2268 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
2270 DP(NETIF_MSG_LINK, "wr 0 byte timed out after %d try\n",
2279 /* start xfer with read op */
2280 val = (MCPR_IMC_COMMAND_ENABLE) |
2281 (MCPR_IMC_COMMAND_READ_OP <<
2282 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
2283 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) |
2285 REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
2287 /* poll for completion */
2289 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
2290 while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
2292 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
2294 DP(NETIF_MSG_LINK, "rd op timed out after %d try\n", i);
2302 for (i = (lc_addr >> 2); i < 4; i++) {
2303 data_array[i] = REG_RD(bp, (MCP_REG_MCPR_IMC_DATAREG0 + i*4));
2305 data_array[i] = ((data_array[i] & 0x000000ff) << 24) |
2306 ((data_array[i] & 0x0000ff00) << 8) |
2307 ((data_array[i] & 0x00ff0000) >> 8) |
2308 ((data_array[i] & 0xff000000) >> 24);
2314 static void bnx2x_cl45_read_or_write(struct bnx2x *bp, struct bnx2x_phy *phy,
2315 u8 devad, u16 reg, u16 or_val)
2318 bnx2x_cl45_read(bp, phy, devad, reg, &val);
2319 bnx2x_cl45_write(bp, phy, devad, reg, val | or_val);
2322 int bnx2x_phy_read(struct link_params *params, u8 phy_addr,
2323 u8 devad, u16 reg, u16 *ret_val)
2327 * Probe for the phy according to the given phy_addr, and execute
2328 * the read request on it
2330 for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
2331 if (params->phy[phy_index].addr == phy_addr) {
2332 return bnx2x_cl45_read(params->bp,
2333 ¶ms->phy[phy_index], devad,
2340 int bnx2x_phy_write(struct link_params *params, u8 phy_addr,
2341 u8 devad, u16 reg, u16 val)
2345 * Probe for the phy according to the given phy_addr, and execute
2346 * the write request on it
2348 for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
2349 if (params->phy[phy_index].addr == phy_addr) {
2350 return bnx2x_cl45_write(params->bp,
2351 ¶ms->phy[phy_index], devad,
2357 static u8 bnx2x_get_warpcore_lane(struct bnx2x_phy *phy,
2358 struct link_params *params)
2361 struct bnx2x *bp = params->bp;
2362 u32 path_swap, path_swap_ovr;
2366 port = params->port;
2368 if (bnx2x_is_4_port_mode(bp)) {
2369 u32 port_swap, port_swap_ovr;
2371 /*figure out path swap value */
2372 path_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR);
2373 if (path_swap_ovr & 0x1)
2374 path_swap = (path_swap_ovr & 0x2);
2376 path_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP);
2381 /*figure out port swap value */
2382 port_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR);
2383 if (port_swap_ovr & 0x1)
2384 port_swap = (port_swap_ovr & 0x2);
2386 port_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP);
2391 lane = (port<<1) + path;
2392 } else { /* two port mode - no port swap */
2394 /*figure out path swap value */
2396 REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP_OVWR);
2397 if (path_swap_ovr & 0x1) {
2398 path_swap = (path_swap_ovr & 0x2);
2401 REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP);
2411 static void bnx2x_set_aer_mmd(struct link_params *params,
2412 struct bnx2x_phy *phy)
2415 u16 offset, aer_val;
2416 struct bnx2x *bp = params->bp;
2417 ser_lane = ((params->lane_config &
2418 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
2419 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
2421 offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
2422 (phy->addr + ser_lane) : 0;
2424 if (USES_WARPCORE(bp)) {
2425 aer_val = bnx2x_get_warpcore_lane(phy, params);
2427 * In Dual-lane mode, two lanes are joined together,
2428 * so in order to configure them, the AER broadcast method is
2430 * 0x200 is the broadcast address for lanes 0,1
2431 * 0x201 is the broadcast address for lanes 2,3
2433 if (phy->flags & FLAGS_WC_DUAL_MODE)
2434 aer_val = (aer_val >> 1) | 0x200;
2435 } else if (CHIP_IS_E2(bp))
2436 aer_val = 0x3800 + offset - 1;
2438 aer_val = 0x3800 + offset;
2439 DP(NETIF_MSG_LINK, "Set AER to 0x%x\n", aer_val);
2440 CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
2441 MDIO_AER_BLOCK_AER_REG, aer_val);
2445 /******************************************************************/
2446 /* Internal phy section */
2447 /******************************************************************/
2449 static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
2451 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2454 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
2455 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
2457 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
2460 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
2463 static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
2467 DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
2469 val = SERDES_RESET_BITS << (port*16);
2471 /* reset and unreset the SerDes/XGXS */
2472 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
2474 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
2476 bnx2x_set_serdes_access(bp, port);
2478 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + port*0x10,
2479 DEFAULT_PHY_DEV_ADDR);
2482 static void bnx2x_xgxs_deassert(struct link_params *params)
2484 struct bnx2x *bp = params->bp;
2487 DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
2488 port = params->port;
2490 val = XGXS_RESET_BITS << (port*16);
2492 /* reset and unreset the SerDes/XGXS */
2493 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
2495 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
2497 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0);
2498 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
2499 params->phy[INT_PHY].def_md_devad);
2502 static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
2503 struct link_params *params, u16 *ieee_fc)
2505 struct bnx2x *bp = params->bp;
2506 *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
2508 * resolve pause mode and advertisement Please refer to Table
2509 * 28B-3 of the 802.3ab-1999 spec
2512 switch (phy->req_flow_ctrl) {
2513 case BNX2X_FLOW_CTRL_AUTO:
2514 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH)
2515 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2518 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2521 case BNX2X_FLOW_CTRL_TX:
2522 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2525 case BNX2X_FLOW_CTRL_RX:
2526 case BNX2X_FLOW_CTRL_BOTH:
2527 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2530 case BNX2X_FLOW_CTRL_NONE:
2532 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
2535 DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
2538 static void set_phy_vars(struct link_params *params,
2539 struct link_vars *vars)
2541 struct bnx2x *bp = params->bp;
2542 u8 actual_phy_idx, phy_index, link_cfg_idx;
2543 u8 phy_config_swapped = params->multi_phy_config &
2544 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
2545 for (phy_index = INT_PHY; phy_index < params->num_phys;
2547 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
2548 actual_phy_idx = phy_index;
2549 if (phy_config_swapped) {
2550 if (phy_index == EXT_PHY1)
2551 actual_phy_idx = EXT_PHY2;
2552 else if (phy_index == EXT_PHY2)
2553 actual_phy_idx = EXT_PHY1;
2555 params->phy[actual_phy_idx].req_flow_ctrl =
2556 params->req_flow_ctrl[link_cfg_idx];
2558 params->phy[actual_phy_idx].req_line_speed =
2559 params->req_line_speed[link_cfg_idx];
2561 params->phy[actual_phy_idx].speed_cap_mask =
2562 params->speed_cap_mask[link_cfg_idx];
2564 params->phy[actual_phy_idx].req_duplex =
2565 params->req_duplex[link_cfg_idx];
2567 if (params->req_line_speed[link_cfg_idx] ==
2569 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
2571 DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
2572 " speed_cap_mask %x\n",
2573 params->phy[actual_phy_idx].req_flow_ctrl,
2574 params->phy[actual_phy_idx].req_line_speed,
2575 params->phy[actual_phy_idx].speed_cap_mask);
2579 static void bnx2x_ext_phy_set_pause(struct link_params *params,
2580 struct bnx2x_phy *phy,
2581 struct link_vars *vars)
2584 struct bnx2x *bp = params->bp;
2585 /* read modify write pause advertizing */
2586 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
2588 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2590 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2591 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2592 if ((vars->ieee_fc &
2593 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2594 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2595 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2597 if ((vars->ieee_fc &
2598 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2599 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2600 val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
2602 DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
2603 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
2606 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
2608 switch (pause_result) { /* ASYM P ASYM P */
2609 case 0xb: /* 1 0 1 1 */
2610 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
2613 case 0xe: /* 1 1 1 0 */
2614 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
2617 case 0x5: /* 0 1 0 1 */
2618 case 0x7: /* 0 1 1 1 */
2619 case 0xd: /* 1 1 0 1 */
2620 case 0xf: /* 1 1 1 1 */
2621 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
2627 if (pause_result & (1<<0))
2628 vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
2629 if (pause_result & (1<<1))
2630 vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
2633 static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
2634 struct link_params *params,
2635 struct link_vars *vars)
2637 struct bnx2x *bp = params->bp;
2638 u16 ld_pause; /* local */
2639 u16 lp_pause; /* link partner */
2644 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
2646 if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
2647 vars->flow_ctrl = phy->req_flow_ctrl;
2648 else if (phy->req_line_speed != SPEED_AUTO_NEG)
2649 vars->flow_ctrl = params->req_fc_auto_adv;
2650 else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
2652 bnx2x_cl45_read(bp, phy,
2654 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
2655 bnx2x_cl45_read(bp, phy,
2657 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
2658 pause_result = (ld_pause &
2659 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
2660 pause_result |= (lp_pause &
2661 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
2662 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
2664 bnx2x_pause_resolve(vars, pause_result);
2668 /******************************************************************/
2669 /* Warpcore section */
2670 /******************************************************************/
2671 /* The init_internal_warpcore should mirror the xgxs,
2672 * i.e. reset the lane (if needed), set aer for the
2673 * init configuration, and set/clear SGMII flag. Internal
2674 * phy init is done purely in phy_init stage.
2676 static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
2677 struct link_params *params,
2678 struct link_vars *vars) {
2679 u16 val16 = 0, lane;
2680 struct bnx2x *bp = params->bp;
2681 DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n");
2682 /* Check adding advertisement for 1G KX */
2683 if (((vars->line_speed == SPEED_AUTO_NEG) &&
2684 (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
2685 (vars->line_speed == SPEED_1000)) {
2689 /* Enable CL37 1G Parallel Detect */
2690 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
2691 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &sd_digital);
2692 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2693 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
2694 (sd_digital | 0x1));
2696 DP(NETIF_MSG_LINK, "Advertize 1G\n");
2698 if (((vars->line_speed == SPEED_AUTO_NEG) &&
2699 (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
2700 (vars->line_speed == SPEED_10000)) {
2701 /* Check adding advertisement for 10G KR */
2703 /* Enable 10G Parallel Detect */
2704 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
2705 MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
2707 DP(NETIF_MSG_LINK, "Advertize 10G\n");
2710 /* Set Transmit PMD settings */
2711 lane = bnx2x_get_warpcore_lane(phy, params);
2712 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2713 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
2714 ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
2715 (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
2716 (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
2717 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2718 MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
2720 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2721 MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL,
2723 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2724 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
2727 /* Advertised speeds */
2728 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
2729 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16);
2731 /* Advertise pause */
2732 bnx2x_ext_phy_set_pause(params, phy, vars);
2734 /* Enable Autoneg */
2735 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
2736 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1000);
2738 /* Over 1G - AN local device user page 1 */
2739 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2740 MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
2742 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
2743 MDIO_WC_REG_DIGITAL5_MISC7, &val16);
2745 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2746 MDIO_WC_REG_DIGITAL5_MISC7, val16 | 0x100);
2749 static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy,
2750 struct link_params *params,
2751 struct link_vars *vars)
2753 struct bnx2x *bp = params->bp;
2756 /* Disable Autoneg */
2757 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2758 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7);
2760 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
2761 MDIO_WC_REG_PAR_DET_10G_CTRL, 0);
2763 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2764 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0x3f00);
2766 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
2767 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0);
2769 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
2770 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
2772 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2773 MDIO_WC_REG_DIGITAL3_UP1, 0x1);
2775 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2776 MDIO_WC_REG_DIGITAL5_MISC7, 0xa);
2778 /* Disable CL36 PCS Tx */
2779 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2780 MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0);
2782 /* Double Wide Single Data Rate @ pll rate */
2783 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2784 MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF);
2786 /* Leave cl72 training enable, needed for KR */
2787 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
2788 MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150,
2791 /* Leave CL72 enabled */
2792 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
2793 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
2795 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2796 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
2799 /* Set speed via PMA/PMD register */
2800 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
2801 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
2803 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
2804 MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
2806 /*Enable encoded forced speed */
2807 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2808 MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
2810 /* Turn TX scramble payload only the 64/66 scrambler */
2811 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2812 MDIO_WC_REG_TX66_CONTROL, 0x9);
2814 /* Turn RX scramble payload only the 64/66 scrambler */
2815 bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
2816 MDIO_WC_REG_RX66_CONTROL, 0xF9);
2818 /* set and clear loopback to cause a reset to 64/66 decoder */
2819 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2820 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000);
2821 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2822 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
2826 static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
2827 struct link_params *params,
2830 struct bnx2x *bp = params->bp;
2831 u16 misc1_val, tap_val, tx_driver_val, lane, val;
2832 /* Hold rxSeqStart */
2833 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
2834 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
2835 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2836 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val | 0x8000));
2838 /* Hold tx_fifo_reset */
2839 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
2840 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
2841 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2842 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, (val | 0x1));
2844 /* Disable CL73 AN */
2845 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
2847 /* Disable 100FX Enable and Auto-Detect */
2848 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
2849 MDIO_WC_REG_FX100_CTRL1, &val);
2850 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2851 MDIO_WC_REG_FX100_CTRL1, (val & 0xFFFA));
2853 /* Disable 100FX Idle detect */
2854 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
2855 MDIO_WC_REG_FX100_CTRL3, &val);
2856 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2857 MDIO_WC_REG_FX100_CTRL3, (val | 0x0080));
2859 /* Set Block address to Remote PHY & Clear forced_speed[5] */
2860 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
2861 MDIO_WC_REG_DIGITAL4_MISC3, &val);
2862 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2863 MDIO_WC_REG_DIGITAL4_MISC3, (val & 0xFF7F));
2865 /* Turn off auto-detect & fiber mode */
2866 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
2867 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
2868 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2869 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
2872 /* Set filter_force_link, disable_false_link and parallel_detect */
2873 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
2874 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val);
2875 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2876 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
2877 ((val | 0x0006) & 0xFFFE));
2880 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
2881 MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val);
2883 misc1_val &= ~(0x1f);
2887 tap_val = ((0x08 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
2888 (0x37 << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
2889 (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
2891 ((0x00 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
2892 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
2893 (0x03 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
2897 tap_val = ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
2898 (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
2899 (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
2901 ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
2902 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
2903 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
2905 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2906 MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
2908 /* Set Transmit PMD settings */
2909 lane = bnx2x_get_warpcore_lane(phy, params);
2910 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2911 MDIO_WC_REG_TX_FIR_TAP,
2912 tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE);
2913 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2914 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
2917 /* Enable fiber mode, enable and invert sig_det */
2918 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
2919 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
2920 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2921 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, val | 0xd);
2923 /* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
2924 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
2925 MDIO_WC_REG_DIGITAL4_MISC3, &val);
2926 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2927 MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080);
2929 /* 10G XFI Full Duplex */
2930 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2931 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
2933 /* Release tx_fifo_reset */
2934 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
2935 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
2936 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2937 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, val & 0xFFFE);
2939 /* Release rxSeqStart */
2940 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
2941 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
2942 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2943 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val & 0x7FFF));
2946 static void bnx2x_warpcore_set_20G_KR2(struct bnx2x *bp,
2947 struct bnx2x_phy *phy)
2949 DP(NETIF_MSG_LINK, "KR2 still not supported !!!\n");
2952 static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp,
2953 struct bnx2x_phy *phy,
2956 /* Rx0 anaRxControl1G */
2957 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2958 MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90);
2960 /* Rx2 anaRxControl1G */
2961 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2962 MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90);
2964 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2965 MDIO_WC_REG_RX66_SCW0, 0xE070);
2967 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2968 MDIO_WC_REG_RX66_SCW1, 0xC0D0);
2970 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2971 MDIO_WC_REG_RX66_SCW2, 0xA0B0);
2973 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2974 MDIO_WC_REG_RX66_SCW3, 0x8090);
2976 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2977 MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0);
2979 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2980 MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0);
2982 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2983 MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0);
2985 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2986 MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0);
2988 /* Serdes Digital Misc1 */
2989 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2990 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008);
2992 /* Serdes Digital4 Misc3 */
2993 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2994 MDIO_WC_REG_DIGITAL4_MISC3, 0x8088);
2996 /* Set Transmit PMD settings */
2997 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
2998 MDIO_WC_REG_TX_FIR_TAP,
2999 ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3000 (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3001 (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET) |
3002 MDIO_WC_REG_TX_FIR_TAP_ENABLE));
3003 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3004 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3005 ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3006 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3007 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
3010 static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
3011 struct link_params *params,
3014 struct bnx2x *bp = params->bp;
3015 u16 val16, digctrl_kx1, digctrl_kx2;
3018 lane = bnx2x_get_warpcore_lane(phy, params);
3020 /* Clear XFI clock comp in non-10G single lane mode. */
3021 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3022 MDIO_WC_REG_RX66_CONTROL, &val16);
3023 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3024 MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13));
3026 if (phy->req_line_speed == SPEED_AUTO_NEG) {
3028 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3029 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3030 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3031 MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
3033 DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n");
3035 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3036 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3038 switch (phy->req_line_speed) {
3048 DP(NETIF_MSG_LINK, "Speed not supported: 0x%x"
3049 "\n", phy->req_line_speed);
3053 if (phy->req_duplex == DUPLEX_FULL)
3056 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3057 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16);
3059 DP(NETIF_MSG_LINK, "set SGMII force speed %d\n",
3060 phy->req_line_speed);
3061 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3062 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3063 DP(NETIF_MSG_LINK, " (readback) %x\n", val16);
3066 /* SGMII Slave mode and disable signal detect */
3067 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3068 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1);
3072 digctrl_kx1 &= 0xff4a;
3074 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3075 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3078 /* Turn off parallel detect */
3079 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3080 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2);
3081 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3082 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3083 (digctrl_kx2 & ~(1<<2)));
3085 /* Re-enable parallel detect */
3086 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3087 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3088 (digctrl_kx2 | (1<<2)));
3090 /* Enable autodet */
3091 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3092 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3093 (digctrl_kx1 | 0x10));
3096 static void bnx2x_warpcore_reset_lane(struct bnx2x *bp,
3097 struct bnx2x_phy *phy,
3101 /* Take lane out of reset after configuration is finished */
3102 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3103 MDIO_WC_REG_DIGITAL5_MISC6, &val);
3108 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3109 MDIO_WC_REG_DIGITAL5_MISC6, val);
3110 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3111 MDIO_WC_REG_DIGITAL5_MISC6, &val);
3115 /* Clear SFI/XFI link settings registers */
3116 static void bnx2x_warpcore_clear_regs(struct bnx2x_phy *phy,
3117 struct link_params *params,
3120 struct bnx2x *bp = params->bp;
3123 /* Set XFI clock comp as default. */
3124 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3125 MDIO_WC_REG_RX66_CONTROL, &val16);
3126 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3127 MDIO_WC_REG_RX66_CONTROL, val16 | (3<<13));
3129 bnx2x_warpcore_reset_lane(bp, phy, 1);
3130 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
3131 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3132 MDIO_WC_REG_FX100_CTRL1, 0x014a);
3133 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3134 MDIO_WC_REG_FX100_CTRL3, 0x0800);
3135 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3136 MDIO_WC_REG_DIGITAL4_MISC3, 0x8008);
3137 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3138 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x0195);
3139 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3140 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x0007);
3141 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3142 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x0002);
3143 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3144 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000);
3145 lane = bnx2x_get_warpcore_lane(phy, params);
3146 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3147 MDIO_WC_REG_TX_FIR_TAP, 0x0000);
3148 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3149 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990);
3150 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3151 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
3152 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3153 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140);
3154 bnx2x_warpcore_reset_lane(bp, phy, 0);
3157 static int bnx2x_get_mod_abs_int_cfg(struct bnx2x *bp,
3159 u32 shmem_base, u8 port,
3160 u8 *gpio_num, u8 *gpio_port)
3165 if (CHIP_IS_E3(bp)) {
3166 cfg_pin = (REG_RD(bp, shmem_base +
3167 offsetof(struct shmem_region,
3168 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
3169 PORT_HW_CFG_E3_MOD_ABS_MASK) >>
3170 PORT_HW_CFG_E3_MOD_ABS_SHIFT;
3173 * Should not happen. This function called upon interrupt
3174 * triggered by GPIO ( since EPIO can only generate interrupts
3176 * So if this function was called and none of the GPIOs was set,
3177 * it means the shit hit the fan.
3179 if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
3180 (cfg_pin > PIN_CFG_GPIO3_P1)) {
3181 DP(NETIF_MSG_LINK, "ERROR: Invalid cfg pin %x for "
3182 "module detect indication\n",
3187 *gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
3188 *gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
3190 *gpio_num = MISC_REGISTERS_GPIO_3;
3193 DP(NETIF_MSG_LINK, "MOD_ABS int GPIO%d_P%d\n", *gpio_num, *gpio_port);
3197 static int bnx2x_is_sfp_module_plugged(struct bnx2x_phy *phy,
3198 struct link_params *params)
3200 struct bnx2x *bp = params->bp;
3201 u8 gpio_num, gpio_port;
3203 if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id,
3204 params->shmem_base, params->port,
3205 &gpio_num, &gpio_port) != 0)
3207 gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
3209 /* Call the handling function in case module is detected */
3216 static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
3217 struct link_params *params,
3218 struct link_vars *vars)
3220 struct bnx2x *bp = params->bp;
3223 u16 lane = bnx2x_get_warpcore_lane(phy, params);
3224 serdes_net_if = (REG_RD(bp, params->shmem_base +
3225 offsetof(struct shmem_region, dev_info.
3226 port_hw_config[params->port].default_cfg)) &
3227 PORT_HW_CFG_NET_SERDES_IF_MASK);
3228 DP(NETIF_MSG_LINK, "Begin Warpcore init, link_speed %d, "
3229 "serdes_net_if = 0x%x\n",
3230 vars->line_speed, serdes_net_if);
3231 bnx2x_set_aer_mmd(params, phy);
3233 vars->phy_flags |= PHY_XGXS_FLAG;
3234 if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
3235 (phy->req_line_speed &&
3236 ((phy->req_line_speed == SPEED_100) ||
3237 (phy->req_line_speed == SPEED_10)))) {
3238 vars->phy_flags |= PHY_SGMII_FLAG;
3239 DP(NETIF_MSG_LINK, "Setting SGMII mode\n");
3240 bnx2x_warpcore_clear_regs(phy, params, lane);
3241 bnx2x_warpcore_set_sgmii_speed(phy, params, 0);
3243 switch (serdes_net_if) {
3244 case PORT_HW_CFG_NET_SERDES_IF_KR:
3245 /* Enable KR Auto Neg */
3246 if (params->loopback_mode == LOOPBACK_NONE)
3247 bnx2x_warpcore_enable_AN_KR(phy, params, vars);
3249 DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n");
3250 bnx2x_warpcore_set_10G_KR(phy, params, vars);
3254 case PORT_HW_CFG_NET_SERDES_IF_XFI:
3255 bnx2x_warpcore_clear_regs(phy, params, lane);
3256 if (vars->line_speed == SPEED_10000) {
3257 DP(NETIF_MSG_LINK, "Setting 10G XFI\n");
3258 bnx2x_warpcore_set_10G_XFI(phy, params, 1);
3260 if (SINGLE_MEDIA_DIRECT(params)) {
3261 DP(NETIF_MSG_LINK, "1G Fiber\n");
3264 DP(NETIF_MSG_LINK, "10/100/1G SGMII\n");
3267 bnx2x_warpcore_set_sgmii_speed(phy,
3274 case PORT_HW_CFG_NET_SERDES_IF_SFI:
3276 bnx2x_warpcore_clear_regs(phy, params, lane);
3277 if (vars->line_speed == SPEED_10000) {
3278 DP(NETIF_MSG_LINK, "Setting 10G SFI\n");
3279 bnx2x_warpcore_set_10G_XFI(phy, params, 0);
3280 } else if (vars->line_speed == SPEED_1000) {
3281 DP(NETIF_MSG_LINK, "Setting 1G Fiber\n");
3282 bnx2x_warpcore_set_sgmii_speed(phy, params, 1);
3284 /* Issue Module detection */
3285 if (bnx2x_is_sfp_module_plugged(phy, params))
3286 bnx2x_sfp_module_detection(phy, params);
3289 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
3290 if (vars->line_speed != SPEED_20000) {
3291 DP(NETIF_MSG_LINK, "Speed not supported yet\n");
3294 DP(NETIF_MSG_LINK, "Setting 20G DXGXS\n");
3295 bnx2x_warpcore_set_20G_DXGXS(bp, phy, lane);
3296 /* Issue Module detection */
3298 bnx2x_sfp_module_detection(phy, params);
3301 case PORT_HW_CFG_NET_SERDES_IF_KR2:
3302 if (vars->line_speed != SPEED_20000) {
3303 DP(NETIF_MSG_LINK, "Speed not supported yet\n");
3306 DP(NETIF_MSG_LINK, "Setting 20G KR2\n");
3307 bnx2x_warpcore_set_20G_KR2(bp, phy);
3311 DP(NETIF_MSG_LINK, "Unsupported Serdes Net Interface "
3312 "0x%x\n", serdes_net_if);
3317 /* Take lane out of reset after configuration is finished */
3318 bnx2x_warpcore_reset_lane(bp, phy, 0);
3319 DP(NETIF_MSG_LINK, "Exit config init\n");
3322 static void bnx2x_sfp_e3_set_transmitter(struct link_params *params,
3323 struct bnx2x_phy *phy,
3326 struct bnx2x *bp = params->bp;
3328 u8 port = params->port;
3330 cfg_pin = REG_RD(bp, params->shmem_base +
3331 offsetof(struct shmem_region,
3332 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
3333 PORT_HW_CFG_TX_LASER_MASK;
3334 /* Set the !tx_en since this pin is DISABLE_TX_LASER */
3335 DP(NETIF_MSG_LINK, "Setting WC TX to %d\n", tx_en);
3336 /* For 20G, the expected pin to be used is 3 pins after the current */
3338 bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1);
3339 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
3340 bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1);
3343 static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy,
3344 struct link_params *params)
3346 struct bnx2x *bp = params->bp;
3348 bnx2x_sfp_e3_set_transmitter(params, phy, 0);
3349 bnx2x_set_mdio_clk(bp, params->chip_id, params->port);
3350 bnx2x_set_aer_mmd(params, phy);
3351 /* Global register */
3352 bnx2x_warpcore_reset_lane(bp, phy, 1);
3354 /* Clear loopback settings (if any) */
3356 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3357 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3358 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3359 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 &
3362 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3363 MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
3364 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3365 MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 & 0xfffe);
3367 /* Update those 1-copy registers */
3368 CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
3369 MDIO_AER_BLOCK_AER_REG, 0);
3370 /* Enable 1G MDIO (1-copy) */
3371 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3372 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
3374 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3375 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
3378 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3379 MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
3380 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3381 MDIO_WC_REG_XGXSBLK1_LANECTRL2,
3386 static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy,
3387 struct link_params *params)
3389 struct bnx2x *bp = params->bp;
3392 DP(NETIF_MSG_LINK, "Setting Warpcore loopback type %x, speed %d\n",
3393 params->loopback_mode, phy->req_line_speed);
3395 if (phy->req_line_speed < SPEED_10000) {
3398 /* Update those 1-copy registers */
3399 CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
3400 MDIO_AER_BLOCK_AER_REG, 0);
3401 /* Enable 1G MDIO (1-copy) */
3402 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3403 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
3405 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3406 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
3408 /* Set 1G loopback based on lane (1-copy) */
3409 lane = bnx2x_get_warpcore_lane(phy, params);
3410 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3411 MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
3412 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3413 MDIO_WC_REG_XGXSBLK1_LANECTRL2,
3416 /* Switch back to 4-copy registers */
3417 bnx2x_set_aer_mmd(params, phy);
3418 /* Global loopback, not recommended. */
3419 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3420 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3421 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3422 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 |
3426 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3427 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3428 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3429 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 |
3432 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3433 MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
3434 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3435 MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 | 0x1);
3440 void bnx2x_link_status_update(struct link_params *params,
3441 struct link_vars *vars)
3443 struct bnx2x *bp = params->bp;
3445 u8 port = params->port;
3446 u32 sync_offset, media_types;
3447 /* Update PHY configuration */
3448 set_phy_vars(params, vars);
3450 vars->link_status = REG_RD(bp, params->shmem_base +
3451 offsetof(struct shmem_region,
3452 port_mb[port].link_status));
3454 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
3455 vars->phy_flags = PHY_XGXS_FLAG;
3456 if (vars->link_up) {
3457 DP(NETIF_MSG_LINK, "phy link up\n");
3459 vars->phy_link_up = 1;
3460 vars->duplex = DUPLEX_FULL;
3461 switch (vars->link_status &
3462 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
3464 vars->duplex = DUPLEX_HALF;
3467 vars->line_speed = SPEED_10;
3471 vars->duplex = DUPLEX_HALF;
3475 vars->line_speed = SPEED_100;
3479 vars->duplex = DUPLEX_HALF;
3482 vars->line_speed = SPEED_1000;
3486 vars->duplex = DUPLEX_HALF;
3489 vars->line_speed = SPEED_2500;
3493 vars->line_speed = SPEED_10000;
3496 vars->line_speed = SPEED_20000;
3501 vars->flow_ctrl = 0;
3502 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
3503 vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
3505 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
3506 vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
3508 if (!vars->flow_ctrl)
3509 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3511 if (vars->line_speed &&
3512 ((vars->line_speed == SPEED_10) ||
3513 (vars->line_speed == SPEED_100))) {
3514 vars->phy_flags |= PHY_SGMII_FLAG;
3516 vars->phy_flags &= ~PHY_SGMII_FLAG;
3518 if (vars->line_speed &&
3519 USES_WARPCORE(bp) &&
3520 (vars->line_speed == SPEED_1000))
3521 vars->phy_flags |= PHY_SGMII_FLAG;
3522 /* anything 10 and over uses the bmac */
3523 link_10g_plus = (vars->line_speed >= SPEED_10000);
3525 if (link_10g_plus) {
3526 if (USES_WARPCORE(bp))
3527 vars->mac_type = MAC_TYPE_XMAC;
3529 vars->mac_type = MAC_TYPE_BMAC;
3531 if (USES_WARPCORE(bp))
3532 vars->mac_type = MAC_TYPE_UMAC;
3534 vars->mac_type = MAC_TYPE_EMAC;
3536 } else { /* link down */
3537 DP(NETIF_MSG_LINK, "phy link down\n");
3539 vars->phy_link_up = 0;
3541 vars->line_speed = 0;
3542 vars->duplex = DUPLEX_FULL;
3543 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3545 /* indicate no mac active */
3546 vars->mac_type = MAC_TYPE_NONE;
3549 /* Sync media type */
3550 sync_offset = params->shmem_base +
3551 offsetof(struct shmem_region,
3552 dev_info.port_hw_config[port].media_type);
3553 media_types = REG_RD(bp, sync_offset);
3555 params->phy[INT_PHY].media_type =
3556 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
3557 PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
3558 params->phy[EXT_PHY1].media_type =
3559 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
3560 PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
3561 params->phy[EXT_PHY2].media_type =
3562 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
3563 PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
3564 DP(NETIF_MSG_LINK, "media_types = 0x%x\n", media_types);
3566 /* Sync AEU offset */
3567 sync_offset = params->shmem_base +
3568 offsetof(struct shmem_region,
3569 dev_info.port_hw_config[port].aeu_int_mask);
3571 vars->aeu_int_mask = REG_RD(bp, sync_offset);
3573 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x int_mask 0x%x\n",
3574 vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
3575 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
3576 vars->line_speed, vars->duplex, vars->flow_ctrl);
3580 static void bnx2x_set_master_ln(struct link_params *params,
3581 struct bnx2x_phy *phy)
3583 struct bnx2x *bp = params->bp;
3584 u16 new_master_ln, ser_lane;
3585 ser_lane = ((params->lane_config &
3586 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3587 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3589 /* set the master_ln for AN */
3590 CL22_RD_OVER_CL45(bp, phy,
3591 MDIO_REG_BANK_XGXS_BLOCK2,
3592 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
3595 CL22_WR_OVER_CL45(bp, phy,
3596 MDIO_REG_BANK_XGXS_BLOCK2 ,
3597 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
3598 (new_master_ln | ser_lane));
3601 static int bnx2x_reset_unicore(struct link_params *params,
3602 struct bnx2x_phy *phy,
3605 struct bnx2x *bp = params->bp;
3608 CL22_RD_OVER_CL45(bp, phy,
3609 MDIO_REG_BANK_COMBO_IEEE0,
3610 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
3612 /* reset the unicore */
3613 CL22_WR_OVER_CL45(bp, phy,
3614 MDIO_REG_BANK_COMBO_IEEE0,
3615 MDIO_COMBO_IEEE0_MII_CONTROL,
3617 MDIO_COMBO_IEEO_MII_CONTROL_RESET));
3619 bnx2x_set_serdes_access(bp, params->port);
3621 /* wait for the reset to self clear */
3622 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
3625 /* the reset erased the previous bank value */
3626 CL22_RD_OVER_CL45(bp, phy,
3627 MDIO_REG_BANK_COMBO_IEEE0,
3628 MDIO_COMBO_IEEE0_MII_CONTROL,
3631 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
3637 netdev_err(bp->dev, "Warning: PHY was not initialized,"
3640 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
3645 static void bnx2x_set_swap_lanes(struct link_params *params,
3646 struct bnx2x_phy *phy)
3648 struct bnx2x *bp = params->bp;
3650 * Each two bits represents a lane number:
3651 * No swap is 0123 => 0x1b no need to enable the swap
3653 u16 ser_lane, rx_lane_swap, tx_lane_swap;
3655 ser_lane = ((params->lane_config &
3656 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3657 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3658 rx_lane_swap = ((params->lane_config &
3659 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
3660 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
3661 tx_lane_swap = ((params->lane_config &
3662 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
3663 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
3665 if (rx_lane_swap != 0x1b) {
3666 CL22_WR_OVER_CL45(bp, phy,
3667 MDIO_REG_BANK_XGXS_BLOCK2,
3668 MDIO_XGXS_BLOCK2_RX_LN_SWAP,
3670 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
3671 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
3673 CL22_WR_OVER_CL45(bp, phy,
3674 MDIO_REG_BANK_XGXS_BLOCK2,
3675 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
3678 if (tx_lane_swap != 0x1b) {
3679 CL22_WR_OVER_CL45(bp, phy,
3680 MDIO_REG_BANK_XGXS_BLOCK2,
3681 MDIO_XGXS_BLOCK2_TX_LN_SWAP,
3683 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
3685 CL22_WR_OVER_CL45(bp, phy,
3686 MDIO_REG_BANK_XGXS_BLOCK2,
3687 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
3691 static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
3692 struct link_params *params)
3694 struct bnx2x *bp = params->bp;
3696 CL22_RD_OVER_CL45(bp, phy,
3697 MDIO_REG_BANK_SERDES_DIGITAL,
3698 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
3700 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
3701 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
3703 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
3704 DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
3705 phy->speed_cap_mask, control2);
3706 CL22_WR_OVER_CL45(bp, phy,
3707 MDIO_REG_BANK_SERDES_DIGITAL,
3708 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
3711 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3712 (phy->speed_cap_mask &
3713 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
3714 DP(NETIF_MSG_LINK, "XGXS\n");
3716 CL22_WR_OVER_CL45(bp, phy,
3717 MDIO_REG_BANK_10G_PARALLEL_DETECT,
3718 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
3719 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
3721 CL22_RD_OVER_CL45(bp, phy,
3722 MDIO_REG_BANK_10G_PARALLEL_DETECT,
3723 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
3728 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
3730 CL22_WR_OVER_CL45(bp, phy,
3731 MDIO_REG_BANK_10G_PARALLEL_DETECT,
3732 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
3735 /* Disable parallel detection of HiG */
3736 CL22_WR_OVER_CL45(bp, phy,
3737 MDIO_REG_BANK_XGXS_BLOCK2,
3738 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
3739 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
3740 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
3744 static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
3745 struct link_params *params,
3746 struct link_vars *vars,
3749 struct bnx2x *bp = params->bp;
3753 CL22_RD_OVER_CL45(bp, phy,
3754 MDIO_REG_BANK_COMBO_IEEE0,
3755 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
3757 /* CL37 Autoneg Enabled */
3758 if (vars->line_speed == SPEED_AUTO_NEG)
3759 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
3760 else /* CL37 Autoneg Disabled */
3761 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
3762 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
3764 CL22_WR_OVER_CL45(bp, phy,
3765 MDIO_REG_BANK_COMBO_IEEE0,
3766 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
3768 /* Enable/Disable Autodetection */
3770 CL22_RD_OVER_CL45(bp, phy,
3771 MDIO_REG_BANK_SERDES_DIGITAL,
3772 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val);
3773 reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
3774 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
3775 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
3776 if (vars->line_speed == SPEED_AUTO_NEG)
3777 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
3779 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
3781 CL22_WR_OVER_CL45(bp, phy,
3782 MDIO_REG_BANK_SERDES_DIGITAL,
3783 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
3785 /* Enable TetonII and BAM autoneg */
3786 CL22_RD_OVER_CL45(bp, phy,
3787 MDIO_REG_BANK_BAM_NEXT_PAGE,
3788 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
3790 if (vars->line_speed == SPEED_AUTO_NEG) {
3791 /* Enable BAM aneg Mode and TetonII aneg Mode */
3792 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
3793 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
3795 /* TetonII and BAM Autoneg Disabled */
3796 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
3797 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
3799 CL22_WR_OVER_CL45(bp, phy,
3800 MDIO_REG_BANK_BAM_NEXT_PAGE,
3801 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
3805 /* Enable Cl73 FSM status bits */
3806 CL22_WR_OVER_CL45(bp, phy,
3807 MDIO_REG_BANK_CL73_USERB0,
3808 MDIO_CL73_USERB0_CL73_UCTRL,
3811 /* Enable BAM Station Manager*/
3812 CL22_WR_OVER_CL45(bp, phy,
3813 MDIO_REG_BANK_CL73_USERB0,
3814 MDIO_CL73_USERB0_CL73_BAM_CTRL1,
3815 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
3816 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
3817 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
3819 /* Advertise CL73 link speeds */
3820 CL22_RD_OVER_CL45(bp, phy,
3821 MDIO_REG_BANK_CL73_IEEEB1,
3822 MDIO_CL73_IEEEB1_AN_ADV2,
3824 if (phy->speed_cap_mask &
3825 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3826 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
3827 if (phy->speed_cap_mask &
3828 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
3829 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
3831 CL22_WR_OVER_CL45(bp, phy,
3832 MDIO_REG_BANK_CL73_IEEEB1,
3833 MDIO_CL73_IEEEB1_AN_ADV2,
3836 /* CL73 Autoneg Enabled */
3837 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
3839 } else /* CL73 Autoneg Disabled */
3842 CL22_WR_OVER_CL45(bp, phy,
3843 MDIO_REG_BANK_CL73_IEEEB0,
3844 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
3847 /* program SerDes, forced speed */
3848 static void bnx2x_program_serdes(struct bnx2x_phy *phy,
3849 struct link_params *params,
3850 struct link_vars *vars)
3852 struct bnx2x *bp = params->bp;
3855 /* program duplex, disable autoneg and sgmii*/
3856 CL22_RD_OVER_CL45(bp, phy,
3857 MDIO_REG_BANK_COMBO_IEEE0,
3858 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
3859 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
3860 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
3861 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
3862 if (phy->req_duplex == DUPLEX_FULL)
3863 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
3864 CL22_WR_OVER_CL45(bp, phy,
3865 MDIO_REG_BANK_COMBO_IEEE0,
3866 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
3870 * - needed only if the speed is greater than 1G (2.5G or 10G)
3872 CL22_RD_OVER_CL45(bp, phy,
3873 MDIO_REG_BANK_SERDES_DIGITAL,
3874 MDIO_SERDES_DIGITAL_MISC1, ®_val);
3875 /* clearing the speed value before setting the right speed */
3876 DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
3878 reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
3879 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
3881 if (!((vars->line_speed == SPEED_1000) ||
3882 (vars->line_speed == SPEED_100) ||
3883 (vars->line_speed == SPEED_10))) {
3885 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
3886 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
3887 if (vars->line_speed == SPEED_10000)
3889 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
3892 CL22_WR_OVER_CL45(bp, phy,
3893 MDIO_REG_BANK_SERDES_DIGITAL,
3894 MDIO_SERDES_DIGITAL_MISC1, reg_val);
3898 static void bnx2x_set_brcm_cl37_advertisement(struct bnx2x_phy *phy,
3899 struct link_params *params)
3901 struct bnx2x *bp = params->bp;
3904 /* configure the 48 bits for BAM AN */
3906 /* set extended capabilities */
3907 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
3908 val |= MDIO_OVER_1G_UP1_2_5G;
3909 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3910 val |= MDIO_OVER_1G_UP1_10G;
3911 CL22_WR_OVER_CL45(bp, phy,
3912 MDIO_REG_BANK_OVER_1G,
3913 MDIO_OVER_1G_UP1, val);
3915 CL22_WR_OVER_CL45(bp, phy,
3916 MDIO_REG_BANK_OVER_1G,
3917 MDIO_OVER_1G_UP3, 0x400);
3920 static void bnx2x_set_ieee_aneg_advertisement(struct bnx2x_phy *phy,
3921 struct link_params *params,
3924 struct bnx2x *bp = params->bp;
3926 /* for AN, we are always publishing full duplex */
3928 CL22_WR_OVER_CL45(bp, phy,
3929 MDIO_REG_BANK_COMBO_IEEE0,
3930 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
3931 CL22_RD_OVER_CL45(bp, phy,
3932 MDIO_REG_BANK_CL73_IEEEB1,
3933 MDIO_CL73_IEEEB1_AN_ADV1, &val);
3934 val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
3935 val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
3936 CL22_WR_OVER_CL45(bp, phy,
3937 MDIO_REG_BANK_CL73_IEEEB1,
3938 MDIO_CL73_IEEEB1_AN_ADV1, val);
3941 static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
3942 struct link_params *params,
3945 struct bnx2x *bp = params->bp;
3948 DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
3949 /* Enable and restart BAM/CL37 aneg */
3952 CL22_RD_OVER_CL45(bp, phy,
3953 MDIO_REG_BANK_CL73_IEEEB0,
3954 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
3957 CL22_WR_OVER_CL45(bp, phy,
3958 MDIO_REG_BANK_CL73_IEEEB0,
3959 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
3961 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
3962 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
3965 CL22_RD_OVER_CL45(bp, phy,
3966 MDIO_REG_BANK_COMBO_IEEE0,
3967 MDIO_COMBO_IEEE0_MII_CONTROL,
3970 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
3972 CL22_WR_OVER_CL45(bp, phy,
3973 MDIO_REG_BANK_COMBO_IEEE0,
3974 MDIO_COMBO_IEEE0_MII_CONTROL,
3976 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
3977 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
3981 static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
3982 struct link_params *params,
3983 struct link_vars *vars)
3985 struct bnx2x *bp = params->bp;
3988 /* in SGMII mode, the unicore is always slave */
3990 CL22_RD_OVER_CL45(bp, phy,
3991 MDIO_REG_BANK_SERDES_DIGITAL,
3992 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
3994 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
3995 /* set sgmii mode (and not fiber) */
3996 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
3997 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
3998 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
3999 CL22_WR_OVER_CL45(bp, phy,
4000 MDIO_REG_BANK_SERDES_DIGITAL,
4001 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
4004 /* if forced speed */
4005 if (!(vars->line_speed == SPEED_AUTO_NEG)) {
4006 /* set speed, disable autoneg */
4009 CL22_RD_OVER_CL45(bp, phy,
4010 MDIO_REG_BANK_COMBO_IEEE0,
4011 MDIO_COMBO_IEEE0_MII_CONTROL,
4013 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4014 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
4015 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
4017 switch (vars->line_speed) {
4020 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
4024 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
4027 /* there is nothing to set for 10M */
4030 /* invalid speed for SGMII */
4031 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
4036 /* setting the full duplex */
4037 if (phy->req_duplex == DUPLEX_FULL)
4039 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
4040 CL22_WR_OVER_CL45(bp, phy,
4041 MDIO_REG_BANK_COMBO_IEEE0,
4042 MDIO_COMBO_IEEE0_MII_CONTROL,
4045 } else { /* AN mode */
4046 /* enable and restart AN */
4047 bnx2x_restart_autoneg(phy, params, 0);
4056 static int bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
4057 struct link_params *params)
4059 struct bnx2x *bp = params->bp;
4060 u16 pd_10g, status2_1000x;
4061 if (phy->req_line_speed != SPEED_AUTO_NEG)
4063 CL22_RD_OVER_CL45(bp, phy,
4064 MDIO_REG_BANK_SERDES_DIGITAL,
4065 MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
4067 CL22_RD_OVER_CL45(bp, phy,
4068 MDIO_REG_BANK_SERDES_DIGITAL,
4069 MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
4071 if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
4072 DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
4077 CL22_RD_OVER_CL45(bp, phy,
4078 MDIO_REG_BANK_10G_PARALLEL_DETECT,
4079 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
4082 if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
4083 DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
4090 static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
4091 struct link_params *params,
4092 struct link_vars *vars,
4095 struct bnx2x *bp = params->bp;
4096 u16 ld_pause; /* local driver */
4097 u16 lp_pause; /* link partner */
4100 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4102 /* resolve from gp_status in case of AN complete and not sgmii */
4103 if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
4104 vars->flow_ctrl = phy->req_flow_ctrl;
4105 else if (phy->req_line_speed != SPEED_AUTO_NEG)
4106 vars->flow_ctrl = params->req_fc_auto_adv;
4107 else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
4108 (!(vars->phy_flags & PHY_SGMII_FLAG))) {
4109 if (bnx2x_direct_parallel_detect_used(phy, params)) {
4110 vars->flow_ctrl = params->req_fc_auto_adv;
4114 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
4115 MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
4116 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
4117 MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
4119 CL22_RD_OVER_CL45(bp, phy,
4120 MDIO_REG_BANK_CL73_IEEEB1,
4121 MDIO_CL73_IEEEB1_AN_ADV1,
4123 CL22_RD_OVER_CL45(bp, phy,
4124 MDIO_REG_BANK_CL73_IEEEB1,
4125 MDIO_CL73_IEEEB1_AN_LP_ADV1,
4127 pause_result = (ld_pause &
4128 MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
4130 pause_result |= (lp_pause &
4131 MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
4133 DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
4136 CL22_RD_OVER_CL45(bp, phy,
4137 MDIO_REG_BANK_COMBO_IEEE0,
4138 MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
4140 CL22_RD_OVER_CL45(bp, phy,
4141 MDIO_REG_BANK_COMBO_IEEE0,
4142 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
4144 pause_result = (ld_pause &
4145 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
4146 pause_result |= (lp_pause &
4147 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
4148 DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
4151 bnx2x_pause_resolve(vars, pause_result);
4153 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
4156 static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
4157 struct link_params *params)
4159 struct bnx2x *bp = params->bp;
4160 u16 rx_status, ustat_val, cl37_fsm_received;
4161 DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
4162 /* Step 1: Make sure signal is detected */
4163 CL22_RD_OVER_CL45(bp, phy,
4167 if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
4168 (MDIO_RX0_RX_STATUS_SIGDET)) {
4169 DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
4170 "rx_status(0x80b0) = 0x%x\n", rx_status);
4171 CL22_WR_OVER_CL45(bp, phy,
4172 MDIO_REG_BANK_CL73_IEEEB0,
4173 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
4174 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
4177 /* Step 2: Check CL73 state machine */
4178 CL22_RD_OVER_CL45(bp, phy,
4179 MDIO_REG_BANK_CL73_USERB0,
4180 MDIO_CL73_USERB0_CL73_USTAT1,
4183 (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
4184 MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
4185 (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
4186 MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
4187 DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
4188 "ustat_val(0x8371) = 0x%x\n", ustat_val);
4192 * Step 3: Check CL37 Message Pages received to indicate LP
4193 * supports only CL37
4195 CL22_RD_OVER_CL45(bp, phy,
4196 MDIO_REG_BANK_REMOTE_PHY,
4197 MDIO_REMOTE_PHY_MISC_RX_STATUS,
4198 &cl37_fsm_received);
4199 if ((cl37_fsm_received &
4200 (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
4201 MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
4202 (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
4203 MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
4204 DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
4205 "misc_rx_status(0x8330) = 0x%x\n",
4210 * The combined cl37/cl73 fsm state information indicating that
4211 * we are connected to a device which does not support cl73, but
4212 * does support cl37 BAM. In this case we disable cl73 and
4213 * restart cl37 auto-neg
4217 CL22_WR_OVER_CL45(bp, phy,
4218 MDIO_REG_BANK_CL73_IEEEB0,
4219 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
4221 /* Restart CL37 autoneg */
4222 bnx2x_restart_autoneg(phy, params, 0);
4223 DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
4226 static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
4227 struct link_params *params,
4228 struct link_vars *vars,
4231 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
4232 vars->link_status |=
4233 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
4235 if (bnx2x_direct_parallel_detect_used(phy, params))
4236 vars->link_status |=
4237 LINK_STATUS_PARALLEL_DETECTION_USED;
4239 static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,
4240 struct link_params *params,
4241 struct link_vars *vars,
4246 struct bnx2x *bp = params->bp;
4247 if (phy->req_line_speed == SPEED_AUTO_NEG)
4248 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
4250 DP(NETIF_MSG_LINK, "phy link up\n");
4252 vars->phy_link_up = 1;
4253 vars->link_status |= LINK_STATUS_LINK_UP;
4255 switch (speed_mask) {
4257 vars->line_speed = SPEED_10;
4258 if (vars->duplex == DUPLEX_FULL)
4259 vars->link_status |= LINK_10TFD;
4261 vars->link_status |= LINK_10THD;
4264 case GP_STATUS_100M:
4265 vars->line_speed = SPEED_100;
4266 if (vars->duplex == DUPLEX_FULL)
4267 vars->link_status |= LINK_100TXFD;
4269 vars->link_status |= LINK_100TXHD;
4273 case GP_STATUS_1G_KX:
4274 vars->line_speed = SPEED_1000;
4275 if (vars->duplex == DUPLEX_FULL)
4276 vars->link_status |= LINK_1000TFD;
4278 vars->link_status |= LINK_1000THD;
4281 case GP_STATUS_2_5G:
4282 vars->line_speed = SPEED_2500;
4283 if (vars->duplex == DUPLEX_FULL)
4284 vars->link_status |= LINK_2500TFD;
4286 vars->link_status |= LINK_2500THD;
4292 "link speed unsupported gp_status 0x%x\n",
4296 case GP_STATUS_10G_KX4:
4297 case GP_STATUS_10G_HIG:
4298 case GP_STATUS_10G_CX4:
4299 case GP_STATUS_10G_KR:
4300 case GP_STATUS_10G_SFI:
4301 case GP_STATUS_10G_XFI:
4302 vars->line_speed = SPEED_10000;
4303 vars->link_status |= LINK_10GTFD;
4305 case GP_STATUS_20G_DXGXS:
4306 vars->line_speed = SPEED_20000;
4307 vars->link_status |= LINK_20GTFD;
4311 "link speed unsupported gp_status 0x%x\n",
4315 } else { /* link_down */
4316 DP(NETIF_MSG_LINK, "phy link down\n");
4318 vars->phy_link_up = 0;
4320 vars->duplex = DUPLEX_FULL;
4321 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4322 vars->mac_type = MAC_TYPE_NONE;
4324 DP(NETIF_MSG_LINK, " phy_link_up %x line_speed %d\n",
4325 vars->phy_link_up, vars->line_speed);
4329 static int bnx2x_link_settings_status(struct bnx2x_phy *phy,
4330 struct link_params *params,
4331 struct link_vars *vars)
4334 struct bnx2x *bp = params->bp;
4336 u16 gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask;
4339 /* Read gp_status */
4340 CL22_RD_OVER_CL45(bp, phy,
4341 MDIO_REG_BANK_GP_STATUS,
4342 MDIO_GP_STATUS_TOP_AN_STATUS1,
4344 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
4345 duplex = DUPLEX_FULL;
4346 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)
4348 speed_mask = gp_status & GP_STATUS_SPEED_MASK;
4349 DP(NETIF_MSG_LINK, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x\n",
4350 gp_status, link_up, speed_mask);
4351 rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
4356 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
4357 if (SINGLE_MEDIA_DIRECT(params)) {
4358 bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
4359 if (phy->req_line_speed == SPEED_AUTO_NEG)
4360 bnx2x_xgxs_an_resolve(phy, params, vars,
4363 } else { /* link_down */
4364 if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
4365 SINGLE_MEDIA_DIRECT(params)) {
4366 /* Check signal is detected */
4367 bnx2x_check_fallback_to_cl37(phy, params);
4371 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n",
4372 vars->duplex, vars->flow_ctrl, vars->link_status);
4376 static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy,
4377 struct link_params *params,
4378 struct link_vars *vars)
4381 struct bnx2x *bp = params->bp;
4384 u16 gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL;
4386 lane = bnx2x_get_warpcore_lane(phy, params);
4387 /* Read gp_status */
4388 if (phy->req_line_speed > SPEED_10000) {
4390 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4392 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4394 DP(NETIF_MSG_LINK, "PCS RX link status = 0x%x-->0x%x\n",
4395 temp_link_up, link_up);
4398 bnx2x_ext_phy_resolve_fc(phy, params, vars);
4400 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4401 MDIO_WC_REG_GP2_STATUS_GP_2_1, &gp_status1);
4402 DP(NETIF_MSG_LINK, "0x81d1 = 0x%x\n", gp_status1);
4403 /* Check for either KR or generic link up. */
4404 gp_status1 = ((gp_status1 >> 8) & 0xf) |
4405 ((gp_status1 >> 12) & 0xf);
4406 link_up = gp_status1 & (1 << lane);
4407 if (link_up && SINGLE_MEDIA_DIRECT(params)) {
4409 if (phy->req_line_speed == SPEED_AUTO_NEG) {
4410 /* Check Autoneg complete */
4411 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4412 MDIO_WC_REG_GP2_STATUS_GP_2_4,
4414 if (gp_status4 & ((1<<12)<<lane))
4415 vars->link_status |=
4416 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
4418 /* Check parallel detect used */
4419 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4420 MDIO_WC_REG_PAR_DET_10G_STATUS,
4423 vars->link_status |=
4424 LINK_STATUS_PARALLEL_DETECTION_USED;
4426 bnx2x_ext_phy_resolve_fc(phy, params, vars);
4431 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4432 MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed);
4434 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4435 MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed);
4437 DP(NETIF_MSG_LINK, "lane %d gp_speed 0x%x\n", lane, gp_speed);
4439 if ((lane & 1) == 0)
4444 rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed,
4447 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n",
4448 vars->duplex, vars->flow_ctrl, vars->link_status);
4451 static void bnx2x_set_gmii_tx_driver(struct link_params *params)
4453 struct bnx2x *bp = params->bp;
4454 struct bnx2x_phy *phy = ¶ms->phy[INT_PHY];
4460 CL22_RD_OVER_CL45(bp, phy,
4461 MDIO_REG_BANK_OVER_1G,
4462 MDIO_OVER_1G_LP_UP2, &lp_up2);
4464 /* bits [10:7] at lp_up2, positioned at [15:12] */
4465 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
4466 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
4467 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
4472 for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
4473 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
4474 CL22_RD_OVER_CL45(bp, phy,
4476 MDIO_TX0_TX_DRIVER, &tx_driver);
4478 /* replace tx_driver bits [15:12] */
4480 (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
4481 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
4482 tx_driver |= lp_up2;
4483 CL22_WR_OVER_CL45(bp, phy,
4485 MDIO_TX0_TX_DRIVER, tx_driver);
4490 static int bnx2x_emac_program(struct link_params *params,
4491 struct link_vars *vars)
4493 struct bnx2x *bp = params->bp;
4494 u8 port = params->port;
4497 DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
4498 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
4500 (EMAC_MODE_25G_MODE |
4501 EMAC_MODE_PORT_MII_10M |
4502 EMAC_MODE_HALF_DUPLEX));
4503 switch (vars->line_speed) {
4505 mode |= EMAC_MODE_PORT_MII_10M;
4509 mode |= EMAC_MODE_PORT_MII;
4513 mode |= EMAC_MODE_PORT_GMII;
4517 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
4521 /* 10G not valid for EMAC */
4522 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
4527 if (vars->duplex == DUPLEX_HALF)
4528 mode |= EMAC_MODE_HALF_DUPLEX;
4530 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
4533 bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
4537 static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
4538 struct link_params *params)
4542 struct bnx2x *bp = params->bp;
4544 for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
4545 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
4546 CL22_WR_OVER_CL45(bp, phy,
4548 MDIO_RX0_RX_EQ_BOOST,
4549 phy->rx_preemphasis[i]);
4552 for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
4553 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
4554 CL22_WR_OVER_CL45(bp, phy,
4557 phy->tx_preemphasis[i]);
4561 static void bnx2x_xgxs_config_init(struct bnx2x_phy *phy,
4562 struct link_params *params,
4563 struct link_vars *vars)
4565 struct bnx2x *bp = params->bp;
4566 u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
4567 (params->loopback_mode == LOOPBACK_XGXS));
4568 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
4569 if (SINGLE_MEDIA_DIRECT(params) &&
4570 (params->feature_config_flags &
4571 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
4572 bnx2x_set_preemphasis(phy, params);
4574 /* forced speed requested? */
4575 if (vars->line_speed != SPEED_AUTO_NEG ||
4576 (SINGLE_MEDIA_DIRECT(params) &&
4577 params->loopback_mode == LOOPBACK_EXT)) {
4578 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
4580 /* disable autoneg */
4581 bnx2x_set_autoneg(phy, params, vars, 0);
4583 /* program speed and duplex */
4584 bnx2x_program_serdes(phy, params, vars);
4586 } else { /* AN_mode */
4587 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
4590 bnx2x_set_brcm_cl37_advertisement(phy, params);
4592 /* program duplex & pause advertisement (for aneg) */
4593 bnx2x_set_ieee_aneg_advertisement(phy, params,
4596 /* enable autoneg */
4597 bnx2x_set_autoneg(phy, params, vars, enable_cl73);
4599 /* enable and restart AN */
4600 bnx2x_restart_autoneg(phy, params, enable_cl73);
4603 } else { /* SGMII mode */
4604 DP(NETIF_MSG_LINK, "SGMII\n");
4606 bnx2x_initialize_sgmii_process(phy, params, vars);
4610 static int bnx2x_prepare_xgxs(struct bnx2x_phy *phy,
4611 struct link_params *params,
4612 struct link_vars *vars)
4615 vars->phy_flags |= PHY_XGXS_FLAG;
4616 if ((phy->req_line_speed &&
4617 ((phy->req_line_speed == SPEED_100) ||
4618 (phy->req_line_speed == SPEED_10))) ||
4619 (!phy->req_line_speed &&
4620 (phy->speed_cap_mask >=
4621 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
4622 (phy->speed_cap_mask <
4623 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
4624 (phy->type == PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD))
4625 vars->phy_flags |= PHY_SGMII_FLAG;
4627 vars->phy_flags &= ~PHY_SGMII_FLAG;
4629 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
4630 bnx2x_set_aer_mmd(params, phy);
4631 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
4632 bnx2x_set_master_ln(params, phy);
4634 rc = bnx2x_reset_unicore(params, phy, 0);
4635 /* reset the SerDes and wait for reset bit return low */
4639 bnx2x_set_aer_mmd(params, phy);
4640 /* setting the masterLn_def again after the reset */
4641 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
4642 bnx2x_set_master_ln(params, phy);
4643 bnx2x_set_swap_lanes(params, phy);
4649 static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
4650 struct bnx2x_phy *phy,
4651 struct link_params *params)
4654 /* Wait for soft reset to get cleared up to 1 sec */
4655 for (cnt = 0; cnt < 1000; cnt++) {
4656 bnx2x_cl45_read(bp, phy,
4657 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl);
4658 if (!(ctrl & (1<<15)))
4664 netdev_err(bp->dev, "Warning: PHY was not initialized,"
4667 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
4671 static void bnx2x_link_int_enable(struct link_params *params)
4673 u8 port = params->port;
4675 struct bnx2x *bp = params->bp;
4677 /* Setting the status to report on link up for either XGXS or SerDes */
4678 if (CHIP_IS_E3(bp)) {
4679 mask = NIG_MASK_XGXS0_LINK_STATUS;
4680 if (!(SINGLE_MEDIA_DIRECT(params)))
4681 mask |= NIG_MASK_MI_INT;
4682 } else if (params->switch_cfg == SWITCH_CFG_10G) {
4683 mask = (NIG_MASK_XGXS0_LINK10G |
4684 NIG_MASK_XGXS0_LINK_STATUS);
4685 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
4686 if (!(SINGLE_MEDIA_DIRECT(params)) &&
4687 params->phy[INT_PHY].type !=
4688 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
4689 mask |= NIG_MASK_MI_INT;
4690 DP(NETIF_MSG_LINK, "enabled external phy int\n");
4693 } else { /* SerDes */
4694 mask = NIG_MASK_SERDES0_LINK_STATUS;
4695 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
4696 if (!(SINGLE_MEDIA_DIRECT(params)) &&
4697 params->phy[INT_PHY].type !=
4698 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
4699 mask |= NIG_MASK_MI_INT;
4700 DP(NETIF_MSG_LINK, "enabled external phy int\n");
4704 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4707 DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
4708 (params->switch_cfg == SWITCH_CFG_10G),
4709 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4710 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
4711 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4712 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4713 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
4714 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4715 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4716 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4719 static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port,
4722 u32 latch_status = 0;
4725 * Disable the MI INT ( external phy int ) by writing 1 to the
4726 * status register. Link down indication is high-active-signal,
4727 * so in this case we need to write the status to clear the XOR
4729 /* Read Latched signals */
4730 latch_status = REG_RD(bp,
4731 NIG_REG_LATCH_STATUS_0 + port*8);
4732 DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status);
4733 /* Handle only those with latched-signal=up.*/
4736 NIG_REG_STATUS_INTERRUPT_PORT0
4738 NIG_STATUS_EMAC0_MI_INT);
4741 NIG_REG_STATUS_INTERRUPT_PORT0
4743 NIG_STATUS_EMAC0_MI_INT);
4745 if (latch_status & 1) {
4747 /* For all latched-signal=up : Re-Arm Latch signals */
4748 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
4749 (latch_status & 0xfffe) | (latch_status & 1));
4751 /* For all latched-signal=up,Write original_signal to status */
4754 static void bnx2x_link_int_ack(struct link_params *params,
4755 struct link_vars *vars, u8 is_10g_plus)
4757 struct bnx2x *bp = params->bp;
4758 u8 port = params->port;
4761 * First reset all status we assume only one line will be
4764 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4765 (NIG_STATUS_XGXS0_LINK10G |
4766 NIG_STATUS_XGXS0_LINK_STATUS |
4767 NIG_STATUS_SERDES0_LINK_STATUS));
4768 if (vars->phy_link_up) {
4769 if (USES_WARPCORE(bp))
4770 mask = NIG_STATUS_XGXS0_LINK_STATUS;
4773 mask = NIG_STATUS_XGXS0_LINK10G;
4774 else if (params->switch_cfg == SWITCH_CFG_10G) {
4776 * Disable the link interrupt by writing 1 to
4777 * the relevant lane in the status register
4780 ((params->lane_config &
4781 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4782 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4783 mask = ((1 << ser_lane) <<
4784 NIG_STATUS_XGXS0_LINK_STATUS_SIZE);
4786 mask = NIG_STATUS_SERDES0_LINK_STATUS;
4788 DP(NETIF_MSG_LINK, "Ack link up interrupt with mask 0x%x\n",
4791 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4796 static int bnx2x_format_ver(u32 num, u8 *str, u16 *len)
4799 u32 mask = 0xf0000000;
4802 u8 remove_leading_zeros = 1;
4804 /* Need more than 10chars for this format */
4812 digit = ((num & mask) >> shift);
4813 if (digit == 0 && remove_leading_zeros) {
4816 } else if (digit < 0xa)
4817 *str_ptr = digit + '0';
4819 *str_ptr = digit - 0xa + 'a';
4820 remove_leading_zeros = 0;
4828 remove_leading_zeros = 1;
4835 static int bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
4842 int bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
4843 u8 *version, u16 len)
4848 u8 *ver_p = version;
4849 u16 remain_len = len;
4850 if (version == NULL || params == NULL)
4854 /* Extract first external phy*/
4856 spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
4858 if (params->phy[EXT_PHY1].format_fw_ver) {
4859 status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
4862 ver_p += (len - remain_len);
4864 if ((params->num_phys == MAX_PHYS) &&
4865 (params->phy[EXT_PHY2].ver_addr != 0)) {
4866 spirom_ver = REG_RD(bp, params->phy[EXT_PHY2].ver_addr);
4867 if (params->phy[EXT_PHY2].format_fw_ver) {
4871 status |= params->phy[EXT_PHY2].format_fw_ver(
4875 ver_p = version + (len - remain_len);
4882 static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
4883 struct link_params *params)
4885 u8 port = params->port;
4886 struct bnx2x *bp = params->bp;
4888 if (phy->req_line_speed != SPEED_1000) {
4891 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
4893 if (!CHIP_IS_E3(bp)) {
4894 /* change the uni_phy_addr in the nig */
4895 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
4898 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
4902 bnx2x_cl45_write(bp, phy,
4904 (MDIO_REG_BANK_AER_BLOCK +
4905 (MDIO_AER_BLOCK_AER_REG & 0xf)),
4908 bnx2x_cl45_write(bp, phy,
4910 (MDIO_REG_BANK_CL73_IEEEB0 +
4911 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
4914 /* set aer mmd back */
4915 bnx2x_set_aer_mmd(params, phy);
4917 if (!CHIP_IS_E3(bp)) {
4919 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
4924 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
4925 bnx2x_cl45_read(bp, phy, 5,
4926 (MDIO_REG_BANK_COMBO_IEEE0 +
4927 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
4929 bnx2x_cl45_write(bp, phy, 5,
4930 (MDIO_REG_BANK_COMBO_IEEE0 +
4931 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
4933 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
4937 int bnx2x_set_led(struct link_params *params,
4938 struct link_vars *vars, u8 mode, u32 speed)
4940 u8 port = params->port;
4941 u16 hw_led_mode = params->hw_led_mode;
4945 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4946 struct bnx2x *bp = params->bp;
4947 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
4948 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
4949 speed, hw_led_mode);
4951 for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) {
4952 if (params->phy[phy_idx].set_link_led) {
4953 params->phy[phy_idx].set_link_led(
4954 ¶ms->phy[phy_idx], params, mode);
4959 case LED_MODE_FRONT_PANEL_OFF:
4961 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
4962 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
4963 SHARED_HW_CFG_LED_MAC1);
4965 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4966 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
4971 * For all other phys, OPER mode is same as ON, so in case
4972 * link is down, do nothing
4977 if (((params->phy[EXT_PHY1].type ==
4978 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) ||
4979 (params->phy[EXT_PHY1].type ==
4980 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722)) &&
4981 CHIP_IS_E2(bp) && params->num_phys == 2) {
4983 * This is a work-around for E2+8727 Configurations
4985 if (mode == LED_MODE_ON ||
4986 speed == SPEED_10000){
4987 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
4988 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
4990 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4991 EMAC_WR(bp, EMAC_REG_EMAC_LED,
4992 (tmp | EMAC_LED_OVERRIDE));
4995 } else if (SINGLE_MEDIA_DIRECT(params) &&
4999 * This is a work-around for HW issue found when link
5002 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
5003 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
5005 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
5008 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
5009 /* Set blinking rate to ~15.9Hz */
5010 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
5011 LED_BLINK_RATE_VAL);
5012 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
5014 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5015 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp & (~EMAC_LED_OVERRIDE)));
5017 if (CHIP_IS_E1(bp) &&
5018 ((speed == SPEED_2500) ||
5019 (speed == SPEED_1000) ||
5020 (speed == SPEED_100) ||
5021 (speed == SPEED_10))) {
5023 * On Everest 1 Ax chip versions for speeds less than
5024 * 10G LED scheme is different
5026 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5028 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
5030 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
5037 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
5046 * This function comes to reflect the actual link state read DIRECTLY from the
5049 int bnx2x_test_link(struct link_params *params, struct link_vars *vars,
5052 struct bnx2x *bp = params->bp;
5053 u16 gp_status = 0, phy_index = 0;
5054 u8 ext_phy_link_up = 0, serdes_phy_type;
5055 struct link_vars temp_vars;
5056 struct bnx2x_phy *int_phy = ¶ms->phy[INT_PHY];
5058 if (CHIP_IS_E3(bp)) {
5060 if (params->req_line_speed[LINK_CONFIG_IDX(INT_PHY)]
5062 /* Check 20G link */
5063 bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
5065 bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
5069 /* Check 10G link and below*/
5070 u8 lane = bnx2x_get_warpcore_lane(int_phy, params);
5071 bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
5072 MDIO_WC_REG_GP2_STATUS_GP_2_1,
5074 gp_status = ((gp_status >> 8) & 0xf) |
5075 ((gp_status >> 12) & 0xf);
5076 link_up = gp_status & (1 << lane);
5081 CL22_RD_OVER_CL45(bp, int_phy,
5082 MDIO_REG_BANK_GP_STATUS,
5083 MDIO_GP_STATUS_TOP_AN_STATUS1,
5085 /* link is up only if both local phy and external phy are up */
5086 if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
5089 /* In XGXS loopback mode, do not check external PHY */
5090 if (params->loopback_mode == LOOPBACK_XGXS)
5093 switch (params->num_phys) {
5095 /* No external PHY */
5098 ext_phy_link_up = params->phy[EXT_PHY1].read_status(
5099 ¶ms->phy[EXT_PHY1],
5100 params, &temp_vars);
5102 case 3: /* Dual Media */
5103 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
5105 serdes_phy_type = ((params->phy[phy_index].media_type ==
5106 ETH_PHY_SFP_FIBER) ||
5107 (params->phy[phy_index].media_type ==
5108 ETH_PHY_XFP_FIBER) ||
5109 (params->phy[phy_index].media_type ==
5110 ETH_PHY_DA_TWINAX));
5112 if (is_serdes != serdes_phy_type)
5114 if (params->phy[phy_index].read_status) {
5116 params->phy[phy_index].read_status(
5117 ¶ms->phy[phy_index],
5118 params, &temp_vars);
5123 if (ext_phy_link_up)
5128 static int bnx2x_link_initialize(struct link_params *params,
5129 struct link_vars *vars)
5132 u8 phy_index, non_ext_phy;
5133 struct bnx2x *bp = params->bp;
5135 * In case of external phy existence, the line speed would be the
5136 * line speed linked up by the external phy. In case it is direct
5137 * only, then the line_speed during initialization will be
5138 * equal to the req_line_speed
5140 vars->line_speed = params->phy[INT_PHY].req_line_speed;
5143 * Initialize the internal phy in case this is a direct board
5144 * (no external phys), or this board has external phy which requires
5147 if (!USES_WARPCORE(bp))
5148 bnx2x_prepare_xgxs(¶ms->phy[INT_PHY], params, vars);
5149 /* init ext phy and enable link state int */
5150 non_ext_phy = (SINGLE_MEDIA_DIRECT(params) ||
5151 (params->loopback_mode == LOOPBACK_XGXS));
5154 (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) ||
5155 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
5156 struct bnx2x_phy *phy = ¶ms->phy[INT_PHY];
5157 if (vars->line_speed == SPEED_AUTO_NEG &&
5160 bnx2x_set_parallel_detection(phy, params);
5161 if (params->phy[INT_PHY].config_init)
5162 params->phy[INT_PHY].config_init(phy,
5167 /* Init external phy*/
5169 if (params->phy[INT_PHY].supported &
5171 vars->link_status |= LINK_STATUS_SERDES_LINK;
5173 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
5176 * No need to initialize second phy in case of first
5177 * phy only selection. In case of second phy, we do
5178 * need to initialize the first phy, since they are
5181 if (params->phy[phy_index].supported &
5183 vars->link_status |= LINK_STATUS_SERDES_LINK;
5185 if (phy_index == EXT_PHY2 &&
5186 (bnx2x_phy_selection(params) ==
5187 PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
5188 DP(NETIF_MSG_LINK, "Not initializing"
5192 params->phy[phy_index].config_init(
5193 ¶ms->phy[phy_index],
5197 /* Reset the interrupt indication after phy was initialized */
5198 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
5200 (NIG_STATUS_XGXS0_LINK10G |
5201 NIG_STATUS_XGXS0_LINK_STATUS |
5202 NIG_STATUS_SERDES0_LINK_STATUS |
5204 bnx2x_update_mng(params, vars->link_status);
5208 static void bnx2x_int_link_reset(struct bnx2x_phy *phy,
5209 struct link_params *params)
5211 /* reset the SerDes/XGXS */
5212 REG_WR(params->bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
5213 (0x1ff << (params->port*16)));
5216 static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
5217 struct link_params *params)
5219 struct bnx2x *bp = params->bp;
5223 gpio_port = BP_PATH(bp);
5225 gpio_port = params->port;
5226 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
5227 MISC_REGISTERS_GPIO_OUTPUT_LOW,
5229 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5230 MISC_REGISTERS_GPIO_OUTPUT_LOW,
5232 DP(NETIF_MSG_LINK, "reset external PHY\n");
5235 static int bnx2x_update_link_down(struct link_params *params,
5236 struct link_vars *vars)
5238 struct bnx2x *bp = params->bp;
5239 u8 port = params->port;
5241 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
5242 bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
5244 /* indicate no mac active */
5245 vars->mac_type = MAC_TYPE_NONE;
5247 /* update shared memory */
5248 vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK |
5249 LINK_STATUS_LINK_UP |
5250 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE |
5251 LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK |
5252 LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK |
5253 LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK);
5254 vars->line_speed = 0;
5255 bnx2x_update_mng(params, vars->link_status);
5257 /* activate nig drain */
5258 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
5261 if (!CHIP_IS_E3(bp))
5262 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
5265 /* reset BigMac/Xmac */
5266 if (CHIP_IS_E1x(bp) ||
5268 bnx2x_bmac_rx_disable(bp, params->port);
5269 REG_WR(bp, GRCBASE_MISC +
5270 MISC_REGISTERS_RESET_REG_2_CLEAR,
5271 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
5274 bnx2x_xmac_disable(params);
5279 static int bnx2x_update_link_up(struct link_params *params,
5280 struct link_vars *vars,
5283 struct bnx2x *bp = params->bp;
5284 u8 port = params->port;
5287 vars->link_status |= LINK_STATUS_LINK_UP;
5289 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
5290 vars->link_status |=
5291 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
5293 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
5294 vars->link_status |=
5295 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
5296 if (USES_WARPCORE(bp)) {
5298 bnx2x_xmac_enable(params, vars, 0);
5300 bnx2x_umac_enable(params, vars, 0);
5301 bnx2x_set_led(params, vars,
5302 LED_MODE_OPER, vars->line_speed);
5304 if ((CHIP_IS_E1x(bp) ||
5307 bnx2x_bmac_enable(params, vars, 0);
5309 bnx2x_set_led(params, vars,
5310 LED_MODE_OPER, SPEED_10000);
5312 rc = bnx2x_emac_program(params, vars);
5313 bnx2x_emac_enable(params, vars, 0);
5316 if ((vars->link_status &
5317 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
5318 && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
5319 SINGLE_MEDIA_DIRECT(params))
5320 bnx2x_set_gmii_tx_driver(params);
5325 if (CHIP_IS_E1x(bp))
5326 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
5330 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
5332 /* update shared memory */
5333 bnx2x_update_mng(params, vars->link_status);
5338 * The bnx2x_link_update function should be called upon link
5340 * Link is considered up as follows:
5341 * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
5343 * - SINGLE_MEDIA - The link between the 577xx and the external
5344 * phy (XGXS) need to up as well as the external link of the
5346 * - DUAL_MEDIA - The link between the 577xx and the first
5347 * external phy needs to be up, and at least one of the 2
5348 * external phy link must be up.
5350 int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
5352 struct bnx2x *bp = params->bp;
5353 struct link_vars phy_vars[MAX_PHYS];
5354 u8 port = params->port;
5355 u8 link_10g_plus, phy_index;
5356 u8 ext_phy_link_up = 0, cur_link_up;
5359 u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
5360 u8 active_external_phy = INT_PHY;
5362 for (phy_index = INT_PHY; phy_index < params->num_phys;
5364 phy_vars[phy_index].flow_ctrl = 0;
5365 phy_vars[phy_index].link_status = 0;
5366 phy_vars[phy_index].line_speed = 0;
5367 phy_vars[phy_index].duplex = DUPLEX_FULL;
5368 phy_vars[phy_index].phy_link_up = 0;
5369 phy_vars[phy_index].link_up = 0;
5370 phy_vars[phy_index].fault_detected = 0;
5373 if (USES_WARPCORE(bp))
5374 bnx2x_set_aer_mmd(params, ¶ms->phy[INT_PHY]);
5376 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
5377 port, (vars->phy_flags & PHY_XGXS_FLAG),
5378 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5380 is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
5382 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
5383 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5385 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
5387 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5388 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5389 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5392 if (!CHIP_IS_E3(bp))
5393 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
5397 * Check external link change only for external phys, and apply
5398 * priority selection between them in case the link on both phys
5399 * is up. Note that instead of the common vars, a temporary
5400 * vars argument is used since each phy may have different link/
5401 * speed/duplex result
5403 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
5405 struct bnx2x_phy *phy = ¶ms->phy[phy_index];
5406 if (!phy->read_status)
5408 /* Read link status and params of this ext phy */
5409 cur_link_up = phy->read_status(phy, params,
5410 &phy_vars[phy_index]);
5412 DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
5415 DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
5420 if (!ext_phy_link_up) {
5421 ext_phy_link_up = 1;
5422 active_external_phy = phy_index;
5424 switch (bnx2x_phy_selection(params)) {
5425 case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
5426 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
5428 * In this option, the first PHY makes sure to pass the
5429 * traffic through itself only.
5430 * Its not clear how to reset the link on the second phy
5432 active_external_phy = EXT_PHY1;
5434 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
5436 * In this option, the first PHY makes sure to pass the
5437 * traffic through the second PHY.
5439 active_external_phy = EXT_PHY2;
5443 * Link indication on both PHYs with the following cases
5445 * - FIRST_PHY means that second phy wasn't initialized,
5446 * hence its link is expected to be down
5447 * - SECOND_PHY means that first phy should not be able
5448 * to link up by itself (using configuration)
5449 * - DEFAULT should be overriden during initialiazation
5451 DP(NETIF_MSG_LINK, "Invalid link indication"
5452 "mpc=0x%x. DISABLING LINK !!!\n",
5453 params->multi_phy_config);
5454 ext_phy_link_up = 0;
5459 prev_line_speed = vars->line_speed;
5462 * Read the status of the internal phy. In case of
5463 * DIRECT_SINGLE_MEDIA board, this link is the external link,
5464 * otherwise this is the link between the 577xx and the first
5467 if (params->phy[INT_PHY].read_status)
5468 params->phy[INT_PHY].read_status(
5469 ¶ms->phy[INT_PHY],
5472 * The INT_PHY flow control reside in the vars. This include the
5473 * case where the speed or flow control are not set to AUTO.
5474 * Otherwise, the active external phy flow control result is set
5475 * to the vars. The ext_phy_line_speed is needed to check if the
5476 * speed is different between the internal phy and external phy.
5477 * This case may be result of intermediate link speed change.
5479 if (active_external_phy > INT_PHY) {
5480 vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
5482 * Link speed is taken from the XGXS. AN and FC result from
5485 vars->link_status |= phy_vars[active_external_phy].link_status;
5488 * if active_external_phy is first PHY and link is up - disable
5489 * disable TX on second external PHY
5491 if (active_external_phy == EXT_PHY1) {
5492 if (params->phy[EXT_PHY2].phy_specific_func) {
5493 DP(NETIF_MSG_LINK, "Disabling TX on"
5495 params->phy[EXT_PHY2].phy_specific_func(
5496 ¶ms->phy[EXT_PHY2],
5497 params, DISABLE_TX);
5501 ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
5502 vars->duplex = phy_vars[active_external_phy].duplex;
5503 if (params->phy[active_external_phy].supported &
5505 vars->link_status |= LINK_STATUS_SERDES_LINK;
5507 vars->link_status &= ~LINK_STATUS_SERDES_LINK;
5508 DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
5509 active_external_phy);
5512 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
5514 if (params->phy[phy_index].flags &
5515 FLAGS_REARM_LATCH_SIGNAL) {
5516 bnx2x_rearm_latch_signal(bp, port,
5518 active_external_phy);
5522 DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
5523 " ext_phy_line_speed = %d\n", vars->flow_ctrl,
5524 vars->link_status, ext_phy_line_speed);
5526 * Upon link speed change set the NIG into drain mode. Comes to
5527 * deals with possible FIFO glitch due to clk change when speed
5528 * is decreased without link down indicator
5531 if (vars->phy_link_up) {
5532 if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
5533 (ext_phy_line_speed != vars->line_speed)) {
5534 DP(NETIF_MSG_LINK, "Internal link speed %d is"
5535 " different than the external"
5536 " link speed %d\n", vars->line_speed,
5537 ext_phy_line_speed);
5538 vars->phy_link_up = 0;
5539 } else if (prev_line_speed != vars->line_speed) {
5540 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4,
5546 /* anything 10 and over uses the bmac */
5547 link_10g_plus = (vars->line_speed >= SPEED_10000);
5549 bnx2x_link_int_ack(params, vars, link_10g_plus);
5552 * In case external phy link is up, and internal link is down
5553 * (not initialized yet probably after link initialization, it
5554 * needs to be initialized.
5555 * Note that after link down-up as result of cable plug, the xgxs
5556 * link would probably become up again without the need
5559 if (!(SINGLE_MEDIA_DIRECT(params))) {
5560 DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
5561 " init_preceding = %d\n", ext_phy_link_up,
5563 params->phy[EXT_PHY1].flags &
5564 FLAGS_INIT_XGXS_FIRST);
5565 if (!(params->phy[EXT_PHY1].flags &
5566 FLAGS_INIT_XGXS_FIRST)
5567 && ext_phy_link_up && !vars->phy_link_up) {
5568 vars->line_speed = ext_phy_line_speed;
5569 if (vars->line_speed < SPEED_1000)
5570 vars->phy_flags |= PHY_SGMII_FLAG;
5572 vars->phy_flags &= ~PHY_SGMII_FLAG;
5574 if (params->phy[INT_PHY].config_init)
5575 params->phy[INT_PHY].config_init(
5576 ¶ms->phy[INT_PHY], params,
5581 * Link is up only if both local phy and external phy (in case of
5582 * non-direct board) are up and no fault detected on active PHY.
5584 vars->link_up = (vars->phy_link_up &&
5586 SINGLE_MEDIA_DIRECT(params)) &&
5587 (phy_vars[active_external_phy].fault_detected == 0));
5590 rc = bnx2x_update_link_up(params, vars, link_10g_plus);
5592 rc = bnx2x_update_link_down(params, vars);
5598 /*****************************************************************************/
5599 /* External Phy section */
5600 /*****************************************************************************/
5601 void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
5603 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
5604 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
5606 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
5607 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
5610 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
5611 u32 spirom_ver, u32 ver_addr)
5613 DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
5614 (u16)(spirom_ver>>16), (u16)spirom_ver, port);
5617 REG_WR(bp, ver_addr, spirom_ver);
5620 static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp,
5621 struct bnx2x_phy *phy,
5624 u16 fw_ver1, fw_ver2;
5626 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
5627 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
5628 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
5629 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
5630 bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2),
5634 static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp,
5635 struct bnx2x_phy *phy,
5636 struct link_vars *vars)
5639 bnx2x_cl45_read(bp, phy,
5641 MDIO_AN_REG_STATUS, &val);
5642 bnx2x_cl45_read(bp, phy,
5644 MDIO_AN_REG_STATUS, &val);
5646 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5647 if ((val & (1<<0)) == 0)
5648 vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
5651 /******************************************************************/
5652 /* common BCM8073/BCM8727 PHY SECTION */
5653 /******************************************************************/
5654 static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
5655 struct link_params *params,
5656 struct link_vars *vars)
5658 struct bnx2x *bp = params->bp;
5659 if (phy->req_line_speed == SPEED_10 ||
5660 phy->req_line_speed == SPEED_100) {
5661 vars->flow_ctrl = phy->req_flow_ctrl;
5665 if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
5666 (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) {
5668 u16 ld_pause; /* local */
5669 u16 lp_pause; /* link partner */
5670 bnx2x_cl45_read(bp, phy,
5672 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
5674 bnx2x_cl45_read(bp, phy,
5676 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
5677 pause_result = (ld_pause &
5678 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
5679 pause_result |= (lp_pause &
5680 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
5682 bnx2x_pause_resolve(vars, pause_result);
5683 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
5687 static int bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
5688 struct bnx2x_phy *phy,
5692 u16 fw_ver1, fw_msgout;
5695 /* Boot port from external ROM */
5697 bnx2x_cl45_write(bp, phy,
5699 MDIO_PMA_REG_GEN_CTRL,
5702 /* ucode reboot and rst */
5703 bnx2x_cl45_write(bp, phy,
5705 MDIO_PMA_REG_GEN_CTRL,
5708 bnx2x_cl45_write(bp, phy,
5710 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
5712 /* Reset internal microprocessor */
5713 bnx2x_cl45_write(bp, phy,
5715 MDIO_PMA_REG_GEN_CTRL,
5716 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
5718 /* Release srst bit */
5719 bnx2x_cl45_write(bp, phy,
5721 MDIO_PMA_REG_GEN_CTRL,
5722 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
5724 /* Delay 100ms per the PHY specifications */
5727 /* 8073 sometimes taking longer to download */
5732 "bnx2x_8073_8727_external_rom_boot port %x:"
5733 "Download failed. fw version = 0x%x\n",
5739 bnx2x_cl45_read(bp, phy,
5741 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
5742 bnx2x_cl45_read(bp, phy,
5744 MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
5747 } while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
5748 ((fw_msgout & 0xff) != 0x03 && (phy->type ==
5749 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)));
5751 /* Clear ser_boot_ctl bit */
5752 bnx2x_cl45_write(bp, phy,
5754 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
5755 bnx2x_save_bcm_spirom_ver(bp, phy, port);
5758 "bnx2x_8073_8727_external_rom_boot port %x:"
5759 "Download complete. fw version = 0x%x\n",
5765 /******************************************************************/
5766 /* BCM8073 PHY SECTION */
5767 /******************************************************************/
5768 static int bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
5770 /* This is only required for 8073A1, version 102 only */
5773 /* Read 8073 HW revision*/
5774 bnx2x_cl45_read(bp, phy,
5776 MDIO_PMA_REG_8073_CHIP_REV, &val);
5779 /* No need to workaround in 8073 A1 */
5783 bnx2x_cl45_read(bp, phy,
5785 MDIO_PMA_REG_ROM_VER2, &val);
5787 /* SNR should be applied only for version 0x102 */
5794 static int bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
5796 u16 val, cnt, cnt1 ;
5798 bnx2x_cl45_read(bp, phy,
5800 MDIO_PMA_REG_8073_CHIP_REV, &val);
5803 /* No need to workaround in 8073 A1 */
5806 /* XAUI workaround in 8073 A0: */
5809 * After loading the boot ROM and restarting Autoneg, poll
5813 for (cnt = 0; cnt < 1000; cnt++) {
5814 bnx2x_cl45_read(bp, phy,
5816 MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
5819 * If bit [14] = 0 or bit [13] = 0, continue on with
5820 * system initialization (XAUI work-around not required, as
5821 * these bits indicate 2.5G or 1G link up).
5823 if (!(val & (1<<14)) || !(val & (1<<13))) {
5824 DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
5826 } else if (!(val & (1<<15))) {
5827 DP(NETIF_MSG_LINK, "bit 15 went off\n");
5829 * If bit 15 is 0, then poll Dev1, Reg $C841 until it's
5830 * MSB (bit15) goes to 1 (indicating that the XAUI
5831 * workaround has completed), then continue on with
5832 * system initialization.
5834 for (cnt1 = 0; cnt1 < 1000; cnt1++) {
5835 bnx2x_cl45_read(bp, phy,
5837 MDIO_PMA_REG_8073_XAUI_WA, &val);
5838 if (val & (1<<15)) {
5840 "XAUI workaround has completed\n");
5849 DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
5853 static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy)
5855 /* Force KR or KX */
5856 bnx2x_cl45_write(bp, phy,
5857 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
5858 bnx2x_cl45_write(bp, phy,
5859 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
5860 bnx2x_cl45_write(bp, phy,
5861 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
5862 bnx2x_cl45_write(bp, phy,
5863 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
5866 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
5867 struct bnx2x_phy *phy,
5868 struct link_vars *vars)
5871 struct bnx2x *bp = params->bp;
5872 bnx2x_cl45_read(bp, phy,
5873 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
5875 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
5876 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
5877 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
5878 if ((vars->ieee_fc &
5879 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
5880 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
5881 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
5883 if ((vars->ieee_fc &
5884 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
5885 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
5886 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
5888 if ((vars->ieee_fc &
5889 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
5890 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
5891 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
5894 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
5896 bnx2x_cl45_write(bp, phy,
5897 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
5901 static int bnx2x_8073_config_init(struct bnx2x_phy *phy,
5902 struct link_params *params,
5903 struct link_vars *vars)
5905 struct bnx2x *bp = params->bp;
5908 DP(NETIF_MSG_LINK, "Init 8073\n");
5911 gpio_port = BP_PATH(bp);
5913 gpio_port = params->port;
5914 /* Restore normal power mode*/
5915 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5916 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
5918 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
5919 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
5922 bnx2x_cl45_write(bp, phy,
5923 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2));
5924 bnx2x_cl45_write(bp, phy,
5925 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004);
5927 bnx2x_8073_set_pause_cl37(params, phy, vars);
5929 bnx2x_cl45_read(bp, phy,
5930 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
5932 bnx2x_cl45_read(bp, phy,
5933 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
5935 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
5937 /* Swap polarity if required - Must be done only in non-1G mode */
5938 if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
5939 /* Configure the 8073 to swap _P and _N of the KR lines */
5940 DP(NETIF_MSG_LINK, "Swapping polarity for the 8073\n");
5941 /* 10G Rx/Tx and 1G Tx signal polarity swap */
5942 bnx2x_cl45_read(bp, phy,
5944 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
5945 bnx2x_cl45_write(bp, phy,
5947 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
5952 /* Enable CL37 BAM */
5953 if (REG_RD(bp, params->shmem_base +
5954 offsetof(struct shmem_region, dev_info.
5955 port_hw_config[params->port].default_cfg)) &
5956 PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
5958 bnx2x_cl45_read(bp, phy,
5960 MDIO_AN_REG_8073_BAM, &val);
5961 bnx2x_cl45_write(bp, phy,
5963 MDIO_AN_REG_8073_BAM, val | 1);
5964 DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
5966 if (params->loopback_mode == LOOPBACK_EXT) {
5967 bnx2x_807x_force_10G(bp, phy);
5968 DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
5971 bnx2x_cl45_write(bp, phy,
5972 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
5974 if (phy->req_line_speed != SPEED_AUTO_NEG) {
5975 if (phy->req_line_speed == SPEED_10000) {
5977 } else if (phy->req_line_speed == SPEED_2500) {
5980 * Note that 2.5G works only when used with 1G
5987 if (phy->speed_cap_mask &
5988 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
5991 /* Note that 2.5G works only when used with 1G advertisement */
5992 if (phy->speed_cap_mask &
5993 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
5994 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
5996 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
5999 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
6000 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
6002 if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
6003 (phy->req_line_speed == SPEED_AUTO_NEG)) ||
6004 (phy->req_line_speed == SPEED_2500)) {
6006 /* Allow 2.5G for A1 and above */
6007 bnx2x_cl45_read(bp, phy,
6008 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
6010 DP(NETIF_MSG_LINK, "Add 2.5G\n");
6016 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
6020 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
6021 /* Add support for CL37 (passive mode) II */
6023 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
6024 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
6025 (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
6028 /* Add support for CL37 (passive mode) III */
6029 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
6032 * The SNR will improve about 2db by changing BW and FEE main
6033 * tap. Rest commands are executed after link is up
6034 * Change FFE main cursor to 5 in EDC register
6036 if (bnx2x_8073_is_snr_needed(bp, phy))
6037 bnx2x_cl45_write(bp, phy,
6038 MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
6041 /* Enable FEC (Forware Error Correction) Request in the AN */
6042 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
6044 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
6046 bnx2x_ext_phy_set_pause(params, phy, vars);
6048 /* Restart autoneg */
6050 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
6051 DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
6052 ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
6056 static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
6057 struct link_params *params,
6058 struct link_vars *vars)
6060 struct bnx2x *bp = params->bp;
6063 u16 link_status = 0;
6064 u16 an1000_status = 0;
6066 bnx2x_cl45_read(bp, phy,
6067 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
6069 DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
6071 /* clear the interrupt LASI status register */
6072 bnx2x_cl45_read(bp, phy,
6073 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
6074 bnx2x_cl45_read(bp, phy,
6075 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
6076 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
6078 bnx2x_cl45_read(bp, phy,
6079 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
6081 /* Check the LASI */
6082 bnx2x_cl45_read(bp, phy,
6083 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
6085 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
6087 /* Check the link status */
6088 bnx2x_cl45_read(bp, phy,
6089 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
6090 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
6092 bnx2x_cl45_read(bp, phy,
6093 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
6094 bnx2x_cl45_read(bp, phy,
6095 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
6096 link_up = ((val1 & 4) == 4);
6097 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
6100 ((phy->req_line_speed != SPEED_10000))) {
6101 if (bnx2x_8073_xaui_wa(bp, phy) != 0)
6104 bnx2x_cl45_read(bp, phy,
6105 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
6106 bnx2x_cl45_read(bp, phy,
6107 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
6109 /* Check the link status on 1.1.2 */
6110 bnx2x_cl45_read(bp, phy,
6111 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
6112 bnx2x_cl45_read(bp, phy,
6113 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
6114 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
6115 "an_link_status=0x%x\n", val2, val1, an1000_status);
6117 link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
6118 if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
6120 * The SNR will improve about 2dbby changing the BW and FEE main
6121 * tap. The 1st write to change FFE main tap is set before
6122 * restart AN. Change PLL Bandwidth in EDC register
6124 bnx2x_cl45_write(bp, phy,
6125 MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
6128 /* Change CDR Bandwidth in EDC register */
6129 bnx2x_cl45_write(bp, phy,
6130 MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
6133 bnx2x_cl45_read(bp, phy,
6134 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
6137 /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
6138 if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
6140 vars->line_speed = SPEED_10000;
6141 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
6143 } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
6145 vars->line_speed = SPEED_2500;
6146 DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
6148 } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
6150 vars->line_speed = SPEED_1000;
6151 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
6155 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
6160 /* Swap polarity if required */
6161 if (params->lane_config &
6162 PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
6163 /* Configure the 8073 to swap P and N of the KR lines */
6164 bnx2x_cl45_read(bp, phy,
6166 MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
6168 * Set bit 3 to invert Rx in 1G mode and clear this bit
6169 * when it`s in 10G mode.
6171 if (vars->line_speed == SPEED_1000) {
6172 DP(NETIF_MSG_LINK, "Swapping 1G polarity for"
6178 bnx2x_cl45_write(bp, phy,
6180 MDIO_XS_REG_8073_RX_CTRL_PCIE,
6183 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
6184 bnx2x_8073_resolve_fc(phy, params, vars);
6185 vars->duplex = DUPLEX_FULL;
6190 static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
6191 struct link_params *params)
6193 struct bnx2x *bp = params->bp;
6196 gpio_port = BP_PATH(bp);
6198 gpio_port = params->port;
6199 DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
6201 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6202 MISC_REGISTERS_GPIO_OUTPUT_LOW,
6206 /******************************************************************/
6207 /* BCM8705 PHY SECTION */
6208 /******************************************************************/
6209 static int bnx2x_8705_config_init(struct bnx2x_phy *phy,
6210 struct link_params *params,
6211 struct link_vars *vars)
6213 struct bnx2x *bp = params->bp;
6214 DP(NETIF_MSG_LINK, "init 8705\n");
6215 /* Restore normal power mode*/
6216 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6217 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
6219 bnx2x_ext_phy_hw_reset(bp, params->port);
6220 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
6221 bnx2x_wait_reset_complete(bp, phy, params);
6223 bnx2x_cl45_write(bp, phy,
6224 MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
6225 bnx2x_cl45_write(bp, phy,
6226 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
6227 bnx2x_cl45_write(bp, phy,
6228 MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
6229 bnx2x_cl45_write(bp, phy,
6230 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
6231 /* BCM8705 doesn't have microcode, hence the 0 */
6232 bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
6236 static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
6237 struct link_params *params,
6238 struct link_vars *vars)
6242 struct bnx2x *bp = params->bp;
6243 DP(NETIF_MSG_LINK, "read status 8705\n");
6244 bnx2x_cl45_read(bp, phy,
6245 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
6246 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
6248 bnx2x_cl45_read(bp, phy,
6249 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
6250 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
6252 bnx2x_cl45_read(bp, phy,
6253 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
6255 bnx2x_cl45_read(bp, phy,
6256 MDIO_PMA_DEVAD, 0xc809, &val1);
6257 bnx2x_cl45_read(bp, phy,
6258 MDIO_PMA_DEVAD, 0xc809, &val1);
6260 DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
6261 link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
6263 vars->line_speed = SPEED_10000;
6264 bnx2x_ext_phy_resolve_fc(phy, params, vars);
6269 /******************************************************************/
6270 /* SFP+ module Section */
6271 /******************************************************************/
6272 static u8 bnx2x_get_gpio_port(struct link_params *params)
6275 u32 swap_val, swap_override;
6276 struct bnx2x *bp = params->bp;
6278 gpio_port = BP_PATH(bp);
6280 gpio_port = params->port;
6281 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
6282 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
6283 return gpio_port ^ (swap_val && swap_override);
6286 static void bnx2x_sfp_e1e2_set_transmitter(struct link_params *params,
6287 struct bnx2x_phy *phy,
6291 u8 port = params->port;
6292 struct bnx2x *bp = params->bp;
6295 /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
6296 tx_en_mode = REG_RD(bp, params->shmem_base +
6297 offsetof(struct shmem_region,
6298 dev_info.port_hw_config[port].sfp_ctrl)) &
6299 PORT_HW_CFG_TX_LASER_MASK;
6300 DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x "
6301 "mode = %x\n", tx_en, port, tx_en_mode);
6302 switch (tx_en_mode) {
6303 case PORT_HW_CFG_TX_LASER_MDIO:
6305 bnx2x_cl45_read(bp, phy,
6307 MDIO_PMA_REG_PHY_IDENTIFIER,
6315 bnx2x_cl45_write(bp, phy,
6317 MDIO_PMA_REG_PHY_IDENTIFIER,
6320 case PORT_HW_CFG_TX_LASER_GPIO0:
6321 case PORT_HW_CFG_TX_LASER_GPIO1:
6322 case PORT_HW_CFG_TX_LASER_GPIO2:
6323 case PORT_HW_CFG_TX_LASER_GPIO3:
6326 u8 gpio_port, gpio_mode;
6328 gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH;
6330 gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW;
6332 gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0;
6333 gpio_port = bnx2x_get_gpio_port(params);
6334 bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
6338 DP(NETIF_MSG_LINK, "Invalid TX_LASER_MDIO 0x%x\n", tx_en_mode);
6343 static void bnx2x_sfp_set_transmitter(struct link_params *params,
6344 struct bnx2x_phy *phy,
6347 struct bnx2x *bp = params->bp;
6348 DP(NETIF_MSG_LINK, "Setting SFP+ transmitter to %d\n", tx_en);
6350 bnx2x_sfp_e3_set_transmitter(params, phy, tx_en);
6352 bnx2x_sfp_e1e2_set_transmitter(params, phy, tx_en);
6355 static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
6356 struct link_params *params,
6357 u16 addr, u8 byte_cnt, u8 *o_buf)
6359 struct bnx2x *bp = params->bp;
6362 if (byte_cnt > 16) {
6363 DP(NETIF_MSG_LINK, "Reading from eeprom is"
6364 " is limited to 0xf\n");
6367 /* Set the read command byte count */
6368 bnx2x_cl45_write(bp, phy,
6369 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
6370 (byte_cnt | 0xa000));
6372 /* Set the read command address */
6373 bnx2x_cl45_write(bp, phy,
6374 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
6377 /* Activate read command */
6378 bnx2x_cl45_write(bp, phy,
6379 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
6382 /* Wait up to 500us for command complete status */
6383 for (i = 0; i < 100; i++) {
6384 bnx2x_cl45_read(bp, phy,
6386 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
6387 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
6388 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
6393 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
6394 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
6396 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
6397 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
6401 /* Read the buffer */
6402 for (i = 0; i < byte_cnt; i++) {
6403 bnx2x_cl45_read(bp, phy,
6405 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
6406 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
6409 for (i = 0; i < 100; i++) {
6410 bnx2x_cl45_read(bp, phy,
6412 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
6413 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
6414 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
6421 static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy,
6422 struct link_params *params,
6423 u16 addr, u8 byte_cnt,
6427 u8 i, j = 0, cnt = 0;
6430 struct bnx2x *bp = params->bp;
6431 /*DP(NETIF_MSG_LINK, "bnx2x_direct_read_sfp_module_eeprom:"
6432 " addr %d, cnt %d\n",
6434 if (byte_cnt > 16) {
6435 DP(NETIF_MSG_LINK, "Reading from eeprom is"
6436 " is limited to 16 bytes\n");
6440 /* 4 byte aligned address */
6441 addr32 = addr & (~0x3);
6443 rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt,
6445 } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT));
6448 for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) {
6449 o_buf[j] = *((u8 *)data_array + i);
6457 static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
6458 struct link_params *params,
6459 u16 addr, u8 byte_cnt, u8 *o_buf)
6461 struct bnx2x *bp = params->bp;
6464 if (byte_cnt > 16) {
6465 DP(NETIF_MSG_LINK, "Reading from eeprom is"
6466 " is limited to 0xf\n");
6470 /* Need to read from 1.8000 to clear it */
6471 bnx2x_cl45_read(bp, phy,
6473 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
6476 /* Set the read command byte count */
6477 bnx2x_cl45_write(bp, phy,
6479 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
6480 ((byte_cnt < 2) ? 2 : byte_cnt));
6482 /* Set the read command address */
6483 bnx2x_cl45_write(bp, phy,
6485 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
6487 /* Set the destination address */
6488 bnx2x_cl45_write(bp, phy,
6491 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
6493 /* Activate read command */
6494 bnx2x_cl45_write(bp, phy,
6496 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
6499 * Wait appropriate time for two-wire command to finish before
6500 * polling the status register
6504 /* Wait up to 500us for command complete status */
6505 for (i = 0; i < 100; i++) {
6506 bnx2x_cl45_read(bp, phy,
6508 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
6509 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
6510 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
6515 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
6516 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
6518 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
6519 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
6523 /* Read the buffer */
6524 for (i = 0; i < byte_cnt; i++) {
6525 bnx2x_cl45_read(bp, phy,
6527 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
6528 o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
6531 for (i = 0; i < 100; i++) {
6532 bnx2x_cl45_read(bp, phy,
6534 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
6535 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
6536 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
6544 int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
6545 struct link_params *params, u16 addr,
6546 u8 byte_cnt, u8 *o_buf)
6549 switch (phy->type) {
6550 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6551 rc = bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
6554 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6555 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
6556 rc = bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
6559 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
6560 rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr,
6567 static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
6568 struct link_params *params,
6571 struct bnx2x *bp = params->bp;
6572 u32 sync_offset = 0, phy_idx, media_types;
6573 u8 val, check_limiting_mode = 0;
6574 *edc_mode = EDC_MODE_LIMITING;
6576 phy->media_type = ETH_PHY_UNSPECIFIED;
6577 /* First check for copper cable */
6578 if (bnx2x_read_sfp_module_eeprom(phy,
6580 SFP_EEPROM_CON_TYPE_ADDR,
6583 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
6588 case SFP_EEPROM_CON_TYPE_VAL_COPPER:
6590 u8 copper_module_type;
6591 phy->media_type = ETH_PHY_DA_TWINAX;
6593 * Check if its active cable (includes SFP+ module)
6596 if (bnx2x_read_sfp_module_eeprom(phy,
6598 SFP_EEPROM_FC_TX_TECH_ADDR,
6600 &copper_module_type) != 0) {
6602 "Failed to read copper-cable-type"
6603 " from SFP+ EEPROM\n");
6607 if (copper_module_type &
6608 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
6609 DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
6610 check_limiting_mode = 1;
6611 } else if (copper_module_type &
6612 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
6613 DP(NETIF_MSG_LINK, "Passive Copper"
6614 " cable detected\n");
6616 EDC_MODE_PASSIVE_DAC;
6618 DP(NETIF_MSG_LINK, "Unknown copper-cable-"
6619 "type 0x%x !!!\n", copper_module_type);
6624 case SFP_EEPROM_CON_TYPE_VAL_LC:
6625 phy->media_type = ETH_PHY_SFP_FIBER;
6626 DP(NETIF_MSG_LINK, "Optic module detected\n");
6627 check_limiting_mode = 1;
6630 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
6634 sync_offset = params->shmem_base +
6635 offsetof(struct shmem_region,
6636 dev_info.port_hw_config[params->port].media_type);
6637 media_types = REG_RD(bp, sync_offset);
6638 /* Update media type for non-PMF sync */
6639 for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
6640 if (&(params->phy[phy_idx]) == phy) {
6641 media_types &= ~(PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
6642 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
6643 media_types |= ((phy->media_type &
6644 PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
6645 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
6649 REG_WR(bp, sync_offset, media_types);
6650 if (check_limiting_mode) {
6651 u8 options[SFP_EEPROM_OPTIONS_SIZE];
6652 if (bnx2x_read_sfp_module_eeprom(phy,
6654 SFP_EEPROM_OPTIONS_ADDR,
6655 SFP_EEPROM_OPTIONS_SIZE,
6657 DP(NETIF_MSG_LINK, "Failed to read Option"
6658 " field from module EEPROM\n");
6661 if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
6662 *edc_mode = EDC_MODE_LINEAR;
6664 *edc_mode = EDC_MODE_LIMITING;
6666 DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
6670 * This function read the relevant field from the module (SFP+), and verify it
6671 * is compliant with this board
6673 static int bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
6674 struct link_params *params)
6676 struct bnx2x *bp = params->bp;
6678 u32 fw_resp, fw_cmd_param;
6679 char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
6680 char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
6681 phy->flags &= ~FLAGS_SFP_NOT_APPROVED;
6682 val = REG_RD(bp, params->shmem_base +
6683 offsetof(struct shmem_region, dev_info.
6684 port_feature_config[params->port].config));
6685 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
6686 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
6687 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
6691 if (params->feature_config_flags &
6692 FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
6693 /* Use specific phy request */
6694 cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
6695 } else if (params->feature_config_flags &
6696 FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
6697 /* Use first phy request only in case of non-dual media*/
6698 if (DUAL_MEDIA(params)) {
6699 DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
6703 cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
6705 /* No support in OPT MDL detection */
6706 DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
6711 fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
6712 fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param);
6713 if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
6714 DP(NETIF_MSG_LINK, "Approved module\n");
6718 /* format the warning message */
6719 if (bnx2x_read_sfp_module_eeprom(phy,
6721 SFP_EEPROM_VENDOR_NAME_ADDR,
6722 SFP_EEPROM_VENDOR_NAME_SIZE,
6724 vendor_name[0] = '\0';
6726 vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
6727 if (bnx2x_read_sfp_module_eeprom(phy,
6729 SFP_EEPROM_PART_NO_ADDR,
6730 SFP_EEPROM_PART_NO_SIZE,
6732 vendor_pn[0] = '\0';
6734 vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
6736 netdev_err(bp->dev, "Warning: Unqualified SFP+ module detected,"
6737 " Port %d from %s part number %s\n",
6738 params->port, vendor_name, vendor_pn);
6739 phy->flags |= FLAGS_SFP_NOT_APPROVED;
6743 static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
6744 struct link_params *params)
6748 struct bnx2x *bp = params->bp;
6751 * Initialization time after hot-plug may take up to 300ms for
6752 * some phys type ( e.g. JDSU )
6755 for (timeout = 0; timeout < 60; timeout++) {
6756 if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
6758 DP(NETIF_MSG_LINK, "SFP+ module initialization "
6759 "took %d ms\n", timeout * 5);
6767 static void bnx2x_8727_power_module(struct bnx2x *bp,
6768 struct bnx2x_phy *phy,
6770 /* Make sure GPIOs are not using for LED mode */
6773 * In the GPIO register, bit 4 is use to determine if the GPIOs are
6774 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
6776 * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0
6777 * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1
6778 * where the 1st bit is the over-current(only input), and 2nd bit is
6779 * for power( only output )
6781 * In case of NOC feature is disabled and power is up, set GPIO control
6782 * as input to enable listening of over-current indication
6784 if (phy->flags & FLAGS_NOC)
6790 * Set GPIO control to OUTPUT, and set the power bit
6791 * to according to the is_power_up
6795 bnx2x_cl45_write(bp, phy,
6797 MDIO_PMA_REG_8727_GPIO_CTRL,
6801 static int bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
6802 struct bnx2x_phy *phy,
6805 u16 cur_limiting_mode;
6807 bnx2x_cl45_read(bp, phy,
6809 MDIO_PMA_REG_ROM_VER2,
6810 &cur_limiting_mode);
6811 DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
6814 if (edc_mode == EDC_MODE_LIMITING) {
6815 DP(NETIF_MSG_LINK, "Setting LIMITING MODE\n");
6816 bnx2x_cl45_write(bp, phy,
6818 MDIO_PMA_REG_ROM_VER2,
6820 } else { /* LRM mode ( default )*/
6822 DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
6825 * Changing to LRM mode takes quite few seconds. So do it only
6826 * if current mode is limiting (default is LRM)
6828 if (cur_limiting_mode != EDC_MODE_LIMITING)
6831 bnx2x_cl45_write(bp, phy,
6833 MDIO_PMA_REG_LRM_MODE,
6835 bnx2x_cl45_write(bp, phy,
6837 MDIO_PMA_REG_ROM_VER2,
6839 bnx2x_cl45_write(bp, phy,
6841 MDIO_PMA_REG_MISC_CTRL0,
6843 bnx2x_cl45_write(bp, phy,
6845 MDIO_PMA_REG_LRM_MODE,
6851 static int bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
6852 struct bnx2x_phy *phy,
6857 bnx2x_cl45_read(bp, phy,
6859 MDIO_PMA_REG_PHY_IDENTIFIER,
6862 bnx2x_cl45_write(bp, phy,
6864 MDIO_PMA_REG_PHY_IDENTIFIER,
6865 (phy_identifier & ~(1<<9)));
6867 bnx2x_cl45_read(bp, phy,
6869 MDIO_PMA_REG_ROM_VER2,
6871 /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
6872 bnx2x_cl45_write(bp, phy,
6874 MDIO_PMA_REG_ROM_VER2,
6875 (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
6877 bnx2x_cl45_write(bp, phy,
6879 MDIO_PMA_REG_PHY_IDENTIFIER,
6880 (phy_identifier | (1<<9)));
6885 static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
6886 struct link_params *params,
6889 struct bnx2x *bp = params->bp;
6893 bnx2x_sfp_set_transmitter(params, phy, 0);
6896 if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
6897 bnx2x_sfp_set_transmitter(params, phy, 1);
6900 DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
6906 static void bnx2x_set_e1e2_module_fault_led(struct link_params *params,
6909 struct bnx2x *bp = params->bp;
6911 u32 fault_led_gpio = REG_RD(bp, params->shmem_base +
6912 offsetof(struct shmem_region,
6913 dev_info.port_hw_config[params->port].sfp_ctrl)) &
6914 PORT_HW_CFG_FAULT_MODULE_LED_MASK;
6915 switch (fault_led_gpio) {
6916 case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED:
6918 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0:
6919 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1:
6920 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2:
6921 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3:
6923 u8 gpio_port = bnx2x_get_gpio_port(params);
6924 u16 gpio_pin = fault_led_gpio -
6925 PORT_HW_CFG_FAULT_MODULE_LED_GPIO0;
6926 DP(NETIF_MSG_LINK, "Set fault module-detected led "
6927 "pin %x port %x mode %x\n",
6928 gpio_pin, gpio_port, gpio_mode);
6929 bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
6933 DP(NETIF_MSG_LINK, "Error: Invalid fault led mode 0x%x\n",
6938 static void bnx2x_set_e3_module_fault_led(struct link_params *params,
6942 u8 port = params->port;
6943 struct bnx2x *bp = params->bp;
6944 pin_cfg = (REG_RD(bp, params->shmem_base +
6945 offsetof(struct shmem_region,
6946 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
6947 PORT_HW_CFG_E3_FAULT_MDL_LED_MASK) >>
6948 PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT;
6949 DP(NETIF_MSG_LINK, "Setting Fault LED to %d using pin cfg %d\n",
6950 gpio_mode, pin_cfg);
6951 bnx2x_set_cfg_pin(bp, pin_cfg, gpio_mode);
6954 static void bnx2x_set_sfp_module_fault_led(struct link_params *params,
6957 struct bnx2x *bp = params->bp;
6958 DP(NETIF_MSG_LINK, "Setting SFP+ module fault LED to %d\n", gpio_mode);
6959 if (CHIP_IS_E3(bp)) {
6961 * Low ==> if SFP+ module is supported otherwise
6962 * High ==> if SFP+ module is not on the approved vendor list
6964 bnx2x_set_e3_module_fault_led(params, gpio_mode);
6966 bnx2x_set_e1e2_module_fault_led(params, gpio_mode);
6969 static void bnx2x_warpcore_power_module(struct link_params *params,
6970 struct bnx2x_phy *phy,
6974 struct bnx2x *bp = params->bp;
6976 pin_cfg = (REG_RD(bp, params->shmem_base +
6977 offsetof(struct shmem_region,
6978 dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
6979 PORT_HW_CFG_E3_PWR_DIS_MASK) >>
6980 PORT_HW_CFG_E3_PWR_DIS_SHIFT;
6981 DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n",
6984 * Low ==> corresponding SFP+ module is powered
6985 * high ==> the SFP+ module is powered down
6987 bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1);
6990 static void bnx2x_power_sfp_module(struct link_params *params,
6991 struct bnx2x_phy *phy,
6994 struct bnx2x *bp = params->bp;
6995 DP(NETIF_MSG_LINK, "Setting SFP+ power to %x\n", power);
6997 switch (phy->type) {
6998 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6999 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
7000 bnx2x_8727_power_module(params->bp, phy, power);
7002 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
7003 bnx2x_warpcore_power_module(params, phy, power);
7009 static void bnx2x_warpcore_set_limiting_mode(struct link_params *params,
7010 struct bnx2x_phy *phy,
7014 u16 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
7015 struct bnx2x *bp = params->bp;
7017 u8 lane = bnx2x_get_warpcore_lane(phy, params);
7018 /* This is a global register which controls all lanes */
7019 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
7020 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
7021 val &= ~(0xf << (lane << 2));
7024 case EDC_MODE_LINEAR:
7025 case EDC_MODE_LIMITING:
7026 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
7028 case EDC_MODE_PASSIVE_DAC:
7029 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC;
7035 val |= (mode << (lane << 2));
7036 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
7037 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, val);
7039 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
7040 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
7045 static void bnx2x_set_limiting_mode(struct link_params *params,
7046 struct bnx2x_phy *phy,
7049 switch (phy->type) {
7050 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7051 bnx2x_8726_set_limiting_mode(params->bp, phy, edc_mode);
7053 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7054 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
7055 bnx2x_8727_set_limiting_mode(params->bp, phy, edc_mode);
7057 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
7058 bnx2x_warpcore_set_limiting_mode(params, phy, edc_mode);
7063 int bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
7064 struct link_params *params)
7066 struct bnx2x *bp = params->bp;
7070 u32 val = REG_RD(bp, params->shmem_base +
7071 offsetof(struct shmem_region, dev_info.
7072 port_feature_config[params->port].config));
7074 DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
7076 /* Power up module */
7077 bnx2x_power_sfp_module(params, phy, 1);
7078 if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
7079 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
7081 } else if (bnx2x_verify_sfp_module(phy, params) != 0) {
7082 /* check SFP+ module compatibility */
7083 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
7085 /* Turn on fault module-detected led */
7086 bnx2x_set_sfp_module_fault_led(params,
7087 MISC_REGISTERS_GPIO_HIGH);
7089 /* Check if need to power down the SFP+ module */
7090 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
7091 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN) {
7092 DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
7093 bnx2x_power_sfp_module(params, phy, 0);
7097 /* Turn off fault module-detected led */
7098 bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
7102 * Check and set limiting mode / LRM mode on 8726. On 8727 it
7103 * is done automatically
7105 bnx2x_set_limiting_mode(params, phy, edc_mode);
7108 * Enable transmit for this module if the module is approved, or
7109 * if unapproved modules should also enable the Tx laser
7112 (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
7113 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
7114 bnx2x_sfp_set_transmitter(params, phy, 1);
7116 bnx2x_sfp_set_transmitter(params, phy, 0);
7121 void bnx2x_handle_module_detect_int(struct link_params *params)
7123 struct bnx2x *bp = params->bp;
7124 struct bnx2x_phy *phy;
7126 u8 gpio_num, gpio_port;
7128 phy = ¶ms->phy[INT_PHY];
7130 phy = ¶ms->phy[EXT_PHY1];
7132 if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id, params->shmem_base,
7133 params->port, &gpio_num, &gpio_port) ==
7135 DP(NETIF_MSG_LINK, "Failed to get MOD_ABS interrupt config\n");
7139 /* Set valid module led off */
7140 bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH);
7142 /* Get current gpio val reflecting module plugged in / out*/
7143 gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
7145 /* Call the handling function in case module is detected */
7146 if (gpio_val == 0) {
7147 bnx2x_power_sfp_module(params, phy, 1);
7148 bnx2x_set_gpio_int(bp, gpio_num,
7149 MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
7151 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
7152 bnx2x_sfp_module_detection(phy, params);
7154 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
7156 u32 val = REG_RD(bp, params->shmem_base +
7157 offsetof(struct shmem_region, dev_info.
7158 port_feature_config[params->port].
7161 bnx2x_set_gpio_int(bp, gpio_num,
7162 MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
7165 * Module was plugged out.
7166 * Disable transmit for this module
7168 phy->media_type = ETH_PHY_NOT_PRESENT;
7169 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
7170 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
7171 bnx2x_sfp_set_transmitter(params, phy, 0);
7175 /******************************************************************/
7176 /* Used by 8706 and 8727 */
7177 /******************************************************************/
7178 static void bnx2x_sfp_mask_fault(struct bnx2x *bp,
7179 struct bnx2x_phy *phy,
7180 u16 alarm_status_offset,
7181 u16 alarm_ctrl_offset)
7183 u16 alarm_status, val;
7184 bnx2x_cl45_read(bp, phy,
7185 MDIO_PMA_DEVAD, alarm_status_offset,
7187 bnx2x_cl45_read(bp, phy,
7188 MDIO_PMA_DEVAD, alarm_status_offset,
7190 /* Mask or enable the fault event. */
7191 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, &val);
7192 if (alarm_status & (1<<0))
7196 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, val);
7198 /******************************************************************/
7199 /* common BCM8706/BCM8726 PHY SECTION */
7200 /******************************************************************/
7201 static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
7202 struct link_params *params,
7203 struct link_vars *vars)
7206 u16 val1, val2, rx_sd, pcs_status;
7207 struct bnx2x *bp = params->bp;
7208 DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
7210 bnx2x_cl45_read(bp, phy,
7211 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
7213 bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_REG_TX_ALARM,
7214 MDIO_PMA_REG_TX_ALARM_CTRL);
7216 /* clear LASI indication*/
7217 bnx2x_cl45_read(bp, phy,
7218 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
7219 bnx2x_cl45_read(bp, phy,
7220 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
7221 DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
7223 bnx2x_cl45_read(bp, phy,
7224 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
7225 bnx2x_cl45_read(bp, phy,
7226 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
7227 bnx2x_cl45_read(bp, phy,
7228 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
7229 bnx2x_cl45_read(bp, phy,
7230 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
7232 DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
7233 " link_status 0x%x\n", rx_sd, pcs_status, val2);
7235 * link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
7236 * are set, or if the autoneg bit 1 is set
7238 link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
7241 vars->line_speed = SPEED_1000;
7243 vars->line_speed = SPEED_10000;
7244 bnx2x_ext_phy_resolve_fc(phy, params, vars);
7245 vars->duplex = DUPLEX_FULL;
7248 /* Capture 10G link fault. Read twice to clear stale value. */
7249 if (vars->line_speed == SPEED_10000) {
7250 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
7251 MDIO_PMA_REG_TX_ALARM, &val1);
7252 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
7253 MDIO_PMA_REG_TX_ALARM, &val1);
7255 vars->fault_detected = 1;
7261 /******************************************************************/
7262 /* BCM8706 PHY SECTION */
7263 /******************************************************************/
7264 static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
7265 struct link_params *params,
7266 struct link_vars *vars)
7270 struct bnx2x *bp = params->bp;
7271 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7272 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
7274 bnx2x_ext_phy_hw_reset(bp, params->port);
7275 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
7276 bnx2x_wait_reset_complete(bp, phy, params);
7278 /* Wait until fw is loaded */
7279 for (cnt = 0; cnt < 100; cnt++) {
7280 bnx2x_cl45_read(bp, phy,
7281 MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
7286 DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt);
7287 if ((params->feature_config_flags &
7288 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
7291 for (i = 0; i < 4; i++) {
7292 reg = MDIO_XS_8706_REG_BANK_RX0 +
7293 i*(MDIO_XS_8706_REG_BANK_RX1 -
7294 MDIO_XS_8706_REG_BANK_RX0);
7295 bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val);
7296 /* Clear first 3 bits of the control */
7298 /* Set control bits according to configuration */
7299 val |= (phy->rx_preemphasis[i] & 0x7);
7300 DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706"
7301 " reg 0x%x <-- val 0x%x\n", reg, val);
7302 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val);
7306 if (phy->req_line_speed == SPEED_10000) {
7307 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
7309 bnx2x_cl45_write(bp, phy,
7311 MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
7312 bnx2x_cl45_write(bp, phy,
7313 MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_ALARM_CTRL,
7315 /* Arm LASI for link and Tx fault. */
7316 bnx2x_cl45_write(bp, phy,
7317 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 3);
7319 /* Force 1Gbps using autoneg with 1G advertisement */
7321 /* Allow CL37 through CL73 */
7322 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
7323 bnx2x_cl45_write(bp, phy,
7324 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
7326 /* Enable Full-Duplex advertisement on CL37 */
7327 bnx2x_cl45_write(bp, phy,
7328 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
7329 /* Enable CL37 AN */
7330 bnx2x_cl45_write(bp, phy,
7331 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
7333 bnx2x_cl45_write(bp, phy,
7334 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
7336 /* Enable clause 73 AN */
7337 bnx2x_cl45_write(bp, phy,
7338 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
7339 bnx2x_cl45_write(bp, phy,
7340 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
7342 bnx2x_cl45_write(bp, phy,
7343 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
7346 bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
7349 * If TX Laser is controlled by GPIO_0, do not let PHY go into low
7350 * power mode, if TX Laser is disabled
7353 tx_en_mode = REG_RD(bp, params->shmem_base +
7354 offsetof(struct shmem_region,
7355 dev_info.port_hw_config[params->port].sfp_ctrl))
7356 & PORT_HW_CFG_TX_LASER_MASK;
7358 if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
7359 DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
7360 bnx2x_cl45_read(bp, phy,
7361 MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1);
7363 bnx2x_cl45_write(bp, phy,
7364 MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1);
7370 static int bnx2x_8706_read_status(struct bnx2x_phy *phy,
7371 struct link_params *params,
7372 struct link_vars *vars)
7374 return bnx2x_8706_8726_read_status(phy, params, vars);
7377 /******************************************************************/
7378 /* BCM8726 PHY SECTION */
7379 /******************************************************************/
7380 static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
7381 struct link_params *params)
7383 struct bnx2x *bp = params->bp;
7384 DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
7385 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
7388 static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
7389 struct link_params *params)
7391 struct bnx2x *bp = params->bp;
7392 /* Need to wait 100ms after reset */
7395 /* Micro controller re-boot */
7396 bnx2x_cl45_write(bp, phy,
7397 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
7399 /* Set soft reset */
7400 bnx2x_cl45_write(bp, phy,
7402 MDIO_PMA_REG_GEN_CTRL,
7403 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
7405 bnx2x_cl45_write(bp, phy,
7407 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
7409 bnx2x_cl45_write(bp, phy,
7411 MDIO_PMA_REG_GEN_CTRL,
7412 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
7414 /* wait for 150ms for microcode load */
7417 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
7418 bnx2x_cl45_write(bp, phy,
7420 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
7423 bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
7426 static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
7427 struct link_params *params,
7428 struct link_vars *vars)
7430 struct bnx2x *bp = params->bp;
7432 u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
7434 bnx2x_cl45_read(bp, phy,
7435 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
7437 if (val1 & (1<<15)) {
7438 DP(NETIF_MSG_LINK, "Tx is disabled\n");
7440 vars->line_speed = 0;
7447 static int bnx2x_8726_config_init(struct bnx2x_phy *phy,
7448 struct link_params *params,
7449 struct link_vars *vars)
7451 struct bnx2x *bp = params->bp;
7452 DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
7454 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
7455 bnx2x_wait_reset_complete(bp, phy, params);
7457 bnx2x_8726_external_rom_boot(phy, params);
7460 * Need to call module detected on initialization since the module
7461 * detection triggered by actual module insertion might occur before
7462 * driver is loaded, and when driver is loaded, it reset all
7463 * registers, including the transmitter
7465 bnx2x_sfp_module_detection(phy, params);
7467 if (phy->req_line_speed == SPEED_1000) {
7468 DP(NETIF_MSG_LINK, "Setting 1G force\n");
7469 bnx2x_cl45_write(bp, phy,
7470 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
7471 bnx2x_cl45_write(bp, phy,
7472 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
7473 bnx2x_cl45_write(bp, phy,
7474 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5);
7475 bnx2x_cl45_write(bp, phy,
7476 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
7478 } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
7479 (phy->speed_cap_mask &
7480 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
7481 ((phy->speed_cap_mask &
7482 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
7483 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
7484 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
7485 /* Set Flow control */
7486 bnx2x_ext_phy_set_pause(params, phy, vars);
7487 bnx2x_cl45_write(bp, phy,
7488 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
7489 bnx2x_cl45_write(bp, phy,
7490 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
7491 bnx2x_cl45_write(bp, phy,
7492 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
7493 bnx2x_cl45_write(bp, phy,
7494 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
7495 bnx2x_cl45_write(bp, phy,
7496 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
7498 * Enable RX-ALARM control to receive interrupt for 1G speed
7501 bnx2x_cl45_write(bp, phy,
7502 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4);
7503 bnx2x_cl45_write(bp, phy,
7504 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
7507 } else { /* Default 10G. Set only LASI control */
7508 bnx2x_cl45_write(bp, phy,
7509 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
7512 /* Set TX PreEmphasis if needed */
7513 if ((params->feature_config_flags &
7514 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
7515 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
7517 phy->tx_preemphasis[0],
7518 phy->tx_preemphasis[1]);
7519 bnx2x_cl45_write(bp, phy,
7521 MDIO_PMA_REG_8726_TX_CTRL1,
7522 phy->tx_preemphasis[0]);
7524 bnx2x_cl45_write(bp, phy,
7526 MDIO_PMA_REG_8726_TX_CTRL2,
7527 phy->tx_preemphasis[1]);
7534 static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
7535 struct link_params *params)
7537 struct bnx2x *bp = params->bp;
7538 DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
7539 /* Set serial boot control for external load */
7540 bnx2x_cl45_write(bp, phy,
7542 MDIO_PMA_REG_GEN_CTRL, 0x0001);
7545 /******************************************************************/
7546 /* BCM8727 PHY SECTION */
7547 /******************************************************************/
7549 static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy,
7550 struct link_params *params, u8 mode)
7552 struct bnx2x *bp = params->bp;
7553 u16 led_mode_bitmask = 0;
7554 u16 gpio_pins_bitmask = 0;
7556 /* Only NOC flavor requires to set the LED specifically */
7557 if (!(phy->flags & FLAGS_NOC))
7560 case LED_MODE_FRONT_PANEL_OFF:
7562 led_mode_bitmask = 0;
7563 gpio_pins_bitmask = 0x03;
7566 led_mode_bitmask = 0;
7567 gpio_pins_bitmask = 0x02;
7570 led_mode_bitmask = 0x60;
7571 gpio_pins_bitmask = 0x11;
7574 bnx2x_cl45_read(bp, phy,
7576 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
7579 val |= led_mode_bitmask;
7580 bnx2x_cl45_write(bp, phy,
7582 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
7584 bnx2x_cl45_read(bp, phy,
7586 MDIO_PMA_REG_8727_GPIO_CTRL,
7589 val |= gpio_pins_bitmask;
7590 bnx2x_cl45_write(bp, phy,
7592 MDIO_PMA_REG_8727_GPIO_CTRL,
7595 static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
7596 struct link_params *params) {
7597 u32 swap_val, swap_override;
7600 * The PHY reset is controlled by GPIO 1. Fake the port number
7601 * to cancel the swap done in set_gpio()
7603 struct bnx2x *bp = params->bp;
7604 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
7605 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
7606 port = (swap_val && swap_override) ^ 1;
7607 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
7608 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
7611 static int bnx2x_8727_config_init(struct bnx2x_phy *phy,
7612 struct link_params *params,
7613 struct link_vars *vars)
7616 u16 tmp1, val, mod_abs, tmp2;
7617 u16 rx_alarm_ctrl_val;
7619 struct bnx2x *bp = params->bp;
7620 /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
7622 bnx2x_wait_reset_complete(bp, phy, params);
7623 rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
7624 /* Should be 0x6 to enable XS on Tx side. */
7625 lasi_ctrl_val = 0x0006;
7627 DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
7629 bnx2x_cl45_write(bp, phy,
7630 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
7632 bnx2x_cl45_write(bp, phy,
7633 MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_ALARM_CTRL,
7635 bnx2x_cl45_write(bp, phy,
7636 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val);
7639 * Initially configure MOD_ABS to interrupt when module is
7642 bnx2x_cl45_read(bp, phy,
7643 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
7645 * Set EDC off by setting OPTXLOS signal input to low (bit 9).
7646 * When the EDC is off it locks onto a reference clock and avoids
7650 if (!(phy->flags & FLAGS_NOC))
7652 bnx2x_cl45_write(bp, phy,
7653 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
7656 /* Make MOD_ABS give interrupt on change */
7657 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
7660 if (phy->flags & FLAGS_NOC)
7664 * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
7665 * status which reflect SFP+ module over-current
7667 if (!(phy->flags & FLAGS_NOC))
7668 val &= 0xff8f; /* Reset bits 4-6 */
7669 bnx2x_cl45_write(bp, phy,
7670 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val);
7672 bnx2x_8727_power_module(bp, phy, 1);
7674 bnx2x_cl45_read(bp, phy,
7675 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
7677 bnx2x_cl45_read(bp, phy,
7678 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
7680 /* Set option 1G speed */
7681 if (phy->req_line_speed == SPEED_1000) {
7682 DP(NETIF_MSG_LINK, "Setting 1G force\n");
7683 bnx2x_cl45_write(bp, phy,
7684 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
7685 bnx2x_cl45_write(bp, phy,
7686 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
7687 bnx2x_cl45_read(bp, phy,
7688 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
7689 DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
7691 * Power down the XAUI until link is up in case of dual-media
7694 if (DUAL_MEDIA(params)) {
7695 bnx2x_cl45_read(bp, phy,
7697 MDIO_PMA_REG_8727_PCS_GP, &val);
7699 bnx2x_cl45_write(bp, phy,
7701 MDIO_PMA_REG_8727_PCS_GP, val);
7703 } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
7704 ((phy->speed_cap_mask &
7705 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
7706 ((phy->speed_cap_mask &
7707 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
7708 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
7710 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
7711 bnx2x_cl45_write(bp, phy,
7712 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
7713 bnx2x_cl45_write(bp, phy,
7714 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
7717 * Since the 8727 has only single reset pin, need to set the 10G
7718 * registers although it is default
7720 bnx2x_cl45_write(bp, phy,
7721 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
7723 bnx2x_cl45_write(bp, phy,
7724 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
7725 bnx2x_cl45_write(bp, phy,
7726 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
7727 bnx2x_cl45_write(bp, phy,
7728 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
7733 * Set 2-wire transfer rate of SFP+ module EEPROM
7734 * to 100Khz since some DACs(direct attached cables) do
7735 * not work at 400Khz.
7737 bnx2x_cl45_write(bp, phy,
7738 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
7741 /* Set TX PreEmphasis if needed */
7742 if ((params->feature_config_flags &
7743 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
7744 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
7745 phy->tx_preemphasis[0],
7746 phy->tx_preemphasis[1]);
7747 bnx2x_cl45_write(bp, phy,
7748 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
7749 phy->tx_preemphasis[0]);
7751 bnx2x_cl45_write(bp, phy,
7752 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
7753 phy->tx_preemphasis[1]);
7757 * If TX Laser is controlled by GPIO_0, do not let PHY go into low
7758 * power mode, if TX Laser is disabled
7760 tx_en_mode = REG_RD(bp, params->shmem_base +
7761 offsetof(struct shmem_region,
7762 dev_info.port_hw_config[params->port].sfp_ctrl))
7763 & PORT_HW_CFG_TX_LASER_MASK;
7765 if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
7767 DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
7768 bnx2x_cl45_read(bp, phy,
7769 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2);
7772 bnx2x_cl45_write(bp, phy,
7773 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
7779 static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
7780 struct link_params *params)
7782 struct bnx2x *bp = params->bp;
7783 u16 mod_abs, rx_alarm_status;
7784 u32 val = REG_RD(bp, params->shmem_base +
7785 offsetof(struct shmem_region, dev_info.
7786 port_feature_config[params->port].
7788 bnx2x_cl45_read(bp, phy,
7790 MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
7791 if (mod_abs & (1<<8)) {
7793 /* Module is absent */
7794 DP(NETIF_MSG_LINK, "MOD_ABS indication "
7795 "show module is absent\n");
7796 phy->media_type = ETH_PHY_NOT_PRESENT;
7798 * 1. Set mod_abs to detect next module
7800 * 2. Set EDC off by setting OPTXLOS signal input to low
7802 * When the EDC is off it locks onto a reference clock and
7803 * avoids becoming 'lost'.
7806 if (!(phy->flags & FLAGS_NOC))
7808 bnx2x_cl45_write(bp, phy,
7810 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
7813 * Clear RX alarm since it stays up as long as
7814 * the mod_abs wasn't changed
7816 bnx2x_cl45_read(bp, phy,
7818 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
7821 /* Module is present */
7822 DP(NETIF_MSG_LINK, "MOD_ABS indication "
7823 "show module is present\n");
7825 * First disable transmitter, and if the module is ok, the
7826 * module_detection will enable it
7827 * 1. Set mod_abs to detect next module absent event ( bit 8)
7828 * 2. Restore the default polarity of the OPRXLOS signal and
7829 * this signal will then correctly indicate the presence or
7830 * absence of the Rx signal. (bit 9)
7833 if (!(phy->flags & FLAGS_NOC))
7835 bnx2x_cl45_write(bp, phy,
7837 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
7840 * Clear RX alarm since it stays up as long as the mod_abs
7841 * wasn't changed. This is need to be done before calling the
7842 * module detection, otherwise it will clear* the link update
7845 bnx2x_cl45_read(bp, phy,
7847 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
7850 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
7851 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
7852 bnx2x_sfp_set_transmitter(params, phy, 0);
7854 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
7855 bnx2x_sfp_module_detection(phy, params);
7857 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
7860 DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
7862 /* No need to check link status in case of module plugged in/out */
7865 static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
7866 struct link_params *params,
7867 struct link_vars *vars)
7870 struct bnx2x *bp = params->bp;
7871 u8 link_up = 0, oc_port = params->port;
7872 u16 link_status = 0;
7873 u16 rx_alarm_status, lasi_ctrl, val1;
7875 /* If PHY is not initialized, do not check link status */
7876 bnx2x_cl45_read(bp, phy,
7877 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
7882 /* Check the LASI on Rx */
7883 bnx2x_cl45_read(bp, phy,
7884 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
7886 vars->line_speed = 0;
7887 DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status);
7889 bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_REG_TX_ALARM,
7890 MDIO_PMA_REG_TX_ALARM_CTRL);
7892 bnx2x_cl45_read(bp, phy,
7893 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
7895 DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
7898 bnx2x_cl45_read(bp, phy,
7899 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
7902 * If a module is present and there is need to check
7905 if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
7906 /* Check over-current using 8727 GPIO0 input*/
7907 bnx2x_cl45_read(bp, phy,
7908 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
7911 if ((val1 & (1<<8)) == 0) {
7912 if (!CHIP_IS_E1x(bp))
7913 oc_port = BP_PATH(bp) + (params->port << 1);
7914 DP(NETIF_MSG_LINK, "8727 Power fault has been detected"
7915 " on port %d\n", oc_port);
7916 netdev_err(bp->dev, "Error: Power fault on Port %d has"
7917 " been detected and the power to "
7918 "that SFP+ module has been removed"
7919 " to prevent failure of the card."
7920 " Please remove the SFP+ module and"
7921 " restart the system to clear this"
7924 /* Disable all RX_ALARMs except for mod_abs */
7925 bnx2x_cl45_write(bp, phy,
7927 MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5));
7929 bnx2x_cl45_read(bp, phy,
7931 MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
7932 /* Wait for module_absent_event */
7934 bnx2x_cl45_write(bp, phy,
7936 MDIO_PMA_REG_PHY_IDENTIFIER, val1);
7937 /* Clear RX alarm */
7938 bnx2x_cl45_read(bp, phy,
7940 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
7943 } /* Over current check */
7945 /* When module absent bit is set, check module */
7946 if (rx_alarm_status & (1<<5)) {
7947 bnx2x_8727_handle_mod_abs(phy, params);
7948 /* Enable all mod_abs and link detection bits */
7949 bnx2x_cl45_write(bp, phy,
7950 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
7953 DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n");
7954 bnx2x_8727_specific_func(phy, params, ENABLE_TX);
7955 /* If transmitter is disabled, ignore false link up indication */
7956 bnx2x_cl45_read(bp, phy,
7957 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
7958 if (val1 & (1<<15)) {
7959 DP(NETIF_MSG_LINK, "Tx is disabled\n");
7963 bnx2x_cl45_read(bp, phy,
7965 MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
7968 * Bits 0..2 --> speed detected,
7969 * Bits 13..15--> link is down
7971 if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
7973 vars->line_speed = SPEED_10000;
7974 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
7976 } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
7978 vars->line_speed = SPEED_1000;
7979 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
7983 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
7987 /* Capture 10G link fault. */
7988 if (vars->line_speed == SPEED_10000) {
7989 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
7990 MDIO_PMA_REG_TX_ALARM, &val1);
7992 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
7993 MDIO_PMA_REG_TX_ALARM, &val1);
7995 if (val1 & (1<<0)) {
7996 vars->fault_detected = 1;
8001 bnx2x_ext_phy_resolve_fc(phy, params, vars);
8002 vars->duplex = DUPLEX_FULL;
8003 DP(NETIF_MSG_LINK, "duplex = 0x%x\n", vars->duplex);
8006 if ((DUAL_MEDIA(params)) &&
8007 (phy->req_line_speed == SPEED_1000)) {
8008 bnx2x_cl45_read(bp, phy,
8010 MDIO_PMA_REG_8727_PCS_GP, &val1);
8012 * In case of dual-media board and 1G, power up the XAUI side,
8013 * otherwise power it down. For 10G it is done automatically
8019 bnx2x_cl45_write(bp, phy,
8021 MDIO_PMA_REG_8727_PCS_GP, val1);
8026 static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
8027 struct link_params *params)
8029 struct bnx2x *bp = params->bp;
8030 /* Disable Transmitter */
8031 bnx2x_sfp_set_transmitter(params, phy, 0);
8033 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0);
8037 /******************************************************************/
8038 /* BCM8481/BCM84823/BCM84833 PHY SECTION */
8039 /******************************************************************/
8040 static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
8041 struct link_params *params)
8043 u16 val, fw_ver1, fw_ver2, cnt;
8045 struct bnx2x *bp = params->bp;
8047 port = params->port;
8049 /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
8050 /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
8051 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
8052 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
8053 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
8054 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
8055 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
8057 for (cnt = 0; cnt < 100; cnt++) {
8058 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
8064 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n");
8065 bnx2x_save_spirom_version(bp, port, 0,
8071 /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
8072 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
8073 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
8074 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
8075 for (cnt = 0; cnt < 100; cnt++) {
8076 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
8082 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n");
8083 bnx2x_save_spirom_version(bp, port, 0,
8088 /* lower 16 bits of the register SPI_FW_STATUS */
8089 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
8090 /* upper 16 bits of register SPI_FW_STATUS */
8091 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
8093 bnx2x_save_spirom_version(bp, port, (fw_ver2<<16) | fw_ver1,
8097 static void bnx2x_848xx_set_led(struct bnx2x *bp,
8098 struct bnx2x_phy *phy)
8102 /* PHYC_CTL_LED_CTL */
8103 bnx2x_cl45_read(bp, phy,
8105 MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
8109 bnx2x_cl45_write(bp, phy,
8111 MDIO_PMA_REG_8481_LINK_SIGNAL, val);
8113 bnx2x_cl45_write(bp, phy,
8115 MDIO_PMA_REG_8481_LED1_MASK,
8118 bnx2x_cl45_write(bp, phy,
8120 MDIO_PMA_REG_8481_LED2_MASK,
8123 /* Select activity source by Tx and Rx, as suggested by PHY AE */
8124 bnx2x_cl45_write(bp, phy,
8126 MDIO_PMA_REG_8481_LED3_MASK,
8129 /* Select the closest activity blink rate to that in 10/100/1000 */
8130 bnx2x_cl45_write(bp, phy,
8132 MDIO_PMA_REG_8481_LED3_BLINK,
8135 bnx2x_cl45_read(bp, phy,
8137 MDIO_PMA_REG_84823_CTL_LED_CTL_1, &val);
8138 val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/
8140 bnx2x_cl45_write(bp, phy,
8142 MDIO_PMA_REG_84823_CTL_LED_CTL_1, val);
8144 /* 'Interrupt Mask' */
8145 bnx2x_cl45_write(bp, phy,
8150 static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
8151 struct link_params *params,
8152 struct link_vars *vars)
8154 struct bnx2x *bp = params->bp;
8155 u16 autoneg_val, an_1000_val, an_10_100_val;
8156 u16 tmp_req_line_speed;
8158 tmp_req_line_speed = phy->req_line_speed;
8159 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
8160 if (phy->req_line_speed == SPEED_10000)
8161 phy->req_line_speed = SPEED_AUTO_NEG;
8164 * This phy uses the NIG latch mechanism since link indication
8165 * arrives through its LED4 and not via its LASI signal, so we
8166 * get steady signal instead of clear on read
8168 bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
8169 1 << NIG_LATCH_BC_ENABLE_MI_INT);
8171 bnx2x_cl45_write(bp, phy,
8172 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
8174 bnx2x_848xx_set_led(bp, phy);
8176 /* set 1000 speed advertisement */
8177 bnx2x_cl45_read(bp, phy,
8178 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
8181 bnx2x_ext_phy_set_pause(params, phy, vars);
8182 bnx2x_cl45_read(bp, phy,
8184 MDIO_AN_REG_8481_LEGACY_AN_ADV,
8186 bnx2x_cl45_read(bp, phy,
8187 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
8189 /* Disable forced speed */
8190 autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
8191 an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
8193 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
8194 (phy->speed_cap_mask &
8195 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
8196 (phy->req_line_speed == SPEED_1000)) {
8197 an_1000_val |= (1<<8);
8198 autoneg_val |= (1<<9 | 1<<12);
8199 if (phy->req_duplex == DUPLEX_FULL)
8200 an_1000_val |= (1<<9);
8201 DP(NETIF_MSG_LINK, "Advertising 1G\n");
8203 an_1000_val &= ~((1<<8) | (1<<9));
8205 bnx2x_cl45_write(bp, phy,
8206 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
8209 /* set 10 speed advertisement */
8210 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
8211 (phy->speed_cap_mask &
8212 (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
8213 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
8214 an_10_100_val |= (1<<7);
8215 /* Enable autoneg and restart autoneg for legacy speeds */
8216 autoneg_val |= (1<<9 | 1<<12);
8218 if (phy->req_duplex == DUPLEX_FULL)
8219 an_10_100_val |= (1<<8);
8220 DP(NETIF_MSG_LINK, "Advertising 100M\n");
8222 /* set 10 speed advertisement */
8223 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
8224 (phy->speed_cap_mask &
8225 (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
8226 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
8227 an_10_100_val |= (1<<5);
8228 autoneg_val |= (1<<9 | 1<<12);
8229 if (phy->req_duplex == DUPLEX_FULL)
8230 an_10_100_val |= (1<<6);
8231 DP(NETIF_MSG_LINK, "Advertising 10M\n");
8234 /* Only 10/100 are allowed to work in FORCE mode */
8235 if (phy->req_line_speed == SPEED_100) {
8236 autoneg_val |= (1<<13);
8237 /* Enabled AUTO-MDIX when autoneg is disabled */
8238 bnx2x_cl45_write(bp, phy,
8239 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
8240 (1<<15 | 1<<9 | 7<<0));
8241 DP(NETIF_MSG_LINK, "Setting 100M force\n");
8243 if (phy->req_line_speed == SPEED_10) {
8244 /* Enabled AUTO-MDIX when autoneg is disabled */
8245 bnx2x_cl45_write(bp, phy,
8246 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
8247 (1<<15 | 1<<9 | 7<<0));
8248 DP(NETIF_MSG_LINK, "Setting 10M force\n");
8251 bnx2x_cl45_write(bp, phy,
8252 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
8255 if (phy->req_duplex == DUPLEX_FULL)
8256 autoneg_val |= (1<<8);
8258 bnx2x_cl45_write(bp, phy,
8260 MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
8262 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
8263 (phy->speed_cap_mask &
8264 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
8265 (phy->req_line_speed == SPEED_10000)) {
8266 DP(NETIF_MSG_LINK, "Advertising 10G\n");
8267 /* Restart autoneg for 10G*/
8269 bnx2x_cl45_write(bp, phy,
8270 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
8272 } else if (phy->req_line_speed != SPEED_10 &&
8273 phy->req_line_speed != SPEED_100) {
8274 bnx2x_cl45_write(bp, phy,
8276 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
8279 /* Save spirom version */
8280 bnx2x_save_848xx_spirom_version(phy, params);
8282 phy->req_line_speed = tmp_req_line_speed;
8287 static int bnx2x_8481_config_init(struct bnx2x_phy *phy,
8288 struct link_params *params,
8289 struct link_vars *vars)
8291 struct bnx2x *bp = params->bp;
8292 /* Restore normal power mode*/
8293 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
8294 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
8297 bnx2x_ext_phy_hw_reset(bp, params->port);
8298 bnx2x_wait_reset_complete(bp, phy, params);
8300 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
8301 return bnx2x_848xx_cmn_config_init(phy, params, vars);
8305 #define PHY84833_HDSHK_WAIT 300
8306 static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy,
8307 struct link_params *params,
8308 struct link_vars *vars)
8313 struct bnx2x *bp = params->bp;
8317 /* Write CMD_OPEN_OVERRIDE to STATUS reg */
8318 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
8319 MDIO_84833_TOP_CFG_SCRATCH_REG2,
8320 PHY84833_CMD_OPEN_OVERRIDE);
8321 for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
8322 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
8323 MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
8324 if (val == PHY84833_CMD_OPEN_FOR_CMDS)
8328 if (idx >= PHY84833_HDSHK_WAIT) {
8329 DP(NETIF_MSG_LINK, "Pairswap: FW not ready.\n");
8333 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
8334 MDIO_84833_TOP_CFG_SCRATCH_REG4,
8336 /* Issue pair swap command */
8337 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
8338 MDIO_84833_TOP_CFG_SCRATCH_REG0,
8339 PHY84833_DIAG_CMD_PAIR_SWAP_CHANGE);
8340 for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
8341 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
8342 MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
8343 if ((val == PHY84833_CMD_COMPLETE_PASS) ||
8344 (val == PHY84833_CMD_COMPLETE_ERROR))
8348 if ((idx >= PHY84833_HDSHK_WAIT) ||
8349 (val == PHY84833_CMD_COMPLETE_ERROR)) {
8350 DP(NETIF_MSG_LINK, "Pairswap: override failed.\n");
8353 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
8354 MDIO_84833_TOP_CFG_SCRATCH_REG2,
8355 PHY84833_CMD_CLEAR_COMPLETE);
8356 DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data);
8360 static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
8361 struct link_params *params,
8362 struct link_vars *vars)
8364 struct bnx2x *bp = params->bp;
8365 u8 port, initialize = 1;
8368 u32 actual_phy_selection, cms_enable;
8373 if (!(CHIP_IS_E1(bp)))
8376 port = params->port;
8378 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
8379 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
8380 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
8383 bnx2x_cl45_write(bp, phy,
8385 MDIO_PMA_REG_CTRL, 0x8000);
8388 bnx2x_wait_reset_complete(bp, phy, params);
8389 /* Wait for GPHY to come out of reset */
8392 /* Bring PHY out of super isolate mode */
8393 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
8394 bnx2x_cl45_read(bp, phy,
8396 MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
8397 val &= ~MDIO_84833_SUPER_ISOLATE;
8398 bnx2x_cl45_write(bp, phy,
8400 MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
8401 bnx2x_wait_reset_complete(bp, phy, params);
8404 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
8405 bnx2x_84833_pair_swap_cfg(phy, params, vars);
8408 * BCM84823 requires that XGXS links up first @ 10G for normal behavior
8410 temp = vars->line_speed;
8411 vars->line_speed = SPEED_10000;
8412 bnx2x_set_autoneg(¶ms->phy[INT_PHY], params, vars, 0);
8413 bnx2x_program_serdes(¶ms->phy[INT_PHY], params, vars);
8414 vars->line_speed = temp;
8416 /* Set dual-media configuration according to configuration */
8418 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
8419 MDIO_CTL_REG_84823_MEDIA, &val);
8420 val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
8421 MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
8422 MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
8423 MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
8424 MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
8425 val |= MDIO_CTL_REG_84823_CTRL_MAC_XFI |
8426 MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L;
8428 actual_phy_selection = bnx2x_phy_selection(params);
8430 switch (actual_phy_selection) {
8431 case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
8432 /* Do nothing. Essentially this is like the priority copper */
8434 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
8435 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
8437 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
8438 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
8440 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
8441 /* Do nothing here. The first PHY won't be initialized at all */
8443 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
8444 val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
8448 if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000)
8449 val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
8451 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
8452 MDIO_CTL_REG_84823_MEDIA, val);
8453 DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
8454 params->multi_phy_config, val);
8457 rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
8459 bnx2x_save_848xx_spirom_version(phy, params);
8460 cms_enable = REG_RD(bp, params->shmem_base +
8461 offsetof(struct shmem_region,
8462 dev_info.port_hw_config[params->port].default_cfg)) &
8463 PORT_HW_CFG_ENABLE_CMS_MASK;
8465 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
8466 MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
8468 val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
8470 val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
8471 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
8472 MDIO_CTL_REG_84823_USER_CTRL_REG, val);
8478 static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
8479 struct link_params *params,
8480 struct link_vars *vars)
8482 struct bnx2x *bp = params->bp;
8483 u16 val, val1, val2;
8487 /* Check 10G-BaseT link status */
8488 /* Check PMD signal ok */
8489 bnx2x_cl45_read(bp, phy,
8490 MDIO_AN_DEVAD, 0xFFFA, &val1);
8491 bnx2x_cl45_read(bp, phy,
8492 MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
8494 DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
8496 /* Check link 10G */
8497 if (val2 & (1<<11)) {
8498 vars->line_speed = SPEED_10000;
8499 vars->duplex = DUPLEX_FULL;
8501 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
8502 } else { /* Check Legacy speed link */
8503 u16 legacy_status, legacy_speed;
8505 /* Enable expansion register 0x42 (Operation mode status) */
8506 bnx2x_cl45_write(bp, phy,
8508 MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
8510 /* Get legacy speed operation status */
8511 bnx2x_cl45_read(bp, phy,
8513 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
8516 DP(NETIF_MSG_LINK, "Legacy speed status"
8517 " = 0x%x\n", legacy_status);
8518 link_up = ((legacy_status & (1<<11)) == (1<<11));
8520 legacy_speed = (legacy_status & (3<<9));
8521 if (legacy_speed == (0<<9))
8522 vars->line_speed = SPEED_10;
8523 else if (legacy_speed == (1<<9))
8524 vars->line_speed = SPEED_100;
8525 else if (legacy_speed == (2<<9))
8526 vars->line_speed = SPEED_1000;
8527 else /* Should not happen */
8528 vars->line_speed = 0;
8530 if (legacy_status & (1<<8))
8531 vars->duplex = DUPLEX_FULL;
8533 vars->duplex = DUPLEX_HALF;
8535 DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
8536 " is_duplex_full= %d\n", vars->line_speed,
8537 (vars->duplex == DUPLEX_FULL));
8538 /* Check legacy speed AN resolution */
8539 bnx2x_cl45_read(bp, phy,
8541 MDIO_AN_REG_8481_LEGACY_MII_STATUS,
8544 vars->link_status |=
8545 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
8546 bnx2x_cl45_read(bp, phy,
8548 MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
8550 if ((val & (1<<0)) == 0)
8551 vars->link_status |=
8552 LINK_STATUS_PARALLEL_DETECTION_USED;
8556 DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n",
8558 bnx2x_ext_phy_resolve_fc(phy, params, vars);
8565 static int bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
8569 spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
8570 status = bnx2x_format_ver(spirom_ver, str, len);
8574 static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
8575 struct link_params *params)
8577 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
8578 MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
8579 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
8580 MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
8583 static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
8584 struct link_params *params)
8586 bnx2x_cl45_write(params->bp, phy,
8587 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
8588 bnx2x_cl45_write(params->bp, phy,
8589 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
8592 static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
8593 struct link_params *params)
8595 struct bnx2x *bp = params->bp;
8598 if (!(CHIP_IS_E1(bp)))
8601 port = params->port;
8603 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
8604 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
8605 MISC_REGISTERS_GPIO_OUTPUT_LOW,
8608 bnx2x_cl45_write(bp, phy,
8610 MDIO_PMA_REG_CTRL, 0x800);
8614 static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
8615 struct link_params *params, u8 mode)
8617 struct bnx2x *bp = params->bp;
8621 if (!(CHIP_IS_E1(bp)))
8624 port = params->port;
8629 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", port);
8631 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
8632 SHARED_HW_CFG_LED_EXTPHY1) {
8635 bnx2x_cl45_write(bp, phy,
8637 MDIO_PMA_REG_8481_LED1_MASK,
8640 bnx2x_cl45_write(bp, phy,
8642 MDIO_PMA_REG_8481_LED2_MASK,
8645 bnx2x_cl45_write(bp, phy,
8647 MDIO_PMA_REG_8481_LED3_MASK,
8650 bnx2x_cl45_write(bp, phy,
8652 MDIO_PMA_REG_8481_LED5_MASK,
8656 bnx2x_cl45_write(bp, phy,
8658 MDIO_PMA_REG_8481_LED1_MASK,
8662 case LED_MODE_FRONT_PANEL_OFF:
8664 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
8667 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
8668 SHARED_HW_CFG_LED_EXTPHY1) {
8671 bnx2x_cl45_write(bp, phy,
8673 MDIO_PMA_REG_8481_LED1_MASK,
8676 bnx2x_cl45_write(bp, phy,
8678 MDIO_PMA_REG_8481_LED2_MASK,
8681 bnx2x_cl45_write(bp, phy,
8683 MDIO_PMA_REG_8481_LED3_MASK,
8686 bnx2x_cl45_write(bp, phy,
8688 MDIO_PMA_REG_8481_LED5_MASK,
8692 bnx2x_cl45_write(bp, phy,
8694 MDIO_PMA_REG_8481_LED1_MASK,
8700 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", port);
8702 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
8703 SHARED_HW_CFG_LED_EXTPHY1) {
8704 /* Set control reg */
8705 bnx2x_cl45_read(bp, phy,
8707 MDIO_PMA_REG_8481_LINK_SIGNAL,
8712 bnx2x_cl45_write(bp, phy,
8714 MDIO_PMA_REG_8481_LINK_SIGNAL,
8718 bnx2x_cl45_write(bp, phy,
8720 MDIO_PMA_REG_8481_LED1_MASK,
8723 bnx2x_cl45_write(bp, phy,
8725 MDIO_PMA_REG_8481_LED2_MASK,
8728 bnx2x_cl45_write(bp, phy,
8730 MDIO_PMA_REG_8481_LED3_MASK,
8733 bnx2x_cl45_write(bp, phy,
8735 MDIO_PMA_REG_8481_LED5_MASK,
8738 bnx2x_cl45_write(bp, phy,
8740 MDIO_PMA_REG_8481_LED1_MASK,
8747 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", port);
8749 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
8750 SHARED_HW_CFG_LED_EXTPHY1) {
8752 /* Set control reg */
8753 bnx2x_cl45_read(bp, phy,
8755 MDIO_PMA_REG_8481_LINK_SIGNAL,
8759 MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
8760 >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) {
8761 DP(NETIF_MSG_LINK, "Setting LINK_SIGNAL\n");
8762 bnx2x_cl45_write(bp, phy,
8764 MDIO_PMA_REG_8481_LINK_SIGNAL,
8769 bnx2x_cl45_write(bp, phy,
8771 MDIO_PMA_REG_8481_LED1_MASK,
8774 bnx2x_cl45_write(bp, phy,
8776 MDIO_PMA_REG_8481_LED2_MASK,
8779 bnx2x_cl45_write(bp, phy,
8781 MDIO_PMA_REG_8481_LED3_MASK,
8784 bnx2x_cl45_write(bp, phy,
8786 MDIO_PMA_REG_8481_LED5_MASK,
8790 bnx2x_cl45_write(bp, phy,
8792 MDIO_PMA_REG_8481_LED1_MASK,
8795 /* Tell LED3 to blink on source */
8796 bnx2x_cl45_read(bp, phy,
8798 MDIO_PMA_REG_8481_LINK_SIGNAL,
8801 val |= (1<<6); /* A83B[8:6]= 1 */
8802 bnx2x_cl45_write(bp, phy,
8804 MDIO_PMA_REG_8481_LINK_SIGNAL,
8810 /******************************************************************/
8811 /* SFX7101 PHY SECTION */
8812 /******************************************************************/
8813 static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
8814 struct link_params *params)
8816 struct bnx2x *bp = params->bp;
8817 /* SFX7101_XGXS_TEST1 */
8818 bnx2x_cl45_write(bp, phy,
8819 MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
8822 static int bnx2x_7101_config_init(struct bnx2x_phy *phy,
8823 struct link_params *params,
8824 struct link_vars *vars)
8826 u16 fw_ver1, fw_ver2, val;
8827 struct bnx2x *bp = params->bp;
8828 DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
8830 /* Restore normal power mode*/
8831 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
8832 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
8834 bnx2x_ext_phy_hw_reset(bp, params->port);
8835 bnx2x_wait_reset_complete(bp, phy, params);
8837 bnx2x_cl45_write(bp, phy,
8838 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1);
8839 DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
8840 bnx2x_cl45_write(bp, phy,
8841 MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
8843 bnx2x_ext_phy_set_pause(params, phy, vars);
8844 /* Restart autoneg */
8845 bnx2x_cl45_read(bp, phy,
8846 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
8848 bnx2x_cl45_write(bp, phy,
8849 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
8851 /* Save spirom version */
8852 bnx2x_cl45_read(bp, phy,
8853 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
8855 bnx2x_cl45_read(bp, phy,
8856 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
8857 bnx2x_save_spirom_version(bp, params->port,
8858 (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
8862 static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
8863 struct link_params *params,
8864 struct link_vars *vars)
8866 struct bnx2x *bp = params->bp;
8869 bnx2x_cl45_read(bp, phy,
8870 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
8871 bnx2x_cl45_read(bp, phy,
8872 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
8873 DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
8875 bnx2x_cl45_read(bp, phy,
8876 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
8877 bnx2x_cl45_read(bp, phy,
8878 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
8879 DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
8881 link_up = ((val1 & 4) == 4);
8882 /* if link is up print the AN outcome of the SFX7101 PHY */
8884 bnx2x_cl45_read(bp, phy,
8885 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
8887 vars->line_speed = SPEED_10000;
8888 vars->duplex = DUPLEX_FULL;
8889 DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
8890 val2, (val2 & (1<<14)));
8891 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
8892 bnx2x_ext_phy_resolve_fc(phy, params, vars);
8897 static int bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
8901 str[0] = (spirom_ver & 0xFF);
8902 str[1] = (spirom_ver & 0xFF00) >> 8;
8903 str[2] = (spirom_ver & 0xFF0000) >> 16;
8904 str[3] = (spirom_ver & 0xFF000000) >> 24;
8910 void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
8914 bnx2x_cl45_read(bp, phy,
8916 MDIO_PMA_REG_7101_RESET, &val);
8918 for (cnt = 0; cnt < 10; cnt++) {
8920 /* Writes a self-clearing reset */
8921 bnx2x_cl45_write(bp, phy,
8923 MDIO_PMA_REG_7101_RESET,
8925 /* Wait for clear */
8926 bnx2x_cl45_read(bp, phy,
8928 MDIO_PMA_REG_7101_RESET, &val);
8930 if ((val & (1<<15)) == 0)
8935 static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
8936 struct link_params *params) {
8937 /* Low power mode is controlled by GPIO 2 */
8938 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
8939 MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
8940 /* The PHY reset is controlled by GPIO 1 */
8941 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
8942 MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
8945 static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy,
8946 struct link_params *params, u8 mode)
8949 struct bnx2x *bp = params->bp;
8951 case LED_MODE_FRONT_PANEL_OFF:
8962 bnx2x_cl45_write(bp, phy,
8964 MDIO_PMA_REG_7107_LINK_LED_CNTL,
8968 /******************************************************************/
8969 /* STATIC PHY DECLARATION */
8970 /******************************************************************/
8972 static struct bnx2x_phy phy_null = {
8973 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
8976 .flags = FLAGS_INIT_XGXS_FIRST,
8977 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
8978 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
8981 .media_type = ETH_PHY_NOT_PRESENT,
8984 .req_line_speed = 0,
8985 .speed_cap_mask = 0,
8988 .config_init = (config_init_t)NULL,
8989 .read_status = (read_status_t)NULL,
8990 .link_reset = (link_reset_t)NULL,
8991 .config_loopback = (config_loopback_t)NULL,
8992 .format_fw_ver = (format_fw_ver_t)NULL,
8993 .hw_reset = (hw_reset_t)NULL,
8994 .set_link_led = (set_link_led_t)NULL,
8995 .phy_specific_func = (phy_specific_func_t)NULL
8998 static struct bnx2x_phy phy_serdes = {
8999 .type = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
9003 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9004 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9006 .supported = (SUPPORTED_10baseT_Half |
9007 SUPPORTED_10baseT_Full |
9008 SUPPORTED_100baseT_Half |
9009 SUPPORTED_100baseT_Full |
9010 SUPPORTED_1000baseT_Full |
9011 SUPPORTED_2500baseX_Full |
9015 SUPPORTED_Asym_Pause),
9016 .media_type = ETH_PHY_BASE_T,
9019 .req_line_speed = 0,
9020 .speed_cap_mask = 0,
9023 .config_init = (config_init_t)bnx2x_xgxs_config_init,
9024 .read_status = (read_status_t)bnx2x_link_settings_status,
9025 .link_reset = (link_reset_t)bnx2x_int_link_reset,
9026 .config_loopback = (config_loopback_t)NULL,
9027 .format_fw_ver = (format_fw_ver_t)NULL,
9028 .hw_reset = (hw_reset_t)NULL,
9029 .set_link_led = (set_link_led_t)NULL,
9030 .phy_specific_func = (phy_specific_func_t)NULL
9033 static struct bnx2x_phy phy_xgxs = {
9034 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
9038 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9039 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9041 .supported = (SUPPORTED_10baseT_Half |
9042 SUPPORTED_10baseT_Full |
9043 SUPPORTED_100baseT_Half |
9044 SUPPORTED_100baseT_Full |
9045 SUPPORTED_1000baseT_Full |
9046 SUPPORTED_2500baseX_Full |
9047 SUPPORTED_10000baseT_Full |
9051 SUPPORTED_Asym_Pause),
9052 .media_type = ETH_PHY_CX4,
9055 .req_line_speed = 0,
9056 .speed_cap_mask = 0,
9059 .config_init = (config_init_t)bnx2x_xgxs_config_init,
9060 .read_status = (read_status_t)bnx2x_link_settings_status,
9061 .link_reset = (link_reset_t)bnx2x_int_link_reset,
9062 .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
9063 .format_fw_ver = (format_fw_ver_t)NULL,
9064 .hw_reset = (hw_reset_t)NULL,
9065 .set_link_led = (set_link_led_t)NULL,
9066 .phy_specific_func = (phy_specific_func_t)NULL
9068 static struct bnx2x_phy phy_warpcore = {
9069 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
9072 .flags = FLAGS_HW_LOCK_REQUIRED,
9073 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9074 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9076 .supported = (SUPPORTED_10baseT_Half |
9077 SUPPORTED_10baseT_Full |
9078 SUPPORTED_100baseT_Half |
9079 SUPPORTED_100baseT_Full |
9080 SUPPORTED_1000baseT_Full |
9081 SUPPORTED_10000baseT_Full |
9082 SUPPORTED_20000baseKR2_Full |
9083 SUPPORTED_20000baseMLD2_Full |
9087 SUPPORTED_Asym_Pause),
9088 .media_type = ETH_PHY_UNSPECIFIED,
9091 .req_line_speed = 0,
9092 .speed_cap_mask = 0,
9093 /* req_duplex = */0,
9095 .config_init = (config_init_t)bnx2x_warpcore_config_init,
9096 .read_status = (read_status_t)bnx2x_warpcore_read_status,
9097 .link_reset = (link_reset_t)bnx2x_warpcore_link_reset,
9098 .config_loopback = (config_loopback_t)bnx2x_set_warpcore_loopback,
9099 .format_fw_ver = (format_fw_ver_t)NULL,
9100 .hw_reset = (hw_reset_t)NULL,
9101 .set_link_led = (set_link_led_t)NULL,
9102 .phy_specific_func = (phy_specific_func_t)NULL
9106 static struct bnx2x_phy phy_7101 = {
9107 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
9110 .flags = FLAGS_FAN_FAILURE_DET_REQ,
9111 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9112 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9114 .supported = (SUPPORTED_10000baseT_Full |
9118 SUPPORTED_Asym_Pause),
9119 .media_type = ETH_PHY_BASE_T,
9122 .req_line_speed = 0,
9123 .speed_cap_mask = 0,
9126 .config_init = (config_init_t)bnx2x_7101_config_init,
9127 .read_status = (read_status_t)bnx2x_7101_read_status,
9128 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
9129 .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
9130 .format_fw_ver = (format_fw_ver_t)bnx2x_7101_format_ver,
9131 .hw_reset = (hw_reset_t)bnx2x_7101_hw_reset,
9132 .set_link_led = (set_link_led_t)bnx2x_7101_set_link_led,
9133 .phy_specific_func = (phy_specific_func_t)NULL
9135 static struct bnx2x_phy phy_8073 = {
9136 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
9139 .flags = FLAGS_HW_LOCK_REQUIRED,
9140 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9141 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9143 .supported = (SUPPORTED_10000baseT_Full |
9144 SUPPORTED_2500baseX_Full |
9145 SUPPORTED_1000baseT_Full |
9149 SUPPORTED_Asym_Pause),
9150 .media_type = ETH_PHY_KR,
9153 .req_line_speed = 0,
9154 .speed_cap_mask = 0,
9157 .config_init = (config_init_t)bnx2x_8073_config_init,
9158 .read_status = (read_status_t)bnx2x_8073_read_status,
9159 .link_reset = (link_reset_t)bnx2x_8073_link_reset,
9160 .config_loopback = (config_loopback_t)NULL,
9161 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
9162 .hw_reset = (hw_reset_t)NULL,
9163 .set_link_led = (set_link_led_t)NULL,
9164 .phy_specific_func = (phy_specific_func_t)NULL
9166 static struct bnx2x_phy phy_8705 = {
9167 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
9170 .flags = FLAGS_INIT_XGXS_FIRST,
9171 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9172 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9174 .supported = (SUPPORTED_10000baseT_Full |
9177 SUPPORTED_Asym_Pause),
9178 .media_type = ETH_PHY_XFP_FIBER,
9181 .req_line_speed = 0,
9182 .speed_cap_mask = 0,
9185 .config_init = (config_init_t)bnx2x_8705_config_init,
9186 .read_status = (read_status_t)bnx2x_8705_read_status,
9187 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
9188 .config_loopback = (config_loopback_t)NULL,
9189 .format_fw_ver = (format_fw_ver_t)bnx2x_null_format_ver,
9190 .hw_reset = (hw_reset_t)NULL,
9191 .set_link_led = (set_link_led_t)NULL,
9192 .phy_specific_func = (phy_specific_func_t)NULL
9194 static struct bnx2x_phy phy_8706 = {
9195 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
9198 .flags = FLAGS_INIT_XGXS_FIRST,
9199 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9200 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9202 .supported = (SUPPORTED_10000baseT_Full |
9203 SUPPORTED_1000baseT_Full |
9206 SUPPORTED_Asym_Pause),
9207 .media_type = ETH_PHY_SFP_FIBER,
9210 .req_line_speed = 0,
9211 .speed_cap_mask = 0,
9214 .config_init = (config_init_t)bnx2x_8706_config_init,
9215 .read_status = (read_status_t)bnx2x_8706_read_status,
9216 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
9217 .config_loopback = (config_loopback_t)NULL,
9218 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
9219 .hw_reset = (hw_reset_t)NULL,
9220 .set_link_led = (set_link_led_t)NULL,
9221 .phy_specific_func = (phy_specific_func_t)NULL
9224 static struct bnx2x_phy phy_8726 = {
9225 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
9228 .flags = (FLAGS_HW_LOCK_REQUIRED |
9229 FLAGS_INIT_XGXS_FIRST),
9230 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9231 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9233 .supported = (SUPPORTED_10000baseT_Full |
9234 SUPPORTED_1000baseT_Full |
9238 SUPPORTED_Asym_Pause),
9239 .media_type = ETH_PHY_NOT_PRESENT,
9242 .req_line_speed = 0,
9243 .speed_cap_mask = 0,
9246 .config_init = (config_init_t)bnx2x_8726_config_init,
9247 .read_status = (read_status_t)bnx2x_8726_read_status,
9248 .link_reset = (link_reset_t)bnx2x_8726_link_reset,
9249 .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
9250 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
9251 .hw_reset = (hw_reset_t)NULL,
9252 .set_link_led = (set_link_led_t)NULL,
9253 .phy_specific_func = (phy_specific_func_t)NULL
9256 static struct bnx2x_phy phy_8727 = {
9257 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
9260 .flags = FLAGS_FAN_FAILURE_DET_REQ,
9261 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9262 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9264 .supported = (SUPPORTED_10000baseT_Full |
9265 SUPPORTED_1000baseT_Full |
9268 SUPPORTED_Asym_Pause),
9269 .media_type = ETH_PHY_NOT_PRESENT,
9272 .req_line_speed = 0,
9273 .speed_cap_mask = 0,
9276 .config_init = (config_init_t)bnx2x_8727_config_init,
9277 .read_status = (read_status_t)bnx2x_8727_read_status,
9278 .link_reset = (link_reset_t)bnx2x_8727_link_reset,
9279 .config_loopback = (config_loopback_t)NULL,
9280 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
9281 .hw_reset = (hw_reset_t)bnx2x_8727_hw_reset,
9282 .set_link_led = (set_link_led_t)bnx2x_8727_set_link_led,
9283 .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func
9285 static struct bnx2x_phy phy_8481 = {
9286 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
9289 .flags = FLAGS_FAN_FAILURE_DET_REQ |
9290 FLAGS_REARM_LATCH_SIGNAL,
9291 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9292 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9294 .supported = (SUPPORTED_10baseT_Half |
9295 SUPPORTED_10baseT_Full |
9296 SUPPORTED_100baseT_Half |
9297 SUPPORTED_100baseT_Full |
9298 SUPPORTED_1000baseT_Full |
9299 SUPPORTED_10000baseT_Full |
9303 SUPPORTED_Asym_Pause),
9304 .media_type = ETH_PHY_BASE_T,
9307 .req_line_speed = 0,
9308 .speed_cap_mask = 0,
9311 .config_init = (config_init_t)bnx2x_8481_config_init,
9312 .read_status = (read_status_t)bnx2x_848xx_read_status,
9313 .link_reset = (link_reset_t)bnx2x_8481_link_reset,
9314 .config_loopback = (config_loopback_t)NULL,
9315 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
9316 .hw_reset = (hw_reset_t)bnx2x_8481_hw_reset,
9317 .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
9318 .phy_specific_func = (phy_specific_func_t)NULL
9321 static struct bnx2x_phy phy_84823 = {
9322 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
9325 .flags = FLAGS_FAN_FAILURE_DET_REQ |
9326 FLAGS_REARM_LATCH_SIGNAL,
9327 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9328 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9330 .supported = (SUPPORTED_10baseT_Half |
9331 SUPPORTED_10baseT_Full |
9332 SUPPORTED_100baseT_Half |
9333 SUPPORTED_100baseT_Full |
9334 SUPPORTED_1000baseT_Full |
9335 SUPPORTED_10000baseT_Full |
9339 SUPPORTED_Asym_Pause),
9340 .media_type = ETH_PHY_BASE_T,
9343 .req_line_speed = 0,
9344 .speed_cap_mask = 0,
9347 .config_init = (config_init_t)bnx2x_848x3_config_init,
9348 .read_status = (read_status_t)bnx2x_848xx_read_status,
9349 .link_reset = (link_reset_t)bnx2x_848x3_link_reset,
9350 .config_loopback = (config_loopback_t)NULL,
9351 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
9352 .hw_reset = (hw_reset_t)NULL,
9353 .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
9354 .phy_specific_func = (phy_specific_func_t)NULL
9357 static struct bnx2x_phy phy_84833 = {
9358 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833,
9361 .flags = FLAGS_FAN_FAILURE_DET_REQ |
9362 FLAGS_REARM_LATCH_SIGNAL,
9363 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9364 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
9366 .supported = (SUPPORTED_10baseT_Half |
9367 SUPPORTED_10baseT_Full |
9368 SUPPORTED_100baseT_Half |
9369 SUPPORTED_100baseT_Full |
9370 SUPPORTED_1000baseT_Full |
9371 SUPPORTED_10000baseT_Full |
9375 SUPPORTED_Asym_Pause),
9376 .media_type = ETH_PHY_BASE_T,
9379 .req_line_speed = 0,
9380 .speed_cap_mask = 0,
9383 .config_init = (config_init_t)bnx2x_848x3_config_init,
9384 .read_status = (read_status_t)bnx2x_848xx_read_status,
9385 .link_reset = (link_reset_t)bnx2x_848x3_link_reset,
9386 .config_loopback = (config_loopback_t)NULL,
9387 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
9388 .hw_reset = (hw_reset_t)NULL,
9389 .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
9390 .phy_specific_func = (phy_specific_func_t)NULL
9393 /*****************************************************************/
9395 /* Populate the phy according. Main function: bnx2x_populate_phy */
9397 /*****************************************************************/
9399 static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
9400 struct bnx2x_phy *phy, u8 port,
9403 /* Get the 4 lanes xgxs config rx and tx */
9404 u32 rx = 0, tx = 0, i;
9405 for (i = 0; i < 2; i++) {
9407 * INT_PHY and EXT_PHY1 share the same value location in the
9408 * shmem. When num_phys is greater than 1, than this value
9409 * applies only to EXT_PHY1
9411 if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
9412 rx = REG_RD(bp, shmem_base +
9413 offsetof(struct shmem_region,
9414 dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
9416 tx = REG_RD(bp, shmem_base +
9417 offsetof(struct shmem_region,
9418 dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
9420 rx = REG_RD(bp, shmem_base +
9421 offsetof(struct shmem_region,
9422 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
9424 tx = REG_RD(bp, shmem_base +
9425 offsetof(struct shmem_region,
9426 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
9429 phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
9430 phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
9432 phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
9433 phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
9437 static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
9438 u8 phy_index, u8 port)
9440 u32 ext_phy_config = 0;
9441 switch (phy_index) {
9443 ext_phy_config = REG_RD(bp, shmem_base +
9444 offsetof(struct shmem_region,
9445 dev_info.port_hw_config[port].external_phy_config));
9448 ext_phy_config = REG_RD(bp, shmem_base +
9449 offsetof(struct shmem_region,
9450 dev_info.port_hw_config[port].external_phy_config2));
9453 DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
9457 return ext_phy_config;
9459 static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
9460 struct bnx2x_phy *phy)
9464 u32 switch_cfg = (REG_RD(bp, shmem_base +
9465 offsetof(struct shmem_region,
9466 dev_info.port_feature_config[port].link_config)) &
9467 PORT_FEATURE_CONNECTED_SWITCH_MASK);
9468 chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16;
9469 DP(NETIF_MSG_LINK, ":chip_id = 0x%x\n", chip_id);
9470 if (USES_WARPCORE(bp)) {
9472 phy_addr = REG_RD(bp,
9473 MISC_REG_WC0_CTRL_PHY_ADDR);
9474 *phy = phy_warpcore;
9475 if (REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR) == 0x3)
9476 phy->flags |= FLAGS_4_PORT_MODE;
9478 phy->flags &= ~FLAGS_4_PORT_MODE;
9479 /* Check Dual mode */
9480 serdes_net_if = (REG_RD(bp, shmem_base +
9481 offsetof(struct shmem_region, dev_info.
9482 port_hw_config[port].default_cfg)) &
9483 PORT_HW_CFG_NET_SERDES_IF_MASK);
9485 * Set the appropriate supported and flags indications per
9486 * interface type of the chip
9488 switch (serdes_net_if) {
9489 case PORT_HW_CFG_NET_SERDES_IF_SGMII:
9490 phy->supported &= (SUPPORTED_10baseT_Half |
9491 SUPPORTED_10baseT_Full |
9492 SUPPORTED_100baseT_Half |
9493 SUPPORTED_100baseT_Full |
9494 SUPPORTED_1000baseT_Full |
9498 SUPPORTED_Asym_Pause);
9499 phy->media_type = ETH_PHY_BASE_T;
9501 case PORT_HW_CFG_NET_SERDES_IF_XFI:
9502 phy->media_type = ETH_PHY_XFP_FIBER;
9504 case PORT_HW_CFG_NET_SERDES_IF_SFI:
9505 phy->supported &= (SUPPORTED_1000baseT_Full |
9506 SUPPORTED_10000baseT_Full |
9509 SUPPORTED_Asym_Pause);
9510 phy->media_type = ETH_PHY_SFP_FIBER;
9512 case PORT_HW_CFG_NET_SERDES_IF_KR:
9513 phy->media_type = ETH_PHY_KR;
9514 phy->supported &= (SUPPORTED_1000baseT_Full |
9515 SUPPORTED_10000baseT_Full |
9519 SUPPORTED_Asym_Pause);
9521 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
9522 phy->media_type = ETH_PHY_KR;
9523 phy->flags |= FLAGS_WC_DUAL_MODE;
9524 phy->supported &= (SUPPORTED_20000baseMLD2_Full |
9527 SUPPORTED_Asym_Pause);
9529 case PORT_HW_CFG_NET_SERDES_IF_KR2:
9530 phy->media_type = ETH_PHY_KR;
9531 phy->flags |= FLAGS_WC_DUAL_MODE;
9532 phy->supported &= (SUPPORTED_20000baseKR2_Full |
9535 SUPPORTED_Asym_Pause);
9538 DP(NETIF_MSG_LINK, "Unknown WC interface type 0x%x\n",
9544 * Enable MDC/MDIO work-around for E3 A0 since free running MDC
9545 * was not set as expected. For B0, ECO will be enabled so there
9546 * won't be an issue there
9548 if (CHIP_REV(bp) == CHIP_REV_Ax)
9549 phy->flags |= FLAGS_MDC_MDIO_WA;
9551 switch (switch_cfg) {
9553 phy_addr = REG_RD(bp,
9554 NIG_REG_SERDES0_CTRL_PHY_ADDR +
9558 case SWITCH_CFG_10G:
9559 phy_addr = REG_RD(bp,
9560 NIG_REG_XGXS0_CTRL_PHY_ADDR +
9565 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
9569 phy->addr = (u8)phy_addr;
9570 phy->mdio_ctrl = bnx2x_get_emac_base(bp,
9571 SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
9574 phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
9576 phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
9578 DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
9579 port, phy->addr, phy->mdio_ctrl);
9581 bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
9585 static int bnx2x_populate_ext_phy(struct bnx2x *bp,
9590 struct bnx2x_phy *phy)
9592 u32 ext_phy_config, phy_type, config2;
9593 u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
9594 ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
9596 phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
9597 /* Select the phy type */
9599 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
9600 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
9603 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
9606 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
9609 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
9610 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
9613 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
9614 /* BCM8727_NOC => BCM8727 no over current */
9615 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
9617 phy->flags |= FLAGS_NOC;
9619 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
9620 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
9621 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
9624 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
9627 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
9630 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
9633 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
9636 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
9644 phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
9645 bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
9648 * The shmem address of the phy version is located on different
9649 * structures. In case this structure is too old, do not set
9652 config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region,
9653 dev_info.shared_hw_config.config2));
9654 if (phy_index == EXT_PHY1) {
9655 phy->ver_addr = shmem_base + offsetof(struct shmem_region,
9656 port_mb[port].ext_phy_fw_version);
9658 /* Check specific mdc mdio settings */
9659 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
9660 mdc_mdio_access = config2 &
9661 SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
9663 u32 size = REG_RD(bp, shmem2_base);
9666 offsetof(struct shmem2_region, ext_phy_fw_version2)) {
9667 phy->ver_addr = shmem2_base +
9668 offsetof(struct shmem2_region,
9669 ext_phy_fw_version2[port]);
9671 /* Check specific mdc mdio settings */
9672 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
9673 mdc_mdio_access = (config2 &
9674 SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
9675 (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
9676 SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
9678 phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
9681 * In case mdc/mdio_access of the external phy is different than the
9682 * mdc/mdio access of the XGXS, a HW lock must be taken in each access
9683 * to prevent one port interfere with another port's CL45 operations.
9685 if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH)
9686 phy->flags |= FLAGS_HW_LOCK_REQUIRED;
9687 DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n",
9688 phy_type, port, phy_index);
9689 DP(NETIF_MSG_LINK, " addr=0x%x, mdio_ctl=0x%x\n",
9690 phy->addr, phy->mdio_ctrl);
9694 static int bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
9695 u32 shmem2_base, u8 port, struct bnx2x_phy *phy)
9698 phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
9699 if (phy_index == INT_PHY)
9700 return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
9701 status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
9706 static void bnx2x_phy_def_cfg(struct link_params *params,
9707 struct bnx2x_phy *phy,
9710 struct bnx2x *bp = params->bp;
9712 /* Populate the default phy configuration for MF mode */
9713 if (phy_index == EXT_PHY2) {
9714 link_config = REG_RD(bp, params->shmem_base +
9715 offsetof(struct shmem_region, dev_info.
9716 port_feature_config[params->port].link_config2));
9717 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
9718 offsetof(struct shmem_region,
9720 port_hw_config[params->port].speed_capability_mask2));
9722 link_config = REG_RD(bp, params->shmem_base +
9723 offsetof(struct shmem_region, dev_info.
9724 port_feature_config[params->port].link_config));
9725 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
9726 offsetof(struct shmem_region,
9728 port_hw_config[params->port].speed_capability_mask));
9730 DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask"
9731 " 0x%x\n", phy_index, link_config, phy->speed_cap_mask);
9733 phy->req_duplex = DUPLEX_FULL;
9734 switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) {
9735 case PORT_FEATURE_LINK_SPEED_10M_HALF:
9736 phy->req_duplex = DUPLEX_HALF;
9737 case PORT_FEATURE_LINK_SPEED_10M_FULL:
9738 phy->req_line_speed = SPEED_10;
9740 case PORT_FEATURE_LINK_SPEED_100M_HALF:
9741 phy->req_duplex = DUPLEX_HALF;
9742 case PORT_FEATURE_LINK_SPEED_100M_FULL:
9743 phy->req_line_speed = SPEED_100;
9745 case PORT_FEATURE_LINK_SPEED_1G:
9746 phy->req_line_speed = SPEED_1000;
9748 case PORT_FEATURE_LINK_SPEED_2_5G:
9749 phy->req_line_speed = SPEED_2500;
9751 case PORT_FEATURE_LINK_SPEED_10G_CX4:
9752 phy->req_line_speed = SPEED_10000;
9755 phy->req_line_speed = SPEED_AUTO_NEG;
9759 switch (link_config & PORT_FEATURE_FLOW_CONTROL_MASK) {
9760 case PORT_FEATURE_FLOW_CONTROL_AUTO:
9761 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
9763 case PORT_FEATURE_FLOW_CONTROL_TX:
9764 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
9766 case PORT_FEATURE_FLOW_CONTROL_RX:
9767 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
9769 case PORT_FEATURE_FLOW_CONTROL_BOTH:
9770 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
9773 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
9778 u32 bnx2x_phy_selection(struct link_params *params)
9780 u32 phy_config_swapped, prio_cfg;
9781 u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
9783 phy_config_swapped = params->multi_phy_config &
9784 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
9786 prio_cfg = params->multi_phy_config &
9787 PORT_HW_CFG_PHY_SELECTION_MASK;
9789 if (phy_config_swapped) {
9791 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
9792 return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
9794 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
9795 return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
9797 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
9798 return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
9800 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
9801 return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
9805 return_cfg = prio_cfg;
9811 int bnx2x_phy_probe(struct link_params *params)
9813 u8 phy_index, actual_phy_idx, link_cfg_idx;
9814 u32 phy_config_swapped, sync_offset, media_types;
9815 struct bnx2x *bp = params->bp;
9816 struct bnx2x_phy *phy;
9817 params->num_phys = 0;
9818 DP(NETIF_MSG_LINK, "Begin phy probe\n");
9819 phy_config_swapped = params->multi_phy_config &
9820 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
9822 for (phy_index = INT_PHY; phy_index < MAX_PHYS;
9824 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
9825 actual_phy_idx = phy_index;
9826 if (phy_config_swapped) {
9827 if (phy_index == EXT_PHY1)
9828 actual_phy_idx = EXT_PHY2;
9829 else if (phy_index == EXT_PHY2)
9830 actual_phy_idx = EXT_PHY1;
9832 DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x,"
9833 " actual_phy_idx %x\n", phy_config_swapped,
9834 phy_index, actual_phy_idx);
9835 phy = ¶ms->phy[actual_phy_idx];
9836 if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
9837 params->shmem2_base, params->port,
9839 params->num_phys = 0;
9840 DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
9842 for (phy_index = INT_PHY;
9843 phy_index < MAX_PHYS;
9848 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
9851 sync_offset = params->shmem_base +
9852 offsetof(struct shmem_region,
9853 dev_info.port_hw_config[params->port].media_type);
9854 media_types = REG_RD(bp, sync_offset);
9857 * Update media type for non-PMF sync only for the first time
9858 * In case the media type changes afterwards, it will be updated
9859 * using the update_status function
9861 if ((media_types & (PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
9862 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
9863 actual_phy_idx))) == 0) {
9864 media_types |= ((phy->media_type &
9865 PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
9866 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
9869 REG_WR(bp, sync_offset, media_types);
9871 bnx2x_phy_def_cfg(params, phy, phy_index);
9875 DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
9879 void bnx2x_init_bmac_loopback(struct link_params *params,
9880 struct link_vars *vars)
9882 struct bnx2x *bp = params->bp;
9884 vars->line_speed = SPEED_10000;
9885 vars->duplex = DUPLEX_FULL;
9886 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
9887 vars->mac_type = MAC_TYPE_BMAC;
9889 vars->phy_flags = PHY_XGXS_FLAG;
9891 bnx2x_xgxs_deassert(params);
9893 /* set bmac loopback */
9894 bnx2x_bmac_enable(params, vars, 1);
9896 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
9899 void bnx2x_init_emac_loopback(struct link_params *params,
9900 struct link_vars *vars)
9902 struct bnx2x *bp = params->bp;
9904 vars->line_speed = SPEED_1000;
9905 vars->duplex = DUPLEX_FULL;
9906 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
9907 vars->mac_type = MAC_TYPE_EMAC;
9909 vars->phy_flags = PHY_XGXS_FLAG;
9911 bnx2x_xgxs_deassert(params);
9912 /* set bmac loopback */
9913 bnx2x_emac_enable(params, vars, 1);
9914 bnx2x_emac_program(params, vars);
9915 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
9918 void bnx2x_init_xmac_loopback(struct link_params *params,
9919 struct link_vars *vars)
9921 struct bnx2x *bp = params->bp;
9923 if (!params->req_line_speed[0])
9924 vars->line_speed = SPEED_10000;
9926 vars->line_speed = params->req_line_speed[0];
9927 vars->duplex = DUPLEX_FULL;
9928 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
9929 vars->mac_type = MAC_TYPE_XMAC;
9930 vars->phy_flags = PHY_XGXS_FLAG;
9932 * Set WC to loopback mode since link is required to provide clock
9933 * to the XMAC in 20G mode
9935 if (vars->line_speed == SPEED_20000) {
9936 bnx2x_set_aer_mmd(params, ¶ms->phy[0]);
9937 bnx2x_warpcore_reset_lane(bp, ¶ms->phy[0], 0);
9938 params->phy[INT_PHY].config_loopback(
9939 ¶ms->phy[INT_PHY],
9942 bnx2x_xmac_enable(params, vars, 1);
9943 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
9946 void bnx2x_init_umac_loopback(struct link_params *params,
9947 struct link_vars *vars)
9949 struct bnx2x *bp = params->bp;
9951 vars->line_speed = SPEED_1000;
9952 vars->duplex = DUPLEX_FULL;
9953 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
9954 vars->mac_type = MAC_TYPE_UMAC;
9955 vars->phy_flags = PHY_XGXS_FLAG;
9956 bnx2x_umac_enable(params, vars, 1);
9958 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
9961 void bnx2x_init_xgxs_loopback(struct link_params *params,
9962 struct link_vars *vars)
9964 struct bnx2x *bp = params->bp;
9966 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
9967 vars->duplex = DUPLEX_FULL;
9968 if (params->req_line_speed[0] == SPEED_1000)
9969 vars->line_speed = SPEED_1000;
9971 vars->line_speed = SPEED_10000;
9973 if (!USES_WARPCORE(bp))
9974 bnx2x_xgxs_deassert(params);
9975 bnx2x_link_initialize(params, vars);
9977 if (params->req_line_speed[0] == SPEED_1000) {
9978 if (USES_WARPCORE(bp))
9979 bnx2x_umac_enable(params, vars, 0);
9981 bnx2x_emac_program(params, vars);
9982 bnx2x_emac_enable(params, vars, 0);
9985 if (USES_WARPCORE(bp))
9986 bnx2x_xmac_enable(params, vars, 0);
9988 bnx2x_bmac_enable(params, vars, 0);
9991 if (params->loopback_mode == LOOPBACK_XGXS) {
9992 /* set 10G XGXS loopback */
9993 params->phy[INT_PHY].config_loopback(
9994 ¶ms->phy[INT_PHY],
9998 /* set external phy loopback */
10000 for (phy_index = EXT_PHY1;
10001 phy_index < params->num_phys; phy_index++) {
10002 if (params->phy[phy_index].config_loopback)
10003 params->phy[phy_index].config_loopback(
10004 ¶ms->phy[phy_index],
10008 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
10010 bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
10013 int bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
10015 struct bnx2x *bp = params->bp;
10016 DP(NETIF_MSG_LINK, "Phy Initialization started\n");
10017 DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n",
10018 params->req_line_speed[0], params->req_flow_ctrl[0]);
10019 DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n",
10020 params->req_line_speed[1], params->req_flow_ctrl[1]);
10021 vars->link_status = 0;
10022 vars->phy_link_up = 0;
10024 vars->line_speed = 0;
10025 vars->duplex = DUPLEX_FULL;
10026 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
10027 vars->mac_type = MAC_TYPE_NONE;
10028 vars->phy_flags = 0;
10030 /* disable attentions */
10031 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
10032 (NIG_MASK_XGXS0_LINK_STATUS |
10033 NIG_MASK_XGXS0_LINK10G |
10034 NIG_MASK_SERDES0_LINK_STATUS |
10037 bnx2x_emac_init(params, vars);
10039 if (params->num_phys == 0) {
10040 DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
10043 set_phy_vars(params, vars);
10045 DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
10046 switch (params->loopback_mode) {
10047 case LOOPBACK_BMAC:
10048 bnx2x_init_bmac_loopback(params, vars);
10050 case LOOPBACK_EMAC:
10051 bnx2x_init_emac_loopback(params, vars);
10053 case LOOPBACK_XMAC:
10054 bnx2x_init_xmac_loopback(params, vars);
10056 case LOOPBACK_UMAC:
10057 bnx2x_init_umac_loopback(params, vars);
10059 case LOOPBACK_XGXS:
10060 case LOOPBACK_EXT_PHY:
10061 bnx2x_init_xgxs_loopback(params, vars);
10064 if (!CHIP_IS_E3(bp)) {
10065 if (params->switch_cfg == SWITCH_CFG_10G)
10066 bnx2x_xgxs_deassert(params);
10068 bnx2x_serdes_deassert(bp, params->port);
10070 bnx2x_link_initialize(params, vars);
10072 bnx2x_link_int_enable(params);
10078 int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
10081 struct bnx2x *bp = params->bp;
10082 u8 phy_index, port = params->port, clear_latch_ind = 0;
10083 DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
10084 /* disable attentions */
10085 vars->link_status = 0;
10086 bnx2x_update_mng(params, vars->link_status);
10087 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
10088 (NIG_MASK_XGXS0_LINK_STATUS |
10089 NIG_MASK_XGXS0_LINK10G |
10090 NIG_MASK_SERDES0_LINK_STATUS |
10093 /* activate nig drain */
10094 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
10096 /* disable nig egress interface */
10097 if (!CHIP_IS_E3(bp)) {
10098 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
10099 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
10102 /* Stop BigMac rx */
10103 if (!CHIP_IS_E3(bp))
10104 bnx2x_bmac_rx_disable(bp, port);
10106 bnx2x_xmac_disable(params);
10108 if (!CHIP_IS_E3(bp))
10109 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
10112 /* The PHY reset is controlled by GPIO 1
10113 * Hold it as vars low
10115 /* clear link led */
10116 bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
10118 if (reset_ext_phy) {
10119 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
10121 if (params->phy[phy_index].link_reset)
10122 params->phy[phy_index].link_reset(
10123 ¶ms->phy[phy_index],
10125 if (params->phy[phy_index].flags &
10126 FLAGS_REARM_LATCH_SIGNAL)
10127 clear_latch_ind = 1;
10131 if (clear_latch_ind) {
10132 /* Clear latching indication */
10133 bnx2x_rearm_latch_signal(bp, port, 0);
10134 bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4,
10135 1 << NIG_LATCH_BC_ENABLE_MI_INT);
10137 if (params->phy[INT_PHY].link_reset)
10138 params->phy[INT_PHY].link_reset(
10139 ¶ms->phy[INT_PHY], params);
10141 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
10142 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
10144 /* disable nig ingress interface */
10145 if (!CHIP_IS_E3(bp)) {
10146 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
10147 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
10150 vars->phy_flags = 0;
10154 /****************************************************************************/
10155 /* Common function */
10156 /****************************************************************************/
10157 static int bnx2x_8073_common_init_phy(struct bnx2x *bp,
10158 u32 shmem_base_path[],
10159 u32 shmem2_base_path[], u8 phy_index,
10162 struct bnx2x_phy phy[PORT_MAX];
10163 struct bnx2x_phy *phy_blk[PORT_MAX];
10166 s8 port_of_path = 0;
10167 u32 swap_val, swap_override;
10168 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
10169 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
10170 port ^= (swap_val && swap_override);
10171 bnx2x_ext_phy_hw_reset(bp, port);
10172 /* PART1 - Reset both phys */
10173 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
10174 u32 shmem_base, shmem2_base;
10175 /* In E2, same phy is using for port0 of the two paths */
10176 if (CHIP_IS_E1x(bp)) {
10177 shmem_base = shmem_base_path[0];
10178 shmem2_base = shmem2_base_path[0];
10179 port_of_path = port;
10181 shmem_base = shmem_base_path[port];
10182 shmem2_base = shmem2_base_path[port];
10186 /* Extract the ext phy address for the port */
10187 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
10188 port_of_path, &phy[port]) !=
10190 DP(NETIF_MSG_LINK, "populate_phy failed\n");
10193 /* disable attentions */
10194 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
10196 (NIG_MASK_XGXS0_LINK_STATUS |
10197 NIG_MASK_XGXS0_LINK10G |
10198 NIG_MASK_SERDES0_LINK_STATUS |
10201 /* Need to take the phy out of low power mode in order
10202 to write to access its registers */
10203 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
10204 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
10207 /* Reset the phy */
10208 bnx2x_cl45_write(bp, &phy[port],
10214 /* Add delay of 150ms after reset */
10217 if (phy[PORT_0].addr & 0x1) {
10218 phy_blk[PORT_0] = &(phy[PORT_1]);
10219 phy_blk[PORT_1] = &(phy[PORT_0]);
10221 phy_blk[PORT_0] = &(phy[PORT_0]);
10222 phy_blk[PORT_1] = &(phy[PORT_1]);
10225 /* PART2 - Download firmware to both phys */
10226 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
10227 if (CHIP_IS_E1x(bp))
10228 port_of_path = port;
10232 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
10233 phy_blk[port]->addr);
10234 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
10238 /* Only set bit 10 = 1 (Tx power down) */
10239 bnx2x_cl45_read(bp, phy_blk[port],
10241 MDIO_PMA_REG_TX_POWER_DOWN, &val);
10243 /* Phase1 of TX_POWER_DOWN reset */
10244 bnx2x_cl45_write(bp, phy_blk[port],
10246 MDIO_PMA_REG_TX_POWER_DOWN,
10251 * Toggle Transmitter: Power down and then up with 600ms delay
10256 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
10257 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
10258 /* Phase2 of POWER_DOWN_RESET */
10259 /* Release bit 10 (Release Tx power down) */
10260 bnx2x_cl45_read(bp, phy_blk[port],
10262 MDIO_PMA_REG_TX_POWER_DOWN, &val);
10264 bnx2x_cl45_write(bp, phy_blk[port],
10266 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
10269 /* Read modify write the SPI-ROM version select register */
10270 bnx2x_cl45_read(bp, phy_blk[port],
10272 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
10273 bnx2x_cl45_write(bp, phy_blk[port],
10275 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
10277 /* set GPIO2 back to LOW */
10278 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
10279 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
10283 static int bnx2x_8726_common_init_phy(struct bnx2x *bp,
10284 u32 shmem_base_path[],
10285 u32 shmem2_base_path[], u8 phy_index,
10290 struct bnx2x_phy phy;
10291 /* Use port1 because of the static port-swap */
10292 /* Enable the module detection interrupt */
10293 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
10294 val |= ((1<<MISC_REGISTERS_GPIO_3)|
10295 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
10296 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
10298 bnx2x_ext_phy_hw_reset(bp, 0);
10300 for (port = 0; port < PORT_MAX; port++) {
10301 u32 shmem_base, shmem2_base;
10303 /* In E2, same phy is using for port0 of the two paths */
10304 if (CHIP_IS_E1x(bp)) {
10305 shmem_base = shmem_base_path[0];
10306 shmem2_base = shmem2_base_path[0];
10308 shmem_base = shmem_base_path[port];
10309 shmem2_base = shmem2_base_path[port];
10311 /* Extract the ext phy address for the port */
10312 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
10315 DP(NETIF_MSG_LINK, "populate phy failed\n");
10320 bnx2x_cl45_write(bp, &phy,
10321 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
10324 /* Set fault module detected LED on */
10325 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
10326 MISC_REGISTERS_GPIO_HIGH,
10332 static void bnx2x_get_ext_phy_reset_gpio(struct bnx2x *bp, u32 shmem_base,
10333 u8 *io_gpio, u8 *io_port)
10336 u32 phy_gpio_reset = REG_RD(bp, shmem_base +
10337 offsetof(struct shmem_region,
10338 dev_info.port_hw_config[PORT_0].default_cfg));
10339 switch (phy_gpio_reset) {
10340 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0:
10344 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0:
10348 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0:
10352 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0:
10356 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1:
10360 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1:
10364 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1:
10368 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1:
10373 /* Don't override the io_gpio and io_port */
10378 static int bnx2x_8727_common_init_phy(struct bnx2x *bp,
10379 u32 shmem_base_path[],
10380 u32 shmem2_base_path[], u8 phy_index,
10383 s8 port, reset_gpio;
10384 u32 swap_val, swap_override;
10385 struct bnx2x_phy phy[PORT_MAX];
10386 struct bnx2x_phy *phy_blk[PORT_MAX];
10388 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
10389 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
10391 reset_gpio = MISC_REGISTERS_GPIO_1;
10395 * Retrieve the reset gpio/port which control the reset.
10396 * Default is GPIO1, PORT1
10398 bnx2x_get_ext_phy_reset_gpio(bp, shmem_base_path[0],
10399 (u8 *)&reset_gpio, (u8 *)&port);
10401 /* Calculate the port based on port swap */
10402 port ^= (swap_val && swap_override);
10404 /* Initiate PHY reset*/
10405 bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW,
10408 bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH,
10413 /* PART1 - Reset both phys */
10414 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
10415 u32 shmem_base, shmem2_base;
10417 /* In E2, same phy is using for port0 of the two paths */
10418 if (CHIP_IS_E1x(bp)) {
10419 shmem_base = shmem_base_path[0];
10420 shmem2_base = shmem2_base_path[0];
10421 port_of_path = port;
10423 shmem_base = shmem_base_path[port];
10424 shmem2_base = shmem2_base_path[port];
10428 /* Extract the ext phy address for the port */
10429 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
10430 port_of_path, &phy[port]) !=
10432 DP(NETIF_MSG_LINK, "populate phy failed\n");
10435 /* disable attentions */
10436 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
10438 (NIG_MASK_XGXS0_LINK_STATUS |
10439 NIG_MASK_XGXS0_LINK10G |
10440 NIG_MASK_SERDES0_LINK_STATUS |
10444 /* Reset the phy */
10445 bnx2x_cl45_write(bp, &phy[port],
10446 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
10449 /* Add delay of 150ms after reset */
10451 if (phy[PORT_0].addr & 0x1) {
10452 phy_blk[PORT_0] = &(phy[PORT_1]);
10453 phy_blk[PORT_1] = &(phy[PORT_0]);
10455 phy_blk[PORT_0] = &(phy[PORT_0]);
10456 phy_blk[PORT_1] = &(phy[PORT_1]);
10458 /* PART2 - Download firmware to both phys */
10459 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
10460 if (CHIP_IS_E1x(bp))
10461 port_of_path = port;
10464 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
10465 phy_blk[port]->addr);
10466 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
10474 static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
10475 u32 shmem2_base_path[], u8 phy_index,
10476 u32 ext_phy_type, u32 chip_id)
10480 switch (ext_phy_type) {
10481 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
10482 rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
10484 phy_index, chip_id);
10486 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
10487 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
10488 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
10489 rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
10491 phy_index, chip_id);
10494 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
10496 * GPIO1 affects both ports, so there's need to pull
10497 * it for single port alone
10499 rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
10501 phy_index, chip_id);
10503 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
10508 "ext_phy 0x%x common init not required\n",
10514 netdev_err(bp->dev, "Warning: PHY was not initialized,"
10520 int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
10521 u32 shmem2_base_path[], u32 chip_id)
10526 u32 ext_phy_type, ext_phy_config;
10527 bnx2x_set_mdio_clk(bp, chip_id, PORT_0);
10528 bnx2x_set_mdio_clk(bp, chip_id, PORT_1);
10529 DP(NETIF_MSG_LINK, "Begin common phy init\n");
10530 if (CHIP_IS_E3(bp)) {
10532 val = REG_RD(bp, MISC_REG_GEN_PURP_HWG);
10533 REG_WR(bp, MISC_REG_GEN_PURP_HWG, val | 1);
10535 /* Check if common init was already done */
10536 phy_ver = REG_RD(bp, shmem_base_path[0] +
10537 offsetof(struct shmem_region,
10538 port_mb[PORT_0].ext_phy_fw_version));
10540 DP(NETIF_MSG_LINK, "Not doing common init; phy ver is 0x%x\n",
10545 /* Read the ext_phy_type for arbitrary port(0) */
10546 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
10548 ext_phy_config = bnx2x_get_ext_phy_config(bp,
10549 shmem_base_path[0],
10551 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
10552 rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
10554 phy_index, ext_phy_type,
10560 u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
10563 struct bnx2x_phy phy;
10564 for (phy_index = INT_PHY; phy_index < MAX_PHYS;
10566 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
10568 DP(NETIF_MSG_LINK, "populate phy failed\n");
10572 if (phy.flags & FLAGS_HW_LOCK_REQUIRED)
10578 u8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
10583 u8 phy_index, fan_failure_det_req = 0;
10584 struct bnx2x_phy phy;
10585 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
10587 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
10590 DP(NETIF_MSG_LINK, "populate phy failed\n");
10593 fan_failure_det_req |= (phy.flags &
10594 FLAGS_FAN_FAILURE_DET_REQ);
10596 return fan_failure_det_req;
10599 void bnx2x_hw_reset_phy(struct link_params *params)
10602 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
10604 if (params->phy[phy_index].hw_reset) {
10605 params->phy[phy_index].hw_reset(
10606 ¶ms->phy[phy_index],
10608 params->phy[phy_index] = phy_null;
10613 void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars,
10614 u32 chip_id, u32 shmem_base, u32 shmem2_base,
10617 u8 gpio_num = 0xff, gpio_port = 0xff, phy_index;
10619 u32 offset, aeu_mask, swap_val, swap_override, sync_offset;
10620 if (CHIP_IS_E3(bp)) {
10621 if (bnx2x_get_mod_abs_int_cfg(bp, chip_id,
10628 struct bnx2x_phy phy;
10629 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
10631 if (bnx2x_populate_phy(bp, phy_index, shmem_base,
10632 shmem2_base, port, &phy)
10634 DP(NETIF_MSG_LINK, "populate phy failed\n");
10637 if (phy.type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
10638 gpio_num = MISC_REGISTERS_GPIO_3;
10645 if (gpio_num == 0xff)
10648 /* Set GPIO3 to trigger SFP+ module insertion/removal */
10649 bnx2x_set_gpio(bp, gpio_num, MISC_REGISTERS_GPIO_INPUT_HI_Z, gpio_port);
10651 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
10652 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
10653 gpio_port ^= (swap_val && swap_override);
10655 vars->aeu_int_mask = AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 <<
10656 (gpio_num + (gpio_port << 2));
10658 sync_offset = shmem_base +
10659 offsetof(struct shmem_region,
10660 dev_info.port_hw_config[port].aeu_int_mask);
10661 REG_WR(bp, sync_offset, vars->aeu_int_mask);
10663 DP(NETIF_MSG_LINK, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x\n",
10664 gpio_num, gpio_port, vars->aeu_int_mask);
10667 offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
10669 offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
10671 /* Open appropriate AEU for interrupts */
10672 aeu_mask = REG_RD(bp, offset);
10673 aeu_mask |= vars->aeu_int_mask;
10674 REG_WR(bp, offset, aeu_mask);
10676 /* Enable the GPIO to trigger interrupt */
10677 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
10678 val |= 1 << (gpio_num + (gpio_port << 2));
10679 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);