diff options
author | Scott Feldman <scofeldm@cisco.com> | 2009-12-23 08:27:54 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-12-24 00:03:41 -0500 |
commit | 7c8445991172cc17eaca9f7de0a300c02caaa49d (patch) | |
tree | 0518a514d0d3e5af0d6442a2ef72aa10bbce58ae /drivers/net/enic/enic_main.c | |
parent | bd2496229e702b2eb50eab5589858a3cdb7847b2 (diff) |
enic: feature add: add ethtool -c/C support
Only rx_usec and tx_usec options for ethtool -C are settable as those
are the only settings that make sense to HW. Adds driver reporting of
intr coalescing timer value in usec units rather than HW units.
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/enic/enic_main.c')
-rw-r--r-- | drivers/net/enic/enic_main.c | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 019b1480cc0c..e56f41672b37 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c | |||
@@ -261,6 +261,62 @@ static void enic_set_msglevel(struct net_device *netdev, u32 value) | |||
261 | enic->msg_enable = value; | 261 | enic->msg_enable = value; |
262 | } | 262 | } |
263 | 263 | ||
264 | static int enic_get_coalesce(struct net_device *netdev, | ||
265 | struct ethtool_coalesce *ecmd) | ||
266 | { | ||
267 | struct enic *enic = netdev_priv(netdev); | ||
268 | |||
269 | ecmd->tx_coalesce_usecs = enic->tx_coalesce_usecs; | ||
270 | ecmd->rx_coalesce_usecs = enic->rx_coalesce_usecs; | ||
271 | |||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | static int enic_set_coalesce(struct net_device *netdev, | ||
276 | struct ethtool_coalesce *ecmd) | ||
277 | { | ||
278 | struct enic *enic = netdev_priv(netdev); | ||
279 | u32 tx_coalesce_usecs; | ||
280 | u32 rx_coalesce_usecs; | ||
281 | |||
282 | tx_coalesce_usecs = min_t(u32, | ||
283 | INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX), | ||
284 | ecmd->tx_coalesce_usecs); | ||
285 | rx_coalesce_usecs = min_t(u32, | ||
286 | INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX), | ||
287 | ecmd->rx_coalesce_usecs); | ||
288 | |||
289 | switch (vnic_dev_get_intr_mode(enic->vdev)) { | ||
290 | case VNIC_DEV_INTR_MODE_INTX: | ||
291 | if (tx_coalesce_usecs != rx_coalesce_usecs) | ||
292 | return -EINVAL; | ||
293 | |||
294 | vnic_intr_coalescing_timer_set(&enic->intr[ENIC_INTX_WQ_RQ], | ||
295 | INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs)); | ||
296 | break; | ||
297 | case VNIC_DEV_INTR_MODE_MSI: | ||
298 | if (tx_coalesce_usecs != rx_coalesce_usecs) | ||
299 | return -EINVAL; | ||
300 | |||
301 | vnic_intr_coalescing_timer_set(&enic->intr[0], | ||
302 | INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs)); | ||
303 | break; | ||
304 | case VNIC_DEV_INTR_MODE_MSIX: | ||
305 | vnic_intr_coalescing_timer_set(&enic->intr[ENIC_MSIX_WQ], | ||
306 | INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs)); | ||
307 | vnic_intr_coalescing_timer_set(&enic->intr[ENIC_MSIX_RQ], | ||
308 | INTR_COALESCE_USEC_TO_HW(rx_coalesce_usecs)); | ||
309 | break; | ||
310 | default: | ||
311 | break; | ||
312 | } | ||
313 | |||
314 | enic->tx_coalesce_usecs = tx_coalesce_usecs; | ||
315 | enic->rx_coalesce_usecs = rx_coalesce_usecs; | ||
316 | |||
317 | return 0; | ||
318 | } | ||
319 | |||
264 | static const struct ethtool_ops enic_ethtool_ops = { | 320 | static const struct ethtool_ops enic_ethtool_ops = { |
265 | .get_settings = enic_get_settings, | 321 | .get_settings = enic_get_settings, |
266 | .get_drvinfo = enic_get_drvinfo, | 322 | .get_drvinfo = enic_get_drvinfo, |
@@ -278,6 +334,8 @@ static const struct ethtool_ops enic_ethtool_ops = { | |||
278 | .set_sg = ethtool_op_set_sg, | 334 | .set_sg = ethtool_op_set_sg, |
279 | .get_tso = ethtool_op_get_tso, | 335 | .get_tso = ethtool_op_get_tso, |
280 | .set_tso = enic_set_tso, | 336 | .set_tso = enic_set_tso, |
337 | .get_coalesce = enic_get_coalesce, | ||
338 | .set_coalesce = enic_set_coalesce, | ||
281 | .get_flags = ethtool_op_get_flags, | 339 | .get_flags = ethtool_op_get_flags, |
282 | .set_flags = ethtool_op_set_flags, | 340 | .set_flags = ethtool_op_set_flags, |
283 | }; | 341 | }; |
@@ -363,12 +421,12 @@ static void enic_mtu_check(struct enic *enic) | |||
363 | u32 mtu = vnic_dev_mtu(enic->vdev); | 421 | u32 mtu = vnic_dev_mtu(enic->vdev); |
364 | 422 | ||
365 | if (mtu && mtu != enic->port_mtu) { | 423 | if (mtu && mtu != enic->port_mtu) { |
424 | enic->port_mtu = mtu; | ||
366 | if (mtu < enic->netdev->mtu) | 425 | if (mtu < enic->netdev->mtu) |
367 | printk(KERN_WARNING PFX | 426 | printk(KERN_WARNING PFX |
368 | "%s: interface MTU (%d) set higher " | 427 | "%s: interface MTU (%d) set higher " |
369 | "than switch port MTU (%d)\n", | 428 | "than switch port MTU (%d)\n", |
370 | enic->netdev->name, enic->netdev->mtu, mtu); | 429 | enic->netdev->name, enic->netdev->mtu, mtu); |
371 | enic->port_mtu = mtu; | ||
372 | } | 430 | } |
373 | } | 431 | } |
374 | 432 | ||
@@ -1990,6 +2048,9 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
1990 | goto err_out_dev_deinit; | 2048 | goto err_out_dev_deinit; |
1991 | } | 2049 | } |
1992 | 2050 | ||
2051 | enic->tx_coalesce_usecs = enic->config.intr_timer_usec; | ||
2052 | enic->rx_coalesce_usecs = enic->tx_coalesce_usecs; | ||
2053 | |||
1993 | netdev->netdev_ops = &enic_netdev_ops; | 2054 | netdev->netdev_ops = &enic_netdev_ops; |
1994 | netdev->watchdog_timeo = 2 * HZ; | 2055 | netdev->watchdog_timeo = 2 * HZ; |
1995 | netdev->ethtool_ops = &enic_ethtool_ops; | 2056 | netdev->ethtool_ops = &enic_ethtool_ops; |