bnx2x_link.c revision 6db5193b29642ab18e6343c8fcbc3417d6e80983
1/* Copyright 2008-2011 Broadcom Corporation 2 * 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"). 7 * 8 * Notwithstanding the above, under no circumstances may you combine this 9 * software in any way with any other Broadcom software provided under a 10 * license other than the GPL, without Broadcom's express prior written 11 * consent. 12 * 13 * Written by Yaniv Rosner 14 * 15 */ 16 17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 18 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> 26 27#include "bnx2x.h" 28#include "bnx2x_cmn.h" 29 30 31/********************************************************/ 32#define ETH_HLEN 14 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 40#define WC_LANE_MAX 4 41#define I2C_SWITCH_WIDTH 2 42#define I2C_BSC0 0 43#define I2C_BSC1 1 44#define I2C_WA_RETRY_CNT 3 45#define MCPR_IMC_COMMAND_READ_OP 1 46#define MCPR_IMC_COMMAND_WRITE_OP 2 47 48/* LED Blink rate that will achieve ~15.9Hz */ 49#define LED_BLINK_RATE_VAL_E3 354 50#define LED_BLINK_RATE_VAL_E1X_E2 480 51/***********************************************************/ 52/* Shortcut definitions */ 53/***********************************************************/ 54 55#define NIG_LATCH_BC_ENABLE_MI_INT 0 56 57#define NIG_STATUS_EMAC0_MI_INT \ 58 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT 59#define NIG_STATUS_XGXS0_LINK10G \ 60 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G 61#define NIG_STATUS_XGXS0_LINK_STATUS \ 62 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS 63#define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \ 64 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE 65#define NIG_STATUS_SERDES0_LINK_STATUS \ 66 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS 67#define NIG_MASK_MI_INT \ 68 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT 69#define NIG_MASK_XGXS0_LINK10G \ 70 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G 71#define NIG_MASK_XGXS0_LINK_STATUS \ 72 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS 73#define NIG_MASK_SERDES0_LINK_STATUS \ 74 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS 75 76#define MDIO_AN_CL73_OR_37_COMPLETE \ 77 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \ 78 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE) 79 80#define XGXS_RESET_BITS \ 81 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \ 82 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \ 83 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \ 84 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \ 85 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB) 86 87#define SERDES_RESET_BITS \ 88 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \ 89 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \ 90 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \ 91 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD) 92 93#define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37 94#define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73 95#define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM 96#define AUTONEG_PARALLEL \ 97 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION 98#define AUTONEG_SGMII_FIBER_AUTODET \ 99 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT 100#define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY 101 102#define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \ 103 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE 104#define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \ 105 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE 106#define GP_STATUS_SPEED_MASK \ 107 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK 108#define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M 109#define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M 110#define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G 111#define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G 112#define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G 113#define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G 114#define GP_STATUS_10G_HIG \ 115 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG 116#define GP_STATUS_10G_CX4 \ 117 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4 118#define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX 119#define GP_STATUS_10G_KX4 \ 120 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4 121#define GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR 122#define GP_STATUS_10G_XFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI 123#define GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS 124#define GP_STATUS_10G_SFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI 125#define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD 126#define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD 127#define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD 128#define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4 129#define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD 130#define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD 131#define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD 132#define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD 133#define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD 134#define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD 135#define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD 136#define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD 137#define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD 138#define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD 139#define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD 140 141 142 143/* */ 144#define SFP_EEPROM_CON_TYPE_ADDR 0x2 145 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 146 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21 147 148 149#define SFP_EEPROM_COMP_CODE_ADDR 0x3 150 #define SFP_EEPROM_COMP_CODE_SR_MASK (1<<4) 151 #define SFP_EEPROM_COMP_CODE_LR_MASK (1<<5) 152 #define SFP_EEPROM_COMP_CODE_LRM_MASK (1<<6) 153 154#define SFP_EEPROM_FC_TX_TECH_ADDR 0x8 155 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4 156 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8 157 158#define SFP_EEPROM_OPTIONS_ADDR 0x40 159 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1 160#define SFP_EEPROM_OPTIONS_SIZE 2 161 162#define EDC_MODE_LINEAR 0x0022 163#define EDC_MODE_LIMITING 0x0044 164#define EDC_MODE_PASSIVE_DAC 0x0055 165 166/* BRB default for class 0 E2 */ 167#define DEFAULT0_E2_BRB_MAC_PAUSE_XOFF_THR 170 168#define DEFAULT0_E2_BRB_MAC_PAUSE_XON_THR 250 169#define DEFAULT0_E2_BRB_MAC_FULL_XOFF_THR 10 170#define DEFAULT0_E2_BRB_MAC_FULL_XON_THR 50 171 172/* BRB thresholds for E2*/ 173#define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE 170 174#define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0 175 176#define PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE 250 177#define PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0 178 179#define PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE 10 180#define PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 90 181 182#define PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE 50 183#define PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE 250 184 185/* BRB default for class 0 E3A0 */ 186#define DEFAULT0_E3A0_BRB_MAC_PAUSE_XOFF_THR 290 187#define DEFAULT0_E3A0_BRB_MAC_PAUSE_XON_THR 410 188#define DEFAULT0_E3A0_BRB_MAC_FULL_XOFF_THR 10 189#define DEFAULT0_E3A0_BRB_MAC_FULL_XON_THR 50 190 191/* BRB thresholds for E3A0 */ 192#define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE 290 193#define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0 194 195#define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE 410 196#define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0 197 198#define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE 10 199#define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 170 200 201#define PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE 50 202#define PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE 410 203 204/* BRB default for E3B0 */ 205#define DEFAULT0_E3B0_BRB_MAC_PAUSE_XOFF_THR 330 206#define DEFAULT0_E3B0_BRB_MAC_PAUSE_XON_THR 490 207#define DEFAULT0_E3B0_BRB_MAC_FULL_XOFF_THR 15 208#define DEFAULT0_E3B0_BRB_MAC_FULL_XON_THR 55 209 210/* BRB thresholds for E3B0 2 port mode*/ 211#define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE 1025 212#define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0 213 214#define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE 1025 215#define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0 216 217#define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE 10 218#define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 1025 219 220#define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE 50 221#define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE 1025 222 223/* only for E3B0*/ 224#define PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR 1025 225#define PFC_E3B0_2P_BRB_FULL_LB_XON_THR 1025 226 227/* Lossy +Lossless GUARANTIED == GUART */ 228#define PFC_E3B0_2P_MIX_PAUSE_LB_GUART 284 229/* Lossless +Lossless*/ 230#define PFC_E3B0_2P_PAUSE_LB_GUART 236 231/* Lossy +Lossy*/ 232#define PFC_E3B0_2P_NON_PAUSE_LB_GUART 342 233 234/* Lossy +Lossless*/ 235#define PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART 284 236/* Lossless +Lossless*/ 237#define PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART 236 238/* Lossy +Lossy*/ 239#define PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART 336 240#define PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST 80 241 242#define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART 0 243#define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST 0 244 245/* BRB thresholds for E3B0 4 port mode */ 246#define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE 304 247#define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0 248 249#define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE 384 250#define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0 251 252#define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE 10 253#define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 304 254 255#define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE 50 256#define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE 384 257 258 259/* only for E3B0*/ 260#define PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR 304 261#define PFC_E3B0_4P_BRB_FULL_LB_XON_THR 384 262#define PFC_E3B0_4P_LB_GUART 120 263 264#define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART 120 265#define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST 80 266 267#define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART 80 268#define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST 120 269 270/* Pause defines*/ 271#define DEFAULT_E3B0_BRB_FULL_LB_XOFF_THR 330 272#define DEFAULT_E3B0_BRB_FULL_LB_XON_THR 490 273#define DEFAULT_E3B0_LB_GUART 40 274 275#define DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART 40 276#define DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART_HYST 0 277 278#define DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART 40 279#define DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART_HYST 0 280 281/* ETS defines*/ 282#define DCBX_INVALID_COS (0xFF) 283 284#define ETS_BW_LIMIT_CREDIT_UPPER_BOUND (0x5000) 285#define ETS_BW_LIMIT_CREDIT_WEIGHT (0x5000) 286#define ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS (1360) 287#define ETS_E3B0_NIG_MIN_W_VAL_20GBPS (2720) 288#define ETS_E3B0_PBF_MIN_W_VAL (10000) 289 290#define MAX_PACKET_SIZE (9700) 291#define WC_UC_TIMEOUT 100 292#define MAX_KR_LINK_RETRY 4 293 294/**********************************************************/ 295/* INTERFACE */ 296/**********************************************************/ 297 298#define CL22_WR_OVER_CL45(_bp, _phy, _bank, _addr, _val) \ 299 bnx2x_cl45_write(_bp, _phy, \ 300 (_phy)->def_md_devad, \ 301 (_bank + (_addr & 0xf)), \ 302 _val) 303 304#define CL22_RD_OVER_CL45(_bp, _phy, _bank, _addr, _val) \ 305 bnx2x_cl45_read(_bp, _phy, \ 306 (_phy)->def_md_devad, \ 307 (_bank + (_addr & 0xf)), \ 308 _val) 309 310static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits) 311{ 312 u32 val = REG_RD(bp, reg); 313 314 val |= bits; 315 REG_WR(bp, reg, val); 316 return val; 317} 318 319static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits) 320{ 321 u32 val = REG_RD(bp, reg); 322 323 val &= ~bits; 324 REG_WR(bp, reg, val); 325 return val; 326} 327 328/******************************************************************/ 329/* EPIO/GPIO section */ 330/******************************************************************/ 331static void bnx2x_get_epio(struct bnx2x *bp, u32 epio_pin, u32 *en) 332{ 333 u32 epio_mask, gp_oenable; 334 *en = 0; 335 /* Sanity check */ 336 if (epio_pin > 31) { 337 DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to get\n", epio_pin); 338 return; 339 } 340 341 epio_mask = 1 << epio_pin; 342 /* Set this EPIO to output */ 343 gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE); 344 REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable & ~epio_mask); 345 346 *en = (REG_RD(bp, MCP_REG_MCPR_GP_INPUTS) & epio_mask) >> epio_pin; 347} 348static void bnx2x_set_epio(struct bnx2x *bp, u32 epio_pin, u32 en) 349{ 350 u32 epio_mask, gp_output, gp_oenable; 351 352 /* Sanity check */ 353 if (epio_pin > 31) { 354 DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to set\n", epio_pin); 355 return; 356 } 357 DP(NETIF_MSG_LINK, "Setting EPIO pin %d to %d\n", epio_pin, en); 358 epio_mask = 1 << epio_pin; 359 /* Set this EPIO to output */ 360 gp_output = REG_RD(bp, MCP_REG_MCPR_GP_OUTPUTS); 361 if (en) 362 gp_output |= epio_mask; 363 else 364 gp_output &= ~epio_mask; 365 366 REG_WR(bp, MCP_REG_MCPR_GP_OUTPUTS, gp_output); 367 368 /* Set the value for this EPIO */ 369 gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE); 370 REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask); 371} 372 373static void bnx2x_set_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 val) 374{ 375 if (pin_cfg == PIN_CFG_NA) 376 return; 377 if (pin_cfg >= PIN_CFG_EPIO0) { 378 bnx2x_set_epio(bp, pin_cfg - PIN_CFG_EPIO0, val); 379 } else { 380 u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3; 381 u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2; 382 bnx2x_set_gpio(bp, gpio_num, (u8)val, gpio_port); 383 } 384} 385 386static u32 bnx2x_get_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 *val) 387{ 388 if (pin_cfg == PIN_CFG_NA) 389 return -EINVAL; 390 if (pin_cfg >= PIN_CFG_EPIO0) { 391 bnx2x_get_epio(bp, pin_cfg - PIN_CFG_EPIO0, val); 392 } else { 393 u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3; 394 u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2; 395 *val = bnx2x_get_gpio(bp, gpio_num, gpio_port); 396 } 397 return 0; 398 399} 400/******************************************************************/ 401/* ETS section */ 402/******************************************************************/ 403static void bnx2x_ets_e2e3a0_disabled(struct link_params *params) 404{ 405 /* ETS disabled configuration*/ 406 struct bnx2x *bp = params->bp; 407 408 DP(NETIF_MSG_LINK, "ETS E2E3 disabled configuration\n"); 409 410 /* 411 * mapping between entry priority to client number (0,1,2 -debug and 412 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST) 413 * 3bits client num. 414 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0 415 * cos1-100 cos0-011 dbg1-010 dbg0-001 MCP-000 416 */ 417 418 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688); 419 /* 420 * Bitmap of 5bits length. Each bit specifies whether the entry behaves 421 * as strict. Bits 0,1,2 - debug and management entries, 3 - 422 * COS0 entry, 4 - COS1 entry. 423 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT 424 * bit4 bit3 bit2 bit1 bit0 425 * MCP and debug are strict 426 */ 427 428 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7); 429 /* defines which entries (clients) are subjected to WFQ arbitration */ 430 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0); 431 /* 432 * For strict priority entries defines the number of consecutive 433 * slots for the highest priority. 434 */ 435 REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100); 436 /* 437 * mapping between the CREDIT_WEIGHT registers and actual client 438 * numbers 439 */ 440 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0); 441 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0); 442 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0); 443 444 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0); 445 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0); 446 REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0); 447 /* ETS mode disable */ 448 REG_WR(bp, PBF_REG_ETS_ENABLED, 0); 449 /* 450 * If ETS mode is enabled (there is no strict priority) defines a WFQ 451 * weight for COS0/COS1. 452 */ 453 REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710); 454 REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710); 455 /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */ 456 REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680); 457 REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680); 458 /* Defines the number of consecutive slots for the strict priority */ 459 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0); 460} 461/****************************************************************************** 462* Description: 463* Getting min_w_val will be set according to line speed . 464*. 465******************************************************************************/ 466static u32 bnx2x_ets_get_min_w_val_nig(const struct link_vars *vars) 467{ 468 u32 min_w_val = 0; 469 /* Calculate min_w_val.*/ 470 if (vars->link_up) { 471 if (SPEED_20000 == vars->line_speed) 472 min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS; 473 else 474 min_w_val = ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS; 475 } else 476 min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS; 477 /** 478 * If the link isn't up (static configuration for example ) The 479 * link will be according to 20GBPS. 480 */ 481 return min_w_val; 482} 483/****************************************************************************** 484* Description: 485* Getting credit upper bound form min_w_val. 486*. 487******************************************************************************/ 488static u32 bnx2x_ets_get_credit_upper_bound(const u32 min_w_val) 489{ 490 const u32 credit_upper_bound = (u32)MAXVAL((150 * min_w_val), 491 MAX_PACKET_SIZE); 492 return credit_upper_bound; 493} 494/****************************************************************************** 495* Description: 496* Set credit upper bound for NIG. 497*. 498******************************************************************************/ 499static void bnx2x_ets_e3b0_set_credit_upper_bound_nig( 500 const struct link_params *params, 501 const u32 min_w_val) 502{ 503 struct bnx2x *bp = params->bp; 504 const u8 port = params->port; 505 const u32 credit_upper_bound = 506 bnx2x_ets_get_credit_upper_bound(min_w_val); 507 508 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_0 : 509 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, credit_upper_bound); 510 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_1 : 511 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, credit_upper_bound); 512 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_2 : 513 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_2, credit_upper_bound); 514 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_3 : 515 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_3, credit_upper_bound); 516 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_4 : 517 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_4, credit_upper_bound); 518 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_5 : 519 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_5, credit_upper_bound); 520 521 if (0 == port) { 522 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_6, 523 credit_upper_bound); 524 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_7, 525 credit_upper_bound); 526 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_8, 527 credit_upper_bound); 528 } 529} 530/****************************************************************************** 531* Description: 532* Will return the NIG ETS registers to init values.Except 533* credit_upper_bound. 534* That isn't used in this configuration (No WFQ is enabled) and will be 535* configured acording to spec 536*. 537******************************************************************************/ 538static void bnx2x_ets_e3b0_nig_disabled(const struct link_params *params, 539 const struct link_vars *vars) 540{ 541 struct bnx2x *bp = params->bp; 542 const u8 port = params->port; 543 const u32 min_w_val = bnx2x_ets_get_min_w_val_nig(vars); 544 /** 545 * mapping between entry priority to client number (0,1,2 -debug and 546 * management clients, 3 - COS0 client, 4 - COS1, ... 8 - 547 * COS5)(HIGHEST) 4bits client num.TODO_ETS - Should be done by 548 * reset value or init tool 549 */ 550 if (port) { 551 REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB, 0x543210); 552 REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB, 0x0); 553 } else { 554 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, 0x76543210); 555 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, 0x8); 556 } 557 /** 558 * For strict priority entries defines the number of consecutive 559 * slots for the highest priority. 560 */ 561 /* TODO_ETS - Should be done by reset value or init tool */ 562 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS : 563 NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100); 564 /** 565 * mapping between the CREDIT_WEIGHT registers and actual client 566 * numbers 567 */ 568 /* TODO_ETS - Should be done by reset value or init tool */ 569 if (port) { 570 /*Port 1 has 6 COS*/ 571 REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB, 0x210543); 572 REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x0); 573 } else { 574 /*Port 0 has 9 COS*/ 575 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_LSB, 576 0x43210876); 577 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x5); 578 } 579 580 /** 581 * Bitmap of 5bits length. Each bit specifies whether the entry behaves 582 * as strict. Bits 0,1,2 - debug and management entries, 3 - 583 * COS0 entry, 4 - COS1 entry. 584 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT 585 * bit4 bit3 bit2 bit1 bit0 586 * MCP and debug are strict 587 */ 588 if (port) 589 REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT, 0x3f); 590 else 591 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1ff); 592 /* defines which entries (clients) are subjected to WFQ arbitration */ 593 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ : 594 NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0); 595 596 /** 597 * Please notice the register address are note continuous and a 598 * for here is note appropriate.In 2 port mode port0 only COS0-5 599 * can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4 600 * port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT 601 * are never used for WFQ 602 */ 603 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 : 604 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0x0); 605 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 : 606 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0x0); 607 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 : 608 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2, 0x0); 609 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_3 : 610 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3, 0x0); 611 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_4 : 612 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4, 0x0); 613 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_5 : 614 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5, 0x0); 615 if (0 == port) { 616 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_6, 0x0); 617 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_7, 0x0); 618 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_8, 0x0); 619 } 620 621 bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val); 622} 623/****************************************************************************** 624* Description: 625* Set credit upper bound for PBF. 626*. 627******************************************************************************/ 628static void bnx2x_ets_e3b0_set_credit_upper_bound_pbf( 629 const struct link_params *params, 630 const u32 min_w_val) 631{ 632 struct bnx2x *bp = params->bp; 633 const u32 credit_upper_bound = 634 bnx2x_ets_get_credit_upper_bound(min_w_val); 635 const u8 port = params->port; 636 u32 base_upper_bound = 0; 637 u8 max_cos = 0; 638 u8 i = 0; 639 /** 640 * In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4 641 * port mode port1 has COS0-2 that can be used for WFQ. 642 */ 643 if (0 == port) { 644 base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P0; 645 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0; 646 } else { 647 base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P1; 648 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1; 649 } 650 651 for (i = 0; i < max_cos; i++) 652 REG_WR(bp, base_upper_bound + (i << 2), credit_upper_bound); 653} 654 655/****************************************************************************** 656* Description: 657* Will return the PBF ETS registers to init values.Except 658* credit_upper_bound. 659* That isn't used in this configuration (No WFQ is enabled) and will be 660* configured acording to spec 661*. 662******************************************************************************/ 663static void bnx2x_ets_e3b0_pbf_disabled(const struct link_params *params) 664{ 665 struct bnx2x *bp = params->bp; 666 const u8 port = params->port; 667 const u32 min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL; 668 u8 i = 0; 669 u32 base_weight = 0; 670 u8 max_cos = 0; 671 672 /** 673 * mapping between entry priority to client number 0 - COS0 674 * client, 2 - COS1, ... 5 - COS5)(HIGHEST) 4bits client num. 675 * TODO_ETS - Should be done by reset value or init tool 676 */ 677 if (port) 678 /* 0x688 (|011|0 10|00 1|000) */ 679 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , 0x688); 680 else 681 /* (10 1|100 |011|0 10|00 1|000) */ 682 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , 0x2C688); 683 684 /* TODO_ETS - Should be done by reset value or init tool */ 685 if (port) 686 /* 0x688 (|011|0 10|00 1|000)*/ 687 REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P1, 0x688); 688 else 689 /* 0x2C688 (10 1|100 |011|0 10|00 1|000) */ 690 REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P0, 0x2C688); 691 692 REG_WR(bp, (port) ? PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P1 : 693 PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P0 , 0x100); 694 695 696 REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 : 697 PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , 0); 698 699 REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 : 700 PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0 , 0); 701 /** 702 * In 2 port mode port0 has COS0-5 that can be used for WFQ. 703 * In 4 port mode port1 has COS0-2 that can be used for WFQ. 704 */ 705 if (0 == port) { 706 base_weight = PBF_REG_COS0_WEIGHT_P0; 707 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0; 708 } else { 709 base_weight = PBF_REG_COS0_WEIGHT_P1; 710 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1; 711 } 712 713 for (i = 0; i < max_cos; i++) 714 REG_WR(bp, base_weight + (0x4 * i), 0); 715 716 bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf); 717} 718/****************************************************************************** 719* Description: 720* E3B0 disable will return basicly the values to init values. 721*. 722******************************************************************************/ 723static int bnx2x_ets_e3b0_disabled(const struct link_params *params, 724 const struct link_vars *vars) 725{ 726 struct bnx2x *bp = params->bp; 727 728 if (!CHIP_IS_E3B0(bp)) { 729 DP(NETIF_MSG_LINK, 730 "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n"); 731 return -EINVAL; 732 } 733 734 bnx2x_ets_e3b0_nig_disabled(params, vars); 735 736 bnx2x_ets_e3b0_pbf_disabled(params); 737 738 return 0; 739} 740 741/****************************************************************************** 742* Description: 743* Disable will return basicly the values to init values. 744*. 745******************************************************************************/ 746int bnx2x_ets_disabled(struct link_params *params, 747 struct link_vars *vars) 748{ 749 struct bnx2x *bp = params->bp; 750 int bnx2x_status = 0; 751 752 if ((CHIP_IS_E2(bp)) || (CHIP_IS_E3A0(bp))) 753 bnx2x_ets_e2e3a0_disabled(params); 754 else if (CHIP_IS_E3B0(bp)) 755 bnx2x_status = bnx2x_ets_e3b0_disabled(params, vars); 756 else { 757 DP(NETIF_MSG_LINK, "bnx2x_ets_disabled - chip not supported\n"); 758 return -EINVAL; 759 } 760 761 return bnx2x_status; 762} 763 764/****************************************************************************** 765* Description 766* Set the COS mappimg to SP and BW until this point all the COS are not 767* set as SP or BW. 768******************************************************************************/ 769static int bnx2x_ets_e3b0_cli_map(const struct link_params *params, 770 const struct bnx2x_ets_params *ets_params, 771 const u8 cos_sp_bitmap, 772 const u8 cos_bw_bitmap) 773{ 774 struct bnx2x *bp = params->bp; 775 const u8 port = params->port; 776 const u8 nig_cli_sp_bitmap = 0x7 | (cos_sp_bitmap << 3); 777 const u8 pbf_cli_sp_bitmap = cos_sp_bitmap; 778 const u8 nig_cli_subject2wfq_bitmap = cos_bw_bitmap << 3; 779 const u8 pbf_cli_subject2wfq_bitmap = cos_bw_bitmap; 780 781 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT : 782 NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, nig_cli_sp_bitmap); 783 784 REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 : 785 PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , pbf_cli_sp_bitmap); 786 787 REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ : 788 NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 789 nig_cli_subject2wfq_bitmap); 790 791 REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 : 792 PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0, 793 pbf_cli_subject2wfq_bitmap); 794 795 return 0; 796} 797 798/****************************************************************************** 799* Description: 800* This function is needed because NIG ARB_CREDIT_WEIGHT_X are 801* not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable. 802******************************************************************************/ 803static int bnx2x_ets_e3b0_set_cos_bw(struct bnx2x *bp, 804 const u8 cos_entry, 805 const u32 min_w_val_nig, 806 const u32 min_w_val_pbf, 807 const u16 total_bw, 808 const u8 bw, 809 const u8 port) 810{ 811 u32 nig_reg_adress_crd_weight = 0; 812 u32 pbf_reg_adress_crd_weight = 0; 813 /* Calculate and set BW for this COS - use 1 instead of 0 for BW */ 814 const u32 cos_bw_nig = ((bw ? bw : 1) * min_w_val_nig) / total_bw; 815 const u32 cos_bw_pbf = ((bw ? bw : 1) * min_w_val_pbf) / total_bw; 816 817 switch (cos_entry) { 818 case 0: 819 nig_reg_adress_crd_weight = 820 (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 : 821 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0; 822 pbf_reg_adress_crd_weight = (port) ? 823 PBF_REG_COS0_WEIGHT_P1 : PBF_REG_COS0_WEIGHT_P0; 824 break; 825 case 1: 826 nig_reg_adress_crd_weight = (port) ? 827 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 : 828 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1; 829 pbf_reg_adress_crd_weight = (port) ? 830 PBF_REG_COS1_WEIGHT_P1 : PBF_REG_COS1_WEIGHT_P0; 831 break; 832 case 2: 833 nig_reg_adress_crd_weight = (port) ? 834 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 : 835 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2; 836 837 pbf_reg_adress_crd_weight = (port) ? 838 PBF_REG_COS2_WEIGHT_P1 : PBF_REG_COS2_WEIGHT_P0; 839 break; 840 case 3: 841 if (port) 842 return -EINVAL; 843 nig_reg_adress_crd_weight = 844 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3; 845 pbf_reg_adress_crd_weight = 846 PBF_REG_COS3_WEIGHT_P0; 847 break; 848 case 4: 849 if (port) 850 return -EINVAL; 851 nig_reg_adress_crd_weight = 852 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4; 853 pbf_reg_adress_crd_weight = PBF_REG_COS4_WEIGHT_P0; 854 break; 855 case 5: 856 if (port) 857 return -EINVAL; 858 nig_reg_adress_crd_weight = 859 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5; 860 pbf_reg_adress_crd_weight = PBF_REG_COS5_WEIGHT_P0; 861 break; 862 } 863 864 REG_WR(bp, nig_reg_adress_crd_weight, cos_bw_nig); 865 866 REG_WR(bp, pbf_reg_adress_crd_weight, cos_bw_pbf); 867 868 return 0; 869} 870/****************************************************************************** 871* Description: 872* Calculate the total BW.A value of 0 isn't legal. 873*. 874******************************************************************************/ 875static int bnx2x_ets_e3b0_get_total_bw( 876 const struct link_params *params, 877 struct bnx2x_ets_params *ets_params, 878 u16 *total_bw) 879{ 880 struct bnx2x *bp = params->bp; 881 u8 cos_idx = 0; 882 u8 is_bw_cos_exist = 0; 883 884 *total_bw = 0 ; 885 886 /* Calculate total BW requested */ 887 for (cos_idx = 0; cos_idx < ets_params->num_of_cos; cos_idx++) { 888 if (bnx2x_cos_state_bw == ets_params->cos[cos_idx].state) { 889 is_bw_cos_exist = 1; 890 if (!ets_params->cos[cos_idx].params.bw_params.bw) { 891 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config BW" 892 "was set to 0\n"); 893 /* 894 * This is to prevent a state when ramrods 895 * can't be sent 896 */ 897 ets_params->cos[cos_idx].params.bw_params.bw 898 = 1; 899 } 900 *total_bw += 901 ets_params->cos[cos_idx].params.bw_params.bw; 902 } 903 } 904 905 /* Check total BW is valid */ 906 if ((1 == is_bw_cos_exist) && (100 != *total_bw)) { 907 if (0 == *total_bw) { 908 DP(NETIF_MSG_LINK, 909 "bnx2x_ets_E3B0_config toatl BW shouldn't be 0\n"); 910 return -EINVAL; 911 } 912 DP(NETIF_MSG_LINK, 913 "bnx2x_ets_E3B0_config toatl BW should be 100\n"); 914 /** 915 * We can handle a case whre the BW isn't 100 this can happen 916 * if the TC are joined. 917 */ 918 } 919 return 0; 920} 921 922/****************************************************************************** 923* Description: 924* Invalidate all the sp_pri_to_cos. 925*. 926******************************************************************************/ 927static void bnx2x_ets_e3b0_sp_pri_to_cos_init(u8 *sp_pri_to_cos) 928{ 929 u8 pri = 0; 930 for (pri = 0; pri < DCBX_MAX_NUM_COS; pri++) 931 sp_pri_to_cos[pri] = DCBX_INVALID_COS; 932} 933/****************************************************************************** 934* Description: 935* Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers 936* according to sp_pri_to_cos. 937*. 938******************************************************************************/ 939static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params, 940 u8 *sp_pri_to_cos, const u8 pri, 941 const u8 cos_entry) 942{ 943 struct bnx2x *bp = params->bp; 944 const u8 port = params->port; 945 const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 : 946 DCBX_E3B0_MAX_NUM_COS_PORT0; 947 948 if (DCBX_INVALID_COS != sp_pri_to_cos[pri]) { 949 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " 950 "parameter There can't be two COS's with " 951 "the same strict pri\n"); 952 return -EINVAL; 953 } 954 955 if (pri > max_num_of_cos) { 956 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " 957 "parameter Illegal strict priority\n"); 958 return -EINVAL; 959 } 960 961 sp_pri_to_cos[pri] = cos_entry; 962 return 0; 963 964} 965 966/****************************************************************************** 967* Description: 968* Returns the correct value according to COS and priority in 969* the sp_pri_cli register. 970*. 971******************************************************************************/ 972static u64 bnx2x_e3b0_sp_get_pri_cli_reg(const u8 cos, const u8 cos_offset, 973 const u8 pri_set, 974 const u8 pri_offset, 975 const u8 entry_size) 976{ 977 u64 pri_cli_nig = 0; 978 pri_cli_nig = ((u64)(cos + cos_offset)) << (entry_size * 979 (pri_set + pri_offset)); 980 981 return pri_cli_nig; 982} 983/****************************************************************************** 984* Description: 985* Returns the correct value according to COS and priority in the 986* sp_pri_cli register for NIG. 987*. 988******************************************************************************/ 989static u64 bnx2x_e3b0_sp_get_pri_cli_reg_nig(const u8 cos, const u8 pri_set) 990{ 991 /* MCP Dbg0 and dbg1 are always with higher strict pri*/ 992 const u8 nig_cos_offset = 3; 993 const u8 nig_pri_offset = 3; 994 995 return bnx2x_e3b0_sp_get_pri_cli_reg(cos, nig_cos_offset, pri_set, 996 nig_pri_offset, 4); 997 998} 999/****************************************************************************** 1000* Description: 1001* Returns the correct value according to COS and priority in the 1002* sp_pri_cli register for PBF. 1003*. 1004******************************************************************************/ 1005static u64 bnx2x_e3b0_sp_get_pri_cli_reg_pbf(const u8 cos, const u8 pri_set) 1006{ 1007 const u8 pbf_cos_offset = 0; 1008 const u8 pbf_pri_offset = 0; 1009 1010 return bnx2x_e3b0_sp_get_pri_cli_reg(cos, pbf_cos_offset, pri_set, 1011 pbf_pri_offset, 3); 1012 1013} 1014 1015/****************************************************************************** 1016* Description: 1017* Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers 1018* according to sp_pri_to_cos.(which COS has higher priority) 1019*. 1020******************************************************************************/ 1021static int bnx2x_ets_e3b0_sp_set_pri_cli_reg(const struct link_params *params, 1022 u8 *sp_pri_to_cos) 1023{ 1024 struct bnx2x *bp = params->bp; 1025 u8 i = 0; 1026 const u8 port = params->port; 1027 /* MCP Dbg0 and dbg1 are always with higher strict pri*/ 1028 u64 pri_cli_nig = 0x210; 1029 u32 pri_cli_pbf = 0x0; 1030 u8 pri_set = 0; 1031 u8 pri_bitmask = 0; 1032 const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 : 1033 DCBX_E3B0_MAX_NUM_COS_PORT0; 1034 1035 u8 cos_bit_to_set = (1 << max_num_of_cos) - 1; 1036 1037 /* Set all the strict priority first */ 1038 for (i = 0; i < max_num_of_cos; i++) { 1039 if (DCBX_INVALID_COS != sp_pri_to_cos[i]) { 1040 if (DCBX_MAX_NUM_COS <= sp_pri_to_cos[i]) { 1041 DP(NETIF_MSG_LINK, 1042 "bnx2x_ets_e3b0_sp_set_pri_cli_reg " 1043 "invalid cos entry\n"); 1044 return -EINVAL; 1045 } 1046 1047 pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig( 1048 sp_pri_to_cos[i], pri_set); 1049 1050 pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf( 1051 sp_pri_to_cos[i], pri_set); 1052 pri_bitmask = 1 << sp_pri_to_cos[i]; 1053 /* COS is used remove it from bitmap.*/ 1054 if (0 == (pri_bitmask & cos_bit_to_set)) { 1055 DP(NETIF_MSG_LINK, 1056 "bnx2x_ets_e3b0_sp_set_pri_cli_reg " 1057 "invalid There can't be two COS's with" 1058 " the same strict pri\n"); 1059 return -EINVAL; 1060 } 1061 cos_bit_to_set &= ~pri_bitmask; 1062 pri_set++; 1063 } 1064 } 1065 1066 /* Set all the Non strict priority i= COS*/ 1067 for (i = 0; i < max_num_of_cos; i++) { 1068 pri_bitmask = 1 << i; 1069 /* Check if COS was already used for SP */ 1070 if (pri_bitmask & cos_bit_to_set) { 1071 /* COS wasn't used for SP */ 1072 pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig( 1073 i, pri_set); 1074 1075 pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf( 1076 i, pri_set); 1077 /* COS is used remove it from bitmap.*/ 1078 cos_bit_to_set &= ~pri_bitmask; 1079 pri_set++; 1080 } 1081 } 1082 1083 if (pri_set != max_num_of_cos) { 1084 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_set_pri_cli_reg not all " 1085 "entries were set\n"); 1086 return -EINVAL; 1087 } 1088 1089 if (port) { 1090 /* Only 6 usable clients*/ 1091 REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB, 1092 (u32)pri_cli_nig); 1093 1094 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , pri_cli_pbf); 1095 } else { 1096 /* Only 9 usable clients*/ 1097 const u32 pri_cli_nig_lsb = (u32) (pri_cli_nig); 1098 const u32 pri_cli_nig_msb = (u32) ((pri_cli_nig >> 32) & 0xF); 1099 1100 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, 1101 pri_cli_nig_lsb); 1102 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, 1103 pri_cli_nig_msb); 1104 1105 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , pri_cli_pbf); 1106 } 1107 return 0; 1108} 1109 1110/****************************************************************************** 1111* Description: 1112* Configure the COS to ETS according to BW and SP settings. 1113******************************************************************************/ 1114int bnx2x_ets_e3b0_config(const struct link_params *params, 1115 const struct link_vars *vars, 1116 struct bnx2x_ets_params *ets_params) 1117{ 1118 struct bnx2x *bp = params->bp; 1119 int bnx2x_status = 0; 1120 const u8 port = params->port; 1121 u16 total_bw = 0; 1122 const u32 min_w_val_nig = bnx2x_ets_get_min_w_val_nig(vars); 1123 const u32 min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL; 1124 u8 cos_bw_bitmap = 0; 1125 u8 cos_sp_bitmap = 0; 1126 u8 sp_pri_to_cos[DCBX_MAX_NUM_COS] = {0}; 1127 const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 : 1128 DCBX_E3B0_MAX_NUM_COS_PORT0; 1129 u8 cos_entry = 0; 1130 1131 if (!CHIP_IS_E3B0(bp)) { 1132 DP(NETIF_MSG_LINK, 1133 "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n"); 1134 return -EINVAL; 1135 } 1136 1137 if ((ets_params->num_of_cos > max_num_of_cos)) { 1138 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config the number of COS " 1139 "isn't supported\n"); 1140 return -EINVAL; 1141 } 1142 1143 /* Prepare sp strict priority parameters*/ 1144 bnx2x_ets_e3b0_sp_pri_to_cos_init(sp_pri_to_cos); 1145 1146 /* Prepare BW parameters*/ 1147 bnx2x_status = bnx2x_ets_e3b0_get_total_bw(params, ets_params, 1148 &total_bw); 1149 if (0 != bnx2x_status) { 1150 DP(NETIF_MSG_LINK, 1151 "bnx2x_ets_E3B0_config get_total_bw failed\n"); 1152 return -EINVAL; 1153 } 1154 1155 /** 1156 * Upper bound is set according to current link speed (min_w_val 1157 * should be the same for upper bound and COS credit val). 1158 */ 1159 bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val_nig); 1160 bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf); 1161 1162 1163 for (cos_entry = 0; cos_entry < ets_params->num_of_cos; cos_entry++) { 1164 if (bnx2x_cos_state_bw == ets_params->cos[cos_entry].state) { 1165 cos_bw_bitmap |= (1 << cos_entry); 1166 /** 1167 * The function also sets the BW in HW(not the mappin 1168 * yet) 1169 */ 1170 bnx2x_status = bnx2x_ets_e3b0_set_cos_bw( 1171 bp, cos_entry, min_w_val_nig, min_w_val_pbf, 1172 total_bw, 1173 ets_params->cos[cos_entry].params.bw_params.bw, 1174 port); 1175 } else if (bnx2x_cos_state_strict == 1176 ets_params->cos[cos_entry].state){ 1177 cos_sp_bitmap |= (1 << cos_entry); 1178 1179 bnx2x_status = bnx2x_ets_e3b0_sp_pri_to_cos_set( 1180 params, 1181 sp_pri_to_cos, 1182 ets_params->cos[cos_entry].params.sp_params.pri, 1183 cos_entry); 1184 1185 } else { 1186 DP(NETIF_MSG_LINK, 1187 "bnx2x_ets_e3b0_config cos state not valid\n"); 1188 return -EINVAL; 1189 } 1190 if (0 != bnx2x_status) { 1191 DP(NETIF_MSG_LINK, 1192 "bnx2x_ets_e3b0_config set cos bw failed\n"); 1193 return bnx2x_status; 1194 } 1195 } 1196 1197 /* Set SP register (which COS has higher priority) */ 1198 bnx2x_status = bnx2x_ets_e3b0_sp_set_pri_cli_reg(params, 1199 sp_pri_to_cos); 1200 1201 if (0 != bnx2x_status) { 1202 DP(NETIF_MSG_LINK, 1203 "bnx2x_ets_E3B0_config set_pri_cli_reg failed\n"); 1204 return bnx2x_status; 1205 } 1206 1207 /* Set client mapping of BW and strict */ 1208 bnx2x_status = bnx2x_ets_e3b0_cli_map(params, ets_params, 1209 cos_sp_bitmap, 1210 cos_bw_bitmap); 1211 1212 if (0 != bnx2x_status) { 1213 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config SP failed\n"); 1214 return bnx2x_status; 1215 } 1216 return 0; 1217} 1218static void bnx2x_ets_bw_limit_common(const struct link_params *params) 1219{ 1220 /* ETS disabled configuration */ 1221 struct bnx2x *bp = params->bp; 1222 DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n"); 1223 /* 1224 * defines which entries (clients) are subjected to WFQ arbitration 1225 * COS0 0x8 1226 * COS1 0x10 1227 */ 1228 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18); 1229 /* 1230 * mapping between the ARB_CREDIT_WEIGHT registers and actual 1231 * client numbers (WEIGHT_0 does not actually have to represent 1232 * client 0) 1233 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0 1234 * cos1-001 cos0-000 dbg1-100 dbg0-011 MCP-010 1235 */ 1236 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A); 1237 1238 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 1239 ETS_BW_LIMIT_CREDIT_UPPER_BOUND); 1240 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 1241 ETS_BW_LIMIT_CREDIT_UPPER_BOUND); 1242 1243 /* ETS mode enabled*/ 1244 REG_WR(bp, PBF_REG_ETS_ENABLED, 1); 1245 1246 /* Defines the number of consecutive slots for the strict priority */ 1247 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0); 1248 /* 1249 * Bitmap of 5bits length. Each bit specifies whether the entry behaves 1250 * as strict. Bits 0,1,2 - debug and management entries, 3 - COS0 1251 * entry, 4 - COS1 entry. 1252 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT 1253 * bit4 bit3 bit2 bit1 bit0 1254 * MCP and debug are strict 1255 */ 1256 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7); 1257 1258 /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/ 1259 REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 1260 ETS_BW_LIMIT_CREDIT_UPPER_BOUND); 1261 REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 1262 ETS_BW_LIMIT_CREDIT_UPPER_BOUND); 1263} 1264 1265void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw, 1266 const u32 cos1_bw) 1267{ 1268 /* ETS disabled configuration*/ 1269 struct bnx2x *bp = params->bp; 1270 const u32 total_bw = cos0_bw + cos1_bw; 1271 u32 cos0_credit_weight = 0; 1272 u32 cos1_credit_weight = 0; 1273 1274 DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n"); 1275 1276 if ((0 == total_bw) || 1277 (0 == cos0_bw) || 1278 (0 == cos1_bw)) { 1279 DP(NETIF_MSG_LINK, "Total BW can't be zero\n"); 1280 return; 1281 } 1282 1283 cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/ 1284 total_bw; 1285 cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/ 1286 total_bw; 1287 1288 bnx2x_ets_bw_limit_common(params); 1289 1290 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight); 1291 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight); 1292 1293 REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight); 1294 REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight); 1295} 1296 1297int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos) 1298{ 1299 /* ETS disabled configuration*/ 1300 struct bnx2x *bp = params->bp; 1301 u32 val = 0; 1302 1303 DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n"); 1304 /* 1305 * Bitmap of 5bits length. Each bit specifies whether the entry behaves 1306 * as strict. Bits 0,1,2 - debug and management entries, 1307 * 3 - COS0 entry, 4 - COS1 entry. 1308 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT 1309 * bit4 bit3 bit2 bit1 bit0 1310 * MCP and debug are strict 1311 */ 1312 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F); 1313 /* 1314 * For strict priority entries defines the number of consecutive slots 1315 * for the highest priority. 1316 */ 1317 REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100); 1318 /* ETS mode disable */ 1319 REG_WR(bp, PBF_REG_ETS_ENABLED, 0); 1320 /* Defines the number of consecutive slots for the strict priority */ 1321 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100); 1322 1323 /* Defines the number of consecutive slots for the strict priority */ 1324 REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos); 1325 1326 /* 1327 * mapping between entry priority to client number (0,1,2 -debug and 1328 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST) 1329 * 3bits client num. 1330 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0 1331 * dbg0-010 dbg1-001 cos1-100 cos0-011 MCP-000 1332 * dbg0-010 dbg1-001 cos0-011 cos1-100 MCP-000 1333 */ 1334 val = (0 == strict_cos) ? 0x2318 : 0x22E0; 1335 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val); 1336 1337 return 0; 1338} 1339/******************************************************************/ 1340/* PFC section */ 1341/******************************************************************/ 1342 1343static void bnx2x_update_pfc_xmac(struct link_params *params, 1344 struct link_vars *vars, 1345 u8 is_lb) 1346{ 1347 struct bnx2x *bp = params->bp; 1348 u32 xmac_base; 1349 u32 pause_val, pfc0_val, pfc1_val; 1350 1351 /* XMAC base adrr */ 1352 xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0; 1353 1354 /* Initialize pause and pfc registers */ 1355 pause_val = 0x18000; 1356 pfc0_val = 0xFFFF8000; 1357 pfc1_val = 0x2; 1358 1359 /* No PFC support */ 1360 if (!(params->feature_config_flags & 1361 FEATURE_CONFIG_PFC_ENABLED)) { 1362 1363 /* 1364 * RX flow control - Process pause frame in receive direction 1365 */ 1366 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) 1367 pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN; 1368 1369 /* 1370 * TX flow control - Send pause packet when buffer is full 1371 */ 1372 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) 1373 pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN; 1374 } else {/* PFC support */ 1375 pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN | 1376 XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN | 1377 XMAC_PFC_CTRL_HI_REG_RX_PFC_EN | 1378 XMAC_PFC_CTRL_HI_REG_TX_PFC_EN; 1379 } 1380 1381 /* Write pause and PFC registers */ 1382 REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val); 1383 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val); 1384 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val); 1385 1386 1387 /* Set MAC address for source TX Pause/PFC frames */ 1388 REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_LO, 1389 ((params->mac_addr[2] << 24) | 1390 (params->mac_addr[3] << 16) | 1391 (params->mac_addr[4] << 8) | 1392 (params->mac_addr[5]))); 1393 REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_HI, 1394 ((params->mac_addr[0] << 8) | 1395 (params->mac_addr[1]))); 1396 1397 udelay(30); 1398} 1399 1400 1401static void bnx2x_emac_get_pfc_stat(struct link_params *params, 1402 u32 pfc_frames_sent[2], 1403 u32 pfc_frames_received[2]) 1404{ 1405 /* Read pfc statistic */ 1406 struct bnx2x *bp = params->bp; 1407 u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; 1408 u32 val_xon = 0; 1409 u32 val_xoff = 0; 1410 1411 DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n"); 1412 1413 /* PFC received frames */ 1414 val_xoff = REG_RD(bp, emac_base + 1415 EMAC_REG_RX_PFC_STATS_XOFF_RCVD); 1416 val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT; 1417 val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD); 1418 val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT; 1419 1420 pfc_frames_received[0] = val_xon + val_xoff; 1421 1422 /* PFC received sent */ 1423 val_xoff = REG_RD(bp, emac_base + 1424 EMAC_REG_RX_PFC_STATS_XOFF_SENT); 1425 val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT; 1426 val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT); 1427 val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT; 1428 1429 pfc_frames_sent[0] = val_xon + val_xoff; 1430} 1431 1432/* Read pfc statistic*/ 1433void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, 1434 u32 pfc_frames_sent[2], 1435 u32 pfc_frames_received[2]) 1436{ 1437 /* Read pfc statistic */ 1438 struct bnx2x *bp = params->bp; 1439 1440 DP(NETIF_MSG_LINK, "pfc statistic\n"); 1441 1442 if (!vars->link_up) 1443 return; 1444 1445 if (MAC_TYPE_EMAC == vars->mac_type) { 1446 DP(NETIF_MSG_LINK, "About to read PFC stats from EMAC\n"); 1447 bnx2x_emac_get_pfc_stat(params, pfc_frames_sent, 1448 pfc_frames_received); 1449 } 1450} 1451/******************************************************************/ 1452/* MAC/PBF section */ 1453/******************************************************************/ 1454static void bnx2x_set_mdio_clk(struct bnx2x *bp, u32 chip_id, u8 port) 1455{ 1456 u32 mode, emac_base; 1457 /** 1458 * Set clause 45 mode, slow down the MDIO clock to 2.5MHz 1459 * (a value of 49==0x31) and make sure that the AUTO poll is off 1460 */ 1461 1462 if (CHIP_IS_E2(bp)) 1463 emac_base = GRCBASE_EMAC0; 1464 else 1465 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; 1466 mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); 1467 mode &= ~(EMAC_MDIO_MODE_AUTO_POLL | 1468 EMAC_MDIO_MODE_CLOCK_CNT); 1469 if (USES_WARPCORE(bp)) 1470 mode |= (74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT); 1471 else 1472 mode |= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT); 1473 1474 mode |= (EMAC_MDIO_MODE_CLAUSE_45); 1475 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, mode); 1476 1477 udelay(40); 1478} 1479 1480static void bnx2x_emac_init(struct link_params *params, 1481 struct link_vars *vars) 1482{ 1483 /* reset and unreset the emac core */ 1484 struct bnx2x *bp = params->bp; 1485 u8 port = params->port; 1486 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; 1487 u32 val; 1488 u16 timeout; 1489 1490 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 1491 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port)); 1492 udelay(5); 1493 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 1494 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port)); 1495 1496 /* init emac - use read-modify-write */ 1497 /* self clear reset */ 1498 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); 1499 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET)); 1500 1501 timeout = 200; 1502 do { 1503 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); 1504 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val); 1505 if (!timeout) { 1506 DP(NETIF_MSG_LINK, "EMAC timeout!\n"); 1507 return; 1508 } 1509 timeout--; 1510 } while (val & EMAC_MODE_RESET); 1511 bnx2x_set_mdio_clk(bp, params->chip_id, port); 1512 /* Set mac address */ 1513 val = ((params->mac_addr[0] << 8) | 1514 params->mac_addr[1]); 1515 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val); 1516 1517 val = ((params->mac_addr[2] << 24) | 1518 (params->mac_addr[3] << 16) | 1519 (params->mac_addr[4] << 8) | 1520 params->mac_addr[5]); 1521 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val); 1522} 1523 1524static void bnx2x_set_xumac_nig(struct link_params *params, 1525 u16 tx_pause_en, 1526 u8 enable) 1527{ 1528 struct bnx2x *bp = params->bp; 1529 1530 REG_WR(bp, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN, 1531 enable); 1532 REG_WR(bp, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN, 1533 enable); 1534 REG_WR(bp, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN : 1535 NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en); 1536} 1537 1538static void bnx2x_umac_disable(struct link_params *params) 1539{ 1540 u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0; 1541 struct bnx2x *bp = params->bp; 1542 if (!(REG_RD(bp, MISC_REG_RESET_REG_2) & 1543 (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port))) 1544 return; 1545 1546 /* Disable RX and TX */ 1547 REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, 0); 1548} 1549 1550static void bnx2x_umac_enable(struct link_params *params, 1551 struct link_vars *vars, u8 lb) 1552{ 1553 u32 val; 1554 u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0; 1555 struct bnx2x *bp = params->bp; 1556 /* Reset UMAC */ 1557 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 1558 (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)); 1559 usleep_range(1000, 1000); 1560 1561 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 1562 (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)); 1563 1564 DP(NETIF_MSG_LINK, "enabling UMAC\n"); 1565 1566 /** 1567 * This register determines on which events the MAC will assert 1568 * error on the i/f to the NIG along w/ EOP. 1569 */ 1570 1571 /** 1572 * BD REG_WR(bp, NIG_REG_P0_MAC_RSV_ERR_MASK + 1573 * params->port*0x14, 0xfffff. 1574 */ 1575 /* This register opens the gate for the UMAC despite its name */ 1576 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1); 1577 1578 val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN | 1579 UMAC_COMMAND_CONFIG_REG_PAD_EN | 1580 UMAC_COMMAND_CONFIG_REG_SW_RESET | 1581 UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK; 1582 switch (vars->line_speed) { 1583 case SPEED_10: 1584 val |= (0<<2); 1585 break; 1586 case SPEED_100: 1587 val |= (1<<2); 1588 break; 1589 case SPEED_1000: 1590 val |= (2<<2); 1591 break; 1592 case SPEED_2500: 1593 val |= (3<<2); 1594 break; 1595 default: 1596 DP(NETIF_MSG_LINK, "Invalid speed for UMAC %d\n", 1597 vars->line_speed); 1598 break; 1599 } 1600 if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) 1601 val |= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE; 1602 1603 if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)) 1604 val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE; 1605 1606 REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val); 1607 udelay(50); 1608 1609 /* Set MAC address for source TX Pause/PFC frames (under SW reset) */ 1610 REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR0, 1611 ((params->mac_addr[2] << 24) | 1612 (params->mac_addr[3] << 16) | 1613 (params->mac_addr[4] << 8) | 1614 (params->mac_addr[5]))); 1615 REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR1, 1616 ((params->mac_addr[0] << 8) | 1617 (params->mac_addr[1]))); 1618 1619 /* Enable RX and TX */ 1620 val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN; 1621 val |= UMAC_COMMAND_CONFIG_REG_TX_ENA | 1622 UMAC_COMMAND_CONFIG_REG_RX_ENA; 1623 REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val); 1624 udelay(50); 1625 1626 /* Remove SW Reset */ 1627 val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET; 1628 1629 /* Check loopback mode */ 1630 if (lb) 1631 val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA; 1632 REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val); 1633 1634 /* 1635 * Maximum Frame Length (RW). Defines a 14-Bit maximum frame 1636 * length used by the MAC receive logic to check frames. 1637 */ 1638 REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710); 1639 bnx2x_set_xumac_nig(params, 1640 ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1); 1641 vars->mac_type = MAC_TYPE_UMAC; 1642 1643} 1644 1645static u8 bnx2x_is_4_port_mode(struct bnx2x *bp) 1646{ 1647 u32 port4mode_ovwr_val; 1648 /* Check 4-port override enabled */ 1649 port4mode_ovwr_val = REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR); 1650 if (port4mode_ovwr_val & (1<<0)) { 1651 /* Return 4-port mode override value */ 1652 return ((port4mode_ovwr_val & (1<<1)) == (1<<1)); 1653 } 1654 /* Return 4-port mode from input pin */ 1655 return (u8)REG_RD(bp, MISC_REG_PORT4MODE_EN); 1656} 1657 1658/* Define the XMAC mode */ 1659static void bnx2x_xmac_init(struct link_params *params, u32 max_speed) 1660{ 1661 struct bnx2x *bp = params->bp; 1662 u32 is_port4mode = bnx2x_is_4_port_mode(bp); 1663 1664 /** 1665 * In 4-port mode, need to set the mode only once, so if XMAC is 1666 * already out of reset, it means the mode has already been set, 1667 * and it must not* reset the XMAC again, since it controls both 1668 * ports of the path 1669 **/ 1670 1671 if ((CHIP_NUM(bp) == CHIP_NUM_57840) && 1672 (REG_RD(bp, MISC_REG_RESET_REG_2) & 1673 MISC_REGISTERS_RESET_REG_2_XMAC)) { 1674 DP(NETIF_MSG_LINK, 1675 "XMAC already out of reset in 4-port mode\n"); 1676 return; 1677 } 1678 1679 /* Hard reset */ 1680 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 1681 MISC_REGISTERS_RESET_REG_2_XMAC); 1682 usleep_range(1000, 1000); 1683 1684 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 1685 MISC_REGISTERS_RESET_REG_2_XMAC); 1686 if (is_port4mode) { 1687 DP(NETIF_MSG_LINK, "Init XMAC to 2 ports x 10G per path\n"); 1688 1689 /* Set the number of ports on the system side to up to 2 */ 1690 REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 1); 1691 1692 /* Set the number of ports on the Warp Core to 10G */ 1693 REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3); 1694 } else { 1695 /* Set the number of ports on the system side to 1 */ 1696 REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 0); 1697 if (max_speed == SPEED_10000) { 1698 DP(NETIF_MSG_LINK, 1699 "Init XMAC to 10G x 1 port per path\n"); 1700 /* Set the number of ports on the Warp Core to 10G */ 1701 REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3); 1702 } else { 1703 DP(NETIF_MSG_LINK, 1704 "Init XMAC to 20G x 2 ports per path\n"); 1705 /* Set the number of ports on the Warp Core to 20G */ 1706 REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 1); 1707 } 1708 } 1709 /* Soft reset */ 1710 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 1711 MISC_REGISTERS_RESET_REG_2_XMAC_SOFT); 1712 usleep_range(1000, 1000); 1713 1714 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 1715 MISC_REGISTERS_RESET_REG_2_XMAC_SOFT); 1716 1717} 1718 1719static void bnx2x_xmac_disable(struct link_params *params) 1720{ 1721 u8 port = params->port; 1722 struct bnx2x *bp = params->bp; 1723 u32 pfc_ctrl, xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0; 1724 1725 if (REG_RD(bp, MISC_REG_RESET_REG_2) & 1726 MISC_REGISTERS_RESET_REG_2_XMAC) { 1727 /* 1728 * Send an indication to change the state in the NIG back to XON 1729 * Clearing this bit enables the next set of this bit to get 1730 * rising edge 1731 */ 1732 pfc_ctrl = REG_RD(bp, xmac_base + XMAC_REG_PFC_CTRL_HI); 1733 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, 1734 (pfc_ctrl & ~(1<<1))); 1735 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, 1736 (pfc_ctrl | (1<<1))); 1737 DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port); 1738 REG_WR(bp, xmac_base + XMAC_REG_CTRL, 0); 1739 } 1740} 1741 1742static int bnx2x_xmac_enable(struct link_params *params, 1743 struct link_vars *vars, u8 lb) 1744{ 1745 u32 val, xmac_base; 1746 struct bnx2x *bp = params->bp; 1747 DP(NETIF_MSG_LINK, "enabling XMAC\n"); 1748 1749 xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0; 1750 1751 bnx2x_xmac_init(params, vars->line_speed); 1752 1753 /* 1754 * This register determines on which events the MAC will assert 1755 * error on the i/f to the NIG along w/ EOP. 1756 */ 1757 1758 /* 1759 * This register tells the NIG whether to send traffic to UMAC 1760 * or XMAC 1761 */ 1762 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0); 1763 1764 /* Set Max packet size */ 1765 REG_WR(bp, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710); 1766 1767 /* CRC append for Tx packets */ 1768 REG_WR(bp, xmac_base + XMAC_REG_TX_CTRL, 0xC800); 1769 1770 /* update PFC */ 1771 bnx2x_update_pfc_xmac(params, vars, 0); 1772 1773 /* Enable TX and RX */ 1774 val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN; 1775 1776 /* Check loopback mode */ 1777 if (lb) 1778 val |= XMAC_CTRL_REG_LINE_LOCAL_LPBK; 1779 REG_WR(bp, xmac_base + XMAC_REG_CTRL, val); 1780 bnx2x_set_xumac_nig(params, 1781 ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1); 1782 1783 vars->mac_type = MAC_TYPE_XMAC; 1784 1785 return 0; 1786} 1787static int bnx2x_emac_enable(struct link_params *params, 1788 struct link_vars *vars, u8 lb) 1789{ 1790 struct bnx2x *bp = params->bp; 1791 u8 port = params->port; 1792 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; 1793 u32 val; 1794 1795 DP(NETIF_MSG_LINK, "enabling EMAC\n"); 1796 1797 /* Disable BMAC */ 1798 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 1799 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); 1800 1801 /* enable emac and not bmac */ 1802 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1); 1803 1804 /* ASIC */ 1805 if (vars->phy_flags & PHY_XGXS_FLAG) { 1806 u32 ser_lane = ((params->lane_config & 1807 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> 1808 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); 1809 1810 DP(NETIF_MSG_LINK, "XGXS\n"); 1811 /* select the master lanes (out of 0-3) */ 1812 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane); 1813 /* select XGXS */ 1814 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); 1815 1816 } else { /* SerDes */ 1817 DP(NETIF_MSG_LINK, "SerDes\n"); 1818 /* select SerDes */ 1819 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0); 1820 } 1821 1822 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE, 1823 EMAC_RX_MODE_RESET); 1824 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE, 1825 EMAC_TX_MODE_RESET); 1826 1827 if (CHIP_REV_IS_SLOW(bp)) { 1828 /* config GMII mode */ 1829 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); 1830 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII)); 1831 } else { /* ASIC */ 1832 /* pause enable/disable */ 1833 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE, 1834 EMAC_RX_MODE_FLOW_EN); 1835 1836 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE, 1837 (EMAC_TX_MODE_EXT_PAUSE_EN | 1838 EMAC_TX_MODE_FLOW_EN)); 1839 if (!(params->feature_config_flags & 1840 FEATURE_CONFIG_PFC_ENABLED)) { 1841 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) 1842 bnx2x_bits_en(bp, emac_base + 1843 EMAC_REG_EMAC_RX_MODE, 1844 EMAC_RX_MODE_FLOW_EN); 1845 1846 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) 1847 bnx2x_bits_en(bp, emac_base + 1848 EMAC_REG_EMAC_TX_MODE, 1849 (EMAC_TX_MODE_EXT_PAUSE_EN | 1850 EMAC_TX_MODE_FLOW_EN)); 1851 } else 1852 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE, 1853 EMAC_TX_MODE_FLOW_EN); 1854 } 1855 1856 /* KEEP_VLAN_TAG, promiscuous */ 1857 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE); 1858 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS; 1859 1860 /* 1861 * Setting this bit causes MAC control frames (except for pause 1862 * frames) to be passed on for processing. This setting has no 1863 * affect on the operation of the pause frames. This bit effects 1864 * all packets regardless of RX Parser packet sorting logic. 1865 * Turn the PFC off to make sure we are in Xon state before 1866 * enabling it. 1867 */ 1868 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0); 1869 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) { 1870 DP(NETIF_MSG_LINK, "PFC is enabled\n"); 1871 /* Enable PFC again */ 1872 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 1873 EMAC_REG_RX_PFC_MODE_RX_EN | 1874 EMAC_REG_RX_PFC_MODE_TX_EN | 1875 EMAC_REG_RX_PFC_MODE_PRIORITIES); 1876 1877 EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM, 1878 ((0x0101 << 1879 EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) | 1880 (0x00ff << 1881 EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT))); 1882 val |= EMAC_RX_MODE_KEEP_MAC_CONTROL; 1883 } 1884 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val); 1885 1886 /* Set Loopback */ 1887 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); 1888 if (lb) 1889 val |= 0x810; 1890 else 1891 val &= ~0x810; 1892 EMAC_WR(bp, EMAC_REG_EMAC_MODE, val); 1893 1894 /* enable emac */ 1895 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1); 1896 1897 /* enable emac for jumbo packets */ 1898 EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE, 1899 (EMAC_RX_MTU_SIZE_JUMBO_ENA | 1900 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD))); 1901 1902 /* strip CRC */ 1903 REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1); 1904 1905 /* disable the NIG in/out to the bmac */ 1906 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0); 1907 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0); 1908 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0); 1909 1910 /* enable the NIG in/out to the emac */ 1911 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1); 1912 val = 0; 1913 if ((params->feature_config_flags & 1914 FEATURE_CONFIG_PFC_ENABLED) || 1915 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) 1916 val = 1; 1917 1918 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val); 1919 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1); 1920 1921 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0); 1922 1923 vars->mac_type = MAC_TYPE_EMAC; 1924 return 0; 1925} 1926 1927static void bnx2x_update_pfc_bmac1(struct link_params *params, 1928 struct link_vars *vars) 1929{ 1930 u32 wb_data[2]; 1931 struct bnx2x *bp = params->bp; 1932 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM : 1933 NIG_REG_INGRESS_BMAC0_MEM; 1934 1935 u32 val = 0x14; 1936 if ((!(params->feature_config_flags & 1937 FEATURE_CONFIG_PFC_ENABLED)) && 1938 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)) 1939 /* Enable BigMAC to react on received Pause packets */ 1940 val |= (1<<5); 1941 wb_data[0] = val; 1942 wb_data[1] = 0; 1943 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2); 1944 1945 /* tx control */ 1946 val = 0xc0; 1947 if (!(params->feature_config_flags & 1948 FEATURE_CONFIG_PFC_ENABLED) && 1949 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) 1950 val |= 0x800000; 1951 wb_data[0] = val; 1952 wb_data[1] = 0; 1953 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2); 1954} 1955 1956static void bnx2x_update_pfc_bmac2(struct link_params *params, 1957 struct link_vars *vars, 1958 u8 is_lb) 1959{ 1960 /* 1961 * Set rx control: Strip CRC and enable BigMAC to relay 1962 * control packets to the system as well 1963 */ 1964 u32 wb_data[2]; 1965 struct bnx2x *bp = params->bp; 1966 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM : 1967 NIG_REG_INGRESS_BMAC0_MEM; 1968 u32 val = 0x14; 1969 1970 if ((!(params->feature_config_flags & 1971 FEATURE_CONFIG_PFC_ENABLED)) && 1972 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)) 1973 /* Enable BigMAC to react on received Pause packets */ 1974 val |= (1<<5); 1975 wb_data[0] = val; 1976 wb_data[1] = 0; 1977 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2); 1978 udelay(30); 1979 1980 /* Tx control */ 1981 val = 0xc0; 1982 if (!(params->feature_config_flags & 1983 FEATURE_CONFIG_PFC_ENABLED) && 1984 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) 1985 val |= 0x800000; 1986 wb_data[0] = val; 1987 wb_data[1] = 0; 1988 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2); 1989 1990 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) { 1991 DP(NETIF_MSG_LINK, "PFC is enabled\n"); 1992 /* Enable PFC RX & TX & STATS and set 8 COS */ 1993 wb_data[0] = 0x0; 1994 wb_data[0] |= (1<<0); /* RX */ 1995 wb_data[0] |= (1<<1); /* TX */ 1996 wb_data[0] |= (1<<2); /* Force initial Xon */ 1997 wb_data[0] |= (1<<3); /* 8 cos */ 1998 wb_data[0] |= (1<<5); /* STATS */ 1999 wb_data[1] = 0; 2000 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, 2001 wb_data, 2); 2002 /* Clear the force Xon */ 2003 wb_data[0] &= ~(1<<2); 2004 } else { 2005 DP(NETIF_MSG_LINK, "PFC is disabled\n"); 2006 /* disable PFC RX & TX & STATS and set 8 COS */ 2007 wb_data[0] = 0x8; 2008 wb_data[1] = 0; 2009 } 2010 2011 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2); 2012 2013 /* 2014 * Set Time (based unit is 512 bit time) between automatic 2015 * re-sending of PP packets amd enable automatic re-send of 2016 * Per-Priroity Packet as long as pp_gen is asserted and 2017 * pp_disable is low. 2018 */ 2019 val = 0x8000; 2020 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) 2021 val |= (1<<16); /* enable automatic re-send */ 2022 2023 wb_data[0] = val; 2024 wb_data[1] = 0; 2025 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL, 2026 wb_data, 2); 2027 2028 /* mac control */ 2029 val = 0x3; /* Enable RX and TX */ 2030 if (is_lb) { 2031 val |= 0x4; /* Local loopback */ 2032 DP(NETIF_MSG_LINK, "enable bmac loopback\n"); 2033 } 2034 /* When PFC enabled, Pass pause frames towards the NIG. */ 2035 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) 2036 val |= ((1<<6)|(1<<5)); 2037 2038 wb_data[0] = val; 2039 wb_data[1] = 0; 2040 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2); 2041} 2042 2043 2044/* PFC BRB internal port configuration params */ 2045struct bnx2x_pfc_brb_threshold_val { 2046 u32 pause_xoff; 2047 u32 pause_xon; 2048 u32 full_xoff; 2049 u32 full_xon; 2050}; 2051 2052struct bnx2x_pfc_brb_e3b0_val { 2053 u32 per_class_guaranty_mode; 2054 u32 lb_guarantied_hyst; 2055 u32 full_lb_xoff_th; 2056 u32 full_lb_xon_threshold; 2057 u32 lb_guarantied; 2058 u32 mac_0_class_t_guarantied; 2059 u32 mac_0_class_t_guarantied_hyst; 2060 u32 mac_1_class_t_guarantied; 2061 u32 mac_1_class_t_guarantied_hyst; 2062}; 2063 2064struct bnx2x_pfc_brb_th_val { 2065 struct bnx2x_pfc_brb_threshold_val pauseable_th; 2066 struct bnx2x_pfc_brb_threshold_val non_pauseable_th; 2067 struct bnx2x_pfc_brb_threshold_val default_class0; 2068 struct bnx2x_pfc_brb_threshold_val default_class1; 2069 2070}; 2071static int bnx2x_pfc_brb_get_config_params( 2072 struct link_params *params, 2073 struct bnx2x_pfc_brb_th_val *config_val) 2074{ 2075 struct bnx2x *bp = params->bp; 2076 DP(NETIF_MSG_LINK, "Setting PFC BRB configuration\n"); 2077 2078 config_val->default_class1.pause_xoff = 0; 2079 config_val->default_class1.pause_xon = 0; 2080 config_val->default_class1.full_xoff = 0; 2081 config_val->default_class1.full_xon = 0; 2082 2083 if (CHIP_IS_E2(bp)) { 2084 /* class0 defaults */ 2085 config_val->default_class0.pause_xoff = 2086 DEFAULT0_E2_BRB_MAC_PAUSE_XOFF_THR; 2087 config_val->default_class0.pause_xon = 2088 DEFAULT0_E2_BRB_MAC_PAUSE_XON_THR; 2089 config_val->default_class0.full_xoff = 2090 DEFAULT0_E2_BRB_MAC_FULL_XOFF_THR; 2091 config_val->default_class0.full_xon = 2092 DEFAULT0_E2_BRB_MAC_FULL_XON_THR; 2093 /* pause able*/ 2094 config_val->pauseable_th.pause_xoff = 2095 PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE; 2096 config_val->pauseable_th.pause_xon = 2097 PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE; 2098 config_val->pauseable_th.full_xoff = 2099 PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE; 2100 config_val->pauseable_th.full_xon = 2101 PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE; 2102 /* non pause able*/ 2103 config_val->non_pauseable_th.pause_xoff = 2104 PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE; 2105 config_val->non_pauseable_th.pause_xon = 2106 PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE; 2107 config_val->non_pauseable_th.full_xoff = 2108 PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE; 2109 config_val->non_pauseable_th.full_xon = 2110 PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE; 2111 } else if (CHIP_IS_E3A0(bp)) { 2112 /* class0 defaults */ 2113 config_val->default_class0.pause_xoff = 2114 DEFAULT0_E3A0_BRB_MAC_PAUSE_XOFF_THR; 2115 config_val->default_class0.pause_xon = 2116 DEFAULT0_E3A0_BRB_MAC_PAUSE_XON_THR; 2117 config_val->default_class0.full_xoff = 2118 DEFAULT0_E3A0_BRB_MAC_FULL_XOFF_THR; 2119 config_val->default_class0.full_xon = 2120 DEFAULT0_E3A0_BRB_MAC_FULL_XON_THR; 2121 /* pause able */ 2122 config_val->pauseable_th.pause_xoff = 2123 PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE; 2124 config_val->pauseable_th.pause_xon = 2125 PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE; 2126 config_val->pauseable_th.full_xoff = 2127 PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE; 2128 config_val->pauseable_th.full_xon = 2129 PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE; 2130 /* non pause able*/ 2131 config_val->non_pauseable_th.pause_xoff = 2132 PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE; 2133 config_val->non_pauseable_th.pause_xon = 2134 PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE; 2135 config_val->non_pauseable_th.full_xoff = 2136 PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE; 2137 config_val->non_pauseable_th.full_xon = 2138 PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE; 2139 } else if (CHIP_IS_E3B0(bp)) { 2140 /* class0 defaults */ 2141 config_val->default_class0.pause_xoff = 2142 DEFAULT0_E3B0_BRB_MAC_PAUSE_XOFF_THR; 2143 config_val->default_class0.pause_xon = 2144 DEFAULT0_E3B0_BRB_MAC_PAUSE_XON_THR; 2145 config_val->default_class0.full_xoff = 2146 DEFAULT0_E3B0_BRB_MAC_FULL_XOFF_THR; 2147 config_val->default_class0.full_xon = 2148 DEFAULT0_E3B0_BRB_MAC_FULL_XON_THR; 2149 2150 if (params->phy[INT_PHY].flags & 2151 FLAGS_4_PORT_MODE) { 2152 config_val->pauseable_th.pause_xoff = 2153 PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE; 2154 config_val->pauseable_th.pause_xon = 2155 PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE; 2156 config_val->pauseable_th.full_xoff = 2157 PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE; 2158 config_val->pauseable_th.full_xon = 2159 PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE; 2160 /* non pause able*/ 2161 config_val->non_pauseable_th.pause_xoff = 2162 PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE; 2163 config_val->non_pauseable_th.pause_xon = 2164 PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE; 2165 config_val->non_pauseable_th.full_xoff = 2166 PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE; 2167 config_val->non_pauseable_th.full_xon = 2168 PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE; 2169 } else { 2170 config_val->pauseable_th.pause_xoff = 2171 PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE; 2172 config_val->pauseable_th.pause_xon = 2173 PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE; 2174 config_val->pauseable_th.full_xoff = 2175 PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE; 2176 config_val->pauseable_th.full_xon = 2177 PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE; 2178 /* non pause able*/ 2179 config_val->non_pauseable_th.pause_xoff = 2180 PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE; 2181 config_val->non_pauseable_th.pause_xon = 2182 PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE; 2183 config_val->non_pauseable_th.full_xoff = 2184 PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE; 2185 config_val->non_pauseable_th.full_xon = 2186 PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE; 2187 } 2188 } else 2189 return -EINVAL; 2190 2191 return 0; 2192} 2193 2194static void bnx2x_pfc_brb_get_e3b0_config_params( 2195 struct link_params *params, 2196 struct bnx2x_pfc_brb_e3b0_val 2197 *e3b0_val, 2198 struct bnx2x_nig_brb_pfc_port_params *pfc_params, 2199 const u8 pfc_enabled) 2200{ 2201 if (pfc_enabled && pfc_params) { 2202 e3b0_val->per_class_guaranty_mode = 1; 2203 e3b0_val->lb_guarantied_hyst = 80; 2204 2205 if (params->phy[INT_PHY].flags & 2206 FLAGS_4_PORT_MODE) { 2207 e3b0_val->full_lb_xoff_th = 2208 PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR; 2209 e3b0_val->full_lb_xon_threshold = 2210 PFC_E3B0_4P_BRB_FULL_LB_XON_THR; 2211 e3b0_val->lb_guarantied = 2212 PFC_E3B0_4P_LB_GUART; 2213 e3b0_val->mac_0_class_t_guarantied = 2214 PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART; 2215 e3b0_val->mac_0_class_t_guarantied_hyst = 2216 PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST; 2217 e3b0_val->mac_1_class_t_guarantied = 2218 PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART; 2219 e3b0_val->mac_1_class_t_guarantied_hyst = 2220 PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST; 2221 } else { 2222 e3b0_val->full_lb_xoff_th = 2223 PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR; 2224 e3b0_val->full_lb_xon_threshold = 2225 PFC_E3B0_2P_BRB_FULL_LB_XON_THR; 2226 e3b0_val->mac_0_class_t_guarantied_hyst = 2227 PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST; 2228 e3b0_val->mac_1_class_t_guarantied = 2229 PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART; 2230 e3b0_val->mac_1_class_t_guarantied_hyst = 2231 PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST; 2232 2233 if (pfc_params->cos0_pauseable != 2234 pfc_params->cos1_pauseable) { 2235 /* nonpauseable= Lossy + pauseable = Lossless*/ 2236 e3b0_val->lb_guarantied = 2237 PFC_E3B0_2P_MIX_PAUSE_LB_GUART; 2238 e3b0_val->mac_0_class_t_guarantied = 2239 PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART; 2240 } else if (pfc_params->cos0_pauseable) { 2241 /* Lossless +Lossless*/ 2242 e3b0_val->lb_guarantied = 2243 PFC_E3B0_2P_PAUSE_LB_GUART; 2244 e3b0_val->mac_0_class_t_guarantied = 2245 PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART; 2246 } else { 2247 /* Lossy +Lossy*/ 2248 e3b0_val->lb_guarantied = 2249 PFC_E3B0_2P_NON_PAUSE_LB_GUART; 2250 e3b0_val->mac_0_class_t_guarantied = 2251 PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART; 2252 } 2253 } 2254 } else { 2255 e3b0_val->per_class_guaranty_mode = 0; 2256 e3b0_val->lb_guarantied_hyst = 0; 2257 e3b0_val->full_lb_xoff_th = 2258 DEFAULT_E3B0_BRB_FULL_LB_XOFF_THR; 2259 e3b0_val->full_lb_xon_threshold = 2260 DEFAULT_E3B0_BRB_FULL_LB_XON_THR; 2261 e3b0_val->lb_guarantied = 2262 DEFAULT_E3B0_LB_GUART; 2263 e3b0_val->mac_0_class_t_guarantied = 2264 DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART; 2265 e3b0_val->mac_0_class_t_guarantied_hyst = 2266 DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART_HYST; 2267 e3b0_val->mac_1_class_t_guarantied = 2268 DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART; 2269 e3b0_val->mac_1_class_t_guarantied_hyst = 2270 DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART_HYST; 2271 } 2272} 2273static int bnx2x_update_pfc_brb(struct link_params *params, 2274 struct link_vars *vars, 2275 struct bnx2x_nig_brb_pfc_port_params 2276 *pfc_params) 2277{ 2278 struct bnx2x *bp = params->bp; 2279 struct bnx2x_pfc_brb_th_val config_val = { {0} }; 2280 struct bnx2x_pfc_brb_threshold_val *reg_th_config = 2281 &config_val.pauseable_th; 2282 struct bnx2x_pfc_brb_e3b0_val e3b0_val = {0}; 2283 const int set_pfc = params->feature_config_flags & 2284 FEATURE_CONFIG_PFC_ENABLED; 2285 const u8 pfc_enabled = (set_pfc && pfc_params); 2286 int bnx2x_status = 0; 2287 u8 port = params->port; 2288 2289 /* default - pause configuration */ 2290 reg_th_config = &config_val.pauseable_th; 2291 bnx2x_status = bnx2x_pfc_brb_get_config_params(params, &config_val); 2292 if (0 != bnx2x_status) 2293 return bnx2x_status; 2294 2295 if (pfc_enabled) { 2296 /* First COS */ 2297 if (pfc_params->cos0_pauseable) 2298 reg_th_config = &config_val.pauseable_th; 2299 else 2300 reg_th_config = &config_val.non_pauseable_th; 2301 } else 2302 reg_th_config = &config_val.default_class0; 2303 /* 2304 * The number of free blocks below which the pause signal to class 0 2305 * of MAC #n is asserted. n=0,1 2306 */ 2307 REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XOFF_THRESHOLD_1 : 2308 BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 , 2309 reg_th_config->pause_xoff); 2310 /* 2311 * The number of free blocks above which the pause signal to class 0 2312 * of MAC #n is de-asserted. n=0,1 2313 */ 2314 REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XON_THRESHOLD_1 : 2315 BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , reg_th_config->pause_xon); 2316 /* 2317 * The number of free blocks below which the full signal to class 0 2318 * of MAC #n is asserted. n=0,1 2319 */ 2320 REG_WR(bp, (port) ? BRB1_REG_FULL_0_XOFF_THRESHOLD_1 : 2321 BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , reg_th_config->full_xoff); 2322 /* 2323 * The number of free blocks above which the full signal to class 0 2324 * of MAC #n is de-asserted. n=0,1 2325 */ 2326 REG_WR(bp, (port) ? BRB1_REG_FULL_0_XON_THRESHOLD_1 : 2327 BRB1_REG_FULL_0_XON_THRESHOLD_0 , reg_th_config->full_xon); 2328 2329 if (pfc_enabled) { 2330 /* Second COS */ 2331 if (pfc_params->cos1_pauseable) 2332 reg_th_config = &config_val.pauseable_th; 2333 else 2334 reg_th_config = &config_val.non_pauseable_th; 2335 } else 2336 reg_th_config = &config_val.default_class1; 2337 /* 2338 * The number of free blocks below which the pause signal to 2339 * class 1 of MAC #n is asserted. n=0,1 2340 **/ 2341 REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XOFF_THRESHOLD_1 : 2342 BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0, 2343 reg_th_config->pause_xoff); 2344 /* 2345 * The number of free blocks above which the pause signal to 2346 * class 1 of MAC #n is de-asserted. n=0,1 2347 */ 2348 REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XON_THRESHOLD_1 : 2349 BRB1_REG_PAUSE_1_XON_THRESHOLD_0, 2350 reg_th_config->pause_xon); 2351 /* 2352 * The number of free blocks below which the full signal to 2353 * class 1 of MAC #n is asserted. n=0,1 2354 */ 2355 REG_WR(bp, (port) ? BRB1_REG_FULL_1_XOFF_THRESHOLD_1 : 2356 BRB1_REG_FULL_1_XOFF_THRESHOLD_0, 2357 reg_th_config->full_xoff); 2358 /* 2359 * The number of free blocks above which the full signal to 2360 * class 1 of MAC #n is de-asserted. n=0,1 2361 */ 2362 REG_WR(bp, (port) ? BRB1_REG_FULL_1_XON_THRESHOLD_1 : 2363 BRB1_REG_FULL_1_XON_THRESHOLD_0, 2364 reg_th_config->full_xon); 2365 2366 if (CHIP_IS_E3B0(bp)) { 2367 bnx2x_pfc_brb_get_e3b0_config_params( 2368 params, 2369 &e3b0_val, 2370 pfc_params, 2371 pfc_enabled); 2372 2373 /*Should be done by init tool */ 2374 /* 2375 * BRB_empty_for_dup = BRB1_REG_BRB_EMPTY_THRESHOLD 2376 * reset value 2377 * 944 2378 */ 2379 REG_WR(bp, BRB1_REG_PER_CLASS_GUARANTY_MODE, 2380 e3b0_val.per_class_guaranty_mode); 2381 2382 /** 2383 * The hysteresis on the guarantied buffer space for the Lb port 2384 * before signaling XON. 2385 **/ 2386 REG_WR(bp, BRB1_REG_LB_GUARANTIED_HYST, 2387 e3b0_val.lb_guarantied_hyst); 2388 /** 2389 * The number of free blocks below which the full signal to the 2390 * LB port is asserted. 2391 */ 2392 REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD, 2393 e3b0_val.full_lb_xoff_th); 2394 /** 2395 * The number of free blocks above which the full signal to the 2396 * LB port is de-asserted. 2397 */ 2398 REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD, 2399 e3b0_val.full_lb_xon_threshold); 2400 /** 2401 * The number of blocks guarantied for the MAC #n port. n=0,1 2402 */ 2403 2404 /*The number of blocks guarantied for the LB port.*/ 2405 REG_WR(bp, BRB1_REG_LB_GUARANTIED, 2406 e3b0_val.lb_guarantied); 2407 2408 /** 2409 * The number of blocks guarantied for the MAC #n port. 2410 */ 2411 REG_WR(bp, BRB1_REG_MAC_GUARANTIED_0, 2412 2 * e3b0_val.mac_0_class_t_guarantied); 2413 REG_WR(bp, BRB1_REG_MAC_GUARANTIED_1, 2414 2 * e3b0_val.mac_1_class_t_guarantied); 2415 /** 2416 * The number of blocks guarantied for class #t in MAC0. t=0,1 2417 */ 2418 REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED, 2419 e3b0_val.mac_0_class_t_guarantied); 2420 REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED, 2421 e3b0_val.mac_0_class_t_guarantied); 2422 /** 2423 * The hysteresis on the guarantied buffer space for class in 2424 * MAC0. t=0,1 2425 */ 2426 REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED_HYST, 2427 e3b0_val.mac_0_class_t_guarantied_hyst); 2428 REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED_HYST, 2429 e3b0_val.mac_0_class_t_guarantied_hyst); 2430 2431 /** 2432 * The number of blocks guarantied for class #t in MAC1.t=0,1 2433 */ 2434 REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED, 2435 e3b0_val.mac_1_class_t_guarantied); 2436 REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED, 2437 e3b0_val.mac_1_class_t_guarantied); 2438 /** 2439 * The hysteresis on the guarantied buffer space for class #t 2440 * in MAC1. t=0,1 2441 */ 2442 REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED_HYST, 2443 e3b0_val.mac_1_class_t_guarantied_hyst); 2444 REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED_HYST, 2445 e3b0_val.mac_1_class_t_guarantied_hyst); 2446 2447 } 2448 2449 return bnx2x_status; 2450} 2451 2452/****************************************************************************** 2453* Description: 2454* This function is needed because NIG ARB_CREDIT_WEIGHT_X are 2455* not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable. 2456******************************************************************************/ 2457int bnx2x_pfc_nig_rx_priority_mask(struct bnx2x *bp, 2458 u8 cos_entry, 2459 u32 priority_mask, u8 port) 2460{ 2461 u32 nig_reg_rx_priority_mask_add = 0; 2462 2463 switch (cos_entry) { 2464 case 0: 2465 nig_reg_rx_priority_mask_add = (port) ? 2466 NIG_REG_P1_RX_COS0_PRIORITY_MASK : 2467 NIG_REG_P0_RX_COS0_PRIORITY_MASK; 2468 break; 2469 case 1: 2470 nig_reg_rx_priority_mask_add = (port) ? 2471 NIG_REG_P1_RX_COS1_PRIORITY_MASK : 2472 NIG_REG_P0_RX_COS1_PRIORITY_MASK; 2473 break; 2474 case 2: 2475 nig_reg_rx_priority_mask_add = (port) ? 2476 NIG_REG_P1_RX_COS2_PRIORITY_MASK : 2477 NIG_REG_P0_RX_COS2_PRIORITY_MASK; 2478 break; 2479 case 3: 2480 if (port) 2481 return -EINVAL; 2482 nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK; 2483 break; 2484 case 4: 2485 if (port) 2486 return -EINVAL; 2487 nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK; 2488 break; 2489 case 5: 2490 if (port) 2491 return -EINVAL; 2492 nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK; 2493 break; 2494 } 2495 2496 REG_WR(bp, nig_reg_rx_priority_mask_add, priority_mask); 2497 2498 return 0; 2499} 2500static void bnx2x_update_mng(struct link_params *params, u32 link_status) 2501{ 2502 struct bnx2x *bp = params->bp; 2503 2504 REG_WR(bp, params->shmem_base + 2505 offsetof(struct shmem_region, 2506 port_mb[params->port].link_status), link_status); 2507} 2508 2509static void bnx2x_update_pfc_nig(struct link_params *params, 2510 struct link_vars *vars, 2511 struct bnx2x_nig_brb_pfc_port_params *nig_params) 2512{ 2513 u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0; 2514 u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0; 2515 u32 pkt_priority_to_cos = 0; 2516 struct bnx2x *bp = params->bp; 2517 u8 port = params->port; 2518 2519 int set_pfc = params->feature_config_flags & 2520 FEATURE_CONFIG_PFC_ENABLED; 2521 DP(NETIF_MSG_LINK, "updating pfc nig parameters\n"); 2522 2523 /* 2524 * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set 2525 * MAC control frames (that are not pause packets) 2526 * will be forwarded to the XCM. 2527 */ 2528 xcm_mask = REG_RD(bp, 2529 port ? NIG_REG_LLH1_XCM_MASK : 2530 NIG_REG_LLH0_XCM_MASK); 2531 /* 2532 * nig params will override non PFC params, since it's possible to 2533 * do transition from PFC to SAFC 2534 */ 2535 if (set_pfc) { 2536 pause_enable = 0; 2537 llfc_out_en = 0; 2538 llfc_enable = 0; 2539 if (CHIP_IS_E3(bp)) 2540 ppp_enable = 0; 2541 else 2542 ppp_enable = 1; 2543 xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN : 2544 NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN); 2545 xcm0_out_en = 0; 2546 p0_hwpfc_enable = 1; 2547 } else { 2548 if (nig_params) { 2549 llfc_out_en = nig_params->llfc_out_en; 2550 llfc_enable = nig_params->llfc_enable; 2551 pause_enable = nig_params->pause_enable; 2552 } else /*defaul non PFC mode - PAUSE */ 2553 pause_enable = 1; 2554 2555 xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN : 2556 NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN); 2557 xcm0_out_en = 1; 2558 } 2559 2560 if (CHIP_IS_E3(bp)) 2561 REG_WR(bp, port ? NIG_REG_BRB1_PAUSE_IN_EN : 2562 NIG_REG_BRB0_PAUSE_IN_EN, pause_enable); 2563 REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 : 2564 NIG_REG_LLFC_OUT_EN_0, llfc_out_en); 2565 REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 : 2566 NIG_REG_LLFC_ENABLE_0, llfc_enable); 2567 REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 : 2568 NIG_REG_PAUSE_ENABLE_0, pause_enable); 2569 2570 REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 : 2571 NIG_REG_PPP_ENABLE_0, ppp_enable); 2572 2573 REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK : 2574 NIG_REG_LLH0_XCM_MASK, xcm_mask); 2575 2576 REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7); 2577 2578 /* output enable for RX_XCM # IF */ 2579 REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en); 2580 2581 /* HW PFC TX enable */ 2582 REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable); 2583 2584 if (nig_params) { 2585 u8 i = 0; 2586 pkt_priority_to_cos = nig_params->pkt_priority_to_cos; 2587 2588 for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++) 2589 bnx2x_pfc_nig_rx_priority_mask(bp, i, 2590 nig_params->rx_cos_priority_mask[i], port); 2591 2592 REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 : 2593 NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0, 2594 nig_params->llfc_high_priority_classes); 2595 2596 REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 : 2597 NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0, 2598 nig_params->llfc_low_priority_classes); 2599 } 2600 REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS : 2601 NIG_REG_P0_PKT_PRIORITY_TO_COS, 2602 pkt_priority_to_cos); 2603} 2604 2605int bnx2x_update_pfc(struct link_params *params, 2606 struct link_vars *vars, 2607 struct bnx2x_nig_brb_pfc_port_params *pfc_params) 2608{ 2609 /* 2610 * The PFC and pause are orthogonal to one another, meaning when 2611 * PFC is enabled, the pause are disabled, and when PFC is 2612 * disabled, pause are set according to the pause result. 2613 */ 2614 u32 val; 2615 struct bnx2x *bp = params->bp; 2616 int bnx2x_status = 0; 2617 u8 bmac_loopback = (params->loopback_mode == LOOPBACK_BMAC); 2618 2619 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) 2620 vars->link_status |= LINK_STATUS_PFC_ENABLED; 2621 else 2622 vars->link_status &= ~LINK_STATUS_PFC_ENABLED; 2623 2624 bnx2x_update_mng(params, vars->link_status); 2625 2626 /* update NIG params */ 2627 bnx2x_update_pfc_nig(params, vars, pfc_params); 2628 2629 /* update BRB params */ 2630 bnx2x_status = bnx2x_update_pfc_brb(params, vars, pfc_params); 2631 if (0 != bnx2x_status) 2632 return bnx2x_status; 2633 2634 if (!vars->link_up) 2635 return bnx2x_status; 2636 2637 DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n"); 2638 if (CHIP_IS_E3(bp)) 2639 bnx2x_update_pfc_xmac(params, vars, 0); 2640 else { 2641 val = REG_RD(bp, MISC_REG_RESET_REG_2); 2642 if ((val & 2643 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) 2644 == 0) { 2645 DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n"); 2646 bnx2x_emac_enable(params, vars, 0); 2647 return bnx2x_status; 2648 } 2649 2650 if (CHIP_IS_E2(bp)) 2651 bnx2x_update_pfc_bmac2(params, vars, bmac_loopback); 2652 else 2653 bnx2x_update_pfc_bmac1(params, vars); 2654 2655 val = 0; 2656 if ((params->feature_config_flags & 2657 FEATURE_CONFIG_PFC_ENABLED) || 2658 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) 2659 val = 1; 2660 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val); 2661 } 2662 return bnx2x_status; 2663} 2664 2665 2666static int bnx2x_bmac1_enable(struct link_params *params, 2667 struct link_vars *vars, 2668 u8 is_lb) 2669{ 2670 struct bnx2x *bp = params->bp; 2671 u8 port = params->port; 2672 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM : 2673 NIG_REG_INGRESS_BMAC0_MEM; 2674 u32 wb_data[2]; 2675 u32 val; 2676 2677 DP(NETIF_MSG_LINK, "Enabling BigMAC1\n"); 2678 2679 /* XGXS control */ 2680 wb_data[0] = 0x3c; 2681 wb_data[1] = 0; 2682 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL, 2683 wb_data, 2); 2684 2685 /* tx MAC SA */ 2686 wb_data[0] = ((params->mac_addr[2] << 24) | 2687 (params->mac_addr[3] << 16) | 2688 (params->mac_addr[4] << 8) | 2689 params->mac_addr[5]); 2690 wb_data[1] = ((params->mac_addr[0] << 8) | 2691 params->mac_addr[1]); 2692 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2); 2693 2694 /* mac control */ 2695 val = 0x3; 2696 if (is_lb) { 2697 val |= 0x4; 2698 DP(NETIF_MSG_LINK, "enable bmac loopback\n"); 2699 } 2700 wb_data[0] = val; 2701 wb_data[1] = 0; 2702 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2); 2703 2704 /* set rx mtu */ 2705 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; 2706 wb_data[1] = 0; 2707 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2); 2708 2709 bnx2x_update_pfc_bmac1(params, vars); 2710 2711 /* set tx mtu */ 2712 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; 2713 wb_data[1] = 0; 2714 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2); 2715 2716 /* set cnt max size */ 2717 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; 2718 wb_data[1] = 0; 2719 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2); 2720 2721 /* configure safc */ 2722 wb_data[0] = 0x1000200; 2723 wb_data[1] = 0; 2724 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS, 2725 wb_data, 2); 2726 2727 return 0; 2728} 2729 2730static int bnx2x_bmac2_enable(struct link_params *params, 2731 struct link_vars *vars, 2732 u8 is_lb) 2733{ 2734 struct bnx2x *bp = params->bp; 2735 u8 port = params->port; 2736 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM : 2737 NIG_REG_INGRESS_BMAC0_MEM; 2738 u32 wb_data[2]; 2739 2740 DP(NETIF_MSG_LINK, "Enabling BigMAC2\n"); 2741 2742 wb_data[0] = 0; 2743 wb_data[1] = 0; 2744 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2); 2745 udelay(30); 2746 2747 /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */ 2748 wb_data[0] = 0x3c; 2749 wb_data[1] = 0; 2750 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL, 2751 wb_data, 2); 2752 2753 udelay(30); 2754 2755 /* tx MAC SA */ 2756 wb_data[0] = ((params->mac_addr[2] << 24) | 2757 (params->mac_addr[3] << 16) | 2758 (params->mac_addr[4] << 8) | 2759 params->mac_addr[5]); 2760 wb_data[1] = ((params->mac_addr[0] << 8) | 2761 params->mac_addr[1]); 2762 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR, 2763 wb_data, 2); 2764 2765 udelay(30); 2766 2767 /* Configure SAFC */ 2768 wb_data[0] = 0x1000200; 2769 wb_data[1] = 0; 2770 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS, 2771 wb_data, 2); 2772 udelay(30); 2773 2774 /* set rx mtu */ 2775 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; 2776 wb_data[1] = 0; 2777 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2); 2778 udelay(30); 2779 2780 /* set tx mtu */ 2781 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; 2782 wb_data[1] = 0; 2783 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2); 2784 udelay(30); 2785 /* set cnt max size */ 2786 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2; 2787 wb_data[1] = 0; 2788 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2); 2789 udelay(30); 2790 bnx2x_update_pfc_bmac2(params, vars, is_lb); 2791 2792 return 0; 2793} 2794 2795static int bnx2x_bmac_enable(struct link_params *params, 2796 struct link_vars *vars, 2797 u8 is_lb) 2798{ 2799 int rc = 0; 2800 u8 port = params->port; 2801 struct bnx2x *bp = params->bp; 2802 u32 val; 2803 /* reset and unreset the BigMac */ 2804 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 2805 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); 2806 msleep(1); 2807 2808 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 2809 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); 2810 2811 /* enable access for bmac registers */ 2812 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1); 2813 2814 /* Enable BMAC according to BMAC type*/ 2815 if (CHIP_IS_E2(bp)) 2816 rc = bnx2x_bmac2_enable(params, vars, is_lb); 2817 else 2818 rc = bnx2x_bmac1_enable(params, vars, is_lb); 2819 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1); 2820 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0); 2821 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0); 2822 val = 0; 2823 if ((params->feature_config_flags & 2824 FEATURE_CONFIG_PFC_ENABLED) || 2825 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) 2826 val = 1; 2827 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val); 2828 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0); 2829 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0); 2830 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0); 2831 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1); 2832 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1); 2833 2834 vars->mac_type = MAC_TYPE_BMAC; 2835 return rc; 2836} 2837 2838static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port) 2839{ 2840 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM : 2841 NIG_REG_INGRESS_BMAC0_MEM; 2842 u32 wb_data[2]; 2843 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4); 2844 2845 /* Only if the bmac is out of reset */ 2846 if (REG_RD(bp, MISC_REG_RESET_REG_2) & 2847 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) && 2848 nig_bmac_enable) { 2849 2850 if (CHIP_IS_E2(bp)) { 2851 /* Clear Rx Enable bit in BMAC_CONTROL register */ 2852 REG_RD_DMAE(bp, bmac_addr + 2853 BIGMAC2_REGISTER_BMAC_CONTROL, 2854 wb_data, 2); 2855 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; 2856 REG_WR_DMAE(bp, bmac_addr + 2857 BIGMAC2_REGISTER_BMAC_CONTROL, 2858 wb_data, 2); 2859 } else { 2860 /* Clear Rx Enable bit in BMAC_CONTROL register */ 2861 REG_RD_DMAE(bp, bmac_addr + 2862 BIGMAC_REGISTER_BMAC_CONTROL, 2863 wb_data, 2); 2864 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; 2865 REG_WR_DMAE(bp, bmac_addr + 2866 BIGMAC_REGISTER_BMAC_CONTROL, 2867 wb_data, 2); 2868 } 2869 msleep(1); 2870 } 2871} 2872 2873static int bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, 2874 u32 line_speed) 2875{ 2876 struct bnx2x *bp = params->bp; 2877 u8 port = params->port; 2878 u32 init_crd, crd; 2879 u32 count = 1000; 2880 2881 /* disable port */ 2882 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1); 2883 2884 /* wait for init credit */ 2885 init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4); 2886 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8); 2887 DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd); 2888 2889 while ((init_crd != crd) && count) { 2890 msleep(5); 2891 2892 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8); 2893 count--; 2894 } 2895 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8); 2896 if (init_crd != crd) { 2897 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n", 2898 init_crd, crd); 2899 return -EINVAL; 2900 } 2901 2902 if (flow_ctrl & BNX2X_FLOW_CTRL_RX || 2903 line_speed == SPEED_10 || 2904 line_speed == SPEED_100 || 2905 line_speed == SPEED_1000 || 2906 line_speed == SPEED_2500) { 2907 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1); 2908 /* update threshold */ 2909 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0); 2910 /* update init credit */ 2911 init_crd = 778; /* (800-18-4) */ 2912 2913 } else { 2914 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE + 2915 ETH_OVREHEAD)/16; 2916 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0); 2917 /* update threshold */ 2918 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh); 2919 /* update init credit */ 2920 switch (line_speed) { 2921 case SPEED_10000: 2922 init_crd = thresh + 553 - 22; 2923 break; 2924 default: 2925 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", 2926 line_speed); 2927 return -EINVAL; 2928 } 2929 } 2930 REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd); 2931 DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n", 2932 line_speed, init_crd); 2933 2934 /* probe the credit changes */ 2935 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1); 2936 msleep(5); 2937 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0); 2938 2939 /* enable port */ 2940 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0); 2941 return 0; 2942} 2943 2944/** 2945 * bnx2x_get_emac_base - retrive emac base address 2946 * 2947 * @bp: driver handle 2948 * @mdc_mdio_access: access type 2949 * @port: port id 2950 * 2951 * This function selects the MDC/MDIO access (through emac0 or 2952 * emac1) depend on the mdc_mdio_access, port, port swapped. Each 2953 * phy has a default access mode, which could also be overridden 2954 * by nvram configuration. This parameter, whether this is the 2955 * default phy configuration, or the nvram overrun 2956 * configuration, is passed here as mdc_mdio_access and selects 2957 * the emac_base for the CL45 read/writes operations 2958 */ 2959static u32 bnx2x_get_emac_base(struct bnx2x *bp, 2960 u32 mdc_mdio_access, u8 port) 2961{ 2962 u32 emac_base = 0; 2963 switch (mdc_mdio_access) { 2964 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE: 2965 break; 2966 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0: 2967 if (REG_RD(bp, NIG_REG_PORT_SWAP)) 2968 emac_base = GRCBASE_EMAC1; 2969 else 2970 emac_base = GRCBASE_EMAC0; 2971 break; 2972 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1: 2973 if (REG_RD(bp, NIG_REG_PORT_SWAP)) 2974 emac_base = GRCBASE_EMAC0; 2975 else 2976 emac_base = GRCBASE_EMAC1; 2977 break; 2978 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH: 2979 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; 2980 break; 2981 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED: 2982 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1; 2983 break; 2984 default: 2985 break; 2986 } 2987 return emac_base; 2988 2989} 2990 2991/******************************************************************/ 2992/* CL22 access functions */ 2993/******************************************************************/ 2994static int bnx2x_cl22_write(struct bnx2x *bp, 2995 struct bnx2x_phy *phy, 2996 u16 reg, u16 val) 2997{ 2998 u32 tmp, mode; 2999 u8 i; 3000 int rc = 0; 3001 /* Switch to CL22 */ 3002 mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); 3003 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, 3004 mode & ~EMAC_MDIO_MODE_CLAUSE_45); 3005 3006 /* address */ 3007 tmp = ((phy->addr << 21) | (reg << 16) | val | 3008 EMAC_MDIO_COMM_COMMAND_WRITE_22 | 3009 EMAC_MDIO_COMM_START_BUSY); 3010 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); 3011 3012 for (i = 0; i < 50; i++) { 3013 udelay(10); 3014 3015 tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); 3016 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { 3017 udelay(5); 3018 break; 3019 } 3020 } 3021 if (tmp & EMAC_MDIO_COMM_START_BUSY) { 3022 DP(NETIF_MSG_LINK, "write phy register failed\n"); 3023 rc = -EFAULT; 3024 } 3025 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode); 3026 return rc; 3027} 3028 3029static int bnx2x_cl22_read(struct bnx2x *bp, 3030 struct bnx2x_phy *phy, 3031 u16 reg, u16 *ret_val) 3032{ 3033 u32 val, mode; 3034 u16 i; 3035 int rc = 0; 3036 3037 /* Switch to CL22 */ 3038 mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); 3039 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, 3040 mode & ~EMAC_MDIO_MODE_CLAUSE_45); 3041 3042 /* address */ 3043 val = ((phy->addr << 21) | (reg << 16) | 3044 EMAC_MDIO_COMM_COMMAND_READ_22 | 3045 EMAC_MDIO_COMM_START_BUSY); 3046 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); 3047 3048 for (i = 0; i < 50; i++) { 3049 udelay(10); 3050 3051 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); 3052 if (!(val & EMAC_MDIO_COMM_START_BUSY)) { 3053 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA); 3054 udelay(5); 3055 break; 3056 } 3057 } 3058 if (val & EMAC_MDIO_COMM_START_BUSY) { 3059 DP(NETIF_MSG_LINK, "read phy register failed\n"); 3060 3061 *ret_val = 0; 3062 rc = -EFAULT; 3063 } 3064 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode); 3065 return rc; 3066} 3067 3068/******************************************************************/ 3069/* CL45 access functions */ 3070/******************************************************************/ 3071static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, 3072 u8 devad, u16 reg, u16 *ret_val) 3073{ 3074 u32 val; 3075 u16 i; 3076 int rc = 0; 3077 if (phy->flags & FLAGS_MDC_MDIO_WA_B0) 3078 bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS, 3079 EMAC_MDIO_STATUS_10MB); 3080 /* address */ 3081 val = ((phy->addr << 21) | (devad << 16) | reg | 3082 EMAC_MDIO_COMM_COMMAND_ADDRESS | 3083 EMAC_MDIO_COMM_START_BUSY); 3084 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); 3085 3086 for (i = 0; i < 50; i++) { 3087 udelay(10); 3088 3089 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); 3090 if (!(val & EMAC_MDIO_COMM_START_BUSY)) { 3091 udelay(5); 3092 break; 3093 } 3094 } 3095 if (val & EMAC_MDIO_COMM_START_BUSY) { 3096 DP(NETIF_MSG_LINK, "read phy register failed\n"); 3097 netdev_err(bp->dev, "MDC/MDIO access timeout\n"); 3098 *ret_val = 0; 3099 rc = -EFAULT; 3100 } else { 3101 /* data */ 3102 val = ((phy->addr << 21) | (devad << 16) | 3103 EMAC_MDIO_COMM_COMMAND_READ_45 | 3104 EMAC_MDIO_COMM_START_BUSY); 3105 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); 3106 3107 for (i = 0; i < 50; i++) { 3108 udelay(10); 3109 3110 val = REG_RD(bp, phy->mdio_ctrl + 3111 EMAC_REG_EMAC_MDIO_COMM); 3112 if (!(val & EMAC_MDIO_COMM_START_BUSY)) { 3113 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA); 3114 break; 3115 } 3116 } 3117 if (val & EMAC_MDIO_COMM_START_BUSY) { 3118 DP(NETIF_MSG_LINK, "read phy register failed\n"); 3119 netdev_err(bp->dev, "MDC/MDIO access timeout\n"); 3120 *ret_val = 0; 3121 rc = -EFAULT; 3122 } 3123 } 3124 /* Work around for E3 A0 */ 3125 if (phy->flags & FLAGS_MDC_MDIO_WA) { 3126 phy->flags ^= FLAGS_DUMMY_READ; 3127 if (phy->flags & FLAGS_DUMMY_READ) { 3128 u16 temp_val; 3129 bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val); 3130 } 3131 } 3132 3133 if (phy->flags & FLAGS_MDC_MDIO_WA_B0) 3134 bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS, 3135 EMAC_MDIO_STATUS_10MB); 3136 return rc; 3137} 3138 3139static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, 3140 u8 devad, u16 reg, u16 val) 3141{ 3142 u32 tmp; 3143 u8 i; 3144 int rc = 0; 3145 if (phy->flags & FLAGS_MDC_MDIO_WA_B0) 3146 bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS, 3147 EMAC_MDIO_STATUS_10MB); 3148 3149 /* address */ 3150 3151 tmp = ((phy->addr << 21) | (devad << 16) | reg | 3152 EMAC_MDIO_COMM_COMMAND_ADDRESS | 3153 EMAC_MDIO_COMM_START_BUSY); 3154 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); 3155 3156 for (i = 0; i < 50; i++) { 3157 udelay(10); 3158 3159 tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); 3160 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { 3161 udelay(5); 3162 break; 3163 } 3164 } 3165 if (tmp & EMAC_MDIO_COMM_START_BUSY) { 3166 DP(NETIF_MSG_LINK, "write phy register failed\n"); 3167 netdev_err(bp->dev, "MDC/MDIO access timeout\n"); 3168 rc = -EFAULT; 3169 3170 } else { 3171 /* data */ 3172 tmp = ((phy->addr << 21) | (devad << 16) | val | 3173 EMAC_MDIO_COMM_COMMAND_WRITE_45 | 3174 EMAC_MDIO_COMM_START_BUSY); 3175 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); 3176 3177 for (i = 0; i < 50; i++) { 3178 udelay(10); 3179 3180 tmp = REG_RD(bp, phy->mdio_ctrl + 3181 EMAC_REG_EMAC_MDIO_COMM); 3182 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { 3183 udelay(5); 3184 break; 3185 } 3186 } 3187 if (tmp & EMAC_MDIO_COMM_START_BUSY) { 3188 DP(NETIF_MSG_LINK, "write phy register failed\n"); 3189 netdev_err(bp->dev, "MDC/MDIO access timeout\n"); 3190 rc = -EFAULT; 3191 } 3192 } 3193 /* Work around for E3 A0 */ 3194 if (phy->flags & FLAGS_MDC_MDIO_WA) { 3195 phy->flags ^= FLAGS_DUMMY_READ; 3196 if (phy->flags & FLAGS_DUMMY_READ) { 3197 u16 temp_val; 3198 bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val); 3199 } 3200 } 3201 if (phy->flags & FLAGS_MDC_MDIO_WA_B0) 3202 bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS, 3203 EMAC_MDIO_STATUS_10MB); 3204 return rc; 3205} 3206 3207 3208/******************************************************************/ 3209/* BSC access functions from E3 */ 3210/******************************************************************/ 3211static void bnx2x_bsc_module_sel(struct link_params *params) 3212{ 3213 int idx; 3214 u32 board_cfg, sfp_ctrl; 3215 u32 i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH]; 3216 struct bnx2x *bp = params->bp; 3217 u8 port = params->port; 3218 /* Read I2C output PINs */ 3219 board_cfg = REG_RD(bp, params->shmem_base + 3220 offsetof(struct shmem_region, 3221 dev_info.shared_hw_config.board)); 3222 i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK; 3223 i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >> 3224 SHARED_HW_CFG_E3_I2C_MUX1_SHIFT; 3225 3226 /* Read I2C output value */ 3227 sfp_ctrl = REG_RD(bp, params->shmem_base + 3228 offsetof(struct shmem_region, 3229 dev_info.port_hw_config[port].e3_cmn_pin_cfg)); 3230 i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0; 3231 i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0; 3232 DP(NETIF_MSG_LINK, "Setting BSC switch\n"); 3233 for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++) 3234 bnx2x_set_cfg_pin(bp, i2c_pins[idx], i2c_val[idx]); 3235} 3236 3237static int bnx2x_bsc_read(struct link_params *params, 3238 struct bnx2x_phy *phy, 3239 u8 sl_devid, 3240 u16 sl_addr, 3241 u8 lc_addr, 3242 u8 xfer_cnt, 3243 u32 *data_array) 3244{ 3245 u32 val, i; 3246 int rc = 0; 3247 struct bnx2x *bp = params->bp; 3248 3249 if ((sl_devid != 0xa0) && (sl_devid != 0xa2)) { 3250 DP(NETIF_MSG_LINK, "invalid sl_devid 0x%x\n", sl_devid); 3251 return -EINVAL; 3252 } 3253 3254 if (xfer_cnt > 16) { 3255 DP(NETIF_MSG_LINK, "invalid xfer_cnt %d. Max is 16 bytes\n", 3256 xfer_cnt); 3257 return -EINVAL; 3258 } 3259 bnx2x_bsc_module_sel(params); 3260 3261 xfer_cnt = 16 - lc_addr; 3262 3263 /* enable the engine */ 3264 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); 3265 val |= MCPR_IMC_COMMAND_ENABLE; 3266 REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val); 3267 3268 /* program slave device ID */ 3269 val = (sl_devid << 16) | sl_addr; 3270 REG_WR(bp, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val); 3271 3272 /* start xfer with 0 byte to update the address pointer ???*/ 3273 val = (MCPR_IMC_COMMAND_ENABLE) | 3274 (MCPR_IMC_COMMAND_WRITE_OP << 3275 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) | 3276 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0); 3277 REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val); 3278 3279 /* poll for completion */ 3280 i = 0; 3281 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); 3282 while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) { 3283 udelay(10); 3284 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); 3285 if (i++ > 1000) { 3286 DP(NETIF_MSG_LINK, "wr 0 byte timed out after %d try\n", 3287 i); 3288 rc = -EFAULT; 3289 break; 3290 } 3291 } 3292 if (rc == -EFAULT) 3293 return rc; 3294 3295 /* start xfer with read op */ 3296 val = (MCPR_IMC_COMMAND_ENABLE) | 3297 (MCPR_IMC_COMMAND_READ_OP << 3298 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) | 3299 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | 3300 (xfer_cnt); 3301 REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val); 3302 3303 /* poll for completion */ 3304 i = 0; 3305 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); 3306 while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) { 3307 udelay(10); 3308 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); 3309 if (i++ > 1000) { 3310 DP(NETIF_MSG_LINK, "rd op timed out after %d try\n", i); 3311 rc = -EFAULT; 3312 break; 3313 } 3314 } 3315 if (rc == -EFAULT) 3316 return rc; 3317 3318 for (i = (lc_addr >> 2); i < 4; i++) { 3319 data_array[i] = REG_RD(bp, (MCP_REG_MCPR_IMC_DATAREG0 + i*4)); 3320#ifdef __BIG_ENDIAN 3321 data_array[i] = ((data_array[i] & 0x000000ff) << 24) | 3322 ((data_array[i] & 0x0000ff00) << 8) | 3323 ((data_array[i] & 0x00ff0000) >> 8) | 3324 ((data_array[i] & 0xff000000) >> 24); 3325#endif 3326 } 3327 return rc; 3328} 3329 3330static void bnx2x_cl45_read_or_write(struct bnx2x *bp, struct bnx2x_phy *phy, 3331 u8 devad, u16 reg, u16 or_val) 3332{ 3333 u16 val; 3334 bnx2x_cl45_read(bp, phy, devad, reg, &val); 3335 bnx2x_cl45_write(bp, phy, devad, reg, val | or_val); 3336} 3337 3338int bnx2x_phy_read(struct link_params *params, u8 phy_addr, 3339 u8 devad, u16 reg, u16 *ret_val) 3340{ 3341 u8 phy_index; 3342 /* 3343 * Probe for the phy according to the given phy_addr, and execute 3344 * the read request on it 3345 */ 3346 for (phy_index = 0; phy_index < params->num_phys; phy_index++) { 3347 if (params->phy[phy_index].addr == phy_addr) { 3348 return bnx2x_cl45_read(params->bp, 3349 ¶ms->phy[phy_index], devad, 3350 reg, ret_val); 3351 } 3352 } 3353 return -EINVAL; 3354} 3355 3356int bnx2x_phy_write(struct link_params *params, u8 phy_addr, 3357 u8 devad, u16 reg, u16 val) 3358{ 3359 u8 phy_index; 3360 /* 3361 * Probe for the phy according to the given phy_addr, and execute 3362 * the write request on it 3363 */ 3364 for (phy_index = 0; phy_index < params->num_phys; phy_index++) { 3365 if (params->phy[phy_index].addr == phy_addr) { 3366 return bnx2x_cl45_write(params->bp, 3367 ¶ms->phy[phy_index], devad, 3368 reg, val); 3369 } 3370 } 3371 return -EINVAL; 3372} 3373static u8 bnx2x_get_warpcore_lane(struct bnx2x_phy *phy, 3374 struct link_params *params) 3375{ 3376 u8 lane = 0; 3377 struct bnx2x *bp = params->bp; 3378 u32 path_swap, path_swap_ovr; 3379 u8 path, port; 3380 3381 path = BP_PATH(bp); 3382 port = params->port; 3383 3384 if (bnx2x_is_4_port_mode(bp)) { 3385 u32 port_swap, port_swap_ovr; 3386 3387 /*figure out path swap value */ 3388 path_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR); 3389 if (path_swap_ovr & 0x1) 3390 path_swap = (path_swap_ovr & 0x2); 3391 else 3392 path_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP); 3393 3394 if (path_swap) 3395 path = path ^ 1; 3396 3397 /*figure out port swap value */ 3398 port_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR); 3399 if (port_swap_ovr & 0x1) 3400 port_swap = (port_swap_ovr & 0x2); 3401 else 3402 port_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP); 3403 3404 if (port_swap) 3405 port = port ^ 1; 3406 3407 lane = (port<<1) + path; 3408 } else { /* two port mode - no port swap */ 3409 3410 /*figure out path swap value */ 3411 path_swap_ovr = 3412 REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP_OVWR); 3413 if (path_swap_ovr & 0x1) { 3414 path_swap = (path_swap_ovr & 0x2); 3415 } else { 3416 path_swap = 3417 REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP); 3418 } 3419 if (path_swap) 3420 path = path ^ 1; 3421 3422 lane = path << 1 ; 3423 } 3424 return lane; 3425} 3426 3427static void bnx2x_set_aer_mmd(struct link_params *params, 3428 struct bnx2x_phy *phy) 3429{ 3430 u32 ser_lane; 3431 u16 offset, aer_val; 3432 struct bnx2x *bp = params->bp; 3433 ser_lane = ((params->lane_config & 3434 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> 3435 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); 3436 3437 offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ? 3438 (phy->addr + ser_lane) : 0; 3439 3440 if (USES_WARPCORE(bp)) { 3441 aer_val = bnx2x_get_warpcore_lane(phy, params); 3442 /* 3443 * In Dual-lane mode, two lanes are joined together, 3444 * so in order to configure them, the AER broadcast method is 3445 * used here. 3446 * 0x200 is the broadcast address for lanes 0,1 3447 * 0x201 is the broadcast address for lanes 2,3 3448 */ 3449 if (phy->flags & FLAGS_WC_DUAL_MODE) 3450 aer_val = (aer_val >> 1) | 0x200; 3451 } else if (CHIP_IS_E2(bp)) 3452 aer_val = 0x3800 + offset - 1; 3453 else 3454 aer_val = 0x3800 + offset; 3455 DP(NETIF_MSG_LINK, "Set AER to 0x%x\n", aer_val); 3456 CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, 3457 MDIO_AER_BLOCK_AER_REG, aer_val); 3458 3459} 3460 3461/******************************************************************/ 3462/* Internal phy section */ 3463/******************************************************************/ 3464 3465static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port) 3466{ 3467 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; 3468 3469 /* Set Clause 22 */ 3470 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1); 3471 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000); 3472 udelay(500); 3473 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f); 3474 udelay(500); 3475 /* Set Clause 45 */ 3476 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0); 3477} 3478 3479static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port) 3480{ 3481 u32 val; 3482 3483 DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n"); 3484 3485 val = SERDES_RESET_BITS << (port*16); 3486 3487 /* reset and unreset the SerDes/XGXS */ 3488 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); 3489 udelay(500); 3490 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); 3491 3492 bnx2x_set_serdes_access(bp, port); 3493 3494 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + port*0x10, 3495 DEFAULT_PHY_DEV_ADDR); 3496} 3497 3498static void bnx2x_xgxs_deassert(struct link_params *params) 3499{ 3500 struct bnx2x *bp = params->bp; 3501 u8 port; 3502 u32 val; 3503 DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n"); 3504 port = params->port; 3505 3506 val = XGXS_RESET_BITS << (port*16); 3507 3508 /* reset and unreset the SerDes/XGXS */ 3509 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); 3510 udelay(500); 3511 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); 3512 3513 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0); 3514 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 3515 params->phy[INT_PHY].def_md_devad); 3516} 3517 3518static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, 3519 struct link_params *params, u16 *ieee_fc) 3520{ 3521 struct bnx2x *bp = params->bp; 3522 *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX; 3523 /** 3524 * resolve pause mode and advertisement Please refer to Table 3525 * 28B-3 of the 802.3ab-1999 spec 3526 */ 3527 3528 switch (phy->req_flow_ctrl) { 3529 case BNX2X_FLOW_CTRL_AUTO: 3530 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) 3531 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; 3532 else 3533 *ieee_fc |= 3534 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; 3535 break; 3536 3537 case BNX2X_FLOW_CTRL_TX: 3538 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; 3539 break; 3540 3541 case BNX2X_FLOW_CTRL_RX: 3542 case BNX2X_FLOW_CTRL_BOTH: 3543 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; 3544 break; 3545 3546 case BNX2X_FLOW_CTRL_NONE: 3547 default: 3548 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; 3549 break; 3550 } 3551 DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc); 3552} 3553 3554static void set_phy_vars(struct link_params *params, 3555 struct link_vars *vars) 3556{ 3557 struct bnx2x *bp = params->bp; 3558 u8 actual_phy_idx, phy_index, link_cfg_idx; 3559 u8 phy_config_swapped = params->multi_phy_config & 3560 PORT_HW_CFG_PHY_SWAPPED_ENABLED; 3561 for (phy_index = INT_PHY; phy_index < params->num_phys; 3562 phy_index++) { 3563 link_cfg_idx = LINK_CONFIG_IDX(phy_index); 3564 actual_phy_idx = phy_index; 3565 if (phy_config_swapped) { 3566 if (phy_index == EXT_PHY1) 3567 actual_phy_idx = EXT_PHY2; 3568 else if (phy_index == EXT_PHY2) 3569 actual_phy_idx = EXT_PHY1; 3570 } 3571 params->phy[actual_phy_idx].req_flow_ctrl = 3572 params->req_flow_ctrl[link_cfg_idx]; 3573 3574 params->phy[actual_phy_idx].req_line_speed = 3575 params->req_line_speed[link_cfg_idx]; 3576 3577 params->phy[actual_phy_idx].speed_cap_mask = 3578 params->speed_cap_mask[link_cfg_idx]; 3579 3580 params->phy[actual_phy_idx].req_duplex = 3581 params->req_duplex[link_cfg_idx]; 3582 3583 if (params->req_line_speed[link_cfg_idx] == 3584 SPEED_AUTO_NEG) 3585 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED; 3586 3587 DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x," 3588 " speed_cap_mask %x\n", 3589 params->phy[actual_phy_idx].req_flow_ctrl, 3590 params->phy[actual_phy_idx].req_line_speed, 3591 params->phy[actual_phy_idx].speed_cap_mask); 3592 } 3593} 3594 3595static void bnx2x_ext_phy_set_pause(struct link_params *params, 3596 struct bnx2x_phy *phy, 3597 struct link_vars *vars) 3598{ 3599 u16 val; 3600 struct bnx2x *bp = params->bp; 3601 /* read modify write pause advertizing */ 3602 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val); 3603 3604 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH; 3605 3606 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ 3607 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); 3608 if ((vars->ieee_fc & 3609 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == 3610 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { 3611 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC; 3612 } 3613 if ((vars->ieee_fc & 3614 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == 3615 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) { 3616 val |= MDIO_AN_REG_ADV_PAUSE_PAUSE; 3617 } 3618 DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val); 3619 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val); 3620} 3621 3622static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result) 3623{ /* LD LP */ 3624 switch (pause_result) { /* ASYM P ASYM P */ 3625 case 0xb: /* 1 0 1 1 */ 3626 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX; 3627 break; 3628 3629 case 0xe: /* 1 1 1 0 */ 3630 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX; 3631 break; 3632 3633 case 0x5: /* 0 1 0 1 */ 3634 case 0x7: /* 0 1 1 1 */ 3635 case 0xd: /* 1 1 0 1 */ 3636 case 0xf: /* 1 1 1 1 */ 3637 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH; 3638 break; 3639 3640 default: 3641 break; 3642 } 3643 if (pause_result & (1<<0)) 3644 vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE; 3645 if (pause_result & (1<<1)) 3646 vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE; 3647} 3648 3649static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, 3650 struct link_params *params, 3651 struct link_vars *vars) 3652{ 3653 struct bnx2x *bp = params->bp; 3654 u16 ld_pause; /* local */ 3655 u16 lp_pause; /* link partner */ 3656 u16 pause_result; 3657 u8 ret = 0; 3658 /* read twice */ 3659 3660 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; 3661 3662 if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) 3663 vars->flow_ctrl = phy->req_flow_ctrl; 3664 else if (phy->req_line_speed != SPEED_AUTO_NEG) 3665 vars->flow_ctrl = params->req_fc_auto_adv; 3666 else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) { 3667 ret = 1; 3668 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) { 3669 bnx2x_cl22_read(bp, phy, 3670 0x4, &ld_pause); 3671 bnx2x_cl22_read(bp, phy, 3672 0x5, &lp_pause); 3673 } else { 3674 bnx2x_cl45_read(bp, phy, 3675 MDIO_AN_DEVAD, 3676 MDIO_AN_REG_ADV_PAUSE, &ld_pause); 3677 bnx2x_cl45_read(bp, phy, 3678 MDIO_AN_DEVAD, 3679 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause); 3680 } 3681 pause_result = (ld_pause & 3682 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8; 3683 pause_result |= (lp_pause & 3684 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10; 3685 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n", 3686 pause_result); 3687 bnx2x_pause_resolve(vars, pause_result); 3688 } 3689 return ret; 3690} 3691/******************************************************************/ 3692/* Warpcore section */ 3693/******************************************************************/ 3694/* The init_internal_warpcore should mirror the xgxs, 3695 * i.e. reset the lane (if needed), set aer for the 3696 * init configuration, and set/clear SGMII flag. Internal 3697 * phy init is done purely in phy_init stage. 3698 */ 3699static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, 3700 struct link_params *params, 3701 struct link_vars *vars) { 3702 u16 val16 = 0, lane, bam37 = 0; 3703 struct bnx2x *bp = params->bp; 3704 DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n"); 3705 3706 /* Disable Autoneg: re-enable it after adv is done. */ 3707 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, 3708 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0); 3709 3710 /* Check adding advertisement for 1G KX */ 3711 if (((vars->line_speed == SPEED_AUTO_NEG) && 3712 (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || 3713 (vars->line_speed == SPEED_1000)) { 3714 u16 sd_digital; 3715 val16 |= (1<<5); 3716 3717 /* Enable CL37 1G Parallel Detect */ 3718 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 3719 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &sd_digital); 3720 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3721 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 3722 (sd_digital | 0x1)); 3723 3724 DP(NETIF_MSG_LINK, "Advertize 1G\n"); 3725 } 3726 if (((vars->line_speed == SPEED_AUTO_NEG) && 3727 (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || 3728 (vars->line_speed == SPEED_10000)) { 3729 /* Check adding advertisement for 10G KR */ 3730 val16 |= (1<<7); 3731 /* Enable 10G Parallel Detect */ 3732 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, 3733 MDIO_WC_REG_PAR_DET_10G_CTRL, 1); 3734 3735 DP(NETIF_MSG_LINK, "Advertize 10G\n"); 3736 } 3737 3738 /* Set Transmit PMD settings */ 3739 lane = bnx2x_get_warpcore_lane(phy, params); 3740 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3741 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 3742 ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | 3743 (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | 3744 (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))); 3745 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3746 MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL, 3747 0x03f0); 3748 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3749 MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL, 3750 0x03f0); 3751 3752 /* Advertised speeds */ 3753 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, 3754 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16); 3755 3756 /* Advertised and set FEC (Forward Error Correction) */ 3757 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, 3758 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2, 3759 (MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY | 3760 MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ)); 3761 3762 /* Enable CL37 BAM */ 3763 if (REG_RD(bp, params->shmem_base + 3764 offsetof(struct shmem_region, dev_info. 3765 port_hw_config[params->port].default_cfg)) & 3766 PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) { 3767 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 3768 MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, &bam37); 3769 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3770 MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, bam37 | 1); 3771 DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n"); 3772 } 3773 3774 /* Advertise pause */ 3775 bnx2x_ext_phy_set_pause(params, phy, vars); 3776 3777 vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY; 3778 3779 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 3780 MDIO_WC_REG_DIGITAL5_MISC7, &val16); 3781 3782 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3783 MDIO_WC_REG_DIGITAL5_MISC7, val16 | 0x100); 3784 3785 /* Over 1G - AN local device user page 1 */ 3786 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3787 MDIO_WC_REG_DIGITAL3_UP1, 0x1f); 3788 3789 /* Enable Autoneg */ 3790 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, 3791 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1000); 3792 3793} 3794 3795static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, 3796 struct link_params *params, 3797 struct link_vars *vars) 3798{ 3799 struct bnx2x *bp = params->bp; 3800 u16 val; 3801 3802 /* Disable Autoneg */ 3803 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3804 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7); 3805 3806 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, 3807 MDIO_WC_REG_PAR_DET_10G_CTRL, 0); 3808 3809 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3810 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0x3f00); 3811 3812 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, 3813 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0); 3814 3815 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, 3816 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0); 3817 3818 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3819 MDIO_WC_REG_DIGITAL3_UP1, 0x1); 3820 3821 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3822 MDIO_WC_REG_DIGITAL5_MISC7, 0xa); 3823 3824 /* Disable CL36 PCS Tx */ 3825 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3826 MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0); 3827 3828 /* Double Wide Single Data Rate @ pll rate */ 3829 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3830 MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF); 3831 3832 /* Leave cl72 training enable, needed for KR */ 3833 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 3834 MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150, 3835 0x2); 3836 3837 /* Leave CL72 enabled */ 3838 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 3839 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 3840 &val); 3841 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3842 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 3843 val | 0x3800); 3844 3845 /* Set speed via PMA/PMD register */ 3846 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 3847 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040); 3848 3849 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 3850 MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB); 3851 3852 /*Enable encoded forced speed */ 3853 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3854 MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30); 3855 3856 /* Turn TX scramble payload only the 64/66 scrambler */ 3857 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3858 MDIO_WC_REG_TX66_CONTROL, 0x9); 3859 3860 /* Turn RX scramble payload only the 64/66 scrambler */ 3861 bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, 3862 MDIO_WC_REG_RX66_CONTROL, 0xF9); 3863 3864 /* set and clear loopback to cause a reset to 64/66 decoder */ 3865 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3866 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000); 3867 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3868 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0); 3869 3870} 3871 3872static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, 3873 struct link_params *params, 3874 u8 is_xfi) 3875{ 3876 struct bnx2x *bp = params->bp; 3877 u16 misc1_val, tap_val, tx_driver_val, lane, val; 3878 /* Hold rxSeqStart */ 3879 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 3880 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val); 3881 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3882 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val | 0x8000)); 3883 3884 /* Hold tx_fifo_reset */ 3885 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 3886 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val); 3887 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3888 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, (val | 0x1)); 3889 3890 /* Disable CL73 AN */ 3891 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0); 3892 3893 /* Disable 100FX Enable and Auto-Detect */ 3894 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 3895 MDIO_WC_REG_FX100_CTRL1, &val); 3896 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3897 MDIO_WC_REG_FX100_CTRL1, (val & 0xFFFA)); 3898 3899 /* Disable 100FX Idle detect */ 3900 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 3901 MDIO_WC_REG_FX100_CTRL3, &val); 3902 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3903 MDIO_WC_REG_FX100_CTRL3, (val | 0x0080)); 3904 3905 /* Set Block address to Remote PHY & Clear forced_speed[5] */ 3906 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 3907 MDIO_WC_REG_DIGITAL4_MISC3, &val); 3908 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3909 MDIO_WC_REG_DIGITAL4_MISC3, (val & 0xFF7F)); 3910 3911 /* Turn off auto-detect & fiber mode */ 3912 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 3913 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val); 3914 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3915 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 3916 (val & 0xFFEE)); 3917 3918 /* Set filter_force_link, disable_false_link and parallel_detect */ 3919 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 3920 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val); 3921 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3922 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 3923 ((val | 0x0006) & 0xFFFE)); 3924 3925 /* Set XFI / SFI */ 3926 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 3927 MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val); 3928 3929 misc1_val &= ~(0x1f); 3930 3931 if (is_xfi) { 3932 misc1_val |= 0x5; 3933 tap_val = ((0x08 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | 3934 (0x37 << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | 3935 (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET)); 3936 tx_driver_val = 3937 ((0x00 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | 3938 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | 3939 (0x03 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)); 3940 3941 } else { 3942 misc1_val |= 0x9; 3943 tap_val = ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | 3944 (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | 3945 (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET)); 3946 tx_driver_val = 3947 ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | 3948 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | 3949 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)); 3950 } 3951 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3952 MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val); 3953 3954 /* Set Transmit PMD settings */ 3955 lane = bnx2x_get_warpcore_lane(phy, params); 3956 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3957 MDIO_WC_REG_TX_FIR_TAP, 3958 tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE); 3959 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3960 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 3961 tx_driver_val); 3962 3963 /* Enable fiber mode, enable and invert sig_det */ 3964 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 3965 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val); 3966 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3967 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, val | 0xd); 3968 3969 /* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */ 3970 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 3971 MDIO_WC_REG_DIGITAL4_MISC3, &val); 3972 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3973 MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080); 3974 3975 /* 10G XFI Full Duplex */ 3976 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3977 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100); 3978 3979 /* Release tx_fifo_reset */ 3980 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 3981 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val); 3982 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3983 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, val & 0xFFFE); 3984 3985 /* Release rxSeqStart */ 3986 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 3987 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val); 3988 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3989 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val & 0x7FFF)); 3990} 3991 3992static void bnx2x_warpcore_set_20G_KR2(struct bnx2x *bp, 3993 struct bnx2x_phy *phy) 3994{ 3995 DP(NETIF_MSG_LINK, "KR2 still not supported !!!\n"); 3996} 3997 3998static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp, 3999 struct bnx2x_phy *phy, 4000 u16 lane) 4001{ 4002 /* Rx0 anaRxControl1G */ 4003 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4004 MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90); 4005 4006 /* Rx2 anaRxControl1G */ 4007 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4008 MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90); 4009 4010 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4011 MDIO_WC_REG_RX66_SCW0, 0xE070); 4012 4013 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4014 MDIO_WC_REG_RX66_SCW1, 0xC0D0); 4015 4016 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4017 MDIO_WC_REG_RX66_SCW2, 0xA0B0); 4018 4019 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4020 MDIO_WC_REG_RX66_SCW3, 0x8090); 4021 4022 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4023 MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0); 4024 4025 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4026 MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0); 4027 4028 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4029 MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0); 4030 4031 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4032 MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0); 4033 4034 /* Serdes Digital Misc1 */ 4035 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4036 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008); 4037 4038 /* Serdes Digital4 Misc3 */ 4039 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4040 MDIO_WC_REG_DIGITAL4_MISC3, 0x8088); 4041 4042 /* Set Transmit PMD settings */ 4043 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4044 MDIO_WC_REG_TX_FIR_TAP, 4045 ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | 4046 (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | 4047 (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET) | 4048 MDIO_WC_REG_TX_FIR_TAP_ENABLE)); 4049 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4050 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 4051 ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | 4052 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | 4053 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))); 4054} 4055 4056static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy, 4057 struct link_params *params, 4058 u8 fiber_mode, 4059 u8 always_autoneg) 4060{ 4061 struct bnx2x *bp = params->bp; 4062 u16 val16, digctrl_kx1, digctrl_kx2; 4063 4064 /* Clear XFI clock comp in non-10G single lane mode. */ 4065 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4066 MDIO_WC_REG_RX66_CONTROL, &val16); 4067 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4068 MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13)); 4069 4070 if (always_autoneg || phy->req_line_speed == SPEED_AUTO_NEG) { 4071 /* SGMII Autoneg */ 4072 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4073 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); 4074 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4075 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 4076 val16 | 0x1000); 4077 DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n"); 4078 } else { 4079 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4080 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); 4081 val16 &= 0xcebf; 4082 switch (phy->req_line_speed) { 4083 case SPEED_10: 4084 break; 4085 case SPEED_100: 4086 val16 |= 0x2000; 4087 break; 4088 case SPEED_1000: 4089 val16 |= 0x0040; 4090 break; 4091 default: 4092 DP(NETIF_MSG_LINK, 4093 "Speed not supported: 0x%x\n", phy->req_line_speed); 4094 return; 4095 } 4096 4097 if (phy->req_duplex == DUPLEX_FULL) 4098 val16 |= 0x0100; 4099 4100 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4101 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16); 4102 4103 DP(NETIF_MSG_LINK, "set SGMII force speed %d\n", 4104 phy->req_line_speed); 4105 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4106 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); 4107 DP(NETIF_MSG_LINK, " (readback) %x\n", val16); 4108 } 4109 4110 /* SGMII Slave mode and disable signal detect */ 4111 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4112 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1); 4113 if (fiber_mode) 4114 digctrl_kx1 = 1; 4115 else 4116 digctrl_kx1 &= 0xff4a; 4117 4118 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4119 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 4120 digctrl_kx1); 4121 4122 /* Turn off parallel detect */ 4123 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4124 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2); 4125 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4126 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 4127 (digctrl_kx2 & ~(1<<2))); 4128 4129 /* Re-enable parallel detect */ 4130 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4131 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 4132 (digctrl_kx2 | (1<<2))); 4133 4134 /* Enable autodet */ 4135 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4136 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 4137 (digctrl_kx1 | 0x10)); 4138} 4139 4140static void bnx2x_warpcore_reset_lane(struct bnx2x *bp, 4141 struct bnx2x_phy *phy, 4142 u8 reset) 4143{ 4144 u16 val; 4145 /* Take lane out of reset after configuration is finished */ 4146 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4147 MDIO_WC_REG_DIGITAL5_MISC6, &val); 4148 if (reset) 4149 val |= 0xC000; 4150 else 4151 val &= 0x3FFF; 4152 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4153 MDIO_WC_REG_DIGITAL5_MISC6, val); 4154 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4155 MDIO_WC_REG_DIGITAL5_MISC6, &val); 4156} 4157 4158 4159 /* Clear SFI/XFI link settings registers */ 4160static void bnx2x_warpcore_clear_regs(struct bnx2x_phy *phy, 4161 struct link_params *params, 4162 u16 lane) 4163{ 4164 struct bnx2x *bp = params->bp; 4165 u16 val16; 4166 4167 /* Set XFI clock comp as default. */ 4168 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4169 MDIO_WC_REG_RX66_CONTROL, &val16); 4170 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4171 MDIO_WC_REG_RX66_CONTROL, val16 | (3<<13)); 4172 4173 bnx2x_warpcore_reset_lane(bp, phy, 1); 4174 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0); 4175 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4176 MDIO_WC_REG_FX100_CTRL1, 0x014a); 4177 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4178 MDIO_WC_REG_FX100_CTRL3, 0x0800); 4179 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4180 MDIO_WC_REG_DIGITAL4_MISC3, 0x8008); 4181 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4182 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x0195); 4183 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4184 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x0007); 4185 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4186 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x0002); 4187 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4188 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000); 4189 lane = bnx2x_get_warpcore_lane(phy, params); 4190 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4191 MDIO_WC_REG_TX_FIR_TAP, 0x0000); 4192 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4193 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990); 4194 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4195 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040); 4196 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4197 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140); 4198 bnx2x_warpcore_reset_lane(bp, phy, 0); 4199} 4200 4201static int bnx2x_get_mod_abs_int_cfg(struct bnx2x *bp, 4202 u32 chip_id, 4203 u32 shmem_base, u8 port, 4204 u8 *gpio_num, u8 *gpio_port) 4205{ 4206 u32 cfg_pin; 4207 *gpio_num = 0; 4208 *gpio_port = 0; 4209 if (CHIP_IS_E3(bp)) { 4210 cfg_pin = (REG_RD(bp, shmem_base + 4211 offsetof(struct shmem_region, 4212 dev_info.port_hw_config[port].e3_sfp_ctrl)) & 4213 PORT_HW_CFG_E3_MOD_ABS_MASK) >> 4214 PORT_HW_CFG_E3_MOD_ABS_SHIFT; 4215 4216 /* 4217 * Should not happen. This function called upon interrupt 4218 * triggered by GPIO ( since EPIO can only generate interrupts 4219 * to MCP). 4220 * So if this function was called and none of the GPIOs was set, 4221 * it means the shit hit the fan. 4222 */ 4223 if ((cfg_pin < PIN_CFG_GPIO0_P0) || 4224 (cfg_pin > PIN_CFG_GPIO3_P1)) { 4225 DP(NETIF_MSG_LINK, 4226 "ERROR: Invalid cfg pin %x for module detect indication\n", 4227 cfg_pin); 4228 return -EINVAL; 4229 } 4230 4231 *gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3; 4232 *gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2; 4233 } else { 4234 *gpio_num = MISC_REGISTERS_GPIO_3; 4235 *gpio_port = port; 4236 } 4237 DP(NETIF_MSG_LINK, "MOD_ABS int GPIO%d_P%d\n", *gpio_num, *gpio_port); 4238 return 0; 4239} 4240 4241static int bnx2x_is_sfp_module_plugged(struct bnx2x_phy *phy, 4242 struct link_params *params) 4243{ 4244 struct bnx2x *bp = params->bp; 4245 u8 gpio_num, gpio_port; 4246 u32 gpio_val; 4247 if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id, 4248 params->shmem_base, params->port, 4249 &gpio_num, &gpio_port) != 0) 4250 return 0; 4251 gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port); 4252 4253 /* Call the handling function in case module is detected */ 4254 if (gpio_val == 0) 4255 return 1; 4256 else 4257 return 0; 4258} 4259static int bnx2x_warpcore_get_sigdet(struct bnx2x_phy *phy, 4260 struct link_params *params) 4261{ 4262 u16 gp2_status_reg0, lane; 4263 struct bnx2x *bp = params->bp; 4264 4265 lane = bnx2x_get_warpcore_lane(phy, params); 4266 4267 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_0, 4268 &gp2_status_reg0); 4269 4270 return (gp2_status_reg0 >> (8+lane)) & 0x1; 4271} 4272 4273static void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy, 4274 struct link_params *params, 4275 struct link_vars *vars) 4276{ 4277 struct bnx2x *bp = params->bp; 4278 u32 serdes_net_if; 4279 u16 gp_status1 = 0, lnkup = 0, lnkup_kr = 0; 4280 u16 lane = bnx2x_get_warpcore_lane(phy, params); 4281 4282 vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1; 4283 4284 if (!vars->turn_to_run_wc_rt) 4285 return; 4286 4287 /* return if there is no link partner */ 4288 if (!(bnx2x_warpcore_get_sigdet(phy, params))) { 4289 DP(NETIF_MSG_LINK, "bnx2x_warpcore_get_sigdet false\n"); 4290 return; 4291 } 4292 4293 if (vars->rx_tx_asic_rst) { 4294 serdes_net_if = (REG_RD(bp, params->shmem_base + 4295 offsetof(struct shmem_region, dev_info. 4296 port_hw_config[params->port].default_cfg)) & 4297 PORT_HW_CFG_NET_SERDES_IF_MASK); 4298 4299 switch (serdes_net_if) { 4300 case PORT_HW_CFG_NET_SERDES_IF_KR: 4301 /* Do we get link yet? */ 4302 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 0x81d1, 4303 &gp_status1); 4304 lnkup = (gp_status1 >> (8+lane)) & 0x1;/* 1G */ 4305 /*10G KR*/ 4306 lnkup_kr = (gp_status1 >> (12+lane)) & 0x1; 4307 4308 DP(NETIF_MSG_LINK, 4309 "gp_status1 0x%x\n", gp_status1); 4310 4311 if (lnkup_kr || lnkup) { 4312 vars->rx_tx_asic_rst = 0; 4313 DP(NETIF_MSG_LINK, 4314 "link up, rx_tx_asic_rst 0x%x\n", 4315 vars->rx_tx_asic_rst); 4316 } else { 4317 /*reset the lane to see if link comes up.*/ 4318 bnx2x_warpcore_reset_lane(bp, phy, 1); 4319 bnx2x_warpcore_reset_lane(bp, phy, 0); 4320 4321 /* restart Autoneg */ 4322 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, 4323 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200); 4324 4325 vars->rx_tx_asic_rst--; 4326 DP(NETIF_MSG_LINK, "0x%x retry left\n", 4327 vars->rx_tx_asic_rst); 4328 } 4329 break; 4330 4331 default: 4332 break; 4333 } 4334 4335 } /*params->rx_tx_asic_rst*/ 4336 4337} 4338 4339static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy, 4340 struct link_params *params, 4341 struct link_vars *vars) 4342{ 4343 struct bnx2x *bp = params->bp; 4344 u32 serdes_net_if; 4345 u8 fiber_mode; 4346 u16 lane = bnx2x_get_warpcore_lane(phy, params); 4347 serdes_net_if = (REG_RD(bp, params->shmem_base + 4348 offsetof(struct shmem_region, dev_info. 4349 port_hw_config[params->port].default_cfg)) & 4350 PORT_HW_CFG_NET_SERDES_IF_MASK); 4351 DP(NETIF_MSG_LINK, "Begin Warpcore init, link_speed %d, " 4352 "serdes_net_if = 0x%x\n", 4353 vars->line_speed, serdes_net_if); 4354 bnx2x_set_aer_mmd(params, phy); 4355 4356 vars->phy_flags |= PHY_XGXS_FLAG; 4357 if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) || 4358 (phy->req_line_speed && 4359 ((phy->req_line_speed == SPEED_100) || 4360 (phy->req_line_speed == SPEED_10)))) { 4361 vars->phy_flags |= PHY_SGMII_FLAG; 4362 DP(NETIF_MSG_LINK, "Setting SGMII mode\n"); 4363 bnx2x_warpcore_clear_regs(phy, params, lane); 4364 bnx2x_warpcore_set_sgmii_speed(phy, params, 0, 1); 4365 } else { 4366 switch (serdes_net_if) { 4367 case PORT_HW_CFG_NET_SERDES_IF_KR: 4368 /* Enable KR Auto Neg */ 4369 if (params->loopback_mode == LOOPBACK_NONE) 4370 bnx2x_warpcore_enable_AN_KR(phy, params, vars); 4371 else { 4372 DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n"); 4373 bnx2x_warpcore_set_10G_KR(phy, params, vars); 4374 } 4375 break; 4376 4377 case PORT_HW_CFG_NET_SERDES_IF_XFI: 4378 bnx2x_warpcore_clear_regs(phy, params, lane); 4379 if (vars->line_speed == SPEED_10000) { 4380 DP(NETIF_MSG_LINK, "Setting 10G XFI\n"); 4381 bnx2x_warpcore_set_10G_XFI(phy, params, 1); 4382 } else { 4383 if (SINGLE_MEDIA_DIRECT(params)) { 4384 DP(NETIF_MSG_LINK, "1G Fiber\n"); 4385 fiber_mode = 1; 4386 } else { 4387 DP(NETIF_MSG_LINK, "10/100/1G SGMII\n"); 4388 fiber_mode = 0; 4389 } 4390 bnx2x_warpcore_set_sgmii_speed(phy, 4391 params, 4392 fiber_mode, 4393 0); 4394 } 4395 4396 break; 4397 4398 case PORT_HW_CFG_NET_SERDES_IF_SFI: 4399 4400 bnx2x_warpcore_clear_regs(phy, params, lane); 4401 if (vars->line_speed == SPEED_10000) { 4402 DP(NETIF_MSG_LINK, "Setting 10G SFI\n"); 4403 bnx2x_warpcore_set_10G_XFI(phy, params, 0); 4404 } else if (vars->line_speed == SPEED_1000) { 4405 DP(NETIF_MSG_LINK, "Setting 1G Fiber\n"); 4406 bnx2x_warpcore_set_sgmii_speed( 4407 phy, params, 1, 0); 4408 } 4409 /* Issue Module detection */ 4410 if (bnx2x_is_sfp_module_plugged(phy, params)) 4411 bnx2x_sfp_module_detection(phy, params); 4412 break; 4413 4414 case PORT_HW_CFG_NET_SERDES_IF_DXGXS: 4415 if (vars->line_speed != SPEED_20000) { 4416 DP(NETIF_MSG_LINK, "Speed not supported yet\n"); 4417 return; 4418 } 4419 DP(NETIF_MSG_LINK, "Setting 20G DXGXS\n"); 4420 bnx2x_warpcore_set_20G_DXGXS(bp, phy, lane); 4421 /* Issue Module detection */ 4422 4423 bnx2x_sfp_module_detection(phy, params); 4424 break; 4425 4426 case PORT_HW_CFG_NET_SERDES_IF_KR2: 4427 if (vars->line_speed != SPEED_20000) { 4428 DP(NETIF_MSG_LINK, "Speed not supported yet\n"); 4429 return; 4430 } 4431 DP(NETIF_MSG_LINK, "Setting 20G KR2\n"); 4432 bnx2x_warpcore_set_20G_KR2(bp, phy); 4433 break; 4434 4435 default: 4436 DP(NETIF_MSG_LINK, 4437 "Unsupported Serdes Net Interface 0x%x\n", 4438 serdes_net_if); 4439 return; 4440 } 4441 } 4442 4443 /* Take lane out of reset after configuration is finished */ 4444 bnx2x_warpcore_reset_lane(bp, phy, 0); 4445 DP(NETIF_MSG_LINK, "Exit config init\n"); 4446} 4447 4448static void bnx2x_sfp_e3_set_transmitter(struct link_params *params, 4449 struct bnx2x_phy *phy, 4450 u8 tx_en) 4451{ 4452 struct bnx2x *bp = params->bp; 4453 u32 cfg_pin; 4454 u8 port = params->port; 4455 4456 cfg_pin = REG_RD(bp, params->shmem_base + 4457 offsetof(struct shmem_region, 4458 dev_info.port_hw_config[port].e3_sfp_ctrl)) & 4459 PORT_HW_CFG_TX_LASER_MASK; 4460 /* Set the !tx_en since this pin is DISABLE_TX_LASER */ 4461 DP(NETIF_MSG_LINK, "Setting WC TX to %d\n", tx_en); 4462 /* For 20G, the expected pin to be used is 3 pins after the current */ 4463 4464 bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1); 4465 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G) 4466 bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1); 4467} 4468 4469static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy, 4470 struct link_params *params) 4471{ 4472 struct bnx2x *bp = params->bp; 4473 u16 val16; 4474 bnx2x_sfp_e3_set_transmitter(params, phy, 0); 4475 bnx2x_set_mdio_clk(bp, params->chip_id, params->port); 4476 bnx2x_set_aer_mmd(params, phy); 4477 /* Global register */ 4478 bnx2x_warpcore_reset_lane(bp, phy, 1); 4479 4480 /* Clear loopback settings (if any) */ 4481 /* 10G & 20G */ 4482 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4483 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); 4484 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4485 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 & 4486 0xBFFF); 4487 4488 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4489 MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16); 4490 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4491 MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 & 0xfffe); 4492 4493 /* Update those 1-copy registers */ 4494 CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, 4495 MDIO_AER_BLOCK_AER_REG, 0); 4496 /* Enable 1G MDIO (1-copy) */ 4497 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4498 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, 4499 &val16); 4500 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4501 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, 4502 val16 & ~0x10); 4503 4504 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4505 MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16); 4506 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4507 MDIO_WC_REG_XGXSBLK1_LANECTRL2, 4508 val16 & 0xff00); 4509 4510} 4511 4512static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy, 4513 struct link_params *params) 4514{ 4515 struct bnx2x *bp = params->bp; 4516 u16 val16; 4517 u32 lane; 4518 DP(NETIF_MSG_LINK, "Setting Warpcore loopback type %x, speed %d\n", 4519 params->loopback_mode, phy->req_line_speed); 4520 4521 if (phy->req_line_speed < SPEED_10000) { 4522 /* 10/100/1000 */ 4523 4524 /* Update those 1-copy registers */ 4525 CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, 4526 MDIO_AER_BLOCK_AER_REG, 0); 4527 /* Enable 1G MDIO (1-copy) */ 4528 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4529 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, 4530 &val16); 4531 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4532 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, 4533 val16 | 0x10); 4534 /* Set 1G loopback based on lane (1-copy) */ 4535 lane = bnx2x_get_warpcore_lane(phy, params); 4536 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4537 MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16); 4538 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4539 MDIO_WC_REG_XGXSBLK1_LANECTRL2, 4540 val16 | (1<<lane)); 4541 4542 /* Switch back to 4-copy registers */ 4543 bnx2x_set_aer_mmd(params, phy); 4544 } else { 4545 /* 10G & 20G */ 4546 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4547 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); 4548 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4549 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 | 4550 0x4000); 4551 4552 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 4553 MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16); 4554 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4555 MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 | 0x1); 4556 } 4557} 4558 4559 4560void bnx2x_link_status_update(struct link_params *params, 4561 struct link_vars *vars) 4562{ 4563 struct bnx2x *bp = params->bp; 4564 u8 link_10g_plus; 4565 u8 port = params->port; 4566 u32 sync_offset, media_types; 4567 /* Update PHY configuration */ 4568 set_phy_vars(params, vars); 4569 4570 vars->link_status = REG_RD(bp, params->shmem_base + 4571 offsetof(struct shmem_region, 4572 port_mb[port].link_status)); 4573 4574 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP); 4575 vars->phy_flags = PHY_XGXS_FLAG; 4576 if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG) 4577 vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG; 4578 4579 if (vars->link_up) { 4580 DP(NETIF_MSG_LINK, "phy link up\n"); 4581 4582 vars->phy_link_up = 1; 4583 vars->duplex = DUPLEX_FULL; 4584 switch (vars->link_status & 4585 LINK_STATUS_SPEED_AND_DUPLEX_MASK) { 4586 case LINK_10THD: 4587 vars->duplex = DUPLEX_HALF; 4588 /* fall thru */ 4589 case LINK_10TFD: 4590 vars->line_speed = SPEED_10; 4591 break; 4592 4593 case LINK_100TXHD: 4594 vars->duplex = DUPLEX_HALF; 4595 /* fall thru */ 4596 case LINK_100T4: 4597 case LINK_100TXFD: 4598 vars->line_speed = SPEED_100; 4599 break; 4600 4601 case LINK_1000THD: 4602 vars->duplex = DUPLEX_HALF; 4603 /* fall thru */ 4604 case LINK_1000TFD: 4605 vars->line_speed = SPEED_1000; 4606 break; 4607 4608 case LINK_2500THD: 4609 vars->duplex = DUPLEX_HALF; 4610 /* fall thru */ 4611 case LINK_2500TFD: 4612 vars->line_speed = SPEED_2500; 4613 break; 4614 4615 case LINK_10GTFD: 4616 vars->line_speed = SPEED_10000; 4617 break; 4618 case LINK_20GTFD: 4619 vars->line_speed = SPEED_20000; 4620 break; 4621 default: 4622 break; 4623 } 4624 vars->flow_ctrl = 0; 4625 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED) 4626 vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX; 4627 4628 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED) 4629 vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX; 4630 4631 if (!vars->flow_ctrl) 4632 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; 4633 4634 if (vars->line_speed && 4635 ((vars->line_speed == SPEED_10) || 4636 (vars->line_speed == SPEED_100))) { 4637 vars->phy_flags |= PHY_SGMII_FLAG; 4638 } else { 4639 vars->phy_flags &= ~PHY_SGMII_FLAG; 4640 } 4641 if (vars->line_speed && 4642 USES_WARPCORE(bp) && 4643 (vars->line_speed == SPEED_1000)) 4644 vars->phy_flags |= PHY_SGMII_FLAG; 4645 /* anything 10 and over uses the bmac */ 4646 link_10g_plus = (vars->line_speed >= SPEED_10000); 4647 4648 if (link_10g_plus) { 4649 if (USES_WARPCORE(bp)) 4650 vars->mac_type = MAC_TYPE_XMAC; 4651 else 4652 vars->mac_type = MAC_TYPE_BMAC; 4653 } else { 4654 if (USES_WARPCORE(bp)) 4655 vars->mac_type = MAC_TYPE_UMAC; 4656 else 4657 vars->mac_type = MAC_TYPE_EMAC; 4658 } 4659 } else { /* link down */ 4660 DP(NETIF_MSG_LINK, "phy link down\n"); 4661 4662 vars->phy_link_up = 0; 4663 4664 vars->line_speed = 0; 4665 vars->duplex = DUPLEX_FULL; 4666 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; 4667 4668 /* indicate no mac active */ 4669 vars->mac_type = MAC_TYPE_NONE; 4670 if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG) 4671 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG; 4672 } 4673 4674 /* Sync media type */ 4675 sync_offset = params->shmem_base + 4676 offsetof(struct shmem_region, 4677 dev_info.port_hw_config[port].media_type); 4678 media_types = REG_RD(bp, sync_offset); 4679 4680 params->phy[INT_PHY].media_type = 4681 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >> 4682 PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT; 4683 params->phy[EXT_PHY1].media_type = 4684 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >> 4685 PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT; 4686 params->phy[EXT_PHY2].media_type = 4687 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >> 4688 PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT; 4689 DP(NETIF_MSG_LINK, "media_types = 0x%x\n", media_types); 4690 4691 /* Sync AEU offset */ 4692 sync_offset = params->shmem_base + 4693 offsetof(struct shmem_region, 4694 dev_info.port_hw_config[port].aeu_int_mask); 4695 4696 vars->aeu_int_mask = REG_RD(bp, sync_offset); 4697 4698 /* Sync PFC status */ 4699 if (vars->link_status & LINK_STATUS_PFC_ENABLED) 4700 params->feature_config_flags |= 4701 FEATURE_CONFIG_PFC_ENABLED; 4702 else 4703 params->feature_config_flags &= 4704 ~FEATURE_CONFIG_PFC_ENABLED; 4705 4706 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x int_mask 0x%x\n", 4707 vars->link_status, vars->phy_link_up, vars->aeu_int_mask); 4708 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n", 4709 vars->line_speed, vars->duplex, vars->flow_ctrl); 4710} 4711 4712 4713static void bnx2x_set_master_ln(struct link_params *params, 4714 struct bnx2x_phy *phy) 4715{ 4716 struct bnx2x *bp = params->bp; 4717 u16 new_master_ln, ser_lane; 4718 ser_lane = ((params->lane_config & 4719 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> 4720 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); 4721 4722 /* set the master_ln for AN */ 4723 CL22_RD_OVER_CL45(bp, phy, 4724 MDIO_REG_BANK_XGXS_BLOCK2, 4725 MDIO_XGXS_BLOCK2_TEST_MODE_LANE, 4726 &new_master_ln); 4727 4728 CL22_WR_OVER_CL45(bp, phy, 4729 MDIO_REG_BANK_XGXS_BLOCK2 , 4730 MDIO_XGXS_BLOCK2_TEST_MODE_LANE, 4731 (new_master_ln | ser_lane)); 4732} 4733 4734static int bnx2x_reset_unicore(struct link_params *params, 4735 struct bnx2x_phy *phy, 4736 u8 set_serdes) 4737{ 4738 struct bnx2x *bp = params->bp; 4739 u16 mii_control; 4740 u16 i; 4741 CL22_RD_OVER_CL45(bp, phy, 4742 MDIO_REG_BANK_COMBO_IEEE0, 4743 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); 4744 4745 /* reset the unicore */ 4746 CL22_WR_OVER_CL45(bp, phy, 4747 MDIO_REG_BANK_COMBO_IEEE0, 4748 MDIO_COMBO_IEEE0_MII_CONTROL, 4749 (mii_control | 4750 MDIO_COMBO_IEEO_MII_CONTROL_RESET)); 4751 if (set_serdes) 4752 bnx2x_set_serdes_access(bp, params->port); 4753 4754 /* wait for the reset to self clear */ 4755 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) { 4756 udelay(5); 4757 4758 /* the reset erased the previous bank value */ 4759 CL22_RD_OVER_CL45(bp, phy, 4760 MDIO_REG_BANK_COMBO_IEEE0, 4761 MDIO_COMBO_IEEE0_MII_CONTROL, 4762 &mii_control); 4763 4764 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) { 4765 udelay(5); 4766 return 0; 4767 } 4768 } 4769 4770 netdev_err(bp->dev, "Warning: PHY was not initialized," 4771 " Port %d\n", 4772 params->port); 4773 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n"); 4774 return -EINVAL; 4775 4776} 4777 4778static void bnx2x_set_swap_lanes(struct link_params *params, 4779 struct bnx2x_phy *phy) 4780{ 4781 struct bnx2x *bp = params->bp; 4782 /* 4783 * Each two bits represents a lane number: 4784 * No swap is 0123 => 0x1b no need to enable the swap 4785 */ 4786 u16 ser_lane, rx_lane_swap, tx_lane_swap; 4787 4788 ser_lane = ((params->lane_config & 4789 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> 4790 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); 4791 rx_lane_swap = ((params->lane_config & 4792 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >> 4793 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT); 4794 tx_lane_swap = ((params->lane_config & 4795 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >> 4796 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT); 4797 4798 if (rx_lane_swap != 0x1b) { 4799 CL22_WR_OVER_CL45(bp, phy, 4800 MDIO_REG_BANK_XGXS_BLOCK2, 4801 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 4802 (rx_lane_swap | 4803 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE | 4804 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE)); 4805 } else { 4806 CL22_WR_OVER_CL45(bp, phy, 4807 MDIO_REG_BANK_XGXS_BLOCK2, 4808 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0); 4809 } 4810 4811 if (tx_lane_swap != 0x1b) { 4812 CL22_WR_OVER_CL45(bp, phy, 4813 MDIO_REG_BANK_XGXS_BLOCK2, 4814 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 4815 (tx_lane_swap | 4816 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE)); 4817 } else { 4818 CL22_WR_OVER_CL45(bp, phy, 4819 MDIO_REG_BANK_XGXS_BLOCK2, 4820 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0); 4821 } 4822} 4823 4824static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy, 4825 struct link_params *params) 4826{ 4827 struct bnx2x *bp = params->bp; 4828 u16 control2; 4829 CL22_RD_OVER_CL45(bp, phy, 4830 MDIO_REG_BANK_SERDES_DIGITAL, 4831 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, 4832 &control2); 4833 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) 4834 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN; 4835 else 4836 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN; 4837 DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n", 4838 phy->speed_cap_mask, control2); 4839 CL22_WR_OVER_CL45(bp, phy, 4840 MDIO_REG_BANK_SERDES_DIGITAL, 4841 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, 4842 control2); 4843 4844 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && 4845 (phy->speed_cap_mask & 4846 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { 4847 DP(NETIF_MSG_LINK, "XGXS\n"); 4848 4849 CL22_WR_OVER_CL45(bp, phy, 4850 MDIO_REG_BANK_10G_PARALLEL_DETECT, 4851 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK, 4852 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT); 4853 4854 CL22_RD_OVER_CL45(bp, phy, 4855 MDIO_REG_BANK_10G_PARALLEL_DETECT, 4856 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, 4857 &control2); 4858 4859 4860 control2 |= 4861 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN; 4862 4863 CL22_WR_OVER_CL45(bp, phy, 4864 MDIO_REG_BANK_10G_PARALLEL_DETECT, 4865 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, 4866 control2); 4867 4868 /* Disable parallel detection of HiG */ 4869 CL22_WR_OVER_CL45(bp, phy, 4870 MDIO_REG_BANK_XGXS_BLOCK2, 4871 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G, 4872 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS | 4873 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS); 4874 } 4875} 4876 4877static void bnx2x_set_autoneg(struct bnx2x_phy *phy, 4878 struct link_params *params, 4879 struct link_vars *vars, 4880 u8 enable_cl73) 4881{ 4882 struct bnx2x *bp = params->bp; 4883 u16 reg_val; 4884 4885 /* CL37 Autoneg */ 4886 CL22_RD_OVER_CL45(bp, phy, 4887 MDIO_REG_BANK_COMBO_IEEE0, 4888 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); 4889 4890 /* CL37 Autoneg Enabled */ 4891 if (vars->line_speed == SPEED_AUTO_NEG) 4892 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN; 4893 else /* CL37 Autoneg Disabled */ 4894 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | 4895 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN); 4896 4897 CL22_WR_OVER_CL45(bp, phy, 4898 MDIO_REG_BANK_COMBO_IEEE0, 4899 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val); 4900 4901 /* Enable/Disable Autodetection */ 4902 4903 CL22_RD_OVER_CL45(bp, phy, 4904 MDIO_REG_BANK_SERDES_DIGITAL, 4905 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val); 4906 reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN | 4907 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT); 4908 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE; 4909 if (vars->line_speed == SPEED_AUTO_NEG) 4910 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET; 4911 else 4912 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET; 4913 4914 CL22_WR_OVER_CL45(bp, phy, 4915 MDIO_REG_BANK_SERDES_DIGITAL, 4916 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val); 4917 4918 /* Enable TetonII and BAM autoneg */ 4919 CL22_RD_OVER_CL45(bp, phy, 4920 MDIO_REG_BANK_BAM_NEXT_PAGE, 4921 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, 4922 ®_val); 4923 if (vars->line_speed == SPEED_AUTO_NEG) { 4924 /* Enable BAM aneg Mode and TetonII aneg Mode */ 4925 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE | 4926 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN); 4927 } else { 4928 /* TetonII and BAM Autoneg Disabled */ 4929 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE | 4930 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN); 4931 } 4932 CL22_WR_OVER_CL45(bp, phy, 4933 MDIO_REG_BANK_BAM_NEXT_PAGE, 4934 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, 4935 reg_val); 4936 4937 if (enable_cl73) { 4938 /* Enable Cl73 FSM status bits */ 4939 CL22_WR_OVER_CL45(bp, phy, 4940 MDIO_REG_BANK_CL73_USERB0, 4941 MDIO_CL73_USERB0_CL73_UCTRL, 4942 0xe); 4943 4944 /* Enable BAM Station Manager*/ 4945 CL22_WR_OVER_CL45(bp, phy, 4946 MDIO_REG_BANK_CL73_USERB0, 4947 MDIO_CL73_USERB0_CL73_BAM_CTRL1, 4948 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN | 4949 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN | 4950 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN); 4951 4952 /* Advertise CL73 link speeds */ 4953 CL22_RD_OVER_CL45(bp, phy, 4954 MDIO_REG_BANK_CL73_IEEEB1, 4955 MDIO_CL73_IEEEB1_AN_ADV2, 4956 ®_val); 4957 if (phy->speed_cap_mask & 4958 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) 4959 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4; 4960 if (phy->speed_cap_mask & 4961 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) 4962 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX; 4963 4964 CL22_WR_OVER_CL45(bp, phy, 4965 MDIO_REG_BANK_CL73_IEEEB1, 4966 MDIO_CL73_IEEEB1_AN_ADV2, 4967 reg_val); 4968 4969 /* CL73 Autoneg Enabled */ 4970 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN; 4971 4972 } else /* CL73 Autoneg Disabled */ 4973 reg_val = 0; 4974 4975 CL22_WR_OVER_CL45(bp, phy, 4976 MDIO_REG_BANK_CL73_IEEEB0, 4977 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val); 4978} 4979 4980/* program SerDes, forced speed */ 4981static void bnx2x_program_serdes(struct bnx2x_phy *phy, 4982 struct link_params *params, 4983 struct link_vars *vars) 4984{ 4985 struct bnx2x *bp = params->bp; 4986 u16 reg_val; 4987 4988 /* program duplex, disable autoneg and sgmii*/ 4989 CL22_RD_OVER_CL45(bp, phy, 4990 MDIO_REG_BANK_COMBO_IEEE0, 4991 MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); 4992 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX | 4993 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | 4994 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK); 4995 if (phy->req_duplex == DUPLEX_FULL) 4996 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; 4997 CL22_WR_OVER_CL45(bp, phy, 4998 MDIO_REG_BANK_COMBO_IEEE0, 4999 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val); 5000 5001 /* 5002 * program speed 5003 * - needed only if the speed is greater than 1G (2.5G or 10G) 5004 */ 5005 CL22_RD_OVER_CL45(bp, phy, 5006 MDIO_REG_BANK_SERDES_DIGITAL, 5007 MDIO_SERDES_DIGITAL_MISC1, ®_val); 5008 /* clearing the speed value before setting the right speed */ 5009 DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val); 5010 5011 reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK | 5012 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL); 5013 5014 if (!((vars->line_speed == SPEED_1000) || 5015 (vars->line_speed == SPEED_100) || 5016 (vars->line_speed == SPEED_10))) { 5017 5018 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M | 5019 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL); 5020 if (vars->line_speed == SPEED_10000) 5021 reg_val |= 5022 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4; 5023 } 5024 5025 CL22_WR_OVER_CL45(bp, phy, 5026 MDIO_REG_BANK_SERDES_DIGITAL, 5027 MDIO_SERDES_DIGITAL_MISC1, reg_val); 5028 5029} 5030 5031static void bnx2x_set_brcm_cl37_advertisement(struct bnx2x_phy *phy, 5032 struct link_params *params) 5033{ 5034 struct bnx2x *bp = params->bp; 5035 u16 val = 0; 5036 5037 /* configure the 48 bits for BAM AN */ 5038 5039 /* set extended capabilities */ 5040 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) 5041 val |= MDIO_OVER_1G_UP1_2_5G; 5042 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) 5043 val |= MDIO_OVER_1G_UP1_10G; 5044 CL22_WR_OVER_CL45(bp, phy, 5045 MDIO_REG_BANK_OVER_1G, 5046 MDIO_OVER_1G_UP1, val); 5047 5048 CL22_WR_OVER_CL45(bp, phy, 5049 MDIO_REG_BANK_OVER_1G, 5050 MDIO_OVER_1G_UP3, 0x400); 5051} 5052 5053static void bnx2x_set_ieee_aneg_advertisement(struct bnx2x_phy *phy, 5054 struct link_params *params, 5055 u16 ieee_fc) 5056{ 5057 struct bnx2x *bp = params->bp; 5058 u16 val; 5059 /* for AN, we are always publishing full duplex */ 5060 5061 CL22_WR_OVER_CL45(bp, phy, 5062 MDIO_REG_BANK_COMBO_IEEE0, 5063 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc); 5064 CL22_RD_OVER_CL45(bp, phy, 5065 MDIO_REG_BANK_CL73_IEEEB1, 5066 MDIO_CL73_IEEEB1_AN_ADV1, &val); 5067 val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH; 5068 val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK); 5069 CL22_WR_OVER_CL45(bp, phy, 5070 MDIO_REG_BANK_CL73_IEEEB1, 5071 MDIO_CL73_IEEEB1_AN_ADV1, val); 5072} 5073 5074static void bnx2x_restart_autoneg(struct bnx2x_phy *phy, 5075 struct link_params *params, 5076 u8 enable_cl73) 5077{ 5078 struct bnx2x *bp = params->bp; 5079 u16 mii_control; 5080 5081 DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n"); 5082 /* Enable and restart BAM/CL37 aneg */ 5083 5084 if (enable_cl73) { 5085 CL22_RD_OVER_CL45(bp, phy, 5086 MDIO_REG_BANK_CL73_IEEEB0, 5087 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, 5088 &mii_control); 5089 5090 CL22_WR_OVER_CL45(bp, phy, 5091 MDIO_REG_BANK_CL73_IEEEB0, 5092 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, 5093 (mii_control | 5094 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN | 5095 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN)); 5096 } else { 5097 5098 CL22_RD_OVER_CL45(bp, phy, 5099 MDIO_REG_BANK_COMBO_IEEE0, 5100 MDIO_COMBO_IEEE0_MII_CONTROL, 5101 &mii_control); 5102 DP(NETIF_MSG_LINK, 5103 "bnx2x_restart_autoneg mii_control before = 0x%x\n", 5104 mii_control); 5105 CL22_WR_OVER_CL45(bp, phy, 5106 MDIO_REG_BANK_COMBO_IEEE0, 5107 MDIO_COMBO_IEEE0_MII_CONTROL, 5108 (mii_control | 5109 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | 5110 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN)); 5111 } 5112} 5113 5114static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, 5115 struct link_params *params, 5116 struct link_vars *vars) 5117{ 5118 struct bnx2x *bp = params->bp; 5119 u16 control1; 5120 5121 /* in SGMII mode, the unicore is always slave */ 5122 5123 CL22_RD_OVER_CL45(bp, phy, 5124 MDIO_REG_BANK_SERDES_DIGITAL, 5125 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, 5126 &control1); 5127 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT; 5128 /* set sgmii mode (and not fiber) */ 5129 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE | 5130 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET | 5131 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE); 5132 CL22_WR_OVER_CL45(bp, phy, 5133 MDIO_REG_BANK_SERDES_DIGITAL, 5134 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, 5135 control1); 5136 5137 /* if forced speed */ 5138 if (!(vars->line_speed == SPEED_AUTO_NEG)) { 5139 /* set speed, disable autoneg */ 5140 u16 mii_control; 5141 5142 CL22_RD_OVER_CL45(bp, phy, 5143 MDIO_REG_BANK_COMBO_IEEE0, 5144 MDIO_COMBO_IEEE0_MII_CONTROL, 5145 &mii_control); 5146 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | 5147 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK| 5148 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX); 5149 5150 switch (vars->line_speed) { 5151 case SPEED_100: 5152 mii_control |= 5153 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100; 5154 break; 5155 case SPEED_1000: 5156 mii_control |= 5157 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000; 5158 break; 5159 case SPEED_10: 5160 /* there is nothing to set for 10M */ 5161 break; 5162 default: 5163 /* invalid speed for SGMII */ 5164 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", 5165 vars->line_speed); 5166 break; 5167 } 5168 5169 /* setting the full duplex */ 5170 if (phy->req_duplex == DUPLEX_FULL) 5171 mii_control |= 5172 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; 5173 CL22_WR_OVER_CL45(bp, phy, 5174 MDIO_REG_BANK_COMBO_IEEE0, 5175 MDIO_COMBO_IEEE0_MII_CONTROL, 5176 mii_control); 5177 5178 } else { /* AN mode */ 5179 /* enable and restart AN */ 5180 bnx2x_restart_autoneg(phy, params, 0); 5181 } 5182} 5183 5184 5185/* 5186 * link management 5187 */ 5188 5189static int bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy, 5190 struct link_params *params) 5191{ 5192 struct bnx2x *bp = params->bp; 5193 u16 pd_10g, status2_1000x; 5194 if (phy->req_line_speed != SPEED_AUTO_NEG) 5195 return 0; 5196 CL22_RD_OVER_CL45(bp, phy, 5197 MDIO_REG_BANK_SERDES_DIGITAL, 5198 MDIO_SERDES_DIGITAL_A_1000X_STATUS2, 5199 &status2_1000x); 5200 CL22_RD_OVER_CL45(bp, phy, 5201 MDIO_REG_BANK_SERDES_DIGITAL, 5202 MDIO_SERDES_DIGITAL_A_1000X_STATUS2, 5203 &status2_1000x); 5204 if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) { 5205 DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n", 5206 params->port); 5207 return 1; 5208 } 5209 5210 CL22_RD_OVER_CL45(bp, phy, 5211 MDIO_REG_BANK_10G_PARALLEL_DETECT, 5212 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS, 5213 &pd_10g); 5214 5215 if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) { 5216 DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n", 5217 params->port); 5218 return 1; 5219 } 5220 return 0; 5221} 5222 5223static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy, 5224 struct link_params *params, 5225 struct link_vars *vars, 5226 u32 gp_status) 5227{ 5228 struct bnx2x *bp = params->bp; 5229 u16 ld_pause; /* local driver */ 5230 u16 lp_pause; /* link partner */ 5231 u16 pause_result; 5232 5233 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; 5234 5235 /* resolve from gp_status in case of AN complete and not sgmii */ 5236 if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) 5237 vars->flow_ctrl = phy->req_flow_ctrl; 5238 else if (phy->req_line_speed != SPEED_AUTO_NEG) 5239 vars->flow_ctrl = params->req_fc_auto_adv; 5240 else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) && 5241 (!(vars->phy_flags & PHY_SGMII_FLAG))) { 5242 if (bnx2x_direct_parallel_detect_used(phy, params)) { 5243 vars->flow_ctrl = params->req_fc_auto_adv; 5244 return; 5245 } 5246 if ((gp_status & 5247 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | 5248 MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) == 5249 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | 5250 MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) { 5251 5252 CL22_RD_OVER_CL45(bp, phy, 5253 MDIO_REG_BANK_CL73_IEEEB1, 5254 MDIO_CL73_IEEEB1_AN_ADV1, 5255 &ld_pause); 5256 CL22_RD_OVER_CL45(bp, phy, 5257 MDIO_REG_BANK_CL73_IEEEB1, 5258 MDIO_CL73_IEEEB1_AN_LP_ADV1, 5259 &lp_pause); 5260 pause_result = (ld_pause & 5261 MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK) 5262 >> 8; 5263 pause_result |= (lp_pause & 5264 MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK) 5265 >> 10; 5266 DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n", 5267 pause_result); 5268 } else { 5269 CL22_RD_OVER_CL45(bp, phy, 5270 MDIO_REG_BANK_COMBO_IEEE0, 5271 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, 5272 &ld_pause); 5273 CL22_RD_OVER_CL45(bp, phy, 5274 MDIO_REG_BANK_COMBO_IEEE0, 5275 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1, 5276 &lp_pause); 5277 pause_result = (ld_pause & 5278 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5; 5279 pause_result |= (lp_pause & 5280 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7; 5281 DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n", 5282 pause_result); 5283 } 5284 bnx2x_pause_resolve(vars, pause_result); 5285 } 5286 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl); 5287} 5288 5289static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy, 5290 struct link_params *params) 5291{ 5292 struct bnx2x *bp = params->bp; 5293 u16 rx_status, ustat_val, cl37_fsm_received; 5294 DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n"); 5295 /* Step 1: Make sure signal is detected */ 5296 CL22_RD_OVER_CL45(bp, phy, 5297 MDIO_REG_BANK_RX0, 5298 MDIO_RX0_RX_STATUS, 5299 &rx_status); 5300 if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) != 5301 (MDIO_RX0_RX_STATUS_SIGDET)) { 5302 DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73." 5303 "rx_status(0x80b0) = 0x%x\n", rx_status); 5304 CL22_WR_OVER_CL45(bp, phy, 5305 MDIO_REG_BANK_CL73_IEEEB0, 5306 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, 5307 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN); 5308 return; 5309 } 5310 /* Step 2: Check CL73 state machine */ 5311 CL22_RD_OVER_CL45(bp, phy, 5312 MDIO_REG_BANK_CL73_USERB0, 5313 MDIO_CL73_USERB0_CL73_USTAT1, 5314 &ustat_val); 5315 if ((ustat_val & 5316 (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK | 5317 MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) != 5318 (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK | 5319 MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) { 5320 DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. " 5321 "ustat_val(0x8371) = 0x%x\n", ustat_val); 5322 return; 5323 } 5324 /* 5325 * Step 3: Check CL37 Message Pages received to indicate LP 5326 * supports only CL37 5327 */ 5328 CL22_RD_OVER_CL45(bp, phy, 5329 MDIO_REG_BANK_REMOTE_PHY, 5330 MDIO_REMOTE_PHY_MISC_RX_STATUS, 5331 &cl37_fsm_received); 5332 if ((cl37_fsm_received & 5333 (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG | 5334 MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) != 5335 (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG | 5336 MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) { 5337 DP(NETIF_MSG_LINK, "No CL37 FSM were received. " 5338 "misc_rx_status(0x8330) = 0x%x\n", 5339 cl37_fsm_received); 5340 return; 5341 } 5342 /* 5343 * The combined cl37/cl73 fsm state information indicating that 5344 * we are connected to a device which does not support cl73, but 5345 * does support cl37 BAM. In this case we disable cl73 and 5346 * restart cl37 auto-neg 5347 */ 5348 5349 /* Disable CL73 */ 5350 CL22_WR_OVER_CL45(bp, phy, 5351 MDIO_REG_BANK_CL73_IEEEB0, 5352 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, 5353 0); 5354 /* Restart CL37 autoneg */ 5355 bnx2x_restart_autoneg(phy, params, 0); 5356 DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n"); 5357} 5358 5359static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy, 5360 struct link_params *params, 5361 struct link_vars *vars, 5362 u32 gp_status) 5363{ 5364 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) 5365 vars->link_status |= 5366 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; 5367 5368 if (bnx2x_direct_parallel_detect_used(phy, params)) 5369 vars->link_status |= 5370 LINK_STATUS_PARALLEL_DETECTION_USED; 5371} 5372static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, 5373 struct link_params *params, 5374 struct link_vars *vars, 5375 u16 is_link_up, 5376 u16 speed_mask, 5377 u16 is_duplex) 5378{ 5379 struct bnx2x *bp = params->bp; 5380 if (phy->req_line_speed == SPEED_AUTO_NEG) 5381 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED; 5382 if (is_link_up) { 5383 DP(NETIF_MSG_LINK, "phy link up\n"); 5384 5385 vars->phy_link_up = 1; 5386 vars->link_status |= LINK_STATUS_LINK_UP; 5387 5388 switch (speed_mask) { 5389 case GP_STATUS_10M: 5390 vars->line_speed = SPEED_10; 5391 if (vars->duplex == DUPLEX_FULL) 5392 vars->link_status |= LINK_10TFD; 5393 else 5394 vars->link_status |= LINK_10THD; 5395 break; 5396 5397 case GP_STATUS_100M: 5398 vars->line_speed = SPEED_100; 5399 if (vars->duplex == DUPLEX_FULL) 5400 vars->link_status |= LINK_100TXFD; 5401 else 5402 vars->link_status |= LINK_100TXHD; 5403 break; 5404 5405 case GP_STATUS_1G: 5406 case GP_STATUS_1G_KX: 5407 vars->line_speed = SPEED_1000; 5408 if (vars->duplex == DUPLEX_FULL) 5409 vars->link_status |= LINK_1000TFD; 5410 else 5411 vars->link_status |= LINK_1000THD; 5412 break; 5413 5414 case GP_STATUS_2_5G: 5415 vars->line_speed = SPEED_2500; 5416 if (vars->duplex == DUPLEX_FULL) 5417 vars->link_status |= LINK_2500TFD; 5418 else 5419 vars->link_status |= LINK_2500THD; 5420 break; 5421 5422 case GP_STATUS_5G: 5423 case GP_STATUS_6G: 5424 DP(NETIF_MSG_LINK, 5425 "link speed unsupported gp_status 0x%x\n", 5426 speed_mask); 5427 return -EINVAL; 5428 5429 case GP_STATUS_10G_KX4: 5430 case GP_STATUS_10G_HIG: 5431 case GP_STATUS_10G_CX4: 5432 case GP_STATUS_10G_KR: 5433 case GP_STATUS_10G_SFI: 5434 case GP_STATUS_10G_XFI: 5435 vars->line_speed = SPEED_10000; 5436 vars->link_status |= LINK_10GTFD; 5437 break; 5438 case GP_STATUS_20G_DXGXS: 5439 vars->line_speed = SPEED_20000; 5440 vars->link_status |= LINK_20GTFD; 5441 break; 5442 default: 5443 DP(NETIF_MSG_LINK, 5444 "link speed unsupported gp_status 0x%x\n", 5445 speed_mask); 5446 return -EINVAL; 5447 } 5448 } else { /* link_down */ 5449 DP(NETIF_MSG_LINK, "phy link down\n"); 5450 5451 vars->phy_link_up = 0; 5452 5453 vars->duplex = DUPLEX_FULL; 5454 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; 5455 vars->mac_type = MAC_TYPE_NONE; 5456 } 5457 DP(NETIF_MSG_LINK, " phy_link_up %x line_speed %d\n", 5458 vars->phy_link_up, vars->line_speed); 5459 return 0; 5460} 5461 5462static int bnx2x_link_settings_status(struct bnx2x_phy *phy, 5463 struct link_params *params, 5464 struct link_vars *vars) 5465{ 5466 5467 struct bnx2x *bp = params->bp; 5468 5469 u16 gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask; 5470 int rc = 0; 5471 5472 /* Read gp_status */ 5473 CL22_RD_OVER_CL45(bp, phy, 5474 MDIO_REG_BANK_GP_STATUS, 5475 MDIO_GP_STATUS_TOP_AN_STATUS1, 5476 &gp_status); 5477 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS) 5478 duplex = DUPLEX_FULL; 5479 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) 5480 link_up = 1; 5481 speed_mask = gp_status & GP_STATUS_SPEED_MASK; 5482 DP(NETIF_MSG_LINK, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x\n", 5483 gp_status, link_up, speed_mask); 5484 rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, speed_mask, 5485 duplex); 5486 if (rc == -EINVAL) 5487 return rc; 5488 5489 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { 5490 if (SINGLE_MEDIA_DIRECT(params)) { 5491 bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status); 5492 if (phy->req_line_speed == SPEED_AUTO_NEG) 5493 bnx2x_xgxs_an_resolve(phy, params, vars, 5494 gp_status); 5495 } 5496 } else { /* link_down */ 5497 if ((phy->req_line_speed == SPEED_AUTO_NEG) && 5498 SINGLE_MEDIA_DIRECT(params)) { 5499 /* Check signal is detected */ 5500 bnx2x_check_fallback_to_cl37(phy, params); 5501 } 5502 } 5503 5504 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n", 5505 vars->duplex, vars->flow_ctrl, vars->link_status); 5506 return rc; 5507} 5508 5509static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy, 5510 struct link_params *params, 5511 struct link_vars *vars) 5512{ 5513 5514 struct bnx2x *bp = params->bp; 5515 5516 u8 lane; 5517 u16 gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL; 5518 int rc = 0; 5519 lane = bnx2x_get_warpcore_lane(phy, params); 5520 /* Read gp_status */ 5521 if (phy->req_line_speed > SPEED_10000) { 5522 u16 temp_link_up; 5523 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 5524 1, &temp_link_up); 5525 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 5526 1, &link_up); 5527 DP(NETIF_MSG_LINK, "PCS RX link status = 0x%x-->0x%x\n", 5528 temp_link_up, link_up); 5529 link_up &= (1<<2); 5530 if (link_up) 5531 bnx2x_ext_phy_resolve_fc(phy, params, vars); 5532 } else { 5533 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 5534 MDIO_WC_REG_GP2_STATUS_GP_2_1, &gp_status1); 5535 DP(NETIF_MSG_LINK, "0x81d1 = 0x%x\n", gp_status1); 5536 /* Check for either KR or generic link up. */ 5537 gp_status1 = ((gp_status1 >> 8) & 0xf) | 5538 ((gp_status1 >> 12) & 0xf); 5539 link_up = gp_status1 & (1 << lane); 5540 if (link_up && SINGLE_MEDIA_DIRECT(params)) { 5541 u16 pd, gp_status4; 5542 if (phy->req_line_speed == SPEED_AUTO_NEG) { 5543 /* Check Autoneg complete */ 5544 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 5545 MDIO_WC_REG_GP2_STATUS_GP_2_4, 5546 &gp_status4); 5547 if (gp_status4 & ((1<<12)<<lane)) 5548 vars->link_status |= 5549 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; 5550 5551 /* Check parallel detect used */ 5552 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 5553 MDIO_WC_REG_PAR_DET_10G_STATUS, 5554 &pd); 5555 if (pd & (1<<15)) 5556 vars->link_status |= 5557 LINK_STATUS_PARALLEL_DETECTION_USED; 5558 } 5559 bnx2x_ext_phy_resolve_fc(phy, params, vars); 5560 } 5561 } 5562 5563 if (lane < 2) { 5564 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 5565 MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed); 5566 } else { 5567 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 5568 MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed); 5569 } 5570 DP(NETIF_MSG_LINK, "lane %d gp_speed 0x%x\n", lane, gp_speed); 5571 5572 if ((lane & 1) == 0) 5573 gp_speed <<= 8; 5574 gp_speed &= 0x3f00; 5575 5576 5577 rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed, 5578 duplex); 5579 5580 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n", 5581 vars->duplex, vars->flow_ctrl, vars->link_status); 5582 return rc; 5583} 5584static void bnx2x_set_gmii_tx_driver(struct link_params *params) 5585{ 5586 struct bnx2x *bp = params->bp; 5587 struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; 5588 u16 lp_up2; 5589 u16 tx_driver; 5590 u16 bank; 5591 5592 /* read precomp */ 5593 CL22_RD_OVER_CL45(bp, phy, 5594 MDIO_REG_BANK_OVER_1G, 5595 MDIO_OVER_1G_LP_UP2, &lp_up2); 5596 5597 /* bits [10:7] at lp_up2, positioned at [15:12] */ 5598 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >> 5599 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) << 5600 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT); 5601 5602 if (lp_up2 == 0) 5603 return; 5604 5605 for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3; 5606 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) { 5607 CL22_RD_OVER_CL45(bp, phy, 5608 bank, 5609 MDIO_TX0_TX_DRIVER, &tx_driver); 5610 5611 /* replace tx_driver bits [15:12] */ 5612 if (lp_up2 != 5613 (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) { 5614 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK; 5615 tx_driver |= lp_up2; 5616 CL22_WR_OVER_CL45(bp, phy, 5617 bank, 5618 MDIO_TX0_TX_DRIVER, tx_driver); 5619 } 5620 } 5621} 5622 5623static int bnx2x_emac_program(struct link_params *params, 5624 struct link_vars *vars) 5625{ 5626 struct bnx2x *bp = params->bp; 5627 u8 port = params->port; 5628 u16 mode = 0; 5629 5630 DP(NETIF_MSG_LINK, "setting link speed & duplex\n"); 5631 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 + 5632 EMAC_REG_EMAC_MODE, 5633 (EMAC_MODE_25G_MODE | 5634 EMAC_MODE_PORT_MII_10M | 5635 EMAC_MODE_HALF_DUPLEX)); 5636 switch (vars->line_speed) { 5637 case SPEED_10: 5638 mode |= EMAC_MODE_PORT_MII_10M; 5639 break; 5640 5641 case SPEED_100: 5642 mode |= EMAC_MODE_PORT_MII; 5643 break; 5644 5645 case SPEED_1000: 5646 mode |= EMAC_MODE_PORT_GMII; 5647 break; 5648 5649 case SPEED_2500: 5650 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII); 5651 break; 5652 5653 default: 5654 /* 10G not valid for EMAC */ 5655 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", 5656 vars->line_speed); 5657 return -EINVAL; 5658 } 5659 5660 if (vars->duplex == DUPLEX_HALF) 5661 mode |= EMAC_MODE_HALF_DUPLEX; 5662 bnx2x_bits_en(bp, 5663 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE, 5664 mode); 5665 5666 bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed); 5667 return 0; 5668} 5669 5670static void bnx2x_set_preemphasis(struct bnx2x_phy *phy, 5671 struct link_params *params) 5672{ 5673 5674 u16 bank, i = 0; 5675 struct bnx2x *bp = params->bp; 5676 5677 for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3; 5678 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) { 5679 CL22_WR_OVER_CL45(bp, phy, 5680 bank, 5681 MDIO_RX0_RX_EQ_BOOST, 5682 phy->rx_preemphasis[i]); 5683 } 5684 5685 for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3; 5686 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) { 5687 CL22_WR_OVER_CL45(bp, phy, 5688 bank, 5689 MDIO_TX0_TX_DRIVER, 5690 phy->tx_preemphasis[i]); 5691 } 5692} 5693 5694static void bnx2x_xgxs_config_init(struct bnx2x_phy *phy, 5695 struct link_params *params, 5696 struct link_vars *vars) 5697{ 5698 struct bnx2x *bp = params->bp; 5699 u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) || 5700 (params->loopback_mode == LOOPBACK_XGXS)); 5701 if (!(vars->phy_flags & PHY_SGMII_FLAG)) { 5702 if (SINGLE_MEDIA_DIRECT(params) && 5703 (params->feature_config_flags & 5704 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) 5705 bnx2x_set_preemphasis(phy, params); 5706 5707 /* forced speed requested? */ 5708 if (vars->line_speed != SPEED_AUTO_NEG || 5709 (SINGLE_MEDIA_DIRECT(params) && 5710 params->loopback_mode == LOOPBACK_EXT)) { 5711 DP(NETIF_MSG_LINK, "not SGMII, no AN\n"); 5712 5713 /* disable autoneg */ 5714 bnx2x_set_autoneg(phy, params, vars, 0); 5715 5716 /* program speed and duplex */ 5717 bnx2x_program_serdes(phy, params, vars); 5718 5719 } else { /* AN_mode */ 5720 DP(NETIF_MSG_LINK, "not SGMII, AN\n"); 5721 5722 /* AN enabled */ 5723 bnx2x_set_brcm_cl37_advertisement(phy, params); 5724 5725 /* program duplex & pause advertisement (for aneg) */ 5726 bnx2x_set_ieee_aneg_advertisement(phy, params, 5727 vars->ieee_fc); 5728 5729 /* enable autoneg */ 5730 bnx2x_set_autoneg(phy, params, vars, enable_cl73); 5731 5732 /* enable and restart AN */ 5733 bnx2x_restart_autoneg(phy, params, enable_cl73); 5734 } 5735 5736 } else { /* SGMII mode */ 5737 DP(NETIF_MSG_LINK, "SGMII\n"); 5738 5739 bnx2x_initialize_sgmii_process(phy, params, vars); 5740 } 5741} 5742 5743static int bnx2x_prepare_xgxs(struct bnx2x_phy *phy, 5744 struct link_params *params, 5745 struct link_vars *vars) 5746{ 5747 int rc; 5748 vars->phy_flags |= PHY_XGXS_FLAG; 5749 if ((phy->req_line_speed && 5750 ((phy->req_line_speed == SPEED_100) || 5751 (phy->req_line_speed == SPEED_10))) || 5752 (!phy->req_line_speed && 5753 (phy->speed_cap_mask >= 5754 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) && 5755 (phy->speed_cap_mask < 5756 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || 5757 (phy->type == PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD)) 5758 vars->phy_flags |= PHY_SGMII_FLAG; 5759 else 5760 vars->phy_flags &= ~PHY_SGMII_FLAG; 5761 5762 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); 5763 bnx2x_set_aer_mmd(params, phy); 5764 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) 5765 bnx2x_set_master_ln(params, phy); 5766 5767 rc = bnx2x_reset_unicore(params, phy, 0); 5768 /* reset the SerDes and wait for reset bit return low */ 5769 if (rc != 0) 5770 return rc; 5771 5772 bnx2x_set_aer_mmd(params, phy); 5773 /* setting the masterLn_def again after the reset */ 5774 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) { 5775 bnx2x_set_master_ln(params, phy); 5776 bnx2x_set_swap_lanes(params, phy); 5777 } 5778 5779 return rc; 5780} 5781 5782static u16 bnx2x_wait_reset_complete(struct bnx2x *bp, 5783 struct bnx2x_phy *phy, 5784 struct link_params *params) 5785{ 5786 u16 cnt, ctrl; 5787 /* Wait for soft reset to get cleared up to 1 sec */ 5788 for (cnt = 0; cnt < 1000; cnt++) { 5789 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) 5790 bnx2x_cl22_read(bp, phy, 5791 MDIO_PMA_REG_CTRL, &ctrl); 5792 else 5793 bnx2x_cl45_read(bp, phy, 5794 MDIO_PMA_DEVAD, 5795 MDIO_PMA_REG_CTRL, &ctrl); 5796 if (!(ctrl & (1<<15))) 5797 break; 5798 msleep(1); 5799 } 5800 5801 if (cnt == 1000) 5802 netdev_err(bp->dev, "Warning: PHY was not initialized," 5803 " Port %d\n", 5804 params->port); 5805 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt); 5806 return cnt; 5807} 5808 5809static void bnx2x_link_int_enable(struct link_params *params) 5810{ 5811 u8 port = params->port; 5812 u32 mask; 5813 struct bnx2x *bp = params->bp; 5814 5815 /* Setting the status to report on link up for either XGXS or SerDes */ 5816 if (CHIP_IS_E3(bp)) { 5817 mask = NIG_MASK_XGXS0_LINK_STATUS; 5818 if (!(SINGLE_MEDIA_DIRECT(params))) 5819 mask |= NIG_MASK_MI_INT; 5820 } else if (params->switch_cfg == SWITCH_CFG_10G) { 5821 mask = (NIG_MASK_XGXS0_LINK10G | 5822 NIG_MASK_XGXS0_LINK_STATUS); 5823 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n"); 5824 if (!(SINGLE_MEDIA_DIRECT(params)) && 5825 params->phy[INT_PHY].type != 5826 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) { 5827 mask |= NIG_MASK_MI_INT; 5828 DP(NETIF_MSG_LINK, "enabled external phy int\n"); 5829 } 5830 5831 } else { /* SerDes */ 5832 mask = NIG_MASK_SERDES0_LINK_STATUS; 5833 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n"); 5834 if (!(SINGLE_MEDIA_DIRECT(params)) && 5835 params->phy[INT_PHY].type != 5836 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) { 5837 mask |= NIG_MASK_MI_INT; 5838 DP(NETIF_MSG_LINK, "enabled external phy int\n"); 5839 } 5840 } 5841 bnx2x_bits_en(bp, 5842 NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 5843 mask); 5844 5845 DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port, 5846 (params->switch_cfg == SWITCH_CFG_10G), 5847 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); 5848 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n", 5849 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), 5850 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18), 5851 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c)); 5852 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n", 5853 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), 5854 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); 5855} 5856 5857static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port, 5858 u8 exp_mi_int) 5859{ 5860 u32 latch_status = 0; 5861 5862 /* 5863 * Disable the MI INT ( external phy int ) by writing 1 to the 5864 * status register. Link down indication is high-active-signal, 5865 * so in this case we need to write the status to clear the XOR 5866 */ 5867 /* Read Latched signals */ 5868 latch_status = REG_RD(bp, 5869 NIG_REG_LATCH_STATUS_0 + port*8); 5870 DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status); 5871 /* Handle only those with latched-signal=up.*/ 5872 if (exp_mi_int) 5873 bnx2x_bits_en(bp, 5874 NIG_REG_STATUS_INTERRUPT_PORT0 5875 + port*4, 5876 NIG_STATUS_EMAC0_MI_INT); 5877 else 5878 bnx2x_bits_dis(bp, 5879 NIG_REG_STATUS_INTERRUPT_PORT0 5880 + port*4, 5881 NIG_STATUS_EMAC0_MI_INT); 5882 5883 if (latch_status & 1) { 5884 5885 /* For all latched-signal=up : Re-Arm Latch signals */ 5886 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8, 5887 (latch_status & 0xfffe) | (latch_status & 1)); 5888 } 5889 /* For all latched-signal=up,Write original_signal to status */ 5890} 5891 5892static void bnx2x_link_int_ack(struct link_params *params, 5893 struct link_vars *vars, u8 is_10g_plus) 5894{ 5895 struct bnx2x *bp = params->bp; 5896 u8 port = params->port; 5897 u32 mask; 5898 /* 5899 * First reset all status we assume only one line will be 5900 * change at a time 5901 */ 5902 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, 5903 (NIG_STATUS_XGXS0_LINK10G | 5904 NIG_STATUS_XGXS0_LINK_STATUS | 5905 NIG_STATUS_SERDES0_LINK_STATUS)); 5906 if (vars->phy_link_up) { 5907 if (USES_WARPCORE(bp)) 5908 mask = NIG_STATUS_XGXS0_LINK_STATUS; 5909 else { 5910 if (is_10g_plus) 5911 mask = NIG_STATUS_XGXS0_LINK10G; 5912 else if (params->switch_cfg == SWITCH_CFG_10G) { 5913 /* 5914 * Disable the link interrupt by writing 1 to 5915 * the relevant lane in the status register 5916 */ 5917 u32 ser_lane = 5918 ((params->lane_config & 5919 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> 5920 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); 5921 mask = ((1 << ser_lane) << 5922 NIG_STATUS_XGXS0_LINK_STATUS_SIZE); 5923 } else 5924 mask = NIG_STATUS_SERDES0_LINK_STATUS; 5925 } 5926 DP(NETIF_MSG_LINK, "Ack link up interrupt with mask 0x%x\n", 5927 mask); 5928 bnx2x_bits_en(bp, 5929 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, 5930 mask); 5931 } 5932} 5933 5934static int bnx2x_format_ver(u32 num, u8 *str, u16 *len) 5935{ 5936 u8 *str_ptr = str; 5937 u32 mask = 0xf0000000; 5938 u8 shift = 8*4; 5939 u8 digit; 5940 u8 remove_leading_zeros = 1; 5941 if (*len < 10) { 5942 /* Need more than 10chars for this format */ 5943 *str_ptr = '\0'; 5944 (*len)--; 5945 return -EINVAL; 5946 } 5947 while (shift > 0) { 5948 5949 shift -= 4; 5950 digit = ((num & mask) >> shift); 5951 if (digit == 0 && remove_leading_zeros) { 5952 mask = mask >> 4; 5953 continue; 5954 } else if (digit < 0xa) 5955 *str_ptr = digit + '0'; 5956 else 5957 *str_ptr = digit - 0xa + 'a'; 5958 remove_leading_zeros = 0; 5959 str_ptr++; 5960 (*len)--; 5961 mask = mask >> 4; 5962 if (shift == 4*4) { 5963 *str_ptr = '.'; 5964 str_ptr++; 5965 (*len)--; 5966 remove_leading_zeros = 1; 5967 } 5968 } 5969 return 0; 5970} 5971 5972 5973static int bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len) 5974{ 5975 str[0] = '\0'; 5976 (*len)--; 5977 return 0; 5978} 5979 5980int bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, 5981 u8 *version, u16 len) 5982{ 5983 struct bnx2x *bp; 5984 u32 spirom_ver = 0; 5985 int status = 0; 5986 u8 *ver_p = version; 5987 u16 remain_len = len; 5988 if (version == NULL || params == NULL) 5989 return -EINVAL; 5990 bp = params->bp; 5991 5992 /* Extract first external phy*/ 5993 version[0] = '\0'; 5994 spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr); 5995 5996 if (params->phy[EXT_PHY1].format_fw_ver) { 5997 status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver, 5998 ver_p, 5999 &remain_len); 6000 ver_p += (len - remain_len); 6001 } 6002 if ((params->num_phys == MAX_PHYS) && 6003 (params->phy[EXT_PHY2].ver_addr != 0)) { 6004 spirom_ver = REG_RD(bp, params->phy[EXT_PHY2].ver_addr); 6005 if (params->phy[EXT_PHY2].format_fw_ver) { 6006 *ver_p = '/'; 6007 ver_p++; 6008 remain_len--; 6009 status |= params->phy[EXT_PHY2].format_fw_ver( 6010 spirom_ver, 6011 ver_p, 6012 &remain_len); 6013 ver_p = version + (len - remain_len); 6014 } 6015 } 6016 *ver_p = '\0'; 6017 return status; 6018} 6019 6020static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, 6021 struct link_params *params) 6022{ 6023 u8 port = params->port; 6024 struct bnx2x *bp = params->bp; 6025 6026 if (phy->req_line_speed != SPEED_1000) { 6027 u32 md_devad = 0; 6028 6029 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n"); 6030 6031 if (!CHIP_IS_E3(bp)) { 6032 /* change the uni_phy_addr in the nig */ 6033 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD + 6034 port*0x18)); 6035 6036 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 6037 0x5); 6038 } 6039 6040 bnx2x_cl45_write(bp, phy, 6041 5, 6042 (MDIO_REG_BANK_AER_BLOCK + 6043 (MDIO_AER_BLOCK_AER_REG & 0xf)), 6044 0x2800); 6045 6046 bnx2x_cl45_write(bp, phy, 6047 5, 6048 (MDIO_REG_BANK_CL73_IEEEB0 + 6049 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)), 6050 0x6041); 6051 msleep(200); 6052 /* set aer mmd back */ 6053 bnx2x_set_aer_mmd(params, phy); 6054 6055 if (!CHIP_IS_E3(bp)) { 6056 /* and md_devad */ 6057 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 6058 md_devad); 6059 } 6060 } else { 6061 u16 mii_ctrl; 6062 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n"); 6063 bnx2x_cl45_read(bp, phy, 5, 6064 (MDIO_REG_BANK_COMBO_IEEE0 + 6065 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)), 6066 &mii_ctrl); 6067 bnx2x_cl45_write(bp, phy, 5, 6068 (MDIO_REG_BANK_COMBO_IEEE0 + 6069 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)), 6070 mii_ctrl | 6071 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK); 6072 } 6073} 6074 6075int bnx2x_set_led(struct link_params *params, 6076 struct link_vars *vars, u8 mode, u32 speed) 6077{ 6078 u8 port = params->port; 6079 u16 hw_led_mode = params->hw_led_mode; 6080 int rc = 0; 6081 u8 phy_idx; 6082 u32 tmp; 6083 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; 6084 struct bnx2x *bp = params->bp; 6085 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode); 6086 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n", 6087 speed, hw_led_mode); 6088 /* In case */ 6089 for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) { 6090 if (params->phy[phy_idx].set_link_led) { 6091 params->phy[phy_idx].set_link_led( 6092 ¶ms->phy[phy_idx], params, mode); 6093 } 6094 } 6095 6096 switch (mode) { 6097 case LED_MODE_FRONT_PANEL_OFF: 6098 case LED_MODE_OFF: 6099 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0); 6100 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 6101 SHARED_HW_CFG_LED_MAC1); 6102 6103 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); 6104 if (params->phy[EXT_PHY1].type == 6105 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) 6106 EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp & 0xfff1); 6107 else { 6108 EMAC_WR(bp, EMAC_REG_EMAC_LED, 6109 (tmp | EMAC_LED_OVERRIDE)); 6110 } 6111 break; 6112 6113 case LED_MODE_OPER: 6114 /* 6115 * For all other phys, OPER mode is same as ON, so in case 6116 * link is down, do nothing 6117 */ 6118 if (!vars->link_up) 6119 break; 6120 case LED_MODE_ON: 6121 if (((params->phy[EXT_PHY1].type == 6122 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) || 6123 (params->phy[EXT_PHY1].type == 6124 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722)) && 6125 CHIP_IS_E2(bp) && params->num_phys == 2) { 6126 /* 6127 * This is a work-around for E2+8727 Configurations 6128 */ 6129 if (mode == LED_MODE_ON || 6130 speed == SPEED_10000){ 6131 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); 6132 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1); 6133 6134 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); 6135 EMAC_WR(bp, EMAC_REG_EMAC_LED, 6136 (tmp | EMAC_LED_OVERRIDE)); 6137 /* 6138 * return here without enabling traffic 6139 * LED blink and setting rate in ON mode. 6140 * In oper mode, enabling LED blink 6141 * and setting rate is needed. 6142 */ 6143 if (mode == LED_MODE_ON) 6144 return rc; 6145 } 6146 } else if (SINGLE_MEDIA_DIRECT(params)) { 6147 /* 6148 * This is a work-around for HW issue found when link 6149 * is up in CL73 6150 */ 6151 if ((!CHIP_IS_E3(bp)) || 6152 (CHIP_IS_E3(bp) && 6153 mode == LED_MODE_ON)) 6154 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1); 6155 6156 if (CHIP_IS_E1x(bp) || 6157 CHIP_IS_E2(bp) || 6158 (mode == LED_MODE_ON)) 6159 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); 6160 else 6161 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 6162 hw_led_mode); 6163 } else if ((params->phy[EXT_PHY1].type == 6164 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) && 6165 (mode != LED_MODE_OPER)) { 6166 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); 6167 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); 6168 EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp | 0x3); 6169 } else 6170 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 6171 hw_led_mode); 6172 6173 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0); 6174 /* Set blinking rate to ~15.9Hz */ 6175 if (CHIP_IS_E3(bp)) 6176 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4, 6177 LED_BLINK_RATE_VAL_E3); 6178 else 6179 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4, 6180 LED_BLINK_RATE_VAL_E1X_E2); 6181 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 + 6182 port*4, 1); 6183 if ((params->phy[EXT_PHY1].type != 6184 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) && 6185 (mode != LED_MODE_OPER)) { 6186 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); 6187 EMAC_WR(bp, EMAC_REG_EMAC_LED, 6188 (tmp & (~EMAC_LED_OVERRIDE))); 6189 } 6190 6191 if (CHIP_IS_E1(bp) && 6192 ((speed == SPEED_2500) || 6193 (speed == SPEED_1000) || 6194 (speed == SPEED_100) || 6195 (speed == SPEED_10))) { 6196 /* 6197 * On Everest 1 Ax chip versions for speeds less than 6198 * 10G LED scheme is different 6199 */ 6200 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 6201 + port*4, 1); 6202 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + 6203 port*4, 0); 6204 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 + 6205 port*4, 1); 6206 } 6207 break; 6208 6209 default: 6210 rc = -EINVAL; 6211 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n", 6212 mode); 6213 break; 6214 } 6215 return rc; 6216 6217} 6218 6219/* 6220 * This function comes to reflect the actual link state read DIRECTLY from the 6221 * HW 6222 */ 6223int bnx2x_test_link(struct link_params *params, struct link_vars *vars, 6224 u8 is_serdes) 6225{ 6226 struct bnx2x *bp = params->bp; 6227 u16 gp_status = 0, phy_index = 0; 6228 u8 ext_phy_link_up = 0, serdes_phy_type; 6229 struct link_vars temp_vars; 6230 struct bnx2x_phy *int_phy = ¶ms->phy[INT_PHY]; 6231 6232 if (CHIP_IS_E3(bp)) { 6233 u16 link_up; 6234 if (params->req_line_speed[LINK_CONFIG_IDX(INT_PHY)] 6235 > SPEED_10000) { 6236 /* Check 20G link */ 6237 bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD, 6238 1, &link_up); 6239 bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD, 6240 1, &link_up); 6241 link_up &= (1<<2); 6242 } else { 6243 /* Check 10G link and below*/ 6244 u8 lane = bnx2x_get_warpcore_lane(int_phy, params); 6245 bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD, 6246 MDIO_WC_REG_GP2_STATUS_GP_2_1, 6247 &gp_status); 6248 gp_status = ((gp_status >> 8) & 0xf) | 6249 ((gp_status >> 12) & 0xf); 6250 link_up = gp_status & (1 << lane); 6251 } 6252 if (!link_up) 6253 return -ESRCH; 6254 } else { 6255 CL22_RD_OVER_CL45(bp, int_phy, 6256 MDIO_REG_BANK_GP_STATUS, 6257 MDIO_GP_STATUS_TOP_AN_STATUS1, 6258 &gp_status); 6259 /* link is up only if both local phy and external phy are up */ 6260 if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)) 6261 return -ESRCH; 6262 } 6263 /* In XGXS loopback mode, do not check external PHY */ 6264 if (params->loopback_mode == LOOPBACK_XGXS) 6265 return 0; 6266 6267 switch (params->num_phys) { 6268 case 1: 6269 /* No external PHY */ 6270 return 0; 6271 case 2: 6272 ext_phy_link_up = params->phy[EXT_PHY1].read_status( 6273 ¶ms->phy[EXT_PHY1], 6274 params, &temp_vars); 6275 break; 6276 case 3: /* Dual Media */ 6277 for (phy_index = EXT_PHY1; phy_index < params->num_phys; 6278 phy_index++) { 6279 serdes_phy_type = ((params->phy[phy_index].media_type == 6280 ETH_PHY_SFP_FIBER) || 6281 (params->phy[phy_index].media_type == 6282 ETH_PHY_XFP_FIBER) || 6283 (params->phy[phy_index].media_type == 6284 ETH_PHY_DA_TWINAX)); 6285 6286 if (is_serdes != serdes_phy_type) 6287 continue; 6288 if (params->phy[phy_index].read_status) { 6289 ext_phy_link_up |= 6290 params->phy[phy_index].read_status( 6291 ¶ms->phy[phy_index], 6292 params, &temp_vars); 6293 } 6294 } 6295 break; 6296 } 6297 if (ext_phy_link_up) 6298 return 0; 6299 return -ESRCH; 6300} 6301 6302static int bnx2x_link_initialize(struct link_params *params, 6303 struct link_vars *vars) 6304{ 6305 int rc = 0; 6306 u8 phy_index, non_ext_phy; 6307 struct bnx2x *bp = params->bp; 6308 /* 6309 * In case of external phy existence, the line speed would be the 6310 * line speed linked up by the external phy. In case it is direct 6311 * only, then the line_speed during initialization will be 6312 * equal to the req_line_speed 6313 */ 6314 vars->line_speed = params->phy[INT_PHY].req_line_speed; 6315 6316 /* 6317 * Initialize the internal phy in case this is a direct board 6318 * (no external phys), or this board has external phy which requires 6319 * to first. 6320 */ 6321 if (!USES_WARPCORE(bp)) 6322 bnx2x_prepare_xgxs(¶ms->phy[INT_PHY], params, vars); 6323 /* init ext phy and enable link state int */ 6324 non_ext_phy = (SINGLE_MEDIA_DIRECT(params) || 6325 (params->loopback_mode == LOOPBACK_XGXS)); 6326 6327 if (non_ext_phy || 6328 (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) || 6329 (params->loopback_mode == LOOPBACK_EXT_PHY)) { 6330 struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; 6331 if (vars->line_speed == SPEED_AUTO_NEG && 6332 (CHIP_IS_E1x(bp) || 6333 CHIP_IS_E2(bp))) 6334 bnx2x_set_parallel_detection(phy, params); 6335 if (params->phy[INT_PHY].config_init) 6336 params->phy[INT_PHY].config_init(phy, 6337 params, 6338 vars); 6339 } 6340 6341 /* Init external phy*/ 6342 if (non_ext_phy) { 6343 if (params->phy[INT_PHY].supported & 6344 SUPPORTED_FIBRE) 6345 vars->link_status |= LINK_STATUS_SERDES_LINK; 6346 } else { 6347 for (phy_index = EXT_PHY1; phy_index < params->num_phys; 6348 phy_index++) { 6349 /* 6350 * No need to initialize second phy in case of first 6351 * phy only selection. In case of second phy, we do 6352 * need to initialize the first phy, since they are 6353 * connected. 6354 */ 6355 if (params->phy[phy_index].supported & 6356 SUPPORTED_FIBRE) 6357 vars->link_status |= LINK_STATUS_SERDES_LINK; 6358 6359 if (phy_index == EXT_PHY2 && 6360 (bnx2x_phy_selection(params) == 6361 PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) { 6362 DP(NETIF_MSG_LINK, 6363 "Not initializing second phy\n"); 6364 continue; 6365 } 6366 params->phy[phy_index].config_init( 6367 ¶ms->phy[phy_index], 6368 params, vars); 6369 } 6370 } 6371 /* Reset the interrupt indication after phy was initialized */ 6372 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + 6373 params->port*4, 6374 (NIG_STATUS_XGXS0_LINK10G | 6375 NIG_STATUS_XGXS0_LINK_STATUS | 6376 NIG_STATUS_SERDES0_LINK_STATUS | 6377 NIG_MASK_MI_INT)); 6378 bnx2x_update_mng(params, vars->link_status); 6379 return rc; 6380} 6381 6382static void bnx2x_int_link_reset(struct bnx2x_phy *phy, 6383 struct link_params *params) 6384{ 6385 /* reset the SerDes/XGXS */ 6386 REG_WR(params->bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, 6387 (0x1ff << (params->port*16))); 6388} 6389 6390static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy, 6391 struct link_params *params) 6392{ 6393 struct bnx2x *bp = params->bp; 6394 u8 gpio_port; 6395 /* HW reset */ 6396 if (CHIP_IS_E2(bp)) 6397 gpio_port = BP_PATH(bp); 6398 else 6399 gpio_port = params->port; 6400 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 6401 MISC_REGISTERS_GPIO_OUTPUT_LOW, 6402 gpio_port); 6403 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 6404 MISC_REGISTERS_GPIO_OUTPUT_LOW, 6405 gpio_port); 6406 DP(NETIF_MSG_LINK, "reset external PHY\n"); 6407} 6408 6409static int bnx2x_update_link_down(struct link_params *params, 6410 struct link_vars *vars) 6411{ 6412 struct bnx2x *bp = params->bp; 6413 u8 port = params->port; 6414 6415 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port); 6416 bnx2x_set_led(params, vars, LED_MODE_OFF, 0); 6417 vars->phy_flags &= ~PHY_PHYSICAL_LINK_FLAG; 6418 /* indicate no mac active */ 6419 vars->mac_type = MAC_TYPE_NONE; 6420 6421 /* update shared memory */ 6422 vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK | 6423 LINK_STATUS_LINK_UP | 6424 LINK_STATUS_PHYSICAL_LINK_FLAG | 6425 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | 6426 LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | 6427 LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | 6428 LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK); 6429 vars->line_speed = 0; 6430 bnx2x_update_mng(params, vars->link_status); 6431 6432 /* activate nig drain */ 6433 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); 6434 6435 /* disable emac */ 6436 if (!CHIP_IS_E3(bp)) 6437 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); 6438 6439 msleep(10); 6440 /* reset BigMac/Xmac */ 6441 if (CHIP_IS_E1x(bp) || 6442 CHIP_IS_E2(bp)) { 6443 bnx2x_bmac_rx_disable(bp, params->port); 6444 REG_WR(bp, GRCBASE_MISC + 6445 MISC_REGISTERS_RESET_REG_2_CLEAR, 6446 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); 6447 } 6448 if (CHIP_IS_E3(bp)) { 6449 bnx2x_xmac_disable(params); 6450 bnx2x_umac_disable(params); 6451 } 6452 6453 return 0; 6454} 6455 6456static int bnx2x_update_link_up(struct link_params *params, 6457 struct link_vars *vars, 6458 u8 link_10g) 6459{ 6460 struct bnx2x *bp = params->bp; 6461 u8 port = params->port; 6462 int rc = 0; 6463 6464 vars->link_status |= (LINK_STATUS_LINK_UP | 6465 LINK_STATUS_PHYSICAL_LINK_FLAG); 6466 vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG; 6467 6468 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) 6469 vars->link_status |= 6470 LINK_STATUS_TX_FLOW_CONTROL_ENABLED; 6471 6472 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) 6473 vars->link_status |= 6474 LINK_STATUS_RX_FLOW_CONTROL_ENABLED; 6475 if (USES_WARPCORE(bp)) { 6476 if (link_10g) { 6477 if (bnx2x_xmac_enable(params, vars, 0) == 6478 -ESRCH) { 6479 DP(NETIF_MSG_LINK, "Found errors on XMAC\n"); 6480 vars->link_up = 0; 6481 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG; 6482 vars->link_status &= ~LINK_STATUS_LINK_UP; 6483 } 6484 } else 6485 bnx2x_umac_enable(params, vars, 0); 6486 bnx2x_set_led(params, vars, 6487 LED_MODE_OPER, vars->line_speed); 6488 } 6489 if ((CHIP_IS_E1x(bp) || 6490 CHIP_IS_E2(bp))) { 6491 if (link_10g) { 6492 if (bnx2x_bmac_enable(params, vars, 0) == 6493 -ESRCH) { 6494 DP(NETIF_MSG_LINK, "Found errors on BMAC\n"); 6495 vars->link_up = 0; 6496 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG; 6497 vars->link_status &= ~LINK_STATUS_LINK_UP; 6498 } 6499 6500 bnx2x_set_led(params, vars, 6501 LED_MODE_OPER, SPEED_10000); 6502 } else { 6503 rc = bnx2x_emac_program(params, vars); 6504 bnx2x_emac_enable(params, vars, 0); 6505 6506 /* AN complete? */ 6507 if ((vars->link_status & 6508 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) 6509 && (!(vars->phy_flags & PHY_SGMII_FLAG)) && 6510 SINGLE_MEDIA_DIRECT(params)) 6511 bnx2x_set_gmii_tx_driver(params); 6512 } 6513 } 6514 6515 /* PBF - link up */ 6516 if (CHIP_IS_E1x(bp)) 6517 rc |= bnx2x_pbf_update(params, vars->flow_ctrl, 6518 vars->line_speed); 6519 6520 /* disable drain */ 6521 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0); 6522 6523 /* update shared memory */ 6524 bnx2x_update_mng(params, vars->link_status); 6525 msleep(20); 6526 return rc; 6527} 6528/* 6529 * The bnx2x_link_update function should be called upon link 6530 * interrupt. 6531 * Link is considered up as follows: 6532 * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs 6533 * to be up 6534 * - SINGLE_MEDIA - The link between the 577xx and the external 6535 * phy (XGXS) need to up as well as the external link of the 6536 * phy (PHY_EXT1) 6537 * - DUAL_MEDIA - The link between the 577xx and the first 6538 * external phy needs to be up, and at least one of the 2 6539 * external phy link must be up. 6540 */ 6541int bnx2x_link_update(struct link_params *params, struct link_vars *vars) 6542{ 6543 struct bnx2x *bp = params->bp; 6544 struct link_vars phy_vars[MAX_PHYS]; 6545 u8 port = params->port; 6546 u8 link_10g_plus, phy_index; 6547 u8 ext_phy_link_up = 0, cur_link_up; 6548 int rc = 0; 6549 u8 is_mi_int = 0; 6550 u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed; 6551 u8 active_external_phy = INT_PHY; 6552 vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG; 6553 for (phy_index = INT_PHY; phy_index < params->num_phys; 6554 phy_index++) { 6555 phy_vars[phy_index].flow_ctrl = 0; 6556 phy_vars[phy_index].link_status = 0; 6557 phy_vars[phy_index].line_speed = 0; 6558 phy_vars[phy_index].duplex = DUPLEX_FULL; 6559 phy_vars[phy_index].phy_link_up = 0; 6560 phy_vars[phy_index].link_up = 0; 6561 phy_vars[phy_index].fault_detected = 0; 6562 } 6563 6564 if (USES_WARPCORE(bp)) 6565 bnx2x_set_aer_mmd(params, ¶ms->phy[INT_PHY]); 6566 6567 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", 6568 port, (vars->phy_flags & PHY_XGXS_FLAG), 6569 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); 6570 6571 is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + 6572 port*0x18) > 0); 6573 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n", 6574 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), 6575 is_mi_int, 6576 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c)); 6577 6578 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n", 6579 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), 6580 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); 6581 6582 /* disable emac */ 6583 if (!CHIP_IS_E3(bp)) 6584 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); 6585 6586 /* 6587 * Step 1: 6588 * Check external link change only for external phys, and apply 6589 * priority selection between them in case the link on both phys 6590 * is up. Note that instead of the common vars, a temporary 6591 * vars argument is used since each phy may have different link/ 6592 * speed/duplex result 6593 */ 6594 for (phy_index = EXT_PHY1; phy_index < params->num_phys; 6595 phy_index++) { 6596 struct bnx2x_phy *phy = ¶ms->phy[phy_index]; 6597 if (!phy->read_status) 6598 continue; 6599 /* Read link status and params of this ext phy */ 6600 cur_link_up = phy->read_status(phy, params, 6601 &phy_vars[phy_index]); 6602 if (cur_link_up) { 6603 DP(NETIF_MSG_LINK, "phy in index %d link is up\n", 6604 phy_index); 6605 } else { 6606 DP(NETIF_MSG_LINK, "phy in index %d link is down\n", 6607 phy_index); 6608 continue; 6609 } 6610 6611 if (!ext_phy_link_up) { 6612 ext_phy_link_up = 1; 6613 active_external_phy = phy_index; 6614 } else { 6615 switch (bnx2x_phy_selection(params)) { 6616 case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT: 6617 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: 6618 /* 6619 * In this option, the first PHY makes sure to pass the 6620 * traffic through itself only. 6621 * Its not clear how to reset the link on the second phy 6622 */ 6623 active_external_phy = EXT_PHY1; 6624 break; 6625 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: 6626 /* 6627 * In this option, the first PHY makes sure to pass the 6628 * traffic through the second PHY. 6629 */ 6630 active_external_phy = EXT_PHY2; 6631 break; 6632 default: 6633 /* 6634 * Link indication on both PHYs with the following cases 6635 * is invalid: 6636 * - FIRST_PHY means that second phy wasn't initialized, 6637 * hence its link is expected to be down 6638 * - SECOND_PHY means that first phy should not be able 6639 * to link up by itself (using configuration) 6640 * - DEFAULT should be overriden during initialiazation 6641 */ 6642 DP(NETIF_MSG_LINK, "Invalid link indication" 6643 "mpc=0x%x. DISABLING LINK !!!\n", 6644 params->multi_phy_config); 6645 ext_phy_link_up = 0; 6646 break; 6647 } 6648 } 6649 } 6650 prev_line_speed = vars->line_speed; 6651 /* 6652 * Step 2: 6653 * Read the status of the internal phy. In case of 6654 * DIRECT_SINGLE_MEDIA board, this link is the external link, 6655 * otherwise this is the link between the 577xx and the first 6656 * external phy 6657 */ 6658 if (params->phy[INT_PHY].read_status) 6659 params->phy[INT_PHY].read_status( 6660 ¶ms->phy[INT_PHY], 6661 params, vars); 6662 /* 6663 * The INT_PHY flow control reside in the vars. This include the 6664 * case where the speed or flow control are not set to AUTO. 6665 * Otherwise, the active external phy flow control result is set 6666 * to the vars. The ext_phy_line_speed is needed to check if the 6667 * speed is different between the internal phy and external phy. 6668 * This case may be result of intermediate link speed change. 6669 */ 6670 if (active_external_phy > INT_PHY) { 6671 vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl; 6672 /* 6673 * Link speed is taken from the XGXS. AN and FC result from 6674 * the external phy. 6675 */ 6676 vars->link_status |= phy_vars[active_external_phy].link_status; 6677 6678 /* 6679 * if active_external_phy is first PHY and link is up - disable 6680 * disable TX on second external PHY 6681 */ 6682 if (active_external_phy == EXT_PHY1) { 6683 if (params->phy[EXT_PHY2].phy_specific_func) { 6684 DP(NETIF_MSG_LINK, 6685 "Disabling TX on EXT_PHY2\n"); 6686 params->phy[EXT_PHY2].phy_specific_func( 6687 ¶ms->phy[EXT_PHY2], 6688 params, DISABLE_TX); 6689 } 6690 } 6691 6692 ext_phy_line_speed = phy_vars[active_external_phy].line_speed; 6693 vars->duplex = phy_vars[active_external_phy].duplex; 6694 if (params->phy[active_external_phy].supported & 6695 SUPPORTED_FIBRE) 6696 vars->link_status |= LINK_STATUS_SERDES_LINK; 6697 else 6698 vars->link_status &= ~LINK_STATUS_SERDES_LINK; 6699 DP(NETIF_MSG_LINK, "Active external phy selected: %x\n", 6700 active_external_phy); 6701 } 6702 6703 for (phy_index = EXT_PHY1; phy_index < params->num_phys; 6704 phy_index++) { 6705 if (params->phy[phy_index].flags & 6706 FLAGS_REARM_LATCH_SIGNAL) { 6707 bnx2x_rearm_latch_signal(bp, port, 6708 phy_index == 6709 active_external_phy); 6710 break; 6711 } 6712 } 6713 DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x," 6714 " ext_phy_line_speed = %d\n", vars->flow_ctrl, 6715 vars->link_status, ext_phy_line_speed); 6716 /* 6717 * Upon link speed change set the NIG into drain mode. Comes to 6718 * deals with possible FIFO glitch due to clk change when speed 6719 * is decreased without link down indicator 6720 */ 6721 6722 if (vars->phy_link_up) { 6723 if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up && 6724 (ext_phy_line_speed != vars->line_speed)) { 6725 DP(NETIF_MSG_LINK, "Internal link speed %d is" 6726 " different than the external" 6727 " link speed %d\n", vars->line_speed, 6728 ext_phy_line_speed); 6729 vars->phy_link_up = 0; 6730 } else if (prev_line_speed != vars->line_speed) { 6731 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 6732 0); 6733 msleep(1); 6734 } 6735 } 6736 6737 /* anything 10 and over uses the bmac */ 6738 link_10g_plus = (vars->line_speed >= SPEED_10000); 6739 6740 bnx2x_link_int_ack(params, vars, link_10g_plus); 6741 6742 /* 6743 * In case external phy link is up, and internal link is down 6744 * (not initialized yet probably after link initialization, it 6745 * needs to be initialized. 6746 * Note that after link down-up as result of cable plug, the xgxs 6747 * link would probably become up again without the need 6748 * initialize it 6749 */ 6750 if (!(SINGLE_MEDIA_DIRECT(params))) { 6751 DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d," 6752 " init_preceding = %d\n", ext_phy_link_up, 6753 vars->phy_link_up, 6754 params->phy[EXT_PHY1].flags & 6755 FLAGS_INIT_XGXS_FIRST); 6756 if (!(params->phy[EXT_PHY1].flags & 6757 FLAGS_INIT_XGXS_FIRST) 6758 && ext_phy_link_up && !vars->phy_link_up) { 6759 vars->line_speed = ext_phy_line_speed; 6760 if (vars->line_speed < SPEED_1000) 6761 vars->phy_flags |= PHY_SGMII_FLAG; 6762 else 6763 vars->phy_flags &= ~PHY_SGMII_FLAG; 6764 6765 if (params->phy[INT_PHY].config_init) 6766 params->phy[INT_PHY].config_init( 6767 ¶ms->phy[INT_PHY], params, 6768 vars); 6769 } 6770 } 6771 /* 6772 * Link is up only if both local phy and external phy (in case of 6773 * non-direct board) are up and no fault detected on active PHY. 6774 */ 6775 vars->link_up = (vars->phy_link_up && 6776 (ext_phy_link_up || 6777 SINGLE_MEDIA_DIRECT(params)) && 6778 (phy_vars[active_external_phy].fault_detected == 0)); 6779 6780 if (vars->link_up) 6781 rc = bnx2x_update_link_up(params, vars, link_10g_plus); 6782 else 6783 rc = bnx2x_update_link_down(params, vars); 6784 6785 return rc; 6786} 6787 6788 6789/*****************************************************************************/ 6790/* External Phy section */ 6791/*****************************************************************************/ 6792void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port) 6793{ 6794 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 6795 MISC_REGISTERS_GPIO_OUTPUT_LOW, port); 6796 msleep(1); 6797 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 6798 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); 6799} 6800 6801static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port, 6802 u32 spirom_ver, u32 ver_addr) 6803{ 6804 DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n", 6805 (u16)(spirom_ver>>16), (u16)spirom_ver, port); 6806 6807 if (ver_addr) 6808 REG_WR(bp, ver_addr, spirom_ver); 6809} 6810 6811static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, 6812 struct bnx2x_phy *phy, 6813 u8 port) 6814{ 6815 u16 fw_ver1, fw_ver2; 6816 6817 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 6818 MDIO_PMA_REG_ROM_VER1, &fw_ver1); 6819 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 6820 MDIO_PMA_REG_ROM_VER2, &fw_ver2); 6821 bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2), 6822 phy->ver_addr); 6823} 6824 6825static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp, 6826 struct bnx2x_phy *phy, 6827 struct link_vars *vars) 6828{ 6829 u16 val; 6830 bnx2x_cl45_read(bp, phy, 6831 MDIO_AN_DEVAD, 6832 MDIO_AN_REG_STATUS, &val); 6833 bnx2x_cl45_read(bp, phy, 6834 MDIO_AN_DEVAD, 6835 MDIO_AN_REG_STATUS, &val); 6836 if (val & (1<<5)) 6837 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; 6838 if ((val & (1<<0)) == 0) 6839 vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED; 6840} 6841 6842/******************************************************************/ 6843/* common BCM8073/BCM8727 PHY SECTION */ 6844/******************************************************************/ 6845static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy, 6846 struct link_params *params, 6847 struct link_vars *vars) 6848{ 6849 struct bnx2x *bp = params->bp; 6850 if (phy->req_line_speed == SPEED_10 || 6851 phy->req_line_speed == SPEED_100) { 6852 vars->flow_ctrl = phy->req_flow_ctrl; 6853 return; 6854 } 6855 6856 if (bnx2x_ext_phy_resolve_fc(phy, params, vars) && 6857 (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) { 6858 u16 pause_result; 6859 u16 ld_pause; /* local */ 6860 u16 lp_pause; /* link partner */ 6861 bnx2x_cl45_read(bp, phy, 6862 MDIO_AN_DEVAD, 6863 MDIO_AN_REG_CL37_FC_LD, &ld_pause); 6864 6865 bnx2x_cl45_read(bp, phy, 6866 MDIO_AN_DEVAD, 6867 MDIO_AN_REG_CL37_FC_LP, &lp_pause); 6868 pause_result = (ld_pause & 6869 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5; 6870 pause_result |= (lp_pause & 6871 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7; 6872 6873 bnx2x_pause_resolve(vars, pause_result); 6874 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n", 6875 pause_result); 6876 } 6877} 6878static int bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, 6879 struct bnx2x_phy *phy, 6880 u8 port) 6881{ 6882 u32 count = 0; 6883 u16 fw_ver1, fw_msgout; 6884 int rc = 0; 6885 6886 /* Boot port from external ROM */ 6887 /* EDC grst */ 6888 bnx2x_cl45_write(bp, phy, 6889 MDIO_PMA_DEVAD, 6890 MDIO_PMA_REG_GEN_CTRL, 6891 0x0001); 6892 6893 /* ucode reboot and rst */ 6894 bnx2x_cl45_write(bp, phy, 6895 MDIO_PMA_DEVAD, 6896 MDIO_PMA_REG_GEN_CTRL, 6897 0x008c); 6898 6899 bnx2x_cl45_write(bp, phy, 6900 MDIO_PMA_DEVAD, 6901 MDIO_PMA_REG_MISC_CTRL1, 0x0001); 6902 6903 /* Reset internal microprocessor */ 6904 bnx2x_cl45_write(bp, phy, 6905 MDIO_PMA_DEVAD, 6906 MDIO_PMA_REG_GEN_CTRL, 6907 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); 6908 6909 /* Release srst bit */ 6910 bnx2x_cl45_write(bp, phy, 6911 MDIO_PMA_DEVAD, 6912 MDIO_PMA_REG_GEN_CTRL, 6913 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); 6914 6915 /* Delay 100ms per the PHY specifications */ 6916 msleep(100); 6917 6918 /* 8073 sometimes taking longer to download */ 6919 do { 6920 count++; 6921 if (count > 300) { 6922 DP(NETIF_MSG_LINK, 6923 "bnx2x_8073_8727_external_rom_boot port %x:" 6924 "Download failed. fw version = 0x%x\n", 6925 port, fw_ver1); 6926 rc = -EINVAL; 6927 break; 6928 } 6929 6930 bnx2x_cl45_read(bp, phy, 6931 MDIO_PMA_DEVAD, 6932 MDIO_PMA_REG_ROM_VER1, &fw_ver1); 6933 bnx2x_cl45_read(bp, phy, 6934 MDIO_PMA_DEVAD, 6935 MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout); 6936 6937 msleep(1); 6938 } while (fw_ver1 == 0 || fw_ver1 == 0x4321 || 6939 ((fw_msgout & 0xff) != 0x03 && (phy->type == 6940 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))); 6941 6942 /* Clear ser_boot_ctl bit */ 6943 bnx2x_cl45_write(bp, phy, 6944 MDIO_PMA_DEVAD, 6945 MDIO_PMA_REG_MISC_CTRL1, 0x0000); 6946 bnx2x_save_bcm_spirom_ver(bp, phy, port); 6947 6948 DP(NETIF_MSG_LINK, 6949 "bnx2x_8073_8727_external_rom_boot port %x:" 6950 "Download complete. fw version = 0x%x\n", 6951 port, fw_ver1); 6952 6953 return rc; 6954} 6955 6956/******************************************************************/ 6957/* BCM8073 PHY SECTION */ 6958/******************************************************************/ 6959static int bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy) 6960{ 6961 /* This is only required for 8073A1, version 102 only */ 6962 u16 val; 6963 6964 /* Read 8073 HW revision*/ 6965 bnx2x_cl45_read(bp, phy, 6966 MDIO_PMA_DEVAD, 6967 MDIO_PMA_REG_8073_CHIP_REV, &val); 6968 6969 if (val != 1) { 6970 /* No need to workaround in 8073 A1 */ 6971 return 0; 6972 } 6973 6974 bnx2x_cl45_read(bp, phy, 6975 MDIO_PMA_DEVAD, 6976 MDIO_PMA_REG_ROM_VER2, &val); 6977 6978 /* SNR should be applied only for version 0x102 */ 6979 if (val != 0x102) 6980 return 0; 6981 6982 return 1; 6983} 6984 6985static int bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy) 6986{ 6987 u16 val, cnt, cnt1 ; 6988 6989 bnx2x_cl45_read(bp, phy, 6990 MDIO_PMA_DEVAD, 6991 MDIO_PMA_REG_8073_CHIP_REV, &val); 6992 6993 if (val > 0) { 6994 /* No need to workaround in 8073 A1 */ 6995 return 0; 6996 } 6997 /* XAUI workaround in 8073 A0: */ 6998 6999 /* 7000 * After loading the boot ROM and restarting Autoneg, poll 7001 * Dev1, Reg $C820: 7002 */ 7003 7004 for (cnt = 0; cnt < 1000; cnt++) { 7005 bnx2x_cl45_read(bp, phy, 7006 MDIO_PMA_DEVAD, 7007 MDIO_PMA_REG_8073_SPEED_LINK_STATUS, 7008 &val); 7009 /* 7010 * If bit [14] = 0 or bit [13] = 0, continue on with 7011 * system initialization (XAUI work-around not required, as 7012 * these bits indicate 2.5G or 1G link up). 7013 */ 7014 if (!(val & (1<<14)) || !(val & (1<<13))) { 7015 DP(NETIF_MSG_LINK, "XAUI work-around not required\n"); 7016 return 0; 7017 } else if (!(val & (1<<15))) { 7018 DP(NETIF_MSG_LINK, "bit 15 went off\n"); 7019 /* 7020 * If bit 15 is 0, then poll Dev1, Reg $C841 until it's 7021 * MSB (bit15) goes to 1 (indicating that the XAUI 7022 * workaround has completed), then continue on with 7023 * system initialization. 7024 */ 7025 for (cnt1 = 0; cnt1 < 1000; cnt1++) { 7026 bnx2x_cl45_read(bp, phy, 7027 MDIO_PMA_DEVAD, 7028 MDIO_PMA_REG_8073_XAUI_WA, &val); 7029 if (val & (1<<15)) { 7030 DP(NETIF_MSG_LINK, 7031 "XAUI workaround has completed\n"); 7032 return 0; 7033 } 7034 msleep(3); 7035 } 7036 break; 7037 } 7038 msleep(3); 7039 } 7040 DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n"); 7041 return -EINVAL; 7042} 7043 7044static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy) 7045{ 7046 /* Force KR or KX */ 7047 bnx2x_cl45_write(bp, phy, 7048 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040); 7049 bnx2x_cl45_write(bp, phy, 7050 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b); 7051 bnx2x_cl45_write(bp, phy, 7052 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000); 7053 bnx2x_cl45_write(bp, phy, 7054 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000); 7055} 7056 7057static void bnx2x_8073_set_pause_cl37(struct link_params *params, 7058 struct bnx2x_phy *phy, 7059 struct link_vars *vars) 7060{ 7061 u16 cl37_val; 7062 struct bnx2x *bp = params->bp; 7063 bnx2x_cl45_read(bp, phy, 7064 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val); 7065 7066 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; 7067 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ 7068 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); 7069 if ((vars->ieee_fc & 7070 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) == 7071 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) { 7072 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC; 7073 } 7074 if ((vars->ieee_fc & 7075 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == 7076 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { 7077 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; 7078 } 7079 if ((vars->ieee_fc & 7080 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == 7081 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) { 7082 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; 7083 } 7084 DP(NETIF_MSG_LINK, 7085 "Ext phy AN advertize cl37 0x%x\n", cl37_val); 7086 7087 bnx2x_cl45_write(bp, phy, 7088 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val); 7089 msleep(500); 7090} 7091 7092static int bnx2x_8073_config_init(struct bnx2x_phy *phy, 7093 struct link_params *params, 7094 struct link_vars *vars) 7095{ 7096 struct bnx2x *bp = params->bp; 7097 u16 val = 0, tmp1; 7098 u8 gpio_port; 7099 DP(NETIF_MSG_LINK, "Init 8073\n"); 7100 7101 if (CHIP_IS_E2(bp)) 7102 gpio_port = BP_PATH(bp); 7103 else 7104 gpio_port = params->port; 7105 /* Restore normal power mode*/ 7106 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 7107 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); 7108 7109 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 7110 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); 7111 7112 /* enable LASI */ 7113 bnx2x_cl45_write(bp, phy, 7114 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, (1<<2)); 7115 bnx2x_cl45_write(bp, phy, 7116 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x0004); 7117 7118 bnx2x_8073_set_pause_cl37(params, phy, vars); 7119 7120 bnx2x_cl45_read(bp, phy, 7121 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); 7122 7123 bnx2x_cl45_read(bp, phy, 7124 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1); 7125 7126 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1); 7127 7128 /* Swap polarity if required - Must be done only in non-1G mode */ 7129 if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) { 7130 /* Configure the 8073 to swap _P and _N of the KR lines */ 7131 DP(NETIF_MSG_LINK, "Swapping polarity for the 8073\n"); 7132 /* 10G Rx/Tx and 1G Tx signal polarity swap */ 7133 bnx2x_cl45_read(bp, phy, 7134 MDIO_PMA_DEVAD, 7135 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val); 7136 bnx2x_cl45_write(bp, phy, 7137 MDIO_PMA_DEVAD, 7138 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, 7139 (val | (3<<9))); 7140 } 7141 7142 7143 /* Enable CL37 BAM */ 7144 if (REG_RD(bp, params->shmem_base + 7145 offsetof(struct shmem_region, dev_info. 7146 port_hw_config[params->port].default_cfg)) & 7147 PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) { 7148 7149 bnx2x_cl45_read(bp, phy, 7150 MDIO_AN_DEVAD, 7151 MDIO_AN_REG_8073_BAM, &val); 7152 bnx2x_cl45_write(bp, phy, 7153 MDIO_AN_DEVAD, 7154 MDIO_AN_REG_8073_BAM, val | 1); 7155 DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n"); 7156 } 7157 if (params->loopback_mode == LOOPBACK_EXT) { 7158 bnx2x_807x_force_10G(bp, phy); 7159 DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n"); 7160 return 0; 7161 } else { 7162 bnx2x_cl45_write(bp, phy, 7163 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002); 7164 } 7165 if (phy->req_line_speed != SPEED_AUTO_NEG) { 7166 if (phy->req_line_speed == SPEED_10000) { 7167 val = (1<<7); 7168 } else if (phy->req_line_speed == SPEED_2500) { 7169 val = (1<<5); 7170 /* 7171 * Note that 2.5G works only when used with 1G 7172 * advertisement 7173 */ 7174 } else 7175 val = (1<<5); 7176 } else { 7177 val = 0; 7178 if (phy->speed_cap_mask & 7179 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) 7180 val |= (1<<7); 7181 7182 /* Note that 2.5G works only when used with 1G advertisement */ 7183 if (phy->speed_cap_mask & 7184 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G | 7185 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) 7186 val |= (1<<5); 7187 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val); 7188 } 7189 7190 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val); 7191 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1); 7192 7193 if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) && 7194 (phy->req_line_speed == SPEED_AUTO_NEG)) || 7195 (phy->req_line_speed == SPEED_2500)) { 7196 u16 phy_ver; 7197 /* Allow 2.5G for A1 and above */ 7198 bnx2x_cl45_read(bp, phy, 7199 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, 7200 &phy_ver); 7201 DP(NETIF_MSG_LINK, "Add 2.5G\n"); 7202 if (phy_ver > 0) 7203 tmp1 |= 1; 7204 else 7205 tmp1 &= 0xfffe; 7206 } else { 7207 DP(NETIF_MSG_LINK, "Disable 2.5G\n"); 7208 tmp1 &= 0xfffe; 7209 } 7210 7211 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1); 7212 /* Add support for CL37 (passive mode) II */ 7213 7214 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1); 7215 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 7216 (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ? 7217 0x20 : 0x40))); 7218 7219 /* Add support for CL37 (passive mode) III */ 7220 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); 7221 7222 /* 7223 * The SNR will improve about 2db by changing BW and FEE main 7224 * tap. Rest commands are executed after link is up 7225 * Change FFE main cursor to 5 in EDC register 7226 */ 7227 if (bnx2x_8073_is_snr_needed(bp, phy)) 7228 bnx2x_cl45_write(bp, phy, 7229 MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN, 7230 0xFB0C); 7231 7232 /* Enable FEC (Forware Error Correction) Request in the AN */ 7233 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1); 7234 tmp1 |= (1<<15); 7235 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1); 7236 7237 bnx2x_ext_phy_set_pause(params, phy, vars); 7238 7239 /* Restart autoneg */ 7240 msleep(500); 7241 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); 7242 DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n", 7243 ((val & (1<<5)) > 0), ((val & (1<<7)) > 0)); 7244 return 0; 7245} 7246 7247static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, 7248 struct link_params *params, 7249 struct link_vars *vars) 7250{ 7251 struct bnx2x *bp = params->bp; 7252 u8 link_up = 0; 7253 u16 val1, val2; 7254 u16 link_status = 0; 7255 u16 an1000_status = 0; 7256 7257 bnx2x_cl45_read(bp, phy, 7258 MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1); 7259 7260 DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1); 7261 7262 /* clear the interrupt LASI status register */ 7263 bnx2x_cl45_read(bp, phy, 7264 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2); 7265 bnx2x_cl45_read(bp, phy, 7266 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1); 7267 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1); 7268 /* Clear MSG-OUT */ 7269 bnx2x_cl45_read(bp, phy, 7270 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1); 7271 7272 /* Check the LASI */ 7273 bnx2x_cl45_read(bp, phy, 7274 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2); 7275 7276 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2); 7277 7278 /* Check the link status */ 7279 bnx2x_cl45_read(bp, phy, 7280 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2); 7281 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2); 7282 7283 bnx2x_cl45_read(bp, phy, 7284 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); 7285 bnx2x_cl45_read(bp, phy, 7286 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); 7287 link_up = ((val1 & 4) == 4); 7288 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1); 7289 7290 if (link_up && 7291 ((phy->req_line_speed != SPEED_10000))) { 7292 if (bnx2x_8073_xaui_wa(bp, phy) != 0) 7293 return 0; 7294 } 7295 bnx2x_cl45_read(bp, phy, 7296 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status); 7297 bnx2x_cl45_read(bp, phy, 7298 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status); 7299 7300 /* Check the link status on 1.1.2 */ 7301 bnx2x_cl45_read(bp, phy, 7302 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); 7303 bnx2x_cl45_read(bp, phy, 7304 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); 7305 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x," 7306 "an_link_status=0x%x\n", val2, val1, an1000_status); 7307 7308 link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1))); 7309 if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) { 7310 /* 7311 * The SNR will improve about 2dbby changing the BW and FEE main 7312 * tap. The 1st write to change FFE main tap is set before 7313 * restart AN. Change PLL Bandwidth in EDC register 7314 */ 7315 bnx2x_cl45_write(bp, phy, 7316 MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH, 7317 0x26BC); 7318 7319 /* Change CDR Bandwidth in EDC register */ 7320 bnx2x_cl45_write(bp, phy, 7321 MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH, 7322 0x0333); 7323 } 7324 bnx2x_cl45_read(bp, phy, 7325 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS, 7326 &link_status); 7327 7328 /* Bits 0..2 --> speed detected, bits 13..15--> link is down */ 7329 if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) { 7330 link_up = 1; 7331 vars->line_speed = SPEED_10000; 7332 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n", 7333 params->port); 7334 } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) { 7335 link_up = 1; 7336 vars->line_speed = SPEED_2500; 7337 DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n", 7338 params->port); 7339 } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) { 7340 link_up = 1; 7341 vars->line_speed = SPEED_1000; 7342 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n", 7343 params->port); 7344 } else { 7345 link_up = 0; 7346 DP(NETIF_MSG_LINK, "port %x: External link is down\n", 7347 params->port); 7348 } 7349 7350 if (link_up) { 7351 /* Swap polarity if required */ 7352 if (params->lane_config & 7353 PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) { 7354 /* Configure the 8073 to swap P and N of the KR lines */ 7355 bnx2x_cl45_read(bp, phy, 7356 MDIO_XS_DEVAD, 7357 MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1); 7358 /* 7359 * Set bit 3 to invert Rx in 1G mode and clear this bit 7360 * when it`s in 10G mode. 7361 */ 7362 if (vars->line_speed == SPEED_1000) { 7363 DP(NETIF_MSG_LINK, "Swapping 1G polarity for" 7364 "the 8073\n"); 7365 val1 |= (1<<3); 7366 } else 7367 val1 &= ~(1<<3); 7368 7369 bnx2x_cl45_write(bp, phy, 7370 MDIO_XS_DEVAD, 7371 MDIO_XS_REG_8073_RX_CTRL_PCIE, 7372 val1); 7373 } 7374 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); 7375 bnx2x_8073_resolve_fc(phy, params, vars); 7376 vars->duplex = DUPLEX_FULL; 7377 } 7378 return link_up; 7379} 7380 7381static void bnx2x_8073_link_reset(struct bnx2x_phy *phy, 7382 struct link_params *params) 7383{ 7384 struct bnx2x *bp = params->bp; 7385 u8 gpio_port; 7386 if (CHIP_IS_E2(bp)) 7387 gpio_port = BP_PATH(bp); 7388 else 7389 gpio_port = params->port; 7390 DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n", 7391 gpio_port); 7392 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 7393 MISC_REGISTERS_GPIO_OUTPUT_LOW, 7394 gpio_port); 7395} 7396 7397/******************************************************************/ 7398/* BCM8705 PHY SECTION */ 7399/******************************************************************/ 7400static int bnx2x_8705_config_init(struct bnx2x_phy *phy, 7401 struct link_params *params, 7402 struct link_vars *vars) 7403{ 7404 struct bnx2x *bp = params->bp; 7405 DP(NETIF_MSG_LINK, "init 8705\n"); 7406 /* Restore normal power mode*/ 7407 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 7408 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); 7409 /* HW reset */ 7410 bnx2x_ext_phy_hw_reset(bp, params->port); 7411 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); 7412 bnx2x_wait_reset_complete(bp, phy, params); 7413 7414 bnx2x_cl45_write(bp, phy, 7415 MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288); 7416 bnx2x_cl45_write(bp, phy, 7417 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf); 7418 bnx2x_cl45_write(bp, phy, 7419 MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100); 7420 bnx2x_cl45_write(bp, phy, 7421 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1); 7422 /* BCM8705 doesn't have microcode, hence the 0 */ 7423 bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0); 7424 return 0; 7425} 7426 7427static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy, 7428 struct link_params *params, 7429 struct link_vars *vars) 7430{ 7431 u8 link_up = 0; 7432 u16 val1, rx_sd; 7433 struct bnx2x *bp = params->bp; 7434 DP(NETIF_MSG_LINK, "read status 8705\n"); 7435 bnx2x_cl45_read(bp, phy, 7436 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1); 7437 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); 7438 7439 bnx2x_cl45_read(bp, phy, 7440 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1); 7441 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); 7442 7443 bnx2x_cl45_read(bp, phy, 7444 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd); 7445 7446 bnx2x_cl45_read(bp, phy, 7447 MDIO_PMA_DEVAD, 0xc809, &val1); 7448 bnx2x_cl45_read(bp, phy, 7449 MDIO_PMA_DEVAD, 0xc809, &val1); 7450 7451 DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1); 7452 link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0)); 7453 if (link_up) { 7454 vars->line_speed = SPEED_10000; 7455 bnx2x_ext_phy_resolve_fc(phy, params, vars); 7456 } 7457 return link_up; 7458} 7459 7460/******************************************************************/ 7461/* SFP+ module Section */ 7462/******************************************************************/ 7463static void bnx2x_set_disable_pmd_transmit(struct link_params *params, 7464 struct bnx2x_phy *phy, 7465 u8 pmd_dis) 7466{ 7467 struct bnx2x *bp = params->bp; 7468 /* 7469 * Disable transmitter only for bootcodes which can enable it afterwards 7470 * (for D3 link) 7471 */ 7472 if (pmd_dis) { 7473 if (params->feature_config_flags & 7474 FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED) 7475 DP(NETIF_MSG_LINK, "Disabling PMD transmitter\n"); 7476 else { 7477 DP(NETIF_MSG_LINK, "NOT disabling PMD transmitter\n"); 7478 return; 7479 } 7480 } else 7481 DP(NETIF_MSG_LINK, "Enabling PMD transmitter\n"); 7482 bnx2x_cl45_write(bp, phy, 7483 MDIO_PMA_DEVAD, 7484 MDIO_PMA_REG_TX_DISABLE, pmd_dis); 7485} 7486 7487static u8 bnx2x_get_gpio_port(struct link_params *params) 7488{ 7489 u8 gpio_port; 7490 u32 swap_val, swap_override; 7491 struct bnx2x *bp = params->bp; 7492 if (CHIP_IS_E2(bp)) 7493 gpio_port = BP_PATH(bp); 7494 else 7495 gpio_port = params->port; 7496 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); 7497 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); 7498 return gpio_port ^ (swap_val && swap_override); 7499} 7500 7501static void bnx2x_sfp_e1e2_set_transmitter(struct link_params *params, 7502 struct bnx2x_phy *phy, 7503 u8 tx_en) 7504{ 7505 u16 val; 7506 u8 port = params->port; 7507 struct bnx2x *bp = params->bp; 7508 u32 tx_en_mode; 7509 7510 /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/ 7511 tx_en_mode = REG_RD(bp, params->shmem_base + 7512 offsetof(struct shmem_region, 7513 dev_info.port_hw_config[port].sfp_ctrl)) & 7514 PORT_HW_CFG_TX_LASER_MASK; 7515 DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x " 7516 "mode = %x\n", tx_en, port, tx_en_mode); 7517 switch (tx_en_mode) { 7518 case PORT_HW_CFG_TX_LASER_MDIO: 7519 7520 bnx2x_cl45_read(bp, phy, 7521 MDIO_PMA_DEVAD, 7522 MDIO_PMA_REG_PHY_IDENTIFIER, 7523 &val); 7524 7525 if (tx_en) 7526 val &= ~(1<<15); 7527 else 7528 val |= (1<<15); 7529 7530 bnx2x_cl45_write(bp, phy, 7531 MDIO_PMA_DEVAD, 7532 MDIO_PMA_REG_PHY_IDENTIFIER, 7533 val); 7534 break; 7535 case PORT_HW_CFG_TX_LASER_GPIO0: 7536 case PORT_HW_CFG_TX_LASER_GPIO1: 7537 case PORT_HW_CFG_TX_LASER_GPIO2: 7538 case PORT_HW_CFG_TX_LASER_GPIO3: 7539 { 7540 u16 gpio_pin; 7541 u8 gpio_port, gpio_mode; 7542 if (tx_en) 7543 gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH; 7544 else 7545 gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW; 7546 7547 gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0; 7548 gpio_port = bnx2x_get_gpio_port(params); 7549 bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port); 7550 break; 7551 } 7552 default: 7553 DP(NETIF_MSG_LINK, "Invalid TX_LASER_MDIO 0x%x\n", tx_en_mode); 7554 break; 7555 } 7556} 7557 7558static void bnx2x_sfp_set_transmitter(struct link_params *params, 7559 struct bnx2x_phy *phy, 7560 u8 tx_en) 7561{ 7562 struct bnx2x *bp = params->bp; 7563 DP(NETIF_MSG_LINK, "Setting SFP+ transmitter to %d\n", tx_en); 7564 if (CHIP_IS_E3(bp)) 7565 bnx2x_sfp_e3_set_transmitter(params, phy, tx_en); 7566 else 7567 bnx2x_sfp_e1e2_set_transmitter(params, phy, tx_en); 7568} 7569 7570static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, 7571 struct link_params *params, 7572 u16 addr, u8 byte_cnt, u8 *o_buf) 7573{ 7574 struct bnx2x *bp = params->bp; 7575 u16 val = 0; 7576 u16 i; 7577 if (byte_cnt > 16) { 7578 DP(NETIF_MSG_LINK, 7579 "Reading from eeprom is limited to 0xf\n"); 7580 return -EINVAL; 7581 } 7582 /* Set the read command byte count */ 7583 bnx2x_cl45_write(bp, phy, 7584 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, 7585 (byte_cnt | 0xa000)); 7586 7587 /* Set the read command address */ 7588 bnx2x_cl45_write(bp, phy, 7589 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, 7590 addr); 7591 7592 /* Activate read command */ 7593 bnx2x_cl45_write(bp, phy, 7594 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, 7595 0x2c0f); 7596 7597 /* Wait up to 500us for command complete status */ 7598 for (i = 0; i < 100; i++) { 7599 bnx2x_cl45_read(bp, phy, 7600 MDIO_PMA_DEVAD, 7601 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); 7602 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == 7603 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) 7604 break; 7605 udelay(5); 7606 } 7607 7608 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) != 7609 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) { 7610 DP(NETIF_MSG_LINK, 7611 "Got bad status 0x%x when reading from SFP+ EEPROM\n", 7612 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK)); 7613 return -EINVAL; 7614 } 7615 7616 /* Read the buffer */ 7617 for (i = 0; i < byte_cnt; i++) { 7618 bnx2x_cl45_read(bp, phy, 7619 MDIO_PMA_DEVAD, 7620 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val); 7621 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK); 7622 } 7623 7624 for (i = 0; i < 100; i++) { 7625 bnx2x_cl45_read(bp, phy, 7626 MDIO_PMA_DEVAD, 7627 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); 7628 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == 7629 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) 7630 return 0; 7631 msleep(1); 7632 } 7633 return -EINVAL; 7634} 7635 7636static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, 7637 struct link_params *params, 7638 u16 addr, u8 byte_cnt, 7639 u8 *o_buf) 7640{ 7641 int rc = 0; 7642 u8 i, j = 0, cnt = 0; 7643 u32 data_array[4]; 7644 u16 addr32; 7645 struct bnx2x *bp = params->bp; 7646 /*DP(NETIF_MSG_LINK, "bnx2x_direct_read_sfp_module_eeprom:" 7647 " addr %d, cnt %d\n", 7648 addr, byte_cnt);*/ 7649 if (byte_cnt > 16) { 7650 DP(NETIF_MSG_LINK, 7651 "Reading from eeprom is limited to 16 bytes\n"); 7652 return -EINVAL; 7653 } 7654 7655 /* 4 byte aligned address */ 7656 addr32 = addr & (~0x3); 7657 do { 7658 rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt, 7659 data_array); 7660 } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT)); 7661 7662 if (rc == 0) { 7663 for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) { 7664 o_buf[j] = *((u8 *)data_array + i); 7665 j++; 7666 } 7667 } 7668 7669 return rc; 7670} 7671 7672static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, 7673 struct link_params *params, 7674 u16 addr, u8 byte_cnt, u8 *o_buf) 7675{ 7676 struct bnx2x *bp = params->bp; 7677 u16 val, i; 7678 7679 if (byte_cnt > 16) { 7680 DP(NETIF_MSG_LINK, 7681 "Reading from eeprom is limited to 0xf\n"); 7682 return -EINVAL; 7683 } 7684 7685 /* Need to read from 1.8000 to clear it */ 7686 bnx2x_cl45_read(bp, phy, 7687 MDIO_PMA_DEVAD, 7688 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, 7689 &val); 7690 7691 /* Set the read command byte count */ 7692 bnx2x_cl45_write(bp, phy, 7693 MDIO_PMA_DEVAD, 7694 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, 7695 ((byte_cnt < 2) ? 2 : byte_cnt)); 7696 7697 /* Set the read command address */ 7698 bnx2x_cl45_write(bp, phy, 7699 MDIO_PMA_DEVAD, 7700 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, 7701 addr); 7702 /* Set the destination address */ 7703 bnx2x_cl45_write(bp, phy, 7704 MDIO_PMA_DEVAD, 7705 0x8004, 7706 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF); 7707 7708 /* Activate read command */ 7709 bnx2x_cl45_write(bp, phy, 7710 MDIO_PMA_DEVAD, 7711 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, 7712 0x8002); 7713 /* 7714 * Wait appropriate time for two-wire command to finish before 7715 * polling the status register 7716 */ 7717 msleep(1); 7718 7719 /* Wait up to 500us for command complete status */ 7720 for (i = 0; i < 100; i++) { 7721 bnx2x_cl45_read(bp, phy, 7722 MDIO_PMA_DEVAD, 7723 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); 7724 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == 7725 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) 7726 break; 7727 udelay(5); 7728 } 7729 7730 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) != 7731 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) { 7732 DP(NETIF_MSG_LINK, 7733 "Got bad status 0x%x when reading from SFP+ EEPROM\n", 7734 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK)); 7735 return -EFAULT; 7736 } 7737 7738 /* Read the buffer */ 7739 for (i = 0; i < byte_cnt; i++) { 7740 bnx2x_cl45_read(bp, phy, 7741 MDIO_PMA_DEVAD, 7742 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val); 7743 o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK); 7744 } 7745 7746 for (i = 0; i < 100; i++) { 7747 bnx2x_cl45_read(bp, phy, 7748 MDIO_PMA_DEVAD, 7749 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); 7750 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == 7751 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) 7752 return 0; 7753 msleep(1); 7754 } 7755 7756 return -EINVAL; 7757} 7758 7759int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, 7760 struct link_params *params, u16 addr, 7761 u8 byte_cnt, u8 *o_buf) 7762{ 7763 int rc = -EINVAL; 7764 switch (phy->type) { 7765 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: 7766 rc = bnx2x_8726_read_sfp_module_eeprom(phy, params, addr, 7767 byte_cnt, o_buf); 7768 break; 7769 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: 7770 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722: 7771 rc = bnx2x_8727_read_sfp_module_eeprom(phy, params, addr, 7772 byte_cnt, o_buf); 7773 break; 7774 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: 7775 rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr, 7776 byte_cnt, o_buf); 7777 break; 7778 } 7779 return rc; 7780} 7781 7782static int bnx2x_get_edc_mode(struct bnx2x_phy *phy, 7783 struct link_params *params, 7784 u16 *edc_mode) 7785{ 7786 struct bnx2x *bp = params->bp; 7787 u32 sync_offset = 0, phy_idx, media_types; 7788 u8 val, check_limiting_mode = 0; 7789 *edc_mode = EDC_MODE_LIMITING; 7790 7791 phy->media_type = ETH_PHY_UNSPECIFIED; 7792 /* First check for copper cable */ 7793 if (bnx2x_read_sfp_module_eeprom(phy, 7794 params, 7795 SFP_EEPROM_CON_TYPE_ADDR, 7796 1, 7797 &val) != 0) { 7798 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n"); 7799 return -EINVAL; 7800 } 7801 7802 switch (val) { 7803 case SFP_EEPROM_CON_TYPE_VAL_COPPER: 7804 { 7805 u8 copper_module_type; 7806 phy->media_type = ETH_PHY_DA_TWINAX; 7807 /* 7808 * Check if its active cable (includes SFP+ module) 7809 * of passive cable 7810 */ 7811 if (bnx2x_read_sfp_module_eeprom(phy, 7812 params, 7813 SFP_EEPROM_FC_TX_TECH_ADDR, 7814 1, 7815 &copper_module_type) != 0) { 7816 DP(NETIF_MSG_LINK, 7817 "Failed to read copper-cable-type" 7818 " from SFP+ EEPROM\n"); 7819 return -EINVAL; 7820 } 7821 7822 if (copper_module_type & 7823 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) { 7824 DP(NETIF_MSG_LINK, "Active Copper cable detected\n"); 7825 check_limiting_mode = 1; 7826 } else if (copper_module_type & 7827 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) { 7828 DP(NETIF_MSG_LINK, 7829 "Passive Copper cable detected\n"); 7830 *edc_mode = 7831 EDC_MODE_PASSIVE_DAC; 7832 } else { 7833 DP(NETIF_MSG_LINK, 7834 "Unknown copper-cable-type 0x%x !!!\n", 7835 copper_module_type); 7836 return -EINVAL; 7837 } 7838 break; 7839 } 7840 case SFP_EEPROM_CON_TYPE_VAL_LC: 7841 phy->media_type = ETH_PHY_SFP_FIBER; 7842 DP(NETIF_MSG_LINK, "Optic module detected\n"); 7843 check_limiting_mode = 1; 7844 break; 7845 default: 7846 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n", 7847 val); 7848 return -EINVAL; 7849 } 7850 sync_offset = params->shmem_base + 7851 offsetof(struct shmem_region, 7852 dev_info.port_hw_config[params->port].media_type); 7853 media_types = REG_RD(bp, sync_offset); 7854 /* Update media type for non-PMF sync */ 7855 for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) { 7856 if (&(params->phy[phy_idx]) == phy) { 7857 media_types &= ~(PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK << 7858 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx)); 7859 media_types |= ((phy->media_type & 7860 PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) << 7861 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx)); 7862 break; 7863 } 7864 } 7865 REG_WR(bp, sync_offset, media_types); 7866 if (check_limiting_mode) { 7867 u8 options[SFP_EEPROM_OPTIONS_SIZE]; 7868 if (bnx2x_read_sfp_module_eeprom(phy, 7869 params, 7870 SFP_EEPROM_OPTIONS_ADDR, 7871 SFP_EEPROM_OPTIONS_SIZE, 7872 options) != 0) { 7873 DP(NETIF_MSG_LINK, 7874 "Failed to read Option field from module EEPROM\n"); 7875 return -EINVAL; 7876 } 7877 if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK)) 7878 *edc_mode = EDC_MODE_LINEAR; 7879 else 7880 *edc_mode = EDC_MODE_LIMITING; 7881 } 7882 DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode); 7883 return 0; 7884} 7885/* 7886 * This function read the relevant field from the module (SFP+), and verify it 7887 * is compliant with this board 7888 */ 7889static int bnx2x_verify_sfp_module(struct bnx2x_phy *phy, 7890 struct link_params *params) 7891{ 7892 struct bnx2x *bp = params->bp; 7893 u32 val, cmd; 7894 u32 fw_resp, fw_cmd_param; 7895 char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1]; 7896 char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1]; 7897 phy->flags &= ~FLAGS_SFP_NOT_APPROVED; 7898 val = REG_RD(bp, params->shmem_base + 7899 offsetof(struct shmem_region, dev_info. 7900 port_feature_config[params->port].config)); 7901 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == 7902 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) { 7903 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n"); 7904 return 0; 7905 } 7906 7907 if (params->feature_config_flags & 7908 FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) { 7909 /* Use specific phy request */ 7910 cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL; 7911 } else if (params->feature_config_flags & 7912 FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) { 7913 /* Use first phy request only in case of non-dual media*/ 7914 if (DUAL_MEDIA(params)) { 7915 DP(NETIF_MSG_LINK, 7916 "FW does not support OPT MDL verification\n"); 7917 return -EINVAL; 7918 } 7919 cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL; 7920 } else { 7921 /* No support in OPT MDL detection */ 7922 DP(NETIF_MSG_LINK, 7923 "FW does not support OPT MDL verification\n"); 7924 return -EINVAL; 7925 } 7926 7927 fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl); 7928 fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param); 7929 if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) { 7930 DP(NETIF_MSG_LINK, "Approved module\n"); 7931 return 0; 7932 } 7933 7934 /* format the warning message */ 7935 if (bnx2x_read_sfp_module_eeprom(phy, 7936 params, 7937 SFP_EEPROM_VENDOR_NAME_ADDR, 7938 SFP_EEPROM_VENDOR_NAME_SIZE, 7939 (u8 *)vendor_name)) 7940 vendor_name[0] = '\0'; 7941 else 7942 vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0'; 7943 if (bnx2x_read_sfp_module_eeprom(phy, 7944 params, 7945 SFP_EEPROM_PART_NO_ADDR, 7946 SFP_EEPROM_PART_NO_SIZE, 7947 (u8 *)vendor_pn)) 7948 vendor_pn[0] = '\0'; 7949 else 7950 vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0'; 7951 7952 netdev_err(bp->dev, "Warning: Unqualified SFP+ module detected," 7953 " Port %d from %s part number %s\n", 7954 params->port, vendor_name, vendor_pn); 7955 phy->flags |= FLAGS_SFP_NOT_APPROVED; 7956 return -EINVAL; 7957} 7958 7959static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, 7960 struct link_params *params) 7961 7962{ 7963 u8 val; 7964 struct bnx2x *bp = params->bp; 7965 u16 timeout; 7966 /* 7967 * Initialization time after hot-plug may take up to 300ms for 7968 * some phys type ( e.g. JDSU ) 7969 */ 7970 7971 for (timeout = 0; timeout < 60; timeout++) { 7972 if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val) 7973 == 0) { 7974 DP(NETIF_MSG_LINK, 7975 "SFP+ module initialization took %d ms\n", 7976 timeout * 5); 7977 return 0; 7978 } 7979 msleep(5); 7980 } 7981 return -EINVAL; 7982} 7983 7984static void bnx2x_8727_power_module(struct bnx2x *bp, 7985 struct bnx2x_phy *phy, 7986 u8 is_power_up) { 7987 /* Make sure GPIOs are not using for LED mode */ 7988 u16 val; 7989 /* 7990 * In the GPIO register, bit 4 is use to determine if the GPIOs are 7991 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for 7992 * output 7993 * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0 7994 * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1 7995 * where the 1st bit is the over-current(only input), and 2nd bit is 7996 * for power( only output ) 7997 * 7998 * In case of NOC feature is disabled and power is up, set GPIO control 7999 * as input to enable listening of over-current indication 8000 */ 8001 if (phy->flags & FLAGS_NOC) 8002 return; 8003 if (is_power_up) 8004 val = (1<<4); 8005 else 8006 /* 8007 * Set GPIO control to OUTPUT, and set the power bit 8008 * to according to the is_power_up 8009 */ 8010 val = (1<<1); 8011 8012 bnx2x_cl45_write(bp, phy, 8013 MDIO_PMA_DEVAD, 8014 MDIO_PMA_REG_8727_GPIO_CTRL, 8015 val); 8016} 8017 8018static int bnx2x_8726_set_limiting_mode(struct bnx2x *bp, 8019 struct bnx2x_phy *phy, 8020 u16 edc_mode) 8021{ 8022 u16 cur_limiting_mode; 8023 8024 bnx2x_cl45_read(bp, phy, 8025 MDIO_PMA_DEVAD, 8026 MDIO_PMA_REG_ROM_VER2, 8027 &cur_limiting_mode); 8028 DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n", 8029 cur_limiting_mode); 8030 8031 if (edc_mode == EDC_MODE_LIMITING) { 8032 DP(NETIF_MSG_LINK, "Setting LIMITING MODE\n"); 8033 bnx2x_cl45_write(bp, phy, 8034 MDIO_PMA_DEVAD, 8035 MDIO_PMA_REG_ROM_VER2, 8036 EDC_MODE_LIMITING); 8037 } else { /* LRM mode ( default )*/ 8038 8039 DP(NETIF_MSG_LINK, "Setting LRM MODE\n"); 8040 8041 /* 8042 * Changing to LRM mode takes quite few seconds. So do it only 8043 * if current mode is limiting (default is LRM) 8044 */ 8045 if (cur_limiting_mode != EDC_MODE_LIMITING) 8046 return 0; 8047 8048 bnx2x_cl45_write(bp, phy, 8049 MDIO_PMA_DEVAD, 8050 MDIO_PMA_REG_LRM_MODE, 8051 0); 8052 bnx2x_cl45_write(bp, phy, 8053 MDIO_PMA_DEVAD, 8054 MDIO_PMA_REG_ROM_VER2, 8055 0x128); 8056 bnx2x_cl45_write(bp, phy, 8057 MDIO_PMA_DEVAD, 8058 MDIO_PMA_REG_MISC_CTRL0, 8059 0x4008); 8060 bnx2x_cl45_write(bp, phy, 8061 MDIO_PMA_DEVAD, 8062 MDIO_PMA_REG_LRM_MODE, 8063 0xaaaa); 8064 } 8065 return 0; 8066} 8067 8068static int bnx2x_8727_set_limiting_mode(struct bnx2x *bp, 8069 struct bnx2x_phy *phy, 8070 u16 edc_mode) 8071{ 8072 u16 phy_identifier; 8073 u16 rom_ver2_val; 8074 bnx2x_cl45_read(bp, phy, 8075 MDIO_PMA_DEVAD, 8076 MDIO_PMA_REG_PHY_IDENTIFIER, 8077 &phy_identifier); 8078 8079 bnx2x_cl45_write(bp, phy, 8080 MDIO_PMA_DEVAD, 8081 MDIO_PMA_REG_PHY_IDENTIFIER, 8082 (phy_identifier & ~(1<<9))); 8083 8084 bnx2x_cl45_read(bp, phy, 8085 MDIO_PMA_DEVAD, 8086 MDIO_PMA_REG_ROM_VER2, 8087 &rom_ver2_val); 8088 /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */ 8089 bnx2x_cl45_write(bp, phy, 8090 MDIO_PMA_DEVAD, 8091 MDIO_PMA_REG_ROM_VER2, 8092 (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff)); 8093 8094 bnx2x_cl45_write(bp, phy, 8095 MDIO_PMA_DEVAD, 8096 MDIO_PMA_REG_PHY_IDENTIFIER, 8097 (phy_identifier | (1<<9))); 8098 8099 return 0; 8100} 8101 8102static void bnx2x_8727_specific_func(struct bnx2x_phy *phy, 8103 struct link_params *params, 8104 u32 action) 8105{ 8106 struct bnx2x *bp = params->bp; 8107 8108 switch (action) { 8109 case DISABLE_TX: 8110 bnx2x_sfp_set_transmitter(params, phy, 0); 8111 break; 8112 case ENABLE_TX: 8113 if (!(phy->flags & FLAGS_SFP_NOT_APPROVED)) 8114 bnx2x_sfp_set_transmitter(params, phy, 1); 8115 break; 8116 default: 8117 DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n", 8118 action); 8119 return; 8120 } 8121} 8122 8123static void bnx2x_set_e1e2_module_fault_led(struct link_params *params, 8124 u8 gpio_mode) 8125{ 8126 struct bnx2x *bp = params->bp; 8127 8128 u32 fault_led_gpio = REG_RD(bp, params->shmem_base + 8129 offsetof(struct shmem_region, 8130 dev_info.port_hw_config[params->port].sfp_ctrl)) & 8131 PORT_HW_CFG_FAULT_MODULE_LED_MASK; 8132 switch (fault_led_gpio) { 8133 case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED: 8134 return; 8135 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0: 8136 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1: 8137 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2: 8138 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3: 8139 { 8140 u8 gpio_port = bnx2x_get_gpio_port(params); 8141 u16 gpio_pin = fault_led_gpio - 8142 PORT_HW_CFG_FAULT_MODULE_LED_GPIO0; 8143 DP(NETIF_MSG_LINK, "Set fault module-detected led " 8144 "pin %x port %x mode %x\n", 8145 gpio_pin, gpio_port, gpio_mode); 8146 bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port); 8147 } 8148 break; 8149 default: 8150 DP(NETIF_MSG_LINK, "Error: Invalid fault led mode 0x%x\n", 8151 fault_led_gpio); 8152 } 8153} 8154 8155static void bnx2x_set_e3_module_fault_led(struct link_params *params, 8156 u8 gpio_mode) 8157{ 8158 u32 pin_cfg; 8159 u8 port = params->port; 8160 struct bnx2x *bp = params->bp; 8161 pin_cfg = (REG_RD(bp, params->shmem_base + 8162 offsetof(struct shmem_region, 8163 dev_info.port_hw_config[port].e3_sfp_ctrl)) & 8164 PORT_HW_CFG_E3_FAULT_MDL_LED_MASK) >> 8165 PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT; 8166 DP(NETIF_MSG_LINK, "Setting Fault LED to %d using pin cfg %d\n", 8167 gpio_mode, pin_cfg); 8168 bnx2x_set_cfg_pin(bp, pin_cfg, gpio_mode); 8169} 8170 8171static void bnx2x_set_sfp_module_fault_led(struct link_params *params, 8172 u8 gpio_mode) 8173{ 8174 struct bnx2x *bp = params->bp; 8175 DP(NETIF_MSG_LINK, "Setting SFP+ module fault LED to %d\n", gpio_mode); 8176 if (CHIP_IS_E3(bp)) { 8177 /* 8178 * Low ==> if SFP+ module is supported otherwise 8179 * High ==> if SFP+ module is not on the approved vendor list 8180 */ 8181 bnx2x_set_e3_module_fault_led(params, gpio_mode); 8182 } else 8183 bnx2x_set_e1e2_module_fault_led(params, gpio_mode); 8184} 8185 8186static void bnx2x_warpcore_power_module(struct link_params *params, 8187 struct bnx2x_phy *phy, 8188 u8 power) 8189{ 8190 u32 pin_cfg; 8191 struct bnx2x *bp = params->bp; 8192 8193 pin_cfg = (REG_RD(bp, params->shmem_base + 8194 offsetof(struct shmem_region, 8195 dev_info.port_hw_config[params->port].e3_sfp_ctrl)) & 8196 PORT_HW_CFG_E3_PWR_DIS_MASK) >> 8197 PORT_HW_CFG_E3_PWR_DIS_SHIFT; 8198 8199 if (pin_cfg == PIN_CFG_NA) 8200 return; 8201 DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n", 8202 power, pin_cfg); 8203 /* 8204 * Low ==> corresponding SFP+ module is powered 8205 * high ==> the SFP+ module is powered down 8206 */ 8207 bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1); 8208} 8209 8210static void bnx2x_warpcore_hw_reset(struct bnx2x_phy *phy, 8211 struct link_params *params) 8212{ 8213 struct bnx2x *bp = params->bp; 8214 bnx2x_warpcore_power_module(params, phy, 0); 8215 /* Put Warpcore in low power mode */ 8216 REG_WR(bp, MISC_REG_WC0_RESET, 0x0c0e); 8217 8218 /* Put LCPLL in low power mode */ 8219 REG_WR(bp, MISC_REG_LCPLL_E40_PWRDWN, 1); 8220 REG_WR(bp, MISC_REG_LCPLL_E40_RESETB_ANA, 0); 8221 REG_WR(bp, MISC_REG_LCPLL_E40_RESETB_DIG, 0); 8222} 8223 8224static void bnx2x_power_sfp_module(struct link_params *params, 8225 struct bnx2x_phy *phy, 8226 u8 power) 8227{ 8228 struct bnx2x *bp = params->bp; 8229 DP(NETIF_MSG_LINK, "Setting SFP+ power to %x\n", power); 8230 8231 switch (phy->type) { 8232 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: 8233 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722: 8234 bnx2x_8727_power_module(params->bp, phy, power); 8235 break; 8236 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: 8237 bnx2x_warpcore_power_module(params, phy, power); 8238 break; 8239 default: 8240 break; 8241 } 8242} 8243static void bnx2x_warpcore_set_limiting_mode(struct link_params *params, 8244 struct bnx2x_phy *phy, 8245 u16 edc_mode) 8246{ 8247 u16 val = 0; 8248 u16 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT; 8249 struct bnx2x *bp = params->bp; 8250 8251 u8 lane = bnx2x_get_warpcore_lane(phy, params); 8252 /* This is a global register which controls all lanes */ 8253 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 8254 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val); 8255 val &= ~(0xf << (lane << 2)); 8256 8257 switch (edc_mode) { 8258 case EDC_MODE_LINEAR: 8259 case EDC_MODE_LIMITING: 8260 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT; 8261 break; 8262 case EDC_MODE_PASSIVE_DAC: 8263 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC; 8264 break; 8265 default: 8266 break; 8267 } 8268 8269 val |= (mode << (lane << 2)); 8270 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 8271 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, val); 8272 /* A must read */ 8273 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 8274 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val); 8275 8276 /* Restart microcode to re-read the new mode */ 8277 bnx2x_warpcore_reset_lane(bp, phy, 1); 8278 bnx2x_warpcore_reset_lane(bp, phy, 0); 8279 8280} 8281 8282static void bnx2x_set_limiting_mode(struct link_params *params, 8283 struct bnx2x_phy *phy, 8284 u16 edc_mode) 8285{ 8286 switch (phy->type) { 8287 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: 8288 bnx2x_8726_set_limiting_mode(params->bp, phy, edc_mode); 8289 break; 8290 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: 8291 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722: 8292 bnx2x_8727_set_limiting_mode(params->bp, phy, edc_mode); 8293 break; 8294 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: 8295 bnx2x_warpcore_set_limiting_mode(params, phy, edc_mode); 8296 break; 8297 } 8298} 8299 8300int bnx2x_sfp_module_detection(struct bnx2x_phy *phy, 8301 struct link_params *params) 8302{ 8303 struct bnx2x *bp = params->bp; 8304 u16 edc_mode; 8305 int rc = 0; 8306 8307 u32 val = REG_RD(bp, params->shmem_base + 8308 offsetof(struct shmem_region, dev_info. 8309 port_feature_config[params->port].config)); 8310 8311 DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n", 8312 params->port); 8313 /* Power up module */ 8314 bnx2x_power_sfp_module(params, phy, 1); 8315 if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) { 8316 DP(NETIF_MSG_LINK, "Failed to get valid module type\n"); 8317 return -EINVAL; 8318 } else if (bnx2x_verify_sfp_module(phy, params) != 0) { 8319 /* check SFP+ module compatibility */ 8320 DP(NETIF_MSG_LINK, "Module verification failed!!\n"); 8321 rc = -EINVAL; 8322 /* Turn on fault module-detected led */ 8323 bnx2x_set_sfp_module_fault_led(params, 8324 MISC_REGISTERS_GPIO_HIGH); 8325 8326 /* Check if need to power down the SFP+ module */ 8327 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == 8328 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN) { 8329 DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n"); 8330 bnx2x_power_sfp_module(params, phy, 0); 8331 return rc; 8332 } 8333 } else { 8334 /* Turn off fault module-detected led */ 8335 bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW); 8336 } 8337 8338 /* 8339 * Check and set limiting mode / LRM mode on 8726. On 8727 it 8340 * is done automatically 8341 */ 8342 bnx2x_set_limiting_mode(params, phy, edc_mode); 8343 8344 /* 8345 * Enable transmit for this module if the module is approved, or 8346 * if unapproved modules should also enable the Tx laser 8347 */ 8348 if (rc == 0 || 8349 (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) != 8350 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) 8351 bnx2x_sfp_set_transmitter(params, phy, 1); 8352 else 8353 bnx2x_sfp_set_transmitter(params, phy, 0); 8354 8355 return rc; 8356} 8357 8358void bnx2x_handle_module_detect_int(struct link_params *params) 8359{ 8360 struct bnx2x *bp = params->bp; 8361 struct bnx2x_phy *phy; 8362 u32 gpio_val; 8363 u8 gpio_num, gpio_port; 8364 if (CHIP_IS_E3(bp)) 8365 phy = ¶ms->phy[INT_PHY]; 8366 else 8367 phy = ¶ms->phy[EXT_PHY1]; 8368 8369 if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id, params->shmem_base, 8370 params->port, &gpio_num, &gpio_port) == 8371 -EINVAL) { 8372 DP(NETIF_MSG_LINK, "Failed to get MOD_ABS interrupt config\n"); 8373 return; 8374 } 8375 8376 /* Set valid module led off */ 8377 bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH); 8378 8379 /* Get current gpio val reflecting module plugged in / out*/ 8380 gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port); 8381 8382 /* Call the handling function in case module is detected */ 8383 if (gpio_val == 0) { 8384 bnx2x_power_sfp_module(params, phy, 1); 8385 bnx2x_set_gpio_int(bp, gpio_num, 8386 MISC_REGISTERS_GPIO_INT_OUTPUT_CLR, 8387 gpio_port); 8388 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) 8389 bnx2x_sfp_module_detection(phy, params); 8390 else 8391 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); 8392 } else { 8393 u32 val = REG_RD(bp, params->shmem_base + 8394 offsetof(struct shmem_region, dev_info. 8395 port_feature_config[params->port]. 8396 config)); 8397 bnx2x_set_gpio_int(bp, gpio_num, 8398 MISC_REGISTERS_GPIO_INT_OUTPUT_SET, 8399 gpio_port); 8400 /* 8401 * Module was plugged out. 8402 * Disable transmit for this module 8403 */ 8404 phy->media_type = ETH_PHY_NOT_PRESENT; 8405 if (((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == 8406 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) || 8407 CHIP_IS_E3(bp)) 8408 bnx2x_sfp_set_transmitter(params, phy, 0); 8409 } 8410} 8411 8412/******************************************************************/ 8413/* Used by 8706 and 8727 */ 8414/******************************************************************/ 8415static void bnx2x_sfp_mask_fault(struct bnx2x *bp, 8416 struct bnx2x_phy *phy, 8417 u16 alarm_status_offset, 8418 u16 alarm_ctrl_offset) 8419{ 8420 u16 alarm_status, val; 8421 bnx2x_cl45_read(bp, phy, 8422 MDIO_PMA_DEVAD, alarm_status_offset, 8423 &alarm_status); 8424 bnx2x_cl45_read(bp, phy, 8425 MDIO_PMA_DEVAD, alarm_status_offset, 8426 &alarm_status); 8427 /* Mask or enable the fault event. */ 8428 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, &val); 8429 if (alarm_status & (1<<0)) 8430 val &= ~(1<<0); 8431 else 8432 val |= (1<<0); 8433 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, val); 8434} 8435/******************************************************************/ 8436/* common BCM8706/BCM8726 PHY SECTION */ 8437/******************************************************************/ 8438static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, 8439 struct link_params *params, 8440 struct link_vars *vars) 8441{ 8442 u8 link_up = 0; 8443 u16 val1, val2, rx_sd, pcs_status; 8444 struct bnx2x *bp = params->bp; 8445 DP(NETIF_MSG_LINK, "XGXS 8706/8726\n"); 8446 /* Clear RX Alarm*/ 8447 bnx2x_cl45_read(bp, phy, 8448 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2); 8449 8450 bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT, 8451 MDIO_PMA_LASI_TXCTRL); 8452 8453 /* clear LASI indication*/ 8454 bnx2x_cl45_read(bp, phy, 8455 MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1); 8456 bnx2x_cl45_read(bp, phy, 8457 MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2); 8458 DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2); 8459 8460 bnx2x_cl45_read(bp, phy, 8461 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd); 8462 bnx2x_cl45_read(bp, phy, 8463 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status); 8464 bnx2x_cl45_read(bp, phy, 8465 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2); 8466 bnx2x_cl45_read(bp, phy, 8467 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2); 8468 8469 DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps" 8470 " link_status 0x%x\n", rx_sd, pcs_status, val2); 8471 /* 8472 * link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status 8473 * are set, or if the autoneg bit 1 is set 8474 */ 8475 link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1))); 8476 if (link_up) { 8477 if (val2 & (1<<1)) 8478 vars->line_speed = SPEED_1000; 8479 else 8480 vars->line_speed = SPEED_10000; 8481 bnx2x_ext_phy_resolve_fc(phy, params, vars); 8482 vars->duplex = DUPLEX_FULL; 8483 } 8484 8485 /* Capture 10G link fault. Read twice to clear stale value. */ 8486 if (vars->line_speed == SPEED_10000) { 8487 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 8488 MDIO_PMA_LASI_TXSTAT, &val1); 8489 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 8490 MDIO_PMA_LASI_TXSTAT, &val1); 8491 if (val1 & (1<<0)) 8492 vars->fault_detected = 1; 8493 } 8494 8495 return link_up; 8496} 8497 8498/******************************************************************/ 8499/* BCM8706 PHY SECTION */ 8500/******************************************************************/ 8501static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, 8502 struct link_params *params, 8503 struct link_vars *vars) 8504{ 8505 u32 tx_en_mode; 8506 u16 cnt, val, tmp1; 8507 struct bnx2x *bp = params->bp; 8508 8509 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 8510 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); 8511 /* HW reset */ 8512 bnx2x_ext_phy_hw_reset(bp, params->port); 8513 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); 8514 bnx2x_wait_reset_complete(bp, phy, params); 8515 8516 /* Wait until fw is loaded */ 8517 for (cnt = 0; cnt < 100; cnt++) { 8518 bnx2x_cl45_read(bp, phy, 8519 MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val); 8520 if (val) 8521 break; 8522 msleep(10); 8523 } 8524 DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt); 8525 if ((params->feature_config_flags & 8526 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { 8527 u8 i; 8528 u16 reg; 8529 for (i = 0; i < 4; i++) { 8530 reg = MDIO_XS_8706_REG_BANK_RX0 + 8531 i*(MDIO_XS_8706_REG_BANK_RX1 - 8532 MDIO_XS_8706_REG_BANK_RX0); 8533 bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val); 8534 /* Clear first 3 bits of the control */ 8535 val &= ~0x7; 8536 /* Set control bits according to configuration */ 8537 val |= (phy->rx_preemphasis[i] & 0x7); 8538 DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706" 8539 " reg 0x%x <-- val 0x%x\n", reg, val); 8540 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val); 8541 } 8542 } 8543 /* Force speed */ 8544 if (phy->req_line_speed == SPEED_10000) { 8545 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n"); 8546 8547 bnx2x_cl45_write(bp, phy, 8548 MDIO_PMA_DEVAD, 8549 MDIO_PMA_REG_DIGITAL_CTRL, 0x400); 8550 bnx2x_cl45_write(bp, phy, 8551 MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL, 8552 0); 8553 /* Arm LASI for link and Tx fault. */ 8554 bnx2x_cl45_write(bp, phy, 8555 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 3); 8556 } else { 8557 /* Force 1Gbps using autoneg with 1G advertisement */ 8558 8559 /* Allow CL37 through CL73 */ 8560 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n"); 8561 bnx2x_cl45_write(bp, phy, 8562 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c); 8563 8564 /* Enable Full-Duplex advertisement on CL37 */ 8565 bnx2x_cl45_write(bp, phy, 8566 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020); 8567 /* Enable CL37 AN */ 8568 bnx2x_cl45_write(bp, phy, 8569 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); 8570 /* 1G support */ 8571 bnx2x_cl45_write(bp, phy, 8572 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5)); 8573 8574 /* Enable clause 73 AN */ 8575 bnx2x_cl45_write(bp, phy, 8576 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); 8577 bnx2x_cl45_write(bp, phy, 8578 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, 8579 0x0400); 8580 bnx2x_cl45_write(bp, phy, 8581 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 8582 0x0004); 8583 } 8584 bnx2x_save_bcm_spirom_ver(bp, phy, params->port); 8585 8586 /* 8587 * If TX Laser is controlled by GPIO_0, do not let PHY go into low 8588 * power mode, if TX Laser is disabled 8589 */ 8590 8591 tx_en_mode = REG_RD(bp, params->shmem_base + 8592 offsetof(struct shmem_region, 8593 dev_info.port_hw_config[params->port].sfp_ctrl)) 8594 & PORT_HW_CFG_TX_LASER_MASK; 8595 8596 if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) { 8597 DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n"); 8598 bnx2x_cl45_read(bp, phy, 8599 MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1); 8600 tmp1 |= 0x1; 8601 bnx2x_cl45_write(bp, phy, 8602 MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1); 8603 } 8604 8605 return 0; 8606} 8607 8608static int bnx2x_8706_read_status(struct bnx2x_phy *phy, 8609 struct link_params *params, 8610 struct link_vars *vars) 8611{ 8612 return bnx2x_8706_8726_read_status(phy, params, vars); 8613} 8614 8615/******************************************************************/ 8616/* BCM8726 PHY SECTION */ 8617/******************************************************************/ 8618static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy, 8619 struct link_params *params) 8620{ 8621 struct bnx2x *bp = params->bp; 8622 DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n"); 8623 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001); 8624} 8625 8626static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy, 8627 struct link_params *params) 8628{ 8629 struct bnx2x *bp = params->bp; 8630 /* Need to wait 100ms after reset */ 8631 msleep(100); 8632 8633 /* Micro controller re-boot */ 8634 bnx2x_cl45_write(bp, phy, 8635 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B); 8636 8637 /* Set soft reset */ 8638 bnx2x_cl45_write(bp, phy, 8639 MDIO_PMA_DEVAD, 8640 MDIO_PMA_REG_GEN_CTRL, 8641 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); 8642 8643 bnx2x_cl45_write(bp, phy, 8644 MDIO_PMA_DEVAD, 8645 MDIO_PMA_REG_MISC_CTRL1, 0x0001); 8646 8647 bnx2x_cl45_write(bp, phy, 8648 MDIO_PMA_DEVAD, 8649 MDIO_PMA_REG_GEN_CTRL, 8650 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); 8651 8652 /* wait for 150ms for microcode load */ 8653 msleep(150); 8654 8655 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */ 8656 bnx2x_cl45_write(bp, phy, 8657 MDIO_PMA_DEVAD, 8658 MDIO_PMA_REG_MISC_CTRL1, 0x0000); 8659 8660 msleep(200); 8661 bnx2x_save_bcm_spirom_ver(bp, phy, params->port); 8662} 8663 8664static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy, 8665 struct link_params *params, 8666 struct link_vars *vars) 8667{ 8668 struct bnx2x *bp = params->bp; 8669 u16 val1; 8670 u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars); 8671 if (link_up) { 8672 bnx2x_cl45_read(bp, phy, 8673 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 8674 &val1); 8675 if (val1 & (1<<15)) { 8676 DP(NETIF_MSG_LINK, "Tx is disabled\n"); 8677 link_up = 0; 8678 vars->line_speed = 0; 8679 } 8680 } 8681 return link_up; 8682} 8683 8684 8685static int bnx2x_8726_config_init(struct bnx2x_phy *phy, 8686 struct link_params *params, 8687 struct link_vars *vars) 8688{ 8689 struct bnx2x *bp = params->bp; 8690 DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); 8691 8692 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); 8693 bnx2x_wait_reset_complete(bp, phy, params); 8694 8695 bnx2x_8726_external_rom_boot(phy, params); 8696 8697 /* 8698 * Need to call module detected on initialization since the module 8699 * detection triggered by actual module insertion might occur before 8700 * driver is loaded, and when driver is loaded, it reset all 8701 * registers, including the transmitter 8702 */ 8703 bnx2x_sfp_module_detection(phy, params); 8704 8705 if (phy->req_line_speed == SPEED_1000) { 8706 DP(NETIF_MSG_LINK, "Setting 1G force\n"); 8707 bnx2x_cl45_write(bp, phy, 8708 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40); 8709 bnx2x_cl45_write(bp, phy, 8710 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD); 8711 bnx2x_cl45_write(bp, phy, 8712 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x5); 8713 bnx2x_cl45_write(bp, phy, 8714 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, 8715 0x400); 8716 } else if ((phy->req_line_speed == SPEED_AUTO_NEG) && 8717 (phy->speed_cap_mask & 8718 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) && 8719 ((phy->speed_cap_mask & 8720 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) != 8721 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { 8722 DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); 8723 /* Set Flow control */ 8724 bnx2x_ext_phy_set_pause(params, phy, vars); 8725 bnx2x_cl45_write(bp, phy, 8726 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20); 8727 bnx2x_cl45_write(bp, phy, 8728 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c); 8729 bnx2x_cl45_write(bp, phy, 8730 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020); 8731 bnx2x_cl45_write(bp, phy, 8732 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); 8733 bnx2x_cl45_write(bp, phy, 8734 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); 8735 /* 8736 * Enable RX-ALARM control to receive interrupt for 1G speed 8737 * change 8738 */ 8739 bnx2x_cl45_write(bp, phy, 8740 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x4); 8741 bnx2x_cl45_write(bp, phy, 8742 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, 8743 0x400); 8744 8745 } else { /* Default 10G. Set only LASI control */ 8746 bnx2x_cl45_write(bp, phy, 8747 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 1); 8748 } 8749 8750 /* Set TX PreEmphasis if needed */ 8751 if ((params->feature_config_flags & 8752 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { 8753 DP(NETIF_MSG_LINK, 8754 "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n", 8755 phy->tx_preemphasis[0], 8756 phy->tx_preemphasis[1]); 8757 bnx2x_cl45_write(bp, phy, 8758 MDIO_PMA_DEVAD, 8759 MDIO_PMA_REG_8726_TX_CTRL1, 8760 phy->tx_preemphasis[0]); 8761 8762 bnx2x_cl45_write(bp, phy, 8763 MDIO_PMA_DEVAD, 8764 MDIO_PMA_REG_8726_TX_CTRL2, 8765 phy->tx_preemphasis[1]); 8766 } 8767 8768 return 0; 8769 8770} 8771 8772static void bnx2x_8726_link_reset(struct bnx2x_phy *phy, 8773 struct link_params *params) 8774{ 8775 struct bnx2x *bp = params->bp; 8776 DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port); 8777 /* Set serial boot control for external load */ 8778 bnx2x_cl45_write(bp, phy, 8779 MDIO_PMA_DEVAD, 8780 MDIO_PMA_REG_GEN_CTRL, 0x0001); 8781} 8782 8783/******************************************************************/ 8784/* BCM8727 PHY SECTION */ 8785/******************************************************************/ 8786 8787static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy, 8788 struct link_params *params, u8 mode) 8789{ 8790 struct bnx2x *bp = params->bp; 8791 u16 led_mode_bitmask = 0; 8792 u16 gpio_pins_bitmask = 0; 8793 u16 val; 8794 /* Only NOC flavor requires to set the LED specifically */ 8795 if (!(phy->flags & FLAGS_NOC)) 8796 return; 8797 switch (mode) { 8798 case LED_MODE_FRONT_PANEL_OFF: 8799 case LED_MODE_OFF: 8800 led_mode_bitmask = 0; 8801 gpio_pins_bitmask = 0x03; 8802 break; 8803 case LED_MODE_ON: 8804 led_mode_bitmask = 0; 8805 gpio_pins_bitmask = 0x02; 8806 break; 8807 case LED_MODE_OPER: 8808 led_mode_bitmask = 0x60; 8809 gpio_pins_bitmask = 0x11; 8810 break; 8811 } 8812 bnx2x_cl45_read(bp, phy, 8813 MDIO_PMA_DEVAD, 8814 MDIO_PMA_REG_8727_PCS_OPT_CTRL, 8815 &val); 8816 val &= 0xff8f; 8817 val |= led_mode_bitmask; 8818 bnx2x_cl45_write(bp, phy, 8819 MDIO_PMA_DEVAD, 8820 MDIO_PMA_REG_8727_PCS_OPT_CTRL, 8821 val); 8822 bnx2x_cl45_read(bp, phy, 8823 MDIO_PMA_DEVAD, 8824 MDIO_PMA_REG_8727_GPIO_CTRL, 8825 &val); 8826 val &= 0xffe0; 8827 val |= gpio_pins_bitmask; 8828 bnx2x_cl45_write(bp, phy, 8829 MDIO_PMA_DEVAD, 8830 MDIO_PMA_REG_8727_GPIO_CTRL, 8831 val); 8832} 8833static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy, 8834 struct link_params *params) { 8835 u32 swap_val, swap_override; 8836 u8 port; 8837 /* 8838 * The PHY reset is controlled by GPIO 1. Fake the port number 8839 * to cancel the swap done in set_gpio() 8840 */ 8841 struct bnx2x *bp = params->bp; 8842 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); 8843 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); 8844 port = (swap_val && swap_override) ^ 1; 8845 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 8846 MISC_REGISTERS_GPIO_OUTPUT_LOW, port); 8847} 8848 8849static int bnx2x_8727_config_init(struct bnx2x_phy *phy, 8850 struct link_params *params, 8851 struct link_vars *vars) 8852{ 8853 u32 tx_en_mode; 8854 u16 tmp1, val, mod_abs, tmp2; 8855 u16 rx_alarm_ctrl_val; 8856 u16 lasi_ctrl_val; 8857 struct bnx2x *bp = params->bp; 8858 /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */ 8859 8860 bnx2x_wait_reset_complete(bp, phy, params); 8861 rx_alarm_ctrl_val = (1<<2) | (1<<5) ; 8862 /* Should be 0x6 to enable XS on Tx side. */ 8863 lasi_ctrl_val = 0x0006; 8864 8865 DP(NETIF_MSG_LINK, "Initializing BCM8727\n"); 8866 /* enable LASI */ 8867 bnx2x_cl45_write(bp, phy, 8868 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, 8869 rx_alarm_ctrl_val); 8870 bnx2x_cl45_write(bp, phy, 8871 MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL, 8872 0); 8873 bnx2x_cl45_write(bp, phy, 8874 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, lasi_ctrl_val); 8875 8876 /* 8877 * Initially configure MOD_ABS to interrupt when module is 8878 * presence( bit 8) 8879 */ 8880 bnx2x_cl45_read(bp, phy, 8881 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); 8882 /* 8883 * Set EDC off by setting OPTXLOS signal input to low (bit 9). 8884 * When the EDC is off it locks onto a reference clock and avoids 8885 * becoming 'lost' 8886 */ 8887 mod_abs &= ~(1<<8); 8888 if (!(phy->flags & FLAGS_NOC)) 8889 mod_abs &= ~(1<<9); 8890 bnx2x_cl45_write(bp, phy, 8891 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); 8892 8893 8894 /* Enable/Disable PHY transmitter output */ 8895 bnx2x_set_disable_pmd_transmit(params, phy, 0); 8896 8897 /* Make MOD_ABS give interrupt on change */ 8898 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, 8899 &val); 8900 val |= (1<<12); 8901 if (phy->flags & FLAGS_NOC) 8902 val |= (3<<5); 8903 8904 /* 8905 * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0 8906 * status which reflect SFP+ module over-current 8907 */ 8908 if (!(phy->flags & FLAGS_NOC)) 8909 val &= 0xff8f; /* Reset bits 4-6 */ 8910 bnx2x_cl45_write(bp, phy, 8911 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val); 8912 8913 bnx2x_8727_power_module(bp, phy, 1); 8914 8915 bnx2x_cl45_read(bp, phy, 8916 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); 8917 8918 bnx2x_cl45_read(bp, phy, 8919 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1); 8920 8921 /* Set option 1G speed */ 8922 if (phy->req_line_speed == SPEED_1000) { 8923 DP(NETIF_MSG_LINK, "Setting 1G force\n"); 8924 bnx2x_cl45_write(bp, phy, 8925 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40); 8926 bnx2x_cl45_write(bp, phy, 8927 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD); 8928 bnx2x_cl45_read(bp, phy, 8929 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1); 8930 DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1); 8931 /* 8932 * Power down the XAUI until link is up in case of dual-media 8933 * and 1G 8934 */ 8935 if (DUAL_MEDIA(params)) { 8936 bnx2x_cl45_read(bp, phy, 8937 MDIO_PMA_DEVAD, 8938 MDIO_PMA_REG_8727_PCS_GP, &val); 8939 val |= (3<<10); 8940 bnx2x_cl45_write(bp, phy, 8941 MDIO_PMA_DEVAD, 8942 MDIO_PMA_REG_8727_PCS_GP, val); 8943 } 8944 } else if ((phy->req_line_speed == SPEED_AUTO_NEG) && 8945 ((phy->speed_cap_mask & 8946 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) && 8947 ((phy->speed_cap_mask & 8948 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) != 8949 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { 8950 8951 DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); 8952 bnx2x_cl45_write(bp, phy, 8953 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0); 8954 bnx2x_cl45_write(bp, phy, 8955 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300); 8956 } else { 8957 /* 8958 * Since the 8727 has only single reset pin, need to set the 10G 8959 * registers although it is default 8960 */ 8961 bnx2x_cl45_write(bp, phy, 8962 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 8963 0x0020); 8964 bnx2x_cl45_write(bp, phy, 8965 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100); 8966 bnx2x_cl45_write(bp, phy, 8967 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040); 8968 bnx2x_cl45_write(bp, phy, 8969 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 8970 0x0008); 8971 } 8972 8973 /* 8974 * Set 2-wire transfer rate of SFP+ module EEPROM 8975 * to 100Khz since some DACs(direct attached cables) do 8976 * not work at 400Khz. 8977 */ 8978 bnx2x_cl45_write(bp, phy, 8979 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR, 8980 0xa001); 8981 8982 /* Set TX PreEmphasis if needed */ 8983 if ((params->feature_config_flags & 8984 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { 8985 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n", 8986 phy->tx_preemphasis[0], 8987 phy->tx_preemphasis[1]); 8988 bnx2x_cl45_write(bp, phy, 8989 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1, 8990 phy->tx_preemphasis[0]); 8991 8992 bnx2x_cl45_write(bp, phy, 8993 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2, 8994 phy->tx_preemphasis[1]); 8995 } 8996 8997 /* 8998 * If TX Laser is controlled by GPIO_0, do not let PHY go into low 8999 * power mode, if TX Laser is disabled 9000 */ 9001 tx_en_mode = REG_RD(bp, params->shmem_base + 9002 offsetof(struct shmem_region, 9003 dev_info.port_hw_config[params->port].sfp_ctrl)) 9004 & PORT_HW_CFG_TX_LASER_MASK; 9005 9006 if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) { 9007 9008 DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n"); 9009 bnx2x_cl45_read(bp, phy, 9010 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2); 9011 tmp2 |= 0x1000; 9012 tmp2 &= 0xFFEF; 9013 bnx2x_cl45_write(bp, phy, 9014 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2); 9015 } 9016 9017 return 0; 9018} 9019 9020static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, 9021 struct link_params *params) 9022{ 9023 struct bnx2x *bp = params->bp; 9024 u16 mod_abs, rx_alarm_status; 9025 u32 val = REG_RD(bp, params->shmem_base + 9026 offsetof(struct shmem_region, dev_info. 9027 port_feature_config[params->port]. 9028 config)); 9029 bnx2x_cl45_read(bp, phy, 9030 MDIO_PMA_DEVAD, 9031 MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); 9032 if (mod_abs & (1<<8)) { 9033 9034 /* Module is absent */ 9035 DP(NETIF_MSG_LINK, 9036 "MOD_ABS indication show module is absent\n"); 9037 phy->media_type = ETH_PHY_NOT_PRESENT; 9038 /* 9039 * 1. Set mod_abs to detect next module 9040 * presence event 9041 * 2. Set EDC off by setting OPTXLOS signal input to low 9042 * (bit 9). 9043 * When the EDC is off it locks onto a reference clock and 9044 * avoids becoming 'lost'. 9045 */ 9046 mod_abs &= ~(1<<8); 9047 if (!(phy->flags & FLAGS_NOC)) 9048 mod_abs &= ~(1<<9); 9049 bnx2x_cl45_write(bp, phy, 9050 MDIO_PMA_DEVAD, 9051 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); 9052 9053 /* 9054 * Clear RX alarm since it stays up as long as 9055 * the mod_abs wasn't changed 9056 */ 9057 bnx2x_cl45_read(bp, phy, 9058 MDIO_PMA_DEVAD, 9059 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status); 9060 9061 } else { 9062 /* Module is present */ 9063 DP(NETIF_MSG_LINK, 9064 "MOD_ABS indication show module is present\n"); 9065 /* 9066 * First disable transmitter, and if the module is ok, the 9067 * module_detection will enable it 9068 * 1. Set mod_abs to detect next module absent event ( bit 8) 9069 * 2. Restore the default polarity of the OPRXLOS signal and 9070 * this signal will then correctly indicate the presence or 9071 * absence of the Rx signal. (bit 9) 9072 */ 9073 mod_abs |= (1<<8); 9074 if (!(phy->flags & FLAGS_NOC)) 9075 mod_abs |= (1<<9); 9076 bnx2x_cl45_write(bp, phy, 9077 MDIO_PMA_DEVAD, 9078 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); 9079 9080 /* 9081 * Clear RX alarm since it stays up as long as the mod_abs 9082 * wasn't changed. This is need to be done before calling the 9083 * module detection, otherwise it will clear* the link update 9084 * alarm 9085 */ 9086 bnx2x_cl45_read(bp, phy, 9087 MDIO_PMA_DEVAD, 9088 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status); 9089 9090 9091 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == 9092 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) 9093 bnx2x_sfp_set_transmitter(params, phy, 0); 9094 9095 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) 9096 bnx2x_sfp_module_detection(phy, params); 9097 else 9098 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); 9099 } 9100 9101 DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", 9102 rx_alarm_status); 9103 /* No need to check link status in case of module plugged in/out */ 9104} 9105 9106static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, 9107 struct link_params *params, 9108 struct link_vars *vars) 9109 9110{ 9111 struct bnx2x *bp = params->bp; 9112 u8 link_up = 0, oc_port = params->port; 9113 u16 link_status = 0; 9114 u16 rx_alarm_status, lasi_ctrl, val1; 9115 9116 /* If PHY is not initialized, do not check link status */ 9117 bnx2x_cl45_read(bp, phy, 9118 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 9119 &lasi_ctrl); 9120 if (!lasi_ctrl) 9121 return 0; 9122 9123 /* Check the LASI on Rx */ 9124 bnx2x_cl45_read(bp, phy, 9125 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, 9126 &rx_alarm_status); 9127 vars->line_speed = 0; 9128 DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status); 9129 9130 bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT, 9131 MDIO_PMA_LASI_TXCTRL); 9132 9133 bnx2x_cl45_read(bp, phy, 9134 MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1); 9135 9136 DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1); 9137 9138 /* Clear MSG-OUT */ 9139 bnx2x_cl45_read(bp, phy, 9140 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1); 9141 9142 /* 9143 * If a module is present and there is need to check 9144 * for over current 9145 */ 9146 if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) { 9147 /* Check over-current using 8727 GPIO0 input*/ 9148 bnx2x_cl45_read(bp, phy, 9149 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL, 9150 &val1); 9151 9152 if ((val1 & (1<<8)) == 0) { 9153 if (!CHIP_IS_E1x(bp)) 9154 oc_port = BP_PATH(bp) + (params->port << 1); 9155 DP(NETIF_MSG_LINK, 9156 "8727 Power fault has been detected on port %d\n", 9157 oc_port); 9158 netdev_err(bp->dev, "Error: Power fault on Port %d has" 9159 " been detected and the power to " 9160 "that SFP+ module has been removed" 9161 " to prevent failure of the card." 9162 " Please remove the SFP+ module and" 9163 " restart the system to clear this" 9164 " error.\n", 9165 oc_port); 9166 /* Disable all RX_ALARMs except for mod_abs */ 9167 bnx2x_cl45_write(bp, phy, 9168 MDIO_PMA_DEVAD, 9169 MDIO_PMA_LASI_RXCTRL, (1<<5)); 9170 9171 bnx2x_cl45_read(bp, phy, 9172 MDIO_PMA_DEVAD, 9173 MDIO_PMA_REG_PHY_IDENTIFIER, &val1); 9174 /* Wait for module_absent_event */ 9175 val1 |= (1<<8); 9176 bnx2x_cl45_write(bp, phy, 9177 MDIO_PMA_DEVAD, 9178 MDIO_PMA_REG_PHY_IDENTIFIER, val1); 9179 /* Clear RX alarm */ 9180 bnx2x_cl45_read(bp, phy, 9181 MDIO_PMA_DEVAD, 9182 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status); 9183 return 0; 9184 } 9185 } /* Over current check */ 9186 9187 /* When module absent bit is set, check module */ 9188 if (rx_alarm_status & (1<<5)) { 9189 bnx2x_8727_handle_mod_abs(phy, params); 9190 /* Enable all mod_abs and link detection bits */ 9191 bnx2x_cl45_write(bp, phy, 9192 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, 9193 ((1<<5) | (1<<2))); 9194 } 9195 DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n"); 9196 bnx2x_8727_specific_func(phy, params, ENABLE_TX); 9197 /* If transmitter is disabled, ignore false link up indication */ 9198 bnx2x_cl45_read(bp, phy, 9199 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1); 9200 if (val1 & (1<<15)) { 9201 DP(NETIF_MSG_LINK, "Tx is disabled\n"); 9202 return 0; 9203 } 9204 9205 bnx2x_cl45_read(bp, phy, 9206 MDIO_PMA_DEVAD, 9207 MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status); 9208 9209 /* 9210 * Bits 0..2 --> speed detected, 9211 * Bits 13..15--> link is down 9212 */ 9213 if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) { 9214 link_up = 1; 9215 vars->line_speed = SPEED_10000; 9216 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n", 9217 params->port); 9218 } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) { 9219 link_up = 1; 9220 vars->line_speed = SPEED_1000; 9221 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n", 9222 params->port); 9223 } else { 9224 link_up = 0; 9225 DP(NETIF_MSG_LINK, "port %x: External link is down\n", 9226 params->port); 9227 } 9228 9229 /* Capture 10G link fault. */ 9230 if (vars->line_speed == SPEED_10000) { 9231 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 9232 MDIO_PMA_LASI_TXSTAT, &val1); 9233 9234 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 9235 MDIO_PMA_LASI_TXSTAT, &val1); 9236 9237 if (val1 & (1<<0)) { 9238 vars->fault_detected = 1; 9239 } 9240 } 9241 9242 if (link_up) { 9243 bnx2x_ext_phy_resolve_fc(phy, params, vars); 9244 vars->duplex = DUPLEX_FULL; 9245 DP(NETIF_MSG_LINK, "duplex = 0x%x\n", vars->duplex); 9246 } 9247 9248 if ((DUAL_MEDIA(params)) && 9249 (phy->req_line_speed == SPEED_1000)) { 9250 bnx2x_cl45_read(bp, phy, 9251 MDIO_PMA_DEVAD, 9252 MDIO_PMA_REG_8727_PCS_GP, &val1); 9253 /* 9254 * In case of dual-media board and 1G, power up the XAUI side, 9255 * otherwise power it down. For 10G it is done automatically 9256 */ 9257 if (link_up) 9258 val1 &= ~(3<<10); 9259 else 9260 val1 |= (3<<10); 9261 bnx2x_cl45_write(bp, phy, 9262 MDIO_PMA_DEVAD, 9263 MDIO_PMA_REG_8727_PCS_GP, val1); 9264 } 9265 return link_up; 9266} 9267 9268static void bnx2x_8727_link_reset(struct bnx2x_phy *phy, 9269 struct link_params *params) 9270{ 9271 struct bnx2x *bp = params->bp; 9272 9273 /* Enable/Disable PHY transmitter output */ 9274 bnx2x_set_disable_pmd_transmit(params, phy, 1); 9275 9276 /* Disable Transmitter */ 9277 bnx2x_sfp_set_transmitter(params, phy, 0); 9278 /* Clear LASI */ 9279 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0); 9280 9281} 9282 9283/******************************************************************/ 9284/* BCM8481/BCM84823/BCM84833 PHY SECTION */ 9285/******************************************************************/ 9286static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy, 9287 struct link_params *params) 9288{ 9289 u16 val, fw_ver1, fw_ver2, cnt; 9290 u8 port; 9291 struct bnx2x *bp = params->bp; 9292 9293 port = params->port; 9294 9295 /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/ 9296 /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */ 9297 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014); 9298 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); 9299 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000); 9300 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300); 9301 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009); 9302 9303 for (cnt = 0; cnt < 100; cnt++) { 9304 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); 9305 if (val & 1) 9306 break; 9307 udelay(5); 9308 } 9309 if (cnt == 100) { 9310 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n"); 9311 bnx2x_save_spirom_version(bp, port, 0, 9312 phy->ver_addr); 9313 return; 9314 } 9315 9316 9317 /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */ 9318 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000); 9319 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); 9320 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A); 9321 for (cnt = 0; cnt < 100; cnt++) { 9322 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); 9323 if (val & 1) 9324 break; 9325 udelay(5); 9326 } 9327 if (cnt == 100) { 9328 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n"); 9329 bnx2x_save_spirom_version(bp, port, 0, 9330 phy->ver_addr); 9331 return; 9332 } 9333 9334 /* lower 16 bits of the register SPI_FW_STATUS */ 9335 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1); 9336 /* upper 16 bits of register SPI_FW_STATUS */ 9337 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2); 9338 9339 bnx2x_save_spirom_version(bp, port, (fw_ver2<<16) | fw_ver1, 9340 phy->ver_addr); 9341} 9342 9343static void bnx2x_848xx_set_led(struct bnx2x *bp, 9344 struct bnx2x_phy *phy) 9345{ 9346 u16 val, offset; 9347 9348 /* PHYC_CTL_LED_CTL */ 9349 bnx2x_cl45_read(bp, phy, 9350 MDIO_PMA_DEVAD, 9351 MDIO_PMA_REG_8481_LINK_SIGNAL, &val); 9352 val &= 0xFE00; 9353 val |= 0x0092; 9354 9355 bnx2x_cl45_write(bp, phy, 9356 MDIO_PMA_DEVAD, 9357 MDIO_PMA_REG_8481_LINK_SIGNAL, val); 9358 9359 bnx2x_cl45_write(bp, phy, 9360 MDIO_PMA_DEVAD, 9361 MDIO_PMA_REG_8481_LED1_MASK, 9362 0x80); 9363 9364 bnx2x_cl45_write(bp, phy, 9365 MDIO_PMA_DEVAD, 9366 MDIO_PMA_REG_8481_LED2_MASK, 9367 0x18); 9368 9369 /* Select activity source by Tx and Rx, as suggested by PHY AE */ 9370 bnx2x_cl45_write(bp, phy, 9371 MDIO_PMA_DEVAD, 9372 MDIO_PMA_REG_8481_LED3_MASK, 9373 0x0006); 9374 9375 /* Select the closest activity blink rate to that in 10/100/1000 */ 9376 bnx2x_cl45_write(bp, phy, 9377 MDIO_PMA_DEVAD, 9378 MDIO_PMA_REG_8481_LED3_BLINK, 9379 0); 9380 9381 /* Configure the blink rate to ~15.9 Hz */ 9382 bnx2x_cl45_write(bp, phy, 9383 MDIO_PMA_DEVAD, 9384 MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH, 9385 MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ); 9386 9387 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) 9388 offset = MDIO_PMA_REG_84833_CTL_LED_CTL_1; 9389 else 9390 offset = MDIO_PMA_REG_84823_CTL_LED_CTL_1; 9391 9392 bnx2x_cl45_read(bp, phy, 9393 MDIO_PMA_DEVAD, offset, &val); 9394 val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/ 9395 bnx2x_cl45_write(bp, phy, 9396 MDIO_PMA_DEVAD, offset, val); 9397 9398 /* 'Interrupt Mask' */ 9399 bnx2x_cl45_write(bp, phy, 9400 MDIO_AN_DEVAD, 9401 0xFFFB, 0xFFFD); 9402} 9403 9404static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, 9405 struct link_params *params, 9406 struct link_vars *vars) 9407{ 9408 struct bnx2x *bp = params->bp; 9409 u16 autoneg_val, an_1000_val, an_10_100_val, an_10g_val; 9410 u16 tmp_req_line_speed; 9411 9412 tmp_req_line_speed = phy->req_line_speed; 9413 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) 9414 if (phy->req_line_speed == SPEED_10000) 9415 phy->req_line_speed = SPEED_AUTO_NEG; 9416 9417 /* 9418 * This phy uses the NIG latch mechanism since link indication 9419 * arrives through its LED4 and not via its LASI signal, so we 9420 * get steady signal instead of clear on read 9421 */ 9422 bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, 9423 1 << NIG_LATCH_BC_ENABLE_MI_INT); 9424 9425 bnx2x_cl45_write(bp, phy, 9426 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000); 9427 9428 bnx2x_848xx_set_led(bp, phy); 9429 9430 /* set 1000 speed advertisement */ 9431 bnx2x_cl45_read(bp, phy, 9432 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, 9433 &an_1000_val); 9434 9435 bnx2x_ext_phy_set_pause(params, phy, vars); 9436 bnx2x_cl45_read(bp, phy, 9437 MDIO_AN_DEVAD, 9438 MDIO_AN_REG_8481_LEGACY_AN_ADV, 9439 &an_10_100_val); 9440 bnx2x_cl45_read(bp, phy, 9441 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL, 9442 &autoneg_val); 9443 /* Disable forced speed */ 9444 autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13)); 9445 an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8)); 9446 9447 if (((phy->req_line_speed == SPEED_AUTO_NEG) && 9448 (phy->speed_cap_mask & 9449 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || 9450 (phy->req_line_speed == SPEED_1000)) { 9451 an_1000_val |= (1<<8); 9452 autoneg_val |= (1<<9 | 1<<12); 9453 if (phy->req_duplex == DUPLEX_FULL) 9454 an_1000_val |= (1<<9); 9455 DP(NETIF_MSG_LINK, "Advertising 1G\n"); 9456 } else 9457 an_1000_val &= ~((1<<8) | (1<<9)); 9458 9459 bnx2x_cl45_write(bp, phy, 9460 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, 9461 an_1000_val); 9462 9463 /* set 100 speed advertisement */ 9464 if (((phy->req_line_speed == SPEED_AUTO_NEG) && 9465 (phy->speed_cap_mask & 9466 (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | 9467 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) && 9468 (phy->supported & 9469 (SUPPORTED_100baseT_Half | 9470 SUPPORTED_100baseT_Full)))) { 9471 an_10_100_val |= (1<<7); 9472 /* Enable autoneg and restart autoneg for legacy speeds */ 9473 autoneg_val |= (1<<9 | 1<<12); 9474 9475 if (phy->req_duplex == DUPLEX_FULL) 9476 an_10_100_val |= (1<<8); 9477 DP(NETIF_MSG_LINK, "Advertising 100M\n"); 9478 } 9479 /* set 10 speed advertisement */ 9480 if (((phy->req_line_speed == SPEED_AUTO_NEG) && 9481 (phy->speed_cap_mask & 9482 (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | 9483 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) && 9484 (phy->supported & 9485 (SUPPORTED_10baseT_Half | 9486 SUPPORTED_10baseT_Full)))) { 9487 an_10_100_val |= (1<<5); 9488 autoneg_val |= (1<<9 | 1<<12); 9489 if (phy->req_duplex == DUPLEX_FULL) 9490 an_10_100_val |= (1<<6); 9491 DP(NETIF_MSG_LINK, "Advertising 10M\n"); 9492 } 9493 9494 /* Only 10/100 are allowed to work in FORCE mode */ 9495 if ((phy->req_line_speed == SPEED_100) && 9496 (phy->supported & 9497 (SUPPORTED_100baseT_Half | 9498 SUPPORTED_100baseT_Full))) { 9499 autoneg_val |= (1<<13); 9500 /* Enabled AUTO-MDIX when autoneg is disabled */ 9501 bnx2x_cl45_write(bp, phy, 9502 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL, 9503 (1<<15 | 1<<9 | 7<<0)); 9504 /* The PHY needs this set even for forced link. */ 9505 an_10_100_val |= (1<<8) | (1<<7); 9506 DP(NETIF_MSG_LINK, "Setting 100M force\n"); 9507 } 9508 if ((phy->req_line_speed == SPEED_10) && 9509 (phy->supported & 9510 (SUPPORTED_10baseT_Half | 9511 SUPPORTED_10baseT_Full))) { 9512 /* Enabled AUTO-MDIX when autoneg is disabled */ 9513 bnx2x_cl45_write(bp, phy, 9514 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL, 9515 (1<<15 | 1<<9 | 7<<0)); 9516 DP(NETIF_MSG_LINK, "Setting 10M force\n"); 9517 } 9518 9519 bnx2x_cl45_write(bp, phy, 9520 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV, 9521 an_10_100_val); 9522 9523 if (phy->req_duplex == DUPLEX_FULL) 9524 autoneg_val |= (1<<8); 9525 9526 /* 9527 * Always write this if this is not 84833. 9528 * For 84833, write it only when it's a forced speed. 9529 */ 9530 if ((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) || 9531 ((autoneg_val & (1<<12)) == 0)) 9532 bnx2x_cl45_write(bp, phy, 9533 MDIO_AN_DEVAD, 9534 MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val); 9535 9536 if (((phy->req_line_speed == SPEED_AUTO_NEG) && 9537 (phy->speed_cap_mask & 9538 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || 9539 (phy->req_line_speed == SPEED_10000)) { 9540 DP(NETIF_MSG_LINK, "Advertising 10G\n"); 9541 /* Restart autoneg for 10G*/ 9542 9543 bnx2x_cl45_read(bp, phy, 9544 MDIO_AN_DEVAD, 9545 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL, 9546 &an_10g_val); 9547 bnx2x_cl45_write(bp, phy, 9548 MDIO_AN_DEVAD, 9549 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL, 9550 an_10g_val | 0x1000); 9551 bnx2x_cl45_write(bp, phy, 9552 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 9553 0x3200); 9554 } else 9555 bnx2x_cl45_write(bp, phy, 9556 MDIO_AN_DEVAD, 9557 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL, 9558 1); 9559 9560 /* Save spirom version */ 9561 bnx2x_save_848xx_spirom_version(phy, params); 9562 9563 phy->req_line_speed = tmp_req_line_speed; 9564 9565 return 0; 9566} 9567 9568static int bnx2x_8481_config_init(struct bnx2x_phy *phy, 9569 struct link_params *params, 9570 struct link_vars *vars) 9571{ 9572 struct bnx2x *bp = params->bp; 9573 /* Restore normal power mode*/ 9574 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 9575 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); 9576 9577 /* HW reset */ 9578 bnx2x_ext_phy_hw_reset(bp, params->port); 9579 bnx2x_wait_reset_complete(bp, phy, params); 9580 9581 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); 9582 return bnx2x_848xx_cmn_config_init(phy, params, vars); 9583} 9584 9585#define PHY84833_CMDHDLR_WAIT 300 9586#define PHY84833_CMDHDLR_MAX_ARGS 5 9587static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy, 9588 struct link_params *params, 9589 u16 fw_cmd, 9590 u16 cmd_args[]) 9591{ 9592 u32 idx; 9593 u16 val; 9594 struct bnx2x *bp = params->bp; 9595 /* Write CMD_OPEN_OVERRIDE to STATUS reg */ 9596 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, 9597 MDIO_84833_CMD_HDLR_STATUS, 9598 PHY84833_STATUS_CMD_OPEN_OVERRIDE); 9599 for (idx = 0; idx < PHY84833_CMDHDLR_WAIT; idx++) { 9600 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 9601 MDIO_84833_CMD_HDLR_STATUS, &val); 9602 if (val == PHY84833_STATUS_CMD_OPEN_FOR_CMDS) 9603 break; 9604 msleep(1); 9605 } 9606 if (idx >= PHY84833_CMDHDLR_WAIT) { 9607 DP(NETIF_MSG_LINK, "FW cmd: FW not ready.\n"); 9608 return -EINVAL; 9609 } 9610 9611 /* Prepare argument(s) and issue command */ 9612 for (idx = 0; idx < PHY84833_CMDHDLR_MAX_ARGS; idx++) { 9613 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, 9614 MDIO_84833_CMD_HDLR_DATA1 + idx, 9615 cmd_args[idx]); 9616 } 9617 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, 9618 MDIO_84833_CMD_HDLR_COMMAND, fw_cmd); 9619 for (idx = 0; idx < PHY84833_CMDHDLR_WAIT; idx++) { 9620 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 9621 MDIO_84833_CMD_HDLR_STATUS, &val); 9622 if ((val == PHY84833_STATUS_CMD_COMPLETE_PASS) || 9623 (val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) 9624 break; 9625 msleep(1); 9626 } 9627 if ((idx >= PHY84833_CMDHDLR_WAIT) || 9628 (val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) { 9629 DP(NETIF_MSG_LINK, "FW cmd failed.\n"); 9630 return -EINVAL; 9631 } 9632 /* Gather returning data */ 9633 for (idx = 0; idx < PHY84833_CMDHDLR_MAX_ARGS; idx++) { 9634 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 9635 MDIO_84833_CMD_HDLR_DATA1 + idx, 9636 &cmd_args[idx]); 9637 } 9638 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, 9639 MDIO_84833_CMD_HDLR_STATUS, 9640 PHY84833_STATUS_CMD_CLEAR_COMPLETE); 9641 return 0; 9642} 9643 9644 9645static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy, 9646 struct link_params *params, 9647 struct link_vars *vars) 9648{ 9649 u32 pair_swap; 9650 u16 data[PHY84833_CMDHDLR_MAX_ARGS]; 9651 int status; 9652 struct bnx2x *bp = params->bp; 9653 9654 /* Check for configuration. */ 9655 pair_swap = REG_RD(bp, params->shmem_base + 9656 offsetof(struct shmem_region, 9657 dev_info.port_hw_config[params->port].xgbt_phy_cfg)) & 9658 PORT_HW_CFG_RJ45_PAIR_SWAP_MASK; 9659 9660 if (pair_swap == 0) 9661 return 0; 9662 9663 /* Only the second argument is used for this command */ 9664 data[1] = (u16)pair_swap; 9665 9666 status = bnx2x_84833_cmd_hdlr(phy, params, 9667 PHY84833_CMD_SET_PAIR_SWAP, data); 9668 if (status == 0) 9669 DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data[1]); 9670 9671 return status; 9672} 9673 9674static u8 bnx2x_84833_get_reset_gpios(struct bnx2x *bp, 9675 u32 shmem_base_path[], 9676 u32 chip_id) 9677{ 9678 u32 reset_pin[2]; 9679 u32 idx; 9680 u8 reset_gpios; 9681 if (CHIP_IS_E3(bp)) { 9682 /* Assume that these will be GPIOs, not EPIOs. */ 9683 for (idx = 0; idx < 2; idx++) { 9684 /* Map config param to register bit. */ 9685 reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] + 9686 offsetof(struct shmem_region, 9687 dev_info.port_hw_config[0].e3_cmn_pin_cfg)); 9688 reset_pin[idx] = (reset_pin[idx] & 9689 PORT_HW_CFG_E3_PHY_RESET_MASK) >> 9690 PORT_HW_CFG_E3_PHY_RESET_SHIFT; 9691 reset_pin[idx] -= PIN_CFG_GPIO0_P0; 9692 reset_pin[idx] = (1 << reset_pin[idx]); 9693 } 9694 reset_gpios = (u8)(reset_pin[0] | reset_pin[1]); 9695 } else { 9696 /* E2, look from diff place of shmem. */ 9697 for (idx = 0; idx < 2; idx++) { 9698 reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] + 9699 offsetof(struct shmem_region, 9700 dev_info.port_hw_config[0].default_cfg)); 9701 reset_pin[idx] &= PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK; 9702 reset_pin[idx] -= PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0; 9703 reset_pin[idx] >>= PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT; 9704 reset_pin[idx] = (1 << reset_pin[idx]); 9705 } 9706 reset_gpios = (u8)(reset_pin[0] | reset_pin[1]); 9707 } 9708 9709 return reset_gpios; 9710} 9711 9712static int bnx2x_84833_hw_reset_phy(struct bnx2x_phy *phy, 9713 struct link_params *params) 9714{ 9715 struct bnx2x *bp = params->bp; 9716 u8 reset_gpios; 9717 u32 other_shmem_base_addr = REG_RD(bp, params->shmem2_base + 9718 offsetof(struct shmem2_region, 9719 other_shmem_base_addr)); 9720 9721 u32 shmem_base_path[2]; 9722 shmem_base_path[0] = params->shmem_base; 9723 shmem_base_path[1] = other_shmem_base_addr; 9724 9725 reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path, 9726 params->chip_id); 9727 9728 bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW); 9729 udelay(10); 9730 DP(NETIF_MSG_LINK, "84833 hw reset on pin values 0x%x\n", 9731 reset_gpios); 9732 9733 return 0; 9734} 9735 9736#define PHY84833_CONSTANT_LATENCY 1193 9737static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, 9738 struct link_params *params, 9739 struct link_vars *vars) 9740{ 9741 struct bnx2x *bp = params->bp; 9742 u8 port, initialize = 1; 9743 u16 val; 9744 u32 actual_phy_selection, cms_enable; 9745 u16 cmd_args[PHY84833_CMDHDLR_MAX_ARGS]; 9746 int rc = 0; 9747 9748 msleep(1); 9749 9750 if (!(CHIP_IS_E1(bp))) 9751 port = BP_PATH(bp); 9752 else 9753 port = params->port; 9754 9755 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) { 9756 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, 9757 MISC_REGISTERS_GPIO_OUTPUT_HIGH, 9758 port); 9759 } else { 9760 /* MDIO reset */ 9761 bnx2x_cl45_write(bp, phy, 9762 MDIO_PMA_DEVAD, 9763 MDIO_PMA_REG_CTRL, 0x8000); 9764 } 9765 9766 bnx2x_wait_reset_complete(bp, phy, params); 9767 9768 /* Wait for GPHY to come out of reset */ 9769 msleep(50); 9770 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { 9771 /* Bring PHY out of super isolate mode */ 9772 bnx2x_cl45_read(bp, phy, 9773 MDIO_CTL_DEVAD, 9774 MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val); 9775 val &= ~MDIO_84833_SUPER_ISOLATE; 9776 bnx2x_cl45_write(bp, phy, 9777 MDIO_CTL_DEVAD, 9778 MDIO_84833_TOP_CFG_XGPHY_STRAP1, val); 9779 bnx2x_84833_pair_swap_cfg(phy, params, vars); 9780 } else { 9781 /* 9782 * BCM84823 requires that XGXS links up first @ 10G for normal 9783 * behavior. 9784 */ 9785 u16 temp; 9786 temp = vars->line_speed; 9787 vars->line_speed = SPEED_10000; 9788 bnx2x_set_autoneg(¶ms->phy[INT_PHY], params, vars, 0); 9789 bnx2x_program_serdes(¶ms->phy[INT_PHY], params, vars); 9790 vars->line_speed = temp; 9791 } 9792 9793 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 9794 MDIO_CTL_REG_84823_MEDIA, &val); 9795 val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK | 9796 MDIO_CTL_REG_84823_MEDIA_LINE_MASK | 9797 MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN | 9798 MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK | 9799 MDIO_CTL_REG_84823_MEDIA_FIBER_1G); 9800 9801 if (CHIP_IS_E3(bp)) { 9802 val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK | 9803 MDIO_CTL_REG_84823_MEDIA_LINE_MASK); 9804 } else { 9805 val |= (MDIO_CTL_REG_84823_CTRL_MAC_XFI | 9806 MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L); 9807 } 9808 9809 actual_phy_selection = bnx2x_phy_selection(params); 9810 9811 switch (actual_phy_selection) { 9812 case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT: 9813 /* Do nothing. Essentially this is like the priority copper */ 9814 break; 9815 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: 9816 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER; 9817 break; 9818 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: 9819 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER; 9820 break; 9821 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY: 9822 /* Do nothing here. The first PHY won't be initialized at all */ 9823 break; 9824 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY: 9825 val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN; 9826 initialize = 0; 9827 break; 9828 } 9829 if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000) 9830 val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G; 9831 9832 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, 9833 MDIO_CTL_REG_84823_MEDIA, val); 9834 DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n", 9835 params->multi_phy_config, val); 9836 9837 /* AutogrEEEn */ 9838 if (params->feature_config_flags & 9839 FEATURE_CONFIG_AUTOGREEEN_ENABLED) 9840 cmd_args[0] = 0x2; 9841 else 9842 cmd_args[0] = 0x0; 9843 9844 cmd_args[1] = 0x0; 9845 cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1; 9846 cmd_args[3] = PHY84833_CONSTANT_LATENCY; 9847 rc = bnx2x_84833_cmd_hdlr(phy, params, 9848 PHY84833_CMD_SET_EEE_MODE, cmd_args); 9849 if (rc != 0) 9850 DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n"); 9851 if (initialize) 9852 rc = bnx2x_848xx_cmn_config_init(phy, params, vars); 9853 else 9854 bnx2x_save_848xx_spirom_version(phy, params); 9855 /* 84833 PHY has a better feature and doesn't need to support this. */ 9856 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) { 9857 cms_enable = REG_RD(bp, params->shmem_base + 9858 offsetof(struct shmem_region, 9859 dev_info.port_hw_config[params->port].default_cfg)) & 9860 PORT_HW_CFG_ENABLE_CMS_MASK; 9861 9862 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 9863 MDIO_CTL_REG_84823_USER_CTRL_REG, &val); 9864 if (cms_enable) 9865 val |= MDIO_CTL_REG_84823_USER_CTRL_CMS; 9866 else 9867 val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS; 9868 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, 9869 MDIO_CTL_REG_84823_USER_CTRL_REG, val); 9870 } 9871 9872 return rc; 9873} 9874 9875static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, 9876 struct link_params *params, 9877 struct link_vars *vars) 9878{ 9879 struct bnx2x *bp = params->bp; 9880 u16 val, val1, val2; 9881 u8 link_up = 0; 9882 9883 9884 /* Check 10G-BaseT link status */ 9885 /* Check PMD signal ok */ 9886 bnx2x_cl45_read(bp, phy, 9887 MDIO_AN_DEVAD, 0xFFFA, &val1); 9888 bnx2x_cl45_read(bp, phy, 9889 MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL, 9890 &val2); 9891 DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2); 9892 9893 /* Check link 10G */ 9894 if (val2 & (1<<11)) { 9895 vars->line_speed = SPEED_10000; 9896 vars->duplex = DUPLEX_FULL; 9897 link_up = 1; 9898 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); 9899 } else { /* Check Legacy speed link */ 9900 u16 legacy_status, legacy_speed; 9901 9902 /* Enable expansion register 0x42 (Operation mode status) */ 9903 bnx2x_cl45_write(bp, phy, 9904 MDIO_AN_DEVAD, 9905 MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42); 9906 9907 /* Get legacy speed operation status */ 9908 bnx2x_cl45_read(bp, phy, 9909 MDIO_AN_DEVAD, 9910 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW, 9911 &legacy_status); 9912 9913 DP(NETIF_MSG_LINK, "Legacy speed status = 0x%x\n", 9914 legacy_status); 9915 link_up = ((legacy_status & (1<<11)) == (1<<11)); 9916 if (link_up) { 9917 legacy_speed = (legacy_status & (3<<9)); 9918 if (legacy_speed == (0<<9)) 9919 vars->line_speed = SPEED_10; 9920 else if (legacy_speed == (1<<9)) 9921 vars->line_speed = SPEED_100; 9922 else if (legacy_speed == (2<<9)) 9923 vars->line_speed = SPEED_1000; 9924 else /* Should not happen */ 9925 vars->line_speed = 0; 9926 9927 if (legacy_status & (1<<8)) 9928 vars->duplex = DUPLEX_FULL; 9929 else 9930 vars->duplex = DUPLEX_HALF; 9931 9932 DP(NETIF_MSG_LINK, 9933 "Link is up in %dMbps, is_duplex_full= %d\n", 9934 vars->line_speed, 9935 (vars->duplex == DUPLEX_FULL)); 9936 /* Check legacy speed AN resolution */ 9937 bnx2x_cl45_read(bp, phy, 9938 MDIO_AN_DEVAD, 9939 MDIO_AN_REG_8481_LEGACY_MII_STATUS, 9940 &val); 9941 if (val & (1<<5)) 9942 vars->link_status |= 9943 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; 9944 bnx2x_cl45_read(bp, phy, 9945 MDIO_AN_DEVAD, 9946 MDIO_AN_REG_8481_LEGACY_AN_EXPANSION, 9947 &val); 9948 if ((val & (1<<0)) == 0) 9949 vars->link_status |= 9950 LINK_STATUS_PARALLEL_DETECTION_USED; 9951 } 9952 } 9953 if (link_up) { 9954 DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n", 9955 vars->line_speed); 9956 bnx2x_ext_phy_resolve_fc(phy, params, vars); 9957 } 9958 9959 return link_up; 9960} 9961 9962 9963static int bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len) 9964{ 9965 int status = 0; 9966 u32 spirom_ver; 9967 spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F); 9968 status = bnx2x_format_ver(spirom_ver, str, len); 9969 return status; 9970} 9971 9972static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy, 9973 struct link_params *params) 9974{ 9975 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, 9976 MISC_REGISTERS_GPIO_OUTPUT_LOW, 0); 9977 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, 9978 MISC_REGISTERS_GPIO_OUTPUT_LOW, 1); 9979} 9980 9981static void bnx2x_8481_link_reset(struct bnx2x_phy *phy, 9982 struct link_params *params) 9983{ 9984 bnx2x_cl45_write(params->bp, phy, 9985 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000); 9986 bnx2x_cl45_write(params->bp, phy, 9987 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1); 9988} 9989 9990static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, 9991 struct link_params *params) 9992{ 9993 struct bnx2x *bp = params->bp; 9994 u8 port; 9995 u16 val16; 9996 9997 if (!(CHIP_IS_E1(bp))) 9998 port = BP_PATH(bp); 9999 else 10000 port = params->port; 10001 10002 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) { 10003 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, 10004 MISC_REGISTERS_GPIO_OUTPUT_LOW, 10005 port); 10006 } else { 10007 bnx2x_cl45_read(bp, phy, 10008 MDIO_CTL_DEVAD, 10009 0x400f, &val16); 10010 bnx2x_cl45_write(bp, phy, 10011 MDIO_PMA_DEVAD, 10012 MDIO_PMA_REG_CTRL, 0x800); 10013 } 10014} 10015 10016static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, 10017 struct link_params *params, u8 mode) 10018{ 10019 struct bnx2x *bp = params->bp; 10020 u16 val; 10021 u8 port; 10022 10023 if (!(CHIP_IS_E1(bp))) 10024 port = BP_PATH(bp); 10025 else 10026 port = params->port; 10027 10028 switch (mode) { 10029 case LED_MODE_OFF: 10030 10031 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", port); 10032 10033 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) == 10034 SHARED_HW_CFG_LED_EXTPHY1) { 10035 10036 /* Set LED masks */ 10037 bnx2x_cl45_write(bp, phy, 10038 MDIO_PMA_DEVAD, 10039 MDIO_PMA_REG_8481_LED1_MASK, 10040 0x0); 10041 10042 bnx2x_cl45_write(bp, phy, 10043 MDIO_PMA_DEVAD, 10044 MDIO_PMA_REG_8481_LED2_MASK, 10045 0x0); 10046 10047 bnx2x_cl45_write(bp, phy, 10048 MDIO_PMA_DEVAD, 10049 MDIO_PMA_REG_8481_LED3_MASK, 10050 0x0); 10051 10052 bnx2x_cl45_write(bp, phy, 10053 MDIO_PMA_DEVAD, 10054 MDIO_PMA_REG_8481_LED5_MASK, 10055 0x0); 10056 10057 } else { 10058 bnx2x_cl45_write(bp, phy, 10059 MDIO_PMA_DEVAD, 10060 MDIO_PMA_REG_8481_LED1_MASK, 10061 0x0); 10062 } 10063 break; 10064 case LED_MODE_FRONT_PANEL_OFF: 10065 10066 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n", 10067 port); 10068 10069 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) == 10070 SHARED_HW_CFG_LED_EXTPHY1) { 10071 10072 /* Set LED masks */ 10073 bnx2x_cl45_write(bp, phy, 10074 MDIO_PMA_DEVAD, 10075 MDIO_PMA_REG_8481_LED1_MASK, 10076 0x0); 10077 10078 bnx2x_cl45_write(bp, phy, 10079 MDIO_PMA_DEVAD, 10080 MDIO_PMA_REG_8481_LED2_MASK, 10081 0x0); 10082 10083 bnx2x_cl45_write(bp, phy, 10084 MDIO_PMA_DEVAD, 10085 MDIO_PMA_REG_8481_LED3_MASK, 10086 0x0); 10087 10088 bnx2x_cl45_write(bp, phy, 10089 MDIO_PMA_DEVAD, 10090 MDIO_PMA_REG_8481_LED5_MASK, 10091 0x20); 10092 10093 } else { 10094 bnx2x_cl45_write(bp, phy, 10095 MDIO_PMA_DEVAD, 10096 MDIO_PMA_REG_8481_LED1_MASK, 10097 0x0); 10098 } 10099 break; 10100 case LED_MODE_ON: 10101 10102 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", port); 10103 10104 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) == 10105 SHARED_HW_CFG_LED_EXTPHY1) { 10106 /* Set control reg */ 10107 bnx2x_cl45_read(bp, phy, 10108 MDIO_PMA_DEVAD, 10109 MDIO_PMA_REG_8481_LINK_SIGNAL, 10110 &val); 10111 val &= 0x8000; 10112 val |= 0x2492; 10113 10114 bnx2x_cl45_write(bp, phy, 10115 MDIO_PMA_DEVAD, 10116 MDIO_PMA_REG_8481_LINK_SIGNAL, 10117 val); 10118 10119 /* Set LED masks */ 10120 bnx2x_cl45_write(bp, phy, 10121 MDIO_PMA_DEVAD, 10122 MDIO_PMA_REG_8481_LED1_MASK, 10123 0x0); 10124 10125 bnx2x_cl45_write(bp, phy, 10126 MDIO_PMA_DEVAD, 10127 MDIO_PMA_REG_8481_LED2_MASK, 10128 0x20); 10129 10130 bnx2x_cl45_write(bp, phy, 10131 MDIO_PMA_DEVAD, 10132 MDIO_PMA_REG_8481_LED3_MASK, 10133 0x20); 10134 10135 bnx2x_cl45_write(bp, phy, 10136 MDIO_PMA_DEVAD, 10137 MDIO_PMA_REG_8481_LED5_MASK, 10138 0x0); 10139 } else { 10140 bnx2x_cl45_write(bp, phy, 10141 MDIO_PMA_DEVAD, 10142 MDIO_PMA_REG_8481_LED1_MASK, 10143 0x20); 10144 } 10145 break; 10146 10147 case LED_MODE_OPER: 10148 10149 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", port); 10150 10151 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) == 10152 SHARED_HW_CFG_LED_EXTPHY1) { 10153 10154 /* Set control reg */ 10155 bnx2x_cl45_read(bp, phy, 10156 MDIO_PMA_DEVAD, 10157 MDIO_PMA_REG_8481_LINK_SIGNAL, 10158 &val); 10159 10160 if (!((val & 10161 MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK) 10162 >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) { 10163 DP(NETIF_MSG_LINK, "Setting LINK_SIGNAL\n"); 10164 bnx2x_cl45_write(bp, phy, 10165 MDIO_PMA_DEVAD, 10166 MDIO_PMA_REG_8481_LINK_SIGNAL, 10167 0xa492); 10168 } 10169 10170 /* Set LED masks */ 10171 bnx2x_cl45_write(bp, phy, 10172 MDIO_PMA_DEVAD, 10173 MDIO_PMA_REG_8481_LED1_MASK, 10174 0x10); 10175 10176 bnx2x_cl45_write(bp, phy, 10177 MDIO_PMA_DEVAD, 10178 MDIO_PMA_REG_8481_LED2_MASK, 10179 0x80); 10180 10181 bnx2x_cl45_write(bp, phy, 10182 MDIO_PMA_DEVAD, 10183 MDIO_PMA_REG_8481_LED3_MASK, 10184 0x98); 10185 10186 bnx2x_cl45_write(bp, phy, 10187 MDIO_PMA_DEVAD, 10188 MDIO_PMA_REG_8481_LED5_MASK, 10189 0x40); 10190 10191 } else { 10192 bnx2x_cl45_write(bp, phy, 10193 MDIO_PMA_DEVAD, 10194 MDIO_PMA_REG_8481_LED1_MASK, 10195 0x80); 10196 10197 /* Tell LED3 to blink on source */ 10198 bnx2x_cl45_read(bp, phy, 10199 MDIO_PMA_DEVAD, 10200 MDIO_PMA_REG_8481_LINK_SIGNAL, 10201 &val); 10202 val &= ~(7<<6); 10203 val |= (1<<6); /* A83B[8:6]= 1 */ 10204 bnx2x_cl45_write(bp, phy, 10205 MDIO_PMA_DEVAD, 10206 MDIO_PMA_REG_8481_LINK_SIGNAL, 10207 val); 10208 } 10209 break; 10210 } 10211 10212 /* 10213 * This is a workaround for E3+84833 until autoneg 10214 * restart is fixed in f/w 10215 */ 10216 if (CHIP_IS_E3(bp)) { 10217 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 10218 MDIO_WC_REG_GP2_STATUS_GP_2_1, &val); 10219 } 10220} 10221 10222/******************************************************************/ 10223/* 54618SE PHY SECTION */ 10224/******************************************************************/ 10225static int bnx2x_54618se_config_init(struct bnx2x_phy *phy, 10226 struct link_params *params, 10227 struct link_vars *vars) 10228{ 10229 struct bnx2x *bp = params->bp; 10230 u8 port; 10231 u16 autoneg_val, an_1000_val, an_10_100_val, fc_val, temp; 10232 u32 cfg_pin; 10233 10234 DP(NETIF_MSG_LINK, "54618SE cfg init\n"); 10235 usleep_range(1000, 1000); 10236 10237 /* This works with E3 only, no need to check the chip 10238 before determining the port. */ 10239 port = params->port; 10240 10241 cfg_pin = (REG_RD(bp, params->shmem_base + 10242 offsetof(struct shmem_region, 10243 dev_info.port_hw_config[port].e3_cmn_pin_cfg)) & 10244 PORT_HW_CFG_E3_PHY_RESET_MASK) >> 10245 PORT_HW_CFG_E3_PHY_RESET_SHIFT; 10246 10247 /* Drive pin high to bring the GPHY out of reset. */ 10248 bnx2x_set_cfg_pin(bp, cfg_pin, 1); 10249 10250 /* wait for GPHY to reset */ 10251 msleep(50); 10252 10253 /* reset phy */ 10254 bnx2x_cl22_write(bp, phy, 10255 MDIO_PMA_REG_CTRL, 0x8000); 10256 bnx2x_wait_reset_complete(bp, phy, params); 10257 10258 /*wait for GPHY to reset */ 10259 msleep(50); 10260 10261 /* Configure LED4: set to INTR (0x6). */ 10262 /* Accessing shadow register 0xe. */ 10263 bnx2x_cl22_write(bp, phy, 10264 MDIO_REG_GPHY_SHADOW, 10265 MDIO_REG_GPHY_SHADOW_LED_SEL2); 10266 bnx2x_cl22_read(bp, phy, 10267 MDIO_REG_GPHY_SHADOW, 10268 &temp); 10269 temp &= ~(0xf << 4); 10270 temp |= (0x6 << 4); 10271 bnx2x_cl22_write(bp, phy, 10272 MDIO_REG_GPHY_SHADOW, 10273 MDIO_REG_GPHY_SHADOW_WR_ENA | temp); 10274 /* Configure INTR based on link status change. */ 10275 bnx2x_cl22_write(bp, phy, 10276 MDIO_REG_INTR_MASK, 10277 ~MDIO_REG_INTR_MASK_LINK_STATUS); 10278 10279 /* Flip the signal detect polarity (set 0x1c.0x1e[8]). */ 10280 bnx2x_cl22_write(bp, phy, 10281 MDIO_REG_GPHY_SHADOW, 10282 MDIO_REG_GPHY_SHADOW_AUTO_DET_MED); 10283 bnx2x_cl22_read(bp, phy, 10284 MDIO_REG_GPHY_SHADOW, 10285 &temp); 10286 temp |= MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD; 10287 bnx2x_cl22_write(bp, phy, 10288 MDIO_REG_GPHY_SHADOW, 10289 MDIO_REG_GPHY_SHADOW_WR_ENA | temp); 10290 10291 /* Set up fc */ 10292 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ 10293 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); 10294 fc_val = 0; 10295 if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == 10296 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) 10297 fc_val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC; 10298 10299 if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == 10300 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) 10301 fc_val |= MDIO_AN_REG_ADV_PAUSE_PAUSE; 10302 10303 /* read all advertisement */ 10304 bnx2x_cl22_read(bp, phy, 10305 0x09, 10306 &an_1000_val); 10307 10308 bnx2x_cl22_read(bp, phy, 10309 0x04, 10310 &an_10_100_val); 10311 10312 bnx2x_cl22_read(bp, phy, 10313 MDIO_PMA_REG_CTRL, 10314 &autoneg_val); 10315 10316 /* Disable forced speed */ 10317 autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13)); 10318 an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8) | (1<<10) | 10319 (1<<11)); 10320 10321 if (((phy->req_line_speed == SPEED_AUTO_NEG) && 10322 (phy->speed_cap_mask & 10323 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || 10324 (phy->req_line_speed == SPEED_1000)) { 10325 an_1000_val |= (1<<8); 10326 autoneg_val |= (1<<9 | 1<<12); 10327 if (phy->req_duplex == DUPLEX_FULL) 10328 an_1000_val |= (1<<9); 10329 DP(NETIF_MSG_LINK, "Advertising 1G\n"); 10330 } else 10331 an_1000_val &= ~((1<<8) | (1<<9)); 10332 10333 bnx2x_cl22_write(bp, phy, 10334 0x09, 10335 an_1000_val); 10336 bnx2x_cl22_read(bp, phy, 10337 0x09, 10338 &an_1000_val); 10339 10340 /* set 100 speed advertisement */ 10341 if (((phy->req_line_speed == SPEED_AUTO_NEG) && 10342 (phy->speed_cap_mask & 10343 (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | 10344 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) { 10345 an_10_100_val |= (1<<7); 10346 /* Enable autoneg and restart autoneg for legacy speeds */ 10347 autoneg_val |= (1<<9 | 1<<12); 10348 10349 if (phy->req_duplex == DUPLEX_FULL) 10350 an_10_100_val |= (1<<8); 10351 DP(NETIF_MSG_LINK, "Advertising 100M\n"); 10352 } 10353 10354 /* set 10 speed advertisement */ 10355 if (((phy->req_line_speed == SPEED_AUTO_NEG) && 10356 (phy->speed_cap_mask & 10357 (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | 10358 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) { 10359 an_10_100_val |= (1<<5); 10360 autoneg_val |= (1<<9 | 1<<12); 10361 if (phy->req_duplex == DUPLEX_FULL) 10362 an_10_100_val |= (1<<6); 10363 DP(NETIF_MSG_LINK, "Advertising 10M\n"); 10364 } 10365 10366 /* Only 10/100 are allowed to work in FORCE mode */ 10367 if (phy->req_line_speed == SPEED_100) { 10368 autoneg_val |= (1<<13); 10369 /* Enabled AUTO-MDIX when autoneg is disabled */ 10370 bnx2x_cl22_write(bp, phy, 10371 0x18, 10372 (1<<15 | 1<<9 | 7<<0)); 10373 DP(NETIF_MSG_LINK, "Setting 100M force\n"); 10374 } 10375 if (phy->req_line_speed == SPEED_10) { 10376 /* Enabled AUTO-MDIX when autoneg is disabled */ 10377 bnx2x_cl22_write(bp, phy, 10378 0x18, 10379 (1<<15 | 1<<9 | 7<<0)); 10380 DP(NETIF_MSG_LINK, "Setting 10M force\n"); 10381 } 10382 10383 /* Check if we should turn on Auto-GrEEEn */ 10384 bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &temp); 10385 if (temp == MDIO_REG_GPHY_ID_54618SE) { 10386 if (params->feature_config_flags & 10387 FEATURE_CONFIG_AUTOGREEEN_ENABLED) { 10388 temp = 6; 10389 DP(NETIF_MSG_LINK, "Enabling Auto-GrEEEn\n"); 10390 } else { 10391 temp = 0; 10392 DP(NETIF_MSG_LINK, "Disabling Auto-GrEEEn\n"); 10393 } 10394 bnx2x_cl22_write(bp, phy, 10395 MDIO_REG_GPHY_CL45_ADDR_REG, MDIO_AN_DEVAD); 10396 bnx2x_cl22_write(bp, phy, 10397 MDIO_REG_GPHY_CL45_DATA_REG, 10398 MDIO_REG_GPHY_EEE_ADV); 10399 bnx2x_cl22_write(bp, phy, 10400 MDIO_REG_GPHY_CL45_ADDR_REG, 10401 (0x1 << 14) | MDIO_AN_DEVAD); 10402 bnx2x_cl22_write(bp, phy, 10403 MDIO_REG_GPHY_CL45_DATA_REG, 10404 temp); 10405 } 10406 10407 bnx2x_cl22_write(bp, phy, 10408 0x04, 10409 an_10_100_val | fc_val); 10410 10411 if (phy->req_duplex == DUPLEX_FULL) 10412 autoneg_val |= (1<<8); 10413 10414 bnx2x_cl22_write(bp, phy, 10415 MDIO_PMA_REG_CTRL, autoneg_val); 10416 10417 return 0; 10418} 10419 10420 10421static void bnx2x_5461x_set_link_led(struct bnx2x_phy *phy, 10422 struct link_params *params, u8 mode) 10423{ 10424 struct bnx2x *bp = params->bp; 10425 u16 temp; 10426 10427 bnx2x_cl22_write(bp, phy, 10428 MDIO_REG_GPHY_SHADOW, 10429 MDIO_REG_GPHY_SHADOW_LED_SEL1); 10430 bnx2x_cl22_read(bp, phy, 10431 MDIO_REG_GPHY_SHADOW, 10432 &temp); 10433 temp &= 0xff00; 10434 10435 DP(NETIF_MSG_LINK, "54618x set link led (mode=%x)\n", mode); 10436 switch (mode) { 10437 case LED_MODE_FRONT_PANEL_OFF: 10438 case LED_MODE_OFF: 10439 temp |= 0x00ee; 10440 break; 10441 case LED_MODE_OPER: 10442 temp |= 0x0001; 10443 break; 10444 case LED_MODE_ON: 10445 temp |= 0x00ff; 10446 break; 10447 default: 10448 break; 10449 } 10450 bnx2x_cl22_write(bp, phy, 10451 MDIO_REG_GPHY_SHADOW, 10452 MDIO_REG_GPHY_SHADOW_WR_ENA | temp); 10453 return; 10454} 10455 10456 10457static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy, 10458 struct link_params *params) 10459{ 10460 struct bnx2x *bp = params->bp; 10461 u32 cfg_pin; 10462 u8 port; 10463 10464 /* 10465 * In case of no EPIO routed to reset the GPHY, put it 10466 * in low power mode. 10467 */ 10468 bnx2x_cl22_write(bp, phy, MDIO_PMA_REG_CTRL, 0x800); 10469 /* 10470 * This works with E3 only, no need to check the chip 10471 * before determining the port. 10472 */ 10473 port = params->port; 10474 cfg_pin = (REG_RD(bp, params->shmem_base + 10475 offsetof(struct shmem_region, 10476 dev_info.port_hw_config[port].e3_cmn_pin_cfg)) & 10477 PORT_HW_CFG_E3_PHY_RESET_MASK) >> 10478 PORT_HW_CFG_E3_PHY_RESET_SHIFT; 10479 10480 /* Drive pin low to put GPHY in reset. */ 10481 bnx2x_set_cfg_pin(bp, cfg_pin, 0); 10482} 10483 10484static u8 bnx2x_54618se_read_status(struct bnx2x_phy *phy, 10485 struct link_params *params, 10486 struct link_vars *vars) 10487{ 10488 struct bnx2x *bp = params->bp; 10489 u16 val; 10490 u8 link_up = 0; 10491 u16 legacy_status, legacy_speed; 10492 10493 /* Get speed operation status */ 10494 bnx2x_cl22_read(bp, phy, 10495 0x19, 10496 &legacy_status); 10497 DP(NETIF_MSG_LINK, "54618SE read_status: 0x%x\n", legacy_status); 10498 10499 /* Read status to clear the PHY interrupt. */ 10500 bnx2x_cl22_read(bp, phy, 10501 MDIO_REG_INTR_STATUS, 10502 &val); 10503 10504 link_up = ((legacy_status & (1<<2)) == (1<<2)); 10505 10506 if (link_up) { 10507 legacy_speed = (legacy_status & (7<<8)); 10508 if (legacy_speed == (7<<8)) { 10509 vars->line_speed = SPEED_1000; 10510 vars->duplex = DUPLEX_FULL; 10511 } else if (legacy_speed == (6<<8)) { 10512 vars->line_speed = SPEED_1000; 10513 vars->duplex = DUPLEX_HALF; 10514 } else if (legacy_speed == (5<<8)) { 10515 vars->line_speed = SPEED_100; 10516 vars->duplex = DUPLEX_FULL; 10517 } 10518 /* Omitting 100Base-T4 for now */ 10519 else if (legacy_speed == (3<<8)) { 10520 vars->line_speed = SPEED_100; 10521 vars->duplex = DUPLEX_HALF; 10522 } else if (legacy_speed == (2<<8)) { 10523 vars->line_speed = SPEED_10; 10524 vars->duplex = DUPLEX_FULL; 10525 } else if (legacy_speed == (1<<8)) { 10526 vars->line_speed = SPEED_10; 10527 vars->duplex = DUPLEX_HALF; 10528 } else /* Should not happen */ 10529 vars->line_speed = 0; 10530 10531 DP(NETIF_MSG_LINK, 10532 "Link is up in %dMbps, is_duplex_full= %d\n", 10533 vars->line_speed, 10534 (vars->duplex == DUPLEX_FULL)); 10535 10536 /* Check legacy speed AN resolution */ 10537 bnx2x_cl22_read(bp, phy, 10538 0x01, 10539 &val); 10540 if (val & (1<<5)) 10541 vars->link_status |= 10542 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; 10543 bnx2x_cl22_read(bp, phy, 10544 0x06, 10545 &val); 10546 if ((val & (1<<0)) == 0) 10547 vars->link_status |= 10548 LINK_STATUS_PARALLEL_DETECTION_USED; 10549 10550 DP(NETIF_MSG_LINK, "BCM54618SE: link speed is %d\n", 10551 vars->line_speed); 10552 10553 /* Report whether EEE is resolved. */ 10554 bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &val); 10555 if (val == MDIO_REG_GPHY_ID_54618SE) { 10556 if (vars->link_status & 10557 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) 10558 val = 0; 10559 else { 10560 bnx2x_cl22_write(bp, phy, 10561 MDIO_REG_GPHY_CL45_ADDR_REG, 10562 MDIO_AN_DEVAD); 10563 bnx2x_cl22_write(bp, phy, 10564 MDIO_REG_GPHY_CL45_DATA_REG, 10565 MDIO_REG_GPHY_EEE_RESOLVED); 10566 bnx2x_cl22_write(bp, phy, 10567 MDIO_REG_GPHY_CL45_ADDR_REG, 10568 (0x1 << 14) | MDIO_AN_DEVAD); 10569 bnx2x_cl22_read(bp, phy, 10570 MDIO_REG_GPHY_CL45_DATA_REG, 10571 &val); 10572 } 10573 DP(NETIF_MSG_LINK, "EEE resolution: 0x%x\n", val); 10574 } 10575 10576 bnx2x_ext_phy_resolve_fc(phy, params, vars); 10577 } 10578 return link_up; 10579} 10580 10581static void bnx2x_54618se_config_loopback(struct bnx2x_phy *phy, 10582 struct link_params *params) 10583{ 10584 struct bnx2x *bp = params->bp; 10585 u16 val; 10586 u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0; 10587 10588 DP(NETIF_MSG_LINK, "2PMA/PMD ext_phy_loopback: 54618se\n"); 10589 10590 /* Enable master/slave manual mmode and set to master */ 10591 /* mii write 9 [bits set 11 12] */ 10592 bnx2x_cl22_write(bp, phy, 0x09, 3<<11); 10593 10594 /* forced 1G and disable autoneg */ 10595 /* set val [mii read 0] */ 10596 /* set val [expr $val & [bits clear 6 12 13]] */ 10597 /* set val [expr $val | [bits set 6 8]] */ 10598 /* mii write 0 $val */ 10599 bnx2x_cl22_read(bp, phy, 0x00, &val); 10600 val &= ~((1<<6) | (1<<12) | (1<<13)); 10601 val |= (1<<6) | (1<<8); 10602 bnx2x_cl22_write(bp, phy, 0x00, val); 10603 10604 /* Set external loopback and Tx using 6dB coding */ 10605 /* mii write 0x18 7 */ 10606 /* set val [mii read 0x18] */ 10607 /* mii write 0x18 [expr $val | [bits set 10 15]] */ 10608 bnx2x_cl22_write(bp, phy, 0x18, 7); 10609 bnx2x_cl22_read(bp, phy, 0x18, &val); 10610 bnx2x_cl22_write(bp, phy, 0x18, val | (1<<10) | (1<<15)); 10611 10612 /* This register opens the gate for the UMAC despite its name */ 10613 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1); 10614 10615 /* 10616 * Maximum Frame Length (RW). Defines a 14-Bit maximum frame 10617 * length used by the MAC receive logic to check frames. 10618 */ 10619 REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710); 10620} 10621 10622/******************************************************************/ 10623/* SFX7101 PHY SECTION */ 10624/******************************************************************/ 10625static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy, 10626 struct link_params *params) 10627{ 10628 struct bnx2x *bp = params->bp; 10629 /* SFX7101_XGXS_TEST1 */ 10630 bnx2x_cl45_write(bp, phy, 10631 MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100); 10632} 10633 10634static int bnx2x_7101_config_init(struct bnx2x_phy *phy, 10635 struct link_params *params, 10636 struct link_vars *vars) 10637{ 10638 u16 fw_ver1, fw_ver2, val; 10639 struct bnx2x *bp = params->bp; 10640 DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n"); 10641 10642 /* Restore normal power mode*/ 10643 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 10644 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); 10645 /* HW reset */ 10646 bnx2x_ext_phy_hw_reset(bp, params->port); 10647 bnx2x_wait_reset_complete(bp, phy, params); 10648 10649 bnx2x_cl45_write(bp, phy, 10650 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x1); 10651 DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n"); 10652 bnx2x_cl45_write(bp, phy, 10653 MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3)); 10654 10655 bnx2x_ext_phy_set_pause(params, phy, vars); 10656 /* Restart autoneg */ 10657 bnx2x_cl45_read(bp, phy, 10658 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val); 10659 val |= 0x200; 10660 bnx2x_cl45_write(bp, phy, 10661 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val); 10662 10663 /* Save spirom version */ 10664 bnx2x_cl45_read(bp, phy, 10665 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1); 10666 10667 bnx2x_cl45_read(bp, phy, 10668 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2); 10669 bnx2x_save_spirom_version(bp, params->port, 10670 (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr); 10671 return 0; 10672} 10673 10674static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy, 10675 struct link_params *params, 10676 struct link_vars *vars) 10677{ 10678 struct bnx2x *bp = params->bp; 10679 u8 link_up; 10680 u16 val1, val2; 10681 bnx2x_cl45_read(bp, phy, 10682 MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2); 10683 bnx2x_cl45_read(bp, phy, 10684 MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1); 10685 DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n", 10686 val2, val1); 10687 bnx2x_cl45_read(bp, phy, 10688 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); 10689 bnx2x_cl45_read(bp, phy, 10690 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); 10691 DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n", 10692 val2, val1); 10693 link_up = ((val1 & 4) == 4); 10694 /* if link is up print the AN outcome of the SFX7101 PHY */ 10695 if (link_up) { 10696 bnx2x_cl45_read(bp, phy, 10697 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS, 10698 &val2); 10699 vars->line_speed = SPEED_10000; 10700 vars->duplex = DUPLEX_FULL; 10701 DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n", 10702 val2, (val2 & (1<<14))); 10703 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); 10704 bnx2x_ext_phy_resolve_fc(phy, params, vars); 10705 } 10706 return link_up; 10707} 10708 10709static int bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len) 10710{ 10711 if (*len < 5) 10712 return -EINVAL; 10713 str[0] = (spirom_ver & 0xFF); 10714 str[1] = (spirom_ver & 0xFF00) >> 8; 10715 str[2] = (spirom_ver & 0xFF0000) >> 16; 10716 str[3] = (spirom_ver & 0xFF000000) >> 24; 10717 str[4] = '\0'; 10718 *len -= 5; 10719 return 0; 10720} 10721 10722void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy) 10723{ 10724 u16 val, cnt; 10725 10726 bnx2x_cl45_read(bp, phy, 10727 MDIO_PMA_DEVAD, 10728 MDIO_PMA_REG_7101_RESET, &val); 10729 10730 for (cnt = 0; cnt < 10; cnt++) { 10731 msleep(50); 10732 /* Writes a self-clearing reset */ 10733 bnx2x_cl45_write(bp, phy, 10734 MDIO_PMA_DEVAD, 10735 MDIO_PMA_REG_7101_RESET, 10736 (val | (1<<15))); 10737 /* Wait for clear */ 10738 bnx2x_cl45_read(bp, phy, 10739 MDIO_PMA_DEVAD, 10740 MDIO_PMA_REG_7101_RESET, &val); 10741 10742 if ((val & (1<<15)) == 0) 10743 break; 10744 } 10745} 10746 10747static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy, 10748 struct link_params *params) { 10749 /* Low power mode is controlled by GPIO 2 */ 10750 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2, 10751 MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port); 10752 /* The PHY reset is controlled by GPIO 1 */ 10753 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, 10754 MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port); 10755} 10756 10757static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy, 10758 struct link_params *params, u8 mode) 10759{ 10760 u16 val = 0; 10761 struct bnx2x *bp = params->bp; 10762 switch (mode) { 10763 case LED_MODE_FRONT_PANEL_OFF: 10764 case LED_MODE_OFF: 10765 val = 2; 10766 break; 10767 case LED_MODE_ON: 10768 val = 1; 10769 break; 10770 case LED_MODE_OPER: 10771 val = 0; 10772 break; 10773 } 10774 bnx2x_cl45_write(bp, phy, 10775 MDIO_PMA_DEVAD, 10776 MDIO_PMA_REG_7107_LINK_LED_CNTL, 10777 val); 10778} 10779 10780/******************************************************************/ 10781/* STATIC PHY DECLARATION */ 10782/******************************************************************/ 10783 10784static struct bnx2x_phy phy_null = { 10785 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN, 10786 .addr = 0, 10787 .def_md_devad = 0, 10788 .flags = FLAGS_INIT_XGXS_FIRST, 10789 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10790 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10791 .mdio_ctrl = 0, 10792 .supported = 0, 10793 .media_type = ETH_PHY_NOT_PRESENT, 10794 .ver_addr = 0, 10795 .req_flow_ctrl = 0, 10796 .req_line_speed = 0, 10797 .speed_cap_mask = 0, 10798 .req_duplex = 0, 10799 .rsrv = 0, 10800 .config_init = (config_init_t)NULL, 10801 .read_status = (read_status_t)NULL, 10802 .link_reset = (link_reset_t)NULL, 10803 .config_loopback = (config_loopback_t)NULL, 10804 .format_fw_ver = (format_fw_ver_t)NULL, 10805 .hw_reset = (hw_reset_t)NULL, 10806 .set_link_led = (set_link_led_t)NULL, 10807 .phy_specific_func = (phy_specific_func_t)NULL 10808}; 10809 10810static struct bnx2x_phy phy_serdes = { 10811 .type = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT, 10812 .addr = 0xff, 10813 .def_md_devad = 0, 10814 .flags = 0, 10815 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10816 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10817 .mdio_ctrl = 0, 10818 .supported = (SUPPORTED_10baseT_Half | 10819 SUPPORTED_10baseT_Full | 10820 SUPPORTED_100baseT_Half | 10821 SUPPORTED_100baseT_Full | 10822 SUPPORTED_1000baseT_Full | 10823 SUPPORTED_2500baseX_Full | 10824 SUPPORTED_TP | 10825 SUPPORTED_Autoneg | 10826 SUPPORTED_Pause | 10827 SUPPORTED_Asym_Pause), 10828 .media_type = ETH_PHY_BASE_T, 10829 .ver_addr = 0, 10830 .req_flow_ctrl = 0, 10831 .req_line_speed = 0, 10832 .speed_cap_mask = 0, 10833 .req_duplex = 0, 10834 .rsrv = 0, 10835 .config_init = (config_init_t)bnx2x_xgxs_config_init, 10836 .read_status = (read_status_t)bnx2x_link_settings_status, 10837 .link_reset = (link_reset_t)bnx2x_int_link_reset, 10838 .config_loopback = (config_loopback_t)NULL, 10839 .format_fw_ver = (format_fw_ver_t)NULL, 10840 .hw_reset = (hw_reset_t)NULL, 10841 .set_link_led = (set_link_led_t)NULL, 10842 .phy_specific_func = (phy_specific_func_t)NULL 10843}; 10844 10845static struct bnx2x_phy phy_xgxs = { 10846 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT, 10847 .addr = 0xff, 10848 .def_md_devad = 0, 10849 .flags = 0, 10850 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10851 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10852 .mdio_ctrl = 0, 10853 .supported = (SUPPORTED_10baseT_Half | 10854 SUPPORTED_10baseT_Full | 10855 SUPPORTED_100baseT_Half | 10856 SUPPORTED_100baseT_Full | 10857 SUPPORTED_1000baseT_Full | 10858 SUPPORTED_2500baseX_Full | 10859 SUPPORTED_10000baseT_Full | 10860 SUPPORTED_FIBRE | 10861 SUPPORTED_Autoneg | 10862 SUPPORTED_Pause | 10863 SUPPORTED_Asym_Pause), 10864 .media_type = ETH_PHY_CX4, 10865 .ver_addr = 0, 10866 .req_flow_ctrl = 0, 10867 .req_line_speed = 0, 10868 .speed_cap_mask = 0, 10869 .req_duplex = 0, 10870 .rsrv = 0, 10871 .config_init = (config_init_t)bnx2x_xgxs_config_init, 10872 .read_status = (read_status_t)bnx2x_link_settings_status, 10873 .link_reset = (link_reset_t)bnx2x_int_link_reset, 10874 .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback, 10875 .format_fw_ver = (format_fw_ver_t)NULL, 10876 .hw_reset = (hw_reset_t)NULL, 10877 .set_link_led = (set_link_led_t)NULL, 10878 .phy_specific_func = (phy_specific_func_t)NULL 10879}; 10880static struct bnx2x_phy phy_warpcore = { 10881 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT, 10882 .addr = 0xff, 10883 .def_md_devad = 0, 10884 .flags = FLAGS_HW_LOCK_REQUIRED, 10885 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10886 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10887 .mdio_ctrl = 0, 10888 .supported = (SUPPORTED_10baseT_Half | 10889 SUPPORTED_10baseT_Full | 10890 SUPPORTED_100baseT_Half | 10891 SUPPORTED_100baseT_Full | 10892 SUPPORTED_1000baseT_Full | 10893 SUPPORTED_10000baseT_Full | 10894 SUPPORTED_20000baseKR2_Full | 10895 SUPPORTED_20000baseMLD2_Full | 10896 SUPPORTED_FIBRE | 10897 SUPPORTED_Autoneg | 10898 SUPPORTED_Pause | 10899 SUPPORTED_Asym_Pause), 10900 .media_type = ETH_PHY_UNSPECIFIED, 10901 .ver_addr = 0, 10902 .req_flow_ctrl = 0, 10903 .req_line_speed = 0, 10904 .speed_cap_mask = 0, 10905 /* req_duplex = */0, 10906 /* rsrv = */0, 10907 .config_init = (config_init_t)bnx2x_warpcore_config_init, 10908 .read_status = (read_status_t)bnx2x_warpcore_read_status, 10909 .link_reset = (link_reset_t)bnx2x_warpcore_link_reset, 10910 .config_loopback = (config_loopback_t)bnx2x_set_warpcore_loopback, 10911 .format_fw_ver = (format_fw_ver_t)NULL, 10912 .hw_reset = (hw_reset_t)bnx2x_warpcore_hw_reset, 10913 .set_link_led = (set_link_led_t)NULL, 10914 .phy_specific_func = (phy_specific_func_t)NULL 10915}; 10916 10917 10918static struct bnx2x_phy phy_7101 = { 10919 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, 10920 .addr = 0xff, 10921 .def_md_devad = 0, 10922 .flags = FLAGS_FAN_FAILURE_DET_REQ, 10923 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10924 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10925 .mdio_ctrl = 0, 10926 .supported = (SUPPORTED_10000baseT_Full | 10927 SUPPORTED_TP | 10928 SUPPORTED_Autoneg | 10929 SUPPORTED_Pause | 10930 SUPPORTED_Asym_Pause), 10931 .media_type = ETH_PHY_BASE_T, 10932 .ver_addr = 0, 10933 .req_flow_ctrl = 0, 10934 .req_line_speed = 0, 10935 .speed_cap_mask = 0, 10936 .req_duplex = 0, 10937 .rsrv = 0, 10938 .config_init = (config_init_t)bnx2x_7101_config_init, 10939 .read_status = (read_status_t)bnx2x_7101_read_status, 10940 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset, 10941 .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback, 10942 .format_fw_ver = (format_fw_ver_t)bnx2x_7101_format_ver, 10943 .hw_reset = (hw_reset_t)bnx2x_7101_hw_reset, 10944 .set_link_led = (set_link_led_t)bnx2x_7101_set_link_led, 10945 .phy_specific_func = (phy_specific_func_t)NULL 10946}; 10947static struct bnx2x_phy phy_8073 = { 10948 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, 10949 .addr = 0xff, 10950 .def_md_devad = 0, 10951 .flags = FLAGS_HW_LOCK_REQUIRED, 10952 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10953 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10954 .mdio_ctrl = 0, 10955 .supported = (SUPPORTED_10000baseT_Full | 10956 SUPPORTED_2500baseX_Full | 10957 SUPPORTED_1000baseT_Full | 10958 SUPPORTED_FIBRE | 10959 SUPPORTED_Autoneg | 10960 SUPPORTED_Pause | 10961 SUPPORTED_Asym_Pause), 10962 .media_type = ETH_PHY_KR, 10963 .ver_addr = 0, 10964 .req_flow_ctrl = 0, 10965 .req_line_speed = 0, 10966 .speed_cap_mask = 0, 10967 .req_duplex = 0, 10968 .rsrv = 0, 10969 .config_init = (config_init_t)bnx2x_8073_config_init, 10970 .read_status = (read_status_t)bnx2x_8073_read_status, 10971 .link_reset = (link_reset_t)bnx2x_8073_link_reset, 10972 .config_loopback = (config_loopback_t)NULL, 10973 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, 10974 .hw_reset = (hw_reset_t)NULL, 10975 .set_link_led = (set_link_led_t)NULL, 10976 .phy_specific_func = (phy_specific_func_t)NULL 10977}; 10978static struct bnx2x_phy phy_8705 = { 10979 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705, 10980 .addr = 0xff, 10981 .def_md_devad = 0, 10982 .flags = FLAGS_INIT_XGXS_FIRST, 10983 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10984 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10985 .mdio_ctrl = 0, 10986 .supported = (SUPPORTED_10000baseT_Full | 10987 SUPPORTED_FIBRE | 10988 SUPPORTED_Pause | 10989 SUPPORTED_Asym_Pause), 10990 .media_type = ETH_PHY_XFP_FIBER, 10991 .ver_addr = 0, 10992 .req_flow_ctrl = 0, 10993 .req_line_speed = 0, 10994 .speed_cap_mask = 0, 10995 .req_duplex = 0, 10996 .rsrv = 0, 10997 .config_init = (config_init_t)bnx2x_8705_config_init, 10998 .read_status = (read_status_t)bnx2x_8705_read_status, 10999 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset, 11000 .config_loopback = (config_loopback_t)NULL, 11001 .format_fw_ver = (format_fw_ver_t)bnx2x_null_format_ver, 11002 .hw_reset = (hw_reset_t)NULL, 11003 .set_link_led = (set_link_led_t)NULL, 11004 .phy_specific_func = (phy_specific_func_t)NULL 11005}; 11006static struct bnx2x_phy phy_8706 = { 11007 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706, 11008 .addr = 0xff, 11009 .def_md_devad = 0, 11010 .flags = FLAGS_INIT_XGXS_FIRST, 11011 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 11012 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 11013 .mdio_ctrl = 0, 11014 .supported = (SUPPORTED_10000baseT_Full | 11015 SUPPORTED_1000baseT_Full | 11016 SUPPORTED_FIBRE | 11017 SUPPORTED_Pause | 11018 SUPPORTED_Asym_Pause), 11019 .media_type = ETH_PHY_SFP_FIBER, 11020 .ver_addr = 0, 11021 .req_flow_ctrl = 0, 11022 .req_line_speed = 0, 11023 .speed_cap_mask = 0, 11024 .req_duplex = 0, 11025 .rsrv = 0, 11026 .config_init = (config_init_t)bnx2x_8706_config_init, 11027 .read_status = (read_status_t)bnx2x_8706_read_status, 11028 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset, 11029 .config_loopback = (config_loopback_t)NULL, 11030 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, 11031 .hw_reset = (hw_reset_t)NULL, 11032 .set_link_led = (set_link_led_t)NULL, 11033 .phy_specific_func = (phy_specific_func_t)NULL 11034}; 11035 11036static struct bnx2x_phy phy_8726 = { 11037 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, 11038 .addr = 0xff, 11039 .def_md_devad = 0, 11040 .flags = (FLAGS_HW_LOCK_REQUIRED | 11041 FLAGS_INIT_XGXS_FIRST), 11042 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 11043 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 11044 .mdio_ctrl = 0, 11045 .supported = (SUPPORTED_10000baseT_Full | 11046 SUPPORTED_1000baseT_Full | 11047 SUPPORTED_Autoneg | 11048 SUPPORTED_FIBRE | 11049 SUPPORTED_Pause | 11050 SUPPORTED_Asym_Pause), 11051 .media_type = ETH_PHY_NOT_PRESENT, 11052 .ver_addr = 0, 11053 .req_flow_ctrl = 0, 11054 .req_line_speed = 0, 11055 .speed_cap_mask = 0, 11056 .req_duplex = 0, 11057 .rsrv = 0, 11058 .config_init = (config_init_t)bnx2x_8726_config_init, 11059 .read_status = (read_status_t)bnx2x_8726_read_status, 11060 .link_reset = (link_reset_t)bnx2x_8726_link_reset, 11061 .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback, 11062 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, 11063 .hw_reset = (hw_reset_t)NULL, 11064 .set_link_led = (set_link_led_t)NULL, 11065 .phy_specific_func = (phy_specific_func_t)NULL 11066}; 11067 11068static struct bnx2x_phy phy_8727 = { 11069 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, 11070 .addr = 0xff, 11071 .def_md_devad = 0, 11072 .flags = FLAGS_FAN_FAILURE_DET_REQ, 11073 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 11074 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 11075 .mdio_ctrl = 0, 11076 .supported = (SUPPORTED_10000baseT_Full | 11077 SUPPORTED_1000baseT_Full | 11078 SUPPORTED_FIBRE | 11079 SUPPORTED_Pause | 11080 SUPPORTED_Asym_Pause), 11081 .media_type = ETH_PHY_NOT_PRESENT, 11082 .ver_addr = 0, 11083 .req_flow_ctrl = 0, 11084 .req_line_speed = 0, 11085 .speed_cap_mask = 0, 11086 .req_duplex = 0, 11087 .rsrv = 0, 11088 .config_init = (config_init_t)bnx2x_8727_config_init, 11089 .read_status = (read_status_t)bnx2x_8727_read_status, 11090 .link_reset = (link_reset_t)bnx2x_8727_link_reset, 11091 .config_loopback = (config_loopback_t)NULL, 11092 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, 11093 .hw_reset = (hw_reset_t)bnx2x_8727_hw_reset, 11094 .set_link_led = (set_link_led_t)bnx2x_8727_set_link_led, 11095 .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func 11096}; 11097static struct bnx2x_phy phy_8481 = { 11098 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, 11099 .addr = 0xff, 11100 .def_md_devad = 0, 11101 .flags = FLAGS_FAN_FAILURE_DET_REQ | 11102 FLAGS_REARM_LATCH_SIGNAL, 11103 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 11104 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 11105 .mdio_ctrl = 0, 11106 .supported = (SUPPORTED_10baseT_Half | 11107 SUPPORTED_10baseT_Full | 11108 SUPPORTED_100baseT_Half | 11109 SUPPORTED_100baseT_Full | 11110 SUPPORTED_1000baseT_Full | 11111 SUPPORTED_10000baseT_Full | 11112 SUPPORTED_TP | 11113 SUPPORTED_Autoneg | 11114 SUPPORTED_Pause | 11115 SUPPORTED_Asym_Pause), 11116 .media_type = ETH_PHY_BASE_T, 11117 .ver_addr = 0, 11118 .req_flow_ctrl = 0, 11119 .req_line_speed = 0, 11120 .speed_cap_mask = 0, 11121 .req_duplex = 0, 11122 .rsrv = 0, 11123 .config_init = (config_init_t)bnx2x_8481_config_init, 11124 .read_status = (read_status_t)bnx2x_848xx_read_status, 11125 .link_reset = (link_reset_t)bnx2x_8481_link_reset, 11126 .config_loopback = (config_loopback_t)NULL, 11127 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, 11128 .hw_reset = (hw_reset_t)bnx2x_8481_hw_reset, 11129 .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led, 11130 .phy_specific_func = (phy_specific_func_t)NULL 11131}; 11132 11133static struct bnx2x_phy phy_84823 = { 11134 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823, 11135 .addr = 0xff, 11136 .def_md_devad = 0, 11137 .flags = FLAGS_FAN_FAILURE_DET_REQ | 11138 FLAGS_REARM_LATCH_SIGNAL, 11139 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 11140 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 11141 .mdio_ctrl = 0, 11142 .supported = (SUPPORTED_10baseT_Half | 11143 SUPPORTED_10baseT_Full | 11144 SUPPORTED_100baseT_Half | 11145 SUPPORTED_100baseT_Full | 11146 SUPPORTED_1000baseT_Full | 11147 SUPPORTED_10000baseT_Full | 11148 SUPPORTED_TP | 11149 SUPPORTED_Autoneg | 11150 SUPPORTED_Pause | 11151 SUPPORTED_Asym_Pause), 11152 .media_type = ETH_PHY_BASE_T, 11153 .ver_addr = 0, 11154 .req_flow_ctrl = 0, 11155 .req_line_speed = 0, 11156 .speed_cap_mask = 0, 11157 .req_duplex = 0, 11158 .rsrv = 0, 11159 .config_init = (config_init_t)bnx2x_848x3_config_init, 11160 .read_status = (read_status_t)bnx2x_848xx_read_status, 11161 .link_reset = (link_reset_t)bnx2x_848x3_link_reset, 11162 .config_loopback = (config_loopback_t)NULL, 11163 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, 11164 .hw_reset = (hw_reset_t)NULL, 11165 .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led, 11166 .phy_specific_func = (phy_specific_func_t)NULL 11167}; 11168 11169static struct bnx2x_phy phy_84833 = { 11170 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833, 11171 .addr = 0xff, 11172 .def_md_devad = 0, 11173 .flags = FLAGS_FAN_FAILURE_DET_REQ | 11174 FLAGS_REARM_LATCH_SIGNAL, 11175 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 11176 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 11177 .mdio_ctrl = 0, 11178 .supported = (SUPPORTED_100baseT_Half | 11179 SUPPORTED_100baseT_Full | 11180 SUPPORTED_1000baseT_Full | 11181 SUPPORTED_10000baseT_Full | 11182 SUPPORTED_TP | 11183 SUPPORTED_Autoneg | 11184 SUPPORTED_Pause | 11185 SUPPORTED_Asym_Pause), 11186 .media_type = ETH_PHY_BASE_T, 11187 .ver_addr = 0, 11188 .req_flow_ctrl = 0, 11189 .req_line_speed = 0, 11190 .speed_cap_mask = 0, 11191 .req_duplex = 0, 11192 .rsrv = 0, 11193 .config_init = (config_init_t)bnx2x_848x3_config_init, 11194 .read_status = (read_status_t)bnx2x_848xx_read_status, 11195 .link_reset = (link_reset_t)bnx2x_848x3_link_reset, 11196 .config_loopback = (config_loopback_t)NULL, 11197 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, 11198 .hw_reset = (hw_reset_t)bnx2x_84833_hw_reset_phy, 11199 .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led, 11200 .phy_specific_func = (phy_specific_func_t)NULL 11201}; 11202 11203static struct bnx2x_phy phy_54618se = { 11204 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE, 11205 .addr = 0xff, 11206 .def_md_devad = 0, 11207 .flags = FLAGS_INIT_XGXS_FIRST, 11208 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 11209 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 11210 .mdio_ctrl = 0, 11211 .supported = (SUPPORTED_10baseT_Half | 11212 SUPPORTED_10baseT_Full | 11213 SUPPORTED_100baseT_Half | 11214 SUPPORTED_100baseT_Full | 11215 SUPPORTED_1000baseT_Full | 11216 SUPPORTED_TP | 11217 SUPPORTED_Autoneg | 11218 SUPPORTED_Pause | 11219 SUPPORTED_Asym_Pause), 11220 .media_type = ETH_PHY_BASE_T, 11221 .ver_addr = 0, 11222 .req_flow_ctrl = 0, 11223 .req_line_speed = 0, 11224 .speed_cap_mask = 0, 11225 /* req_duplex = */0, 11226 /* rsrv = */0, 11227 .config_init = (config_init_t)bnx2x_54618se_config_init, 11228 .read_status = (read_status_t)bnx2x_54618se_read_status, 11229 .link_reset = (link_reset_t)bnx2x_54618se_link_reset, 11230 .config_loopback = (config_loopback_t)bnx2x_54618se_config_loopback, 11231 .format_fw_ver = (format_fw_ver_t)NULL, 11232 .hw_reset = (hw_reset_t)NULL, 11233 .set_link_led = (set_link_led_t)bnx2x_5461x_set_link_led, 11234 .phy_specific_func = (phy_specific_func_t)NULL 11235}; 11236/*****************************************************************/ 11237/* */ 11238/* Populate the phy according. Main function: bnx2x_populate_phy */ 11239/* */ 11240/*****************************************************************/ 11241 11242static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base, 11243 struct bnx2x_phy *phy, u8 port, 11244 u8 phy_index) 11245{ 11246 /* Get the 4 lanes xgxs config rx and tx */ 11247 u32 rx = 0, tx = 0, i; 11248 for (i = 0; i < 2; i++) { 11249 /* 11250 * INT_PHY and EXT_PHY1 share the same value location in the 11251 * shmem. When num_phys is greater than 1, than this value 11252 * applies only to EXT_PHY1 11253 */ 11254 if (phy_index == INT_PHY || phy_index == EXT_PHY1) { 11255 rx = REG_RD(bp, shmem_base + 11256 offsetof(struct shmem_region, 11257 dev_info.port_hw_config[port].xgxs_config_rx[i<<1])); 11258 11259 tx = REG_RD(bp, shmem_base + 11260 offsetof(struct shmem_region, 11261 dev_info.port_hw_config[port].xgxs_config_tx[i<<1])); 11262 } else { 11263 rx = REG_RD(bp, shmem_base + 11264 offsetof(struct shmem_region, 11265 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1])); 11266 11267 tx = REG_RD(bp, shmem_base + 11268 offsetof(struct shmem_region, 11269 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1])); 11270 } 11271 11272 phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff); 11273 phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff); 11274 11275 phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff); 11276 phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff); 11277 } 11278} 11279 11280static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base, 11281 u8 phy_index, u8 port) 11282{ 11283 u32 ext_phy_config = 0; 11284 switch (phy_index) { 11285 case EXT_PHY1: 11286 ext_phy_config = REG_RD(bp, shmem_base + 11287 offsetof(struct shmem_region, 11288 dev_info.port_hw_config[port].external_phy_config)); 11289 break; 11290 case EXT_PHY2: 11291 ext_phy_config = REG_RD(bp, shmem_base + 11292 offsetof(struct shmem_region, 11293 dev_info.port_hw_config[port].external_phy_config2)); 11294 break; 11295 default: 11296 DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index); 11297 return -EINVAL; 11298 } 11299 11300 return ext_phy_config; 11301} 11302static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, 11303 struct bnx2x_phy *phy) 11304{ 11305 u32 phy_addr; 11306 u32 chip_id; 11307 u32 switch_cfg = (REG_RD(bp, shmem_base + 11308 offsetof(struct shmem_region, 11309 dev_info.port_feature_config[port].link_config)) & 11310 PORT_FEATURE_CONNECTED_SWITCH_MASK); 11311 chip_id = (REG_RD(bp, MISC_REG_CHIP_NUM) << 16) | 11312 ((REG_RD(bp, MISC_REG_CHIP_REV) & 0xf) << 12); 11313 11314 DP(NETIF_MSG_LINK, ":chip_id = 0x%x\n", chip_id); 11315 if (USES_WARPCORE(bp)) { 11316 u32 serdes_net_if; 11317 phy_addr = REG_RD(bp, 11318 MISC_REG_WC0_CTRL_PHY_ADDR); 11319 *phy = phy_warpcore; 11320 if (REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR) == 0x3) 11321 phy->flags |= FLAGS_4_PORT_MODE; 11322 else 11323 phy->flags &= ~FLAGS_4_PORT_MODE; 11324 /* Check Dual mode */ 11325 serdes_net_if = (REG_RD(bp, shmem_base + 11326 offsetof(struct shmem_region, dev_info. 11327 port_hw_config[port].default_cfg)) & 11328 PORT_HW_CFG_NET_SERDES_IF_MASK); 11329 /* 11330 * Set the appropriate supported and flags indications per 11331 * interface type of the chip 11332 */ 11333 switch (serdes_net_if) { 11334 case PORT_HW_CFG_NET_SERDES_IF_SGMII: 11335 phy->supported &= (SUPPORTED_10baseT_Half | 11336 SUPPORTED_10baseT_Full | 11337 SUPPORTED_100baseT_Half | 11338 SUPPORTED_100baseT_Full | 11339 SUPPORTED_1000baseT_Full | 11340 SUPPORTED_FIBRE | 11341 SUPPORTED_Autoneg | 11342 SUPPORTED_Pause | 11343 SUPPORTED_Asym_Pause); 11344 phy->media_type = ETH_PHY_BASE_T; 11345 break; 11346 case PORT_HW_CFG_NET_SERDES_IF_XFI: 11347 phy->media_type = ETH_PHY_XFP_FIBER; 11348 break; 11349 case PORT_HW_CFG_NET_SERDES_IF_SFI: 11350 phy->supported &= (SUPPORTED_1000baseT_Full | 11351 SUPPORTED_10000baseT_Full | 11352 SUPPORTED_FIBRE | 11353 SUPPORTED_Pause | 11354 SUPPORTED_Asym_Pause); 11355 phy->media_type = ETH_PHY_SFP_FIBER; 11356 break; 11357 case PORT_HW_CFG_NET_SERDES_IF_KR: 11358 phy->media_type = ETH_PHY_KR; 11359 phy->supported &= (SUPPORTED_1000baseT_Full | 11360 SUPPORTED_10000baseT_Full | 11361 SUPPORTED_FIBRE | 11362 SUPPORTED_Autoneg | 11363 SUPPORTED_Pause | 11364 SUPPORTED_Asym_Pause); 11365 break; 11366 case PORT_HW_CFG_NET_SERDES_IF_DXGXS: 11367 phy->media_type = ETH_PHY_KR; 11368 phy->flags |= FLAGS_WC_DUAL_MODE; 11369 phy->supported &= (SUPPORTED_20000baseMLD2_Full | 11370 SUPPORTED_FIBRE | 11371 SUPPORTED_Pause | 11372 SUPPORTED_Asym_Pause); 11373 break; 11374 case PORT_HW_CFG_NET_SERDES_IF_KR2: 11375 phy->media_type = ETH_PHY_KR; 11376 phy->flags |= FLAGS_WC_DUAL_MODE; 11377 phy->supported &= (SUPPORTED_20000baseKR2_Full | 11378 SUPPORTED_FIBRE | 11379 SUPPORTED_Pause | 11380 SUPPORTED_Asym_Pause); 11381 break; 11382 default: 11383 DP(NETIF_MSG_LINK, "Unknown WC interface type 0x%x\n", 11384 serdes_net_if); 11385 break; 11386 } 11387 11388 /* 11389 * Enable MDC/MDIO work-around for E3 A0 since free running MDC 11390 * was not set as expected. For B0, ECO will be enabled so there 11391 * won't be an issue there 11392 */ 11393 if (CHIP_REV(bp) == CHIP_REV_Ax) 11394 phy->flags |= FLAGS_MDC_MDIO_WA; 11395 else 11396 phy->flags |= FLAGS_MDC_MDIO_WA_B0; 11397 } else { 11398 switch (switch_cfg) { 11399 case SWITCH_CFG_1G: 11400 phy_addr = REG_RD(bp, 11401 NIG_REG_SERDES0_CTRL_PHY_ADDR + 11402 port * 0x10); 11403 *phy = phy_serdes; 11404 break; 11405 case SWITCH_CFG_10G: 11406 phy_addr = REG_RD(bp, 11407 NIG_REG_XGXS0_CTRL_PHY_ADDR + 11408 port * 0x18); 11409 *phy = phy_xgxs; 11410 break; 11411 default: 11412 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n"); 11413 return -EINVAL; 11414 } 11415 } 11416 phy->addr = (u8)phy_addr; 11417 phy->mdio_ctrl = bnx2x_get_emac_base(bp, 11418 SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH, 11419 port); 11420 if (CHIP_IS_E2(bp)) 11421 phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR; 11422 else 11423 phy->def_md_devad = DEFAULT_PHY_DEV_ADDR; 11424 11425 DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n", 11426 port, phy->addr, phy->mdio_ctrl); 11427 11428 bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY); 11429 return 0; 11430} 11431 11432static int bnx2x_populate_ext_phy(struct bnx2x *bp, 11433 u8 phy_index, 11434 u32 shmem_base, 11435 u32 shmem2_base, 11436 u8 port, 11437 struct bnx2x_phy *phy) 11438{ 11439 u32 ext_phy_config, phy_type, config2; 11440 u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH; 11441 ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base, 11442 phy_index, port); 11443 phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); 11444 /* Select the phy type */ 11445 switch (phy_type) { 11446 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 11447 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED; 11448 *phy = phy_8073; 11449 break; 11450 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: 11451 *phy = phy_8705; 11452 break; 11453 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: 11454 *phy = phy_8706; 11455 break; 11456 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: 11457 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; 11458 *phy = phy_8726; 11459 break; 11460 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: 11461 /* BCM8727_NOC => BCM8727 no over current */ 11462 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; 11463 *phy = phy_8727; 11464 phy->flags |= FLAGS_NOC; 11465 break; 11466 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722: 11467 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: 11468 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; 11469 *phy = phy_8727; 11470 break; 11471 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: 11472 *phy = phy_8481; 11473 break; 11474 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: 11475 *phy = phy_84823; 11476 break; 11477 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833: 11478 *phy = phy_84833; 11479 break; 11480 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616: 11481 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE: 11482 *phy = phy_54618se; 11483 break; 11484 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: 11485 *phy = phy_7101; 11486 break; 11487 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: 11488 *phy = phy_null; 11489 return -EINVAL; 11490 default: 11491 *phy = phy_null; 11492 /* In case external PHY wasn't found */ 11493 if ((phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && 11494 (phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) 11495 return -EINVAL; 11496 return 0; 11497 } 11498 11499 phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config); 11500 bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index); 11501 11502 /* 11503 * The shmem address of the phy version is located on different 11504 * structures. In case this structure is too old, do not set 11505 * the address 11506 */ 11507 config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region, 11508 dev_info.shared_hw_config.config2)); 11509 if (phy_index == EXT_PHY1) { 11510 phy->ver_addr = shmem_base + offsetof(struct shmem_region, 11511 port_mb[port].ext_phy_fw_version); 11512 11513 /* Check specific mdc mdio settings */ 11514 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK) 11515 mdc_mdio_access = config2 & 11516 SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK; 11517 } else { 11518 u32 size = REG_RD(bp, shmem2_base); 11519 11520 if (size > 11521 offsetof(struct shmem2_region, ext_phy_fw_version2)) { 11522 phy->ver_addr = shmem2_base + 11523 offsetof(struct shmem2_region, 11524 ext_phy_fw_version2[port]); 11525 } 11526 /* Check specific mdc mdio settings */ 11527 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) 11528 mdc_mdio_access = (config2 & 11529 SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >> 11530 (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT - 11531 SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT); 11532 } 11533 phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port); 11534 11535 /* 11536 * In case mdc/mdio_access of the external phy is different than the 11537 * mdc/mdio access of the XGXS, a HW lock must be taken in each access 11538 * to prevent one port interfere with another port's CL45 operations. 11539 */ 11540 if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH) 11541 phy->flags |= FLAGS_HW_LOCK_REQUIRED; 11542 DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n", 11543 phy_type, port, phy_index); 11544 DP(NETIF_MSG_LINK, " addr=0x%x, mdio_ctl=0x%x\n", 11545 phy->addr, phy->mdio_ctrl); 11546 return 0; 11547} 11548 11549static int bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base, 11550 u32 shmem2_base, u8 port, struct bnx2x_phy *phy) 11551{ 11552 int status = 0; 11553 phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN; 11554 if (phy_index == INT_PHY) 11555 return bnx2x_populate_int_phy(bp, shmem_base, port, phy); 11556 status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base, 11557 port, phy); 11558 return status; 11559} 11560 11561static void bnx2x_phy_def_cfg(struct link_params *params, 11562 struct bnx2x_phy *phy, 11563 u8 phy_index) 11564{ 11565 struct bnx2x *bp = params->bp; 11566 u32 link_config; 11567 /* Populate the default phy configuration for MF mode */ 11568 if (phy_index == EXT_PHY2) { 11569 link_config = REG_RD(bp, params->shmem_base + 11570 offsetof(struct shmem_region, dev_info. 11571 port_feature_config[params->port].link_config2)); 11572 phy->speed_cap_mask = REG_RD(bp, params->shmem_base + 11573 offsetof(struct shmem_region, 11574 dev_info. 11575 port_hw_config[params->port].speed_capability_mask2)); 11576 } else { 11577 link_config = REG_RD(bp, params->shmem_base + 11578 offsetof(struct shmem_region, dev_info. 11579 port_feature_config[params->port].link_config)); 11580 phy->speed_cap_mask = REG_RD(bp, params->shmem_base + 11581 offsetof(struct shmem_region, 11582 dev_info. 11583 port_hw_config[params->port].speed_capability_mask)); 11584 } 11585 DP(NETIF_MSG_LINK, 11586 "Default config phy idx %x cfg 0x%x speed_cap_mask 0x%x\n", 11587 phy_index, link_config, phy->speed_cap_mask); 11588 11589 phy->req_duplex = DUPLEX_FULL; 11590 switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) { 11591 case PORT_FEATURE_LINK_SPEED_10M_HALF: 11592 phy->req_duplex = DUPLEX_HALF; 11593 case PORT_FEATURE_LINK_SPEED_10M_FULL: 11594 phy->req_line_speed = SPEED_10; 11595 break; 11596 case PORT_FEATURE_LINK_SPEED_100M_HALF: 11597 phy->req_duplex = DUPLEX_HALF; 11598 case PORT_FEATURE_LINK_SPEED_100M_FULL: 11599 phy->req_line_speed = SPEED_100; 11600 break; 11601 case PORT_FEATURE_LINK_SPEED_1G: 11602 phy->req_line_speed = SPEED_1000; 11603 break; 11604 case PORT_FEATURE_LINK_SPEED_2_5G: 11605 phy->req_line_speed = SPEED_2500; 11606 break; 11607 case PORT_FEATURE_LINK_SPEED_10G_CX4: 11608 phy->req_line_speed = SPEED_10000; 11609 break; 11610 default: 11611 phy->req_line_speed = SPEED_AUTO_NEG; 11612 break; 11613 } 11614 11615 switch (link_config & PORT_FEATURE_FLOW_CONTROL_MASK) { 11616 case PORT_FEATURE_FLOW_CONTROL_AUTO: 11617 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO; 11618 break; 11619 case PORT_FEATURE_FLOW_CONTROL_TX: 11620 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX; 11621 break; 11622 case PORT_FEATURE_FLOW_CONTROL_RX: 11623 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX; 11624 break; 11625 case PORT_FEATURE_FLOW_CONTROL_BOTH: 11626 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH; 11627 break; 11628 default: 11629 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE; 11630 break; 11631 } 11632} 11633 11634u32 bnx2x_phy_selection(struct link_params *params) 11635{ 11636 u32 phy_config_swapped, prio_cfg; 11637 u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT; 11638 11639 phy_config_swapped = params->multi_phy_config & 11640 PORT_HW_CFG_PHY_SWAPPED_ENABLED; 11641 11642 prio_cfg = params->multi_phy_config & 11643 PORT_HW_CFG_PHY_SELECTION_MASK; 11644 11645 if (phy_config_swapped) { 11646 switch (prio_cfg) { 11647 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: 11648 return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY; 11649 break; 11650 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: 11651 return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY; 11652 break; 11653 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY: 11654 return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY; 11655 break; 11656 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY: 11657 return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY; 11658 break; 11659 } 11660 } else 11661 return_cfg = prio_cfg; 11662 11663 return return_cfg; 11664} 11665 11666 11667int bnx2x_phy_probe(struct link_params *params) 11668{ 11669 u8 phy_index, actual_phy_idx, link_cfg_idx; 11670 u32 phy_config_swapped, sync_offset, media_types; 11671 struct bnx2x *bp = params->bp; 11672 struct bnx2x_phy *phy; 11673 params->num_phys = 0; 11674 DP(NETIF_MSG_LINK, "Begin phy probe\n"); 11675 phy_config_swapped = params->multi_phy_config & 11676 PORT_HW_CFG_PHY_SWAPPED_ENABLED; 11677 11678 for (phy_index = INT_PHY; phy_index < MAX_PHYS; 11679 phy_index++) { 11680 link_cfg_idx = LINK_CONFIG_IDX(phy_index); 11681 actual_phy_idx = phy_index; 11682 if (phy_config_swapped) { 11683 if (phy_index == EXT_PHY1) 11684 actual_phy_idx = EXT_PHY2; 11685 else if (phy_index == EXT_PHY2) 11686 actual_phy_idx = EXT_PHY1; 11687 } 11688 DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x," 11689 " actual_phy_idx %x\n", phy_config_swapped, 11690 phy_index, actual_phy_idx); 11691 phy = ¶ms->phy[actual_phy_idx]; 11692 if (bnx2x_populate_phy(bp, phy_index, params->shmem_base, 11693 params->shmem2_base, params->port, 11694 phy) != 0) { 11695 params->num_phys = 0; 11696 DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n", 11697 phy_index); 11698 for (phy_index = INT_PHY; 11699 phy_index < MAX_PHYS; 11700 phy_index++) 11701 *phy = phy_null; 11702 return -EINVAL; 11703 } 11704 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) 11705 break; 11706 11707 sync_offset = params->shmem_base + 11708 offsetof(struct shmem_region, 11709 dev_info.port_hw_config[params->port].media_type); 11710 media_types = REG_RD(bp, sync_offset); 11711 11712 /* 11713 * Update media type for non-PMF sync only for the first time 11714 * In case the media type changes afterwards, it will be updated 11715 * using the update_status function 11716 */ 11717 if ((media_types & (PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK << 11718 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * 11719 actual_phy_idx))) == 0) { 11720 media_types |= ((phy->media_type & 11721 PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) << 11722 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * 11723 actual_phy_idx)); 11724 } 11725 REG_WR(bp, sync_offset, media_types); 11726 11727 bnx2x_phy_def_cfg(params, phy, phy_index); 11728 params->num_phys++; 11729 } 11730 11731 DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys); 11732 return 0; 11733} 11734 11735void bnx2x_init_bmac_loopback(struct link_params *params, 11736 struct link_vars *vars) 11737{ 11738 struct bnx2x *bp = params->bp; 11739 vars->link_up = 1; 11740 vars->line_speed = SPEED_10000; 11741 vars->duplex = DUPLEX_FULL; 11742 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; 11743 vars->mac_type = MAC_TYPE_BMAC; 11744 11745 vars->phy_flags = PHY_XGXS_FLAG; 11746 11747 bnx2x_xgxs_deassert(params); 11748 11749 /* set bmac loopback */ 11750 bnx2x_bmac_enable(params, vars, 1); 11751 11752 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); 11753} 11754 11755void bnx2x_init_emac_loopback(struct link_params *params, 11756 struct link_vars *vars) 11757{ 11758 struct bnx2x *bp = params->bp; 11759 vars->link_up = 1; 11760 vars->line_speed = SPEED_1000; 11761 vars->duplex = DUPLEX_FULL; 11762 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; 11763 vars->mac_type = MAC_TYPE_EMAC; 11764 11765 vars->phy_flags = PHY_XGXS_FLAG; 11766 11767 bnx2x_xgxs_deassert(params); 11768 /* set bmac loopback */ 11769 bnx2x_emac_enable(params, vars, 1); 11770 bnx2x_emac_program(params, vars); 11771 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); 11772} 11773 11774void bnx2x_init_xmac_loopback(struct link_params *params, 11775 struct link_vars *vars) 11776{ 11777 struct bnx2x *bp = params->bp; 11778 vars->link_up = 1; 11779 if (!params->req_line_speed[0]) 11780 vars->line_speed = SPEED_10000; 11781 else 11782 vars->line_speed = params->req_line_speed[0]; 11783 vars->duplex = DUPLEX_FULL; 11784 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; 11785 vars->mac_type = MAC_TYPE_XMAC; 11786 vars->phy_flags = PHY_XGXS_FLAG; 11787 /* 11788 * Set WC to loopback mode since link is required to provide clock 11789 * to the XMAC in 20G mode 11790 */ 11791 bnx2x_set_aer_mmd(params, ¶ms->phy[0]); 11792 bnx2x_warpcore_reset_lane(bp, ¶ms->phy[0], 0); 11793 params->phy[INT_PHY].config_loopback( 11794 ¶ms->phy[INT_PHY], 11795 params); 11796 11797 bnx2x_xmac_enable(params, vars, 1); 11798 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); 11799} 11800 11801void bnx2x_init_umac_loopback(struct link_params *params, 11802 struct link_vars *vars) 11803{ 11804 struct bnx2x *bp = params->bp; 11805 vars->link_up = 1; 11806 vars->line_speed = SPEED_1000; 11807 vars->duplex = DUPLEX_FULL; 11808 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; 11809 vars->mac_type = MAC_TYPE_UMAC; 11810 vars->phy_flags = PHY_XGXS_FLAG; 11811 bnx2x_umac_enable(params, vars, 1); 11812 11813 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); 11814} 11815 11816void bnx2x_init_xgxs_loopback(struct link_params *params, 11817 struct link_vars *vars) 11818{ 11819 struct bnx2x *bp = params->bp; 11820 vars->link_up = 1; 11821 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; 11822 vars->duplex = DUPLEX_FULL; 11823 if (params->req_line_speed[0] == SPEED_1000) 11824 vars->line_speed = SPEED_1000; 11825 else 11826 vars->line_speed = SPEED_10000; 11827 11828 if (!USES_WARPCORE(bp)) 11829 bnx2x_xgxs_deassert(params); 11830 bnx2x_link_initialize(params, vars); 11831 11832 if (params->req_line_speed[0] == SPEED_1000) { 11833 if (USES_WARPCORE(bp)) 11834 bnx2x_umac_enable(params, vars, 0); 11835 else { 11836 bnx2x_emac_program(params, vars); 11837 bnx2x_emac_enable(params, vars, 0); 11838 } 11839 } else { 11840 if (USES_WARPCORE(bp)) 11841 bnx2x_xmac_enable(params, vars, 0); 11842 else 11843 bnx2x_bmac_enable(params, vars, 0); 11844 } 11845 11846 if (params->loopback_mode == LOOPBACK_XGXS) { 11847 /* set 10G XGXS loopback */ 11848 params->phy[INT_PHY].config_loopback( 11849 ¶ms->phy[INT_PHY], 11850 params); 11851 11852 } else { 11853 /* set external phy loopback */ 11854 u8 phy_index; 11855 for (phy_index = EXT_PHY1; 11856 phy_index < params->num_phys; phy_index++) { 11857 if (params->phy[phy_index].config_loopback) 11858 params->phy[phy_index].config_loopback( 11859 ¶ms->phy[phy_index], 11860 params); 11861 } 11862 } 11863 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); 11864 11865 bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed); 11866} 11867 11868int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) 11869{ 11870 struct bnx2x *bp = params->bp; 11871 DP(NETIF_MSG_LINK, "Phy Initialization started\n"); 11872 DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n", 11873 params->req_line_speed[0], params->req_flow_ctrl[0]); 11874 DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n", 11875 params->req_line_speed[1], params->req_flow_ctrl[1]); 11876 vars->link_status = 0; 11877 vars->phy_link_up = 0; 11878 vars->link_up = 0; 11879 vars->line_speed = 0; 11880 vars->duplex = DUPLEX_FULL; 11881 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; 11882 vars->mac_type = MAC_TYPE_NONE; 11883 vars->phy_flags = 0; 11884 11885 /* disable attentions */ 11886 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4, 11887 (NIG_MASK_XGXS0_LINK_STATUS | 11888 NIG_MASK_XGXS0_LINK10G | 11889 NIG_MASK_SERDES0_LINK_STATUS | 11890 NIG_MASK_MI_INT)); 11891 11892 bnx2x_emac_init(params, vars); 11893 11894 if (params->num_phys == 0) { 11895 DP(NETIF_MSG_LINK, "No phy found for initialization !!\n"); 11896 return -EINVAL; 11897 } 11898 set_phy_vars(params, vars); 11899 11900 DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys); 11901 switch (params->loopback_mode) { 11902 case LOOPBACK_BMAC: 11903 bnx2x_init_bmac_loopback(params, vars); 11904 break; 11905 case LOOPBACK_EMAC: 11906 bnx2x_init_emac_loopback(params, vars); 11907 break; 11908 case LOOPBACK_XMAC: 11909 bnx2x_init_xmac_loopback(params, vars); 11910 break; 11911 case LOOPBACK_UMAC: 11912 bnx2x_init_umac_loopback(params, vars); 11913 break; 11914 case LOOPBACK_XGXS: 11915 case LOOPBACK_EXT_PHY: 11916 bnx2x_init_xgxs_loopback(params, vars); 11917 break; 11918 default: 11919 if (!CHIP_IS_E3(bp)) { 11920 if (params->switch_cfg == SWITCH_CFG_10G) 11921 bnx2x_xgxs_deassert(params); 11922 else 11923 bnx2x_serdes_deassert(bp, params->port); 11924 } 11925 bnx2x_link_initialize(params, vars); 11926 msleep(30); 11927 bnx2x_link_int_enable(params); 11928 break; 11929 } 11930 return 0; 11931} 11932 11933int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, 11934 u8 reset_ext_phy) 11935{ 11936 struct bnx2x *bp = params->bp; 11937 u8 phy_index, port = params->port, clear_latch_ind = 0; 11938 DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); 11939 /* disable attentions */ 11940 vars->link_status = 0; 11941 bnx2x_update_mng(params, vars->link_status); 11942 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 11943 (NIG_MASK_XGXS0_LINK_STATUS | 11944 NIG_MASK_XGXS0_LINK10G | 11945 NIG_MASK_SERDES0_LINK_STATUS | 11946 NIG_MASK_MI_INT)); 11947 11948 /* activate nig drain */ 11949 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); 11950 11951 /* disable nig egress interface */ 11952 if (!CHIP_IS_E3(bp)) { 11953 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0); 11954 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); 11955 } 11956 11957 /* Stop BigMac rx */ 11958 if (!CHIP_IS_E3(bp)) 11959 bnx2x_bmac_rx_disable(bp, port); 11960 else { 11961 bnx2x_xmac_disable(params); 11962 bnx2x_umac_disable(params); 11963 } 11964 /* disable emac */ 11965 if (!CHIP_IS_E3(bp)) 11966 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); 11967 11968 msleep(10); 11969 /* The PHY reset is controlled by GPIO 1 11970 * Hold it as vars low 11971 */ 11972 /* clear link led */ 11973 bnx2x_set_led(params, vars, LED_MODE_OFF, 0); 11974 11975 if (reset_ext_phy) { 11976 bnx2x_set_mdio_clk(bp, params->chip_id, port); 11977 for (phy_index = EXT_PHY1; phy_index < params->num_phys; 11978 phy_index++) { 11979 if (params->phy[phy_index].link_reset) { 11980 bnx2x_set_aer_mmd(params, 11981 ¶ms->phy[phy_index]); 11982 params->phy[phy_index].link_reset( 11983 ¶ms->phy[phy_index], 11984 params); 11985 } 11986 if (params->phy[phy_index].flags & 11987 FLAGS_REARM_LATCH_SIGNAL) 11988 clear_latch_ind = 1; 11989 } 11990 } 11991 11992 if (clear_latch_ind) { 11993 /* Clear latching indication */ 11994 bnx2x_rearm_latch_signal(bp, port, 0); 11995 bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4, 11996 1 << NIG_LATCH_BC_ENABLE_MI_INT); 11997 } 11998 if (params->phy[INT_PHY].link_reset) 11999 params->phy[INT_PHY].link_reset( 12000 ¶ms->phy[INT_PHY], params); 12001 12002 /* disable nig ingress interface */ 12003 if (!CHIP_IS_E3(bp)) { 12004 /* reset BigMac */ 12005 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 12006 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); 12007 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0); 12008 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0); 12009 } else { 12010 u32 xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0; 12011 bnx2x_set_xumac_nig(params, 0, 0); 12012 if (REG_RD(bp, MISC_REG_RESET_REG_2) & 12013 MISC_REGISTERS_RESET_REG_2_XMAC) 12014 REG_WR(bp, xmac_base + XMAC_REG_CTRL, 12015 XMAC_CTRL_REG_SOFT_RESET); 12016 } 12017 vars->link_up = 0; 12018 vars->phy_flags = 0; 12019 return 0; 12020} 12021 12022/****************************************************************************/ 12023/* Common function */ 12024/****************************************************************************/ 12025static int bnx2x_8073_common_init_phy(struct bnx2x *bp, 12026 u32 shmem_base_path[], 12027 u32 shmem2_base_path[], u8 phy_index, 12028 u32 chip_id) 12029{ 12030 struct bnx2x_phy phy[PORT_MAX]; 12031 struct bnx2x_phy *phy_blk[PORT_MAX]; 12032 u16 val; 12033 s8 port = 0; 12034 s8 port_of_path = 0; 12035 u32 swap_val, swap_override; 12036 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); 12037 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); 12038 port ^= (swap_val && swap_override); 12039 bnx2x_ext_phy_hw_reset(bp, port); 12040 /* PART1 - Reset both phys */ 12041 for (port = PORT_MAX - 1; port >= PORT_0; port--) { 12042 u32 shmem_base, shmem2_base; 12043 /* In E2, same phy is using for port0 of the two paths */ 12044 if (CHIP_IS_E1x(bp)) { 12045 shmem_base = shmem_base_path[0]; 12046 shmem2_base = shmem2_base_path[0]; 12047 port_of_path = port; 12048 } else { 12049 shmem_base = shmem_base_path[port]; 12050 shmem2_base = shmem2_base_path[port]; 12051 port_of_path = 0; 12052 } 12053 12054 /* Extract the ext phy address for the port */ 12055 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, 12056 port_of_path, &phy[port]) != 12057 0) { 12058 DP(NETIF_MSG_LINK, "populate_phy failed\n"); 12059 return -EINVAL; 12060 } 12061 /* disable attentions */ 12062 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + 12063 port_of_path*4, 12064 (NIG_MASK_XGXS0_LINK_STATUS | 12065 NIG_MASK_XGXS0_LINK10G | 12066 NIG_MASK_SERDES0_LINK_STATUS | 12067 NIG_MASK_MI_INT)); 12068 12069 /* Need to take the phy out of low power mode in order 12070 to write to access its registers */ 12071 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 12072 MISC_REGISTERS_GPIO_OUTPUT_HIGH, 12073 port); 12074 12075 /* Reset the phy */ 12076 bnx2x_cl45_write(bp, &phy[port], 12077 MDIO_PMA_DEVAD, 12078 MDIO_PMA_REG_CTRL, 12079 1<<15); 12080 } 12081 12082 /* Add delay of 150ms after reset */ 12083 msleep(150); 12084 12085 if (phy[PORT_0].addr & 0x1) { 12086 phy_blk[PORT_0] = &(phy[PORT_1]); 12087 phy_blk[PORT_1] = &(phy[PORT_0]); 12088 } else { 12089 phy_blk[PORT_0] = &(phy[PORT_0]); 12090 phy_blk[PORT_1] = &(phy[PORT_1]); 12091 } 12092 12093 /* PART2 - Download firmware to both phys */ 12094 for (port = PORT_MAX - 1; port >= PORT_0; port--) { 12095 if (CHIP_IS_E1x(bp)) 12096 port_of_path = port; 12097 else 12098 port_of_path = 0; 12099 12100 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", 12101 phy_blk[port]->addr); 12102 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], 12103 port_of_path)) 12104 return -EINVAL; 12105 12106 /* Only set bit 10 = 1 (Tx power down) */ 12107 bnx2x_cl45_read(bp, phy_blk[port], 12108 MDIO_PMA_DEVAD, 12109 MDIO_PMA_REG_TX_POWER_DOWN, &val); 12110 12111 /* Phase1 of TX_POWER_DOWN reset */ 12112 bnx2x_cl45_write(bp, phy_blk[port], 12113 MDIO_PMA_DEVAD, 12114 MDIO_PMA_REG_TX_POWER_DOWN, 12115 (val | 1<<10)); 12116 } 12117 12118 /* 12119 * Toggle Transmitter: Power down and then up with 600ms delay 12120 * between 12121 */ 12122 msleep(600); 12123 12124 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */ 12125 for (port = PORT_MAX - 1; port >= PORT_0; port--) { 12126 /* Phase2 of POWER_DOWN_RESET */ 12127 /* Release bit 10 (Release Tx power down) */ 12128 bnx2x_cl45_read(bp, phy_blk[port], 12129 MDIO_PMA_DEVAD, 12130 MDIO_PMA_REG_TX_POWER_DOWN, &val); 12131 12132 bnx2x_cl45_write(bp, phy_blk[port], 12133 MDIO_PMA_DEVAD, 12134 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10)))); 12135 msleep(15); 12136 12137 /* Read modify write the SPI-ROM version select register */ 12138 bnx2x_cl45_read(bp, phy_blk[port], 12139 MDIO_PMA_DEVAD, 12140 MDIO_PMA_REG_EDC_FFE_MAIN, &val); 12141 bnx2x_cl45_write(bp, phy_blk[port], 12142 MDIO_PMA_DEVAD, 12143 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12))); 12144 12145 /* set GPIO2 back to LOW */ 12146 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 12147 MISC_REGISTERS_GPIO_OUTPUT_LOW, port); 12148 } 12149 return 0; 12150} 12151static int bnx2x_8726_common_init_phy(struct bnx2x *bp, 12152 u32 shmem_base_path[], 12153 u32 shmem2_base_path[], u8 phy_index, 12154 u32 chip_id) 12155{ 12156 u32 val; 12157 s8 port; 12158 struct bnx2x_phy phy; 12159 /* Use port1 because of the static port-swap */ 12160 /* Enable the module detection interrupt */ 12161 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN); 12162 val |= ((1<<MISC_REGISTERS_GPIO_3)| 12163 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT))); 12164 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val); 12165 12166 bnx2x_ext_phy_hw_reset(bp, 0); 12167 msleep(5); 12168 for (port = 0; port < PORT_MAX; port++) { 12169 u32 shmem_base, shmem2_base; 12170 12171 /* In E2, same phy is using for port0 of the two paths */ 12172 if (CHIP_IS_E1x(bp)) { 12173 shmem_base = shmem_base_path[0]; 12174 shmem2_base = shmem2_base_path[0]; 12175 } else { 12176 shmem_base = shmem_base_path[port]; 12177 shmem2_base = shmem2_base_path[port]; 12178 } 12179 /* Extract the ext phy address for the port */ 12180 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, 12181 port, &phy) != 12182 0) { 12183 DP(NETIF_MSG_LINK, "populate phy failed\n"); 12184 return -EINVAL; 12185 } 12186 12187 /* Reset phy*/ 12188 bnx2x_cl45_write(bp, &phy, 12189 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001); 12190 12191 12192 /* Set fault module detected LED on */ 12193 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, 12194 MISC_REGISTERS_GPIO_HIGH, 12195 port); 12196 } 12197 12198 return 0; 12199} 12200static void bnx2x_get_ext_phy_reset_gpio(struct bnx2x *bp, u32 shmem_base, 12201 u8 *io_gpio, u8 *io_port) 12202{ 12203 12204 u32 phy_gpio_reset = REG_RD(bp, shmem_base + 12205 offsetof(struct shmem_region, 12206 dev_info.port_hw_config[PORT_0].default_cfg)); 12207 switch (phy_gpio_reset) { 12208 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0: 12209 *io_gpio = 0; 12210 *io_port = 0; 12211 break; 12212 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0: 12213 *io_gpio = 1; 12214 *io_port = 0; 12215 break; 12216 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0: 12217 *io_gpio = 2; 12218 *io_port = 0; 12219 break; 12220 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0: 12221 *io_gpio = 3; 12222 *io_port = 0; 12223 break; 12224 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1: 12225 *io_gpio = 0; 12226 *io_port = 1; 12227 break; 12228 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1: 12229 *io_gpio = 1; 12230 *io_port = 1; 12231 break; 12232 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1: 12233 *io_gpio = 2; 12234 *io_port = 1; 12235 break; 12236 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1: 12237 *io_gpio = 3; 12238 *io_port = 1; 12239 break; 12240 default: 12241 /* Don't override the io_gpio and io_port */ 12242 break; 12243 } 12244} 12245 12246static int bnx2x_8727_common_init_phy(struct bnx2x *bp, 12247 u32 shmem_base_path[], 12248 u32 shmem2_base_path[], u8 phy_index, 12249 u32 chip_id) 12250{ 12251 s8 port, reset_gpio; 12252 u32 swap_val, swap_override; 12253 struct bnx2x_phy phy[PORT_MAX]; 12254 struct bnx2x_phy *phy_blk[PORT_MAX]; 12255 s8 port_of_path; 12256 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); 12257 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); 12258 12259 reset_gpio = MISC_REGISTERS_GPIO_1; 12260 port = 1; 12261 12262 /* 12263 * Retrieve the reset gpio/port which control the reset. 12264 * Default is GPIO1, PORT1 12265 */ 12266 bnx2x_get_ext_phy_reset_gpio(bp, shmem_base_path[0], 12267 (u8 *)&reset_gpio, (u8 *)&port); 12268 12269 /* Calculate the port based on port swap */ 12270 port ^= (swap_val && swap_override); 12271 12272 /* Initiate PHY reset*/ 12273 bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW, 12274 port); 12275 msleep(1); 12276 bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH, 12277 port); 12278 12279 msleep(5); 12280 12281 /* PART1 - Reset both phys */ 12282 for (port = PORT_MAX - 1; port >= PORT_0; port--) { 12283 u32 shmem_base, shmem2_base; 12284 12285 /* In E2, same phy is using for port0 of the two paths */ 12286 if (CHIP_IS_E1x(bp)) { 12287 shmem_base = shmem_base_path[0]; 12288 shmem2_base = shmem2_base_path[0]; 12289 port_of_path = port; 12290 } else { 12291 shmem_base = shmem_base_path[port]; 12292 shmem2_base = shmem2_base_path[port]; 12293 port_of_path = 0; 12294 } 12295 12296 /* Extract the ext phy address for the port */ 12297 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, 12298 port_of_path, &phy[port]) != 12299 0) { 12300 DP(NETIF_MSG_LINK, "populate phy failed\n"); 12301 return -EINVAL; 12302 } 12303 /* disable attentions */ 12304 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + 12305 port_of_path*4, 12306 (NIG_MASK_XGXS0_LINK_STATUS | 12307 NIG_MASK_XGXS0_LINK10G | 12308 NIG_MASK_SERDES0_LINK_STATUS | 12309 NIG_MASK_MI_INT)); 12310 12311 12312 /* Reset the phy */ 12313 bnx2x_cl45_write(bp, &phy[port], 12314 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); 12315 } 12316 12317 /* Add delay of 150ms after reset */ 12318 msleep(150); 12319 if (phy[PORT_0].addr & 0x1) { 12320 phy_blk[PORT_0] = &(phy[PORT_1]); 12321 phy_blk[PORT_1] = &(phy[PORT_0]); 12322 } else { 12323 phy_blk[PORT_0] = &(phy[PORT_0]); 12324 phy_blk[PORT_1] = &(phy[PORT_1]); 12325 } 12326 /* PART2 - Download firmware to both phys */ 12327 for (port = PORT_MAX - 1; port >= PORT_0; port--) { 12328 if (CHIP_IS_E1x(bp)) 12329 port_of_path = port; 12330 else 12331 port_of_path = 0; 12332 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", 12333 phy_blk[port]->addr); 12334 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], 12335 port_of_path)) 12336 return -EINVAL; 12337 /* Disable PHY transmitter output */ 12338 bnx2x_cl45_write(bp, phy_blk[port], 12339 MDIO_PMA_DEVAD, 12340 MDIO_PMA_REG_TX_DISABLE, 1); 12341 12342 } 12343 return 0; 12344} 12345 12346static int bnx2x_84833_common_init_phy(struct bnx2x *bp, 12347 u32 shmem_base_path[], 12348 u32 shmem2_base_path[], 12349 u8 phy_index, 12350 u32 chip_id) 12351{ 12352 u8 reset_gpios; 12353 struct bnx2x_phy phy; 12354 u32 shmem_base, shmem2_base, cnt; 12355 s8 port = 0; 12356 u16 val; 12357 12358 reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path, chip_id); 12359 bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW); 12360 udelay(10); 12361 bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH); 12362 DP(NETIF_MSG_LINK, "84833 reset pulse on pin values 0x%x\n", 12363 reset_gpios); 12364 for (port = PORT_MAX - 1; port >= PORT_0; port--) { 12365 /* This PHY is for E2 and E3. */ 12366 shmem_base = shmem_base_path[port]; 12367 shmem2_base = shmem2_base_path[port]; 12368 /* Extract the ext phy address for the port */ 12369 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, 12370 0, &phy) != 12371 0) { 12372 DP(NETIF_MSG_LINK, "populate_phy failed\n"); 12373 return -EINVAL; 12374 } 12375 12376 /* Wait for FW completing its initialization. */ 12377 for (cnt = 0; cnt < 1000; cnt++) { 12378 bnx2x_cl45_read(bp, &phy, 12379 MDIO_PMA_DEVAD, 12380 MDIO_PMA_REG_CTRL, &val); 12381 if (!(val & (1<<15))) 12382 break; 12383 msleep(1); 12384 } 12385 if (cnt >= 1000) 12386 DP(NETIF_MSG_LINK, 12387 "84833 Cmn reset timeout (%d)\n", port); 12388 12389 /* Put the port in super isolate mode. */ 12390 bnx2x_cl45_read(bp, &phy, 12391 MDIO_CTL_DEVAD, 12392 MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val); 12393 val |= MDIO_84833_SUPER_ISOLATE; 12394 bnx2x_cl45_write(bp, &phy, 12395 MDIO_CTL_DEVAD, 12396 MDIO_84833_TOP_CFG_XGPHY_STRAP1, val); 12397 } 12398 12399 return 0; 12400} 12401 12402 12403static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], 12404 u32 shmem2_base_path[], u8 phy_index, 12405 u32 ext_phy_type, u32 chip_id) 12406{ 12407 int rc = 0; 12408 12409 switch (ext_phy_type) { 12410 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 12411 rc = bnx2x_8073_common_init_phy(bp, shmem_base_path, 12412 shmem2_base_path, 12413 phy_index, chip_id); 12414 break; 12415 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722: 12416 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: 12417 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: 12418 rc = bnx2x_8727_common_init_phy(bp, shmem_base_path, 12419 shmem2_base_path, 12420 phy_index, chip_id); 12421 break; 12422 12423 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: 12424 /* 12425 * GPIO1 affects both ports, so there's need to pull 12426 * it for single port alone 12427 */ 12428 rc = bnx2x_8726_common_init_phy(bp, shmem_base_path, 12429 shmem2_base_path, 12430 phy_index, chip_id); 12431 break; 12432 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833: 12433 /* 12434 * GPIO3's are linked, and so both need to be toggled 12435 * to obtain required 2us pulse. 12436 */ 12437 rc = bnx2x_84833_common_init_phy(bp, shmem_base_path, 12438 shmem2_base_path, 12439 phy_index, chip_id); 12440 break; 12441 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: 12442 rc = -EINVAL; 12443 break; 12444 default: 12445 DP(NETIF_MSG_LINK, 12446 "ext_phy 0x%x common init not required\n", 12447 ext_phy_type); 12448 break; 12449 } 12450 12451 if (rc != 0) 12452 netdev_err(bp->dev, "Warning: PHY was not initialized," 12453 " Port %d\n", 12454 0); 12455 return rc; 12456} 12457 12458int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], 12459 u32 shmem2_base_path[], u32 chip_id) 12460{ 12461 int rc = 0; 12462 u32 phy_ver, val; 12463 u8 phy_index = 0; 12464 u32 ext_phy_type, ext_phy_config; 12465 bnx2x_set_mdio_clk(bp, chip_id, PORT_0); 12466 bnx2x_set_mdio_clk(bp, chip_id, PORT_1); 12467 DP(NETIF_MSG_LINK, "Begin common phy init\n"); 12468 if (CHIP_IS_E3(bp)) { 12469 /* Enable EPIO */ 12470 val = REG_RD(bp, MISC_REG_GEN_PURP_HWG); 12471 REG_WR(bp, MISC_REG_GEN_PURP_HWG, val | 1); 12472 } 12473 /* Check if common init was already done */ 12474 phy_ver = REG_RD(bp, shmem_base_path[0] + 12475 offsetof(struct shmem_region, 12476 port_mb[PORT_0].ext_phy_fw_version)); 12477 if (phy_ver) { 12478 DP(NETIF_MSG_LINK, "Not doing common init; phy ver is 0x%x\n", 12479 phy_ver); 12480 return 0; 12481 } 12482 12483 /* Read the ext_phy_type for arbitrary port(0) */ 12484 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; 12485 phy_index++) { 12486 ext_phy_config = bnx2x_get_ext_phy_config(bp, 12487 shmem_base_path[0], 12488 phy_index, 0); 12489 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); 12490 rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path, 12491 shmem2_base_path, 12492 phy_index, ext_phy_type, 12493 chip_id); 12494 } 12495 return rc; 12496} 12497 12498static void bnx2x_check_over_curr(struct link_params *params, 12499 struct link_vars *vars) 12500{ 12501 struct bnx2x *bp = params->bp; 12502 u32 cfg_pin; 12503 u8 port = params->port; 12504 u32 pin_val; 12505 12506 cfg_pin = (REG_RD(bp, params->shmem_base + 12507 offsetof(struct shmem_region, 12508 dev_info.port_hw_config[port].e3_cmn_pin_cfg1)) & 12509 PORT_HW_CFG_E3_OVER_CURRENT_MASK) >> 12510 PORT_HW_CFG_E3_OVER_CURRENT_SHIFT; 12511 12512 /* Ignore check if no external input PIN available */ 12513 if (bnx2x_get_cfg_pin(bp, cfg_pin, &pin_val) != 0) 12514 return; 12515 12516 if (!pin_val) { 12517 if ((vars->phy_flags & PHY_OVER_CURRENT_FLAG) == 0) { 12518 netdev_err(bp->dev, "Error: Power fault on Port %d has" 12519 " been detected and the power to " 12520 "that SFP+ module has been removed" 12521 " to prevent failure of the card." 12522 " Please remove the SFP+ module and" 12523 " restart the system to clear this" 12524 " error.\n", 12525 params->port); 12526 vars->phy_flags |= PHY_OVER_CURRENT_FLAG; 12527 } 12528 } else 12529 vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG; 12530} 12531 12532static void bnx2x_analyze_link_error(struct link_params *params, 12533 struct link_vars *vars, u32 lss_status) 12534{ 12535 struct bnx2x *bp = params->bp; 12536 /* Compare new value with previous value */ 12537 u8 led_mode; 12538 u32 half_open_conn = (vars->phy_flags & PHY_HALF_OPEN_CONN_FLAG) > 0; 12539 12540 if ((lss_status ^ half_open_conn) == 0) 12541 return; 12542 12543 /* If values differ */ 12544 DP(NETIF_MSG_LINK, "Link changed:%x %x->%x\n", vars->link_up, 12545 half_open_conn, lss_status); 12546 12547 /* 12548 * a. Update shmem->link_status accordingly 12549 * b. Update link_vars->link_up 12550 */ 12551 if (lss_status) { 12552 DP(NETIF_MSG_LINK, "Remote Fault detected !!!\n"); 12553 vars->link_status &= ~LINK_STATUS_LINK_UP; 12554 vars->link_up = 0; 12555 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG; 12556 /* 12557 * Set LED mode to off since the PHY doesn't know about these 12558 * errors 12559 */ 12560 led_mode = LED_MODE_OFF; 12561 } else { 12562 DP(NETIF_MSG_LINK, "Remote Fault cleared\n"); 12563 vars->link_status |= LINK_STATUS_LINK_UP; 12564 vars->link_up = 1; 12565 vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG; 12566 led_mode = LED_MODE_OPER; 12567 } 12568 /* Update the LED according to the link state */ 12569 bnx2x_set_led(params, vars, led_mode, SPEED_10000); 12570 12571 /* Update link status in the shared memory */ 12572 bnx2x_update_mng(params, vars->link_status); 12573 12574 /* C. Trigger General Attention */ 12575 vars->periodic_flags |= PERIODIC_FLAGS_LINK_EVENT; 12576 bnx2x_notify_link_changed(bp); 12577} 12578 12579/****************************************************************************** 12580* Description: 12581* This function checks for half opened connection change indication. 12582* When such change occurs, it calls the bnx2x_analyze_link_error 12583* to check if Remote Fault is set or cleared. Reception of remote fault 12584* status message in the MAC indicates that the peer's MAC has detected 12585* a fault, for example, due to break in the TX side of fiber. 12586* 12587******************************************************************************/ 12588static void bnx2x_check_half_open_conn(struct link_params *params, 12589 struct link_vars *vars) 12590{ 12591 struct bnx2x *bp = params->bp; 12592 u32 lss_status = 0; 12593 u32 mac_base; 12594 /* In case link status is physically up @ 10G do */ 12595 if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0) 12596 return; 12597 12598 if (CHIP_IS_E3(bp) && 12599 (REG_RD(bp, MISC_REG_RESET_REG_2) & 12600 (MISC_REGISTERS_RESET_REG_2_XMAC))) { 12601 /* Check E3 XMAC */ 12602 /* 12603 * Note that link speed cannot be queried here, since it may be 12604 * zero while link is down. In case UMAC is active, LSS will 12605 * simply not be set 12606 */ 12607 mac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0; 12608 12609 /* Clear stick bits (Requires rising edge) */ 12610 REG_WR(bp, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0); 12611 REG_WR(bp, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 12612 XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS | 12613 XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS); 12614 if (REG_RD(bp, mac_base + XMAC_REG_RX_LSS_STATUS)) 12615 lss_status = 1; 12616 12617 bnx2x_analyze_link_error(params, vars, lss_status); 12618 } else if (REG_RD(bp, MISC_REG_RESET_REG_2) & 12619 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) { 12620 /* Check E1X / E2 BMAC */ 12621 u32 lss_status_reg; 12622 u32 wb_data[2]; 12623 mac_base = params->port ? NIG_REG_INGRESS_BMAC1_MEM : 12624 NIG_REG_INGRESS_BMAC0_MEM; 12625 /* Read BIGMAC_REGISTER_RX_LSS_STATUS */ 12626 if (CHIP_IS_E2(bp)) 12627 lss_status_reg = BIGMAC2_REGISTER_RX_LSS_STAT; 12628 else 12629 lss_status_reg = BIGMAC_REGISTER_RX_LSS_STATUS; 12630 12631 REG_RD_DMAE(bp, mac_base + lss_status_reg, wb_data, 2); 12632 lss_status = (wb_data[0] > 0); 12633 12634 bnx2x_analyze_link_error(params, vars, lss_status); 12635 } 12636} 12637 12638void bnx2x_period_func(struct link_params *params, struct link_vars *vars) 12639{ 12640 struct bnx2x *bp = params->bp; 12641 u16 phy_idx; 12642 for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) { 12643 if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) { 12644 bnx2x_set_aer_mmd(params, ¶ms->phy[phy_idx]); 12645 bnx2x_check_half_open_conn(params, vars); 12646 break; 12647 } 12648 } 12649 12650 if (CHIP_IS_E3(bp)) { 12651 struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; 12652 bnx2x_set_aer_mmd(params, phy); 12653 bnx2x_check_over_curr(params, vars); 12654 bnx2x_warpcore_config_runtime(phy, params, vars); 12655 } 12656 12657} 12658 12659u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base) 12660{ 12661 u8 phy_index; 12662 struct bnx2x_phy phy; 12663 for (phy_index = INT_PHY; phy_index < MAX_PHYS; 12664 phy_index++) { 12665 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, 12666 0, &phy) != 0) { 12667 DP(NETIF_MSG_LINK, "populate phy failed\n"); 12668 return 0; 12669 } 12670 12671 if (phy.flags & FLAGS_HW_LOCK_REQUIRED) 12672 return 1; 12673 } 12674 return 0; 12675} 12676 12677u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, 12678 u32 shmem_base, 12679 u32 shmem2_base, 12680 u8 port) 12681{ 12682 u8 phy_index, fan_failure_det_req = 0; 12683 struct bnx2x_phy phy; 12684 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; 12685 phy_index++) { 12686 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, 12687 port, &phy) 12688 != 0) { 12689 DP(NETIF_MSG_LINK, "populate phy failed\n"); 12690 return 0; 12691 } 12692 fan_failure_det_req |= (phy.flags & 12693 FLAGS_FAN_FAILURE_DET_REQ); 12694 } 12695 return fan_failure_det_req; 12696} 12697 12698void bnx2x_hw_reset_phy(struct link_params *params) 12699{ 12700 u8 phy_index; 12701 struct bnx2x *bp = params->bp; 12702 bnx2x_update_mng(params, 0); 12703 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4, 12704 (NIG_MASK_XGXS0_LINK_STATUS | 12705 NIG_MASK_XGXS0_LINK10G | 12706 NIG_MASK_SERDES0_LINK_STATUS | 12707 NIG_MASK_MI_INT)); 12708 12709 for (phy_index = INT_PHY; phy_index < MAX_PHYS; 12710 phy_index++) { 12711 if (params->phy[phy_index].hw_reset) { 12712 params->phy[phy_index].hw_reset( 12713 ¶ms->phy[phy_index], 12714 params); 12715 params->phy[phy_index] = phy_null; 12716 } 12717 } 12718} 12719 12720void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars, 12721 u32 chip_id, u32 shmem_base, u32 shmem2_base, 12722 u8 port) 12723{ 12724 u8 gpio_num = 0xff, gpio_port = 0xff, phy_index; 12725 u32 val; 12726 u32 offset, aeu_mask, swap_val, swap_override, sync_offset; 12727 if (CHIP_IS_E3(bp)) { 12728 if (bnx2x_get_mod_abs_int_cfg(bp, chip_id, 12729 shmem_base, 12730 port, 12731 &gpio_num, 12732 &gpio_port) != 0) 12733 return; 12734 } else { 12735 struct bnx2x_phy phy; 12736 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; 12737 phy_index++) { 12738 if (bnx2x_populate_phy(bp, phy_index, shmem_base, 12739 shmem2_base, port, &phy) 12740 != 0) { 12741 DP(NETIF_MSG_LINK, "populate phy failed\n"); 12742 return; 12743 } 12744 if (phy.type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) { 12745 gpio_num = MISC_REGISTERS_GPIO_3; 12746 gpio_port = port; 12747 break; 12748 } 12749 } 12750 } 12751 12752 if (gpio_num == 0xff) 12753 return; 12754 12755 /* Set GPIO3 to trigger SFP+ module insertion/removal */ 12756 bnx2x_set_gpio(bp, gpio_num, MISC_REGISTERS_GPIO_INPUT_HI_Z, gpio_port); 12757 12758 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); 12759 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); 12760 gpio_port ^= (swap_val && swap_override); 12761 12762 vars->aeu_int_mask = AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 << 12763 (gpio_num + (gpio_port << 2)); 12764 12765 sync_offset = shmem_base + 12766 offsetof(struct shmem_region, 12767 dev_info.port_hw_config[port].aeu_int_mask); 12768 REG_WR(bp, sync_offset, vars->aeu_int_mask); 12769 12770 DP(NETIF_MSG_LINK, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x\n", 12771 gpio_num, gpio_port, vars->aeu_int_mask); 12772 12773 if (port == 0) 12774 offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0; 12775 else 12776 offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0; 12777 12778 /* Open appropriate AEU for interrupts */ 12779 aeu_mask = REG_RD(bp, offset); 12780 aeu_mask |= vars->aeu_int_mask; 12781 REG_WR(bp, offset, aeu_mask); 12782 12783 /* Enable the GPIO to trigger interrupt */ 12784 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN); 12785 val |= 1 << (gpio_num + (gpio_port << 2)); 12786 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val); 12787} 12788