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_ksettings(struct net_device
*netdev
,
107 struct ethtool_link_ksettings
*ecmd
)
109 struct enic
*enic
= netdev_priv(netdev
);
110 struct ethtool_link_settings
*base
= &ecmd
->base
;
112 ethtool_link_ksettings_add_link_mode(ecmd
, supported
,
114 ethtool_link_ksettings_add_link_mode(ecmd
, supported
, FIBRE
);
115 ethtool_link_ksettings_add_link_mode(ecmd
, advertising
,
117 ethtool_link_ksettings_add_link_mode(ecmd
, advertising
, FIBRE
);
118 base
->port
= PORT_FIBRE
;
120 if (netif_carrier_ok(netdev
)) {
121 base
->speed
= vnic_dev_port_speed(enic
->vdev
);
122 base
->duplex
= DUPLEX_FULL
;
124 base
->speed
= SPEED_UNKNOWN
;
125 base
->duplex
= DUPLEX_UNKNOWN
;
128 base
->autoneg
= AUTONEG_DISABLE
;
133 static void enic_get_drvinfo(struct net_device
*netdev
,
134 struct ethtool_drvinfo
*drvinfo
)
136 struct enic
*enic
= netdev_priv(netdev
);
137 struct vnic_devcmd_fw_info
*fw_info
;
140 err
= enic_dev_fw_info(enic
, &fw_info
);
141 /* return only when pci_zalloc_consistent fails in vnic_dev_fw_info
142 * For other failures, like devcmd failure, we return previously
148 strlcpy(drvinfo
->driver
, DRV_NAME
, sizeof(drvinfo
->driver
));
149 strlcpy(drvinfo
->version
, DRV_VERSION
, sizeof(drvinfo
->version
));
150 strlcpy(drvinfo
->fw_version
, fw_info
->fw_version
,
151 sizeof(drvinfo
->fw_version
));
152 strlcpy(drvinfo
->bus_info
, pci_name(enic
->pdev
),
153 sizeof(drvinfo
->bus_info
));
156 static void enic_get_strings(struct net_device
*netdev
, u32 stringset
,
163 for (i
= 0; i
< enic_n_tx_stats
; i
++) {
164 memcpy(data
, enic_tx_stats
[i
].name
, ETH_GSTRING_LEN
);
165 data
+= ETH_GSTRING_LEN
;
167 for (i
= 0; i
< enic_n_rx_stats
; i
++) {
168 memcpy(data
, enic_rx_stats
[i
].name
, ETH_GSTRING_LEN
);
169 data
+= ETH_GSTRING_LEN
;
171 for (i
= 0; i
< enic_n_gen_stats
; i
++) {
172 memcpy(data
, enic_gen_stats
[i
].name
, ETH_GSTRING_LEN
);
173 data
+= ETH_GSTRING_LEN
;
179 static int enic_get_sset_count(struct net_device
*netdev
, int sset
)
183 return enic_n_tx_stats
+ enic_n_rx_stats
+ enic_n_gen_stats
;
189 static void enic_get_ethtool_stats(struct net_device
*netdev
,
190 struct ethtool_stats
*stats
, u64
*data
)
192 struct enic
*enic
= netdev_priv(netdev
);
193 struct vnic_stats
*vstats
;
197 err
= enic_dev_stats_dump(enic
, &vstats
);
198 /* return only when pci_zalloc_consistent fails in vnic_dev_stats_dump
199 * For other failures, like devcmd failure, we return previously
205 for (i
= 0; i
< enic_n_tx_stats
; i
++)
206 *(data
++) = ((u64
*)&vstats
->tx
)[enic_tx_stats
[i
].index
];
207 for (i
= 0; i
< enic_n_rx_stats
; i
++)
208 *(data
++) = ((u64
*)&vstats
->rx
)[enic_rx_stats
[i
].index
];
209 for (i
= 0; i
< enic_n_gen_stats
; i
++)
210 *(data
++) = ((u64
*)&enic
->gen_stats
)[enic_gen_stats
[i
].index
];
213 static u32
enic_get_msglevel(struct net_device
*netdev
)
215 struct enic
*enic
= netdev_priv(netdev
);
216 return enic
->msg_enable
;
219 static void enic_set_msglevel(struct net_device
*netdev
, u32 value
)
221 struct enic
*enic
= netdev_priv(netdev
);
222 enic
->msg_enable
= value
;
225 static int enic_get_coalesce(struct net_device
*netdev
,
226 struct ethtool_coalesce
*ecmd
)
228 struct enic
*enic
= netdev_priv(netdev
);
229 struct enic_rx_coal
*rxcoal
= &enic
->rx_coalesce_setting
;
231 if (vnic_dev_get_intr_mode(enic
->vdev
) == VNIC_DEV_INTR_MODE_MSIX
)
232 ecmd
->tx_coalesce_usecs
= enic
->tx_coalesce_usecs
;
233 ecmd
->rx_coalesce_usecs
= enic
->rx_coalesce_usecs
;
234 if (rxcoal
->use_adaptive_rx_coalesce
)
235 ecmd
->use_adaptive_rx_coalesce
= 1;
236 ecmd
->rx_coalesce_usecs_low
= rxcoal
->small_pkt_range_start
;
237 ecmd
->rx_coalesce_usecs_high
= rxcoal
->range_end
;
242 static int enic_coalesce_valid(struct enic
*enic
,
243 struct ethtool_coalesce
*ec
)
245 u32 coalesce_usecs_max
= vnic_dev_get_intr_coal_timer_max(enic
->vdev
);
246 u32 rx_coalesce_usecs_high
= min_t(u32
, coalesce_usecs_max
,
247 ec
->rx_coalesce_usecs_high
);
248 u32 rx_coalesce_usecs_low
= min_t(u32
, coalesce_usecs_max
,
249 ec
->rx_coalesce_usecs_low
);
251 if (ec
->rx_max_coalesced_frames
||
252 ec
->rx_coalesce_usecs_irq
||
253 ec
->rx_max_coalesced_frames_irq
||
254 ec
->tx_max_coalesced_frames
||
255 ec
->tx_coalesce_usecs_irq
||
256 ec
->tx_max_coalesced_frames_irq
||
257 ec
->stats_block_coalesce_usecs
||
258 ec
->use_adaptive_tx_coalesce
||
260 ec
->rx_max_coalesced_frames_low
||
261 ec
->tx_coalesce_usecs_low
||
262 ec
->tx_max_coalesced_frames_low
||
264 ec
->rx_max_coalesced_frames_high
||
265 ec
->tx_coalesce_usecs_high
||
266 ec
->tx_max_coalesced_frames_high
||
267 ec
->rate_sample_interval
)
270 if ((vnic_dev_get_intr_mode(enic
->vdev
) != VNIC_DEV_INTR_MODE_MSIX
) &&
271 ec
->tx_coalesce_usecs
)
274 if ((ec
->tx_coalesce_usecs
> coalesce_usecs_max
) ||
275 (ec
->rx_coalesce_usecs
> coalesce_usecs_max
) ||
276 (ec
->rx_coalesce_usecs_low
> coalesce_usecs_max
) ||
277 (ec
->rx_coalesce_usecs_high
> coalesce_usecs_max
))
278 netdev_info(enic
->netdev
, "ethtool_set_coalesce: adaptor supports max coalesce value of %d. Setting max value.\n",
281 if (ec
->rx_coalesce_usecs_high
&&
282 (rx_coalesce_usecs_high
<
283 rx_coalesce_usecs_low
+ ENIC_AIC_LARGE_PKT_DIFF
))
289 static int enic_set_coalesce(struct net_device
*netdev
,
290 struct ethtool_coalesce
*ecmd
)
292 struct enic
*enic
= netdev_priv(netdev
);
293 u32 tx_coalesce_usecs
;
294 u32 rx_coalesce_usecs
;
295 u32 rx_coalesce_usecs_low
;
296 u32 rx_coalesce_usecs_high
;
297 u32 coalesce_usecs_max
;
298 unsigned int i
, intr
;
300 struct enic_rx_coal
*rxcoal
= &enic
->rx_coalesce_setting
;
302 ret
= enic_coalesce_valid(enic
, ecmd
);
305 coalesce_usecs_max
= vnic_dev_get_intr_coal_timer_max(enic
->vdev
);
306 tx_coalesce_usecs
= min_t(u32
, ecmd
->tx_coalesce_usecs
,
308 rx_coalesce_usecs
= min_t(u32
, ecmd
->rx_coalesce_usecs
,
311 rx_coalesce_usecs_low
= min_t(u32
, ecmd
->rx_coalesce_usecs_low
,
313 rx_coalesce_usecs_high
= min_t(u32
, ecmd
->rx_coalesce_usecs_high
,
316 if (vnic_dev_get_intr_mode(enic
->vdev
) == VNIC_DEV_INTR_MODE_MSIX
) {
317 for (i
= 0; i
< enic
->wq_count
; i
++) {
318 intr
= enic_msix_wq_intr(enic
, i
);
319 vnic_intr_coalescing_timer_set(&enic
->intr
[intr
],
322 enic
->tx_coalesce_usecs
= tx_coalesce_usecs
;
324 rxcoal
->use_adaptive_rx_coalesce
= !!ecmd
->use_adaptive_rx_coalesce
;
325 if (!rxcoal
->use_adaptive_rx_coalesce
)
326 enic_intr_coal_set_rx(enic
, rx_coalesce_usecs
);
327 if (ecmd
->rx_coalesce_usecs_high
) {
328 rxcoal
->range_end
= rx_coalesce_usecs_high
;
329 rxcoal
->small_pkt_range_start
= rx_coalesce_usecs_low
;
330 rxcoal
->large_pkt_range_start
= rx_coalesce_usecs_low
+
331 ENIC_AIC_LARGE_PKT_DIFF
;
334 enic
->rx_coalesce_usecs
= rx_coalesce_usecs
;
339 static int enic_grxclsrlall(struct enic
*enic
, struct ethtool_rxnfc
*cmd
,
342 int j
, ret
= 0, cnt
= 0;
344 cmd
->data
= enic
->rfs_h
.max
- enic
->rfs_h
.free
;
345 for (j
= 0; j
< (1 << ENIC_RFS_FLW_BITSHIFT
); j
++) {
346 struct hlist_head
*hhead
;
347 struct hlist_node
*tmp
;
348 struct enic_rfs_fltr_node
*n
;
350 hhead
= &enic
->rfs_h
.ht_head
[j
];
351 hlist_for_each_entry_safe(n
, tmp
, hhead
, node
) {
352 if (cnt
== cmd
->rule_cnt
)
354 rule_locs
[cnt
] = n
->fltr_id
;
363 static int enic_grxclsrule(struct enic
*enic
, struct ethtool_rxnfc
*cmd
)
365 struct ethtool_rx_flow_spec
*fsp
=
366 (struct ethtool_rx_flow_spec
*)&cmd
->fs
;
367 struct enic_rfs_fltr_node
*n
;
369 n
= htbl_fltr_search(enic
, (u16
)fsp
->location
);
372 switch (n
->keys
.basic
.ip_proto
) {
374 fsp
->flow_type
= TCP_V4_FLOW
;
377 fsp
->flow_type
= UDP_V4_FLOW
;
384 fsp
->h_u
.tcp_ip4_spec
.ip4src
= flow_get_u32_src(&n
->keys
);
385 fsp
->m_u
.tcp_ip4_spec
.ip4src
= (__u32
)~0;
387 fsp
->h_u
.tcp_ip4_spec
.ip4dst
= flow_get_u32_dst(&n
->keys
);
388 fsp
->m_u
.tcp_ip4_spec
.ip4dst
= (__u32
)~0;
390 fsp
->h_u
.tcp_ip4_spec
.psrc
= n
->keys
.ports
.src
;
391 fsp
->m_u
.tcp_ip4_spec
.psrc
= (__u16
)~0;
393 fsp
->h_u
.tcp_ip4_spec
.pdst
= n
->keys
.ports
.dst
;
394 fsp
->m_u
.tcp_ip4_spec
.pdst
= (__u16
)~0;
396 fsp
->ring_cookie
= n
->rq_id
;
401 static int enic_get_rxnfc(struct net_device
*dev
, struct ethtool_rxnfc
*cmd
,
404 struct enic
*enic
= netdev_priv(dev
);
408 case ETHTOOL_GRXRINGS
:
409 cmd
->data
= enic
->rq_count
;
411 case ETHTOOL_GRXCLSRLCNT
:
412 spin_lock_bh(&enic
->rfs_h
.lock
);
413 cmd
->rule_cnt
= enic
->rfs_h
.max
- enic
->rfs_h
.free
;
414 cmd
->data
= enic
->rfs_h
.max
;
415 spin_unlock_bh(&enic
->rfs_h
.lock
);
417 case ETHTOOL_GRXCLSRLALL
:
418 spin_lock_bh(&enic
->rfs_h
.lock
);
419 ret
= enic_grxclsrlall(enic
, cmd
, rule_locs
);
420 spin_unlock_bh(&enic
->rfs_h
.lock
);
422 case ETHTOOL_GRXCLSRULE
:
423 spin_lock_bh(&enic
->rfs_h
.lock
);
424 ret
= enic_grxclsrule(enic
, cmd
);
425 spin_unlock_bh(&enic
->rfs_h
.lock
);
435 static int enic_get_tunable(struct net_device
*dev
,
436 const struct ethtool_tunable
*tuna
, void *data
)
438 struct enic
*enic
= netdev_priv(dev
);
442 case ETHTOOL_RX_COPYBREAK
:
443 *(u32
*)data
= enic
->rx_copybreak
;
453 static int enic_set_tunable(struct net_device
*dev
,
454 const struct ethtool_tunable
*tuna
,
457 struct enic
*enic
= netdev_priv(dev
);
461 case ETHTOOL_RX_COPYBREAK
:
462 enic
->rx_copybreak
= *(u32
*)data
;
472 static u32
enic_get_rxfh_key_size(struct net_device
*netdev
)
477 static int enic_get_rxfh(struct net_device
*netdev
, u32
*indir
, u8
*hkey
,
480 struct enic
*enic
= netdev_priv(netdev
);
483 memcpy(hkey
, enic
->rss_key
, ENIC_RSS_LEN
);
486 *hfunc
= ETH_RSS_HASH_TOP
;
491 static int enic_set_rxfh(struct net_device
*netdev
, const u32
*indir
,
492 const u8
*hkey
, const u8 hfunc
)
494 struct enic
*enic
= netdev_priv(netdev
);
496 if ((hfunc
!= ETH_RSS_HASH_NO_CHANGE
&& hfunc
!= ETH_RSS_HASH_TOP
) ||
501 memcpy(enic
->rss_key
, hkey
, ENIC_RSS_LEN
);
503 return __enic_set_rsskey(enic
);
506 static const struct ethtool_ops enic_ethtool_ops
= {
507 .get_drvinfo
= enic_get_drvinfo
,
508 .get_msglevel
= enic_get_msglevel
,
509 .set_msglevel
= enic_set_msglevel
,
510 .get_link
= ethtool_op_get_link
,
511 .get_strings
= enic_get_strings
,
512 .get_sset_count
= enic_get_sset_count
,
513 .get_ethtool_stats
= enic_get_ethtool_stats
,
514 .get_coalesce
= enic_get_coalesce
,
515 .set_coalesce
= enic_set_coalesce
,
516 .get_rxnfc
= enic_get_rxnfc
,
517 .get_tunable
= enic_get_tunable
,
518 .set_tunable
= enic_set_tunable
,
519 .get_rxfh_key_size
= enic_get_rxfh_key_size
,
520 .get_rxfh
= enic_get_rxfh
,
521 .set_rxfh
= enic_set_rxfh
,
522 .get_link_ksettings
= enic_get_ksettings
,
525 void enic_set_ethtool_ops(struct net_device
*netdev
)
527 netdev
->ethtool_ops
= &enic_ethtool_ops
;