Blame view

kernel/linux-rt-4.4.41/drivers/net/wireless/ath/wil6210/ethtool.c 3.18 KB
5113f6f70   김현기   kernel add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
  /*
   * 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()
  ", __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()
  ", __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()
  ", __func__);
  
  	tx_itr_en = wil_r(wil, RGF_DMA_ITR_TX_CNT_CTL);
  	if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN)
  		tx_itr_val = wil_r(wil, RGF_DMA_ITR_TX_CNT_TRSH);
  
  	rx_itr_en = wil_r(wil, RGF_DMA_ITR_RX_CNT_CTL);
  	if (rx_itr_en & BIT_DMA_ITR_RX_CNT_CTL_EN)
  		rx_itr_val = wil_r(wil, RGF_DMA_ITR_RX_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)
  ", __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
  ");
  		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:
  ");
  	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;
  }