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