Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'bnx2x-next'

Yuval Mintz says:

====================
bnx2x: link and protection changes

This patch series contains 2 small additions to link configuration,
as well as a safeguard against loading the device on a hardware at
a failed state.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+89 -17
+13 -2
drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
··· 521 521 */ 522 522 #define PORT_HW_CFG_TX_DRV_BROADCAST_MASK 0x000F0000 523 523 #define PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT 16 524 + /* Set non-default values for TXFIR in SFP mode. */ 525 + #define PORT_HW_CFG_TX_DRV_IFIR_MASK 0x00F00000 526 + #define PORT_HW_CFG_TX_DRV_IFIR_SHIFT 20 527 + 528 + /* Set non-default values for IPREDRIVER in SFP mode. */ 529 + #define PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK 0x0F000000 530 + #define PORT_HW_CFG_TX_DRV_IPREDRIVER_SHIFT 24 531 + 532 + /* Set non-default values for POST2 in SFP mode. */ 533 + #define PORT_HW_CFG_TX_DRV_POST2_MASK 0xF0000000 534 + #define PORT_HW_CFG_TX_DRV_POST2_SHIFT 28 524 535 525 536 u32 reserved0[5]; /* 0x17c */ 526 537 ··· 2258 2247 #define LINK_SFP_EEPROM_COMP_CODE_LRM 0x00004000 2259 2248 2260 2249 u32 reserved5[2]; 2261 - u32 reserved6[PORT_MAX]; 2262 - 2250 + u32 link_change_count[PORT_MAX]; /* Offset 0x160-0x164 */ 2251 + #define LINK_CHANGE_COUNT_MASK 0xff /* Offset 0x168 */ 2263 2252 /* driver version for each personality */ 2264 2253 struct os_drv_ver func_os_drv_ver[E2_FUNC_MAX]; /* Offset 0x16c */ 2265 2254
+67 -15
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
··· 195 195 196 196 #define MAX_PACKET_SIZE (9700) 197 197 #define MAX_KR_LINK_RETRY 4 198 + #define DEFAULT_TX_DRV_BRDCT 2 199 + #define DEFAULT_TX_DRV_IFIR 0 200 + #define DEFAULT_TX_DRV_POST2 3 201 + #define DEFAULT_TX_DRV_IPRE_DRIVER 6 198 202 199 203 /**********************************************************/ 200 204 /* INTERFACE */ ··· 3599 3595 * init configuration, and set/clear SGMII flag. Internal 3600 3596 * phy init is done purely in phy_init stage. 3601 3597 */ 3602 - #define WC_TX_DRIVER(post2, idriver, ipre) \ 3598 + #define WC_TX_DRIVER(post2, idriver, ipre, ifir) \ 3603 3599 ((post2 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | \ 3604 3600 (idriver << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | \ 3605 - (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)) 3601 + (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET) | \ 3602 + (ifir << MDIO_WC_REG_TX0_TX_DRIVER_IFIR_OFFSET)) 3606 3603 3607 3604 #define WC_TX_FIR(post, main, pre) \ 3608 3605 ((post << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | \ ··· 3770 3765 lane = bnx2x_get_warpcore_lane(phy, params); 3771 3766 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3772 3767 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 3773 - WC_TX_DRIVER(0x02, 0x06, 0x09)); 3768 + WC_TX_DRIVER(0x02, 0x06, 0x09, 0)); 3774 3769 /* Configure the next lane if dual mode */ 3775 3770 if (phy->flags & FLAGS_WC_DUAL_MODE) 3776 3771 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3777 3772 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*(lane+1), 3778 - WC_TX_DRIVER(0x02, 0x06, 0x09)); 3773 + WC_TX_DRIVER(0x02, 0x06, 0x09, 0)); 3779 3774 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3780 3775 MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL, 3781 3776 0x03f0); ··· 3938 3933 struct bnx2x *bp = params->bp; 3939 3934 u16 misc1_val, tap_val, tx_driver_val, lane, val; 3940 3935 u32 cfg_tap_val, tx_drv_brdct, tx_equal; 3936 + u32 ifir_val, ipost2_val, ipre_driver_val; 3941 3937 3942 3938 /* Hold rxSeqStart */ 3943 3939 bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, ··· 3984 3978 if (is_xfi) { 3985 3979 misc1_val |= 0x5; 3986 3980 tap_val = WC_TX_FIR(0x08, 0x37, 0x00); 3987 - tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03); 3981 + tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03, 0); 3988 3982 } else { 3989 3983 cfg_tap_val = REG_RD(bp, params->shmem_base + 3990 3984 offsetof(struct shmem_region, dev_info. ··· 3992 3986 sfi_tap_values)); 3993 3987 3994 3988 tx_equal = cfg_tap_val & PORT_HW_CFG_TX_EQUALIZATION_MASK; 3995 - 3996 - tx_drv_brdct = (cfg_tap_val & 3997 - PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >> 3998 - PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT; 3999 3989 4000 3990 misc1_val |= 0x9; 4001 3991 ··· 4001 3999 else 4002 4000 tap_val = WC_TX_FIR(0x0f, 0x2b, 0x02); 4003 4001 4004 - if (tx_drv_brdct) 4005 - tx_driver_val = WC_TX_DRIVER(0x03, (u16)tx_drv_brdct, 4006 - 0x06); 4007 - else 4008 - tx_driver_val = WC_TX_DRIVER(0x03, 0x02, 0x06); 4002 + ifir_val = DEFAULT_TX_DRV_IFIR; 4003 + ipost2_val = DEFAULT_TX_DRV_POST2; 4004 + ipre_driver_val = DEFAULT_TX_DRV_IPRE_DRIVER; 4005 + tx_drv_brdct = DEFAULT_TX_DRV_BRDCT; 4006 + 4007 + /* If any of the IFIR/IPRE_DRIVER/POST@ is set, apply all 4008 + * configuration. 4009 + */ 4010 + if (cfg_tap_val & (PORT_HW_CFG_TX_DRV_IFIR_MASK | 4011 + PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK | 4012 + PORT_HW_CFG_TX_DRV_POST2_MASK)) { 4013 + ifir_val = (cfg_tap_val & 4014 + PORT_HW_CFG_TX_DRV_IFIR_MASK) >> 4015 + PORT_HW_CFG_TX_DRV_IFIR_SHIFT; 4016 + ipre_driver_val = (cfg_tap_val & 4017 + PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK) 4018 + >> PORT_HW_CFG_TX_DRV_IPREDRIVER_SHIFT; 4019 + ipost2_val = (cfg_tap_val & 4020 + PORT_HW_CFG_TX_DRV_POST2_MASK) >> 4021 + PORT_HW_CFG_TX_DRV_POST2_SHIFT; 4022 + } 4023 + 4024 + if (cfg_tap_val & PORT_HW_CFG_TX_DRV_BROADCAST_MASK) { 4025 + tx_drv_brdct = (cfg_tap_val & 4026 + PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >> 4027 + PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT; 4028 + } 4029 + 4030 + tx_driver_val = WC_TX_DRIVER(ipost2_val, tx_drv_brdct, 4031 + ipre_driver_val, ifir_val); 4009 4032 } 4010 4033 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4011 4034 MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val); ··· 4171 4144 MDIO_WC_REG_TX_FIR_TAP_ENABLE)); 4172 4145 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4173 4146 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 4174 - WC_TX_DRIVER(0x02, 0x02, 0x02)); 4147 + WC_TX_DRIVER(0x02, 0x02, 0x02, 0)); 4175 4148 } 4176 4149 4177 4150 static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy, ··· 6758 6731 msleep(20); 6759 6732 return rc; 6760 6733 } 6734 + 6735 + static void bnx2x_chng_link_count(struct link_params *params, bool clear) 6736 + { 6737 + struct bnx2x *bp = params->bp; 6738 + u32 addr, val; 6739 + 6740 + /* Verify the link_change_count is supported by the MFW */ 6741 + if (!(SHMEM2_HAS(bp, link_change_count))) 6742 + return; 6743 + 6744 + addr = params->shmem2_base + 6745 + offsetof(struct shmem2_region, link_change_count[params->port]); 6746 + if (clear) 6747 + val = 0; 6748 + else 6749 + val = REG_RD(bp, addr) + 1; 6750 + REG_WR(bp, addr, val); 6751 + } 6752 + 6761 6753 /* The bnx2x_link_update function should be called upon link 6762 6754 * interrupt. 6763 6755 * Link is considered up as follows: ··· 6795 6749 struct link_vars phy_vars[MAX_PHYS]; 6796 6750 u8 port = params->port; 6797 6751 u8 link_10g_plus, phy_index; 6752 + u32 prev_link_status = vars->link_status; 6798 6753 u8 ext_phy_link_up = 0, cur_link_up; 6799 6754 int rc = 0; 6800 6755 u8 is_mi_int = 0; ··· 7034 6987 rc = bnx2x_update_link_up(params, vars, link_10g_plus); 7035 6988 else 7036 6989 rc = bnx2x_update_link_down(params, vars); 6990 + 6991 + if ((prev_link_status ^ vars->link_status) & LINK_STATUS_LINK_UP) 6992 + bnx2x_chng_link_count(params, false); 7037 6993 7038 6994 /* Update MCP link status was changed */ 7039 6995 if (params->feature_config_flags & FEATURE_CONFIG_BC_SUPPORTS_AFEX) ··· 12681 12631 params->link_flags = PHY_INITIALIZED; 12682 12632 /* Driver opens NIG-BRB filters */ 12683 12633 bnx2x_set_rx_filter(params, 1); 12634 + bnx2x_chng_link_count(params, true); 12684 12635 /* Check if link flap can be avoided */ 12685 12636 lfa_status = bnx2x_check_lfa(params); 12686 12637 ··· 12756 12705 DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); 12757 12706 /* Disable attentions */ 12758 12707 vars->link_status = 0; 12708 + bnx2x_chng_link_count(params, true); 12759 12709 bnx2x_update_mng(params, vars->link_status); 12760 12710 vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK | 12761 12711 SHMEM_EEE_ACTIVE_BIT);
+7
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
··· 11650 11650 u32 val = 0, val2 = 0; 11651 11651 int rc = 0; 11652 11652 11653 + /* Validate that chip access is feasible */ 11654 + if (REG_RD(bp, MISC_REG_CHIP_NUM) == 0xffffffff) { 11655 + dev_err(&bp->pdev->dev, 11656 + "Chip read returns all Fs. Preventing probe from continuing\n"); 11657 + return -EINVAL; 11658 + } 11659 + 11653 11660 bnx2x_get_common_hwinfo(bp); 11654 11661 11655 11662 /*
+2
drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
··· 7341 7341 #define MDIO_WC_REG_TX2_ANA_CTRL0 0x8081 7342 7342 #define MDIO_WC_REG_TX3_ANA_CTRL0 0x8091 7343 7343 #define MDIO_WC_REG_TX0_TX_DRIVER 0x8067 7344 + #define MDIO_WC_REG_TX0_TX_DRIVER_IFIR_OFFSET 0x01 7345 + #define MDIO_WC_REG_TX0_TX_DRIVER_IFIR_MASK 0x000e 7344 7346 #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET 0x04 7345 7347 #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_MASK 0x00f0 7346 7348 #define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET 0x08