Commit 7a1e9b20 authored by Sathya Perla's avatar Sathya Perla Committed by David S. Miller

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: default avatarSathya Perla <sathyap@serverengines.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a058a632
...@@ -151,6 +151,7 @@ struct be_eq_obj { ...@@ -151,6 +151,7 @@ struct be_eq_obj {
struct be_mcc_obj { struct be_mcc_obj {
struct be_queue_info q; struct be_queue_info q;
struct be_queue_info cq; struct be_queue_info cq;
bool rearm_cq;
}; };
struct be_drvr_stats { struct be_drvr_stats {
......
...@@ -104,10 +104,26 @@ static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter) ...@@ -104,10 +104,26 @@ static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
return NULL; return NULL;
} }
void be_async_mcc_enable(struct be_adapter *adapter)
{
spin_lock_bh(&adapter->mcc_cq_lock);
be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, 0);
adapter->mcc_obj.rearm_cq = true;
spin_unlock_bh(&adapter->mcc_cq_lock);
}
void be_async_mcc_disable(struct be_adapter *adapter)
{
adapter->mcc_obj.rearm_cq = false;
}
int be_process_mcc(struct be_adapter *adapter) int be_process_mcc(struct be_adapter *adapter)
{ {
struct be_mcc_compl *compl; struct be_mcc_compl *compl;
int num = 0, status = 0; int num = 0, status = 0;
struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
spin_lock_bh(&adapter->mcc_cq_lock); spin_lock_bh(&adapter->mcc_cq_lock);
while ((compl = be_mcc_compl_get(adapter))) { while ((compl = be_mcc_compl_get(adapter))) {
...@@ -120,14 +136,14 @@ int be_process_mcc(struct be_adapter *adapter) ...@@ -120,14 +136,14 @@ int be_process_mcc(struct be_adapter *adapter)
(struct be_async_event_link_state *) compl); (struct be_async_event_link_state *) compl);
} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
status = be_mcc_compl_process(adapter, compl); status = be_mcc_compl_process(adapter, compl);
atomic_dec(&adapter->mcc_obj.q.used); atomic_dec(&mcc_obj->q.used);
} }
be_mcc_compl_use(compl); be_mcc_compl_use(compl);
num++; num++;
} }
if (num) if (num)
be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, num); be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num);
spin_unlock_bh(&adapter->mcc_cq_lock); spin_unlock_bh(&adapter->mcc_cq_lock);
return status; return status;
......
...@@ -937,6 +937,8 @@ extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, ...@@ -937,6 +937,8 @@ extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
struct be_dma_mem *nonemb_cmd); struct be_dma_mem *nonemb_cmd);
extern int be_cmd_fw_init(struct be_adapter *adapter); extern int be_cmd_fw_init(struct be_adapter *adapter);
extern int be_cmd_fw_clean(struct be_adapter *adapter); extern int be_cmd_fw_clean(struct be_adapter *adapter);
extern void be_async_mcc_enable(struct be_adapter *adapter);
extern void be_async_mcc_disable(struct be_adapter *adapter);
extern int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, extern int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
u32 loopback_type, u32 pkt_size, u32 loopback_type, u32 pkt_size,
u32 num_pkts, u64 pattern); u32 num_pkts, u64 pattern);
......
...@@ -1655,6 +1655,9 @@ static int be_open(struct net_device *netdev) ...@@ -1655,6 +1655,9 @@ static int be_open(struct net_device *netdev)
/* Rx compl queue may be in unarmed state; rearm it */ /* Rx compl queue may be in unarmed state; rearm it */
be_cq_notify(adapter, adapter->rx_obj.cq.id, true, 0); be_cq_notify(adapter, adapter->rx_obj.cq.id, true, 0);
/* Now that interrupts are on we can process async mcc */
be_async_mcc_enable(adapter);
status = be_cmd_link_status_query(adapter, &link_up, &mac_speed, status = be_cmd_link_status_query(adapter, &link_up, &mac_speed,
&link_speed); &link_speed);
if (status) if (status)
...@@ -1780,6 +1783,8 @@ static int be_close(struct net_device *netdev) ...@@ -1780,6 +1783,8 @@ static int be_close(struct net_device *netdev)
cancel_delayed_work_sync(&adapter->work); cancel_delayed_work_sync(&adapter->work);
be_async_mcc_disable(adapter);
netif_stop_queue(netdev); netif_stop_queue(netdev);
netif_carrier_off(netdev); netif_carrier_off(netdev);
adapter->link_up = false; adapter->link_up = false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment