akaros/kern/drivers/net/bnx2x/bnx2x_link.c
<<
>>
Prefs
   1/* Copyright 2008-2013 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#include <linux_compat.h>
  18
  19#include "bnx2x.h"
  20#include "bnx2x_cmn.h"
  21
  22typedef int (*read_sfp_module_eeprom_func_p)(struct bnx2x_phy *phy,
  23                                             struct link_params *params,
  24                                             uint8_t dev_addr, uint16_t addr,
  25                                             uint8_t byte_cnt,
  26                                             uint8_t *o_buf, uint8_t);
  27/********************************************************/
  28#define ETH_HLEN                        14
  29/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
  30#define ETH_OVREHEAD                    (ETHERHDRSIZE + 8 + 8)
  31#define ETH_MIN_PACKET_SIZE             60
  32#define ETH_MAX_PACKET_SIZE             1500
  33#define ETH_MAX_JUMBO_PACKET_SIZE       9600
  34#define MDIO_ACCESS_TIMEOUT             1000
  35#define WC_LANE_MAX                     4
  36#define I2C_SWITCH_WIDTH                2
  37#define I2C_BSC0                        0
  38#define I2C_BSC1                        1
  39#define I2C_WA_RETRY_CNT                3
  40#define I2C_WA_PWR_ITER                 (I2C_WA_RETRY_CNT - 1)
  41#define MCPR_IMC_COMMAND_READ_OP        1
  42#define MCPR_IMC_COMMAND_WRITE_OP       2
  43
  44/* LED Blink rate that will achieve ~15.9Hz */
  45#define LED_BLINK_RATE_VAL_E3           354
  46#define LED_BLINK_RATE_VAL_E1X_E2       480
  47/***********************************************************/
  48/*                      Shortcut definitions               */
  49/***********************************************************/
  50
  51#define NIG_LATCH_BC_ENABLE_MI_INT 0
  52
  53#define NIG_STATUS_EMAC0_MI_INT \
  54                NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
  55#define NIG_STATUS_XGXS0_LINK10G \
  56                NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
  57#define NIG_STATUS_XGXS0_LINK_STATUS \
  58                NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
  59#define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
  60                NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
  61#define NIG_STATUS_SERDES0_LINK_STATUS \
  62                NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
  63#define NIG_MASK_MI_INT \
  64                NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
  65#define NIG_MASK_XGXS0_LINK10G \
  66                NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
  67#define NIG_MASK_XGXS0_LINK_STATUS \
  68                NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
  69#define NIG_MASK_SERDES0_LINK_STATUS \
  70                NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
  71
  72#define MDIO_AN_CL73_OR_37_COMPLETE \
  73                (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
  74                 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
  75
  76#define XGXS_RESET_BITS \
  77        (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
  78         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
  79         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
  80         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
  81         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
  82
  83#define SERDES_RESET_BITS \
  84        (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
  85         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
  86         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
  87         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
  88
  89#define AUTONEG_CL37            SHARED_HW_CFG_AN_ENABLE_CL37
  90#define AUTONEG_CL73            SHARED_HW_CFG_AN_ENABLE_CL73
  91#define AUTONEG_BAM             SHARED_HW_CFG_AN_ENABLE_BAM
  92#define AUTONEG_PARALLEL \
  93                                SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
  94#define AUTONEG_SGMII_FIBER_AUTODET \
  95                                SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
  96#define AUTONEG_REMOTE_PHY      SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
  97
  98#define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
  99                        MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
 100#define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
 101                        MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
 102#define GP_STATUS_SPEED_MASK \
 103                        MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
 104#define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
 105#define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
 106#define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
 107#define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
 108#define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
 109#define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
 110#define GP_STATUS_10G_HIG \
 111                        MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
 112#define GP_STATUS_10G_CX4 \
 113                        MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
 114#define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
 115#define GP_STATUS_10G_KX4 \
 116                        MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
 117#define GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR
 118#define GP_STATUS_10G_XFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI
 119#define GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS
 120#define GP_STATUS_10G_SFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI
 121#define GP_STATUS_20G_KR2 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_KR2
 122#define LINK_10THD              LINK_STATUS_SPEED_AND_DUPLEX_10THD
 123#define LINK_10TFD              LINK_STATUS_SPEED_AND_DUPLEX_10TFD
 124#define LINK_100TXHD            LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
 125#define LINK_100T4              LINK_STATUS_SPEED_AND_DUPLEX_100T4
 126#define LINK_100TXFD            LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
 127#define LINK_1000THD            LINK_STATUS_SPEED_AND_DUPLEX_1000THD
 128#define LINK_1000TFD            LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
 129#define LINK_1000XFD            LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
 130#define LINK_2500THD            LINK_STATUS_SPEED_AND_DUPLEX_2500THD
 131#define LINK_2500TFD            LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
 132#define LINK_2500XFD            LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
 133#define LINK_10GTFD             LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
 134#define LINK_10GXFD             LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
 135#define LINK_20GTFD             LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
 136#define LINK_20GXFD             LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
 137
 138#define LINK_UPDATE_MASK \
 139                        (LINK_STATUS_SPEED_AND_DUPLEX_MASK | \
 140                         LINK_STATUS_LINK_UP | \
 141                         LINK_STATUS_PHYSICAL_LINK_FLAG | \
 142                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | \
 143                         LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | \
 144                         LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | \
 145                         LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | \
 146                         LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | \
 147                         LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE)
 148
 149#define SFP_EEPROM_CON_TYPE_ADDR                0x2
 150        #define SFP_EEPROM_CON_TYPE_VAL_UNKNOWN 0x0
 151        #define SFP_EEPROM_CON_TYPE_VAL_LC      0x7
 152        #define SFP_EEPROM_CON_TYPE_VAL_COPPER  0x21
 153        #define SFP_EEPROM_CON_TYPE_VAL_RJ45    0x22
 154
 155
 156#define SFP_EEPROM_10G_COMP_CODE_ADDR           0x3
 157        #define SFP_EEPROM_10G_COMP_CODE_SR_MASK        (1<<4)
 158        #define SFP_EEPROM_10G_COMP_CODE_LR_MASK        (1<<5)
 159        #define SFP_EEPROM_10G_COMP_CODE_LRM_MASK       (1<<6)
 160
 161#define SFP_EEPROM_1G_COMP_CODE_ADDR            0x6
 162        #define SFP_EEPROM_1G_COMP_CODE_SX      (1<<0)
 163        #define SFP_EEPROM_1G_COMP_CODE_LX      (1<<1)
 164        #define SFP_EEPROM_1G_COMP_CODE_CX      (1<<2)
 165        #define SFP_EEPROM_1G_COMP_CODE_BASE_T  (1<<3)
 166
 167#define SFP_EEPROM_FC_TX_TECH_ADDR              0x8
 168        #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
 169        #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE  0x8
 170
 171#define SFP_EEPROM_OPTIONS_ADDR                 0x40
 172        #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
 173#define SFP_EEPROM_OPTIONS_SIZE                 2
 174
 175#define EDC_MODE_LINEAR                         0x0022
 176#define EDC_MODE_LIMITING                               0x0044
 177#define EDC_MODE_PASSIVE_DAC                    0x0055
 178#define EDC_MODE_ACTIVE_DAC                     0x0066
 179
 180/* ETS defines*/
 181#define DCBX_INVALID_COS                                        (0xFF)
 182
 183#define ETS_BW_LIMIT_CREDIT_UPPER_BOUND         (0x5000)
 184#define ETS_BW_LIMIT_CREDIT_WEIGHT              (0x5000)
 185#define ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS             (1360)
 186#define ETS_E3B0_NIG_MIN_W_VAL_20GBPS                   (2720)
 187#define ETS_E3B0_PBF_MIN_W_VAL                          (10000)
 188
 189#define MAX_PACKET_SIZE                                 (9700)
 190#define MAX_KR_LINK_RETRY                               4
 191
 192/**********************************************************/
 193/*                     INTERFACE                          */
 194/**********************************************************/
 195
 196#define CL22_WR_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
 197        bnx2x_cl45_write(_bp, _phy, \
 198                (_phy)->def_md_devad, \
 199                (_bank + (_addr & 0xf)), \
 200                _val)
 201
 202#define CL22_RD_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
 203        bnx2x_cl45_read(_bp, _phy, \
 204                (_phy)->def_md_devad, \
 205                (_bank + (_addr & 0xf)), \
 206                _val)
 207
 208static int bnx2x_check_half_open_conn(struct link_params *params,
 209                                      struct link_vars *vars, uint8_t notify);
 210static int bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
 211                                      struct link_params *params);
 212
 213static uint32_t bnx2x_bits_en(struct bnx2x *bp, uint32_t reg, uint32_t bits)
 214{
 215        uint32_t val = REG_RD(bp, reg);
 216
 217        val |= bits;
 218        REG_WR(bp, reg, val);
 219        return val;
 220}
 221
 222static uint32_t bnx2x_bits_dis(struct bnx2x *bp, uint32_t reg, uint32_t bits)
 223{
 224        uint32_t val = REG_RD(bp, reg);
 225
 226        val &= ~bits;
 227        REG_WR(bp, reg, val);
 228        return val;
 229}
 230
 231/*
 232 * bnx2x_check_lfa - This function checks if link reinitialization is required,
 233 *                   or link flap can be avoided.
 234 *
 235 * @params:     link parameters
 236 * Returns 0 if Link Flap Avoidance conditions are met otherwise, the failed
 237 *         condition code.
 238 */
 239static int bnx2x_check_lfa(struct link_params *params)
 240{
 241        uint32_t link_status, cfg_idx, lfa_mask, cfg_size;
 242        uint32_t cur_speed_cap_mask, cur_req_fc_auto_adv, additional_config;
 243        uint32_t saved_val, req_val, eee_status;
 244        struct bnx2x *bp = params->bp;
 245
 246        additional_config =
 247                REG_RD(bp, params->lfa_base +
 248                           offsetof(struct shmem_lfa, additional_config));
 249
 250        /* NOTE: must be first condition checked -
 251        * to verify DCC bit is cleared in any case!
 252        */
 253        if (additional_config & NO_LFA_DUE_TO_DCC_MASK) {
 254                DP(NETIF_MSG_LINK, "No LFA due to DCC flap after clp exit\n");
 255                REG_WR(bp, params->lfa_base +
 256                           offsetof(struct shmem_lfa, additional_config),
 257                       additional_config & ~NO_LFA_DUE_TO_DCC_MASK);
 258                return LFA_DCC_LFA_DISABLED;
 259        }
 260
 261        /* Verify that link is up */
 262        link_status = REG_RD(bp, params->shmem_base +
 263                             offsetof(struct shmem_region,
 264                                      port_mb[params->port].link_status));
 265        if (!(link_status & LINK_STATUS_LINK_UP))
 266                return LFA_LINK_DOWN;
 267
 268        /* if loaded after BOOT from SAN, don't flap the link in any case and
 269         * rely on link set by preboot driver
 270         */
 271        if (params->feature_config_flags & FEATURE_CONFIG_BOOT_FROM_SAN)
 272                return 0;
 273
 274        /* Verify that loopback mode is not set */
 275        if (params->loopback_mode)
 276                return LFA_LOOPBACK_ENABLED;
 277
 278        /* Verify that MFW supports LFA */
 279        if (!params->lfa_base)
 280                return LFA_MFW_IS_TOO_OLD;
 281
 282        if (params->num_phys == 3) {
 283                cfg_size = 2;
 284                lfa_mask = 0xffffffff;
 285        } else {
 286                cfg_size = 1;
 287                lfa_mask = 0xffff;
 288        }
 289
 290        /* Compare Duplex */
 291        saved_val = REG_RD(bp, params->lfa_base +
 292                           offsetof(struct shmem_lfa, req_duplex));
 293        req_val = params->req_duplex[0] | (params->req_duplex[1] << 16);
 294        if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
 295                DP(NETIF_MSG_LINK, "Duplex mismatch %x vs. %x\n",
 296                               (saved_val & lfa_mask), (req_val & lfa_mask));
 297                return LFA_DUPLEX_MISMATCH;
 298        }
 299        /* Compare Flow Control */
 300        saved_val = REG_RD(bp, params->lfa_base +
 301                           offsetof(struct shmem_lfa, req_flow_ctrl));
 302        req_val = params->req_flow_ctrl[0] | (params->req_flow_ctrl[1] << 16);
 303        if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
 304                DP(NETIF_MSG_LINK, "Flow control mismatch %x vs. %x\n",
 305                               (saved_val & lfa_mask), (req_val & lfa_mask));
 306                return LFA_FLOW_CTRL_MISMATCH;
 307        }
 308        /* Compare Link Speed */
 309        saved_val = REG_RD(bp, params->lfa_base +
 310                           offsetof(struct shmem_lfa, req_line_speed));
 311        req_val = params->req_line_speed[0] | (params->req_line_speed[1] << 16);
 312        if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
 313                DP(NETIF_MSG_LINK, "Link speed mismatch %x vs. %x\n",
 314                               (saved_val & lfa_mask), (req_val & lfa_mask));
 315                return LFA_LINK_SPEED_MISMATCH;
 316        }
 317
 318        for (cfg_idx = 0; cfg_idx < cfg_size; cfg_idx++) {
 319                cur_speed_cap_mask = REG_RD(bp, params->lfa_base +
 320                                            offsetof(struct shmem_lfa,
 321                                                     speed_cap_mask[cfg_idx]));
 322
 323                if (cur_speed_cap_mask != params->speed_cap_mask[cfg_idx]) {
 324                        DP(NETIF_MSG_LINK, "Speed Cap mismatch %x vs. %x\n",
 325                                       cur_speed_cap_mask,
 326                                       params->speed_cap_mask[cfg_idx]);
 327                        return LFA_SPEED_CAP_MISMATCH;
 328                }
 329        }
 330
 331        cur_req_fc_auto_adv =
 332                REG_RD(bp, params->lfa_base +
 333                       offsetof(struct shmem_lfa, additional_config)) &
 334                REQ_FC_AUTO_ADV_MASK;
 335
 336        if ((uint16_t)cur_req_fc_auto_adv != params->req_fc_auto_adv) {
 337                DP(NETIF_MSG_LINK, "Flow Ctrl AN mismatch %x vs. %x\n",
 338                               cur_req_fc_auto_adv, params->req_fc_auto_adv);
 339                return LFA_FLOW_CTRL_MISMATCH;
 340        }
 341
 342        eee_status = REG_RD(bp, params->shmem2_base +
 343                            offsetof(struct shmem2_region,
 344                                     eee_status[params->port]));
 345
 346        if (((eee_status & SHMEM_EEE_LPI_REQUESTED_BIT) ^
 347             (params->eee_mode & EEE_MODE_ENABLE_LPI)) ||
 348            ((eee_status & SHMEM_EEE_REQUESTED_BIT) ^
 349             (params->eee_mode & EEE_MODE_ADV_LPI))) {
 350                DP(NETIF_MSG_LINK, "EEE mismatch %x vs. %x\n", params->eee_mode,
 351                               eee_status);
 352                return LFA_EEE_MISMATCH;
 353        }
 354
 355        /* LFA conditions are met */
 356        return 0;
 357}
 358/******************************************************************/
 359/*                      EPIO/GPIO section                         */
 360/******************************************************************/
 361static void bnx2x_get_epio(struct bnx2x *bp, uint32_t epio_pin, uint32_t *en)
 362{
 363        uint32_t epio_mask, gp_oenable;
 364        *en = 0;
 365        /* Sanity check */
 366        if (epio_pin > 31) {
 367                DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to get\n", epio_pin);
 368                return;
 369        }
 370
 371        epio_mask = 1 << epio_pin;
 372        /* Set this EPIO to output */
 373        gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE);
 374        REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable & ~epio_mask);
 375
 376        *en = (REG_RD(bp, MCP_REG_MCPR_GP_INPUTS) & epio_mask) >> epio_pin;
 377}
 378static void bnx2x_set_epio(struct bnx2x *bp, uint32_t epio_pin, uint32_t en)
 379{
 380        uint32_t epio_mask, gp_output, gp_oenable;
 381
 382        /* Sanity check */
 383        if (epio_pin > 31) {
 384                DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to set\n", epio_pin);
 385                return;
 386        }
 387        DP(NETIF_MSG_LINK, "Setting EPIO pin %d to %d\n", epio_pin, en);
 388        epio_mask = 1 << epio_pin;
 389        /* Set this EPIO to output */
 390        gp_output = REG_RD(bp, MCP_REG_MCPR_GP_OUTPUTS);
 391        if (en)
 392                gp_output |= epio_mask;
 393        else
 394                gp_output &= ~epio_mask;
 395
 396        REG_WR(bp, MCP_REG_MCPR_GP_OUTPUTS, gp_output);
 397
 398        /* Set the value for this EPIO */
 399        gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE);
 400        REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask);
 401}
 402
 403static void bnx2x_set_cfg_pin(struct bnx2x *bp, uint32_t pin_cfg,
 404                              uint32_t val)
 405{
 406        if (pin_cfg == PIN_CFG_NA)
 407                return;
 408        if (pin_cfg >= PIN_CFG_EPIO0) {
 409                bnx2x_set_epio(bp, pin_cfg - PIN_CFG_EPIO0, val);
 410        } else {
 411                uint8_t gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
 412                uint8_t gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
 413                bnx2x_set_gpio(bp, gpio_num, (uint8_t)val, gpio_port);
 414        }
 415}
 416
 417static uint32_t bnx2x_get_cfg_pin(struct bnx2x *bp, uint32_t pin_cfg,
 418                                  uint32_t *val)
 419{
 420        if (pin_cfg == PIN_CFG_NA)
 421                return -EINVAL;
 422        if (pin_cfg >= PIN_CFG_EPIO0) {
 423                bnx2x_get_epio(bp, pin_cfg - PIN_CFG_EPIO0, val);
 424        } else {
 425                uint8_t gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
 426                uint8_t gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
 427                *val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
 428        }
 429        return 0;
 430
 431}
 432/******************************************************************/
 433/*                              ETS section                       */
 434/******************************************************************/
 435static void bnx2x_ets_e2e3a0_disabled(struct link_params *params)
 436{
 437        /* ETS disabled configuration*/
 438        struct bnx2x *bp = params->bp;
 439
 440        DP(NETIF_MSG_LINK, "ETS E2E3 disabled configuration\n");
 441
 442        /* mapping between entry  priority to client number (0,1,2 -debug and
 443         * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
 444         * 3bits client num.
 445         *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
 446         * cos1-100     cos0-011     dbg1-010     dbg0-001     MCP-000
 447         */
 448
 449        REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
 450        /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
 451         * as strict.  Bits 0,1,2 - debug and management entries, 3 -
 452         * COS0 entry, 4 - COS1 entry.
 453         * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
 454         * bit4   bit3    bit2   bit1     bit0
 455         * MCP and debug are strict
 456         */
 457
 458        REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
 459        /* defines which entries (clients) are subjected to WFQ arbitration */
 460        REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
 461        /* For strict priority entries defines the number of consecutive
 462         * slots for the highest priority.
 463         */
 464        REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
 465        /* mapping between the CREDIT_WEIGHT registers and actual client
 466         * numbers
 467         */
 468        REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
 469        REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
 470        REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
 471
 472        REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
 473        REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
 474        REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
 475        /* ETS mode disable */
 476        REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
 477        /* If ETS mode is enabled (there is no strict priority) defines a WFQ
 478         * weight for COS0/COS1.
 479         */
 480        REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
 481        REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710);
 482        /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
 483        REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680);
 484        REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680);
 485        /* Defines the number of consecutive slots for the strict priority */
 486        REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
 487}
 488/******************************************************************************
 489* Description:
 490*       Getting min_w_val will be set according to line speed .
 491*.
 492******************************************************************************/
 493static uint32_t bnx2x_ets_get_min_w_val_nig(const struct link_vars *vars)
 494{
 495        uint32_t min_w_val = 0;
 496        /* Calculate min_w_val.*/
 497        if (vars->link_up) {
 498                if (vars->line_speed == SPEED_20000)
 499                        min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
 500                else
 501                        min_w_val = ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS;
 502        } else
 503                min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
 504        /* If the link isn't up (static configuration for example ) The
 505         * link will be according to 20GBPS.
 506         */
 507        return min_w_val;
 508}
 509/******************************************************************************
 510* Description:
 511*       Getting credit upper bound form min_w_val.
 512*.
 513******************************************************************************/
 514static uint32_t bnx2x_ets_get_credit_upper_bound(const uint32_t min_w_val)
 515{
 516        const uint32_t credit_upper_bound = (uint32_t)MAXVAL((150 * min_w_val),
 517                                                MAX_PACKET_SIZE);
 518        return credit_upper_bound;
 519}
 520/******************************************************************************
 521* Description:
 522*       Set credit upper bound for NIG.
 523*.
 524******************************************************************************/
 525static void bnx2x_ets_e3b0_set_credit_upper_bound_nig(
 526        const struct link_params *params,
 527        const uint32_t min_w_val)
 528{
 529        struct bnx2x *bp = params->bp;
 530        const uint8_t port = params->port;
 531        const uint32_t credit_upper_bound =
 532            bnx2x_ets_get_credit_upper_bound(min_w_val);
 533
 534        REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_0 :
 535                NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, credit_upper_bound);
 536        REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_1 :
 537                   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, credit_upper_bound);
 538        REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_2 :
 539                   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_2, credit_upper_bound);
 540        REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_3 :
 541                   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_3, credit_upper_bound);
 542        REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_4 :
 543                   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_4, credit_upper_bound);
 544        REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_5 :
 545                   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_5, credit_upper_bound);
 546
 547        if (!port) {
 548                REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_6,
 549                        credit_upper_bound);
 550                REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_7,
 551                        credit_upper_bound);
 552                REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_8,
 553                        credit_upper_bound);
 554        }
 555}
 556/******************************************************************************
 557* Description:
 558*       Will return the NIG ETS registers to init values.Except
 559*       credit_upper_bound.
 560*       That isn't used in this configuration (No WFQ is enabled) and will be
 561*       configured acording to spec
 562*.
 563******************************************************************************/
 564static void bnx2x_ets_e3b0_nig_disabled(const struct link_params *params,
 565                                        const struct link_vars *vars)
 566{
 567        struct bnx2x *bp = params->bp;
 568        const uint8_t port = params->port;
 569        const uint32_t min_w_val = bnx2x_ets_get_min_w_val_nig(vars);
 570        /* Mapping between entry  priority to client number (0,1,2 -debug and
 571         * management clients, 3 - COS0 client, 4 - COS1, ... 8 -
 572         * COS5)(HIGHEST) 4bits client num.TODO_ETS - Should be done by
 573         * reset value or init tool
 574         */
 575        if (port) {
 576                REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB, 0x543210);
 577                REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB, 0x0);
 578        } else {
 579                REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, 0x76543210);
 580                REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, 0x8);
 581        }
 582        /* For strict priority entries defines the number of consecutive
 583         * slots for the highest priority.
 584         */
 585        REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS :
 586                   NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
 587        /* Mapping between the CREDIT_WEIGHT registers and actual client
 588         * numbers
 589         */
 590        if (port) {
 591                /*Port 1 has 6 COS*/
 592                REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB, 0x210543);
 593                REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x0);
 594        } else {
 595                /*Port 0 has 9 COS*/
 596                REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_LSB,
 597                       0x43210876);
 598                REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x5);
 599        }
 600
 601        /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
 602         * as strict.  Bits 0,1,2 - debug and management entries, 3 -
 603         * COS0 entry, 4 - COS1 entry.
 604         * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
 605         * bit4   bit3    bit2   bit1     bit0
 606         * MCP and debug are strict
 607         */
 608        if (port)
 609                REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT, 0x3f);
 610        else
 611                REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1ff);
 612        /* defines which entries (clients) are subjected to WFQ arbitration */
 613        REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
 614                   NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
 615
 616        /* Please notice the register address are note continuous and a
 617         * for here is note appropriate.In 2 port mode port0 only COS0-5
 618         * can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4
 619         * port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT
 620         * are never used for WFQ
 621         */
 622        REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
 623                   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0x0);
 624        REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
 625                   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0x0);
 626        REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
 627                   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2, 0x0);
 628        REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_3 :
 629                   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3, 0x0);
 630        REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_4 :
 631                   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4, 0x0);
 632        REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_5 :
 633                   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5, 0x0);
 634        if (!port) {
 635                REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_6, 0x0);
 636                REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_7, 0x0);
 637                REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_8, 0x0);
 638        }
 639
 640        bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val);
 641}
 642/******************************************************************************
 643* Description:
 644*       Set credit upper bound for PBF.
 645*.
 646******************************************************************************/
 647static void bnx2x_ets_e3b0_set_credit_upper_bound_pbf(
 648        const struct link_params *params,
 649        const uint32_t min_w_val)
 650{
 651        struct bnx2x *bp = params->bp;
 652        const uint32_t credit_upper_bound =
 653            bnx2x_ets_get_credit_upper_bound(min_w_val);
 654        const uint8_t port = params->port;
 655        uint32_t base_upper_bound = 0;
 656        uint8_t max_cos = 0;
 657        uint8_t i = 0;
 658        /* In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4
 659         * port mode port1 has COS0-2 that can be used for WFQ.
 660         */
 661        if (!port) {
 662                base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P0;
 663                max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0;
 664        } else {
 665                base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P1;
 666                max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1;
 667        }
 668
 669        for (i = 0; i < max_cos; i++)
 670                REG_WR(bp, base_upper_bound + (i << 2), credit_upper_bound);
 671}
 672
 673/******************************************************************************
 674* Description:
 675*       Will return the PBF ETS registers to init values.Except
 676*       credit_upper_bound.
 677*       That isn't used in this configuration (No WFQ is enabled) and will be
 678*       configured acording to spec
 679*.
 680******************************************************************************/
 681static void bnx2x_ets_e3b0_pbf_disabled(const struct link_params *params)
 682{
 683        struct bnx2x *bp = params->bp;
 684        const uint8_t port = params->port;
 685        const uint32_t min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL;
 686        uint8_t i = 0;
 687        uint32_t base_weight = 0;
 688        uint8_t max_cos = 0;
 689
 690        /* Mapping between entry  priority to client number 0 - COS0
 691         * client, 2 - COS1, ... 5 - COS5)(HIGHEST) 4bits client num.
 692         * TODO_ETS - Should be done by reset value or init tool
 693         */
 694        if (port)
 695                /*  0x688 (|011|0 10|00 1|000) */
 696                REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , 0x688);
 697        else
 698                /*  (10 1|100 |011|0 10|00 1|000) */
 699                REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , 0x2C688);
 700
 701        /* TODO_ETS - Should be done by reset value or init tool */
 702        if (port)
 703                /* 0x688 (|011|0 10|00 1|000)*/
 704                REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P1, 0x688);
 705        else
 706        /* 0x2C688 (10 1|100 |011|0 10|00 1|000) */
 707        REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P0, 0x2C688);
 708
 709        REG_WR(bp, (port) ? PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P1 :
 710                   PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P0 , 0x100);
 711
 712
 713        REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
 714                   PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , 0);
 715
 716        REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
 717                   PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0 , 0);
 718        /* In 2 port mode port0 has COS0-5 that can be used for WFQ.
 719         * In 4 port mode port1 has COS0-2 that can be used for WFQ.
 720         */
 721        if (!port) {
 722                base_weight = PBF_REG_COS0_WEIGHT_P0;
 723                max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0;
 724        } else {
 725                base_weight = PBF_REG_COS0_WEIGHT_P1;
 726                max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1;
 727        }
 728
 729        for (i = 0; i < max_cos; i++)
 730                REG_WR(bp, base_weight + (0x4 * i), 0);
 731
 732        bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
 733}
 734/******************************************************************************
 735* Description:
 736*       E3B0 disable will return basicly the values to init values.
 737*.
 738******************************************************************************/
 739static int bnx2x_ets_e3b0_disabled(const struct link_params *params,
 740                                   const struct link_vars *vars)
 741{
 742        struct bnx2x *bp = params->bp;
 743
 744        if (!CHIP_IS_E3B0(bp)) {
 745                DP(NETIF_MSG_LINK,
 746                   "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
 747                return -EINVAL;
 748        }
 749
 750        bnx2x_ets_e3b0_nig_disabled(params, vars);
 751
 752        bnx2x_ets_e3b0_pbf_disabled(params);
 753
 754        return 0;
 755}
 756
 757/******************************************************************************
 758* Description:
 759*       Disable will return basicly the values to init values.
 760*
 761******************************************************************************/
 762int bnx2x_ets_disabled(struct link_params *params,
 763                      struct link_vars *vars)
 764{
 765        struct bnx2x *bp = params->bp;
 766        int bnx2x_status = 0;
 767
 768        if ((CHIP_IS_E2(bp)) || (CHIP_IS_E3A0(bp)))
 769                bnx2x_ets_e2e3a0_disabled(params);
 770        else if (CHIP_IS_E3B0(bp))
 771                bnx2x_status = bnx2x_ets_e3b0_disabled(params, vars);
 772        else {
 773                DP(NETIF_MSG_LINK, "bnx2x_ets_disabled - chip not supported\n");
 774                return -EINVAL;
 775        }
 776
 777        return bnx2x_status;
 778}
 779
 780/******************************************************************************
 781* Description
 782*       Set the COS mappimg to SP and BW until this point all the COS are not
 783*       set as SP or BW.
 784******************************************************************************/
 785static int bnx2x_ets_e3b0_cli_map(const struct link_params *params,
 786                                  const struct bnx2x_ets_params *ets_params,
 787                                  const uint8_t cos_sp_bitmap,
 788                                  const uint8_t cos_bw_bitmap)
 789{
 790        struct bnx2x *bp = params->bp;
 791        const uint8_t port = params->port;
 792        const uint8_t nig_cli_sp_bitmap = 0x7 | (cos_sp_bitmap << 3);
 793        const uint8_t pbf_cli_sp_bitmap = cos_sp_bitmap;
 794        const uint8_t nig_cli_subject2wfq_bitmap = cos_bw_bitmap << 3;
 795        const uint8_t pbf_cli_subject2wfq_bitmap = cos_bw_bitmap;
 796
 797        REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT :
 798               NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, nig_cli_sp_bitmap);
 799
 800        REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
 801               PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , pbf_cli_sp_bitmap);
 802
 803        REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
 804               NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ,
 805               nig_cli_subject2wfq_bitmap);
 806
 807        REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
 808               PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0,
 809               pbf_cli_subject2wfq_bitmap);
 810
 811        return 0;
 812}
 813
 814/******************************************************************************
 815* Description:
 816*       This function is needed because NIG ARB_CREDIT_WEIGHT_X are
 817*       not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
 818******************************************************************************/
 819static int bnx2x_ets_e3b0_set_cos_bw(struct bnx2x *bp,
 820                                     const uint8_t cos_entry,
 821                                     const uint32_t min_w_val_nig,
 822                                     const uint32_t min_w_val_pbf,
 823                                     const uint16_t total_bw,
 824                                     const uint8_t bw,
 825                                     const uint8_t port)
 826{
 827        uint32_t nig_reg_adress_crd_weight = 0;
 828        uint32_t pbf_reg_adress_crd_weight = 0;
 829        /* Calculate and set BW for this COS - use 1 instead of 0 for BW */
 830        const uint32_t cos_bw_nig = ((bw ? bw : 1) * min_w_val_nig) / total_bw;
 831        const uint32_t cos_bw_pbf = ((bw ? bw : 1) * min_w_val_pbf) / total_bw;
 832
 833        switch (cos_entry) {
 834        case 0:
 835            nig_reg_adress_crd_weight =
 836                 (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
 837                     NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0;
 838             pbf_reg_adress_crd_weight = (port) ?
 839                 PBF_REG_COS0_WEIGHT_P1 : PBF_REG_COS0_WEIGHT_P0;
 840             break;
 841        case 1:
 842             nig_reg_adress_crd_weight = (port) ?
 843                 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
 844                 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1;
 845             pbf_reg_adress_crd_weight = (port) ?
 846                 PBF_REG_COS1_WEIGHT_P1 : PBF_REG_COS1_WEIGHT_P0;
 847             break;
 848        case 2:
 849             nig_reg_adress_crd_weight = (port) ?
 850                 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
 851                 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2;
 852
 853                 pbf_reg_adress_crd_weight = (port) ?
 854                     PBF_REG_COS2_WEIGHT_P1 : PBF_REG_COS2_WEIGHT_P0;
 855             break;
 856        case 3:
 857            if (port)
 858                        return -EINVAL;
 859             nig_reg_adress_crd_weight =
 860                 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3;
 861             pbf_reg_adress_crd_weight =
 862                 PBF_REG_COS3_WEIGHT_P0;
 863             break;
 864        case 4:
 865            if (port)
 866                return -EINVAL;
 867             nig_reg_adress_crd_weight =
 868                 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4;
 869             pbf_reg_adress_crd_weight = PBF_REG_COS4_WEIGHT_P0;
 870             break;
 871        case 5:
 872            if (port)
 873                return -EINVAL;
 874             nig_reg_adress_crd_weight =
 875                 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5;
 876             pbf_reg_adress_crd_weight = PBF_REG_COS5_WEIGHT_P0;
 877             break;
 878        }
 879
 880        REG_WR(bp, nig_reg_adress_crd_weight, cos_bw_nig);
 881
 882        REG_WR(bp, pbf_reg_adress_crd_weight, cos_bw_pbf);
 883
 884        return 0;
 885}
 886/******************************************************************************
 887* Description:
 888*       Calculate the total BW.A value of 0 isn't legal.
 889*
 890******************************************************************************/
 891static int bnx2x_ets_e3b0_get_total_bw(
 892        const struct link_params *params,
 893        struct bnx2x_ets_params *ets_params,
 894        uint16_t *total_bw)
 895{
 896        struct bnx2x *bp = params->bp;
 897        uint8_t cos_idx = 0;
 898        uint8_t is_bw_cos_exist = 0;
 899
 900        *total_bw = 0 ;
 901        /* Calculate total BW requested */
 902        for (cos_idx = 0; cos_idx < ets_params->num_of_cos; cos_idx++) {
 903                if (ets_params->cos[cos_idx].state == bnx2x_cos_state_bw) {
 904                        is_bw_cos_exist = 1;
 905                        if (!ets_params->cos[cos_idx].params.bw_params.bw) {
 906                                DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config BW"
 907                                                   "was set to 0\n");
 908                                /* This is to prevent a state when ramrods
 909                                 * can't be sent
 910                                 */
 911                                ets_params->cos[cos_idx].params.bw_params.bw
 912                                         = 1;
 913                        }
 914                        *total_bw +=
 915                                ets_params->cos[cos_idx].params.bw_params.bw;
 916                }
 917        }
 918
 919        /* Check total BW is valid */
 920        if ((is_bw_cos_exist == 1) && (*total_bw != 100)) {
 921                if (*total_bw == 0) {
 922                        DP(NETIF_MSG_LINK,
 923                           "bnx2x_ets_E3B0_config total BW shouldn't be 0\n");
 924                        return -EINVAL;
 925                }
 926                DP(NETIF_MSG_LINK,
 927                   "bnx2x_ets_E3B0_config total BW should be 100\n");
 928                /* We can handle a case whre the BW isn't 100 this can happen
 929                 * if the TC are joined.
 930                 */
 931        }
 932        return 0;
 933}
 934
 935/******************************************************************************
 936* Description:
 937*       Invalidate all the sp_pri_to_cos.
 938*
 939******************************************************************************/
 940static void bnx2x_ets_e3b0_sp_pri_to_cos_init(uint8_t *sp_pri_to_cos)
 941{
 942        uint8_t pri = 0;
 943        for (pri = 0; pri < DCBX_MAX_NUM_COS; pri++)
 944                sp_pri_to_cos[pri] = DCBX_INVALID_COS;
 945}
 946/******************************************************************************
 947* Description:
 948*       Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
 949*       according to sp_pri_to_cos.
 950*
 951******************************************************************************/
 952static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,
 953                                            uint8_t *sp_pri_to_cos,
 954                                            const uint8_t pri,
 955                                            const uint8_t cos_entry)
 956{
 957        struct bnx2x *bp = params->bp;
 958        const uint8_t port = params->port;
 959        const uint8_t max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
 960                DCBX_E3B0_MAX_NUM_COS_PORT0;
 961
 962        if (pri >= max_num_of_cos) {
 963                DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
 964                   "parameter Illegal strict priority\n");
 965            return -EINVAL;
 966        }
 967
 968        if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) {
 969                DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
 970                                   "parameter There can't be two COS's with "
 971                                   "the same strict pri\n");
 972                return -EINVAL;
 973        }
 974
 975        sp_pri_to_cos[pri] = cos_entry;
 976        return 0;
 977
 978}
 979
 980/******************************************************************************
 981* Description:
 982*       Returns the correct value according to COS and priority in
 983*       the sp_pri_cli register.
 984*
 985******************************************************************************/
 986static uint64_t bnx2x_e3b0_sp_get_pri_cli_reg(const uint8_t cos,
 987                                         const uint8_t cos_offset,
 988                                         const uint8_t pri_set,
 989                                         const uint8_t pri_offset,
 990                                         const uint8_t entry_size)
 991{
 992        uint64_t pri_cli_nig = 0;
 993        pri_cli_nig = ((uint64_t)(cos + cos_offset)) << (entry_size *
 994                                                    (pri_set + pri_offset));
 995
 996        return pri_cli_nig;
 997}
 998/******************************************************************************
 999* Description:
1000*       Returns the correct value according to COS and priority in the
1001*       sp_pri_cli register for NIG.
1002*
1003******************************************************************************/
1004static uint64_t bnx2x_e3b0_sp_get_pri_cli_reg_nig(const uint8_t cos,
1005                                             const uint8_t pri_set)
1006{
1007        /* MCP Dbg0 and dbg1 are always with higher strict pri*/
1008        const uint8_t nig_cos_offset = 3;
1009        const uint8_t nig_pri_offset = 3;
1010
1011        return bnx2x_e3b0_sp_get_pri_cli_reg(cos, nig_cos_offset, pri_set,
1012                nig_pri_offset, 4);
1013
1014}
1015/******************************************************************************
1016* Description:
1017*       Returns the correct value according to COS and priority in the
1018*       sp_pri_cli register for PBF.
1019*
1020******************************************************************************/
1021static uint64_t bnx2x_e3b0_sp_get_pri_cli_reg_pbf(const uint8_t cos,
1022                                             const uint8_t pri_set)
1023{
1024        const uint8_t pbf_cos_offset = 0;
1025        const uint8_t pbf_pri_offset = 0;
1026
1027        return bnx2x_e3b0_sp_get_pri_cli_reg(cos, pbf_cos_offset, pri_set,
1028                pbf_pri_offset, 3);
1029
1030}
1031
1032/******************************************************************************
1033* Description:
1034*       Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
1035*       according to sp_pri_to_cos.(which COS has higher priority)
1036*
1037******************************************************************************/
1038static int bnx2x_ets_e3b0_sp_set_pri_cli_reg(const struct link_params *params,
1039                                             uint8_t *sp_pri_to_cos)
1040{
1041        struct bnx2x *bp = params->bp;
1042        uint8_t i = 0;
1043        const uint8_t port = params->port;
1044        /* MCP Dbg0 and dbg1 are always with higher strict pri*/
1045        uint64_t pri_cli_nig = 0x210;
1046        uint32_t pri_cli_pbf = 0x0;
1047        uint8_t pri_set = 0;
1048        uint8_t pri_bitmask = 0;
1049        const uint8_t max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
1050                DCBX_E3B0_MAX_NUM_COS_PORT0;
1051
1052        uint8_t cos_bit_to_set = (1 << max_num_of_cos) - 1;
1053
1054        /* Set all the strict priority first */
1055        for (i = 0; i < max_num_of_cos; i++) {
1056                if (sp_pri_to_cos[i] != DCBX_INVALID_COS) {
1057                        if (sp_pri_to_cos[i] >= DCBX_MAX_NUM_COS) {
1058                                DP(NETIF_MSG_LINK,
1059                                           "bnx2x_ets_e3b0_sp_set_pri_cli_reg "
1060                                           "invalid cos entry\n");
1061                                return -EINVAL;
1062                        }
1063
1064                        pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
1065                            sp_pri_to_cos[i], pri_set);
1066
1067                        pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
1068                            sp_pri_to_cos[i], pri_set);
1069                        pri_bitmask = 1 << sp_pri_to_cos[i];
1070                        /* COS is used remove it from bitmap.*/
1071                        if (!(pri_bitmask & cos_bit_to_set)) {
1072                                DP(NETIF_MSG_LINK,
1073                                        "bnx2x_ets_e3b0_sp_set_pri_cli_reg "
1074                                        "invalid There can't be two COS's with"
1075                                        " the same strict pri\n");
1076                                return -EINVAL;
1077                        }
1078                        cos_bit_to_set &= ~pri_bitmask;
1079                        pri_set++;
1080                }
1081        }
1082
1083        /* Set all the Non strict priority i= COS*/
1084        for (i = 0; i < max_num_of_cos; i++) {
1085                pri_bitmask = 1 << i;
1086                /* Check if COS was already used for SP */
1087                if (pri_bitmask & cos_bit_to_set) {
1088                        /* COS wasn't used for SP */
1089                        pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
1090                            i, pri_set);
1091
1092                        pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
1093                            i, pri_set);
1094                        /* COS is used remove it from bitmap.*/
1095                        cos_bit_to_set &= ~pri_bitmask;
1096                        pri_set++;
1097                }
1098        }
1099
1100        if (pri_set != max_num_of_cos) {
1101                DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_set_pri_cli_reg not all "
1102                                   "entries were set\n");
1103                return -EINVAL;
1104        }
1105
1106        if (port) {
1107                /* Only 6 usable clients*/
1108                REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB,
1109                       (uint32_t)pri_cli_nig);
1110
1111                REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , pri_cli_pbf);
1112        } else {
1113                /* Only 9 usable clients*/
1114                const uint32_t pri_cli_nig_lsb = (uint32_t) (pri_cli_nig);
1115                const uint32_t pri_cli_nig_msb = (uint32_t) ((pri_cli_nig >> 32) & 0xF);
1116
1117                REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB,
1118                       pri_cli_nig_lsb);
1119                REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB,
1120                       pri_cli_nig_msb);
1121
1122                REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , pri_cli_pbf);
1123        }
1124        return 0;
1125}
1126
1127/******************************************************************************
1128* Description:
1129*       Configure the COS to ETS according to BW and SP settings.
1130******************************************************************************/
1131int bnx2x_ets_e3b0_config(const struct link_params *params,
1132                         const struct link_vars *vars,
1133                         struct bnx2x_ets_params *ets_params)
1134{
1135        struct bnx2x *bp = params->bp;
1136        int bnx2x_status = 0;
1137        const uint8_t port = params->port;
1138        uint16_t total_bw = 0;
1139        const uint32_t min_w_val_nig = bnx2x_ets_get_min_w_val_nig(vars);
1140        const uint32_t min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL;
1141        uint8_t cos_bw_bitmap = 0;
1142        uint8_t cos_sp_bitmap = 0;
1143        uint8_t sp_pri_to_cos[DCBX_MAX_NUM_COS] = {0};
1144        const uint8_t max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
1145                DCBX_E3B0_MAX_NUM_COS_PORT0;
1146        uint8_t cos_entry = 0;
1147
1148        if (!CHIP_IS_E3B0(bp)) {
1149                DP(NETIF_MSG_LINK,
1150                   "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
1151                return -EINVAL;
1152        }
1153
1154        if ((ets_params->num_of_cos > max_num_of_cos)) {
1155                DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config the number of COS "
1156                                   "isn't supported\n");
1157                return -EINVAL;
1158        }
1159
1160        /* Prepare sp strict priority parameters*/
1161        bnx2x_ets_e3b0_sp_pri_to_cos_init(sp_pri_to_cos);
1162
1163        /* Prepare BW parameters*/
1164        bnx2x_status = bnx2x_ets_e3b0_get_total_bw(params, ets_params,
1165                                                   &total_bw);
1166        if (bnx2x_status) {
1167                DP(NETIF_MSG_LINK,
1168                   "bnx2x_ets_E3B0_config get_total_bw failed\n");
1169                return -EINVAL;
1170        }
1171
1172        /* Upper bound is set according to current link speed (min_w_val
1173         * should be the same for upper bound and COS credit val).
1174         */
1175        bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val_nig);
1176        bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
1177
1178
1179        for (cos_entry = 0; cos_entry < ets_params->num_of_cos; cos_entry++) {
1180                if (bnx2x_cos_state_bw == ets_params->cos[cos_entry].state) {
1181                        cos_bw_bitmap |= (1 << cos_entry);
1182                        /* The function also sets the BW in HW(not the mappin
1183                         * yet)
1184                         */
1185                        bnx2x_status = bnx2x_ets_e3b0_set_cos_bw(
1186                                bp, cos_entry, min_w_val_nig, min_w_val_pbf,
1187                                total_bw,
1188                                ets_params->cos[cos_entry].params.bw_params.bw,
1189                                 port);
1190                } else if (bnx2x_cos_state_strict ==
1191                        ets_params->cos[cos_entry].state){
1192                        cos_sp_bitmap |= (1 << cos_entry);
1193
1194                        bnx2x_status = bnx2x_ets_e3b0_sp_pri_to_cos_set(
1195                                params,
1196                                sp_pri_to_cos,
1197                                ets_params->cos[cos_entry].params.sp_params.pri,
1198                                cos_entry);
1199
1200                } else {
1201                        DP(NETIF_MSG_LINK,
1202                           "bnx2x_ets_e3b0_config cos state not valid\n");
1203                        return -EINVAL;
1204                }
1205                if (bnx2x_status) {
1206                        DP(NETIF_MSG_LINK,
1207                           "bnx2x_ets_e3b0_config set cos bw failed\n");
1208                        return bnx2x_status;
1209                }
1210        }
1211
1212        /* Set SP register (which COS has higher priority) */
1213        bnx2x_status = bnx2x_ets_e3b0_sp_set_pri_cli_reg(params,
1214                                                         sp_pri_to_cos);
1215
1216        if (bnx2x_status) {
1217                DP(NETIF_MSG_LINK,
1218                   "bnx2x_ets_E3B0_config set_pri_cli_reg failed\n");
1219                return bnx2x_status;
1220        }
1221
1222        /* Set client mapping of BW and strict */
1223        bnx2x_status = bnx2x_ets_e3b0_cli_map(params, ets_params,
1224                                              cos_sp_bitmap,
1225                                              cos_bw_bitmap);
1226
1227        if (bnx2x_status) {
1228                DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config SP failed\n");
1229                return bnx2x_status;
1230        }
1231        return 0;
1232}
1233static void bnx2x_ets_bw_limit_common(const struct link_params *params)
1234{
1235        /* ETS disabled configuration */
1236        struct bnx2x *bp = params->bp;
1237        DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
1238        /* Defines which entries (clients) are subjected to WFQ arbitration
1239         * COS0 0x8
1240         * COS1 0x10
1241         */
1242        REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
1243        /* Mapping between the ARB_CREDIT_WEIGHT registers and actual
1244         * client numbers (WEIGHT_0 does not actually have to represent
1245         * client 0)
1246         *    PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1247         *  cos1-001     cos0-000     dbg1-100     dbg0-011     MCP-010
1248         */
1249        REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
1250
1251        REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
1252               ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1253        REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
1254               ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1255
1256        /* ETS mode enabled*/
1257        REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
1258
1259        /* Defines the number of consecutive slots for the strict priority */
1260        REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
1261        /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1262         * as strict.  Bits 0,1,2 - debug and management entries, 3 - COS0
1263         * entry, 4 - COS1 entry.
1264         * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1265         * bit4   bit3    bit2     bit1    bit0
1266         * MCP and debug are strict
1267         */
1268        REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
1269
1270        /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
1271        REG_WR(bp, PBF_REG_COS0_UPPER_BOUND,
1272               ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1273        REG_WR(bp, PBF_REG_COS1_UPPER_BOUND,
1274               ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1275}
1276
1277void bnx2x_ets_bw_limit(const struct link_params *params,
1278                        const uint32_t cos0_bw,
1279                        const uint32_t cos1_bw)
1280{
1281        /* ETS disabled configuration*/
1282        struct bnx2x *bp = params->bp;
1283        const uint32_t total_bw = cos0_bw + cos1_bw;
1284        uint32_t cos0_credit_weight = 0;
1285        uint32_t cos1_credit_weight = 0;
1286
1287        DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
1288
1289        if ((!total_bw) ||
1290            (!cos0_bw) ||
1291            (!cos1_bw)) {
1292                DP(NETIF_MSG_LINK, "Total BW can't be zero\n");
1293                return;
1294        }
1295
1296        cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
1297                total_bw;
1298        cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
1299                total_bw;
1300
1301        bnx2x_ets_bw_limit_common(params);
1302
1303        REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
1304        REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
1305
1306        REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
1307        REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
1308}
1309
1310int bnx2x_ets_strict(const struct link_params *params,
1311                     const uint8_t strict_cos)
1312{
1313        /* ETS disabled configuration*/
1314        struct bnx2x *bp = params->bp;
1315        uint32_t val    = 0;
1316
1317        DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
1318        /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1319         * as strict.  Bits 0,1,2 - debug and management entries,
1320         * 3 - COS0 entry, 4 - COS1 entry.
1321         *  COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1322         *  bit4   bit3   bit2      bit1     bit0
1323         * MCP and debug are strict
1324         */
1325        REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
1326        /* For strict priority entries defines the number of consecutive slots
1327         * for the highest priority.
1328         */
1329        REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
1330        /* ETS mode disable */
1331        REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
1332        /* Defines the number of consecutive slots for the strict priority */
1333        REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
1334
1335        /* Defines the number of consecutive slots for the strict priority */
1336        REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
1337
1338        /* Mapping between entry  priority to client number (0,1,2 -debug and
1339         * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
1340         * 3bits client num.
1341         *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1342         * dbg0-010     dbg1-001     cos1-100     cos0-011     MCP-000
1343         * dbg0-010     dbg1-001     cos0-011     cos1-100     MCP-000
1344         */
1345        val = (!strict_cos) ? 0x2318 : 0x22E0;
1346        REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
1347
1348        return 0;
1349}
1350
1351/******************************************************************/
1352/*                      PFC section                               */
1353/******************************************************************/
1354static void bnx2x_update_pfc_xmac(struct link_params *params,
1355                                  struct link_vars *vars,
1356                                  uint8_t is_lb)
1357{
1358        struct bnx2x *bp = params->bp;
1359        uint32_t xmac_base;
1360        uint32_t pause_val, pfc0_val, pfc1_val;
1361
1362        /* XMAC base adrr */
1363        xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1364
1365        /* Initialize pause and pfc registers */
1366        pause_val = 0x18000;
1367        pfc0_val = 0xFFFF8000;
1368        pfc1_val = 0x2;
1369
1370        /* No PFC support */
1371        if (!(params->feature_config_flags &
1372              FEATURE_CONFIG_PFC_ENABLED)) {
1373
1374                /* RX flow control - Process pause frame in receive direction
1375                 */
1376                if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1377                        pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN;
1378
1379                /* TX flow control - Send pause packet when buffer is full */
1380                if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1381                        pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN;
1382        } else {/* PFC support */
1383                pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN |
1384                        XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN |
1385                        XMAC_PFC_CTRL_HI_REG_RX_PFC_EN |
1386                        XMAC_PFC_CTRL_HI_REG_TX_PFC_EN |
1387                        XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
1388                /* Write pause and PFC registers */
1389                REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
1390                REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
1391                REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
1392                pfc1_val &= ~XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
1393
1394        }
1395
1396        /* Write pause and PFC registers */
1397        REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
1398        REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
1399        REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
1400
1401
1402        /* Set MAC address for source TX Pause/PFC frames */
1403        REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_LO,
1404               ((params->mac_addr[2] << 24) |
1405                (params->mac_addr[3] << 16) |
1406                (params->mac_addr[4] << 8) |
1407                (params->mac_addr[5])));
1408        REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_HI,
1409               ((params->mac_addr[0] << 8) |
1410                (params->mac_addr[1])));
1411
1412        udelay(30);
1413}
1414
1415/******************************************************************/
1416/*                      MAC/PBF section                           */
1417/******************************************************************/
1418static void bnx2x_set_mdio_clk(struct bnx2x *bp, uint32_t chip_id,
1419                               uint32_t emac_base)
1420{
1421        uint32_t new_mode, cur_mode;
1422        uint32_t clc_cnt;
1423        /* Set clause 45 mode, slow down the MDIO clock to 2.5MHz
1424         * (a value of 49==0x31) and make sure that the AUTO poll is off
1425         */
1426        cur_mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
1427
1428        if (USES_WARPCORE(bp))
1429                clc_cnt = 74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
1430        else
1431                clc_cnt = 49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
1432
1433        if (((cur_mode & EMAC_MDIO_MODE_CLOCK_CNT) == clc_cnt) &&
1434            (cur_mode & (EMAC_MDIO_MODE_CLAUSE_45)))
1435                return;
1436
1437        new_mode = cur_mode &
1438                ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
1439        new_mode |= clc_cnt;
1440        new_mode |= (EMAC_MDIO_MODE_CLAUSE_45);
1441
1442        DP(NETIF_MSG_LINK, "Changing emac_mode from 0x%x to 0x%x\n",
1443           cur_mode, new_mode);
1444        REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, new_mode);
1445        udelay(40);
1446}
1447
1448static void bnx2x_set_mdio_emac_per_phy(struct bnx2x *bp,
1449                                        struct link_params *params)
1450{
1451        uint8_t phy_index;
1452        /* Set mdio clock per phy */
1453        for (phy_index = INT_PHY; phy_index < params->num_phys;
1454              phy_index++)
1455                bnx2x_set_mdio_clk(bp, params->chip_id,
1456                                   params->phy[phy_index].mdio_ctrl);
1457}
1458
1459static uint8_t bnx2x_is_4_port_mode(struct bnx2x *bp)
1460{
1461        uint32_t port4mode_ovwr_val;
1462        /* Check 4-port override enabled */
1463        port4mode_ovwr_val = REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR);
1464        if (port4mode_ovwr_val & (1<<0)) {
1465                /* Return 4-port mode override value */
1466                return ((port4mode_ovwr_val & (1<<1)) == (1<<1));
1467        }
1468        /* Return 4-port mode from input pin */
1469        return (uint8_t)REG_RD(bp, MISC_REG_PORT4MODE_EN);
1470}
1471
1472static void bnx2x_emac_init(struct link_params *params,
1473                            struct link_vars *vars)
1474{
1475        /* reset and unreset the emac core */
1476        struct bnx2x *bp = params->bp;
1477        uint8_t port = params->port;
1478        uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1479        uint32_t val;
1480        uint16_t timeout;
1481
1482        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1483               (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1484        udelay(5);
1485        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1486               (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1487
1488        /* init emac - use read-modify-write */
1489        /* self clear reset */
1490        val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1491        EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
1492
1493        timeout = 200;
1494        do {
1495                val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1496                DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
1497                if (!timeout) {
1498                        DP(NETIF_MSG_LINK, "EMAC timeout!\n");
1499                        return;
1500                }
1501                timeout--;
1502        } while (val & EMAC_MODE_RESET);
1503
1504        bnx2x_set_mdio_emac_per_phy(bp, params);
1505        /* Set mac address */
1506        val = ((params->mac_addr[0] << 8) |
1507                params->mac_addr[1]);
1508        EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
1509
1510        val = ((params->mac_addr[2] << 24) |
1511               (params->mac_addr[3] << 16) |
1512               (params->mac_addr[4] << 8) |
1513                params->mac_addr[5]);
1514        EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
1515}
1516
1517static void bnx2x_set_xumac_nig(struct link_params *params,
1518                                uint16_t tx_pause_en,
1519                                uint8_t enable)
1520{
1521        struct bnx2x *bp = params->bp;
1522
1523        REG_WR(bp, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN,
1524               enable);
1525        REG_WR(bp, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN,
1526               enable);
1527        REG_WR(bp, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN :
1528               NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
1529}
1530
1531static void bnx2x_set_umac_rxtx(struct link_params *params, uint8_t en)
1532{
1533        uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
1534        uint32_t val;
1535        struct bnx2x *bp = params->bp;
1536        if (!(REG_RD(bp, MISC_REG_RESET_REG_2) &
1537                   (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)))
1538                return;
1539        val = REG_RD(bp, umac_base + UMAC_REG_COMMAND_CONFIG);
1540        if (en)
1541                val |= (UMAC_COMMAND_CONFIG_REG_TX_ENA |
1542                        UMAC_COMMAND_CONFIG_REG_RX_ENA);
1543        else
1544                val &= ~(UMAC_COMMAND_CONFIG_REG_TX_ENA |
1545                         UMAC_COMMAND_CONFIG_REG_RX_ENA);
1546        /* Disable RX and TX */
1547        REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1548}
1549
1550static void bnx2x_umac_enable(struct link_params *params,
1551                            struct link_vars *vars, uint8_t lb)
1552{
1553        uint32_t val;
1554        uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
1555        struct bnx2x *bp = params->bp;
1556        /* Reset UMAC */
1557        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1558               (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
1559        kthread_usleep(1000);
1560
1561        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1562               (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
1563
1564        DP(NETIF_MSG_LINK, "enabling UMAC\n");
1565
1566        /* This register opens the gate for the UMAC despite its name */
1567        REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
1568
1569        val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN |
1570                UMAC_COMMAND_CONFIG_REG_PAD_EN |
1571                UMAC_COMMAND_CONFIG_REG_SW_RESET |
1572                UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK;
1573        switch (vars->line_speed) {
1574        case SPEED_10:
1575                val |= (0<<2);
1576                break;
1577        case SPEED_100:
1578                val |= (1<<2);
1579                break;
1580        case SPEED_1000:
1581                val |= (2<<2);
1582                break;
1583        case SPEED_2500:
1584                val |= (3<<2);
1585                break;
1586        default:
1587                DP(NETIF_MSG_LINK, "Invalid speed for UMAC %d\n",
1588                               vars->line_speed);
1589                break;
1590        }
1591        if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1592                val |= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE;
1593
1594        if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1595                val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE;
1596
1597        if (vars->duplex == DUPLEX_HALF)
1598                val |= UMAC_COMMAND_CONFIG_REG_HD_ENA;
1599
1600        REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1601        udelay(50);
1602
1603        /* Configure UMAC for EEE */
1604        if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
1605                DP(NETIF_MSG_LINK, "configured UMAC for EEE\n");
1606                REG_WR(bp, umac_base + UMAC_REG_UMAC_EEE_CTRL,
1607                       UMAC_UMAC_EEE_CTRL_REG_EEE_EN);
1608                REG_WR(bp, umac_base + UMAC_REG_EEE_WAKE_TIMER, 0x11);
1609        } else {
1610                REG_WR(bp, umac_base + UMAC_REG_UMAC_EEE_CTRL, 0x0);
1611        }
1612
1613        /* Set MAC address for source TX Pause/PFC frames (under SW reset) */
1614        REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR0,
1615               ((params->mac_addr[2] << 24) |
1616                (params->mac_addr[3] << 16) |
1617                (params->mac_addr[4] << 8) |
1618                (params->mac_addr[5])));
1619        REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR1,
1620               ((params->mac_addr[0] << 8) |
1621                (params->mac_addr[1])));
1622
1623        /* Enable RX and TX */
1624        val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN;
1625        val |= UMAC_COMMAND_CONFIG_REG_TX_ENA |
1626                UMAC_COMMAND_CONFIG_REG_RX_ENA;
1627        REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1628        udelay(50);
1629
1630        /* Remove SW Reset */
1631        val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET;
1632
1633        /* Check loopback mode */
1634        if (lb)
1635                val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA;
1636        REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1637
1638        /* Maximum Frame Length (RW). Defines a 14-Bit maximum frame
1639         * length used by the MAC receive logic to check frames.
1640         */
1641        REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
1642        bnx2x_set_xumac_nig(params,
1643                            ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
1644        vars->mac_type = MAC_TYPE_UMAC;
1645}
1646
1647/* Define the XMAC mode */
1648static void bnx2x_xmac_init(struct link_params *params, uint32_t max_speed)
1649{
1650        struct bnx2x *bp = params->bp;
1651        uint32_t is_port4mode = bnx2x_is_4_port_mode(bp);
1652
1653        /* In 4-port mode, need to set the mode only once, so if XMAC is
1654         * already out of reset, it means the mode has already been set,
1655         * and it must not* reset the XMAC again, since it controls both
1656         * ports of the path
1657         */
1658
1659        if (((CHIP_NUM(bp) == CHIP_NUM_57840_4_10) ||
1660             (CHIP_NUM(bp) == CHIP_NUM_57840_2_20) ||
1661             (CHIP_NUM(bp) == CHIP_NUM_57840_OBSOLETE)) &&
1662            is_port4mode &&
1663            (REG_RD(bp, MISC_REG_RESET_REG_2) &
1664             MISC_REGISTERS_RESET_REG_2_XMAC)) {
1665                DP(NETIF_MSG_LINK,
1666                   "XMAC already out of reset in 4-port mode\n");
1667                return;
1668        }
1669
1670        /* Hard reset */
1671        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1672               MISC_REGISTERS_RESET_REG_2_XMAC);
1673        kthread_usleep(1000);
1674
1675        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1676               MISC_REGISTERS_RESET_REG_2_XMAC);
1677        if (is_port4mode) {
1678                DP(NETIF_MSG_LINK, "Init XMAC to 2 ports x 10G per path\n");
1679
1680                /* Set the number of ports on the system side to up to 2 */
1681                REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 1);
1682
1683                /* Set the number of ports on the Warp Core to 10G */
1684                REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
1685        } else {
1686                /* Set the number of ports on the system side to 1 */
1687                REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 0);
1688                if (max_speed == SPEED_10000) {
1689                        DP(NETIF_MSG_LINK,
1690                           "Init XMAC to 10G x 1 port per path\n");
1691                        /* Set the number of ports on the Warp Core to 10G */
1692                        REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
1693                } else {
1694                        DP(NETIF_MSG_LINK,
1695                           "Init XMAC to 20G x 2 ports per path\n");
1696                        /* Set the number of ports on the Warp Core to 20G */
1697                        REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 1);
1698                }
1699        }
1700        /* Soft reset */
1701        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1702               MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
1703        kthread_usleep(1000);
1704
1705        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1706               MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
1707
1708}
1709
1710static void bnx2x_set_xmac_rxtx(struct link_params *params, uint8_t en)
1711{
1712        uint8_t port = params->port;
1713        struct bnx2x *bp = params->bp;
1714        uint32_t pfc_ctrl, xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1715        uint32_t val;
1716
1717        if (REG_RD(bp, MISC_REG_RESET_REG_2) &
1718            MISC_REGISTERS_RESET_REG_2_XMAC) {
1719                /* Send an indication to change the state in the NIG back to XON
1720                 * Clearing this bit enables the next set of this bit to get
1721                 * rising edge
1722                 */
1723                pfc_ctrl = REG_RD(bp, xmac_base + XMAC_REG_PFC_CTRL_HI);
1724                REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI,
1725                       (pfc_ctrl & ~(1<<1)));
1726                REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI,
1727                       (pfc_ctrl | (1<<1)));
1728                DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port);
1729                val = REG_RD(bp, xmac_base + XMAC_REG_CTRL);
1730                if (en)
1731                        val |= (XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN);
1732                else
1733                        val &= ~(XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN);
1734                REG_WR(bp, xmac_base + XMAC_REG_CTRL, val);
1735        }
1736}
1737
1738static int bnx2x_xmac_enable(struct link_params *params,
1739                             struct link_vars *vars, uint8_t lb)
1740{
1741        uint32_t val, xmac_base;
1742        struct bnx2x *bp = params->bp;
1743        DP(NETIF_MSG_LINK, "enabling XMAC\n");
1744
1745        xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1746
1747        bnx2x_xmac_init(params, vars->line_speed);
1748
1749        /* This register determines on which events the MAC will assert
1750         * error on the i/f to the NIG along w/ EOP.
1751         */
1752
1753        /* This register tells the NIG whether to send traffic to UMAC
1754         * or XMAC
1755         */
1756        REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0);
1757
1758        /* When XMAC is in XLGMII mode, disable sending idles for fault
1759         * detection.
1760         */
1761        if (!(params->phy[INT_PHY].flags & FLAGS_TX_ERROR_CHECK)) {
1762                REG_WR(bp, xmac_base + XMAC_REG_RX_LSS_CTRL,
1763                       (XMAC_RX_LSS_CTRL_REG_LOCAL_FAULT_DISABLE |
1764                        XMAC_RX_LSS_CTRL_REG_REMOTE_FAULT_DISABLE));
1765                REG_WR(bp, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
1766                REG_WR(bp, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
1767                       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
1768                       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
1769        }
1770        /* Set Max packet size */
1771        REG_WR(bp, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710);
1772
1773        /* CRC append for Tx packets */
1774        REG_WR(bp, xmac_base + XMAC_REG_TX_CTRL, 0xC800);
1775
1776        /* update PFC */
1777        bnx2x_update_pfc_xmac(params, vars, 0);
1778
1779        if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
1780                DP(NETIF_MSG_LINK, "Setting XMAC for EEE\n");
1781                REG_WR(bp, xmac_base + XMAC_REG_EEE_TIMERS_HI, 0x1380008);
1782                REG_WR(bp, xmac_base + XMAC_REG_EEE_CTRL, 0x1);
1783        } else {
1784                REG_WR(bp, xmac_base + XMAC_REG_EEE_CTRL, 0x0);
1785        }
1786
1787        /* Enable TX and RX */
1788        val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
1789
1790        /* Set MAC in XLGMII mode for dual-mode */
1791        if ((vars->line_speed == SPEED_20000) &&
1792            (params->phy[INT_PHY].supported &
1793             SUPPORTED_20000baseKR2_Full))
1794                val |= XMAC_CTRL_REG_XLGMII_ALIGN_ENB;
1795
1796        /* Check loopback mode */
1797        if (lb)
1798                val |= XMAC_CTRL_REG_LINE_LOCAL_LPBK;
1799        REG_WR(bp, xmac_base + XMAC_REG_CTRL, val);
1800        bnx2x_set_xumac_nig(params,
1801                            ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
1802
1803        vars->mac_type = MAC_TYPE_XMAC;
1804
1805        return 0;
1806}
1807
1808static int bnx2x_emac_enable(struct link_params *params,
1809                             struct link_vars *vars, uint8_t lb)
1810{
1811        struct bnx2x *bp = params->bp;
1812        uint8_t port = params->port;
1813        uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1814        uint32_t val;
1815
1816        DP(NETIF_MSG_LINK, "enabling EMAC\n");
1817
1818        /* Disable BMAC */
1819        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1820               (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1821
1822        /* enable emac and not bmac */
1823        REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
1824
1825        /* ASIC */
1826        if (vars->phy_flags & PHY_XGXS_FLAG) {
1827                uint32_t ser_lane = ((params->lane_config &
1828                                 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1829                                PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1830
1831                DP(NETIF_MSG_LINK, "XGXS\n");
1832                /* select the master lanes (out of 0-3) */
1833                REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane);
1834                /* select XGXS */
1835                REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
1836
1837        } else { /* SerDes */
1838                DP(NETIF_MSG_LINK, "SerDes\n");
1839                /* select SerDes */
1840                REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
1841        }
1842
1843        bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
1844                      EMAC_RX_MODE_RESET);
1845        bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1846                      EMAC_TX_MODE_RESET);
1847
1848                /* pause enable/disable */
1849                bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
1850                               EMAC_RX_MODE_FLOW_EN);
1851
1852                bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
1853                               (EMAC_TX_MODE_EXT_PAUSE_EN |
1854                                EMAC_TX_MODE_FLOW_EN));
1855                if (!(params->feature_config_flags &
1856                      FEATURE_CONFIG_PFC_ENABLED)) {
1857                        if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1858                                bnx2x_bits_en(bp, emac_base +
1859                                              EMAC_REG_EMAC_RX_MODE,
1860                                              EMAC_RX_MODE_FLOW_EN);
1861
1862                        if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1863                                bnx2x_bits_en(bp, emac_base +
1864                                              EMAC_REG_EMAC_TX_MODE,
1865                                              (EMAC_TX_MODE_EXT_PAUSE_EN |
1866                                               EMAC_TX_MODE_FLOW_EN));
1867                } else
1868                        bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1869                                      EMAC_TX_MODE_FLOW_EN);
1870
1871        /* KEEP_VLAN_TAG, promiscuous */
1872        val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
1873        val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
1874
1875        /* Setting this bit causes MAC control frames (except for pause
1876         * frames) to be passed on for processing. This setting has no
1877         * affect on the operation of the pause frames. This bit effects
1878         * all packets regardless of RX Parser packet sorting logic.
1879         * Turn the PFC off to make sure we are in Xon state before
1880         * enabling it.
1881         */
1882        EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
1883        if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
1884                DP(NETIF_MSG_LINK, "PFC is enabled\n");
1885                /* Enable PFC again */
1886                EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
1887                        EMAC_REG_RX_PFC_MODE_RX_EN |
1888                        EMAC_REG_RX_PFC_MODE_TX_EN |
1889                        EMAC_REG_RX_PFC_MODE_PRIORITIES);
1890
1891                EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
1892                        ((0x0101 <<
1893                          EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
1894                         (0x00ff <<
1895                          EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
1896                val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
1897        }
1898        EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
1899
1900        /* Set Loopback */
1901        val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1902        if (lb)
1903                val |= 0x810;
1904        else
1905                val &= ~0x810;
1906        EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
1907
1908        /* Enable emac */
1909        REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
1910
1911        /* Enable emac for jumbo packets */
1912        EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
1913                (EMAC_RX_MTU_SIZE_JUMBO_ENA |
1914                 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
1915
1916        /* Strip CRC */
1917        REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
1918
1919        /* Disable the NIG in/out to the bmac */
1920        REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
1921        REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
1922        REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
1923
1924        /* Enable the NIG in/out to the emac */
1925        REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
1926        val = 0;
1927        if ((params->feature_config_flags &
1928              FEATURE_CONFIG_PFC_ENABLED) ||
1929            (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1930                val = 1;
1931
1932        REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
1933        REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
1934
1935        REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
1936
1937        vars->mac_type = MAC_TYPE_EMAC;
1938        return 0;
1939}
1940
1941static void bnx2x_update_pfc_bmac1(struct link_params *params,
1942                                   struct link_vars *vars)
1943{
1944        uint32_t wb_data[2];
1945        struct bnx2x *bp = params->bp;
1946        uint32_t bmac_addr =  params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1947                NIG_REG_INGRESS_BMAC0_MEM;
1948
1949        uint32_t val = 0x14;
1950        if ((!(params->feature_config_flags &
1951              FEATURE_CONFIG_PFC_ENABLED)) &&
1952                (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1953                /* Enable BigMAC to react on received Pause packets */
1954                val |= (1<<5);
1955        wb_data[0] = val;
1956        wb_data[1] = 0;
1957        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
1958
1959        /* TX control */
1960        val = 0xc0;
1961        if (!(params->feature_config_flags &
1962              FEATURE_CONFIG_PFC_ENABLED) &&
1963                (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1964                val |= 0x800000;
1965        wb_data[0] = val;
1966        wb_data[1] = 0;
1967        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
1968}
1969
1970static void bnx2x_update_pfc_bmac2(struct link_params *params,
1971                                   struct link_vars *vars,
1972                                   uint8_t is_lb)
1973{
1974        /* Set rx control: Strip CRC and enable BigMAC to relay
1975         * control packets to the system as well
1976         */
1977        uint32_t wb_data[2];
1978        struct bnx2x *bp = params->bp;
1979        uint32_t bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1980                NIG_REG_INGRESS_BMAC0_MEM;
1981        uint32_t val = 0x14;
1982
1983        if ((!(params->feature_config_flags &
1984              FEATURE_CONFIG_PFC_ENABLED)) &&
1985                (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1986                /* Enable BigMAC to react on received Pause packets */
1987                val |= (1<<5);
1988        wb_data[0] = val;
1989        wb_data[1] = 0;
1990        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
1991        udelay(30);
1992
1993        /* Tx control */
1994        val = 0xc0;
1995        if (!(params->feature_config_flags &
1996                                FEATURE_CONFIG_PFC_ENABLED) &&
1997            (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1998                val |= 0x800000;
1999        wb_data[0] = val;
2000        wb_data[1] = 0;
2001        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
2002
2003        if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
2004                DP(NETIF_MSG_LINK, "PFC is enabled\n");
2005                /* Enable PFC RX & TX & STATS and set 8 COS  */
2006                wb_data[0] = 0x0;
2007                wb_data[0] |= (1<<0);  /* RX */
2008                wb_data[0] |= (1<<1);  /* TX */
2009                wb_data[0] |= (1<<2);  /* Force initial Xon */
2010                wb_data[0] |= (1<<3);  /* 8 cos */
2011                wb_data[0] |= (1<<5);  /* STATS */
2012                wb_data[1] = 0;
2013                REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
2014                            wb_data, 2);
2015                /* Clear the force Xon */
2016                wb_data[0] &= ~(1<<2);
2017        } else {
2018                DP(NETIF_MSG_LINK, "PFC is disabled\n");
2019                /* Disable PFC RX & TX & STATS and set 8 COS */
2020                wb_data[0] = 0x8;
2021                wb_data[1] = 0;
2022        }
2023
2024        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
2025
2026        /* Set Time (based unit is 512 bit time) between automatic
2027         * re-sending of PP packets amd enable automatic re-send of
2028         * Per-Priroity Packet as long as pp_gen is asserted and
2029         * pp_disable is low.
2030         */
2031        val = 0x8000;
2032        if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2033                val |= (1<<16); /* enable automatic re-send */
2034
2035        wb_data[0] = val;
2036        wb_data[1] = 0;
2037        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
2038                    wb_data, 2);
2039
2040        /* mac control */
2041        val = 0x3; /* Enable RX and TX */
2042        if (is_lb) {
2043                val |= 0x4; /* Local loopback */
2044                DP(NETIF_MSG_LINK, "enable bmac loopback\n");
2045        }
2046        /* When PFC enabled, Pass pause frames towards the NIG. */
2047        if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2048                val |= ((1<<6)|(1<<5));
2049
2050        wb_data[0] = val;
2051        wb_data[1] = 0;
2052        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2053}
2054
2055/******************************************************************************
2056* Description:
2057*  This function is needed because NIG ARB_CREDIT_WEIGHT_X are
2058*  not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
2059******************************************************************************/
2060static int bnx2x_pfc_nig_rx_priority_mask(struct bnx2x *bp,
2061                                           uint8_t cos_entry,
2062                                           uint32_t priority_mask,
2063                                          uint8_t port)
2064{
2065        uint32_t nig_reg_rx_priority_mask_add = 0;
2066
2067        switch (cos_entry) {
2068        case 0:
2069             nig_reg_rx_priority_mask_add = (port) ?
2070                 NIG_REG_P1_RX_COS0_PRIORITY_MASK :
2071                 NIG_REG_P0_RX_COS0_PRIORITY_MASK;
2072             break;
2073        case 1:
2074            nig_reg_rx_priority_mask_add = (port) ?
2075                NIG_REG_P1_RX_COS1_PRIORITY_MASK :
2076                NIG_REG_P0_RX_COS1_PRIORITY_MASK;
2077            break;
2078        case 2:
2079            nig_reg_rx_priority_mask_add = (port) ?
2080                NIG_REG_P1_RX_COS2_PRIORITY_MASK :
2081                NIG_REG_P0_RX_COS2_PRIORITY_MASK;
2082            break;
2083        case 3:
2084            if (port)
2085                return -EINVAL;
2086            nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK;
2087            break;
2088        case 4:
2089            if (port)
2090                return -EINVAL;
2091            nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK;
2092            break;
2093        case 5:
2094            if (port)
2095                return -EINVAL;
2096            nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK;
2097            break;
2098        }
2099
2100        REG_WR(bp, nig_reg_rx_priority_mask_add, priority_mask);
2101
2102        return 0;
2103}
2104static void bnx2x_update_mng(struct link_params *params, uint32_t link_status)
2105{
2106        struct bnx2x *bp = params->bp;
2107
2108        REG_WR(bp, params->shmem_base +
2109               offsetof(struct shmem_region,
2110                        port_mb[params->port].link_status), link_status);
2111}
2112
2113static void bnx2x_update_link_attr(struct link_params *params,
2114                                   uint32_t link_attr)
2115{
2116        struct bnx2x *bp = params->bp;
2117
2118        if (SHMEM2_HAS(bp, link_attr_sync))
2119                REG_WR(bp, params->shmem2_base +
2120                       offsetof(struct shmem2_region,
2121                                link_attr_sync[params->port]), link_attr);
2122}
2123
2124static void bnx2x_update_pfc_nig(struct link_params *params,
2125                struct link_vars *vars,
2126                struct bnx2x_nig_brb_pfc_port_params *nig_params)
2127{
2128        uint32_t xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
2129        uint32_t llfc_enable = 0, xcm_out_en = 0, hwpfc_enable = 0;
2130        uint32_t pkt_priority_to_cos = 0;
2131        struct bnx2x *bp = params->bp;
2132        uint8_t port = params->port;
2133
2134        int set_pfc = params->feature_config_flags &
2135                FEATURE_CONFIG_PFC_ENABLED;
2136        DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
2137
2138        /* When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
2139         * MAC control frames (that are not pause packets)
2140         * will be forwarded to the XCM.
2141         */
2142        xcm_mask = REG_RD(bp, port ? NIG_REG_LLH1_XCM_MASK :
2143                          NIG_REG_LLH0_XCM_MASK);
2144        /* NIG params will override non PFC params, since it's possible to
2145         * do transition from PFC to SAFC
2146         */
2147        if (set_pfc) {
2148                pause_enable = 0;
2149                llfc_out_en = 0;
2150                llfc_enable = 0;
2151                if (CHIP_IS_E3(bp))
2152                        ppp_enable = 0;
2153                else
2154                        ppp_enable = 1;
2155                xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2156                                     NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2157                xcm_out_en = 0;
2158                hwpfc_enable = 1;
2159        } else  {
2160                if (nig_params) {
2161                        llfc_out_en = nig_params->llfc_out_en;
2162                        llfc_enable = nig_params->llfc_enable;
2163                        pause_enable = nig_params->pause_enable;
2164                } else  /* Default non PFC mode - PAUSE */
2165                        pause_enable = 1;
2166
2167                xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2168                        NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2169                xcm_out_en = 1;
2170        }
2171
2172        if (CHIP_IS_E3(bp))
2173                REG_WR(bp, port ? NIG_REG_BRB1_PAUSE_IN_EN :
2174                       NIG_REG_BRB0_PAUSE_IN_EN, pause_enable);
2175        REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
2176               NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
2177        REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
2178               NIG_REG_LLFC_ENABLE_0, llfc_enable);
2179        REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
2180               NIG_REG_PAUSE_ENABLE_0, pause_enable);
2181
2182        REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
2183               NIG_REG_PPP_ENABLE_0, ppp_enable);
2184
2185        REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
2186               NIG_REG_LLH0_XCM_MASK, xcm_mask);
2187
2188        REG_WR(bp, port ? NIG_REG_LLFC_EGRESS_SRC_ENABLE_1 :
2189               NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
2190
2191        /* Output enable for RX_XCM # IF */
2192        REG_WR(bp, port ? NIG_REG_XCM1_OUT_EN :
2193               NIG_REG_XCM0_OUT_EN, xcm_out_en);
2194
2195        /* HW PFC TX enable */
2196        REG_WR(bp, port ? NIG_REG_P1_HWPFC_ENABLE :
2197               NIG_REG_P0_HWPFC_ENABLE, hwpfc_enable);
2198
2199        if (nig_params) {
2200                uint8_t i = 0;
2201                pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
2202
2203                for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++)
2204                        bnx2x_pfc_nig_rx_priority_mask(bp, i,
2205                nig_params->rx_cos_priority_mask[i], port);
2206
2207                REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
2208                       NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
2209                       nig_params->llfc_high_priority_classes);
2210
2211                REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
2212                       NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
2213                       nig_params->llfc_low_priority_classes);
2214        }
2215        REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
2216               NIG_REG_P0_PKT_PRIORITY_TO_COS,
2217               pkt_priority_to_cos);
2218}
2219
2220int bnx2x_update_pfc(struct link_params *params,
2221                      struct link_vars *vars,
2222                      struct bnx2x_nig_brb_pfc_port_params *pfc_params)
2223{
2224        /* The PFC and pause are orthogonal to one another, meaning when
2225         * PFC is enabled, the pause are disabled, and when PFC is
2226         * disabled, pause are set according to the pause result.
2227         */
2228        uint32_t val;
2229        struct bnx2x *bp = params->bp;
2230        uint8_t bmac_loopback = (params->loopback_mode == LOOPBACK_BMAC);
2231
2232        if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2233                vars->link_status |= LINK_STATUS_PFC_ENABLED;
2234        else
2235                vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
2236
2237        bnx2x_update_mng(params, vars->link_status);
2238
2239        /* Update NIG params */
2240        bnx2x_update_pfc_nig(params, vars, pfc_params);
2241
2242        if (!vars->link_up)
2243                return 0;
2244
2245        DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
2246
2247        if (CHIP_IS_E3(bp)) {
2248                if (vars->mac_type == MAC_TYPE_XMAC)
2249                        bnx2x_update_pfc_xmac(params, vars, 0);
2250        } else {
2251                val = REG_RD(bp, MISC_REG_RESET_REG_2);
2252                if ((val &
2253                     (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
2254                    == 0) {
2255                        DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
2256                        bnx2x_emac_enable(params, vars, 0);
2257                        return 0;
2258                }
2259                if (CHIP_IS_E2(bp))
2260                        bnx2x_update_pfc_bmac2(params, vars, bmac_loopback);
2261                else
2262                        bnx2x_update_pfc_bmac1(params, vars);
2263
2264                val = 0;
2265                if ((params->feature_config_flags &
2266                     FEATURE_CONFIG_PFC_ENABLED) ||
2267                    (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
2268                        val = 1;
2269                REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
2270        }
2271        return 0;
2272}
2273
2274static int bnx2x_bmac1_enable(struct link_params *params,
2275                              struct link_vars *vars,
2276                              uint8_t is_lb)
2277{
2278        struct bnx2x *bp = params->bp;
2279        uint8_t port = params->port;
2280        uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2281                               NIG_REG_INGRESS_BMAC0_MEM;
2282        uint32_t wb_data[2];
2283        uint32_t val;
2284
2285        DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
2286
2287        /* XGXS control */
2288        wb_data[0] = 0x3c;
2289        wb_data[1] = 0;
2290        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
2291                    wb_data, 2);
2292
2293        /* TX MAC SA */
2294        wb_data[0] = ((params->mac_addr[2] << 24) |
2295                       (params->mac_addr[3] << 16) |
2296                       (params->mac_addr[4] << 8) |
2297                        params->mac_addr[5]);
2298        wb_data[1] = ((params->mac_addr[0] << 8) |
2299                        params->mac_addr[1]);
2300        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
2301
2302        /* MAC control */
2303        val = 0x3;
2304        if (is_lb) {
2305                val |= 0x4;
2306                DP(NETIF_MSG_LINK, "enable bmac loopback\n");
2307        }
2308        wb_data[0] = val;
2309        wb_data[1] = 0;
2310        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
2311
2312        /* Set rx mtu */
2313        wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2314        wb_data[1] = 0;
2315        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
2316
2317        bnx2x_update_pfc_bmac1(params, vars);
2318
2319        /* Set tx mtu */
2320        wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2321        wb_data[1] = 0;
2322        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
2323
2324        /* Set cnt max size */
2325        wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2326        wb_data[1] = 0;
2327        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2328
2329        /* Configure SAFC */
2330        wb_data[0] = 0x1000200;
2331        wb_data[1] = 0;
2332        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
2333                    wb_data, 2);
2334
2335        return 0;
2336}
2337
2338static int bnx2x_bmac2_enable(struct link_params *params,
2339                              struct link_vars *vars,
2340                              uint8_t is_lb)
2341{
2342        struct bnx2x *bp = params->bp;
2343        uint8_t port = params->port;
2344        uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2345                               NIG_REG_INGRESS_BMAC0_MEM;
2346        uint32_t wb_data[2];
2347
2348        DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
2349
2350        wb_data[0] = 0;
2351        wb_data[1] = 0;
2352        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2353        udelay(30);
2354
2355        /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
2356        wb_data[0] = 0x3c;
2357        wb_data[1] = 0;
2358        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
2359                    wb_data, 2);
2360
2361        udelay(30);
2362
2363        /* TX MAC SA */
2364        wb_data[0] = ((params->mac_addr[2] << 24) |
2365                       (params->mac_addr[3] << 16) |
2366                       (params->mac_addr[4] << 8) |
2367                        params->mac_addr[5]);
2368        wb_data[1] = ((params->mac_addr[0] << 8) |
2369                        params->mac_addr[1]);
2370        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
2371                    wb_data, 2);
2372
2373        udelay(30);
2374
2375        /* Configure SAFC */
2376        wb_data[0] = 0x1000200;
2377        wb_data[1] = 0;
2378        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
2379                    wb_data, 2);
2380        udelay(30);
2381
2382        /* Set RX MTU */
2383        wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2384        wb_data[1] = 0;
2385        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
2386        udelay(30);
2387
2388        /* Set TX MTU */
2389        wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2390        wb_data[1] = 0;
2391        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
2392        udelay(30);
2393        /* Set cnt max size */
2394        wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
2395        wb_data[1] = 0;
2396        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2397        udelay(30);
2398        bnx2x_update_pfc_bmac2(params, vars, is_lb);
2399
2400        return 0;
2401}
2402
2403static int bnx2x_bmac_enable(struct link_params *params,
2404                             struct link_vars *vars,
2405                             uint8_t is_lb, uint8_t reset_bmac)
2406{
2407        int rc = 0;
2408        uint8_t port = params->port;
2409        struct bnx2x *bp = params->bp;
2410        uint32_t val;
2411        /* Reset and unreset the BigMac */
2412        if (reset_bmac) {
2413                REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2414                       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2415                kthread_usleep(1000);
2416        }
2417
2418        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2419               (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2420
2421        /* Enable access for bmac registers */
2422        REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
2423
2424        /* Enable BMAC according to BMAC type*/
2425        if (CHIP_IS_E2(bp))
2426                rc = bnx2x_bmac2_enable(params, vars, is_lb);
2427        else
2428                rc = bnx2x_bmac1_enable(params, vars, is_lb);
2429        REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
2430        REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
2431        REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
2432        val = 0;
2433        if ((params->feature_config_flags &
2434              FEATURE_CONFIG_PFC_ENABLED) ||
2435            (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
2436                val = 1;
2437        REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
2438        REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
2439        REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
2440        REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
2441        REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
2442        REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
2443
2444        vars->mac_type = MAC_TYPE_BMAC;
2445        return rc;
2446}
2447
2448static void bnx2x_set_bmac_rx(struct bnx2x *bp, uint32_t chip_id,
2449                              uint8_t port,
2450                              uint8_t en)
2451{
2452        uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2453                        NIG_REG_INGRESS_BMAC0_MEM;
2454        uint32_t wb_data[2];
2455        uint32_t nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
2456
2457        if (CHIP_IS_E2(bp))
2458                bmac_addr += BIGMAC2_REGISTER_BMAC_CONTROL;
2459        else
2460                bmac_addr += BIGMAC_REGISTER_BMAC_CONTROL;
2461        /* Only if the bmac is out of reset */
2462        if (REG_RD(bp, MISC_REG_RESET_REG_2) &
2463                        (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
2464            nig_bmac_enable) {
2465                /* Clear Rx Enable bit in BMAC_CONTROL register */
2466                REG_RD_DMAE(bp, bmac_addr, wb_data, 2);
2467                if (en)
2468                        wb_data[0] |= BMAC_CONTROL_RX_ENABLE;
2469                else
2470                        wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
2471                REG_WR_DMAE(bp, bmac_addr, wb_data, 2);
2472                kthread_usleep(1000);
2473        }
2474}
2475
2476static int bnx2x_pbf_update(struct link_params *params, uint32_t flow_ctrl,
2477                            uint32_t line_speed)
2478{
2479        struct bnx2x *bp = params->bp;
2480        uint8_t port = params->port;
2481        uint32_t init_crd, crd;
2482        uint32_t count = 1000;
2483
2484        /* Disable port */
2485        REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
2486
2487        /* Wait for init credit */
2488        init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
2489        crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2490        DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
2491
2492        while ((init_crd != crd) && count) {
2493                kthread_usleep(5000);
2494                crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2495                count--;
2496        }
2497        crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2498        if (init_crd != crd) {
2499                DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
2500                          init_crd, crd);
2501                return -EINVAL;
2502        }
2503
2504        if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
2505            line_speed == SPEED_10 ||
2506            line_speed == SPEED_100 ||
2507            line_speed == SPEED_1000 ||
2508            line_speed == SPEED_2500) {
2509                REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
2510                /* Update threshold */
2511                REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
2512                /* Update init credit */
2513                init_crd = 778;         /* (800-18-4) */
2514
2515        } else {
2516                uint32_t thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
2517                              ETH_OVREHEAD)/16;
2518                REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
2519                /* Update threshold */
2520                REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
2521                /* Update init credit */
2522                switch (line_speed) {
2523                case SPEED_10000:
2524                        init_crd = thresh + 553 - 22;
2525                        break;
2526                default:
2527                        DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2528                                  line_speed);
2529                        return -EINVAL;
2530                }
2531        }
2532        REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
2533        DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
2534                 line_speed, init_crd);
2535
2536        /* Probe the credit changes */
2537        REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
2538        kthread_usleep(5000);
2539        REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
2540
2541        /* Enable port */
2542        REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
2543        return 0;
2544}
2545
2546/**
2547 * bnx2x_get_emac_base - retrive emac base address
2548 *
2549 * @bp:                 driver handle
2550 * @mdc_mdio_access:    access type
2551 * @port:               port id
2552 *
2553 * This function selects the MDC/MDIO access (through emac0 or
2554 * emac1) depend on the mdc_mdio_access, port, port swapped. Each
2555 * phy has a default access mode, which could also be overridden
2556 * by nvram configuration. This parameter, whether this is the
2557 * default phy configuration, or the nvram overrun
2558 * configuration, is passed here as mdc_mdio_access and selects
2559 * the emac_base for the CL45 read/writes operations
2560 */
2561static uint32_t bnx2x_get_emac_base(struct bnx2x *bp,
2562                               uint32_t mdc_mdio_access, uint8_t port)
2563{
2564        uint32_t emac_base = 0;
2565        switch (mdc_mdio_access) {
2566        case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
2567                break;
2568        case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
2569                if (REG_RD(bp, NIG_REG_PORT_SWAP))
2570                        emac_base = GRCBASE_EMAC1;
2571                else
2572                        emac_base = GRCBASE_EMAC0;
2573                break;
2574        case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
2575                if (REG_RD(bp, NIG_REG_PORT_SWAP))
2576                        emac_base = GRCBASE_EMAC0;
2577                else
2578                        emac_base = GRCBASE_EMAC1;
2579                break;
2580        case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
2581                emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2582                break;
2583        case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
2584                emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
2585                break;
2586        default:
2587                break;
2588        }
2589        return emac_base;
2590
2591}
2592
2593/******************************************************************/
2594/*                      CL22 access functions                     */
2595/******************************************************************/
2596static int bnx2x_cl22_write(struct bnx2x *bp,
2597                                       struct bnx2x_phy *phy,
2598                                       uint16_t reg, uint16_t val)
2599{
2600        uint32_t tmp, mode;
2601        uint8_t i;
2602        int rc = 0;
2603        /* Switch to CL22 */
2604        mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
2605        REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
2606               mode & ~EMAC_MDIO_MODE_CLAUSE_45);
2607
2608        /* Address */
2609        tmp = ((phy->addr << 21) | (reg << 16) | val |
2610               EMAC_MDIO_COMM_COMMAND_WRITE_22 |
2611               EMAC_MDIO_COMM_START_BUSY);
2612        REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2613
2614        for (i = 0; i < 50; i++) {
2615                udelay(10);
2616
2617                tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2618                if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2619                        udelay(5);
2620                        break;
2621                }
2622        }
2623        if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2624                DP(NETIF_MSG_LINK, "write phy register failed\n");
2625                rc = -EFAULT;
2626        }
2627        REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
2628        return rc;
2629}
2630
2631static int bnx2x_cl22_read(struct bnx2x *bp,
2632                                      struct bnx2x_phy *phy,
2633                                      uint16_t reg, uint16_t *ret_val)
2634{
2635        uint32_t val, mode;
2636        uint16_t i;
2637        int rc = 0;
2638
2639        /* Switch to CL22 */
2640        mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
2641        REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
2642               mode & ~EMAC_MDIO_MODE_CLAUSE_45);
2643
2644        /* Address */
2645        val = ((phy->addr << 21) | (reg << 16) |
2646               EMAC_MDIO_COMM_COMMAND_READ_22 |
2647               EMAC_MDIO_COMM_START_BUSY);
2648        REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2649
2650        for (i = 0; i < 50; i++) {
2651                udelay(10);
2652
2653                val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2654                if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2655                        *ret_val = (uint16_t)(val & EMAC_MDIO_COMM_DATA);
2656                        udelay(5);
2657                        break;
2658                }
2659        }
2660        if (val & EMAC_MDIO_COMM_START_BUSY) {
2661                DP(NETIF_MSG_LINK, "read phy register failed\n");
2662
2663                *ret_val = 0;
2664                rc = -EFAULT;
2665        }
2666        REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
2667        return rc;
2668}
2669
2670/******************************************************************/
2671/*                      CL45 access functions                     */
2672/******************************************************************/
2673static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
2674                           uint8_t devad, uint16_t reg, uint16_t *ret_val)
2675{
2676        uint32_t val;
2677        uint16_t i;
2678        int rc = 0;
2679        uint32_t chip_id;
2680        if (phy->flags & FLAGS_MDC_MDIO_WA_G) {
2681                chip_id = (REG_RD(bp, MISC_REG_CHIP_NUM) << 16) |
2682                          ((REG_RD(bp, MISC_REG_CHIP_REV) & 0xf) << 12);
2683                bnx2x_set_mdio_clk(bp, chip_id, phy->mdio_ctrl);
2684        }
2685
2686        if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
2687                bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2688                              EMAC_MDIO_STATUS_10MB);
2689        /* Address */
2690        val = ((phy->addr << 21) | (devad << 16) | reg |
2691               EMAC_MDIO_COMM_COMMAND_ADDRESS |
2692               EMAC_MDIO_COMM_START_BUSY);
2693        REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2694
2695        for (i = 0; i < 50; i++) {
2696                udelay(10);
2697
2698                val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2699                if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2700                        udelay(5);
2701                        break;
2702                }
2703        }
2704        if (val & EMAC_MDIO_COMM_START_BUSY) {
2705                DP(NETIF_MSG_LINK, "read phy register failed\n");
2706                netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
2707                *ret_val = 0;
2708                rc = -EFAULT;
2709        } else {
2710                /* Data */
2711                val = ((phy->addr << 21) | (devad << 16) |
2712                       EMAC_MDIO_COMM_COMMAND_READ_45 |
2713                       EMAC_MDIO_COMM_START_BUSY);
2714                REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2715
2716                for (i = 0; i < 50; i++) {
2717                        udelay(10);
2718
2719                        val = REG_RD(bp, phy->mdio_ctrl +
2720                                     EMAC_REG_EMAC_MDIO_COMM);
2721                        if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2722                                *ret_val = (uint16_t)(val & EMAC_MDIO_COMM_DATA);
2723                                break;
2724                        }
2725                }
2726                if (val & EMAC_MDIO_COMM_START_BUSY) {
2727                        DP(NETIF_MSG_LINK, "read phy register failed\n");
2728                        netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
2729                        *ret_val = 0;
2730                        rc = -EFAULT;
2731                }
2732        }
2733        /* Work around for E3 A0 */
2734        if (phy->flags & FLAGS_MDC_MDIO_WA) {
2735                phy->flags ^= FLAGS_DUMMY_READ;
2736                if (phy->flags & FLAGS_DUMMY_READ) {
2737                        uint16_t temp_val;
2738                        bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
2739                }
2740        }
2741
2742        if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
2743                bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2744                               EMAC_MDIO_STATUS_10MB);
2745        return rc;
2746}
2747
2748static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
2749                            uint8_t devad, uint16_t reg, uint16_t val)
2750{
2751        uint32_t tmp;
2752        uint8_t i;
2753        int rc = 0;
2754        uint32_t chip_id;
2755        if (phy->flags & FLAGS_MDC_MDIO_WA_G) {
2756                chip_id = (REG_RD(bp, MISC_REG_CHIP_NUM) << 16) |
2757                          ((REG_RD(bp, MISC_REG_CHIP_REV) & 0xf) << 12);
2758                bnx2x_set_mdio_clk(bp, chip_id, phy->mdio_ctrl);
2759        }
2760
2761        if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
2762                bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2763                              EMAC_MDIO_STATUS_10MB);
2764
2765        /* Address */
2766        tmp = ((phy->addr << 21) | (devad << 16) | reg |
2767               EMAC_MDIO_COMM_COMMAND_ADDRESS |
2768               EMAC_MDIO_COMM_START_BUSY);
2769        REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2770
2771        for (i = 0; i < 50; i++) {
2772                udelay(10);
2773
2774                tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2775                if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2776                        udelay(5);
2777                        break;
2778                }
2779        }
2780        if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2781                DP(NETIF_MSG_LINK, "write phy register failed\n");
2782                netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
2783                rc = -EFAULT;
2784        } else {
2785                /* Data */
2786                tmp = ((phy->addr << 21) | (devad << 16) | val |
2787                       EMAC_MDIO_COMM_COMMAND_WRITE_45 |
2788                       EMAC_MDIO_COMM_START_BUSY);
2789                REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2790
2791                for (i = 0; i < 50; i++) {
2792                        udelay(10);
2793
2794                        tmp = REG_RD(bp, phy->mdio_ctrl +
2795                                     EMAC_REG_EMAC_MDIO_COMM);
2796                        if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2797                                udelay(5);
2798                                break;
2799                        }
2800                }
2801                if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2802                        DP(NETIF_MSG_LINK, "write phy register failed\n");
2803                        netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
2804                        rc = -EFAULT;
2805                }
2806        }
2807        /* Work around for E3 A0 */
2808        if (phy->flags & FLAGS_MDC_MDIO_WA) {
2809                phy->flags ^= FLAGS_DUMMY_READ;
2810                if (phy->flags & FLAGS_DUMMY_READ) {
2811                        uint16_t temp_val;
2812                        bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
2813                }
2814        }
2815        if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
2816                bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2817                               EMAC_MDIO_STATUS_10MB);
2818        return rc;
2819}
2820
2821/******************************************************************/
2822/*                      EEE section                                */
2823/******************************************************************/
2824static uint8_t bnx2x_eee_has_cap(struct link_params *params)
2825{
2826        struct bnx2x *bp = params->bp;
2827
2828        if (REG_RD(bp, params->shmem2_base) <=
2829                   offsetof(struct shmem2_region, eee_status[params->port]))
2830                return 0;
2831
2832        return 1;
2833}
2834
2835static int bnx2x_eee_nvram_to_time(uint32_t nvram_mode, uint32_t *idle_timer)
2836{
2837        switch (nvram_mode) {
2838        case PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED:
2839                *idle_timer = EEE_MODE_NVRAM_BALANCED_TIME;
2840                break;
2841        case PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE:
2842                *idle_timer = EEE_MODE_NVRAM_AGGRESSIVE_TIME;
2843                break;
2844        case PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY:
2845                *idle_timer = EEE_MODE_NVRAM_LATENCY_TIME;
2846                break;
2847        default:
2848                *idle_timer = 0;
2849                break;
2850        }
2851
2852        return 0;
2853}
2854
2855static int bnx2x_eee_time_to_nvram(uint32_t idle_timer, uint32_t *nvram_mode)
2856{
2857        switch (idle_timer) {
2858        case EEE_MODE_NVRAM_BALANCED_TIME:
2859                *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED;
2860                break;
2861        case EEE_MODE_NVRAM_AGGRESSIVE_TIME:
2862                *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE;
2863                break;
2864        case EEE_MODE_NVRAM_LATENCY_TIME:
2865                *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY;
2866                break;
2867        default:
2868                *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED;
2869                break;
2870        }
2871
2872        return 0;
2873}
2874
2875static uint32_t bnx2x_eee_calc_timer(struct link_params *params)
2876{
2877        uint32_t eee_mode, eee_idle;
2878        struct bnx2x *bp = params->bp;
2879
2880        if (params->eee_mode & EEE_MODE_OVERRIDE_NVRAM) {
2881                if (params->eee_mode & EEE_MODE_OUTPUT_TIME) {
2882                        /* time value in eee_mode --> used directly*/
2883                        eee_idle = params->eee_mode & EEE_MODE_TIMER_MASK;
2884                } else {
2885                        /* hsi value in eee_mode --> time */
2886                        if (bnx2x_eee_nvram_to_time(params->eee_mode &
2887                                                    EEE_MODE_NVRAM_MASK,
2888                                                    &eee_idle))
2889                                return 0;
2890                }
2891        } else {
2892                /* hsi values in nvram --> time*/
2893                eee_mode = ((REG_RD(bp, params->shmem_base +
2894                                    offsetof(struct shmem_region, dev_info.
2895                                    port_feature_config[params->port].
2896                                    eee_power_mode)) &
2897                             PORT_FEAT_CFG_EEE_POWER_MODE_MASK) >>
2898                            PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT);
2899
2900                if (bnx2x_eee_nvram_to_time(eee_mode, &eee_idle))
2901                        return 0;
2902        }
2903
2904        return eee_idle;
2905}
2906
2907static int bnx2x_eee_set_timers(struct link_params *params,
2908                                   struct link_vars *vars)
2909{
2910        uint32_t eee_idle = 0, eee_mode;
2911        struct bnx2x *bp = params->bp;
2912
2913        eee_idle = bnx2x_eee_calc_timer(params);
2914
2915        if (eee_idle) {
2916                REG_WR(bp, MISC_REG_CPMU_LP_IDLE_THR_P0 + (params->port << 2),
2917                       eee_idle);
2918        } else if ((params->eee_mode & EEE_MODE_ENABLE_LPI) &&
2919                   (params->eee_mode & EEE_MODE_OVERRIDE_NVRAM) &&
2920                   (params->eee_mode & EEE_MODE_OUTPUT_TIME)) {
2921                DP(NETIF_MSG_LINK, "Error: Tx LPI is enabled with timer 0\n");
2922                return -EINVAL;
2923        }
2924
2925        vars->eee_status &= ~(SHMEM_EEE_TIMER_MASK | SHMEM_EEE_TIME_OUTPUT_BIT);
2926        if (params->eee_mode & EEE_MODE_OUTPUT_TIME) {
2927                /* eee_idle in 1u --> eee_status in 16u */
2928                eee_idle >>= 4;
2929                vars->eee_status |= (eee_idle & SHMEM_EEE_TIMER_MASK) |
2930                                    SHMEM_EEE_TIME_OUTPUT_BIT;
2931        } else {
2932                if (bnx2x_eee_time_to_nvram(eee_idle, &eee_mode))
2933                        return -EINVAL;
2934                vars->eee_status |= eee_mode;
2935        }
2936
2937        return 0;
2938}
2939
2940static int bnx2x_eee_initial_config(struct link_params *params,
2941                                     struct link_vars *vars, uint8_t mode)
2942{
2943        vars->eee_status |= ((uint32_t) mode) << SHMEM_EEE_SUPPORTED_SHIFT;
2944
2945        /* Propogate params' bits --> vars (for migration exposure) */
2946        if (params->eee_mode & EEE_MODE_ENABLE_LPI)
2947                vars->eee_status |= SHMEM_EEE_LPI_REQUESTED_BIT;
2948        else
2949                vars->eee_status &= ~SHMEM_EEE_LPI_REQUESTED_BIT;
2950
2951        if (params->eee_mode & EEE_MODE_ADV_LPI)
2952                vars->eee_status |= SHMEM_EEE_REQUESTED_BIT;
2953        else
2954                vars->eee_status &= ~SHMEM_EEE_REQUESTED_BIT;
2955
2956        return bnx2x_eee_set_timers(params, vars);
2957}
2958
2959static int bnx2x_eee_disable(struct bnx2x_phy *phy,
2960                                struct link_params *params,
2961                                struct link_vars *vars)
2962{
2963        struct bnx2x *bp = params->bp;
2964
2965        /* Make Certain LPI is disabled */
2966        REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2), 0);
2967
2968        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, 0x0);
2969
2970        vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
2971
2972        return 0;
2973}
2974
2975static int bnx2x_eee_advertise(struct bnx2x_phy *phy,
2976                                  struct link_params *params,
2977                                  struct link_vars *vars, uint8_t modes)
2978{
2979        struct bnx2x *bp = params->bp;
2980        uint16_t val = 0;
2981
2982        /* Mask events preventing LPI generation */
2983        REG_WR(bp, MISC_REG_CPMU_LP_MASK_EXT_P0 + (params->port << 2), 0xfc20);
2984
2985        if (modes & SHMEM_EEE_10G_ADV) {
2986                DP(NETIF_MSG_LINK, "Advertise 10GBase-T EEE\n");
2987                val |= 0x8;
2988        }
2989        if (modes & SHMEM_EEE_1G_ADV) {
2990                DP(NETIF_MSG_LINK, "Advertise 1GBase-T EEE\n");
2991                val |= 0x4;
2992        }
2993
2994        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, val);
2995
2996        vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
2997        vars->eee_status |= (modes << SHMEM_EEE_ADV_STATUS_SHIFT);
2998
2999        return 0;
3000}
3001
3002static void bnx2x_update_mng_eee(struct link_params *params,
3003                                 uint32_t eee_status)
3004{
3005        struct bnx2x *bp = params->bp;
3006
3007        if (bnx2x_eee_has_cap(params))
3008                REG_WR(bp, params->shmem2_base +
3009                       offsetof(struct shmem2_region,
3010                                eee_status[params->port]), eee_status);
3011}
3012
3013static void bnx2x_eee_an_resolve(struct bnx2x_phy *phy,
3014                                  struct link_params *params,
3015                                  struct link_vars *vars)
3016{
3017        struct bnx2x *bp = params->bp;
3018        uint16_t adv = 0, lp = 0;
3019        uint32_t lp_adv = 0;
3020        uint8_t neg = 0;
3021
3022        bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, &adv);
3023        bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_LP_EEE_ADV, &lp);
3024
3025        if (lp & 0x2) {
3026                lp_adv |= SHMEM_EEE_100M_ADV;
3027                if (adv & 0x2) {
3028                        if (vars->line_speed == SPEED_100)
3029                                neg = 1;
3030                        DP(NETIF_MSG_LINK, "EEE negotiated - 100M\n");
3031                }
3032        }
3033        if (lp & 0x14) {
3034                lp_adv |= SHMEM_EEE_1G_ADV;
3035                if (adv & 0x14) {
3036                        if (vars->line_speed == SPEED_1000)
3037                                neg = 1;
3038                        DP(NETIF_MSG_LINK, "EEE negotiated - 1G\n");
3039                }
3040        }
3041        if (lp & 0x68) {
3042                lp_adv |= SHMEM_EEE_10G_ADV;
3043                if (adv & 0x68) {
3044                        if (vars->line_speed == SPEED_10000)
3045                                neg = 1;
3046                        DP(NETIF_MSG_LINK, "EEE negotiated - 10G\n");
3047                }
3048        }
3049
3050        vars->eee_status &= ~SHMEM_EEE_LP_ADV_STATUS_MASK;
3051        vars->eee_status |= (lp_adv << SHMEM_EEE_LP_ADV_STATUS_SHIFT);
3052
3053        if (neg) {
3054                DP(NETIF_MSG_LINK, "EEE is active\n");
3055                vars->eee_status |= SHMEM_EEE_ACTIVE_BIT;
3056        }
3057
3058}
3059
3060/******************************************************************/
3061/*                      BSC access functions from E3              */
3062/******************************************************************/
3063static void bnx2x_bsc_module_sel(struct link_params *params)
3064{
3065        int idx;
3066        uint32_t board_cfg, sfp_ctrl;
3067        uint32_t i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH];
3068        struct bnx2x *bp = params->bp;
3069        uint8_t port = params->port;
3070        /* Read I2C output PINs */
3071        board_cfg = REG_RD(bp, params->shmem_base +
3072                           offsetof(struct shmem_region,
3073                                    dev_info.shared_hw_config.board));
3074        i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK;
3075        i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >>
3076                        SHARED_HW_CFG_E3_I2C_MUX1_SHIFT;
3077
3078        /* Read I2C output value */
3079        sfp_ctrl = REG_RD(bp, params->shmem_base +
3080                          offsetof(struct shmem_region,
3081                                 dev_info.port_hw_config[port].e3_cmn_pin_cfg));
3082        i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0;
3083        i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0;
3084        DP(NETIF_MSG_LINK, "Setting BSC switch\n");
3085        for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++)
3086                bnx2x_set_cfg_pin(bp, i2c_pins[idx], i2c_val[idx]);
3087}
3088
3089static int bnx2x_bsc_read(struct link_params *params,
3090                          struct bnx2x *bp,
3091                          uint8_t sl_devid,
3092                          uint16_t sl_addr,
3093                          uint8_t lc_addr,
3094                          uint8_t xfer_cnt,
3095                          uint32_t *data_array)
3096{
3097        uint32_t val, i;
3098        int rc = 0;
3099
3100        if (xfer_cnt > 16) {
3101                DP(NETIF_MSG_LINK, "invalid xfer_cnt %d. Max is 16 bytes\n",
3102                                        xfer_cnt);
3103                return -EINVAL;
3104        }
3105        bnx2x_bsc_module_sel(params);
3106
3107        xfer_cnt = 16 - lc_addr;
3108
3109        /* Enable the engine */
3110        val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3111        val |= MCPR_IMC_COMMAND_ENABLE;
3112        REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3113
3114        /* Program slave device ID */
3115        val = (sl_devid << 16) | sl_addr;
3116        REG_WR(bp, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val);
3117
3118        /* Start xfer with 0 byte to update the address pointer ???*/
3119        val = (MCPR_IMC_COMMAND_ENABLE) |
3120              (MCPR_IMC_COMMAND_WRITE_OP <<
3121                MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3122                (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0);
3123        REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3124
3125        /* Poll for completion */
3126        i = 0;
3127        val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3128        while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3129                udelay(10);
3130                val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3131                if (i++ > 1000) {
3132                        DP(NETIF_MSG_LINK, "wr 0 byte timed out after %d try\n",
3133                                                                i);
3134                        rc = -EFAULT;
3135                        break;
3136                }
3137        }
3138        if (rc == -EFAULT)
3139                return rc;
3140
3141        /* Start xfer with read op */
3142        val = (MCPR_IMC_COMMAND_ENABLE) |
3143                (MCPR_IMC_COMMAND_READ_OP <<
3144                MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3145                (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) |
3146                  (xfer_cnt);
3147        REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3148
3149        /* Poll for completion */
3150        i = 0;
3151        val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3152        while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3153                udelay(10);
3154                val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3155                if (i++ > 1000) {
3156                        DP(NETIF_MSG_LINK, "rd op timed out after %d try\n", i);
3157                        rc = -EFAULT;
3158                        break;
3159                }
3160        }
3161        if (rc == -EFAULT)
3162                return rc;
3163
3164        for (i = (lc_addr >> 2); i < 4; i++) {
3165                data_array[i] = REG_RD(bp, (MCP_REG_MCPR_IMC_DATAREG0 + i*4));
3166#ifdef __BIG_ENDIAN
3167                data_array[i] = ((data_array[i] & 0x000000ff) << 24) |
3168                                ((data_array[i] & 0x0000ff00) << 8) |
3169                                ((data_array[i] & 0x00ff0000) >> 8) |
3170                                ((data_array[i] & 0xff000000) >> 24);
3171#endif
3172        }
3173        return rc;
3174}
3175
3176static void bnx2x_cl45_read_or_write(struct bnx2x *bp, struct bnx2x_phy *phy,
3177                                     uint8_t devad, uint16_t reg,
3178                                     uint16_t or_val)
3179{
3180        uint16_t val;
3181        bnx2x_cl45_read(bp, phy, devad, reg, &val);
3182        bnx2x_cl45_write(bp, phy, devad, reg, val | or_val);
3183}
3184
3185static void bnx2x_cl45_read_and_write(struct bnx2x *bp,
3186                                      struct bnx2x_phy *phy,
3187                                      uint8_t devad, uint16_t reg,
3188                                      uint16_t and_val)
3189{
3190        uint16_t val;
3191        bnx2x_cl45_read(bp, phy, devad, reg, &val);
3192        bnx2x_cl45_write(bp, phy, devad, reg, val & and_val);
3193}
3194
3195int bnx2x_phy_read(struct link_params *params, uint8_t phy_addr,
3196                   uint8_t devad, uint16_t reg, uint16_t *ret_val)
3197{
3198        uint8_t phy_index;
3199        /* Probe for the phy according to the given phy_addr, and execute
3200         * the read request on it
3201         */
3202        for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
3203                if (params->phy[phy_index].addr == phy_addr) {
3204                        return bnx2x_cl45_read(params->bp,
3205                                               &params->phy[phy_index], devad,
3206                                               reg, ret_val);
3207                }
3208        }
3209        return -EINVAL;
3210}
3211
3212int bnx2x_phy_write(struct link_params *params, uint8_t phy_addr,
3213                    uint8_t devad, uint16_t reg, uint16_t val)
3214{
3215        uint8_t phy_index;
3216        /* Probe for the phy according to the given phy_addr, and execute
3217         * the write request on it
3218         */
3219        for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
3220                if (params->phy[phy_index].addr == phy_addr) {
3221                        return bnx2x_cl45_write(params->bp,
3222                                                &params->phy[phy_index], devad,
3223                                                reg, val);
3224                }
3225        }
3226        return -EINVAL;
3227}
3228static uint8_t bnx2x_get_warpcore_lane(struct bnx2x_phy *phy,
3229                                  struct link_params *params)
3230{
3231        uint8_t lane = 0;
3232        struct bnx2x *bp = params->bp;
3233        uint32_t path_swap, path_swap_ovr;
3234        uint8_t path, port;
3235
3236        path = BP_PATH(bp);
3237        port = params->port;
3238
3239        if (bnx2x_is_4_port_mode(bp)) {
3240                uint32_t port_swap, port_swap_ovr;
3241
3242                /* Figure out path swap value */
3243                path_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR);
3244                if (path_swap_ovr & 0x1)
3245                        path_swap = (path_swap_ovr & 0x2);
3246                else
3247                        path_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP);
3248
3249                if (path_swap)
3250                        path = path ^ 1;
3251
3252                /* Figure out port swap value */
3253                port_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR);
3254                if (port_swap_ovr & 0x1)
3255                        port_swap = (port_swap_ovr & 0x2);
3256                else
3257                        port_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP);
3258
3259                if (port_swap)
3260                        port = port ^ 1;
3261
3262                lane = (port<<1) + path;
3263        } else { /* Two port mode - no port swap */
3264
3265                /* Figure out path swap value */
3266                path_swap_ovr =
3267                        REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP_OVWR);
3268                if (path_swap_ovr & 0x1) {
3269                        path_swap = (path_swap_ovr & 0x2);
3270                } else {
3271                        path_swap =
3272                                REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP);
3273                }
3274                if (path_swap)
3275                        path = path ^ 1;
3276
3277                lane = path << 1 ;
3278        }
3279        return lane;
3280}
3281
3282static void bnx2x_set_aer_mmd(struct link_params *params,
3283                              struct bnx2x_phy *phy)
3284{
3285        uint32_t ser_lane;
3286        uint16_t offset, aer_val;
3287        struct bnx2x *bp = params->bp;
3288        ser_lane = ((params->lane_config &
3289                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3290                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3291
3292        offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
3293                (phy->addr + ser_lane) : 0;
3294
3295        if (USES_WARPCORE(bp)) {
3296                aer_val = bnx2x_get_warpcore_lane(phy, params);
3297                /* In Dual-lane mode, two lanes are joined together,
3298                 * so in order to configure them, the AER broadcast method is
3299                 * used here.
3300                 * 0x200 is the broadcast address for lanes 0,1
3301                 * 0x201 is the broadcast address for lanes 2,3
3302                 */
3303                if (phy->flags & FLAGS_WC_DUAL_MODE)
3304                        aer_val = (aer_val >> 1) | 0x200;
3305        } else if (CHIP_IS_E2(bp))
3306                aer_val = 0x3800 + offset - 1;
3307        else
3308                aer_val = 0x3800 + offset;
3309
3310        CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
3311                          MDIO_AER_BLOCK_AER_REG, aer_val);
3312
3313}
3314
3315/******************************************************************/
3316/*                      Internal phy section                      */
3317/******************************************************************/
3318
3319static void bnx2x_set_serdes_access(struct bnx2x *bp, uint8_t port)
3320{
3321        uint32_t emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3322
3323        /* Set Clause 22 */
3324        REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
3325        REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
3326        udelay(500);
3327        REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
3328        udelay(500);
3329         /* Set Clause 45 */
3330        REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
3331}
3332
3333static void bnx2x_serdes_deassert(struct bnx2x *bp, uint8_t port)
3334{
3335        uint32_t val;
3336
3337        DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
3338
3339        val = SERDES_RESET_BITS << (port*16);
3340
3341        /* Reset and unreset the SerDes/XGXS */
3342        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3343        udelay(500);
3344        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3345
3346        bnx2x_set_serdes_access(bp, port);
3347
3348        REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + port*0x10,
3349               DEFAULT_PHY_DEV_ADDR);
3350}
3351
3352static void bnx2x_xgxs_specific_func(struct bnx2x_phy *phy,
3353                                     struct link_params *params,
3354                                     uint32_t action)
3355{
3356        struct bnx2x *bp = params->bp;
3357        switch (action) {
3358        case PHY_INIT:
3359                /* Set correct devad */
3360                REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + params->port*0x18, 0);
3361                REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
3362                       phy->def_md_devad);
3363                break;
3364        }
3365}
3366
3367static void bnx2x_xgxs_deassert(struct link_params *params)
3368{
3369        struct bnx2x *bp = params->bp;
3370        uint8_t port;
3371        uint32_t val;
3372        DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
3373        port = params->port;
3374
3375        val = XGXS_RESET_BITS << (port*16);
3376
3377        /* Reset and unreset the SerDes/XGXS */
3378        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3379        udelay(500);
3380        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3381        bnx2x_xgxs_specific_func(&params->phy[INT_PHY], params,
3382                                 PHY_INIT);
3383}
3384
3385static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
3386                                     struct link_params *params,
3387                                     uint16_t *ieee_fc)
3388{
3389        struct bnx2x *bp = params->bp;
3390        *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
3391        /* Resolve pause mode and advertisement Please refer to Table
3392         * 28B-3 of the 802.3ab-1999 spec
3393         */
3394
3395        switch (phy->req_flow_ctrl) {
3396        case BNX2X_FLOW_CTRL_AUTO:
3397                switch (params->req_fc_auto_adv) {
3398                case BNX2X_FLOW_CTRL_BOTH:
3399                        *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3400                        break;
3401                case BNX2X_FLOW_CTRL_RX:
3402                case BNX2X_FLOW_CTRL_TX:
3403                        *ieee_fc |=
3404                                MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3405                        break;
3406                default:
3407                        break;
3408                }
3409                break;
3410        case BNX2X_FLOW_CTRL_TX:
3411                *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3412                break;
3413
3414        case BNX2X_FLOW_CTRL_RX:
3415        case BNX2X_FLOW_CTRL_BOTH:
3416                *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3417                break;
3418
3419        case BNX2X_FLOW_CTRL_NONE:
3420        default:
3421                *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
3422                break;
3423        }
3424        DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
3425}
3426
3427static void set_phy_vars(struct link_params *params,
3428                         struct link_vars *vars)
3429{
3430        struct bnx2x *bp = params->bp;
3431        uint8_t actual_phy_idx, phy_index, link_cfg_idx;
3432        uint8_t phy_config_swapped = params->multi_phy_config &
3433                        PORT_HW_CFG_PHY_SWAPPED_ENABLED;
3434        for (phy_index = INT_PHY; phy_index < params->num_phys;
3435              phy_index++) {
3436                link_cfg_idx = LINK_CONFIG_IDX(phy_index);
3437                actual_phy_idx = phy_index;
3438                if (phy_config_swapped) {
3439                        if (phy_index == EXT_PHY1)
3440                                actual_phy_idx = EXT_PHY2;
3441                        else if (phy_index == EXT_PHY2)
3442                                actual_phy_idx = EXT_PHY1;
3443                }
3444                params->phy[actual_phy_idx].req_flow_ctrl =
3445                        params->req_flow_ctrl[link_cfg_idx];
3446
3447                params->phy[actual_phy_idx].req_line_speed =
3448                        params->req_line_speed[link_cfg_idx];
3449
3450                params->phy[actual_phy_idx].speed_cap_mask =
3451                        params->speed_cap_mask[link_cfg_idx];
3452
3453                params->phy[actual_phy_idx].req_duplex =
3454                        params->req_duplex[link_cfg_idx];
3455
3456                if (params->req_line_speed[link_cfg_idx] ==
3457                    SPEED_AUTO_NEG)
3458                        vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
3459
3460                DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
3461                           " speed_cap_mask %x\n",
3462                           params->phy[actual_phy_idx].req_flow_ctrl,
3463                           params->phy[actual_phy_idx].req_line_speed,
3464                           params->phy[actual_phy_idx].speed_cap_mask);
3465        }
3466}
3467
3468static void bnx2x_ext_phy_set_pause(struct link_params *params,
3469                                    struct bnx2x_phy *phy,
3470                                    struct link_vars *vars)
3471{
3472        uint16_t val;
3473        struct bnx2x *bp = params->bp;
3474        /* Read modify write pause advertizing */
3475        bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
3476
3477        val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3478
3479        /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3480        bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
3481        if ((vars->ieee_fc &
3482            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3483            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3484                val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3485        }
3486        if ((vars->ieee_fc &
3487            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3488            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3489                val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
3490        }
3491        DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
3492        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
3493}
3494
3495static void bnx2x_pause_resolve(struct link_vars *vars, uint32_t pause_result)
3496{                                               /*  LD      LP   */
3497        switch (pause_result) {                 /* ASYM P ASYM P */
3498        case 0xb:                               /*   1  0   1  1 */
3499                vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
3500                break;
3501
3502        case 0xe:                               /*   1  1   1  0 */
3503                vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
3504                break;
3505
3506        case 0x5:                               /*   0  1   0  1 */
3507        case 0x7:                               /*   0  1   1  1 */
3508        case 0xd:                               /*   1  1   0  1 */
3509        case 0xf:                               /*   1  1   1  1 */
3510                vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
3511                break;
3512
3513        default:
3514                break;
3515        }
3516        if (pause_result & (1<<0))
3517                vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
3518        if (pause_result & (1<<1))
3519                vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
3520
3521}
3522
3523static void bnx2x_ext_phy_update_adv_fc(struct bnx2x_phy *phy,
3524                                        struct link_params *params,
3525                                        struct link_vars *vars)
3526{
3527        uint16_t ld_pause;              /* local */
3528        uint16_t lp_pause;              /* link partner */
3529        uint16_t pause_result;
3530        struct bnx2x *bp = params->bp;
3531        if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) {
3532                bnx2x_cl22_read(bp, phy, 0x4, &ld_pause);
3533                bnx2x_cl22_read(bp, phy, 0x5, &lp_pause);
3534        } else if (CHIP_IS_E3(bp) &&
3535                SINGLE_MEDIA_DIRECT(params)) {
3536                uint8_t lane = bnx2x_get_warpcore_lane(phy, params);
3537                uint16_t gp_status, gp_mask;
3538                bnx2x_cl45_read(bp, phy,
3539                                MDIO_AN_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_4,
3540                                &gp_status);
3541                gp_mask = (MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL |
3542                           MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP) <<
3543                        lane;
3544                if ((gp_status & gp_mask) == gp_mask) {
3545                        bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
3546                                        MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3547                        bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
3548                                        MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3549                } else {
3550                        bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
3551                                        MDIO_AN_REG_CL37_FC_LD, &ld_pause);
3552                        bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
3553                                        MDIO_AN_REG_CL37_FC_LP, &lp_pause);
3554                        ld_pause = ((ld_pause &
3555                                     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
3556                                    << 3);
3557                        lp_pause = ((lp_pause &
3558                                     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
3559                                    << 3);
3560                }
3561        } else {
3562                bnx2x_cl45_read(bp, phy,
3563                                MDIO_AN_DEVAD,
3564                                MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3565                bnx2x_cl45_read(bp, phy,
3566                                MDIO_AN_DEVAD,
3567                                MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3568        }
3569        pause_result = (ld_pause &
3570                        MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
3571        pause_result |= (lp_pause &
3572                         MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
3573        DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n", pause_result);
3574        bnx2x_pause_resolve(vars, pause_result);
3575
3576}
3577
3578static uint8_t bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
3579                                   struct link_params *params,
3580                                   struct link_vars *vars)
3581{
3582        uint8_t ret = 0;
3583        vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3584        if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) {
3585                /* Update the advertised flow-controled of LD/LP in AN */
3586                if (phy->req_line_speed == SPEED_AUTO_NEG)
3587                        bnx2x_ext_phy_update_adv_fc(phy, params, vars);
3588                /* But set the flow-control result as the requested one */
3589                vars->flow_ctrl = phy->req_flow_ctrl;
3590        } else if (phy->req_line_speed != SPEED_AUTO_NEG)
3591                vars->flow_ctrl = params->req_fc_auto_adv;
3592        else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
3593                ret = 1;
3594                bnx2x_ext_phy_update_adv_fc(phy, params, vars);
3595        }
3596        return ret;
3597}
3598/******************************************************************/
3599/*                      Warpcore section                          */
3600/******************************************************************/
3601/* The init_internal_warpcore should mirror the xgxs,
3602 * i.e. reset the lane (if needed), set aer for the
3603 * init configuration, and set/clear SGMII flag. Internal
3604 * phy init is done purely in phy_init stage.
3605 */
3606#define WC_TX_DRIVER(post2, idriver, ipre) \
3607        ((post2 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | \
3608         (idriver << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | \
3609         (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))
3610
3611#define WC_TX_FIR(post, main, pre) \
3612        ((post << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | \
3613         (main << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | \
3614         (pre << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET))
3615
3616static void bnx2x_warpcore_enable_AN_KR2(struct bnx2x_phy *phy,
3617                                         struct link_params *params,
3618                                         struct link_vars *vars)
3619{
3620        struct bnx2x *bp = params->bp;
3621        uint16_t i;
3622        static struct bnx2x_reg_set reg_set[] = {
3623                /* Step 1 - Program the TX/RX alignment markers */
3624                {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL5, 0xa157},
3625                {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL7, 0xcbe2},
3626                {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL6, 0x7537},
3627                {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL9, 0xa157},
3628                {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL11, 0xcbe2},
3629                {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL10, 0x7537},
3630                /* Step 2 - Configure the NP registers */
3631                {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_USERB0_CTRL, 0x000a},
3632                {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL1, 0x6400},
3633                {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL3, 0x0620},
3634                {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CODE_FIELD, 0x0157},
3635                {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI1, 0x6464},
3636                {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI2, 0x3150},
3637                {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI3, 0x3150},
3638                {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_BAM_CODE, 0x0157},
3639                {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_UD_CODE, 0x0620}
3640        };
3641        DP(NETIF_MSG_LINK, "Enabling 20G-KR2\n");
3642
3643        bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3644                                 MDIO_WC_REG_CL49_USERB0_CTRL, (3<<6));
3645
3646        for (i = 0; i < ARRAY_SIZE(reg_set); i++)
3647                bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg,
3648                                 reg_set[i].val);
3649
3650        /* Start KR2 work-around timer which handles BCM8073 link-parner */
3651        params->link_attr_sync |= LINK_ATTR_SYNC_KR2_ENABLE;
3652        bnx2x_update_link_attr(params, params->link_attr_sync);
3653}
3654
3655static void bnx2x_disable_kr2(struct link_params *params,
3656                              struct link_vars *vars,
3657                              struct bnx2x_phy *phy)
3658{
3659        struct bnx2x *bp = params->bp;
3660        int i;
3661        static struct bnx2x_reg_set reg_set[] = {
3662                /* Step 1 - Program the TX/RX alignment markers */
3663                {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL5, 0x7690},
3664                {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL7, 0xe647},
3665                {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL6, 0xc4f0},
3666                {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL9, 0x7690},
3667                {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL11, 0xe647},
3668                {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL10, 0xc4f0},
3669                {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_USERB0_CTRL, 0x000c},
3670                {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL1, 0x6000},
3671                {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL3, 0x0000},
3672                {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CODE_FIELD, 0x0002},
3673                {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI1, 0x0000},
3674                {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI2, 0x0af7},
3675                {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI3, 0x0af7},
3676                {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_BAM_CODE, 0x0002},
3677                {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_UD_CODE, 0x0000}
3678        };
3679        DP(NETIF_MSG_LINK, "Disabling 20G-KR2\n");
3680
3681        for (i = 0; i < ARRAY_SIZE(reg_set); i++)
3682                bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg,
3683                                 reg_set[i].val);
3684        params->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE;
3685        bnx2x_update_link_attr(params, params->link_attr_sync);
3686
3687        vars->check_kr2_recovery_cnt = CHECK_KR2_RECOVERY_CNT;
3688}
3689
3690static void bnx2x_warpcore_set_lpi_passthrough(struct bnx2x_phy *phy,
3691                                               struct link_params *params)
3692{
3693        struct bnx2x *bp = params->bp;
3694
3695        DP(NETIF_MSG_LINK, "Configure WC for LPI pass through\n");
3696        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3697                         MDIO_WC_REG_EEE_COMBO_CONTROL0, 0x7c);
3698        bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3699                                 MDIO_WC_REG_DIGITAL4_MISC5, 0xc000);
3700}
3701
3702static void bnx2x_warpcore_restart_AN_KR(struct bnx2x_phy *phy,
3703                                         struct link_params *params)
3704{
3705        /* Restart autoneg on the leading lane only */
3706        struct bnx2x *bp = params->bp;
3707        uint16_t lane = bnx2x_get_warpcore_lane(phy, params);
3708        CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
3709                          MDIO_AER_BLOCK_AER_REG, lane);
3710        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3711                         MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
3712
3713        /* Restore AER */
3714        bnx2x_set_aer_mmd(params, phy);
3715}
3716
3717static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
3718                                        struct link_params *params,
3719                                        struct link_vars *vars) {
3720        uint16_t lane, i, cl72_ctrl, an_adv = 0, val;
3721        uint32_t wc_lane_config;
3722        struct bnx2x *bp = params->bp;
3723        static struct bnx2x_reg_set reg_set[] = {
3724                {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
3725                {MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0},
3726                {MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415},
3727                {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190},
3728                /* Disable Autoneg: re-enable it after adv is done. */
3729                {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0},
3730                {MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_KR_CONTROL, 0x2},
3731                {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP, 0},
3732        };
3733        DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n");
3734        /* Set to default registers that may be overriden by 10G force */
3735        for (i = 0; i < ARRAY_SIZE(reg_set); i++)
3736                bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg,
3737                                 reg_set[i].val);
3738
3739        bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3740                        MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &cl72_ctrl);
3741        cl72_ctrl &= 0x08ff;
3742        cl72_ctrl |= 0x3800;
3743        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3744                         MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, cl72_ctrl);
3745
3746        /* Check adding advertisement for 1G KX */
3747        if (((vars->line_speed == SPEED_AUTO_NEG) &&
3748             (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
3749            (vars->line_speed == SPEED_1000)) {
3750                uint16_t addr = MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2;
3751                an_adv |= (1<<5);
3752
3753                /* Enable CL37 1G Parallel Detect */
3754                bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, addr, 0x1);
3755                DP(NETIF_MSG_LINK, "Advertize 1G\n");
3756        }
3757        if (((vars->line_speed == SPEED_AUTO_NEG) &&
3758             (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
3759            (vars->line_speed ==  SPEED_10000)) {
3760                /* Check adding advertisement for 10G KR */
3761                an_adv |= (1<<7);
3762                /* Enable 10G Parallel Detect */
3763                CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
3764                                  MDIO_AER_BLOCK_AER_REG, 0);
3765
3766                bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3767                                 MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
3768                bnx2x_set_aer_mmd(params, phy);
3769                DP(NETIF_MSG_LINK, "Advertize 10G\n");
3770        }
3771
3772        /* Set Transmit PMD settings */
3773        lane = bnx2x_get_warpcore_lane(phy, params);
3774        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3775                         MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3776                         WC_TX_DRIVER(0x02, 0x06, 0x09));
3777        /* Configure the next lane if dual mode */
3778        if (phy->flags & FLAGS_WC_DUAL_MODE)
3779                bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3780                                 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*(lane+1),
3781                                 WC_TX_DRIVER(0x02, 0x06, 0x09));
3782        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3783                         MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
3784                         0x03f0);
3785        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3786                         MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL,
3787                         0x03f0);
3788
3789        /* Advertised speeds */
3790        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3791                         MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, an_adv);
3792
3793        /* Advertised and set FEC (Forward Error Correction) */
3794        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3795                         MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2,
3796                         (MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY |
3797                          MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ));
3798
3799        /* Enable CL37 BAM */
3800        if (REG_RD(bp, params->shmem_base +
3801                   offsetof(struct shmem_region, dev_info.
3802                            port_hw_config[params->port].default_cfg)) &
3803            PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
3804                bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3805                                         MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL,
3806                                         1);
3807                DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
3808        }
3809
3810        /* Advertise pause */
3811        bnx2x_ext_phy_set_pause(params, phy, vars);
3812        vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
3813        bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3814                                 MDIO_WC_REG_DIGITAL5_MISC7, 0x100);
3815
3816        /* Over 1G - AN local device user page 1 */
3817        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3818                        MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
3819
3820        if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
3821             (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)) ||
3822            (phy->req_line_speed == SPEED_20000)) {
3823
3824                CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
3825                                  MDIO_AER_BLOCK_AER_REG, lane);
3826
3827                bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3828                                         MDIO_WC_REG_RX1_PCI_CTRL + (0x10*lane),
3829                                         (1<<11));
3830
3831                bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3832                                 MDIO_WC_REG_XGXS_X2_CONTROL3, 0x7);
3833                bnx2x_set_aer_mmd(params, phy);
3834
3835                bnx2x_warpcore_enable_AN_KR2(phy, params, vars);
3836        } else {
3837                /* Enable Auto-Detect to support 1G over CL37 as well */
3838                bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3839                                 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x10);
3840                wc_lane_config = REG_RD(bp, params->shmem_base +
3841                                        offsetof(struct shmem_region, dev_info.
3842                                        shared_hw_config.wc_lane_config));
3843                bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3844                                MDIO_WC_REG_RX0_PCI_CTRL + (lane << 4), &val);
3845                /* Force cl48 sync_status LOW to avoid getting stuck in CL73
3846                 * parallel-detect loop when CL73 and CL37 are enabled.
3847                 */
3848                val |= 1 << 11;
3849
3850                /* Restore Polarity settings in case it was run over by
3851                 * previous link owner
3852                 */
3853                if (wc_lane_config &
3854                    (SHARED_HW_CFG_RX_LANE0_POL_FLIP_ENABLED << lane))
3855                        val |= 3 << 2;
3856                else
3857                        val &= ~(3 << 2);
3858                bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3859                                 MDIO_WC_REG_RX0_PCI_CTRL + (lane << 4),
3860                                 val);
3861
3862                bnx2x_disable_kr2(params, vars, phy);
3863        }
3864
3865        /* Enable Autoneg: only on the main lane */
3866        bnx2x_warpcore_restart_AN_KR(phy, params);
3867}
3868
3869static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy,
3870                                      struct link_params *params,
3871                                      struct link_vars *vars)
3872{
3873        struct bnx2x *bp = params->bp;
3874        uint16_t val16, i, lane;
3875        static struct bnx2x_reg_set reg_set[] = {
3876                /* Disable Autoneg */
3877                {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
3878                {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3879                        0x3f00},
3880                {MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0},
3881                {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0},
3882                {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1},
3883                {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa},
3884                /* Leave cl72 training enable, needed for KR */
3885                {MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_KR_CONTROL, 0x2}
3886        };
3887
3888        for (i = 0; i < ARRAY_SIZE(reg_set); i++)
3889                bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg,
3890                                 reg_set[i].val);
3891
3892        lane = bnx2x_get_warpcore_lane(phy, params);
3893        /* Global registers */
3894        CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
3895                          MDIO_AER_BLOCK_AER_REG, 0);
3896        /* Disable CL36 PCS Tx */
3897        bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3898                        MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
3899        val16 &= ~(0x0011 << lane);
3900        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3901                         MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
3902
3903        bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3904                        MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
3905        val16 |= (0x0303 << (lane << 1));
3906        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3907                         MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
3908        /* Restore AER */
3909        bnx2x_set_aer_mmd(params, phy);
3910        /* Set speed via PMA/PMD register */
3911        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3912                         MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
3913
3914        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3915                         MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
3916
3917        /* Enable encoded forced speed */
3918        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3919                         MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
3920
3921        /* Turn TX scramble payload only the 64/66 scrambler */
3922        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3923                         MDIO_WC_REG_TX66_CONTROL, 0x9);
3924
3925        /* Turn RX scramble payload only the 64/66 scrambler */
3926        bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3927                                 MDIO_WC_REG_RX66_CONTROL, 0xF9);
3928
3929        /* Set and clear loopback to cause a reset to 64/66 decoder */
3930        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3931                         MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000);
3932        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3933                         MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
3934
3935}
3936
3937static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
3938                                       struct link_params *params,
3939                                       uint8_t is_xfi)
3940{
3941        struct bnx2x *bp = params->bp;
3942        uint16_t misc1_val, tap_val, tx_driver_val, lane, val;
3943        uint32_t cfg_tap_val, tx_drv_brdct, tx_equal;
3944
3945        /* Hold rxSeqStart */
3946        bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3947                                 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x8000);
3948
3949        /* Hold tx_fifo_reset */
3950        bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3951                                 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x1);
3952
3953        /* Disable CL73 AN */
3954        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
3955
3956        /* Disable 100FX Enable and Auto-Detect */
3957        bnx2x_cl45_read_and_write(bp, phy, MDIO_WC_DEVAD,
3958                                  MDIO_WC_REG_FX100_CTRL1, 0xFFFA);
3959
3960        /* Disable 100FX Idle detect */
3961        bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3962                                 MDIO_WC_REG_FX100_CTRL3, 0x0080);
3963
3964        /* Set Block address to Remote PHY & Clear forced_speed[5] */
3965        bnx2x_cl45_read_and_write(bp, phy, MDIO_WC_DEVAD,
3966                                  MDIO_WC_REG_DIGITAL4_MISC3, 0xFF7F);
3967
3968        /* Turn off auto-detect & fiber mode */
3969        bnx2x_cl45_read_and_write(bp, phy, MDIO_WC_DEVAD,
3970                                  MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3971                                  0xFFEE);
3972
3973        /* Set filter_force_link, disable_false_link and parallel_detect */
3974        bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3975                        MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val);
3976        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3977                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3978                         ((val | 0x0006) & 0xFFFE));
3979
3980        /* Set XFI / SFI */
3981        bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3982                        MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val);
3983
3984        misc1_val &= ~(0x1f);
3985
3986        if (is_xfi) {
3987                misc1_val |= 0x5;
3988                tap_val = WC_TX_FIR(0x08, 0x37, 0x00);
3989                tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03);
3990        } else {
3991                cfg_tap_val = REG_RD(bp, params->shmem_base +
3992                                     offsetof(struct shmem_region, dev_info.
3993                                              port_hw_config[params->port].
3994                                              sfi_tap_values));
3995
3996                tx_equal = cfg_tap_val & PORT_HW_CFG_TX_EQUALIZATION_MASK;
3997
3998                tx_drv_brdct = (cfg_tap_val &
3999                                PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >>
4000                               PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT;
4001
4002                misc1_val |= 0x9;
4003
4004                /* TAP values are controlled by nvram, if value there isn't 0 */
4005                if (tx_equal)
4006                        tap_val = (uint16_t)tx_equal;
4007                else
4008                        tap_val = WC_TX_FIR(0x0f, 0x2b, 0x02);
4009
4010                if (tx_drv_brdct)
4011                        tx_driver_val = WC_TX_DRIVER(0x03,
4012                                                     (uint16_t)tx_drv_brdct,
4013                                                     0x06);
4014                else
4015                        tx_driver_val = WC_TX_DRIVER(0x03, 0x02, 0x06);
4016        }
4017        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4018                         MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
4019
4020        /* Set Transmit PMD settings */
4021        lane = bnx2x_get_warpcore_lane(phy, params);
4022        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4023                         MDIO_WC_REG_TX_FIR_TAP,
4024                         tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE);
4025        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4026                         MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
4027                         tx_driver_val);
4028
4029        /* Enable fiber mode, enable and invert sig_det */
4030        bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
4031                                 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0xd);
4032
4033        /* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
4034        bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
4035                                 MDIO_WC_REG_DIGITAL4_MISC3, 0x8080);
4036
4037        bnx2x_warpcore_set_lpi_passthrough(phy, params);
4038
4039        /* 10G XFI Full Duplex */
4040        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4041                         MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
4042
4043        /* Release tx_fifo_reset */
4044        bnx2x_cl45_read_and_write(bp, phy, MDIO_WC_DEVAD,
4045                                  MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3,
4046                                  0xFFFE);
4047        /* Release rxSeqStart */
4048        bnx2x_cl45_read_and_write(bp, phy, MDIO_WC_DEVAD,
4049                                  MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x7FFF);
4050}
4051
4052static void bnx2x_warpcore_set_20G_force_KR2(struct bnx2x_phy *phy,
4053                                             struct link_params *params)
4054{
4055        uint16_t val;
4056        struct bnx2x *bp = params->bp;
4057        /* Set global registers, so set AER lane to 0 */
4058        CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4059                          MDIO_AER_BLOCK_AER_REG, 0);
4060
4061        /* Disable sequencer */
4062        bnx2x_cl45_read_and_write(bp, phy, MDIO_WC_DEVAD,
4063                                  MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, ~(1<<13));
4064
4065        bnx2x_set_aer_mmd(params, phy);
4066
4067        bnx2x_cl45_read_and_write(bp, phy, MDIO_PMA_DEVAD,
4068                                  MDIO_WC_REG_PMD_KR_CONTROL, ~(1<<1));
4069        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
4070                         MDIO_AN_REG_CTRL, 0);
4071        /* Turn off CL73 */
4072        bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4073                        MDIO_WC_REG_CL73_USERB0_CTRL, &val);
4074        val &= ~(1<<5);
4075        val |= (1<<6);
4076        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4077                         MDIO_WC_REG_CL73_USERB0_CTRL, val);
4078
4079        /* Set 20G KR2 force speed */
4080        bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
4081                                 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x1f);
4082
4083        bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
4084                                 MDIO_WC_REG_DIGITAL4_MISC3, (1<<7));
4085
4086        bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4087                        MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &val);
4088        val &= ~(3<<14);
4089        val |= (1<<15);
4090        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4091                         MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, val);
4092        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4093                         MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP, 0x835A);
4094
4095        /* Enable sequencer (over lane 0) */
4096        CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4097                          MDIO_AER_BLOCK_AER_REG, 0);
4098
4099        bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
4100                                 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, (1<<13));
4101
4102        bnx2x_set_aer_mmd(params, phy);
4103}
4104
4105static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp,
4106                                         struct bnx2x_phy *phy,
4107                                         uint16_t lane)
4108{
4109        /* Rx0 anaRxControl1G */
4110        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4111                         MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90);
4112
4113        /* Rx2 anaRxControl1G */
4114        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4115                         MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90);
4116
4117        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4118                         MDIO_WC_REG_RX66_SCW0, 0xE070);
4119
4120        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4121                         MDIO_WC_REG_RX66_SCW1, 0xC0D0);
4122
4123        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4124                         MDIO_WC_REG_RX66_SCW2, 0xA0B0);
4125
4126        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4127                         MDIO_WC_REG_RX66_SCW3, 0x8090);
4128
4129        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4130                         MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0);
4131
4132        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4133                         MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0);
4134
4135        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4136                         MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0);
4137
4138        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4139                         MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0);
4140
4141        /* Serdes Digital Misc1 */
4142        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4143                         MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008);
4144
4145        /* Serdes Digital4 Misc3 */
4146        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4147                         MDIO_WC_REG_DIGITAL4_MISC3, 0x8088);
4148
4149        /* Set Transmit PMD settings */
4150        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4151                         MDIO_WC_REG_TX_FIR_TAP,
4152                         (WC_TX_FIR(0x12, 0x2d, 0x00) |
4153                          MDIO_WC_REG_TX_FIR_TAP_ENABLE));
4154        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4155                         MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
4156                         WC_TX_DRIVER(0x02, 0x02, 0x02));
4157}
4158
4159static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
4160                                           struct link_params *params,
4161                                           uint8_t fiber_mode,
4162                                           uint8_t always_autoneg)
4163{
4164        struct bnx2x *bp = params->bp;
4165        uint16_t val16, digctrl_kx1, digctrl_kx2;
4166
4167        /* Clear XFI clock comp in non-10G single lane mode. */
4168        bnx2x_cl45_read_and_write(bp, phy, MDIO_WC_DEVAD,
4169                                  MDIO_WC_REG_RX66_CONTROL, ~(3<<13));
4170
4171        bnx2x_warpcore_set_lpi_passthrough(phy, params);
4172
4173        if (always_autoneg || phy->req_line_speed == SPEED_AUTO_NEG) {
4174                /* SGMII Autoneg */
4175                bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
4176                                         MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
4177                                         0x1000);
4178                DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n");
4179        } else {
4180                bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4181                                MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4182                val16 &= 0xcebf;
4183                switch (phy->req_line_speed) {
4184                case SPEED_10:
4185                        break;
4186                case SPEED_100:
4187                        val16 |= 0x2000;
4188                        break;
4189                case SPEED_1000:
4190                        val16 |= 0x0040;
4191                        break;
4192                default:
4193                        DP(NETIF_MSG_LINK,
4194                           "Speed not supported: 0x%x\n", phy->req_line_speed);
4195                        return;
4196                }
4197
4198                if (phy->req_duplex == DUPLEX_FULL)
4199                        val16 |= 0x0100;
4200
4201                bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4202                                MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16);
4203
4204                DP(NETIF_MSG_LINK, "set SGMII force speed %d\n",
4205                               phy->req_line_speed);
4206                bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4207                                MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4208                DP(NETIF_MSG_LINK, "  (readback) %x\n", val16);
4209        }
4210
4211        /* SGMII Slave mode and disable signal detect */
4212        bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4213                        MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1);
4214        if (fiber_mode)
4215                digctrl_kx1 = 1;
4216        else
4217                digctrl_kx1 &= 0xff4a;
4218
4219        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4220                        MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4221                        digctrl_kx1);
4222
4223        /* Turn off parallel detect */
4224        bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4225                        MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2);
4226        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4227                        MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4228                        (digctrl_kx2 & ~(1<<2)));
4229
4230        /* Re-enable parallel detect */
4231        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4232                        MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4233                        (digctrl_kx2 | (1<<2)));
4234
4235        /* Enable autodet */
4236        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4237                        MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4238                        (digctrl_kx1 | 0x10));
4239}
4240
4241static void bnx2x_warpcore_reset_lane(struct bnx2x *bp,
4242                                      struct bnx2x_phy *phy,
4243                                      uint8_t reset)
4244{
4245        uint16_t val;
4246        /* Take lane out of reset after configuration is finished */
4247        bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4248                        MDIO_WC_REG_DIGITAL5_MISC6, &val);
4249        if (reset)
4250                val |= 0xC000;
4251        else
4252                val &= 0x3FFF;
4253        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4254                         MDIO_WC_REG_DIGITAL5_MISC6, val);
4255        bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4256                         MDIO_WC_REG_DIGITAL5_MISC6, &val);
4257}
4258/* Clear SFI/XFI link settings registers */
4259static void bnx2x_warpcore_clear_regs(struct bnx2x_phy *phy,
4260                                      struct link_params *params,
4261                                      uint16_t lane)
4262{
4263        struct bnx2x *bp = params->bp;
4264        uint16_t i;
4265        static struct bnx2x_reg_set wc_regs[] = {
4266                {MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0},
4267                {MDIO_WC_DEVAD, MDIO_WC_REG_FX100_CTRL1, 0x014a},
4268                {MDIO_WC_DEVAD, MDIO_WC_REG_FX100_CTRL3, 0x0800},
4269                {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL4_MISC3, 0x8008},
4270                {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4271                        0x0195},
4272                {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4273                        0x0007},
4274                {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3,
4275                        0x0002},
4276                {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000},
4277                {MDIO_WC_DEVAD, MDIO_WC_REG_TX_FIR_TAP, 0x0000},
4278                {MDIO_WC_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040},
4279                {MDIO_WC_DEVAD, MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140}
4280        };
4281        /* Set XFI clock comp as default. */
4282        bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
4283                                 MDIO_WC_REG_RX66_CONTROL, (3<<13));
4284
4285        for (i = 0; i < ARRAY_SIZE(wc_regs); i++)
4286                bnx2x_cl45_write(bp, phy, wc_regs[i].devad, wc_regs[i].reg,
4287                                 wc_regs[i].val);
4288
4289        lane = bnx2x_get_warpcore_lane(phy, params);
4290        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4291                         MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990);
4292
4293}
4294
4295static int bnx2x_get_mod_abs_int_cfg(struct bnx2x *bp,
4296                                                uint32_t chip_id,
4297                                                uint32_t shmem_base,
4298                                     uint8_t port,
4299                                                uint8_t *gpio_num,
4300                                     uint8_t *gpio_port)
4301{
4302        uint32_t cfg_pin;
4303        *gpio_num = 0;
4304        *gpio_port = 0;
4305        if (CHIP_IS_E3(bp)) {
4306                cfg_pin = (REG_RD(bp, shmem_base +
4307                                offsetof(struct shmem_region,
4308                                dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4309                                PORT_HW_CFG_E3_MOD_ABS_MASK) >>
4310                                PORT_HW_CFG_E3_MOD_ABS_SHIFT;
4311
4312                /* Should not happen. This function called upon interrupt
4313                 * triggered by GPIO ( since EPIO can only generate interrupts
4314                 * to MCP).
4315                 * So if this function was called and none of the GPIOs was set,
4316                 * it means the shit hit the fan.
4317                 */
4318                if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
4319                    (cfg_pin > PIN_CFG_GPIO3_P1)) {
4320                        DP(NETIF_MSG_LINK,
4321                           "No cfg pin %x for module detect indication\n",
4322                           cfg_pin);
4323                        return -EINVAL;
4324                }
4325
4326                *gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
4327                *gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
4328        } else {
4329                *gpio_num = MISC_REGISTERS_GPIO_3;
4330                *gpio_port = port;
4331        }
4332
4333        return 0;
4334}
4335
4336static int bnx2x_is_sfp_module_plugged(struct bnx2x_phy *phy,
4337                                       struct link_params *params)
4338{
4339        struct bnx2x *bp = params->bp;
4340        uint8_t gpio_num, gpio_port;
4341        uint32_t gpio_val;
4342        if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id,
4343                                      params->shmem_base, params->port,
4344                                      &gpio_num, &gpio_port) != 0)
4345                return 0;
4346        gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
4347
4348        /* Call the handling function in case module is detected */
4349        if (gpio_val == 0)
4350                return 1;
4351        else
4352                return 0;
4353}
4354static int bnx2x_warpcore_get_sigdet(struct bnx2x_phy *phy,
4355                                     struct link_params *params)
4356{
4357        uint16_t gp2_status_reg0, lane;
4358        struct bnx2x *bp = params->bp;
4359
4360        lane = bnx2x_get_warpcore_lane(phy, params);
4361
4362        bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_0,
4363                                 &gp2_status_reg0);
4364
4365        return (gp2_status_reg0 >> (8+lane)) & 0x1;
4366}
4367
4368static void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy,
4369                                          struct link_params *params,
4370                                          struct link_vars *vars)
4371{
4372        struct bnx2x *bp = params->bp;
4373        uint32_t serdes_net_if;
4374        uint16_t gp_status1 = 0, lnkup = 0, lnkup_kr = 0;
4375
4376        vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1;
4377
4378        if (!vars->turn_to_run_wc_rt)
4379                return;
4380
4381        if (vars->rx_tx_asic_rst) {
4382                uint16_t lane = bnx2x_get_warpcore_lane(phy, params);
4383                serdes_net_if = (REG_RD(bp, params->shmem_base +
4384                                offsetof(struct shmem_region, dev_info.
4385                                port_hw_config[params->port].default_cfg)) &
4386                                PORT_HW_CFG_NET_SERDES_IF_MASK);
4387
4388                switch (serdes_net_if) {
4389                case PORT_HW_CFG_NET_SERDES_IF_KR:
4390                        /* Do we get link yet? */
4391                        bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 0x81d1,
4392                                        &gp_status1);
4393                        lnkup = (gp_status1 >> (8+lane)) & 0x1;/* 1G */
4394                                /*10G KR*/
4395                        lnkup_kr = (gp_status1 >> (12+lane)) & 0x1;
4396
4397                        if (lnkup_kr || lnkup) {
4398                                vars->rx_tx_asic_rst = 0;
4399                        } else {
4400                                /* Reset the lane to see if link comes up.*/
4401                                bnx2x_warpcore_reset_lane(bp, phy, 1);
4402                                bnx2x_warpcore_reset_lane(bp, phy, 0);
4403
4404                                /* Restart Autoneg */
4405                                bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
4406                                        MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
4407
4408                                vars->rx_tx_asic_rst--;
4409                                DP(NETIF_MSG_LINK, "0x%x retry left\n",
4410                                vars->rx_tx_asic_rst);
4411                        }
4412                        break;
4413
4414                default:
4415                        break;
4416                }
4417
4418        } /*params->rx_tx_asic_rst*/
4419
4420}
4421static void bnx2x_warpcore_config_sfi(struct bnx2x_phy *phy,
4422                                      struct link_params *params)
4423{
4424        uint16_t lane = bnx2x_get_warpcore_lane(phy, params);
4425        struct bnx2x *bp = params->bp;
4426        bnx2x_warpcore_clear_regs(phy, params, lane);
4427        if ((params->req_line_speed[LINK_CONFIG_IDX(INT_PHY)] ==
4428             SPEED_10000) &&
4429            (phy->media_type != ETH_PHY_SFP_1G_FIBER)) {
4430                DP(NETIF_MSG_LINK, "Setting 10G SFI\n");
4431                bnx2x_warpcore_set_10G_XFI(phy, params, 0);
4432        } else {
4433                DP(NETIF_MSG_LINK, "Setting 1G Fiber\n");
4434                bnx2x_warpcore_set_sgmii_speed(phy, params, 1, 0);
4435        }
4436}
4437
4438static void bnx2x_sfp_e3_set_transmitter(struct link_params *params,
4439                                         struct bnx2x_phy *phy,
4440                                         uint8_t tx_en)
4441{
4442        struct bnx2x *bp = params->bp;
4443        uint32_t cfg_pin;
4444        uint8_t port = params->port;
4445
4446        cfg_pin = REG_RD(bp, params->shmem_base +
4447                         offsetof(struct shmem_region,
4448                                  dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4449                PORT_HW_CFG_E3_TX_LASER_MASK;
4450        /* Set the !tx_en since this pin is DISABLE_TX_LASER */
4451        DP(NETIF_MSG_LINK, "Setting WC TX to %d\n", tx_en);
4452
4453        /* For 20G, the expected pin to be used is 3 pins after the current */
4454        bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1);
4455        if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
4456                bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1);
4457}
4458
4459static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
4460                                       struct link_params *params,
4461                                       struct link_vars *vars)
4462{
4463        struct bnx2x *bp = params->bp;
4464        uint32_t serdes_net_if;
4465        uint8_t fiber_mode;
4466        uint16_t lane = bnx2x_get_warpcore_lane(phy, params);
4467        serdes_net_if = (REG_RD(bp, params->shmem_base +
4468                         offsetof(struct shmem_region, dev_info.
4469                                  port_hw_config[params->port].default_cfg)) &
4470                         PORT_HW_CFG_NET_SERDES_IF_MASK);
4471        DP(NETIF_MSG_LINK, "Begin Warpcore init, link_speed %d, "
4472                           "serdes_net_if = 0x%x\n",
4473                       vars->line_speed, serdes_net_if);
4474        bnx2x_set_aer_mmd(params, phy);
4475        bnx2x_warpcore_reset_lane(bp, phy, 1);
4476        vars->phy_flags |= PHY_XGXS_FLAG;
4477        if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
4478            (phy->req_line_speed &&
4479             ((phy->req_line_speed == SPEED_100) ||
4480              (phy->req_line_speed == SPEED_10)))) {
4481                vars->phy_flags |= PHY_SGMII_FLAG;
4482                DP(NETIF_MSG_LINK, "Setting SGMII mode\n");
4483                bnx2x_warpcore_clear_regs(phy, params, lane);
4484                bnx2x_warpcore_set_sgmii_speed(phy, params, 0, 1);
4485        } else {
4486                switch (serdes_net_if) {
4487                case PORT_HW_CFG_NET_SERDES_IF_KR:
4488                        /* Enable KR Auto Neg */
4489                        if (params->loopback_mode != LOOPBACK_EXT)
4490                                bnx2x_warpcore_enable_AN_KR(phy, params, vars);
4491                        else {
4492                                DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n");
4493                                bnx2x_warpcore_set_10G_KR(phy, params, vars);
4494                        }
4495                        break;
4496
4497                case PORT_HW_CFG_NET_SERDES_IF_XFI:
4498                        bnx2x_warpcore_clear_regs(phy, params, lane);
4499                        if (vars->line_speed == SPEED_10000) {
4500                                DP(NETIF_MSG_LINK, "Setting 10G XFI\n");
4501                                bnx2x_warpcore_set_10G_XFI(phy, params, 1);
4502                        } else {
4503                                if (SINGLE_MEDIA_DIRECT(params)) {
4504                                        DP(NETIF_MSG_LINK, "1G Fiber\n");
4505                                        fiber_mode = 1;
4506                                } else {
4507                                        DP(NETIF_MSG_LINK, "10/100/1G SGMII\n");
4508                                        fiber_mode = 0;
4509                                }
4510                                bnx2x_warpcore_set_sgmii_speed(phy,
4511                                                                params,
4512                                                                fiber_mode,
4513                                                                0);
4514                        }
4515
4516                        break;
4517
4518                case PORT_HW_CFG_NET_SERDES_IF_SFI:
4519                        /* Issue Module detection if module is plugged, or
4520                         * enabled transmitter to avoid current leakage in case
4521                         * no module is connected
4522                         */
4523                        if ((params->loopback_mode == LOOPBACK_NONE) ||
4524                            (params->loopback_mode == LOOPBACK_EXT)) {
4525                                if (bnx2x_is_sfp_module_plugged(phy, params))
4526                                        bnx2x_sfp_module_detection(phy, params);
4527                                else
4528                                        bnx2x_sfp_e3_set_transmitter(params,
4529                                                                     phy, 1);
4530                        }
4531
4532                        bnx2x_warpcore_config_sfi(phy, params);
4533                        break;
4534
4535                case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
4536                        if (vars->line_speed != SPEED_20000) {
4537                                DP(NETIF_MSG_LINK, "Speed not supported yet\n");
4538                                return;
4539                        }
4540                        DP(NETIF_MSG_LINK, "Setting 20G DXGXS\n");
4541                        bnx2x_warpcore_set_20G_DXGXS(bp, phy, lane);
4542                        /* Issue Module detection */
4543
4544                        bnx2x_sfp_module_detection(phy, params);
4545                        break;
4546                case PORT_HW_CFG_NET_SERDES_IF_KR2:
4547                        if (!params->loopback_mode) {
4548                                bnx2x_warpcore_enable_AN_KR(phy, params, vars);
4549                        } else {
4550                                DP(NETIF_MSG_LINK, "Setting KR 20G-Force\n");
4551                                bnx2x_warpcore_set_20G_force_KR2(phy, params);
4552                        }
4553                        break;
4554                default:
4555                        DP(NETIF_MSG_LINK,
4556                           "Unsupported Serdes Net Interface 0x%x\n",
4557                           serdes_net_if);
4558                        return;
4559                }
4560        }
4561
4562        /* Take lane out of reset after configuration is finished */
4563        bnx2x_warpcore_reset_lane(bp, phy, 0);
4564        DP(NETIF_MSG_LINK, "Exit config init\n");
4565}
4566
4567static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy,
4568                                      struct link_params *params)
4569{
4570        struct bnx2x *bp = params->bp;
4571        uint16_t val16, lane;
4572        bnx2x_sfp_e3_set_transmitter(params, phy, 0);
4573        bnx2x_set_mdio_emac_per_phy(bp, params);
4574        bnx2x_set_aer_mmd(params, phy);
4575        /* Global register */
4576        bnx2x_warpcore_reset_lane(bp, phy, 1);
4577
4578        /* Clear loopback settings (if any) */
4579        /* 10G & 20G */
4580        bnx2x_cl45_read_and_write(bp, phy, MDIO_WC_DEVAD,
4581                                  MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0xBFFF);
4582
4583        bnx2x_cl45_read_and_write(bp, phy, MDIO_WC_DEVAD,
4584                                  MDIO_WC_REG_IEEE0BLK_MIICNTL, 0xfffe);
4585
4586        /* Update those 1-copy registers */
4587        CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4588                          MDIO_AER_BLOCK_AER_REG, 0);
4589        /* Enable 1G MDIO (1-copy) */
4590        bnx2x_cl45_read_and_write(bp, phy, MDIO_WC_DEVAD,
4591                                  MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4592                                  ~0x10);
4593
4594        bnx2x_cl45_read_and_write(bp, phy, MDIO_WC_DEVAD,
4595                                  MDIO_WC_REG_XGXSBLK1_LANECTRL2, 0xff00);
4596        lane = bnx2x_get_warpcore_lane(phy, params);
4597        /* Disable CL36 PCS Tx */
4598        bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4599                        MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
4600        val16 |= (0x11 << lane);
4601        if (phy->flags & FLAGS_WC_DUAL_MODE)
4602                val16 |= (0x22 << lane);
4603        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4604                         MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
4605
4606        bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4607                        MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
4608        val16 &= ~(0x0303 << (lane << 1));
4609        val16 |= (0x0101 << (lane << 1));
4610        if (phy->flags & FLAGS_WC_DUAL_MODE) {
4611                val16 &= ~(0x0c0c << (lane << 1));
4612                val16 |= (0x0404 << (lane << 1));
4613        }
4614
4615        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4616                         MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
4617        /* Restore AER */
4618        bnx2x_set_aer_mmd(params, phy);
4619
4620}
4621
4622static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy,
4623                                        struct link_params *params)
4624{
4625        struct bnx2x *bp = params->bp;
4626        uint16_t val16;
4627        uint32_t lane;
4628        DP(NETIF_MSG_LINK, "Setting Warpcore loopback type %x, speed %d\n",
4629                       params->loopback_mode, phy->req_line_speed);
4630
4631        if (phy->req_line_speed < SPEED_10000 ||
4632            phy->supported & SUPPORTED_20000baseKR2_Full) {
4633                /* 10/100/1000/20G-KR2 */
4634
4635                /* Update those 1-copy registers */
4636                CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4637                                  MDIO_AER_BLOCK_AER_REG, 0);
4638                /* Enable 1G MDIO (1-copy) */
4639                bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
4640                                         MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4641                                         0x10);
4642                /* Set 1G loopback based on lane (1-copy) */
4643                lane = bnx2x_get_warpcore_lane(phy, params);
4644                bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4645                                MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
4646                val16 |= (1<<lane);
4647                if (phy->flags & FLAGS_WC_DUAL_MODE)
4648                        val16 |= (2<<lane);
4649                bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4650                                 MDIO_WC_REG_XGXSBLK1_LANECTRL2,
4651                                 val16);
4652
4653                /* Switch back to 4-copy registers */
4654                bnx2x_set_aer_mmd(params, phy);
4655        } else {
4656                /* 10G / 20G-DXGXS */
4657                bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
4658                                         MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
4659                                         0x4000);
4660                bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
4661                                         MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1);
4662        }
4663}
4664
4665
4666
4667static void bnx2x_sync_link(struct link_params *params,
4668                             struct link_vars *vars)
4669{
4670        struct bnx2x *bp = params->bp;
4671        uint8_t link_10g_plus;
4672        if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4673                vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
4674        vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
4675        if (vars->link_up) {
4676                DP(NETIF_MSG_LINK, "phy link up\n");
4677
4678                vars->phy_link_up = 1;
4679                vars->duplex = DUPLEX_FULL;
4680                switch (vars->link_status &
4681                        LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
4682                case LINK_10THD:
4683                        vars->duplex = DUPLEX_HALF;
4684                        /* Fall thru */
4685                case LINK_10TFD:
4686                        vars->line_speed = SPEED_10;
4687                        break;
4688
4689                case LINK_100TXHD:
4690                        vars->duplex = DUPLEX_HALF;
4691                        /* Fall thru */
4692                case LINK_100T4:
4693                case LINK_100TXFD:
4694                        vars->line_speed = SPEED_100;
4695                        break;
4696
4697                case LINK_1000THD:
4698                        vars->duplex = DUPLEX_HALF;
4699                        /* Fall thru */
4700                case LINK_1000TFD:
4701                        vars->line_speed = SPEED_1000;
4702                        break;
4703
4704                case LINK_2500THD:
4705                        vars->duplex = DUPLEX_HALF;
4706                        /* Fall thru */
4707                case LINK_2500TFD:
4708                        vars->line_speed = SPEED_2500;
4709                        break;
4710
4711                case LINK_10GTFD:
4712                        vars->line_speed = SPEED_10000;
4713                        break;
4714                case LINK_20GTFD:
4715                        vars->line_speed = SPEED_20000;
4716                        break;
4717                default:
4718                        break;
4719                }
4720                vars->flow_ctrl = 0;
4721                if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
4722                        vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
4723
4724                if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
4725                        vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
4726
4727                if (!vars->flow_ctrl)
4728                        vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4729
4730                if (vars->line_speed &&
4731                    ((vars->line_speed == SPEED_10) ||
4732                     (vars->line_speed == SPEED_100))) {
4733                        vars->phy_flags |= PHY_SGMII_FLAG;
4734                } else {
4735                        vars->phy_flags &= ~PHY_SGMII_FLAG;
4736                }
4737                if (vars->line_speed &&
4738                    USES_WARPCORE(bp) &&
4739                    (vars->line_speed == SPEED_1000))
4740                        vars->phy_flags |= PHY_SGMII_FLAG;
4741                /* Anything 10 and over uses the bmac */
4742                link_10g_plus = (vars->line_speed >= SPEED_10000);
4743
4744                if (link_10g_plus) {
4745                        if (USES_WARPCORE(bp))
4746                                vars->mac_type = MAC_TYPE_XMAC;
4747                        else
4748                                vars->mac_type = MAC_TYPE_BMAC;
4749                } else {
4750                        if (USES_WARPCORE(bp))
4751                                vars->mac_type = MAC_TYPE_UMAC;
4752                        else
4753                                vars->mac_type = MAC_TYPE_EMAC;
4754                }
4755        } else { /* Link down */
4756                DP(NETIF_MSG_LINK, "phy link down\n");
4757
4758                vars->phy_link_up = 0;
4759
4760                vars->line_speed = 0;
4761                vars->duplex = DUPLEX_FULL;
4762                vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4763
4764                /* Indicate no mac active */
4765                vars->mac_type = MAC_TYPE_NONE;
4766                if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4767                        vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
4768                if (vars->link_status & LINK_STATUS_SFP_TX_FAULT)
4769                        vars->phy_flags |= PHY_SFP_TX_FAULT_FLAG;
4770        }
4771}
4772
4773void bnx2x_link_status_update(struct link_params *params,
4774                              struct link_vars *vars)
4775{
4776        struct bnx2x *bp = params->bp;
4777        uint8_t port = params->port;
4778        uint32_t sync_offset, media_types;
4779        /* Update PHY configuration */
4780        set_phy_vars(params, vars);
4781
4782        vars->link_status = REG_RD(bp, params->shmem_base +
4783                                   offsetof(struct shmem_region,
4784                                            port_mb[port].link_status));
4785
4786        /* Force link UP in non LOOPBACK_EXT loopback mode(s) */
4787        if (params->loopback_mode != LOOPBACK_NONE &&
4788            params->loopback_mode != LOOPBACK_EXT)
4789                vars->link_status |= LINK_STATUS_LINK_UP;
4790
4791        if (bnx2x_eee_has_cap(params))
4792                vars->eee_status = REG_RD(bp, params->shmem2_base +
4793                                          offsetof(struct shmem2_region,
4794                                                   eee_status[params->port]));
4795
4796        vars->phy_flags = PHY_XGXS_FLAG;
4797        bnx2x_sync_link(params, vars);
4798        /* Sync media type */
4799        sync_offset = params->shmem_base +
4800                        offsetof(struct shmem_region,
4801                                 dev_info.port_hw_config[port].media_type);
4802        media_types = REG_RD(bp, sync_offset);
4803
4804        params->phy[INT_PHY].media_type =
4805                (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
4806                PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
4807        params->phy[EXT_PHY1].media_type =
4808                (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
4809                PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
4810        params->phy[EXT_PHY2].media_type =
4811                (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
4812                PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
4813        DP(NETIF_MSG_LINK, "media_types = 0x%x\n", media_types);
4814
4815        /* Sync AEU offset */
4816        sync_offset = params->shmem_base +
4817                        offsetof(struct shmem_region,
4818                                 dev_info.port_hw_config[port].aeu_int_mask);
4819
4820        vars->aeu_int_mask = REG_RD(bp, sync_offset);
4821
4822        /* Sync PFC status */
4823        if (vars->link_status & LINK_STATUS_PFC_ENABLED)
4824                params->feature_config_flags |=
4825                                        FEATURE_CONFIG_PFC_ENABLED;
4826        else
4827                params->feature_config_flags &=
4828                                        ~FEATURE_CONFIG_PFC_ENABLED;
4829
4830        if (SHMEM2_HAS(bp, link_attr_sync))
4831                params->link_attr_sync = SHMEM2_RD(bp,
4832                                                 link_attr_sync[params->port]);
4833
4834        DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x int_mask 0x%x\n",
4835                 vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
4836        DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
4837                 vars->line_speed, vars->duplex, vars->flow_ctrl);
4838}
4839
4840static void bnx2x_set_master_ln(struct link_params *params,
4841                                struct bnx2x_phy *phy)
4842{
4843        struct bnx2x *bp = params->bp;
4844        uint16_t new_master_ln, ser_lane;
4845        ser_lane = ((params->lane_config &
4846                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4847                    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4848
4849        /* Set the master_ln for AN */
4850        CL22_RD_OVER_CL45(bp, phy,
4851                          MDIO_REG_BANK_XGXS_BLOCK2,
4852                          MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4853                          &new_master_ln);
4854
4855        CL22_WR_OVER_CL45(bp, phy,
4856                          MDIO_REG_BANK_XGXS_BLOCK2 ,
4857                          MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4858                          (new_master_ln | ser_lane));
4859}
4860
4861static int bnx2x_reset_unicore(struct link_params *params,
4862                               struct bnx2x_phy *phy,
4863                               uint8_t set_serdes)
4864{
4865        struct bnx2x *bp = params->bp;
4866        uint16_t mii_control;
4867        uint16_t i;
4868        CL22_RD_OVER_CL45(bp, phy,
4869                          MDIO_REG_BANK_COMBO_IEEE0,
4870                          MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
4871
4872        /* Reset the unicore */
4873        CL22_WR_OVER_CL45(bp, phy,
4874                          MDIO_REG_BANK_COMBO_IEEE0,
4875                          MDIO_COMBO_IEEE0_MII_CONTROL,
4876                          (mii_control |
4877                           MDIO_COMBO_IEEO_MII_CONTROL_RESET));
4878        if (set_serdes)
4879                bnx2x_set_serdes_access(bp, params->port);
4880
4881        /* Wait for the reset to self clear */
4882        for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
4883                udelay(5);
4884
4885                /* The reset erased the previous bank value */
4886                CL22_RD_OVER_CL45(bp, phy,
4887                                  MDIO_REG_BANK_COMBO_IEEE0,
4888                                  MDIO_COMBO_IEEE0_MII_CONTROL,
4889                                  &mii_control);
4890
4891                if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
4892                        udelay(5);
4893                        return 0;
4894                }
4895        }
4896
4897        netdev_err(bp->dev,  "Warning: PHY was not initialized,"
4898                              " Port %d\n",
4899                         params->port);
4900        DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
4901        return -EINVAL;
4902
4903}
4904
4905static void bnx2x_set_swap_lanes(struct link_params *params,
4906                                 struct bnx2x_phy *phy)
4907{