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

Commit da6c8063 authored by Rajesh Borundia's avatar Rajesh Borundia Committed by David S. Miller
Browse files

qlcnic: Use shared interrupt vector for Tx and Rx



o VF will use shared MSI-X interrupt vector for Tx and Rx.
o When QLCNIC_INTR_SHARED flag is set Tx and Rx will
  share MSI-X interrupt vector. Tx will use a separate
  MSI-X interrupt vector from Rx otherwise.

Signed-off-by: default avatarRajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f8468331
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -897,6 +897,7 @@ struct qlcnic_ipaddr {
#define QLCNIC_FW_RESET_OWNER		0x2000
#define QLCNIC_FW_HANG			0x4000
#define QLCNIC_FW_LRO_MSS_CAP		0x8000
#define QLCNIC_TX_INTR_SHARED		0x10000
#define QLCNIC_IS_MSI_FAMILY(adapter) \
	((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))

+16 −5
Original line number Diff line number Diff line
@@ -410,7 +410,10 @@ int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr)
					      num_intr));
	/* account for AEN interrupt MSI-X based interrupts */
	num_msix += 1;

	if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
		num_msix += adapter->max_drv_tx_rings;

	err = qlcnic_enable_msix(adapter, num_msix);
	if (err == -ENOMEM)
		return err;
@@ -1243,6 +1246,7 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
	struct qlcnic_tx_mbx mbx;
	struct qlcnic_tx_mbx_out *mbx_out;
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	u32 msix_vector;

	/* Reset host resources */
	tx->producer = 0;
@@ -1257,10 +1261,16 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
	mbx.cnsmr_index_low = LSD(tx->hw_cons_phys_addr);
	mbx.cnsmr_index_high = MSD(tx->hw_cons_phys_addr);
	mbx.size = tx->num_desc;
	if (adapter->flags & QLCNIC_MSIX_ENABLED)
		msix_id = ahw->intr_tbl[adapter->max_sds_rings + ring].id;
	if (adapter->flags & QLCNIC_MSIX_ENABLED) {
		if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
			msix_vector = adapter->max_sds_rings + ring;
		else
			msix_vector = adapter->max_sds_rings - 1;
		msix_id = ahw->intr_tbl[msix_vector].id;
	} else {
		msix_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
	}

	if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
		mbx.intr_id = msix_id;
	else
@@ -1282,7 +1292,8 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
	mbx_out = (struct qlcnic_tx_mbx_out *)&cmd.rsp.arg[2];
	tx->crb_cmd_producer = ahw->pci_base0 + mbx_out->host_prod;
	tx->ctx_id = mbx_out->ctx_id;
	if (adapter->flags & QLCNIC_MSIX_ENABLED) {
	if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
	    !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
		intr_mask = ahw->intr_tbl[adapter->max_sds_rings + ring].src;
		tx->crb_intr_mask = ahw->pci_base0 + intr_mask;
	}
+46 −10
Original line number Diff line number Diff line
@@ -1691,6 +1691,29 @@ static int qlcnic_83xx_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring,
	return count;
}

static int qlcnic_83xx_msix_sriov_vf_poll(struct napi_struct *napi, int budget)
{
	int tx_complete;
	int work_done;
	struct qlcnic_host_sds_ring *sds_ring;
	struct qlcnic_adapter *adapter;
	struct qlcnic_host_tx_ring *tx_ring;

	sds_ring = container_of(napi, struct qlcnic_host_sds_ring, napi);
	adapter = sds_ring->adapter;
	/* tx ring count = 1 */
	tx_ring = adapter->tx_ring;

	tx_complete = qlcnic_process_cmd_ring(adapter, tx_ring, budget);
	work_done = qlcnic_83xx_process_rcv_ring(sds_ring, budget);
	if ((work_done < budget) && tx_complete) {
		napi_complete(&sds_ring->napi);
		qlcnic_83xx_enable_intr(adapter, sds_ring);
	}

	return work_done;
}

