]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/net/bnx2x/bnx2x_link.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[net-next-2.6.git] / drivers / net / bnx2x / bnx2x_link.c
index 3e99bf9c42b9a83ae18437538f42322e38413d28..38aeffef2a832be22a48ceaa14b3d612bbb4ee64 100644 (file)
                (_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");
@@ -4008,7 +3904,7 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
                              MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
                if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
                    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
-                       return 0;;
+                       return 0;
                msleep(1);
        }
        return -EINVAL;
@@ -4092,16 +3988,16 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
                              MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
                if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
                    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
-                       return 0;;
+                       return 0;
                msleep(1);
        }
 
        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(
                                        &params->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(
                        &params->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;