X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnx2x%2Fbnx2x_link.c;h=580919619252e3d0594f5365226bc295a8efcba9;hb=8d5b5d9c7b86e44fda29a367db3ccd2815a52f7c;hp=3e99bf9c42b9a83ae18437538f42322e38413d28;hpb=7c1552d196682f05abaa8e49f81c40a9b6459b67;p=mv-sheeva.git diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 3e99bf9c42b..58091961925 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -181,6 +181,12 @@ (_bank + (_addr & 0xf)), \ _val) +static u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 *ret_val); + +static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 val); + static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits) { u32 val = REG_RD(bp, reg); @@ -594,7 +600,7 @@ static u8 bnx2x_bmac2_enable(struct link_params *params, return 0; } -u8 bnx2x_bmac_enable(struct link_params *params, +static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, u8 is_lb) { @@ -604,7 +610,7 @@ u8 bnx2x_bmac_enable(struct link_params *params, /* reset and unreset the BigMac */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - udelay(10); + msleep(1); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); @@ -2537,122 +2543,6 @@ static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, } } -/* - *------------------------------------------------------------------------ - * bnx2x_override_led_value - - * - * Override the led value of the requested led - * - *------------------------------------------------------------------------ - */ -u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, - u32 led_idx, u32 value) -{ - u32 reg_val; - - /* If port 0 then use EMAC0, else use EMAC1*/ - u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - - DP(NETIF_MSG_LINK, - "bnx2x_override_led_value() port %x led_idx %d value %d\n", - port, led_idx, value); - - switch (led_idx) { - case 0: /* 10MB led */ - /* Read the current value of the LED register in - the EMAC block */ - reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); - /* Set the OVERRIDE bit to 1 */ - reg_val |= EMAC_LED_OVERRIDE; - /* If value is 1, set the 10M_OVERRIDE bit, - otherwise reset it.*/ - reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) : - (reg_val & ~EMAC_LED_10MB_OVERRIDE); - REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); - break; - case 1: /*100MB led */ - /*Read the current value of the LED register in - the EMAC block */ - reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); - /* Set the OVERRIDE bit to 1 */ - reg_val |= EMAC_LED_OVERRIDE; - /* If value is 1, set the 100M_OVERRIDE bit, - otherwise reset it.*/ - reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) : - (reg_val & ~EMAC_LED_100MB_OVERRIDE); - REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); - break; - case 2: /* 1000MB led */ - /* Read the current value of the LED register in the - EMAC block */ - reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); - /* Set the OVERRIDE bit to 1 */ - reg_val |= EMAC_LED_OVERRIDE; - /* If value is 1, set the 1000M_OVERRIDE bit, otherwise - reset it. */ - reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) : - (reg_val & ~EMAC_LED_1000MB_OVERRIDE); - REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); - break; - case 3: /* 2500MB led */ - /* Read the current value of the LED register in the - EMAC block*/ - reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); - /* Set the OVERRIDE bit to 1 */ - reg_val |= EMAC_LED_OVERRIDE; - /* If value is 1, set the 2500M_OVERRIDE bit, otherwise - reset it.*/ - reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) : - (reg_val & ~EMAC_LED_2500MB_OVERRIDE); - REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); - break; - case 4: /*10G led */ - if (port == 0) { - REG_WR(bp, NIG_REG_LED_10G_P0, - value); - } else { - REG_WR(bp, NIG_REG_LED_10G_P1, - value); - } - break; - case 5: /* TRAFFIC led */ - /* Find if the traffic control is via BMAC or EMAC */ - if (port == 0) - reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN); - else - reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN); - - /* Override the traffic led in the EMAC:*/ - if (reg_val == 1) { - /* Read the current value of the LED register in - the EMAC block */ - reg_val = REG_RD(bp, emac_base + - EMAC_REG_EMAC_LED); - /* Set the TRAFFIC_OVERRIDE bit to 1 */ - reg_val |= EMAC_LED_OVERRIDE; - /* If value is 1, set the TRAFFIC bit, otherwise - reset it.*/ - reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) : - (reg_val & ~EMAC_LED_TRAFFIC); - REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); - } else { /* Override the traffic led in the BMAC: */ - REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 - + port*4, 1); - REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4, - value); - } - break; - default: - DP(NETIF_MSG_LINK, - "bnx2x_override_led_value() unknown led index %d " - "(should be 0-5)\n", led_idx); - return -EINVAL; - } - - return 0; -} - - u8 bnx2x_set_led(struct link_params *params, struct link_vars *vars, u8 mode, u32 speed) { @@ -3635,13 +3525,19 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1); /* Enable CL37 BAM */ - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8073_BAM, &val); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8073_BAM, val | 1); + if (REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_hw_config[params->port].default_cfg)) & + PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) { + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8073_BAM, &val); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8073_BAM, val | 1); + DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n"); + } if (params->loopback_mode == LOOPBACK_EXT) { bnx2x_807x_force_10G(bp, phy); DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n"); @@ -4099,9 +3995,9 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, return -EINVAL; } -u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, - struct link_params *params, u16 addr, - u8 byte_cnt, u8 *o_buf) +static u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, u16 addr, + u8 byte_cnt, u8 *o_buf) { if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) return bnx2x_8726_read_sfp_module_eeprom(phy, params, addr, @@ -5412,7 +5308,7 @@ static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; u16 autoneg_val, an_1000_val, an_10_100_val; - bnx2x_wait_reset_complete(bp, phy); + bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, 1 << NIG_LATCH_BC_ENABLE_MI_INT); @@ -5541,6 +5437,7 @@ static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy, /* HW reset */ bnx2x_ext_phy_hw_reset(bp, params->port); + bnx2x_wait_reset_complete(bp, phy); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); return bnx2x_848xx_cmn_config_init(phy, params, vars); @@ -5551,7 +5448,7 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u8 port = params->port, initialize = 1; + u8 port, initialize = 1; u16 val; u16 temp; u32 actual_phy_selection; @@ -5560,11 +5457,16 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, /* This is just for MDIO_CTL_REG_84823_MEDIA register. */ msleep(1); + if (CHIP_IS_E2(bp)) + port = BP_PATH(bp); + else + port = params->port; bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); - msleep(200); /* 100 is not enough */ - + bnx2x_wait_reset_complete(bp, phy); + /* Wait for GPHY to come out of reset */ + msleep(50); /* BCM84823 requires that XGXS links up first @ 10G for normal behavior */ temp = vars->line_speed; @@ -5735,7 +5637,11 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, struct link_params *params) { struct bnx2x *bp = params->bp; - u8 port = params->port; + u8 port; + if (CHIP_IS_E2(bp)) + port = BP_PATH(bp); + else + port = params->port; bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, MISC_REGISTERS_GPIO_OUTPUT_LOW, port); @@ -6819,13 +6725,6 @@ u8 bnx2x_phy_probe(struct link_params *params) return 0; } -u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx) -{ - if (phy_idx < params->num_phys) - return params->phy[phy_idx].supported; - return 0; -} - static void set_phy_vars(struct link_params *params) { struct bnx2x *bp = params->bp; @@ -7045,7 +6944,7 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, u8 reset_ext_phy) { struct bnx2x *bp = params->bp; - u8 phy_index, port = params->port; + u8 phy_index, port = params->port, clear_latch_ind = 0; DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); /* disable attentions */ vars->link_status = 0; @@ -7083,9 +6982,18 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, params->phy[phy_index].link_reset( ¶ms->phy[phy_index], params); + if (params->phy[phy_index].flags & + FLAGS_REARM_LATCH_SIGNAL) + clear_latch_ind = 1; } } + if (clear_latch_ind) { + /* Clear latching indication */ + bnx2x_rearm_latch_signal(bp, port, 0); + bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4, + 1 << NIG_LATCH_BC_ENABLE_MI_INT); + } if (params->phy[INT_PHY].link_reset) params->phy[INT_PHY].link_reset( ¶ms->phy[INT_PHY], params); @@ -7116,6 +7024,7 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, s8 port; s8 port_of_path = 0; + bnx2x_ext_phy_hw_reset(bp, 0); /* PART1 - Reset both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { u32 shmem_base, shmem2_base; @@ -7138,7 +7047,8 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, return -EINVAL; } /* disable attentions */ - bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, + bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + + port_of_path*4, (NIG_MASK_XGXS0_LINK_STATUS | NIG_MASK_XGXS0_LINK10G | NIG_MASK_SERDES0_LINK_STATUS | @@ -7249,7 +7159,7 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT))); REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val); - bnx2x_ext_phy_hw_reset(bp, 1); + bnx2x_ext_phy_hw_reset(bp, 0); msleep(5); for (port = 0; port < PORT_MAX; port++) { u32 shmem_base, shmem2_base;