aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/broadcom')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h4
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c22
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c73
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h7
4 files changed, 68 insertions, 38 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index 0dd22bb44f0d..bd990c2e5d1b 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -1540,7 +1540,7 @@ static inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set)
1540{ 1540{
1541 if (SHMEM2_HAS(bp, drv_flags)) { 1541 if (SHMEM2_HAS(bp, drv_flags)) {
1542 u32 drv_flags; 1542 u32 drv_flags;
1543 bnx2x_acquire_hw_lock(bp, HW_LOCK_DRV_FLAGS); 1543 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_DRV_FLAGS);
1544 drv_flags = SHMEM2_RD(bp, drv_flags); 1544 drv_flags = SHMEM2_RD(bp, drv_flags);
1545 1545
1546 if (set) 1546 if (set)
@@ -1550,7 +1550,7 @@ static inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set)
1550 1550
1551 SHMEM2_WR(bp, drv_flags, drv_flags); 1551 SHMEM2_WR(bp, drv_flags, drv_flags);
1552 DP(NETIF_MSG_HW, "drv_flags 0x%08x\n", drv_flags); 1552 DP(NETIF_MSG_HW, "drv_flags 0x%08x\n", drv_flags);
1553 bnx2x_release_hw_lock(bp, HW_LOCK_DRV_FLAGS); 1553 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_DRV_FLAGS);
1554 } 1554 }
1555} 1555}
1556 1556
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index 31a8b38ab15e..37a5c52197eb 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -882,11 +882,27 @@ static int bnx2x_get_eeprom_len(struct net_device *dev)
882 return bp->common.flash_size; 882 return bp->common.flash_size;
883} 883}
884 884
885/* Per pf misc lock must be aquired before the per port mcp lock. Otherwise, had
886 * we done things the other way around, if two pfs from the same port would
887 * attempt to access nvram at the same time, we could run into a scenario such
888 * as:
889 * pf A takes the port lock.
890 * pf B succeeds in taking the same lock since they are from the same port.
891 * pf A takes the per pf misc lock. Performs eeprom access.
892 * pf A finishes. Unlocks the per pf misc lock.
893 * Pf B takes the lock and proceeds to perform it's own access.
894 * pf A unlocks the per port lock, while pf B is still working (!).
895 * mcp takes the per port lock and corrupts pf B's access (and/or has it's own
896 * acess corrupted by pf B).*
897 */
885static int bnx2x_acquire_nvram_lock(struct bnx2x *bp) 898static int bnx2x_acquire_nvram_lock(struct bnx2x *bp)
886{ 899{
887 int port = BP_PORT(bp); 900 int port = BP_PORT(bp);
888 int count, i; 901 int count, i;
889 u32 val = 0; 902 u32 val;
903
904 /* acquire HW lock: protect against other PFs in PF Direct Assignment */
905 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_NVRAM);
890 906
891 /* adjust timeout for emulation/FPGA */ 907 /* adjust timeout for emulation/FPGA */
892 count = BNX2X_NVRAM_TIMEOUT_COUNT; 908 count = BNX2X_NVRAM_TIMEOUT_COUNT;
@@ -917,7 +933,7 @@ static int bnx2x_release_nvram_lock(struct bnx2x *bp)
917{ 933{
918 int port = BP_PORT(bp); 934 int port = BP_PORT(bp);
919 int count, i; 935 int count, i;
920 u32 val = 0; 936 u32 val;
921 937
922 /* adjust timeout for emulation/FPGA */ 938 /* adjust timeout for emulation/FPGA */
923 count = BNX2X_NVRAM_TIMEOUT_COUNT; 939 count = BNX2X_NVRAM_TIMEOUT_COUNT;
@@ -941,6 +957,8 @@ static int bnx2x_release_nvram_lock(struct bnx2x *bp)
941 return -EBUSY; 957 return -EBUSY;
942 } 958 }
943 959
960 /* release HW lock: protect against other PFs in PF Direct Assignment */
961 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_NVRAM);
944 return 0; 962 return 0;
945} 963}
946 964
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)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
index 8c79e00b37e8..8ade7bd9a717 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
@@ -5731,6 +5731,7 @@
5731#define MISC_REGISTERS_GPIO_PORT_SHIFT 4 5731#define MISC_REGISTERS_GPIO_PORT_SHIFT 4
5732#define MISC_REGISTERS_GPIO_SET_POS 8 5732#define MISC_REGISTERS_GPIO_SET_POS 8
5733#define MISC_REGISTERS_RESET_REG_1_CLEAR 0x588 5733#define MISC_REGISTERS_RESET_REG_1_CLEAR 0x588
5734#define MISC_REGISTERS_RESET_REG_1_RST_DORQ (0x1<<19)
5734#define MISC_REGISTERS_RESET_REG_1_RST_HC (0x1<<29) 5735#define MISC_REGISTERS_RESET_REG_1_RST_HC (0x1<<29)
5735#define MISC_REGISTERS_RESET_REG_1_RST_NIG (0x1<<7) 5736#define MISC_REGISTERS_RESET_REG_1_RST_NIG (0x1<<7)
5736#define MISC_REGISTERS_RESET_REG_1_RST_PXP (0x1<<26) 5737#define MISC_REGISTERS_RESET_REG_1_RST_PXP (0x1<<26)
@@ -5783,15 +5784,17 @@
5783#define MISC_REGISTERS_SPIO_OUTPUT_HIGH 1 5784#define MISC_REGISTERS_SPIO_OUTPUT_HIGH 1
5784#define MISC_REGISTERS_SPIO_OUTPUT_LOW 0 5785#define MISC_REGISTERS_SPIO_OUTPUT_LOW 0
5785#define MISC_REGISTERS_SPIO_SET_POS 8 5786#define MISC_REGISTERS_SPIO_SET_POS 8
5786#define HW_LOCK_DRV_FLAGS 10
5787#define HW_LOCK_MAX_RESOURCE_VALUE 31 5787#define HW_LOCK_MAX_RESOURCE_VALUE 31
5788#define HW_LOCK_RESOURCE_DRV_FLAGS 10
5788#define HW_LOCK_RESOURCE_GPIO 1 5789#define HW_LOCK_RESOURCE_GPIO 1
5789#define HW_LOCK_RESOURCE_MDIO 0 5790#define HW_LOCK_RESOURCE_MDIO 0
5791#define HW_LOCK_RESOURCE_NVRAM 12
5790#define HW_LOCK_RESOURCE_PORT0_ATT_MASK 3 5792#define HW_LOCK_RESOURCE_PORT0_ATT_MASK 3
5791#define HW_LOCK_RESOURCE_RECOVERY_LEADER_0 8 5793#define HW_LOCK_RESOURCE_RECOVERY_LEADER_0 8
5792#define HW_LOCK_RESOURCE_RECOVERY_LEADER_1 9 5794#define HW_LOCK_RESOURCE_RECOVERY_LEADER_1 9
5793#define HW_LOCK_RESOURCE_SPIO 2 5795#define HW_LOCK_RESOURCE_RECOVERY_REG 11
5794#define HW_LOCK_RESOURCE_RESET 5 5796#define HW_LOCK_RESOURCE_RESET 5
5797#define HW_LOCK_RESOURCE_SPIO 2
5795#define AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT (0x1<<4) 5798#define AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT (0x1<<4)
5796#define AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR (0x1<<5) 5799#define AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR (0x1<<5)
5797#define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (0x1<<18) 5800#define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (0x1<<18)