/*
* QLogic qlcnic NIC Driver
* Copyright (c) 2009-2010 QLogic Corporation
*
* See LICENSE.qlcnic for copyright and licensing details.
*/
#include "qlcnic.h"
static u32
qlcnic_poll_rsp(struct qlcnic_adapter *adapter)
{
u32 rsp;
int timeout = 0;
do {
/* give atleast 1ms for firmware to respond */
msleep(1);
if (++timeout > QLCNIC_OS_CRB_RETRY_COUNT)
return QLCNIC_CDRP_RSP_TIMEOUT;
rsp = QLCRD32(adapter, QLCNIC_CDRP_CRB_OFFSET);
} while (!QLCNIC_CDRP_IS_RSP(rsp));
return rsp;
}
void
qlcnic_issue_cmd(struct qlcnic_adapter *adapter, struct qlcnic_cmd_args *cmd)
{
u32 rsp;
u32 signature;
struct pci_dev *pdev = adapter->pdev;
struct qlcnic_hardware_context *ahw = adapter->ahw;
signature = QLCNIC_CDRP_SIGNATURE_MAKE(ahw->pci_func,
adapter->fw_hal_version);
/* Acquire semaphore before accessing CRB */
if (qlcnic_api_lock(adapter)) {
cmd->rsp.cmd = QLCNIC_RCODE_TIMEOUT;
return;
}
QLCWR32(adapter, QLCNIC_SIGN_CRB_OFFSET, signature);
QLCWR32(adapter, QLCNIC_ARG1_CRB_OFFSET, cmd->req.arg1);
QLCWR32(adapter, QLCNIC_ARG2_CRB_OFFSET, cmd->req.arg2);
QLCWR32(adapter, QLCNIC_ARG3_CRB_OFFSET, cmd->req.arg3);
QLCWR32(adapter, QLCNIC_CDRP_CRB_OFFSET,
QLCNIC_CDRP_FORM_CMD(cmd->req.cmd));
rsp = qlcnic_poll_rsp(adapter);
if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) {
dev_err(&pdev->dev, "CDRP response timeout.\n");
cmd->rsp.cmd = QLCNIC_RCODE_TIMEOUT;
} else if (rsp == QLCNIC_CDRP_RSP_FAIL) {
cmd->rsp.cmd = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
switch (cmd->rsp.cmd) {
case QLCNIC_RCODE_INVALID_ARGS:
dev_err(&pdev->dev, "CDRP invalid args: 0x%x.\n",
cmd->rsp.cmd);
break;
case QLCNIC_RCODE_NOT_SUPPORTED:
case QLCNIC_RCODE_NOT_IMPL:
dev_err(&pdev->dev,
"CDRP command not supported: 0x%x.\n",
cmd->rsp.cmd);
break;
case QLCNIC_RCODE_NOT_PERMITTED:
dev_err(&pdev->dev,
"CDRP requested action not permitted: 0x%x.\n",
cmd->rsp.cmd);
break;
case QLCNIC_RCODE_INVALID:
dev_err(&pdev->dev,
"CDRP invalid or unknown cmd received: 0x%x.\n",
cmd->rsp.cmd);
break;
case QLCNIC_RCODE_TIMEOUT:
dev_err(&pdev->dev, "CDRP command timeout: 0x%x.\n",
cmd->rsp.cmd);
break;
default:
dev_err(&pdev->dev, "CDRP command failed: 0x%x.\n",
cmd->rsp.cmd);
}
} else if (rsp == QLCNIC_CDRP_RSP_OK)