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