linux/drivers/net/bnx2x_link.c
<<
>>
Prefs
   1/* Copyright 2008-2009 Broadcom Corporation
   2 *
   3 * Unless you and Broadcom execute a separate written software license
   4 * agreement governing use of this software, this software is licensed to you
   5 * under the terms of the GNU General Public License version 2, available
   6 * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
   7 *
   8 * Notwithstanding the above, under no circumstances may you combine this
   9 * software in any way with any other Broadcom software provided under a
  10 * license other than the GPL, without Broadcom's express prior written
  11 * consent.
  12 *
  13 * Written by Yaniv Rosner
  14 *
  15 */
  16
  17#include <linux/kernel.h>
  18#include <linux/errno.h>
  19#include <linux/pci.h>
  20#include <linux/netdevice.h>
  21#include <linux/delay.h>
  22#include <linux/ethtool.h>
  23#include <linux/mutex.h>
  24
  25#include "bnx2x.h"
  26
  27/********************************************************/
  28#define ETH_HLEN                        14
  29#define ETH_OVREHEAD            (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
  30#define ETH_MIN_PACKET_SIZE             60
  31#define ETH_MAX_PACKET_SIZE             1500
  32#define ETH_MAX_JUMBO_PACKET_SIZE       9600
  33#define MDIO_ACCESS_TIMEOUT             1000
  34#define BMAC_CONTROL_RX_ENABLE  2
  35
  36/***********************************************************/
  37/*                      Shortcut definitions               */
  38/***********************************************************/
  39
  40#define NIG_LATCH_BC_ENABLE_MI_INT 0
  41
  42#define NIG_STATUS_EMAC0_MI_INT \
  43                NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
  44#define NIG_STATUS_XGXS0_LINK10G \
  45                NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
  46#define NIG_STATUS_XGXS0_LINK_STATUS \
  47                NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
  48#define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
  49                NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
  50#define NIG_STATUS_SERDES0_LINK_STATUS \
  51                NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
  52#define NIG_MASK_MI_INT \
  53                NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
  54#define NIG_MASK_XGXS0_LINK10G \
  55                NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
  56#define NIG_MASK_XGXS0_LINK_STATUS \
  57                NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
  58#define NIG_MASK_SERDES0_LINK_STATUS \
  59                NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
  60
  61#define MDIO_AN_CL73_OR_37_COMPLETE \
  62                (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
  63                 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
  64
  65#define XGXS_RESET_BITS \
  66        (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
  67         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
  68         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
  69         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
  70         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
  71
  72#define SERDES_RESET_BITS \
  73        (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
  74         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
  75         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
  76         MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
  77
  78#define AUTONEG_CL37            SHARED_HW_CFG_AN_ENABLE_CL37
  79#define AUTONEG_CL73            SHARED_HW_CFG_AN_ENABLE_CL73
  80#define AUTONEG_BAM             SHARED_HW_CFG_AN_ENABLE_BAM
  81#define AUTONEG_PARALLEL \
  82                                SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
  83#define AUTONEG_SGMII_FIBER_AUTODET \
  84                                SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
  85#define AUTONEG_REMOTE_PHY      SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
  86
  87#define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
  88                        MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
  89#define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
  90                        MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
  91#define GP_STATUS_SPEED_MASK \
  92                        MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
  93#define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
  94#define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
  95#define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
  96#define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
  97#define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
  98#define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
  99#define GP_STATUS_10G_HIG \
 100                        MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
 101#define GP_STATUS_10G_CX4 \
 102                        MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
 103#define GP_STATUS_12G_HIG \
 104                        MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
 105#define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
 106#define GP_STATUS_13G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
 107#define GP_STATUS_15G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
 108#define GP_STATUS_16G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
 109#define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
 110#define GP_STATUS_10G_KX4 \
 111                        MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
 112
 113#define LINK_10THD                      LINK_STATUS_SPEED_AND_DUPLEX_10THD
 114#define LINK_10TFD                      LINK_STATUS_SPEED_AND_DUPLEX_10TFD
 115#define LINK_100TXHD            LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
 116#define LINK_100T4                      LINK_STATUS_SPEED_AND_DUPLEX_100T4
 117#define LINK_100TXFD            LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
 118#define LINK_1000THD            LINK_STATUS_SPEED_AND_DUPLEX_1000THD
 119#define LINK_1000TFD            LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
 120#define LINK_1000XFD            LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
 121#define LINK_2500THD            LINK_STATUS_SPEED_AND_DUPLEX_2500THD
 122#define LINK_2500TFD            LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
 123#define LINK_2500XFD            LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
 124#define LINK_10GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
 125#define LINK_10GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
 126#define LINK_12GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
 127#define LINK_12GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
 128#define LINK_12_5GTFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
 129#define LINK_12_5GXFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
 130#define LINK_13GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
 131#define LINK_13GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
 132#define LINK_15GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
 133#define LINK_15GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
 134#define LINK_16GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
 135#define LINK_16GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
 136
 137#define PHY_XGXS_FLAG                   0x1
 138#define PHY_SGMII_FLAG                  0x2
 139#define PHY_SERDES_FLAG                 0x4
 140
 141/* */
 142#define SFP_EEPROM_CON_TYPE_ADDR                0x2
 143        #define SFP_EEPROM_CON_TYPE_VAL_LC              0x7
 144        #define SFP_EEPROM_CON_TYPE_VAL_COPPER  0x21
 145
 146
 147#define SFP_EEPROM_COMP_CODE_ADDR               0x3
 148        #define SFP_EEPROM_COMP_CODE_SR_MASK    (1<<4)
 149        #define SFP_EEPROM_COMP_CODE_LR_MASK    (1<<5)
 150        #define SFP_EEPROM_COMP_CODE_LRM_MASK   (1<<6)
 151
 152#define SFP_EEPROM_FC_TX_TECH_ADDR              0x8
 153        #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
 154        #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE      0x8
 155
 156#define SFP_EEPROM_OPTIONS_ADDR                 0x40
 157        #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
 158#define SFP_EEPROM_OPTIONS_SIZE                 2
 159
 160#define EDC_MODE_LINEAR                         0x0022
 161#define EDC_MODE_LIMITING                               0x0044
 162#define EDC_MODE_PASSIVE_DAC                    0x0055
 163
 164
 165
 166/**********************************************************/
 167/*                     INTERFACE                          */
 168/**********************************************************/
 169#define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
 170        bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
 171                DEFAULT_PHY_DEV_ADDR, \
 172                (_bank + (_addr & 0xf)), \
 173                _val)
 174
 175#define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
 176        bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
 177                DEFAULT_PHY_DEV_ADDR, \
 178                (_bank + (_addr & 0xf)), \
 179                _val)
 180
 181static void bnx2x_set_serdes_access(struct link_params *params)
 182{
 183        struct bnx2x *bp = params->bp;
 184        u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
 185
 186        /* Set Clause 22 */
 187        REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1);
 188        REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
 189        udelay(500);
 190        REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
 191        udelay(500);
 192         /* Set Clause 45 */
 193        REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 0);
 194}
 195static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags)
 196{
 197        struct bnx2x *bp = params->bp;
 198
 199        if (phy_flags & PHY_XGXS_FLAG) {
 200                REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
 201                           params->port*0x18, 0);
 202                REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
 203                           DEFAULT_PHY_DEV_ADDR);
 204        } else {
 205                bnx2x_set_serdes_access(params);
 206
 207                REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
 208                           params->port*0x10,
 209                           DEFAULT_PHY_DEV_ADDR);
 210        }
 211}
 212
 213static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
 214{
 215        u32 val = REG_RD(bp, reg);
 216
 217        val |= bits;
 218        REG_WR(bp, reg, val);
 219        return val;
 220}
 221
 222static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
 223{
 224        u32 val = REG_RD(bp, reg);
 225
 226        val &= ~bits;
 227        REG_WR(bp, reg, val);
 228        return val;
 229}
 230
 231static void bnx2x_emac_init(struct link_params *params,
 232                           struct link_vars *vars)
 233{
 234        /* reset and unreset the emac core */
 235        struct bnx2x *bp = params->bp;
 236        u8 port = params->port;
 237        u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
 238        u32 val;
 239        u16 timeout;
 240
 241        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
 242                   (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
 243        udelay(5);
 244        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
 245                   (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
 246
 247        /* init emac - use read-modify-write */
 248        /* self clear reset */
 249        val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
 250        EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
 251
 252        timeout = 200;
 253        do {
 254                val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
 255                DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
 256                if (!timeout) {
 257                        DP(NETIF_MSG_LINK, "EMAC timeout!\n");
 258                        return;
 259                }
 260                timeout--;
 261        } while (val & EMAC_MODE_RESET);
 262
 263        /* Set mac address */
 264        val = ((params->mac_addr[0] << 8) |
 265                params->mac_addr[1]);
 266        EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
 267
 268        val = ((params->mac_addr[2] << 24) |
 269               (params->mac_addr[3] << 16) |
 270               (params->mac_addr[4] << 8) |
 271                params->mac_addr[5]);
 272        EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
 273}
 274
 275static u8 bnx2x_emac_enable(struct link_params *params,
 276                          struct link_vars *vars, u8 lb)
 277{
 278        struct bnx2x *bp = params->bp;
 279        u8 port = params->port;
 280        u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
 281        u32 val;
 282
 283        DP(NETIF_MSG_LINK, "enabling EMAC\n");
 284
 285        /* enable emac and not bmac */
 286        REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
 287
 288        /* for paladium */
 289        if (CHIP_REV_IS_EMUL(bp)) {
 290                /* Use lane 1 (of lanes 0-3) */
 291                REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
 292                REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
 293                            port*4, 1);
 294        }
 295        /* for fpga */
 296        else
 297
 298        if (CHIP_REV_IS_FPGA(bp)) {
 299                /* Use lane 1 (of lanes 0-3) */
 300                DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
 301
 302                REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
 303                REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
 304                            0);
 305        } else
 306        /* ASIC */
 307        if (vars->phy_flags & PHY_XGXS_FLAG) {
 308                u32 ser_lane = ((params->lane_config &
 309                            PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
 310                            PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
 311
 312                DP(NETIF_MSG_LINK, "XGXS\n");
 313                /* select the master lanes (out of 0-3) */
 314                REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
 315                           port*4, ser_lane);
 316                /* select XGXS */
 317                REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
 318                           port*4, 1);
 319
 320        } else { /* SerDes */
 321                DP(NETIF_MSG_LINK, "SerDes\n");
 322                /* select SerDes */
 323                REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
 324                           port*4, 0);
 325        }
 326
 327        bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
 328                    EMAC_RX_MODE_RESET);
 329        bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
 330                    EMAC_TX_MODE_RESET);
 331
 332        if (CHIP_REV_IS_SLOW(bp)) {
 333                /* config GMII mode */
 334                val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
 335                EMAC_WR(bp, EMAC_REG_EMAC_MODE,
 336                            (val | EMAC_MODE_PORT_GMII));
 337        } else { /* ASIC */
 338                /* pause enable/disable */
 339                bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
 340                               EMAC_RX_MODE_FLOW_EN);
 341                if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
 342                        bnx2x_bits_en(bp, emac_base +
 343                                    EMAC_REG_EMAC_RX_MODE,
 344                                    EMAC_RX_MODE_FLOW_EN);
 345
 346                bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
 347                             (EMAC_TX_MODE_EXT_PAUSE_EN |
 348                              EMAC_TX_MODE_FLOW_EN));
 349                if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
 350                        bnx2x_bits_en(bp, emac_base +
 351                                    EMAC_REG_EMAC_TX_MODE,
 352                                   (EMAC_TX_MODE_EXT_PAUSE_EN |
 353                                    EMAC_TX_MODE_FLOW_EN));
 354        }
 355
 356        /* KEEP_VLAN_TAG, promiscuous */
 357        val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
 358        val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
 359        EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
 360
 361        /* Set Loopback */
 362        val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
 363        if (lb)
 364                val |= 0x810;
 365        else
 366                val &= ~0x810;
 367        EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
 368
 369        /* enable emac */
 370        REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
 371
 372        /* enable emac for jumbo packets */
 373        EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
 374                (EMAC_RX_MTU_SIZE_JUMBO_ENA |
 375                 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
 376
 377        /* strip CRC */
 378        REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
 379
 380        /* disable the NIG in/out to the bmac */
 381        REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
 382        REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
 383        REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
 384
 385        /* enable the NIG in/out to the emac */
 386        REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
 387        val = 0;
 388        if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
 389                val = 1;
 390
 391        REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
 392        REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
 393
 394        if (CHIP_REV_IS_EMUL(bp)) {
 395                /* take the BigMac out of reset */
 396                REG_WR(bp,
 397                           GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
 398                           (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
 399
 400                /* enable access for bmac registers */
 401                REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
 402        } else
 403                REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
 404
 405        vars->mac_type = MAC_TYPE_EMAC;
 406        return 0;
 407}
 408
 409
 410
 411static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
 412                          u8 is_lb)
 413{
 414        struct bnx2x *bp = params->bp;
 415        u8 port = params->port;
 416        u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
 417                               NIG_REG_INGRESS_BMAC0_MEM;
 418        u32 wb_data[2];
 419        u32 val;
 420
 421        DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
 422        /* reset and unreset the BigMac */
 423        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
 424               (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
 425        msleep(1);
 426
 427        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
 428               (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
 429
 430        /* enable access for bmac registers */
 431        REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
 432
 433        /* XGXS control */
 434        wb_data[0] = 0x3c;
 435        wb_data[1] = 0;
 436        REG_WR_DMAE(bp, bmac_addr +
 437                      BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
 438                      wb_data, 2);
 439
 440        /* tx MAC SA */
 441        wb_data[0] = ((params->mac_addr[2] << 24) |
 442                       (params->mac_addr[3] << 16) |
 443                       (params->mac_addr[4] << 8) |
 444                        params->mac_addr[5]);
 445        wb_data[1] = ((params->mac_addr[0] << 8) |
 446                        params->mac_addr[1]);
 447        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
 448                    wb_data, 2);
 449
 450        /* tx control */
 451        val = 0xc0;
 452        if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
 453                val |= 0x800000;
 454        wb_data[0] = val;
 455        wb_data[1] = 0;
 456        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
 457                        wb_data, 2);
 458
 459        /* mac control */
 460        val = 0x3;
 461        if (is_lb) {
 462                val |= 0x4;
 463                DP(NETIF_MSG_LINK, "enable bmac loopback\n");
 464        }
 465        wb_data[0] = val;
 466        wb_data[1] = 0;
 467        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
 468                    wb_data, 2);
 469
 470        /* set rx mtu */
 471        wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
 472        wb_data[1] = 0;
 473        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
 474                        wb_data, 2);
 475
 476        /* rx control set to don't strip crc */
 477        val = 0x14;
 478        if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
 479                val |= 0x20;
 480        wb_data[0] = val;
 481        wb_data[1] = 0;
 482        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
 483                        wb_data, 2);
 484
 485        /* set tx mtu */
 486        wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
 487        wb_data[1] = 0;
 488        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
 489                        wb_data, 2);
 490
 491        /* set cnt max size */
 492        wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
 493        wb_data[1] = 0;
 494        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
 495                    wb_data, 2);
 496
 497        /* configure safc */
 498        wb_data[0] = 0x1000200;
 499        wb_data[1] = 0;
 500        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
 501                    wb_data, 2);
 502        /* fix for emulation */
 503        if (CHIP_REV_IS_EMUL(bp)) {
 504                wb_data[0] = 0xf000;
 505                wb_data[1] = 0;
 506                REG_WR_DMAE(bp,
 507                            bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
 508                            wb_data, 2);
 509        }
 510
 511        REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
 512        REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
 513        REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
 514        val = 0;
 515        if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
 516                val = 1;
 517        REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
 518        REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
 519        REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
 520        REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
 521        REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
 522        REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
 523
 524        vars->mac_type = MAC_TYPE_BMAC;
 525        return 0;
 526}
 527
 528static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
 529{
 530        struct bnx2x *bp = params->bp;
 531        u32 val;
 532
 533        if (phy_flags & PHY_XGXS_FLAG) {
 534                DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
 535                val = XGXS_RESET_BITS;
 536
 537        } else { /* SerDes */
 538                DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
 539                val = SERDES_RESET_BITS;
 540        }
 541
 542        val = val << (params->port*16);
 543
 544        /* reset and unreset the SerDes/XGXS */
 545        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
 546                    val);
 547        udelay(500);
 548        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
 549                    val);
 550        bnx2x_set_phy_mdio(params, phy_flags);
 551}
 552
 553void bnx2x_link_status_update(struct link_params *params,
 554                            struct link_vars   *vars)
 555{
 556        struct bnx2x *bp = params->bp;
 557        u8 link_10g;
 558        u8 port = params->port;
 559
 560        if (params->switch_cfg ==  SWITCH_CFG_1G)
 561                vars->phy_flags = PHY_SERDES_FLAG;
 562        else
 563                vars->phy_flags = PHY_XGXS_FLAG;
 564        vars->link_status = REG_RD(bp, params->shmem_base +
 565                                          offsetof(struct shmem_region,
 566                                           port_mb[port].link_status));
 567
 568        vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
 569
 570        if (vars->link_up) {
 571                DP(NETIF_MSG_LINK, "phy link up\n");
 572
 573                vars->phy_link_up = 1;
 574                vars->duplex = DUPLEX_FULL;
 575                switch (vars->link_status &
 576                                        LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
 577                        case LINK_10THD:
 578                                vars->duplex = DUPLEX_HALF;
 579                                /* fall thru */
 580                        case LINK_10TFD:
 581                                vars->line_speed = SPEED_10;
 582                                break;
 583
 584                        case LINK_100TXHD:
 585                                vars->duplex = DUPLEX_HALF;
 586                                /* fall thru */
 587                        case LINK_100T4:
 588                        case LINK_100TXFD:
 589                                vars->line_speed = SPEED_100;
 590                                break;
 591
 592                        case LINK_1000THD:
 593                                vars->duplex = DUPLEX_HALF;
 594                                /* fall thru */
 595                        case LINK_1000TFD:
 596                                vars->line_speed = SPEED_1000;
 597                                break;
 598
 599                        case LINK_2500THD:
 600                                vars->duplex = DUPLEX_HALF;
 601                                /* fall thru */
 602                        case LINK_2500TFD:
 603                                vars->line_speed = SPEED_2500;
 604                                break;
 605
 606                        case LINK_10GTFD:
 607                                vars->line_speed = SPEED_10000;
 608                                break;
 609
 610                        case LINK_12GTFD:
 611                                vars->line_speed = SPEED_12000;
 612                                break;
 613
 614                        case LINK_12_5GTFD:
 615                                vars->line_speed = SPEED_12500;
 616                                break;
 617
 618                        case LINK_13GTFD:
 619                                vars->line_speed = SPEED_13000;
 620                                break;
 621
 622                        case LINK_15GTFD:
 623                                vars->line_speed = SPEED_15000;
 624                                break;
 625
 626                        case LINK_16GTFD:
 627                                vars->line_speed = SPEED_16000;
 628                                break;
 629
 630                        default:
 631                                break;
 632                }
 633
 634                if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
 635                        vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
 636                else
 637                        vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
 638
 639                if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
 640                        vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
 641                else
 642                        vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
 643
 644                if (vars->phy_flags & PHY_XGXS_FLAG) {
 645                        if (vars->line_speed &&
 646                            ((vars->line_speed == SPEED_10) ||
 647                             (vars->line_speed == SPEED_100))) {
 648                                vars->phy_flags |= PHY_SGMII_FLAG;
 649                        } else {
 650                                vars->phy_flags &= ~PHY_SGMII_FLAG;
 651                        }
 652                }
 653
 654                /* anything 10 and over uses the bmac */
 655                link_10g = ((vars->line_speed == SPEED_10000) ||
 656                            (vars->line_speed == SPEED_12000) ||
 657                            (vars->line_speed == SPEED_12500) ||
 658                            (vars->line_speed == SPEED_13000) ||
 659                            (vars->line_speed == SPEED_15000) ||
 660                            (vars->line_speed == SPEED_16000));
 661                if (link_10g)
 662                        vars->mac_type = MAC_TYPE_BMAC;
 663                else
 664                        vars->mac_type = MAC_TYPE_EMAC;
 665
 666        } else { /* link down */
 667                DP(NETIF_MSG_LINK, "phy link down\n");
 668
 669                vars->phy_link_up = 0;
 670
 671                vars->line_speed = 0;
 672                vars->duplex = DUPLEX_FULL;
 673                vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
 674
 675                /* indicate no mac active */
 676                vars->mac_type = MAC_TYPE_NONE;
 677        }
 678
 679        DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x\n",
 680                 vars->link_status, vars->phy_link_up);
 681        DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
 682                 vars->line_speed, vars->duplex, vars->flow_ctrl);
 683}
 684
 685static void bnx2x_update_mng(struct link_params *params, u32 link_status)
 686{
 687        struct bnx2x *bp = params->bp;
 688
 689        REG_WR(bp, params->shmem_base +
 690                   offsetof(struct shmem_region,
 691                            port_mb[params->port].link_status),
 692                        link_status);
 693}
 694
 695static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
 696{
 697        u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
 698                NIG_REG_INGRESS_BMAC0_MEM;
 699        u32 wb_data[2];
 700        u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
 701
 702        /* Only if the bmac is out of reset */
 703        if (REG_RD(bp, MISC_REG_RESET_REG_2) &
 704                        (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
 705            nig_bmac_enable) {
 706
 707                /* Clear Rx Enable bit in BMAC_CONTROL register */
 708                REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
 709                            wb_data, 2);
 710                wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
 711                REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
 712                            wb_data, 2);
 713
 714                msleep(1);
 715        }
 716}
 717
 718static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
 719                         u32 line_speed)
 720{
 721        struct bnx2x *bp = params->bp;
 722        u8 port = params->port;
 723        u32 init_crd, crd;
 724        u32 count = 1000;
 725
 726        /* disable port */
 727        REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
 728
 729        /* wait for init credit */
 730        init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
 731        crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
 732        DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
 733
 734        while ((init_crd != crd) && count) {
 735                msleep(5);
 736
 737                crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
 738                count--;
 739        }
 740        crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
 741        if (init_crd != crd) {
 742                DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
 743                          init_crd, crd);
 744                return -EINVAL;
 745        }
 746
 747        if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
 748            line_speed == SPEED_10 ||
 749            line_speed == SPEED_100 ||
 750            line_speed == SPEED_1000 ||
 751            line_speed == SPEED_2500) {
 752                REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
 753                /* update threshold */
 754                REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
 755                /* update init credit */
 756                init_crd = 778;         /* (800-18-4) */
 757
 758        } else {
 759                u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
 760                              ETH_OVREHEAD)/16;
 761                REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
 762                /* update threshold */
 763                REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
 764                /* update init credit */
 765                switch (line_speed) {
 766                case SPEED_10000:
 767                        init_crd = thresh + 553 - 22;
 768                        break;
 769
 770                case SPEED_12000:
 771                        init_crd = thresh + 664 - 22;
 772                        break;
 773
 774                case SPEED_13000:
 775                        init_crd = thresh + 742 - 22;
 776                        break;
 777
 778                case SPEED_16000:
 779                        init_crd = thresh + 778 - 22;
 780                        break;
 781                default:
 782                        DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
 783                                  line_speed);
 784                        return -EINVAL;
 785                }
 786        }
 787        REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
 788        DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
 789                 line_speed, init_crd);
 790
 791        /* probe the credit changes */
 792        REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
 793        msleep(5);
 794        REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
 795
 796        /* enable port */
 797        REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
 798        return 0;
 799}
 800
 801static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
 802{
 803        u32 emac_base;
 804
 805        switch (ext_phy_type) {
 806        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
 807        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
 808        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
 809                /* All MDC/MDIO is directed through single EMAC */
 810                if (REG_RD(bp, NIG_REG_PORT_SWAP))
 811                        emac_base = GRCBASE_EMAC0;
 812                else
 813                        emac_base = GRCBASE_EMAC1;
 814                break;
 815        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
 816                emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
 817                break;
 818        default:
 819                emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
 820                break;
 821        }
 822        return emac_base;
 823
 824}
 825
 826u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
 827                  u8 phy_addr, u8 devad, u16 reg, u16 val)
 828{
 829        u32 tmp, saved_mode;
 830        u8 i, rc = 0;
 831        u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
 832
 833        /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
 834         * (a value of 49==0x31) and make sure that the AUTO poll is off
 835         */
 836
 837        saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
 838        tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
 839                             EMAC_MDIO_MODE_CLOCK_CNT);
 840        tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
 841                (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
 842        REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
 843        REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
 844        udelay(40);
 845
 846        /* address */
 847
 848        tmp = ((phy_addr << 21) | (devad << 16) | reg |
 849               EMAC_MDIO_COMM_COMMAND_ADDRESS |
 850               EMAC_MDIO_COMM_START_BUSY);
 851        REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
 852
 853        for (i = 0; i < 50; i++) {
 854                udelay(10);
 855
 856                tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
 857                if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
 858                        udelay(5);
 859                        break;
 860                }
 861        }
 862        if (tmp & EMAC_MDIO_COMM_START_BUSY) {
 863                DP(NETIF_MSG_LINK, "write phy register failed\n");
 864                rc = -EFAULT;
 865        } else {
 866                /* data */
 867                tmp = ((phy_addr << 21) | (devad << 16) | val |
 868                       EMAC_MDIO_COMM_COMMAND_WRITE_45 |
 869                       EMAC_MDIO_COMM_START_BUSY);
 870                REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
 871
 872                for (i = 0; i < 50; i++) {
 873                        udelay(10);
 874
 875                        tmp = REG_RD(bp, mdio_ctrl +
 876                                         EMAC_REG_EMAC_MDIO_COMM);
 877                        if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
 878                                udelay(5);
 879                                break;
 880                        }
 881                }
 882                if (tmp & EMAC_MDIO_COMM_START_BUSY) {
 883                        DP(NETIF_MSG_LINK, "write phy register failed\n");
 884                        rc = -EFAULT;
 885                }
 886        }
 887
 888        /* Restore the saved mode */
 889        REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
 890
 891        return rc;
 892}
 893
 894u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
 895                 u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
 896{
 897        u32 val, saved_mode;
 898        u16 i;
 899        u8 rc = 0;
 900
 901        u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
 902        /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
 903         * (a value of 49==0x31) and make sure that the AUTO poll is off
 904         */
 905
 906        saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
 907        val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
 908                             EMAC_MDIO_MODE_CLOCK_CNT));
 909        val |= (EMAC_MDIO_MODE_CLAUSE_45 |
 910                (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
 911        REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
 912        REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
 913        udelay(40);
 914
 915        /* address */
 916        val = ((phy_addr << 21) | (devad << 16) | reg |
 917               EMAC_MDIO_COMM_COMMAND_ADDRESS |
 918               EMAC_MDIO_COMM_START_BUSY);
 919        REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
 920
 921        for (i = 0; i < 50; i++) {
 922                udelay(10);
 923
 924                val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
 925                if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
 926                        udelay(5);
 927                        break;
 928                }
 929        }
 930        if (val & EMAC_MDIO_COMM_START_BUSY) {
 931                DP(NETIF_MSG_LINK, "read phy register failed\n");
 932
 933                *ret_val = 0;
 934                rc = -EFAULT;
 935
 936        } else {
 937                /* data */
 938                val = ((phy_addr << 21) | (devad << 16) |
 939                       EMAC_MDIO_COMM_COMMAND_READ_45 |
 940                       EMAC_MDIO_COMM_START_BUSY);
 941                REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
 942
 943                for (i = 0; i < 50; i++) {
 944                        udelay(10);
 945
 946                        val = REG_RD(bp, mdio_ctrl +
 947                                          EMAC_REG_EMAC_MDIO_COMM);
 948                        if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
 949                                *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
 950                                break;
 951                        }
 952                }
 953                if (val & EMAC_MDIO_COMM_START_BUSY) {
 954                        DP(NETIF_MSG_LINK, "read phy register failed\n");
 955
 956                        *ret_val = 0;
 957                        rc = -EFAULT;
 958                }
 959        }
 960
 961        /* Restore the saved mode */
 962        REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
 963
 964        return rc;
 965}
 966
 967static void bnx2x_set_aer_mmd(struct link_params *params,
 968                            struct link_vars   *vars)
 969{
 970        struct bnx2x *bp = params->bp;
 971        u32 ser_lane;
 972        u16 offset;
 973
 974        ser_lane = ((params->lane_config &
 975                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
 976                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
 977
 978        offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
 979                (params->phy_addr + ser_lane) : 0;
 980
 981        CL45_WR_OVER_CL22(bp, params->port,
 982                              params->phy_addr,
 983                              MDIO_REG_BANK_AER_BLOCK,
 984                              MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
 985}
 986
 987static void bnx2x_set_master_ln(struct link_params *params)
 988{
 989        struct bnx2x *bp = params->bp;
 990        u16 new_master_ln, ser_lane;
 991        ser_lane =  ((params->lane_config &
 992                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
 993                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
 994
 995        /* set the master_ln for AN */
 996        CL45_RD_OVER_CL22(bp, params->port,
 997                              params->phy_addr,
 998                              MDIO_REG_BANK_XGXS_BLOCK2,
 999                              MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1000                              &new_master_ln);
1001
1002        CL45_WR_OVER_CL22(bp, params->port,
1003                              params->phy_addr,
1004                              MDIO_REG_BANK_XGXS_BLOCK2 ,
1005                              MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1006                              (new_master_ln | ser_lane));
1007}
1008
1009static u8 bnx2x_reset_unicore(struct link_params *params)
1010{
1011        struct bnx2x *bp = params->bp;
1012        u16 mii_control;
1013        u16 i;
1014
1015        CL45_RD_OVER_CL22(bp, params->port,
1016                              params->phy_addr,
1017                              MDIO_REG_BANK_COMBO_IEEE0,
1018                              MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
1019
1020        /* reset the unicore */
1021        CL45_WR_OVER_CL22(bp, params->port,
1022                              params->phy_addr,
1023                              MDIO_REG_BANK_COMBO_IEEE0,
1024                              MDIO_COMBO_IEEE0_MII_CONTROL,
1025                              (mii_control |
1026                               MDIO_COMBO_IEEO_MII_CONTROL_RESET));
1027        if (params->switch_cfg == SWITCH_CFG_1G)
1028                bnx2x_set_serdes_access(params);
1029
1030        /* wait for the reset to self clear */
1031        for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
1032                udelay(5);
1033
1034                /* the reset erased the previous bank value */
1035                CL45_RD_OVER_CL22(bp, params->port,
1036                                      params->phy_addr,
1037                              MDIO_REG_BANK_COMBO_IEEE0,
1038                              MDIO_COMBO_IEEE0_MII_CONTROL,
1039                              &mii_control);
1040
1041                if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1042                        udelay(5);
1043                        return 0;
1044                }
1045        }
1046
1047        DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1048        return -EINVAL;
1049
1050}
1051
1052static void bnx2x_set_swap_lanes(struct link_params *params)
1053{
1054        struct bnx2x *bp = params->bp;
1055        /* Each two bits represents a lane number:
1056           No swap is 0123 => 0x1b no need to enable the swap */
1057        u16 ser_lane, rx_lane_swap, tx_lane_swap;
1058
1059        ser_lane = ((params->lane_config &
1060                         PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1061                        PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1062        rx_lane_swap = ((params->lane_config &
1063                             PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1064                            PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1065        tx_lane_swap = ((params->lane_config &
1066                             PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1067                            PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1068
1069        if (rx_lane_swap != 0x1b) {
1070                CL45_WR_OVER_CL22(bp, params->port,
1071                                      params->phy_addr,
1072                                    MDIO_REG_BANK_XGXS_BLOCK2,
1073                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1074                                    (rx_lane_swap |
1075                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1076                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1077        } else {
1078                CL45_WR_OVER_CL22(bp, params->port,
1079                                      params->phy_addr,
1080                                      MDIO_REG_BANK_XGXS_BLOCK2,
1081                                      MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1082        }
1083
1084        if (tx_lane_swap != 0x1b) {
1085                CL45_WR_OVER_CL22(bp, params->port,
1086                                      params->phy_addr,
1087                                      MDIO_REG_BANK_XGXS_BLOCK2,
1088                                      MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1089                                      (tx_lane_swap |
1090                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1091        } else {
1092                CL45_WR_OVER_CL22(bp, params->port,
1093                                      params->phy_addr,
1094                                      MDIO_REG_BANK_XGXS_BLOCK2,
1095                                      MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1096        }
1097}
1098
1099static void bnx2x_set_parallel_detection(struct link_params *params,
1100                                       u8                phy_flags)
1101{
1102        struct bnx2x *bp = params->bp;
1103        u16 control2;
1104
1105        CL45_RD_OVER_CL22(bp, params->port,
1106                              params->phy_addr,
1107                              MDIO_REG_BANK_SERDES_DIGITAL,
1108                              MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1109                              &control2);
1110
1111
1112        control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1113
1114
1115        CL45_WR_OVER_CL22(bp, params->port,
1116                              params->phy_addr,
1117                              MDIO_REG_BANK_SERDES_DIGITAL,
1118                              MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1119                              control2);
1120
1121        if (phy_flags & PHY_XGXS_FLAG) {
1122                DP(NETIF_MSG_LINK, "XGXS\n");
1123
1124                CL45_WR_OVER_CL22(bp, params->port,
1125                                      params->phy_addr,
1126                                MDIO_REG_BANK_10G_PARALLEL_DETECT,
1127                                MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1128                                MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1129
1130                CL45_RD_OVER_CL22(bp, params->port,
1131                                      params->phy_addr,
1132                                MDIO_REG_BANK_10G_PARALLEL_DETECT,
1133                                MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1134                                &control2);
1135
1136
1137                control2 |=
1138                    MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1139
1140                CL45_WR_OVER_CL22(bp, params->port,
1141                                      params->phy_addr,
1142                                MDIO_REG_BANK_10G_PARALLEL_DETECT,
1143                                MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1144                                control2);
1145
1146                /* Disable parallel detection of HiG */
1147                CL45_WR_OVER_CL22(bp, params->port,
1148                                      params->phy_addr,
1149                                MDIO_REG_BANK_XGXS_BLOCK2,
1150                                MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1151                                MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1152                                MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1153        }
1154}
1155
1156static void bnx2x_set_autoneg(struct link_params *params,
1157                            struct link_vars *vars,
1158                            u8 enable_cl73)
1159{
1160        struct bnx2x *bp = params->bp;
1161        u16 reg_val;
1162
1163        /* CL37 Autoneg */
1164
1165        CL45_RD_OVER_CL22(bp, params->port,
1166                              params->phy_addr,
1167                              MDIO_REG_BANK_COMBO_IEEE0,
1168                              MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1169
1170        /* CL37 Autoneg Enabled */
1171        if (vars->line_speed == SPEED_AUTO_NEG)
1172                reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1173        else /* CL37 Autoneg Disabled */
1174                reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1175                             MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1176
1177        CL45_WR_OVER_CL22(bp, params->port,
1178                              params->phy_addr,
1179                              MDIO_REG_BANK_COMBO_IEEE0,
1180                              MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1181
1182        /* Enable/Disable Autodetection */
1183
1184        CL45_RD_OVER_CL22(bp, params->port,
1185                              params->phy_addr,
1186                              MDIO_REG_BANK_SERDES_DIGITAL,
1187                              MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1188        reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
1189                    MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
1190        reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
1191        if (vars->line_speed == SPEED_AUTO_NEG)
1192                reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1193        else
1194                reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1195
1196        CL45_WR_OVER_CL22(bp, params->port,
1197                              params->phy_addr,
1198                              MDIO_REG_BANK_SERDES_DIGITAL,
1199                              MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1200
1201        /* Enable TetonII and BAM autoneg */
1202        CL45_RD_OVER_CL22(bp, params->port,
1203                              params->phy_addr,
1204                              MDIO_REG_BANK_BAM_NEXT_PAGE,
1205                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1206                          &reg_val);
1207        if (vars->line_speed == SPEED_AUTO_NEG) {
1208                /* Enable BAM aneg Mode and TetonII aneg Mode */
1209                reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1210                            MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1211        } else {
1212                /* TetonII and BAM Autoneg Disabled */
1213                reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1214                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1215        }
1216        CL45_WR_OVER_CL22(bp, params->port,
1217                              params->phy_addr,
1218                              MDIO_REG_BANK_BAM_NEXT_PAGE,
1219                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1220                              reg_val);
1221
1222        if (enable_cl73) {
1223                /* Enable Cl73 FSM status bits */
1224                CL45_WR_OVER_CL22(bp, params->port,
1225                                      params->phy_addr,
1226                                      MDIO_REG_BANK_CL73_USERB0,
1227                                    MDIO_CL73_USERB0_CL73_UCTRL,
1228                                    MDIO_CL73_USERB0_CL73_UCTRL_USTAT1_MUXSEL);
1229
1230                /* Enable BAM Station Manager*/
1231                CL45_WR_OVER_CL22(bp, params->port,
1232                        params->phy_addr,
1233                        MDIO_REG_BANK_CL73_USERB0,
1234                        MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1235                        MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1236                        MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1237                        MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
1238
1239                /* Merge CL73 and CL37 aneg resolution */
1240                CL45_RD_OVER_CL22(bp, params->port,
1241                                      params->phy_addr,
1242                                      MDIO_REG_BANK_CL73_USERB0,
1243                                      MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1244                                      &reg_val);
1245
1246                if (params->speed_cap_mask &
1247                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
1248                        /* Set the CL73 AN speed */
1249                        CL45_RD_OVER_CL22(bp, params->port,
1250                                              params->phy_addr,
1251                                              MDIO_REG_BANK_CL73_IEEEB1,
1252                                              MDIO_CL73_IEEEB1_AN_ADV2,
1253                                              &reg_val);
1254
1255                        CL45_WR_OVER_CL22(bp, params->port,
1256                                              params->phy_addr,
1257                                              MDIO_REG_BANK_CL73_IEEEB1,
1258                                              MDIO_CL73_IEEEB1_AN_ADV2,
1259                          reg_val | MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4);
1260
1261                }
1262                /* CL73 Autoneg Enabled */
1263                reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
1264
1265        } else /* CL73 Autoneg Disabled */
1266                reg_val = 0;
1267
1268        CL45_WR_OVER_CL22(bp, params->port,
1269                              params->phy_addr,
1270                              MDIO_REG_BANK_CL73_IEEEB0,
1271                              MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1272}
1273
1274/* program SerDes, forced speed */
1275static void bnx2x_program_serdes(struct link_params *params,
1276                               struct link_vars *vars)
1277{
1278        struct bnx2x *bp = params->bp;
1279        u16 reg_val;
1280
1281        /* program duplex, disable autoneg and sgmii*/
1282        CL45_RD_OVER_CL22(bp, params->port,
1283                              params->phy_addr,
1284                              MDIO_REG_BANK_COMBO_IEEE0,
1285                              MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1286        reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1287                     MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1288                     MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
1289        if (params->req_duplex == DUPLEX_FULL)
1290                reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1291        CL45_WR_OVER_CL22(bp, params->port,
1292                              params->phy_addr,
1293                              MDIO_REG_BANK_COMBO_IEEE0,
1294                              MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1295
1296        /* program speed
1297           - needed only if the speed is greater than 1G (2.5G or 10G) */
1298        CL45_RD_OVER_CL22(bp, params->port,
1299                                      params->phy_addr,
1300                                      MDIO_REG_BANK_SERDES_DIGITAL,
1301                                      MDIO_SERDES_DIGITAL_MISC1, &reg_val);
1302        /* clearing the speed value before setting the right speed */
1303        DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1304
1305        reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1306                     MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1307
1308        if (!((vars->line_speed == SPEED_1000) ||
1309              (vars->line_speed == SPEED_100) ||
1310              (vars->line_speed == SPEED_10))) {
1311
1312                reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1313                            MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1314                if (vars->line_speed == SPEED_10000)
1315                        reg_val |=
1316                                MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1317                if (vars->line_speed == SPEED_13000)
1318                        reg_val |=
1319                                MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1320        }
1321
1322        CL45_WR_OVER_CL22(bp, params->port,
1323                                      params->phy_addr,
1324                                      MDIO_REG_BANK_SERDES_DIGITAL,
1325                                      MDIO_SERDES_DIGITAL_MISC1, reg_val);
1326
1327}
1328
1329static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1330{
1331        struct bnx2x *bp = params->bp;
1332        u16 val = 0;
1333
1334        /* configure the 48 bits for BAM AN */
1335
1336        /* set extended capabilities */
1337        if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1338                val |= MDIO_OVER_1G_UP1_2_5G;
1339        if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1340                val |= MDIO_OVER_1G_UP1_10G;
1341        CL45_WR_OVER_CL22(bp, params->port,
1342                              params->phy_addr,
1343                              MDIO_REG_BANK_OVER_1G,
1344                              MDIO_OVER_1G_UP1, val);
1345
1346        CL45_WR_OVER_CL22(bp, params->port,
1347                              params->phy_addr,
1348                              MDIO_REG_BANK_OVER_1G,
1349                              MDIO_OVER_1G_UP3, 0x400);
1350}
1351
1352static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc)
1353{
1354        *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1355        /* resolve pause mode and advertisement
1356         * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1357
1358        switch (params->req_flow_ctrl) {
1359        case BNX2X_FLOW_CTRL_AUTO:
1360                if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
1361                        *ieee_fc |=
1362                             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1363                } else {
1364                        *ieee_fc |=
1365                       MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1366                }
1367                break;
1368        case BNX2X_FLOW_CTRL_TX:
1369                *ieee_fc |=
1370                       MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1371                break;
1372
1373        case BNX2X_FLOW_CTRL_RX:
1374        case BNX2X_FLOW_CTRL_BOTH:
1375                *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1376                break;
1377
1378        case BNX2X_FLOW_CTRL_NONE:
1379        default:
1380                *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1381                break;
1382        }
1383}
1384
1385static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1386                                           u16 ieee_fc)
1387{
1388        struct bnx2x *bp = params->bp;
1389        /* for AN, we are always publishing full duplex */
1390
1391        CL45_WR_OVER_CL22(bp, params->port,
1392                              params->phy_addr,
1393                              MDIO_REG_BANK_COMBO_IEEE0,
1394                              MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
1395}
1396
1397static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73)
1398{
1399        struct bnx2x *bp = params->bp;
1400        u16 mii_control;
1401
1402        DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1403        /* Enable and restart BAM/CL37 aneg */
1404
1405        if (enable_cl73) {
1406                CL45_RD_OVER_CL22(bp, params->port,
1407                                      params->phy_addr,
1408                                      MDIO_REG_BANK_CL73_IEEEB0,
1409                                      MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1410                                      &mii_control);
1411
1412                CL45_WR_OVER_CL22(bp, params->port,
1413                                params->phy_addr,
1414                                MDIO_REG_BANK_CL73_IEEEB0,
1415                                MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1416                                (mii_control |
1417                                MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1418                                MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1419        } else {
1420
1421                CL45_RD_OVER_CL22(bp, params->port,
1422                                      params->phy_addr,
1423                                      MDIO_REG_BANK_COMBO_IEEE0,
1424                                      MDIO_COMBO_IEEE0_MII_CONTROL,
1425                                      &mii_control);
1426                DP(NETIF_MSG_LINK,
1427                         "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1428                         mii_control);
1429                CL45_WR_OVER_CL22(bp, params->port,
1430                                      params->phy_addr,
1431                                      MDIO_REG_BANK_COMBO_IEEE0,
1432                                      MDIO_COMBO_IEEE0_MII_CONTROL,
1433                                      (mii_control |
1434                                       MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1435                                       MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1436        }
1437}
1438
1439static void bnx2x_initialize_sgmii_process(struct link_params *params,
1440                                         struct link_vars *vars)
1441{
1442        struct bnx2x *bp = params->bp;
1443        u16 control1;
1444
1445        /* in SGMII mode, the unicore is always slave */
1446
1447        CL45_RD_OVER_CL22(bp, params->port,
1448                              params->phy_addr,
1449                              MDIO_REG_BANK_SERDES_DIGITAL,
1450                              MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1451                      &control1);
1452        control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1453        /* set sgmii mode (and not fiber) */
1454        control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1455                      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1456                      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1457        CL45_WR_OVER_CL22(bp, params->port,
1458                              params->phy_addr,
1459                              MDIO_REG_BANK_SERDES_DIGITAL,
1460                              MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1461                              control1);
1462
1463        /* if forced speed */
1464        if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1465                /* set speed, disable autoneg */
1466                u16 mii_control;
1467
1468                CL45_RD_OVER_CL22(bp, params->port,
1469                                      params->phy_addr,
1470                                      MDIO_REG_BANK_COMBO_IEEE0,
1471                                      MDIO_COMBO_IEEE0_MII_CONTROL,
1472                                      &mii_control);
1473                mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1474                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1475                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1476
1477                switch (vars->line_speed) {
1478                case SPEED_100:
1479                        mii_control |=
1480                                MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1481                        break;
1482                case SPEED_1000:
1483                        mii_control |=
1484                                MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1485                        break;
1486                case SPEED_10:
1487                        /* there is nothing to set for 10M */
1488                        break;
1489                default:
1490                        /* invalid speed for SGMII */
1491                        DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1492                                  vars->line_speed);
1493                        break;
1494                }
1495
1496                /* setting the full duplex */
1497                if (params->req_duplex == DUPLEX_FULL)
1498                        mii_control |=
1499                                MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1500                CL45_WR_OVER_CL22(bp, params->port,
1501                                      params->phy_addr,
1502                                      MDIO_REG_BANK_COMBO_IEEE0,
1503                                      MDIO_COMBO_IEEE0_MII_CONTROL,
1504                                      mii_control);
1505
1506        } else { /* AN mode */
1507                /* enable and restart AN */
1508                bnx2x_restart_autoneg(params, 0);
1509        }
1510}
1511
1512
1513/*
1514 * link management
1515 */
1516
1517static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1518{                                               /*  LD      LP   */
1519        switch (pause_result) {                 /* ASYM P ASYM P */
1520        case 0xb:                               /*   1  0   1  1 */
1521                vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
1522                break;
1523
1524        case 0xe:                               /*   1  1   1  0 */
1525                vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
1526                break;
1527
1528        case 0x5:                               /*   0  1   0  1 */
1529        case 0x7:                               /*   0  1   1  1 */
1530        case 0xd:                               /*   1  1   0  1 */
1531        case 0xf:                               /*   1  1   1  1 */
1532                vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
1533                break;
1534
1535        default:
1536                break;
1537        }
1538}
1539
1540static u8 bnx2x_ext_phy_resolve_fc(struct link_params *params,
1541                                  struct link_vars *vars)
1542{
1543        struct bnx2x *bp = params->bp;
1544        u8 ext_phy_addr;
1545        u16 ld_pause;           /* local */
1546        u16 lp_pause;           /* link partner */
1547        u16 an_complete;        /* AN complete */
1548        u16 pause_result;
1549        u8 ret = 0;
1550        u32 ext_phy_type;
1551        u8 port = params->port;
1552        ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
1553        ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1554        /* read twice */
1555
1556        bnx2x_cl45_read(bp, port,
1557                      ext_phy_type,
1558                      ext_phy_addr,
1559                      MDIO_AN_DEVAD,
1560                      MDIO_AN_REG_STATUS, &an_complete);
1561        bnx2x_cl45_read(bp, port,
1562                      ext_phy_type,
1563                      ext_phy_addr,
1564                      MDIO_AN_DEVAD,
1565                      MDIO_AN_REG_STATUS, &an_complete);
1566
1567        if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1568                ret = 1;
1569                bnx2x_cl45_read(bp, port,
1570                              ext_phy_type,
1571                              ext_phy_addr,
1572                              MDIO_AN_DEVAD,
1573                              MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1574                bnx2x_cl45_read(bp, port,
1575                              ext_phy_type,
1576                              ext_phy_addr,
1577                              MDIO_AN_DEVAD,
1578                              MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1579                pause_result = (ld_pause &
1580                                MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1581                pause_result |= (lp_pause &
1582                                 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1583                DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1584                   pause_result);
1585                bnx2x_pause_resolve(vars, pause_result);
1586                if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
1587                     ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1588                        bnx2x_cl45_read(bp, port,
1589                                      ext_phy_type,
1590                                      ext_phy_addr,
1591                                      MDIO_AN_DEVAD,
1592                                      MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1593
1594                        bnx2x_cl45_read(bp, port,
1595                                      ext_phy_type,
1596                                      ext_phy_addr,
1597                                      MDIO_AN_DEVAD,
1598                                      MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1599                        pause_result = (ld_pause &
1600                                MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1601                        pause_result |= (lp_pause &
1602                                MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1603
1604                        bnx2x_pause_resolve(vars, pause_result);
1605                        DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1606                                 pause_result);
1607                }
1608        }
1609        return ret;
1610}
1611
1612
1613static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1614                                  struct link_vars *vars,
1615                                  u32 gp_status)
1616{
1617        struct bnx2x *bp = params->bp;
1618        u16 ld_pause;   /* local driver */
1619        u16 lp_pause;   /* link partner */
1620        u16 pause_result;
1621
1622        vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1623
1624        /* resolve from gp_status in case of AN complete and not sgmii */
1625        if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1626            (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1627            (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1628            (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1629             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1630                CL45_RD_OVER_CL22(bp, params->port,
1631                                      params->phy_addr,
1632                                      MDIO_REG_BANK_COMBO_IEEE0,
1633                                      MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1634                                      &ld_pause);
1635                CL45_RD_OVER_CL22(bp, params->port,
1636                                      params->phy_addr,
1637                        MDIO_REG_BANK_COMBO_IEEE0,
1638                        MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1639                        &lp_pause);
1640                pause_result = (ld_pause &
1641                                MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1642                pause_result |= (lp_pause &
1643                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1644                DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1645                bnx2x_pause_resolve(vars, pause_result);
1646        } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1647                   (bnx2x_ext_phy_resolve_fc(params, vars))) {
1648                return;
1649        } else {
1650                if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
1651                        vars->flow_ctrl = params->req_fc_auto_adv;
1652                else
1653                        vars->flow_ctrl = params->req_flow_ctrl;
1654        }
1655        DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1656}
1657
1658static void bnx2x_check_fallback_to_cl37(struct link_params *params)
1659{
1660        struct bnx2x *bp = params->bp;
1661        u16 rx_status, ustat_val, cl37_fsm_recieved;
1662        DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
1663        /* Step 1: Make sure signal is detected */
1664        CL45_RD_OVER_CL22(bp, params->port,
1665                              params->phy_addr,
1666                              MDIO_REG_BANK_RX0,
1667                              MDIO_RX0_RX_STATUS,
1668                              &rx_status);
1669        if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
1670            (MDIO_RX0_RX_STATUS_SIGDET)) {
1671                DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
1672                             "rx_status(0x80b0) = 0x%x\n", rx_status);
1673                CL45_WR_OVER_CL22(bp, params->port,
1674                                      params->phy_addr,
1675                                      MDIO_REG_BANK_CL73_IEEEB0,
1676                                      MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1677                                      MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
1678                return;
1679        }
1680        /* Step 2: Check CL73 state machine */
1681        CL45_RD_OVER_CL22(bp, params->port,
1682                              params->phy_addr,
1683                              MDIO_REG_BANK_CL73_USERB0,
1684                              MDIO_CL73_USERB0_CL73_USTAT1,
1685                              &ustat_val);
1686        if ((ustat_val &
1687             (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
1688              MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
1689            (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
1690              MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
1691                DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
1692                             "ustat_val(0x8371) = 0x%x\n", ustat_val);
1693                return;
1694        }
1695        /* Step 3: Check CL37 Message Pages received to indicate LP
1696        supports only CL37 */
1697        CL45_RD_OVER_CL22(bp, params->port,
1698                              params->phy_addr,
1699                              MDIO_REG_BANK_REMOTE_PHY,
1700                              MDIO_REMOTE_PHY_MISC_RX_STATUS,
1701                              &cl37_fsm_recieved);
1702        if ((cl37_fsm_recieved &
1703             (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
1704             MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
1705            (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
1706              MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
1707                DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
1708                             "misc_rx_status(0x8330) = 0x%x\n",
1709                         cl37_fsm_recieved);
1710                return;
1711        }
1712        /* The combined cl37/cl73 fsm state information indicating that we are
1713        connected to a device which does not support cl73, but does support
1714        cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */
1715        /* Disable CL73 */
1716        CL45_WR_OVER_CL22(bp, params->port,
1717                              params->phy_addr,
1718                              MDIO_REG_BANK_CL73_IEEEB0,
1719                              MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1720                              0);
1721        /* Restart CL37 autoneg */
1722        bnx2x_restart_autoneg(params, 0);
1723        DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
1724}
1725static u8 bnx2x_link_settings_status(struct link_params *params,
1726                                   struct link_vars *vars,
1727                                   u32 gp_status,
1728                                   u8 ext_phy_link_up)
1729{
1730        struct bnx2x *bp = params->bp;
1731        u16 new_line_speed;
1732        u8 rc = 0;
1733        vars->link_status = 0;
1734
1735        if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1736                DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1737                         gp_status);
1738
1739                vars->phy_link_up = 1;
1740                vars->link_status |= LINK_STATUS_LINK_UP;
1741
1742                if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1743                        vars->duplex = DUPLEX_FULL;
1744                else
1745                        vars->duplex = DUPLEX_HALF;
1746
1747                bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1748
1749                switch (gp_status & GP_STATUS_SPEED_MASK) {
1750                case GP_STATUS_10M:
1751                        new_line_speed = SPEED_10;
1752                        if (vars->duplex == DUPLEX_FULL)
1753                                vars->link_status |= LINK_10TFD;
1754                        else
1755                                vars->link_status |= LINK_10THD;
1756                        break;
1757
1758                case GP_STATUS_100M:
1759                        new_line_speed = SPEED_100;
1760                        if (vars->duplex == DUPLEX_FULL)
1761                                vars->link_status |= LINK_100TXFD;
1762                        else
1763                                vars->link_status |= LINK_100TXHD;
1764                        break;
1765
1766                case GP_STATUS_1G:
1767                case GP_STATUS_1G_KX:
1768                        new_line_speed = SPEED_1000;
1769                        if (vars->duplex == DUPLEX_FULL)
1770                                vars->link_status |= LINK_1000TFD;
1771                        else
1772                                vars->link_status |= LINK_1000THD;
1773                        break;
1774
1775                case GP_STATUS_2_5G:
1776                        new_line_speed = SPEED_2500;
1777                        if (vars->duplex == DUPLEX_FULL)
1778                                vars->link_status |= LINK_2500TFD;
1779                        else
1780                                vars->link_status |= LINK_2500THD;
1781                        break;
1782
1783                case GP_STATUS_5G:
1784                case GP_STATUS_6G:
1785                        DP(NETIF_MSG_LINK,
1786                                 "link speed unsupported  gp_status 0x%x\n",
1787                                  gp_status);
1788                        return -EINVAL;
1789
1790                case GP_STATUS_10G_KX4:
1791                case GP_STATUS_10G_HIG:
1792                case GP_STATUS_10G_CX4:
1793                        new_line_speed = SPEED_10000;
1794                        vars->link_status |= LINK_10GTFD;
1795                        break;
1796
1797                case GP_STATUS_12G_HIG:
1798                        new_line_speed = SPEED_12000;
1799                        vars->link_status |= LINK_12GTFD;
1800                        break;
1801
1802                case GP_STATUS_12_5G:
1803                        new_line_speed = SPEED_12500;
1804                        vars->link_status |= LINK_12_5GTFD;
1805                        break;
1806
1807                case GP_STATUS_13G:
1808                        new_line_speed = SPEED_13000;
1809                        vars->link_status |= LINK_13GTFD;
1810                        break;
1811
1812                case GP_STATUS_15G:
1813                        new_line_speed = SPEED_15000;
1814                        vars->link_status |= LINK_15GTFD;
1815                        break;
1816
1817                case GP_STATUS_16G:
1818                        new_line_speed = SPEED_16000;
1819                        vars->link_status |= LINK_16GTFD;
1820                        break;
1821
1822                default:
1823                        DP(NETIF_MSG_LINK,
1824                                  "link speed unsupported gp_status 0x%x\n",
1825                                  gp_status);
1826                        return -EINVAL;
1827                }
1828
1829                /* Upon link speed change set the NIG into drain mode.
1830                Comes to deals with possible FIFO glitch due to clk change
1831                when speed is decreased without link down indicator */
1832                if (new_line_speed != vars->line_speed) {
1833                        if (XGXS_EXT_PHY_TYPE(params->ext_phy_config) !=
1834                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT &&
1835                            ext_phy_link_up) {
1836                                DP(NETIF_MSG_LINK, "Internal link speed %d is"
1837                                            " different than the external"
1838                                            " link speed %d\n", new_line_speed,
1839                                          vars->line_speed);
1840                                vars->phy_link_up = 0;
1841                                return 0;
1842                        }
1843                        REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
1844                                    + params->port*4, 0);
1845                        msleep(1);
1846                }
1847                vars->line_speed = new_line_speed;
1848                vars->link_status |= LINK_STATUS_SERDES_LINK;
1849
1850                if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1851                    ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1852                     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1853                    (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1854                     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
1855                    (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1856                     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) {
1857                        vars->autoneg = AUTO_NEG_ENABLED;
1858
1859                        if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1860                                vars->autoneg |= AUTO_NEG_COMPLETE;
1861                                vars->link_status |=
1862                                        LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1863                        }
1864
1865                        vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1866                        vars->link_status |=
1867                                LINK_STATUS_PARALLEL_DETECTION_USED;
1868
1869                }
1870                if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1871                        vars->link_status |=
1872                                LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1873
1874                if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1875                        vars->link_status |=
1876                                LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1877
1878        } else { /* link_down */
1879                DP(NETIF_MSG_LINK, "phy link down\n");
1880
1881                vars->phy_link_up = 0;
1882
1883                vars->duplex = DUPLEX_FULL;
1884                vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1885                vars->autoneg = AUTO_NEG_DISABLED;
1886                vars->mac_type = MAC_TYPE_NONE;
1887
1888                if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1889                    ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1890                     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT))) {
1891                        /* Check signal is detected */
1892                        bnx2x_check_fallback_to_cl37(params);
1893                }
1894        }
1895
1896        DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %x line_speed %x \n",
1897                 gp_status, vars->phy_link_up, vars->line_speed);
1898        DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x"
1899                 " autoneg 0x%x\n",
1900                 vars->duplex,
1901                 vars->flow_ctrl, vars->autoneg);
1902        DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1903
1904        return rc;
1905}
1906
1907static void bnx2x_set_gmii_tx_driver(struct link_params *params)
1908{
1909        struct bnx2x *bp = params->bp;
1910        u16 lp_up2;
1911        u16 tx_driver;
1912        u16 bank;
1913
1914        /* read precomp */
1915        CL45_RD_OVER_CL22(bp, params->port,
1916                              params->phy_addr,
1917                              MDIO_REG_BANK_OVER_1G,
1918                              MDIO_OVER_1G_LP_UP2, &lp_up2);
1919
1920        /* bits [10:7] at lp_up2, positioned at [15:12] */
1921        lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1922                   MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1923                  MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1924
1925        if (lp_up2 == 0)
1926                return;
1927
1928        for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
1929              bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
1930                CL45_RD_OVER_CL22(bp, params->port,
1931                                      params->phy_addr,
1932                                      bank,
1933                                      MDIO_TX0_TX_DRIVER, &tx_driver);
1934
1935                /* replace tx_driver bits [15:12] */
1936                if (lp_up2 !=
1937                    (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
1938                        tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1939                        tx_driver |= lp_up2;
1940                        CL45_WR_OVER_CL22(bp, params->port,
1941                                              params->phy_addr,
1942                                              bank,
1943                                              MDIO_TX0_TX_DRIVER, tx_driver);
1944                }
1945        }
1946}
1947
1948static u8 bnx2x_emac_program(struct link_params *params,
1949                           u32 line_speed, u32 duplex)
1950{
1951        struct bnx2x *bp = params->bp;
1952        u8 port = params->port;
1953        u16 mode = 0;
1954
1955        DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1956        bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1957                     EMAC_REG_EMAC_MODE,
1958                     (EMAC_MODE_25G_MODE |
1959                     EMAC_MODE_PORT_MII_10M |
1960                     EMAC_MODE_HALF_DUPLEX));
1961        switch (line_speed) {
1962        case SPEED_10:
1963                mode |= EMAC_MODE_PORT_MII_10M;
1964                break;
1965
1966        case SPEED_100:
1967                mode |= EMAC_MODE_PORT_MII;
1968                break;
1969
1970        case SPEED_1000:
1971                mode |= EMAC_MODE_PORT_GMII;
1972                break;
1973
1974        case SPEED_2500:
1975                mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1976                break;
1977
1978        default:
1979                /* 10G not valid for EMAC */
1980                DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1981                return -EINVAL;
1982        }
1983
1984        if (duplex == DUPLEX_HALF)
1985                mode |= EMAC_MODE_HALF_DUPLEX;
1986        bnx2x_bits_en(bp,
1987                    GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1988                    mode);
1989
1990        bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1991                    line_speed, params->hw_led_mode, params->chip_id);
1992        return 0;
1993}
1994
1995/*****************************************************************************/
1996/*                           External Phy section                            */
1997/*****************************************************************************/
1998void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
1999{
2000        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2001                       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
2002        msleep(1);
2003        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2004                      MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
2005}
2006
2007static void bnx2x_ext_phy_reset(struct link_params *params,
2008                              struct link_vars   *vars)
2009{
2010        struct bnx2x *bp = params->bp;
2011        u32 ext_phy_type;
2012        u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2013
2014        DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
2015        ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2016        /* The PHY reset is controled by GPIO 1
2017         * Give it 1ms of reset pulse
2018         */
2019        if (vars->phy_flags & PHY_XGXS_FLAG) {
2020
2021                switch (ext_phy_type) {
2022                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2023                        DP(NETIF_MSG_LINK, "XGXS Direct\n");
2024                        break;
2025
2026                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2027                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2028                        DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
2029
2030                        /* Restore normal power mode*/
2031                        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2032                                      MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2033                                          params->port);
2034
2035                        /* HW reset */
2036                        bnx2x_ext_phy_hw_reset(bp, params->port);
2037
2038                        bnx2x_cl45_write(bp, params->port,
2039                                       ext_phy_type,
2040                                       ext_phy_addr,
2041                                       MDIO_PMA_DEVAD,
2042                                       MDIO_PMA_REG_CTRL, 0xa040);
2043                        break;
2044
2045                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
2046                        break;
2047
2048                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
2049
2050                        /* Restore normal power mode*/
2051                        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2052                                          MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2053                                          params->port);
2054
2055                        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2056                                          MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2057                                          params->port);
2058
2059                        bnx2x_cl45_write(bp, params->port,
2060                                       ext_phy_type,
2061                                       ext_phy_addr,
2062                                       MDIO_PMA_DEVAD,
2063                                       MDIO_PMA_REG_CTRL,
2064                                       1<<15);
2065                        break;
2066
2067                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2068                        DP(NETIF_MSG_LINK, "XGXS 8072\n");
2069
2070                        /* Unset Low Power Mode and SW reset */
2071                        /* Restore normal power mode*/
2072                        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2073                                      MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2074                                          params->port);
2075
2076                        bnx2x_cl45_write(bp, params->port,
2077                                       ext_phy_type,
2078                                       ext_phy_addr,
2079                                       MDIO_PMA_DEVAD,
2080                                       MDIO_PMA_REG_CTRL,
2081                                       1<<15);
2082                        break;
2083
2084                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2085                        DP(NETIF_MSG_LINK, "XGXS 8073\n");
2086
2087                        /* Restore normal power mode*/
2088                        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2089                                      MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2090                                          params->port);
2091
2092                        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2093                                      MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2094                                          params->port);
2095                        break;
2096
2097                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
2098                        DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
2099
2100                        /* Restore normal power mode*/
2101                        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2102                                      MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2103                                          params->port);
2104
2105                        /* HW reset */
2106                        bnx2x_ext_phy_hw_reset(bp, params->port);
2107                        break;
2108
2109                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
2110                        /* Restore normal power mode*/
2111                        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2112                                      MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2113                                          params->port);
2114
2115                        /* HW reset */
2116                        bnx2x_ext_phy_hw_reset(bp, params->port);
2117
2118                        bnx2x_cl45_write(bp, params->port,
2119                                       ext_phy_type,
2120                                       ext_phy_addr,
2121                                       MDIO_PMA_DEVAD,
2122                                       MDIO_PMA_REG_CTRL,
2123                                       1<<15);
2124                        break;
2125                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2126                        DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
2127                        break;
2128
2129                default:
2130                        DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
2131                           params->ext_phy_config);
2132                        break;
2133                }
2134
2135        } else { /* SerDes */
2136                ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2137                switch (ext_phy_type) {
2138                case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
2139                        DP(NETIF_MSG_LINK, "SerDes Direct\n");
2140                        break;
2141
2142                case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
2143                        DP(NETIF_MSG_LINK, "SerDes 5482\n");
2144                        bnx2x_ext_phy_hw_reset(bp, params->port);
2145                        break;
2146
2147                default:
2148                        DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
2149                                 params->ext_phy_config);
2150                        break;
2151                }
2152        }
2153}
2154
2155static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
2156                                    u32 shmem_base, u32 spirom_ver)
2157{
2158        DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
2159                 (u16)(spirom_ver>>16), (u16)spirom_ver, port);
2160        REG_WR(bp, shmem_base +
2161                   offsetof(struct shmem_region,
2162                            port_mb[port].ext_phy_fw_version),
2163                        spirom_ver);
2164}
2165
2166static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
2167                                    u32 ext_phy_type, u8 ext_phy_addr,
2168                                    u32 shmem_base)
2169{
2170        u16 fw_ver1, fw_ver2;
2171
2172        bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2173                      MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2174        bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2175                      MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2176        bnx2x_save_spirom_version(bp, port, shmem_base,
2177                                (u32)(fw_ver1<<16 | fw_ver2));
2178}
2179
2180
2181static void bnx2x_save_8481_spirom_version(struct bnx2x *bp, u8 port,
2182                                         u8 ext_phy_addr, u32 shmem_base)
2183{
2184        u16 val, fw_ver1, fw_ver2, cnt;
2185        /* For the 32 bits registers in 8481, access via MDIO2ARM interface.*/
2186        /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
2187        bnx2x_cl45_write(bp, port,
2188                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2189                       ext_phy_addr, MDIO_PMA_DEVAD,
2190                       0xA819, 0x0014);
2191        bnx2x_cl45_write(bp, port,
2192                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2193                       ext_phy_addr,
2194                       MDIO_PMA_DEVAD,
2195                       0xA81A,
2196                       0xc200);
2197        bnx2x_cl45_write(bp, port,
2198                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2199                       ext_phy_addr,
2200                       MDIO_PMA_DEVAD,
2201                       0xA81B,
2202                       0x0000);
2203        bnx2x_cl45_write(bp, port,
2204                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2205                       ext_phy_addr,
2206                       MDIO_PMA_DEVAD,
2207                       0xA81C,
2208                       0x0300);
2209        bnx2x_cl45_write(bp, port,
2210                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2211                       ext_phy_addr,
2212                       MDIO_PMA_DEVAD,
2213                       0xA817,
2214                       0x0009);
2215
2216        for (cnt = 0; cnt < 100; cnt++) {
2217                bnx2x_cl45_read(bp, port,
2218                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2219                              ext_phy_addr,
2220                              MDIO_PMA_DEVAD,
2221                              0xA818,
2222                              &val);
2223                if (val & 1)
2224                        break;
2225                udelay(5);
2226        }
2227        if (cnt == 100) {
2228                DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(1)\n");
2229                bnx2x_save_spirom_version(bp, port,
2230                                        shmem_base, 0);
2231                return;
2232        }
2233
2234
2235        /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
2236        bnx2x_cl45_write(bp, port,
2237                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2238                       ext_phy_addr, MDIO_PMA_DEVAD,
2239                       0xA819, 0x0000);
2240        bnx2x_cl45_write(bp, port,
2241                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2242                       ext_phy_addr, MDIO_PMA_DEVAD,
2243                       0xA81A, 0xc200);
2244        bnx2x_cl45_write(bp, port,
2245                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2246                       ext_phy_addr, MDIO_PMA_DEVAD,
2247                       0xA817, 0x000A);
2248        for (cnt = 0; cnt < 100; cnt++) {
2249                bnx2x_cl45_read(bp, port,
2250                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2251                              ext_phy_addr,
2252                              MDIO_PMA_DEVAD,
2253                              0xA818,
2254                              &val);
2255                if (val & 1)
2256                        break;
2257                udelay(5);
2258        }
2259        if (cnt == 100) {
2260                DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(2)\n");
2261                bnx2x_save_spirom_version(bp, port,
2262                                        shmem_base, 0);
2263                return;
2264        }
2265
2266        /* lower 16 bits of the register SPI_FW_STATUS */
2267        bnx2x_cl45_read(bp, port,
2268                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2269                      ext_phy_addr,
2270                      MDIO_PMA_DEVAD,
2271                      0xA81B,
2272                      &fw_ver1);
2273        /* upper 16 bits of register SPI_FW_STATUS */
2274        bnx2x_cl45_read(bp, port,
2275                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2276                      ext_phy_addr,
2277                      MDIO_PMA_DEVAD,
2278                      0xA81C,
2279                      &fw_ver2);
2280
2281        bnx2x_save_spirom_version(bp, port,
2282                                shmem_base, (fw_ver2<<16) | fw_ver1);
2283}
2284
2285static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
2286{
2287        struct bnx2x *bp = params->bp;
2288        u8 port = params->port;
2289        u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2290        u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2291
2292        /* Need to wait 200ms after reset */
2293        msleep(200);
2294        /* Boot port from external ROM
2295         * Set ser_boot_ctl bit in the MISC_CTRL1 register
2296         */
2297        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2298                            MDIO_PMA_DEVAD,
2299                            MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2300
2301        /* Reset internal microprocessor */
2302        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2303                          MDIO_PMA_DEVAD,
2304                          MDIO_PMA_REG_GEN_CTRL,
2305                          MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2306        /* set micro reset = 0 */
2307        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2308                            MDIO_PMA_DEVAD,
2309                            MDIO_PMA_REG_GEN_CTRL,
2310                            MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2311        /* Reset internal microprocessor */
2312        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2313                          MDIO_PMA_DEVAD,
2314                          MDIO_PMA_REG_GEN_CTRL,
2315                          MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2316        /* wait for 100ms for code download via SPI port */
2317        msleep(100);
2318
2319        /* Clear ser_boot_ctl bit */
2320        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2321                            MDIO_PMA_DEVAD,
2322                            MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2323        /* Wait 100ms */
2324        msleep(100);
2325
2326        bnx2x_save_bcm_spirom_ver(bp, port,
2327                                ext_phy_type,
2328                                ext_phy_addr,
2329                                params->shmem_base);
2330}
2331
2332static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2333{
2334        /* This is only required for 8073A1, version 102 only */
2335
2336        struct bnx2x *bp = params->bp;
2337        u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2338        u16 val;
2339
2340        /* Read 8073 HW revision*/
2341        bnx2x_cl45_read(bp, params->port,
2342                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2343                      ext_phy_addr,
2344                      MDIO_PMA_DEVAD,
2345                      MDIO_PMA_REG_8073_CHIP_REV, &val);
2346
2347        if (val != 1) {
2348                /* No need to workaround in 8073 A1 */
2349                return 0;
2350        }
2351
2352        bnx2x_cl45_read(bp, params->port,
2353                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2354                      ext_phy_addr,
2355                      MDIO_PMA_DEVAD,
2356                      MDIO_PMA_REG_ROM_VER2, &val);
2357
2358        /* SNR should be applied only for version 0x102 */
2359        if (val != 0x102)
2360                return 0;
2361
2362        return 1;
2363}
2364
2365static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2366{
2367        struct bnx2x *bp = params->bp;
2368        u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2369        u16 val, cnt, cnt1 ;
2370
2371        bnx2x_cl45_read(bp, params->port,
2372                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2373                      ext_phy_addr,
2374                      MDIO_PMA_DEVAD,
2375                      MDIO_PMA_REG_8073_CHIP_REV, &val);
2376
2377        if (val > 0) {
2378                /* No need to workaround in 8073 A1 */
2379                return 0;
2380        }
2381        /* XAUI workaround in 8073 A0: */
2382
2383        /* After loading the boot ROM and restarting Autoneg,
2384        poll Dev1, Reg $C820: */
2385
2386        for (cnt = 0; cnt < 1000; cnt++) {
2387                bnx2x_cl45_read(bp, params->port,
2388                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2389                              ext_phy_addr,
2390                              MDIO_PMA_DEVAD,
2391                              MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
2392                              &val);
2393                  /* If bit [14] = 0 or bit [13] = 0, continue on with
2394                   system initialization (XAUI work-around not required,
2395                    as these bits indicate 2.5G or 1G link up). */
2396                if (!(val & (1<<14)) || !(val & (1<<13))) {
2397                        DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2398                        return 0;
2399                } else if (!(val & (1<<15))) {
2400                        DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2401                         /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2402                          it's MSB (bit 15) goes to 1 (indicating that the
2403                          XAUI workaround has completed),
2404                          then continue on with system initialization.*/
2405                        for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2406                                bnx2x_cl45_read(bp, params->port,
2407                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2408                                        ext_phy_addr,
2409                                        MDIO_PMA_DEVAD,
2410                                        MDIO_PMA_REG_8073_XAUI_WA, &val);
2411                                if (val & (1<<15)) {
2412                                        DP(NETIF_MSG_LINK,
2413                                          "XAUI workaround has completed\n");
2414                                        return 0;
2415                                 }
2416                                 msleep(3);
2417                        }
2418                        break;
2419                }
2420                msleep(3);
2421        }
2422        DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2423        return -EINVAL;
2424}
2425
2426static void bnx2x_bcm8073_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
2427                                                  u8 ext_phy_addr,
2428                                                  u32 ext_phy_type,
2429                                                  u32 shmem_base)
2430{
2431        /* Boot port from external ROM  */
2432        /* EDC grst */
2433        bnx2x_cl45_write(bp, port,
2434                       ext_phy_type,
2435                       ext_phy_addr,
2436                       MDIO_PMA_DEVAD,
2437                       MDIO_PMA_REG_GEN_CTRL,
2438                       0x0001);
2439
2440        /* ucode reboot and rst */
2441        bnx2x_cl45_write(bp, port,
2442                       ext_phy_type,
2443                       ext_phy_addr,
2444                       MDIO_PMA_DEVAD,
2445                       MDIO_PMA_REG_GEN_CTRL,
2446                       0x008c);
2447
2448        bnx2x_cl45_write(bp, port,
2449                       ext_phy_type,
2450                       ext_phy_addr,
2451                       MDIO_PMA_DEVAD,
2452                       MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2453
2454        /* Reset internal microprocessor */
2455        bnx2x_cl45_write(bp, port,
2456                       ext_phy_type,
2457                       ext_phy_addr,
2458                       MDIO_PMA_DEVAD,
2459                       MDIO_PMA_REG_GEN_CTRL,
2460                       MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2461
2462        /* Release srst bit */
2463        bnx2x_cl45_write(bp, port,
2464                       ext_phy_type,
2465                       ext_phy_addr,
2466                       MDIO_PMA_DEVAD,
2467                       MDIO_PMA_REG_GEN_CTRL,
2468                       MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2469
2470        /* wait for 100ms for code download via SPI port */
2471        msleep(100);
2472
2473        /* Clear ser_boot_ctl bit */
2474        bnx2x_cl45_write(bp, port,
2475                       ext_phy_type,
2476                       ext_phy_addr,
2477                       MDIO_PMA_DEVAD,
2478                       MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2479
2480        bnx2x_save_bcm_spirom_ver(bp, port,
2481                                ext_phy_type,
2482                                ext_phy_addr,
2483                                shmem_base);
2484}
2485
2486static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2487                                          u8 ext_phy_addr,
2488                                          u32 shmem_base)
2489{
2490        bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr,
2491                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2492                                         shmem_base);
2493}
2494
2495static void bnx2x_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
2496                                          u8 ext_phy_addr,
2497                                          u32 shmem_base)
2498{
2499        bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr,
2500                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2501                                         shmem_base);
2502
2503}
2504
2505static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
2506{
2507        struct bnx2x *bp = params->bp;
2508        u8 port = params->port;
2509        u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2510        u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2511
2512        /* Need to wait 100ms after reset */
2513        msleep(100);
2514
2515        /* Set serial boot control for external load */
2516        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2517                       MDIO_PMA_DEVAD,
2518                       MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2519
2520        /* Micro controller re-boot */
2521        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2522                       MDIO_PMA_DEVAD,
2523                       MDIO_PMA_REG_GEN_CTRL,
2524                       MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2525
2526        /* Set soft reset */
2527        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2528                       MDIO_PMA_DEVAD,
2529                       MDIO_PMA_REG_GEN_CTRL,
2530                       MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2531
2532        /* Set PLL register value to be same like in P13 ver */
2533        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2534                       MDIO_PMA_DEVAD,
2535                       MDIO_PMA_REG_PLL_CTRL,
2536                       0x73A0);
2537
2538        /* Clear soft reset.
2539        Will automatically reset micro-controller re-boot */
2540        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2541                       MDIO_PMA_DEVAD,
2542                       MDIO_PMA_REG_GEN_CTRL,
2543                       MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2544
2545        /* wait for 150ms for microcode load */
2546        msleep(150);
2547
2548        /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
2549        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2550                       MDIO_PMA_DEVAD,
2551                       MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2552
2553        msleep(200);
2554        bnx2x_save_bcm_spirom_ver(bp, port,
2555                                ext_phy_type,
2556                                ext_phy_addr,
2557                                params->shmem_base);
2558}
2559
2560static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, u8 port,
2561                                    u32 ext_phy_type, u8 ext_phy_addr,
2562                                    u8 tx_en)
2563{
2564        u16 val;
2565
2566        DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
2567                 tx_en, port);
2568        /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
2569        bnx2x_cl45_read(bp, port,
2570                      ext_phy_type,
2571                      ext_phy_addr,
2572                      MDIO_PMA_DEVAD,
2573                      MDIO_PMA_REG_PHY_IDENTIFIER,
2574                      &val);
2575
2576        if (tx_en)
2577                val &= ~(1<<15);
2578        else
2579                val |= (1<<15);
2580
2581        bnx2x_cl45_write(bp, port,
2582                       ext_phy_type,
2583                       ext_phy_addr,
2584                       MDIO_PMA_DEVAD,
2585                       MDIO_PMA_REG_PHY_IDENTIFIER,
2586                       val);
2587}
2588
2589static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params,
2590                                          u16 addr, u8 byte_cnt, u8 *o_buf)
2591{
2592        struct bnx2x *bp = params->bp;
2593        u16 val = 0;
2594        u16 i;
2595        u8 port = params->port;
2596        u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2597        u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2598
2599        if (byte_cnt > 16) {
2600                DP(NETIF_MSG_LINK, "Reading from eeprom is"
2601                            " is limited to 0xf\n");
2602                return -EINVAL;
2603        }
2604        /* Set the read command byte count */
2605        bnx2x_cl45_write(bp, port,
2606                       ext_phy_type,
2607                       ext_phy_addr,
2608                       MDIO_PMA_DEVAD,
2609                       MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
2610                       (byte_cnt | 0xa000));
2611
2612        /* Set the read command address */
2613        bnx2x_cl45_write(bp, port,
2614                       ext_phy_type,
2615                       ext_phy_addr,
2616                       MDIO_PMA_DEVAD,
2617                       MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
2618                       addr);
2619
2620        /* Activate read command */
2621        bnx2x_cl45_write(bp, port,
2622                       ext_phy_type,
2623                       ext_phy_addr,
2624                       MDIO_PMA_DEVAD,
2625                       MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2626                       0x2c0f);
2627
2628        /* Wait up to 500us for command complete status */
2629        for (i = 0; i < 100; i++) {
2630                bnx2x_cl45_read(bp, port,
2631                              ext_phy_type,
2632                              ext_phy_addr,
2633                              MDIO_PMA_DEVAD,
2634                              MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2635                if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2636                    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
2637                        break;
2638                udelay(5);
2639        }
2640
2641        if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
2642                    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
2643                DP(NETIF_MSG_LINK,
2644                         "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2645                         (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
2646                return -EINVAL;
2647        }
2648
2649        /* Read the buffer */
2650        for (i = 0; i < byte_cnt; i++) {
2651                bnx2x_cl45_read(bp, port,
2652                              ext_phy_type,
2653                              ext_phy_addr,
2654                              MDIO_PMA_DEVAD,
2655                              MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2656                o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
2657        }
2658
2659        for (i = 0; i < 100; i++) {
2660                bnx2x_cl45_read(bp, port,
2661                              ext_phy_type,
2662                              ext_phy_addr,
2663                              MDIO_PMA_DEVAD,
2664                              MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2665                if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2666                    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
2667                        return 0;;
2668                msleep(1);
2669        }
2670        return -EINVAL;
2671}
2672
2673static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
2674                                          u16 addr, u8 byte_cnt, u8 *o_buf)
2675{
2676        struct bnx2x *bp = params->bp;
2677        u16 val, i;
2678        u8 port = params->port;
2679        u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2680        u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2681
2682        if (byte_cnt > 16) {
2683                DP(NETIF_MSG_LINK, "Reading from eeprom is"
2684                            " is limited to 0xf\n");
2685                return -EINVAL;
2686        }
2687
2688        /* Need to read from 1.8000 to clear it */
2689        bnx2x_cl45_read(bp, port,
2690                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2691                      ext_phy_addr,
2692                      MDIO_PMA_DEVAD,
2693                      MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2694                      &val);
2695
2696        /* Set the read command byte count */
2697        bnx2x_cl45_write(bp, port,
2698                       ext_phy_type,
2699                       ext_phy_addr,
2700                       MDIO_PMA_DEVAD,
2701                       MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
2702                       ((byte_cnt < 2) ? 2 : byte_cnt));
2703
2704        /* Set the read command address */
2705        bnx2x_cl45_write(bp, port,
2706                       ext_phy_type,
2707                       ext_phy_addr,
2708                       MDIO_PMA_DEVAD,
2709                       MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
2710                       addr);
2711        /* Set the destination address */
2712        bnx2x_cl45_write(bp, port,
2713                       ext_phy_type,
2714                       ext_phy_addr,
2715                       MDIO_PMA_DEVAD,
2716                       0x8004,
2717                       MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
2718
2719        /* Activate read command */
2720        bnx2x_cl45_write(bp, port,
2721                       ext_phy_type,
2722                       ext_phy_addr,
2723                       MDIO_PMA_DEVAD,
2724                       MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2725                       0x8002);
2726        /* Wait appropriate time for two-wire command to finish before
2727        polling the status register */
2728        msleep(1);
2729
2730        /* Wait up to 500us for command complete status */
2731        for (i = 0; i < 100; i++) {
2732                bnx2x_cl45_read(bp, port,
2733                              ext_phy_type,
2734                              ext_phy_addr,
2735                              MDIO_PMA_DEVAD,
2736                              MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2737                if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2738                    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
2739                        break;
2740                udelay(5);
2741        }
2742
2743        if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
2744                    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
2745                DP(NETIF_MSG_LINK,
2746                         "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2747                         (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
2748                return -EINVAL;
2749        }
2750
2751        /* Read the buffer */
2752        for (i = 0; i < byte_cnt; i++) {
2753                bnx2x_cl45_read(bp, port,
2754                              ext_phy_type,
2755                              ext_phy_addr,
2756                              MDIO_PMA_DEVAD,
2757                              MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
2758                o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
2759        }
2760
2761        for (i = 0; i < 100; i++) {
2762                bnx2x_cl45_read(bp, port,
2763                              ext_phy_type,
2764                              ext_phy_addr,
2765                              MDIO_PMA_DEVAD,
2766                              MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2767                if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2768                    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
2769                        return 0;;
2770                msleep(1);
2771        }
2772
2773        return -EINVAL;
2774}
2775
2776u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
2777                                     u8 byte_cnt, u8 *o_buf)
2778{
2779        u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2780
2781        if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
2782                return bnx2x_8726_read_sfp_module_eeprom(params, addr,
2783                                                       byte_cnt, o_buf);
2784        else if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
2785                return bnx2x_8727_read_sfp_module_eeprom(params, addr,
2786                                                       byte_cnt, o_buf);
2787        return -EINVAL;
2788}
2789
2790static u8 bnx2x_get_edc_mode(struct link_params *params,
2791                                  u16 *edc_mode)
2792{
2793        struct bnx2x *bp = params->bp;
2794        u8 val, check_limiting_mode = 0;
2795        *edc_mode = EDC_MODE_LIMITING;
2796
2797        /* First check for copper cable */
2798        if (bnx2x_read_sfp_module_eeprom(params,
2799                                       SFP_EEPROM_CON_TYPE_ADDR,
2800                                       1,
2801                                       &val) != 0) {
2802                DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
2803                return -EINVAL;
2804        }
2805
2806        switch (val) {
2807        case SFP_EEPROM_CON_TYPE_VAL_COPPER:
2808        {
2809                u8 copper_module_type;
2810
2811                /* Check if its active cable( includes SFP+ module)
2812                of passive cable*/
2813                if (bnx2x_read_sfp_module_eeprom(params,
2814                                               SFP_EEPROM_FC_TX_TECH_ADDR,
2815                                               1,
2816                                               &copper_module_type) !=
2817                    0) {
2818                        DP(NETIF_MSG_LINK,
2819                                "Failed to read copper-cable-type"
2820                                " from SFP+ EEPROM\n");
2821                        return -EINVAL;
2822                }
2823
2824                if (copper_module_type &
2825                    SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
2826                        DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
2827                        check_limiting_mode = 1;
2828                } else if (copper_module_type &
2829                        SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
2830                                DP(NETIF_MSG_LINK, "Passive Copper"
2831                                            " cable detected\n");
2832                                *edc_mode =
2833                                      EDC_MODE_PASSIVE_DAC;
2834                } else {
2835                        DP(NETIF_MSG_LINK, "Unknown copper-cable-"
2836                                     "type 0x%x !!!\n", copper_module_type);
2837                        return -EINVAL;
2838                }
2839                break;
2840        }
2841        case SFP_EEPROM_CON_TYPE_VAL_LC:
2842                DP(NETIF_MSG_LINK, "Optic module detected\n");
2843                check_limiting_mode = 1;
2844                break;
2845        default:
2846                DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
2847                         val);
2848                return -EINVAL;
2849        }
2850
2851        if (check_limiting_mode) {
2852                u8 options[SFP_EEPROM_OPTIONS_SIZE];
2853                if (bnx2x_read_sfp_module_eeprom(params,
2854                                               SFP_EEPROM_OPTIONS_ADDR,
2855                                               SFP_EEPROM_OPTIONS_SIZE,
2856                                               options) != 0) {
2857                        DP(NETIF_MSG_LINK, "Failed to read Option"
2858                                " field from module EEPROM\n");
2859                        return -EINVAL;
2860                }
2861                if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
2862                        *edc_mode = EDC_MODE_LINEAR;
2863                else
2864                        *edc_mode = EDC_MODE_LIMITING;
2865        }
2866        DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
2867        return 0;
2868}
2869
2870/* This function read the relevant field from the module ( SFP+ ),
2871        and verify it is compliant with this board */
2872static u8 bnx2x_verify_sfp_module(struct link_params *params)
2873{
2874        struct bnx2x *bp = params->bp;
2875        u32 val;
2876        u32 fw_resp;
2877        char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
2878        char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
2879
2880        val = REG_RD(bp, params->shmem_base +
2881                         offsetof(struct shmem_region, dev_info.
2882                                  port_feature_config[params->port].config));
2883        if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
2884            PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
2885                DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
2886                return 0;
2887        }
2888
2889        /* Ask the FW to validate the module */
2890        if (!(params->feature_config_flags &
2891              FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY)) {
2892                DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
2893                            "verification\n");
2894                return -EINVAL;
2895        }
2896
2897        fw_resp = bnx2x_fw_command(bp, DRV_MSG_CODE_VRFY_OPT_MDL);
2898        if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
2899                DP(NETIF_MSG_LINK, "Approved module\n");
2900                return 0;
2901        }
2902
2903        /* format the warning message */
2904        if (bnx2x_read_sfp_module_eeprom(params,
2905                                       SFP_EEPROM_VENDOR_NAME_ADDR,
2906                                       SFP_EEPROM_VENDOR_NAME_SIZE,
2907                                       (u8 *)vendor_name))
2908                vendor_name[0] = '\0';
2909        else
2910                vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
2911        if (bnx2x_read_sfp_module_eeprom(params,
2912                                       SFP_EEPROM_PART_NO_ADDR,
2913                                       SFP_EEPROM_PART_NO_SIZE,
2914                                       (u8 *)vendor_pn))
2915                vendor_pn[0] = '\0';
2916        else
2917                vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
2918
2919        printk(KERN_INFO PFX  "Warning: "
2920                         "Unqualified SFP+ module "
2921                         "detected on %s, Port %d from %s part number %s\n"
2922                        , bp->dev->name, params->port,
2923                        vendor_name, vendor_pn);
2924        return -EINVAL;
2925}
2926
2927static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
2928                                        u16 edc_mode)
2929{
2930        struct bnx2x *bp = params->bp;
2931        u8 port = params->port;
2932        u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2933        u16 cur_limiting_mode;
2934
2935        bnx2x_cl45_read(bp, port,
2936                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2937                      ext_phy_addr,
2938                      MDIO_PMA_DEVAD,
2939                      MDIO_PMA_REG_ROM_VER2,
2940                      &cur_limiting_mode);
2941        DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
2942                 cur_limiting_mode);
2943
2944        if (edc_mode == EDC_MODE_LIMITING) {
2945                DP(NETIF_MSG_LINK,
2946                         "Setting LIMITING MODE\n");
2947                bnx2x_cl45_write(bp, port,
2948                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2949                               ext_phy_addr,
2950                               MDIO_PMA_DEVAD,
2951                               MDIO_PMA_REG_ROM_VER2,
2952                               EDC_MODE_LIMITING);
2953        } else { /* LRM mode ( default )*/
2954
2955                DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
2956
2957                /* Changing to LRM mode takes quite few seconds.
2958                So do it only if current mode is limiting
2959                ( default is LRM )*/
2960                if (cur_limiting_mode != EDC_MODE_LIMITING)
2961                        return 0;
2962
2963                bnx2x_cl45_write(bp, port,
2964                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2965                               ext_phy_addr,
2966                               MDIO_PMA_DEVAD,
2967                               MDIO_PMA_REG_LRM_MODE,
2968                               0);
2969                bnx2x_cl45_write(bp, port,
2970                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2971                               ext_phy_addr,
2972                               MDIO_PMA_DEVAD,
2973                               MDIO_PMA_REG_ROM_VER2,
2974                               0x128);
2975                bnx2x_cl45_write(bp, port,
2976                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2977                               ext_phy_addr,
2978                               MDIO_PMA_DEVAD,
2979                               MDIO_PMA_REG_MISC_CTRL0,
2980                               0x4008);
2981                bnx2x_cl45_write(bp, port,
2982                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2983                               ext_phy_addr,
2984                               MDIO_PMA_DEVAD,
2985                               MDIO_PMA_REG_LRM_MODE,
2986                               0xaaaa);
2987        }
2988        return 0;
2989}
2990
2991static u8 bnx2x_bcm8727_set_limiting_mode(struct link_params *params,
2992                                        u16 edc_mode)
2993{
2994        struct bnx2x *bp = params->bp;
2995        u8 port = params->port;
2996        u16 phy_identifier;
2997        u16 rom_ver2_val;
2998        u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2999
3000        bnx2x_cl45_read(bp, port,
3001                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3002                       ext_phy_addr,
3003                       MDIO_PMA_DEVAD,
3004                       MDIO_PMA_REG_PHY_IDENTIFIER,
3005                       &phy_identifier);
3006
3007        bnx2x_cl45_write(bp, port,
3008                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3009                       ext_phy_addr,
3010                       MDIO_PMA_DEVAD,
3011                       MDIO_PMA_REG_PHY_IDENTIFIER,
3012                       (phy_identifier & ~(1<<9)));
3013
3014        bnx2x_cl45_read(bp, port,
3015                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3016                      ext_phy_addr,
3017                      MDIO_PMA_DEVAD,
3018                      MDIO_PMA_REG_ROM_VER2,
3019                      &rom_ver2_val);
3020        /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
3021        bnx2x_cl45_write(bp, port,
3022                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3023                       ext_phy_addr,
3024                       MDIO_PMA_DEVAD,
3025                       MDIO_PMA_REG_ROM_VER2,
3026                       (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
3027
3028        bnx2x_cl45_write(bp, port,
3029                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3030                       ext_phy_addr,
3031                       MDIO_PMA_DEVAD,
3032                       MDIO_PMA_REG_PHY_IDENTIFIER,
3033                       (phy_identifier | (1<<9)));
3034
3035        return 0;
3036}
3037
3038
3039static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
3040{
3041        u8 val;
3042        struct bnx2x *bp = params->bp;
3043        u16 timeout;
3044        /* Initialization time after hot-plug may take up to 300ms for some
3045        phys type ( e.g. JDSU ) */
3046        for (timeout = 0; timeout < 60; timeout++) {
3047                if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
3048                    == 0) {
3049                        DP(NETIF_MSG_LINK, "SFP+ module initialization "
3050                                     "took %d ms\n", timeout * 5);
3051                        return 0;
3052                }
3053                msleep(5);
3054        }
3055        return -EINVAL;
3056}
3057
3058static void bnx2x_8727_power_module(struct bnx2x *bp,
3059                                  struct link_params *params,
3060                                  u8 ext_phy_addr, u8 is_power_up) {
3061        /* Make sure GPIOs are not using for LED mode */
3062        u16 val;
3063        u8 port = params->port;
3064        /*
3065         * In the GPIO register, bit 4 is use to detemine if the GPIOs are
3066         * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
3067         * output
3068         * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
3069         * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
3070         * where the 1st bit is the over-current(only input), and 2nd bit is
3071         * for power( only output )
3072        */
3073
3074        /*
3075         * In case of NOC feature is disabled and power is up, set GPIO control
3076         *  as input to enable listening of over-current indication
3077         */
3078
3079        if (!(params->feature_config_flags &
3080              FEATURE_CONFIG_BCM8727_NOC) && is_power_up)
3081                val = (1<<4);
3082        else
3083                /*
3084                 * Set GPIO control to OUTPUT, and set the power bit
3085                 * to according to the is_power_up
3086                 */
3087                val = ((!(is_power_up)) << 1);
3088
3089        bnx2x_cl45_write(bp, port,
3090                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3091                       ext_phy_addr,
3092                       MDIO_PMA_DEVAD,
3093                       MDIO_PMA_REG_8727_GPIO_CTRL,
3094                       val);
3095}
3096
3097static u8 bnx2x_sfp_module_detection(struct link_params *params)
3098{
3099        struct bnx2x *bp = params->bp;
3100        u16 edc_mode;
3101        u8 rc = 0;
3102        u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3103        u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3104        u32 val = REG_RD(bp, params->shmem_base +
3105                             offsetof(struct shmem_region, dev_info.
3106                                     port_feature_config[params->port].config));
3107
3108        DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
3109                 params->port);
3110
3111        if (bnx2x_get_edc_mode(params, &edc_mode) != 0) {
3112                DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
3113                return -EINVAL;
3114        } else if (bnx2x_verify_sfp_module(params) !=
3115                   0) {
3116                /* check SFP+ module compatibility */
3117                DP(NETIF_MSG_LINK, "Module verification failed!!\n");
3118                rc = -EINVAL;
3119                /* Turn on fault module-detected led */
3120                bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
3121                                  MISC_REGISTERS_GPIO_HIGH,
3122                                  params->port);
3123                if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
3124                    ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
3125                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) {
3126                        /* Shutdown SFP+ module */
3127                        DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
3128                        bnx2x_8727_power_module(bp, params,
3129                                              ext_phy_addr, 0);
3130                        return rc;
3131                }
3132        } else {
3133                /* Turn off fault module-detected led */
3134                DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n");
3135                bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
3136                                          MISC_REGISTERS_GPIO_LOW,
3137                                          params->port);
3138        }
3139
3140        /* power up the SFP module */
3141        if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
3142                bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
3143
3144        /* Check and set limiting mode / LRM mode on 8726.
3145        On 8727 it is done automatically */
3146        if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
3147                bnx2x_bcm8726_set_limiting_mode(params, edc_mode);
3148        else
3149                bnx2x_bcm8727_set_limiting_mode(params, edc_mode);
3150        /*
3151         * Enable transmit for this module if the module is approved, or
3152         * if unapproved modules should also enable the Tx laser
3153         */
3154        if (rc == 0 ||
3155            (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
3156            PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
3157                bnx2x_sfp_set_transmitter(bp, params->port,
3158                                        ext_phy_type, ext_phy_addr, 1);
3159        else
3160                bnx2x_sfp_set_transmitter(bp, params->port,
3161                                        ext_phy_type, ext_phy_addr, 0);
3162
3163        return rc;
3164}
3165
3166void bnx2x_handle_module_detect_int(struct link_params *params)
3167{
3168        struct bnx2x *bp = params->bp;
3169        u32 gpio_val;
3170        u8 port = params->port;
3171
3172        /* Set valid module led off */
3173        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
3174                          MISC_REGISTERS_GPIO_HIGH,
3175                          params->port);
3176
3177        /* Get current gpio val refelecting module plugged in / out*/
3178        gpio_val = bnx2x_get_gpio(bp,  MISC_REGISTERS_GPIO_3, port);
3179
3180        /* Call the handling function in case module is detected */
3181        if (gpio_val == 0) {
3182
3183                bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
3184                                      MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
3185                                      port);
3186
3187                if (bnx2x_wait_for_sfp_module_initialized(params) ==
3188                    0)
3189                        bnx2x_sfp_module_detection(params);
3190                else
3191                        DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
3192        } else {
3193                u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3194
3195                u32 ext_phy_type =
3196                        XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3197                u32 val = REG_RD(bp, params->shmem_base +
3198                                     offsetof(struct shmem_region, dev_info.
3199                                              port_feature_config[params->port].
3200                                              config));
3201
3202                bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
3203                                      MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
3204                                      port);
3205                /* Module was plugged out. */
3206                /* Disable transmit for this module */
3207                if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
3208                    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
3209                        bnx2x_sfp_set_transmitter(bp, params->port,
3210                                                ext_phy_type, ext_phy_addr, 0);
3211        }
3212}
3213
3214static void bnx2x_bcm807x_force_10G(struct link_params *params)
3215{
3216        struct bnx2x *bp = params->bp;
3217        u8 port = params->port;
3218        u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3219        u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3220
3221        /* Force KR or KX */
3222        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3223                       MDIO_PMA_DEVAD,
3224                       MDIO_PMA_REG_CTRL,
3225                       0x2040);
3226        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3227                       MDIO_PMA_DEVAD,
3228                       MDIO_PMA_REG_10G_CTRL2,
3229                       0x000b);
3230        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3231                       MDIO_PMA_DEVAD,
3232                       MDIO_PMA_REG_BCM_CTRL,
3233                       0x0000);
3234        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3235                       MDIO_AN_DEVAD,
3236                       MDIO_AN_REG_CTRL,
3237                       0x0000);
3238}
3239
3240static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
3241{
3242        struct bnx2x *bp = params->bp;
3243        u8 port = params->port;
3244        u16 val;
3245        u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3246        u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3247
3248        bnx2x_cl45_read(bp, params->port,
3249                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
3250                      ext_phy_addr,
3251                      MDIO_PMA_DEVAD,
3252                      MDIO_PMA_REG_8073_CHIP_REV, &val);
3253
3254        if (val == 0) {
3255                /* Mustn't set low power mode in 8073 A0 */
3256                return;
3257        }
3258
3259        /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
3260        bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
3261                       MDIO_XS_DEVAD,
3262                       MDIO_XS_PLL_SEQUENCER, &val);
3263        val &= ~(1<<13);
3264        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3265                       MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
3266
3267        /* PLL controls */
3268        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3269                       MDIO_XS_DEVAD, 0x805E, 0x1077);
3270        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3271                       MDIO_XS_DEVAD, 0x805D, 0x0000);
3272        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3273                       MDIO_XS_DEVAD, 0x805C, 0x030B);
3274        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3275                       MDIO_XS_DEVAD, 0x805B, 0x1240);
3276        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3277                       MDIO_XS_DEVAD, 0x805A, 0x2490);
3278
3279        /* Tx Controls */
3280        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3281                       MDIO_XS_DEVAD, 0x80A7, 0x0C74);
3282        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3283                       MDIO_XS_DEVAD, 0x80A6, 0x9041);
3284        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3285                       MDIO_XS_DEVAD, 0x80A5, 0x4640);
3286
3287        /* Rx Controls */
3288        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3289                       MDIO_XS_DEVAD, 0x80FE, 0x01C4);
3290        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3291                       MDIO_XS_DEVAD, 0x80FD, 0x9249);
3292        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3293                       MDIO_XS_DEVAD, 0x80FC, 0x2015);
3294
3295        /* Enable PLL sequencer  (use read-modify-write to set bit 13) */
3296        bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
3297                       MDIO_XS_DEVAD,
3298                       MDIO_XS_PLL_SEQUENCER, &val);
3299        val |= (1<<13);
3300        bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3301                       MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
3302}
3303
3304static void bnx2x_8073_set_pause_cl37(struct link_params *params,
3305                                  struct link_vars *vars)
3306{
3307        struct bnx2x *bp = params->bp;
3308        u16 cl37_val;
3309        u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3310        u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3311
3312        bnx2x_cl45_read(bp, params->port,
3313                      ext_phy_type,
3314                      ext_phy_addr,
3315                      MDIO_AN_DEVAD,
3316                      MDIO_AN_REG_CL37_FC_LD, &cl37_val);
3317
3318        cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3319        /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3320
3321        if ((vars->ieee_fc &
3322            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
3323            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
3324                cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
3325        }
3326        if ((vars->ieee_fc &
3327            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3328            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3329                cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3330        }
3331        if ((vars->ieee_fc &
3332            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3333            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3334                cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3335        }
3336        DP(NETIF_MSG_LINK,
3337                 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
3338
3339        bnx2x_cl45_write(bp, params->port,
3340                       ext_phy_type,
3341                       ext_phy_addr,
3342                       MDIO_AN_DEVAD,
3343                       MDIO_AN_REG_CL37_FC_LD, cl37_val);
3344        msleep(500);
3345}
3346
3347static void bnx2x_ext_phy_set_pause(struct link_params *params,
3348                                  struct link_vars *vars)
3349{
3350        struct bnx2x *bp = params->bp;
3351        u16 val;
3352        u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3353        u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3354
3355        /* read modify write pause advertizing */
3356        bnx2x_cl45_read(bp, params->port,
3357                      ext_phy_type,
3358                      ext_phy_addr,
3359                      MDIO_AN_DEVAD,
3360                      MDIO_AN_REG_ADV_PAUSE, &val);
3361
3362        val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3363
3364        /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3365
3366        if ((vars->ieee_fc &
3367            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3368            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3369                val |=  MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3370        }
3371        if ((vars->ieee_fc &
3372            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3373            MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3374                val |=
3375                 MDIO_AN_REG_ADV_PAUSE_PAUSE;
3376        }
3377        DP(NETIF_MSG_LINK,
3378                 "Ext phy AN advertize 0x%x\n", val);
3379        bnx2x_cl45_write(bp, params->port,
3380                       ext_phy_type,
3381                       ext_phy_addr,
3382                       MDIO_AN_DEVAD,
3383                       MDIO_AN_REG_ADV_PAUSE, val);
3384}
3385static void bnx2x_set_preemphasis(struct link_params *params)
3386{
3387        u16 bank, i = 0;
3388        struct bnx2x *bp = params->bp;
3389
3390        for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
3391              bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
3392                        CL45_WR_OVER_CL22(bp, params->port,
3393                                              params->phy_addr,
3394                                              bank,
3395                                              MDIO_RX0_RX_EQ_BOOST,
3396                                              params->xgxs_config_rx[i]);
3397        }
3398
3399        for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
3400                      bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
3401                        CL45_WR_OVER_CL22(bp, params->port,
3402                                              params->phy_addr,
3403                                              bank,
3404                                              MDIO_TX0_TX_DRIVER,
3405                                              params->xgxs_config_tx[i]);
3406        }
3407}
3408
3409
3410static void bnx2x_8481_set_led4(struct link_params *params,
3411                              u32 ext_phy_type, u8 ext_phy_addr)
3412{
3413        struct bnx2x *bp = params->bp;
3414
3415        /* PHYC_CTL_LED_CTL */
3416        bnx2x_cl45_write(bp, params->port,
3417                       ext_phy_type,
3418                       ext_phy_addr,
3419                       MDIO_PMA_DEVAD,
3420                       MDIO_PMA_REG_8481_LINK_SIGNAL, 0xa482);
3421
3422        /* Unmask LED4 for 10G link */
3423        bnx2x_cl45_write(bp, params->port,
3424                       ext_phy_type,
3425                       ext_phy_addr,
3426                       MDIO_PMA_DEVAD,
3427                       MDIO_PMA_REG_8481_SIGNAL_MASK, (1<<6));
3428        /* 'Interrupt Mask' */
3429        bnx2x_cl45_write(bp, params->port,
3430                       ext_phy_type,
3431                       ext_phy_addr,
3432                       MDIO_AN_DEVAD,
3433                       0xFFFB, 0xFFFD);
3434}
3435static void bnx2x_8481_set_legacy_led_mode(struct link_params *params,
3436                                         u32 ext_phy_type, u8 ext_phy_addr)
3437{
3438        struct bnx2x *bp = params->bp;
3439
3440        /* LED1 (10G Link): Disable LED1 when 10/100/1000 link */
3441        /* LED2 (1G/100/10 Link): Enable LED2 when 10/100/1000 link) */
3442        bnx2x_cl45_write(bp, params->port,
3443                       ext_phy_type,
3444                       ext_phy_addr,
3445                       MDIO_AN_DEVAD,
3446                       MDIO_AN_REG_8481_LEGACY_SHADOW,
3447                       (1<<15) | (0xd << 10) | (0xc<<4) | 0xe);
3448}
3449
3450static void bnx2x_8481_set_10G_led_mode(struct link_params *params,
3451                                      u32 ext_phy_type, u8 ext_phy_addr)
3452{
3453        struct bnx2x *bp = params->bp;
3454        u16 val1;
3455
3456        /* LED1 (10G Link) */
3457        /* Enable continuse based on source 7(10G-link) */
3458        bnx2x_cl45_read(bp, params->port,
3459                       ext_phy_type,
3460                       ext_phy_addr,
3461                       MDIO_PMA_DEVAD,
3462                       MDIO_PMA_REG_8481_LINK_SIGNAL,
3463                       &val1);
3464        /* Set bit 2 to 0, and bits [1:0] to 10 */
3465        val1 &= ~((1<<0) | (1<<2)); /* Clear bits 0,2*/
3466        val1 |= (1<<1); /* Set bit 1 */
3467
3468        bnx2x_cl45_write(bp, params->port,
3469                       ext_phy_type,
3470                       ext_phy_addr,
3471                       MDIO_PMA_DEVAD,
3472                       MDIO_PMA_REG_8481_LINK_SIGNAL,
3473                       val1);
3474
3475        /* Unmask LED1 for 10G link */
3476        bnx2x_cl45_read(bp, params->port,
3477                      ext_phy_type,
3478                      ext_phy_addr,
3479                      MDIO_PMA_DEVAD,
3480                      MDIO_PMA_REG_8481_LED1_MASK,
3481                      &val1);
3482        /* Set bit 2 to 0, and bits [1:0] to 10 */
3483        val1 |= (1<<7);
3484        bnx2x_cl45_write(bp, params->port,
3485                       ext_phy_type,
3486                       ext_phy_addr,
3487                       MDIO_PMA_DEVAD,
3488                       MDIO_PMA_REG_8481_LED1_MASK,
3489                       val1);
3490
3491        /* LED2 (1G/100/10G Link) */
3492        /* Mask LED2 for 10G link */
3493        bnx2x_cl45_write(bp, params->port,
3494                       ext_phy_type,
3495                       ext_phy_addr,
3496                       MDIO_PMA_DEVAD,
3497                       MDIO_PMA_REG_8481_LED2_MASK,
3498                       0);
3499
3500        /* LED3 (10G/1G/100/10G Activity) */
3501        bnx2x_cl45_read(bp, params->port,
3502                      ext_phy_type,
3503                      ext_phy_addr,
3504                      MDIO_PMA_DEVAD,
3505                      MDIO_PMA_REG_8481_LINK_SIGNAL,
3506                      &val1);
3507        /* Enable blink based on source 4(Activity) */
3508        val1 &= ~((1<<7) | (1<<8)); /* Clear bits 7,8 */
3509        val1 |= (1<<6); /* Set only bit 6 */
3510        bnx2x_cl45_write(bp, params->port,
3511                       ext_phy_type,
3512                       ext_phy_addr,
3513                       MDIO_PMA_DEVAD,
3514                       MDIO_PMA_REG_8481_LINK_SIGNAL,
3515                       val1);
3516
3517        bnx2x_cl45_read(bp, params->port,
3518                      ext_phy_type,
3519                      ext_phy_addr,
3520                      MDIO_PMA_DEVAD,
3521                      MDIO_PMA_REG_8481_LED3_MASK,
3522                      &val1);
3523        val1 |= (1<<4); /* Unmask LED3 for 10G link */
3524        bnx2x_cl45_write(bp, params->port,
3525                       ext_phy_type,
3526                       ext_phy_addr,
3527                       MDIO_PMA_DEVAD,
3528                       MDIO_PMA_REG_8481_LED3_MASK,
3529                       val1);
3530}
3531
3532
3533static void bnx2x_init_internal_phy(struct link_params *params,
3534                                  struct link_vars *vars,
3535                                  u8 enable_cl73)
3536{
3537        struct bnx2x *bp = params->bp;
3538
3539        if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
3540                if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
3541                     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3542                    (params->feature_config_flags &
3543                     FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
3544                        bnx2x_set_preemphasis(params);
3545
3546                /* forced speed requested? */
3547                if (vars->line_speed != SPEED_AUTO_NEG) {
3548                        DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
3549
3550                        /* disable autoneg */
3551                        bnx2x_set_autoneg(params, vars, 0);
3552
3553                        /* program speed and duplex */
3554                        bnx2x_program_serdes(params, vars);
3555
3556                } else { /* AN_mode */
3557                        DP(NETIF_MSG_LINK, "not SGMII, AN\n");
3558
3559                        /* AN enabled */
3560                        bnx2x_set_brcm_cl37_advertisment(params);
3561
3562                        /* program duplex & pause advertisement (for aneg) */
3563                        bnx2x_set_ieee_aneg_advertisment(params,
3564                                                       vars->ieee_fc);
3565
3566                        /* enable autoneg */
3567                        bnx2x_set_autoneg(params, vars, enable_cl73);
3568
3569                        /* enable and restart AN */
3570                        bnx2x_restart_autoneg(params, enable_cl73);
3571                }
3572
3573        } else { /* SGMII mode */
3574                DP(NETIF_MSG_LINK, "SGMII\n");
3575
3576                bnx2x_initialize_sgmii_process(params, vars);
3577        }
3578}
3579
3580static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
3581{
3582        struct bnx2x *bp = params->bp;
3583        u32 ext_phy_type;
3584        u8 ext_phy_addr;
3585        u16 cnt;
3586        u16 ctrl = 0;
3587        u16 val = 0;
3588        u8 rc = 0;
3589
3590        if (vars->phy_flags & PHY_XGXS_FLAG) {
3591                ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3592
3593                ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3594                /* Make sure that the soft reset is off (expect for the 8072:
3595                 * due to the lock, it will be done inside the specific
3596                 * handling)
3597                 */
3598                if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3599                    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3600                   (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
3601                    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
3602                    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
3603                        /* Wait for soft reset to get cleared upto 1 sec */
3604                        for (cnt = 0; cnt < 1000; cnt++) {
3605                                bnx2x_cl45_read(bp, params->port,
3606                                              ext_phy_type,
3607                                              ext_phy_addr,
3608                                              MDIO_PMA_DEVAD,
3609                                              MDIO_PMA_REG_CTRL, &ctrl);
3610                                if (!(ctrl & (1<<15)))
3611                                        break;
3612                                msleep(1);
3613                        }
3614                        DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
3615                                 ctrl, cnt);
3616                }
3617
3618                switch (ext_phy_type) {
3619                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3620                        break;
3621
3622                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3623                        DP(NETIF_MSG_LINK, "XGXS 8705\n");
3624
3625                        bnx2x_cl45_write(bp, params->port,
3626                                       ext_phy_type,
3627                                       ext_phy_addr,
3628                                       MDIO_PMA_DEVAD,
3629                                       MDIO_PMA_REG_MISC_CTRL,
3630                                       0x8288);
3631                        bnx2x_cl45_write(bp, params->port,
3632                                       ext_phy_type,
3633                                       ext_phy_addr,
3634                                       MDIO_PMA_DEVAD,
3635                                       MDIO_PMA_REG_PHY_IDENTIFIER,
3636                                       0x7fbf);
3637                        bnx2x_cl45_write(bp, params->port,
3638                                       ext_phy_type,
3639                                       ext_phy_addr,
3640                                       MDIO_PMA_DEVAD,
3641                                       MDIO_PMA_REG_CMU_PLL_BYPASS,
3642                                       0x0100);
3643                        bnx2x_cl45_write(bp, params->port,
3644                                       ext_phy_type,
3645                                       ext_phy_addr,
3646                                       MDIO_WIS_DEVAD,
3647                                       MDIO_WIS_REG_LASI_CNTL, 0x1);
3648
3649                        /* BCM8705 doesn't have microcode, hence the 0 */
3650                        bnx2x_save_spirom_version(bp, params->port,
3651                                                params->shmem_base, 0);
3652                        break;
3653
3654                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3655                        /* Wait until fw is loaded */
3656                        for (cnt = 0; cnt < 100; cnt++) {
3657                                bnx2x_cl45_read(bp, params->port, ext_phy_type,
3658                                              ext_phy_addr, MDIO_PMA_DEVAD,
3659                                              MDIO_PMA_REG_ROM_VER1, &val);
3660                                if (val)
3661                                        break;
3662                                msleep(10);
3663                        }
3664                        DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
3665                                "after %d ms\n", cnt);
3666                        if ((params->feature_config_flags &
3667                             FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3668                                u8 i;
3669                                u16 reg;
3670                                for (i = 0; i < 4; i++) {
3671                                        reg = MDIO_XS_8706_REG_BANK_RX0 +
3672                                                i*(MDIO_XS_8706_REG_BANK_RX1 -
3673                                                   MDIO_XS_8706_REG_BANK_RX0);
3674                                        bnx2x_cl45_read(bp, params->port,
3675                                                      ext_phy_type,
3676                                                      ext_phy_addr,
3677                                                      MDIO_XS_DEVAD,
3678                                                      reg, &val);
3679                                        /* Clear first 3 bits of the control */
3680                                        val &= ~0x7;
3681                                        /* Set control bits according to
3682                                        configuation */
3683                                        val |= (params->xgxs_config_rx[i] &
3684                                                0x7);
3685                                        DP(NETIF_MSG_LINK, "Setting RX"
3686                                                 "Equalizer to BCM8706 reg 0x%x"
3687                                                 " <-- val 0x%x\n", reg, val);
3688                                        bnx2x_cl45_write(bp, params->port,
3689                                                       ext_phy_type,
3690                                                       ext_phy_addr,
3691                                                       MDIO_XS_DEVAD,
3692                                                       reg, val);
3693                                }
3694                        }
3695                        /* Force speed */
3696                        /* First enable LASI */
3697                        bnx2x_cl45_write(bp, params->port,
3698                                       ext_phy_type,
3699                                       ext_phy_addr,
3700                                       MDIO_PMA_DEVAD,
3701                                       MDIO_PMA_REG_RX_ALARM_CTRL,
3702                                       0x0400);
3703                        bnx2x_cl45_write(bp, params->port,
3704                                       ext_phy_type,
3705                                       ext_phy_addr,
3706                                       MDIO_PMA_DEVAD,
3707                                       MDIO_PMA_REG_LASI_CTRL, 0x0004);
3708
3709                        if (params->req_line_speed == SPEED_10000) {
3710                                DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
3711
3712                                bnx2x_cl45_write(bp, params->port,
3713                                               ext_phy_type,
3714                                               ext_phy_addr,
3715                                               MDIO_PMA_DEVAD,
3716                                               MDIO_PMA_REG_DIGITAL_CTRL,
3717                                               0x400);
3718                        } else {
3719                                /* Force 1Gbps using autoneg with 1G
3720                                advertisment */
3721
3722                                /* Allow CL37 through CL73 */
3723                                DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
3724                                bnx2x_cl45_write(bp, params->port,
3725                                               ext_phy_type,
3726                                               ext_phy_addr,
3727                                               MDIO_AN_DEVAD,
3728                                               MDIO_AN_REG_CL37_CL73,
3729                                               0x040c);
3730
3731                                /* Enable Full-Duplex advertisment on CL37 */
3732                                bnx2x_cl45_write(bp, params->port,
3733                                               ext_phy_type,
3734                                               ext_phy_addr,
3735                                               MDIO_AN_DEVAD,
3736                                               MDIO_AN_REG_CL37_FC_LP,
3737                                               0x0020);
3738                                /* Enable CL37 AN */
3739                                bnx2x_cl45_write(bp, params->port,
3740                                               ext_phy_type,
3741                                               ext_phy_addr,
3742                                               MDIO_AN_DEVAD,
3743                                               MDIO_AN_REG_CL37_AN,
3744                                               0x1000);
3745                                /* 1G support */
3746                                bnx2x_cl45_write(bp, params->port,
3747                                               ext_phy_type,
3748                                               ext_phy_addr,
3749                                               MDIO_AN_DEVAD,
3750                                               MDIO_AN_REG_ADV, (1<<5));
3751
3752                                /* Enable clause 73 AN */
3753                                bnx2x_cl45_write(bp, params->port,
3754                                               ext_phy_type,
3755                                               ext_phy_addr,
3756                                               MDIO_AN_DEVAD,
3757                                               MDIO_AN_REG_CTRL,
3758                                               0x1200);
3759
3760                        }
3761                        bnx2x_save_bcm_spirom_ver(bp, params->port,
3762                                                ext_phy_type,
3763                                                ext_phy_addr,
3764                                                params->shmem_base);
3765                        break;
3766                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3767                        DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3768                        bnx2x_bcm8726_external_rom_boot(params);
3769
3770                        /* Need to call module detected on initialization since
3771                        the module detection triggered by actual module
3772                        insertion might occur before driver is loaded, and when
3773                        driver is loaded, it reset all registers, including the
3774                        transmitter */
3775                        bnx2x_sfp_module_detection(params);
3776
3777                        /* Set Flow control */
3778                        bnx2x_ext_phy_set_pause(params, vars);
3779                        if (params->req_line_speed == SPEED_1000) {
3780                                DP(NETIF_MSG_LINK, "Setting 1G force\n");
3781                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
3782                                               ext_phy_addr, MDIO_PMA_DEVAD,
3783                                               MDIO_PMA_REG_CTRL, 0x40);
3784                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
3785                                               ext_phy_addr, MDIO_PMA_DEVAD,
3786                                               MDIO_PMA_REG_10G_CTRL2, 0xD);
3787                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
3788                                               ext_phy_addr, MDIO_PMA_DEVAD,
3789                                               MDIO_PMA_REG_LASI_CTRL, 0x5);
3790                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
3791                                               ext_phy_addr, MDIO_PMA_DEVAD,
3792                                               MDIO_PMA_REG_RX_ALARM_CTRL,
3793                                               0x400);
3794                        } else if ((params->req_line_speed ==
3795                                    SPEED_AUTO_NEG) &&
3796                                   ((params->speed_cap_mask &
3797                                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3798                                DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
3799                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
3800                                               ext_phy_addr, MDIO_AN_DEVAD,
3801                                               MDIO_AN_REG_ADV, 0x20);
3802                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
3803                                               ext_phy_addr, MDIO_AN_DEVAD,
3804                                               MDIO_AN_REG_CL37_CL73, 0x040c);
3805                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
3806                                               ext_phy_addr, MDIO_AN_DEVAD,
3807                                               MDIO_AN_REG_CL37_FC_LD, 0x0020);
3808                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
3809                                               ext_phy_addr, MDIO_AN_DEVAD,
3810                                               MDIO_AN_REG_CL37_AN, 0x1000);
3811                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
3812                                               ext_phy_addr, MDIO_AN_DEVAD,
3813                                               MDIO_AN_REG_CTRL, 0x1200);
3814
3815                                /* Enable RX-ALARM control to receive
3816                                interrupt for 1G speed change */
3817                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
3818                                               ext_phy_addr, MDIO_PMA_DEVAD,
3819                                               MDIO_PMA_REG_LASI_CTRL, 0x4);
3820                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
3821                                               ext_phy_addr, MDIO_PMA_DEVAD,
3822                                               MDIO_PMA_REG_RX_ALARM_CTRL,
3823                                               0x400);
3824
3825                        } else { /* Default 10G. Set only LASI control */
3826                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
3827                                               ext_phy_addr, MDIO_PMA_DEVAD,
3828                                               MDIO_PMA_REG_LASI_CTRL, 1);
3829                        }
3830
3831                        /* Set TX PreEmphasis if needed */
3832                        if ((params->feature_config_flags &
3833                             FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3834                                DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
3835                                         "TX_CTRL2 0x%x\n",
3836                                         params->xgxs_config_tx[0],
3837                                         params->xgxs_config_tx[1]);
3838                                bnx2x_cl45_write(bp, params->port,
3839                                               ext_phy_type,
3840                                               ext_phy_addr,
3841                                               MDIO_PMA_DEVAD,
3842                                               MDIO_PMA_REG_8726_TX_CTRL1,
3843                                               params->xgxs_config_tx[0]);
3844
3845                                bnx2x_cl45_write(bp, params->port,
3846                                               ext_phy_type,
3847                                               ext_phy_addr,
3848                                               MDIO_PMA_DEVAD,
3849                                               MDIO_PMA_REG_8726_TX_CTRL2,
3850                                               params->xgxs_config_tx[1]);
3851                        }
3852                        break;
3853                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3854                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3855                {
3856                        u16 tmp1;
3857                        u16 rx_alarm_ctrl_val;
3858                        u16 lasi_ctrl_val;
3859                        if (ext_phy_type ==
3860                            PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3861                                rx_alarm_ctrl_val = 0x400;
3862                                lasi_ctrl_val = 0x0004;
3863                        } else {
3864                                rx_alarm_ctrl_val = (1<<2);
3865                                lasi_ctrl_val = 0x0004;
3866                        }
3867
3868                        /* enable LASI */
3869                        bnx2x_cl45_write(bp, params->port,
3870                                   ext_phy_type,
3871                                   ext_phy_addr,
3872                                   MDIO_PMA_DEVAD,
3873                                   MDIO_PMA_REG_RX_ALARM_CTRL,
3874                                   rx_alarm_ctrl_val);
3875
3876                        bnx2x_cl45_write(bp, params->port,
3877                                       ext_phy_type,
3878                                       ext_phy_addr,
3879                                       MDIO_PMA_DEVAD,
3880                                       MDIO_PMA_REG_LASI_CTRL,
3881                                       lasi_ctrl_val);
3882
3883                        bnx2x_8073_set_pause_cl37(params, vars);
3884
3885                        if (ext_phy_type ==
3886                            PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072)
3887                                bnx2x_bcm8072_external_rom_boot(params);
3888                        else
3889                                /* In case of 8073 with long xaui lines,
3890                                don't set the 8073 xaui low power*/
3891                                bnx2x_bcm8073_set_xaui_low_power_mode(params);
3892
3893                        bnx2x_cl45_read(bp, params->port,
3894                                      ext_phy_type,
3895                                      ext_phy_addr,
3896                                      MDIO_PMA_DEVAD,
3897                                      MDIO_PMA_REG_M8051_MSGOUT_REG,
3898                                      &tmp1);
3899
3900                        bnx2x_cl45_read(bp, params->port,
3901                                      ext_phy_type,
3902                                      ext_phy_addr,
3903                                      MDIO_PMA_DEVAD,
3904                                      MDIO_PMA_REG_RX_ALARM, &tmp1);
3905
3906                        DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
3907                                             "0x%x\n", tmp1);
3908
3909                        /* If this is forced speed, set to KR or KX
3910                         * (all other are not supported)
3911                         */
3912                        if (params->loopback_mode == LOOPBACK_EXT) {
3913                                bnx2x_bcm807x_force_10G(params);
3914                                DP(NETIF_MSG_LINK,
3915                                        "Forced speed 10G on 807X\n");
3916                                break;
3917                        } else {
3918                                bnx2x_cl45_write(bp, params->port,
3919                                               ext_phy_type, ext_phy_addr,
3920                                               MDIO_PMA_DEVAD,
3921                                               MDIO_PMA_REG_BCM_CTRL,
3922                                               0x0002);
3923                        }
3924                        if (params->req_line_speed != SPEED_AUTO_NEG) {
3925                                if (params->req_line_speed == SPEED_10000) {
3926                                        val = (1<<7);
3927                                } else if (params->req_line_speed ==
3928                                           SPEED_2500) {
3929                                        val = (1<<5);
3930                                        /* Note that 2.5G works only
3931                                        when used with 1G advertisment */
3932                                } else
3933                                        val = (1<<5);
3934                        } else {
3935
3936                                val = 0;
3937                                if (params->speed_cap_mask &
3938                                        PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3939                                        val |= (1<<7);
3940
3941                                /* Note that 2.5G works only when
3942                                used with 1G advertisment */
3943                                if (params->speed_cap_mask &
3944                                        (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
3945                                         PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
3946                                        val |= (1<<5);
3947                                DP(NETIF_MSG_LINK,
3948                                         "807x autoneg val = 0x%x\n", val);
3949                        }
3950
3951                        bnx2x_cl45_write(bp, params->port,
3952                                       ext_phy_type,
3953                                       ext_phy_addr,
3954                                       MDIO_AN_DEVAD,
3955                                       MDIO_AN_REG_ADV, val);
3956                        if (ext_phy_type ==
3957                            PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3958                                bnx2x_cl45_read(bp, params->port,
3959                                              ext_phy_type,
3960                                              ext_phy_addr,
3961                                              MDIO_AN_DEVAD,
3962                                              MDIO_AN_REG_8073_2_5G, &tmp1);
3963
3964                                if (((params->speed_cap_mask &
3965                                      PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
3966                                     (params->req_line_speed ==
3967                                      SPEED_AUTO_NEG)) ||
3968                                    (params->req_line_speed ==
3969                                     SPEED_2500)) {
3970                                        u16 phy_ver;
3971                                        /* Allow 2.5G for A1 and above */
3972                                        bnx2x_cl45_read(bp, params->port,
3973                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
3974                                         ext_phy_addr,
3975                                         MDIO_PMA_DEVAD,
3976                                         MDIO_PMA_REG_8073_CHIP_REV, &phy_ver);
3977                                        DP(NETIF_MSG_LINK, "Add 2.5G\n");
3978                                        if (phy_ver > 0)
3979                                                tmp1 |= 1;
3980                                        else
3981                                                tmp1 &= 0xfffe;
3982                                } else {
3983                                        DP(NETIF_MSG_LINK, "Disable 2.5G\n");
3984                                        tmp1 &= 0xfffe;
3985                                }
3986
3987                                bnx2x_cl45_write(bp, params->port,
3988                                               ext_phy_type,
3989                                               ext_phy_addr,
3990                                               MDIO_AN_DEVAD,
3991                                               MDIO_AN_REG_8073_2_5G, tmp1);
3992                        }
3993
3994                        /* Add support for CL37 (passive mode) II */
3995
3996                        bnx2x_cl45_read(bp, params->port,
3997                                       ext_phy_type,
3998                                       ext_phy_addr,
3999                                       MDIO_AN_DEVAD,
4000                                       MDIO_AN_REG_CL37_FC_LD,
4001                                       &tmp1);
4002
4003                        bnx2x_cl45_write(bp, params->port,
4004                                       ext_phy_type,
4005                                       ext_phy_addr,
4006                                       MDIO_AN_DEVAD,
4007                                       MDIO_AN_REG_CL37_FC_LD, (tmp1 |
4008                                       ((params->req_duplex == DUPLEX_FULL) ?
4009                                       0x20 : 0x40)));
4010
4011                        /* Add support for CL37 (passive mode) III */
4012                        bnx2x_cl45_write(bp, params->port,
4013                                       ext_phy_type,
4014                                       ext_phy_addr,
4015                                       MDIO_AN_DEVAD,
4016                                       MDIO_AN_REG_CL37_AN, 0x1000);
4017
4018                        if (ext_phy_type ==
4019                            PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4020                                /* The SNR will improve about 2db by changing
4021                                BW and FEE main tap. Rest commands are executed
4022                                after link is up*/
4023                                /*Change FFE main cursor to 5 in EDC register*/
4024                                if (bnx2x_8073_is_snr_needed(params))
4025                                        bnx2x_cl45_write(bp, params->port,
4026                                                    ext_phy_type,
4027                                                    ext_phy_addr,
4028                                                    MDIO_PMA_DEVAD,
4029                                                    MDIO_PMA_REG_EDC_FFE_MAIN,
4030                                                    0xFB0C);
4031
4032                                /* Enable FEC (Forware Error Correction)
4033                                Request in the AN */
4034                                bnx2x_cl45_read(bp, params->port,
4035                                              ext_phy_type,
4036                                              ext_phy_addr,
4037                                              MDIO_AN_DEVAD,
4038                                              MDIO_AN_REG_ADV2, &tmp1);
4039
4040                                tmp1 |= (1<<15);
4041
4042                                bnx2x_cl45_write(bp, params->port,
4043                                               ext_phy_type,
4044                                               ext_phy_addr,
4045                                               MDIO_AN_DEVAD,
4046                                               MDIO_AN_REG_ADV2, tmp1);
4047
4048                        }
4049
4050                        bnx2x_ext_phy_set_pause(params, vars);
4051
4052                        /* Restart autoneg */
4053                        msleep(500);
4054                        bnx2x_cl45_write(bp, params->port,
4055                                       ext_phy_type,
4056                                       ext_phy_addr,
4057                                       MDIO_AN_DEVAD,
4058                                       MDIO_AN_REG_CTRL, 0x1200);
4059                        DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
4060                           "Advertise 1G=%x, 10G=%x\n",
4061                           ((val & (1<<5)) > 0),
4062                           ((val & (1<<7)) > 0));
4063                        break;
4064                }
4065
4066                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
4067                {
4068                        u16 tmp1;
4069                        u16 rx_alarm_ctrl_val;
4070                        u16 lasi_ctrl_val;
4071
4072                        /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
4073
4074                        u16 mod_abs;
4075                        rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
4076                        lasi_ctrl_val = 0x0004;
4077
4078                        DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
4079                        /* enable LASI */
4080                        bnx2x_cl45_write(bp, params->port,
4081                                       ext_phy_type,
4082                                       ext_phy_addr,
4083                                       MDIO_PMA_DEVAD,
4084                                       MDIO_PMA_REG_RX_ALARM_CTRL,
4085                                       rx_alarm_ctrl_val);
4086
4087                        bnx2x_cl45_write(bp, params->port,
4088                                       ext_phy_type,
4089                                       ext_phy_addr,
4090                                       MDIO_PMA_DEVAD,
4091                                       MDIO_PMA_REG_LASI_CTRL,
4092                                       lasi_ctrl_val);
4093
4094                        /* Initially configure  MOD_ABS to interrupt when
4095                        module is presence( bit 8) */
4096                        bnx2x_cl45_read(bp, params->port,
4097                                      ext_phy_type,
4098                                      ext_phy_addr,
4099                                      MDIO_PMA_DEVAD,
4100                                      MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
4101                        /* Set EDC off by setting OPTXLOS signal input to low
4102                        (bit 9).
4103                        When the EDC is off it locks onto a reference clock and
4104                        avoids becoming 'lost'.*/
4105                        mod_abs &= ~((1<<8) | (1<<9));
4106                        bnx2x_cl45_write(bp, params->port,
4107                                       ext_phy_type,
4108                                       ext_phy_addr,
4109                                       MDIO_PMA_DEVAD,
4110                                       MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4111
4112                        /* Make MOD_ABS give interrupt on change */
4113                        bnx2x_cl45_read(bp, params->port,
4114                                      ext_phy_type,
4115                                      ext_phy_addr,
4116                                      MDIO_PMA_DEVAD,
4117                                      MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4118                                      &val);
4119                        val |= (1<<12);
4120                        bnx2x_cl45_write(bp, params->port,
4121                                       ext_phy_type,
4122                                       ext_phy_addr,
4123                                       MDIO_PMA_DEVAD,
4124                                       MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4125                                       val);
4126
4127                        /* Set 8727 GPIOs to input to allow reading from the
4128                        8727 GPIO0 status which reflect SFP+ module
4129                        over-current */
4130
4131                        bnx2x_cl45_read(bp, params->port,
4132                                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4133                                       ext_phy_addr,
4134                                       MDIO_PMA_DEVAD,
4135                                       MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4136                                       &val);
4137                        val &= 0xff8f; /* Reset bits 4-6 */
4138                        bnx2x_cl45_write(bp, params->port,
4139                                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4140                                       ext_phy_addr,
4141                                       MDIO_PMA_DEVAD,
4142                                       MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4143                                       val);
4144
4145                        bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
4146                        bnx2x_bcm8073_set_xaui_low_power_mode(params);
4147
4148                        bnx2x_cl45_read(bp, params->port,
4149                                      ext_phy_type,
4150                                      ext_phy_addr,
4151                                      MDIO_PMA_DEVAD,
4152                                      MDIO_PMA_REG_M8051_MSGOUT_REG,
4153                                      &tmp1);
4154
4155                        bnx2x_cl45_read(bp, params->port,
4156                                      ext_phy_type,
4157                                      ext_phy_addr,
4158                                      MDIO_PMA_DEVAD,
4159                                      MDIO_PMA_REG_RX_ALARM, &tmp1);
4160
4161                        /* Set option 1G speed */
4162                        if (params->req_line_speed == SPEED_1000) {
4163
4164                                DP(NETIF_MSG_LINK, "Setting 1G force\n");
4165                                bnx2x_cl45_write(bp, params->port,
4166                                               ext_phy_type,
4167                                               ext_phy_addr,
4168                                               MDIO_PMA_DEVAD,
4169                                               MDIO_PMA_REG_CTRL, 0x40);
4170                                bnx2x_cl45_write(bp, params->port,
4171                                               ext_phy_type,
4172                                               ext_phy_addr,
4173                                               MDIO_PMA_DEVAD,
4174                                               MDIO_PMA_REG_10G_CTRL2, 0xD);
4175                                bnx2x_cl45_read(bp, params->port,
4176                                      ext_phy_type,
4177                                      ext_phy_addr,
4178                                      MDIO_PMA_DEVAD,
4179                                      MDIO_PMA_REG_10G_CTRL2, &tmp1);
4180                                DP(NETIF_MSG_LINK, "1.7 = 0x%x \n", tmp1);
4181
4182                        } else if ((params->req_line_speed ==
4183                                    SPEED_AUTO_NEG) &&
4184                                   ((params->speed_cap_mask &
4185                                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
4186
4187                                DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
4188                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
4189                                               ext_phy_addr, MDIO_AN_DEVAD,
4190                                               MDIO_PMA_REG_8727_MISC_CTRL, 0);
4191                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
4192                                               ext_phy_addr, MDIO_AN_DEVAD,
4193                                               MDIO_AN_REG_CL37_AN, 0x1300);
4194                        } else {
4195                                /* Since the 8727 has only single reset pin,
4196                                need to set the 10G registers although it is
4197                                default */
4198                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
4199                                               ext_phy_addr, MDIO_AN_DEVAD,
4200                                               MDIO_AN_REG_CTRL, 0x0020);
4201                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
4202                                               ext_phy_addr, MDIO_AN_DEVAD,
4203                                               0x7, 0x0100);
4204                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
4205                                               ext_phy_addr, MDIO_PMA_DEVAD,
4206                                               MDIO_PMA_REG_CTRL, 0x2040);
4207                                bnx2x_cl45_write(bp, params->port, ext_phy_type,
4208                                               ext_phy_addr, MDIO_PMA_DEVAD,
4209                                               MDIO_PMA_REG_10G_CTRL2, 0x0008);
4210                        }
4211
4212                        /* Set 2-wire transfer rate to 400Khz since 100Khz
4213                        is not operational */
4214                        bnx2x_cl45_write(bp, params->port,
4215                                       ext_phy_type,
4216                                       ext_phy_addr,
4217                                       MDIO_PMA_DEVAD,
4218                                       MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
4219                                       0xa101);
4220
4221                        /* Set TX PreEmphasis if needed */
4222                        if ((params->feature_config_flags &
4223                             FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
4224                                DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
4225                                         "TX_CTRL2 0x%x\n",
4226                                         params->xgxs_config_tx[0],
4227                                         params->xgxs_config_tx[1]);
4228                                bnx2x_cl45_write(bp, params->port,
4229                                               ext_phy_type,
4230                                               ext_phy_addr,
4231                                               MDIO_PMA_DEVAD,
4232                                               MDIO_PMA_REG_8727_TX_CTRL1,
4233                                               params->xgxs_config_tx[0]);
4234
4235                                bnx2x_cl45_write(bp, params->port,
4236                                               ext_phy_type,
4237                                               ext_phy_addr,
4238                                               MDIO_PMA_DEVAD,
4239                                               MDIO_PMA_REG_8727_TX_CTRL2,
4240                                               params->xgxs_config_tx[1]);
4241                        }
4242
4243                        break;
4244                }
4245
4246                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4247                {
4248                        u16 fw_ver1, fw_ver2;
4249                        DP(NETIF_MSG_LINK,
4250                                "Setting the SFX7101 LASI indication\n");
4251
4252                        bnx2x_cl45_write(bp, params->port,
4253                                       ext_phy_type,
4254                                       ext_phy_addr,
4255                                       MDIO_PMA_DEVAD,
4256                                       MDIO_PMA_REG_LASI_CTRL, 0x1);
4257                        DP(NETIF_MSG_LINK,
4258                          "Setting the SFX7101 LED to blink on traffic\n");
4259                        bnx2x_cl45_write(bp, params->port,
4260                                       ext_phy_type,
4261                                       ext_phy_addr,
4262                                       MDIO_PMA_DEVAD,
4263                                       MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
4264
4265                        bnx2x_ext_phy_set_pause(params, vars);
4266                        /* Restart autoneg */
4267                        bnx2x_cl45_read(bp, params->port,
4268                                      ext_phy_type,
4269                                      ext_phy_addr,
4270                                      MDIO_AN_DEVAD,
4271                                      MDIO_AN_REG_CTRL, &val);
4272                        val |= 0x200;
4273                        bnx2x_cl45_write(bp, params->port,
4274                                       ext_phy_type,
4275                                       ext_phy_addr,
4276                                       MDIO_AN_DEVAD,
4277                                       MDIO_AN_REG_CTRL, val);
4278
4279                        /* Save spirom version */
4280                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
4281                                      ext_phy_addr, MDIO_PMA_DEVAD,
4282                                      MDIO_PMA_REG_7101_VER1, &fw_ver1);
4283
4284                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
4285                                      ext_phy_addr, MDIO_PMA_DEVAD,
4286                                      MDIO_PMA_REG_7101_VER2, &fw_ver2);
4287
4288                        bnx2x_save_spirom_version(params->bp, params->port,
4289                                                params->shmem_base,
4290                                                (u32)(fw_ver1<<16 | fw_ver2));
4291                        break;
4292                }
4293                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
4294                        /* This phy uses the NIG latch mechanism since link
4295                                indication arrives through its LED4 and not via
4296                                its LASI signal, so we get steady signal
4297                                instead of clear on read */
4298                        bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
4299                                    1 << NIG_LATCH_BC_ENABLE_MI_INT);
4300
4301                        bnx2x_8481_set_led4(params, ext_phy_type, ext_phy_addr);
4302                        if (params->req_line_speed == SPEED_AUTO_NEG) {
4303
4304                                u16 autoneg_val, an_1000_val, an_10_100_val;
4305                                /* set 1000 speed advertisement */
4306                                bnx2x_cl45_read(bp, params->port,
4307                                              ext_phy_type,
4308                                              ext_phy_addr,
4309                                              MDIO_AN_DEVAD,
4310                                              MDIO_AN_REG_8481_1000T_CTRL,
4311                                              &an_1000_val);
4312
4313                                if (params->speed_cap_mask &
4314                                    PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) {
4315                                        an_1000_val |= (1<<8);
4316                                        if (params->req_duplex == DUPLEX_FULL)
4317                                                an_1000_val |= (1<<9);
4318                                        DP(NETIF_MSG_LINK, "Advertising 1G\n");
4319                                } else
4320                                        an_1000_val &= ~((1<<8) | (1<<9));
4321
4322                                bnx2x_cl45_write(bp, params->port,
4323                                               ext_phy_type,
4324                                               ext_phy_addr,
4325                                               MDIO_AN_DEVAD,
4326                                               MDIO_AN_REG_8481_1000T_CTRL,
4327                                               an_1000_val);
4328
4329                                /* set 100 speed advertisement */
4330                                bnx2x_cl45_read(bp, params->port,
4331                                              ext_phy_type,
4332                                              ext_phy_addr,
4333                                              MDIO_AN_DEVAD,
4334                                              MDIO_AN_REG_8481_LEGACY_AN_ADV,
4335                                              &an_10_100_val);
4336
4337                                if (params->speed_cap_mask &
4338                                 (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
4339                                  PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) {
4340                                        an_10_100_val |= (1<<7);
4341                                        if (params->req_duplex == DUPLEX_FULL)
4342                                                an_10_100_val |= (1<<8);
4343                                        DP(NETIF_MSG_LINK,
4344                                                "Advertising 100M\n");
4345                                } else
4346                                        an_10_100_val &= ~((1<<7) | (1<<8));
4347
4348                                /* set 10 speed advertisement */
4349                                if (params->speed_cap_mask &
4350                                  (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
4351                                   PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) {
4352                                        an_10_100_val |= (1<<5);
4353                                        if (params->req_duplex == DUPLEX_FULL)
4354                                                an_10_100_val |= (1<<6);
4355                                        DP(NETIF_MSG_LINK, "Advertising 10M\n");
4356                                     }
4357                                else
4358                                        an_10_100_val &= ~((1<<5) | (1<<6));
4359
4360                                bnx2x_cl45_write(bp, params->port,
4361                                               ext_phy_type,
4362                                               ext_phy_addr,
4363                                               MDIO_AN_DEVAD,
4364                                               MDIO_AN_REG_8481_LEGACY_AN_ADV,
4365                                               an_10_100_val);
4366
4367                                bnx2x_cl45_read(bp, params->port,
4368                                              ext_phy_type,
4369                                              ext_phy_addr,
4370                                              MDIO_AN_DEVAD,
4371                                              MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4372                                              &autoneg_val);
4373
4374                                /* Disable forced speed */
4375                                autoneg_val &= ~(1<<6|1<<13);
4376
4377                                /* Enable autoneg and restart autoneg
4378                                for legacy speeds */
4379                                autoneg_val |= (1<<9|1<<12);
4380
4381                                if (params->req_duplex == DUPLEX_FULL)
4382                                        autoneg_val |= (1<<8);
4383                                else
4384                                        autoneg_val &= ~(1<<8);
4385
4386                                bnx2x_cl45_write(bp, params->port,
4387                                               ext_phy_type,
4388                                               ext_phy_addr,
4389                                               MDIO_AN_DEVAD,
4390                                               MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4391                                               autoneg_val);
4392
4393                                if (params->speed_cap_mask &
4394                                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
4395                                        DP(NETIF_MSG_LINK, "Advertising 10G\n");
4396                                        /* Restart autoneg for 10G*/
4397                        bnx2x_cl45_read(bp, params->port,
4398                                      ext_phy_type,
4399                                      ext_phy_addr,
4400                                      MDIO_AN_DEVAD,
4401                                      MDIO_AN_REG_CTRL, &val);
4402                        val |= 0x200;
4403                        bnx2x_cl45_write(bp, params->port,
4404                                       ext_phy_type,
4405                                       ext_phy_addr,
4406                                       MDIO_AN_DEVAD,
4407                                       MDIO_AN_REG_CTRL, val);
4408                                }
4409                        } else {
4410                                /* Force speed */
4411                                u16 autoneg_ctrl, pma_ctrl;
4412                                bnx2x_cl45_read(bp, params->port,
4413                                              ext_phy_type,
4414                                              ext_phy_addr,
4415                                              MDIO_AN_DEVAD,
4416                                              MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4417                                              &autoneg_ctrl);
4418
4419                                /* Disable autoneg */
4420                                autoneg_ctrl &= ~(1<<12);
4421
4422                                /* Set 1000 force */
4423                                switch (params->req_line_speed) {
4424                                case SPEED_10000:
4425                                        DP(NETIF_MSG_LINK,
4426                                                "Unable to set 10G force !\n");
4427                                        break;
4428                                case SPEED_1000:
4429                                        bnx2x_cl45_read(bp, params->port,
4430                                                      ext_phy_type,
4431                                                      ext_phy_addr,
4432                                                      MDIO_PMA_DEVAD,
4433                                                      MDIO_PMA_REG_CTRL,
4434                                                      &pma_ctrl);
4435                                        autoneg_ctrl &= ~(1<<13);
4436                                        autoneg_ctrl |= (1<<6);
4437                                        pma_ctrl &= ~(1<<13);
4438                                        pma_ctrl |= (1<<6);
4439                                        DP(NETIF_MSG_LINK,
4440                                                "Setting 1000M force\n");
4441                                        bnx2x_cl45_write(bp, params->port,
4442                                                       ext_phy_type,
4443                                                       ext_phy_addr,
4444                                                       MDIO_PMA_DEVAD,
4445                                                       MDIO_PMA_REG_CTRL,
4446                                                       pma_ctrl);
4447                                        break;
4448                                case SPEED_100:
4449                                        autoneg_ctrl |= (1<<13);
4450                                        autoneg_ctrl &= ~(1<<6);
4451                                        DP(NETIF_MSG_LINK,
4452                                                "Setting 100M force\n");
4453                                        break;
4454                                case SPEED_10:
4455                                        autoneg_ctrl &= ~(1<<13);
4456                                        autoneg_ctrl &= ~(1<<6);
4457                                        DP(NETIF_MSG_LINK,
4458                                                "Setting 10M force\n");
4459                                        break;
4460                                }
4461
4462                                /* Duplex mode */
4463                                if (params->req_duplex == DUPLEX_FULL) {
4464                                        autoneg_ctrl |= (1<<8);
4465                                        DP(NETIF_MSG_LINK,
4466                                                "Setting full duplex\n");
4467                                } else
4468                                        autoneg_ctrl &= ~(1<<8);
4469
4470                                /* Update autoneg ctrl and pma ctrl */
4471                                bnx2x_cl45_write(bp, params->port,
4472                                               ext_phy_type,
4473                                               ext_phy_addr,
4474                                               MDIO_AN_DEVAD,
4475                                               MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4476                                               autoneg_ctrl);
4477                        }
4478
4479                        /* Save spirom version */
4480                        bnx2x_save_8481_spirom_version(bp, params->port,
4481                                                     ext_phy_addr,
4482                                                     params->shmem_base);
4483                        break;
4484                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4485                        DP(NETIF_MSG_LINK,
4486                                 "XGXS PHY Failure detected 0x%x\n",
4487                                 params->ext_phy_config);
4488                        rc = -EINVAL;
4489                        break;
4490                default:
4491                        DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
4492                                  params->ext_phy_config);
4493                        rc = -EINVAL;
4494                        break;
4495                }
4496
4497        } else { /* SerDes */
4498
4499                ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4500                switch (ext_phy_type) {
4501                case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
4502                        DP(NETIF_MSG_LINK, "SerDes Direct\n");
4503                        break;
4504
4505                case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
4506                        DP(NETIF_MSG_LINK, "SerDes 5482\n");
4507                        break;
4508
4509                default:
4510                        DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
4511                           params->ext_phy_config);
4512                        break;
4513                }
4514        }
4515        return rc;
4516}
4517
4518static void bnx2x_8727_handle_mod_abs(struct link_params *params)
4519{
4520        struct bnx2x *bp = params->bp;
4521        u16 mod_abs, rx_alarm_status;
4522        u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
4523        u32 val = REG_RD(bp, params->shmem_base +
4524                             offsetof(struct shmem_region, dev_info.
4525                                      port_feature_config[params->port].
4526                                      config));
4527        bnx2x_cl45_read(bp, params->port,
4528                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4529                      ext_phy_addr,
4530                      MDIO_PMA_DEVAD,
4531                      MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
4532        if (mod_abs & (1<<8)) {
4533
4534                /* Module is absent */
4535                DP(NETIF_MSG_LINK, "MOD_ABS indication "
4536                            "show module is absent\n");
4537
4538                /* 1. Set mod_abs to detect next module
4539                presence event
4540                   2. Set EDC off by setting OPTXLOS signal input to low
4541                        (bit 9).
4542                        When the EDC is off it locks onto a reference clock and
4543                        avoids becoming 'lost'.*/
4544                mod_abs &= ~((1<<8)|(1<<9));
4545                bnx2x_cl45_write(bp, params->port,
4546                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4547                               ext_phy_addr,
4548                               MDIO_PMA_DEVAD,
4549                               MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4550
4551                /* Clear RX alarm since it stays up as long as
4552                the mod_abs wasn't changed */
4553                bnx2x_cl45_read(bp, params->port,
4554                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4555                              ext_phy_addr,
4556                              MDIO_PMA_DEVAD,
4557                              MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4558
4559        } else {
4560                /* Module is present */
4561                DP(NETIF_MSG_LINK, "MOD_ABS indication "
4562                            "show module is present\n");
4563                /* First thing, disable transmitter,
4564                and if the module is ok, the
4565                module_detection will enable it*/
4566
4567                /* 1. Set mod_abs to detect next module
4568                absent event ( bit 8)
4569                   2. Restore the default polarity of the OPRXLOS signal and
4570                this signal will then correctly indicate the presence or
4571                absence of the Rx signal. (bit 9) */
4572                mod_abs |= ((1<<8)|(1<<9));
4573                bnx2x_cl45_write(bp, params->port,
4574                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4575                       ext_phy_addr,
4576                       MDIO_PMA_DEVAD,
4577                       MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4578
4579                /* Clear RX alarm since it stays up as long as
4580                the mod_abs wasn't changed. This is need to be done
4581                before calling the module detection, otherwise it will clear
4582                the link update alarm */
4583                bnx2x_cl45_read(bp, params->port,
4584                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4585                              ext_phy_addr,
4586                              MDIO_PMA_DEVAD,
4587                              MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4588
4589
4590                if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
4591                    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
4592                        bnx2x_sfp_set_transmitter(bp, params->port,
4593                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4594                                        ext_phy_addr, 0);
4595
4596                if (bnx2x_wait_for_sfp_module_initialized(params)
4597                    == 0)
4598                        bnx2x_sfp_module_detection(params);
4599                else
4600                        DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
4601        }
4602
4603        DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
4604                 rx_alarm_status);
4605        /* No need to check link status in case of
4606        module plugged in/out */
4607}
4608
4609
4610static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
4611                                 struct link_vars *vars,
4612                                 u8 is_mi_int)
4613{
4614        struct bnx2x *bp = params->bp;
4615        u32 ext_phy_type;
4616        u8 ext_phy_addr;
4617        u16 val1 = 0, val2;
4618        u16 rx_sd, pcs_status;
4619        u8 ext_phy_link_up = 0;
4620        u8 port = params->port;
4621
4622        if (vars->phy_flags & PHY_XGXS_FLAG) {
4623                ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
4624                ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4625                switch (ext_phy_type) {
4626                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4627                        DP(NETIF_MSG_LINK, "XGXS Direct\n");
4628                        ext_phy_link_up = 1;
4629                        break;
4630
4631                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4632                        DP(NETIF_MSG_LINK, "XGXS 8705\n");
4633                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
4634                                      ext_phy_addr,
4635                                      MDIO_WIS_DEVAD,
4636                                      MDIO_WIS_REG_LASI_STATUS, &val1);
4637                        DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4638
4639                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
4640                                      ext_phy_addr,
4641                                      MDIO_WIS_DEVAD,
4642                                      MDIO_WIS_REG_LASI_STATUS, &val1);
4643                        DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4644
4645                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
4646                                      ext_phy_addr,
4647                                      MDIO_PMA_DEVAD,
4648                                      MDIO_PMA_REG_RX_SD, &rx_sd);
4649
4650                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
4651                                      ext_phy_addr,
4652                                      1,
4653                                      0xc809, &val1);
4654                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
4655                                      ext_phy_addr,
4656                                      1,
4657                                      0xc809, &val1);
4658
4659                        DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
4660                        ext_phy_link_up = ((rx_sd & 0x1) && (val1 & (1<<9))
4661                                           && ((val1 & (1<<8)) == 0));
4662                        if (ext_phy_link_up)
4663                                vars->line_speed = SPEED_10000;
4664                        break;
4665
4666                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4667                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4668                        DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
4669                        /* Clear RX Alarm*/
4670                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
4671                                      ext_phy_addr,
4672                                      MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
4673                                      &val2);
4674                        /* clear LASI indication*/
4675                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
4676                                      ext_phy_addr,
4677                                      MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
4678                                      &val1);
4679                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
4680                                      ext_phy_addr,
4681                                      MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
4682                                      &val2);
4683                        DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
4684                                     "0x%x\n", val1, val2);
4685
4686                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
4687                                      ext_phy_addr,
4688                                      MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
4689                                      &rx_sd);
4690                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
4691                                      ext_phy_addr,
4692                                      MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
4693                                      &pcs_status);
4694                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
4695                                      ext_phy_addr,
4696                                      MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
4697                                      &val2);
4698                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
4699                                      ext_phy_addr,
4700                                      MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
4701                                      &val2);
4702
4703                        DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
4704                           "  pcs_status 0x%x 1Gbps link_status 0x%x\n",
4705                           rx_sd, pcs_status, val2);
4706                        /* link is up if both bit 0 of pmd_rx_sd and
4707                         * bit 0 of pcs_status are set, or if the autoneg bit
4708                           1 is set
4709                         */
4710                        ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
4711                                           (val2 & (1<<1)));
4712                        if (ext_phy_link_up) {
4713                                if (ext_phy_type ==
4714                                     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
4715                                        /* If transmitter is disabled,
4716                                        ignore false link up indication */
4717                                        bnx2x_cl45_read(bp, params->port,
4718                                                   ext_phy_type,
4719                                                   ext_phy_addr,
4720                                                   MDIO_PMA_DEVAD,
4721                                                   MDIO_PMA_REG_PHY_IDENTIFIER,
4722                                                   &val1);
4723                                        if (val1 & (1<<15)) {
4724                                                DP(NETIF_MSG_LINK, "Tx is "
4725                                                            "disabled\n");
4726                                                ext_phy_link_up = 0;
4727                                                break;
4728                                        }
4729                                }
4730                                if (val2 & (1<<1))
4731                                        vars->line_speed = SPEED_1000;
4732                                else
4733                                        vars->line_speed = SPEED_10000;
4734                        }
4735                        break;
4736
4737                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
4738                {
4739                        u16 link_status = 0;
4740                        u16 rx_alarm_status;
4741                        /* Check the LASI */
4742                        bnx2x_cl45_read(bp, params->port,
4743                                      ext_phy_type,
4744                                      ext_phy_addr,
4745                                      MDIO_PMA_DEVAD,
4746                                      MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4747
4748                        DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
4749                                 rx_alarm_status);
4750
4751                        bnx2x_cl45_read(bp, params->port,
4752                                      ext_phy_type,
4753                                      ext_phy_addr,
4754                                      MDIO_PMA_DEVAD,
4755                                      MDIO_PMA_REG_LASI_STATUS, &val1);
4756
4757                        DP(NETIF_MSG_LINK,
4758                                 "8727 LASI status 0x%x\n",
4759                                 val1);
4760
4761                        /* Clear MSG-OUT */
4762                        bnx2x_cl45_read(bp, params->port,
4763                                      ext_phy_type,
4764                                      ext_phy_addr,
4765                                      MDIO_PMA_DEVAD,
4766                                      MDIO_PMA_REG_M8051_MSGOUT_REG,
4767                                      &val1);
4768
4769                        /*
4770                         * If a module is present and there is need to check
4771                         * for over current
4772                         */
4773                        if (!(params->feature_config_flags &
4774                              FEATURE_CONFIG_BCM8727_NOC) &&
4775                            !(rx_alarm_status & (1<<5))) {
4776                                /* Check over-current using 8727 GPIO0 input*/
4777                                bnx2x_cl45_read(bp, params->port,
4778                                              ext_phy_type,
4779                                              ext_phy_addr,
4780                                              MDIO_PMA_DEVAD,
4781                                              MDIO_PMA_REG_8727_GPIO_CTRL,
4782                                              &val1);
4783
4784                                if ((val1 & (1<<8)) == 0) {
4785                                        DP(NETIF_MSG_LINK, "8727 Power fault"
4786                                                     " has been detected on "
4787                                                     "port %d\n",
4788                                                 params->port);
4789                                        printk(KERN_ERR PFX  "Error:  Power"
4790                                                 " fault on %s Port %d has"
4791                                                 " been detected and the"
4792                                                 " power to that SFP+ module"
4793                                                 " has been removed to prevent"
4794                                                 " failure of the card. Please"
4795                                                 " remove the SFP+ module and"
4796                                                 " restart the system to clear"
4797                                                 " this error.\n"
4798                        , bp->dev->name, params->port);
4799                                        /*
4800                                         * Disable all RX_ALARMs except for
4801                                         * mod_abs
4802                                         */
4803                                        bnx2x_cl45_write(bp, params->port,
4804                                                     ext_phy_type,
4805                                                     ext_phy_addr,
4806                                                     MDIO_PMA_DEVAD,
4807                                                     MDIO_PMA_REG_RX_ALARM_CTRL,
4808                                                     (1<<5));
4809
4810                                        bnx2x_cl45_read(bp, params->port,
4811                                                    ext_phy_type,
4812                                                    ext_phy_addr,
4813                                                    MDIO_PMA_DEVAD,
4814                                                    MDIO_PMA_REG_PHY_IDENTIFIER,
4815                                                    &val1);
4816                                        /* Wait for module_absent_event */
4817                                        val1 |= (1<<8);
4818                                        bnx2x_cl45_write(bp, params->port,
4819                                                    ext_phy_type,
4820                                                    ext_phy_addr,
4821                                                    MDIO_PMA_DEVAD,
4822                                                    MDIO_PMA_REG_PHY_IDENTIFIER,
4823                                                    val1);
4824                                        /* Clear RX alarm */
4825                                        bnx2x_cl45_read(bp, params->port,
4826                                                      ext_phy_type,
4827                                                      ext_phy_addr,
4828                                                      MDIO_PMA_DEVAD,
4829                                                      MDIO_PMA_REG_RX_ALARM,
4830                                                      &rx_alarm_status);
4831                                        break;
4832                                }
4833                        } /* Over current check */
4834
4835                        /* When module absent bit is set, check module */
4836                        if (rx_alarm_status & (1<<5)) {
4837                                bnx2x_8727_handle_mod_abs(params);
4838                                /* Enable all mod_abs and link detection bits */
4839                                bnx2x_cl45_write(bp, params->port,
4840                                               ext_phy_type,
4841                                               ext_phy_addr,
4842                                               MDIO_PMA_DEVAD,
4843                                               MDIO_PMA_REG_RX_ALARM_CTRL,
4844                                               ((1<<5) | (1<<2)));
4845                        }
4846
4847                        /* If transmitter is disabled,
4848                        ignore false link up indication */
4849                        bnx2x_cl45_read(bp, params->port,
4850                                      ext_phy_type,
4851                                      ext_phy_addr,
4852                                      MDIO_PMA_DEVAD,
4853                                      MDIO_PMA_REG_PHY_IDENTIFIER,
4854                                      &val1);
4855                        if (val1 & (1<<15)) {
4856                                DP(NETIF_MSG_LINK, "Tx is disabled\n");
4857                                ext_phy_link_up = 0;
4858                                break;
4859                        }
4860
4861                        bnx2x_cl45_read(bp, params->port,
4862                                      ext_phy_type,
4863                                      ext_phy_addr,
4864                                      MDIO_PMA_DEVAD,
4865                                      MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
4866                                      &link_status);
4867
4868                        /* Bits 0..2 --> speed detected,
4869                           bits 13..15--> link is down */
4870                        if ((link_status & (1<<2)) &&
4871                            (!(link_status & (1<<15)))) {
4872                                ext_phy_link_up = 1;
4873                                vars->line_speed = SPEED_10000;
4874                        } else if ((link_status & (1<<0)) &&
4875                                   (!(link_status & (1<<13)))) {
4876                                ext_phy_link_up = 1;
4877                                vars->line_speed = SPEED_1000;
4878                                DP(NETIF_MSG_LINK,
4879                                         "port %x: External link"
4880                                         " up in 1G\n", params->port);
4881                        } else {
4882                                ext_phy_link_up = 0;
4883                                DP(NETIF_MSG_LINK,
4884                                         "port %x: External link"
4885                                         " is down\n", params->port);
4886                        }
4887                        break;
4888                }
4889
4890                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4891                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4892                {
4893                        u16 link_status = 0;
4894                        u16 an1000_status = 0;
4895
4896                        if (ext_phy_type ==
4897                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
4898                                bnx2x_cl45_read(bp, params->port,
4899                                      ext_phy_type,
4900                                      ext_phy_addr,
4901                                      MDIO_PCS_DEVAD,
4902                                      MDIO_PCS_REG_LASI_STATUS, &val1);
4903                        bnx2x_cl45_read(bp, params->port,
4904                                      ext_phy_type,
4905                                      ext_phy_addr,
4906                                      MDIO_PCS_DEVAD,
4907                                      MDIO_PCS_REG_LASI_STATUS, &val2);
4908                        DP(NETIF_MSG_LINK,
4909                                 "870x LASI status 0x%x->0x%x\n",
4910                                  val1, val2);
4911                        } else {
4912                                /* In 8073, port1 is directed through emac0 and
4913                                 * port0 is directed through emac1
4914                                 */
4915                                bnx2x_cl45_read(bp, params->port,
4916                                              ext_phy_type,
4917                                              ext_phy_addr,
4918                                              MDIO_PMA_DEVAD,
4919                                              MDIO_PMA_REG_LASI_STATUS, &val1);
4920
4921                                DP(NETIF_MSG_LINK,
4922                                         "8703 LASI status 0x%x\n",
4923                                          val1);
4924                        }
4925
4926                        /* clear the interrupt LASI status register */
4927                        bnx2x_cl45_read(bp, params->port,
4928                                      ext_phy_type,
4929                                      ext_phy_addr,
4930                                      MDIO_PCS_DEVAD,
4931                                      MDIO_PCS_REG_STATUS, &val2);
4932                        bnx2x_cl45_read(bp, params->port,
4933                                      ext_phy_type,
4934                                      ext_phy_addr,
4935                                      MDIO_PCS_DEVAD,
4936                                      MDIO_PCS_REG_STATUS, &val1);
4937                        DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
4938                           val2, val1);
4939                        /* Clear MSG-OUT */
4940                        bnx2x_cl45_read(bp, params->port,
4941                                      ext_phy_type,
4942                                      ext_phy_addr,
4943                                      MDIO_PMA_DEVAD,
4944                                      MDIO_PMA_REG_M8051_MSGOUT_REG,
4945                                      &val1);
4946
4947                        /* Check the LASI */
4948                        bnx2x_cl45_read(bp, params->port,
4949                                      ext_phy_type,
4950                                      ext_phy_addr,
4951                                      MDIO_PMA_DEVAD,
4952                                      MDIO_PMA_REG_RX_ALARM, &val2);
4953
4954                        DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
4955
4956                        /* Check the link status */
4957                        bnx2x_cl45_read(bp, params->port,
4958                                      ext_phy_type,
4959                                      ext_phy_addr,
4960                                      MDIO_PCS_DEVAD,
4961                                      MDIO_PCS_REG_STATUS, &val2);
4962                        DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
4963
4964                        bnx2x_cl45_read(bp, params->port,
4965                                      ext_phy_type,
4966                                      ext_phy_addr,
4967                                      MDIO_PMA_DEVAD,
4968                                      MDIO_PMA_REG_STATUS, &val2);
4969                        bnx2x_cl45_read(bp, params->port,
4970                                      ext_phy_type,
4971                                      ext_phy_addr,
4972                                      MDIO_PMA_DEVAD,
4973                                      MDIO_PMA_REG_STATUS, &val1);
4974                        ext_phy_link_up = ((val1 & 4) == 4);
4975                        DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
4976                        if (ext_phy_type ==
4977                            PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4978
4979                                if (ext_phy_link_up &&
4980                                    ((params->req_line_speed !=
4981                                        SPEED_10000))) {
4982                                        if (bnx2x_bcm8073_xaui_wa(params)
4983                                             != 0) {
4984                                                ext_phy_link_up = 0;
4985                                                break;
4986                                        }
4987                                }
4988                                bnx2x_cl45_read(bp, params->port,
4989                                              ext_phy_type,
4990                                              ext_phy_addr,
4991                                              MDIO_AN_DEVAD,
4992                                              MDIO_AN_REG_LINK_STATUS,
4993                                              &an1000_status);
4994                                bnx2x_cl45_read(bp, params->port,
4995                                              ext_phy_type,
4996                                              ext_phy_addr,
4997                                              MDIO_AN_DEVAD,
4998                                              MDIO_AN_REG_LINK_STATUS,
4999                                              &an1000_status);
5000
5001                                /* Check the link status on 1.1.2 */
5002                                bnx2x_cl45_read(bp, params->port,
5003                                              ext_phy_type,
5004                                              ext_phy_addr,
5005                                              MDIO_PMA_DEVAD,
5006                                              MDIO_PMA_REG_STATUS, &val2);
5007                                bnx2x_cl45_read(bp, params->port,
5008                                              ext_phy_type,
5009                                              ext_phy_addr,
5010                                              MDIO_PMA_DEVAD,
5011                                              MDIO_PMA_REG_STATUS, &val1);
5012                                DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
5013                                             "an_link_status=0x%x\n",
5014                                          val2, val1, an1000_status);
5015
5016                                ext_phy_link_up = (((val1 & 4) == 4) ||
5017                                                (an1000_status & (1<<1)));
5018                                if (ext_phy_link_up &&
5019                                    bnx2x_8073_is_snr_needed(params)) {
5020                                        /* The SNR will improve about 2dbby
5021                                        changing the BW and FEE main tap.*/
5022
5023                                        /* The 1st write to change FFE main
5024                                        tap is set before restart AN */
5025                                        /* Change PLL Bandwidth in EDC
5026                                        register */
5027                                        bnx2x_cl45_write(bp, port, ext_phy_type,
5028                                                    ext_phy_addr,
5029                                                    MDIO_PMA_DEVAD,
5030                                                    MDIO_PMA_REG_PLL_BANDWIDTH,
5031                                                    0x26BC);
5032
5033                                        /* Change CDR Bandwidth in EDC
5034                                        register */
5035                                        bnx2x_cl45_write(bp, port, ext_phy_type,
5036                                                    ext_phy_addr,
5037                                                    MDIO_PMA_DEVAD,
5038                                                    MDIO_PMA_REG_CDR_BANDWIDTH,
5039                                                    0x0333);
5040                                }
5041                                bnx2x_cl45_read(bp, params->port,
5042                                           ext_phy_type,
5043                                           ext_phy_addr,
5044                                           MDIO_PMA_DEVAD,
5045                                           MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
5046                                           &link_status);
5047
5048                                /* Bits 0..2 --> speed detected,
5049                                   bits 13..15--> link is down */
5050                                if ((link_status & (1<<2)) &&
5051                                    (!(link_status & (1<<15)))) {
5052                                        ext_phy_link_up = 1;
5053                                        vars->line_speed = SPEED_10000;
5054                                        DP(NETIF_MSG_LINK,
5055                                                 "port %x: External link"
5056                                                 " up in 10G\n", params->port);
5057                                } else if ((link_status & (1<<1)) &&
5058                                           (!(link_status & (1<<14)))) {
5059                                        ext_phy_link_up = 1;
5060                                        vars->line_speed = SPEED_2500;
5061                                        DP(NETIF_MSG_LINK,
5062                                                 "port %x: External link"
5063                                                 " up in 2.5G\n", params->port);
5064                                } else if ((link_status & (1<<0)) &&
5065                                           (!(link_status & (1<<13)))) {
5066                                        ext_phy_link_up = 1;
5067                                        vars->line_speed = SPEED_1000;
5068                                        DP(NETIF_MSG_LINK,
5069                                                 "port %x: External link"
5070                                                 " up in 1G\n", params->port);
5071                                } else {
5072                                        ext_phy_link_up = 0;
5073                                        DP(NETIF_MSG_LINK,
5074                                                 "port %x: External link"
5075                                                 " is down\n", params->port);
5076                                }
5077                        } else {
5078                                /* See if 1G link is up for the 8072 */
5079                                bnx2x_cl45_read(bp, params->port,
5080                                              ext_phy_type,
5081                                              ext_phy_addr,
5082                                              MDIO_AN_DEVAD,
5083                                              MDIO_AN_REG_LINK_STATUS,
5084                                              &an1000_status);
5085                                bnx2x_cl45_read(bp, params->port,
5086                                              ext_phy_type,
5087                                              ext_phy_addr,
5088                                              MDIO_AN_DEVAD,
5089                                              MDIO_AN_REG_LINK_STATUS,
5090                                              &an1000_status);
5091                                if (an1000_status & (1<<1)) {
5092                                        ext_phy_link_up = 1;
5093                                        vars->line_speed = SPEED_1000;
5094                                        DP(NETIF_MSG_LINK,
5095                                                 "port %x: External link"
5096                                                 " up in 1G\n", params->port);
5097                                } else if (ext_phy_link_up) {
5098                                        ext_phy_link_up = 1;
5099                                        vars->line_speed = SPEED_10000;
5100                                        DP(NETIF_MSG_LINK,
5101                                                 "port %x: External link"
5102                                                 " up in 10G\n", params->port);
5103                                }
5104                        }
5105
5106
5107                        break;
5108                }
5109                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5110                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
5111                                      ext_phy_addr,
5112                                      MDIO_PMA_DEVAD,
5113                                      MDIO_PMA_REG_LASI_STATUS, &val2);
5114                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
5115                                      ext_phy_addr,
5116                                      MDIO_PMA_DEVAD,
5117                                      MDIO_PMA_REG_LASI_STATUS, &val1);
5118                        DP(NETIF_MSG_LINK,
5119                                 "10G-base-T LASI status 0x%x->0x%x\n",
5120                                  val2, val1);
5121                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
5122                                      ext_phy_addr,
5123                                      MDIO_PMA_DEVAD,
5124                                      MDIO_PMA_REG_STATUS, &val2);
5125                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
5126                                      ext_phy_addr,
5127                                      MDIO_PMA_DEVAD,
5128                                      MDIO_PMA_REG_STATUS, &val1);
5129                        DP(NETIF_MSG_LINK,
5130                                 "10G-base-T PMA status 0x%x->0x%x\n",
5131                                 val2, val1);
5132                        ext_phy_link_up = ((val1 & 4) == 4);
5133                        /* if link is up
5134                         * print the AN outcome of the SFX7101 PHY
5135                         */
5136                        if (ext_phy_link_up) {
5137                                bnx2x_cl45_read(bp, params->port,
5138                                              ext_phy_type,
5139                                              ext_phy_addr,
5140                                              MDIO_AN_DEVAD,
5141                                              MDIO_AN_REG_MASTER_STATUS,
5142                                              &val2);
5143                                vars->line_speed = SPEED_10000;
5144                                DP(NETIF_MSG_LINK,
5145                                         "SFX7101 AN status 0x%x->Master=%x\n",
5146                                          val2,
5147                                         (val2 & (1<<14)));
5148                        }
5149                        break;
5150                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
5151                        /* Check 10G-BaseT link status */
5152                        /* Check PMD signal ok */
5153                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
5154                                                      ext_phy_addr,
5155                                                      MDIO_AN_DEVAD,
5156                                                      0xFFFA,
5157                                                      &val1);
5158                        bnx2x_cl45_read(bp, params->port, ext_phy_type,
5159                                      ext_phy_addr,
5160                                      MDIO_PMA_DEVAD,
5161                                      MDIO_PMA_REG_8481_PMD_SIGNAL,
5162                                      &val2);
5163                        DP(NETIF_MSG_LINK, "PMD_SIGNAL 1.a811 = 0x%x\n", val2);
5164
5165                        /* Check link 10G */
5166                        if (val2 & (1<<11)) {
5167                                vars->line_speed = SPEED_10000;
5168                                ext_phy_link_up = 1;
5169                                bnx2x_8481_set_10G_led_mode(params,
5170                                                          ext_phy_type,
5171                                                          ext_phy_addr);
5172                        } else { /* Check Legacy speed link */
5173                                u16 legacy_status, legacy_speed;
5174
5175                                /* Enable expansion register 0x42
5176                                (Operation mode status) */
5177                                bnx2x_cl45_write(bp, params->port,
5178                                         ext_phy_type,
5179                                         ext_phy_addr,
5180                                         MDIO_AN_DEVAD,
5181                                         MDIO_AN_REG_8481_EXPANSION_REG_ACCESS,
5182                                         0xf42);
5183
5184                                /* Get legacy speed operation status */
5185                                bnx2x_cl45_read(bp, params->port,
5186                                          ext_phy_type,
5187                                          ext_phy_addr,
5188                                          MDIO_AN_DEVAD,
5189                                          MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
5190                                          &legacy_status);
5191
5192                                DP(NETIF_MSG_LINK, "Legacy speed status"
5193                                             " = 0x%x\n", legacy_status);
5194                                ext_phy_link_up = ((legacy_status & (1<<11))
5195                                                   == (1<<11));
5196                                if (ext_phy_link_up) {
5197                                        legacy_speed = (legacy_status & (3<<9));
5198                                        if (legacy_speed == (0<<9))
5199                                                vars->line_speed = SPEED_10;
5200                                        else if (legacy_speed == (1<<9))
5201                                                vars->line_speed =
5202                                                        SPEED_100;
5203                                        else if (legacy_speed == (2<<9))
5204                                                vars->line_speed =
5205                                                        SPEED_1000;
5206                                        else /* Should not happen */
5207                                                vars->line_speed = 0;
5208
5209                                        if (legacy_status & (1<<8))
5210                                                vars->duplex = DUPLEX_FULL;
5211                                        else
5212                                                vars->duplex = DUPLEX_HALF;
5213
5214                                        DP(NETIF_MSG_LINK, "Link is up "
5215                                                     "in %dMbps, is_duplex_full"
5216                                                     "= %d\n",
5217                                                vars->line_speed,
5218                                                (vars->duplex == DUPLEX_FULL));
5219                                        bnx2x_8481_set_legacy_led_mode(params,
5220                                                                 ext_phy_type,
5221                                                                 ext_phy_addr);
5222                                }
5223                        }
5224                        break;
5225                default:
5226                        DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
5227                           params->ext_phy_config);
5228                        ext_phy_link_up = 0;
5229                        break;
5230                }
5231                /* Set SGMII mode for external phy */
5232                if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
5233                        if (vars->line_speed < SPEED_1000)
5234                                vars->phy_flags |= PHY_SGMII_FLAG;
5235                        else
5236                                vars->phy_flags &= ~PHY_SGMII_FLAG;
5237                }
5238
5239        } else { /* SerDes */
5240                ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
5241                switch (ext_phy_type) {
5242                case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
5243                        DP(NETIF_MSG_LINK, "SerDes Direct\n");
5244                        ext_phy_link_up = 1;
5245                        break;
5246
5247                case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
5248                        DP(NETIF_MSG_LINK, "SerDes 5482\n");
5249                        ext_phy_link_up = 1;
5250                        break;
5251
5252                default:
5253                        DP(NETIF_MSG_LINK,
5254                                 "BAD SerDes ext_phy_config 0x%x\n",
5255                                 params->ext_phy_config);
5256                        ext_phy_link_up = 0;
5257                        break;
5258                }
5259        }
5260
5261        return ext_phy_link_up;
5262}
5263
5264static void bnx2x_link_int_enable(struct link_params *params)
5265{
5266        u8 port = params->port;
5267        u32 ext_phy_type;
5268        u32 mask;
5269        struct bnx2x *bp = params->bp;
5270
5271        /* setting the status to report on link up
5272           for either XGXS or SerDes */
5273
5274        if (params->switch_cfg == SWITCH_CFG_10G) {
5275                mask = (NIG_MASK_XGXS0_LINK10G |
5276                        NIG_MASK_XGXS0_LINK_STATUS);
5277                DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
5278                ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5279                if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
5280                    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
5281                    (ext_phy_type !=
5282                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
5283                        mask |= NIG_MASK_MI_INT;
5284                        DP(NETIF_MSG_LINK, "enabled external phy int\n");
5285                }
5286
5287        } else { /* SerDes */
5288                mask = NIG_MASK_SERDES0_LINK_STATUS;
5289                DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
5290                ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
5291                if ((ext_phy_type !=
5292                                PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
5293                    (ext_phy_type !=
5294                                PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
5295                        mask |= NIG_MASK_MI_INT;
5296                        DP(NETIF_MSG_LINK, "enabled external phy int\n");
5297                }
5298        }
5299        bnx2x_bits_en(bp,
5300                      NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5301                      mask);
5302
5303        DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
5304                 (params->switch_cfg == SWITCH_CFG_10G),
5305                 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5306        DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
5307                 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5308                 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5309                 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
5310        DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5311           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5312           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5313}
5314
5315static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port,
5316                                        u8 is_mi_int)
5317{
5318        u32 latch_status = 0, is_mi_int_status;
5319        /* Disable the MI INT ( external phy int )
5320         * by writing 1 to the status register. Link down indication
5321         * is high-active-signal, so in this case we need to write the
5322         * status to clear the XOR
5323         */
5324        /* Read Latched signals */
5325        latch_status = REG_RD(bp,
5326                                  NIG_REG_LATCH_STATUS_0 + port*8);
5327        is_mi_int_status = REG_RD(bp,
5328                                  NIG_REG_STATUS_INTERRUPT_PORT0 + port*4);
5329        DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x,"
5330                     "latch_status = 0x%x\n",
5331                 is_mi_int, is_mi_int_status, latch_status);
5332        /* Handle only those with latched-signal=up.*/
5333        if (latch_status & 1) {
5334                /* For all latched-signal=up,Write original_signal to status */
5335                if (is_mi_int)
5336                        bnx2x_bits_en(bp,
5337                                    NIG_REG_STATUS_INTERRUPT_PORT0
5338                                    + port*4,
5339                                    NIG_STATUS_EMAC0_MI_INT);
5340                else
5341                        bnx2x_bits_dis(bp,
5342                                     NIG_REG_STATUS_INTERRUPT_PORT0
5343                                     + port*4,
5344                                     NIG_STATUS_EMAC0_MI_INT);
5345                /* For all latched-signal=up : Re-Arm Latch signals */
5346                REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
5347                           (latch_status & 0xfffe) | (latch_status & 1));
5348        }
5349}
5350/*
5351 * link management
5352 */
5353static void bnx2x_link_int_ack(struct link_params *params,
5354                             struct link_vars *vars, u8 is_10g,
5355                             u8 is_mi_int)
5356{
5357        struct bnx2x *bp = params->bp;
5358        u8 port = params->port;
5359
5360        /* first reset all status
5361         * we assume only one line will be change at a time */
5362        bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5363                     (NIG_STATUS_XGXS0_LINK10G |
5364                      NIG_STATUS_XGXS0_LINK_STATUS |
5365                      NIG_STATUS_SERDES0_LINK_STATUS));
5366        if (XGXS_EXT_PHY_TYPE(params->ext_phy_config)
5367            == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) {
5368                bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int);
5369        }
5370        if (vars->phy_link_up) {
5371                if (is_10g) {
5372                        /* Disable the 10G link interrupt
5373                         * by writing 1 to the status register
5374                         */
5375                        DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
5376                        bnx2x_bits_en(bp,
5377                                      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5378                                      NIG_STATUS_XGXS0_LINK10G);
5379
5380                } else if (params->switch_cfg == SWITCH_CFG_10G) {
5381                        /* Disable the link interrupt
5382                         * by writing 1 to the relevant lane
5383                         * in the status register
5384                         */
5385                        u32 ser_lane = ((params->lane_config &
5386                                    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
5387                                    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
5388
5389                        DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
5390                                 vars->line_speed);
5391                        bnx2x_bits_en(bp,
5392                                      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5393                                      ((1 << ser_lane) <<
5394                                       NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
5395
5396                } else { /* SerDes */
5397                        DP(NETIF_MSG_LINK, "SerDes phy link up\n");
5398                        /* Disable the link interrupt
5399                         * by writing 1 to the status register
5400                         */
5401                        bnx2x_bits_en(bp,
5402                                      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5403                                      NIG_STATUS_SERDES0_LINK_STATUS);
5404                }
5405
5406        } else { /* link_down */
5407        }
5408}
5409
5410static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
5411{
5412        u8 *str_ptr = str;
5413        u32 mask = 0xf0000000;
5414        u8 shift = 8*4;
5415        u8 digit;
5416        if (len < 10) {
5417                /* Need more than 10chars for this format */
5418                *str_ptr = '\0';
5419                return -EINVAL;
5420        }
5421        while (shift > 0) {
5422
5423                shift -= 4;
5424                digit = ((num & mask) >> shift);
5425                if (digit < 0xa)
5426                        *str_ptr = digit + '0';
5427                else
5428                        *str_ptr = digit - 0xa + 'a';
5429                str_ptr++;
5430                mask = mask >> 4;
5431                if (shift == 4*4) {
5432                        *str_ptr = ':';
5433                        str_ptr++;
5434                }
5435        }
5436        *str_ptr = '\0';
5437        return 0;
5438}
5439
5440u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
5441                              u8 *version, u16 len)
5442{
5443        struct bnx2x *bp;
5444        u32 ext_phy_type = 0;
5445        u32 spirom_ver = 0;
5446        u8 status;
5447
5448        if (version == NULL || params == NULL)
5449                return -EINVAL;
5450        bp = params->bp;
5451
5452        spirom_ver = REG_RD(bp, params->shmem_base +
5453                   offsetof(struct shmem_region,
5454                            port_mb[params->port].ext_phy_fw_version));
5455
5456        status = 0;
5457        /* reset the returned value to zero */
5458        ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5459        switch (ext_phy_type) {
5460        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5461
5462                if (len < 5)
5463                        return -EINVAL;
5464
5465                version[0] = (spirom_ver & 0xFF);
5466                version[1] = (spirom_ver & 0xFF00) >> 8;
5467                version[2] = (spirom_ver & 0xFF0000) >> 16;
5468                version[3] = (spirom_ver & 0xFF000000) >> 24;
5469                version[4] = '\0';
5470
5471                break;
5472        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5473        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5474        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
5475        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5476        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5477                status = bnx2x_format_ver(spirom_ver, version, len);
5478                break;
5479        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
5480                spirom_ver = ((spirom_ver & 0xF80) >> 7) << 16 |
5481                        (spirom_ver & 0x7F);
5482                status = bnx2x_format_ver(spirom_ver, version, len);
5483                break;
5484        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5485        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5486                version[0] = '\0';
5487                break;
5488
5489        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
5490                DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
5491                                    " type is FAILURE!\n");
5492                status = -EINVAL;
5493                break;
5494
5495        default:
5496                break;
5497        }
5498        return status;
5499}
5500
5501static void bnx2x_set_xgxs_loopback(struct link_params *params,
5502                                  struct link_vars *vars,
5503                                  u8 is_10g)
5504{
5505        u8 port = params->port;
5506        struct bnx2x *bp = params->bp;
5507
5508        if (is_10g) {
5509                u32 md_devad;
5510
5511                DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
5512
5513                /* change the uni_phy_addr in the nig */
5514                md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
5515                                          port*0x18));
5516
5517                REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
5518
5519                bnx2x_cl45_write(bp, port, 0,
5520                               params->phy_addr,
5521                               5,
5522                               (MDIO_REG_BANK_AER_BLOCK +
5523                                (MDIO_AER_BLOCK_AER_REG & 0xf)),
5524                               0x2800);
5525
5526                bnx2x_cl45_write(bp, port, 0,
5527                               params->phy_addr,
5528                               5,
5529                               (MDIO_REG_BANK_CL73_IEEEB0 +
5530                                (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
5531                               0x6041);
5532                msleep(200);
5533                /* set aer mmd back */
5534                bnx2x_set_aer_mmd(params, vars);
5535
5536                /* and md_devad */
5537                REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
5538                            md_devad);
5539
5540        } else {
5541                u16 mii_control;
5542
5543                DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
5544
5545                CL45_RD_OVER_CL22(bp, port,
5546                                      params->phy_addr,
5547                                      MDIO_REG_BANK_COMBO_IEEE0,
5548                                      MDIO_COMBO_IEEE0_MII_CONTROL,
5549                                      &mii_control);
5550
5551                CL45_WR_OVER_CL22(bp, port,
5552                                      params->phy_addr,
5553                                      MDIO_REG_BANK_COMBO_IEEE0,
5554                                      MDIO_COMBO_IEEE0_MII_CONTROL,
5555                                      (mii_control |
5556                                       MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
5557        }
5558}
5559
5560
5561static void bnx2x_ext_phy_loopback(struct link_params *params)
5562{
5563        struct bnx2x *bp = params->bp;
5564        u8 ext_phy_addr;
5565        u32 ext_phy_type;
5566
5567        if (params->switch_cfg == SWITCH_CFG_10G) {
5568                ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5569                ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
5570                /* CL37 Autoneg Enabled */
5571                switch (ext_phy_type) {
5572                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5573                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
5574                        DP(NETIF_MSG_LINK,
5575                                "ext_phy_loopback: We should not get here\n");
5576                        break;
5577                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5578                        DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
5579                        break;
5580                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5581                        DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
5582                        break;
5583                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5584                        DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
5585                        bnx2x_cl45_write(bp, params->port, ext_phy_type,
5586                                       ext_phy_addr,
5587                                       MDIO_PMA_DEVAD,
5588                                       MDIO_PMA_REG_CTRL,
5589                                       0x0001);
5590                        break;
5591                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5592                        /* SFX7101_XGXS_TEST1 */
5593                        bnx2x_cl45_write(bp, params->port, ext_phy_type,
5594                                       ext_phy_addr,
5595                                       MDIO_XS_DEVAD,
5596                                       MDIO_XS_SFX7101_XGXS_TEST1,
5597                                       0x100);
5598                        DP(NETIF_MSG_LINK,
5599                                "ext_phy_loopback: set ext phy loopback\n");
5600                        break;
5601                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5602
5603                        break;
5604                } /* switch external PHY type */
5605        } else {
5606                /* serdes */
5607                ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
5608                ext_phy_addr = (params->ext_phy_config  &
5609                PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
5610                >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
5611        }
5612}
5613
5614
5615/*
5616 *------------------------------------------------------------------------
5617 * bnx2x_override_led_value -
5618 *
5619 * Override the led value of the requsted led
5620 *
5621 *------------------------------------------------------------------------
5622 */
5623u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
5624                          u32 led_idx, u32 value)
5625{
5626        u32 reg_val;
5627
5628        /* If port 0 then use EMAC0, else use EMAC1*/
5629        u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5630
5631        DP(NETIF_MSG_LINK,
5632                 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
5633                 port, led_idx, value);
5634
5635        switch (led_idx) {
5636        case 0: /* 10MB led */
5637                /* Read the current value of the LED register in
5638                the EMAC block */
5639                reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5640                /* Set the OVERRIDE bit to 1 */
5641                reg_val |= EMAC_LED_OVERRIDE;
5642                /* If value is 1, set the 10M_OVERRIDE bit,
5643                otherwise reset it.*/
5644                reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
5645                        (reg_val & ~EMAC_LED_10MB_OVERRIDE);
5646                REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5647                break;
5648        case 1: /*100MB led    */
5649                /*Read the current value of the LED register in
5650                the EMAC block */
5651                reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5652                /*  Set the OVERRIDE bit to 1 */
5653                reg_val |= EMAC_LED_OVERRIDE;
5654                /*  If value is 1, set the 100M_OVERRIDE bit,
5655                otherwise reset it.*/
5656                reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
5657                        (reg_val & ~EMAC_LED_100MB_OVERRIDE);
5658                REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5659                break;
5660        case 2: /* 1000MB led */
5661                /* Read the current value of the LED register in the
5662                EMAC block */
5663                reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5664                /* Set the OVERRIDE bit to 1 */
5665                reg_val |= EMAC_LED_OVERRIDE;
5666                /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
5667                reset it. */
5668                reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
5669                        (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
5670                REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5671                break;
5672        case 3: /* 2500MB led */
5673                /*  Read the current value of the LED register in the
5674                EMAC block*/
5675                reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5676                /* Set the OVERRIDE bit to 1 */
5677                reg_val |= EMAC_LED_OVERRIDE;
5678                /*  If value is 1, set the 2500M_OVERRIDE bit, otherwise
5679                reset it.*/
5680                reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
5681                        (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
5682                REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5683                break;
5684        case 4: /*10G led */
5685                if (port == 0) {
5686                        REG_WR(bp, NIG_REG_LED_10G_P0,
5687                                    value);
5688                } else {
5689                        REG_WR(bp, NIG_REG_LED_10G_P1,
5690                                    value);
5691                }
5692                break;
5693        case 5: /* TRAFFIC led */
5694                /* Find if the traffic control is via BMAC or EMAC */
5695                if (port == 0)
5696                        reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
5697                else
5698                        reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
5699
5700                /*  Override the traffic led in the EMAC:*/
5701                if (reg_val == 1) {
5702                        /* Read the current value of the LED register in
5703                        the EMAC block */
5704                        reg_val = REG_RD(bp, emac_base +
5705                                             EMAC_REG_EMAC_LED);
5706                        /* Set the TRAFFIC_OVERRIDE bit to 1 */
5707                        reg_val |= EMAC_LED_OVERRIDE;
5708                        /* If value is 1, set the TRAFFIC bit, otherwise
5709                        reset it.*/
5710                        reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
5711                                (reg_val & ~EMAC_LED_TRAFFIC);
5712                        REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5713                } else { /* Override the traffic led in the BMAC: */
5714                        REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5715                                   + port*4, 1);
5716                        REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
5717                                    value);
5718                }
5719                break;
5720        default:
5721                DP(NETIF_MSG_LINK,
5722                         "bnx2x_override_led_value() unknown led index %d "
5723                         "(should be 0-5)\n", led_idx);
5724                return -EINVAL;
5725        }
5726
5727        return 0;
5728}
5729
5730
5731u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
5732               u16 hw_led_mode, u32 chip_id)
5733{
5734        u8 rc = 0;
5735        u32 tmp;
5736        u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5737
5738        DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
5739        DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
5740                 speed, hw_led_mode);
5741        switch (mode) {
5742        case LED_MODE_OFF:
5743                REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
5744                REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
5745                           SHARED_HW_CFG_LED_MAC1);
5746
5747                tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5748                EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
5749                break;
5750
5751        case LED_MODE_OPER:
5752                REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
5753                REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
5754                           port*4, 0);
5755                /* Set blinking rate to ~15.9Hz */
5756                REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
5757                           LED_BLINK_RATE_VAL);
5758                REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
5759                           port*4, 1);
5760                tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5761                EMAC_WR(bp, EMAC_REG_EMAC_LED,
5762                            (tmp & (~EMAC_LED_OVERRIDE)));
5763
5764                if (!CHIP_IS_E1H(bp) &&
5765                    ((speed == SPEED_2500) ||
5766                     (speed == SPEED_1000) ||
5767                     (speed == SPEED_100) ||
5768                     (speed == SPEED_10))) {
5769                        /* On Everest 1 Ax chip versions for speeds less than
5770                        10G LED scheme is different */
5771                        REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5772                                   + port*4, 1);
5773                        REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
5774                                   port*4, 0);
5775                        REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
5776                                   port*4, 1);
5777                }
5778                break;
5779
5780        default:
5781                rc = -EINVAL;
5782                DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
5783                         mode);
5784                break;
5785        }
5786        return rc;
5787
5788}
5789
5790u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
5791{
5792        struct bnx2x *bp = params->bp;
5793        u16 gp_status = 0;
5794
5795        CL45_RD_OVER_CL22(bp, params->port,
5796                              params->phy_addr,
5797                              MDIO_REG_BANK_GP_STATUS,
5798                              MDIO_GP_STATUS_TOP_AN_STATUS1,
5799                              &gp_status);
5800        /* link is up only if both local phy and external phy are up */
5801        if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
5802            bnx2x_ext_phy_is_link_up(params, vars, 1))
5803                return 0;
5804
5805        return -ESRCH;
5806}
5807
5808static u8 bnx2x_link_initialize(struct link_params *params,
5809                              struct link_vars *vars)
5810{
5811        struct bnx2x *bp = params->bp;
5812        u8 port = params->port;
5813        u8 rc = 0;
5814        u8 non_ext_phy;
5815        u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5816
5817        /* Activate the external PHY */
5818        bnx2x_ext_phy_reset(params, vars);
5819
5820        bnx2x_set_aer_mmd(params, vars);
5821
5822        if (vars->phy_flags & PHY_XGXS_FLAG)
5823                bnx2x_set_master_ln(params);
5824
5825        rc = bnx2x_reset_unicore(params);
5826        /* reset the SerDes and wait for reset bit return low */
5827        if (rc != 0)
5828                return rc;
5829
5830        bnx2x_set_aer_mmd(params, vars);
5831
5832        /* setting the masterLn_def again after the reset */
5833        if (vars->phy_flags & PHY_XGXS_FLAG) {
5834                bnx2x_set_master_ln(params);
5835                bnx2x_set_swap_lanes(params);
5836        }
5837
5838        if (vars->phy_flags & PHY_XGXS_FLAG) {
5839                if ((params->req_line_speed &&
5840                    ((params->req_line_speed == SPEED_100) ||
5841                     (params->req_line_speed == SPEED_10))) ||
5842                    (!params->req_line_speed &&
5843                     (params->speed_cap_mask >=
5844                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
5845                     (params->speed_cap_mask <
5846                       PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
5847                     ))  {
5848                        vars->phy_flags |= PHY_SGMII_FLAG;
5849                } else {
5850                        vars->phy_flags &= ~PHY_SGMII_FLAG;
5851                }
5852        }
5853        /* In case of external phy existance, the line speed would be the
5854         line speed linked up by the external phy. In case it is direct only,
5855          then the line_speed during initialization will be equal to the
5856           req_line_speed*/
5857        vars->line_speed = params->req_line_speed;
5858
5859        bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
5860
5861        /* init ext phy and enable link state int */
5862        non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
5863                       (params->loopback_mode == LOOPBACK_XGXS_10));
5864
5865        if (non_ext_phy ||
5866            (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
5867            (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
5868            (params->loopback_mode == LOOPBACK_EXT_PHY)) {
5869                if (params->req_line_speed == SPEED_AUTO_NEG)
5870                        bnx2x_set_parallel_detection(params, vars->phy_flags);
5871                bnx2x_init_internal_phy(params, vars, non_ext_phy);
5872        }
5873
5874        if (!non_ext_phy)
5875                rc |= bnx2x_ext_phy_init(params, vars);
5876
5877        bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5878                     (NIG_STATUS_XGXS0_LINK10G |
5879                      NIG_STATUS_XGXS0_LINK_STATUS |
5880                      NIG_STATUS_SERDES0_LINK_STATUS));
5881
5882        return rc;
5883
5884}
5885
5886
5887u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
5888{
5889        struct bnx2x *bp = params->bp;
5890        u32 val;
5891
5892        DP(NETIF_MSG_LINK, "Phy Initialization started\n");
5893        DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n",
5894                 params->req_line_speed, params->req_flow_ctrl);
5895        vars->link_status = 0;
5896        vars->phy_link_up = 0;
5897        vars->link_up = 0;
5898        vars->line_speed = 0;
5899        vars->duplex = DUPLEX_FULL;
5900        vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5901        vars->mac_type = MAC_TYPE_NONE;
5902
5903        if (params->switch_cfg ==  SWITCH_CFG_1G)
5904                vars->phy_flags = PHY_SERDES_FLAG;
5905        else
5906                vars->phy_flags = PHY_XGXS_FLAG;
5907
5908        /* disable attentions */
5909        bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
5910                       (NIG_MASK_XGXS0_LINK_STATUS |
5911                        NIG_MASK_XGXS0_LINK10G |
5912                        NIG_MASK_SERDES0_LINK_STATUS |
5913                        NIG_MASK_MI_INT));
5914
5915        bnx2x_emac_init(params, vars);
5916
5917        if (CHIP_REV_IS_FPGA(bp)) {
5918
5919                vars->link_up = 1;
5920                vars->line_speed = SPEED_10000;
5921                vars->duplex = DUPLEX_FULL;
5922                vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5923                vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
5924                /* enable on E1.5 FPGA */
5925                if (CHIP_IS_E1H(bp)) {
5926                        vars->flow_ctrl |=
5927                                        (BNX2X_FLOW_CTRL_TX |
5928                                         BNX2X_FLOW_CTRL_RX);
5929                        vars->link_status |=
5930                                        (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
5931                                         LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
5932                }
5933
5934                bnx2x_emac_enable(params, vars, 0);
5935                bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
5936                /* disable drain */
5937                REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
5938
5939                /* update shared memory */
5940                bnx2x_update_mng(params, vars->link_status);
5941
5942                return 0;
5943
5944        } else
5945        if (CHIP_REV_IS_EMUL(bp)) {
5946
5947                vars->link_up = 1;
5948                vars->line_speed = SPEED_10000;
5949                vars->duplex = DUPLEX_FULL;
5950                vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5951                vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
5952
5953                bnx2x_bmac_enable(params, vars, 0);
5954
5955                bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
5956                /* Disable drain */
5957                REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
5958                                    + params->port*4, 0);
5959
5960                /* update shared memory */
5961                bnx2x_update_mng(params, vars->link_status);
5962
5963                return 0;
5964
5965        } else
5966        if (params->loopback_mode == LOOPBACK_BMAC) {
5967
5968                vars->link_up = 1;
5969                vars->line_speed = SPEED_10000;
5970                vars->duplex = DUPLEX_FULL;
5971                vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5972                vars->mac_type = MAC_TYPE_BMAC;
5973
5974                vars->phy_flags = PHY_XGXS_FLAG;
5975
5976                bnx2x_phy_deassert(params, vars->phy_flags);
5977                /* set bmac loopback */
5978                bnx2x_bmac_enable(params, vars, 1);
5979
5980                REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
5981                    params->port*4, 0);
5982
5983        } else if (params->loopback_mode == LOOPBACK_EMAC) {
5984
5985                vars->link_up = 1;
5986                vars->line_speed = SPEED_1000;
5987                vars->duplex = DUPLEX_FULL;
5988                vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5989                vars->mac_type = MAC_TYPE_EMAC;
5990
5991                vars->phy_flags = PHY_XGXS_FLAG;
5992
5993                bnx2x_phy_deassert(params, vars->phy_flags);
5994                /* set bmac loopback */
5995                bnx2x_emac_enable(params, vars, 1);
5996                bnx2x_emac_program(params, vars->line_speed,
5997                                              vars->duplex);
5998                REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
5999                    params->port*4, 0);
6000
6001        } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
6002                   (params->loopback_mode == LOOPBACK_EXT_PHY)) {
6003
6004                vars->link_up = 1;
6005                vars->line_speed = SPEED_10000;
6006                vars->duplex = DUPLEX_FULL;
6007                vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6008
6009                vars->phy_flags = PHY_XGXS_FLAG;
6010
6011                val = REG_RD(bp,
6012                                 NIG_REG_XGXS0_CTRL_PHY_ADDR+
6013                                 params->port*0x18);
6014                params->phy_addr = (u8)val;
6015
6016                bnx2x_phy_deassert(params, vars->phy_flags);
6017                bnx2x_link_initialize(params, vars);
6018
6019                vars->mac_type = MAC_TYPE_BMAC;
6020
6021                bnx2x_bmac_enable(params, vars, 0);
6022
6023                if (params->loopback_mode == LOOPBACK_XGXS_10) {
6024                        /* set 10G XGXS loopback */
6025                        bnx2x_set_xgxs_loopback(params, vars, 1);
6026                } else {
6027                        /* set external phy loopback */
6028                        bnx2x_ext_phy_loopback(params);
6029                }
6030                REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6031                            params->port*4, 0);
6032
6033                bnx2x_set_led(bp, params->port, LED_MODE_OPER,
6034                            vars->line_speed, params->hw_led_mode,
6035                            params->chip_id);
6036
6037        } else
6038        /* No loopback */
6039        {
6040                bnx2x_phy_deassert(params, vars->phy_flags);
6041                switch (params->switch_cfg) {
6042                case SWITCH_CFG_1G:
6043                        vars->phy_flags |= PHY_SERDES_FLAG;
6044                        if ((params->ext_phy_config &
6045                             PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
6046                             PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
6047                                vars->phy_flags |= PHY_SGMII_FLAG;
6048                        }
6049
6050                        val = REG_RD(bp,
6051                                         NIG_REG_SERDES0_CTRL_PHY_ADDR+
6052                                         params->port*0x10);
6053
6054                        params->phy_addr = (u8)val;
6055
6056                        break;
6057                case SWITCH_CFG_10G:
6058                        vars->phy_flags |= PHY_XGXS_FLAG;
6059                        val = REG_RD(bp,
6060                                 NIG_REG_XGXS0_CTRL_PHY_ADDR+
6061                                 params->port*0x18);
6062                        params->phy_addr = (u8)val;
6063
6064                        break;
6065                default:
6066                        DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
6067                        return -EINVAL;
6068                }
6069                DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
6070
6071                bnx2x_link_initialize(params, vars);
6072                msleep(30);
6073                bnx2x_link_int_enable(params);
6074        }
6075        return 0;
6076}
6077
6078static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
6079{
6080        DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
6081
6082        /* Set serial boot control for external load */
6083        bnx2x_cl45_write(bp, port,
6084                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
6085                       MDIO_PMA_DEVAD,
6086                       MDIO_PMA_REG_GEN_CTRL, 0x0001);
6087}
6088
6089u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
6090                  u8 reset_ext_phy)
6091{
6092        struct bnx2x *bp = params->bp;
6093        u32 ext_phy_config = params->ext_phy_config;
6094        u16 hw_led_mode = params->hw_led_mode;
6095        u32 chip_id = params->chip_id;
6096        u8 port = params->port;
6097        u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
6098        u32 val = REG_RD(bp, params->shmem_base +
6099                             offsetof(struct shmem_region, dev_info.
6100                                      port_feature_config[params->port].
6101                                      config));
6102
6103        /* disable attentions */
6104        vars->link_status = 0;
6105        bnx2x_update_mng(params, vars->link_status);
6106        bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6107                     (NIG_MASK_XGXS0_LINK_STATUS |
6108                      NIG_MASK_XGXS0_LINK10G |
6109                      NIG_MASK_SERDES0_LINK_STATUS |
6110                      NIG_MASK_MI_INT));
6111
6112        /* activate nig drain */
6113        REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6114
6115        /* disable nig egress interface */
6116        REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
6117        REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
6118
6119        /* Stop BigMac rx */
6120        bnx2x_bmac_rx_disable(bp, port);
6121
6122        /* disable emac */
6123        REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6124
6125        msleep(10);
6126        /* The PHY reset is controled by GPIO 1
6127         * Hold it as vars low
6128         */
6129         /* clear link led */
6130        bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
6131        if (reset_ext_phy) {
6132                switch (ext_phy_type) {
6133                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
6134                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
6135                        break;
6136
6137                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6138                {
6139
6140                        /* Disable Transmitter */
6141                        u8 ext_phy_addr =
6142                                XGXS_EXT_PHY_ADDR(params->ext_phy_config);
6143                        if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
6144                            PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
6145                                bnx2x_sfp_set_transmitter(bp, port,
6146                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6147                                        ext_phy_addr, 0);
6148                        break;
6149                }
6150                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6151                        DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
6152                                 "low power mode\n",
6153                                 port);
6154                        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6155                                          MISC_REGISTERS_GPIO_OUTPUT_LOW,
6156                                          port);
6157                        break;
6158                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6159                {
6160                        u8 ext_phy_addr =
6161                                XGXS_EXT_PHY_ADDR(params->ext_phy_config);
6162                        /* Set soft reset */
6163                        bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
6164                        break;
6165                }
6166                default:
6167                        /* HW reset */
6168                        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6169                                          MISC_REGISTERS_GPIO_OUTPUT_LOW,
6170                                          port);
6171                        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6172                                          MISC_REGISTERS_GPIO_OUTPUT_LOW,
6173                                          port);
6174                        DP(NETIF_MSG_LINK, "reset external PHY\n");
6175                }
6176        }
6177        /* reset the SerDes/XGXS */
6178        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
6179               (0x1ff << (port*16)));
6180
6181        /* reset BigMac */
6182        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
6183               (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6184
6185        /* disable nig ingress interface */
6186        REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
6187        REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
6188        REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
6189        REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
6190        vars->link_up = 0;
6191        return 0;
6192}
6193
6194static u8 bnx2x_update_link_down(struct link_params *params,
6195                               struct link_vars *vars)
6196{
6197        struct bnx2x *bp = params->bp;
6198        u8 port = params->port;
6199
6200        DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
6201        bnx2x_set_led(bp, port, LED_MODE_OFF,
6202                    0, params->hw_led_mode,
6203                    params->chip_id);
6204
6205        /* indicate no mac active */
6206        vars->mac_type = MAC_TYPE_NONE;
6207
6208        /* update shared memory */
6209        vars->link_status = 0;
6210        vars->line_speed = 0;
6211        bnx2x_update_mng(params, vars->link_status);
6212
6213        /* activate nig drain */
6214        REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6215
6216        /* disable emac */
6217        REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6218
6219        msleep(10);
6220
6221        /* reset BigMac */
6222        bnx2x_bmac_rx_disable(bp, params->port);
6223        REG_WR(bp, GRCBASE_MISC +
6224                   MISC_REGISTERS_RESET_REG_2_CLEAR,
6225                   (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6226        return 0;
6227}
6228
6229static u8 bnx2x_update_link_up(struct link_params *params,
6230                             struct link_vars *vars,
6231                             u8 link_10g, u32 gp_status)
6232{
6233        struct bnx2x *bp = params->bp;
6234        u8 port = params->port;
6235        u8 rc = 0;
6236
6237        vars->link_status |= LINK_STATUS_LINK_UP;
6238        if (link_10g) {
6239                bnx2x_bmac_enable(params, vars, 0);
6240                bnx2x_set_led(bp, port, LED_MODE_OPER,
6241                            SPEED_10000, params->hw_led_mode,
6242                            params->chip_id);
6243
6244        } else {
6245                bnx2x_emac_enable(params, vars, 0);
6246                rc = bnx2x_emac_program(params, vars->line_speed,
6247                                      vars->duplex);
6248
6249                /* AN complete? */
6250                if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
6251                        if (!(vars->phy_flags &
6252                              PHY_SGMII_FLAG))
6253                                bnx2x_set_gmii_tx_driver(params);
6254                }
6255        }
6256
6257        /* PBF - link up */
6258        rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
6259                              vars->line_speed);
6260
6261        /* disable drain */
6262        REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
6263
6264        /* update shared memory */
6265        bnx2x_update_mng(params, vars->link_status);
6266        msleep(20);
6267        return rc;
6268}
6269/* This function should called upon link interrupt */
6270/* In case vars->link_up, driver needs to
6271        1. Update the pbf
6272        2. Disable drain
6273        3. Update the shared memory
6274        4. Indicate link up
6275        5. Set LEDs
6276   Otherwise,
6277        1. Update shared memory
6278        2. Reset BigMac
6279        3. Report link down
6280        4. Unset LEDs
6281*/
6282u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
6283{
6284        struct bnx2x *bp = params->bp;
6285        u8 port = params->port;
6286        u16 gp_status;
6287        u8 link_10g;
6288        u8 ext_phy_link_up, rc = 0;
6289        u32 ext_phy_type;
6290        u8 is_mi_int = 0;
6291
6292        DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
6293                 port, (vars->phy_flags & PHY_XGXS_FLAG),
6294                 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
6295
6296        is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
6297                                    port*0x18) > 0);
6298        DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
6299                 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
6300                 is_mi_int,
6301                 REG_RD(bp,
6302                            NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
6303
6304        DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
6305          REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
6306          REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
6307
6308        /* disable emac */
6309        REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6310
6311        ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
6312
6313        /* Check external link change only for non-direct */
6314        ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars, is_mi_int);
6315
6316        /* Read gp_status */
6317        CL45_RD_OVER_CL22(bp, port, params->phy_addr,
6318                              MDIO_REG_BANK_GP_STATUS,
6319                              MDIO_GP_STATUS_TOP_AN_STATUS1,
6320                              &gp_status);
6321
6322        rc = bnx2x_link_settings_status(params, vars, gp_status,
6323                                      ext_phy_link_up);
6324        if (rc != 0)
6325                return rc;
6326
6327        /* anything 10 and over uses the bmac */
6328        link_10g = ((vars->line_speed == SPEED_10000) ||
6329                    (vars->line_speed == SPEED_12000) ||
6330                    (vars->line_speed == SPEED_12500) ||
6331                    (vars->line_speed == SPEED_13000) ||
6332                    (vars->line_speed == SPEED_15000) ||
6333                    (vars->line_speed == SPEED_16000));
6334
6335        bnx2x_link_int_ack(params, vars, link_10g, is_mi_int);
6336
6337        /* In case external phy link is up, and internal link is down
6338        ( not initialized yet probably after link initialization, it needs
6339        to be initialized.
6340        Note that after link down-up as result of cable plug,
6341        the xgxs link would probably become up again without the need to
6342        initialize it*/
6343
6344        if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
6345            (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
6346            (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
6347            (ext_phy_link_up && !vars->phy_link_up))
6348                bnx2x_init_internal_phy(params, vars, 0);
6349
6350        /* link is up only if both local phy and external phy are up */
6351        vars->link_up = (ext_phy_link_up && vars->phy_link_up);
6352
6353        if (vars->link_up)
6354                rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
6355        else
6356                rc = bnx2x_update_link_down(params, vars);
6357
6358        return rc;
6359}
6360
6361static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6362{
6363        u8 ext_phy_addr[PORT_MAX];
6364        u16 val;
6365        s8 port;
6366
6367        /* PART1 - Reset both phys */
6368        for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6369                /* Extract the ext phy address for the port */
6370                u32 ext_phy_config = REG_RD(bp, shmem_base +
6371                                        offsetof(struct shmem_region,
6372                   dev_info.port_hw_config[port].external_phy_config));
6373
6374                /* disable attentions */
6375                bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6376                             (NIG_MASK_XGXS0_LINK_STATUS |
6377                              NIG_MASK_XGXS0_LINK10G |
6378                              NIG_MASK_SERDES0_LINK_STATUS |
6379                              NIG_MASK_MI_INT));
6380
6381                ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
6382
6383                /* Need to take the phy out of low power mode in order
6384                        to write to access its registers */
6385                bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6386                                  MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
6387
6388                /* Reset the phy */
6389                bnx2x_cl45_write(bp, port,
6390                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6391                               ext_phy_addr[port],
6392                               MDIO_PMA_DEVAD,
6393                               MDIO_PMA_REG_CTRL,
6394                               1<<15);
6395        }
6396
6397        /* Add delay of 150ms after reset */
6398        msleep(150);
6399
6400        /* PART2 - Download firmware to both phys */
6401        for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6402                u16 fw_ver1;
6403
6404                bnx2x_bcm8073_external_rom_boot(bp, port,
6405                                              ext_phy_addr[port], shmem_base);
6406
6407                bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6408                              ext_phy_addr[port],
6409                              MDIO_PMA_DEVAD,
6410                              MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6411                if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
6412                        DP(NETIF_MSG_LINK,
6413                                 "bnx2x_8073_common_init_phy port %x:"
6414                                 "Download failed. fw version = 0x%x\n",
6415                                 port, fw_ver1);
6416                        return -EINVAL;
6417                }
6418
6419                /* Only set bit 10 = 1 (Tx power down) */
6420                bnx2x_cl45_read(bp, port,
6421                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6422                              ext_phy_addr[port],
6423                              MDIO_PMA_DEVAD,
6424                              MDIO_PMA_REG_TX_POWER_DOWN, &val);
6425
6426                /* Phase1 of TX_POWER_DOWN reset */
6427                bnx2x_cl45_write(bp, port,
6428                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6429                               ext_phy_addr[port],
6430                               MDIO_PMA_DEVAD,
6431                               MDIO_PMA_REG_TX_POWER_DOWN,
6432                               (val | 1<<10));
6433        }
6434
6435        /* Toggle Transmitter: Power down and then up with 600ms
6436           delay between */
6437        msleep(600);
6438
6439        /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
6440        for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6441                /* Phase2 of POWER_DOWN_RESET */
6442                /* Release bit 10 (Release Tx power down) */
6443                bnx2x_cl45_read(bp, port,
6444                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6445                              ext_phy_addr[port],
6446                              MDIO_PMA_DEVAD,
6447                              MDIO_PMA_REG_TX_POWER_DOWN, &val);
6448
6449                bnx2x_cl45_write(bp, port,
6450                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6451                               ext_phy_addr[port],
6452                               MDIO_PMA_DEVAD,
6453                               MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
6454                msleep(15);
6455
6456                /* Read modify write the SPI-ROM version select register */
6457                bnx2x_cl45_read(bp, port,
6458                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6459                              ext_phy_addr[port],
6460                              MDIO_PMA_DEVAD,
6461                              MDIO_PMA_REG_EDC_FFE_MAIN, &val);
6462                bnx2x_cl45_write(bp, port,
6463                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6464                              ext_phy_addr[port],
6465                              MDIO_PMA_DEVAD,
6466                              MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
6467
6468                /* set GPIO2 back to LOW */
6469                bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6470                                  MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
6471        }
6472        return 0;
6473
6474}
6475
6476static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6477{
6478        u8 ext_phy_addr[PORT_MAX];
6479        s8 port, first_port, i;
6480        u32 swap_val, swap_override;
6481        DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n");
6482        swap_val = REG_RD(bp,  NIG_REG_PORT_SWAP);
6483        swap_override = REG_RD(bp,  NIG_REG_STRAP_OVERRIDE);
6484
6485        bnx2x_ext_phy_hw_reset(bp, 1 ^ (swap_val && swap_override));
6486        msleep(5);
6487
6488        if (swap_val && swap_override)
6489                first_port = PORT_0;
6490        else
6491                first_port = PORT_1;
6492
6493        /* PART1 - Reset both phys */
6494        for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) {
6495                /* Extract the ext phy address for the port */
6496                u32 ext_phy_config = REG_RD(bp, shmem_base +
6497                                        offsetof(struct shmem_region,
6498                   dev_info.port_hw_config[port].external_phy_config));
6499
6500                /* disable attentions */
6501                bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6502                             (NIG_MASK_XGXS0_LINK_STATUS |
6503                              NIG_MASK_XGXS0_LINK10G |
6504                              NIG_MASK_SERDES0_LINK_STATUS |
6505                              NIG_MASK_MI_INT));
6506
6507                ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
6508
6509                /* Reset the phy */
6510                bnx2x_cl45_write(bp, port,
6511                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6512                               ext_phy_addr[port],
6513                               MDIO_PMA_DEVAD,
6514                               MDIO_PMA_REG_CTRL,
6515                               1<<15);
6516        }
6517
6518        /* Add delay of 150ms after reset */
6519        msleep(150);
6520
6521        /* PART2 - Download firmware to both phys */
6522        for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) {
6523                u16 fw_ver1;
6524
6525                bnx2x_bcm8727_external_rom_boot(bp, port,
6526                                              ext_phy_addr[port], shmem_base);
6527
6528                bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6529                              ext_phy_addr[port],
6530                              MDIO_PMA_DEVAD,
6531                              MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6532                if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
6533                        DP(NETIF_MSG_LINK,
6534                                 "bnx2x_8727_common_init_phy port %x:"
6535                                 "Download failed. fw version = 0x%x\n",
6536                                 port, fw_ver1);
6537                        return -EINVAL;
6538                }
6539        }
6540
6541        return 0;
6542}
6543
6544
6545static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6546{
6547        u8 ext_phy_addr;
6548        u32 val;
6549        s8 port;
6550
6551        /* Use port1 because of the static port-swap */
6552        /* Enable the module detection interrupt */
6553        val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
6554        val |= ((1<<MISC_REGISTERS_GPIO_3)|
6555                (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
6556        REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
6557
6558        bnx2x_ext_phy_hw_reset(bp, 1);
6559        msleep(5);
6560        for (port = 0; port < PORT_MAX; port++) {
6561                /* Extract the ext phy address for the port */
6562                u32 ext_phy_config = REG_RD(bp, shmem_base +
6563                                        offsetof(struct shmem_region,
6564                        dev_info.port_hw_config[port].external_phy_config));
6565
6566                ext_phy_addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
6567                DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
6568                         ext_phy_addr);
6569
6570                bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
6571
6572                /* Set fault module detected LED on */
6573                bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
6574                                  MISC_REGISTERS_GPIO_HIGH,
6575                                  port);
6576        }
6577
6578        return 0;
6579}
6580
6581u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6582{
6583        u8 rc = 0;
6584        u32 ext_phy_type;
6585
6586        DP(NETIF_MSG_LINK, "Begin common phy init\n");
6587
6588        /* Read the ext_phy_type for arbitrary port(0) */
6589        ext_phy_type = XGXS_EXT_PHY_TYPE(
6590                        REG_RD(bp, shmem_base +
6591                           offsetof(struct shmem_region,
6592                             dev_info.port_hw_config[0].external_phy_config)));
6593
6594        switch (ext_phy_type) {
6595        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6596        {
6597                rc = bnx2x_8073_common_init_phy(bp, shmem_base);
6598                break;
6599        }
6600
6601        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6602        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
6603                rc = bnx2x_8727_common_init_phy(bp, shmem_base);
6604                break;
6605
6606        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6607                /* GPIO1 affects both ports, so there's need to pull
6608                it for single port alone */
6609                rc = bnx2x_8726_common_init_phy(bp, shmem_base);
6610
6611                break;
6612        default:
6613                DP(NETIF_MSG_LINK,
6614                         "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
6615                         ext_phy_type);
6616                break;
6617        }
6618
6619        return rc;
6620}
6621
6622void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
6623{
6624        u16 val, cnt;
6625
6626        bnx2x_cl45_read(bp, port,
6627                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6628                      phy_addr,
6629                      MDIO_PMA_DEVAD,
6630                      MDIO_PMA_REG_7101_RESET, &val);
6631
6632        for (cnt = 0; cnt < 10; cnt++) {
6633                msleep(50);
6634                /* Writes a self-clearing reset */
6635                bnx2x_cl45_write(bp, port,
6636                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6637                               phy_addr,
6638                               MDIO_PMA_DEVAD,
6639                               MDIO_PMA_REG_7101_RESET,
6640                               (val | (1<<15)));
6641                /* Wait for clear */
6642                bnx2x_cl45_read(bp, port,
6643                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6644                              phy_addr,
6645                              MDIO_PMA_DEVAD,
6646                              MDIO_PMA_REG_7101_RESET, &val);
6647
6648                if ((val & (1<<15)) == 0)
6649                        break;
6650        }
6651}
6652