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

Commit ea7ea65a authored by Vasanthy Kolluri's avatar Vasanthy Kolluri Committed by David S. Miller
Browse files

enic: Add support to configure hardware interrupt coalesce timers in a platform independent way



enic driver and the underlying hardware use different units for representing the interrupt coalesce timer.
Driver converts the interrupt coalesce timer in usec to hardware cycles while setting the relevant hardware
registers. The conversion factor can be different for each of the adapter hardware types. So it is dynamically
learnt from the adapter firmware using the devcmd CMD_INTR_COAL_CONVERT. This allows the driver to configure
the hardware interrupt coalesce timers in a platform independent way.

Signed-off-by: default avatarDanny Guo <dannguo@cisco.com>
Signed-off-by: default avatarVasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: default avatarRoopa Prabhu <roprabhu@cisco.com>
Signed-off-by: default avatarDavid Wang <dwang2@cisco.com>
Signed-off-by: default avatarDavid S. Miller <davem@conan.davemloft.net>
parent 3fa2a1df
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -32,7 +32,7 @@


#define DRV_NAME		"enic"
#define DRV_NAME		"enic"
#define DRV_DESCRIPTION		"Cisco VIC Ethernet NIC Driver"
#define DRV_DESCRIPTION		"Cisco VIC Ethernet NIC Driver"
#define DRV_VERSION		"2.1.1.20"
#define DRV_VERSION		"2.1.1.24"
#define DRV_COPYRIGHT		"Copyright 2008-2011 Cisco Systems, Inc"
#define DRV_COPYRIGHT		"Copyright 2008-2011 Cisco Systems, Inc"


#define ENIC_BARS_MAX		6
#define ENIC_BARS_MAX		6
+11 −0
Original line number Original line Diff line number Diff line
@@ -166,6 +166,17 @@ int enic_dev_disable(struct enic *enic)
	return err;
	return err;
}
}


