diff options
author | Eilon Greenstein <eilong@broadcom.com> | 2009-02-12 03:36:55 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-16 02:31:24 -0500 |
commit | 589abe3a0f594a7707a15674ca9e80370c972832 (patch) | |
tree | a7930047ca7f5340b9053948fcba98128de4d588 /drivers/net/bnx2x_main.c | |
parent | 4acac6a53a3c9dfc604a9a8647f16b0242080e93 (diff) |
bnx2x: Supporting BCM8726 PHY
Also adding the ability to recognize the optic module and disable it if it is
not authorized for safety reasons - since this feature might upset some users
which are willing to take the risk, it is optional and can be disabled by
setting an nvram bit (or a trivial driver patch to set this bit).
This dual port PHY requires special handling if the ports are swapped.
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>
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r-- | drivers/net/bnx2x_main.c | 90 |
1 files changed, 75 insertions, 15 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 95f8e58e73b4..5acbd98778b8 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c | |||
@@ -2112,7 +2112,7 @@ static void bnx2x__link_reset(struct bnx2x *bp) | |||
2112 | { | 2112 | { |
2113 | if (!BP_NOMCP(bp)) { | 2113 | if (!BP_NOMCP(bp)) { |
2114 | bnx2x_acquire_phy_lock(bp); | 2114 | bnx2x_acquire_phy_lock(bp); |
2115 | bnx2x_link_reset(&bp->link_params, &bp->link_vars); | 2115 | bnx2x_link_reset(&bp->link_params, &bp->link_vars, 1); |
2116 | bnx2x_release_phy_lock(bp); | 2116 | bnx2x_release_phy_lock(bp); |
2117 | } else | 2117 | } else |
2118 | BNX2X_ERR("Bootcode is missing -not resetting link\n"); | 2118 | BNX2X_ERR("Bootcode is missing -not resetting link\n"); |
@@ -2613,6 +2613,13 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) | |||
2613 | } | 2613 | } |
2614 | } | 2614 | } |
2615 | 2615 | ||
2616 | if (attn & (AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 | | ||
2617 | AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1)) { | ||
2618 | bnx2x_acquire_phy_lock(bp); | ||
2619 | bnx2x_handle_module_detect_int(&bp->link_params); | ||
2620 | bnx2x_release_phy_lock(bp); | ||
2621 | } | ||
2622 | |||
2616 | if (attn & HW_INTERRUT_ASSERT_SET_0) { | 2623 | if (attn & HW_INTERRUT_ASSERT_SET_0) { |
2617 | 2624 | ||
2618 | val = REG_RD(bp, reg_offset); | 2625 | val = REG_RD(bp, reg_offset); |
@@ -5905,6 +5912,37 @@ static int bnx2x_init_port(struct bnx2x *bp) | |||
5905 | /* Port DMAE comes here */ | 5912 | /* Port DMAE comes here */ |
5906 | 5913 | ||
5907 | switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { | 5914 | switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { |
5915 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: | ||
5916 | { | ||
5917 | u32 swap_val, swap_override, aeu_gpio_mask, offset; | ||
5918 | |||
5919 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, | ||
5920 | MISC_REGISTERS_GPIO_INPUT_HI_Z, port); | ||
5921 | |||
5922 | /* The GPIO should be swapped if the swap register is | ||
5923 | set and active */ | ||
5924 | swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); | ||
5925 | swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); | ||
5926 | |||
5927 | /* Select function upon port-swap configuration */ | ||
5928 | if (port == 0) { | ||
5929 | offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0; | ||
5930 | aeu_gpio_mask = (swap_val && swap_override) ? | ||
5931 | AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 : | ||
5932 | AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0; | ||
5933 | } else { | ||
5934 | offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0; | ||
5935 | aeu_gpio_mask = (swap_val && swap_override) ? | ||
5936 | AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 : | ||
5937 | AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1; | ||
5938 | } | ||
5939 | val = REG_RD(bp, offset); | ||
5940 | /* add GPIO3 to group */ | ||
5941 | val |= aeu_gpio_mask; | ||
5942 | REG_WR(bp, offset, val); | ||
5943 | } | ||
5944 | break; | ||
5945 | |||
5908 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: | 5946 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: |
5909 | /* add SPIO 5 to group 0 */ | 5947 | /* add SPIO 5 to group 0 */ |
5910 | val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); | 5948 | val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); |
@@ -7623,48 +7661,60 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, | |||
7623 | SUPPORTED_Asym_Pause); | 7661 | SUPPORTED_Asym_Pause); |
7624 | break; | 7662 | break; |
7625 | 7663 | ||
7626 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: | 7664 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: |
7627 | BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n", | 7665 | BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n", |
7628 | ext_phy_type); | 7666 | ext_phy_type); |
7629 | 7667 | ||
7630 | bp->port.supported |= (SUPPORTED_10000baseT_Full | | 7668 | bp->port.supported |= (SUPPORTED_10000baseT_Full | |
7669 | SUPPORTED_1000baseT_Full | | ||
7631 | SUPPORTED_FIBRE | | 7670 | SUPPORTED_FIBRE | |
7671 | SUPPORTED_Autoneg | | ||
7632 | SUPPORTED_Pause | | 7672 | SUPPORTED_Pause | |
7633 | SUPPORTED_Asym_Pause); | 7673 | SUPPORTED_Asym_Pause); |
7634 | break; | 7674 | break; |
7635 | 7675 | ||
7636 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: | 7676 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: |
7637 | BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n", | 7677 | BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n", |
7638 | ext_phy_type); | 7678 | ext_phy_type); |
7639 | 7679 | ||
7640 | bp->port.supported |= (SUPPORTED_10000baseT_Full | | 7680 | bp->port.supported |= (SUPPORTED_10000baseT_Full | |
7681 | SUPPORTED_2500baseX_Full | | ||
7641 | SUPPORTED_1000baseT_Full | | 7682 | SUPPORTED_1000baseT_Full | |
7642 | SUPPORTED_FIBRE | | 7683 | SUPPORTED_FIBRE | |
7684 | SUPPORTED_Autoneg | | ||
7685 | SUPPORTED_Pause | | ||
7686 | SUPPORTED_Asym_Pause); | ||
7687 | break; | ||
7688 | |||
7689 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: | ||
7690 | BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n", | ||
7691 | ext_phy_type); | ||
7692 | |||
7693 | bp->port.supported |= (SUPPORTED_10000baseT_Full | | ||
7694 | SUPPORTED_FIBRE | | ||
7643 | SUPPORTED_Pause | | 7695 | SUPPORTED_Pause | |
7644 | SUPPORTED_Asym_Pause); | 7696 | SUPPORTED_Asym_Pause); |
7645 | break; | 7697 | break; |
7646 | 7698 | ||
7647 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: | 7699 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: |
7648 | BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n", | 7700 | BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n", |
7649 | ext_phy_type); | 7701 | ext_phy_type); |
7650 | 7702 | ||
7651 | bp->port.supported |= (SUPPORTED_10000baseT_Full | | 7703 | bp->port.supported |= (SUPPORTED_10000baseT_Full | |
7652 | SUPPORTED_1000baseT_Full | | 7704 | SUPPORTED_1000baseT_Full | |
7653 | SUPPORTED_FIBRE | | 7705 | SUPPORTED_FIBRE | |
7654 | SUPPORTED_Autoneg | | ||
7655 | SUPPORTED_Pause | | 7706 | SUPPORTED_Pause | |
7656 | SUPPORTED_Asym_Pause); | 7707 | SUPPORTED_Asym_Pause); |
7657 | break; | 7708 | break; |
7658 | 7709 | ||
7659 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: | 7710 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: |
7660 | BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n", | 7711 | BNX2X_DEV_INFO("ext_phy_type 0x%x (8726)\n", |
7661 | ext_phy_type); | 7712 | ext_phy_type); |
7662 | 7713 | ||
7663 | bp->port.supported |= (SUPPORTED_10000baseT_Full | | 7714 | bp->port.supported |= (SUPPORTED_10000baseT_Full | |
7664 | SUPPORTED_2500baseX_Full | | ||
7665 | SUPPORTED_1000baseT_Full | | 7715 | SUPPORTED_1000baseT_Full | |
7666 | SUPPORTED_FIBRE | | ||
7667 | SUPPORTED_Autoneg | | 7716 | SUPPORTED_Autoneg | |
7717 | SUPPORTED_FIBRE | | ||
7668 | SUPPORTED_Pause | | 7718 | SUPPORTED_Pause | |
7669 | SUPPORTED_Asym_Pause); | 7719 | SUPPORTED_Asym_Pause); |
7670 | break; | 7720 | break; |
@@ -7905,6 +7955,7 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) | |||
7905 | { | 7955 | { |
7906 | int port = BP_PORT(bp); | 7956 | int port = BP_PORT(bp); |
7907 | u32 val, val2; | 7957 | u32 val, val2; |
7958 | u32 config; | ||
7908 | 7959 | ||
7909 | bp->link_params.bp = bp; | 7960 | bp->link_params.bp = bp; |
7910 | bp->link_params.port = port; | 7961 | bp->link_params.port = port; |
@@ -7923,6 +7974,14 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) | |||
7923 | bp->port.link_config = | 7974 | bp->port.link_config = |
7924 | SHMEM_RD(bp, dev_info.port_feature_config[port].link_config); | 7975 | SHMEM_RD(bp, dev_info.port_feature_config[port].link_config); |
7925 | 7976 | ||
7977 | config = SHMEM_RD(bp, dev_info.port_feature_config[port].config); | ||
7978 | if (config & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_ENABLED) | ||
7979 | bp->link_params.feature_config_flags |= | ||
7980 | FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED; | ||
7981 | else | ||
7982 | bp->link_params.feature_config_flags &= | ||
7983 | ~FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED; | ||
7984 | |||
7926 | BNX2X_DEV_INFO("serdes_config 0x%08x lane_config 0x%08x\n" | 7985 | BNX2X_DEV_INFO("serdes_config 0x%08x lane_config 0x%08x\n" |
7927 | KERN_INFO " ext_phy_config 0x%08x speed_cap_mask 0x%08x" | 7986 | KERN_INFO " ext_phy_config 0x%08x speed_cap_mask 0x%08x" |
7928 | " link_config 0x%08x\n", | 7987 | " link_config 0x%08x\n", |
@@ -8121,10 +8180,11 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
8121 | 8180 | ||
8122 | switch (ext_phy_type) { | 8181 | switch (ext_phy_type) { |
8123 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: | 8182 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: |
8124 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: | ||
8125 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: | ||
8126 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: | 8183 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: |
8127 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: | 8184 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: |
8185 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: | ||
8186 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: | ||
8187 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: | ||
8128 | cmd->port = PORT_FIBRE; | 8188 | cmd->port = PORT_FIBRE; |
8129 | break; | 8189 | break; |
8130 | 8190 | ||
@@ -8807,7 +8867,7 @@ static int bnx2x_set_eeprom(struct net_device *dev, | |||
8807 | if ((bp->state == BNX2X_STATE_OPEN) || | 8867 | if ((bp->state == BNX2X_STATE_OPEN) || |
8808 | (bp->state == BNX2X_STATE_DISABLED)) { | 8868 | (bp->state == BNX2X_STATE_DISABLED)) { |
8809 | rc |= bnx2x_link_reset(&bp->link_params, | 8869 | rc |= bnx2x_link_reset(&bp->link_params, |
8810 | &bp->link_vars); | 8870 | &bp->link_vars, 1); |
8811 | rc |= bnx2x_phy_init(&bp->link_params, | 8871 | rc |= bnx2x_phy_init(&bp->link_params, |
8812 | &bp->link_vars); | 8872 | &bp->link_vars); |
8813 | } | 8873 | } |