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