diff options
author | Yaniv Rosner <yanivr@broadcom.com> | 2011-06-13 21:34:17 -0400 |
---|---|---|
committer | David S. Miller <davem@conan.davemloft.net> | 2011-06-15 10:56:57 -0400 |
commit | 6583e33baefbe4dea04999ec91be1a1371cd1528 (patch) | |
tree | c96ee11e53d20989463ef7a97798f6e3075255a0 /drivers | |
parent | 3c9ada227c56c6f41e24b01d183b00b007c7ac93 (diff) |
bnx2x: Add new PHY 54616s
Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@conan.davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/bnx2x/bnx2x_link.c | 467 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_reg.h | 12 |
2 files changed, 471 insertions, 8 deletions
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index b777d2c9633f..73938f9201a9 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c | |||
@@ -134,6 +134,9 @@ | |||
134 | #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD | 134 | #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD |
135 | #define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD | 135 | #define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD |
136 | #define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD | 136 | #define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD |
137 | |||
138 | |||
139 | |||
137 | /* */ | 140 | /* */ |
138 | #define SFP_EEPROM_CON_TYPE_ADDR 0x2 | 141 | #define SFP_EEPROM_CON_TYPE_ADDR 0x2 |
139 | #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 | 142 | #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 |
@@ -2060,6 +2063,83 @@ static u32 bnx2x_get_emac_base(struct bnx2x *bp, | |||
2060 | } | 2063 | } |
2061 | 2064 | ||
2062 | /******************************************************************/ | 2065 | /******************************************************************/ |
2066 | /* CL22 access functions */ | ||
2067 | /******************************************************************/ | ||
2068 | static int bnx2x_cl22_write(struct bnx2x *bp, | ||
2069 | struct bnx2x_phy *phy, | ||
2070 | u16 reg, u16 val) | ||
2071 | { | ||
2072 | u32 tmp, mode; | ||
2073 | u8 i; | ||
2074 | int rc = 0; | ||
2075 | /* Switch to CL22 */ | ||
2076 | mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); | ||
2077 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, | ||
2078 | mode & ~EMAC_MDIO_MODE_CLAUSE_45); | ||
2079 | |||
2080 | /* address */ | ||
2081 | tmp = ((phy->addr << 21) | (reg << 16) | val | | ||
2082 | EMAC_MDIO_COMM_COMMAND_WRITE_22 | | ||
2083 | EMAC_MDIO_COMM_START_BUSY); | ||
2084 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); | ||
2085 | |||
2086 | for (i = 0; i < 50; i++) { | ||
2087 | udelay(10); | ||
2088 | |||
2089 | tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); | ||
2090 | if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { | ||
2091 | udelay(5); | ||
2092 | break; | ||
2093 | } | ||
2094 | } | ||
2095 | if (tmp & EMAC_MDIO_COMM_START_BUSY) { | ||
2096 | DP(NETIF_MSG_LINK, "write phy register failed\n"); | ||
2097 | rc = -EFAULT; | ||
2098 | } | ||
2099 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode); | ||
2100 | return rc; | ||
2101 | } | ||
2102 | |||
2103 | static int bnx2x_cl22_read(struct bnx2x *bp, | ||
2104 | struct bnx2x_phy *phy, | ||
2105 | u16 reg, u16 *ret_val) | ||
2106 | { | ||
2107 | u32 val, mode; | ||
2108 | u16 i; | ||
2109 | int rc = 0; | ||
2110 | |||
2111 | /* Switch to CL22 */ | ||
2112 | mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); | ||
2113 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, | ||
2114 | mode & ~EMAC_MDIO_MODE_CLAUSE_45); | ||
2115 | |||
2116 | /* address */ | ||
2117 | val = ((phy->addr << 21) | (reg << 16) | | ||
2118 | EMAC_MDIO_COMM_COMMAND_READ_22 | | ||
2119 | EMAC_MDIO_COMM_START_BUSY); | ||
2120 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); | ||
2121 | |||
2122 | for (i = 0; i < 50; i++) { | ||
2123 | udelay(10); | ||
2124 | |||
2125 | val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); | ||
2126 | if (!(val & EMAC_MDIO_COMM_START_BUSY)) { | ||
2127 | *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA); | ||
2128 | udelay(5); | ||
2129 | break; | ||
2130 | } | ||
2131 | } | ||
2132 | if (val & EMAC_MDIO_COMM_START_BUSY) { | ||
2133 | DP(NETIF_MSG_LINK, "read phy register failed\n"); | ||
2134 | |||
2135 | *ret_val = 0; | ||
2136 | rc = -EFAULT; | ||
2137 | } | ||
2138 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode); | ||
2139 | return rc; | ||
2140 | } | ||
2141 | |||
2142 | /******************************************************************/ | ||
2063 | /* CL45 access functions */ | 2143 | /* CL45 access functions */ |
2064 | /******************************************************************/ | 2144 | /******************************************************************/ |
2065 | static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, | 2145 | static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, |
@@ -2649,12 +2729,19 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, | |||
2649 | vars->flow_ctrl = params->req_fc_auto_adv; | 2729 | vars->flow_ctrl = params->req_fc_auto_adv; |
2650 | else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) { | 2730 | else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) { |
2651 | ret = 1; | 2731 | ret = 1; |
2652 | bnx2x_cl45_read(bp, phy, | 2732 | if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616) { |
2653 | MDIO_AN_DEVAD, | 2733 | bnx2x_cl22_read(bp, phy, |
2654 | MDIO_AN_REG_ADV_PAUSE, &ld_pause); | 2734 | 0x4, &ld_pause); |
2655 | bnx2x_cl45_read(bp, phy, | 2735 | bnx2x_cl22_read(bp, phy, |
2656 | MDIO_AN_DEVAD, | 2736 | 0x5, &lp_pause); |
2657 | MDIO_AN_REG_LP_AUTO_NEG, &lp_pause); | 2737 | } else { |
2738 | bnx2x_cl45_read(bp, phy, | ||
2739 | MDIO_AN_DEVAD, | ||
2740 | MDIO_AN_REG_ADV_PAUSE, &ld_pause); | ||
2741 | bnx2x_cl45_read(bp, phy, | ||
2742 | MDIO_AN_DEVAD, | ||
2743 | MDIO_AN_REG_LP_AUTO_NEG, &lp_pause); | ||
2744 | } | ||
2658 | pause_result = (ld_pause & | 2745 | pause_result = (ld_pause & |
2659 | MDIO_AN_REG_ADV_PAUSE_MASK) >> 8; | 2746 | MDIO_AN_REG_ADV_PAUSE_MASK) >> 8; |
2660 | pause_result |= (lp_pause & | 2747 | pause_result |= (lp_pause & |
@@ -4653,8 +4740,13 @@ static u16 bnx2x_wait_reset_complete(struct bnx2x *bp, | |||
4653 | u16 cnt, ctrl; | 4740 | u16 cnt, ctrl; |
4654 | /* Wait for soft reset to get cleared up to 1 sec */ | 4741 | /* Wait for soft reset to get cleared up to 1 sec */ |
4655 | for (cnt = 0; cnt < 1000; cnt++) { | 4742 | for (cnt = 0; cnt < 1000; cnt++) { |
4656 | bnx2x_cl45_read(bp, phy, | 4743 | if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616) |
4657 | MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl); | 4744 | bnx2x_cl22_read(bp, phy, |
4745 | MDIO_PMA_REG_CTRL, &ctrl); | ||
4746 | else | ||
4747 | bnx2x_cl45_read(bp, phy, | ||
4748 | MDIO_PMA_DEVAD, | ||
4749 | MDIO_PMA_REG_CTRL, &ctrl); | ||
4658 | if (!(ctrl & (1<<15))) | 4750 | if (!(ctrl & (1<<15))) |
4659 | break; | 4751 | break; |
4660 | msleep(1); | 4752 | msleep(1); |
@@ -8808,6 +8900,329 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, | |||
8808 | } | 8900 | } |
8809 | } | 8901 | } |
8810 | /******************************************************************/ | 8902 | /******************************************************************/ |
8903 | /* 54616S PHY SECTION */ | ||
8904 | /******************************************************************/ | ||
8905 | static int bnx2x_54616s_config_init(struct bnx2x_phy *phy, | ||
8906 | struct link_params *params, | ||
8907 | struct link_vars *vars) | ||
8908 | { | ||
8909 | struct bnx2x *bp = params->bp; | ||
8910 | u8 port; | ||
8911 | u16 autoneg_val, an_1000_val, an_10_100_val, fc_val, temp; | ||
8912 | u32 cfg_pin; | ||
8913 | |||
8914 | DP(NETIF_MSG_LINK, "54616S cfg init\n"); | ||
8915 | usleep_range(1000, 1000); | ||
8916 | |||
8917 | /* This works with E3 only, no need to check the chip | ||
8918 | before determining the port. */ | ||
8919 | port = params->port; | ||
8920 | |||
8921 | cfg_pin = (REG_RD(bp, params->shmem_base + | ||
8922 | offsetof(struct shmem_region, | ||
8923 | dev_info.port_hw_config[port].e3_cmn_pin_cfg)) & | ||
8924 | PORT_HW_CFG_E3_PHY_RESET_MASK) >> | ||
8925 | PORT_HW_CFG_E3_PHY_RESET_SHIFT; | ||
8926 | |||
8927 | /* Drive pin high to bring the GPHY out of reset. */ | ||
8928 | bnx2x_set_cfg_pin(bp, cfg_pin, 1); | ||
8929 | |||
8930 | /* wait for GPHY to reset */ | ||
8931 | msleep(50); | ||
8932 | |||
8933 | /* reset phy */ | ||
8934 | bnx2x_cl22_write(bp, phy, | ||
8935 | MDIO_PMA_REG_CTRL, 0x8000); | ||
8936 | bnx2x_wait_reset_complete(bp, phy, params); | ||
8937 | |||
8938 | /*wait for GPHY to reset */ | ||
8939 | msleep(50); | ||
8940 | |||
8941 | /* Configure LED4: set to INTR (0x6). */ | ||
8942 | /* Accessing shadow register 0xe. */ | ||
8943 | bnx2x_cl22_write(bp, phy, | ||
8944 | MDIO_REG_GPHY_SHADOW, | ||
8945 | MDIO_REG_GPHY_SHADOW_LED_SEL2); | ||
8946 | bnx2x_cl22_read(bp, phy, | ||
8947 | MDIO_REG_GPHY_SHADOW, | ||
8948 | &temp); | ||
8949 | temp &= ~(0xf << 4); | ||
8950 | temp |= (0x6 << 4); | ||
8951 | bnx2x_cl22_write(bp, phy, | ||
8952 | MDIO_REG_GPHY_SHADOW, | ||
8953 | MDIO_REG_GPHY_SHADOW_WR_ENA | temp); | ||
8954 | /* Configure INTR based on link status change. */ | ||
8955 | bnx2x_cl22_write(bp, phy, | ||
8956 | MDIO_REG_INTR_MASK, | ||
8957 | ~MDIO_REG_INTR_MASK_LINK_STATUS); | ||
8958 | |||
8959 | /* Flip the signal detect polarity (set 0x1c.0x1e[8]). */ | ||
8960 | bnx2x_cl22_write(bp, phy, | ||
8961 | MDIO_REG_GPHY_SHADOW, | ||
8962 | MDIO_REG_GPHY_SHADOW_AUTO_DET_MED); | ||
8963 | bnx2x_cl22_read(bp, phy, | ||
8964 | MDIO_REG_GPHY_SHADOW, | ||
8965 | &temp); | ||
8966 | temp |= MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD; | ||
8967 | bnx2x_cl22_write(bp, phy, | ||
8968 | MDIO_REG_GPHY_SHADOW, | ||
8969 | MDIO_REG_GPHY_SHADOW_WR_ENA | temp); | ||
8970 | |||
8971 | /* Set up fc */ | ||
8972 | /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ | ||
8973 | bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); | ||
8974 | fc_val = 0; | ||
8975 | if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == | ||
8976 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) | ||
8977 | fc_val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC; | ||
8978 | |||
8979 | if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == | ||
8980 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) | ||
8981 | fc_val |= MDIO_AN_REG_ADV_PAUSE_PAUSE; | ||
8982 | |||
8983 | /* read all advertisement */ | ||
8984 | bnx2x_cl22_read(bp, phy, | ||
8985 | 0x09, | ||
8986 | &an_1000_val); | ||
8987 | |||
8988 | bnx2x_cl22_read(bp, phy, | ||
8989 | 0x04, | ||
8990 | &an_10_100_val); | ||
8991 | |||
8992 | bnx2x_cl22_read(bp, phy, | ||
8993 | MDIO_PMA_REG_CTRL, | ||
8994 | &autoneg_val); | ||
8995 | |||
8996 | /* Disable forced speed */ | ||
8997 | autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13)); | ||
8998 | an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8) | (1<<10) | | ||
8999 | (1<<11)); | ||
9000 | |||
9001 | if (((phy->req_line_speed == SPEED_AUTO_NEG) && | ||
9002 | (phy->speed_cap_mask & | ||
9003 | PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || | ||
9004 | (phy->req_line_speed == SPEED_1000)) { | ||
9005 | an_1000_val |= (1<<8); | ||
9006 | autoneg_val |= (1<<9 | 1<<12); | ||
9007 | if (phy->req_duplex == DUPLEX_FULL) | ||
9008 | an_1000_val |= (1<<9); | ||
9009 | DP(NETIF_MSG_LINK, "Advertising 1G\n"); | ||
9010 | } else | ||
9011 | an_1000_val &= ~((1<<8) | (1<<9)); | ||
9012 | |||
9013 | bnx2x_cl22_write(bp, phy, | ||
9014 | 0x09, | ||
9015 | an_1000_val); | ||
9016 | bnx2x_cl22_read(bp, phy, | ||
9017 | 0x09, | ||
9018 | &an_1000_val); | ||
9019 | |||
9020 | /* set 100 speed advertisement */ | ||
9021 | if (((phy->req_line_speed == SPEED_AUTO_NEG) && | ||
9022 | (phy->speed_cap_mask & | ||
9023 | (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | | ||
9024 | PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) { | ||
9025 | an_10_100_val |= (1<<7); | ||
9026 | /* Enable autoneg and restart autoneg for legacy speeds */ | ||
9027 | autoneg_val |= (1<<9 | 1<<12); | ||
9028 | |||
9029 | if (phy->req_duplex == DUPLEX_FULL) | ||
9030 | an_10_100_val |= (1<<8); | ||
9031 | DP(NETIF_MSG_LINK, "Advertising 100M\n"); | ||
9032 | } | ||
9033 | |||
9034 | /* set 10 speed advertisement */ | ||
9035 | if (((phy->req_line_speed == SPEED_AUTO_NEG) && | ||
9036 | (phy->speed_cap_mask & | ||
9037 | (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | | ||
9038 | PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) { | ||
9039 | an_10_100_val |= (1<<5); | ||
9040 | autoneg_val |= (1<<9 | 1<<12); | ||
9041 | if (phy->req_duplex == DUPLEX_FULL) | ||
9042 | an_10_100_val |= (1<<6); | ||
9043 | DP(NETIF_MSG_LINK, "Advertising 10M\n"); | ||
9044 | } | ||
9045 | |||
9046 | /* Only 10/100 are allowed to work in FORCE mode */ | ||
9047 | if (phy->req_line_speed == SPEED_100) { | ||
9048 | autoneg_val |= (1<<13); | ||
9049 | /* Enabled AUTO-MDIX when autoneg is disabled */ | ||
9050 | bnx2x_cl22_write(bp, phy, | ||
9051 | 0x18, | ||
9052 | (1<<15 | 1<<9 | 7<<0)); | ||
9053 | DP(NETIF_MSG_LINK, "Setting 100M force\n"); | ||
9054 | } | ||
9055 | if (phy->req_line_speed == SPEED_10) { | ||
9056 | /* Enabled AUTO-MDIX when autoneg is disabled */ | ||
9057 | bnx2x_cl22_write(bp, phy, | ||
9058 | 0x18, | ||
9059 | (1<<15 | 1<<9 | 7<<0)); | ||
9060 | DP(NETIF_MSG_LINK, "Setting 10M force\n"); | ||
9061 | } | ||
9062 | |||
9063 | bnx2x_cl22_write(bp, phy, | ||
9064 | 0x04, | ||
9065 | an_10_100_val | fc_val); | ||
9066 | |||
9067 | if (phy->req_duplex == DUPLEX_FULL) | ||
9068 | autoneg_val |= (1<<8); | ||
9069 | |||
9070 | bnx2x_cl22_write(bp, phy, | ||
9071 | MDIO_PMA_REG_CTRL, autoneg_val); | ||
9072 | |||
9073 | return 0; | ||
9074 | } | ||
9075 | |||
9076 | static void bnx2x_54616s_set_link_led(struct bnx2x_phy *phy, | ||
9077 | struct link_params *params, u8 mode) | ||
9078 | { | ||
9079 | struct bnx2x *bp = params->bp; | ||
9080 | DP(NETIF_MSG_LINK, "54616S set link led (mode=%x)\n", mode); | ||
9081 | switch (mode) { | ||
9082 | case LED_MODE_FRONT_PANEL_OFF: | ||
9083 | case LED_MODE_OFF: | ||
9084 | case LED_MODE_OPER: | ||
9085 | case LED_MODE_ON: | ||
9086 | default: | ||
9087 | break; | ||
9088 | } | ||
9089 | return; | ||
9090 | } | ||
9091 | |||
9092 | static void bnx2x_54616s_link_reset(struct bnx2x_phy *phy, | ||
9093 | struct link_params *params) | ||
9094 | { | ||
9095 | struct bnx2x *bp = params->bp; | ||
9096 | u32 cfg_pin; | ||
9097 | u8 port; | ||
9098 | |||
9099 | /* This works with E3 only, no need to check the chip | ||
9100 | before determining the port. */ | ||
9101 | port = params->port; | ||
9102 | cfg_pin = (REG_RD(bp, params->shmem_base + | ||
9103 | offsetof(struct shmem_region, | ||
9104 | dev_info.port_hw_config[port].e3_cmn_pin_cfg)) & | ||
9105 | PORT_HW_CFG_E3_PHY_RESET_MASK) >> | ||
9106 | PORT_HW_CFG_E3_PHY_RESET_SHIFT; | ||
9107 | |||
9108 | /* Drive pin low to put GPHY in reset. */ | ||
9109 | bnx2x_set_cfg_pin(bp, cfg_pin, 0); | ||
9110 | } | ||
9111 | |||
9112 | static u8 bnx2x_54616s_read_status(struct bnx2x_phy *phy, | ||
9113 | struct link_params *params, | ||
9114 | struct link_vars *vars) | ||
9115 | { | ||
9116 | struct bnx2x *bp = params->bp; | ||
9117 | u16 val; | ||
9118 | u8 link_up = 0; | ||
9119 | u16 legacy_status, legacy_speed; | ||
9120 | |||
9121 | /* Get speed operation status */ | ||
9122 | bnx2x_cl22_read(bp, phy, | ||
9123 | 0x19, | ||
9124 | &legacy_status); | ||
9125 | DP(NETIF_MSG_LINK, "54616S read_status: 0x%x\n", legacy_status); | ||
9126 | |||
9127 | /* Read status to clear the PHY interrupt. */ | ||
9128 | bnx2x_cl22_read(bp, phy, | ||
9129 | MDIO_REG_INTR_STATUS, | ||
9130 | &val); | ||
9131 | |||
9132 | link_up = ((legacy_status & (1<<2)) == (1<<2)); | ||
9133 | |||
9134 | if (link_up) { | ||
9135 | legacy_speed = (legacy_status & (7<<8)); | ||
9136 | if (legacy_speed == (7<<8)) { | ||
9137 | vars->line_speed = SPEED_1000; | ||
9138 | vars->duplex = DUPLEX_FULL; | ||
9139 | } else if (legacy_speed == (6<<8)) { | ||
9140 | vars->line_speed = SPEED_1000; | ||
9141 | vars->duplex = DUPLEX_HALF; | ||
9142 | } else if (legacy_speed == (5<<8)) { | ||
9143 | vars->line_speed = SPEED_100; | ||
9144 | vars->duplex = DUPLEX_FULL; | ||
9145 | } | ||
9146 | /* Omitting 100Base-T4 for now */ | ||
9147 | else if (legacy_speed == (3<<8)) { | ||
9148 | vars->line_speed = SPEED_100; | ||
9149 | vars->duplex = DUPLEX_HALF; | ||
9150 | } else if (legacy_speed == (2<<8)) { | ||
9151 | vars->line_speed = SPEED_10; | ||
9152 | vars->duplex = DUPLEX_FULL; | ||
9153 | } else if (legacy_speed == (1<<8)) { | ||
9154 | vars->line_speed = SPEED_10; | ||
9155 | vars->duplex = DUPLEX_HALF; | ||
9156 | } else /* Should not happen */ | ||
9157 | vars->line_speed = 0; | ||
9158 | |||
9159 | DP(NETIF_MSG_LINK, "Link is up in %dMbps," | ||
9160 | " is_duplex_full= %d\n", vars->line_speed, | ||
9161 | (vars->duplex == DUPLEX_FULL)); | ||
9162 | |||
9163 | /* Check legacy speed AN resolution */ | ||
9164 | bnx2x_cl22_read(bp, phy, | ||
9165 | 0x01, | ||
9166 | &val); | ||
9167 | if (val & (1<<5)) | ||
9168 | vars->link_status |= | ||
9169 | LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; | ||
9170 | bnx2x_cl22_read(bp, phy, | ||
9171 | 0x06, | ||
9172 | &val); | ||
9173 | if ((val & (1<<0)) == 0) | ||
9174 | vars->link_status |= | ||
9175 | LINK_STATUS_PARALLEL_DETECTION_USED; | ||
9176 | |||
9177 | DP(NETIF_MSG_LINK, "BCM54616S: link speed is %d\n", | ||
9178 | vars->line_speed); | ||
9179 | bnx2x_ext_phy_resolve_fc(phy, params, vars); | ||
9180 | } | ||
9181 | return link_up; | ||
9182 | } | ||
9183 | |||
9184 | static void bnx2x_54616s_config_loopback(struct bnx2x_phy *phy, | ||
9185 | struct link_params *params) | ||
9186 | { | ||
9187 | struct bnx2x *bp = params->bp; | ||
9188 | u16 val; | ||
9189 | u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0; | ||
9190 | |||
9191 | DP(NETIF_MSG_LINK, "2PMA/PMD ext_phy_loopback: 54616s\n"); | ||
9192 | |||
9193 | /* Enable master/slave manual mmode and set to master */ | ||
9194 | /* mii write 9 [bits set 11 12] */ | ||
9195 | bnx2x_cl22_write(bp, phy, 0x09, 3<<11); | ||
9196 | |||
9197 | /* forced 1G and disable autoneg */ | ||
9198 | /* set val [mii read 0] */ | ||
9199 | /* set val [expr $val & [bits clear 6 12 13]] */ | ||
9200 | /* set val [expr $val | [bits set 6 8]] */ | ||
9201 | /* mii write 0 $val */ | ||
9202 | bnx2x_cl22_read(bp, phy, 0x00, &val); | ||
9203 | val &= ~((1<<6) | (1<<12) | (1<<13)); | ||
9204 | val |= (1<<6) | (1<<8); | ||
9205 | bnx2x_cl22_write(bp, phy, 0x00, val); | ||
9206 | |||
9207 | /* Set external loopback and Tx using 6dB coding */ | ||
9208 | /* mii write 0x18 7 */ | ||
9209 | /* set val [mii read 0x18] */ | ||
9210 | /* mii write 0x18 [expr $val | [bits set 10 15]] */ | ||
9211 | bnx2x_cl22_write(bp, phy, 0x18, 7); | ||
9212 | bnx2x_cl22_read(bp, phy, 0x18, &val); | ||
9213 | bnx2x_cl22_write(bp, phy, 0x18, val | (1<<10) | (1<<15)); | ||
9214 | |||
9215 | /* This register opens the gate for the UMAC despite its name */ | ||
9216 | REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1); | ||
9217 | |||
9218 | /* | ||
9219 | * Maximum Frame Length (RW). Defines a 14-Bit maximum frame | ||
9220 | * length used by the MAC receive logic to check frames. | ||
9221 | */ | ||
9222 | REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710); | ||
9223 | } | ||
9224 | |||
9225 | /******************************************************************/ | ||
8811 | /* SFX7101 PHY SECTION */ | 9226 | /* SFX7101 PHY SECTION */ |
8812 | /******************************************************************/ | 9227 | /******************************************************************/ |
8813 | static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy, | 9228 | static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy, |
@@ -9390,6 +9805,39 @@ static struct bnx2x_phy phy_84833 = { | |||
9390 | .phy_specific_func = (phy_specific_func_t)NULL | 9805 | .phy_specific_func = (phy_specific_func_t)NULL |
9391 | }; | 9806 | }; |
9392 | 9807 | ||
9808 | static struct bnx2x_phy phy_54616s = { | ||
9809 | .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616, | ||
9810 | .addr = 0xff, | ||
9811 | .def_md_devad = 0, | ||
9812 | .flags = FLAGS_INIT_XGXS_FIRST, | ||
9813 | .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, | ||
9814 | .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, | ||
9815 | .mdio_ctrl = 0, | ||
9816 | .supported = (SUPPORTED_10baseT_Half | | ||
9817 | SUPPORTED_10baseT_Full | | ||
9818 | SUPPORTED_100baseT_Half | | ||
9819 | SUPPORTED_100baseT_Full | | ||
9820 | SUPPORTED_1000baseT_Full | | ||
9821 | SUPPORTED_TP | | ||
9822 | SUPPORTED_Autoneg | | ||
9823 | SUPPORTED_Pause | | ||
9824 | SUPPORTED_Asym_Pause), | ||
9825 | .media_type = ETH_PHY_BASE_T, | ||
9826 | .ver_addr = 0, | ||
9827 | .req_flow_ctrl = 0, | ||
9828 | .req_line_speed = 0, | ||
9829 | .speed_cap_mask = 0, | ||
9830 | /* req_duplex = */0, | ||
9831 | /* rsrv = */0, | ||
9832 | .config_init = (config_init_t)bnx2x_54616s_config_init, | ||
9833 | .read_status = (read_status_t)bnx2x_54616s_read_status, | ||
9834 | .link_reset = (link_reset_t)bnx2x_54616s_link_reset, | ||
9835 | .config_loopback = (config_loopback_t)bnx2x_54616s_config_loopback, | ||
9836 | .format_fw_ver = (format_fw_ver_t)NULL, | ||
9837 | .hw_reset = (hw_reset_t)NULL, | ||
9838 | .set_link_led = (set_link_led_t)bnx2x_54616s_set_link_led, | ||
9839 | .phy_specific_func = (phy_specific_func_t)NULL | ||
9840 | }; | ||
9393 | /*****************************************************************/ | 9841 | /*****************************************************************/ |
9394 | /* */ | 9842 | /* */ |
9395 | /* Populate the phy according. Main function: bnx2x_populate_phy */ | 9843 | /* Populate the phy according. Main function: bnx2x_populate_phy */ |
@@ -9630,6 +10078,9 @@ static int bnx2x_populate_ext_phy(struct bnx2x *bp, | |||
9630 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833: | 10078 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833: |
9631 | *phy = phy_84833; | 10079 | *phy = phy_84833; |
9632 | break; | 10080 | break; |
10081 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616: | ||
10082 | *phy = phy_54616s; | ||
10083 | break; | ||
9633 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: | 10084 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: |
9634 | *phy = phy_7101; | 10085 | *phy = phy_7101; |
9635 | break; | 10086 | break; |
diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 23c89a863a58..bf43b9b16d8b 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h | |||
@@ -5420,7 +5420,9 @@ | |||
5420 | #define EMAC_LED_OVERRIDE (1L<<0) | 5420 | #define EMAC_LED_OVERRIDE (1L<<0) |
5421 | #define EMAC_LED_TRAFFIC (1L<<6) | 5421 | #define EMAC_LED_TRAFFIC (1L<<6) |
5422 | #define EMAC_MDIO_COMM_COMMAND_ADDRESS (0L<<26) | 5422 | #define EMAC_MDIO_COMM_COMMAND_ADDRESS (0L<<26) |
5423 | #define EMAC_MDIO_COMM_COMMAND_READ_22 (2L<<26) | ||
5423 | #define EMAC_MDIO_COMM_COMMAND_READ_45 (3L<<26) | 5424 | #define EMAC_MDIO_COMM_COMMAND_READ_45 (3L<<26) |
5425 | #define EMAC_MDIO_COMM_COMMAND_WRITE_22 (1L<<26) | ||
5424 | #define EMAC_MDIO_COMM_COMMAND_WRITE_45 (1L<<26) | 5426 | #define EMAC_MDIO_COMM_COMMAND_WRITE_45 (1L<<26) |
5425 | #define EMAC_MDIO_COMM_DATA (0xffffL<<0) | 5427 | #define EMAC_MDIO_COMM_DATA (0xffffL<<0) |
5426 | #define EMAC_MDIO_COMM_START_BUSY (1L<<29) | 5428 | #define EMAC_MDIO_COMM_START_BUSY (1L<<29) |
@@ -6737,6 +6739,16 @@ Theotherbitsarereservedandshouldbezero*/ | |||
6737 | 6739 | ||
6738 | #define DIGITAL5_ACTUAL_SPEED_TX_MASK 0x003f | 6740 | #define DIGITAL5_ACTUAL_SPEED_TX_MASK 0x003f |
6739 | 6741 | ||
6742 | /* 54616s */ | ||
6743 | #define MDIO_REG_INTR_STATUS 0x1a | ||
6744 | #define MDIO_REG_INTR_MASK 0x1b | ||
6745 | #define MDIO_REG_INTR_MASK_LINK_STATUS (0x1 << 1) | ||
6746 | #define MDIO_REG_GPHY_SHADOW 0x1c | ||
6747 | #define MDIO_REG_GPHY_SHADOW_LED_SEL2 (0x0e << 10) | ||
6748 | #define MDIO_REG_GPHY_SHADOW_WR_ENA (0x1 << 15) | ||
6749 | #define MDIO_REG_GPHY_SHADOW_AUTO_DET_MED (0x1e << 10) | ||
6750 | #define MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD (0x1 << 8) | ||
6751 | |||
6740 | #define IGU_FUNC_BASE 0x0400 | 6752 | #define IGU_FUNC_BASE 0x0400 |
6741 | 6753 | ||
6742 | #define IGU_ADDR_MSIX 0x0000 | 6754 | #define IGU_ADDR_MSIX 0x0000 |