aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSathya Perla <sathyap@serverengines.com>2010-02-16 20:35:11 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-17 16:35:39 -0500
commit7a1e9b2059d147461cff3dfbabbfb43f296a1eef (patch)
tree96cede2e32bf278b86a06faab7c7940ee5d776b3 /drivers
parenta058a632747dd0f1799b12f4ecd54e43f5b5f10d (diff)
be2net: don't rearm mcc cq when device is not open
When an MCC cmd is issued (via a netdev/ethtool op) while the device is not open, the MCC CQ gets processed but the EQ is not processed (as isr is not registered.) This can cause the EQ to become full. So, while the device is not open, CQ must not be re-armed to prevent EQ entries. Signed-off-by: Sathya Perla <sathyap@serverengines.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/benet/be.h1
-rw-r--r--drivers/net/benet/be_cmds.c20
-rw-r--r--drivers/net/benet/be_cmds.h2
-rw-r--r--drivers/net/benet/be_main.c5
4 files changed, 26 insertions, 2 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 5038c16bfe9b..2734a41a4627 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -151,6 +151,7 @@ struct be_eq_obj {
151struct be_mcc_obj { 151struct be_mcc_obj {
152 struct be_queue_info q; 152 struct be_queue_info q;
153 struct be_queue_info cq; 153 struct be_queue_info cq;
154 bool rearm_cq;
154}; 155};
155 156
156struct be_drvr_stats { 157struct be_drvr_stats {
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 477f82bc647e..d7546b450505 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -104,10 +104,26 @@ static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
104 return NULL; 104 return NULL;
105} 105}
106 106
107void be_async_mcc_enable(struct be_adapter *adapter)
108{
109 spin_lock_bh(&adapter->mcc_cq_lock);
110
111 be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, 0);
112 adapter->mcc_obj.rearm_cq = true;
113
114 spin_unlock_bh(&adapter->mcc_cq_lock);
115}
116
117void be_async_mcc_disable(struct be_adapter *adapter)
118{
119 adapter->mcc_obj.rearm_cq = false;
120}
121
107int be_process_mcc(struct be_adapter *adapter) 122int be_process_mcc(struct be_adapter *adapter)
108{ 123{
109 struct be_mcc_compl *compl; 124 struct be_mcc_compl *compl;
110 int num = 0, status = 0; 125 int num = 0, status = 0;
126 struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
111 127
112 spin_lock_bh(&adapter->mcc_cq_lock); 128 spin_lock_bh(&adapter->mcc_cq_lock);
113 while ((compl = be_mcc_compl_get(adapter))) { 129 while ((compl = be_mcc_compl_get(adapter))) {
@@ -120,14 +136,14 @@ int be_process_mcc(struct be_adapter *adapter)
120 (struct be_async_event_link_state *) compl); 136 (struct be_async_event_link_state *) compl);
121 } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { 137 } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
122 status = be_mcc_compl_process(adapter, compl); 138 status = be_mcc_compl_process(adapter, compl);
123 atomic_dec(&adapter->mcc_obj.q.used); 139 atomic_dec(&mcc_obj->q.used);
124 } 140 }
125 be_mcc_compl_use(compl); 141 be_mcc_compl_use(compl);
126 num++; 142 num++;
127 } 143 }
128 144
129 if (num) 145 if (num)
130 be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, num); 146 be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num);
131 147
132 spin_unlock_bh(&adapter->mcc_cq_lock); 148 spin_unlock_bh(&adapter->mcc_cq_lock);
133 return status; 149 return status;
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 7297b5a47657..01501dbae00a 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -937,6 +937,8 @@ extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
937 struct be_dma_mem *nonemb_cmd); 937 struct be_dma_mem *nonemb_cmd);
938extern int be_cmd_fw_init(struct be_adapter *adapter); 938extern int be_cmd_fw_init(struct be_adapter *adapter);
939extern int be_cmd_fw_clean(struct be_adapter *adapter); 939extern int be_cmd_fw_clean(struct be_adapter *adapter);
940extern void be_async_mcc_enable(struct be_adapter *adapter);
941extern void be_async_mcc_disable(struct be_adapter *adapter);
940extern int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, 942extern int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
941 u32 loopback_type, u32 pkt_size, 943 u32 loopback_type, u32 pkt_size,
942 u32 num_pkts, u64 pattern); 944 u32 num_pkts, u64 pattern);
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 7bf1900df665..43dbe288a5ef 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -1655,6 +1655,9 @@ static int be_open(struct net_device *netdev)
1655 /* Rx compl queue may be in unarmed state; rearm it */ 1655 /* Rx compl queue may be in unarmed state; rearm it */
1656 be_cq_notify(adapter, adapter->rx_obj.cq.id, true, 0); 1656 be_cq_notify(adapter, adapter->rx_obj.cq.id, true, 0);
1657 1657
1658 /* Now that interrupts are on we can process async mcc */
1659 be_async_mcc_enable(adapter);
1660
1658 status = be_cmd_link_status_query(adapter, &link_up, &mac_speed, 1661 status = be_cmd_link_status_query(adapter, &link_up, &mac_speed,
1659 &link_speed); 1662 &link_speed);
1660 if (status) 1663 if (status)
@@ -1780,6 +1783,8 @@ static int be_close(struct net_device *netdev)
1780 1783
1781 cancel_delayed_work_sync(&adapter->work); 1784 cancel_delayed_work_sync(&adapter->work);
1782 1785
1786 be_async_mcc_disable(adapter);
1787
1783 netif_stop_queue(netdev); 1788 netif_stop_queue(netdev);
1784 netif_carrier_off(netdev); 1789 netif_carrier_off(netdev);
1785 adapter->link_up = false; 1790 adapter->link_up = false;