2 * Copyright 2013 Cisco Systems, Inc. All rights reserved.
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 #include <linux/netdevice.h>
20 #include <linux/ethtool.h>
25 #include "enic_clsf.h"
27 #include "vnic_stats.h"
30 char name
[ETH_GSTRING_LEN
];
34 #define ENIC_TX_STAT(stat) { \
36 .index = offsetof(struct vnic_tx_stats, stat) / sizeof(u64) \
39 #define ENIC_RX_STAT(stat) { \
41 .index = offsetof(struct vnic_rx_stats, stat) / sizeof(u64) \
44 #define ENIC_GEN_STAT(stat) { \
46 .index = offsetof(struct vnic_gen_stats, stat) / sizeof(u64)\
49 static const struct enic_stat enic_tx_stats
[] = {
50 ENIC_TX_STAT(tx_frames_ok
),
51 ENIC_TX_STAT(tx_unicast_frames_ok
),
52 ENIC_TX_STAT(tx_multicast_frames_ok
),
53 ENIC_TX_STAT(tx_broadcast_frames_ok
),
54 ENIC_TX_STAT(tx_bytes_ok
),
55 ENIC_TX_STAT(tx_unicast_bytes_ok
),
56 ENIC_TX_STAT(tx_multicast_bytes_ok
),
57 ENIC_TX_STAT(tx_broadcast_bytes_ok
),
58 ENIC_TX_STAT(tx_drops
),
59 ENIC_TX_STAT(tx_errors
),
63 static const struct enic_stat enic_rx_stats
[] = {
64 ENIC_RX_STAT(rx_frames_ok
),
65 ENIC_RX_STAT(rx_frames_total
),
66 ENIC_RX_STAT(rx_unicast_frames_ok
),
67 ENIC_RX_STAT(rx_multicast_frames_ok
),
68 ENIC_RX_STAT(rx_broadcast_frames_ok
),
69 ENIC_RX_STAT(rx_bytes_ok
),
70 ENIC_RX_STAT(rx_unicast_bytes_ok
),
71 ENIC_RX_STAT(rx_multicast_bytes_ok
),
72 ENIC_RX_STAT(rx_broadcast_bytes_ok
),
73 ENIC_RX_STAT(rx_drop
),
74 ENIC_RX_STAT(rx_no_bufs
),
75 ENIC_RX_STAT(rx_errors
),
77 ENIC_RX_STAT(rx_crc_errors
),
78 ENIC_RX_STAT(rx_frames_64
),
79 ENIC_RX_STAT(rx_frames_127
),
80 ENIC_RX_STAT(rx_frames_255
),
81 ENIC_RX_STAT(rx_frames_511
),
82 ENIC_RX_STAT(rx_frames_1023
),
83 ENIC_RX_STAT(rx_frames_1518
),
84 ENIC_RX_STAT(rx_frames_to_max
),
87 static const struct enic_stat enic_gen_stats
[] = {
88 ENIC_GEN_STAT(dma_map_error
),
91 static const unsigned int enic_n_tx_stats
= ARRAY_SIZE(enic_tx_stats
);
92 static const unsigned int enic_n_rx_stats
= ARRAY_SIZE(enic_rx_stats
);
93 static const unsigned int enic_n_gen_stats
= ARRAY_SIZE(enic_gen_stats
);
95 static void enic_intr_coal_set_rx(struct enic
*enic
, u32 timer
)
100 for (i
= 0; i
< enic
->rq_count
; i
++) {
101 intr
= enic_msix_rq_intr(enic
, i
);
102 vnic_intr_coalescing_timer_set(&enic
->intr
[intr
], timer
);
106 static int enic_get_settings(struct net_device
*netdev
,
107 struct ethtool_cmd
*ecmd
)
109 struct enic
*enic
= netdev_priv(netdev
);
111 ecmd
->supported
= (SUPPORTED_10000baseT_Full
| SUPPORTED_FIBRE
);
112 ecmd
->advertising
= (ADVERTISED_10000baseT_Full
| ADVERTISED_FIBRE
);
113 ecmd
->port
= PORT_FIBRE
;
114 ecmd
->transceiver
= XCVR_EXTERNAL
;
116 if (netif_carrier_ok(netdev
)) {
117 ethtool_cmd_speed_set(ecmd
, vnic_dev_port_speed(enic
->vdev
));
118 ecmd
->duplex
= DUPLEX_FULL
;
120 ethtool_cmd_speed_set(ecmd
, SPEED_UNKNOWN
);
121 ecmd
->duplex
= DUPLEX_UNKNOWN
;
124 ecmd
->autoneg
= AUTONEG_DISABLE
;
129 static void enic_get_drvinfo(struct net_device
*netdev
,
130 struct ethtool_drvinfo
*drvinfo
)
132 struct enic
*enic
= netdev_priv(netdev
);
133 struct vnic_devcmd_fw_info
*fw_info
;
135 enic_dev_fw_info(enic
, &fw_info
);
137 strlcpy(drvinfo
->driver
, DRV_NAME
, sizeof(drvinfo
->driver
));
138 strlcpy(drvinfo
->version
, DRV_VERSION
, sizeof(drvinfo
->version
));
139 strlcpy(drvinfo
->fw_version
, fw_info
->fw_version
,
140 sizeof(drvinfo
->fw_version
));
141 strlcpy(drvinfo
->bus_info
, pci_name(enic
->pdev
),
142 sizeof(drvinfo
->bus_info
));
145 static void enic_get_strings(struct net_device
*netdev
, u32 stringset
,
152 for (i
= 0; i
< enic_n_tx_stats
; i
++) {
153 memcpy(data
, enic_tx_stats
[i
].name
, ETH_GSTRING_LEN
);
154 data
+= ETH_GSTRING_LEN
;
156 for (i
= 0; i
< enic_n_rx_stats
; i
++) {
157 memcpy(data
, enic_rx_stats
[i
].name
, ETH_GSTRING_LEN
);
158 data
+= ETH_GSTRING_LEN
;
160 for (i
= 0; i
< enic_n_gen_stats
; i
++) {
161 memcpy(data
, enic_gen_stats
[i
].name
, ETH_GSTRING_LEN
);
162 data
+= ETH_GSTRING_LEN
;
168 static int enic_get_sset_count(struct net_device
*netdev
, int sset
)
172 return enic_n_tx_stats
+ enic_n_rx_stats
+ enic_n_gen_stats
;
178 static void enic_get_ethtool_stats(struct net_device
*netdev
,
179 struct ethtool_stats
*stats
, u64
*data
)
181 struct enic
*enic
= netdev_priv(netdev
);
182 struct vnic_stats
*vstats
;
185 enic_dev_stats_dump(enic
, &vstats
);
187 for (i
= 0; i
< enic_n_tx_stats
; i
++)
188 *(data
++) = ((u64
*)&vstats
->tx
)[enic_tx_stats
[i
].index
];
189 for (i
= 0; i
< enic_n_rx_stats
; i
++)
190 *(data
++) = ((u64
*)&vstats
->rx
)[enic_rx_stats
[i
].index
];
191 for (i
= 0; i
< enic_n_gen_stats
; i
++)
192 *(data
++) = ((u64
*)&enic
->gen_stats
)[enic_gen_stats
[i
].index
];
195 static u32
enic_get_msglevel(struct net_device
*netdev
)
197 struct enic
*enic
= netdev_priv(netdev
);
198 return enic
->msg_enable
;
201 static void enic_set_msglevel(struct net_device
*netdev
, u32 value
)
203 struct enic
*enic
= netdev_priv(netdev
);
204 enic
->msg_enable
= value
;
207 static int enic_get_coalesce(struct net_device
*netdev
,
208 struct ethtool_coalesce
*ecmd
)
210 struct enic
*enic
= netdev_priv(netdev
);
211 struct enic_rx_coal
*rxcoal
= &enic
->rx_coalesce_setting
;
213 ecmd
->tx_coalesce_usecs
= enic
->tx_coalesce_usecs
;
214 ecmd
->rx_coalesce_usecs
= enic
->rx_coalesce_usecs
;
215 if (rxcoal
->use_adaptive_rx_coalesce
)
216 ecmd
->use_adaptive_rx_coalesce
= 1;
217 ecmd
->rx_coalesce_usecs_low
= rxcoal
->small_pkt_range_start
;
218 ecmd
->rx_coalesce_usecs_high
= rxcoal
->range_end
;
223 static int enic_set_coalesce(struct net_device
*netdev
,
224 struct ethtool_coalesce
*ecmd
)
226 struct enic
*enic
= netdev_priv(netdev
);
227 u32 tx_coalesce_usecs
;
228 u32 rx_coalesce_usecs
;
229 u32 rx_coalesce_usecs_low
;
230 u32 rx_coalesce_usecs_high
;
231 u32 coalesce_usecs_max
;
232 unsigned int i
, intr
;
233 struct enic_rx_coal
*rxcoal
= &enic
->rx_coalesce_setting
;
235 coalesce_usecs_max
= vnic_dev_get_intr_coal_timer_max(enic
->vdev
);
236 tx_coalesce_usecs
= min_t(u32
, ecmd
->tx_coalesce_usecs
,
238 rx_coalesce_usecs
= min_t(u32
, ecmd
->rx_coalesce_usecs
,
241 rx_coalesce_usecs_low
= min_t(u32
, ecmd
->rx_coalesce_usecs_low
,
243 rx_coalesce_usecs_high
= min_t(u32
, ecmd
->rx_coalesce_usecs_high
,
246 switch (vnic_dev_get_intr_mode(enic
->vdev
)) {
247 case VNIC_DEV_INTR_MODE_INTX
:
248 if (tx_coalesce_usecs
!= rx_coalesce_usecs
)
250 if (ecmd
->use_adaptive_rx_coalesce
||
251 ecmd
->rx_coalesce_usecs_low
||
252 ecmd
->rx_coalesce_usecs_high
)
255 intr
= enic_legacy_io_intr();
256 vnic_intr_coalescing_timer_set(&enic
->intr
[intr
],
259 case VNIC_DEV_INTR_MODE_MSI
:
260 if (tx_coalesce_usecs
!= rx_coalesce_usecs
)
262 if (ecmd
->use_adaptive_rx_coalesce
||
263 ecmd
->rx_coalesce_usecs_low
||
264 ecmd
->rx_coalesce_usecs_high
)
267 vnic_intr_coalescing_timer_set(&enic
->intr
[0],
270 case VNIC_DEV_INTR_MODE_MSIX
:
271 if (ecmd
->rx_coalesce_usecs_high
&&
272 (rx_coalesce_usecs_high
<
273 rx_coalesce_usecs_low
+ ENIC_AIC_LARGE_PKT_DIFF
))
276 for (i
= 0; i
< enic
->wq_count
; i
++) {
277 intr
= enic_msix_wq_intr(enic
, i
);
278 vnic_intr_coalescing_timer_set(&enic
->intr
[intr
],
282 rxcoal
->use_adaptive_rx_coalesce
=
283 !!ecmd
->use_adaptive_rx_coalesce
;
284 if (!rxcoal
->use_adaptive_rx_coalesce
)
285 enic_intr_coal_set_rx(enic
, rx_coalesce_usecs
);
287 if (ecmd
->rx_coalesce_usecs_high
) {
288 rxcoal
->range_end
= rx_coalesce_usecs_high
;
289 rxcoal
->small_pkt_range_start
= rx_coalesce_usecs_low
;
290 rxcoal
->large_pkt_range_start
= rx_coalesce_usecs_low
+
291 ENIC_AIC_LARGE_PKT_DIFF
;
298 enic
->tx_coalesce_usecs
= tx_coalesce_usecs
;
299 enic
->rx_coalesce_usecs
= rx_coalesce_usecs
;
304 static int enic_grxclsrlall(struct enic
*enic
, struct ethtool_rxnfc
*cmd
,
307 int j
, ret
= 0, cnt
= 0;
309 cmd
->data
= enic
->rfs_h
.max
- enic
->rfs_h
.free
;
310 for (j
= 0; j
< (1 << ENIC_RFS_FLW_BITSHIFT
); j
++) {
311 struct hlist_head
*hhead
;
312 struct hlist_node
*tmp
;
313 struct enic_rfs_fltr_node
*n
;
315 hhead
= &enic
->rfs_h
.ht_head
[j
];
316 hlist_for_each_entry_safe(n
, tmp
, hhead
, node
) {
317 if (cnt
== cmd
->rule_cnt
)
319 rule_locs
[cnt
] = n
->fltr_id
;
328 static int enic_grxclsrule(struct enic
*enic
, struct ethtool_rxnfc
*cmd
)
330 struct ethtool_rx_flow_spec
*fsp
=
331 (struct ethtool_rx_flow_spec
*)&cmd
->fs
;
332 struct enic_rfs_fltr_node
*n
;
334 n
= htbl_fltr_search(enic
, (u16
)fsp
->location
);
337 switch (n
->keys
.basic
.ip_proto
) {
339 fsp
->flow_type
= TCP_V4_FLOW
;
342 fsp
->flow_type
= UDP_V4_FLOW
;
349 fsp
->h_u
.tcp_ip4_spec
.ip4src
= flow_get_u32_src(&n
->keys
);
350 fsp
->m_u
.tcp_ip4_spec
.ip4src
= (__u32
)~0;
352 fsp
->h_u
.tcp_ip4_spec
.ip4dst
= flow_get_u32_dst(&n
->keys
);
353 fsp
->m_u
.tcp_ip4_spec
.ip4dst
= (__u32
)~0;
355 fsp
->h_u
.tcp_ip4_spec
.psrc
= n
->keys
.ports
.src
;
356 fsp
->m_u
.tcp_ip4_spec
.psrc
= (__u16
)~0;
358 fsp
->h_u
.tcp_ip4_spec
.pdst
= n
->keys
.ports
.dst
;
359 fsp
->m_u
.tcp_ip4_spec
.pdst
= (__u16
)~0;
361 fsp
->ring_cookie
= n
->rq_id
;
366 static int enic_get_rxnfc(struct net_device
*dev
, struct ethtool_rxnfc
*cmd
,
369 struct enic
*enic
= netdev_priv(dev
);
373 case ETHTOOL_GRXRINGS
:
374 cmd
->data
= enic
->rq_count
;
376 case ETHTOOL_GRXCLSRLCNT
:
377 spin_lock_bh(&enic
->rfs_h
.lock
);
378 cmd
->rule_cnt
= enic
->rfs_h
.max
- enic
->rfs_h
.free
;
379 cmd
->data
= enic
->rfs_h
.max
;
380 spin_unlock_bh(&enic
->rfs_h
.lock
);
382 case ETHTOOL_GRXCLSRLALL
:
383 spin_lock_bh(&enic
->rfs_h
.lock
);
384 ret
= enic_grxclsrlall(enic
, cmd
, rule_locs
);
385 spin_unlock_bh(&enic
->rfs_h
.lock
);
387 case ETHTOOL_GRXCLSRULE
:
388 spin_lock_bh(&enic
->rfs_h
.lock
);
389 ret
= enic_grxclsrule(enic
, cmd
);
390 spin_unlock_bh(&enic
->rfs_h
.lock
);
400 static int enic_get_tunable(struct net_device
*dev
,
401 const struct ethtool_tunable
*tuna
, void *data
)
403 struct enic
*enic
= netdev_priv(dev
);
407 case ETHTOOL_RX_COPYBREAK
:
408 *(u32
*)data
= enic
->rx_copybreak
;
418 static int enic_set_tunable(struct net_device
*dev
,
419 const struct ethtool_tunable
*tuna
,
422 struct enic
*enic
= netdev_priv(dev
);
426 case ETHTOOL_RX_COPYBREAK
:
427 enic
->rx_copybreak
= *(u32
*)data
;
437 static u32
enic_get_rxfh_key_size(struct net_device
*netdev
)
442 static int enic_get_rxfh(struct net_device
*netdev
, u32
*indir
, u8
*hkey
,
445 struct enic
*enic
= netdev_priv(netdev
);
448 memcpy(hkey
, enic
->rss_key
, ENIC_RSS_LEN
);
451 *hfunc
= ETH_RSS_HASH_TOP
;
456 static int enic_set_rxfh(struct net_device
*netdev
, const u32
*indir
,
457 const u8
*hkey
, const u8 hfunc
)
459 struct enic
*enic
= netdev_priv(netdev
);
461 if ((hfunc
!= ETH_RSS_HASH_NO_CHANGE
&& hfunc
!= ETH_RSS_HASH_TOP
) ||
466 memcpy(enic
->rss_key
, hkey
, ENIC_RSS_LEN
);
468 return __enic_set_rsskey(enic
);
471 static const struct ethtool_ops enic_ethtool_ops
= {
472 .get_settings
= enic_get_settings
,
473 .get_drvinfo
= enic_get_drvinfo
,
474 .get_msglevel
= enic_get_msglevel
,
475 .set_msglevel
= enic_set_msglevel
,
476 .get_link
= ethtool_op_get_link
,
477 .get_strings
= enic_get_strings
,
478 .get_sset_count
= enic_get_sset_count
,
479 .get_ethtool_stats
= enic_get_ethtool_stats
,
480 .get_coalesce
= enic_get_coalesce
,
481 .set_coalesce
= enic_set_coalesce
,
482 .get_rxnfc
= enic_get_rxnfc
,
483 .get_tunable
= enic_get_tunable
,
484 .set_tunable
= enic_set_tunable
,
485 .get_rxfh_key_size
= enic_get_rxfh_key_size
,
486 .get_rxfh
= enic_get_rxfh
,
487 .set_rxfh
= enic_set_rxfh
,
490 void enic_set_ethtool_ops(struct net_device
*netdev
)
492 netdev
->ethtool_ops
= &enic_ethtool_ops
;