diff options
Diffstat (limited to 'drivers/net/netxen/netxen_nic_ethtool.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_ethtool.c | 109 |
1 files changed, 96 insertions, 13 deletions
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index e16ea46c24b..3886135006e 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -37,7 +37,6 @@ #include "netxen_nic.h" #include "netxen_nic_hw.h" -#include "netxen_nic_phan_reg.h" struct netxen_nic_stats { char stat_string[ETH_GSTRING_LEN]; @@ -57,7 +56,8 @@ static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = { {"rx_dropped", NETXEN_NIC_STAT(stats.rxdropped)}, {"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)}, {"csummed", NETXEN_NIC_STAT(stats.csummed)}, - {"no_rcv", NETXEN_NIC_STAT(stats.no_rcv)}, + {"rx_pkts", NETXEN_NIC_STAT(stats.rx_pkts)}, + {"lro_pkts", NETXEN_NIC_STAT(stats.lro_pkts)}, {"rx_bytes", NETXEN_NIC_STAT(stats.rxbytes)}, {"tx_bytes", NETXEN_NIC_STAT(stats.txbytes)}, }; @@ -490,28 +490,86 @@ netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, } static void -netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) +netxen_nic_get_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring) { struct netxen_adapter *adapter = netdev_priv(dev); - ring->rx_pending = 0; - ring->rx_jumbo_pending = 0; - ring->rx_pending += adapter->recv_ctx. - rds_rings[RCV_RING_NORMAL].num_desc; - ring->rx_jumbo_pending += adapter->recv_ctx. - rds_rings[RCV_RING_JUMBO].num_desc; + ring->rx_pending = adapter->num_rxd; + ring->rx_jumbo_pending = adapter->num_jumbo_rxd; + ring->rx_jumbo_pending += adapter->num_lro_rxd; ring->tx_pending = adapter->num_txd; - if (adapter->ahw.port_type == NETXEN_NIC_GBE) + if (adapter->ahw.port_type == NETXEN_NIC_GBE) { ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G; - else + ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_1G; + } else { ring->rx_max_pending = MAX_RCV_DESCRIPTORS_10G; - ring->tx_max_pending = MAX_CMD_DESCRIPTORS_HOST; - ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS; + ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_10G; + } + + ring->tx_max_pending = MAX_CMD_DESCRIPTORS; + ring->rx_mini_max_pending = 0; ring->rx_mini_pending = 0; } +static u32 +netxen_validate_ringparam(u32 val, u32 min, u32 max, char *r_name) +{ + u32 num_desc; + num_desc = max(val, min); + num_desc = min(num_desc, max); + num_desc = roundup_pow_of_two(num_desc); + + if (val != num_desc) { + printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n", + netxen_nic_driver_name, r_name, num_desc, val); + } + + return num_desc; +} + +static int +netxen_nic_set_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring) +{ + struct netxen_adapter *adapter = netdev_priv(dev); + u16 max_rcv_desc = MAX_RCV_DESCRIPTORS_10G; + u16 max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G; + u16 num_rxd, num_jumbo_rxd, num_txd; + + if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) + return -EOPNOTSUPP; + + if (ring->rx_mini_pending) + return -EOPNOTSUPP; + + if (adapter->ahw.port_type == NETXEN_NIC_GBE) { + max_rcv_desc = MAX_RCV_DESCRIPTORS_1G; + max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G; + } + + num_rxd = netxen_validate_ringparam(ring->rx_pending, + MIN_RCV_DESCRIPTORS, max_rcv_desc, "rx"); + + num_jumbo_rxd = netxen_validate_ringparam(ring->rx_jumbo_pending, + MIN_JUMBO_DESCRIPTORS, max_jumbo_desc, "rx jumbo"); + + num_txd = netxen_validate_ringparam(ring->tx_pending, + MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx"); + + if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd && + num_jumbo_rxd == adapter->num_jumbo_rxd) + return 0; + + adapter->num_rxd = num_rxd; + adapter->num_jumbo_rxd = num_jumbo_rxd; + adapter->num_txd = num_txd; + + return netxen_nic_reset_context(adapter); +} + static void netxen_nic_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause) @@ -883,6 +941,28 @@ static int netxen_get_intr_coalesce(struct net_device *netdev, return 0; } +static int netxen_nic_set_flags(struct net_device *netdev, u32 data) +{ + struct netxen_adapter *adapter = netdev_priv(netdev); + int hw_lro; + + if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)) + return -EINVAL; + + ethtool_op_set_flags(netdev, data); + + hw_lro = (data & ETH_FLAG_LRO) ? NETXEN_NIC_LRO_ENABLED : 0; + + if (netxen_config_hw_lro(adapter, hw_lro)) + return -EIO; + + if ((hw_lro == 0) && netxen_send_lro_cleanup(adapter)) + return -EIO; + + + return 0; +} + struct ethtool_ops netxen_nic_ethtool_ops = { .get_settings = netxen_nic_get_settings, .set_settings = netxen_nic_set_settings, @@ -893,6 +973,7 @@ struct ethtool_ops netxen_nic_ethtool_ops = { .get_eeprom_len = netxen_nic_get_eeprom_len, .get_eeprom = netxen_nic_get_eeprom, .get_ringparam = netxen_nic_get_ringparam, + .set_ringparam = netxen_nic_set_ringparam, .get_pauseparam = netxen_nic_get_pauseparam, .set_pauseparam = netxen_nic_set_pauseparam, .set_tx_csum = ethtool_op_set_tx_csum, @@ -909,4 +990,6 @@ struct ethtool_ops netxen_nic_ethtool_ops = { .set_rx_csum = netxen_nic_set_rx_csum, .get_coalesce = netxen_get_intr_coalesce, .set_coalesce = netxen_set_intr_coalesce, + .get_flags = ethtool_op_get_flags, + .set_flags = netxen_nic_set_flags, }; |