summaryrefslogtreecommitdiffstats
path: root/drivers/net/qlcnic/qlcnic_ctx.c
diff options
context:
space:
mode:
authorAmit Kumar Salecha <amit.salecha@qlogic.com>2010-06-22 05:19:01 +0200
committerDavid S. Miller <davem@davemloft.net>2010-06-23 22:16:30 +0200
commit8a15ad1fb14d67450742cf975a76e744b3189f4d (patch)
treed64402cdeec98e3838d8c73924db199a294ba845 /drivers/net/qlcnic/qlcnic_ctx.c
parentqlcnic: fix mac address mgmt (diff)
downloadlinux-8a15ad1fb14d67450742cf975a76e744b3189f4d.tar.xz
linux-8a15ad1fb14d67450742cf975a76e744b3189f4d.zip
qlcnic: release device resources during interface down
Previously we were allocating device resources during probe and release them during remove. Now alloc during interface up and release in interface down. This helps in device performance, as it doesn't need to keep track of inactive resources. Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_ctx.c')
-rw-r--r--drivers/net/qlcnic/qlcnic_ctx.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index 7c96c8e06c3f..be341c1564b8 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -180,6 +180,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
for (i = 0; i < nrds_rings; i++) {
rds_ring = &recv_ctx->rds_rings[i];
+ rds_ring->producer = 0;
prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr);
prq_rds[i].ring_size = cpu_to_le32(rds_ring->num_desc);
@@ -193,6 +194,8 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
for (i = 0; i < nsds_rings; i++) {
sds_ring = &recv_ctx->sds_rings[i];
+ sds_ring->consumer = 0;
+ memset(sds_ring->desc_head, 0, STATUS_DESC_RINGSIZE(sds_ring));
prq_sds[i].host_phys_addr = cpu_to_le64(sds_ring->phys_addr);
prq_sds[i].ring_size = cpu_to_le32(sds_ring->num_desc);
@@ -293,6 +296,11 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter)
dma_addr_t rq_phys_addr, rsp_phys_addr;
struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring;
+ /* reset host resources */
+ tx_ring->producer = 0;
+ tx_ring->sw_consumer = 0;
+ *(tx_ring->hw_consumer) = 0;
+
rq_size = SIZEOF_HOSTRQ_TX(struct qlcnic_hostrq_tx_ctx);
rq_addr = pci_alloc_consistent(adapter->pdev,
rq_size, &rq_phys_addr);
@@ -476,15 +484,6 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)
sds_ring->desc_head = (struct status_desc *)addr;
}
-
- err = qlcnic_fw_cmd_create_rx_ctx(adapter);
- if (err)
- goto err_out_free;
- err = qlcnic_fw_cmd_create_tx_ctx(adapter);
- if (err)
- goto err_out_free;
-
- set_bit(__QLCNIC_FW_ATTACHED, &adapter->state);
return 0;
err_out_free:
@@ -492,15 +491,27 @@ err_out_free:
return err;
}
-void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
+
+int qlcnic_fw_create_ctx(struct qlcnic_adapter *adapter)
{
- struct qlcnic_recv_context *recv_ctx;
- struct qlcnic_host_rds_ring *rds_ring;
- struct qlcnic_host_sds_ring *sds_ring;
- struct qlcnic_host_tx_ring *tx_ring;
- int ring;
+ int err;
+
+ err = qlcnic_fw_cmd_create_rx_ctx(adapter);
+ if (err)
+ return err;
+ err = qlcnic_fw_cmd_create_tx_ctx(adapter);
+ if (err) {
+ qlcnic_fw_cmd_destroy_rx_ctx(adapter);
+ return err;
+ }
+
+ set_bit(__QLCNIC_FW_ATTACHED, &adapter->state);
+ return 0;
+}
+void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter)
+{
if (test_and_clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) {
qlcnic_fw_cmd_destroy_rx_ctx(adapter);
qlcnic_fw_cmd_destroy_tx_ctx(adapter);
@@ -508,6 +519,15 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
/* Allow dma queues to drain after context reset */
msleep(20);
}
+}
+
+void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
+{
+ struct qlcnic_recv_context *recv_ctx;
+ struct qlcnic_host_rds_ring *rds_ring;
+ struct qlcnic_host_sds_ring *sds_ring;
+ struct qlcnic_host_tx_ring *tx_ring;
+ int ring;
recv_ctx = &adapter->recv_ctx;