aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSritej Velaga <sritej.velaga@qlogic.com>2012-02-03 06:35:10 -0500
committerDavid S. Miller <davem@davemloft.net>2012-02-04 15:59:28 -0500
commit2dcd5d95ad6b281fca6f2d5e252bbf7e8e20655b (patch)
tree3deaaa4c47ca20b7f2113cc078b8bb3af1619ed2
parente1f4c485cdb2b1d7aae172b731f6c2b403381ebb (diff)
netxen_nic: fix cdrp race condition
Reading CRB registers(if reqd) before releasing the api lock. Signed-off-by: Sritej Velaga <sritej.velaga@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic.h12
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c149
2 files changed, 89 insertions, 72 deletions
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h
index a876dffd7101..1b09ba172310 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h
@@ -686,6 +686,18 @@ struct netxen_recv_context {
686 dma_addr_t phys_addr; 686 dma_addr_t phys_addr;
687}; 687};
688 688
689struct _cdrp_cmd {
690 u32 cmd;
691 u32 arg1;
692 u32 arg2;
693 u32 arg3;
694};
695
696struct netxen_cmd_args {
697 struct _cdrp_cmd req;
698 struct _cdrp_cmd rsp;
699};
700
689/* New HW context creation */ 701/* New HW context creation */
690 702
691#define NX_OS_CRB_RETRY_COUNT 4000 703#define NX_OS_CRB_RETRY_COUNT 4000
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
index a925392abd6f..d46e8cb394eb 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
@@ -48,28 +48,27 @@ netxen_poll_rsp(struct netxen_adapter *adapter)
48} 48}
49 49
50static u32 50static u32
51netxen_issue_cmd(struct netxen_adapter *adapter, 51netxen_issue_cmd(struct netxen_adapter *adapter, struct netxen_cmd_args *cmd)
52 u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd)
53{ 52{
54 u32 rsp; 53 u32 rsp;
55 u32 signature = 0; 54 u32 signature = 0;
56 u32 rcode = NX_RCODE_SUCCESS; 55 u32 rcode = NX_RCODE_SUCCESS;
57 56
58 signature = NX_CDRP_SIGNATURE_MAKE(pci_fn, version); 57 signature = NX_CDRP_SIGNATURE_MAKE(adapter->ahw.pci_func,
59 58 NXHAL_VERSION);
60 /* Acquire semaphore before accessing CRB */ 59 /* Acquire semaphore before accessing CRB */
61 if (netxen_api_lock(adapter)) 60 if (netxen_api_lock(adapter))
62 return NX_RCODE_TIMEOUT; 61 return NX_RCODE_TIMEOUT;
63 62
64 NXWR32(adapter, NX_SIGN_CRB_OFFSET, signature); 63 NXWR32(adapter, NX_SIGN_CRB_OFFSET, signature);
65 64
66 NXWR32(adapter, NX_ARG1_CRB_OFFSET, arg1); 65 NXWR32(adapter, NX_ARG1_CRB_OFFSET, cmd->req.arg1);
67 66
68 NXWR32(adapter, NX_ARG2_CRB_OFFSET, arg2); 67 NXWR32(adapter, NX_ARG2_CRB_OFFSET, cmd->req.arg2);
69 68
70 NXWR32(adapter, NX_ARG3_CRB_OFFSET, arg3); 69 NXWR32(adapter, NX_ARG3_CRB_OFFSET, cmd->req.arg3);
71 70
72 NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd)); 71 NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd->req.cmd));
73 72
74 rsp = netxen_poll_rsp(adapter); 73 rsp = netxen_poll_rsp(adapter);
75 74
@@ -83,8 +82,15 @@ netxen_issue_cmd(struct netxen_adapter *adapter,
83 82
84 printk(KERN_ERR "%s: failed card response code:0x%x\n", 83 printk(KERN_ERR "%s: failed card response code:0x%x\n",
85 netxen_nic_driver_name, rcode); 84 netxen_nic_driver_name, rcode);
85 } else if (rsp == NX_CDRP_RSP_OK) {
86 if (cmd->rsp.arg2)
87 cmd->rsp.arg2 = NXRD32(adapter, NX_ARG2_CRB_OFFSET);
88 if (cmd->rsp.arg3)
89 cmd->rsp.arg3 = NXRD32(adapter, NX_ARG3_CRB_OFFSET);
86 } 90 }
87 91
92 if (cmd->rsp.arg1)
93 cmd->rsp.arg1 = NXRD32(adapter, NX_ARG1_CRB_OFFSET);
88 /* Release semaphore */ 94 /* Release semaphore */
89 netxen_api_unlock(adapter); 95 netxen_api_unlock(adapter);
90 96
@@ -96,15 +102,16 @@ nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu)
96{ 102{
97 u32 rcode = NX_RCODE_SUCCESS; 103 u32 rcode = NX_RCODE_SUCCESS;
98 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; 104 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
105 struct netxen_cmd_args cmd;
106
107 memset(&cmd, 0, sizeof(cmd));
108 cmd.req.cmd = NX_CDRP_CMD_SET_MTU;
109 cmd.req.arg1 = recv_ctx->context_id;
110 cmd.req.arg2 = mtu;
111 cmd.req.arg3 = 0;
99 112
100 if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE) 113 if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE)
101 rcode = netxen_issue_cmd(adapter, 114 netxen_issue_cmd(adapter, &cmd);
102 adapter->ahw.pci_func,
103 NXHAL_VERSION,
104 recv_ctx->context_id,
105 mtu,
106 0,
107 NX_CDRP_CMD_SET_MTU);
108 115
109 if (rcode != NX_RCODE_SUCCESS) 116 if (rcode != NX_RCODE_SUCCESS)
110 return -EIO; 117 return -EIO;
@@ -116,15 +123,14 @@ int
116nx_fw_cmd_set_gbe_port(struct netxen_adapter *adapter, 123nx_fw_cmd_set_gbe_port(struct netxen_adapter *adapter,
117 u32 speed, u32 duplex, u32 autoneg) 124 u32 speed, u32 duplex, u32 autoneg)
118{ 125{
119 126 struct netxen_cmd_args cmd;
120 return netxen_issue_cmd(adapter, 127
121 adapter->ahw.pci_func, 128 memset(&cmd, 0, sizeof(cmd));
122 NXHAL_VERSION, 129 cmd.req.cmd = NX_CDRP_CMD_CONFIG_GBE_PORT;
123 speed, 130 cmd.req.arg1 = speed;
124 duplex, 131 cmd.req.arg2 = duplex;
125 autoneg, 132 cmd.req.arg3 = autoneg;
126 NX_CDRP_CMD_CONFIG_GBE_PORT); 133 return netxen_issue_cmd(adapter, &cmd);
127
128} 134}
129 135
130static int 136static int
@@ -139,6 +145,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
139 nx_cardrsp_sds_ring_t *prsp_sds; 145 nx_cardrsp_sds_ring_t *prsp_sds;
140 struct nx_host_rds_ring *rds_ring; 146 struct nx_host_rds_ring *rds_ring;
141 struct nx_host_sds_ring *sds_ring; 147 struct nx_host_sds_ring *sds_ring;
148 struct netxen_cmd_args cmd;
142 149
143 dma_addr_t hostrq_phys_addr, cardrsp_phys_addr; 150 dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
144 u64 phys_addr; 151 u64 phys_addr;
@@ -218,13 +225,12 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
218 } 225 }
219 226
220 phys_addr = hostrq_phys_addr; 227 phys_addr = hostrq_phys_addr;
221 err = netxen_issue_cmd(adapter, 228 memset(&cmd, 0, sizeof(cmd));
222 adapter->ahw.pci_func, 229 cmd.req.arg1 = (u32)(phys_addr >> 32);
223 NXHAL_VERSION, 230 cmd.req.arg2 = (u32)(phys_addr & 0xffffffff);
224 (u32)(phys_addr >> 32), 231 cmd.req.arg3 = rq_size;
225 (u32)(phys_addr & 0xffffffff), 232 cmd.req.cmd = NX_CDRP_CMD_CREATE_RX_CTX;
226 rq_size, 233 err = netxen_issue_cmd(adapter, &cmd);
227 NX_CDRP_CMD_CREATE_RX_CTX);
228 if (err) { 234 if (err) {
229 printk(KERN_WARNING 235 printk(KERN_WARNING
230 "Failed to create rx ctx in firmware%d\n", err); 236 "Failed to create rx ctx in firmware%d\n", err);
@@ -273,15 +279,15 @@ static void
273nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter) 279nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter)
274{ 280{
275 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; 281 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
282 struct netxen_cmd_args cmd;
276 283
277 if (netxen_issue_cmd(adapter, 284 memset(&cmd, 0, sizeof(cmd));
278 adapter->ahw.pci_func, 285 cmd.req.arg1 = recv_ctx->context_id;
279 NXHAL_VERSION, 286 cmd.req.arg2 = NX_DESTROY_CTX_RESET;
280 recv_ctx->context_id, 287 cmd.req.arg3 = 0;
281 NX_DESTROY_CTX_RESET, 288 cmd.req.cmd = NX_CDRP_CMD_DESTROY_RX_CTX;
282 0,
283 NX_CDRP_CMD_DESTROY_RX_CTX)) {
284 289
290 if (netxen_issue_cmd(adapter, &cmd)) {
285 printk(KERN_WARNING 291 printk(KERN_WARNING
286 "%s: Failed to destroy rx ctx in firmware\n", 292 "%s: Failed to destroy rx ctx in firmware\n",
287 netxen_nic_driver_name); 293 netxen_nic_driver_name);
@@ -302,6 +308,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
302 dma_addr_t rq_phys_addr, rsp_phys_addr; 308 dma_addr_t rq_phys_addr, rsp_phys_addr;
303 struct nx_host_tx_ring *tx_ring = adapter->tx_ring; 309 struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
304 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; 310 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
311 struct netxen_cmd_args cmd;
305 312
306 rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t); 313 rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t);
307 rq_addr = pci_alloc_consistent(adapter->pdev, 314 rq_addr = pci_alloc_consistent(adapter->pdev,
@@ -345,13 +352,12 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
345 prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc); 352 prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc);
346 353
347 phys_addr = rq_phys_addr; 354 phys_addr = rq_phys_addr;
348 err = netxen_issue_cmd(adapter, 355 memset(&cmd, 0, sizeof(cmd));
349 adapter->ahw.pci_func, 356 cmd.req.arg1 = (u32)(phys_addr >> 32);
350 NXHAL_VERSION, 357 cmd.req.arg2 = ((u32)phys_addr & 0xffffffff);
351 (u32)(phys_addr >> 32), 358 cmd.req.arg3 = rq_size;
352 ((u32)phys_addr & 0xffffffff), 359 cmd.req.cmd = NX_CDRP_CMD_CREATE_TX_CTX;
353 rq_size, 360 err = netxen_issue_cmd(adapter, &cmd);
354 NX_CDRP_CMD_CREATE_TX_CTX);
355 361
356 if (err == NX_RCODE_SUCCESS) { 362 if (err == NX_RCODE_SUCCESS) {
357 temp = le32_to_cpu(prsp->cds_ring.host_producer_crb); 363 temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
@@ -380,14 +386,14 @@ out_free_rq:
380static void 386static void
381nx_fw_cmd_destroy_tx_ctx(struct netxen_adapter *adapter) 387nx_fw_cmd_destroy_tx_ctx(struct netxen_adapter *adapter)
382{ 388{
383 if (netxen_issue_cmd(adapter, 389 struct netxen_cmd_args cmd;
384 adapter->ahw.pci_func, 390
385 NXHAL_VERSION, 391 memset(&cmd, 0, sizeof(cmd));
386 adapter->tx_context_id, 392 cmd.req.arg1 = adapter->tx_context_id;
387 NX_DESTROY_CTX_RESET, 393 cmd.req.arg2 = NX_DESTROY_CTX_RESET;
388 0, 394 cmd.req.arg3 = 0;
389 NX_CDRP_CMD_DESTROY_TX_CTX)) { 395 cmd.req.cmd = NX_CDRP_CMD_DESTROY_TX_CTX;
390 396 if (netxen_issue_cmd(adapter, &cmd)) {
391 printk(KERN_WARNING 397 printk(KERN_WARNING
392 "%s: Failed to destroy tx ctx in firmware\n", 398 "%s: Failed to destroy tx ctx in firmware\n",
393 netxen_nic_driver_name); 399 netxen_nic_driver_name);
@@ -398,34 +404,33 @@ int
398nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val) 404nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val)
399{ 405{
400 u32 rcode; 406 u32 rcode;
401 407 struct netxen_cmd_args cmd;
402 rcode = netxen_issue_cmd(adapter, 408
403 adapter->ahw.pci_func, 409 memset(&cmd, 0, sizeof(cmd));
404 NXHAL_VERSION, 410 cmd.req.arg1 = reg;
405 reg, 411 cmd.req.arg2 = 0;
406 0, 412 cmd.req.arg3 = 0;
407 0, 413 cmd.req.cmd = NX_CDRP_CMD_READ_PHY;
408 NX_CDRP_CMD_READ_PHY); 414 cmd.rsp.arg1 = 1;
409 415 rcode = netxen_issue_cmd(adapter, &cmd);
410 if (rcode != NX_RCODE_SUCCESS) 416 if (rcode != NX_RCODE_SUCCESS)
411 return -EIO; 417 return -EIO;
412 418
413 return NXRD32(adapter, NX_ARG1_CRB_OFFSET); 419 return cmd.rsp.arg1;
414} 420}
415 421
416int 422int
417nx_fw_cmd_set_phy(struct netxen_adapter *adapter, u32 reg, u32 val) 423nx_fw_cmd_set_phy(struct netxen_adapter *adapter, u32 reg, u32 val)
418{ 424{
419 u32 rcode; 425 u32 rcode;
420 426 struct netxen_cmd_args cmd;
421 rcode = netxen_issue_cmd(adapter, 427
422 adapter->ahw.pci_func, 428 memset(&cmd, 0, sizeof(cmd));
423 NXHAL_VERSION, 429 cmd.req.arg1 = reg;
424 reg, 430 cmd.req.arg2 = val;
425 val, 431 cmd.req.arg3 = 0;
426 0, 432 cmd.req.cmd = NX_CDRP_CMD_WRITE_PHY;
427 NX_CDRP_CMD_WRITE_PHY); 433 rcode = netxen_issue_cmd(adapter, &cmd);
428
429 if (rcode != NX_RCODE_SUCCESS) 434 if (rcode != NX_RCODE_SUCCESS)
430 return -EIO; 435 return -EIO;
431 436