diff options
author | Eilon Greenstein <eilong@broadcom.com> | 2009-02-12 03:37:02 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-16 02:31:31 -0500 |
commit | a35da8dbf1ff403633bb6256fba691b224f17f61 (patch) | |
tree | 1b0f47d0dcb97b27b5e390a940de57b6431903a3 /drivers | |
parent | 285771852891b52a740b4ab2f2903cbfef5ec6a9 (diff) |
bnx2x: Saving PHY FW version
Some PHYs (like the BCM8726) FW version cannot be read after activating the
PHY, so we need to save this information
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')
-rw-r--r-- | drivers/net/bnx2x_hsi.h | 2 | ||||
-rw-r--r-- | drivers/net/bnx2x_link.c | 180 |
2 files changed, 92 insertions, 90 deletions
diff --git a/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h index 7b9acb3667ef..7a62bfd18aa8 100644 --- a/drivers/net/bnx2x_hsi.h +++ b/drivers/net/bnx2x_hsi.h | |||
@@ -634,6 +634,8 @@ struct drv_port_mb { | |||
634 | 634 | ||
635 | u32 stat_nig_timer; | 635 | u32 stat_nig_timer; |
636 | 636 | ||
637 | /* MCP firmware does not use this field */ | ||
638 | u32 ext_phy_fw_version; | ||
637 | 639 | ||
638 | }; | 640 | }; |
639 | 641 | ||
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index bed11b9c2c2d..ffa412f63c96 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c | |||
@@ -2047,6 +2047,31 @@ static void bnx2x_ext_phy_reset(struct link_params *params, | |||
2047 | } | 2047 | } |
2048 | } | 2048 | } |
2049 | 2049 | ||
2050 | |||
2051 | static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port, | ||
2052 | u32 shmem_base, u32 spirom_ver) | ||
2053 | { | ||
2054 | DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x\n", | ||
2055 | (u16)(spirom_ver>>16), (u16)spirom_ver); | ||
2056 | REG_WR(bp, shmem_base + | ||
2057 | offsetof(struct shmem_region, | ||
2058 | port_mb[port].ext_phy_fw_version), | ||
2059 | spirom_ver); | ||
2060 | } | ||
2061 | |||
2062 | static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port, | ||
2063 | u32 ext_phy_type, u8 ext_phy_addr, | ||
2064 | u32 shmem_base) | ||
2065 | { | ||
2066 | u16 fw_ver1, fw_ver2; | ||
2067 | bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD, | ||
2068 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); | ||
2069 | bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD, | ||
2070 | MDIO_PMA_REG_ROM_VER2, &fw_ver2); | ||
2071 | bnx2x_save_spirom_version(bp, port, shmem_base, | ||
2072 | (u32)(fw_ver1<<16 | fw_ver2)); | ||
2073 | } | ||
2074 | |||
2050 | static void bnx2x_bcm8072_external_rom_boot(struct link_params *params) | 2075 | static void bnx2x_bcm8072_external_rom_boot(struct link_params *params) |
2051 | { | 2076 | { |
2052 | struct bnx2x *bp = params->bp; | 2077 | struct bnx2x *bp = params->bp; |
@@ -2055,7 +2080,6 @@ static void bnx2x_bcm8072_external_rom_boot(struct link_params *params) | |||
2055 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | 2080 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> |
2056 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | 2081 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); |
2057 | u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); | 2082 | u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); |
2058 | u16 fw_ver1, fw_ver2; | ||
2059 | 2083 | ||
2060 | /* Need to wait 200ms after reset */ | 2084 | /* Need to wait 200ms after reset */ |
2061 | msleep(200); | 2085 | msleep(200); |
@@ -2091,14 +2115,10 @@ static void bnx2x_bcm8072_external_rom_boot(struct link_params *params) | |||
2091 | /* Wait 100ms */ | 2115 | /* Wait 100ms */ |
2092 | msleep(100); | 2116 | msleep(100); |
2093 | 2117 | ||
2094 | /* Print the PHY FW version */ | 2118 | bnx2x_save_bcm_spirom_ver(bp, port, |
2095 | bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, | 2119 | ext_phy_type, |
2096 | MDIO_PMA_DEVAD, | 2120 | ext_phy_addr, |
2097 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); | 2121 | params->shmem_base); |
2098 | bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, | ||
2099 | MDIO_PMA_DEVAD, | ||
2100 | MDIO_PMA_REG_ROM_VER2, &fw_ver2); | ||
2101 | DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2); | ||
2102 | } | 2122 | } |
2103 | 2123 | ||
2104 | static u8 bnx2x_8073_is_snr_needed(struct link_params *params) | 2124 | static u8 bnx2x_8073_is_snr_needed(struct link_params *params) |
@@ -2200,9 +2220,8 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params) | |||
2200 | } | 2220 | } |
2201 | 2221 | ||
2202 | static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port, | 2222 | static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port, |
2203 | u8 ext_phy_addr) | 2223 | u8 ext_phy_addr, u32 shmem_base) |
2204 | { | 2224 | { |
2205 | u16 fw_ver1, fw_ver2; | ||
2206 | /* Boot port from external ROM */ | 2225 | /* Boot port from external ROM */ |
2207 | /* EDC grst */ | 2226 | /* EDC grst */ |
2208 | bnx2x_cl45_write(bp, port, | 2227 | bnx2x_cl45_write(bp, port, |
@@ -2252,17 +2271,10 @@ static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port, | |||
2252 | MDIO_PMA_DEVAD, | 2271 | MDIO_PMA_DEVAD, |
2253 | MDIO_PMA_REG_MISC_CTRL1, 0x0000); | 2272 | MDIO_PMA_REG_MISC_CTRL1, 0x0000); |
2254 | 2273 | ||
2255 | bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | 2274 | bnx2x_save_bcm_spirom_ver(bp, port, |
2256 | ext_phy_addr, | 2275 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, |
2257 | MDIO_PMA_DEVAD, | 2276 | ext_phy_addr, |
2258 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); | 2277 | shmem_base); |
2259 | bnx2x_cl45_read(bp, port, | ||
2260 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
2261 | ext_phy_addr, | ||
2262 | MDIO_PMA_DEVAD, | ||
2263 | MDIO_PMA_REG_ROM_VER2, &fw_ver2); | ||
2264 | DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2); | ||
2265 | |||
2266 | } | 2278 | } |
2267 | 2279 | ||
2268 | static void bnx2x_bcm8726_external_rom_boot(struct link_params *params) | 2280 | static void bnx2x_bcm8726_external_rom_boot(struct link_params *params) |
@@ -2310,6 +2322,10 @@ static void bnx2x_bcm8726_external_rom_boot(struct link_params *params) | |||
2310 | MDIO_PMA_REG_MISC_CTRL1, 0x0000); | 2322 | MDIO_PMA_REG_MISC_CTRL1, 0x0000); |
2311 | 2323 | ||
2312 | msleep(200); | 2324 | msleep(200); |
2325 | bnx2x_save_bcm_spirom_ver(bp, port, | ||
2326 | ext_phy_type, | ||
2327 | ext_phy_addr, | ||
2328 | params->shmem_base); | ||
2313 | } | 2329 | } |
2314 | 2330 | ||
2315 | static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port, | 2331 | static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port, |
@@ -3051,12 +3067,25 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
3051 | ext_phy_addr, | 3067 | ext_phy_addr, |
3052 | MDIO_WIS_DEVAD, | 3068 | MDIO_WIS_DEVAD, |
3053 | MDIO_WIS_REG_LASI_CNTL, 0x1); | 3069 | MDIO_WIS_REG_LASI_CNTL, 0x1); |
3070 | |||
3071 | bnx2x_save_bcm_spirom_ver(bp, params->port, | ||
3072 | ext_phy_type, | ||
3073 | ext_phy_addr, | ||
3074 | params->shmem_base); | ||
3054 | break; | 3075 | break; |
3055 | 3076 | ||
3056 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: | 3077 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: |
3057 | DP(NETIF_MSG_LINK, "XGXS 8706\n"); | 3078 | /* Wait until fw is loaded */ |
3058 | 3079 | for (cnt = 0; cnt < 100; cnt++) { | |
3059 | msleep(10); | 3080 | bnx2x_cl45_read(bp, params->port, ext_phy_type, |
3081 | ext_phy_addr, MDIO_PMA_DEVAD, | ||
3082 | MDIO_PMA_REG_ROM_VER1, &val); | ||
3083 | if (val) | ||
3084 | break; | ||
3085 | msleep(10); | ||
3086 | } | ||
3087 | DP(NETIF_MSG_LINK, "XGXS 8706 is initialized " | ||
3088 | "after %d ms\n", cnt); | ||
3060 | /* Force speed */ | 3089 | /* Force speed */ |
3061 | /* First enable LASI */ | 3090 | /* First enable LASI */ |
3062 | bnx2x_cl45_write(bp, params->port, | 3091 | bnx2x_cl45_write(bp, params->port, |
@@ -3123,7 +3152,10 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
3123 | 0x1200); | 3152 | 0x1200); |
3124 | 3153 | ||
3125 | } | 3154 | } |
3126 | 3155 | bnx2x_save_bcm_spirom_ver(bp, params->port, | |
3156 | ext_phy_type, | ||
3157 | ext_phy_addr, | ||
3158 | params->shmem_base); | ||
3127 | break; | 3159 | break; |
3128 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: | 3160 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: |
3129 | DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); | 3161 | DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); |
@@ -3404,6 +3436,8 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
3404 | break; | 3436 | break; |
3405 | } | 3437 | } |
3406 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: | 3438 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: |
3439 | { | ||
3440 | u16 fw_ver1, fw_ver2; | ||
3407 | DP(NETIF_MSG_LINK, | 3441 | DP(NETIF_MSG_LINK, |
3408 | "Setting the SFX7101 LASI indication\n"); | 3442 | "Setting the SFX7101 LASI indication\n"); |
3409 | 3443 | ||
@@ -3434,7 +3468,21 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
3434 | MDIO_AN_DEVAD, | 3468 | MDIO_AN_DEVAD, |
3435 | MDIO_AN_REG_CTRL, val); | 3469 | MDIO_AN_REG_CTRL, val); |
3436 | 3470 | ||
3471 | /* Save spirom version */ | ||
3472 | bnx2x_cl45_read(bp, params->port, ext_phy_type, | ||
3473 | ext_phy_addr, MDIO_PMA_DEVAD, | ||
3474 | MDIO_PMA_REG_7101_VER1, &fw_ver1); | ||
3475 | |||
3476 | bnx2x_cl45_read(bp, params->port, ext_phy_type, | ||
3477 | ext_phy_addr, MDIO_PMA_DEVAD, | ||
3478 | MDIO_PMA_REG_7101_VER2, &fw_ver2); | ||
3479 | |||
3480 | bnx2x_save_spirom_version(params->bp, params->port, | ||
3481 | params->shmem_base, | ||
3482 | (u32)(fw_ver1<<16 | fw_ver2)); | ||
3483 | |||
3437 | break; | 3484 | break; |
3485 | } | ||
3438 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: | 3486 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: |
3439 | DP(NETIF_MSG_LINK, | 3487 | DP(NETIF_MSG_LINK, |
3440 | "Setting the BCM8481 LASI control\n"); | 3488 | "Setting the BCM8481 LASI control\n"); |
@@ -3458,6 +3506,11 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
3458 | MDIO_AN_DEVAD, | 3506 | MDIO_AN_DEVAD, |
3459 | MDIO_AN_REG_CTRL, val); | 3507 | MDIO_AN_REG_CTRL, val); |
3460 | 3508 | ||
3509 | bnx2x_save_bcm_spirom_ver(bp, params->port, | ||
3510 | ext_phy_type, | ||
3511 | ext_phy_addr, | ||
3512 | params->shmem_base); | ||
3513 | |||
3461 | break; | 3514 | break; |
3462 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: | 3515 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: |
3463 | DP(NETIF_MSG_LINK, | 3516 | DP(NETIF_MSG_LINK, |
@@ -4146,91 +4199,38 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, | |||
4146 | { | 4199 | { |
4147 | struct bnx2x *bp = params->bp; | 4200 | struct bnx2x *bp = params->bp; |
4148 | u32 ext_phy_type = 0; | 4201 | u32 ext_phy_type = 0; |
4149 | u16 val = 0; | 4202 | u32 spirom_ver = 0; |
4150 | u8 ext_phy_addr = 0 ; | ||
4151 | u8 status = 0 ; | 4203 | u8 status = 0 ; |
4152 | u32 ver_num; | ||
4153 | 4204 | ||
4154 | if (version == NULL || params == NULL) | 4205 | if (version == NULL || params == NULL) |
4155 | return -EINVAL; | 4206 | return -EINVAL; |
4156 | 4207 | ||
4208 | spirom_ver = REG_RD(bp, params->shmem_base + | ||
4209 | offsetof(struct shmem_region, | ||
4210 | port_mb[params->port].ext_phy_fw_version)); | ||
4211 | |||
4157 | /* reset the returned value to zero */ | 4212 | /* reset the returned value to zero */ |
4158 | ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); | 4213 | ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); |
4159 | ext_phy_addr = ((params->ext_phy_config & | ||
4160 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | ||
4161 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | ||
4162 | |||
4163 | switch (ext_phy_type) { | 4214 | switch (ext_phy_type) { |
4164 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: | 4215 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: |
4165 | 4216 | ||
4166 | if (len < 5) | 4217 | if (len < 5) |
4167 | return -EINVAL; | 4218 | return -EINVAL; |
4168 | 4219 | ||
4169 | /* Take ext phy out of reset */ | 4220 | version[0] = (spirom_ver & 0xFF); |
4170 | if (!driver_loaded) | 4221 | version[1] = (spirom_ver & 0xFF00) >> 8; |
4171 | bnx2x_turn_on_ef(bp, params->port, ext_phy_addr, | 4222 | version[2] = (spirom_ver & 0xFF0000) >> 16; |
4172 | ext_phy_type); | 4223 | version[3] = (spirom_ver & 0xFF000000) >> 24; |
4173 | |||
4174 | /* wait for 1ms */ | ||
4175 | msleep(1); | ||
4176 | |||
4177 | bnx2x_cl45_read(bp, params->port, | ||
4178 | ext_phy_type, | ||
4179 | ext_phy_addr, | ||
4180 | MDIO_PMA_DEVAD, | ||
4181 | MDIO_PMA_REG_7101_VER1, &val); | ||
4182 | version[2] = (val & 0xFF); | ||
4183 | version[3] = ((val & 0xFF00)>>8); | ||
4184 | |||
4185 | bnx2x_cl45_read(bp, params->port, | ||
4186 | ext_phy_type, | ||
4187 | ext_phy_addr, | ||
4188 | MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, | ||
4189 | &val); | ||
4190 | version[0] = (val & 0xFF); | ||
4191 | version[1] = ((val & 0xFF00)>>8); | ||
4192 | version[4] = '\0'; | 4224 | version[4] = '\0'; |
4193 | 4225 | ||
4194 | if (!driver_loaded) | ||
4195 | bnx2x_turn_off_sf(bp, params->port); | ||
4196 | break; | 4226 | break; |
4197 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: | 4227 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: |
4198 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: | 4228 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: |
4199 | { | ||
4200 | /* Take ext phy out of reset */ | ||
4201 | if (!driver_loaded) | ||
4202 | bnx2x_turn_on_ef(bp, params->port, ext_phy_addr, | ||
4203 | ext_phy_type); | ||
4204 | |||
4205 | bnx2x_cl45_read(bp, params->port, ext_phy_type, | ||
4206 | ext_phy_addr, | ||
4207 | MDIO_PMA_DEVAD, | ||
4208 | MDIO_PMA_REG_ROM_VER1, &val); | ||
4209 | ver_num = val<<16; | ||
4210 | bnx2x_cl45_read(bp, params->port, ext_phy_type, | ||
4211 | ext_phy_addr, | ||
4212 | MDIO_PMA_DEVAD, | ||
4213 | MDIO_PMA_REG_ROM_VER2, &val); | ||
4214 | ver_num |= val; | ||
4215 | status = bnx2x_format_ver(ver_num, version, len); | ||
4216 | break; | ||
4217 | } | ||
4218 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: | 4229 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: |
4219 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: | 4230 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: |
4220 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: | 4231 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: |
4221 | bnx2x_cl45_read(bp, params->port, ext_phy_type, | 4232 | status = bnx2x_format_ver(spirom_ver, version, len); |
4222 | ext_phy_addr, | ||
4223 | MDIO_PMA_DEVAD, | ||
4224 | MDIO_PMA_REG_ROM_VER1, &val); | ||
4225 | ver_num = val<<16; | ||
4226 | bnx2x_cl45_read(bp, params->port, ext_phy_type, | ||
4227 | ext_phy_addr, | ||
4228 | MDIO_PMA_DEVAD, | ||
4229 | MDIO_PMA_REG_ROM_VER2, &val); | ||
4230 | ver_num |= val; | ||
4231 | status = bnx2x_format_ver(ver_num, version, len); | ||
4232 | break; | 4233 | break; |
4233 | |||
4234 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: | 4234 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: |
4235 | break; | 4235 | break; |
4236 | 4236 | ||
@@ -5128,7 +5128,7 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) | |||
5128 | u16 fw_ver1; | 5128 | u16 fw_ver1; |
5129 | 5129 | ||
5130 | bnx2x_bcm8073_external_rom_boot(bp, port, | 5130 | bnx2x_bcm8073_external_rom_boot(bp, port, |
5131 | ext_phy_addr[port]); | 5131 | ext_phy_addr[port], shmem_base); |
5132 | 5132 | ||
5133 | bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | 5133 | bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, |
5134 | ext_phy_addr[port], | 5134 | ext_phy_addr[port], |