Commit 2dcd5d95 authored by Sritej Velaga's avatar Sritej Velaga Committed by David S. Miller

netxen_nic: fix cdrp race condition

Reading CRB registers(if reqd) before releasing the api lock.
Signed-off-by: default avatarSritej Velaga <sritej.velaga@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e1f4c485
...@@ -686,6 +686,18 @@ struct netxen_recv_context { ...@@ -686,6 +686,18 @@ struct netxen_recv_context {
dma_addr_t phys_addr; dma_addr_t phys_addr;
}; };
struct _cdrp_cmd {
u32 cmd;
u32 arg1;
u32 arg2;
u32 arg3;
};
struct netxen_cmd_args {
struct _cdrp_cmd req;
struct _cdrp_cmd rsp;
};
/* New HW context creation */ /* New HW context creation */
#define NX_OS_CRB_RETRY_COUNT 4000 #define NX_OS_CRB_RETRY_COUNT 4000
......
...@@ -48,28 +48,27 @@ netxen_poll_rsp(struct netxen_adapter *adapter) ...@@ -48,28 +48,27 @@ netxen_poll_rsp(struct netxen_adapter *adapter)
} }
static u32 static u32
netxen_issue_cmd(struct netxen_adapter *adapter, netxen_issue_cmd(struct netxen_adapter *adapter, struct netxen_cmd_args *cmd)
u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd)
{ {
u32 rsp; u32 rsp;
u32 signature = 0; u32 signature = 0;
u32 rcode = NX_RCODE_SUCCESS; u32 rcode = NX_RCODE_SUCCESS;
signature = NX_CDRP_SIGNATURE_MAKE(pci_fn, version); signature = NX_CDRP_SIGNATURE_MAKE(adapter->ahw.pci_func,
NXHAL_VERSION);
/* Acquire semaphore before accessing CRB */ /* Acquire semaphore before accessing CRB */
if (netxen_api_lock(adapter)) if (netxen_api_lock(adapter))
return NX_RCODE_TIMEOUT; return NX_RCODE_TIMEOUT;
NXWR32(adapter, NX_SIGN_CRB_OFFSET, signature); NXWR32(adapter, NX_SIGN_CRB_OFFSET, signature);
NXWR32(adapter, NX_ARG1_CRB_OFFSET, arg1); NXWR32(adapter, NX_ARG1_CRB_OFFSET, cmd->req.arg1);
NXWR32(adapter, NX_ARG2_CRB_OFFSET, arg2); NXWR32(adapter, NX_ARG2_CRB_OFFSET, cmd->req.arg2);
NXWR32(adapter, NX_ARG3_CRB_OFFSET, arg3); NXWR32(adapter, NX_ARG3_CRB_OFFSET, cmd->req.arg3);
NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd)); NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd->req.cmd));
rsp = netxen_poll_rsp(adapter); rsp = netxen_poll_rsp(adapter);
...@@ -83,8 +82,15 @@ netxen_issue_cmd(struct netxen_adapter *adapter, ...@@ -83,8 +82,15 @@ netxen_issue_cmd(struct netxen_adapter *adapter,
printk(KERN_ERR "%s: failed card response code:0x%x\n", printk(KERN_ERR "%s: failed card response code:0x%x\n",
netxen_nic_driver_name, rcode); netxen_nic_driver_name, rcode);
} else if (rsp == NX_CDRP_RSP_OK) {
if (cmd->rsp.arg2)
cmd->rsp.arg2 = NXRD32(adapter, NX_ARG2_CRB_OFFSET);
if (cmd->rsp.arg3)
cmd->rsp.arg3 = NXRD32(adapter, NX_ARG3_CRB_OFFSET);
} }
if (cmd->rsp.arg1)
cmd->rsp.arg1 = NXRD32(adapter, NX_ARG1_CRB_OFFSET);
/* Release semaphore */ /* Release semaphore */
netxen_api_unlock(adapter); netxen_api_unlock(adapter);
...@@ -96,15 +102,16 @@ nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu) ...@@ -96,15 +102,16 @@ nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu)
{ {
u32 rcode = NX_RCODE_SUCCESS; u32 rcode = NX_RCODE_SUCCESS;
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
struct netxen_cmd_args cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.req.cmd = NX_CDRP_CMD_SET_MTU;
cmd.req.arg1 = recv_ctx->context_id;
cmd.req.arg2 = mtu;
cmd.req.arg3 = 0;
if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE) if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE)
rcode = netxen_issue_cmd(adapter, netxen_issue_cmd(adapter, &cmd);
adapter->ahw.pci_func,
NXHAL_VERSION,
recv_ctx->context_id,
mtu,
0,
NX_CDRP_CMD_SET_MTU);
if (rcode != NX_RCODE_SUCCESS) if (rcode != NX_RCODE_SUCCESS)
return -EIO; return -EIO;
...@@ -116,15 +123,14 @@ int ...@@ -116,15 +123,14 @@ int
nx_fw_cmd_set_gbe_port(struct netxen_adapter *adapter, nx_fw_cmd_set_gbe_port(struct netxen_adapter *adapter,
u32 speed, u32 duplex, u32 autoneg) u32 speed, u32 duplex, u32 autoneg)
{ {
struct netxen_cmd_args cmd;
return netxen_issue_cmd(adapter,
adapter->ahw.pci_func, memset(&cmd, 0, sizeof(cmd));
NXHAL_VERSION, cmd.req.cmd = NX_CDRP_CMD_CONFIG_GBE_PORT;
speed, cmd.req.arg1 = speed;
duplex, cmd.req.arg2 = duplex;
autoneg, cmd.req.arg3 = autoneg;
NX_CDRP_CMD_CONFIG_GBE_PORT); return netxen_issue_cmd(adapter, &cmd);
} }
static int static int
...@@ -139,6 +145,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) ...@@ -139,6 +145,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
nx_cardrsp_sds_ring_t *prsp_sds; nx_cardrsp_sds_ring_t *prsp_sds;
struct nx_host_rds_ring *rds_ring; struct nx_host_rds_ring *rds_ring;
struct nx_host_sds_ring *sds_ring; struct nx_host_sds_ring *sds_ring;
struct netxen_cmd_args cmd;
dma_addr_t hostrq_phys_addr, cardrsp_phys_addr; dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
u64 phys_addr; u64 phys_addr;
...@@ -218,13 +225,12 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) ...@@ -218,13 +225,12 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
} }
phys_addr = hostrq_phys_addr; phys_addr = hostrq_phys_addr;
err = netxen_issue_cmd(adapter, memset(&cmd, 0, sizeof(cmd));
adapter->ahw.pci_func, cmd.req.arg1 = (u32)(phys_addr >> 32);
NXHAL_VERSION, cmd.req.arg2 = (u32)(phys_addr & 0xffffffff);
(u32)(phys_addr >> 32), cmd.req.arg3 = rq_size;
(u32)(phys_addr & 0xffffffff), cmd.req.cmd = NX_CDRP_CMD_CREATE_RX_CTX;
rq_size, err = netxen_issue_cmd(adapter, &cmd);
NX_CDRP_CMD_CREATE_RX_CTX);
if (err) { if (err) {
printk(KERN_WARNING printk(KERN_WARNING
"Failed to create rx ctx in firmware%d\n", err); "Failed to create rx ctx in firmware%d\n", err);
...@@ -273,15 +279,15 @@ static void ...@@ -273,15 +279,15 @@ static void
nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter) nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter)
{ {
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
struct netxen_cmd_args cmd;
if (netxen_issue_cmd(adapter, memset(&cmd, 0, sizeof(cmd));
adapter->ahw.pci_func, cmd.req.arg1 = recv_ctx->context_id;
NXHAL_VERSION, cmd.req.arg2 = NX_DESTROY_CTX_RESET;
recv_ctx->context_id, cmd.req.arg3 = 0;
NX_DESTROY_CTX_RESET, cmd.req.cmd = NX_CDRP_CMD_DESTROY_RX_CTX;
0,
NX_CDRP_CMD_DESTROY_RX_CTX)) {
if (netxen_issue_cmd(adapter, &cmd)) {
printk(KERN_WARNING printk(KERN_WARNING
"%s: Failed to destroy rx ctx in firmware\n", "%s: Failed to destroy rx ctx in firmware\n",
netxen_nic_driver_name); netxen_nic_driver_name);
...@@ -302,6 +308,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) ...@@ -302,6 +308,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
dma_addr_t rq_phys_addr, rsp_phys_addr; dma_addr_t rq_phys_addr, rsp_phys_addr;
struct nx_host_tx_ring *tx_ring = adapter->tx_ring; struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
struct netxen_cmd_args cmd;
rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t); rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t);
rq_addr = pci_alloc_consistent(adapter->pdev, rq_addr = pci_alloc_consistent(adapter->pdev,
...@@ -345,13 +352,12 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) ...@@ -345,13 +352,12 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc); prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc);
phys_addr = rq_phys_addr; phys_addr = rq_phys_addr;
err = netxen_issue_cmd(adapter, memset(&cmd, 0, sizeof(cmd));
adapter->ahw.pci_func, cmd.req.arg1 = (u32)(phys_addr >> 32);
NXHAL_VERSION, cmd.req.arg2 = ((u32)phys_addr & 0xffffffff);
(u32)(phys_addr >> 32), cmd.req.arg3 = rq_size;
((u32)phys_addr & 0xffffffff), cmd.req.cmd = NX_CDRP_CMD_CREATE_TX_CTX;
rq_size, err = netxen_issue_cmd(adapter, &cmd);
NX_CDRP_CMD_CREATE_TX_CTX);
if (err == NX_RCODE_SUCCESS) { if (err == NX_RCODE_SUCCESS) {
temp = le32_to_cpu(prsp->cds_ring.host_producer_crb); temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
...@@ -380,14 +386,14 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) ...@@ -380,14 +386,14 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
static void static void
nx_fw_cmd_destroy_tx_ctx(struct netxen_adapter *adapter) nx_fw_cmd_destroy_tx_ctx(struct netxen_adapter *adapter)
{ {
if (netxen_issue_cmd(adapter, struct netxen_cmd_args cmd;
adapter->ahw.pci_func,
NXHAL_VERSION, memset(&cmd, 0, sizeof(cmd));
adapter->tx_context_id, cmd.req.arg1 = adapter->tx_context_id;
NX_DESTROY_CTX_RESET, cmd.req.arg2 = NX_DESTROY_CTX_RESET;
0, cmd.req.arg3 = 0;
NX_CDRP_CMD_DESTROY_TX_CTX)) { cmd.req.cmd = NX_CDRP_CMD_DESTROY_TX_CTX;
if (netxen_issue_cmd(adapter, &cmd)) {
printk(KERN_WARNING printk(KERN_WARNING
"%s: Failed to destroy tx ctx in firmware\n", "%s: Failed to destroy tx ctx in firmware\n",
netxen_nic_driver_name); netxen_nic_driver_name);
...@@ -398,34 +404,33 @@ int ...@@ -398,34 +404,33 @@ int
nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val) nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val)
{ {
u32 rcode; u32 rcode;
struct netxen_cmd_args cmd;
rcode = netxen_issue_cmd(adapter,
adapter->ahw.pci_func, memset(&cmd, 0, sizeof(cmd));
NXHAL_VERSION, cmd.req.arg1 = reg;
reg, cmd.req.arg2 = 0;
0, cmd.req.arg3 = 0;
0, cmd.req.cmd = NX_CDRP_CMD_READ_PHY;
NX_CDRP_CMD_READ_PHY); cmd.rsp.arg1 = 1;
rcode = netxen_issue_cmd(adapter, &cmd);
if (rcode != NX_RCODE_SUCCESS) if (rcode != NX_RCODE_SUCCESS)
return -EIO; return -EIO;
return NXRD32(adapter, NX_ARG1_CRB_OFFSET); return cmd.rsp.arg1;
} }
int int
nx_fw_cmd_set_phy(struct netxen_adapter *adapter, u32 reg, u32 val) nx_fw_cmd_set_phy(struct netxen_adapter *adapter, u32 reg, u32 val)
{ {
u32 rcode; u32 rcode;
struct netxen_cmd_args cmd;
rcode = netxen_issue_cmd(adapter,
adapter->ahw.pci_func, memset(&cmd, 0, sizeof(cmd));
NXHAL_VERSION, cmd.req.arg1 = reg;
reg, cmd.req.arg2 = val;
val, cmd.req.arg3 = 0;
0, cmd.req.cmd = NX_CDRP_CMD_WRITE_PHY;
NX_CDRP_CMD_WRITE_PHY); rcode = netxen_issue_cmd(adapter, &cmd);
if (rcode != NX_RCODE_SUCCESS) if (rcode != NX_RCODE_SUCCESS)
return -EIO; return -EIO;
......
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