aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEilon Greenstein <eilong@broadcom.com>2009-08-12 04:22:16 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-13 02:02:18 -0400
commit2f9044603c8b9ead9eb4d88e360093b44d362b58 (patch)
tree21019592618ddb1e24881c1ea1b1bffc58060e6e
parent0c593270432035b7b9ba27ee7dd4f32f6feea2e0 (diff)
bnx2x: BCM8481 LED4 instead of LASI
The BCM8481 does not generate LASI interrupt for 10M, 100M and 1G link, so we are using LED4 output as the interrupt input to the 57711. This requires some adaptation in the link interrupt routines 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>
-rw-r--r--drivers/net/bnx2x_link.c498
-rw-r--r--drivers/net/bnx2x_reg.h32
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
1591static u8 bnx2x_link_settings_status(struct link_params *params, 1595static 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
3199static 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}
3224static 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
3239static 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
3185static void bnx2x_init_internal_phy(struct link_params *params, 3322static 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
4106static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, 4406static 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 5108static 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 */
4782static void bnx2x_link_int_ack(struct link_params *params, 5146static 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