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