diff options
author | Michael Chan <mchan@broadcom.com> | 2007-05-03 16:24:05 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-05-03 16:24:05 -0400 |
commit | 1b8227c48e164655f02aa0eff55862af2d05da51 (patch) | |
tree | ee1598123fba3ee397a463ff706ec8f235464523 /drivers/net | |
parent | 27a005b883984ef3a3cf24e7ddd78eb78902f494 (diff) |
[BNX2]: Add indirect spinlock.
The indirect register access method will be used by more than one
caller in BH context (NAPI poll and timer), so a spinlock is required.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/bnx2.c | 12 | ||||
-rw-r--r-- | drivers/net/bnx2.h | 1 |
2 files changed, 12 insertions, 1 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index ab589090d634..cb74f122138c 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -234,21 +234,29 @@ static inline u32 bnx2_tx_avail(struct bnx2 *bp) | |||
234 | static u32 | 234 | static u32 |
235 | bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset) | 235 | bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset) |
236 | { | 236 | { |
237 | u32 val; | ||
238 | |||
239 | spin_lock_bh(&bp->indirect_lock); | ||
237 | REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset); | 240 | REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset); |
238 | return (REG_RD(bp, BNX2_PCICFG_REG_WINDOW)); | 241 | val = REG_RD(bp, BNX2_PCICFG_REG_WINDOW); |
242 | spin_unlock_bh(&bp->indirect_lock); | ||
243 | return val; | ||
239 | } | 244 | } |
240 | 245 | ||
241 | static void | 246 | static void |
242 | bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val) | 247 | bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val) |
243 | { | 248 | { |
249 | spin_lock_bh(&bp->indirect_lock); | ||
244 | REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset); | 250 | REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset); |
245 | REG_WR(bp, BNX2_PCICFG_REG_WINDOW, val); | 251 | REG_WR(bp, BNX2_PCICFG_REG_WINDOW, val); |
252 | spin_unlock_bh(&bp->indirect_lock); | ||
246 | } | 253 | } |
247 | 254 | ||
248 | static void | 255 | static void |
249 | bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val) | 256 | bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val) |
250 | { | 257 | { |
251 | offset += cid_addr; | 258 | offset += cid_addr; |
259 | spin_lock_bh(&bp->indirect_lock); | ||
252 | if (CHIP_NUM(bp) == CHIP_NUM_5709) { | 260 | if (CHIP_NUM(bp) == CHIP_NUM_5709) { |
253 | int i; | 261 | int i; |
254 | 262 | ||
@@ -266,6 +274,7 @@ bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val) | |||
266 | REG_WR(bp, BNX2_CTX_DATA_ADR, offset); | 274 | REG_WR(bp, BNX2_CTX_DATA_ADR, offset); |
267 | REG_WR(bp, BNX2_CTX_DATA, val); | 275 | REG_WR(bp, BNX2_CTX_DATA, val); |
268 | } | 276 | } |
277 | spin_unlock_bh(&bp->indirect_lock); | ||
269 | } | 278 | } |
270 | 279 | ||
271 | static int | 280 | static int |
@@ -6039,6 +6048,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
6039 | bp->pdev = pdev; | 6048 | bp->pdev = pdev; |
6040 | 6049 | ||
6041 | spin_lock_init(&bp->phy_lock); | 6050 | spin_lock_init(&bp->phy_lock); |
6051 | spin_lock_init(&bp->indirect_lock); | ||
6042 | INIT_WORK(&bp->reset_task, bnx2_reset_task); | 6052 | INIT_WORK(&bp->reset_task, bnx2_reset_task); |
6043 | 6053 | ||
6044 | dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0); | 6054 | dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0); |
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 124bd03cff3e..ba175a800c8e 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h | |||
@@ -6522,6 +6522,7 @@ struct bnx2 { | |||
6522 | 6522 | ||
6523 | /* Used to synchronize phy accesses. */ | 6523 | /* Used to synchronize phy accesses. */ |
6524 | spinlock_t phy_lock; | 6524 | spinlock_t phy_lock; |
6525 | spinlock_t indirect_lock; | ||
6525 | 6526 | ||
6526 | u32 phy_flags; | 6527 | u32 phy_flags; |
6527 | #define PHY_SERDES_FLAG 1 | 6528 | #define PHY_SERDES_FLAG 1 |