diff options
author | Yaniv Rosner <yanivr@broadcom.com> | 2011-05-31 21:28:43 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-06-01 13:10:57 -0700 |
commit | 020c7e3f3cd38d41104c7f55d3d5732c5ac939be (patch) | |
tree | 1d9cbc811c8310fe2a909df3ba6740334afceadc | |
parent | 9045f6b44a01737a84c5bb79f580dccce6806d80 (diff) |
bnx2x: Adjust BCM8726 module detection settings
Move BCM8726 module detection code into a separate function to be called only once during initialization.
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/bnx2x_hsi.h | 5 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_link.c | 100 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_link.h | 4 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_main.c | 4 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_reg.h | 1 |
5 files changed, 85 insertions, 29 deletions
diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 5bfdbcc94a7c..c308a48c8f4b 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -263,7 +263,10 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ #define PORT_HW_CFG_FAULT_MODULE_LED_GPIO2 0x00000200 #define PORT_HW_CFG_FAULT_MODULE_LED_GPIO3 0x00000300 #define PORT_HW_CFG_FAULT_MODULE_LED_DISABLED 0x00000400 - u32 Reserved01[11]; /* 0x158 */ + + u32 Reserved01[10]; /* 0x158 */ + + u32 aeu_int_mask; /* 0x190 */ u32 media_type; /* 0x194 */ #define PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK 0x000000FF diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 81bcd6141065..e44c19d86c39 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -1915,8 +1915,15 @@ void bnx2x_link_status_update(struct link_params *params, PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT; DP(NETIF_MSG_LINK, "media_types = 0x%x\n", media_types); - DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n", - vars->link_status, vars->phy_link_up); + /* Sync AEU offset */ + sync_offset = params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].aeu_int_mask); + + vars->aeu_int_mask = REG_RD(bp, sync_offset); + + DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x int_mask 0x%x\n", + vars->link_status, vars->phy_link_up, vars->aeu_int_mask); DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n", vars->line_speed, vars->duplex, vars->flow_ctrl); } @@ -5522,8 +5529,6 @@ static int bnx2x_8726_config_init(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u32 val; - u32 swap_val, swap_override, aeu_gpio_mask, offset; DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); @@ -5602,30 +5607,6 @@ static int bnx2x_8726_config_init(struct bnx2x_phy *phy, phy->tx_preemphasis[1]); } - /* Set GPIO3 to trigger SFP+ module insertion/removal */ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_INPUT_HI_Z, params->port); - - /* The GPIO should be swapped if the swap register is set and active */ - swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); - swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); - - /* Select function upon port-swap configuration */ - if (params->port == 0) { - offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0; - aeu_gpio_mask = (swap_val && swap_override) ? - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 : - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0; - } else { - offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0; - aeu_gpio_mask = (swap_val && swap_override) ? - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 : - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1; - } - val = REG_RD(bp, offset); - /* add GPIO3 to group */ - val |= aeu_gpio_mask; - REG_WR(bp, offset, val); return 0; } @@ -8521,3 +8502,66 @@ void bnx2x_hw_reset_phy(struct link_params *params) } } } + +void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars, + u32 chip_id, u32 shmem_base, u32 shmem2_base, + u8 port) +{ + u8 gpio_num = 0xff, gpio_port = 0xff, phy_index; + u32 val; + u32 offset, aeu_mask, swap_val, swap_override, sync_offset; + + { + struct bnx2x_phy phy; + for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; + phy_index++) { + if (bnx2x_populate_phy(bp, phy_index, shmem_base, + shmem2_base, port, &phy) + != 0) { + DP(NETIF_MSG_LINK, "populate phy failed\n"); + return; + } + if (phy.type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) { + gpio_num = MISC_REGISTERS_GPIO_3; + gpio_port = port; + break; + } + } + } + + if (gpio_num == 0xff) + return; + + /* Set GPIO3 to trigger SFP+ module insertion/removal */ + bnx2x_set_gpio(bp, gpio_num, MISC_REGISTERS_GPIO_INPUT_HI_Z, gpio_port); + + swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); + swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); + gpio_port ^= (swap_val && swap_override); + + vars->aeu_int_mask = AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 << + (gpio_num + (gpio_port << 2)); + + sync_offset = shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].aeu_int_mask); + REG_WR(bp, sync_offset, vars->aeu_int_mask); + + DP(NETIF_MSG_LINK, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x\n", + gpio_num, gpio_port, vars->aeu_int_mask); + + if (port == 0) + offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0; + else + offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0; + + /* Open appropriate AEU for interrupts */ + aeu_mask = REG_RD(bp, offset); + aeu_mask |= vars->aeu_int_mask; + REG_WR(bp, offset, aeu_mask); + + /* Enable the GPIO to trigger interrupt */ + val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN); + val |= 1 << (gpio_num + (gpio_port << 2)); + REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val); +} diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 906b5117083d..a106d8cbd69f 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -277,6 +277,7 @@ struct link_vars { u8 fault_detected; u8 rsrv1; u16 rsrv2; + u32 aeu_int_mask; }; /***********************************************************/ @@ -401,4 +402,7 @@ int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos); void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, u32 pfc_frames_sent[2], u32 pfc_frames_received[2]); +void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars, + u32 chip_id, u32 shmem_base, u32 shmem2_base, + u8 port); #endif /* BNX2X_LINK_H */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index c6591c46ebdf..2e89b6cf37ae 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -4452,6 +4452,10 @@ void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) #endif + /* Initialize MOD_ABS interrupts */ + bnx2x_init_mod_abs_int(bp, &bp->link_vars, bp->common.chip_id, + bp->common.shmem_base, bp->common.shmem2_base, + BP_PORT(bp)); /* ensure status block indices were read */ rmb(); diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 11d35250b092..949e8bd73188 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -5184,6 +5184,7 @@ #define AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT (1<<11) #define AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT (1<<13) #define AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR (1<<12) +#define AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 (1<<2) #define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 (1<<5) #define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 (1<<9) #define AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR (1<<12) |