Exemplo n.º 1
0
static int enic_set_coalesce(struct net_device *netdev,
	struct ethtool_coalesce *ecmd)
{
	struct enic *enic = netdev_priv(netdev);
	u32 tx_coalesce_usecs;
	u32 rx_coalesce_usecs;
	u32 rx_coalesce_usecs_low;
	u32 rx_coalesce_usecs_high;
	u32 coalesce_usecs_max;
	unsigned int i, intr;
	int ret;
	struct enic_rx_coal *rxcoal = &enic->rx_coalesce_setting;

	ret = enic_coalesce_valid(enic, ecmd);
	if (ret)
		return ret;
	coalesce_usecs_max = vnic_dev_get_intr_coal_timer_max(enic->vdev);
	tx_coalesce_usecs = min_t(u32, ecmd->tx_coalesce_usecs,
				  coalesce_usecs_max);
	rx_coalesce_usecs = min_t(u32, ecmd->rx_coalesce_usecs,
				  coalesce_usecs_max);

	rx_coalesce_usecs_low = min_t(u32, ecmd->rx_coalesce_usecs_low,
				      coalesce_usecs_max);
	rx_coalesce_usecs_high = min_t(u32, ecmd->rx_coalesce_usecs_high,
				       coalesce_usecs_max);

	if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX) {
		for (i = 0; i < enic->wq_count; i++) {
			intr = enic_msix_wq_intr(enic, i);
			vnic_intr_coalescing_timer_set(&enic->intr[intr],
						       tx_coalesce_usecs);
		}
		enic->tx_coalesce_usecs = tx_coalesce_usecs;
	}
	rxcoal->use_adaptive_rx_coalesce = !!ecmd->use_adaptive_rx_coalesce;
	if (!rxcoal->use_adaptive_rx_coalesce)
		enic_intr_coal_set_rx(enic, rx_coalesce_usecs);
	if (ecmd->rx_coalesce_usecs_high) {
		rxcoal->range_end = rx_coalesce_usecs_high;
		rxcoal->small_pkt_range_start = rx_coalesce_usecs_low;
		rxcoal->large_pkt_range_start = rx_coalesce_usecs_low +
						ENIC_AIC_LARGE_PKT_DIFF;
	}

	enic->rx_coalesce_usecs = rx_coalesce_usecs;

	return 0;
}
Exemplo n.º 2
0
static int enic_set_coalesce(struct net_device *netdev,
	struct ethtool_coalesce *ecmd)
{
	struct enic *enic = netdev_priv(netdev);
	u32 tx_coalesce_usecs;
	u32 rx_coalesce_usecs;
	u32 rx_coalesce_usecs_low;
	u32 rx_coalesce_usecs_high;
	u32 coalesce_usecs_max;
	unsigned int i, intr;
	struct enic_rx_coal *rxcoal = &enic->rx_coalesce_setting;

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

	rx_coalesce_usecs_low = min_t(u32, ecmd->rx_coalesce_usecs_low,
				      coalesce_usecs_max);
	rx_coalesce_usecs_high = min_t(u32, ecmd->rx_coalesce_usecs_high,
				       coalesce_usecs_max);

	switch (vnic_dev_get_intr_mode(enic->vdev)) {
	case VNIC_DEV_INTR_MODE_INTX:
		if (tx_coalesce_usecs != rx_coalesce_usecs)
			return -EINVAL;
		if (ecmd->use_adaptive_rx_coalesce	||
		    ecmd->rx_coalesce_usecs_low		||
		    ecmd->rx_coalesce_usecs_high)
			return -EINVAL;

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

		vnic_intr_coalescing_timer_set(&enic->intr[0],
			tx_coalesce_usecs);
		break;
	case VNIC_DEV_INTR_MODE_MSIX:
		if (ecmd->rx_coalesce_usecs_high &&
		    (rx_coalesce_usecs_high <
		     rx_coalesce_usecs_low + ENIC_AIC_LARGE_PKT_DIFF))
				return -EINVAL;

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

		rxcoal->use_adaptive_rx_coalesce =
					!!ecmd->use_adaptive_rx_coalesce;
		if (!rxcoal->use_adaptive_rx_coalesce)
			enic_intr_coal_set_rx(enic, rx_coalesce_usecs);

		if (ecmd->rx_coalesce_usecs_high) {
			rxcoal->range_end = rx_coalesce_usecs_high;
			rxcoal->small_pkt_range_start = rx_coalesce_usecs_low;
			rxcoal->large_pkt_range_start = rx_coalesce_usecs_low +
							ENIC_AIC_LARGE_PKT_DIFF;
		}
		break;
	default:
		break;
	}

	enic->tx_coalesce_usecs = tx_coalesce_usecs;
	enic->rx_coalesce_usecs = rx_coalesce_usecs;

	return 0;
}