int enic_dev_intr_coal_timer_info(struct enic *enic)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_intr_coal_timer_info(enic->vdev);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_vnic_dev_deinit(struct enic *enic)
int enic_vnic_dev_deinit(struct enic *enic)
{
{
	int err;
	int err;
+1 −0
Original line number Original line Diff line number Diff line
@@ -34,6 +34,7 @@ int enic_dev_hang_notify(struct enic *enic);
int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic);
int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic);
int enic_dev_enable(struct enic *enic);
int enic_dev_enable(struct enic *enic);
int enic_dev_disable(struct enic *enic);
int enic_dev_disable(struct enic *enic);
int enic_dev_intr_coal_timer_info(struct enic *enic);
int enic_vnic_dev_deinit(struct enic *enic);
int enic_vnic_dev_deinit(struct enic *enic);
int enic_dev_init_prov2(struct enic *enic, struct vic_provinfo *vp);
int enic_dev_init_prov2(struct enic *enic, struct vic_provinfo *vp);
int enic_dev_deinit_done(struct enic *enic, int *status);
int enic_dev_deinit_done(struct enic *enic, int *status);
+16 −10
Original line number Original line Diff line number Diff line
@@ -284,12 +284,10 @@ static int enic_set_coalesce(struct net_device *netdev,
	u32 rx_coalesce_usecs;
	u32 rx_coalesce_usecs;
	unsigned int i, intr;
	unsigned int i, intr;


	tx_coalesce_usecs = min_t(u32,
	tx_coalesce_usecs = min_t(u32, ecmd->tx_coalesce_usecs,
		INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX),
		vnic_dev_get_intr_coal_timer_max(enic->vdev));
		ecmd->tx_coalesce_usecs);
	rx_coalesce_usecs = min_t(u32, ecmd->rx_coalesce_usecs,
	rx_coalesce_usecs = min_t(u32,
		vnic_dev_get_intr_coal_timer_max(enic->vdev));
		INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX),
		ecmd->rx_coalesce_usecs);


	switch (vnic_dev_get_intr_mode(enic->vdev)) {
	switch (vnic_dev_get_intr_mode(enic->vdev)) {
	case VNIC_DEV_INTR_MODE_INTX:
	case VNIC_DEV_INTR_MODE_INTX:
@@ -298,26 +296,26 @@ static int enic_set_coalesce(struct net_device *netdev,


		intr = enic_legacy_io_intr();
		intr = enic_legacy_io_intr();
		vnic_intr_coalescing_timer_set(&enic->intr[intr],
		vnic_intr_coalescing_timer_set(&enic->intr[intr],
			INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
			tx_coalesce_usecs);
		break;
		break;
	case VNIC_DEV_INTR_MODE_MSI:
	case VNIC_DEV_INTR_MODE_MSI:
		if (tx_coalesce_usecs != rx_coalesce_usecs)
		if (tx_coalesce_usecs != rx_coalesce_usecs)
			return -EINVAL;
			return -EINVAL;


		vnic_intr_coalescing_timer_set(&enic->intr[0],
		vnic_intr_coalescing_timer_set(&enic->intr[0],
			INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
			tx_coalesce_usecs);
		break;
		break;
	case VNIC_DEV_INTR_MODE_MSIX:
	case VNIC_DEV_INTR_MODE_MSIX:
		for (i = 0; i < enic->wq_count; i++) {
		for (i = 0; i < enic->wq_count; i++) {
			intr = enic_msix_wq_intr(enic, i);
			intr = enic_msix_wq_intr(enic, i);
			vnic_intr_coalescing_timer_set(&enic->intr[intr],
			vnic_intr_coalescing_timer_set(&enic->intr[intr],
				INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
				tx_coalesce_usecs);
		}
		}


		for (i = 0; i < enic->rq_count; i++) {
		for (i = 0; i < enic->rq_count; i++) {
			intr = enic_msix_rq_intr(enic, i);
			intr = enic_msix_rq_intr(enic, i);
			vnic_intr_coalescing_timer_set(&enic->intr[intr],
			vnic_intr_coalescing_timer_set(&enic->intr[intr],
				INTR_COALESCE_USEC_TO_HW(rx_coalesce_usecs));
				rx_coalesce_usecs);
		}
		}


		break;
		break;
@@ -2175,6 +2173,14 @@ static int enic_dev_init(struct enic *enic)
	unsigned int i;
	unsigned int i;
	int err;
	int err;


	/* Get interrupt coalesce timer info */
	err = enic_dev_intr_coal_timer_info(enic);
	if (err) {
		dev_warn(dev, "Using default conversion factor for "
			"interrupt coalesce timer\n");
		vnic_dev_intr_coal_timer_info_default(enic->vdev);
	}

	/* Get vNIC configuration
	/* Get vNIC configuration
	 */
	 */


+3 −4
Original line number Original line Diff line number Diff line
@@ -90,9 +90,8 @@ int enic_get_vnic_config(struct enic *enic)
		max_t(u16, ENIC_MIN_MTU,
		max_t(u16, ENIC_MIN_MTU,
		c->mtu));
		c->mtu));


	c->intr_timer_usec = min_t(u32,
	c->intr_timer_usec = min_t(u32, c->intr_timer_usec,
		INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX),
		vnic_dev_get_intr_coal_timer_max(enic->vdev));
		c->intr_timer_usec);


	dev_info(enic_get_dev(enic),
	dev_info(enic_get_dev(enic),
		"vNIC MAC addr %pM wq/rq %d/%d mtu %d\n",
		"vNIC MAC addr %pM wq/rq %d/%d mtu %d\n",
@@ -303,7 +302,7 @@ void enic_init_vnic_resources(struct enic *enic)


	for (i = 0; i < enic->intr_count; i++) {
	for (i = 0; i < enic->intr_count; i++) {
		vnic_intr_init(&enic->intr[i],
		vnic_intr_init(&enic->intr[i],
			INTR_COALESCE_USEC_TO_HW(enic->config.intr_timer_usec),
			enic->config.intr_timer_usec,
			enic->config.intr_timer_type,
			enic->config.intr_timer_type,
			mask_on_assertion);
			mask_on_assertion);
	}
	}
Loading