diff options
author | Ron Mercer <ron.mercer@qlogic.com> | 2009-11-03 13:49:30 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-04 05:01:37 -0800 |
commit | 1e34e307d0ebe536feb39c957c849a485bc81486 (patch) | |
tree | 1b835350717e9ffde6d29a734422931556f62c15 /drivers/net/qlge/qlge_mpi.c | |
parent | 32a5b2a0d516ba4056d9e9b8b14e34bef3f68921 (diff) |
qlge: Add firmware/driver sub-command support.
These sub-commands are issued by another (FCoE) function requesting
an operation on a shared resource.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/qlge/qlge_mpi.c')
-rw-r--r-- | drivers/net/qlge/qlge_mpi.c | 56 |
1 files changed, 49 insertions, 7 deletions
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c index bac7b86f2129..f5619fe87bb2 100644 --- a/drivers/net/qlge/qlge_mpi.c +++ b/drivers/net/qlge/qlge_mpi.c @@ -1038,8 +1038,11 @@ void ql_mpi_idc_work(struct work_struct *work) int status; struct mbox_params *mbcp = &qdev->idc_mbc; u32 aen; + int timeout; + rtnl_lock(); aen = mbcp->mbox_out[1] >> 16; + timeout = (mbcp->mbox_out[1] >> 8) & 0xf; switch (aen) { default: @@ -1047,22 +1050,61 @@ void ql_mpi_idc_work(struct work_struct *work) "Bug: Unhandled IDC action.\n"); break; case MB_CMD_PORT_RESET: - case MB_CMD_SET_PORT_CFG: case MB_CMD_STOP_FW: ql_link_off(qdev); + case MB_CMD_SET_PORT_CFG: /* Signal the resulting link up AEN * that the frame routing and mac addr * needs to be set. * */ set_bit(QL_CAM_RT_SET, &qdev->flags); - rtnl_lock(); - status = ql_mb_idc_ack(qdev); - rtnl_unlock(); - if (status) { - QPRINTK(qdev, DRV, ERR, - "Bug: No pending IDC!\n"); + /* Do ACK if required */ + if (timeout) { + status = ql_mb_idc_ack(qdev); + if (status) + QPRINTK(qdev, DRV, ERR, + "Bug: No pending IDC!\n"); + } else { + QPRINTK(qdev, DRV, DEBUG, + "IDC ACK not required\n"); + status = 0; /* success */ + } + break; + + /* These sub-commands issued by another (FCoE) + * function are requesting to do an operation + * on the shared resource (MPI environment). + * We currently don't issue these so we just + * ACK the request. + */ + case MB_CMD_IOP_RESTART_MPI: + case MB_CMD_IOP_PREP_LINK_DOWN: + /* Drop the link, reload the routing + * table when link comes up. + */ + ql_link_off(qdev); + set_bit(QL_CAM_RT_SET, &qdev->flags); + /* Fall through. */ + case MB_CMD_IOP_DVR_START: + case MB_CMD_IOP_FLASH_ACC: + case MB_CMD_IOP_CORE_DUMP_MPI: + case MB_CMD_IOP_PREP_UPDATE_MPI: + case MB_CMD_IOP_COMP_UPDATE_MPI: + case MB_CMD_IOP_NONE: /* an IDC without params */ + /* Do ACK if required */ + if (timeout) { + status = ql_mb_idc_ack(qdev); + if (status) + QPRINTK(qdev, DRV, ERR, + "Bug: No pending IDC!\n"); + } else { + QPRINTK(qdev, DRV, DEBUG, + "IDC ACK not required\n"); + status = 0; /* success */ } + break; } + rtnl_unlock(); } void ql_mpi_work(struct work_struct *work) |