diff options
author | Suresh Reddy <Suresh.Reddy@emulex.com> | 2015-07-10 05:32:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-07-10 23:24:30 -0700 |
commit | 9c8559750cd7b7936dd38810fc2110fc91d7d527 (patch) | |
tree | 6838d849e43444c5beb70b2e4b1de0d690926656 /drivers/net/ethernet/emulex/benet/be_cmds.c | |
parent | 8af65c2f4deeb02a128c5cf29fa351b70bf16424 (diff) | |
download | linux-9c8559750cd7b7936dd38810fc2110fc91d7d527.tar.gz linux-9c8559750cd7b7936dd38810fc2110fc91d7d527.tar.bz2 linux-9c8559750cd7b7936dd38810fc2110fc91d7d527.zip |
be2net: make SET_LOOPBACK_MODE cmd asynchrounous
The SET_LOOPBACK_MODE command is always issued from ethtool only in a
process context. So, while waiting for the cmd to complete, the driver
can sleep instead of holding spin_lock_bh() on the mcc_lock. This is done
by calling be_mcc_notify() instead of be_mcc_notify_wait() (that returns
only after the cmd completes while the MCCQ is locked).
Signed-off-by: Suresh Reddy <suresh.reddy@avagotech.com>
Signed-off-by: Sathya Perla <sathya.perla@avagotech.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/emulex/benet/be_cmds.c')
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 93934d347a23..ecad46f79653 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -172,6 +172,12 @@ static void be_async_cmd_process(struct be_adapter *adapter, return; } + if (opcode == OPCODE_LOWLEVEL_SET_LOOPBACK_MODE && + subsystem == CMD_SUBSYSTEM_LOWLEVEL) { + complete(&adapter->et_cmd_compl); + return; + } + if ((opcode == OPCODE_COMMON_WRITE_FLASHROM || opcode == OPCODE_COMMON_WRITE_OBJECT) && subsystem == CMD_SUBSYSTEM_COMMON) { @@ -2600,7 +2606,7 @@ int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, wrb = wrb_from_mccq(adapter); if (!wrb) { status = -EBUSY; - goto err; + goto err_unlock; } req = embedded_payload(wrb); @@ -2614,8 +2620,19 @@ int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, req->loopback_type = loopback_type; req->loopback_state = enable; - status = be_mcc_notify_wait(adapter); -err: + status = be_mcc_notify(adapter); + if (status) + goto err_unlock; + + spin_unlock_bh(&adapter->mcc_lock); + + if (!wait_for_completion_timeout(&adapter->et_cmd_compl, + msecs_to_jiffies(SET_LB_MODE_TIMEOUT))) + status = -ETIMEDOUT; + + return status; + +err_unlock: spin_unlock_bh(&adapter->mcc_lock); return status; } |