mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
78366f69be
Add advanced interrupt moderation support available since "Sparrow B0". Legacy interrupt moderation used only one counter to moderate tx, rx, and misc interrupts. Advanced interrupt moderation bypasses misc, and handles separately tx and rx interrupts. In addition it has two timers for each interrupt type. Max burst duration timer which defines how long to postpone interrupt after first event (receive event for rx and tx complete event for tx), and interframe timeout which defines how to determine the end of the burst and issue interrupt even if the first timer still pending. Capabilities flags in wil_priv is set on initialization according to HW. The rest of the code checks for advanced interrupt capability bit in capabilities flags field. Debugfs is split accordingly: "legacy" interrupt moderation remains unchanged, new debugs files added for advanced interrupt moderation support. Module params are aligned to support advanced interrupt moderation (tx & rx). When not available (for legacy interrupt moderation) will use only rx configuration; Tx configuration will be ignored in this case. Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
126 lines
3.6 KiB
C
126 lines
3.6 KiB
C
/*
|
|
* Copyright (c) 2014 Qualcomm Atheros, Inc.
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#include <linux/etherdevice.h>
|
|
#include <linux/pci.h>
|
|
#include <linux/rtnetlink.h>
|
|
#include <net/cfg80211.h>
|
|
|
|
#include "wil6210.h"
|
|
|
|
static int wil_ethtoolops_begin(struct net_device *ndev)
|
|
{
|
|
struct wil6210_priv *wil = ndev_to_wil(ndev);
|
|
|
|
mutex_lock(&wil->mutex);
|
|
|
|
wil_dbg_misc(wil, "%s()\n", __func__);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void wil_ethtoolops_complete(struct net_device *ndev)
|
|
{
|
|
struct wil6210_priv *wil = ndev_to_wil(ndev);
|
|
|
|
wil_dbg_misc(wil, "%s()\n", __func__);
|
|
|
|
mutex_unlock(&wil->mutex);
|
|
}
|
|
|
|
static int wil_ethtoolops_get_coalesce(struct net_device *ndev,
|
|
struct ethtool_coalesce *cp)
|
|
{
|
|
struct wil6210_priv *wil = ndev_to_wil(ndev);
|
|
u32 tx_itr_en, tx_itr_val = 0;
|
|
u32 rx_itr_en, rx_itr_val = 0;
|
|
|
|
wil_dbg_misc(wil, "%s()\n", __func__);
|
|
|
|
if (test_bit(hw_capability_advanced_itr_moderation,
|
|
wil->hw_capabilities)) {
|
|
tx_itr_en = ioread32(wil->csr +
|
|
HOSTADDR(RGF_DMA_ITR_TX_CNT_CTL));
|
|
if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN)
|
|
tx_itr_val =
|
|
ioread32(wil->csr +
|
|
HOSTADDR(RGF_DMA_ITR_TX_CNT_TRSH));
|
|
|
|
rx_itr_en = ioread32(wil->csr +
|
|
HOSTADDR(RGF_DMA_ITR_RX_CNT_CTL));
|
|
if (rx_itr_en & BIT_DMA_ITR_RX_CNT_CTL_EN)
|
|
rx_itr_val =
|
|
ioread32(wil->csr +
|
|
HOSTADDR(RGF_DMA_ITR_RX_CNT_TRSH));
|
|
} else {
|
|
rx_itr_en = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_CRL));
|
|
if (rx_itr_en & BIT_DMA_ITR_CNT_CRL_EN)
|
|
rx_itr_val = ioread32(wil->csr +
|
|
HOSTADDR(RGF_DMA_ITR_CNT_TRSH));
|
|
}
|
|
|
|
cp->tx_coalesce_usecs = tx_itr_val;
|
|
cp->rx_coalesce_usecs = rx_itr_val;
|
|
return 0;
|
|
}
|
|
|
|
static int wil_ethtoolops_set_coalesce(struct net_device *ndev,
|
|
struct ethtool_coalesce *cp)
|
|
{
|
|
struct wil6210_priv *wil = ndev_to_wil(ndev);
|
|
|
|
wil_dbg_misc(wil, "%s(rx %d usec, tx %d usec)\n", __func__,
|
|
cp->rx_coalesce_usecs, cp->tx_coalesce_usecs);
|
|
|
|
if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) {
|
|
wil_dbg_misc(wil, "No IRQ coalescing in monitor mode\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
/* only @rx_coalesce_usecs and @tx_coalesce_usecs supported,
|
|
* ignore other parameters
|
|
*/
|
|
|
|
if (cp->rx_coalesce_usecs > WIL6210_ITR_TRSH_MAX ||
|
|
cp->tx_coalesce_usecs > WIL6210_ITR_TRSH_MAX)
|
|
goto out_bad;
|
|
|
|
wil->tx_max_burst_duration = cp->tx_coalesce_usecs;
|
|
wil->rx_max_burst_duration = cp->rx_coalesce_usecs;
|
|
wil_configure_interrupt_moderation(wil);
|
|
|
|
return 0;
|
|
|
|
out_bad:
|
|
wil_dbg_misc(wil, "Unsupported coalescing params. Raw command:\n");
|
|
print_hex_dump_debug("DBG[MISC] coal ", DUMP_PREFIX_OFFSET, 16, 4,
|
|
cp, sizeof(*cp), false);
|
|
return -EINVAL;
|
|
}
|
|
|
|
static const struct ethtool_ops wil_ethtool_ops = {
|
|
.begin = wil_ethtoolops_begin,
|
|
.complete = wil_ethtoolops_complete,
|
|
.get_drvinfo = cfg80211_get_drvinfo,
|
|
.get_coalesce = wil_ethtoolops_get_coalesce,
|
|
.set_coalesce = wil_ethtoolops_set_coalesce,
|
|
};
|
|
|
|
void wil_set_ethtoolops(struct net_device *ndev)
|
|
{
|
|
ndev->ethtool_ops = &wil_ethtool_ops;
|
|
}
|