aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2013-01-22 22:21:52 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-23 13:58:29 -0500
commitad9b4359c7839d4d87aad2c0d50c8a2ef3bcddb3 (patch)
treef64349d80b54c58cd85f5f6e8fcb756c07c1d322 /drivers
parent580d9d081341aad5341884f9e6b070c01512e94c (diff)
cnic, bnx2x: Add CNIC_DRV_STATE_HANDLES_IRQ to ethdev->drv_state
In INTA mode, cnic and bnx2x share the same IRQ. During chip reset, for example, cnic will stop servicing IRQs after it has shutdown the cnic hardware resources. However, the shared IRQ is still active as bnx2x needs to finish the reset. There is a window when bnx2x does not know that cnic is no longer handling IRQ and things don't always work properly. Add a flag to tell bnx2x that cnic is handling IRQ. The flag is set before the first cnic IRQ is expected and cleared when no more cnic IRQs are expected, so there should be no race conditions. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com> 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')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c14
-rw-r--r--drivers/net/ethernet/broadcom/cnic.c4
-rw-r--r--drivers/net/ethernet/broadcom/cnic_if.h1
3 files changed, 11 insertions, 8 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index ac00ddcd32fa..c4daee1b7286 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -1875,14 +1875,12 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
1875 if (status & (mask | 0x1)) { 1875 if (status & (mask | 0x1)) {
1876 struct cnic_ops *c_ops = NULL; 1876 struct cnic_ops *c_ops = NULL;
1877 1877
1878 if (likely(bp->state == BNX2X_STATE_OPEN)) { 1878 rcu_read_lock();
1879 rcu_read_lock(); 1879 c_ops = rcu_dereference(bp->cnic_ops);
1880 c_ops = rcu_dereference(bp->cnic_ops); 1880 if (c_ops && (bp->cnic_eth_dev.drv_state &
1881 if (c_ops) 1881 CNIC_DRV_STATE_HANDLES_IRQ))
1882 c_ops->cnic_handler(bp->cnic_data, 1882 c_ops->cnic_handler(bp->cnic_data, NULL);
1883 NULL); 1883 rcu_read_unlock();
1884 rcu_read_unlock();
1885 }
1886 1884
1887 status &= ~mask; 1885 status &= ~mask;
1888 } 1886 }
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
index df8c30d1a52c..1c4dadc7ebbb 100644
--- a/drivers/net/ethernet/broadcom/cnic.c
+++ b/drivers/net/ethernet/broadcom/cnic.c
@@ -4816,6 +4816,8 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)
4816 return err; 4816 return err;
4817 } 4817 }
4818 4818
4819 ethdev->drv_state |= CNIC_DRV_STATE_HANDLES_IRQ;
4820
4819 return 0; 4821 return 0;
4820} 4822}
4821 4823
@@ -5136,6 +5138,7 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev)
5136 if (ret) 5138 if (ret)
5137 return ret; 5139 return ret;
5138 5140
5141 ethdev->drv_state |= CNIC_DRV_STATE_HANDLES_IRQ;
5139 return 0; 5142 return 0;
5140} 5143}
5141 5144
@@ -5387,6 +5390,7 @@ static void cnic_stop_hw(struct cnic_dev *dev)
5387 } 5390 }
5388 cnic_shutdown_rings(dev); 5391 cnic_shutdown_rings(dev);
5389 cp->stop_cm(dev); 5392 cp->stop_cm(dev);
5393 cp->ethdev->drv_state &= ~CNIC_DRV_STATE_HANDLES_IRQ;
5390 clear_bit(CNIC_F_CNIC_UP, &dev->flags); 5394 clear_bit(CNIC_F_CNIC_UP, &dev->flags);
5391 RCU_INIT_POINTER(cp->ulp_ops[CNIC_ULP_L4], NULL); 5395 RCU_INIT_POINTER(cp->ulp_ops[CNIC_ULP_L4], NULL);
5392 synchronize_rcu(); 5396 synchronize_rcu();
diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h
index 2a35436f9095..0c9367a0f57d 100644
--- a/drivers/net/ethernet/broadcom/cnic_if.h
+++ b/drivers/net/ethernet/broadcom/cnic_if.h
@@ -179,6 +179,7 @@ struct cnic_eth_dev {
179#define CNIC_DRV_STATE_NO_ISCSI_OOO 0x00000004 179#define CNIC_DRV_STATE_NO_ISCSI_OOO 0x00000004
180#define CNIC_DRV_STATE_NO_ISCSI 0x00000008 180#define CNIC_DRV_STATE_NO_ISCSI 0x00000008
181#define CNIC_DRV_STATE_NO_FCOE 0x00000010 181#define CNIC_DRV_STATE_NO_FCOE 0x00000010
182#define CNIC_DRV_STATE_HANDLES_IRQ 0x00000020
182 u32 chip_id; 183 u32 chip_id;
183 u32 max_kwqe_pending; 184 u32 max_kwqe_pending;
184 struct pci_dev *pdev; 185 struct pci_dev *pdev;