diff options
-rw-r--r-- | drivers/net/bnx2x_link.c | 498 | ||||
-rw-r--r-- | drivers/net/bnx2x_reg.h | 32 |
2 files changed, 468 insertions, 62 deletions
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index 1f17334c8f02..9e1f19a00ab1 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c | |||
@@ -37,6 +37,10 @@ | |||
37 | /* Shortcut definitions */ | 37 | /* Shortcut definitions */ |
38 | /***********************************************************/ | 38 | /***********************************************************/ |
39 | 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 | ||
40 | #define NIG_STATUS_XGXS0_LINK10G \ | 44 | #define NIG_STATUS_XGXS0_LINK10G \ |
41 | NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G | 45 | NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G |
42 | #define NIG_STATUS_XGXS0_LINK_STATUS \ | 46 | #define NIG_STATUS_XGXS0_LINK_STATUS \ |
@@ -1589,8 +1593,9 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params, | |||
1589 | 1593 | ||
1590 | 1594 | ||
1591 | static u8 bnx2x_link_settings_status(struct link_params *params, | 1595 | static u8 bnx2x_link_settings_status(struct link_params *params, |
1592 | struct link_vars *vars, | 1596 | struct link_vars *vars, |
1593 | u32 gp_status) | 1597 | u32 gp_status, |
1598 | u8 ext_phy_link_up) | ||
1594 | { | 1599 | { |
1595 | struct bnx2x *bp = params->bp; | 1600 | struct bnx2x *bp = params->bp; |
1596 | u16 new_line_speed; | 1601 | u16 new_line_speed; |
@@ -1696,6 +1701,16 @@ static u8 bnx2x_link_settings_status(struct link_params *params, | |||
1696 | Comes to deals with possible FIFO glitch due to clk change | 1701 | Comes to deals with possible FIFO glitch due to clk change |
1697 | when speed is decreased without link down indicator */ | 1702 | when speed is decreased without link down indicator */ |
1698 | if (new_line_speed != vars->line_speed) { | 1703 | if (new_line_speed != vars->line_speed) { |
1704 | if (XGXS_EXT_PHY_TYPE(params->ext_phy_config) != | ||
1705 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT && | ||
1706 | ext_phy_link_up) { | ||
1707 | DP(NETIF_MSG_LINK, "Internal link speed %d is" | ||
1708 | " different than the external" | ||
1709 | " link speed %d\n", new_line_speed, | ||
1710 | vars->line_speed); | ||
1711 | vars->phy_link_up = 0; | ||
1712 | return 0; | ||
1713 | } | ||
1699 | REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE | 1714 | REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE |
1700 | + params->port*4, 0); | 1715 | + params->port*4, 0); |
1701 | msleep(1); | 1716 | msleep(1); |
@@ -1709,9 +1724,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, | |||
1709 | (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == | 1724 | (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == |
1710 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || | 1725 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || |
1711 | (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == | 1726 | (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == |
1712 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) || | 1727 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) { |
1713 | (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == | ||
1714 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481))) { | ||
1715 | vars->autoneg = AUTO_NEG_ENABLED; | 1728 | vars->autoneg = AUTO_NEG_ENABLED; |
1716 | 1729 | ||
1717 | if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { | 1730 | if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { |
@@ -3182,6 +3195,130 @@ static void bnx2x_set_preemphasis(struct link_params *params) | |||
3182 | } | 3195 | } |
3183 | } | 3196 | } |
3184 | 3197 | ||
3198 | |||
3199 | static void bnx2x_8481_set_led4(struct link_params *params, | ||
3200 | u32 ext_phy_type, u8 ext_phy_addr) | ||
3201 | { | ||
3202 | struct bnx2x *bp = params->bp; | ||
3203 | |||
3204 | /* PHYC_CTL_LED_CTL */ | ||
3205 | bnx2x_cl45_write(bp, params->port, | ||
3206 | ext_phy_type, | ||
3207 | ext_phy_addr, | ||
3208 | MDIO_PMA_DEVAD, | ||
3209 | MDIO_PMA_REG_8481_LINK_SIGNAL, 0xa482); | ||
3210 | |||
3211 | /* Unmask LED4 for 10G link */ | ||
3212 | bnx2x_cl45_write(bp, params->port, | ||
3213 | ext_phy_type, | ||
3214 | ext_phy_addr, | ||
3215 | MDIO_PMA_DEVAD, | ||
3216 | MDIO_PMA_REG_8481_SIGNAL_MASK, (1<<6)); | ||
3217 | /* 'Interrupt Mask' */ | ||
3218 | bnx2x_cl45_write(bp, params->port, | ||
3219 | ext_phy_type, | ||
3220 | ext_phy_addr, | ||
3221 | MDIO_AN_DEVAD, | ||
3222 | 0xFFFB, 0xFFFD); | ||
3223 | } | ||
3224 | static void bnx2x_8481_set_legacy_led_mode(struct link_params *params, | ||
3225 | u32 ext_phy_type, u8 ext_phy_addr) | ||
3226 | { | ||
3227 | struct bnx2x *bp = params->bp; | ||
3228 | |||
3229 | /* LED1 (10G Link): Disable LED1 when 10/100/1000 link */ | ||
3230 | /* LED2 (1G/100/10 Link): Enable LED2 when 10/100/1000 link) */ | ||
3231 | bnx2x_cl45_write(bp, params->port, | ||
3232 | ext_phy_type, | ||
3233 | ext_phy_addr, | ||
3234 | MDIO_AN_DEVAD, | ||
3235 | MDIO_AN_REG_8481_LEGACY_SHADOW, | ||
3236 | (1<<15) | (0xd << 10) | (0xc<<4) | 0xe); | ||
3237 | } | ||
3238 | |||
3239 | static void bnx2x_8481_set_10G_led_mode(struct link_params *params, | ||
3240 | u32 ext_phy_type, u8 ext_phy_addr) | ||
3241 | { | ||
3242 | struct bnx2x *bp = params->bp; | ||
3243 | u16 val1; | ||
3244 | |||
3245 | /* LED1 (10G Link) */ | ||
3246 | /* Enable continuse based on source 7(10G-link) */ | ||
3247 | bnx2x_cl45_read(bp, params->port, | ||
3248 | ext_phy_type, | ||
3249 | ext_phy_addr, | ||
3250 | MDIO_PMA_DEVAD, | ||
3251 | MDIO_PMA_REG_8481_LINK_SIGNAL, | ||
3252 | &val1); | ||
3253 | /* Set bit 2 to 0, and bits [1:0] to 10 */ | ||
3254 | val1 &= ~((1<<0) | (1<<2)); /* Clear bits 0,2*/ | ||
3255 | val1 |= (1<<1); /* Set bit 1 */ | ||
3256 | |||
3257 | bnx2x_cl45_write(bp, params->port, | ||
3258 | ext_phy_type, | ||
3259 | ext_phy_addr, | ||
3260 | MDIO_PMA_DEVAD, | ||
3261 | MDIO_PMA_REG_8481_LINK_SIGNAL, | ||
3262 | val1); | ||
3263 | |||
3264 | /* Unmask LED1 for 10G link */ | ||
3265 | bnx2x_cl45_read(bp, params->port, | ||
3266 | ext_phy_type, | ||
3267 | ext_phy_addr, | ||
3268 | MDIO_PMA_DEVAD, | ||
3269 | MDIO_PMA_REG_8481_LED1_MASK, | ||
3270 | &val1); | ||
3271 | /* Set bit 2 to 0, and bits [1:0] to 10 */ | ||
3272 | val1 |= (1<<7); | ||
3273 | bnx2x_cl45_write(bp, params->port, | ||
3274 | ext_phy_type, | ||
3275 | ext_phy_addr, | ||
3276 | MDIO_PMA_DEVAD, | ||
3277 | MDIO_PMA_REG_8481_LED1_MASK, | ||
3278 | val1); | ||
3279 | |||
3280 | /* LED2 (1G/100/10G Link) */ | ||
3281 | /* Mask LED2 for 10G link */ | ||
3282 | bnx2x_cl45_write(bp, params->port, | ||
3283 | ext_phy_type, | ||
3284 | ext_phy_addr, | ||
3285 | MDIO_PMA_DEVAD, | ||
3286 | MDIO_PMA_REG_8481_LED2_MASK, | ||
3287 | 0); | ||
3288 | |||
3289 | /* LED3 (10G/1G/100/10G Activity) */ | ||
3290 | bnx2x_cl45_read(bp, params->port, | ||
3291 | ext_phy_type, | ||
3292 | ext_phy_addr, | ||
3293 | MDIO_PMA_DEVAD, | ||
3294 | MDIO_PMA_REG_8481_LINK_SIGNAL, | ||
3295 | &val1); | ||
3296 | /* Enable blink based on source 4(Activity) */ | ||
3297 | val1 &= ~((1<<7) | (1<<8)); /* Clear bits 7,8 */ | ||
3298 | val1 |= (1<<6); /* Set only bit 6 */ | ||
3299 | bnx2x_cl45_write(bp, params->port, | ||
3300 | ext_phy_type, | ||
3301 | ext_phy_addr, | ||
3302 | MDIO_PMA_DEVAD, | ||
3303 | MDIO_PMA_REG_8481_LINK_SIGNAL, | ||
3304 | val1); | ||
3305 | |||
3306 | bnx2x_cl45_read(bp, params->port, | ||
3307 | ext_phy_type, | ||
3308 | ext_phy_addr, | ||
3309 | MDIO_PMA_DEVAD, | ||
3310 | MDIO_PMA_REG_8481_LED3_MASK, | ||
3311 | &val1); | ||
3312 | val1 |= (1<<4); /* Unmask LED3 for 10G link */ | ||
3313 | bnx2x_cl45_write(bp, params->port, | ||
3314 | ext_phy_type, | ||
3315 | ext_phy_addr, | ||
3316 | MDIO_PMA_DEVAD, | ||
3317 | MDIO_PMA_REG_8481_LED3_MASK, | ||
3318 | val1); | ||
3319 | } | ||
3320 | |||
3321 | |||
3185 | static void bnx2x_init_internal_phy(struct link_params *params, | 3322 | static void bnx2x_init_internal_phy(struct link_params *params, |
3186 | struct link_vars *vars) | 3323 | struct link_vars *vars) |
3187 | { | 3324 | { |
@@ -3947,16 +4084,109 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
3947 | break; | 4084 | break; |
3948 | } | 4085 | } |
3949 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: | 4086 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: |
3950 | DP(NETIF_MSG_LINK, | 4087 | /* This phy uses the NIG latch mechanism since link |
3951 | "Setting the BCM8481 LASI control\n"); | 4088 | indication arrives through its LED4 and not via |
4089 | its LASI signal, so we get steady signal | ||
4090 | instead of clear on read */ | ||
4091 | bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, | ||
4092 | 1 << NIG_LATCH_BC_ENABLE_MI_INT); | ||
4093 | |||
4094 | bnx2x_8481_set_led4(params, ext_phy_type, ext_phy_addr); | ||
4095 | if (params->req_line_speed == SPEED_AUTO_NEG) { | ||
4096 | |||
4097 | u16 autoneg_val, an_1000_val, an_10_100_val; | ||
4098 | /* set 1000 speed advertisement */ | ||
4099 | bnx2x_cl45_read(bp, params->port, | ||
4100 | ext_phy_type, | ||
4101 | ext_phy_addr, | ||
4102 | MDIO_AN_DEVAD, | ||
4103 | MDIO_AN_REG_8481_1000T_CTRL, | ||
4104 | &an_1000_val); | ||
3952 | 4105 | ||
3953 | bnx2x_cl45_write(bp, params->port, | 4106 | if (params->speed_cap_mask & |
3954 | ext_phy_type, | 4107 | PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) { |
3955 | ext_phy_addr, | 4108 | an_1000_val |= (1<<8); |
3956 | MDIO_PMA_DEVAD, | 4109 | if (params->req_duplex == DUPLEX_FULL) |
3957 | MDIO_PMA_REG_LASI_CTRL, 0x1); | 4110 | an_1000_val |= (1<<9); |
4111 | DP(NETIF_MSG_LINK, "Advertising 1G\n"); | ||
4112 | } else | ||
4113 | an_1000_val &= ~((1<<8) | (1<<9)); | ||
3958 | 4114 | ||
3959 | /* Restart autoneg */ | 4115 | bnx2x_cl45_write(bp, params->port, |
4116 | ext_phy_type, | ||
4117 | ext_phy_addr, | ||
4118 | MDIO_AN_DEVAD, | ||
4119 | MDIO_AN_REG_8481_1000T_CTRL, | ||
4120 | an_1000_val); | ||
4121 | |||
4122 | /* set 100 speed advertisement */ | ||
4123 | bnx2x_cl45_read(bp, params->port, | ||
4124 | ext_phy_type, | ||
4125 | ext_phy_addr, | ||
4126 | MDIO_AN_DEVAD, | ||
4127 | MDIO_AN_REG_8481_LEGACY_AN_ADV, | ||
4128 | &an_10_100_val); | ||
4129 | |||
4130 | if (params->speed_cap_mask & | ||
4131 | (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | | ||
4132 | PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) { | ||
4133 | an_10_100_val |= (1<<7); | ||
4134 | if (params->req_duplex == DUPLEX_FULL) | ||
4135 | an_10_100_val |= (1<<8); | ||
4136 | DP(NETIF_MSG_LINK, | ||
4137 | "Advertising 100M\n"); | ||
4138 | } else | ||
4139 | an_10_100_val &= ~((1<<7) | (1<<8)); | ||
4140 | |||
4141 | /* set 10 speed advertisement */ | ||
4142 | if (params->speed_cap_mask & | ||
4143 | (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | | ||
4144 | PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) { | ||
4145 | an_10_100_val |= (1<<5); | ||
4146 | if (params->req_duplex == DUPLEX_FULL) | ||
4147 | an_10_100_val |= (1<<6); | ||
4148 | DP(NETIF_MSG_LINK, "Advertising 10M\n"); | ||
4149 | } | ||
4150 | else | ||
4151 | an_10_100_val &= ~((1<<5) | (1<<6)); | ||
4152 | |||
4153 | bnx2x_cl45_write(bp, params->port, | ||
4154 | ext_phy_type, | ||
4155 | ext_phy_addr, | ||
4156 | MDIO_AN_DEVAD, | ||
4157 | MDIO_AN_REG_8481_LEGACY_AN_ADV, | ||
4158 | an_10_100_val); | ||
4159 | |||
4160 | bnx2x_cl45_read(bp, params->port, | ||
4161 | ext_phy_type, | ||
4162 | ext_phy_addr, | ||
4163 | MDIO_AN_DEVAD, | ||
4164 | MDIO_AN_REG_8481_LEGACY_MII_CTRL, | ||
4165 | &autoneg_val); | ||
4166 | |||
4167 | /* Disable forced speed */ | ||
4168 | autoneg_val &= ~(1<<6|1<<13); | ||
4169 | |||
4170 | /* Enable autoneg and restart autoneg | ||
4171 | for legacy speeds */ | ||
4172 | autoneg_val |= (1<<9|1<<12); | ||
4173 | |||
4174 | if (params->req_duplex == DUPLEX_FULL) | ||
4175 | autoneg_val |= (1<<8); | ||
4176 | else | ||
4177 | autoneg_val &= ~(1<<8); | ||
4178 | |||
4179 | bnx2x_cl45_write(bp, params->port, | ||
4180 | ext_phy_type, | ||
4181 | ext_phy_addr, | ||
4182 | MDIO_AN_DEVAD, | ||
4183 | MDIO_AN_REG_8481_LEGACY_MII_CTRL, | ||
4184 | autoneg_val); | ||
4185 | |||
4186 | if (params->speed_cap_mask & | ||
4187 | PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) { | ||
4188 | DP(NETIF_MSG_LINK, "Advertising 10G\n"); | ||
4189 | /* Restart autoneg for 10G*/ | ||
3960 | bnx2x_cl45_read(bp, params->port, | 4190 | bnx2x_cl45_read(bp, params->port, |
3961 | ext_phy_type, | 4191 | ext_phy_type, |
3962 | ext_phy_addr, | 4192 | ext_phy_addr, |
@@ -3968,6 +4198,76 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
3968 | ext_phy_addr, | 4198 | ext_phy_addr, |
3969 | MDIO_AN_DEVAD, | 4199 | MDIO_AN_DEVAD, |
3970 | MDIO_AN_REG_CTRL, val); | 4200 | MDIO_AN_REG_CTRL, val); |
4201 | } | ||
4202 | } else { | ||
4203 | /* Force speed */ | ||
4204 | u16 autoneg_ctrl, pma_ctrl; | ||
4205 | bnx2x_cl45_read(bp, params->port, | ||
4206 | ext_phy_type, | ||
4207 | ext_phy_addr, | ||
4208 | MDIO_AN_DEVAD, | ||
4209 | MDIO_AN_REG_8481_LEGACY_MII_CTRL, | ||
4210 | &autoneg_ctrl); | ||
4211 | |||
4212 | /* Disable autoneg */ | ||
4213 | autoneg_ctrl &= ~(1<<12); | ||
4214 | |||
4215 | /* Set 1000 force */ | ||
4216 | switch (params->req_line_speed) { | ||
4217 | case SPEED_10000: | ||
4218 | DP(NETIF_MSG_LINK, | ||
4219 | "Unable to set 10G force !\n"); | ||
4220 | break; | ||
4221 | case SPEED_1000: | ||
4222 | bnx2x_cl45_read(bp, params->port, | ||
4223 | ext_phy_type, | ||
4224 | ext_phy_addr, | ||
4225 | MDIO_PMA_DEVAD, | ||
4226 | MDIO_PMA_REG_CTRL, | ||
4227 | &pma_ctrl); | ||
4228 | autoneg_ctrl &= ~(1<<13); | ||
4229 | autoneg_ctrl |= (1<<6); | ||
4230 | pma_ctrl &= ~(1<<13); | ||
4231 | pma_ctrl |= (1<<6); | ||
4232 | DP(NETIF_MSG_LINK, | ||
4233 | "Setting 1000M force\n"); | ||
4234 | bnx2x_cl45_write(bp, params->port, | ||
4235 | ext_phy_type, | ||
4236 | ext_phy_addr, | ||
4237 | MDIO_PMA_DEVAD, | ||
4238 | MDIO_PMA_REG_CTRL, | ||
4239 | pma_ctrl); | ||
4240 | break; | ||
4241 | case SPEED_100: | ||
4242 | autoneg_ctrl |= (1<<13); | ||
4243 | autoneg_ctrl &= ~(1<<6); | ||
4244 | DP(NETIF_MSG_LINK, | ||
4245 | "Setting 100M force\n"); | ||
4246 | break; | ||
4247 | case SPEED_10: | ||
4248 | autoneg_ctrl &= ~(1<<13); | ||
4249 | autoneg_ctrl &= ~(1<<6); | ||
4250 | DP(NETIF_MSG_LINK, | ||
4251 | "Setting 10M force\n"); | ||
4252 | break; | ||
4253 | } | ||
4254 | |||
4255 | /* Duplex mode */ | ||
4256 | if (params->req_duplex == DUPLEX_FULL) { | ||
4257 | autoneg_ctrl |= (1<<8); | ||
4258 | DP(NETIF_MSG_LINK, | ||
4259 | "Setting full duplex\n"); | ||
4260 | } else | ||
4261 | autoneg_ctrl &= ~(1<<8); | ||
4262 | |||
4263 | /* Update autoneg ctrl and pma ctrl */ | ||
4264 | bnx2x_cl45_write(bp, params->port, | ||
4265 | ext_phy_type, | ||
4266 | ext_phy_addr, | ||
4267 | MDIO_AN_DEVAD, | ||
4268 | MDIO_AN_REG_8481_LEGACY_MII_CTRL, | ||
4269 | autoneg_ctrl); | ||
4270 | } | ||
3971 | 4271 | ||
3972 | bnx2x_save_bcm_spirom_ver(bp, params->port, | 4272 | bnx2x_save_bcm_spirom_ver(bp, params->port, |
3973 | ext_phy_type, | 4273 | ext_phy_type, |
@@ -4104,7 +4404,8 @@ static void bnx2x_8727_handle_mod_abs(struct link_params *params) | |||
4104 | 4404 | ||
4105 | 4405 | ||
4106 | static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | 4406 | static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, |
4107 | struct link_vars *vars) | 4407 | struct link_vars *vars, |
4408 | u8 is_mi_int) | ||
4108 | { | 4409 | { |
4109 | struct bnx2x *bp = params->bp; | 4410 | struct bnx2x *bp = params->bp; |
4110 | u32 ext_phy_type; | 4411 | u32 ext_phy_type; |
@@ -4647,48 +4948,77 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
4647 | } | 4948 | } |
4648 | break; | 4949 | break; |
4649 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: | 4950 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: |
4650 | /* Clear LASI interrupt */ | ||
4651 | bnx2x_cl45_read(bp, params->port, | ||
4652 | ext_phy_type, | ||
4653 | ext_phy_addr, | ||
4654 | MDIO_PMA_DEVAD, | ||
4655 | MDIO_PMA_REG_LASI_STATUS, &val1); | ||
4656 | DP(NETIF_MSG_LINK, "8481 LASI status reg = 0x%x\n", | ||
4657 | val1); | ||
4658 | |||
4659 | /* Check 10G-BaseT link status */ | 4951 | /* Check 10G-BaseT link status */ |
4660 | /* Check Global PMD signal ok */ | 4952 | /* Check PMD signal ok */ |
4661 | bnx2x_cl45_read(bp, params->port, ext_phy_type, | 4953 | bnx2x_cl45_read(bp, params->port, ext_phy_type, |
4662 | ext_phy_addr, | 4954 | ext_phy_addr, |
4663 | MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, | 4955 | MDIO_AN_DEVAD, |
4664 | &rx_sd); | 4956 | 0xFFFA, |
4665 | /* Check PCS block lock */ | 4957 | &val1); |
4666 | bnx2x_cl45_read(bp, params->port, ext_phy_type, | 4958 | bnx2x_cl45_read(bp, params->port, ext_phy_type, |
4667 | ext_phy_addr, | 4959 | ext_phy_addr, |
4668 | MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, | 4960 | MDIO_PMA_DEVAD, |
4669 | &pcs_status); | 4961 | MDIO_PMA_REG_8481_PMD_SIGNAL, |
4670 | DP(NETIF_MSG_LINK, "8481 1.a = 0x%x, 1.20 = 0x%x\n", | 4962 | &val2); |
4671 | rx_sd, pcs_status); | 4963 | DP(NETIF_MSG_LINK, "PMD_SIGNAL 1.a811 = 0x%x\n", val2); |
4672 | if (rx_sd & pcs_status & 0x1) { | 4964 | |
4965 | /* Check link 10G */ | ||
4966 | if (val2 & (1<<11)) { | ||
4673 | vars->line_speed = SPEED_10000; | 4967 | vars->line_speed = SPEED_10000; |
4674 | ext_phy_link_up = 1; | 4968 | ext_phy_link_up = 1; |
4675 | } else { | 4969 | bnx2x_8481_set_10G_led_mode(params, |
4676 | 4970 | ext_phy_type, | |
4677 | /* Check 1000-BaseT link status */ | 4971 | ext_phy_addr); |
4678 | bnx2x_cl45_read(bp, params->port, ext_phy_type, | 4972 | } else { /* Check Legacy speed link */ |
4679 | ext_phy_addr, | 4973 | u16 legacy_status, legacy_speed; |
4680 | MDIO_AN_DEVAD, 0xFFE1, | 4974 | |
4681 | &val1); | 4975 | /* Enable expansion register 0x42 |
4976 | (Operation mode status) */ | ||
4977 | bnx2x_cl45_write(bp, params->port, | ||
4978 | ext_phy_type, | ||
4979 | ext_phy_addr, | ||
4980 | MDIO_AN_DEVAD, | ||
4981 | MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, | ||
4982 | 0xf42); | ||
4682 | 4983 | ||
4683 | bnx2x_cl45_read(bp, params->port, ext_phy_type, | 4984 | /* Get legacy speed operation status */ |
4684 | ext_phy_addr, | 4985 | bnx2x_cl45_read(bp, params->port, |
4685 | MDIO_AN_DEVAD, 0xFFE1, | 4986 | ext_phy_type, |
4686 | &val2); | 4987 | ext_phy_addr, |
4687 | DP(NETIF_MSG_LINK, "8481 7.FFE1 =" | 4988 | MDIO_AN_DEVAD, |
4688 | "0x%x-->0x%x\n", val1, val2); | 4989 | MDIO_AN_REG_8481_EXPANSION_REG_RD_RW, |
4689 | if (val2 & (1<<2)) { | 4990 | &legacy_status); |
4690 | vars->line_speed = SPEED_1000; | 4991 | |
4691 | ext_phy_link_up = 1; | 4992 | DP(NETIF_MSG_LINK, "Legacy speed status" |
4993 | " = 0x%x\n", legacy_status); | ||
4994 | ext_phy_link_up = ((legacy_status & (1<<11)) | ||
4995 | == (1<<11)); | ||
4996 | if (ext_phy_link_up) { | ||
4997 | legacy_speed = (legacy_status & (3<<9)); | ||
4998 | if (legacy_speed == (0<<9)) | ||
4999 | vars->line_speed = SPEED_10; | ||
5000 | else if (legacy_speed == (1<<9)) | ||
5001 | vars->line_speed = | ||
5002 | SPEED_100; | ||
5003 | else if (legacy_speed == (2<<9)) | ||
5004 | vars->line_speed = | ||
5005 | SPEED_1000; | ||
5006 | else /* Should not happen */ | ||
5007 | vars->line_speed = 0; | ||
5008 | |||
5009 | if (legacy_status & (1<<8)) | ||
5010 | vars->duplex = DUPLEX_FULL; | ||
5011 | else | ||
5012 | vars->duplex = DUPLEX_HALF; | ||
5013 | |||
5014 | DP(NETIF_MSG_LINK, "Link is up " | ||
5015 | "in %dMbps, is_duplex_full" | ||
5016 | "= %d\n", | ||
5017 | vars->line_speed, | ||
5018 | (vars->duplex == DUPLEX_FULL)); | ||
5019 | bnx2x_8481_set_legacy_led_mode(params, | ||
5020 | ext_phy_type, | ||
5021 | ext_phy_addr); | ||
4692 | } | 5022 | } |
4693 | } | 5023 | } |
4694 | 5024 | ||
@@ -4775,12 +5105,47 @@ static void bnx2x_link_int_enable(struct link_params *params) | |||
4775 | REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); | 5105 | REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); |
4776 | } | 5106 | } |
4777 | 5107 | ||
4778 | 5108 | static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port, | |
5109 | u8 is_mi_int) | ||
5110 | { | ||
5111 | u32 latch_status = 0, is_mi_int_status; | ||
5112 | /* Disable the MI INT ( external phy int ) | ||
5113 | * by writing 1 to the status register. Link down indication | ||
5114 | * is high-active-signal, so in this case we need to write the | ||
5115 | * status to clear the XOR | ||
5116 | */ | ||
5117 | /* Read Latched signals */ | ||
5118 | latch_status = REG_RD(bp, | ||
5119 | NIG_REG_LATCH_STATUS_0 + port*8); | ||
5120 | is_mi_int_status = REG_RD(bp, | ||
5121 | NIG_REG_STATUS_INTERRUPT_PORT0 + port*4); | ||
5122 | DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x," | ||
5123 | "latch_status = 0x%x\n", | ||
5124 | is_mi_int, is_mi_int_status, latch_status); | ||
5125 | /* Handle only those with latched-signal=up.*/ | ||
5126 | if (latch_status & 1) { | ||
5127 | /* For all latched-signal=up,Write original_signal to status */ | ||
5128 | if (is_mi_int) | ||
5129 | bnx2x_bits_en(bp, | ||
5130 | NIG_REG_STATUS_INTERRUPT_PORT0 | ||
5131 | + port*4, | ||
5132 | NIG_STATUS_EMAC0_MI_INT); | ||
5133 | else | ||
5134 | bnx2x_bits_dis(bp, | ||
5135 | NIG_REG_STATUS_INTERRUPT_PORT0 | ||
5136 | + port*4, | ||
5137 | NIG_STATUS_EMAC0_MI_INT); | ||
5138 | /* For all latched-signal=up : Re-Arm Latch signals */ | ||
5139 | REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8, | ||
5140 | (latch_status & 0xfffe) | (latch_status & 1)); | ||
5141 | } | ||
5142 | } | ||
4779 | /* | 5143 | /* |
4780 | * link management | 5144 | * link management |
4781 | */ | 5145 | */ |
4782 | static void bnx2x_link_int_ack(struct link_params *params, | 5146 | static void bnx2x_link_int_ack(struct link_params *params, |
4783 | struct link_vars *vars, u8 is_10g) | 5147 | struct link_vars *vars, u8 is_10g, |
5148 | u8 is_mi_int) | ||
4784 | { | 5149 | { |
4785 | struct bnx2x *bp = params->bp; | 5150 | struct bnx2x *bp = params->bp; |
4786 | u8 port = params->port; | 5151 | u8 port = params->port; |
@@ -4791,6 +5156,10 @@ static void bnx2x_link_int_ack(struct link_params *params, | |||
4791 | (NIG_STATUS_XGXS0_LINK10G | | 5156 | (NIG_STATUS_XGXS0_LINK10G | |
4792 | NIG_STATUS_XGXS0_LINK_STATUS | | 5157 | NIG_STATUS_XGXS0_LINK_STATUS | |
4793 | NIG_STATUS_SERDES0_LINK_STATUS)); | 5158 | NIG_STATUS_SERDES0_LINK_STATUS)); |
5159 | if (XGXS_EXT_PHY_TYPE(params->ext_phy_config) | ||
5160 | == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) { | ||
5161 | bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int); | ||
5162 | } | ||
4794 | if (vars->phy_link_up) { | 5163 | if (vars->phy_link_up) { |
4795 | if (is_10g) { | 5164 | if (is_10g) { |
4796 | /* Disable the 10G link interrupt | 5165 | /* Disable the 10G link interrupt |
@@ -4810,7 +5179,8 @@ static void bnx2x_link_int_ack(struct link_params *params, | |||
4810 | PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> | 5179 | PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> |
4811 | PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); | 5180 | PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); |
4812 | 5181 | ||
4813 | DP(NETIF_MSG_LINK, "1G XGXS phy link up\n"); | 5182 | DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n", |
5183 | vars->line_speed); | ||
4814 | bnx2x_bits_en(bp, | 5184 | bnx2x_bits_en(bp, |
4815 | NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, | 5185 | NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, |
4816 | ((1 << ser_lane) << | 5186 | ((1 << ser_lane) << |
@@ -5270,7 +5640,7 @@ u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars) | |||
5270 | &gp_status); | 5640 | &gp_status); |
5271 | /* link is up only if both local phy and external phy are up */ | 5641 | /* link is up only if both local phy and external phy are up */ |
5272 | if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) && | 5642 | if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) && |
5273 | bnx2x_ext_phy_is_link_up(params, vars)) | 5643 | bnx2x_ext_phy_is_link_up(params, vars, 1)) |
5274 | return 0; | 5644 | return 0; |
5275 | 5645 | ||
5276 | return -ESRCH; | 5646 | return -ESRCH; |
@@ -5758,16 +6128,19 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
5758 | u8 link_10g; | 6128 | u8 link_10g; |
5759 | u8 ext_phy_link_up, rc = 0; | 6129 | u8 ext_phy_link_up, rc = 0; |
5760 | u32 ext_phy_type; | 6130 | u32 ext_phy_type; |
6131 | u8 is_mi_int = 0; | ||
5761 | 6132 | ||
5762 | DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", | 6133 | DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", |
5763 | port, | 6134 | port, (vars->phy_flags & PHY_XGXS_FLAG), |
5764 | (vars->phy_flags & PHY_XGXS_FLAG), | 6135 | REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); |
5765 | REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); | ||
5766 | 6136 | ||
6137 | is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + | ||
6138 | port*0x18) > 0); | ||
5767 | DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n", | 6139 | DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n", |
5768 | REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), | 6140 | REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), |
5769 | REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18), | 6141 | is_mi_int, |
5770 | REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c)); | 6142 | REG_RD(bp, |
6143 | NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c)); | ||
5771 | 6144 | ||
5772 | DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n", | 6145 | DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n", |
5773 | REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), | 6146 | REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), |
@@ -5779,7 +6152,7 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
5779 | ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); | 6152 | ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); |
5780 | 6153 | ||
5781 | /* Check external link change only for non-direct */ | 6154 | /* Check external link change only for non-direct */ |
5782 | ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars); | 6155 | ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars, is_mi_int); |
5783 | 6156 | ||
5784 | /* Read gp_status */ | 6157 | /* Read gp_status */ |
5785 | CL45_RD_OVER_CL22(bp, port, params->phy_addr, | 6158 | CL45_RD_OVER_CL22(bp, port, params->phy_addr, |
@@ -5787,7 +6160,8 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
5787 | MDIO_GP_STATUS_TOP_AN_STATUS1, | 6160 | MDIO_GP_STATUS_TOP_AN_STATUS1, |
5788 | &gp_status); | 6161 | &gp_status); |
5789 | 6162 | ||
5790 | rc = bnx2x_link_settings_status(params, vars, gp_status); | 6163 | rc = bnx2x_link_settings_status(params, vars, gp_status, |
6164 | ext_phy_link_up); | ||
5791 | if (rc != 0) | 6165 | if (rc != 0) |
5792 | return rc; | 6166 | return rc; |
5793 | 6167 | ||
@@ -5799,7 +6173,7 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
5799 | (vars->line_speed == SPEED_15000) || | 6173 | (vars->line_speed == SPEED_15000) || |
5800 | (vars->line_speed == SPEED_16000)); | 6174 | (vars->line_speed == SPEED_16000)); |
5801 | 6175 | ||
5802 | bnx2x_link_int_ack(params, vars, link_10g); | 6176 | bnx2x_link_int_ack(params, vars, link_10g, is_mi_int); |
5803 | 6177 | ||
5804 | /* In case external phy link is up, and internal link is down | 6178 | /* In case external phy link is up, and internal link is down |
5805 | ( not initialized yet probably after link initialization, it needs | 6179 | ( not initialized yet probably after link initialization, it needs |
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h index 25639e2df52b..9a20da5bf19a 100644 --- a/drivers/net/bnx2x_reg.h +++ b/drivers/net/bnx2x_reg.h | |||
@@ -1681,6 +1681,24 @@ | |||
1681 | /* [RW 17] Debug only. RX_EOP_DSCR_lb_FIFO in NIG_RX_EOP. Data | 1681 | /* [RW 17] Debug only. RX_EOP_DSCR_lb_FIFO in NIG_RX_EOP. Data |
1682 | packet_length[13:0]; mac_error[14]; trunc_error[15]; parity[16] */ | 1682 | packet_length[13:0]; mac_error[14]; trunc_error[15]; parity[16] */ |
1683 | #define NIG_REG_INGRESS_EOP_LB_FIFO 0x104e4 | 1683 | #define NIG_REG_INGRESS_EOP_LB_FIFO 0x104e4 |
1684 | /* [RW 27] 0 - must be active for Everest A0; 1- for Everest B0 when latch | ||
1685 | logic for interrupts must be used. Enable per bit of interrupt of | ||
1686 | ~latch_status.latch_status */ | ||
1687 | #define NIG_REG_LATCH_BC_0 0x16210 | ||
1688 | /* [RW 27] Latch for each interrupt from Unicore.b[0] | ||
1689 | status_emac0_misc_mi_int; b[1] status_emac0_misc_mi_complete; | ||
1690 | b[2]status_emac0_misc_cfg_change; b[3]status_emac0_misc_link_status; | ||
1691 | b[4]status_emac0_misc_link_change; b[5]status_emac0_misc_attn; | ||
1692 | b[6]status_serdes0_mac_crs; b[7]status_serdes0_autoneg_complete; | ||
1693 | b[8]status_serdes0_fiber_rxact; b[9]status_serdes0_link_status; | ||
1694 | b[10]status_serdes0_mr_page_rx; b[11]status_serdes0_cl73_an_complete; | ||
1695 | b[12]status_serdes0_cl73_mr_page_rx; b[13]status_serdes0_rx_sigdet; | ||
1696 | b[14]status_xgxs0_remotemdioreq; b[15]status_xgxs0_link10g; | ||
1697 | b[16]status_xgxs0_autoneg_complete; b[17]status_xgxs0_fiber_rxact; | ||
1698 | b[21:18]status_xgxs0_link_status; b[22]status_xgxs0_mr_page_rx; | ||
1699 | b[23]status_xgxs0_cl73_an_complete; b[24]status_xgxs0_cl73_mr_page_rx; | ||
1700 | b[25]status_xgxs0_rx_sigdet; b[26]status_xgxs0_mac_crs */ | ||
1701 | #define NIG_REG_LATCH_STATUS_0 0x18000 | ||
1684 | /* [RW 1] led 10g for port 0 */ | 1702 | /* [RW 1] led 10g for port 0 */ |
1685 | #define NIG_REG_LED_10G_P0 0x10320 | 1703 | #define NIG_REG_LED_10G_P0 0x10320 |
1686 | /* [RW 1] led 10g for port 1 */ | 1704 | /* [RW 1] led 10g for port 1 */ |
@@ -1871,6 +1889,7 @@ | |||
1871 | #define NIG_REG_XGXS_LANE_SEL_P0 0x102e8 | 1889 | #define NIG_REG_XGXS_LANE_SEL_P0 0x102e8 |
1872 | /* [RW 1] selection for port0 for NIG_MUX block : 0 = SerDes; 1 = XGXS */ | 1890 | /* [RW 1] selection for port0 for NIG_MUX block : 0 = SerDes; 1 = XGXS */ |
1873 | #define NIG_REG_XGXS_SERDES0_MODE_SEL 0x102e0 | 1891 | #define NIG_REG_XGXS_SERDES0_MODE_SEL 0x102e0 |
1892 | #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT (0x1<<0) | ||
1874 | #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS (0x1<<9) | 1893 | #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS (0x1<<9) |
1875 | #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G (0x1<<15) | 1894 | #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G (0x1<<15) |
1876 | #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS (0xf<<18) | 1895 | #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS (0xf<<18) |
@@ -5889,6 +5908,13 @@ Theotherbitsarereservedandshouldbezero*/ | |||
5889 | #define MDIO_PMA_REG_7101_VER1 0xc026 | 5908 | #define MDIO_PMA_REG_7101_VER1 0xc026 |
5890 | #define MDIO_PMA_REG_7101_VER2 0xc027 | 5909 | #define MDIO_PMA_REG_7101_VER2 0xc027 |
5891 | 5910 | ||
5911 | #define MDIO_PMA_REG_8481_PMD_SIGNAL 0xa811 | ||
5912 | #define MDIO_PMA_REG_8481_LED1_MASK 0xa82c | ||
5913 | #define MDIO_PMA_REG_8481_LED2_MASK 0xa82f | ||
5914 | #define MDIO_PMA_REG_8481_LED3_MASK 0xa832 | ||
5915 | #define MDIO_PMA_REG_8481_SIGNAL_MASK 0xa835 | ||
5916 | #define MDIO_PMA_REG_8481_LINK_SIGNAL 0xa83b | ||
5917 | |||
5892 | 5918 | ||
5893 | #define MDIO_WIS_DEVAD 0x2 | 5919 | #define MDIO_WIS_DEVAD 0x2 |
5894 | /*bcm*/ | 5920 | /*bcm*/ |
@@ -5942,6 +5968,12 @@ Theotherbitsarereservedandshouldbezero*/ | |||
5942 | 5968 | ||
5943 | #define MDIO_AN_REG_8073_2_5G 0x8329 | 5969 | #define MDIO_AN_REG_8073_2_5G 0x8329 |
5944 | 5970 | ||
5971 | #define MDIO_AN_REG_8481_LEGACY_MII_CTRL 0xffe0 | ||
5972 | #define MDIO_AN_REG_8481_LEGACY_AN_ADV 0xffe4 | ||
5973 | #define MDIO_AN_REG_8481_1000T_CTRL 0xffe9 | ||
5974 | #define MDIO_AN_REG_8481_EXPANSION_REG_RD_RW 0xfff5 | ||
5975 | #define MDIO_AN_REG_8481_EXPANSION_REG_ACCESS 0xfff7 | ||
5976 | #define MDIO_AN_REG_8481_LEGACY_SHADOW 0xfffc | ||
5945 | 5977 | ||
5946 | #define IGU_FUNC_BASE 0x0400 | 5978 | #define IGU_FUNC_BASE 0x0400 |
5947 | 5979 | ||