Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a15ad1f authored by Amit Kumar Salecha's avatar Amit Kumar Salecha Committed by David S. Miller
Browse files

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: default avatarAmit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 42f65cba
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -1124,6 +1124,10 @@ void __iomem *qlcnic_get_ioaddr(struct qlcnic_adapter *, u32);
int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter);
int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter);
void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter);
void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter);


int qlcnic_fw_create_ctx(struct qlcnic_adapter *adapter);
void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter);

void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter);
void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter);
void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter);
void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter);
void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter);


+35 −15
Original line number Original line Diff line number Diff line
@@ -180,6 +180,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
	for (i = 0; i < nrds_rings; i++) {
	for (i = 0; i < nrds_rings; i++) {


		rds_ring = &recv_ctx->rds_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].host_phys_addr = cpu_to_le64(rds_ring->phys_addr);
		prq_rds[i].ring_size = cpu_to_le32(rds_ring->num_desc);
		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++) {
	for (i = 0; i < nsds_rings; i++) {


		sds_ring = &recv_ctx->sds_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].host_phys_addr = cpu_to_le64(sds_ring->phys_addr);
		prq_sds[i].ring_size = cpu_to_le32(sds_ring->num_desc);
		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;
	dma_addr_t	rq_phys_addr, rsp_phys_addr;
	struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring;
	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_size = SIZEOF_HOSTRQ_TX(struct qlcnic_hostrq_tx_ctx);
	rq_addr = pci_alloc_consistent(adapter->pdev,
	rq_addr = pci_alloc_consistent(adapter->pdev,
		rq_size, &rq_phys_addr);
		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;
		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;
	return 0;


err_out_free:
err_out_free:
@@ -492,15 +491,27 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)
	return err;
	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;
	int err;
	struct qlcnic_host_rds_ring *rds_ring;

	struct qlcnic_host_sds_ring *sds_ring;
	err = qlcnic_fw_cmd_create_rx_ctx(adapter);
	struct qlcnic_host_tx_ring *tx_ring;
	if (err)
	int ring;
		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)) {
	if (test_and_clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) {
		qlcnic_fw_cmd_destroy_rx_ctx(adapter);
		qlcnic_fw_cmd_destroy_rx_ctx(adapter);
		qlcnic_fw_cmd_destroy_tx_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 */
		/* Allow dma queues to drain after context reset */
		msleep(20);
		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;
	recv_ctx = &adapter->recv_ctx;


+5 −2
Original line number Original line Diff line number Diff line
@@ -348,7 +348,7 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
	for (i = 0; diag_registers[i] != -1; i++)
	for (i = 0; diag_registers[i] != -1; i++)
		regs_buff[i] = QLCRD32(adapter, diag_registers[i]);
		regs_buff[i] = QLCRD32(adapter, diag_registers[i]);


	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
	if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
		return;
		return;


	regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
	regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
@@ -833,6 +833,9 @@ static int qlcnic_blink_led(struct net_device *dev, u32 val)
	struct qlcnic_adapter *adapter = netdev_priv(dev);
	struct qlcnic_adapter *adapter = netdev_priv(dev);
	int ret;
	int ret;


	if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
		return -EIO;

	ret = adapter->nic_ops->config_led(adapter, 1, 0xf);
	ret = adapter->nic_ops->config_led(adapter, 1, 0xf);
	if (ret) {
	if (ret) {
		dev_err(&adapter->pdev->dev,
		dev_err(&adapter->pdev->dev,
@@ -904,7 +907,7 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev,
{
{
	struct qlcnic_adapter *adapter = netdev_priv(netdev);
	struct qlcnic_adapter *adapter = netdev_priv(netdev);


	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
	if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
		return -EINVAL;
		return -EINVAL;


	/*
	/*
+2 −2
Original line number Original line Diff line number Diff line
@@ -327,7 +327,7 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter,


	i = 0;
	i = 0;


	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
	if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
		return -EIO;
		return -EIO;


	tx_ring = adapter->tx_ring;
	tx_ring = adapter->tx_ring;
@@ -431,7 +431,7 @@ void qlcnic_set_multi(struct net_device *netdev)
	u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
	u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
	u32 mode = VPORT_MISS_MODE_DROP;
	u32 mode = VPORT_MISS_MODE_DROP;


	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
	if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
		return;
		return;


	qlcnic_nic_add_mac(adapter, adapter->mac_addr);
	qlcnic_nic_add_mac(adapter, adapter->mac_addr);
+26 −0
Original line number Original line Diff line number Diff line
@@ -125,6 +125,32 @@ void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter)
	}
	}
}
}


void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter)
{
	struct qlcnic_recv_context *recv_ctx;
	struct qlcnic_host_rds_ring *rds_ring;
	struct qlcnic_rx_buffer *rx_buf;
	int i, ring;

	recv_ctx = &adapter->recv_ctx;
	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
		rds_ring = &recv_ctx->rds_rings[ring];

		spin_lock(&rds_ring->lock);

		INIT_LIST_HEAD(&rds_ring->free_list);

		rx_buf = rds_ring->rx_buf_arr;
		for (i = 0; i < rds_ring->num_desc; i++) {
			list_add_tail(&rx_buf->list,
					&rds_ring->free_list);
			rx_buf++;
		}

		spin_unlock(&rds_ring->lock);
	}
}

void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter)
void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter)
{
{
	struct qlcnic_cmd_buffer *cmd_buf;
	struct qlcnic_cmd_buffer *cmd_buf;
Loading