1 /****************************************************************************
2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2005-2006 Fen Systems Ltd.
4 * Copyright 2006-2008 Solarflare Communications Inc.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation, incorporated herein by reference.
11 #include <linux/netdevice.h>
12 #include <linux/ethtool.h>
13 #include <linux/rtnetlink.h>
14 #include "net_driver.h"
21 static int efx_ethtool_set_tx_csum(struct net_device
*net_dev
, u32 enable
);
23 struct ethtool_string
{
24 char name
[ETH_GSTRING_LEN
];
27 struct efx_ethtool_stat
{
30 EFX_ETHTOOL_STAT_SOURCE_mac_stats
,
31 EFX_ETHTOOL_STAT_SOURCE_nic
,
32 EFX_ETHTOOL_STAT_SOURCE_channel
35 u64(*get_stat
) (void *field
); /* Reader function */
38 /* Initialiser for a struct #efx_ethtool_stat with type-checking */
39 #define EFX_ETHTOOL_STAT(stat_name, source_name, field, field_type, \
40 get_stat_function) { \
42 .source = EFX_ETHTOOL_STAT_SOURCE_##source_name, \
43 .offset = ((((field_type *) 0) == \
44 &((struct efx_##source_name *)0)->field) ? \
45 offsetof(struct efx_##source_name, field) : \
46 offsetof(struct efx_##source_name, field)), \
47 .get_stat = get_stat_function, \
50 static u64
efx_get_uint_stat(void *field
)
52 return *(unsigned int *)field
;
55 static u64
efx_get_ulong_stat(void *field
)
57 return *(unsigned long *)field
;
60 static u64
efx_get_u64_stat(void *field
)
62 return *(u64
*) field
;
65 static u64
efx_get_atomic_stat(void *field
)
67 return atomic_read((atomic_t
*) field
);
70 #define EFX_ETHTOOL_ULONG_MAC_STAT(field) \
71 EFX_ETHTOOL_STAT(field, mac_stats, field, \
72 unsigned long, efx_get_ulong_stat)
74 #define EFX_ETHTOOL_U64_MAC_STAT(field) \
75 EFX_ETHTOOL_STAT(field, mac_stats, field, \
76 u64, efx_get_u64_stat)
78 #define EFX_ETHTOOL_UINT_NIC_STAT(name) \
79 EFX_ETHTOOL_STAT(name, nic, n_##name, \
80 unsigned int, efx_get_uint_stat)
82 #define EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(field) \
83 EFX_ETHTOOL_STAT(field, nic, field, \
84 atomic_t, efx_get_atomic_stat)
86 #define EFX_ETHTOOL_UINT_CHANNEL_STAT(field) \
87 EFX_ETHTOOL_STAT(field, channel, n_##field, \
88 unsigned int, efx_get_uint_stat)
90 static struct efx_ethtool_stat efx_ethtool_stats
[] = {
91 EFX_ETHTOOL_U64_MAC_STAT(tx_bytes
),
92 EFX_ETHTOOL_U64_MAC_STAT(tx_good_bytes
),
93 EFX_ETHTOOL_U64_MAC_STAT(tx_bad_bytes
),
94 EFX_ETHTOOL_ULONG_MAC_STAT(tx_packets
),
95 EFX_ETHTOOL_ULONG_MAC_STAT(tx_bad
),
96 EFX_ETHTOOL_ULONG_MAC_STAT(tx_pause
),
97 EFX_ETHTOOL_ULONG_MAC_STAT(tx_control
),
98 EFX_ETHTOOL_ULONG_MAC_STAT(tx_unicast
),
99 EFX_ETHTOOL_ULONG_MAC_STAT(tx_multicast
),
100 EFX_ETHTOOL_ULONG_MAC_STAT(tx_broadcast
),
101 EFX_ETHTOOL_ULONG_MAC_STAT(tx_lt64
),
102 EFX_ETHTOOL_ULONG_MAC_STAT(tx_64
),
103 EFX_ETHTOOL_ULONG_MAC_STAT(tx_65_to_127
),
104 EFX_ETHTOOL_ULONG_MAC_STAT(tx_128_to_255
),
105 EFX_ETHTOOL_ULONG_MAC_STAT(tx_256_to_511
),
106 EFX_ETHTOOL_ULONG_MAC_STAT(tx_512_to_1023
),
107 EFX_ETHTOOL_ULONG_MAC_STAT(tx_1024_to_15xx
),
108 EFX_ETHTOOL_ULONG_MAC_STAT(tx_15xx_to_jumbo
),
109 EFX_ETHTOOL_ULONG_MAC_STAT(tx_gtjumbo
),
110 EFX_ETHTOOL_ULONG_MAC_STAT(tx_collision
),
111 EFX_ETHTOOL_ULONG_MAC_STAT(tx_single_collision
),
112 EFX_ETHTOOL_ULONG_MAC_STAT(tx_multiple_collision
),
113 EFX_ETHTOOL_ULONG_MAC_STAT(tx_excessive_collision
),
114 EFX_ETHTOOL_ULONG_MAC_STAT(tx_deferred
),
115 EFX_ETHTOOL_ULONG_MAC_STAT(tx_late_collision
),
116 EFX_ETHTOOL_ULONG_MAC_STAT(tx_excessive_deferred
),
117 EFX_ETHTOOL_ULONG_MAC_STAT(tx_non_tcpudp
),
118 EFX_ETHTOOL_ULONG_MAC_STAT(tx_mac_src_error
),
119 EFX_ETHTOOL_ULONG_MAC_STAT(tx_ip_src_error
),
120 EFX_ETHTOOL_U64_MAC_STAT(rx_bytes
),
121 EFX_ETHTOOL_U64_MAC_STAT(rx_good_bytes
),
122 EFX_ETHTOOL_U64_MAC_STAT(rx_bad_bytes
),
123 EFX_ETHTOOL_ULONG_MAC_STAT(rx_packets
),
124 EFX_ETHTOOL_ULONG_MAC_STAT(rx_good
),
125 EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad
),
126 EFX_ETHTOOL_ULONG_MAC_STAT(rx_pause
),
127 EFX_ETHTOOL_ULONG_MAC_STAT(rx_control
),
128 EFX_ETHTOOL_ULONG_MAC_STAT(rx_unicast
),
129 EFX_ETHTOOL_ULONG_MAC_STAT(rx_multicast
),
130 EFX_ETHTOOL_ULONG_MAC_STAT(rx_broadcast
),
131 EFX_ETHTOOL_ULONG_MAC_STAT(rx_lt64
),
132 EFX_ETHTOOL_ULONG_MAC_STAT(rx_64
),
133 EFX_ETHTOOL_ULONG_MAC_STAT(rx_65_to_127
),
134 EFX_ETHTOOL_ULONG_MAC_STAT(rx_128_to_255
),
135 EFX_ETHTOOL_ULONG_MAC_STAT(rx_256_to_511
),
136 EFX_ETHTOOL_ULONG_MAC_STAT(rx_512_to_1023
),
137 EFX_ETHTOOL_ULONG_MAC_STAT(rx_1024_to_15xx
),
138 EFX_ETHTOOL_ULONG_MAC_STAT(rx_15xx_to_jumbo
),
139 EFX_ETHTOOL_ULONG_MAC_STAT(rx_gtjumbo
),
140 EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_lt64
),
141 EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_64_to_15xx
),
142 EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_15xx_to_jumbo
),
143 EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_gtjumbo
),
144 EFX_ETHTOOL_ULONG_MAC_STAT(rx_overflow
),
145 EFX_ETHTOOL_ULONG_MAC_STAT(rx_missed
),
146 EFX_ETHTOOL_ULONG_MAC_STAT(rx_false_carrier
),
147 EFX_ETHTOOL_ULONG_MAC_STAT(rx_symbol_error
),
148 EFX_ETHTOOL_ULONG_MAC_STAT(rx_align_error
),
149 EFX_ETHTOOL_ULONG_MAC_STAT(rx_length_error
),
150 EFX_ETHTOOL_ULONG_MAC_STAT(rx_internal_error
),
151 EFX_ETHTOOL_UINT_NIC_STAT(rx_nodesc_drop_cnt
),
152 EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(rx_reset
),
153 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tobe_disc
),
154 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_ip_hdr_chksum_err
),
155 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tcp_udp_chksum_err
),
156 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_frm_trunc
),
159 /* Number of ethtool statistics */
160 #define EFX_ETHTOOL_NUM_STATS ARRAY_SIZE(efx_ethtool_stats)
162 /**************************************************************************
166 **************************************************************************
169 /* Identify device by flashing LEDs */
170 static int efx_ethtool_phys_id(struct net_device
*net_dev
, u32 seconds
)
172 struct efx_nic
*efx
= net_dev
->priv
;
174 efx
->board_info
.blink(efx
, 1);
175 schedule_timeout_interruptible(seconds
* HZ
);
176 efx
->board_info
.blink(efx
, 0);
180 /* This must be called with rtnl_lock held. */
181 int efx_ethtool_get_settings(struct net_device
*net_dev
,
182 struct ethtool_cmd
*ecmd
)
184 struct efx_nic
*efx
= net_dev
->priv
;
187 mutex_lock(&efx
->mac_lock
);
188 rc
= falcon_xmac_get_settings(efx
, ecmd
);
189 mutex_unlock(&efx
->mac_lock
);
194 /* This must be called with rtnl_lock held. */
195 int efx_ethtool_set_settings(struct net_device
*net_dev
,
196 struct ethtool_cmd
*ecmd
)
198 struct efx_nic
*efx
= net_dev
->priv
;
201 mutex_lock(&efx
->mac_lock
);
202 rc
= falcon_xmac_set_settings(efx
, ecmd
);
203 mutex_unlock(&efx
->mac_lock
);
205 efx_reconfigure_port(efx
);
210 static void efx_ethtool_get_drvinfo(struct net_device
*net_dev
,
211 struct ethtool_drvinfo
*info
)
213 struct efx_nic
*efx
= net_dev
->priv
;
215 strlcpy(info
->driver
, EFX_DRIVER_NAME
, sizeof(info
->driver
));
216 strlcpy(info
->version
, EFX_DRIVER_VERSION
, sizeof(info
->version
));
217 strlcpy(info
->bus_info
, pci_name(efx
->pci_dev
), sizeof(info
->bus_info
));
220 static int efx_ethtool_get_stats_count(struct net_device
*net_dev
)
222 return EFX_ETHTOOL_NUM_STATS
;
225 static void efx_ethtool_get_strings(struct net_device
*net_dev
,
226 u32 string_set
, u8
*strings
)
228 struct ethtool_string
*ethtool_strings
=
229 (struct ethtool_string
*)strings
;
232 if (string_set
== ETH_SS_STATS
)
233 for (i
= 0; i
< EFX_ETHTOOL_NUM_STATS
; i
++)
234 strncpy(ethtool_strings
[i
].name
,
235 efx_ethtool_stats
[i
].name
,
236 sizeof(ethtool_strings
[i
].name
));
239 static void efx_ethtool_get_stats(struct net_device
*net_dev
,
240 struct ethtool_stats
*stats
,
243 struct efx_nic
*efx
= net_dev
->priv
;
244 struct efx_mac_stats
*mac_stats
= &efx
->mac_stats
;
245 struct efx_ethtool_stat
*stat
;
246 struct efx_channel
*channel
;
249 EFX_BUG_ON_PARANOID(stats
->n_stats
!= EFX_ETHTOOL_NUM_STATS
);
251 /* Update MAC and NIC statistics */
252 net_dev
->get_stats(net_dev
);
254 /* Fill detailed statistics buffer */
255 for (i
= 0; i
< EFX_ETHTOOL_NUM_STATS
; i
++) {
256 stat
= &efx_ethtool_stats
[i
];
257 switch (stat
->source
) {
258 case EFX_ETHTOOL_STAT_SOURCE_mac_stats
:
259 data
[i
] = stat
->get_stat((void *)mac_stats
+
262 case EFX_ETHTOOL_STAT_SOURCE_nic
:
263 data
[i
] = stat
->get_stat((void *)efx
+ stat
->offset
);
265 case EFX_ETHTOOL_STAT_SOURCE_channel
:
267 efx_for_each_channel(channel
, efx
)
268 data
[i
] += stat
->get_stat((void *)channel
+
275 static int efx_ethtool_set_tx_csum(struct net_device
*net_dev
, u32 enable
)
277 struct efx_nic
*efx
= net_dev
->priv
;
280 rc
= ethtool_op_set_tx_csum(net_dev
, enable
);
284 efx_flush_queues(efx
);
289 static int efx_ethtool_set_rx_csum(struct net_device
*net_dev
, u32 enable
)
291 struct efx_nic
*efx
= net_dev
->priv
;
293 /* No way to stop the hardware doing the checks; we just
296 efx
->rx_checksum_enabled
= (enable
? 1 : 0);
301 static u32
efx_ethtool_get_rx_csum(struct net_device
*net_dev
)
303 struct efx_nic
*efx
= net_dev
->priv
;
305 return efx
->rx_checksum_enabled
;
308 /* Restart autonegotiation */
309 static int efx_ethtool_nway_reset(struct net_device
*net_dev
)
311 struct efx_nic
*efx
= net_dev
->priv
;
313 return mii_nway_restart(&efx
->mii
);
316 static u32
efx_ethtool_get_link(struct net_device
*net_dev
)
318 struct efx_nic
*efx
= net_dev
->priv
;
323 static int efx_ethtool_get_coalesce(struct net_device
*net_dev
,
324 struct ethtool_coalesce
*coalesce
)
326 struct efx_nic
*efx
= net_dev
->priv
;
327 struct efx_tx_queue
*tx_queue
;
328 struct efx_rx_queue
*rx_queue
;
329 struct efx_channel
*channel
;
331 memset(coalesce
, 0, sizeof(*coalesce
));
333 /* Find lowest IRQ moderation across all used TX queues */
334 coalesce
->tx_coalesce_usecs_irq
= ~((u32
) 0);
335 efx_for_each_tx_queue(tx_queue
, efx
) {
336 channel
= tx_queue
->channel
;
337 if (channel
->irq_moderation
< coalesce
->tx_coalesce_usecs_irq
) {
338 if (channel
->used_flags
!= EFX_USED_BY_RX_TX
)
339 coalesce
->tx_coalesce_usecs_irq
=
340 channel
->irq_moderation
;
342 coalesce
->tx_coalesce_usecs_irq
= 0;
346 /* Find lowest IRQ moderation across all used RX queues */
347 coalesce
->rx_coalesce_usecs_irq
= ~((u32
) 0);
348 efx_for_each_rx_queue(rx_queue
, efx
) {
349 channel
= rx_queue
->channel
;
350 if (channel
->irq_moderation
< coalesce
->rx_coalesce_usecs_irq
)
351 coalesce
->rx_coalesce_usecs_irq
=
352 channel
->irq_moderation
;
358 /* Set coalescing parameters
359 * The difficulties occur for shared channels
361 static int efx_ethtool_set_coalesce(struct net_device
*net_dev
,
362 struct ethtool_coalesce
*coalesce
)
364 struct efx_nic
*efx
= net_dev
->priv
;
365 struct efx_channel
*channel
;
366 struct efx_tx_queue
*tx_queue
;
367 unsigned tx_usecs
, rx_usecs
;
369 if (coalesce
->use_adaptive_rx_coalesce
||
370 coalesce
->use_adaptive_tx_coalesce
)
373 if (coalesce
->rx_coalesce_usecs
|| coalesce
->tx_coalesce_usecs
) {
374 EFX_ERR(efx
, "invalid coalescing setting. "
375 "Only rx/tx_coalesce_usecs_irq are supported\n");
379 rx_usecs
= coalesce
->rx_coalesce_usecs_irq
;
380 tx_usecs
= coalesce
->tx_coalesce_usecs_irq
;
382 /* If the channel is shared only allow RX parameters to be set */
383 efx_for_each_tx_queue(tx_queue
, efx
) {
384 if ((tx_queue
->channel
->used_flags
== EFX_USED_BY_RX_TX
) &&
386 EFX_ERR(efx
, "Channel is shared. "
387 "Only RX coalescing may be set\n");
392 efx_init_irq_moderation(efx
, tx_usecs
, rx_usecs
);
394 /* Reset channel to pick up new moderation value. Note that
395 * this may change the value of the irq_moderation field
396 * (e.g. to allow for hardware timer granularity).
398 efx_for_each_channel(channel
, efx
)
399 falcon_set_int_moderation(channel
);
404 static int efx_ethtool_set_pauseparam(struct net_device
*net_dev
,
405 struct ethtool_pauseparam
*pause
)
407 struct efx_nic
*efx
= net_dev
->priv
;
408 enum efx_fc_type flow_control
= efx
->flow_control
;
411 flow_control
&= ~(EFX_FC_RX
| EFX_FC_TX
| EFX_FC_AUTO
);
412 flow_control
|= pause
->rx_pause
? EFX_FC_RX
: 0;
413 flow_control
|= pause
->tx_pause
? EFX_FC_TX
: 0;
414 flow_control
|= pause
->autoneg
? EFX_FC_AUTO
: 0;
416 /* Try to push the pause parameters */
417 mutex_lock(&efx
->mac_lock
);
418 rc
= falcon_xmac_set_pause(efx
, flow_control
);
419 mutex_unlock(&efx
->mac_lock
);
422 efx_reconfigure_port(efx
);
427 static void efx_ethtool_get_pauseparam(struct net_device
*net_dev
,
428 struct ethtool_pauseparam
*pause
)
430 struct efx_nic
*efx
= net_dev
->priv
;
432 pause
->rx_pause
= (efx
->flow_control
& EFX_FC_RX
) ? 1 : 0;
433 pause
->tx_pause
= (efx
->flow_control
& EFX_FC_TX
) ? 1 : 0;
434 pause
->autoneg
= (efx
->flow_control
& EFX_FC_AUTO
) ? 1 : 0;
438 struct ethtool_ops efx_ethtool_ops
= {
439 .get_settings
= efx_ethtool_get_settings
,
440 .set_settings
= efx_ethtool_set_settings
,
441 .get_drvinfo
= efx_ethtool_get_drvinfo
,
442 .nway_reset
= efx_ethtool_nway_reset
,
443 .get_link
= efx_ethtool_get_link
,
444 .get_coalesce
= efx_ethtool_get_coalesce
,
445 .set_coalesce
= efx_ethtool_set_coalesce
,
446 .get_pauseparam
= efx_ethtool_get_pauseparam
,
447 .set_pauseparam
= efx_ethtool_set_pauseparam
,
448 .get_rx_csum
= efx_ethtool_get_rx_csum
,
449 .set_rx_csum
= efx_ethtool_set_rx_csum
,
450 .get_tx_csum
= ethtool_op_get_tx_csum
,
451 .set_tx_csum
= efx_ethtool_set_tx_csum
,
452 .get_sg
= ethtool_op_get_sg
,
453 .set_sg
= ethtool_op_set_sg
,
454 .get_flags
= ethtool_op_get_flags
,
455 .set_flags
= ethtool_op_set_flags
,
456 .get_strings
= efx_ethtool_get_strings
,
457 .phys_id
= efx_ethtool_phys_id
,
458 .get_stats_count
= efx_ethtool_get_stats_count
,
459 .get_ethtool_stats
= efx_ethtool_get_stats
,