linux/drivers/net/bnx2x/bnx2x_link.c
<<
>>
Prefs
   1/* Copyright 2008-2009 Broadcom Corporation
   2 *
   3 * Unless you and Broadcom execute a separate written software license
   4 * agreement governing use of this software, this software is licensed to you
   5 * under the terms of the GNU General Public License version 2, available
   6 * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
   7 *
   8 * Notwithstanding the above, under no circumstances may you combine this
   9 * software in any way with any other Broadcom software provided under a
  10 * license other than the GPL, without Broadcom's express prior written
  11 * consent.
  12 *
  13 * Written by Yaniv Rosner
  14 *
  15 */
  16
  17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  18
  19#include <linux/kernel.h>
  20#include <linux/errno.h>
  21#include <linux/pci.h>
  22#include <linux/netdevice.h>
  23#include <linux/delay.h>
  24#include <linux/ethtool.h>
  25#include <linux/mutex.h>
  26
  27#include "bnx2x.h"
  28
  29/********************************************************/
  30#define ETH_HLEN                        14
  31#define ETH_OVREHEAD            (ETH_HLEN + 8 + 8)/* 16 for CRC + VLAN + LLC */
  32#define ETH_MIN_PACKET_SIZE             60
  33#define ETH_MAX_PACKET_SIZE             1500
  34#define ETH_MAX_JUMBO_PACKET_SIZE       9600
  35#define MDIO_ACCESS_TIMEOUT             1000
  36#define BMAC_CONTROL_RX_ENABLE  2
  37
  38/***********************************************************/
  39/*                      Shortcut definitions               */
  40/***********************************************************/
  41
  42#define NIG_LATCH_BC_ENABLE_MI_INT 0
  43
  44#define NIG_STATUS_EMAC0_MI_INT \
  45                NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
  46#define NIG_STATUS_XGXS0_LINK10G \
  47                NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
  48#define NIG_STATUS_XGXS0_LINK_STATUS \
  49                NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
  50#define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
  51                NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
  52#define NIG_STATUS_SERDES0_LINK_STATUS \
  53                NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
  54#define NIG_MASK_MI_INT \
  55                NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
  56#define NIG_MASK_XGXS0_LINK10G \
  57                NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
  58#define NIG_MASK_XGXS0_LINK_STATUS \
  59                NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
  60#define NIG_MASK_SERDES0_LINK_STATUS \
  61                NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
  62
  63#define MDIO_AN_CL73_OR_37_COMPLETE \
  64                (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
  65                 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
  66
  67#define XGXS_RESET_BITS \
  68        (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
  69         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
  70         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
  71         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
  72         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
  73
  74#define SERDES_RESET_BITS \
  75        (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
  76         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
  77         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
  78         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
  79
  80#define AUTONEG_CL37            SHARED_HW_CFG_AN_ENABLE_CL37
  81#define AUTONEG_CL73            SHARED_HW_CFG_AN_ENABLE_CL73
  82#define AUTONEG_BAM             SHARED_HW_CFG_AN_ENABLE_BAM
  83#define AUTONEG_PARALLEL \
  84                                SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
  85#define AUTONEG_SGMII_FIBER_AUTODET \
  86                                SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
  87#define AUTONEG_REMOTE_PHY      SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
  88
  89#define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
  90                        MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
  91#define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
  92                        MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
  93#define GP_STATUS_SPEED_MASK \
  94                        MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
  95#define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
  96#define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
  97#define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
  98#define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
  99#define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
 100#define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
 101#define GP_STATUS_10G_HIG \
 102                        MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
 103#define GP_STATUS_10G_CX4 \
 104                        MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
 105#define GP_STATUS_12G_HIG \
 106                        MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
 107#define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
 108#define GP_STATUS_13G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
 109#define GP_STATUS_15G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
 110#define GP_STATUS_16G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
 111#define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
 112#define GP_STATUS_10G_KX4 \
 113                        MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
 114
 115#define LINK_10THD                      LINK_STATUS_SPEED_AND_DUPLEX_10THD
 116#define LINK_10TFD                      LINK_STATUS_SPEED_AND_DUPLEX_10TFD
 117#define LINK_100TXHD            LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
 118#define LINK_100T4                      LINK_STATUS_SPEED_AND_DUPLEX_100T4
 119#define LINK_100TXFD            LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
 120#define LINK_1000THD            LINK_STATUS_SPEED_AND_DUPLEX_1000THD
 121#define LINK_1000TFD            LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
 122#define LINK_1000XFD            LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
 123#define LINK_2500THD            LINK_STATUS_SPEED_AND_DUPLEX_2500THD
 124#define LINK_2500TFD            LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
 125#define LINK_2500XFD            LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
 126#define LINK_10GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
 127#define LINK_10GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
 128#define LINK_12GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
 129#define LINK_12GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
 130#define LINK_12_5GTFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
 131#define LINK_12_5GXFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
 132#define LINK_13GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
 133#define LINK_13GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
 134#define LINK_15GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
 135#define LINK_15GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
 136#define LINK_16GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
 137#define LINK_16GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
 138
 139#define PHY_XGXS_FLAG                   0x1
 140#define PHY_SGMII_FLAG                  0x2
 141#define PHY_SERDES_FLAG                 0x4
 142
 143/* */
 144#define SFP_EEPROM_CON_TYPE_ADDR                0x2
 145        #define SFP_EEPROM_CON_TYPE_VAL_LC              0x7
 146        #define SFP_EEPROM_CON_TYPE_VAL_COPPER  0x21
 147
 148
 149#define SFP_EEPROM_COMP_CODE_ADDR               0x3
 150        #define SFP_EEPROM_COMP_CODE_SR_MASK    (1<<4)
 151        #define SFP_EEPROM_COMP_CODE_LR_MASK    (1<<5)
 152        #define SFP_EEPROM_COMP_CODE_LRM_MASK   (1<<6)
 153
 154#define SFP_EEPROM_FC_TX_TECH_ADDR              0x8
 155        #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
 156        #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE      0x8
 157
 158#define SFP_EEPROM_OPTIONS_ADDR                 0x40
 159        #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
 160#define SFP_EEPROM_OPTIONS_SIZE                 2
 161
 162#define EDC_MODE_LINEAR                         0x0022
 163#define EDC_MODE_LIMITING                               0x0044
 164#define EDC_MODE_PASSIVE_DAC                    0x0055
 165
 166
 167#define ETS_BW_LIMIT_CREDIT_UPPER_BOUND         (0x5000)
 168#define ETS_BW_LIMIT_CREDIT_WEIGHT              (0x5000)
 169/**********************************************************/
 170/*                     INTERFACE                          */
 171/**********************************************************/
 172
 173#define CL45_WR_OVER_CL22(_bp, _phy, _bank, _addr, _val) \
 174        bnx2x_cl45_write(_bp, _phy, \
 175                (_phy)->def_md_devad, \
 176                (_bank + (_addr & 0xf)), \
 177                _val)
 178
 179#define CL45_RD_OVER_CL22(_bp, _phy, _bank, _addr, _val) \
 180        bnx2x_cl45_read(_bp, _phy, \
 181                (_phy)->def_md_devad, \
 182                (_bank + (_addr & 0xf)), \
 183                _val)
 184
 185static u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
 186                          u8 devad, u16 reg, u16 *ret_val);
 187
 188static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
 189                           u8 devad, u16 reg, u16 val);
 190
 191static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
 192{
 193        u32 val = REG_RD(bp, reg);
 194
 195        val |= bits;
 196        REG_WR(bp, reg, val);
 197        return val;
 198}
 199
 200static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
 201{
 202        u32 val = REG_RD(bp, reg);
 203
 204        val &= ~bits;
 205        REG_WR(bp, reg, val);
 206        return val;
 207}
 208
 209/******************************************************************/
 210/*                              ETS section                       */
 211/******************************************************************/
 212void bnx2x_ets_disabled(struct link_params *params)
 213{
 214        /* ETS disabled configuration*/
 215        struct bnx2x *bp = params->bp;
 216
 217        DP(NETIF_MSG_LINK, "ETS disabled configuration\n");
 218
 219        /**
 220         * mapping between entry  priority to client number (0,1,2 -debug and
 221         * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
 222         * 3bits client num.
 223         *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
 224         * cos1-100     cos0-011     dbg1-010     dbg0-001     MCP-000
 225         */
 226
 227        REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
 228        /**
 229         * Bitmap of 5bits length. Each bit specifies whether the entry behaves
 230         * as strict.  Bits 0,1,2 - debug and management entries, 3 -
 231         * COS0 entry, 4 - COS1 entry.
 232         * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
 233         * bit4   bit3    bit2   bit1     bit0
 234         * MCP and debug are strict
 235         */
 236
 237        REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
 238        /* defines which entries (clients) are subjected to WFQ arbitration */
 239        REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
 240        /**
 241        * For strict priority entries defines the number of consecutive
 242        * slots for the highest priority.
 243        */
 244        REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
 245        /**
 246         * mapping between the CREDIT_WEIGHT registers and actual client
 247         * numbers
 248         */
 249        REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
 250        REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
 251        REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
 252
 253        REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
 254        REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
 255        REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
 256        /* ETS mode disable */
 257        REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
 258        /**
 259         * If ETS mode is enabled (there is no strict priority) defines a WFQ
 260         * weight for COS0/COS1.
 261         */
 262        REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
 263        REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710);
 264        /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
 265        REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680);
 266        REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680);
 267        /* Defines the number of consecutive slots for the strict priority */
 268        REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
 269}
 270
 271void bnx2x_ets_bw_limit_common(const struct link_params *params)
 272{
 273        /* ETS disabled configuration */
 274        struct bnx2x *bp = params->bp;
 275        DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
 276        /**
 277        * defines which entries (clients) are subjected to WFQ arbitration
 278        * COS0 0x8
 279        * COS1 0x10
 280        */
 281        REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
 282        /**
 283        * mapping between the ARB_CREDIT_WEIGHT registers and actual
 284        * client numbers (WEIGHT_0 does not actually have to represent
 285        * client 0)
 286        *    PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
 287        *  cos1-001     cos0-000     dbg1-100     dbg0-011     MCP-010
 288        */
 289        REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
 290
 291        REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
 292               ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
 293        REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
 294               ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
 295
 296        /* ETS mode enabled*/
 297        REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
 298
 299        /* Defines the number of consecutive slots for the strict priority */
 300        REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
 301        /**
 302        * Bitmap of 5bits length. Each bit specifies whether the entry behaves
 303        * as strict.  Bits 0,1,2 - debug and management entries, 3 - COS0
 304        * entry, 4 - COS1 entry.
 305        * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
 306        * bit4   bit3     bit2     bit1    bit0
 307        * MCP and debug are strict
 308        */
 309        REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
 310
 311        /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
 312        REG_WR(bp, PBF_REG_COS0_UPPER_BOUND,
 313               ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
 314        REG_WR(bp, PBF_REG_COS1_UPPER_BOUND,
 315               ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
 316}
 317
 318void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
 319                        const u32 cos1_bw)
 320{
 321        /* ETS disabled configuration*/
 322        struct bnx2x *bp = params->bp;
 323        const u32 total_bw = cos0_bw + cos1_bw;
 324        u32 cos0_credit_weight = 0;
 325        u32 cos1_credit_weight = 0;
 326
 327        DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
 328
 329        if ((0 == total_bw) ||
 330            (0 == cos0_bw) ||
 331            (0 == cos1_bw)) {
 332                DP(NETIF_MSG_LINK,
 333                   "bnx2x_ets_bw_limit: Total BW can't be zero\n");
 334                return;
 335        }
 336
 337        cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
 338                total_bw;
 339        cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
 340                total_bw;
 341
 342        bnx2x_ets_bw_limit_common(params);
 343
 344        REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
 345        REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
 346
 347        REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
 348        REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
 349}
 350
 351u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
 352{
 353        /* ETS disabled configuration*/
 354        struct bnx2x *bp = params->bp;
 355        u32 val = 0;
 356
 357        DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
 358        /**
 359         * Bitmap of 5bits length. Each bit specifies whether the entry behaves
 360         * as strict.  Bits 0,1,2 - debug and management entries,
 361         * 3 - COS0 entry, 4 - COS1 entry.
 362         *  COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
 363         *  bit4   bit3   bit2      bit1     bit0
 364         * MCP and debug are strict
 365         */
 366        REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
 367        /**
 368         * For strict priority entries defines the number of consecutive slots
 369         * for the highest priority.
 370         */
 371        REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
 372        /* ETS mode disable */
 373        REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
 374        /* Defines the number of consecutive slots for the strict priority */
 375        REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
 376
 377        /* Defines the number of consecutive slots for the strict priority */
 378        REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
 379
 380        /**
 381        * mapping between entry  priority to client number (0,1,2 -debug and
 382        * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
 383        * 3bits client num.
 384        *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
 385        * dbg0-010     dbg1-001     cos1-100     cos0-011     MCP-000
 386        * dbg0-010     dbg1-001     cos0-011     cos1-100     MCP-000
 387        */
 388        val = (0 == strict_cos) ? 0x2318 : 0x22E0;
 389        REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
 390
 391        return 0;
 392}
 393/******************************************************************/
 394/*                      ETS section                               */
 395/******************************************************************/
 396
 397static void bnx2x_bmac2_get_pfc_stat(struct link_params *params,
 398                                     u32 pfc_frames_sent[2],
 399                                     u32 pfc_frames_received[2])
 400{
 401        /* Read pfc statistic */
 402        struct bnx2x *bp = params->bp;
 403        u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
 404                NIG_REG_INGRESS_BMAC0_MEM;
 405
 406        DP(NETIF_MSG_LINK, "pfc statistic read from BMAC\n");
 407
 408        REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_STAT_GTPP,
 409                                        pfc_frames_sent, 2);
 410
 411        REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_STAT_GRPP,
 412                                        pfc_frames_received, 2);
 413
 414}
 415static void bnx2x_emac_get_pfc_stat(struct link_params *params,
 416                                    u32 pfc_frames_sent[2],
 417                                    u32 pfc_frames_received[2])
 418{
 419        /* Read pfc statistic */
 420        struct bnx2x *bp = params->bp;
 421        u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
 422        u32 val_xon = 0;
 423        u32 val_xoff = 0;
 424
 425        DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n");
 426
 427        /* PFC received frames */
 428        val_xoff = REG_RD(bp, emac_base +
 429                                EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
 430        val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
 431        val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
 432        val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
 433
 434        pfc_frames_received[0] = val_xon + val_xoff;
 435
 436        /* PFC received sent */
 437        val_xoff = REG_RD(bp, emac_base +
 438                                EMAC_REG_RX_PFC_STATS_XOFF_SENT);
 439        val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
 440        val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
 441        val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
 442
 443        pfc_frames_sent[0] = val_xon + val_xoff;
 444}
 445
 446void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
 447                         u32 pfc_frames_sent[2],
 448                         u32 pfc_frames_received[2])
 449{
 450        /* Read pfc statistic */
 451        struct bnx2x *bp = params->bp;
 452        u32 val = 0;
 453        DP(NETIF_MSG_LINK, "pfc statistic\n");
 454
 455        if (!vars->link_up)
 456                return;
 457
 458        val = REG_RD(bp, MISC_REG_RESET_REG_2);
 459        if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
 460            == 0) {
 461                DP(NETIF_MSG_LINK, "About to read stats from EMAC\n");
 462                bnx2x_emac_get_pfc_stat(params, pfc_frames_sent,
 463                                        pfc_frames_received);
 464        } else {
 465                DP(NETIF_MSG_LINK, "About to read stats from BMAC\n");
 466                bnx2x_bmac2_get_pfc_stat(params, pfc_frames_sent,
 467                                         pfc_frames_received);
 468        }
 469}
 470/******************************************************************/
 471/*                      MAC/PBF section                           */
 472/******************************************************************/
 473static void bnx2x_emac_init(struct link_params *params,
 474                           struct link_vars *vars)
 475{
 476        /* reset and unreset the emac core */
 477        struct bnx2x *bp = params->bp;
 478        u8 port = params->port;
 479        u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
 480        u32 val;
 481        u16 timeout;
 482
 483        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
 484                   (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
 485        udelay(5);
 486        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
 487                   (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
 488
 489        /* init emac - use read-modify-write */
 490        /* self clear reset */
 491        val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
 492        EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
 493
 494        timeout = 200;
 495        do {
 496                val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
 497                DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
 498                if (!timeout) {
 499                        DP(NETIF_MSG_LINK, "EMAC timeout!\n");
 500                        return;
 501                }
 502                timeout--;
 503        } while (val & EMAC_MODE_RESET);
 504
 505        /* Set mac address */
 506        val = ((params->mac_addr[0] << 8) |
 507                params->mac_addr[1]);
 508        EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
 509
 510        val = ((params->mac_addr[2] << 24) |
 511               (params->mac_addr[3] << 16) |
 512               (params->mac_addr[4] << 8) |
 513                params->mac_addr[5]);
 514        EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
 515}
 516
 517static u8 bnx2x_emac_enable(struct link_params *params,
 518                          struct link_vars *vars, u8 lb)
 519{
 520        struct bnx2x *bp = params->bp;
 521        u8 port = params->port;
 522        u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
 523        u32 val;
 524
 525        DP(NETIF_MSG_LINK, "enabling EMAC\n");
 526
 527        /* enable emac and not bmac */
 528        REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
 529
 530        /* for paladium */
 531        if (CHIP_REV_IS_EMUL(bp)) {
 532                /* Use lane 1 (of lanes 0-3) */
 533                REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
 534                REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
 535                            port*4, 1);
 536        }
 537        /* for fpga */
 538        else
 539
 540        if (CHIP_REV_IS_FPGA(bp)) {
 541                /* Use lane 1 (of lanes 0-3) */
 542                DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
 543
 544                REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
 545                REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
 546                            0);
 547        } else
 548        /* ASIC */
 549        if (vars->phy_flags & PHY_XGXS_FLAG) {
 550                u32 ser_lane = ((params->lane_config &
 551                            PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
 552                            PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
 553
 554                DP(NETIF_MSG_LINK, "XGXS\n");
 555                /* select the master lanes (out of 0-3) */
 556                REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
 557                           port*4, ser_lane);
 558                /* select XGXS */
 559                REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
 560                           port*4, 1);
 561
 562        } else { /* SerDes */
 563                DP(NETIF_MSG_LINK, "SerDes\n");
 564                /* select SerDes */
 565                REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
 566                           port*4, 0);
 567        }
 568
 569        bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
 570                    EMAC_RX_MODE_RESET);
 571        bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
 572                    EMAC_TX_MODE_RESET);
 573
 574        if (CHIP_REV_IS_SLOW(bp)) {
 575                /* config GMII mode */
 576                val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
 577                EMAC_WR(bp, EMAC_REG_EMAC_MODE,
 578                            (val | EMAC_MODE_PORT_GMII));
 579        } else { /* ASIC */
 580                /* pause enable/disable */
 581                bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
 582                               EMAC_RX_MODE_FLOW_EN);
 583
 584                bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
 585                               (EMAC_TX_MODE_EXT_PAUSE_EN |
 586                                EMAC_TX_MODE_FLOW_EN));
 587                if (!(params->feature_config_flags &
 588                      FEATURE_CONFIG_PFC_ENABLED)) {
 589                        if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
 590                                bnx2x_bits_en(bp, emac_base +
 591                                              EMAC_REG_EMAC_RX_MODE,
 592                                              EMAC_RX_MODE_FLOW_EN);
 593
 594                        if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
 595                                bnx2x_bits_en(bp, emac_base +
 596                                              EMAC_REG_EMAC_TX_MODE,
 597                                              (EMAC_TX_MODE_EXT_PAUSE_EN |
 598                                               EMAC_TX_MODE_FLOW_EN));
 599                } else
 600                        bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
 601                                      EMAC_TX_MODE_FLOW_EN);
 602        }
 603
 604        /* KEEP_VLAN_TAG, promiscuous */
 605        val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
 606        val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
 607
 608        /**
 609        * Setting this bit causes MAC control frames (except for pause
 610        * frames) to be passed on for processing. This setting has no
 611        * affect on the operation of the pause frames. This bit effects
 612        * all packets regardless of RX Parser packet sorting logic.
 613        * Turn the PFC off to make sure we are in Xon state before
 614        * enabling it.
 615        */
 616        EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
 617        if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
 618                DP(NETIF_MSG_LINK, "PFC is enabled\n");
 619                /* Enable PFC again */
 620                EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
 621                        EMAC_REG_RX_PFC_MODE_RX_EN |
 622                        EMAC_REG_RX_PFC_MODE_TX_EN |
 623                        EMAC_REG_RX_PFC_MODE_PRIORITIES);
 624
 625                EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
 626                        ((0x0101 <<
 627                          EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
 628                         (0x00ff <<
 629                          EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
 630                val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
 631        }
 632        EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
 633
 634        /* Set Loopback */
 635        val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
 636        if (lb)
 637                val |= 0x810;
 638        else
 639                val &= ~0x810;
 640        EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
 641
 642        /* enable emac */
 643        REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
 644
 645        /* enable emac for jumbo packets */
 646        EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
 647                (EMAC_RX_MTU_SIZE_JUMBO_ENA |
 648                 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
 649
 650        /* strip CRC */
 651        REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
 652
 653        /* disable the NIG in/out to the bmac */
 654        REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
 655        REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
 656        REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
 657
 658        /* enable the NIG in/out to the emac */
 659        REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
 660        val = 0;
 661        if ((params->feature_config_flags &
 662              FEATURE_CONFIG_PFC_ENABLED) ||
 663            (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
 664                val = 1;
 665
 666        REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
 667        REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
 668
 669        if (CHIP_REV_IS_EMUL(bp)) {
 670                /* take the BigMac out of reset */
 671                REG_WR(bp,
 672                           GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
 673                           (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
 674
 675                /* enable access for bmac registers */
 676                REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
 677        } else
 678                REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
 679
 680        vars->mac_type = MAC_TYPE_EMAC;
 681        return 0;
 682}
 683
 684static void bnx2x_update_pfc_bmac1(struct link_params *params,
 685                                   struct link_vars *vars)
 686{
 687        u32 wb_data[2];
 688        struct bnx2x *bp = params->bp;
 689        u32 bmac_addr =  params->port ? NIG_REG_INGRESS_BMAC1_MEM :
 690                NIG_REG_INGRESS_BMAC0_MEM;
 691
 692        u32 val = 0x14;
 693        if ((!(params->feature_config_flags &
 694              FEATURE_CONFIG_PFC_ENABLED)) &&
 695                (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
 696                /* Enable BigMAC to react on received Pause packets */
 697                val |= (1<<5);
 698        wb_data[0] = val;
 699        wb_data[1] = 0;
 700        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
 701
 702        /* tx control */
 703        val = 0xc0;
 704        if (!(params->feature_config_flags &
 705              FEATURE_CONFIG_PFC_ENABLED) &&
 706                (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
 707                val |= 0x800000;
 708        wb_data[0] = val;
 709        wb_data[1] = 0;
 710        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
 711}
 712
 713static void bnx2x_update_pfc_bmac2(struct link_params *params,
 714                                   struct link_vars *vars,
 715                                   u8 is_lb)
 716{
 717        /*
 718         * Set rx control: Strip CRC and enable BigMAC to relay
 719         * control packets to the system as well
 720         */
 721        u32 wb_data[2];
 722        struct bnx2x *bp = params->bp;
 723        u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
 724                NIG_REG_INGRESS_BMAC0_MEM;
 725        u32 val = 0x14;
 726
 727        if ((!(params->feature_config_flags &
 728              FEATURE_CONFIG_PFC_ENABLED)) &&
 729                (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
 730                /* Enable BigMAC to react on received Pause packets */
 731                val |= (1<<5);
 732        wb_data[0] = val;
 733        wb_data[1] = 0;
 734        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL,
 735                        wb_data, 2);
 736        udelay(30);
 737
 738        /* Tx control */
 739        val = 0xc0;
 740        if (!(params->feature_config_flags &
 741                                FEATURE_CONFIG_PFC_ENABLED) &&
 742            (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
 743                val |= 0x800000;
 744        wb_data[0] = val;
 745        wb_data[1] = 0;
 746        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
 747
 748        if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
 749                DP(NETIF_MSG_LINK, "PFC is enabled\n");
 750                /* Enable PFC RX & TX & STATS and set 8 COS  */
 751                wb_data[0] = 0x0;
 752                wb_data[0] |= (1<<0);  /* RX */
 753                wb_data[0] |= (1<<1);  /* TX */
 754                wb_data[0] |= (1<<2);  /* Force initial Xon */
 755                wb_data[0] |= (1<<3);  /* 8 cos */
 756                wb_data[0] |= (1<<5);  /* STATS */
 757                wb_data[1] = 0;
 758                REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
 759                            wb_data, 2);
 760                /* Clear the force Xon */
 761                wb_data[0] &= ~(1<<2);
 762        } else {
 763                DP(NETIF_MSG_LINK, "PFC is disabled\n");
 764                /* disable PFC RX & TX & STATS and set 8 COS */
 765                wb_data[0] = 0x8;
 766                wb_data[1] = 0;
 767        }
 768
 769        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
 770
 771        /**
 772        * Set Time (based unit is 512 bit time) between automatic
 773        * re-sending of PP packets amd enable automatic re-send of
 774        * Per-Priroity Packet as long as pp_gen is asserted and
 775        * pp_disable is low.
 776        */
 777        val = 0x8000;
 778        if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
 779                val |= (1<<16); /* enable automatic re-send */
 780
 781        wb_data[0] = val;
 782        wb_data[1] = 0;
 783        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
 784                        wb_data, 2);
 785
 786        /* mac control */
 787        val = 0x3; /* Enable RX and TX */
 788        if (is_lb) {
 789                val |= 0x4; /* Local loopback */
 790                DP(NETIF_MSG_LINK, "enable bmac loopback\n");
 791        }
 792        /* When PFC enabled, Pass pause frames towards the NIG. */
 793        if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
 794                val |= ((1<<6)|(1<<5));
 795
 796        wb_data[0] = val;
 797        wb_data[1] = 0;
 798        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL,
 799                        wb_data, 2);
 800}
 801
 802static void bnx2x_update_pfc_brb(struct link_params *params,
 803                struct link_vars *vars,
 804                struct bnx2x_nig_brb_pfc_port_params *pfc_params)
 805{
 806        struct bnx2x *bp = params->bp;
 807        int set_pfc = params->feature_config_flags &
 808                FEATURE_CONFIG_PFC_ENABLED;
 809
 810        /* default - pause configuration */
 811        u32 pause_xoff_th = PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE;
 812        u32 pause_xon_th = PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE;
 813        u32 full_xoff_th = PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE;
 814        u32 full_xon_th = PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE;
 815
 816        if (set_pfc && pfc_params)
 817                /* First COS */
 818                if (!pfc_params->cos0_pauseable) {
 819                        pause_xoff_th =
 820                          PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE;
 821                        pause_xon_th =
 822                          PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE;
 823                        full_xoff_th =
 824                          PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE;
 825                        full_xon_th =
 826                          PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE;
 827                }
 828        /* The number of free blocks below which the pause signal to class 0
 829           of MAC #n is asserted. n=0,1 */
 830        REG_WR(bp, BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 , pause_xoff_th);
 831        /* The number of free blocks above which the pause signal to class 0
 832           of MAC #n is de-asserted. n=0,1 */
 833        REG_WR(bp, BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , pause_xon_th);
 834        /* The number of free blocks below which the full signal to class 0
 835           of MAC #n is asserted. n=0,1 */
 836        REG_WR(bp, BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , full_xoff_th);
 837        /* The number of free blocks above which the full signal to class 0
 838           of MAC #n is de-asserted. n=0,1 */
 839        REG_WR(bp, BRB1_REG_FULL_0_XON_THRESHOLD_0 , full_xon_th);
 840
 841        if (set_pfc && pfc_params) {
 842                /* Second COS */
 843                if (pfc_params->cos1_pauseable) {
 844                        pause_xoff_th =
 845                          PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE;
 846                        pause_xon_th =
 847                          PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE;
 848                        full_xoff_th =
 849                          PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE;
 850                        full_xon_th =
 851                          PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE;
 852                } else {
 853                        pause_xoff_th =
 854                          PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE;
 855                        pause_xon_th =
 856                          PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE;
 857                        full_xoff_th =
 858                          PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE;
 859                        full_xon_th =
 860                          PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE;
 861                }
 862                /**
 863                 * The number of free blocks below which the pause signal to
 864                 * class 1 of MAC #n is asserted. n=0,1
 865                 **/
 866                REG_WR(bp, BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0, pause_xoff_th);
 867                /**
 868                 * The number of free blocks above which the pause signal to
 869                 * class 1 of MAC #n is de-asserted. n=0,1
 870                 **/
 871                REG_WR(bp, BRB1_REG_PAUSE_1_XON_THRESHOLD_0, pause_xon_th);
 872                /**
 873                 * The number of free blocks below which the full signal to
 874                 * class 1 of MAC #n is asserted. n=0,1
 875                 **/
 876                REG_WR(bp, BRB1_REG_FULL_1_XOFF_THRESHOLD_0, full_xoff_th);
 877                /**
 878                 * The number of free blocks above which the full signal to
 879                 * class 1 of MAC #n is de-asserted. n=0,1
 880                 **/
 881                REG_WR(bp, BRB1_REG_FULL_1_XON_THRESHOLD_0, full_xon_th);
 882        }
 883}
 884
 885static void bnx2x_update_pfc_nig(struct link_params *params,
 886                struct link_vars *vars,
 887                struct bnx2x_nig_brb_pfc_port_params *nig_params)
 888{
 889        u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
 890        u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0;
 891        u32 pkt_priority_to_cos = 0;
 892        u32 val;
 893        struct bnx2x *bp = params->bp;
 894        int port = params->port;
 895        int set_pfc = params->feature_config_flags &
 896                FEATURE_CONFIG_PFC_ENABLED;
 897        DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
 898
 899        /**
 900         * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
 901         * MAC control frames (that are not pause packets)
 902         * will be forwarded to the XCM.
 903         */
 904        xcm_mask = REG_RD(bp,
 905                                port ? NIG_REG_LLH1_XCM_MASK :
 906                                NIG_REG_LLH0_XCM_MASK);
 907        /**
 908         * nig params will override non PFC params, since it's possible to
 909         * do transition from PFC to SAFC
 910         */
 911        if (set_pfc) {
 912                pause_enable = 0;
 913                llfc_out_en = 0;
 914                llfc_enable = 0;
 915                ppp_enable = 1;
 916                xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
 917                                     NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
 918                xcm0_out_en = 0;
 919                p0_hwpfc_enable = 1;
 920        } else  {
 921                if (nig_params) {
 922                        llfc_out_en = nig_params->llfc_out_en;
 923                        llfc_enable = nig_params->llfc_enable;
 924                        pause_enable = nig_params->pause_enable;
 925                } else  /*defaul non PFC mode - PAUSE */
 926                        pause_enable = 1;
 927
 928                xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
 929                        NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
 930                xcm0_out_en = 1;
 931        }
 932
 933        REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
 934               NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
 935        REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
 936               NIG_REG_LLFC_ENABLE_0, llfc_enable);
 937        REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
 938               NIG_REG_PAUSE_ENABLE_0, pause_enable);
 939
 940        REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
 941               NIG_REG_PPP_ENABLE_0, ppp_enable);
 942
 943        REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
 944               NIG_REG_LLH0_XCM_MASK, xcm_mask);
 945
 946        REG_WR(bp,  NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
 947
 948        /* output enable for RX_XCM # IF */
 949        REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en);
 950
 951        /* HW PFC TX enable */
 952        REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable);
 953
 954        /* 0x2 = BMAC, 0x1= EMAC */
 955        switch (vars->mac_type) {
 956        case MAC_TYPE_EMAC:
 957                val = 1;
 958                break;
 959        case MAC_TYPE_BMAC:
 960                val = 0;
 961                break;
 962        default:
 963                val = 0;
 964                break;
 965        }
 966        REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT, val);
 967
 968        if (nig_params) {
 969                pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
 970
 971                REG_WR(bp, port ? NIG_REG_P1_RX_COS0_PRIORITY_MASK :
 972                       NIG_REG_P0_RX_COS0_PRIORITY_MASK,
 973                       nig_params->rx_cos0_priority_mask);
 974
 975                REG_WR(bp, port ? NIG_REG_P1_RX_COS1_PRIORITY_MASK :
 976                       NIG_REG_P0_RX_COS1_PRIORITY_MASK,
 977                       nig_params->rx_cos1_priority_mask);
 978
 979                REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
 980                       NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
 981                       nig_params->llfc_high_priority_classes);
 982
 983                REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
 984                       NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
 985                       nig_params->llfc_low_priority_classes);
 986        }
 987        REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
 988               NIG_REG_P0_PKT_PRIORITY_TO_COS,
 989               pkt_priority_to_cos);
 990}
 991
 992
 993void bnx2x_update_pfc(struct link_params *params,
 994                      struct link_vars *vars,
 995                      struct bnx2x_nig_brb_pfc_port_params *pfc_params)
 996{
 997        /**
 998         * The PFC and pause are orthogonal to one another, meaning when
 999         * PFC is enabled, the pause are disabled, and when PFC is
1000         * disabled, pause are set according to the pause result.
1001         */
1002        u32 val;
1003        struct bnx2x *bp = params->bp;
1004
1005        /* update NIG params */
1006        bnx2x_update_pfc_nig(params, vars, pfc_params);
1007
1008        /* update BRB params */
1009        bnx2x_update_pfc_brb(params, vars, pfc_params);
1010
1011        if (!vars->link_up)
1012                return;
1013
1014        val = REG_RD(bp, MISC_REG_RESET_REG_2);
1015        if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
1016            == 0) {
1017                DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
1018                bnx2x_emac_enable(params, vars, 0);
1019                return;
1020        }
1021
1022        DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
1023        if (CHIP_IS_E2(bp))
1024                bnx2x_update_pfc_bmac2(params, vars, 0);
1025        else
1026                bnx2x_update_pfc_bmac1(params, vars);
1027
1028        val = 0;
1029        if ((params->feature_config_flags &
1030              FEATURE_CONFIG_PFC_ENABLED) ||
1031            (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1032                val = 1;
1033        REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
1034}
1035
1036static u8 bnx2x_bmac1_enable(struct link_params *params,
1037                             struct link_vars *vars,
1038                          u8 is_lb)
1039{
1040        struct bnx2x *bp = params->bp;
1041        u8 port = params->port;
1042        u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1043                               NIG_REG_INGRESS_BMAC0_MEM;
1044        u32 wb_data[2];
1045        u32 val;
1046
1047        DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
1048
1049        /* XGXS control */
1050        wb_data[0] = 0x3c;
1051        wb_data[1] = 0;
1052        REG_WR_DMAE(bp, bmac_addr +
1053                      BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
1054                      wb_data, 2);
1055
1056        /* tx MAC SA */
1057        wb_data[0] = ((params->mac_addr[2] << 24) |
1058                       (params->mac_addr[3] << 16) |
1059                       (params->mac_addr[4] << 8) |
1060                        params->mac_addr[5]);
1061        wb_data[1] = ((params->mac_addr[0] << 8) |
1062                        params->mac_addr[1]);
1063        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
1064                    wb_data, 2);
1065
1066        /* mac control */
1067        val = 0x3;
1068        if (is_lb) {
1069                val |= 0x4;
1070                DP(NETIF_MSG_LINK, "enable bmac loopback\n");
1071        }
1072        wb_data[0] = val;
1073        wb_data[1] = 0;
1074        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
1075                    wb_data, 2);
1076
1077        /* set rx mtu */
1078        wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1079        wb_data[1] = 0;
1080        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
1081                        wb_data, 2);
1082
1083        bnx2x_update_pfc_bmac1(params, vars);
1084
1085        /* set tx mtu */
1086        wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1087        wb_data[1] = 0;
1088        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
1089                        wb_data, 2);
1090
1091        /* set cnt max size */
1092        wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1093        wb_data[1] = 0;
1094        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
1095                    wb_data, 2);
1096
1097        /* configure safc */
1098        wb_data[0] = 0x1000200;
1099        wb_data[1] = 0;
1100        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
1101                    wb_data, 2);
1102        /* fix for emulation */
1103        if (CHIP_REV_IS_EMUL(bp)) {
1104                wb_data[0] = 0xf000;
1105                wb_data[1] = 0;
1106                REG_WR_DMAE(bp,
1107                            bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
1108                            wb_data, 2);
1109        }
1110
1111
1112        return 0;
1113}
1114
1115static u8 bnx2x_bmac2_enable(struct link_params *params,
1116                             struct link_vars *vars,
1117                             u8 is_lb)
1118{
1119        struct bnx2x *bp = params->bp;
1120        u8 port = params->port;
1121        u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1122                               NIG_REG_INGRESS_BMAC0_MEM;
1123        u32 wb_data[2];
1124
1125        DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
1126
1127        wb_data[0] = 0;
1128        wb_data[1] = 0;
1129        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL,
1130                        wb_data, 2);
1131        udelay(30);
1132
1133        /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
1134        wb_data[0] = 0x3c;
1135        wb_data[1] = 0;
1136        REG_WR_DMAE(bp, bmac_addr +
1137                        BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
1138                        wb_data, 2);
1139
1140        udelay(30);
1141
1142        /* tx MAC SA */
1143        wb_data[0] = ((params->mac_addr[2] << 24) |
1144                       (params->mac_addr[3] << 16) |
1145                       (params->mac_addr[4] << 8) |
1146                        params->mac_addr[5]);
1147        wb_data[1] = ((params->mac_addr[0] << 8) |
1148                        params->mac_addr[1]);
1149        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
1150                        wb_data, 2);
1151
1152        udelay(30);
1153
1154        /* Configure SAFC */
1155        wb_data[0] = 0x1000200;
1156        wb_data[1] = 0;
1157        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
1158                        wb_data, 2);
1159        udelay(30);
1160
1161        /* set rx mtu */
1162        wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1163        wb_data[1] = 0;
1164        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE,
1165                        wb_data, 2);
1166        udelay(30);
1167
1168        /* set tx mtu */
1169        wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
1170        wb_data[1] = 0;
1171        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE,
1172                        wb_data, 2);
1173        udelay(30);
1174        /* set cnt max size */
1175        wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
1176        wb_data[1] = 0;
1177        REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE,
1178                        wb_data, 2);
1179        udelay(30);
1180        bnx2x_update_pfc_bmac2(params, vars, is_lb);
1181
1182        return 0;
1183}
1184
1185static u8 bnx2x_bmac_enable(struct link_params *params,
1186                            struct link_vars *vars,
1187                            u8 is_lb)
1188{
1189        u8 rc, port = params->port;
1190        struct bnx2x *bp = params->bp;
1191        u32 val;
1192        /* reset and unreset the BigMac */
1193        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1194                     (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1195        msleep(1);
1196
1197        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1198                     (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1199
1200        /* enable access for bmac registers */
1201        REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
1202
1203        /* Enable BMAC according to BMAC type*/
1204        if (CHIP_IS_E2(bp))
1205                rc = bnx2x_bmac2_enable(params, vars, is_lb);
1206        else
1207                rc = bnx2x_bmac1_enable(params, vars, is_lb);
1208        REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
1209        REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
1210        REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
1211        val = 0;
1212        if ((params->feature_config_flags &
1213              FEATURE_CONFIG_PFC_ENABLED) ||
1214            (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1215                val = 1;
1216        REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
1217        REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
1218        REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
1219        REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
1220        REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
1221        REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
1222
1223        vars->mac_type = MAC_TYPE_BMAC;
1224        return rc;
1225}
1226
1227
1228static void bnx2x_update_mng(struct link_params *params, u32 link_status)
1229{
1230        struct bnx2x *bp = params->bp;
1231
1232        REG_WR(bp, params->shmem_base +
1233                   offsetof(struct shmem_region,
1234                            port_mb[params->port].link_status),
1235                        link_status);
1236}
1237
1238static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
1239{
1240        u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1241                NIG_REG_INGRESS_BMAC0_MEM;
1242        u32 wb_data[2];
1243        u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
1244
1245        /* Only if the bmac is out of reset */
1246        if (REG_RD(bp, MISC_REG_RESET_REG_2) &
1247                        (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
1248            nig_bmac_enable) {
1249
1250                if (CHIP_IS_E2(bp)) {
1251                        /* Clear Rx Enable bit in BMAC_CONTROL register */
1252                        REG_RD_DMAE(bp, bmac_addr +
1253                                        BIGMAC2_REGISTER_BMAC_CONTROL,
1254                                        wb_data, 2);
1255                        wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
1256                        REG_WR_DMAE(bp, bmac_addr +
1257                                        BIGMAC2_REGISTER_BMAC_CONTROL,
1258                                        wb_data, 2);
1259                } else {
1260                        /* Clear Rx Enable bit in BMAC_CONTROL register */
1261                        REG_RD_DMAE(bp, bmac_addr +
1262                                        BIGMAC_REGISTER_BMAC_CONTROL,
1263                                        wb_data, 2);
1264                        wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
1265                        REG_WR_DMAE(bp, bmac_addr +
1266                                        BIGMAC_REGISTER_BMAC_CONTROL,
1267                                        wb_data, 2);
1268                }
1269                msleep(1);
1270        }
1271}
1272
1273static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
1274                         u32 line_speed)
1275{
1276        struct bnx2x *bp = params->bp;
1277        u8 port = params->port;
1278        u32 init_crd, crd;
1279        u32 count = 1000;
1280
1281        /* disable port */
1282        REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
1283
1284        /* wait for init credit */
1285        init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
1286        crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
1287        DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
1288
1289        while ((init_crd != crd) && count) {
1290                msleep(5);
1291
1292                crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
1293                count--;
1294        }
1295        crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
1296        if (init_crd != crd) {
1297                DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
1298                          init_crd, crd);
1299                return -EINVAL;
1300        }
1301
1302        if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
1303            line_speed == SPEED_10 ||
1304            line_speed == SPEED_100 ||
1305            line_speed == SPEED_1000 ||
1306            line_speed == SPEED_2500) {
1307                REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
1308                /* update threshold */
1309                REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
1310                /* update init credit */
1311                init_crd = 778;         /* (800-18-4) */
1312
1313        } else {
1314                u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
1315                              ETH_OVREHEAD)/16;
1316                REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
1317                /* update threshold */
1318                REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
1319                /* update init credit */
1320                switch (line_speed) {
1321                case SPEED_10000:
1322                        init_crd = thresh + 553 - 22;
1323                        break;
1324
1325                case SPEED_12000:
1326                        init_crd = thresh + 664 - 22;
1327                        break;
1328
1329                case SPEED_13000:
1330                        init_crd = thresh + 742 - 22;
1331                        break;
1332
1333                case SPEED_16000:
1334                        init_crd = thresh + 778 - 22;
1335                        break;
1336                default:
1337                        DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1338                                  line_speed);
1339                        return -EINVAL;
1340                }
1341        }
1342        REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
1343        DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
1344                 line_speed, init_crd);
1345
1346        /* probe the credit changes */
1347        REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
1348        msleep(5);
1349        REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
1350
1351        /* enable port */
1352        REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
1353        return 0;
1354}
1355
1356static u32 bnx2x_get_emac_base(struct bnx2x *bp,
1357                               u32 mdc_mdio_access, u8 port)
1358{
1359        u32 emac_base = 0;
1360        switch (mdc_mdio_access) {
1361        case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
1362                break;
1363        case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
1364                if (REG_RD(bp, NIG_REG_PORT_SWAP))
1365                        emac_base = GRCBASE_EMAC1;
1366                else
1367                        emac_base = GRCBASE_EMAC0;
1368                break;
1369        case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
1370                if (REG_RD(bp, NIG_REG_PORT_SWAP))
1371                        emac_base = GRCBASE_EMAC0;
1372                else
1373                        emac_base = GRCBASE_EMAC1;
1374                break;
1375        case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
1376                emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1377                break;
1378        case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
1379                emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
1380                break;
1381        default:
1382                break;
1383        }
1384        return emac_base;
1385
1386}
1387
1388u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
1389                    u8 devad, u16 reg, u16 val)
1390{
1391        u32 tmp, saved_mode;
1392        u8 i, rc = 0;
1393
1394        /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
1395         * (a value of 49==0x31) and make sure that the AUTO poll is off
1396         */
1397
1398        saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
1399        tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
1400                             EMAC_MDIO_MODE_CLOCK_CNT);
1401        tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
1402                (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
1403        REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
1404        REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
1405        udelay(40);
1406
1407        /* address */
1408
1409        tmp = ((phy->addr << 21) | (devad << 16) | reg |
1410               EMAC_MDIO_COMM_COMMAND_ADDRESS |
1411               EMAC_MDIO_COMM_START_BUSY);
1412        REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
1413
1414        for (i = 0; i < 50; i++) {
1415                udelay(10);
1416
1417                tmp = REG_RD(bp, phy->mdio_ctrl +
1418                                   EMAC_REG_EMAC_MDIO_COMM);
1419                if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
1420                        udelay(5);
1421                        break;
1422                }
1423        }
1424        if (tmp & EMAC_MDIO_COMM_START_BUSY) {
1425                DP(NETIF_MSG_LINK, "write phy register failed\n");
1426                rc = -EFAULT;
1427        } else {
1428                /* data */
1429                tmp = ((phy->addr << 21) | (devad << 16) | val |
1430                       EMAC_MDIO_COMM_COMMAND_WRITE_45 |
1431                       EMAC_MDIO_COMM_START_BUSY);
1432                REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
1433
1434                for (i = 0; i < 50; i++) {
1435                        udelay(10);
1436
1437                        tmp = REG_RD(bp, phy->mdio_ctrl +
1438                                         EMAC_REG_EMAC_MDIO_COMM);
1439                        if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
1440                                udelay(5);
1441                                break;
1442                        }
1443                }
1444                if (tmp & EMAC_MDIO_COMM_START_BUSY) {
1445                        DP(NETIF_MSG_LINK, "write phy register failed\n");
1446                        rc = -EFAULT;
1447                }
1448        }
1449
1450        /* Restore the saved mode */
1451        REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
1452
1453        return rc;
1454}
1455
1456u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
1457                   u8 devad, u16 reg, u16 *ret_val)
1458{
1459        u32 val, saved_mode;
1460        u16 i;
1461        u8 rc = 0;
1462
1463        /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
1464         * (a value of 49==0x31) and make sure that the AUTO poll is off
1465         */
1466
1467        saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
1468        val = saved_mode & ~((EMAC_MDIO_MODE_AUTO_POLL |
1469                             EMAC_MDIO_MODE_CLOCK_CNT));
1470        val |= (EMAC_MDIO_MODE_CLAUSE_45 |
1471                (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
1472        REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
1473        REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
1474        udelay(40);
1475
1476        /* address */
1477        val = ((phy->addr << 21) | (devad << 16) | reg |
1478               EMAC_MDIO_COMM_COMMAND_ADDRESS |
1479               EMAC_MDIO_COMM_START_BUSY);
1480        REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
1481
1482        for (i = 0; i < 50; i++) {
1483                udelay(10);
1484
1485                val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
1486                if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
1487                        udelay(5);
1488                        break;
1489                }
1490        }
1491        if (val & EMAC_MDIO_COMM_START_BUSY) {
1492                DP(NETIF_MSG_LINK, "read phy register failed\n");
1493
1494                *ret_val = 0;
1495                rc = -EFAULT;
1496
1497        } else {
1498                /* data */
1499                val = ((phy->addr << 21) | (devad << 16) |
1500                       EMAC_MDIO_COMM_COMMAND_READ_45 |
1501                       EMAC_MDIO_COMM_START_BUSY);
1502                REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
1503
1504                for (i = 0; i < 50; i++) {
1505                        udelay(10);
1506
1507                        val = REG_RD(bp, phy->mdio_ctrl +
1508                                          EMAC_REG_EMAC_MDIO_COMM);
1509                        if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
1510                                *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
1511                                break;
1512                        }
1513                }
1514                if (val & EMAC_MDIO_COMM_START_BUSY) {
1515                        DP(NETIF_MSG_LINK, "read phy register failed\n");
1516
1517                        *ret_val = 0;
1518                        rc = -EFAULT;
1519                }
1520        }
1521
1522        /* Restore the saved mode */
1523        REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
1524
1525        return rc;
1526}
1527
1528u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr,
1529                  u8 devad, u16 reg, u16 *ret_val)
1530{
1531        u8 phy_index;
1532        /**
1533         * Probe for the phy according to the given phy_addr, and execute
1534         * the read request on it
1535         */
1536        for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
1537                if (params->phy[phy_index].addr == phy_addr) {
1538                        return bnx2x_cl45_read(params->bp,
1539                                               &params->phy[phy_index], devad,
1540                                               reg, ret_val);
1541                }
1542        }
1543        return -EINVAL;
1544}
1545
1546u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr,
1547                   u8 devad, u16 reg, u16 val)
1548{
1549        u8 phy_index;
1550        /**
1551         * Probe for the phy according to the given phy_addr, and execute
1552         * the write request on it
1553         */
1554        for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
1555                if (params->phy[phy_index].addr == phy_addr) {
1556                        return bnx2x_cl45_write(params->bp,
1557                                                &params->phy[phy_index], devad,
1558                                                reg, val);
1559                }
1560        }
1561        return -EINVAL;
1562}
1563
1564static void bnx2x_set_aer_mmd_xgxs(struct link_params *params,
1565                                   struct bnx2x_phy *phy)
1566{
1567        u32 ser_lane;
1568        u16 offset, aer_val;
1569        struct bnx2x *bp = params->bp;
1570        ser_lane = ((params->lane_config &
1571                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1572                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1573
1574        offset = phy->addr + ser_lane;
1575        if (CHIP_IS_E2(bp))
1576                aer_val = 0x3800 + offset - 1;
1577        else
1578                aer_val = 0x3800 + offset;
1579        CL45_WR_OVER_CL22(bp, phy,
1580                                MDIO_REG_BANK_AER_BLOCK,
1581                                MDIO_AER_BLOCK_AER_REG, aer_val);
1582}
1583static void bnx2x_set_aer_mmd_serdes(struct bnx2x *bp,
1584                                     struct bnx2x_phy *phy)
1585{
1586        CL45_WR_OVER_CL22(bp, phy,
1587                                MDIO_REG_BANK_AER_BLOCK,
1588                                MDIO_AER_BLOCK_AER_REG, 0x3800);
1589}
1590
1591/******************************************************************/
1592/*                      Internal phy section                      */
1593/******************************************************************/
1594
1595static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
1596{
1597        u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1598
1599        /* Set Clause 22 */
1600        REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
1601        REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
1602        udelay(500);
1603        REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
1604        udelay(500);
1605         /* Set Clause 45 */
1606        REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
1607}
1608
1609static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
1610{
1611        u32 val;
1612
1613        DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
1614
1615        val = SERDES_RESET_BITS << (port*16);
1616
1617        /* reset and unreset the SerDes/XGXS */
1618        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
1619        udelay(500);
1620        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
1621
1622        bnx2x_set_serdes_access(bp, port);
1623
1624        REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
1625                     port*0x10,
1626                     DEFAULT_PHY_DEV_ADDR);
1627}
1628
1629static void bnx2x_xgxs_deassert(struct link_params *params)
1630{
1631        struct bnx2x *bp = params->bp;
1632        u8 port;
1633        u32 val;
1634        DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
1635        port = params->port;
1636
1637        val = XGXS_RESET_BITS << (port*16);
1638
1639        /* reset and unreset the SerDes/XGXS */
1640        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
1641        udelay(500);
1642        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
1643
1644        REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
1645                     port*0x18, 0);
1646        REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
1647                     params->phy[INT_PHY].def_md_devad);
1648}
1649
1650
1651void bnx2x_link_status_update(struct link_params *params,
1652                            struct link_vars   *vars)
1653{
1654        struct bnx2x *bp = params->bp;
1655        u8 link_10g;
1656        u8 port = params->port;
1657
1658        vars->link_status = REG_RD(bp, params->shmem_base +
1659                                          offsetof(struct shmem_region,
1660                                           port_mb[port].link_status));
1661
1662        vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
1663
1664        if (vars->link_up) {
1665                DP(NETIF_MSG_LINK, "phy link up\n");
1666
1667                vars->phy_link_up = 1;
1668                vars->duplex = DUPLEX_FULL;
1669                switch (vars->link_status &
1670                                        LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
1671                        case LINK_10THD:
1672                                vars->duplex = DUPLEX_HALF;
1673                                /* fall thru */
1674                        case LINK_10TFD:
1675                                vars->line_speed = SPEED_10;
1676                                break;
1677
1678                        case LINK_100TXHD:
1679                                vars->duplex = DUPLEX_HALF;
1680                                /* fall thru */
1681                        case LINK_100T4:
1682                        case LINK_100TXFD:
1683                                vars->line_speed = SPEED_100;
1684                                break;
1685
1686                        case LINK_1000THD:
1687                                vars->duplex = DUPLEX_HALF;
1688                                /* fall thru */
1689                        case LINK_1000TFD:
1690                                vars->line_speed = SPEED_1000;
1691                                break;
1692
1693                        case LINK_2500THD:
1694                                vars->duplex = DUPLEX_HALF;
1695                                /* fall thru */
1696                        case LINK_2500TFD:
1697                                vars->line_speed = SPEED_2500;
1698                                break;
1699
1700                        case LINK_10GTFD:
1701                                vars->line_speed = SPEED_10000;
1702                                break;
1703
1704                        case LINK_12GTFD:
1705                                vars->line_speed = SPEED_12000;
1706                                break;
1707
1708                        case LINK_12_5GTFD:
1709                                vars->line_speed = SPEED_12500;
1710                                break;
1711
1712                        case LINK_13GTFD:
1713                                vars->line_speed = SPEED_13000;
1714                                break;
1715
1716                        case LINK_15GTFD:
1717                                vars->line_speed = SPEED_15000;
1718                                break;
1719
1720                        case LINK_16GTFD:
1721                                vars->line_speed = SPEED_16000;
1722                                break;
1723
1724                        default:
1725                                break;
1726                }
1727                vars->flow_ctrl = 0;
1728                if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
1729                        vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
1730
1731                if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
1732                        vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
1733
1734                if (!vars->flow_ctrl)
1735                        vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1736
1737                if (vars->line_speed &&
1738                    ((vars->line_speed == SPEED_10) ||
1739                     (vars->line_speed == SPEED_100))) {
1740                        vars->phy_flags |= PHY_SGMII_FLAG;
1741                } else {
1742                        vars->phy_flags &= ~PHY_SGMII_FLAG;
1743                }
1744
1745                /* anything 10 and over uses the bmac */
1746                link_10g = ((vars->line_speed == SPEED_10000) ||
1747                            (vars->line_speed == SPEED_12000) ||
1748                            (vars->line_speed == SPEED_12500) ||
1749                            (vars->line_speed == SPEED_13000) ||
1750                            (vars->line_speed == SPEED_15000) ||
1751                            (vars->line_speed == SPEED_16000));
1752                if (link_10g)
1753                        vars->mac_type = MAC_TYPE_BMAC;
1754                else
1755                        vars->mac_type = MAC_TYPE_EMAC;
1756
1757        } else { /* link down */
1758                DP(NETIF_MSG_LINK, "phy link down\n");
1759
1760                vars->phy_link_up = 0;
1761
1762                vars->line_speed = 0;
1763                vars->duplex = DUPLEX_FULL;
1764                vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1765
1766                /* indicate no mac active */
1767                vars->mac_type = MAC_TYPE_NONE;
1768        }
1769
1770        DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x\n",
1771                 vars->link_status, vars->phy_link_up);
1772        DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
1773                 vars->line_speed, vars->duplex, vars->flow_ctrl);
1774}
1775
1776
1777static void bnx2x_set_master_ln(struct link_params *params,
1778                                struct bnx2x_phy *phy)
1779{
1780        struct bnx2x *bp = params->bp;
1781        u16 new_master_ln, ser_lane;
1782        ser_lane =  ((params->lane_config &
1783                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1784                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1785
1786        /* set the master_ln for AN */
1787        CL45_RD_OVER_CL22(bp, phy,
1788                              MDIO_REG_BANK_XGXS_BLOCK2,
1789                              MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1790                              &new_master_ln);
1791
1792        CL45_WR_OVER_CL22(bp, phy,
1793                              MDIO_REG_BANK_XGXS_BLOCK2 ,
1794                              MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1795                              (new_master_ln | ser_lane));
1796}
1797
1798static u8 bnx2x_reset_unicore(struct link_params *params,
1799                              struct bnx2x_phy *phy,
1800                              u8 set_serdes)
1801{
1802        struct bnx2x *bp = params->bp;
1803        u16 mii_control;
1804        u16 i;
1805
1806        CL45_RD_OVER_CL22(bp, phy,
1807                              MDIO_REG_BANK_COMBO_IEEE0,
1808                              MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
1809
1810        /* reset the unicore */
1811        CL45_WR_OVER_CL22(bp, phy,
1812                              MDIO_REG_BANK_COMBO_IEEE0,
1813                              MDIO_COMBO_IEEE0_MII_CONTROL,
1814                              (mii_control |
1815                               MDIO_COMBO_IEEO_MII_CONTROL_RESET));
1816        if (set_serdes)
1817                bnx2x_set_serdes_access(bp, params->port);
1818
1819        /* wait for the reset to self clear */
1820        for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
1821                udelay(5);
1822
1823                /* the reset erased the previous bank value */
1824                CL45_RD_OVER_CL22(bp, phy,
1825                              MDIO_REG_BANK_COMBO_IEEE0,
1826                              MDIO_COMBO_IEEE0_MII_CONTROL,
1827                              &mii_control);
1828
1829                if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1830                        udelay(5);
1831                        return 0;
1832                }
1833        }
1834
1835        DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1836        return -EINVAL;
1837
1838}
1839
1840static void bnx2x_set_swap_lanes(struct link_params *params,
1841                                 struct bnx2x_phy *phy)
1842{
1843        struct bnx2x *bp = params->bp;
1844        /* Each two bits represents a lane number:
1845           No swap is 0123 => 0x1b no need to enable the swap */
1846        u16 ser_lane, rx_lane_swap, tx_lane_swap;
1847
1848        ser_lane = ((params->lane_config &
1849                         PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1850                        PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1851        rx_lane_swap = ((params->lane_config &
1852                             PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1853                            PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1854        tx_lane_swap = ((params->lane_config &
1855                             PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1856                            PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1857
1858        if (rx_lane_swap != 0x1b) {
1859                CL45_WR_OVER_CL22(bp, phy,
1860                                    MDIO_REG_BANK_XGXS_BLOCK2,
1861                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1862                                    (rx_lane_swap |
1863                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1864                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1865        } else {
1866                CL45_WR_OVER_CL22(bp, phy,
1867                                      MDIO_REG_BANK_XGXS_BLOCK2,
1868                                      MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1869        }
1870
1871        if (tx_lane_swap != 0x1b) {
1872                CL45_WR_OVER_CL22(bp, phy,
1873                                      MDIO_REG_BANK_XGXS_BLOCK2,
1874                                      MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1875                                      (tx_lane_swap |
1876                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1877        } else {
1878                CL45_WR_OVER_CL22(bp, phy,
1879                                      MDIO_REG_BANK_XGXS_BLOCK2,
1880                                      MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1881        }
1882}
1883
1884static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
1885                                         struct link_params *params)
1886{
1887        struct bnx2x *bp = params->bp;
1888        u16 control2;
1889        CL45_RD_OVER_CL22(bp, phy,
1890                              MDIO_REG_BANK_SERDES_DIGITAL,
1891                              MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1892                              &control2);
1893        if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
1894                control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1895        else
1896                control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1897        DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
1898                phy->speed_cap_mask, control2);
1899        CL45_WR_OVER_CL22(bp, phy,
1900                              MDIO_REG_BANK_SERDES_DIGITAL,
1901                              MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1902                              control2);
1903
1904        if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
1905             (phy->speed_cap_mask &
1906                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
1907                DP(NETIF_MSG_LINK, "XGXS\n");
1908
1909                CL45_WR_OVER_CL22(bp, phy,
1910                                MDIO_REG_BANK_10G_PARALLEL_DETECT,
1911                                MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1912                                MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1913
1914                CL45_RD_OVER_CL22(bp, phy,
1915                                MDIO_REG_BANK_10G_PARALLEL_DETECT,
1916                                MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1917                                &control2);
1918
1919
1920                control2 |=
1921                    MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1922
1923                CL45_WR_OVER_CL22(bp, phy,
1924                                MDIO_REG_BANK_10G_PARALLEL_DETECT,
1925                                MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1926                                control2);
1927
1928                /* Disable parallel detection of HiG */
1929                CL45_WR_OVER_CL22(bp, phy,
1930                                MDIO_REG_BANK_XGXS_BLOCK2,
1931                                MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1932                                MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1933                                MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1934        }
1935}
1936
1937static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
1938                              struct link_params *params,
1939                            struct link_vars *vars,
1940                            u8 enable_cl73)
1941{
1942        struct bnx2x *bp = params->bp;
1943        u16 reg_val;
1944
1945        /* CL37 Autoneg */
1946        CL45_RD_OVER_CL22(bp, phy,
1947                              MDIO_REG_BANK_COMBO_IEEE0,
1948                              MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1949
1950        /* CL37 Autoneg Enabled */
1951        if (vars->line_speed == SPEED_AUTO_NEG)
1952                reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1953        else /* CL37 Autoneg Disabled */
1954                reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1955                             MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1956
1957        CL45_WR_OVER_CL22(bp, phy,
1958                              MDIO_REG_BANK_COMBO_IEEE0,
1959                              MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1960
1961        /* Enable/Disable Autodetection */
1962
1963        CL45_RD_OVER_CL22(bp, phy,
1964                              MDIO_REG_BANK_SERDES_DIGITAL,
1965                              MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1966        reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
1967                    MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
1968        reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
1969        if (vars->line_speed == SPEED_AUTO_NEG)
1970                reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1971        else
1972                reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1973
1974        CL45_WR_OVER_CL22(bp, phy,
1975                              MDIO_REG_BANK_SERDES_DIGITAL,
1976                              MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1977
1978        /* Enable TetonII and BAM autoneg */
1979        CL45_RD_OVER_CL22(bp, phy,
1980                              MDIO_REG_BANK_BAM_NEXT_PAGE,
1981                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1982                          &reg_val);
1983        if (vars->line_speed == SPEED_AUTO_NEG) {
1984                /* Enable BAM aneg Mode and TetonII aneg Mode */
1985                reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1986                            MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1987        } else {
1988                /* TetonII and BAM Autoneg Disabled */
1989                reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1990                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1991        }
1992        CL45_WR_OVER_CL22(bp, phy,
1993                              MDIO_REG_BANK_BAM_NEXT_PAGE,
1994                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1995                              reg_val);
1996
1997        if (enable_cl73) {
1998                /* Enable Cl73 FSM status bits */
1999                CL45_WR_OVER_CL22(bp, phy,
2000                                      MDIO_REG_BANK_CL73_USERB0,
2001                                    MDIO_CL73_USERB0_CL73_UCTRL,
2002                                      0xe);
2003
2004                /* Enable BAM Station Manager*/
2005                CL45_WR_OVER_CL22(bp, phy,
2006                        MDIO_REG_BANK_CL73_USERB0,
2007                        MDIO_CL73_USERB0_CL73_BAM_CTRL1,
2008                        MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
2009                        MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
2010                        MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
2011
2012                /* Advertise CL73 link speeds */
2013                CL45_RD_OVER_CL22(bp, phy,
2014                                              MDIO_REG_BANK_CL73_IEEEB1,
2015                                              MDIO_CL73_IEEEB1_AN_ADV2,
2016                                              &reg_val);
2017                if (phy->speed_cap_mask &
2018                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2019                        reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
2020                if (phy->speed_cap_mask &
2021                    PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
2022                        reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
2023
2024                CL45_WR_OVER_CL22(bp, phy,
2025                                              MDIO_REG_BANK_CL73_IEEEB1,
2026                                              MDIO_CL73_IEEEB1_AN_ADV2,
2027                                      reg_val);
2028
2029                /* CL73 Autoneg Enabled */
2030                reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
2031
2032        } else /* CL73 Autoneg Disabled */
2033                reg_val = 0;
2034
2035        CL45_WR_OVER_CL22(bp, phy,
2036                              MDIO_REG_BANK_CL73_IEEEB0,
2037                              MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
2038}
2039
2040/* program SerDes, forced speed */
2041static void bnx2x_program_serdes(struct bnx2x_phy *phy,
2042                                 struct link_params *params,
2043                               struct link_vars *vars)
2044{
2045        struct bnx2x *bp = params->bp;
2046        u16 reg_val;
2047
2048        /* program duplex, disable autoneg and sgmii*/
2049        CL45_RD_OVER_CL22(bp, phy,
2050                              MDIO_REG_BANK_COMBO_IEEE0,
2051                              MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
2052        reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
2053                     MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
2054                     MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
2055        if (phy->req_duplex == DUPLEX_FULL)
2056                reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
2057        CL45_WR_OVER_CL22(bp, phy,
2058                              MDIO_REG_BANK_COMBO_IEEE0,
2059                              MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
2060
2061        /* program speed
2062           - needed only if the speed is greater than 1G (2.5G or 10G) */
2063        CL45_RD_OVER_CL22(bp, phy,
2064                                      MDIO_REG_BANK_SERDES_DIGITAL,
2065                                      MDIO_SERDES_DIGITAL_MISC1, &reg_val);
2066        /* clearing the speed value before setting the right speed */
2067        DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
2068
2069        reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
2070                     MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
2071
2072        if (!((vars->line_speed == SPEED_1000) ||
2073              (vars->line_speed == SPEED_100) ||
2074              (vars->line_speed == SPEED_10))) {
2075
2076                reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
2077                            MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
2078                if (vars->line_speed == SPEED_10000)
2079                        reg_val |=
2080                                MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
2081                if (vars->line_speed == SPEED_13000)
2082                        reg_val |=
2083                                MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
2084        }
2085
2086        CL45_WR_OVER_CL22(bp, phy,
2087                                      MDIO_REG_BANK_SERDES_DIGITAL,
2088                                      MDIO_SERDES_DIGITAL_MISC1, reg_val);
2089
2090}
2091
2092static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x_phy *phy,
2093                                             struct link_params *params)
2094{
2095        struct bnx2x *bp = params->bp;
2096        u16 val = 0;
2097
2098        /* configure the 48 bits for BAM AN */
2099
2100        /* set extended capabilities */
2101        if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
2102                val |= MDIO_OVER_1G_UP1_2_5G;
2103        if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2104                val |= MDIO_OVER_1G_UP1_10G;
2105        CL45_WR_OVER_CL22(bp, phy,
2106                              MDIO_REG_BANK_OVER_1G,
2107                              MDIO_OVER_1G_UP1, val);
2108
2109        CL45_WR_OVER_CL22(bp, phy,
2110                              MDIO_REG_BANK_OVER_1G,
2111                              MDIO_OVER_1G_UP3, 0x400);
2112}
2113
2114static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
2115                                     struct link_params *params, u16 *ieee_fc)
2116{
2117        struct bnx2x *bp = params->bp;
2118        *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
2119        /* resolve pause mode and advertisement
2120         * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
2121
2122        switch (phy->req_flow_ctrl) {
2123        case BNX2X_FLOW_CTRL_AUTO:
2124                if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
2125                        *ieee_fc |=
2126                             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2127                } else {
2128                        *ieee_fc |=
2129                       MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2130                }
2131                break;
2132        case BNX2X_FLOW_CTRL_TX:
2133                *ieee_fc |=
2134                       MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2135                break;
2136
2137        case BNX2X_FLOW_CTRL_RX:
2138        case BNX2X_FLOW_CTRL_BOTH:
2139                *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2140                break;
2141
2142        case BNX2X_FLOW_CTRL_NONE:
2143        default:
2144                *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
2145                break;
2146        }
2147        DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
2148}
2149
2150static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x_phy *phy,
2151                                             struct link_params *params,
2152                                           u16 ieee_fc)
2153{
2154        struct bnx2x *bp = params->bp;
2155        u16 val;
2156        /* for AN, we are always publishing full duplex */
2157
2158        CL45_WR_OVER_CL22(bp, phy,
2159                              MDIO_REG_BANK_COMBO_IEEE0,
2160                              MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
2161        CL45_RD_OVER_CL22(bp, phy,
2162                              MDIO_REG_BANK_CL73_IEEEB1,
2163                              MDIO_CL73_IEEEB1_AN_ADV1, &val);
2164        val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
2165        val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
2166        CL45_WR_OVER_CL22(bp, phy,
2167                              MDIO_REG_BANK_CL73_IEEEB1,
2168                              MDIO_CL73_IEEEB1_AN_ADV1, val);
2169}
2170
2171static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
2172                                  struct link_params *params,
2173                                  u8 enable_cl73)
2174{
2175        struct bnx2x *bp = params->bp;
2176        u16 mii_control;
2177
2178        DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
2179        /* Enable and restart BAM/CL37 aneg */
2180
2181        if (enable_cl73) {
2182                CL45_RD_OVER_CL22(bp, phy,
2183                                      MDIO_REG_BANK_CL73_IEEEB0,
2184                                      MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2185                                      &mii_control);
2186
2187                CL45_WR_OVER_CL22(bp, phy,
2188                                MDIO_REG_BANK_CL73_IEEEB0,
2189                                MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2190                                (mii_control |
2191                                MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
2192                                MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
2193        } else {
2194
2195                CL45_RD_OVER_CL22(bp, phy,
2196                                      MDIO_REG_BANK_COMBO_IEEE0,
2197                                      MDIO_COMBO_IEEE0_MII_CONTROL,
2198                                      &mii_control);
2199                DP(NETIF_MSG_LINK,
2200                         "bnx2x_restart_autoneg mii_control before = 0x%x\n",
2201                         mii_control);
2202                CL45_WR_OVER_CL22(bp, phy,
2203                                      MDIO_REG_BANK_COMBO_IEEE0,
2204                                      MDIO_COMBO_IEEE0_MII_CONTROL,
2205                                      (mii_control |
2206                                       MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
2207                                       MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
2208        }
2209}
2210
2211static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
2212                                           struct link_params *params,
2213                                         struct link_vars *vars)
2214{
2215        struct bnx2x *bp = params->bp;
2216        u16 control1;
2217
2218        /* in SGMII mode, the unicore is always slave */
2219
2220        CL45_RD_OVER_CL22(bp, phy,
2221                              MDIO_REG_BANK_SERDES_DIGITAL,
2222                              MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
2223                      &control1);
2224        control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
2225        /* set sgmii mode (and not fiber) */
2226        control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
2227                      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
2228                      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
2229        CL45_WR_OVER_CL22(bp, phy,
2230                              MDIO_REG_BANK_SERDES_DIGITAL,
2231                              MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
2232                              control1);
2233
2234        /* if forced speed */
2235        if (!(vars->line_speed == SPEED_AUTO_NEG)) {
2236                /* set speed, disable autoneg */
2237                u16 mii_control;
2238
2239                CL45_RD_OVER_CL22(bp, phy,
2240                                      MDIO_REG_BANK_COMBO_IEEE0,
2241                                      MDIO_COMBO_IEEE0_MII_CONTROL,
2242                                      &mii_control);
2243                mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
2244                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
2245                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
2246
2247                switch (vars->line_speed) {
2248                case SPEED_100:
2249                        mii_control |=
2250                                MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
2251                        break;
2252                case SPEED_1000:
2253                        mii_control |=
2254                                MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
2255                        break;
2256                case SPEED_10:
2257                        /* there is nothing to set for 10M */
2258                        break;
2259                default:
2260                        /* invalid speed for SGMII */
2261                        DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2262                                  vars->line_speed);
2263                        break;
2264                }
2265
2266                /* setting the full duplex */
2267                if (phy->req_duplex == DUPLEX_FULL)
2268                        mii_control |=
2269                                MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
2270                CL45_WR_OVER_CL22(bp, phy,
2271                                      MDIO_REG_BANK_COMBO_IEEE0,
2272                                      MDIO_COMBO_IEEE0_MII_CONTROL,
2273                                      mii_control);
2274
2275        } else { /* AN mode */
2276                /* enable and restart AN */
2277                bnx2x_restart_autoneg(phy, params, 0);
2278        }
2279}
2280
2281
2282/*
2283 * link management
2284 */
2285
2286static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
2287{                                               /*  LD      LP   */
2288        switch (pause_result) {                 /* ASYM P ASYM P */
2289        case 0xb:                               /*   1  0   1  1 */
2290                vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
2291                break;
2292
2293        case 0xe:                               /*   1  1   1  0 */
2294                vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
2295                break;
2296
2297        case 0x5:                               /*   0  1   0  1 */
2298        case 0x7:                               /*   0  1   1  1 */
2299        case 0xd:                               /*   1  1   0  1 */
2300        case 0xf:                               /*   1  1   1  1 */
2301                vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
2302                break;
2303
2304        default:
2305                break;
2306        }
2307        if (pause_result & (1<<0))
2308                vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
2309        if (pause_result & (1<<1))
2310                vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
2311}
2312
2313static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
2314                                            struct link_params *params)
2315{
2316        struct bnx2x *bp = params->bp;
2317        u16 pd_10g, status2_1000x;
2318        if (phy->req_line_speed != SPEED_AUTO_NEG)
2319                return 0;
2320        CL45_RD_OVER_CL22(bp, phy,
2321                              MDIO_REG_BANK_SERDES_DIGITAL,
2322                              MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
2323                              &status2_1000x);
2324        CL45_RD_OVER_CL22(bp, phy,
2325                              MDIO_REG_BANK_SERDES_DIGITAL,
2326                              MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
2327                              &status2_1000x);
2328        if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
2329                DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
2330                         params->port);
2331                return 1;
2332        }
2333
2334        CL45_RD_OVER_CL22(bp, phy,
2335                              MDIO_REG_BANK_10G_PARALLEL_DETECT,
2336                              MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
2337                              &pd_10g);
2338
2339        if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
2340                DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
2341                         params->port);
2342                return 1;
2343        }
2344        return 0;
2345}
2346
2347static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
2348                                    struct link_params *params,
2349                                    struct link_vars *vars,
2350                                    u32 gp_status)
2351{
2352        struct bnx2x *bp = params->bp;
2353        u16 ld_pause;   /* local driver */
2354        u16 lp_pause;   /* link partner */
2355        u16 pause_result;
2356
2357        vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
2358
2359        /* resolve from gp_status in case of AN complete and not sgmii */
2360        if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
2361                vars->flow_ctrl = phy->req_flow_ctrl;
2362        else if (phy->req_line_speed != SPEED_AUTO_NEG)
2363                vars->flow_ctrl = params->req_fc_auto_adv;
2364        else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
2365                 (!(vars->phy_flags & PHY_SGMII_FLAG))) {
2366                if (bnx2x_direct_parallel_detect_used(phy, params)) {
2367                        vars->flow_ctrl = params->req_fc_auto_adv;
2368                        return;
2369                }
2370                if ((gp_status &
2371                    (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
2372                     MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
2373                    (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
2374                     MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
2375
2376                        CL45_RD_OVER_CL22(bp, phy,
2377                                              MDIO_REG_BANK_CL73_IEEEB1,
2378                                              MDIO_CL73_IEEEB1_AN_ADV1,
2379                                              &ld_pause);
2380                        CL45_RD_OVER_CL22(bp, phy,
2381                                             MDIO_REG_BANK_CL73_IEEEB1,
2382                                             MDIO_CL73_IEEEB1_AN_LP_ADV1,
2383                                             &lp_pause);
2384                        pause_result = (ld_pause &
2385                                        MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
2386                                        >> 8;
2387                        pause_result |= (lp_pause &
2388                                        MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
2389                                        >> 10;
2390                        DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
2391                                 pause_result);
2392                } else {
2393                        CL45_RD_OVER_CL22(bp, phy,
2394                                              MDIO_REG_BANK_COMBO_IEEE0,
2395                                              MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
2396                                              &ld_pause);
2397                        CL45_RD_OVER_CL22(bp, phy,
2398                               MDIO_REG_BANK_COMBO_IEEE0,
2399                               MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
2400                               &lp_pause);
2401                        pause_result = (ld_pause &
2402                                MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
2403                        pause_result |= (lp_pause &
2404                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
2405                        DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
2406                                 pause_result);
2407                }
2408                bnx2x_pause_resolve(vars, pause_result);
2409        }
2410        DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
2411}
2412
2413static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
2414                                         struct link_params *params)
2415{
2416        struct bnx2x *bp = params->bp;
2417        u16 rx_status, ustat_val, cl37_fsm_recieved;
2418        DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
2419        /* Step 1: Make sure signal is detected */
2420        CL45_RD_OVER_CL22(bp, phy,
2421                              MDIO_REG_BANK_RX0,
2422                              MDIO_RX0_RX_STATUS,
2423                              &rx_status);
2424        if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
2425            (MDIO_RX0_RX_STATUS_SIGDET)) {
2426                DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
2427                             "rx_status(0x80b0) = 0x%x\n", rx_status);
2428                CL45_WR_OVER_CL22(bp, phy,
2429                                      MDIO_REG_BANK_CL73_IEEEB0,
2430                                      MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2431                                      MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
2432                return;
2433        }
2434        /* Step 2: Check CL73 state machine */
2435        CL45_RD_OVER_CL22(bp, phy,
2436                              MDIO_REG_BANK_CL73_USERB0,
2437                              MDIO_CL73_USERB0_CL73_USTAT1,
2438                              &ustat_val);
2439        if ((ustat_val &
2440             (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
2441              MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
2442            (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
2443              MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
2444                DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
2445                             "ustat_val(0x8371) = 0x%x\n", ustat_val);
2446                return;
2447        }
2448        /* Step 3: Check CL37 Message Pages received to indicate LP
2449        supports only CL37 */
2450        CL45_RD_OVER_CL22(bp, phy,
2451                              MDIO_REG_BANK_REMOTE_PHY,
2452                              MDIO_REMOTE_PHY_MISC_RX_STATUS,
2453                              &cl37_fsm_recieved);
2454        if ((cl37_fsm_recieved &
2455             (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
2456             MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
2457            (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
2458              MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
2459                DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
2460                             "misc_rx_status(0x8330) = 0x%x\n",
2461                         cl37_fsm_recieved);
2462                return;
2463        }
2464        /* The combined cl37/cl73 fsm state information indicating that we are
2465        connected to a device which does not support cl73, but does support
2466        cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */
2467        /* Disable CL73 */
2468        CL45_WR_OVER_CL22(bp, phy,
2469                              MDIO_REG_BANK_CL73_IEEEB0,
2470                              MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
2471                              0);
2472        /* Restart CL37 autoneg */
2473        bnx2x_restart_autoneg(phy, params, 0);
2474        DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
2475}
2476
2477static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
2478                                  struct link_params *params,
2479                                  struct link_vars *vars,
2480                                  u32 gp_status)
2481{
2482        if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
2483                vars->link_status |=
2484                        LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
2485
2486        if (bnx2x_direct_parallel_detect_used(phy, params))
2487                vars->link_status |=
2488                        LINK_STATUS_PARALLEL_DETECTION_USED;
2489}
2490
2491static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy,
2492                                     struct link_params *params,
2493                                     struct link_vars *vars)
2494{
2495        struct bnx2x *bp = params->bp;
2496        u16 new_line_speed , gp_status;
2497        u8 rc = 0;
2498
2499        /* Read gp_status */
2500        CL45_RD_OVER_CL22(bp, phy,
2501                                MDIO_REG_BANK_GP_STATUS,
2502                                MDIO_GP_STATUS_TOP_AN_STATUS1,
2503                                &gp_status);
2504
2505        if (phy->req_line_speed == SPEED_AUTO_NEG)
2506                vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
2507        if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
2508                DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
2509                         gp_status);
2510
2511                vars->phy_link_up = 1;
2512                vars->link_status |= LINK_STATUS_LINK_UP;
2513
2514                if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
2515                        vars->duplex = DUPLEX_FULL;
2516                else
2517                        vars->duplex = DUPLEX_HALF;
2518
2519                if (SINGLE_MEDIA_DIRECT(params)) {
2520                        bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
2521                        if (phy->req_line_speed == SPEED_AUTO_NEG)
2522                                bnx2x_xgxs_an_resolve(phy, params, vars,
2523                                                      gp_status);
2524                }
2525
2526                switch (gp_status & GP_STATUS_SPEED_MASK) {
2527                case GP_STATUS_10M:
2528                        new_line_speed = SPEED_10;
2529                        if (vars->duplex == DUPLEX_FULL)
2530                                vars->link_status |= LINK_10TFD;
2531                        else
2532                                vars->link_status |= LINK_10THD;
2533                        break;
2534
2535                case GP_STATUS_100M:
2536                        new_line_speed = SPEED_100;
2537                        if (vars->duplex == DUPLEX_FULL)
2538                                vars->link_status |= LINK_100TXFD;
2539                        else
2540                                vars->link_status |= LINK_100TXHD;
2541                        break;
2542
2543                case GP_STATUS_1G:
2544                case GP_STATUS_1G_KX:
2545                        new_line_speed = SPEED_1000;
2546                        if (vars->duplex == DUPLEX_FULL)
2547                                vars->link_status |= LINK_1000TFD;
2548                        else
2549                                vars->link_status |= LINK_1000THD;
2550                        break;
2551
2552                case GP_STATUS_2_5G:
2553                        new_line_speed = SPEED_2500;
2554                        if (vars->duplex == DUPLEX_FULL)
2555                                vars->link_status |= LINK_2500TFD;
2556                        else
2557                                vars->link_status |= LINK_2500THD;
2558                        break;
2559
2560                case GP_STATUS_5G:
2561                case GP_STATUS_6G:
2562                        DP(NETIF_MSG_LINK,
2563                                 "link speed unsupported  gp_status 0x%x\n",
2564                                  gp_status);
2565                        return -EINVAL;
2566
2567                case GP_STATUS_10G_KX4:
2568                case GP_STATUS_10G_HIG:
2569                case GP_STATUS_10G_CX4:
2570                        new_line_speed = SPEED_10000;
2571                        vars->link_status |= LINK_10GTFD;
2572                        break;
2573
2574                case GP_STATUS_12G_HIG:
2575                        new_line_speed = SPEED_12000;
2576                        vars->link_status |= LINK_12GTFD;
2577                        break;
2578
2579                case GP_STATUS_12_5G:
2580                        new_line_speed = SPEED_12500;
2581                        vars->link_status |= LINK_12_5GTFD;
2582                        break;
2583
2584                case GP_STATUS_13G:
2585                        new_line_speed = SPEED_13000;
2586                        vars->link_status |= LINK_13GTFD;
2587                        break;
2588
2589                case GP_STATUS_15G:
2590                        new_line_speed = SPEED_15000;
2591                        vars->link_status |= LINK_15GTFD;
2592                        break;
2593
2594                case GP_STATUS_16G:
2595                        new_line_speed = SPEED_16000;
2596                        vars->link_status |= LINK_16GTFD;
2597                        break;
2598
2599                default:
2600                        DP(NETIF_MSG_LINK,
2601                                  "link speed unsupported gp_status 0x%x\n",
2602                                  gp_status);
2603                        return -EINVAL;
2604                }
2605
2606                vars->line_speed = new_line_speed;
2607
2608        } else { /* link_down */
2609                DP(NETIF_MSG_LINK, "phy link down\n");
2610
2611                vars->phy_link_up = 0;
2612
2613                vars->duplex = DUPLEX_FULL;
2614                vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
2615                vars->mac_type = MAC_TYPE_NONE;
2616
2617                if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
2618                    SINGLE_MEDIA_DIRECT(params)) {
2619                        /* Check signal is detected */
2620                        bnx2x_check_fallback_to_cl37(phy, params);
2621                }
2622        }
2623
2624        DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %x line_speed %x\n",
2625                 gp_status, vars->phy_link_up, vars->line_speed);
2626        DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
2627                   vars->duplex, vars->flow_ctrl, vars->link_status);
2628        return rc;
2629}
2630
2631static void bnx2x_set_gmii_tx_driver(struct link_params *params)
2632{
2633        struct bnx2x *bp = params->bp;
2634        struct bnx2x_phy *phy = &params->phy[INT_PHY];
2635        u16 lp_up2;
2636        u16 tx_driver;
2637        u16 bank;
2638
2639        /* read precomp */
2640        CL45_RD_OVER_CL22(bp, phy,
2641                              MDIO_REG_BANK_OVER_1G,
2642                              MDIO_OVER_1G_LP_UP2, &lp_up2);
2643
2644        /* bits [10:7] at lp_up2, positioned at [15:12] */
2645        lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
2646                   MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
2647                  MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
2648
2649        if (lp_up2 == 0)
2650                return;
2651
2652        for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
2653              bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
2654                CL45_RD_OVER_CL22(bp, phy,
2655                                      bank,
2656                                      MDIO_TX0_TX_DRIVER, &tx_driver);
2657
2658                /* replace tx_driver bits [15:12] */
2659                if (lp_up2 !=
2660                    (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
2661                        tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
2662                        tx_driver |= lp_up2;
2663                        CL45_WR_OVER_CL22(bp, phy,
2664                                              bank,
2665                                              MDIO_TX0_TX_DRIVER, tx_driver);
2666                }
2667        }
2668}
2669
2670static u8 bnx2x_emac_program(struct link_params *params,
2671                             struct link_vars *vars)
2672{
2673        struct bnx2x *bp = params->bp;
2674        u8 port = params->port;
2675        u16 mode = 0;
2676
2677        DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
2678        bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
2679                     EMAC_REG_EMAC_MODE,
2680                     (EMAC_MODE_25G_MODE |
2681                     EMAC_MODE_PORT_MII_10M |
2682                     EMAC_MODE_HALF_DUPLEX));
2683        switch (vars->line_speed) {
2684        case SPEED_10:
2685                mode |= EMAC_MODE_PORT_MII_10M;
2686                break;
2687
2688        case SPEED_100:
2689                mode |= EMAC_MODE_PORT_MII;
2690                break;
2691
2692        case SPEED_1000:
2693                mode |= EMAC_MODE_PORT_GMII;
2694                break;
2695
2696        case SPEED_2500:
2697                mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
2698                break;
2699
2700        default:
2701                /* 10G not valid for EMAC */
2702                DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2703                           vars->line_speed);
2704                return -EINVAL;
2705        }
2706
2707        if (vars->duplex == DUPLEX_HALF)
2708                mode |= EMAC_MODE_HALF_DUPLEX;
2709        bnx2x_bits_en(bp,
2710                    GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
2711                    mode);
2712
2713        bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
2714        return 0;
2715}
2716
2717static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
2718                                  struct link_params *params)
2719{
2720
2721        u16 bank, i = 0;
2722        struct bnx2x *bp = params->bp;
2723
2724        for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
2725              bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
2726                        CL45_WR_OVER_CL22(bp, phy,
2727                                          bank,
2728                                          MDIO_RX0_RX_EQ_BOOST,
2729                                          phy->rx_preemphasis[i]);
2730        }
2731
2732        for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
2733                      bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
2734                        CL45_WR_OVER_CL22(bp, phy,
2735                                          bank,
2736                                          MDIO_TX0_TX_DRIVER,
2737                                          phy->tx_preemphasis[i]);
2738        }
2739}
2740
2741static void bnx2x_init_internal_phy(struct bnx2x_phy *phy,
2742                                    struct link_params *params,
2743                                    struct link_vars *vars)
2744{
2745        struct bnx2x *bp = params->bp;
2746        u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
2747                          (params->loopback_mode == LOOPBACK_XGXS));
2748        if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2749                if (SINGLE_MEDIA_DIRECT(params) &&
2750                    (params->feature_config_flags &
2751                     FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
2752                        bnx2x_set_preemphasis(phy, params);
2753
2754                /* forced speed requested? */
2755                if (vars->line_speed != SPEED_AUTO_NEG ||
2756                    (SINGLE_MEDIA_DIRECT(params) &&
2757                          params->loopback_mode == LOOPBACK_EXT)) {
2758                        DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2759
2760                        /* disable autoneg */
2761                        bnx2x_set_autoneg(phy, params, vars, 0);
2762
2763                        /* program speed and duplex */
2764                        bnx2x_program_serdes(phy, params, vars);
2765
2766                } else { /* AN_mode */
2767                        DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2768
2769                        /* AN enabled */
2770                        bnx2x_set_brcm_cl37_advertisment(phy, params);
2771
2772                        /* program duplex & pause advertisement (for aneg) */
2773                        bnx2x_set_ieee_aneg_advertisment(phy, params,
2774                                                       vars->ieee_fc);
2775
2776                        /* enable autoneg */
2777                        bnx2x_set_autoneg(phy, params, vars, enable_cl73);
2778
2779                        /* enable and restart AN */
2780                        bnx2x_restart_autoneg(phy, params, enable_cl73);
2781                }
2782
2783        } else { /* SGMII mode */
2784                DP(NETIF_MSG_LINK, "SGMII\n");
2785
2786                bnx2x_initialize_sgmii_process(phy, params, vars);
2787        }
2788}
2789
2790static u8 bnx2x_init_serdes(struct bnx2x_phy *phy,
2791                            struct link_params *params,
2792                            struct link_vars *vars)
2793{
2794        u8 rc;
2795        vars->phy_flags |= PHY_SGMII_FLAG;
2796        bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2797        bnx2x_set_aer_mmd_serdes(params->bp, phy);
2798        rc = bnx2x_reset_unicore(params, phy, 1);
2799        /* reset the SerDes and wait for reset bit return low */
2800        if (rc != 0)
2801                return rc;
2802        bnx2x_set_aer_mmd_serdes(params->bp, phy);
2803
2804        return rc;
2805}
2806
2807static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy,
2808                          struct link_params *params,
2809                          struct link_vars *vars)
2810{
2811        u8 rc;
2812        vars->phy_flags = PHY_XGXS_FLAG;
2813        if ((phy->req_line_speed &&
2814             ((phy->req_line_speed == SPEED_100) ||
2815              (phy->req_line_speed == SPEED_10))) ||
2816            (!phy->req_line_speed &&
2817             (phy->speed_cap_mask >=
2818              PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
2819             (phy->speed_cap_mask <
2820              PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
2821             ))
2822                vars->phy_flags |= PHY_SGMII_FLAG;
2823        else
2824                vars->phy_flags &= ~PHY_SGMII_FLAG;
2825
2826        bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2827        bnx2x_set_aer_mmd_xgxs(params, phy);
2828        bnx2x_set_master_ln(params, phy);
2829
2830        rc = bnx2x_reset_unicore(params, phy, 0);
2831        /* reset the SerDes and wait for reset bit return low */
2832        if (rc != 0)
2833                return rc;
2834
2835        bnx2x_set_aer_mmd_xgxs(params, phy);
2836
2837        /* setting the masterLn_def again after the reset */
2838        bnx2x_set_master_ln(params, phy);
2839        bnx2x_set_swap_lanes(params, phy);
2840
2841        return rc;
2842}
2843
2844static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
2845                                     struct bnx2x_phy *phy)
2846{
2847        u16 cnt, ctrl;
2848        /* Wait for soft reset to get cleared upto 1 sec */
2849        for (cnt = 0; cnt < 1000; cnt++) {
2850                bnx2x_cl45_read(bp, phy,
2851                                MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl);
2852                if (!(ctrl & (1<<15)))
2853                        break;
2854                msleep(1);
2855        }
2856        DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
2857        return cnt;
2858}
2859
2860static void bnx2x_link_int_enable(struct link_params *params)
2861{
2862        u8 port = params->port;
2863        u32 mask;
2864        struct bnx2x *bp = params->bp;
2865
2866        /* setting the status to report on link up
2867           for either XGXS or SerDes */
2868
2869        if (params->switch_cfg == SWITCH_CFG_10G) {
2870                mask = (NIG_MASK_XGXS0_LINK10G |
2871                        NIG_MASK_XGXS0_LINK_STATUS);
2872                DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
2873                if (!(SINGLE_MEDIA_DIRECT(params)) &&
2874                        params->phy[INT_PHY].type !=
2875                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
2876                        mask |= NIG_MASK_MI_INT;
2877                        DP(NETIF_MSG_LINK, "enabled external phy int\n");
2878                }
2879
2880        } else { /* SerDes */
2881                mask = NIG_MASK_SERDES0_LINK_STATUS;
2882                DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
2883                if (!(SINGLE_MEDIA_DIRECT(params)) &&
2884                        params->phy[INT_PHY].type !=
2885                                PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
2886                        mask |= NIG_MASK_MI_INT;
2887                        DP(NETIF_MSG_LINK, "enabled external phy int\n");
2888                }
2889        }
2890        bnx2x_bits_en(bp,
2891                      NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
2892                      mask);
2893
2894        DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
2895                 (params->switch_cfg == SWITCH_CFG_10G),
2896                 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
2897        DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
2898                 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
2899                 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
2900                 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
2901        DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
2902           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
2903           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
2904}
2905
2906static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port,
2907                                     u8 exp_mi_int)
2908{
2909        u32 latch_status = 0;
2910
2911        /**
2912         * Disable the MI INT ( external phy int ) by writing 1 to the
2913         * status register. Link down indication is high-active-signal,
2914         * so in this case we need to write the status to clear the XOR
2915         */
2916        /* Read Latched signals */
2917        latch_status = REG_RD(bp,
2918                                    NIG_REG_LATCH_STATUS_0 + port*8);
2919        DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status);
2920        /* Handle only those with latched-signal=up.*/
2921        if (exp_mi_int)
2922                bnx2x_bits_en(bp,
2923                              NIG_REG_STATUS_INTERRUPT_PORT0
2924                              + port*4,
2925                              NIG_STATUS_EMAC0_MI_INT);
2926        else
2927                bnx2x_bits_dis(bp,
2928                               NIG_REG_STATUS_INTERRUPT_PORT0
2929                               + port*4,
2930                               NIG_STATUS_EMAC0_MI_INT);
2931
2932        if (latch_status & 1) {
2933
2934                /* For all latched-signal=up : Re-Arm Latch signals */
2935                REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
2936                             (latch_status & 0xfffe) | (latch_status & 1));
2937        }
2938        /* For all latched-signal=up,Write original_signal to status */
2939}
2940
2941static void bnx2x_link_int_ack(struct link_params *params,
2942                             struct link_vars *vars, u8 is_10g)
2943{
2944        struct bnx2x *bp = params->bp;
2945        u8 port = params->port;
2946
2947        /* first reset all status
2948         * we assume only one line will be change at a time */
2949        bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2950                     (NIG_STATUS_XGXS0_LINK10G |
2951                      NIG_STATUS_XGXS0_LINK_STATUS |
2952                      NIG_STATUS_SERDES0_LINK_STATUS));
2953        if (vars->phy_link_up) {
2954                if (is_10g) {
2955                        /* Disable the 10G link interrupt
2956                         * by writing 1 to the status register
2957                         */
2958                        DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
2959                        bnx2x_bits_en(bp,
2960                                      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2961                                      NIG_STATUS_XGXS0_LINK10G);
2962
2963                } else if (params->switch_cfg == SWITCH_CFG_10G) {
2964                        /* Disable the link interrupt
2965                         * by writing 1 to the relevant lane
2966                         * in the status register
2967                         */
2968                        u32 ser_lane = ((params->lane_config &
2969                                    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
2970                                    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
2971
2972                        DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
2973                                 vars->line_speed);
2974                        bnx2x_bits_en(bp,
2975                                      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2976                                      ((1 << ser_lane) <<
2977                                       NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
2978
2979                } else { /* SerDes */
2980                        DP(NETIF_MSG_LINK, "SerDes phy link up\n");
2981                        /* Disable the link interrupt
2982                         * by writing 1 to the status register
2983                         */
2984                        bnx2x_bits_en(bp,
2985                                      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2986                                      NIG_STATUS_SERDES0_LINK_STATUS);
2987                }
2988
2989        }
2990}
2991
2992static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len)
2993{
2994        u8 *str_ptr = str;
2995        u32 mask = 0xf0000000;
2996        u8 shift = 8*4;
2997        u8 digit;
2998        u8 remove_leading_zeros = 1;
2999        if (*len < 10) {
3000                /* Need more than 10chars for this format */
3001                *str_ptr = '\0';
3002                (*len)--;
3003                return -EINVAL;
3004        }
3005        while (shift > 0) {
3006
3007                shift -= 4;
3008                digit = ((num & mask) >> shift);
3009                if (digit == 0 && remove_leading_zeros) {
3010                        mask = mask >> 4;
3011                        continue;
3012                } else if (digit < 0xa)
3013                        *str_ptr = digit + '0';
3014                else
3015                        *str_ptr = digit - 0xa + 'a';
3016                remove_leading_zeros = 0;
3017                str_ptr++;
3018                (*len)--;
3019                mask = mask >> 4;
3020                if (shift == 4*4) {
3021                        *str_ptr = '.';
3022                        str_ptr++;
3023                        (*len)--;
3024                        remove_leading_zeros = 1;
3025                }
3026        }
3027        return 0;
3028}
3029
3030
3031static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
3032{
3033        str[0] = '\0';
3034        (*len)--;
3035        return 0;
3036}
3037
3038u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3039                              u8 *version, u16 len)
3040{
3041        struct bnx2x *bp;
3042        u32 spirom_ver = 0;
3043        u8 status = 0;
3044        u8 *ver_p = version;
3045        u16 remain_len = len;
3046        if (version == NULL || params == NULL)
3047                return -EINVAL;
3048        bp = params->bp;
3049
3050        /* Extract first external phy*/
3051        version[0] = '\0';
3052        spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
3053
3054        if (params->phy[EXT_PHY1].format_fw_ver) {
3055                status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
3056                                                              ver_p,
3057                                                              &remain_len);
3058                ver_p += (len - remain_len);
3059        }
3060        if ((params->num_phys == MAX_PHYS) &&
3061            (params->phy[EXT_PHY2].ver_addr != 0)) {
3062                spirom_ver = REG_RD(bp,
3063                                          params->phy[EXT_PHY2].ver_addr);
3064                if (params->phy[EXT_PHY2].format_fw_ver) {
3065                        *ver_p = '/';
3066                        ver_p++;
3067                        remain_len--;
3068                        status |= params->phy[EXT_PHY2].format_fw_ver(
3069                                spirom_ver,
3070                                ver_p,
3071                                &remain_len);
3072                        ver_p = version + (len - remain_len);
3073                }
3074        }
3075        *ver_p = '\0';
3076        return status;
3077}
3078
3079static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
3080                                    struct link_params *params)
3081{
3082        u8 port = params->port;
3083        struct bnx2x *bp = params->bp;
3084
3085        if (phy->req_line_speed != SPEED_1000) {
3086                u32 md_devad;
3087
3088                DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
3089
3090                /* change the uni_phy_addr in the nig */
3091                md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
3092                                          port*0x18));
3093
3094                REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
3095
3096                bnx2x_cl45_write(bp, phy,
3097                               5,
3098                               (MDIO_REG_BANK_AER_BLOCK +
3099                                (MDIO_AER_BLOCK_AER_REG & 0xf)),
3100                               0x2800);
3101
3102                bnx2x_cl45_write(bp, phy,
3103                               5,
3104                               (MDIO_REG_BANK_CL73_IEEEB0 +
3105                                (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
3106                               0x6041);
3107                msleep(200);
3108                /* set aer mmd back */
3109                bnx2x_set_aer_mmd_xgxs(params, phy);
3110
3111                /* and md_devad */
3112                REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
3113                            md_devad);
3114
3115        } else {
3116                u16 mii_ctrl;
3117                DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
3118                bnx2x_cl45_read(bp, phy, 5,
3119                                (MDIO_REG_BANK_COMBO_IEEE0 +
3120                                (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
3121                                &mii_ctrl);
3122                bnx2x_cl45_write(bp, phy, 5,
3123                                 (MDIO_REG_BANK_COMBO_IEEE0 +
3124                                 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
3125                                 mii_ctrl |
3126                                 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
3127        }
3128}
3129
3130u8 bnx2x_set_led(struct link_params *params,
3131                 struct link_vars *vars, u8 mode, u32 speed)
3132{
3133        u8 port = params->port;
3134        u16 hw_led_mode = params->hw_led_mode;
3135        u8 rc = 0, phy_idx;
3136        u32 tmp;
3137        u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3138        struct bnx2x *bp = params->bp;
3139        DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
3140        DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
3141                 speed, hw_led_mode);
3142        /* In case */
3143        for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) {
3144                if (params->phy[phy_idx].set_link_led) {
3145                        params->phy[phy_idx].set_link_led(
3146                                &params->phy[phy_idx], params, mode);
3147                }
3148        }
3149
3150        switch (mode) {
3151        case LED_MODE_FRONT_PANEL_OFF:
3152        case LED_MODE_OFF:
3153                REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
3154                REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
3155                           SHARED_HW_CFG_LED_MAC1);
3156
3157                tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3158                EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
3159                break;
3160
3161        case LED_MODE_OPER:
3162                /**
3163                 * For all other phys, OPER mode is same as ON, so in case
3164                 * link is down, do nothing
3165                 **/
3166                if (!vars->link_up)
3167                        break;
3168        case LED_MODE_ON:
3169                if (params->phy[EXT_PHY1].type ==
3170                    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727 &&
3171                    CHIP_IS_E2(bp) && params->num_phys == 2) {
3172                        /**
3173                        * This is a work-around for E2+8727 Configurations
3174                        */
3175                        if (mode == LED_MODE_ON ||
3176                                speed == SPEED_10000){
3177                                REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
3178                                REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
3179
3180                                tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3181                                EMAC_WR(bp, EMAC_REG_EMAC_LED,
3182                                        (tmp | EMAC_LED_OVERRIDE));
3183                                return rc;
3184                        }
3185                } else if (SINGLE_MEDIA_DIRECT(params)) {
3186                        /**
3187                        * This is a work-around for HW issue found when link
3188                        * is up in CL73
3189                        */
3190                        REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
3191                        REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
3192                } else {
3193                        REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
3194                                   hw_led_mode);
3195                }
3196
3197                REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
3198                           port*4, 0);
3199                /* Set blinking rate to ~15.9Hz */
3200                REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
3201                           LED_BLINK_RATE_VAL);
3202                REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
3203                           port*4, 1);
3204                tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3205                EMAC_WR(bp, EMAC_REG_EMAC_LED,
3206                            (tmp & (~EMAC_LED_OVERRIDE)));
3207
3208                if (CHIP_IS_E1(bp) &&
3209                    ((speed == SPEED_2500) ||
3210                     (speed == SPEED_1000) ||
3211                     (speed == SPEED_100) ||
3212                     (speed == SPEED_10))) {
3213                        /* On Everest 1 Ax chip versions for speeds less than
3214                        10G LED scheme is different */
3215                        REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3216                                   + port*4, 1);
3217                        REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
3218                                   port*4, 0);
3219                        REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
3220                                   port*4, 1);
3221                }
3222                break;
3223
3224        default:
3225                rc = -EINVAL;
3226                DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
3227                         mode);
3228                break;
3229        }
3230        return rc;
3231
3232}
3233
3234/**
3235 * This function comes to reflect the actual link state read DIRECTLY from the
3236 * HW
3237 */
3238u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars,
3239                   u8 is_serdes)
3240{
3241        struct bnx2x *bp = params->bp;
3242        u16 gp_status = 0, phy_index = 0;
3243        u8 ext_phy_link_up = 0, serdes_phy_type;
3244        struct link_vars temp_vars;
3245
3246        CL45_RD_OVER_CL22(bp, &params->phy[INT_PHY],
3247                              MDIO_REG_BANK_GP_STATUS,
3248                              MDIO_GP_STATUS_TOP_AN_STATUS1,
3249                              &gp_status);
3250        /* link is up only if both local phy and external phy are up */
3251        if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
3252                return -ESRCH;
3253
3254        switch (params->num_phys) {
3255        case 1:
3256                /* No external PHY */
3257                return 0;
3258        case 2:
3259                ext_phy_link_up = params->phy[EXT_PHY1].read_status(
3260                        &params->phy[EXT_PHY1],
3261                        params, &temp_vars);
3262                break;
3263        case 3: /* Dual Media */
3264                for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3265                      phy_index++) {
3266                        serdes_phy_type = ((params->phy[phy_index].media_type ==
3267                                            ETH_PHY_SFP_FIBER) ||
3268                                           (params->phy[phy_index].media_type ==
3269                                            ETH_PHY_XFP_FIBER));
3270
3271                        if (is_serdes != serdes_phy_type)
3272                                continue;
3273                        if (params->phy[phy_index].read_status) {
3274                                ext_phy_link_up |=
3275                                        params->phy[phy_index].read_status(
3276                                                &params->phy[phy_index],
3277                                                params, &temp_vars);
3278                        }
3279                }
3280                break;
3281        }
3282        if (ext_phy_link_up)
3283                return 0;
3284        return -ESRCH;
3285}
3286
3287static u8 bnx2x_link_initialize(struct link_params *params,
3288                                struct link_vars *vars)
3289{
3290        u8 rc = 0;
3291        u8 phy_index, non_ext_phy;
3292        struct bnx2x *bp = params->bp;
3293        /**
3294        * In case of external phy existence, the line speed would be the
3295        * line speed linked up by the external phy. In case it is direct
3296        * only, then the line_speed during initialization will be
3297        * equal to the req_line_speed
3298        */
3299        vars->line_speed = params->phy[INT_PHY].req_line_speed;
3300
3301        /**
3302         * Initialize the internal phy in case this is a direct board
3303         * (no external phys), or this board has external phy which requires
3304         * to first.
3305         */
3306
3307        if (params->phy[INT_PHY].config_init)
3308                params->phy[INT_PHY].config_init(
3309                        &params->phy[INT_PHY],
3310                        params, vars);
3311
3312        /* init ext phy and enable link state int */
3313        non_ext_phy = (SINGLE_MEDIA_DIRECT(params) ||
3314                       (params->loopback_mode == LOOPBACK_XGXS));
3315
3316        if (non_ext_phy ||
3317            (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) ||
3318            (params->loopback_mode == LOOPBACK_EXT_PHY)) {
3319                struct bnx2x_phy *phy = &params->phy[INT_PHY];
3320                if (vars->line_speed == SPEED_AUTO_NEG)
3321                        bnx2x_set_parallel_detection(phy, params);
3322                bnx2x_init_internal_phy(phy, params, vars);
3323        }
3324
3325        /* Init external phy*/
3326        if (!non_ext_phy)
3327                for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3328                      phy_index++) {
3329                        /**
3330                         * No need to initialize second phy in case of first
3331                         * phy only selection. In case of second phy, we do
3332                         * need to initialize the first phy, since they are
3333                         * connected.
3334                         **/
3335                        if (phy_index == EXT_PHY2 &&
3336                            (bnx2x_phy_selection(params) ==
3337                             PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
3338                                DP(NETIF_MSG_LINK, "Not initializing"
3339                                                   "second phy\n");
3340                                continue;
3341                        }
3342                        params->phy[phy_index].config_init(
3343                                &params->phy[phy_index],
3344                                params, vars);
3345                }
3346
3347        /* Reset the interrupt indication after phy was initialized */
3348        bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
3349                       params->port*4,
3350                       (NIG_STATUS_XGXS0_LINK10G |
3351                        NIG_STATUS_XGXS0_LINK_STATUS |
3352                        NIG_STATUS_SERDES0_LINK_STATUS |
3353                        NIG_MASK_MI_INT));
3354        return rc;
3355}
3356
3357static void bnx2x_int_link_reset(struct bnx2x_phy *phy,
3358                                 struct link_params *params)
3359{
3360        /* reset the SerDes/XGXS */
3361        REG_WR(params->bp, GRCBASE_MISC +
3362                     MISC_REGISTERS_RESET_REG_3_CLEAR,
3363                     (0x1ff << (params->port*16)));
3364}
3365
3366static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
3367                                        struct link_params *params)
3368{
3369        struct bnx2x *bp = params->bp;
3370        u8 gpio_port;
3371        /* HW reset */
3372        if (CHIP_IS_E2(bp))
3373                gpio_port = BP_PATH(bp);
3374        else
3375                gpio_port = params->port;
3376        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3377                            MISC_REGISTERS_GPIO_OUTPUT_LOW,
3378                            gpio_port);
3379        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3380                            MISC_REGISTERS_GPIO_OUTPUT_LOW,
3381                            gpio_port);
3382        DP(NETIF_MSG_LINK, "reset external PHY\n");
3383}
3384
3385static u8 bnx2x_update_link_down(struct link_params *params,
3386                               struct link_vars *vars)
3387{
3388        struct bnx2x *bp = params->bp;
3389        u8 port = params->port;
3390
3391        DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
3392        bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
3393
3394        /* indicate no mac active */
3395        vars->mac_type = MAC_TYPE_NONE;
3396
3397        /* update shared memory */
3398        vars->link_status = 0;
3399        vars->line_speed = 0;
3400        bnx2x_update_mng(params, vars->link_status);
3401
3402        /* activate nig drain */
3403        REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
3404
3405        /* disable emac */
3406        REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
3407
3408        msleep(10);
3409
3410        /* reset BigMac */
3411        bnx2x_bmac_rx_disable(bp, params->port);
3412        REG_WR(bp, GRCBASE_MISC +
3413                   MISC_REGISTERS_RESET_REG_2_CLEAR,
3414                   (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
3415        return 0;
3416}
3417
3418static u8 bnx2x_update_link_up(struct link_params *params,
3419                             struct link_vars *vars,
3420                             u8 link_10g)
3421{
3422        struct bnx2x *bp = params->bp;
3423        u8 port = params->port;
3424        u8 rc = 0;
3425
3426        vars->link_status |= LINK_STATUS_LINK_UP;
3427
3428        if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
3429                vars->link_status |=
3430                        LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
3431
3432        if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
3433                vars->link_status |=
3434                        LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
3435
3436        if (link_10g) {
3437                bnx2x_bmac_enable(params, vars, 0);
3438                bnx2x_set_led(params, vars,
3439                              LED_MODE_OPER, SPEED_10000);
3440        } else {
3441                rc = bnx2x_emac_program(params, vars);
3442
3443                bnx2x_emac_enable(params, vars, 0);
3444
3445                /* AN complete? */
3446                if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
3447                    && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
3448                    SINGLE_MEDIA_DIRECT(params))
3449                        bnx2x_set_gmii_tx_driver(params);
3450        }
3451
3452        /* PBF - link up */
3453        if (!(CHIP_IS_E2(bp)))
3454                rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
3455                                       vars->line_speed);
3456
3457        /* disable drain */
3458        REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
3459
3460        /* update shared memory */
3461        bnx2x_update_mng(params, vars->link_status);
3462        msleep(20);
3463        return rc;
3464}
3465/**
3466 * The bnx2x_link_update function should be called upon link
3467 * interrupt.
3468 * Link is considered up as follows:
3469 * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
3470 *   to be up
3471 * - SINGLE_MEDIA - The link between the 577xx and the external
3472 *   phy (XGXS) need to up as well as the external link of the
3473 *   phy (PHY_EXT1)
3474 * - DUAL_MEDIA - The link between the 577xx and the first
3475 *   external phy needs to be up, and at least one of the 2
3476 *   external phy link must be up.
3477 */
3478u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
3479{
3480        struct bnx2x *bp = params->bp;
3481        struct link_vars phy_vars[MAX_PHYS];
3482        u8 port = params->port;
3483        u8 link_10g, phy_index;
3484        u8 ext_phy_link_up = 0, cur_link_up, rc = 0;
3485        u8 is_mi_int = 0;
3486        u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
3487        u8 active_external_phy = INT_PHY;
3488        vars->link_status = 0;
3489        for (phy_index = INT_PHY; phy_index < params->num_phys;
3490              phy_index++) {
3491                phy_vars[phy_index].flow_ctrl = 0;
3492                phy_vars[phy_index].link_status = 0;
3493                phy_vars[phy_index].line_speed = 0;
3494                phy_vars[phy_index].duplex = DUPLEX_FULL;
3495                phy_vars[phy_index].phy_link_up = 0;
3496                phy_vars[phy_index].link_up = 0;
3497        }
3498
3499        DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
3500                 port, (vars->phy_flags & PHY_XGXS_FLAG),
3501                 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
3502
3503        is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
3504                                    port*0x18) > 0);
3505        DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
3506                 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
3507                 is_mi_int,
3508                 REG_RD(bp,
3509                            NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
3510
3511        DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
3512          REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
3513          REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
3514
3515        /* disable emac */
3516        REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
3517
3518        /**
3519        * Step 1:
3520        * Check external link change only for external phys, and apply
3521        * priority selection between them in case the link on both phys
3522        * is up. Note that the instead of the common vars, a temporary
3523        * vars argument is used since each phy may have different link/
3524        * speed/duplex result
3525        */
3526        for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3527              phy_index++) {
3528                struct bnx2x_phy *phy = &params->phy[phy_index];
3529                if (!phy->read_status)
3530                        continue;
3531                /* Read link status and params of this ext phy */
3532                cur_link_up = phy->read_status(phy, params,
3533                                               &phy_vars[phy_index]);
3534                if (cur_link_up) {
3535                        DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
3536                                   phy_index);
3537                } else {
3538                        DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
3539                                   phy_index);
3540                        continue;
3541                }
3542
3543                if (!ext_phy_link_up) {
3544                        ext_phy_link_up = 1;
3545                        active_external_phy = phy_index;
3546                } else {
3547                        switch (bnx2x_phy_selection(params)) {
3548                        case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
3549                        case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
3550                        /**
3551                         * In this option, the first PHY makes sure to pass the
3552                         * traffic through itself only.
3553                         * Its not clear how to reset the link on the second phy
3554                         **/
3555                                active_external_phy = EXT_PHY1;
3556                                break;
3557                        case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
3558                        /**
3559                         * In this option, the first PHY makes sure to pass the
3560                         * traffic through the second PHY.
3561                         **/
3562                                active_external_phy = EXT_PHY2;
3563                                break;
3564                        default:
3565                        /**
3566                         * Link indication on both PHYs with the following cases
3567                         * is invalid:
3568                         * - FIRST_PHY means that second phy wasn't initialized,
3569                         * hence its link is expected to be down
3570                         * - SECOND_PHY means that first phy should not be able
3571                         * to link up by itself (using configuration)
3572                         * - DEFAULT should be overriden during initialiazation
3573                         **/
3574                                DP(NETIF_MSG_LINK, "Invalid link indication"
3575                                           "mpc=0x%x. DISABLING LINK !!!\n",
3576                                           params->multi_phy_config);
3577                                ext_phy_link_up = 0;
3578                                break;
3579                        }
3580                }
3581        }
3582        prev_line_speed = vars->line_speed;
3583        /**
3584        * Step 2:
3585        * Read the status of the internal phy. In case of
3586        * DIRECT_SINGLE_MEDIA board, this link is the external link,
3587        * otherwise this is the link between the 577xx and the first
3588        * external phy
3589        */
3590        if (params->phy[INT_PHY].read_status)
3591                params->phy[INT_PHY].read_status(
3592                        &params->phy[INT_PHY],
3593                        params, vars);
3594        /**
3595         * The INT_PHY flow control reside in the vars. This include the
3596         * case where the speed or flow control are not set to AUTO.
3597         * Otherwise, the active external phy flow control result is set
3598         * to the vars. The ext_phy_line_speed is needed to check if the
3599         * speed is different between the internal phy and external phy.
3600         * This case may be result of intermediate link speed change.
3601         */
3602        if (active_external_phy > INT_PHY) {
3603                vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
3604                /**
3605                 * Link speed is taken from the XGXS. AN and FC result from
3606                 * the external phy.
3607                 */
3608                vars->link_status |= phy_vars[active_external_phy].link_status;
3609
3610                /**
3611                 * if active_external_phy is first PHY and link is up - disable
3612                 * disable TX on second external PHY
3613                 */
3614                if (active_external_phy == EXT_PHY1) {
3615                        if (params->phy[EXT_PHY2].phy_specific_func) {
3616                                DP(NETIF_MSG_LINK, "Disabling TX on"
3617                                                   " EXT_PHY2\n");
3618                                params->phy[EXT_PHY2].phy_specific_func(
3619                                        &params->phy[EXT_PHY2],
3620                                        params, DISABLE_TX);
3621                        }
3622                }
3623
3624                ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
3625                vars->duplex = phy_vars[active_external_phy].duplex;
3626                if (params->phy[active_external_phy].supported &
3627                    SUPPORTED_FIBRE)
3628                        vars->link_status |= LINK_STATUS_SERDES_LINK;
3629                DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
3630                           active_external_phy);
3631        }
3632
3633        for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3634              phy_index++) {
3635                if (params->phy[phy_index].flags &
3636                    FLAGS_REARM_LATCH_SIGNAL) {
3637                        bnx2x_rearm_latch_signal(bp, port,
3638                                                 phy_index ==
3639                                                 active_external_phy);
3640                        break;
3641                }
3642        }
3643        DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
3644                   " ext_phy_line_speed = %d\n", vars->flow_ctrl,
3645                   vars->link_status, ext_phy_line_speed);
3646        /**
3647         * Upon link speed change set the NIG into drain mode. Comes to
3648         * deals with possible FIFO glitch due to clk change when speed
3649         * is decreased without link down indicator
3650         */
3651
3652        if (vars->phy_link_up) {
3653                if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
3654                    (ext_phy_line_speed != vars->line_speed)) {
3655                        DP(NETIF_MSG_LINK, "Internal link speed %d is"
3656                                   " different than the external"
3657                                   " link speed %d\n", vars->line_speed,
3658                                   ext_phy_line_speed);
3659                        vars->phy_link_up = 0;
3660                } else if (prev_line_speed != vars->line_speed) {
3661                        REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3662                                     + params->port*4, 0);
3663                        msleep(1);
3664                }
3665        }
3666
3667        /* anything 10 and over uses the bmac */
3668        link_10g = ((vars->line_speed == SPEED_10000) ||
3669                    (vars->line_speed == SPEED_12000) ||
3670                    (vars->line_speed == SPEED_12500) ||
3671                    (vars->line_speed == SPEED_13000) ||
3672                    (vars->line_speed == SPEED_15000) ||
3673                    (vars->line_speed == SPEED_16000));
3674
3675        bnx2x_link_int_ack(params, vars, link_10g);
3676
3677        /**
3678        * In case external phy link is up, and internal link is down
3679        * (not initialized yet probably after link initialization, it
3680        * needs to be initialized.
3681        * Note that after link down-up as result of cable plug, the xgxs
3682        * link would probably become up again without the need
3683        * initialize it
3684        */
3685        if (!(SINGLE_MEDIA_DIRECT(params))) {
3686                DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
3687                           " init_preceding = %d\n", ext_phy_link_up,
3688                           vars->phy_link_up,
3689                           params->phy[EXT_PHY1].flags &
3690                           FLAGS_INIT_XGXS_FIRST);
3691                if (!(params->phy[EXT_PHY1].flags &
3692                      FLAGS_INIT_XGXS_FIRST)
3693                    && ext_phy_link_up && !vars->phy_link_up) {
3694                        vars->line_speed = ext_phy_line_speed;
3695                        if (vars->line_speed < SPEED_1000)
3696                                vars->phy_flags |= PHY_SGMII_FLAG;
3697                        else
3698                                vars->phy_flags &= ~PHY_SGMII_FLAG;
3699                        bnx2x_init_internal_phy(&params->phy[INT_PHY],
3700                                                params,
3701                                                vars);
3702                }
3703        }
3704        /**
3705         *  Link is up only if both local phy and external phy (in case of
3706         *  non-direct board) are up
3707         */
3708        vars->link_up = (vars->phy_link_up &&
3709                         (ext_phy_link_up ||
3710                          SINGLE_MEDIA_DIRECT(params)));
3711
3712        if (vars->link_up)
3713                rc = bnx2x_update_link_up(params, vars, link_10g);
3714        else
3715                rc = bnx2x_update_link_down(params, vars);
3716
3717        return rc;
3718}
3719
3720
3721/*****************************************************************************/
3722/*                          External Phy section                             */
3723/*****************************************************************************/
3724void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
3725{
3726        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3727                            MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
3728        msleep(1);
3729        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3730                            MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
3731}
3732
3733static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
3734                                      u32 spirom_ver, u32 ver_addr)
3735{
3736        DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
3737                 (u16)(spirom_ver>>16), (u16)spirom_ver, port);
3738
3739        if (ver_addr)
3740                REG_WR(bp, ver_addr, spirom_ver);
3741}
3742
3743static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp,
3744                                      struct bnx2x_phy *phy,
3745                                      u8 port)
3746{
3747        u16 fw_ver1, fw_ver2;
3748
3749        bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
3750                      MDIO_PMA_REG_ROM_VER1, &fw_ver1);
3751        bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
3752                      MDIO_PMA_REG_ROM_VER2, &fw_ver2);
3753        bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2),
3754                                  phy->ver_addr);
3755}
3756
3757static void bnx2x_ext_phy_set_pause(struct link_params *params,
3758                                    struct bnx2x_phy *phy,
3759                                    struct link_vars *vars)
3760{
3761        u16 val;
3762        struct bnx2x *bp = params->bp;
3763        /* read modify write pause advertizing */
3764        bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
3765
3766        val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3767
3768        /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3769        bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
3770        if ((vars->ieee_fc &
3771            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3772            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3773                val |=  MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3774        }
3775        if ((vars->ieee_fc &
3776            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3777            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3778                val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
3779        }
3780        DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
3781        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
3782}
3783
3784static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
3785                                   struct link_params *params,
3786                                   struct link_vars *vars)
3787{
3788        struct bnx2x *bp = params->bp;
3789        u16 ld_pause;           /* local */
3790        u16 lp_pause;           /* link partner */
3791        u16 pause_result;
3792        u8 ret = 0;
3793        /* read twice */
3794
3795        vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3796
3797        if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
3798                vars->flow_ctrl = phy->req_flow_ctrl;
3799        else if (phy->req_line_speed != SPEED_AUTO_NEG)
3800                vars->flow_ctrl = params->req_fc_auto_adv;
3801        else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
3802                ret = 1;
3803                bnx2x_cl45_read(bp, phy,
3804                              MDIO_AN_DEVAD,
3805                              MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3806                bnx2x_cl45_read(bp, phy,
3807                              MDIO_AN_DEVAD,
3808                              MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3809                pause_result = (ld_pause &
3810                                MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
3811                pause_result |= (lp_pause &
3812                                 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
3813                DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
3814                   pause_result);
3815                bnx2x_pause_resolve(vars, pause_result);
3816        }
3817        return ret;
3818}
3819
3820static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp,
3821                                       struct bnx2x_phy *phy,
3822                                       struct link_vars *vars)
3823{
3824        u16 val;
3825        bnx2x_cl45_read(bp, phy,
3826                        MDIO_AN_DEVAD,
3827                        MDIO_AN_REG_STATUS, &val);
3828        bnx2x_cl45_read(bp, phy,
3829                        MDIO_AN_DEVAD,
3830                        MDIO_AN_REG_STATUS, &val);
3831        if (val & (1<<5))
3832                vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
3833        if ((val & (1<<0)) == 0)
3834                vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
3835}
3836
3837/******************************************************************/
3838/*              common BCM8073/BCM8727 PHY SECTION                */
3839/******************************************************************/
3840static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
3841                                  struct link_params *params,
3842                                  struct link_vars *vars)
3843{
3844        struct bnx2x *bp = params->bp;
3845        if (phy->req_line_speed == SPEED_10 ||
3846            phy->req_line_speed == SPEED_100) {
3847                vars->flow_ctrl = phy->req_flow_ctrl;
3848                return;
3849        }
3850
3851        if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
3852            (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) {
3853                u16 pause_result;
3854                u16 ld_pause;           /* local */
3855                u16 lp_pause;           /* link partner */
3856                bnx2x_cl45_read(bp, phy,
3857                                MDIO_AN_DEVAD,
3858                                MDIO_AN_REG_CL37_FC_LD, &ld_pause);
3859
3860                bnx2x_cl45_read(bp, phy,
3861                                MDIO_AN_DEVAD,
3862                                MDIO_AN_REG_CL37_FC_LP, &lp_pause);
3863                pause_result = (ld_pause &
3864                                MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
3865                pause_result |= (lp_pause &
3866                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
3867
3868                bnx2x_pause_resolve(vars, pause_result);
3869                DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
3870                           pause_result);
3871        }
3872}
3873static u8 bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
3874                                              struct bnx2x_phy *phy,
3875                                              u8 port)
3876{
3877        u32 count = 0;
3878        u16 fw_ver1, fw_msgout;
3879        u8 rc = 0;
3880
3881        /* Boot port from external ROM  */
3882        /* EDC grst */
3883        bnx2x_cl45_write(bp, phy,
3884                       MDIO_PMA_DEVAD,
3885                       MDIO_PMA_REG_GEN_CTRL,
3886                       0x0001);
3887
3888        /* ucode reboot and rst */
3889        bnx2x_cl45_write(bp, phy,
3890                       MDIO_PMA_DEVAD,
3891                       MDIO_PMA_REG_GEN_CTRL,
3892                       0x008c);
3893
3894        bnx2x_cl45_write(bp, phy,
3895                       MDIO_PMA_DEVAD,
3896                       MDIO_PMA_REG_MISC_CTRL1, 0x0001);
3897
3898        /* Reset internal microprocessor */
3899        bnx2x_cl45_write(bp, phy,
3900                       MDIO_PMA_DEVAD,
3901                       MDIO_PMA_REG_GEN_CTRL,
3902                       MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
3903
3904        /* Release srst bit */
3905        bnx2x_cl45_write(bp, phy,
3906                       MDIO_PMA_DEVAD,
3907                       MDIO_PMA_REG_GEN_CTRL,
3908                       MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
3909
3910        /* Delay 100ms per the PHY specifications */
3911        msleep(100);
3912
3913        /* 8073 sometimes taking longer to download */
3914        do {
3915                count++;
3916                if (count > 300) {
3917                        DP(NETIF_MSG_LINK,
3918                                 "bnx2x_8073_8727_external_rom_boot port %x:"
3919                                 "Download failed. fw version = 0x%x\n",
3920                                 port, fw_ver1);
3921                        rc = -EINVAL;
3922                        break;
3923                }
3924
3925                bnx2x_cl45_read(bp, phy,
3926                                MDIO_PMA_DEVAD,
3927                                MDIO_PMA_REG_ROM_VER1, &fw_ver1);
3928                bnx2x_cl45_read(bp, phy,
3929                                MDIO_PMA_DEVAD,
3930                                MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
3931
3932                msleep(1);
3933        } while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
3934                        ((fw_msgout & 0xff) != 0x03 && (phy->type ==
3935                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)));
3936
3937        /* Clear ser_boot_ctl bit */
3938        bnx2x_cl45_write(bp, phy,
3939                       MDIO_PMA_DEVAD,
3940                       MDIO_PMA_REG_MISC_CTRL1, 0x0000);
3941        bnx2x_save_bcm_spirom_ver(bp, phy, port);
3942
3943        DP(NETIF_MSG_LINK,
3944                 "bnx2x_8073_8727_external_rom_boot port %x:"
3945                 "Download complete. fw version = 0x%x\n",
3946                 port, fw_ver1);
3947
3948        return rc;
3949}
3950
3951/******************************************************************/
3952/*                      BCM8073 PHY SECTION                       */
3953/******************************************************************/
3954static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
3955{
3956        /* This is only required for 8073A1, version 102 only */
3957        u16 val;
3958
3959        /* Read 8073 HW revision*/
3960        bnx2x_cl45_read(bp, phy,
3961                      MDIO_PMA_DEVAD,
3962                      MDIO_PMA_REG_8073_CHIP_REV, &val);
3963
3964        if (val != 1) {
3965                /* No need to workaround in 8073 A1 */
3966                return 0;
3967        }
3968
3969        bnx2x_cl45_read(bp, phy,
3970                      MDIO_PMA_DEVAD,
3971                      MDIO_PMA_REG_ROM_VER2, &val);
3972
3973        /* SNR should be applied only for version 0x102 */
3974        if (val != 0x102)
3975                return 0;
3976
3977        return 1;
3978}
3979
3980static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
3981{
3982        u16 val, cnt, cnt1 ;
3983
3984        bnx2x_cl45_read(bp, phy,
3985                      MDIO_PMA_DEVAD,
3986                      MDIO_PMA_REG_8073_CHIP_REV, &val);
3987
3988        if (val > 0) {
3989                /* No need to workaround in 8073 A1 */
3990                return 0;
3991        }
3992        /* XAUI workaround in 8073 A0: */
3993
3994        /* After loading the boot ROM and restarting Autoneg,
3995        poll Dev1, Reg $C820: */
3996
3997        for (cnt = 0; cnt < 1000; cnt++) {
3998                bnx2x_cl45_read(bp, phy,
3999                              MDIO_PMA_DEVAD,
4000                              MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
4001                              &val);
4002                  /* If bit [14] = 0 or bit [13] = 0, continue on with
4003                   system initialization (XAUI work-around not required,
4004                    as these bits indicate 2.5G or 1G link up). */
4005                if (!(val & (1<<14)) || !(val & (1<<13))) {
4006                        DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
4007                        return 0;
4008                } else if (!(val & (1<<15))) {
4009                        DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
4010                         /* If bit 15 is 0, then poll Dev1, Reg $C841 until
4011                          it's MSB (bit 15) goes to 1 (indicating that the
4012                          XAUI workaround has completed),
4013                          then continue on with system initialization.*/
4014                        for (cnt1 = 0; cnt1 < 1000; cnt1++) {
4015                                bnx2x_cl45_read(bp, phy,
4016                                        MDIO_PMA_DEVAD,
4017                                        MDIO_PMA_REG_8073_XAUI_WA, &val);
4018                                if (val & (1<<15)) {
4019                                        DP(NETIF_MSG_LINK,
4020                                          "XAUI workaround has completed\n");
4021                                        return 0;
4022                                 }
4023                                 msleep(3);
4024                        }
4025                        break;
4026                }
4027                msleep(3);
4028        }
4029        DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
4030        return -EINVAL;
4031}
4032
4033static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy)
4034{
4035        /* Force KR or KX */
4036        bnx2x_cl45_write(bp, phy,
4037                         MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
4038        bnx2x_cl45_write(bp, phy,
4039                         MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
4040        bnx2x_cl45_write(bp, phy,
4041                         MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
4042        bnx2x_cl45_write(bp, phy,
4043                         MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
4044}
4045
4046static void bnx2x_8073_set_pause_cl37(struct link_params *params,
4047                                      struct bnx2x_phy *phy,
4048                                      struct link_vars *vars)
4049{
4050        u16 cl37_val;
4051        struct bnx2x *bp = params->bp;
4052        bnx2x_cl45_read(bp, phy,
4053                        MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
4054
4055        cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
4056        /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
4057        bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
4058        if ((vars->ieee_fc &
4059            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
4060            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
4061                cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
4062        }
4063        if ((vars->ieee_fc &
4064            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
4065            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
4066                cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
4067        }
4068        if ((vars->ieee_fc &
4069            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
4070            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
4071                cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
4072        }
4073        DP(NETIF_MSG_LINK,
4074                 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
4075
4076        bnx2x_cl45_write(bp, phy,
4077                         MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
4078        msleep(500);
4079}
4080
4081static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy,
4082                                 struct link_params *params,
4083                                 struct link_vars *vars)
4084{
4085        struct bnx2x *bp = params->bp;
4086        u16 val = 0, tmp1;
4087        u8 gpio_port;
4088        DP(NETIF_MSG_LINK, "Init 8073\n");
4089
4090        if (CHIP_IS_E2(bp))
4091                gpio_port = BP_PATH(bp);
4092        else
4093                gpio_port = params->port;
4094        /* Restore normal power mode*/
4095        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4096                            MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
4097
4098        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4099                            MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
4100
4101        /* enable LASI */
4102        bnx2x_cl45_write(bp, phy,
4103                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2));
4104        bnx2x_cl45_write(bp, phy,
4105                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,  0x0004);
4106
4107        bnx2x_8073_set_pause_cl37(params, phy, vars);
4108
4109        bnx2x_cl45_read(bp, phy,
4110                        MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
4111
4112        bnx2x_cl45_read(bp, phy,
4113                        MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
4114
4115        DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
4116
4117        /**
4118         * If this is forced speed, set to KR or KX (all other are not
4119         * supported)
4120         */
4121        /* Swap polarity if required - Must be done only in non-1G mode */
4122        if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
4123                /* Configure the 8073 to swap _P and _N of the KR lines */
4124                DP(NETIF_MSG_LINK, "Swapping polarity for the 8073\n");
4125                /* 10G Rx/Tx and 1G Tx signal polarity swap */
4126                bnx2x_cl45_read(bp, phy,
4127                                MDIO_PMA_DEVAD,
4128                                MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
4129                bnx2x_cl45_write(bp, phy,
4130                                 MDIO_PMA_DEVAD,
4131                                 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
4132                                 (val | (3<<9)));
4133        }
4134
4135
4136        /* Enable CL37 BAM */
4137        if (REG_RD(bp, params->shmem_base +
4138                         offsetof(struct shmem_region, dev_info.
4139                                  port_hw_config[params->port].default_cfg)) &
4140            PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
4141
4142                bnx2x_cl45_read(bp, phy,
4143                                MDIO_AN_DEVAD,
4144                                MDIO_AN_REG_8073_BAM, &val);
4145                bnx2x_cl45_write(bp, phy,
4146                                 MDIO_AN_DEVAD,
4147                                 MDIO_AN_REG_8073_BAM, val | 1);
4148                DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
4149        }
4150        if (params->loopback_mode == LOOPBACK_EXT) {
4151                bnx2x_807x_force_10G(bp, phy);
4152                DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
4153                return 0;
4154        } else {
4155                bnx2x_cl45_write(bp, phy,
4156                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
4157        }
4158        if (phy->req_line_speed != SPEED_AUTO_NEG) {
4159                if (phy->req_line_speed == SPEED_10000) {
4160                        val = (1<<7);
4161                } else if (phy->req_line_speed ==  SPEED_2500) {
4162                        val = (1<<5);
4163                        /* Note that 2.5G works only
4164                        when used with 1G advertisment */
4165                } else
4166                        val = (1<<5);
4167        } else {
4168                val = 0;
4169                if (phy->speed_cap_mask &
4170                        PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4171                        val |= (1<<7);
4172
4173                /* Note that 2.5G works only when
4174                used with 1G advertisment */
4175                if (phy->speed_cap_mask &
4176                        (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
4177                         PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
4178                        val |= (1<<5);
4179                DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
4180        }
4181
4182        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
4183        bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
4184
4185        if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
4186             (phy->req_line_speed == SPEED_AUTO_NEG)) ||
4187            (phy->req_line_speed == SPEED_2500)) {
4188                u16 phy_ver;
4189                /* Allow 2.5G for A1 and above */
4190                bnx2x_cl45_read(bp, phy,
4191                                MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
4192                                &phy_ver);
4193                DP(NETIF_MSG_LINK, "Add 2.5G\n");
4194                if (phy_ver > 0)
4195                        tmp1 |= 1;
4196                else
4197                        tmp1 &= 0xfffe;
4198        } else {
4199                DP(NETIF_MSG_LINK, "Disable 2.5G\n");
4200                tmp1 &= 0xfffe;
4201        }
4202
4203        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
4204        /* Add support for CL37 (passive mode) II */
4205
4206        bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
4207        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
4208                         (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
4209                                  0x20 : 0x40)));
4210
4211        /* Add support for CL37 (passive mode) III */
4212        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
4213
4214        /* The SNR will improve about 2db by changing
4215        BW and FEE main tap. Rest commands are executed
4216        after link is up*/
4217        if (bnx2x_8073_is_snr_needed(bp, phy))
4218                bnx2x_cl45_write(bp, phy,
4219                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
4220                                 0xFB0C);
4221
4222        /* Enable FEC (Forware Error Correction) Request in the AN */
4223        bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
4224        tmp1 |= (1<<15);
4225        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
4226
4227        bnx2x_ext_phy_set_pause(params, phy, vars);
4228
4229        /* Restart autoneg */
4230        msleep(500);
4231        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
4232        DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
4233                   ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
4234        return 0;
4235}
4236
4237static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
4238                                 struct link_params *params,
4239                                 struct link_vars *vars)
4240{
4241        struct bnx2x *bp = params->bp;
4242        u8 link_up = 0;
4243        u16 val1, val2;
4244        u16 link_status = 0;
4245        u16 an1000_status = 0;
4246
4247        bnx2x_cl45_read(bp, phy,
4248                        MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
4249
4250        DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
4251
4252        /* clear the interrupt LASI status register */
4253        bnx2x_cl45_read(bp, phy,
4254                        MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
4255        bnx2x_cl45_read(bp, phy,
4256                        MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
4257        DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
4258        /* Clear MSG-OUT */
4259        bnx2x_cl45_read(bp, phy,
4260                        MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
4261
4262        /* Check the LASI */
4263        bnx2x_cl45_read(bp, phy,
4264                        MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
4265
4266        DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
4267
4268        /* Check the link status */
4269        bnx2x_cl45_read(bp, phy,
4270                        MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
4271        DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
4272
4273        bnx2x_cl45_read(bp, phy,
4274                        MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
4275        bnx2x_cl45_read(bp, phy,
4276                        MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
4277        link_up = ((val1 & 4) == 4);
4278        DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
4279
4280        if (link_up &&
4281             ((phy->req_line_speed != SPEED_10000))) {
4282                if (bnx2x_8073_xaui_wa(bp, phy) != 0)
4283                        return 0;
4284        }
4285        bnx2x_cl45_read(bp, phy,
4286                        MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
4287        bnx2x_cl45_read(bp, phy,
4288                        MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
4289
4290        /* Check the link status on 1.1.2 */
4291        bnx2x_cl45_read(bp, phy,
4292                        MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
4293        bnx2x_cl45_read(bp, phy,
4294                        MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
4295        DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
4296                   "an_link_status=0x%x\n", val2, val1, an1000_status);
4297
4298        link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
4299        if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
4300                /* The SNR will improve about 2dbby
4301                changing the BW and FEE main tap.*/
4302                /* The 1st write to change FFE main
4303                tap is set before restart AN */
4304                /* Change PLL Bandwidth in EDC
4305                register */
4306                bnx2x_cl45_write(bp, phy,
4307                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
4308                                 0x26BC);
4309
4310                /* Change CDR Bandwidth in EDC register */
4311                bnx2x_cl45_write(bp, phy,
4312                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
4313                                 0x0333);
4314        }
4315        bnx2x_cl45_read(bp, phy,
4316                        MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
4317                        &link_status);
4318
4319        /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
4320        if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
4321                link_up = 1;
4322                vars->line_speed = SPEED_10000;
4323                DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
4324                           params->port);
4325        } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
4326                link_up = 1;
4327                vars->line_speed = SPEED_2500;
4328                DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
4329                           params->port);
4330        } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
4331                link_up = 1;
4332                vars->line_speed = SPEED_1000;
4333                DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
4334                           params->port);
4335        } else {
4336                link_up = 0;
4337                DP(NETIF_MSG_LINK, "port %x: External link is down\n",
4338                           params->port);
4339        }
4340
4341        if (link_up) {
4342                /* Swap polarity if required */
4343                if (params->lane_config &
4344                    PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
4345                        /* Configure the 8073 to swap P and N of the KR lines */
4346                        bnx2x_cl45_read(bp, phy,
4347                                        MDIO_XS_DEVAD,
4348                                        MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
4349                        /**
4350                        * Set bit 3 to invert Rx in 1G mode and clear this bit
4351                        * when it`s in 10G mode.
4352                        */
4353                        if (vars->line_speed == SPEED_1000) {
4354                                DP(NETIF_MSG_LINK, "Swapping 1G polarity for"
4355                                              "the 8073\n");
4356                                val1 |= (1<<3);
4357                        } else
4358                                val1 &= ~(1<<3);
4359
4360                        bnx2x_cl45_write(bp, phy,
4361                                         MDIO_XS_DEVAD,
4362                                         MDIO_XS_REG_8073_RX_CTRL_PCIE,
4363                                         val1);
4364                }
4365                bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
4366                bnx2x_8073_resolve_fc(phy, params, vars);
4367                vars->duplex = DUPLEX_FULL;
4368        }
4369        return link_up;
4370}
4371
4372static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
4373                                  struct link_params *params)
4374{
4375        struct bnx2x *bp = params->bp;
4376        u8 gpio_port;
4377        if (CHIP_IS_E2(bp))
4378                gpio_port = BP_PATH(bp);
4379        else
4380                gpio_port = params->port;
4381        DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
4382           gpio_port);
4383        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4384                            MISC_REGISTERS_GPIO_OUTPUT_LOW,
4385                            gpio_port);
4386}
4387
4388/******************************************************************/
4389/*                      BCM8705 PHY SECTION                       */
4390/******************************************************************/
4391static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy,
4392                                 struct link_params *params,
4393                                 struct link_vars *vars)
4394{
4395        struct bnx2x *bp = params->bp;
4396        DP(NETIF_MSG_LINK, "init 8705\n");
4397        /* Restore normal power mode*/
4398        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4399                            MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
4400        /* HW reset */
4401        bnx2x_ext_phy_hw_reset(bp, params->port);
4402        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
4403        bnx2x_wait_reset_complete(bp, phy);
4404
4405        bnx2x_cl45_write(bp, phy,
4406                         MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
4407        bnx2x_cl45_write(bp, phy,
4408                         MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
4409        bnx2x_cl45_write(bp, phy,
4410                         MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
4411        bnx2x_cl45_write(bp, phy,
4412                         MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
4413        /* BCM8705 doesn't have microcode, hence the 0 */
4414        bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
4415        return 0;
4416}
4417
4418static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
4419                                 struct link_params *params,
4420                                 struct link_vars *vars)
4421{
4422        u8 link_up = 0;
4423        u16 val1, rx_sd;
4424        struct bnx2x *bp = params->bp;
4425        DP(NETIF_MSG_LINK, "read status 8705\n");
4426        bnx2x_cl45_read(bp, phy,
4427                      MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
4428        DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4429
4430        bnx2x_cl45_read(bp, phy,
4431                      MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
4432        DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4433
4434        bnx2x_cl45_read(bp, phy,
4435                      MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
4436
4437        bnx2x_cl45_read(bp, phy,
4438                      MDIO_PMA_DEVAD, 0xc809, &val1);
4439        bnx2x_cl45_read(bp, phy,
4440                      MDIO_PMA_DEVAD, 0xc809, &val1);
4441
4442        DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
4443        link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
4444        if (link_up) {
4445                vars->line_speed = SPEED_10000;
4446                bnx2x_ext_phy_resolve_fc(phy, params, vars);
4447        }
4448        return link_up;
4449}
4450
4451/******************************************************************/
4452/*                      SFP+ module Section                       */
4453/******************************************************************/
4454static void bnx2x_sfp_set_transmitter(struct bnx2x *bp,
4455                                      struct bnx2x_phy *phy,
4456                                      u8 port,
4457                                      u8 tx_en)
4458{
4459        u16 val;
4460
4461        DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
4462                 tx_en, port);
4463        /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
4464        bnx2x_cl45_read(bp, phy,
4465                      MDIO_PMA_DEVAD,
4466                      MDIO_PMA_REG_PHY_IDENTIFIER,
4467                      &val);
4468
4469        if (tx_en)
4470                val &= ~(1<<15);
4471        else
4472                val |= (1<<15);
4473
4474        bnx2x_cl45_write(bp, phy,
4475                       MDIO_PMA_DEVAD,
4476                       MDIO_PMA_REG_PHY_IDENTIFIER,
4477                       val);
4478}
4479
4480static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
4481                                            struct link_params *params,
4482                                          u16 addr, u8 byte_cnt, u8 *o_buf)
4483{
4484        struct bnx2x *bp = params->bp;
4485        u16 val = 0;
4486        u16 i;
4487        if (byte_cnt > 16) {
4488                DP(NETIF_MSG_LINK, "Reading from eeprom is"
4489                            " is limited to 0xf\n");
4490                return -EINVAL;
4491        }
4492        /* Set the read command byte count */
4493        bnx2x_cl45_write(bp, phy,
4494                         MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
4495                       (byte_cnt | 0xa000));
4496
4497        /* Set the read command address */
4498        bnx2x_cl45_write(bp, phy,
4499                         MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
4500                       addr);
4501
4502        /* Activate read command */
4503        bnx2x_cl45_write(bp, phy,
4504                         MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
4505                       0x2c0f);
4506
4507        /* Wait up to 500us for command complete status */
4508        for (i = 0; i < 100; i++) {
4509                bnx2x_cl45_read(bp, phy,
4510                              MDIO_PMA_DEVAD,
4511                              MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
4512                if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
4513                    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
4514                        break;
4515                udelay(5);
4516        }
4517
4518        if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
4519                    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
4520                DP(NETIF_MSG_LINK,
4521                         "Got bad status 0x%x when reading from SFP+ EEPROM\n",
4522                         (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
4523                return -EINVAL;
4524        }
4525
4526        /* Read the buffer */
4527        for (i = 0; i < byte_cnt; i++) {
4528                bnx2x_cl45_read(bp, phy,
4529                              MDIO_PMA_DEVAD,
4530                              MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
4531                o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
4532        }
4533
4534        for (i = 0; i < 100; i++) {
4535                bnx2x_cl45_read(bp, phy,
4536                              MDIO_PMA_DEVAD,
4537                              MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
4538                if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
4539                    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
4540                        return 0;
4541                msleep(1);
4542        }
4543        return -EINVAL;
4544}
4545
4546static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
4547                                            struct link_params *params,
4548                                          u16 addr, u8 byte_cnt, u8 *o_buf)
4549{
4550        struct bnx2x *bp = params->bp;
4551        u16 val, i;
4552
4553        if (byte_cnt > 16) {
4554                DP(NETIF_MSG_LINK, "Reading from eeprom is"
4555                            " is limited to 0xf\n");
4556                return -EINVAL;
4557        }
4558
4559        /* Need to read from 1.8000 to clear it */
4560        bnx2x_cl45_read(bp, phy,
4561                      MDIO_PMA_DEVAD,
4562                      MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
4563                      &val);
4564
4565        /* Set the read command byte count */
4566        bnx2x_cl45_write(bp, phy,
4567                       MDIO_PMA_DEVAD,
4568                       MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
4569                       ((byte_cnt < 2) ? 2 : byte_cnt));
4570
4571        /* Set the read command address */
4572        bnx2x_cl45_write(bp, phy,
4573                       MDIO_PMA_DEVAD,
4574                       MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
4575                       addr);
4576        /* Set the destination address */
4577        bnx2x_cl45_write(bp, phy,
4578                       MDIO_PMA_DEVAD,
4579                       0x8004,
4580                       MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
4581
4582        /* Activate read command */
4583        bnx2x_cl45_write(bp, phy,
4584                       MDIO_PMA_DEVAD,
4585                       MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
4586                       0x8002);
4587        /* Wait appropriate time for two-wire command to finish before
4588        polling the status register */
4589        msleep(1);
4590
4591        /* Wait up to 500us for command complete status */
4592        for (i = 0; i < 100; i++) {
4593                bnx2x_cl45_read(bp, phy,
4594                              MDIO_PMA_DEVAD,
4595                              MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
4596                if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
4597                    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
4598                        break;
4599                udelay(5);
4600        }
4601
4602        if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
4603                    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
4604                DP(NETIF_MSG_LINK,
4605                         "Got bad status 0x%x when reading from SFP+ EEPROM\n",
4606                         (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
4607                return -EINVAL;
4608        }
4609
4610        /* Read the buffer */
4611        for (i = 0; i < byte_cnt; i++) {
4612                bnx2x_cl45_read(bp, phy,
4613                              MDIO_PMA_DEVAD,
4614                              MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
4615                o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
4616        }
4617
4618        for (i = 0; i < 100; i++) {
4619                bnx2x_cl45_read(bp, phy,
4620                              MDIO_PMA_DEVAD,
4621                              MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
4622                if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
4623                    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
4624                        return 0;
4625                msleep(1);
4626        }
4627
4628        return -EINVAL;
4629}
4630
4631static u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
4632                                       struct link_params *params, u16 addr,
4633                                       u8 byte_cnt, u8 *o_buf)
4634{
4635        if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
4636                return bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
4637                                                       byte_cnt, o_buf);
4638        else if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
4639                return bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
4640                                                       byte_cnt, o_buf);
4641        return -EINVAL;
4642}
4643
4644static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy,
4645                             struct link_params *params,
4646                                  u16 *edc_mode)
4647{
4648        struct bnx2x *bp = params->bp;
4649        u8 val, check_limiting_mode = 0;
4650        *edc_mode = EDC_MODE_LIMITING;
4651
4652        /* First check for copper cable */
4653        if (bnx2x_read_sfp_module_eeprom(phy,
4654                                         params,
4655                                         SFP_EEPROM_CON_TYPE_ADDR,
4656                                         1,
4657                                         &val) != 0) {
4658                DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
4659                return -EINVAL;
4660        }
4661
4662        switch (val) {
4663        case SFP_EEPROM_CON_TYPE_VAL_COPPER:
4664        {
4665                u8 copper_module_type;
4666
4667                /* Check if its active cable( includes SFP+ module)
4668                of passive cable*/
4669                if (bnx2x_read_sfp_module_eeprom(phy,
4670                                               params,
4671                                               SFP_EEPROM_FC_TX_TECH_ADDR,
4672                                               1,
4673                                               &copper_module_type) !=
4674                    0) {
4675                        DP(NETIF_MSG_LINK,
4676                                "Failed to read copper-cable-type"
4677                                " from SFP+ EEPROM\n");
4678                        return -EINVAL;
4679                }
4680
4681                if (copper_module_type &
4682                    SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
4683                        DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
4684                        check_limiting_mode = 1;
4685                } else if (copper_module_type &
4686                        SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
4687                                DP(NETIF_MSG_LINK, "Passive Copper"
4688                                            " cable detected\n");
4689                                *edc_mode =
4690                                      EDC_MODE_PASSIVE_DAC;
4691                } else {
4692                        DP(NETIF_MSG_LINK, "Unknown copper-cable-"
4693                                     "type 0x%x !!!\n", copper_module_type);
4694                        return -EINVAL;
4695                }
4696                break;
4697        }
4698        case SFP_EEPROM_CON_TYPE_VAL_LC:
4699                DP(NETIF_MSG_LINK, "Optic module detected\n");
4700                check_limiting_mode = 1;
4701                break;
4702        default:
4703                DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
4704                         val);
4705                return -EINVAL;
4706        }
4707
4708        if (check_limiting_mode) {
4709                u8 options[SFP_EEPROM_OPTIONS_SIZE];
4710                if (bnx2x_read_sfp_module_eeprom(phy,
4711                                                 params,
4712                                                 SFP_EEPROM_OPTIONS_ADDR,
4713                                                 SFP_EEPROM_OPTIONS_SIZE,
4714                                                 options) != 0) {
4715                        DP(NETIF_MSG_LINK, "Failed to read Option"
4716                                " field from module EEPROM\n");
4717                        return -EINVAL;
4718                }
4719                if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
4720                        *edc_mode = EDC_MODE_LINEAR;
4721                else
4722                        *edc_mode = EDC_MODE_LIMITING;
4723        }
4724        DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
4725        return 0;
4726}
4727/* This function read the relevant field from the module ( SFP+ ),
4728        and verify it is compliant with this board */
4729static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
4730                                  struct link_params *params)
4731{
4732        struct bnx2x *bp = params->bp;
4733        u32 val, cmd;
4734        u32 fw_resp, fw_cmd_param;
4735        char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
4736        char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
4737        phy->flags &= ~FLAGS_SFP_NOT_APPROVED;
4738        val = REG_RD(bp, params->shmem_base +
4739                         offsetof(struct shmem_region, dev_info.
4740                                  port_feature_config[params->port].config));
4741        if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
4742            PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
4743                DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
4744                return 0;
4745        }
4746
4747        if (params->feature_config_flags &
4748            FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
4749                /* Use specific phy request */
4750                cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
4751        } else if (params->feature_config_flags &
4752                   FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
4753                /* Use first phy request only in case of non-dual media*/
4754                if (DUAL_MEDIA(params)) {
4755                        DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
4756                           "verification\n");
4757                        return -EINVAL;
4758                }
4759                cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
4760        } else {
4761                /* No support in OPT MDL detection */
4762                DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
4763                          "verification\n");
4764                return -EINVAL;
4765        }
4766
4767        fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
4768        fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param);
4769        if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
4770                DP(NETIF_MSG_LINK, "Approved module\n");
4771                return 0;
4772        }
4773
4774        /* format the warning message */
4775        if (bnx2x_read_sfp_module_eeprom(phy,
4776                                         params,
4777                                       SFP_EEPROM_VENDOR_NAME_ADDR,
4778                                       SFP_EEPROM_VENDOR_NAME_SIZE,
4779                                       (u8 *)vendor_name))
4780                vendor_name[0] = '\0';
4781        else
4782                vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
4783        if (bnx2x_read_sfp_module_eeprom(phy,
4784                                         params,
4785                                       SFP_EEPROM_PART_NO_ADDR,
4786                                       SFP_EEPROM_PART_NO_SIZE,
4787                                       (u8 *)vendor_pn))
4788                vendor_pn[0] = '\0';
4789        else
4790                vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
4791
4792        netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected,"
4793                             " Port %d from %s part number %s\n",
4794                    params->port, vendor_name, vendor_pn);
4795        phy->flags |= FLAGS_SFP_NOT_APPROVED;
4796        return -EINVAL;
4797}
4798
4799static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
4800                                                struct link_params *params)
4801
4802{
4803        u8 val;
4804        struct bnx2x *bp = params->bp;
4805        u16 timeout;
4806        /* Initialization time after hot-plug may take up to 300ms for some
4807        phys type ( e.g. JDSU ) */
4808        for (timeout = 0; timeout < 60; timeout++) {
4809                if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
4810                    == 0) {
4811                        DP(NETIF_MSG_LINK, "SFP+ module initialization "
4812                                     "took %d ms\n", timeout * 5);
4813                        return 0;
4814                }
4815                msleep(5);
4816        }
4817        return -EINVAL;
4818}
4819
4820static void bnx2x_8727_power_module(struct bnx2x *bp,
4821                                    struct bnx2x_phy *phy,
4822                                    u8 is_power_up) {
4823        /* Make sure GPIOs are not using for LED mode */
4824        u16 val;
4825        /*
4826         * In the GPIO register, bit 4 is use to detemine if the GPIOs are
4827         * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
4828         * output
4829         * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
4830         * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
4831         * where the 1st bit is the over-current(only input), and 2nd bit is
4832         * for power( only output )
4833        */
4834
4835        /*
4836         * In case of NOC feature is disabled and power is up, set GPIO control
4837         *  as input to enable listening of over-current indication
4838         */
4839        if (phy->flags & FLAGS_NOC)
4840                return;
4841        if (!(phy->flags &
4842              FLAGS_NOC) && is_power_up)
4843                val = (1<<4);
4844        else
4845                /*
4846                 * Set GPIO control to OUTPUT, and set the power bit
4847                 * to according to the is_power_up
4848                 */
4849                val = ((!(is_power_up)) << 1);
4850
4851        bnx2x_cl45_write(bp, phy,
4852                         MDIO_PMA_DEVAD,
4853                         MDIO_PMA_REG_8727_GPIO_CTRL,
4854                         val);
4855}
4856
4857static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
4858                                       struct bnx2x_phy *phy,
4859                                       u16 edc_mode)
4860{
4861        u16 cur_limiting_mode;
4862
4863        bnx2x_cl45_read(bp, phy,
4864                      MDIO_PMA_DEVAD,
4865                      MDIO_PMA_REG_ROM_VER2,
4866                      &cur_limiting_mode);
4867        DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
4868                 cur_limiting_mode);
4869
4870        if (edc_mode == EDC_MODE_LIMITING) {
4871                DP(NETIF_MSG_LINK,
4872                         "Setting LIMITING MODE\n");
4873                bnx2x_cl45_write(bp, phy,
4874                                 MDIO_PMA_DEVAD,
4875                                 MDIO_PMA_REG_ROM_VER2,
4876                                 EDC_MODE_LIMITING);
4877        } else { /* LRM mode ( default )*/
4878
4879                DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
4880
4881                /* Changing to LRM mode takes quite few seconds.
4882                So do it only if current mode is limiting
4883                ( default is LRM )*/
4884                if (cur_limiting_mode != EDC_MODE_LIMITING)
4885                        return 0;
4886
4887                bnx2x_cl45_write(bp, phy,
4888                               MDIO_PMA_DEVAD,
4889                               MDIO_PMA_REG_LRM_MODE,
4890                               0);
4891                bnx2x_cl45_write(bp, phy,
4892                               MDIO_PMA_DEVAD,
4893                               MDIO_PMA_REG_ROM_VER2,
4894                               0x128);
4895                bnx2x_cl45_write(bp, phy,
4896                               MDIO_PMA_DEVAD,
4897                               MDIO_PMA_REG_MISC_CTRL0,
4898                               0x4008);
4899                bnx2x_cl45_write(bp, phy,
4900                               MDIO_PMA_DEVAD,
4901                               MDIO_PMA_REG_LRM_MODE,
4902                               0xaaaa);
4903        }
4904        return 0;
4905}
4906
4907static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
4908                                       struct bnx2x_phy *phy,
4909                                        u16 edc_mode)
4910{
4911        u16 phy_identifier;
4912        u16 rom_ver2_val;
4913        bnx2x_cl45_read(bp, phy,
4914                       MDIO_PMA_DEVAD,
4915                       MDIO_PMA_REG_PHY_IDENTIFIER,
4916                       &phy_identifier);
4917
4918        bnx2x_cl45_write(bp, phy,
4919                       MDIO_PMA_DEVAD,
4920                       MDIO_PMA_REG_PHY_IDENTIFIER,
4921                       (phy_identifier & ~(1<<9)));
4922
4923        bnx2x_cl45_read(bp, phy,
4924                      MDIO_PMA_DEVAD,
4925                      MDIO_PMA_REG_ROM_VER2,
4926                      &rom_ver2_val);
4927        /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
4928        bnx2x_cl45_write(bp, phy,
4929                       MDIO_PMA_DEVAD,
4930                       MDIO_PMA_REG_ROM_VER2,
4931                       (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
4932
4933        bnx2x_cl45_write(bp, phy,
4934                       MDIO_PMA_DEVAD,
4935                       MDIO_PMA_REG_PHY_IDENTIFIER,
4936                       (phy_identifier | (1<<9)));
4937
4938        return 0;
4939}
4940
4941static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
4942                                     struct link_params *params,
4943                                     u32 action)
4944{
4945        struct bnx2x *bp = params->bp;
4946
4947        switch (action) {
4948        case DISABLE_TX:
4949                bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
4950                break;
4951        case ENABLE_TX:
4952                if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
4953                        bnx2x_sfp_set_transmitter(bp, phy, params->port, 1);
4954                break;
4955        default:
4956                DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
4957                   action);
4958                return;
4959        }
4960}
4961
4962static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
4963                                     struct link_params *params)
4964{
4965        struct bnx2x *bp = params->bp;
4966        u16 edc_mode;
4967        u8 rc = 0;
4968
4969        u32 val = REG_RD(bp, params->shmem_base +
4970                             offsetof(struct shmem_region, dev_info.
4971                                     port_feature_config[params->port].config));
4972
4973        DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
4974                 params->port);
4975
4976        if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
4977                DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
4978                return -EINVAL;
4979        } else if (bnx2x_verify_sfp_module(phy, params) !=
4980                   0) {
4981                /* check SFP+ module compatibility */
4982                DP(NETIF_MSG_LINK, "Module verification failed!!\n");
4983                rc = -EINVAL;
4984                /* Turn on fault module-detected led */
4985                bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4986                                  MISC_REGISTERS_GPIO_HIGH,
4987                                  params->port);
4988                if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
4989                    ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
4990                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) {
4991                        /* Shutdown SFP+ module */
4992                        DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
4993                        bnx2x_8727_power_module(bp, phy, 0);
4994                        return rc;
4995                }
4996        } else {
4997                /* Turn off fault module-detected led */
4998                DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n");
4999                bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5000                                          MISC_REGISTERS_GPIO_LOW,
5001                                          params->port);
5002        }
5003
5004        /* power up the SFP module */
5005        if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
5006                bnx2x_8727_power_module(bp, phy, 1);
5007
5008        /* Check and set limiting mode / LRM mode on 8726.
5009        On 8727 it is done automatically */
5010        if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
5011                bnx2x_8726_set_limiting_mode(bp, phy, edc_mode);
5012        else
5013                bnx2x_8727_set_limiting_mode(bp, phy, edc_mode);
5014        /*
5015         * Enable transmit for this module if the module is approved, or
5016         * if unapproved modules should also enable the Tx laser
5017         */
5018        if (rc == 0 ||
5019            (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
5020            PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
5021                bnx2x_sfp_set_transmitter(bp, phy, params->port, 1);
5022        else
5023                bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
5024
5025        return rc;
5026}
5027
5028void bnx2x_handle_module_detect_int(struct link_params *params)
5029{
5030        struct bnx2x *bp = params->bp;
5031        struct bnx2x_phy *phy = &params->phy[EXT_PHY1];
5032        u32 gpio_val;
5033        u8 port = params->port;
5034
5035        /* Set valid module led off */
5036        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5037                          MISC_REGISTERS_GPIO_HIGH,
5038                          params->port);
5039
5040        /* Get current gpio val refelecting module plugged in / out*/
5041        gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
5042
5043        /* Call the handling function in case module is detected */
5044        if (gpio_val == 0) {
5045
5046                bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
5047                                   MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
5048                                   port);
5049
5050                if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
5051                        bnx2x_sfp_module_detection(phy, params);
5052                else
5053                        DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
5054        } else {
5055                u32 val = REG_RD(bp, params->shmem_base +
5056                                     offsetof(struct shmem_region, dev_info.
5057                                              port_feature_config[params->port].
5058                                              config));
5059
5060                bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
5061                                   MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
5062                                   port);
5063                /* Module was plugged out. */
5064                /* Disable transmit for this module */
5065                if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
5066                    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
5067                        bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
5068        }
5069}
5070
5071/******************************************************************/
5072/*              common BCM8706/BCM8726 PHY SECTION                */
5073/******************************************************************/
5074static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
5075                                      struct link_params *params,
5076                                      struct link_vars *vars)
5077{
5078        u8 link_up = 0;
5079        u16 val1, val2, rx_sd, pcs_status;
5080        struct bnx2x *bp = params->bp;
5081        DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
5082        /* Clear RX Alarm*/
5083        bnx2x_cl45_read(bp, phy,
5084                        MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
5085        /* clear LASI indication*/
5086        bnx2x_cl45_read(bp, phy,
5087                        MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
5088        bnx2x_cl45_read(bp, phy,
5089                        MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
5090        DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
5091
5092        bnx2x_cl45_read(bp, phy,
5093                        MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
5094        bnx2x_cl45_read(bp, phy,
5095                        MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
5096        bnx2x_cl45_read(bp, phy,
5097                        MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
5098        bnx2x_cl45_read(bp, phy,
5099                        MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
5100
5101        DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
5102                        " link_status 0x%x\n", rx_sd, pcs_status, val2);
5103        /* link is up if both bit 0 of pmd_rx_sd and
5104         * bit 0 of pcs_status are set, or if the autoneg bit
5105         * 1 is set
5106         */
5107        link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
5108        if (link_up) {
5109                if (val2 & (1<<1))
5110                        vars->line_speed = SPEED_1000;
5111                else
5112                        vars->line_speed = SPEED_10000;
5113                bnx2x_ext_phy_resolve_fc(phy, params, vars);
5114                vars->duplex = DUPLEX_FULL;
5115        }
5116        return link_up;
5117}
5118
5119/******************************************************************/
5120/*                      BCM8706 PHY SECTION                       */
5121/******************************************************************/
5122static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
5123                                 struct link_params *params,
5124                                 struct link_vars *vars)
5125{
5126        u16 cnt, val;
5127        struct bnx2x *bp = params->bp;
5128        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5129                            MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
5130        /* HW reset */
5131        bnx2x_ext_phy_hw_reset(bp, params->port);
5132        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
5133        bnx2x_wait_reset_complete(bp, phy);
5134
5135        /* Wait until fw is loaded */
5136        for (cnt = 0; cnt < 100; cnt++) {
5137                bnx2x_cl45_read(bp, phy,
5138                                MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
5139                if (val)
5140                        break;
5141                msleep(10);
5142        }
5143        DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt);
5144        if ((params->feature_config_flags &
5145             FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
5146                u8 i;
5147                u16 reg;
5148                for (i = 0; i < 4; i++) {
5149                        reg = MDIO_XS_8706_REG_BANK_RX0 +
5150                                i*(MDIO_XS_8706_REG_BANK_RX1 -
5151                                   MDIO_XS_8706_REG_BANK_RX0);
5152                        bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val);
5153                        /* Clear first 3 bits of the control */
5154                        val &= ~0x7;
5155                        /* Set control bits according to configuration */
5156                        val |= (phy->rx_preemphasis[i] & 0x7);
5157                        DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706"
5158                                   " reg 0x%x <-- val 0x%x\n", reg, val);
5159                        bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val);
5160                }
5161        }
5162        /* Force speed */
5163        if (phy->req_line_speed == SPEED_10000) {
5164                DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
5165
5166                bnx2x_cl45_write(bp, phy,
5167                                 MDIO_PMA_DEVAD,
5168                                 MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
5169                bnx2x_cl45_write(bp, phy,
5170                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
5171        } else {
5172                /* Force 1Gbps using autoneg with 1G advertisment */
5173
5174                /* Allow CL37 through CL73 */
5175                DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
5176                bnx2x_cl45_write(bp, phy,
5177                                 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
5178
5179                /* Enable Full-Duplex advertisment on CL37 */
5180                bnx2x_cl45_write(bp, phy,
5181                                 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
5182                /* Enable CL37 AN */
5183                bnx2x_cl45_write(bp, phy,
5184                                 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
5185                /* 1G support */
5186                bnx2x_cl45_write(bp, phy,
5187                                 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
5188
5189                /* Enable clause 73 AN */
5190                bnx2x_cl45_write(bp, phy,
5191                                 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
5192                bnx2x_cl45_write(bp, phy,
5193                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5194                                 0x0400);
5195                bnx2x_cl45_write(bp, phy,
5196                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
5197                                 0x0004);
5198        }
5199        bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
5200        return 0;
5201}
5202
5203static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy,
5204                                 struct link_params *params,
5205                                 struct link_vars *vars)
5206{
5207        return bnx2x_8706_8726_read_status(phy, params, vars);
5208}
5209
5210/******************************************************************/
5211/*                      BCM8726 PHY SECTION                       */
5212/******************************************************************/
5213static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
5214                                       struct link_params *params)
5215{
5216        struct bnx2x *bp = params->bp;
5217        DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
5218        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
5219}
5220
5221static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
5222                                         struct link_params *params)
5223{
5224        struct bnx2x *bp = params->bp;
5225        /* Need to wait 100ms after reset */
5226        msleep(100);
5227
5228        /* Micro controller re-boot */
5229        bnx2x_cl45_write(bp, phy,
5230                         MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
5231
5232        /* Set soft reset */
5233        bnx2x_cl45_write(bp, phy,
5234                       MDIO_PMA_DEVAD,
5235                       MDIO_PMA_REG_GEN_CTRL,
5236                       MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
5237
5238        bnx2x_cl45_write(bp, phy,
5239                       MDIO_PMA_DEVAD,
5240                       MDIO_PMA_REG_MISC_CTRL1, 0x0001);
5241
5242        bnx2x_cl45_write(bp, phy,
5243                       MDIO_PMA_DEVAD,
5244                       MDIO_PMA_REG_GEN_CTRL,
5245                       MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
5246
5247        /* wait for 150ms for microcode load */
5248        msleep(150);
5249
5250        /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
5251        bnx2x_cl45_write(bp, phy,
5252                       MDIO_PMA_DEVAD,
5253                       MDIO_PMA_REG_MISC_CTRL1, 0x0000);
5254
5255        msleep(200);
5256        bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
5257}
5258
5259static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
5260                                 struct link_params *params,
5261                                 struct link_vars *vars)
5262{
5263        struct bnx2x *bp = params->bp;
5264        u16 val1;
5265        u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
5266        if (link_up) {
5267                bnx2x_cl45_read(bp, phy,
5268                                MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
5269                                &val1);
5270                if (val1 & (1<<15)) {
5271                        DP(NETIF_MSG_LINK, "Tx is disabled\n");
5272                        link_up = 0;
5273                        vars->line_speed = 0;
5274                }
5275        }
5276        return link_up;
5277}
5278
5279
5280static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy,
5281                                 struct link_params *params,
5282                                 struct link_vars *vars)
5283{
5284        struct bnx2x *bp = params->bp;
5285        u32 val;
5286        u32 swap_val, swap_override, aeu_gpio_mask, offset;
5287        DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
5288        /* Restore normal power mode*/
5289        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5290                            MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
5291
5292        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
5293                            MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
5294
5295        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
5296        bnx2x_wait_reset_complete(bp, phy);
5297
5298        bnx2x_8726_external_rom_boot(phy, params);
5299
5300        /* Need to call module detected on initialization since
5301        the module detection triggered by actual module
5302        insertion might occur before driver is loaded, and when
5303        driver is loaded, it reset all registers, including the
5304        transmitter */
5305        bnx2x_sfp_module_detection(phy, params);
5306
5307        if (phy->req_line_speed == SPEED_1000) {
5308                DP(NETIF_MSG_LINK, "Setting 1G force\n");
5309                bnx2x_cl45_write(bp, phy,
5310                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
5311                bnx2x_cl45_write(bp, phy,
5312                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
5313                bnx2x_cl45_write(bp, phy,
5314                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5);
5315                bnx2x_cl45_write(bp, phy,
5316                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5317                                 0x400);
5318        } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
5319                   (phy->speed_cap_mask &
5320                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
5321                   ((phy->speed_cap_mask &
5322                      PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
5323                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
5324                DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
5325                /* Set Flow control */
5326                bnx2x_ext_phy_set_pause(params, phy, vars);
5327                bnx2x_cl45_write(bp, phy,
5328                                 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
5329                bnx2x_cl45_write(bp, phy,
5330                                 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
5331                bnx2x_cl45_write(bp, phy,
5332                                 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
5333                bnx2x_cl45_write(bp, phy,
5334                                 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
5335                bnx2x_cl45_write(bp, phy,
5336                                MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
5337                /* Enable RX-ALARM control to receive
5338                interrupt for 1G speed change */
5339                bnx2x_cl45_write(bp, phy,
5340                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4);
5341                bnx2x_cl45_write(bp, phy,
5342                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5343                                 0x400);
5344
5345        } else { /* Default 10G. Set only LASI control */
5346                bnx2x_cl45_write(bp, phy,
5347                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
5348        }
5349
5350        /* Set TX PreEmphasis if needed */
5351        if ((params->feature_config_flags &
5352             FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
5353                DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
5354                         "TX_CTRL2 0x%x\n",
5355                         phy->tx_preemphasis[0],
5356                         phy->tx_preemphasis[1]);
5357                bnx2x_cl45_write(bp, phy,
5358                                 MDIO_PMA_DEVAD,
5359                                 MDIO_PMA_REG_8726_TX_CTRL1,
5360                                 phy->tx_preemphasis[0]);
5361
5362                bnx2x_cl45_write(bp, phy,
5363                                 MDIO_PMA_DEVAD,
5364                                 MDIO_PMA_REG_8726_TX_CTRL2,
5365                                 phy->tx_preemphasis[1]);
5366        }
5367
5368        /* Set GPIO3 to trigger SFP+ module insertion/removal */
5369        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
5370                            MISC_REGISTERS_GPIO_INPUT_HI_Z, params->port);
5371
5372        /* The GPIO should be swapped if the swap register is set and active */
5373        swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
5374        swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
5375
5376        /* Select function upon port-swap configuration */
5377        if (params->port == 0) {
5378                offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
5379                aeu_gpio_mask = (swap_val && swap_override) ?
5380                        AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 :
5381                        AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0;
5382        } else {
5383                offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
5384                aeu_gpio_mask = (swap_val && swap_override) ?
5385                        AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 :
5386                        AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1;
5387        }
5388        val = REG_RD(bp, offset);
5389        /* add GPIO3 to group */
5390        val |= aeu_gpio_mask;
5391        REG_WR(bp, offset, val);
5392        return 0;
5393
5394}
5395
5396static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
5397                                  struct link_params *params)
5398{
5399        struct bnx2x *bp = params->bp;
5400        DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
5401        /* Set serial boot control for external load */
5402        bnx2x_cl45_write(bp, phy,
5403                         MDIO_PMA_DEVAD,
5404                         MDIO_PMA_REG_GEN_CTRL, 0x0001);
5405}
5406
5407/******************************************************************/
5408/*                      BCM8727 PHY SECTION                       */
5409/******************************************************************/
5410
5411static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy,
5412                                    struct link_params *params, u8 mode)
5413{
5414        struct bnx2x *bp = params->bp;
5415        u16 led_mode_bitmask = 0;
5416        u16 gpio_pins_bitmask = 0;
5417        u16 val;
5418        /* Only NOC flavor requires to set the LED specifically */
5419        if (!(phy->flags & FLAGS_NOC))
5420                return;
5421        switch (mode) {
5422        case LED_MODE_FRONT_PANEL_OFF:
5423        case LED_MODE_OFF:
5424                led_mode_bitmask = 0;
5425                gpio_pins_bitmask = 0x03;
5426                break;
5427        case LED_MODE_ON:
5428                led_mode_bitmask = 0;
5429                gpio_pins_bitmask = 0x02;
5430                break;
5431        case LED_MODE_OPER:
5432                led_mode_bitmask = 0x60;
5433                gpio_pins_bitmask = 0x11;
5434                break;
5435        }
5436        bnx2x_cl45_read(bp, phy,
5437                        MDIO_PMA_DEVAD,
5438                        MDIO_PMA_REG_8727_PCS_OPT_CTRL,
5439                        &val);
5440        val &= 0xff8f;
5441        val |= led_mode_bitmask;
5442        bnx2x_cl45_write(bp, phy,
5443                         MDIO_PMA_DEVAD,
5444                         MDIO_PMA_REG_8727_PCS_OPT_CTRL,
5445                         val);
5446        bnx2x_cl45_read(bp, phy,
5447                        MDIO_PMA_DEVAD,
5448                        MDIO_PMA_REG_8727_GPIO_CTRL,
5449                        &val);
5450        val &= 0xffe0;
5451        val |= gpio_pins_bitmask;
5452        bnx2x_cl45_write(bp, phy,
5453                         MDIO_PMA_DEVAD,
5454                         MDIO_PMA_REG_8727_GPIO_CTRL,
5455                         val);
5456}
5457static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
5458                                struct link_params *params) {
5459        u32 swap_val, swap_override;
5460        u8 port;
5461        /**
5462         * The PHY reset is controlled by GPIO 1. Fake the port number
5463         * to cancel the swap done in set_gpio()
5464         */
5465        struct bnx2x *bp = params->bp;
5466        swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
5467        swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
5468        port = (swap_val && swap_override) ^ 1;
5469        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
5470                            MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
5471}
5472
5473static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy,
5474                                 struct link_params *params,
5475                                 struct link_vars *vars)
5476{
5477        u16 tmp1, val, mod_abs;
5478        u16 rx_alarm_ctrl_val;
5479        u16 lasi_ctrl_val;
5480        struct bnx2x *bp = params->bp;
5481        /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
5482
5483        bnx2x_wait_reset_complete(bp, phy);
5484        rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
5485        lasi_ctrl_val = 0x0004;
5486
5487        DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
5488        /* enable LASI */
5489        bnx2x_cl45_write(bp, phy,
5490                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5491                         rx_alarm_ctrl_val);
5492
5493        bnx2x_cl45_write(bp, phy,
5494                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val);
5495
5496        /* Initially configure  MOD_ABS to interrupt when
5497        module is presence( bit 8) */
5498        bnx2x_cl45_read(bp, phy,
5499                        MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
5500        /* Set EDC off by setting OPTXLOS signal input to low
5501        (bit 9).
5502        When the EDC is off it locks onto a reference clock and
5503        avoids becoming 'lost'.*/
5504        mod_abs &= ~(1<<8);
5505        if (!(phy->flags & FLAGS_NOC))
5506                mod_abs &= ~(1<<9);
5507        bnx2x_cl45_write(bp, phy,
5508                         MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
5509
5510
5511        /* Make MOD_ABS give interrupt on change */
5512        bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
5513                        &val);
5514        val |= (1<<12);
5515        if (phy->flags & FLAGS_NOC)
5516                val |= (3<<5);
5517
5518        /**
5519         * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
5520         * status which reflect SFP+ module over-current
5521         */
5522        if (!(phy->flags & FLAGS_NOC))
5523                val &= 0xff8f; /* Reset bits 4-6 */
5524        bnx2x_cl45_write(bp, phy,
5525                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val);
5526
5527        bnx2x_8727_power_module(bp, phy, 1);
5528
5529        bnx2x_cl45_read(bp, phy,
5530                        MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
5531
5532        bnx2x_cl45_read(bp, phy,
5533                        MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
5534
5535        /* Set option 1G speed */
5536        if (phy->req_line_speed == SPEED_1000) {
5537                DP(NETIF_MSG_LINK, "Setting 1G force\n");
5538                bnx2x_cl45_write(bp, phy,
5539                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
5540                bnx2x_cl45_write(bp, phy,
5541                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
5542                bnx2x_cl45_read(bp, phy,
5543                                MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
5544                DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
5545                /**
5546                 * Power down the XAUI until link is up in case of dual-media
5547                 * and 1G
5548                 */
5549                if (DUAL_MEDIA(params)) {
5550                        bnx2x_cl45_read(bp, phy,
5551                                        MDIO_PMA_DEVAD,
5552                                        MDIO_PMA_REG_8727_PCS_GP, &val);
5553                        val |= (3<<10);
5554                        bnx2x_cl45_write(bp, phy,
5555                                         MDIO_PMA_DEVAD,
5556                                         MDIO_PMA_REG_8727_PCS_GP, val);
5557                }
5558        } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
5559                   ((phy->speed_cap_mask &
5560                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
5561                   ((phy->speed_cap_mask &
5562                      PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
5563                   PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
5564
5565                DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
5566                bnx2x_cl45_write(bp, phy,
5567                                 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
5568                bnx2x_cl45_write(bp, phy,
5569                                 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
5570        } else {
5571                /**
5572                 * Since the 8727 has only single reset pin, need to set the 10G
5573                 * registers although it is default
5574                 */
5575                bnx2x_cl45_write(bp, phy,
5576                                 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
5577                                 0x0020);
5578                bnx2x_cl45_write(bp, phy,
5579                                 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
5580                bnx2x_cl45_write(bp, phy,
5581                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
5582                bnx2x_cl45_write(bp, phy,
5583                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
5584                                 0x0008);
5585        }
5586
5587        /* Set 2-wire transfer rate of SFP+ module EEPROM
5588         * to 100Khz since some DACs(direct attached cables) do
5589         * not work at 400Khz.
5590         */
5591        bnx2x_cl45_write(bp, phy,
5592                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
5593                         0xa001);
5594
5595        /* Set TX PreEmphasis if needed */
5596        if ((params->feature_config_flags &
5597             FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
5598                DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
5599                           phy->tx_preemphasis[0],
5600                           phy->tx_preemphasis[1]);
5601                bnx2x_cl45_write(bp, phy,
5602                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
5603                                 phy->tx_preemphasis[0]);
5604
5605                bnx2x_cl45_write(bp, phy,
5606                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
5607                                 phy->tx_preemphasis[1]);
5608        }
5609
5610        return 0;
5611}
5612
5613static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
5614                                      struct link_params *params)
5615{
5616        struct bnx2x *bp = params->bp;
5617        u16 mod_abs, rx_alarm_status;
5618        u32 val = REG_RD(bp, params->shmem_base +
5619                             offsetof(struct shmem_region, dev_info.
5620                                      port_feature_config[params->port].
5621                                      config));
5622        bnx2x_cl45_read(bp, phy,
5623                      MDIO_PMA_DEVAD,
5624                      MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
5625        if (mod_abs & (1<<8)) {
5626
5627                /* Module is absent */
5628                DP(NETIF_MSG_LINK, "MOD_ABS indication "
5629                            "show module is absent\n");
5630
5631                /* 1. Set mod_abs to detect next module
5632                presence event
5633                   2. Set EDC off by setting OPTXLOS signal input to low
5634                        (bit 9).
5635                        When the EDC is off it locks onto a reference clock and
5636                        avoids becoming 'lost'.*/
5637                mod_abs &= ~(1<<8);
5638                if (!(phy->flags & FLAGS_NOC))
5639                        mod_abs &= ~(1<<9);
5640                bnx2x_cl45_write(bp, phy,
5641                               MDIO_PMA_DEVAD,
5642                               MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
5643
5644                /* Clear RX alarm since it stays up as long as
5645                the mod_abs wasn't changed */
5646                bnx2x_cl45_read(bp, phy,
5647                              MDIO_PMA_DEVAD,
5648                              MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
5649
5650        } else {
5651                /* Module is present */
5652                DP(NETIF_MSG_LINK, "MOD_ABS indication "
5653                            "show module is present\n");
5654                /* First thing, disable transmitter,
5655                and if the module is ok, the
5656                module_detection will enable it*/
5657
5658                /* 1. Set mod_abs to detect next module
5659                absent event ( bit 8)
5660                   2. Restore the default polarity of the OPRXLOS signal and
5661                this signal will then correctly indicate the presence or
5662                absence of the Rx signal. (bit 9) */
5663                mod_abs |= (1<<8);
5664                if (!(phy->flags & FLAGS_NOC))
5665                        mod_abs |= (1<<9);
5666                bnx2x_cl45_write(bp, phy,
5667                                 MDIO_PMA_DEVAD,
5668                                 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
5669
5670                /* Clear RX alarm since it stays up as long as
5671                the mod_abs wasn't changed. This is need to be done
5672                before calling the module detection, otherwise it will clear
5673                the link update alarm */
5674                bnx2x_cl45_read(bp, phy,
5675                                MDIO_PMA_DEVAD,
5676                                MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
5677
5678
5679                if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
5680                    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
5681                        bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
5682
5683                if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
5684                        bnx2x_sfp_module_detection(phy, params);
5685                else
5686                        DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
5687        }
5688
5689        DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
5690                 rx_alarm_status);
5691        /* No need to check link status in case of
5692        module plugged in/out */
5693}
5694
5695static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
5696                                 struct link_params *params,
5697                                 struct link_vars *vars)
5698
5699{
5700        struct bnx2x *bp = params->bp;
5701        u8 link_up = 0;
5702        u16 link_status = 0;
5703        u16 rx_alarm_status, lasi_ctrl, val1;
5704
5705        /* If PHY is not initialized, do not check link status */
5706        bnx2x_cl45_read(bp, phy,
5707                        MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
5708                        &lasi_ctrl);
5709        if (!lasi_ctrl)
5710                return 0;
5711
5712        /* Check the LASI */
5713        bnx2x_cl45_read(bp, phy,
5714                        MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
5715                        &rx_alarm_status);
5716        vars->line_speed = 0;
5717        DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS  0x%x\n", rx_alarm_status);
5718
5719        bnx2x_cl45_read(bp, phy,
5720                        MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
5721
5722        DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
5723
5724        /* Clear MSG-OUT */
5725        bnx2x_cl45_read(bp, phy,
5726                        MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
5727
5728        /**
5729         * If a module is present and there is need to check
5730         * for over current
5731         */
5732        if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
5733                /* Check over-current using 8727 GPIO0 input*/
5734                bnx2x_cl45_read(bp, phy,
5735                                MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
5736                                &val1);
5737
5738                if ((val1 & (1<<8)) == 0) {
5739                        DP(NETIF_MSG_LINK, "8727 Power fault has been detected"
5740                                       " on port %d\n", params->port);
5741                        netdev_err(bp->dev, "Error:  Power fault on Port %d has"
5742                                            " been detected and the power to "
5743                                            "that SFP+ module has been removed"
5744                                            " to prevent failure of the card."
5745                                            " Please remove the SFP+ module and"
5746                                            " restart the system to clear this"
5747                                            " error.\n",
5748                                   params->port);
5749
5750                        /*
5751                         * Disable all RX_ALARMs except for
5752                         * mod_abs
5753                         */
5754                        bnx2x_cl45_write(bp, phy,
5755                                         MDIO_PMA_DEVAD,
5756                                         MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5));
5757
5758                        bnx2x_cl45_read(bp, phy,
5759                                        MDIO_PMA_DEVAD,
5760                                        MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
5761                        /* Wait for module_absent_event */
5762                        val1 |= (1<<8);
5763                        bnx2x_cl45_write(bp, phy,
5764                                         MDIO_PMA_DEVAD,
5765                                         MDIO_PMA_REG_PHY_IDENTIFIER, val1);
5766                        /* Clear RX alarm */
5767                        bnx2x_cl45_read(bp, phy,
5768                                MDIO_PMA_DEVAD,
5769                                MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
5770                        return 0;
5771                }
5772        } /* Over current check */
5773
5774        /* When module absent bit is set, check module */
5775        if (rx_alarm_status & (1<<5)) {
5776                bnx2x_8727_handle_mod_abs(phy, params);
5777                /* Enable all mod_abs and link detection bits */
5778                bnx2x_cl45_write(bp, phy,
5779                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5780                                 ((1<<5) | (1<<2)));
5781        }
5782        DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n");
5783        bnx2x_8727_specific_func(phy, params, ENABLE_TX);
5784        /* If transmitter is disabled, ignore false link up indication */
5785        bnx2x_cl45_read(bp, phy,
5786                        MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
5787        if (val1 & (1<<15)) {
5788                DP(NETIF_MSG_LINK, "Tx is disabled\n");
5789                return 0;
5790        }
5791
5792        bnx2x_cl45_read(bp, phy,
5793                        MDIO_PMA_DEVAD,
5794                        MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
5795
5796        /* Bits 0..2 --> speed detected,
5797           bits 13..15--> link is down */
5798        if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
5799                link_up = 1;
5800                vars->line_speed = SPEED_10000;
5801        } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
5802                link_up = 1;
5803                vars->line_speed = SPEED_1000;
5804                DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
5805                           params->port);
5806        } else {
5807                link_up = 0;
5808                DP(NETIF_MSG_LINK, "port %x: External link is down\n",
5809                           params->port);
5810        }
5811        if (link_up) {
5812                bnx2x_ext_phy_resolve_fc(phy, params, vars);
5813                vars->duplex = DUPLEX_FULL;
5814                DP(NETIF_MSG_LINK, "duplex = 0x%x\n", vars->duplex);
5815        }
5816
5817        if ((DUAL_MEDIA(params)) &&
5818            (phy->req_line_speed == SPEED_1000)) {
5819                bnx2x_cl45_read(bp, phy,
5820                                MDIO_PMA_DEVAD,
5821                                MDIO_PMA_REG_8727_PCS_GP, &val1);
5822                /**
5823                 * In case of dual-media board and 1G, power up the XAUI side,
5824                 * otherwise power it down. For 10G it is done automatically
5825                 */
5826                if (link_up)
5827                        val1 &= ~(3<<10);
5828                else
5829                        val1 |= (3<<10);
5830                bnx2x_cl45_write(bp, phy,
5831                                 MDIO_PMA_DEVAD,
5832                                 MDIO_PMA_REG_8727_PCS_GP, val1);
5833        }
5834        return link_up;
5835}
5836
5837static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
5838                                  struct link_params *params)
5839{
5840        struct bnx2x *bp = params->bp;
5841        /* Disable Transmitter */
5842        bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
5843        /* Clear LASI */
5844        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0);
5845
5846}
5847
5848/******************************************************************/
5849/*              BCM8481/BCM84823/BCM84833 PHY SECTION             */
5850/******************************************************************/
5851static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
5852                                           struct link_params *params)
5853{
5854        u16 val, fw_ver1, fw_ver2, cnt;
5855        struct bnx2x *bp = params->bp;
5856
5857        /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
5858        /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
5859        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
5860        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
5861        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
5862        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
5863        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
5864
5865        for (cnt = 0; cnt < 100; cnt++) {
5866                bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
5867                if (val & 1)
5868                        break;
5869                udelay(5);
5870        }
5871        if (cnt == 100) {
5872                DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n");
5873                bnx2x_save_spirom_version(bp, params->port, 0,
5874                                          phy->ver_addr);
5875                return;
5876        }
5877
5878
5879        /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
5880        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
5881        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
5882        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
5883        for (cnt = 0; cnt < 100; cnt++) {
5884                bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
5885                if (val & 1)
5886                        break;
5887                udelay(5);
5888        }
5889        if (cnt == 100) {
5890                DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n");
5891                bnx2x_save_spirom_version(bp, params->port, 0,
5892                                          phy->ver_addr);
5893                return;
5894        }
5895
5896        /* lower 16 bits of the register SPI_FW_STATUS */
5897        bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
5898        /* upper 16 bits of register SPI_FW_STATUS */
5899        bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
5900
5901        bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1,
5902                                  phy->ver_addr);
5903}
5904
5905static void bnx2x_848xx_set_led(struct bnx2x *bp,
5906                                struct bnx2x_phy *phy)
5907{
5908        u16 val;
5909
5910        /* PHYC_CTL_LED_CTL */
5911        bnx2x_cl45_read(bp, phy,
5912                        MDIO_PMA_DEVAD,
5913                        MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
5914        val &= 0xFE00;
5915        val |= 0x0092;
5916
5917        bnx2x_cl45_write(bp, phy,
5918                         MDIO_PMA_DEVAD,
5919                         MDIO_PMA_REG_8481_LINK_SIGNAL, val);
5920
5921        bnx2x_cl45_write(bp, phy,
5922                         MDIO_PMA_DEVAD,
5923                         MDIO_PMA_REG_8481_LED1_MASK,
5924                         0x80);
5925
5926        bnx2x_cl45_write(bp, phy,
5927                         MDIO_PMA_DEVAD,
5928                         MDIO_PMA_REG_8481_LED2_MASK,
5929                         0x18);
5930
5931        /* Select activity source by Tx and Rx, as suggested by PHY AE */
5932        bnx2x_cl45_write(bp, phy,
5933                         MDIO_PMA_DEVAD,
5934                         MDIO_PMA_REG_8481_LED3_MASK,
5935                         0x0006);
5936
5937        /* Select the closest activity blink rate to that in 10/100/1000 */
5938        bnx2x_cl45_write(bp, phy,
5939                        MDIO_PMA_DEVAD,
5940                        MDIO_PMA_REG_8481_LED3_BLINK,
5941                        0);
5942
5943        bnx2x_cl45_read(bp, phy,
5944                        MDIO_PMA_DEVAD,
5945                        MDIO_PMA_REG_84823_CTL_LED_CTL_1, &val);
5946        val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/
5947
5948        bnx2x_cl45_write(bp, phy,
5949                         MDIO_PMA_DEVAD,
5950                         MDIO_PMA_REG_84823_CTL_LED_CTL_1, val);
5951
5952        /* 'Interrupt Mask' */
5953        bnx2x_cl45_write(bp, phy,
5954                         MDIO_AN_DEVAD,
5955                         0xFFFB, 0xFFFD);
5956}
5957
5958static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
5959                                      struct link_params *params,
5960                                      struct link_vars *vars)
5961{
5962        struct bnx2x *bp = params->bp;
5963        u16 autoneg_val, an_1000_val, an_10_100_val;
5964
5965        bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
5966                      1 << NIG_LATCH_BC_ENABLE_MI_INT);
5967
5968        bnx2x_cl45_write(bp, phy,
5969                         MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
5970
5971        bnx2x_848xx_set_led(bp, phy);
5972
5973        /* set 1000 speed advertisement */
5974        bnx2x_cl45_read(bp, phy,
5975                        MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
5976                        &an_1000_val);
5977
5978        bnx2x_ext_phy_set_pause(params, phy, vars);
5979        bnx2x_cl45_read(bp, phy,
5980                        MDIO_AN_DEVAD,
5981                        MDIO_AN_REG_8481_LEGACY_AN_ADV,
5982                        &an_10_100_val);
5983        bnx2x_cl45_read(bp, phy,
5984                        MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
5985                        &autoneg_val);
5986        /* Disable forced speed */
5987        autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
5988        an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
5989
5990        if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
5991             (phy->speed_cap_mask &
5992             PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
5993            (phy->req_line_speed == SPEED_1000)) {
5994                an_1000_val |= (1<<8);
5995                autoneg_val |= (1<<9 | 1<<12);
5996                if (phy->req_duplex == DUPLEX_FULL)
5997                        an_1000_val |= (1<<9);
5998                DP(NETIF_MSG_LINK, "Advertising 1G\n");
5999        } else
6000                an_1000_val &= ~((1<<8) | (1<<9));
6001
6002        bnx2x_cl45_write(bp, phy,
6003                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
6004                         an_1000_val);
6005
6006        /* set 10 speed advertisement */
6007        if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
6008             (phy->speed_cap_mask &
6009             (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
6010              PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
6011                an_10_100_val |= (1<<7);
6012                /* Enable autoneg and restart autoneg for legacy speeds */
6013                autoneg_val |= (1<<9 | 1<<12);
6014
6015                if (phy->req_duplex == DUPLEX_FULL)
6016                        an_10_100_val |= (1<<8);
6017                DP(NETIF_MSG_LINK, "Advertising 100M\n");
6018        }
6019        /* set 10 speed advertisement */
6020        if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
6021            (phy->speed_cap_mask &
6022          (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
6023           PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
6024                an_10_100_val |= (1<<5);
6025                autoneg_val |= (1<<9 | 1<<12);
6026                if (phy->req_duplex == DUPLEX_FULL)
6027                        an_10_100_val |= (1<<6);
6028                DP(NETIF_MSG_LINK, "Advertising 10M\n");
6029        }
6030
6031        /* Only 10/100 are allowed to work in FORCE mode */
6032        if (phy->req_line_speed == SPEED_100) {
6033                autoneg_val |= (1<<13);
6034                /* Enabled AUTO-MDIX when autoneg is disabled */
6035                bnx2x_cl45_write(bp, phy,
6036                                 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
6037                                 (1<<15 | 1<<9 | 7<<0));
6038                DP(NETIF_MSG_LINK, "Setting 100M force\n");
6039        }
6040        if (phy->req_line_speed == SPEED_10) {
6041                /* Enabled AUTO-MDIX when autoneg is disabled */
6042                bnx2x_cl45_write(bp, phy,
6043                                 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
6044                                 (1<<15 | 1<<9 | 7<<0));
6045                DP(NETIF_MSG_LINK, "Setting 10M force\n");
6046        }
6047
6048        bnx2x_cl45_write(bp, phy,
6049                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
6050                         an_10_100_val);
6051
6052        if (phy->req_duplex == DUPLEX_FULL)
6053                autoneg_val |= (1<<8);
6054
6055        bnx2x_cl45_write(bp, phy,
6056                         MDIO_AN_DEVAD,
6057                         MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
6058
6059        if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
6060            (phy->speed_cap_mask &
6061             PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
6062                (phy->req_line_speed == SPEED_10000)) {
6063                DP(NETIF_MSG_LINK, "Advertising 10G\n");
6064                /* Restart autoneg for 10G*/
6065
6066                bnx2x_cl45_write(bp, phy,
6067                                 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
6068                                 0x3200);
6069        } else if (phy->req_line_speed != SPEED_10 &&
6070                   phy->req_line_speed != SPEED_100) {
6071                bnx2x_cl45_write(bp, phy,
6072                                 MDIO_AN_DEVAD,
6073                                 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
6074                                 1);
6075        }
6076        /* Save spirom version */
6077        bnx2x_save_848xx_spirom_version(phy, params);
6078
6079        return 0;
6080}
6081
6082static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy,
6083                                 struct link_params *params,
6084                                 struct link_vars *vars)
6085{
6086        struct bnx2x *bp = params->bp;
6087        /* Restore normal power mode*/
6088        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6089                            MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
6090
6091        /* HW reset */
6092        bnx2x_ext_phy_hw_reset(bp, params->port);
6093        bnx2x_wait_reset_complete(bp, phy);
6094
6095        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
6096        return bnx2x_848xx_cmn_config_init(phy, params, vars);
6097}
6098
6099static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
6100                                  struct link_params *params,
6101                                  struct link_vars *vars)
6102{
6103        struct bnx2x *bp = params->bp;
6104        u8 port, initialize = 1;
6105        u16 val;
6106        u16 temp;
6107        u32 actual_phy_selection;
6108        u8 rc = 0;
6109
6110        /* This is just for MDIO_CTL_REG_84823_MEDIA register. */
6111
6112        msleep(1);
6113        if (CHIP_IS_E2(bp))
6114                port = BP_PATH(bp);
6115        else
6116                port = params->port;
6117        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
6118                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
6119                       port);
6120        bnx2x_wait_reset_complete(bp, phy);
6121        /* Wait for GPHY to come out of reset */
6122        msleep(50);
6123        /* BCM84823 requires that XGXS links up first @ 10G for normal
6124        behavior */
6125        temp = vars->line_speed;
6126        vars->line_speed = SPEED_10000;
6127        bnx2x_set_autoneg(&params->phy[INT_PHY], params, vars, 0);
6128        bnx2x_program_serdes(&params->phy[INT_PHY], params, vars);
6129        vars->line_speed = temp;
6130
6131        /* Set dual-media configuration according to configuration */
6132
6133        bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
6134                        MDIO_CTL_REG_84823_MEDIA, &val);
6135        val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
6136                 MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
6137                 MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
6138                 MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
6139                 MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
6140        val |= MDIO_CTL_REG_84823_CTRL_MAC_XFI |
6141                MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L;
6142
6143        actual_phy_selection = bnx2x_phy_selection(params);
6144
6145        switch (actual_phy_selection) {
6146        case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
6147                /* Do nothing. Essentialy this is like the priority copper */
6148                break;
6149        case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
6150                val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
6151                break;
6152        case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
6153                val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
6154                break;
6155        case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
6156                /* Do nothing here. The first PHY won't be initialized at all */
6157                break;
6158        case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
6159                val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
6160                initialize = 0;
6161                break;
6162        }
6163        if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000)
6164                val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
6165
6166        bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
6167                         MDIO_CTL_REG_84823_MEDIA, val);
6168        DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
6169                   params->multi_phy_config, val);
6170
6171        if (initialize)
6172                rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
6173        else
6174                bnx2x_save_848xx_spirom_version(phy, params);
6175        return rc;
6176}
6177
6178static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
6179                                       struct link_params *params,
6180                                       struct link_vars *vars)
6181{
6182        struct bnx2x *bp = params->bp;
6183        u16 val, val1, val2;
6184        u8 link_up = 0;
6185
6186        /* Check 10G-BaseT link status */
6187        /* Check PMD signal ok */
6188        bnx2x_cl45_read(bp, phy,
6189                        MDIO_AN_DEVAD, 0xFFFA, &val1);
6190        bnx2x_cl45_read(bp, phy,
6191                        MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
6192                        &val2);
6193        DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
6194
6195        /* Check link 10G */
6196        if (val2 & (1<<11)) {
6197                vars->line_speed = SPEED_10000;
6198                vars->duplex = DUPLEX_FULL;
6199                link_up = 1;
6200                bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
6201        } else { /* Check Legacy speed link */
6202                u16 legacy_status, legacy_speed;
6203
6204                /* Enable expansion register 0x42 (Operation mode status) */
6205                bnx2x_cl45_write(bp, phy,
6206                                 MDIO_AN_DEVAD,
6207                                 MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
6208
6209                /* Get legacy speed operation status */
6210                bnx2x_cl45_read(bp, phy,
6211                                MDIO_AN_DEVAD,
6212                                MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
6213                                &legacy_status);
6214
6215                DP(NETIF_MSG_LINK, "Legacy speed status"
6216                             " = 0x%x\n", legacy_status);
6217                link_up = ((legacy_status & (1<<11)) == (1<<11));
6218                if (link_up) {
6219                        legacy_speed = (legacy_status & (3<<9));
6220                        if (legacy_speed == (0<<9))
6221                                vars->line_speed = SPEED_10;
6222                        else if (legacy_speed == (1<<9))
6223                                vars->line_speed = SPEED_100;
6224                        else if (legacy_speed == (2<<9))
6225                                vars->line_speed = SPEED_1000;
6226                        else /* Should not happen */
6227                                vars->line_speed = 0;
6228
6229                        if (legacy_status & (1<<8))
6230                                vars->duplex = DUPLEX_FULL;
6231                        else
6232                                vars->duplex = DUPLEX_HALF;
6233
6234                        DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
6235                                   " is_duplex_full= %d\n", vars->line_speed,
6236                                   (vars->duplex == DUPLEX_FULL));
6237                        /* Check legacy speed AN resolution */
6238                        bnx2x_cl45_read(bp, phy,
6239                                        MDIO_AN_DEVAD,
6240                                        MDIO_AN_REG_8481_LEGACY_MII_STATUS,
6241                                        &val);
6242                        if (val & (1<<5))
6243                                vars->link_status |=
6244                                        LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6245                        bnx2x_cl45_read(bp, phy,
6246                                        MDIO_AN_DEVAD,
6247                                        MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
6248                                        &val);
6249                        if ((val & (1<<0)) == 0)
6250                                vars->link_status |=
6251                                        LINK_STATUS_PARALLEL_DETECTION_USED;
6252                }
6253        }
6254        if (link_up) {
6255                DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n",
6256                           vars->line_speed);
6257                bnx2x_ext_phy_resolve_fc(phy, params, vars);
6258        }
6259
6260        return link_up;
6261}
6262
6263static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
6264{
6265        u8 status = 0;
6266        u32 spirom_ver;
6267        spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
6268        status = bnx2x_format_ver(spirom_ver, str, len);
6269        return status;
6270}
6271
6272static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
6273                                struct link_params *params)
6274{
6275        bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
6276                            MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
6277        bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
6278                            MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
6279}
6280
6281static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
6282                                        struct link_params *params)
6283{
6284        bnx2x_cl45_write(params->bp, phy,
6285                         MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
6286        bnx2x_cl45_write(params->bp, phy,
6287                         MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
6288}
6289
6290static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
6291                                   struct link_params *params)
6292{
6293        struct bnx2x *bp = params->bp;
6294        u8 port;
6295        if (CHIP_IS_E2(bp))
6296                port = BP_PATH(bp);
6297        else
6298                port = params->port;
6299        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
6300                            MISC_REGISTERS_GPIO_OUTPUT_LOW,
6301                            port);
6302}
6303
6304static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
6305                                     struct link_params *params, u8 mode)
6306{
6307        struct bnx2x *bp = params->bp;
6308        u16 val;
6309
6310        switch (mode) {
6311        case LED_MODE_OFF:
6312
6313                DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", params->port);
6314
6315                if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
6316                    SHARED_HW_CFG_LED_EXTPHY1) {
6317
6318                        /* Set LED masks */
6319                        bnx2x_cl45_write(bp, phy,
6320                                        MDIO_PMA_DEVAD,
6321                                        MDIO_PMA_REG_8481_LED1_MASK,
6322                                        0x0);
6323
6324                        bnx2x_cl45_write(bp, phy,
6325                                        MDIO_PMA_DEVAD,
6326                                        MDIO_PMA_REG_8481_LED2_MASK,
6327                                        0x0);
6328
6329                        bnx2x_cl45_write(bp, phy,
6330                                        MDIO_PMA_DEVAD,
6331                                        MDIO_PMA_REG_8481_LED3_MASK,
6332                                        0x0);
6333
6334                        bnx2x_cl45_write(bp, phy,
6335                                        MDIO_PMA_DEVAD,
6336                                        MDIO_PMA_REG_8481_LED5_MASK,
6337                                        0x0);
6338
6339                } else {
6340                        bnx2x_cl45_write(bp, phy,
6341                                         MDIO_PMA_DEVAD,
6342                                         MDIO_PMA_REG_8481_LED1_MASK,
6343                                         0x0);
6344                }
6345                break;
6346        case LED_MODE_FRONT_PANEL_OFF:
6347
6348                DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
6349                   params->port);
6350
6351                if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
6352                    SHARED_HW_CFG_LED_EXTPHY1) {
6353
6354                        /* Set LED masks */
6355                        bnx2x_cl45_write(bp, phy,
6356                                        MDIO_PMA_DEVAD,
6357                                        MDIO_PMA_REG_8481_LED1_MASK,
6358                                        0x0);
6359
6360                        bnx2x_cl45_write(bp, phy,
6361                                        MDIO_PMA_DEVAD,
6362                                        MDIO_PMA_REG_8481_LED2_MASK,
6363                                        0x0);
6364
6365                        bnx2x_cl45_write(bp, phy,
6366                                        MDIO_PMA_DEVAD,
6367                                        MDIO_PMA_REG_8481_LED3_MASK,
6368                                        0x0);
6369
6370                        bnx2x_cl45_write(bp, phy,
6371                                        MDIO_PMA_DEVAD,
6372                                        MDIO_PMA_REG_8481_LED5_MASK,
6373                                        0x20);
6374
6375                } else {
6376                        bnx2x_cl45_write(bp, phy,
6377                                         MDIO_PMA_DEVAD,
6378                                         MDIO_PMA_REG_8481_LED1_MASK,
6379                                         0x0);
6380                }
6381                break;
6382        case LED_MODE_ON:
6383
6384                DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", params->port);
6385
6386                if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
6387                    SHARED_HW_CFG_LED_EXTPHY1) {
6388                        /* Set control reg */
6389                        bnx2x_cl45_read(bp, phy,
6390                                        MDIO_PMA_DEVAD,
6391                                        MDIO_PMA_REG_8481_LINK_SIGNAL,
6392                                        &val);
6393                        val &= 0x8000;
6394                        val |= 0x2492;
6395
6396                        bnx2x_cl45_write(bp, phy,
6397                                        MDIO_PMA_DEVAD,
6398                                        MDIO_PMA_REG_8481_LINK_SIGNAL,
6399                                        val);
6400
6401                        /* Set LED masks */
6402                        bnx2x_cl45_write(bp, phy,
6403                                        MDIO_PMA_DEVAD,
6404                                        MDIO_PMA_REG_8481_LED1_MASK,
6405                                        0x0);
6406
6407                        bnx2x_cl45_write(bp, phy,
6408                                        MDIO_PMA_DEVAD,
6409                                        MDIO_PMA_REG_8481_LED2_MASK,
6410                                        0x20);
6411
6412                        bnx2x_cl45_write(bp, phy,
6413                                        MDIO_PMA_DEVAD,
6414                                        MDIO_PMA_REG_8481_LED3_MASK,
6415                                        0x20);
6416
6417                        bnx2x_cl45_write(bp, phy,
6418                                        MDIO_PMA_DEVAD,
6419                                        MDIO_PMA_REG_8481_LED5_MASK,
6420                                        0x0);
6421                } else {
6422                        bnx2x_cl45_write(bp, phy,
6423                                        MDIO_PMA_DEVAD,
6424                                        MDIO_PMA_REG_8481_LED1_MASK,
6425                                        0x20);
6426                }
6427                break;
6428
6429        case LED_MODE_OPER:
6430
6431                DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", params->port);
6432
6433                if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
6434                    SHARED_HW_CFG_LED_EXTPHY1) {
6435
6436                        /* Set control reg */
6437                        bnx2x_cl45_read(bp, phy,
6438                                        MDIO_PMA_DEVAD,
6439                                        MDIO_PMA_REG_8481_LINK_SIGNAL,
6440                                        &val);
6441
6442                        if (!((val &
6443                              MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
6444                           >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)){
6445                                DP(NETIF_MSG_LINK, "Seting LINK_SIGNAL\n");
6446                                bnx2x_cl45_write(bp, phy,
6447                                                 MDIO_PMA_DEVAD,
6448                                                 MDIO_PMA_REG_8481_LINK_SIGNAL,
6449                                                 0xa492);
6450                        }
6451
6452                        /* Set LED masks */
6453                        bnx2x_cl45_write(bp, phy,
6454                                        MDIO_PMA_DEVAD,
6455                                        MDIO_PMA_REG_8481_LED1_MASK,
6456                                        0x10);
6457
6458                        bnx2x_cl45_write(bp, phy,
6459                                        MDIO_PMA_DEVAD,
6460                                        MDIO_PMA_REG_8481_LED2_MASK,
6461                                        0x80);
6462
6463                        bnx2x_cl45_write(bp, phy,
6464                                        MDIO_PMA_DEVAD,
6465                                        MDIO_PMA_REG_8481_LED3_MASK,
6466                                        0x98);
6467
6468                        bnx2x_cl45_write(bp, phy,
6469                                        MDIO_PMA_DEVAD,
6470                                        MDIO_PMA_REG_8481_LED5_MASK,
6471                                        0x40);
6472
6473                } else {
6474                        bnx2x_cl45_write(bp, phy,
6475                                         MDIO_PMA_DEVAD,
6476                                         MDIO_PMA_REG_8481_LED1_MASK,
6477                                         0x80);
6478
6479                        /* Tell LED3 to blink on source */
6480                        bnx2x_cl45_read(bp, phy,
6481                                        MDIO_PMA_DEVAD,
6482                                        MDIO_PMA_REG_8481_LINK_SIGNAL,
6483                                        &val);
6484                        val &= ~(7<<6);
6485                        val |= (1<<6); /* A83B[8:6]= 1 */
6486                        bnx2x_cl45_write(bp, phy,
6487                                         MDIO_PMA_DEVAD,
6488                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
6489                                         val);
6490                }
6491                break;
6492        }
6493}
6494/******************************************************************/
6495/*                      SFX7101 PHY SECTION                       */
6496/******************************************************************/
6497static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
6498                                       struct link_params *params)
6499{
6500        struct bnx2x *bp = params->bp;
6501        /* SFX7101_XGXS_TEST1 */
6502        bnx2x_cl45_write(bp, phy,
6503                         MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
6504}
6505
6506static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy,
6507                                 struct link_params *params,
6508                                 struct link_vars *vars)
6509{
6510        u16 fw_ver1, fw_ver2, val;
6511        struct bnx2x *bp = params->bp;
6512        DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
6513
6514        /* Restore normal power mode*/
6515        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6516                            MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
6517        /* HW reset */
6518        bnx2x_ext_phy_hw_reset(bp, params->port);
6519        bnx2x_wait_reset_complete(bp, phy);
6520
6521        bnx2x_cl45_write(bp, phy,
6522                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1);
6523        DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
6524        bnx2x_cl45_write(bp, phy,
6525                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
6526
6527        bnx2x_ext_phy_set_pause(params, phy, vars);
6528        /* Restart autoneg */
6529        bnx2x_cl45_read(bp, phy,
6530                        MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
6531        val |= 0x200;
6532        bnx2x_cl45_write(bp, phy,
6533                         MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
6534
6535        /* Save spirom version */
6536        bnx2x_cl45_read(bp, phy,
6537                        MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
6538
6539        bnx2x_cl45_read(bp, phy,
6540                        MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
6541        bnx2x_save_spirom_version(bp, params->port,
6542                                  (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
6543        return 0;
6544}
6545
6546static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
6547                                 struct link_params *params,
6548                                 struct link_vars *vars)
6549{
6550        struct bnx2x *bp = params->bp;
6551        u8 link_up;
6552        u16 val1, val2;
6553        bnx2x_cl45_read(bp, phy,
6554                        MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
6555        bnx2x_cl45_read(bp, phy,
6556                        MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
6557        DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
6558                   val2, val1);
6559        bnx2x_cl45_read(bp, phy,
6560                        MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
6561        bnx2x_cl45_read(bp, phy,
6562                        MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
6563        DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
6564                   val2, val1);
6565        link_up = ((val1 & 4) == 4);
6566        /* if link is up
6567         * print the AN outcome of the SFX7101 PHY
6568         */
6569        if (link_up) {
6570                bnx2x_cl45_read(bp, phy,
6571                                MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
6572                                &val2);
6573                vars->line_speed = SPEED_10000;
6574                vars->duplex = DUPLEX_FULL;
6575                DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
6576                           val2, (val2 & (1<<14)));
6577                bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
6578                bnx2x_ext_phy_resolve_fc(phy, params, vars);
6579        }
6580        return link_up;
6581}
6582
6583
6584static u8 bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
6585{
6586        if (*len < 5)
6587                return -EINVAL;
6588        str[0] = (spirom_ver & 0xFF);
6589        str[1] = (spirom_ver & 0xFF00) >> 8;
6590        str[2] = (spirom_ver & 0xFF0000) >> 16;
6591        str[3] = (spirom_ver & 0xFF000000) >> 24;
6592        str[4] = '\0';
6593        *len -= 5;
6594        return 0;
6595}
6596
6597void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
6598{
6599        u16 val, cnt;
6600
6601        bnx2x_cl45_read(bp, phy,
6602                      MDIO_PMA_DEVAD,
6603                      MDIO_PMA_REG_7101_RESET, &val);
6604
6605        for (cnt = 0; cnt < 10; cnt++) {
6606                msleep(50);
6607                /* Writes a self-clearing reset */
6608                bnx2x_cl45_write(bp, phy,
6609                               MDIO_PMA_DEVAD,
6610                               MDIO_PMA_REG_7101_RESET,
6611                               (val | (1<<15)));
6612                /* Wait for clear */
6613                bnx2x_cl45_read(bp, phy,
6614                              MDIO_PMA_DEVAD,
6615                              MDIO_PMA_REG_7101_RESET, &val);
6616
6617                if ((val & (1<<15)) == 0)
6618                        break;
6619        }
6620}
6621
6622static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
6623                                struct link_params *params) {
6624        /* Low power mode is controlled by GPIO 2 */
6625        bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
6626                            MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
6627        /* The PHY reset is controlled by GPIO 1 */
6628        bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
6629                            MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
6630}
6631
6632static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy,
6633                                    struct link_params *params, u8 mode)
6634{
6635        u16 val = 0;
6636        struct bnx2x *bp = params->bp;
6637        switch (mode) {
6638        case LED_MODE_FRONT_PANEL_OFF:
6639        case LED_MODE_OFF:
6640                val = 2;
6641                break;
6642        case LED_MODE_ON:
6643                val = 1;
6644                break;
6645        case LED_MODE_OPER:
6646                val = 0;
6647                break;
6648        }
6649        bnx2x_cl45_write(bp, phy,
6650                         MDIO_PMA_DEVAD,
6651                         MDIO_PMA_REG_7107_LINK_LED_CNTL,
6652                         val);
6653}
6654
6655/******************************************************************/
6656/*                      STATIC PHY DECLARATION                    */
6657/******************************************************************/
6658
6659static struct bnx2x_phy phy_null = {
6660        .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
6661        .addr           = 0,
6662        .flags          = FLAGS_INIT_XGXS_FIRST,
6663        .def_md_devad   = 0,
6664        .reserved       = 0,
6665        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6666        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6667        .mdio_ctrl      = 0,
6668        .supported      = 0,
6669        .media_type     = ETH_PHY_NOT_PRESENT,
6670        .ver_addr       = 0,
6671        .req_flow_ctrl  = 0,
6672        .req_line_speed = 0,
6673        .speed_cap_mask = 0,
6674        .req_duplex     = 0,
6675        .rsrv           = 0,
6676        .config_init    = (config_init_t)NULL,
6677        .read_status    = (read_status_t)NULL,
6678        .link_reset     = (link_reset_t)NULL,
6679        .config_loopback = (config_loopback_t)NULL,
6680        .format_fw_ver  = (format_fw_ver_t)NULL,
6681        .hw_reset       = (hw_reset_t)NULL,
6682        .set_link_led   = (set_link_led_t)NULL,
6683        .phy_specific_func = (phy_specific_func_t)NULL
6684};
6685
6686static struct bnx2x_phy phy_serdes = {
6687        .type           = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
6688        .addr           = 0xff,
6689        .flags          = 0,
6690        .def_md_devad   = 0,
6691        .reserved       = 0,
6692        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6693        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6694        .mdio_ctrl      = 0,
6695        .supported      = (SUPPORTED_10baseT_Half |
6696                           SUPPORTED_10baseT_Full |
6697                           SUPPORTED_100baseT_Half |
6698                           SUPPORTED_100baseT_Full |
6699                           SUPPORTED_1000baseT_Full |
6700                           SUPPORTED_2500baseX_Full |
6701                           SUPPORTED_TP |
6702                           SUPPORTED_Autoneg |
6703                           SUPPORTED_Pause |
6704                           SUPPORTED_Asym_Pause),
6705        .media_type     = ETH_PHY_UNSPECIFIED,
6706        .ver_addr       = 0,
6707        .req_flow_ctrl  = 0,
6708        .req_line_speed = 0,
6709        .speed_cap_mask = 0,
6710        .req_duplex     = 0,
6711        .rsrv           = 0,
6712        .config_init    = (config_init_t)bnx2x_init_serdes,
6713        .read_status    = (read_status_t)bnx2x_link_settings_status,
6714        .link_reset     = (link_reset_t)bnx2x_int_link_reset,
6715        .config_loopback = (config_loopback_t)NULL,
6716        .format_fw_ver  = (format_fw_ver_t)NULL,
6717        .hw_reset       = (hw_reset_t)NULL,
6718        .set_link_led   = (set_link_led_t)NULL,
6719        .phy_specific_func = (phy_specific_func_t)NULL
6720};
6721
6722static struct bnx2x_phy phy_xgxs = {
6723        .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
6724        .addr           = 0xff,
6725        .flags          = 0,
6726        .def_md_devad   = 0,
6727        .reserved       = 0,
6728        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6729        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6730        .mdio_ctrl      = 0,
6731        .supported      = (SUPPORTED_10baseT_Half |
6732                           SUPPORTED_10baseT_Full |
6733                           SUPPORTED_100baseT_Half |
6734                           SUPPORTED_100baseT_Full |
6735                           SUPPORTED_1000baseT_Full |
6736                           SUPPORTED_2500baseX_Full |
6737                           SUPPORTED_10000baseT_Full |
6738                           SUPPORTED_FIBRE |
6739                           SUPPORTED_Autoneg |
6740                           SUPPORTED_Pause |
6741                           SUPPORTED_Asym_Pause),
6742        .media_type     = ETH_PHY_UNSPECIFIED,
6743        .ver_addr       = 0,
6744        .req_flow_ctrl  = 0,
6745        .req_line_speed = 0,
6746        .speed_cap_mask = 0,
6747        .req_duplex     = 0,
6748        .rsrv           = 0,
6749        .config_init    = (config_init_t)bnx2x_init_xgxs,
6750        .read_status    = (read_status_t)bnx2x_link_settings_status,
6751        .link_reset     = (link_reset_t)bnx2x_int_link_reset,
6752        .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
6753        .format_fw_ver  = (format_fw_ver_t)NULL,
6754        .hw_reset       = (hw_reset_t)NULL,
6755        .set_link_led   = (set_link_led_t)NULL,
6756        .phy_specific_func = (phy_specific_func_t)NULL
6757};
6758
6759static struct bnx2x_phy phy_7101 = {
6760        .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6761        .addr           = 0xff,
6762        .flags          = FLAGS_FAN_FAILURE_DET_REQ,
6763        .def_md_devad   = 0,
6764        .reserved       = 0,
6765        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6766        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6767        .mdio_ctrl      = 0,
6768        .supported      = (SUPPORTED_10000baseT_Full |
6769                           SUPPORTED_TP |
6770                           SUPPORTED_Autoneg |
6771                           SUPPORTED_Pause |
6772                           SUPPORTED_Asym_Pause),
6773        .media_type     = ETH_PHY_BASE_T,
6774        .ver_addr       = 0,
6775        .req_flow_ctrl  = 0,
6776        .req_line_speed = 0,
6777        .speed_cap_mask = 0,
6778        .req_duplex     = 0,
6779        .rsrv           = 0,
6780        .config_init    = (config_init_t)bnx2x_7101_config_init,
6781        .read_status    = (read_status_t)bnx2x_7101_read_status,
6782        .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
6783        .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
6784        .format_fw_ver  = (format_fw_ver_t)bnx2x_7101_format_ver,
6785        .hw_reset       = (hw_reset_t)bnx2x_7101_hw_reset,
6786        .set_link_led   = (set_link_led_t)bnx2x_7101_set_link_led,
6787        .phy_specific_func = (phy_specific_func_t)NULL
6788};
6789static struct bnx2x_phy phy_8073 = {
6790        .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6791        .addr           = 0xff,
6792        .flags          = FLAGS_HW_LOCK_REQUIRED,
6793        .def_md_devad   = 0,
6794        .reserved       = 0,
6795        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6796        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6797        .mdio_ctrl      = 0,
6798        .supported      = (SUPPORTED_10000baseT_Full |
6799                           SUPPORTED_2500baseX_Full |
6800                           SUPPORTED_1000baseT_Full |
6801                           SUPPORTED_FIBRE |
6802                           SUPPORTED_Autoneg |
6803                           SUPPORTED_Pause |
6804                           SUPPORTED_Asym_Pause),
6805        .media_type     = ETH_PHY_UNSPECIFIED,
6806        .ver_addr       = 0,
6807        .req_flow_ctrl  = 0,
6808        .req_line_speed = 0,
6809        .speed_cap_mask = 0,
6810        .req_duplex     = 0,
6811        .rsrv           = 0,
6812        .config_init    = (config_init_t)bnx2x_8073_config_init,
6813        .read_status    = (read_status_t)bnx2x_8073_read_status,
6814        .link_reset     = (link_reset_t)bnx2x_8073_link_reset,
6815        .config_loopback = (config_loopback_t)NULL,
6816        .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
6817        .hw_reset       = (hw_reset_t)NULL,
6818        .set_link_led   = (set_link_led_t)NULL,
6819        .phy_specific_func = (phy_specific_func_t)NULL
6820};
6821static struct bnx2x_phy phy_8705 = {
6822        .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
6823        .addr           = 0xff,
6824        .flags          = FLAGS_INIT_XGXS_FIRST,
6825        .def_md_devad   = 0,
6826        .reserved       = 0,
6827        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6828        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6829        .mdio_ctrl      = 0,
6830        .supported      = (SUPPORTED_10000baseT_Full |
6831                           SUPPORTED_FIBRE |
6832                           SUPPORTED_Pause |
6833                           SUPPORTED_Asym_Pause),
6834        .media_type     = ETH_PHY_XFP_FIBER,
6835        .ver_addr       = 0,
6836        .req_flow_ctrl  = 0,
6837        .req_line_speed = 0,
6838        .speed_cap_mask = 0,
6839        .req_duplex     = 0,
6840        .rsrv           = 0,
6841        .config_init    = (config_init_t)bnx2x_8705_config_init,
6842        .read_status    = (read_status_t)bnx2x_8705_read_status,
6843        .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
6844        .config_loopback = (config_loopback_t)NULL,
6845        .format_fw_ver  = (format_fw_ver_t)bnx2x_null_format_ver,
6846        .hw_reset       = (hw_reset_t)NULL,
6847        .set_link_led   = (set_link_led_t)NULL,
6848        .phy_specific_func = (phy_specific_func_t)NULL
6849};
6850static struct bnx2x_phy phy_8706 = {
6851        .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
6852        .addr           = 0xff,
6853        .flags          = FLAGS_INIT_XGXS_FIRST,
6854        .def_md_devad   = 0,
6855        .reserved       = 0,
6856        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6857        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6858        .mdio_ctrl      = 0,
6859        .supported      = (SUPPORTED_10000baseT_Full |
6860                           SUPPORTED_1000baseT_Full |
6861                           SUPPORTED_FIBRE |
6862                           SUPPORTED_Pause |
6863                           SUPPORTED_Asym_Pause),
6864        .media_type     = ETH_PHY_SFP_FIBER,
6865        .ver_addr       = 0,
6866        .req_flow_ctrl  = 0,
6867        .req_line_speed = 0,
6868        .speed_cap_mask = 0,
6869        .req_duplex     = 0,
6870        .rsrv           = 0,
6871        .config_init    = (config_init_t)bnx2x_8706_config_init,
6872        .read_status    = (read_status_t)bnx2x_8706_read_status,
6873        .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
6874        .config_loopback = (config_loopback_t)NULL,
6875        .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
6876        .hw_reset       = (hw_reset_t)NULL,
6877        .set_link_led   = (set_link_led_t)NULL,
6878        .phy_specific_func = (phy_specific_func_t)NULL
6879};
6880
6881static struct bnx2x_phy phy_8726 = {
6882        .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
6883        .addr           = 0xff,
6884        .flags          = (FLAGS_HW_LOCK_REQUIRED |
6885                           FLAGS_INIT_XGXS_FIRST),
6886        .def_md_devad   = 0,
6887        .reserved       = 0,
6888        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6889        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6890        .mdio_ctrl      = 0,
6891        .supported      = (SUPPORTED_10000baseT_Full |
6892                           SUPPORTED_1000baseT_Full |
6893                           SUPPORTED_Autoneg |
6894                           SUPPORTED_FIBRE |
6895                           SUPPORTED_Pause |
6896                           SUPPORTED_Asym_Pause),
6897        .media_type     = ETH_PHY_SFP_FIBER,
6898        .ver_addr       = 0,
6899        .req_flow_ctrl  = 0,
6900        .req_line_speed = 0,
6901        .speed_cap_mask = 0,
6902        .req_duplex     = 0,
6903        .rsrv           = 0,
6904        .config_init    = (config_init_t)bnx2x_8726_config_init,
6905        .read_status    = (read_status_t)bnx2x_8726_read_status,
6906        .link_reset     = (link_reset_t)bnx2x_8726_link_reset,
6907        .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
6908        .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
6909        .hw_reset       = (hw_reset_t)NULL,
6910        .set_link_led   = (set_link_led_t)NULL,
6911        .phy_specific_func = (phy_specific_func_t)NULL
6912};
6913
6914static struct bnx2x_phy phy_8727 = {
6915        .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6916        .addr           = 0xff,
6917        .flags          = FLAGS_FAN_FAILURE_DET_REQ,
6918        .def_md_devad   = 0,
6919        .reserved       = 0,
6920        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6921        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6922        .mdio_ctrl      = 0,
6923        .supported      = (SUPPORTED_10000baseT_Full |
6924                           SUPPORTED_1000baseT_Full |
6925                           SUPPORTED_FIBRE |
6926                           SUPPORTED_Pause |
6927                           SUPPORTED_Asym_Pause),
6928        .media_type     = ETH_PHY_SFP_FIBER,
6929        .ver_addr       = 0,
6930        .req_flow_ctrl  = 0,
6931        .req_line_speed = 0,
6932        .speed_cap_mask = 0,
6933        .req_duplex     = 0,
6934        .rsrv           = 0,
6935        .config_init    = (config_init_t)bnx2x_8727_config_init,
6936        .read_status    = (read_status_t)bnx2x_8727_read_status,
6937        .link_reset     = (link_reset_t)bnx2x_8727_link_reset,
6938        .config_loopback = (config_loopback_t)NULL,
6939        .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
6940        .hw_reset       = (hw_reset_t)bnx2x_8727_hw_reset,
6941        .set_link_led   = (set_link_led_t)bnx2x_8727_set_link_led,
6942        .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func
6943};
6944static struct bnx2x_phy phy_8481 = {
6945        .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
6946        .addr           = 0xff,
6947        .flags          = FLAGS_FAN_FAILURE_DET_REQ |
6948                          FLAGS_REARM_LATCH_SIGNAL,
6949        .def_md_devad   = 0,
6950        .reserved       = 0,
6951        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6952        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6953        .mdio_ctrl      = 0,
6954        .supported      = (SUPPORTED_10baseT_Half |
6955                           SUPPORTED_10baseT_Full |
6956                           SUPPORTED_100baseT_Half |
6957                           SUPPORTED_100baseT_Full |
6958                           SUPPORTED_1000baseT_Full |
6959                           SUPPORTED_10000baseT_Full |
6960                           SUPPORTED_TP |
6961                           SUPPORTED_Autoneg |
6962                           SUPPORTED_Pause |
6963                           SUPPORTED_Asym_Pause),
6964        .media_type     = ETH_PHY_BASE_T,
6965        .ver_addr       = 0,
6966        .req_flow_ctrl  = 0,
6967        .req_line_speed = 0,
6968        .speed_cap_mask = 0,
6969        .req_duplex     = 0,
6970        .rsrv           = 0,
6971        .config_init    = (config_init_t)bnx2x_8481_config_init,
6972        .read_status    = (read_status_t)bnx2x_848xx_read_status,
6973        .link_reset     = (link_reset_t)bnx2x_8481_link_reset,
6974        .config_loopback = (config_loopback_t)NULL,
6975        .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
6976        .hw_reset       = (hw_reset_t)bnx2x_8481_hw_reset,
6977        .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
6978        .phy_specific_func = (phy_specific_func_t)NULL
6979};
6980
6981static struct bnx2x_phy phy_84823 = {
6982        .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
6983        .addr           = 0xff,
6984        .flags          = FLAGS_FAN_FAILURE_DET_REQ |
6985                          FLAGS_REARM_LATCH_SIGNAL,
6986        .def_md_devad   = 0,
6987        .reserved       = 0,
6988        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6989        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6990        .mdio_ctrl      = 0,
6991        .supported      = (SUPPORTED_10baseT_Half |
6992                           SUPPORTED_10baseT_Full |
6993                           SUPPORTED_100baseT_Half |
6994                           SUPPORTED_100baseT_Full |
6995                           SUPPORTED_1000baseT_Full |
6996                           SUPPORTED_10000baseT_Full |
6997                           SUPPORTED_TP |
6998                           SUPPORTED_Autoneg |
6999                           SUPPORTED_Pause |
7000                           SUPPORTED_Asym_Pause),
7001        .media_type     = ETH_PHY_BASE_T,
7002        .ver_addr       = 0,
7003        .req_flow_ctrl  = 0,
7004        .req_line_speed = 0,
7005        .speed_cap_mask = 0,
7006        .req_duplex     = 0,
7007        .rsrv           = 0,
7008        .config_init    = (config_init_t)bnx2x_848x3_config_init,
7009        .read_status    = (read_status_t)bnx2x_848xx_read_status,
7010        .link_reset     = (link_reset_t)bnx2x_848x3_link_reset,
7011        .config_loopback = (config_loopback_t)NULL,
7012        .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
7013        .hw_reset       = (hw_reset_t)NULL,
7014        .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
7015        .phy_specific_func = (phy_specific_func_t)NULL
7016};
7017
7018/*****************************************************************/
7019/*                                                               */
7020/* Populate the phy according. Main function: bnx2x_populate_phy   */
7021/*                                                               */
7022/*****************************************************************/
7023
7024static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
7025                                     struct bnx2x_phy *phy, u8 port,
7026                                     u8 phy_index)
7027{
7028        /* Get the 4 lanes xgxs config rx and tx */
7029        u32 rx = 0, tx = 0, i;
7030        for (i = 0; i < 2; i++) {
7031                /**
7032                 * INT_PHY and EXT_PHY1 share the same value location in the
7033                 * shmem. When num_phys is greater than 1, than this value
7034                 * applies only to EXT_PHY1
7035                 */
7036                if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
7037                        rx = REG_RD(bp, shmem_base +
7038                                    offsetof(struct shmem_region,
7039                           dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
7040
7041                        tx = REG_RD(bp, shmem_base +
7042                                    offsetof(struct shmem_region,
7043                           dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
7044                } else {
7045                        rx = REG_RD(bp, shmem_base +
7046                                    offsetof(struct shmem_region,
7047                          dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
7048
7049                        tx = REG_RD(bp, shmem_base +
7050                                    offsetof(struct shmem_region,
7051                          dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
7052                }
7053
7054                phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
7055                phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
7056
7057                phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
7058                phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
7059        }
7060}
7061
7062static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
7063                                    u8 phy_index, u8 port)
7064{
7065        u32 ext_phy_config = 0;
7066        switch (phy_index) {
7067        case EXT_PHY1:
7068                ext_phy_config = REG_RD(bp, shmem_base +
7069                                              offsetof(struct shmem_region,
7070                        dev_info.port_hw_config[port].external_phy_config));
7071                break;
7072        case EXT_PHY2:
7073                ext_phy_config = REG_RD(bp, shmem_base +
7074                                              offsetof(struct shmem_region,
7075                        dev_info.port_hw_config[port].external_phy_config2));
7076                break;
7077        default:
7078                DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
7079                return -EINVAL;
7080        }
7081
7082        return ext_phy_config;
7083}
7084static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
7085                                 struct bnx2x_phy *phy)
7086{
7087        u32 phy_addr;
7088        u32 chip_id;
7089        u32 switch_cfg = (REG_RD(bp, shmem_base +
7090                                       offsetof(struct shmem_region,
7091                        dev_info.port_feature_config[port].link_config)) &
7092                          PORT_FEATURE_CONNECTED_SWITCH_MASK);
7093        chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16;
7094        switch (switch_cfg) {
7095        case SWITCH_CFG_1G:
7096                phy_addr = REG_RD(bp,
7097                                        NIG_REG_SERDES0_CTRL_PHY_ADDR +
7098                                        port * 0x10);
7099                *phy = phy_serdes;
7100                break;
7101        case SWITCH_CFG_10G:
7102                phy_addr = REG_RD(bp,
7103                                        NIG_REG_XGXS0_CTRL_PHY_ADDR +
7104                                        port * 0x18);
7105                *phy = phy_xgxs;
7106                break;
7107        default:
7108                DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
7109                return -EINVAL;
7110        }
7111        phy->addr = (u8)phy_addr;
7112        phy->mdio_ctrl = bnx2x_get_emac_base(bp,
7113                                            SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
7114                                            port);
7115        if (CHIP_IS_E2(bp))
7116                phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
7117        else
7118                phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
7119
7120        DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
7121                   port, phy->addr, phy->mdio_ctrl);
7122
7123        bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
7124        return 0;
7125}
7126
7127static u8 bnx2x_populate_ext_phy(struct bnx2x *bp,
7128                                 u8 phy_index,
7129                                 u32 shmem_base,
7130                                 u32 shmem2_base,
7131                                 u8 port,
7132                                 struct bnx2x_phy *phy)
7133{
7134        u32 ext_phy_config, phy_type, config2;
7135        u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
7136        ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
7137                                                  phy_index, port);
7138        phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
7139        /* Select the phy type */
7140        switch (phy_type) {
7141        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
7142                mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
7143                *phy = phy_8073;
7144                break;
7145        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
7146                *phy = phy_8705;
7147                break;
7148        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
7149                *phy = phy_8706;
7150                break;
7151        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7152                mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
7153                *phy = phy_8726;
7154                break;
7155        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
7156                /* BCM8727_NOC => BCM8727 no over current */
7157                mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
7158                *phy = phy_8727;
7159                phy->flags |= FLAGS_NOC;
7160                break;
7161        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7162                mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
7163                *phy = phy_8727;
7164                break;
7165        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
7166                *phy = phy_8481;
7167                break;
7168        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
7169                *phy = phy_84823;
7170                break;
7171        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
7172                *phy = phy_7101;
7173                break;
7174        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
7175                *phy = phy_null;
7176                return -EINVAL;
7177        default:
7178                *phy = phy_null;
7179                return 0;
7180        }
7181
7182        phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
7183        bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
7184
7185        /**
7186        * The shmem address of the phy version is located on different
7187        * structures. In case this structure is too old, do not set
7188        * the address
7189        */
7190        config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region,
7191                                        dev_info.shared_hw_config.config2));
7192        if (phy_index == EXT_PHY1) {
7193                phy->ver_addr = shmem_base + offsetof(struct shmem_region,
7194                                port_mb[port].ext_phy_fw_version);
7195
7196        /* Check specific mdc mdio settings */
7197        if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
7198                mdc_mdio_access = config2 &
7199                SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
7200        } else {
7201                u32 size = REG_RD(bp, shmem2_base);
7202
7203                if (size >
7204                    offsetof(struct shmem2_region, ext_phy_fw_version2)) {
7205                        phy->ver_addr = shmem2_base +
7206                            offsetof(struct shmem2_region,
7207                                     ext_phy_fw_version2[port]);
7208                }
7209                /* Check specific mdc mdio settings */
7210                if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
7211                        mdc_mdio_access = (config2 &
7212                        SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
7213                        (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
7214                         SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
7215        }
7216        phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
7217
7218        /**
7219         * In case mdc/mdio_access of the external phy is different than the
7220         * mdc/mdio access of the XGXS, a HW lock must be taken in each access
7221         * to prevent one port interfere with another port's CL45 operations.
7222         */
7223        if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH)
7224                phy->flags |= FLAGS_HW_LOCK_REQUIRED;
7225        DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n",
7226                   phy_type, port, phy_index);
7227        DP(NETIF_MSG_LINK, "             addr=0x%x, mdio_ctl=0x%x\n",
7228                   phy->addr, phy->mdio_ctrl);
7229        return 0;
7230}
7231
7232static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
7233                             u32 shmem2_base, u8 port, struct bnx2x_phy *phy)
7234{
7235        u8 status = 0;
7236        phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
7237        if (phy_index == INT_PHY)
7238                return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
7239        status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
7240                                        port, phy);
7241        return status;
7242}
7243
7244static void bnx2x_phy_def_cfg(struct link_params *params,
7245                              struct bnx2x_phy *phy,
7246                              u8 phy_index)
7247{
7248        struct bnx2x *bp = params->bp;
7249        u32 link_config;
7250        /* Populate the default phy configuration for MF mode */
7251        if (phy_index == EXT_PHY2) {
7252                link_config = REG_RD(bp, params->shmem_base +
7253                                         offsetof(struct shmem_region, dev_info.
7254                        port_feature_config[params->port].link_config2));
7255                phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
7256                                        offsetof(struct shmem_region, dev_info.
7257                        port_hw_config[params->port].speed_capability_mask2));
7258        } else {
7259                link_config = REG_RD(bp, params->shmem_base +
7260                                offsetof(struct shmem_region, dev_info.
7261                                port_feature_config[params->port].link_config));
7262                phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
7263                                offsetof(struct shmem_region, dev_info.
7264                           port_hw_config[params->port].speed_capability_mask));
7265        }
7266        DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask"
7267                       " 0x%x\n", phy_index, link_config, phy->speed_cap_mask);
7268
7269        phy->req_duplex = DUPLEX_FULL;
7270        switch (link_config  & PORT_FEATURE_LINK_SPEED_MASK) {
7271        case PORT_FEATURE_LINK_SPEED_10M_HALF:
7272                phy->req_duplex = DUPLEX_HALF;
7273        case PORT_FEATURE_LINK_SPEED_10M_FULL:
7274                phy->req_line_speed = SPEED_10;
7275                break;
7276        case PORT_FEATURE_LINK_SPEED_100M_HALF:
7277                phy->req_duplex = DUPLEX_HALF;
7278        case PORT_FEATURE_LINK_SPEED_100M_FULL:
7279                phy->req_line_speed = SPEED_100;
7280                break;
7281        case PORT_FEATURE_LINK_SPEED_1G:
7282                phy->req_line_speed = SPEED_1000;
7283                break;
7284        case PORT_FEATURE_LINK_SPEED_2_5G:
7285                phy->req_line_speed = SPEED_2500;
7286                break;
7287        case PORT_FEATURE_LINK_SPEED_10G_CX4:
7288                phy->req_line_speed = SPEED_10000;
7289                break;
7290        default:
7291                phy->req_line_speed = SPEED_AUTO_NEG;
7292                break;
7293        }
7294
7295        switch (link_config  & PORT_FEATURE_FLOW_CONTROL_MASK) {
7296        case PORT_FEATURE_FLOW_CONTROL_AUTO:
7297                phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
7298                break;
7299        case PORT_FEATURE_FLOW_CONTROL_TX:
7300                phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
7301                break;
7302        case PORT_FEATURE_FLOW_CONTROL_RX:
7303                phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
7304                break;
7305        case PORT_FEATURE_FLOW_CONTROL_BOTH:
7306                phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
7307                break;
7308        default:
7309                phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7310                break;
7311        }
7312}
7313
7314u32 bnx2x_phy_selection(struct link_params *params)
7315{
7316        u32 phy_config_swapped, prio_cfg;
7317        u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
7318
7319        phy_config_swapped = params->multi_phy_config &
7320                PORT_HW_CFG_PHY_SWAPPED_ENABLED;
7321
7322        prio_cfg = params->multi_phy_config &
7323                        PORT_HW_CFG_PHY_SELECTION_MASK;
7324
7325        if (phy_config_swapped) {
7326                switch (prio_cfg) {
7327                case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
7328                     return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
7329                     break;
7330                case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
7331                     return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
7332                     break;
7333                case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
7334                     return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
7335                     break;
7336                case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
7337                     return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
7338                     break;
7339                }
7340        } else
7341                return_cfg = prio_cfg;
7342
7343        return return_cfg;
7344}
7345
7346
7347u8 bnx2x_phy_probe(struct link_params *params)
7348{
7349        u8 phy_index, actual_phy_idx, link_cfg_idx;
7350        u32 phy_config_swapped;
7351        struct bnx2x *bp = params->bp;
7352        struct bnx2x_phy *phy;
7353        params->num_phys = 0;
7354        DP(NETIF_MSG_LINK, "Begin phy probe\n");
7355        phy_config_swapped = params->multi_phy_config &
7356                PORT_HW_CFG_PHY_SWAPPED_ENABLED;
7357
7358        for (phy_index = INT_PHY; phy_index < MAX_PHYS;
7359              phy_index++) {
7360                link_cfg_idx = LINK_CONFIG_IDX(phy_index);
7361                actual_phy_idx = phy_index;
7362                if (phy_config_swapped) {
7363                        if (phy_index == EXT_PHY1)
7364                                actual_phy_idx = EXT_PHY2;
7365                        else if (phy_index == EXT_PHY2)
7366                                actual_phy_idx = EXT_PHY1;
7367                }
7368                DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x,"
7369                               " actual_phy_idx %x\n", phy_config_swapped,
7370                           phy_index, actual_phy_idx);
7371                phy = &params->phy[actual_phy_idx];
7372                if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
7373                                       params->shmem2_base, params->port,
7374                                       phy) != 0) {
7375                        params->num_phys = 0;
7376                        DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
7377                                   phy_index);
7378                        for (phy_index = INT_PHY;
7379                              phy_index < MAX_PHYS;
7380                              phy_index++)
7381                                *phy = phy_null;
7382                        return -EINVAL;
7383                }
7384                if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
7385                        break;
7386
7387                bnx2x_phy_def_cfg(params, phy, phy_index);
7388                params->num_phys++;
7389        }
7390
7391        DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
7392        return 0;
7393}
7394
7395static void set_phy_vars(struct link_params *params)
7396{
7397        struct bnx2x *bp = params->bp;
7398        u8 actual_phy_idx, phy_index, link_cfg_idx;
7399        u8 phy_config_swapped = params->multi_phy_config &
7400                        PORT_HW_CFG_PHY_SWAPPED_ENABLED;
7401        for (phy_index = INT_PHY; phy_index < params->num_phys;
7402              phy_index++) {
7403                link_cfg_idx = LINK_CONFIG_IDX(phy_index);
7404                actual_phy_idx = phy_index;
7405                if (phy_config_swapped) {
7406                        if (phy_index == EXT_PHY1)
7407                                actual_phy_idx = EXT_PHY2;
7408                        else if (phy_index == EXT_PHY2)
7409                                actual_phy_idx = EXT_PHY1;
7410                }
7411                params->phy[actual_phy_idx].req_flow_ctrl  =
7412                        params->req_flow_ctrl[link_cfg_idx];
7413
7414                params->phy[actual_phy_idx].req_line_speed =
7415                        params->req_line_speed[link_cfg_idx];
7416
7417                params->phy[actual_phy_idx].speed_cap_mask =
7418                        params->speed_cap_mask[link_cfg_idx];
7419
7420                params->phy[actual_phy_idx].req_duplex =
7421                        params->req_duplex[link_cfg_idx];
7422
7423                DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
7424                           " speed_cap_mask %x\n",
7425                           params->phy[actual_phy_idx].req_flow_ctrl,
7426                           params->phy[actual_phy_idx].req_line_speed,
7427                           params->phy[actual_phy_idx].speed_cap_mask);
7428        }
7429}
7430
7431u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
7432{
7433        struct bnx2x *bp = params->bp;
7434        DP(NETIF_MSG_LINK, "Phy Initialization started\n");
7435        DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n",
7436                   params->req_line_speed[0], params->req_flow_ctrl[0]);
7437        DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n",
7438                   params->req_line_speed[1], params->req_flow_ctrl[1]);
7439        vars->link_status = 0;
7440        vars->phy_link_up = 0;
7441        vars->link_up = 0;
7442        vars->line_speed = 0;
7443        vars->duplex = DUPLEX_FULL;
7444        vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7445        vars->mac_type = MAC_TYPE_NONE;
7446        vars->phy_flags = 0;
7447
7448        /* disable attentions */
7449        bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
7450                       (NIG_MASK_XGXS0_LINK_STATUS |
7451                        NIG_MASK_XGXS0_LINK10G |
7452                        NIG_MASK_SERDES0_LINK_STATUS |
7453                        NIG_MASK_MI_INT));
7454
7455        bnx2x_emac_init(params, vars);
7456
7457        if (params->num_phys == 0) {
7458                DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
7459                return -EINVAL;
7460        }
7461        set_phy_vars(params);
7462
7463        DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
7464        if (CHIP_REV_IS_FPGA(bp)) {
7465
7466                vars->link_up = 1;
7467                vars->line_speed = SPEED_10000;
7468                vars->duplex = DUPLEX_FULL;
7469                vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7470                vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
7471                /* enable on E1.5 FPGA */
7472                if (CHIP_IS_E1H(bp)) {
7473                        vars->flow_ctrl |=
7474                                        (BNX2X_FLOW_CTRL_TX |
7475                                         BNX2X_FLOW_CTRL_RX);
7476                        vars->link_status |=
7477                                        (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
7478                                         LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
7479                }
7480
7481                bnx2x_emac_enable(params, vars, 0);
7482                if (!(CHIP_IS_E2(bp)))
7483                        bnx2x_pbf_update(params, vars->flow_ctrl,
7484                                         vars->line_speed);
7485                /* disable drain */
7486                REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
7487
7488                /* update shared memory */
7489                bnx2x_update_mng(params, vars->link_status);
7490
7491                return 0;
7492
7493        } else
7494        if (CHIP_REV_IS_EMUL(bp)) {
7495
7496                vars->link_up = 1;
7497                vars->line_speed = SPEED_10000;
7498                vars->duplex = DUPLEX_FULL;
7499                vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7500                vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
7501
7502                bnx2x_bmac_enable(params, vars, 0);
7503
7504                bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
7505                /* Disable drain */
7506                REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
7507                                    + params->port*4, 0);
7508
7509                /* update shared memory */
7510                bnx2x_update_mng(params, vars->link_status);
7511
7512                return 0;
7513
7514        } else
7515        if (params->loopback_mode == LOOPBACK_BMAC) {
7516
7517                vars->link_up = 1;
7518                vars->line_speed = SPEED_10000;
7519                vars->duplex = DUPLEX_FULL;
7520                vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7521                vars->mac_type = MAC_TYPE_BMAC;
7522
7523                vars->phy_flags = PHY_XGXS_FLAG;
7524
7525                bnx2x_xgxs_deassert(params);
7526
7527                /* set bmac loopback */
7528                bnx2x_bmac_enable(params, vars, 1);
7529
7530                REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
7531                    params->port*4, 0);
7532
7533        } else if (params->loopback_mode == LOOPBACK_EMAC) {
7534
7535                vars->link_up = 1;
7536                vars->line_speed = SPEED_1000;
7537                vars->duplex = DUPLEX_FULL;
7538                vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7539                vars->mac_type = MAC_TYPE_EMAC;
7540
7541                vars->phy_flags = PHY_XGXS_FLAG;
7542
7543                bnx2x_xgxs_deassert(params);
7544                /* set bmac loopback */
7545                bnx2x_emac_enable(params, vars, 1);
7546                bnx2x_emac_program(params, vars);
7547                REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
7548                    params->port*4, 0);
7549
7550        } else if ((params->loopback_mode == LOOPBACK_XGXS) ||
7551                   (params->loopback_mode == LOOPBACK_EXT_PHY)) {
7552
7553                vars->link_up = 1;
7554                vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7555                vars->duplex = DUPLEX_FULL;
7556                if (params->req_line_speed[0] == SPEED_1000) {
7557                        vars->line_speed = SPEED_1000;
7558                        vars->mac_type = MAC_TYPE_EMAC;
7559                } else {
7560                        vars->line_speed = SPEED_10000;
7561                        vars->mac_type = MAC_TYPE_BMAC;
7562                }
7563
7564                bnx2x_xgxs_deassert(params);
7565                bnx2x_link_initialize(params, vars);
7566
7567                if (params->req_line_speed[0] == SPEED_1000) {
7568                        bnx2x_emac_program(params, vars);
7569                        bnx2x_emac_enable(params, vars, 0);
7570                } else
7571                bnx2x_bmac_enable(params, vars, 0);
7572
7573                if (params->loopback_mode == LOOPBACK_XGXS) {
7574                        /* set 10G XGXS loopback */
7575                        params->phy[INT_PHY].config_loopback(
7576                                &params->phy[INT_PHY],
7577                                params);
7578
7579                } else {
7580                        /* set external phy loopback */
7581                        u8 phy_index;
7582                        for (phy_index = EXT_PHY1;
7583                              phy_index < params->num_phys; phy_index++) {
7584                                if (params->phy[phy_index].config_loopback)
7585                                        params->phy[phy_index].config_loopback(
7586                                                &params->phy[phy_index],
7587                                                params);
7588                        }
7589                }
7590
7591                REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
7592                            params->port*4, 0);
7593
7594                bnx2x_set_led(params, vars,
7595                              LED_MODE_OPER, vars->line_speed);
7596        } else
7597        /* No loopback */
7598        {
7599                if (params->switch_cfg == SWITCH_CFG_10G)
7600                        bnx2x_xgxs_deassert(params);
7601                else
7602                        bnx2x_serdes_deassert(bp, params->port);
7603
7604                bnx2x_link_initialize(params, vars);
7605                msleep(30);
7606                bnx2x_link_int_enable(params);
7607        }
7608        return 0;
7609}
7610u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
7611                  u8 reset_ext_phy)
7612{
7613        struct bnx2x *bp = params->bp;
7614        u8 phy_index, port = params->port, clear_latch_ind = 0;
7615        DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
7616        /* disable attentions */
7617        vars->link_status = 0;
7618        bnx2x_update_mng(params, vars->link_status);
7619        bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
7620                     (NIG_MASK_XGXS0_LINK_STATUS |
7621                      NIG_MASK_XGXS0_LINK10G |
7622                      NIG_MASK_SERDES0_LINK_STATUS |
7623                      NIG_MASK_MI_INT));
7624
7625        /* activate nig drain */
7626        REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
7627
7628        /* disable nig egress interface */
7629        REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
7630        REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
7631
7632        /* Stop BigMac rx */
7633        bnx2x_bmac_rx_disable(bp, port);
7634
7635        /* disable emac */
7636        REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
7637
7638        msleep(10);
7639        /* The PHY reset is controled by GPIO 1
7640         * Hold it as vars low
7641         */
7642         /* clear link led */
7643        bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
7644
7645        if (reset_ext_phy) {
7646                for (phy_index = EXT_PHY1; phy_index < params->num_phys;
7647                      phy_index++) {
7648                        if (params->phy[phy_index].link_reset)
7649                                params->phy[phy_index].link_reset(
7650                                        &params->phy[phy_index],
7651                                        params);
7652                        if (params->phy[phy_index].flags &
7653                            FLAGS_REARM_LATCH_SIGNAL)
7654                                clear_latch_ind = 1;
7655                }
7656        }
7657
7658        if (clear_latch_ind) {
7659                /* Clear latching indication */
7660                bnx2x_rearm_latch_signal(bp, port, 0);
7661                bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4,
7662                               1 << NIG_LATCH_BC_ENABLE_MI_INT);
7663        }
7664        if (params->phy[INT_PHY].link_reset)
7665                params->phy[INT_PHY].link_reset(
7666                        &params->phy[INT_PHY], params);
7667        /* reset BigMac */
7668        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
7669               (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
7670
7671        /* disable nig ingress interface */
7672        REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
7673        REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
7674        REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
7675        REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
7676        vars->link_up = 0;
7677        return 0;
7678}
7679
7680/****************************************************************************/
7681/*                              Common function                             */
7682/****************************************************************************/
7683static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp,
7684                                     u32 shmem_base_path[],
7685                                     u32 shmem2_base_path[], u8 phy_index,
7686                                     u32 chip_id)
7687{
7688        struct bnx2x_phy phy[PORT_MAX];
7689        struct bnx2x_phy *phy_blk[PORT_MAX];
7690        u16 val;
7691        s8 port = 0;
7692        s8 port_of_path = 0;
7693        u32 swap_val, swap_override;
7694        swap_val = REG_RD(bp,  NIG_REG_PORT_SWAP);
7695        swap_override = REG_RD(bp,  NIG_REG_STRAP_OVERRIDE);
7696        port ^= (swap_val && swap_override);
7697        bnx2x_ext_phy_hw_reset(bp, port);
7698        /* PART1 - Reset both phys */
7699        for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7700                u32 shmem_base, shmem2_base;
7701                /* In E2, same phy is using for port0 of the two paths */
7702                if (CHIP_IS_E2(bp)) {
7703                        shmem_base = shmem_base_path[port];
7704                        shmem2_base = shmem2_base_path[port];
7705                        port_of_path = 0;
7706                } else {
7707                        shmem_base = shmem_base_path[0];
7708                        shmem2_base = shmem2_base_path[0];
7709                        port_of_path = port;
7710                }
7711
7712                /* Extract the ext phy address for the port */
7713                if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7714                                       port_of_path, &phy[port]) !=
7715                    0) {
7716                        DP(NETIF_MSG_LINK, "populate_phy failed\n");
7717                        return -EINVAL;
7718                }
7719                /* disable attentions */
7720                bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
7721                               port_of_path*4,
7722                             (NIG_MASK_XGXS0_LINK_STATUS |
7723                              NIG_MASK_XGXS0_LINK10G |
7724                              NIG_MASK_SERDES0_LINK_STATUS |
7725                              NIG_MASK_MI_INT));
7726
7727                /* Need to take the phy out of low power mode in order
7728                        to write to access its registers */
7729                bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7730                                  MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
7731
7732                /* Reset the phy */
7733                bnx2x_cl45_write(bp, &phy[port],
7734                               MDIO_PMA_DEVAD,
7735                               MDIO_PMA_REG_CTRL,
7736                               1<<15);
7737        }
7738
7739        /* Add delay of 150ms after reset */
7740        msleep(150);
7741
7742        if (phy[PORT_0].addr & 0x1) {
7743                phy_blk[PORT_0] = &(phy[PORT_1]);
7744                phy_blk[PORT_1] = &(phy[PORT_0]);
7745        } else {
7746                phy_blk[PORT_0] = &(phy[PORT_0]);
7747                phy_blk[PORT_1] = &(phy[PORT_1]);
7748        }
7749
7750        /* PART2 - Download firmware to both phys */
7751        for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7752                if (CHIP_IS_E2(bp))
7753                        port_of_path = 0;
7754                else
7755                        port_of_path = port;
7756
7757                DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
7758                           phy_blk[port]->addr);
7759                if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
7760                                                      port_of_path))
7761                        return -EINVAL;
7762
7763                /* Only set bit 10 = 1 (Tx power down) */
7764                bnx2x_cl45_read(bp, phy_blk[port],
7765                              MDIO_PMA_DEVAD,
7766                              MDIO_PMA_REG_TX_POWER_DOWN, &val);
7767
7768                /* Phase1 of TX_POWER_DOWN reset */
7769                bnx2x_cl45_write(bp, phy_blk[port],
7770                               MDIO_PMA_DEVAD,
7771                               MDIO_PMA_REG_TX_POWER_DOWN,
7772                               (val | 1<<10));
7773        }
7774
7775        /* Toggle Transmitter: Power down and then up with 600ms
7776           delay between */
7777        msleep(600);
7778
7779        /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
7780        for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7781                /* Phase2 of POWER_DOWN_RESET */
7782                /* Release bit 10 (Release Tx power down) */
7783                bnx2x_cl45_read(bp, phy_blk[port],
7784                              MDIO_PMA_DEVAD,
7785                              MDIO_PMA_REG_TX_POWER_DOWN, &val);
7786
7787                bnx2x_cl45_write(bp, phy_blk[port],
7788                               MDIO_PMA_DEVAD,
7789                               MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
7790                msleep(15);
7791
7792                /* Read modify write the SPI-ROM version select register */
7793                bnx2x_cl45_read(bp, phy_blk[port],
7794                              MDIO_PMA_DEVAD,
7795                              MDIO_PMA_REG_EDC_FFE_MAIN, &val);
7796                bnx2x_cl45_write(bp, phy_blk[port],
7797                              MDIO_PMA_DEVAD,
7798                              MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
7799
7800                /* set GPIO2 back to LOW */
7801                bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7802                                  MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
7803        }
7804        return 0;
7805}
7806static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp,
7807                                     u32 shmem_base_path[],
7808                                     u32 shmem2_base_path[], u8 phy_index,
7809                                     u32 chip_id)
7810{
7811        u32 val;
7812        s8 port;
7813        struct bnx2x_phy phy;
7814        /* Use port1 because of the static port-swap */
7815        /* Enable the module detection interrupt */
7816        val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
7817        val |= ((1<<MISC_REGISTERS_GPIO_3)|
7818                (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
7819        REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
7820
7821        bnx2x_ext_phy_hw_reset(bp, 0);
7822        msleep(5);
7823        for (port = 0; port < PORT_MAX; port++) {
7824                u32 shmem_base, shmem2_base;
7825
7826                /* In E2, same phy is using for port0 of the two paths */
7827                if (CHIP_IS_E2(bp)) {
7828                        shmem_base = shmem_base_path[port];
7829                        shmem2_base = shmem2_base_path[port];
7830                } else {
7831                        shmem_base = shmem_base_path[0];
7832                        shmem2_base = shmem2_base_path[0];
7833                }
7834                /* Extract the ext phy address for the port */
7835                if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7836                                       port, &phy) !=
7837                    0) {
7838                        DP(NETIF_MSG_LINK, "populate phy failed\n");
7839                        return -EINVAL;
7840                }
7841
7842                /* Reset phy*/
7843                bnx2x_cl45_write(bp, &phy,
7844                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
7845
7846
7847                /* Set fault module detected LED on */
7848                bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
7849                                  MISC_REGISTERS_GPIO_HIGH,
7850                                  port);
7851        }
7852
7853        return 0;
7854}
7855static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp,
7856                                     u32 shmem_base_path[],
7857                                     u32 shmem2_base_path[], u8 phy_index,
7858                                     u32 chip_id)
7859{
7860        s8 port;
7861        u32 swap_val, swap_override;
7862        struct bnx2x_phy phy[PORT_MAX];
7863        struct bnx2x_phy *phy_blk[PORT_MAX];
7864        s8 port_of_path;
7865        swap_val = REG_RD(bp,  NIG_REG_PORT_SWAP);
7866        swap_override = REG_RD(bp,  NIG_REG_STRAP_OVERRIDE);
7867
7868        port = 1;
7869
7870        bnx2x_ext_phy_hw_reset(bp, port ^ (swap_val && swap_override));
7871
7872        /* Calculate the port based on port swap */
7873        port ^= (swap_val && swap_override);
7874
7875        msleep(5);
7876
7877        /* PART1 - Reset both phys */
7878        for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7879                u32 shmem_base, shmem2_base;
7880
7881                /* In E2, same phy is using for port0 of the two paths */
7882                if (CHIP_IS_E2(bp)) {
7883                        shmem_base = shmem_base_path[port];
7884                        shmem2_base = shmem2_base_path[port];
7885                        port_of_path = 0;
7886                } else {
7887                        shmem_base = shmem_base_path[0];
7888                        shmem2_base = shmem2_base_path[0];
7889                        port_of_path = port;
7890                }
7891
7892                /* Extract the ext phy address for the port */
7893                if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7894                                       port_of_path, &phy[port]) !=
7895                                       0) {
7896                        DP(NETIF_MSG_LINK, "populate phy failed\n");
7897                        return -EINVAL;
7898                }
7899                /* disable attentions */
7900                bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
7901                               port_of_path*4,
7902                               (NIG_MASK_XGXS0_LINK_STATUS |
7903                                NIG_MASK_XGXS0_LINK10G |
7904                                NIG_MASK_SERDES0_LINK_STATUS |
7905                                NIG_MASK_MI_INT));
7906
7907
7908                /* Reset the phy */
7909                bnx2x_cl45_write(bp, &phy[port],
7910                               MDIO_PMA_DEVAD,
7911                               MDIO_PMA_REG_CTRL,
7912                               1<<15);
7913        }
7914
7915        /* Add delay of 150ms after reset */
7916        msleep(150);
7917        if (phy[PORT_0].addr & 0x1) {
7918                phy_blk[PORT_0] = &(phy[PORT_1]);
7919                phy_blk[PORT_1] = &(phy[PORT_0]);
7920        } else {
7921                phy_blk[PORT_0] = &(phy[PORT_0]);
7922                phy_blk[PORT_1] = &(phy[PORT_1]);
7923        }
7924        /* PART2 - Download firmware to both phys */
7925        for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7926                 if (CHIP_IS_E2(bp))
7927                        port_of_path = 0;
7928                else
7929                        port_of_path = port;
7930                DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
7931                           phy_blk[port]->addr);
7932                if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
7933                                                      port_of_path))
7934                        return -EINVAL;
7935
7936        }
7937        return 0;
7938}
7939
7940static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
7941                                    u32 shmem2_base_path[], u8 phy_index,
7942                                    u32 ext_phy_type, u32 chip_id)
7943{
7944        u8 rc = 0;
7945
7946        switch (ext_phy_type) {
7947        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
7948                rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
7949                                                shmem2_base_path,
7950                                                phy_index, chip_id);
7951                break;
7952
7953        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7954        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
7955                rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
7956                                                shmem2_base_path,
7957                                                phy_index, chip_id);
7958                break;
7959
7960        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7961                /* GPIO1 affects both ports, so there's need to pull
7962                it for single port alone */
7963                rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
7964                                                shmem2_base_path,
7965                                                phy_index, chip_id);
7966                break;
7967        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
7968                rc = -EINVAL;
7969                break;
7970        default:
7971                DP(NETIF_MSG_LINK,
7972                         "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
7973                         ext_phy_type);
7974                break;
7975        }
7976
7977        return rc;
7978}
7979
7980u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
7981                         u32 shmem2_base_path[], u32 chip_id)
7982{
7983        u8 rc = 0;
7984        u32 phy_ver;
7985        u8 phy_index;
7986        u32 ext_phy_type, ext_phy_config;
7987        DP(NETIF_MSG_LINK, "Begin common phy init\n");
7988
7989        if (CHIP_REV_IS_EMUL(bp))
7990                return 0;
7991
7992        /* Check if common init was already done */
7993        phy_ver = REG_RD(bp, shmem_base_path[0] +
7994                         offsetof(struct shmem_region,
7995                                  port_mb[PORT_0].ext_phy_fw_version));
7996        if (phy_ver) {
7997                DP(NETIF_MSG_LINK, "Not doing common init; phy ver is 0x%x\n",
7998                               phy_ver);
7999                return 0;
8000        }
8001
8002        /* Read the ext_phy_type for arbitrary port(0) */
8003        for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
8004              phy_index++) {
8005                ext_phy_config = bnx2x_get_ext_phy_config(bp,
8006                                                          shmem_base_path[0],
8007                                                          phy_index, 0);
8008                ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
8009                rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
8010                                                shmem2_base_path,
8011                                                phy_index, ext_phy_type,
8012                                                chip_id);
8013        }
8014        return rc;
8015}
8016
8017u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
8018{
8019        u8 phy_index;
8020        struct bnx2x_phy phy;
8021        for (phy_index = INT_PHY; phy_index < MAX_PHYS;
8022              phy_index++) {
8023                if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
8024                                       0, &phy) != 0) {
8025                        DP(NETIF_MSG_LINK, "populate phy failed\n");
8026                        return 0;
8027                }
8028
8029                if (phy.flags & FLAGS_HW_LOCK_REQUIRED)
8030                        return 1;
8031        }
8032        return 0;
8033}
8034
8035u8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
8036                             u32 shmem_base,
8037                             u32 shmem2_base,
8038                             u8 port)
8039{
8040        u8 phy_index, fan_failure_det_req = 0;
8041        struct bnx2x_phy phy;
8042        for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
8043              phy_index++) {
8044                if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
8045                                       port, &phy)
8046                    != 0) {
8047                        DP(NETIF_MSG_LINK, "populate phy failed\n");
8048                        return 0;
8049                }
8050                fan_failure_det_req |= (phy.flags &
8051                                        FLAGS_FAN_FAILURE_DET_REQ);
8052        }
8053        return fan_failure_det_req;
8054}
8055
8056void bnx2x_hw_reset_phy(struct link_params *params)
8057{
8058        u8 phy_index;
8059        for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
8060              phy_index++) {
8061                if (params->phy[phy_index].hw_reset) {
8062                        params->phy[phy_index].hw_reset(
8063                                &params->phy[phy_index],
8064                                params);
8065                        params->phy[phy_index] = phy_null;
8066                }
8067        }
8068}
8069