static int qlcnic_83xx_poll(struct napi_struct *napi, int budget)
{
	int tx_complete;
@@ -1768,7 +1791,8 @@ void qlcnic_83xx_napi_enable(struct qlcnic_adapter *adapter)
			qlcnic_83xx_enable_intr(adapter, sds_ring);
	}

	if (adapter->flags & QLCNIC_MSIX_ENABLED) {
	if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
	    !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
		for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
			tx_ring = &adapter->tx_ring[ring];
			napi_enable(&tx_ring->napi);
@@ -1795,7 +1819,8 @@ void qlcnic_83xx_napi_disable(struct qlcnic_adapter *adapter)
		napi_disable(&sds_ring->napi);
	}

	if (adapter->flags & QLCNIC_MSIX_ENABLED) {
	if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
	    !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
		for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
			tx_ring = &adapter->tx_ring[ring];
			qlcnic_83xx_disable_tx_intr(adapter, tx_ring);
@@ -1808,7 +1833,7 @@ void qlcnic_83xx_napi_disable(struct qlcnic_adapter *adapter)
int qlcnic_83xx_napi_add(struct qlcnic_adapter *adapter,
			 struct net_device *netdev)
{
	int ring, max_sds_rings;
	int ring, max_sds_rings, temp;
	struct qlcnic_host_sds_ring *sds_ring;
	struct qlcnic_host_tx_ring *tx_ring;
	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
@@ -1819,22 +1844,32 @@ int qlcnic_83xx_napi_add(struct qlcnic_adapter *adapter,
	max_sds_rings = adapter->max_sds_rings;
	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
		sds_ring = &recv_ctx->sds_rings[ring];
		if (adapter->flags & QLCNIC_MSIX_ENABLED)
		if (adapter->flags & QLCNIC_MSIX_ENABLED) {
			if (!(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
				netif_napi_add(netdev, &sds_ring->napi,
					       qlcnic_83xx_rx_poll,
					       QLCNIC_NETDEV_WEIGHT * 2);
		else
			} else {
				temp = QLCNIC_NETDEV_WEIGHT / max_sds_rings;
				netif_napi_add(netdev, &sds_ring->napi,
					       qlcnic_83xx_msix_sriov_vf_poll,
					       temp);
			}

		} else {
			netif_napi_add(netdev, &sds_ring->napi,
				       qlcnic_83xx_poll,
				       QLCNIC_NETDEV_WEIGHT / max_sds_rings);
		}
	}

	if (qlcnic_alloc_tx_rings(adapter, netdev)) {
		qlcnic_free_sds_rings(recv_ctx);
		return -ENOMEM;
	}

	if (adapter->flags & QLCNIC_MSIX_ENABLED) {
	if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
	    !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
		for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
			tx_ring = &adapter->tx_ring[ring];
			netif_napi_add(netdev, &tx_ring->napi,
@@ -1860,7 +1895,8 @@ void qlcnic_83xx_napi_del(struct qlcnic_adapter *adapter)

	qlcnic_free_sds_rings(adapter->recv_ctx);

	if ((adapter->flags & QLCNIC_MSIX_ENABLED)) {
	if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
	    !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
		for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
			tx_ring = &adapter->tx_ring[ring];
			netif_napi_del(&tx_ring->napi);
+16 −7
Original line number Diff line number Diff line
@@ -400,7 +400,15 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
{
	struct pci_dev *pdev = adapter->pdev;
	int err = -1, i;
	int max_tx_rings;
	int max_tx_rings, tx_vector;

	if (adapter->flags & QLCNIC_TX_INTR_SHARED) {
		max_tx_rings = 0;
		tx_vector = 0;
	} else {
		max_tx_rings = adapter->max_drv_tx_rings;
		tx_vector = 1;
	}

	if (!adapter->msix_entries) {
		adapter->msix_entries = kcalloc(num_msix,
@@ -423,7 +431,6 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
			if (qlcnic_83xx_check(adapter)) {
				adapter->ahw->num_msix = num_msix;
				/* subtract mail box and tx ring vectors */
				max_tx_rings = adapter->max_drv_tx_rings;
				adapter->max_sds_rings = num_msix -
							 max_tx_rings - 1;
			} else {
@@ -436,11 +443,11 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
				 "Unable to allocate %d MSI-X interrupt vectors\n",
				 num_msix);
			if (qlcnic_83xx_check(adapter)) {
				if (err < QLC_83XX_MINIMUM_VECTOR)
				if (err < (QLC_83XX_MINIMUM_VECTOR - tx_vector))
					return err;
				err -= (adapter->max_drv_tx_rings + 1);
				err -= (max_tx_rings + 1);
				num_msix = rounddown_pow_of_two(err);
				num_msix += (adapter->max_drv_tx_rings + 1);
				num_msix += (max_tx_rings + 1);
			} else {
				num_msix = rounddown_pow_of_two(err);
			}
@@ -1285,7 +1292,8 @@ qlcnic_request_irq(struct qlcnic_adapter *adapter)
			}
		}
		if (qlcnic_83xx_check(adapter) &&
		    (adapter->flags & QLCNIC_MSIX_ENABLED)) {
		    (adapter->flags & QLCNIC_MSIX_ENABLED) &&
		    !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
			handler = qlcnic_msix_tx_intr;
			for (ring = 0; ring < adapter->max_drv_tx_rings;
			     ring++) {
@@ -1321,7 +1329,8 @@ qlcnic_free_irq(struct qlcnic_adapter *adapter)
				free_irq(sds_ring->irq, sds_ring);
			}
		}
		if (qlcnic_83xx_check(adapter)) {
		if (qlcnic_83xx_check(adapter) &&
		    !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
			for (ring = 0; ring < adapter->max_drv_tx_rings;
			     ring++) {
				tx_ring = &adapter->tx_ring[ring];
+1 −0
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ int qlcnic_sriov_vf_init(struct qlcnic_adapter *adapter, int pci_using_dac)
	spin_lock_init(&ahw->mbx_lock);
	set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
	ahw->msix_supported = 1;
	adapter->flags |= QLCNIC_TX_INTR_SHARED;

	if (qlcnic_sriov_setup_vf(adapter, pci_using_dac))
		return -EIO;