aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
diff options
context:
space:
mode:
authorAriel Elior <ariele@broadcom.com>2012-01-26 01:01:50 -0500
committerDavid S. Miller <davem@davemloft.net>2012-01-26 13:39:52 -0500
commitf16da43b5df947cef427f19b8f5c4b2f5d566231 (patch)
treea9076701c918b56a4daedc4e7bd6336101f4cdf8 /drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
parentd1e2d9660e6bca2f06606b4bc65ea669bf669b0a (diff)
bnx2x: Lock PF-common resources
Use hardware locks to protect resources common to several Physical Functions. In a virtualized environment the RTNL lock only protects a PF's driver against the PFs sharing it's VMs with regard to device resources. Other PFs may reside in other VMs under other OSs, and are not subject to the lock. Such resources which were previously protected implicitly by the RTNL lock must now be protected explicitly with dedicated HW locks. Signed-off-by: Ariel Elior <ariele@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c73
1 files changed, 41 insertions, 32 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 9a1c4501f0ec..4824b0f8bd23 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -3724,11 +3724,11 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
3724 */ 3724 */
3725void bnx2x_set_reset_global(struct bnx2x *bp) 3725void bnx2x_set_reset_global(struct bnx2x *bp)
3726{ 3726{
3727 u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); 3727 u32 val;
3728 3728 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
3729 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
3729 REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val | BNX2X_GLOBAL_RESET_BIT); 3730 REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val | BNX2X_GLOBAL_RESET_BIT);
3730 barrier(); 3731 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
3731 mmiowb();
3732} 3732}
3733 3733
3734/* 3734/*
@@ -3738,11 +3738,11 @@ void bnx2x_set_reset_global(struct bnx2x *bp)
3738 */ 3738 */
3739static inline void bnx2x_clear_reset_global(struct bnx2x *bp) 3739static inline void bnx2x_clear_reset_global(struct bnx2x *bp)
3740{ 3740{
3741 u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); 3741 u32 val;
3742 3742 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
3743 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
3743 REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~BNX2X_GLOBAL_RESET_BIT)); 3744 REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~BNX2X_GLOBAL_RESET_BIT));
3744 barrier(); 3745 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
3745 mmiowb();
3746} 3746}
3747 3747
3748/* 3748/*
@@ -3765,15 +3765,17 @@ static inline bool bnx2x_reset_is_global(struct bnx2x *bp)
3765 */ 3765 */
3766static inline void bnx2x_set_reset_done(struct bnx2x *bp) 3766static inline void bnx2x_set_reset_done(struct bnx2x *bp)
3767{ 3767{
3768 u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); 3768 u32 val;
3769 u32 bit = BP_PATH(bp) ? 3769 u32 bit = BP_PATH(bp) ?
3770 BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT; 3770 BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT;
3771 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
3772 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
3771 3773
3772 /* Clear the bit */ 3774 /* Clear the bit */
3773 val &= ~bit; 3775 val &= ~bit;
3774 REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val); 3776 REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val);
3775 barrier(); 3777
3776 mmiowb(); 3778 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
3777} 3779}
3778 3780
3779/* 3781/*
@@ -3783,15 +3785,16 @@ static inline void bnx2x_set_reset_done(struct bnx2x *bp)
3783 */ 3785 */
3784void bnx2x_set_reset_in_progress(struct bnx2x *bp) 3786void bnx2x_set_reset_in_progress(struct bnx2x *bp)
3785{ 3787{
3786 u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); 3788 u32 val;
3787 u32 bit = BP_PATH(bp) ? 3789 u32 bit = BP_PATH(bp) ?
3788 BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT; 3790 BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT;
3791 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
3792 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
3789 3793
3790 /* Set the bit */ 3794 /* Set the bit */
3791 val |= bit; 3795 val |= bit;
3792 REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val); 3796 REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val);
3793 barrier(); 3797 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
3794 mmiowb();
3795} 3798}
3796 3799
3797/* 3800/*
@@ -3815,12 +3818,15 @@ bool bnx2x_reset_is_done(struct bnx2x *bp, int engine)
3815 */ 3818 */
3816void bnx2x_inc_load_cnt(struct bnx2x *bp) 3819void bnx2x_inc_load_cnt(struct bnx2x *bp)
3817{ 3820{
3818 u32 val1, val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); 3821 u32 val1, val;
3819 u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : 3822 u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK :
3820 BNX2X_PATH0_LOAD_CNT_MASK; 3823 BNX2X_PATH0_LOAD_CNT_MASK;
3821 u32 shift = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_SHIFT : 3824 u32 shift = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_SHIFT :
3822 BNX2X_PATH0_LOAD_CNT_SHIFT; 3825 BNX2X_PATH0_LOAD_CNT_SHIFT;
3823 3826
3827 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
3828 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
3829
3824 DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val); 3830 DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val);
3825 3831
3826 /* get the current counter value */ 3832 /* get the current counter value */
@@ -3836,8 +3842,7 @@ void bnx2x_inc_load_cnt(struct bnx2x *bp)
3836 val |= ((val1 << shift) & mask); 3842 val |= ((val1 << shift) & mask);
3837 3843
3838 REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val); 3844 REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val);
3839 barrier(); 3845 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
3840 mmiowb();
3841} 3846}
3842 3847
3843/** 3848/**
@@ -3851,12 +3856,14 @@ void bnx2x_inc_load_cnt(struct bnx2x *bp)
3851 */ 3856 */
3852u32 bnx2x_dec_load_cnt(struct bnx2x *bp) 3857u32 bnx2x_dec_load_cnt(struct bnx2x *bp)
3853{ 3858{
3854 u32 val1, val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); 3859 u32 val1, val;
3855 u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : 3860 u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK :
3856 BNX2X_PATH0_LOAD_CNT_MASK; 3861 BNX2X_PATH0_LOAD_CNT_MASK;
3857 u32 shift = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_SHIFT : 3862 u32 shift = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_SHIFT :
3858 BNX2X_PATH0_LOAD_CNT_SHIFT; 3863 BNX2X_PATH0_LOAD_CNT_SHIFT;
3859 3864
3865 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
3866 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
3860 DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val); 3867 DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val);
3861 3868
3862 /* get the current counter value */ 3869 /* get the current counter value */
@@ -3872,10 +3879,8 @@ u32 bnx2x_dec_load_cnt(struct bnx2x *bp)
3872 val |= ((val1 << shift) & mask); 3879 val |= ((val1 << shift) & mask);
3873 3880
3874 REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val); 3881 REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val);
3875 barrier(); 3882 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
3876 mmiowb(); 3883 return val1 != 0;
3877
3878 return val1;
3879} 3884}
3880 3885
3881/* 3886/*
@@ -3907,11 +3912,13 @@ static inline u32 bnx2x_get_load_cnt(struct bnx2x *bp, int engine)
3907 */ 3912 */
3908static inline void bnx2x_clear_load_cnt(struct bnx2x *bp) 3913static inline void bnx2x_clear_load_cnt(struct bnx2x *bp)
3909{ 3914{
3910 u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); 3915 u32 val;
3911 u32 mask = (BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : 3916 u32 mask = (BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK :
3912 BNX2X_PATH0_LOAD_CNT_MASK); 3917 BNX2X_PATH0_LOAD_CNT_MASK);
3913 3918 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
3919 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
3914 REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~mask)); 3920 REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~mask));
3921 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
3915} 3922}
3916 3923
3917static inline void _print_next_block(int idx, const char *blk) 3924static inline void _print_next_block(int idx, const char *blk)
@@ -8809,11 +8816,13 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
8809{ 8816{
8810 u32 val; 8817 u32 val;
8811 8818
8812 /* Check if there is any driver already loaded */ 8819 /* possibly another driver is trying to reset the chip */
8813 val = REG_RD(bp, MISC_REG_UNPREPARED); 8820 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
8814 if (val == 0x1) { 8821
8822 /* check if doorbell queue is reset */
8823 if (REG_RD(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET)
8824 & MISC_REGISTERS_RESET_REG_1_RST_DORQ) {
8815 8825
8816 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
8817 /* 8826 /*
8818 * Check if it is the UNDI driver 8827 * Check if it is the UNDI driver
8819 * UNDI driver initializes CID offset for normal bell to 0x7 8828 * UNDI driver initializes CID offset for normal bell to 0x7
@@ -8905,10 +8914,10 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
8905 (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & 8914 (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) &
8906 DRV_MSG_SEQ_NUMBER_MASK); 8915 DRV_MSG_SEQ_NUMBER_MASK);
8907 } 8916 }
8908
8909 /* now it's safe to release the lock */
8910 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
8911 } 8917 }
8918
8919 /* now it's safe to release the lock */
8920 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
8912} 8921}
8913 8922
8914static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) 8923static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)