From patchwork Wed Jul 15 10:04:40 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Govindarajulu Varadarajan <_govind@gmx.com> X-Patchwork-Id: 495746 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 4FDD21402BA for ; Wed, 15 Jul 2015 20:05:31 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756032AbbGOKFU (ORCPT ); Wed, 15 Jul 2015 06:05:20 -0400 Received: from mout.gmx.net ([212.227.15.18]:59320 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756028AbbGOKFS (ORCPT ); Wed, 15 Jul 2015 06:05:18 -0400 Received: from ws.cisco.cisco ([72.163.220.17]) by mail.gmx.com (mrgmx002) with ESMTPSA (Nemesis) id 0Mb7lL-1ZYv0j3K8Z-00KhVd; Wed, 15 Jul 2015 12:05:15 +0200 From: Govindarajulu Varadarajan <_govind@gmx.com> To: davem@davemloft.net, netdev@vger.kernel.org Cc: ssujith@cisco.com, benve@cisco.com, Govindarajulu Varadarajan <_govind@gmx.com> Subject: [PATCH net-next 2/2] enic: allow adaptive coalesce setting for msi/legacy intr Date: Wed, 15 Jul 2015 15:34:40 +0530 Message-Id: <1436954680-10248-2-git-send-email-_govind@gmx.com> X-Mailer: git-send-email 2.4.5 In-Reply-To: <1436954680-10248-1-git-send-email-_govind@gmx.com> References: <1436954680-10248-1-git-send-email-_govind@gmx.com> X-Provags-ID: V03:K0:9CODeYF9eZA+twweoO9gFvcuDkhSSQnBpNl7cz4Sjc8Sghenaph 6tMYaTJ2wHaY5gVfZFdUbZctjZrssWSrwedS6H3wcYAG/qe4rPCFWGp4qQWhomEyVUwH8Nt 32ObT5nLpOs/+ZjnclNAlF8vLQ4ouF8qOUzOEGeoDPgeYIHPxgsJ8iKbLuxP3+Eyalew9IW nPJKltHO/kOQkQVZyw+wQ== X-UI-Out-Filterresults: notjunk:1; V01:K0:pMNcJmpUFpU=:8HhxCpklcTkW/jg888vnbX C2R4AoP5iHG03Ki0LGMjgNYi2Gc+qF2iz1WUsylJRVAJgHqWvDC0imwJ70NEM0HVc99zH/mW6 Ch0xWuaKA/3rzHtMxDQ5eTrJe2rYTiirKzh2m7GMVypEDYM5qDzFEZ7EkgWPBd+edFK/c15UJ ICcJjb+YhYpXql2wCEXEeMbHRekr0CvPy0ob0Ysi3hqFHInGH9r4/zcbG8dWTcIsr3qbJEqkF Vhnghmicy+iGfbHxH+W4rcIz2BGdNvqlR5dkJ+HWdmNe3gaNrXjXFUPEdk7qoRjUEiKsTmd7y 2+hopmKy1zzHP+VMCV5u/oABXxnZQwvWulOrVhSy9kHeIEj1Y6rafzrK7Pk8k7pwfcnWpghvE 1zwWl6XGQQky9kgkXYa/tWZz1he13/FlDsV7sJzs5VEAKqoNlkxAAgOyTBAueu5vIM6wLeqTw GU5ZTy6nV/x8I0NLiIImFzjE1Q3YbdjV63grEfR19dLSNvKnjdoN1Nh0vByNWx7GsxghgpVWV iavXAyGbquccc+prFm5NKDgU2VM1YLHRzvq36LSklLTXmQA3okS5lKXw5E/6FOwwBluAYvOxf 7q1NJDTsNx3XTuh5vlUXGfrbdPwBoNc9E2U/GzeGUxXVQZuVNoCX4sK5CnbUcmZKcgpZoMR9v Ze5OZd2RUvCRiuESAxAigc+NimhJBqacHlvJ3DEApSgGXVQ== Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org * Allow setting of adaptive coalescing setting for all types of interrupt. * In msi & legacy intr, we use single interrupt for rx & tx. In this case tx_coalesce_usecs is invalid. We should use only rx_coalesce_usecs. Do not display tx_coal values for msi/intx. And do not allow user to set this as well. * Driver supports only tx/rx_coalesce_usec and adaptive coalesce settings. For other values, driver does not return error. So ethtool succeeds for unsupported values. Introduce enic_coalesce_valid() function to validate the coalescing values. * If user requests for coalesce value greater than what adaptor supports, driver uses the max value. We should at least log this. Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com> --- drivers/net/ethernet/cisco/enic/enic_ethtool.c | 113 ++++++++++++++----------- 1 file changed, 65 insertions(+), 48 deletions(-) diff --git a/drivers/net/ethernet/cisco/enic/enic_ethtool.c b/drivers/net/ethernet/cisco/enic/enic_ethtool.c index f3f1601..f44a39c 100644 --- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c +++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c @@ -224,7 +224,8 @@ static int enic_get_coalesce(struct net_device *netdev, struct enic *enic = netdev_priv(netdev); struct enic_rx_coal *rxcoal = &enic->rx_coalesce_setting; - ecmd->tx_coalesce_usecs = enic->tx_coalesce_usecs; + if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX) + ecmd->tx_coalesce_usecs = enic->tx_coalesce_usecs; ecmd->rx_coalesce_usecs = enic->rx_coalesce_usecs; if (rxcoal->use_adaptive_rx_coalesce) ecmd->use_adaptive_rx_coalesce = 1; @@ -234,6 +235,53 @@ static int enic_get_coalesce(struct net_device *netdev, return 0; } +static int enic_coalesce_valid(struct enic *enic, + struct ethtool_coalesce *ec) +{ + u32 coalesce_usecs_max = vnic_dev_get_intr_coal_timer_max(enic->vdev); + u32 rx_coalesce_usecs_high = min_t(u32, coalesce_usecs_max, + ec->rx_coalesce_usecs_high); + u32 rx_coalesce_usecs_low = min_t(u32, coalesce_usecs_max, + ec->rx_coalesce_usecs_low); + + if (ec->rx_max_coalesced_frames || + ec->rx_coalesce_usecs_irq || + ec->rx_max_coalesced_frames_irq || + ec->tx_max_coalesced_frames || + ec->tx_coalesce_usecs_irq || + ec->tx_max_coalesced_frames_irq || + ec->stats_block_coalesce_usecs || + ec->use_adaptive_tx_coalesce || + ec->pkt_rate_low || + ec->rx_max_coalesced_frames_low || + ec->tx_coalesce_usecs_low || + ec->tx_max_coalesced_frames_low || + ec->pkt_rate_high || + ec->rx_max_coalesced_frames_high || + ec->tx_coalesce_usecs_high || + ec->tx_max_coalesced_frames_high || + ec->rate_sample_interval) + return -EINVAL; + + if ((vnic_dev_get_intr_mode(enic->vdev) != VNIC_DEV_INTR_MODE_MSIX) && + ec->tx_coalesce_usecs) + return -EINVAL; + + if ((ec->tx_coalesce_usecs > coalesce_usecs_max) || + (ec->rx_coalesce_usecs > coalesce_usecs_max) || + (ec->rx_coalesce_usecs_low > coalesce_usecs_max) || + (ec->rx_coalesce_usecs_high > coalesce_usecs_max)) + netdev_info(enic->netdev, "ethtool_set_coalesce: adaptor supports max coalesce value of %d. Setting max value.\n", + coalesce_usecs_max); + + if (ec->rx_coalesce_usecs_high && + (rx_coalesce_usecs_high < + rx_coalesce_usecs_low + ENIC_AIC_LARGE_PKT_DIFF)) + return -EINVAL; + + return 0; +} + static int enic_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ecmd) { @@ -244,8 +292,12 @@ static int enic_set_coalesce(struct net_device *netdev, 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); @@ -257,59 +309,24 @@ static int enic_set_coalesce(struct net_device *netdev, 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; - + 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); - } - - 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; + tx_coalesce_usecs); } - break; - default: - break; + 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->tx_coalesce_usecs = tx_coalesce_usecs; enic->rx_coalesce_usecs = rx_coalesce_usecs; return 0;