diff options
author | Yaniv Rosner <yaniv.rosner@broadcom.com> | 2010-09-07 07:41:07 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-09-07 16:15:40 -0400 |
commit | c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfd (patch) | |
tree | 35407386797909073baafe68fdca35b71d5df0e5 /drivers/net/bnx2x/bnx2x_link.c | |
parent | d90d96baf0cc044bcdedc9ee9e925b5937865673 (diff) |
bnx2x: Apply logic changes for the new scheme
Make the needed changes for the new scheme especially around PHY
initialization, and link detection.
- The get_emac_base function was changed to enable setting different MAC
access setting for each PHY based of external configuration.
- As a part of the dual-media preparation, the save_spirom_version was
modified to accept a PHY specific version address to be saved in the
shmem. This will enable to save more than single spirom version in
different locations.
- The test_link function was changed also as a preparation for the
dual-media upcoming changes
- Duplicate initialization logic was removed from the
link_setting_status and link_initialize functions
Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_link.c')
-rw-r--r-- | drivers/net/bnx2x/bnx2x_link.c | 331 |
1 files changed, 154 insertions, 177 deletions
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 72ac8dcf6e20..fcf99bf62fa1 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c | |||
@@ -195,24 +195,6 @@ static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port) | |||
195 | REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0); | 195 | REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0); |
196 | } | 196 | } |
197 | 197 | ||
198 | static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags) | ||
199 | { | ||
200 | struct bnx2x *bp = params->bp; | ||
201 | |||
202 | if (phy_flags & PHY_XGXS_FLAG) { | ||
203 | REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + | ||
204 | params->port*0x18, 0); | ||
205 | REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18, | ||
206 | DEFAULT_PHY_DEV_ADDR); | ||
207 | } else { | ||
208 | bnx2x_set_serdes_access(bp, params->port); | ||
209 | |||
210 | REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + | ||
211 | params->port*0x10, | ||
212 | DEFAULT_PHY_DEV_ADDR); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits) | 198 | static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits) |
217 | { | 199 | { |
218 | u32 val = REG_RD(bp, reg); | 200 | u32 val = REG_RD(bp, reg); |
@@ -528,31 +510,46 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, | |||
528 | return 0; | 510 | return 0; |
529 | } | 511 | } |
530 | 512 | ||
531 | static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags) | 513 | static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port) |
532 | { | 514 | { |
533 | struct bnx2x *bp = params->bp; | ||
534 | u32 val; | 515 | u32 val; |
535 | 516 | ||
536 | if (phy_flags & PHY_XGXS_FLAG) { | 517 | DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n"); |
537 | DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n"); | ||
538 | val = XGXS_RESET_BITS; | ||
539 | 518 | ||
540 | } else { /* SerDes */ | 519 | val = SERDES_RESET_BITS << (port*16); |
541 | DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n"); | ||
542 | val = SERDES_RESET_BITS; | ||
543 | } | ||
544 | |||
545 | val = val << (params->port*16); | ||
546 | 520 | ||
547 | /* reset and unreset the SerDes/XGXS */ | 521 | /* reset and unreset the SerDes/XGXS */ |
548 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, | 522 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); |
549 | val); | ||
550 | udelay(500); | 523 | udelay(500); |
551 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, | 524 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); |
552 | val); | 525 | |
553 | bnx2x_set_phy_mdio(params, phy_flags); | 526 | bnx2x_set_serdes_access(bp, port); |
527 | |||
528 | REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + | ||
529 | port*0x10, | ||
530 | DEFAULT_PHY_DEV_ADDR); | ||
554 | } | 531 | } |
555 | 532 | ||
533 | static void bnx2x_xgxs_deassert(struct link_params *params) | ||
534 | { | ||
535 | struct bnx2x *bp = params->bp; | ||
536 | u8 port; | ||
537 | u32 val; | ||
538 | DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n"); | ||
539 | port = params->port; | ||
540 | |||
541 | val = XGXS_RESET_BITS << (port*16); | ||
542 | |||
543 | /* reset and unreset the SerDes/XGXS */ | ||
544 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); | ||
545 | udelay(500); | ||
546 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); | ||
547 | |||
548 | REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + | ||
549 | port*0x18, 0); | ||
550 | REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, | ||
551 | params->phy[INT_PHY].def_md_devad); | ||
552 | } | ||
556 | void bnx2x_link_status_update(struct link_params *params, | 553 | void bnx2x_link_status_update(struct link_params *params, |
557 | struct link_vars *vars) | 554 | struct link_vars *vars) |
558 | { | 555 | { |
@@ -799,25 +796,32 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, | |||
799 | return 0; | 796 | return 0; |
800 | } | 797 | } |
801 | 798 | ||
802 | static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port) | 799 | static u32 bnx2x_get_emac_base(struct bnx2x *bp, |
800 | u32 mdc_mdio_access, u8 port) | ||
803 | { | 801 | { |
804 | u32 emac_base; | 802 | u32 emac_base = 0; |
805 | 803 | switch (mdc_mdio_access) { | |
806 | switch (ext_phy_type) { | 804 | case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE: |
807 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: | 805 | break; |
808 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: | 806 | case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0: |
809 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: | 807 | if (REG_RD(bp, NIG_REG_PORT_SWAP)) |
810 | /* All MDC/MDIO is directed through single EMAC */ | 808 | emac_base = GRCBASE_EMAC1; |
809 | else | ||
810 | emac_base = GRCBASE_EMAC0; | ||
811 | break; | ||
812 | case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1: | ||
811 | if (REG_RD(bp, NIG_REG_PORT_SWAP)) | 813 | if (REG_RD(bp, NIG_REG_PORT_SWAP)) |
812 | emac_base = GRCBASE_EMAC0; | 814 | emac_base = GRCBASE_EMAC0; |
813 | else | 815 | else |
814 | emac_base = GRCBASE_EMAC1; | 816 | emac_base = GRCBASE_EMAC1; |
815 | break; | 817 | break; |
816 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: | 818 | case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH: |
819 | emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; | ||
820 | break; | ||
821 | case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED: | ||
817 | emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1; | 822 | emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1; |
818 | break; | 823 | break; |
819 | default: | 824 | default: |
820 | emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; | ||
821 | break; | 825 | break; |
822 | } | 826 | } |
823 | return emac_base; | 827 | return emac_base; |
@@ -1147,7 +1151,7 @@ static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy, | |||
1147 | control2); | 1151 | control2); |
1148 | 1152 | ||
1149 | if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && | 1153 | if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && |
1150 | (params->speed_cap_mask & | 1154 | (phy->speed_cap_mask & |
1151 | PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { | 1155 | PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { |
1152 | DP(NETIF_MSG_LINK, "XGXS\n"); | 1156 | DP(NETIF_MSG_LINK, "XGXS\n"); |
1153 | 1157 | ||
@@ -1777,7 +1781,7 @@ static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, | |||
1777 | struct bnx2x *bp = params->bp; | 1781 | struct bnx2x *bp = params->bp; |
1778 | u16 new_line_speed , gp_status; | 1782 | u16 new_line_speed , gp_status; |
1779 | u8 rc = 0; | 1783 | u8 rc = 0; |
1780 | u32 ext_phy_type; | 1784 | |
1781 | /* Read gp_status */ | 1785 | /* Read gp_status */ |
1782 | CL45_RD_OVER_CL22(bp, phy, | 1786 | CL45_RD_OVER_CL22(bp, phy, |
1783 | MDIO_REG_BANK_GP_STATUS, | 1787 | MDIO_REG_BANK_GP_STATUS, |
@@ -1885,30 +1889,7 @@ static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, | |||
1885 | } | 1889 | } |
1886 | 1890 | ||
1887 | vars->line_speed = new_line_speed; | 1891 | vars->line_speed = new_line_speed; |
1888 | vars->link_status |= LINK_STATUS_SERDES_LINK; | ||
1889 | ext_phy_type = params->phy[EXT_PHY1].type; | ||
1890 | if ((params->req_line_speed == SPEED_AUTO_NEG) && | ||
1891 | ((ext_phy_type == | ||
1892 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) || | ||
1893 | (ext_phy_type == | ||
1894 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || | ||
1895 | (ext_phy_type == | ||
1896 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) || | ||
1897 | (ext_phy_type == | ||
1898 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) { | ||
1899 | vars->autoneg = AUTO_NEG_ENABLED; | ||
1900 | |||
1901 | if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { | ||
1902 | vars->autoneg |= AUTO_NEG_COMPLETE; | ||
1903 | vars->link_status |= | ||
1904 | LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; | ||
1905 | } | ||
1906 | 1892 | ||
1907 | vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED; | ||
1908 | vars->link_status |= | ||
1909 | LINK_STATUS_PARALLEL_DETECTION_USED; | ||
1910 | |||
1911 | } | ||
1912 | 1893 | ||
1913 | } else { /* link_down */ | 1894 | } else { /* link_down */ |
1914 | DP(NETIF_MSG_LINK, "phy link down\n"); | 1895 | DP(NETIF_MSG_LINK, "phy link down\n"); |
@@ -1917,14 +1898,12 @@ static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, | |||
1917 | 1898 | ||
1918 | vars->duplex = DUPLEX_FULL; | 1899 | vars->duplex = DUPLEX_FULL; |
1919 | vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; | 1900 | vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; |
1920 | vars->autoneg = AUTO_NEG_DISABLED; | ||
1921 | vars->mac_type = MAC_TYPE_NONE; | 1901 | vars->mac_type = MAC_TYPE_NONE; |
1922 | 1902 | ||
1923 | if ((params->req_line_speed == SPEED_AUTO_NEG) && | 1903 | if ((phy->req_line_speed == SPEED_AUTO_NEG) && |
1924 | (SINGLE_MEDIA_DIRECT(params))) { | 1904 | SINGLE_MEDIA_DIRECT(params)) { |
1925 | /* Check signal is detected */ | 1905 | /* Check signal is detected */ |
1926 | bnx2x_check_fallback_to_cl37(¶ms->phy[INT_PHY], | 1906 | bnx2x_check_fallback_to_cl37(phy, params); |
1927 | params); | ||
1928 | } | 1907 | } |
1929 | } | 1908 | } |
1930 | 1909 | ||
@@ -2078,6 +2057,7 @@ static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy, | |||
2078 | 2057 | ||
2079 | return rc; | 2058 | return rc; |
2080 | } | 2059 | } |
2060 | |||
2081 | /*****************************************************************************/ | 2061 | /*****************************************************************************/ |
2082 | /* External Phy section */ | 2062 | /* External Phy section */ |
2083 | /*****************************************************************************/ | 2063 | /*****************************************************************************/ |
@@ -2091,19 +2071,18 @@ void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port) | |||
2091 | } | 2071 | } |
2092 | 2072 | ||
2093 | static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port, | 2073 | static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port, |
2094 | u32 shmem_base, u32 spirom_ver) | 2074 | u32 spirom_ver, u32 ver_addr) |
2095 | { | 2075 | { |
2096 | DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n", | 2076 | DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n", |
2097 | (u16)(spirom_ver>>16), (u16)spirom_ver, port); | 2077 | (u16)(spirom_ver>>16), (u16)spirom_ver, port); |
2098 | REG_WR(bp, shmem_base + | 2078 | |
2099 | offsetof(struct shmem_region, | 2079 | if (ver_addr) |
2100 | port_mb[port].ext_phy_fw_version), | 2080 | REG_WR(bp, ver_addr, spirom_ver); |
2101 | spirom_ver); | ||
2102 | } | 2081 | } |
2103 | 2082 | ||
2104 | static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port, | 2083 | static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, |
2105 | struct bnx2x_phy *phy, | 2084 | struct bnx2x_phy *phy, |
2106 | u32 shmem_base) | 2085 | u8 port) |
2107 | { | 2086 | { |
2108 | u16 fw_ver1, fw_ver2; | 2087 | u16 fw_ver1, fw_ver2; |
2109 | 2088 | ||
@@ -2111,13 +2090,12 @@ static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port, | |||
2111 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); | 2090 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); |
2112 | bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, | 2091 | bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, |
2113 | MDIO_PMA_REG_ROM_VER2, &fw_ver2); | 2092 | MDIO_PMA_REG_ROM_VER2, &fw_ver2); |
2114 | bnx2x_save_spirom_version(bp, port, shmem_base, | 2093 | bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2), |
2115 | (u32)(fw_ver1<<16 | fw_ver2)); | 2094 | phy->ver_addr); |
2116 | } | 2095 | } |
2117 | 2096 | ||
2118 | static void bnx2x_save_8481_spirom_version(struct bnx2x_phy *phy, | 2097 | static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy, |
2119 | struct link_params *params, | 2098 | struct link_params *params) |
2120 | u32 shmem_base) | ||
2121 | { | 2099 | { |
2122 | u16 val, fw_ver1, fw_ver2, cnt; | 2100 | u16 val, fw_ver1, fw_ver2, cnt; |
2123 | struct bnx2x *bp = params->bp; | 2101 | struct bnx2x *bp = params->bp; |
@@ -2137,9 +2115,9 @@ static void bnx2x_save_8481_spirom_version(struct bnx2x_phy *phy, | |||
2137 | udelay(5); | 2115 | udelay(5); |
2138 | } | 2116 | } |
2139 | if (cnt == 100) { | 2117 | if (cnt == 100) { |
2140 | DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(1)\n"); | 2118 | DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n"); |
2141 | bnx2x_save_spirom_version(bp, params->port, | 2119 | bnx2x_save_spirom_version(bp, params->port, 0, |
2142 | shmem_base, 0); | 2120 | phy->ver_addr); |
2143 | return; | 2121 | return; |
2144 | } | 2122 | } |
2145 | 2123 | ||
@@ -2169,7 +2147,6 @@ static void bnx2x_save_8481_spirom_version(struct bnx2x_phy *phy, | |||
2169 | bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1, | 2147 | bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1, |
2170 | phy->ver_addr); | 2148 | phy->ver_addr); |
2171 | } | 2149 | } |
2172 | |||
2173 | static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy) | 2150 | static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy) |
2174 | { | 2151 | { |
2175 | /* This is only required for 8073A1, version 102 only */ | 2152 | /* This is only required for 8073A1, version 102 only */ |
@@ -2250,7 +2227,7 @@ static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy) | |||
2250 | 2227 | ||
2251 | static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, | 2228 | static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, |
2252 | struct bnx2x_phy *phy, | 2229 | struct bnx2x_phy *phy, |
2253 | u8 port, u32 shmem_base) | 2230 | u8 port) |
2254 | { | 2231 | { |
2255 | /* Boot port from external ROM */ | 2232 | /* Boot port from external ROM */ |
2256 | /* EDC grst */ | 2233 | /* EDC grst */ |
@@ -2288,7 +2265,7 @@ static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, | |||
2288 | bnx2x_cl45_write(bp, phy, | 2265 | bnx2x_cl45_write(bp, phy, |
2289 | MDIO_PMA_DEVAD, | 2266 | MDIO_PMA_DEVAD, |
2290 | MDIO_PMA_REG_MISC_CTRL1, 0x0000); | 2267 | MDIO_PMA_REG_MISC_CTRL1, 0x0000); |
2291 | bnx2x_save_bcm_spirom_ver(bp, port, phy, shmem_base); | 2268 | bnx2x_save_bcm_spirom_ver(bp, phy, port); |
2292 | } | 2269 | } |
2293 | 2270 | ||
2294 | static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy, | 2271 | static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy, |
@@ -2326,9 +2303,7 @@ static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy, | |||
2326 | MDIO_PMA_REG_MISC_CTRL1, 0x0000); | 2303 | MDIO_PMA_REG_MISC_CTRL1, 0x0000); |
2327 | 2304 | ||
2328 | msleep(200); | 2305 | msleep(200); |
2329 | bnx2x_save_bcm_spirom_ver(bp, params->port, | 2306 | bnx2x_save_bcm_spirom_ver(bp, phy, params->port); |
2330 | phy, | ||
2331 | params->shmem_base); | ||
2332 | } | 2307 | } |
2333 | 2308 | ||
2334 | static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, | 2309 | static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, |
@@ -3055,7 +3030,7 @@ static void bnx2x_set_preemphasis(struct bnx2x_phy *phy, | |||
3055 | } | 3030 | } |
3056 | } | 3031 | } |
3057 | 3032 | ||
3058 | static void bnx2x_8481_set_led(struct bnx2x *bp, | 3033 | static void bnx2x_848xx_set_led(struct bnx2x *bp, |
3059 | struct bnx2x_phy *phy) | 3034 | struct bnx2x_phy *phy) |
3060 | { | 3035 | { |
3061 | u16 val; | 3036 | u16 val; |
@@ -3195,7 +3170,6 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, | |||
3195 | /* HW reset */ | 3170 | /* HW reset */ |
3196 | bnx2x_ext_phy_hw_reset(bp, params->port); | 3171 | bnx2x_ext_phy_hw_reset(bp, params->port); |
3197 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); | 3172 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); |
3198 | |||
3199 | bnx2x_wait_reset_complete(bp, phy); | 3173 | bnx2x_wait_reset_complete(bp, phy); |
3200 | 3174 | ||
3201 | /* Wait until fw is loaded */ | 3175 | /* Wait until fw is loaded */ |
@@ -3262,7 +3236,7 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, | |||
3262 | MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, | 3236 | MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, |
3263 | 0x0004); | 3237 | 0x0004); |
3264 | } | 3238 | } |
3265 | bnx2x_save_bcm_spirom_ver(bp, params->port, phy, params->shmem_base); | 3239 | bnx2x_save_bcm_spirom_ver(bp, phy, params->port); |
3266 | return 0; | 3240 | return 0; |
3267 | } | 3241 | } |
3268 | 3242 | ||
@@ -3512,6 +3486,7 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, | |||
3512 | return 0; | 3486 | return 0; |
3513 | } | 3487 | } |
3514 | 3488 | ||
3489 | |||
3515 | static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, | 3490 | static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, |
3516 | struct link_params *params, | 3491 | struct link_params *params, |
3517 | struct link_vars *vars) | 3492 | struct link_vars *vars) |
@@ -3690,7 +3665,7 @@ static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, | |||
3690 | 3665 | ||
3691 | bnx2x_cl45_write(bp, phy, | 3666 | bnx2x_cl45_write(bp, phy, |
3692 | MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000); | 3667 | MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000); |
3693 | bnx2x_8481_set_led(bp, phy); | 3668 | bnx2x_848xx_set_led(bp, phy); |
3694 | /* set 1000 speed advertisement */ | 3669 | /* set 1000 speed advertisement */ |
3695 | bnx2x_cl45_read(bp, phy, | 3670 | bnx2x_cl45_read(bp, phy, |
3696 | MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, | 3671 | MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, |
@@ -3795,7 +3770,7 @@ static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, | |||
3795 | 1); | 3770 | 1); |
3796 | } | 3771 | } |
3797 | /* Save spirom version */ | 3772 | /* Save spirom version */ |
3798 | bnx2x_save_8481_spirom_version(phy, params, params->shmem_base); | 3773 | bnx2x_save_848xx_spirom_version(phy, params); |
3799 | 3774 | ||
3800 | return 0; | 3775 | return 0; |
3801 | } | 3776 | } |
@@ -3935,6 +3910,7 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, | |||
3935 | module plugged in/out */ | 3910 | module plugged in/out */ |
3936 | } | 3911 | } |
3937 | 3912 | ||
3913 | |||
3938 | static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy, | 3914 | static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy, |
3939 | struct link_params *params, | 3915 | struct link_params *params, |
3940 | struct link_vars *vars) | 3916 | struct link_vars *vars) |
@@ -4011,7 +3987,6 @@ static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, | |||
4011 | } | 3987 | } |
4012 | return link_up; | 3988 | return link_up; |
4013 | } | 3989 | } |
4014 | |||
4015 | static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy, | 3990 | static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy, |
4016 | struct link_params *params, | 3991 | struct link_params *params, |
4017 | struct link_vars *vars) | 3992 | struct link_vars *vars) |
@@ -4038,6 +4013,7 @@ static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy, | |||
4038 | } | 4013 | } |
4039 | return link_up; | 4014 | return link_up; |
4040 | } | 4015 | } |
4016 | |||
4041 | static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, | 4017 | static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, |
4042 | struct link_params *params, | 4018 | struct link_params *params, |
4043 | struct link_vars *vars) | 4019 | struct link_vars *vars) |
@@ -4183,7 +4159,6 @@ static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy, | |||
4183 | pause_result); | 4159 | pause_result); |
4184 | } | 4160 | } |
4185 | } | 4161 | } |
4186 | |||
4187 | static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, | 4162 | static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, |
4188 | struct link_params *params, | 4163 | struct link_params *params, |
4189 | struct link_vars *vars) | 4164 | struct link_vars *vars) |
@@ -4415,6 +4390,7 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, | |||
4415 | 4390 | ||
4416 | return link_up; | 4391 | return link_up; |
4417 | } | 4392 | } |
4393 | |||
4418 | static void bnx2x_link_int_enable(struct link_params *params) | 4394 | static void bnx2x_link_int_enable(struct link_params *params) |
4419 | { | 4395 | { |
4420 | u8 port = params->port; | 4396 | u8 port = params->port; |
@@ -4616,7 +4592,6 @@ static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len) | |||
4616 | (*len)--; | 4592 | (*len)--; |
4617 | return 0; | 4593 | return 0; |
4618 | } | 4594 | } |
4619 | |||
4620 | u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, | 4595 | u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, |
4621 | u8 *version, u16 len) | 4596 | u8 *version, u16 len) |
4622 | { | 4597 | { |
@@ -4706,6 +4681,7 @@ static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy, | |||
4706 | bnx2x_cl45_write(bp, phy, | 4681 | bnx2x_cl45_write(bp, phy, |
4707 | MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100); | 4682 | MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100); |
4708 | } | 4683 | } |
4684 | |||
4709 | /* | 4685 | /* |
4710 | *------------------------------------------------------------------------ | 4686 | *------------------------------------------------------------------------ |
4711 | * bnx2x_override_led_value - | 4687 | * bnx2x_override_led_value - |
@@ -4892,7 +4868,7 @@ u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed) | |||
4892 | u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars) | 4868 | u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars) |
4893 | { | 4869 | { |
4894 | struct bnx2x *bp = params->bp; | 4870 | struct bnx2x *bp = params->bp; |
4895 | u16 gp_status = 0; | 4871 | u16 gp_status = 0, phy_index = 0; |
4896 | 4872 | ||
4897 | CL45_RD_OVER_CL22(bp, ¶ms->phy[INT_PHY], | 4873 | CL45_RD_OVER_CL22(bp, ¶ms->phy[INT_PHY], |
4898 | MDIO_REG_BANK_GP_STATUS, | 4874 | MDIO_REG_BANK_GP_STATUS, |
@@ -4902,86 +4878,59 @@ u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars) | |||
4902 | if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { | 4878 | if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { |
4903 | u8 ext_phy_link_up = 1; | 4879 | u8 ext_phy_link_up = 1; |
4904 | struct link_vars temp_vars; | 4880 | struct link_vars temp_vars; |
4905 | if (params->phy[EXT_PHY1].read_status) | 4881 | for (phy_index = EXT_PHY1; phy_index < params->num_phys; |
4906 | ext_phy_link_up &= | 4882 | phy_index++) { |
4907 | params->phy[EXT_PHY1].read_status( | 4883 | if (params->phy[phy_index].read_status) |
4908 | ¶ms->phy[EXT_PHY1], | 4884 | ext_phy_link_up &= |
4885 | params->phy[phy_index].read_status( | ||
4886 | ¶ms->phy[phy_index], | ||
4909 | params, &temp_vars); | 4887 | params, &temp_vars); |
4888 | } | ||
4910 | if (ext_phy_link_up) | 4889 | if (ext_phy_link_up) |
4911 | return 0; | 4890 | return 0; |
4912 | } | 4891 | } |
4913 | |||
4914 | return -ESRCH; | 4892 | return -ESRCH; |
4915 | } | 4893 | } |
4916 | 4894 | ||
4917 | static u8 bnx2x_link_initialize(struct link_params *params, | 4895 | static u8 bnx2x_link_initialize(struct link_params *params, |
4918 | struct link_vars *vars) | 4896 | struct link_vars *vars) |
4919 | { | 4897 | { |
4920 | struct bnx2x *bp = params->bp; | ||
4921 | u8 rc = 0; | 4898 | u8 rc = 0; |
4922 | u8 phy_index, non_ext_phy; | 4899 | u8 phy_index, non_ext_phy; |
4923 | struct bnx2x_phy *ext_phy = ¶ms->phy[EXT_PHY1]; | 4900 | struct bnx2x *bp = params->bp; |
4924 | struct bnx2x_phy *int_phy = ¶ms->phy[INT_PHY]; | 4901 | /** |
4925 | /* Activate the external PHY */ | 4902 | * In case of external phy existence, the line speed would be the |
4926 | 4903 | * line speed linked up by the external phy. In case it is direct | |
4927 | bnx2x_set_aer_mmd(params, int_phy); | 4904 | * only, then the line_speed during initialization will be |
4928 | 4905 | * equal to the req_line_speed | |
4929 | if (vars->phy_flags & PHY_XGXS_FLAG) | 4906 | */ |
4930 | bnx2x_set_master_ln(params, int_phy); | 4907 | vars->line_speed = params->phy[INT_PHY].req_line_speed; |
4931 | |||
4932 | rc = bnx2x_reset_unicore(params, int_phy, | ||
4933 | int_phy->type == | ||
4934 | PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT); | ||
4935 | /* reset the SerDes and wait for reset bit return low */ | ||
4936 | if (rc != 0) | ||
4937 | return rc; | ||
4938 | |||
4939 | bnx2x_set_aer_mmd(params, int_phy); | ||
4940 | |||
4941 | /* setting the masterLn_def again after the reset */ | ||
4942 | if (vars->phy_flags & PHY_XGXS_FLAG) { | ||
4943 | bnx2x_set_master_ln(params, int_phy); | ||
4944 | bnx2x_set_swap_lanes(params, int_phy); | ||
4945 | } | ||
4946 | 4908 | ||
4947 | if (vars->phy_flags & PHY_XGXS_FLAG) { | 4909 | /** |
4948 | if ((params->req_line_speed && | 4910 | * Initialize the internal phy in case this is a direct board |
4949 | ((params->req_line_speed == SPEED_100) || | 4911 | * (no external phys), or this board has external phy which requires |
4950 | (params->req_line_speed == SPEED_10))) || | 4912 | * to first. |
4951 | (!params->req_line_speed && | 4913 | */ |
4952 | (params->speed_cap_mask >= | ||
4953 | PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) && | ||
4954 | (params->speed_cap_mask < | ||
4955 | PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) | ||
4956 | )) { | ||
4957 | vars->phy_flags |= PHY_SGMII_FLAG; | ||
4958 | } else { | ||
4959 | vars->phy_flags &= ~PHY_SGMII_FLAG; | ||
4960 | } | ||
4961 | } | ||
4962 | /* In case of external phy existance, the line speed would be the | ||
4963 | line speed linked up by the external phy. In case it is direct only, | ||
4964 | then the line_speed during initialization will be equal to the | ||
4965 | req_line_speed*/ | ||
4966 | vars->line_speed = params->req_line_speed; | ||
4967 | 4914 | ||
4968 | bnx2x_calc_ieee_aneg_adv(int_phy, params, &vars->ieee_fc); | 4915 | if (params->phy[INT_PHY].config_init) |
4916 | params->phy[INT_PHY].config_init( | ||
4917 | ¶ms->phy[INT_PHY], | ||
4918 | params, vars); | ||
4969 | 4919 | ||
4970 | /* init ext phy and enable link state int */ | 4920 | /* init ext phy and enable link state int */ |
4971 | non_ext_phy = ((ext_phy->type == | 4921 | non_ext_phy = (SINGLE_MEDIA_DIRECT(params) || |
4972 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) || | ||
4973 | (params->loopback_mode == LOOPBACK_XGXS_10)); | 4922 | (params->loopback_mode == LOOPBACK_XGXS_10)); |
4974 | 4923 | ||
4975 | if (non_ext_phy || | 4924 | if (non_ext_phy || |
4976 | (ext_phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || | 4925 | (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) || |
4977 | (ext_phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) || | ||
4978 | (ext_phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) || | ||
4979 | (params->loopback_mode == LOOPBACK_EXT_PHY)) { | 4926 | (params->loopback_mode == LOOPBACK_EXT_PHY)) { |
4927 | struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; | ||
4980 | if (vars->line_speed == SPEED_AUTO_NEG) | 4928 | if (vars->line_speed == SPEED_AUTO_NEG) |
4981 | bnx2x_set_parallel_detection(int_phy, params); | 4929 | bnx2x_set_parallel_detection(phy, params); |
4982 | bnx2x_init_internal_phy(int_phy, params, vars); | 4930 | bnx2x_init_internal_phy(phy, params, vars); |
4983 | } | 4931 | } |
4984 | 4932 | ||
4933 | /* Init external phy*/ | ||
4985 | if (!non_ext_phy) | 4934 | if (!non_ext_phy) |
4986 | for (phy_index = EXT_PHY1; phy_index < params->num_phys; | 4935 | for (phy_index = EXT_PHY1; phy_index < params->num_phys; |
4987 | phy_index++) { | 4936 | phy_index++) { |
@@ -4997,7 +4946,6 @@ static u8 bnx2x_link_initialize(struct link_params *params, | |||
4997 | NIG_STATUS_XGXS0_LINK_STATUS | | 4946 | NIG_STATUS_XGXS0_LINK_STATUS | |
4998 | NIG_STATUS_SERDES0_LINK_STATUS | | 4947 | NIG_STATUS_SERDES0_LINK_STATUS | |
4999 | NIG_MASK_MI_INT)); | 4948 | NIG_MASK_MI_INT)); |
5000 | |||
5001 | return rc; | 4949 | return rc; |
5002 | } | 4950 | } |
5003 | 4951 | ||
@@ -5122,7 +5070,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) | |||
5122 | 5070 | ||
5123 | vars->phy_flags = PHY_XGXS_FLAG; | 5071 | vars->phy_flags = PHY_XGXS_FLAG; |
5124 | 5072 | ||
5125 | bnx2x_phy_deassert(params, vars->phy_flags); | 5073 | bnx2x_xgxs_deassert(params); |
5126 | 5074 | ||
5127 | /* set bmac loopback */ | 5075 | /* set bmac loopback */ |
5128 | bnx2x_bmac_enable(params, vars, 1); | 5076 | bnx2x_bmac_enable(params, vars, 1); |
@@ -5140,7 +5088,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) | |||
5140 | 5088 | ||
5141 | vars->phy_flags = PHY_XGXS_FLAG; | 5089 | vars->phy_flags = PHY_XGXS_FLAG; |
5142 | 5090 | ||
5143 | bnx2x_phy_deassert(params, vars->phy_flags); | 5091 | bnx2x_xgxs_deassert(params); |
5144 | /* set bmac loopback */ | 5092 | /* set bmac loopback */ |
5145 | bnx2x_emac_enable(params, vars, 1); | 5093 | bnx2x_emac_enable(params, vars, 1); |
5146 | bnx2x_emac_program(params, vars); | 5094 | bnx2x_emac_program(params, vars); |
@@ -5161,7 +5109,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) | |||
5161 | NIG_REG_XGXS0_CTRL_PHY_ADDR+ | 5109 | NIG_REG_XGXS0_CTRL_PHY_ADDR+ |
5162 | params->port*0x18); | 5110 | params->port*0x18); |
5163 | 5111 | ||
5164 | bnx2x_phy_deassert(params, vars->phy_flags); | 5112 | bnx2x_xgxs_deassert(params); |
5165 | bnx2x_link_initialize(params, vars); | 5113 | bnx2x_link_initialize(params, vars); |
5166 | 5114 | ||
5167 | vars->mac_type = MAC_TYPE_BMAC; | 5115 | vars->mac_type = MAC_TYPE_BMAC; |
@@ -5194,8 +5142,9 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) | |||
5194 | /* No loopback */ | 5142 | /* No loopback */ |
5195 | { | 5143 | { |
5196 | if (params->switch_cfg == SWITCH_CFG_10G) | 5144 | if (params->switch_cfg == SWITCH_CFG_10G) |
5197 | vars->phy_flags = PHY_XGXS_FLAG; | 5145 | bnx2x_xgxs_deassert(params); |
5198 | bnx2x_phy_deassert(params, vars->phy_flags); | 5146 | else |
5147 | bnx2x_serdes_deassert(bp, params->port); | ||
5199 | bnx2x_link_initialize(params, vars); | 5148 | bnx2x_link_initialize(params, vars); |
5200 | msleep(30); | 5149 | msleep(30); |
5201 | bnx2x_link_int_enable(params); | 5150 | bnx2x_link_int_enable(params); |
@@ -5282,9 +5231,7 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, | |||
5282 | u8 reset_ext_phy) | 5231 | u8 reset_ext_phy) |
5283 | { | 5232 | { |
5284 | struct bnx2x *bp = params->bp; | 5233 | struct bnx2x *bp = params->bp; |
5285 | |||
5286 | u8 phy_index, port = params->port; | 5234 | u8 phy_index, port = params->port; |
5287 | |||
5288 | DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); | 5235 | DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); |
5289 | /* disable attentions */ | 5236 | /* disable attentions */ |
5290 | vars->link_status = 0; | 5237 | vars->link_status = 0; |
@@ -5340,7 +5287,6 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, | |||
5340 | return 0; | 5287 | return 0; |
5341 | } | 5288 | } |
5342 | 5289 | ||
5343 | |||
5344 | static u8 bnx2x_update_link_down(struct link_params *params, | 5290 | static u8 bnx2x_update_link_down(struct link_params *params, |
5345 | struct link_vars *vars) | 5291 | struct link_vars *vars) |
5346 | { | 5292 | { |
@@ -6078,7 +6024,7 @@ static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, | |||
6078 | } | 6024 | } |
6079 | phy->addr = (u8)phy_addr; | 6025 | phy->addr = (u8)phy_addr; |
6080 | phy->mdio_ctrl = bnx2x_get_emac_base(bp, | 6026 | phy->mdio_ctrl = bnx2x_get_emac_base(bp, |
6081 | phy->type, | 6027 | SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH, |
6082 | port); | 6028 | port); |
6083 | phy->def_md_devad = DEFAULT_PHY_DEV_ADDR; | 6029 | phy->def_md_devad = DEFAULT_PHY_DEV_ADDR; |
6084 | 6030 | ||
@@ -6095,14 +6041,15 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, | |||
6095 | u8 port, | 6041 | u8 port, |
6096 | struct bnx2x_phy *phy) | 6042 | struct bnx2x_phy *phy) |
6097 | { | 6043 | { |
6098 | u32 ext_phy_config, phy_type; | 6044 | u32 ext_phy_config, phy_type, config2; |
6099 | 6045 | u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH; | |
6100 | ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base, | 6046 | ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base, |
6101 | phy_index, port); | 6047 | phy_index, port); |
6102 | phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); | 6048 | phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); |
6103 | /* Select the phy type */ | 6049 | /* Select the phy type */ |
6104 | switch (phy_type) { | 6050 | switch (phy_type) { |
6105 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: | 6051 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: |
6052 | mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED; | ||
6106 | *phy = phy_8073; | 6053 | *phy = phy_8073; |
6107 | break; | 6054 | break; |
6108 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: | 6055 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: |
@@ -6112,14 +6059,17 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, | |||
6112 | *phy = phy_8706; | 6059 | *phy = phy_8706; |
6113 | break; | 6060 | break; |
6114 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: | 6061 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: |
6062 | mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; | ||
6115 | *phy = phy_8726; | 6063 | *phy = phy_8726; |
6116 | break; | 6064 | break; |
6117 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: | 6065 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: |
6118 | /* BCM8727_NOC => BCM8727 no over current */ | 6066 | /* BCM8727_NOC => BCM8727 no over current */ |
6067 | mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; | ||
6119 | *phy = phy_8727; | 6068 | *phy = phy_8727; |
6120 | phy->flags |= FLAGS_NOC; | 6069 | phy->flags |= FLAGS_NOC; |
6121 | break; | 6070 | break; |
6122 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: | 6071 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: |
6072 | mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; | ||
6123 | *phy = phy_8727; | 6073 | *phy = phy_8727; |
6124 | break; | 6074 | break; |
6125 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: | 6075 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: |
@@ -6141,8 +6091,36 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, | |||
6141 | 6091 | ||
6142 | phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config); | 6092 | phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config); |
6143 | bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index); | 6093 | bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index); |
6144 | phy->mdio_ctrl = bnx2x_get_emac_base(bp, phy->type, port); | ||
6145 | 6094 | ||
6095 | /** | ||
6096 | * The shmem address of the phy version is located on different | ||
6097 | * structures. In case this structure is too old, do not set | ||
6098 | * the address | ||
6099 | */ | ||
6100 | config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region, | ||
6101 | dev_info.shared_hw_config.config2)); | ||
6102 | |||
6103 | phy->ver_addr = shmem_base + offsetof(struct shmem_region, | ||
6104 | port_mb[port].ext_phy_fw_version); | ||
6105 | |||
6106 | /* Check specific mdc mdio settings */ | ||
6107 | if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK) | ||
6108 | mdc_mdio_access = config2 & | ||
6109 | SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK; | ||
6110 | |||
6111 | phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port); | ||
6112 | |||
6113 | /** | ||
6114 | * In case mdc/mdio_access of the external phy is different than the | ||
6115 | * mdc/mdio access of the XGXS, a HW lock must be taken in each access | ||
6116 | * to prevent one port interfere with another port's CL45 operations. | ||
6117 | */ | ||
6118 | if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH) | ||
6119 | phy->flags |= FLAGS_HW_LOCK_REQUIRED; | ||
6120 | DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n", | ||
6121 | phy_type, port, phy_index); | ||
6122 | DP(NETIF_MSG_LINK, " addr=0x%x, mdio_ctl=0x%x\n", | ||
6123 | phy->addr, phy->mdio_ctrl); | ||
6146 | return 0; | 6124 | return 0; |
6147 | } | 6125 | } |
6148 | 6126 | ||
@@ -6262,7 +6240,6 @@ u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx) | |||
6262 | return 0; | 6240 | return 0; |
6263 | } | 6241 | } |
6264 | 6242 | ||
6265 | |||
6266 | static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) | 6243 | static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) |
6267 | { | 6244 | { |
6268 | struct bnx2x_phy phy[PORT_MAX]; | 6245 | struct bnx2x_phy phy[PORT_MAX]; |
@@ -6314,7 +6291,7 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) | |||
6314 | u16 fw_ver1; | 6291 | u16 fw_ver1; |
6315 | 6292 | ||
6316 | bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], | 6293 | bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], |
6317 | port, shmem_base); | 6294 | port); |
6318 | 6295 | ||
6319 | bnx2x_cl45_read(bp, phy_blk[port], | 6296 | bnx2x_cl45_read(bp, phy_blk[port], |
6320 | MDIO_PMA_DEVAD, | 6297 | MDIO_PMA_DEVAD, |
@@ -6427,7 +6404,7 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) | |||
6427 | u16 fw_ver1; | 6404 | u16 fw_ver1; |
6428 | 6405 | ||
6429 | bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], | 6406 | bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], |
6430 | port, shmem_base); | 6407 | port); |
6431 | bnx2x_cl45_read(bp, phy_blk[port], | 6408 | bnx2x_cl45_read(bp, phy_blk[port], |
6432 | MDIO_PMA_DEVAD, | 6409 | MDIO_PMA_DEVAD, |
6433 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); | 6410 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); |