linux/drivers/net/wireless/ath/wil6210/ethtool.c
<<
>>
Prefs
   1// SPDX-License-Identifier: ISC
   2/*
   3 * Copyright (c) 2014,2017 Qualcomm Atheros, Inc.
   4 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
   5 */
   6
   7#include <linux/etherdevice.h>
   8#include <linux/pci.h>
   9#include <linux/rtnetlink.h>
  10#include <net/cfg80211.h>
  11
  12#include "wil6210.h"
  13
  14static int wil_ethtoolops_get_coalesce(struct net_device *ndev,
  15                                       struct ethtool_coalesce *cp)
  16{
  17        struct wil6210_priv *wil = ndev_to_wil(ndev);
  18        u32 tx_itr_en, tx_itr_val = 0;
  19        u32 rx_itr_en, rx_itr_val = 0;
  20        int ret;
  21
  22        mutex_lock(&wil->mutex);
  23        wil_dbg_misc(wil, "ethtoolops_get_coalesce\n");
  24
  25        ret = wil_pm_runtime_get(wil);
  26        if (ret < 0)
  27                goto out;
  28
  29        tx_itr_en = wil_r(wil, RGF_DMA_ITR_TX_CNT_CTL);
  30        if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN)
  31                tx_itr_val = wil_r(wil, RGF_DMA_ITR_TX_CNT_TRSH);
  32
  33        rx_itr_en = wil_r(wil, RGF_DMA_ITR_RX_CNT_CTL);
  34        if (rx_itr_en & BIT_DMA_ITR_RX_CNT_CTL_EN)
  35                rx_itr_val = wil_r(wil, RGF_DMA_ITR_RX_CNT_TRSH);
  36
  37        wil_pm_runtime_put(wil);
  38
  39        cp->tx_coalesce_usecs = tx_itr_val;
  40        cp->rx_coalesce_usecs = rx_itr_val;
  41        ret = 0;
  42
  43out:
  44        mutex_unlock(&wil->mutex);
  45        return ret;
  46}
  47
  48static int wil_ethtoolops_set_coalesce(struct net_device *ndev,
  49                                       struct ethtool_coalesce *cp)
  50{
  51        struct wil6210_priv *wil = ndev_to_wil(ndev);
  52        struct wireless_dev *wdev = ndev->ieee80211_ptr;
  53        int ret;
  54
  55        mutex_lock(&wil->mutex);
  56        wil_dbg_misc(wil, "ethtoolops_set_coalesce: rx %d usec, tx %d usec\n",
  57                     cp->rx_coalesce_usecs, cp->tx_coalesce_usecs);
  58
  59        if (wdev->iftype == NL80211_IFTYPE_MONITOR) {
  60                wil_dbg_misc(wil, "No IRQ coalescing in monitor mode\n");
  61                ret = -EINVAL;
  62                goto out;
  63        }
  64
  65        /* only @rx_coalesce_usecs and @tx_coalesce_usecs supported,
  66         * ignore other parameters
  67         */
  68
  69        if (cp->rx_coalesce_usecs > WIL6210_ITR_TRSH_MAX ||
  70            cp->tx_coalesce_usecs > WIL6210_ITR_TRSH_MAX)
  71                goto out_bad;
  72
  73        wil->tx_max_burst_duration = cp->tx_coalesce_usecs;
  74        wil->rx_max_burst_duration = cp->rx_coalesce_usecs;
  75
  76        ret = wil_pm_runtime_get(wil);
  77        if (ret < 0)
  78                goto out;
  79
  80        wil->txrx_ops.configure_interrupt_moderation(wil);
  81
  82        wil_pm_runtime_put(wil);
  83        ret = 0;
  84
  85out:
  86        mutex_unlock(&wil->mutex);
  87        return ret;
  88
  89out_bad:
  90        wil_dbg_misc(wil, "Unsupported coalescing params. Raw command:\n");
  91        print_hex_dump_debug("DBG[MISC] coal ", DUMP_PREFIX_OFFSET, 16, 4,
  92                             cp, sizeof(*cp), false);
  93        mutex_unlock(&wil->mutex);
  94        return -EINVAL;
  95}
  96
  97static const struct ethtool_ops wil_ethtool_ops = {
  98        .supported_coalesce_params = ETHTOOL_COALESCE_USECS,
  99        .get_drvinfo    = cfg80211_get_drvinfo,
 100        .get_coalesce   = wil_ethtoolops_get_coalesce,
 101        .set_coalesce   = wil_ethtoolops_set_coalesce,
 102};
 103
 104void wil_set_ethtoolops(struct net_device *ndev)
 105{
 106        ndev->ethtool_ops = &wil_ethtool_ops;
 107}
 108