📄 ixgbe_ethtool.c
字号:
ring->rx_jumbo_pending = 0;}static int ixgbe_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring){ struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_tx_buffer *old_buf; struct ixgbe_rx_buffer *old_rx_buf; void *old_desc; int i, err; u32 new_rx_count, new_tx_count, old_size; dma_addr_t old_dma; if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; new_rx_count = max(ring->rx_pending, (u32)IXGBE_MIN_RXD); new_rx_count = min(new_rx_count, (u32)IXGBE_MAX_RXD); new_rx_count = ALIGN(new_rx_count, IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE); new_tx_count = max(ring->tx_pending, (u32)IXGBE_MIN_TXD); new_tx_count = min(new_tx_count, (u32)IXGBE_MAX_TXD); new_tx_count = ALIGN(new_tx_count, IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE); if ((new_tx_count == adapter->tx_ring->count) && (new_rx_count == adapter->rx_ring->count)) { /* nothing to do */ return 0; } if (netif_running(adapter->netdev)) ixgbe_down(adapter); /* * We can't just free everything and then setup again, * because the ISRs in MSI-X mode get passed pointers * to the tx and rx ring structs. */ if (new_tx_count != adapter->tx_ring->count) { for (i = 0; i < adapter->num_tx_queues; i++) { /* Save existing descriptor ring */ old_buf = adapter->tx_ring[i].tx_buffer_info; old_desc = adapter->tx_ring[i].desc; old_size = adapter->tx_ring[i].size; old_dma = adapter->tx_ring[i].dma; /* Try to allocate a new one */ adapter->tx_ring[i].tx_buffer_info = NULL; adapter->tx_ring[i].desc = NULL; adapter->tx_ring[i].count = new_tx_count; err = ixgbe_setup_tx_resources(adapter, &adapter->tx_ring[i]); if (err) { /* Restore the old one so at least the adapter still works, even if we failed the request */ adapter->tx_ring[i].tx_buffer_info = old_buf; adapter->tx_ring[i].desc = old_desc; adapter->tx_ring[i].size = old_size; adapter->tx_ring[i].dma = old_dma; goto err_setup; } /* Free the old buffer manually */ vfree(old_buf); pci_free_consistent(adapter->pdev, old_size, old_desc, old_dma); } } if (new_rx_count != adapter->rx_ring->count) { for (i = 0; i < adapter->num_rx_queues; i++) { old_rx_buf = adapter->rx_ring[i].rx_buffer_info; old_desc = adapter->rx_ring[i].desc; old_size = adapter->rx_ring[i].size; old_dma = adapter->rx_ring[i].dma; adapter->rx_ring[i].rx_buffer_info = NULL; adapter->rx_ring[i].desc = NULL; adapter->rx_ring[i].dma = 0; adapter->rx_ring[i].count = new_rx_count; err = ixgbe_setup_rx_resources(adapter, &adapter->rx_ring[i]); if (err) { adapter->rx_ring[i].rx_buffer_info = old_rx_buf; adapter->rx_ring[i].desc = old_desc; adapter->rx_ring[i].size = old_size; adapter->rx_ring[i].dma = old_dma; goto err_setup; } vfree(old_rx_buf); pci_free_consistent(adapter->pdev, old_size, old_desc, old_dma); } } err = 0;err_setup: if (netif_running(adapter->netdev)) ixgbe_up(adapter); return err;}static int ixgbe_get_sset_count(struct net_device *netdev, int sset){ switch (sset) { case ETH_SS_STATS: return IXGBE_STATS_LEN; default: return -EOPNOTSUPP; }}static void ixgbe_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, u64 *data){ struct ixgbe_adapter *adapter = netdev_priv(netdev); u64 *queue_stat; int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64); int j, k; int i; ixgbe_update_stats(adapter); for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { char *p = (char *)adapter + ixgbe_gstrings_stats[i].stat_offset; data[i] = (ixgbe_gstrings_stats[i].sizeof_stat == sizeof(u64)) ? *(u64 *)p : *(u32 *)p; } for (j = 0; j < adapter->num_tx_queues; j++) { queue_stat = (u64 *)&adapter->tx_ring[j].stats; for (k = 0; k < stat_count; k++) data[i + k] = queue_stat[k]; i += k; } for (j = 0; j < adapter->num_rx_queues; j++) { queue_stat = (u64 *)&adapter->rx_ring[j].stats; for (k = 0; k < stat_count; k++) data[i + k] = queue_stat[k]; i += k; }}static void ixgbe_get_strings(struct net_device *netdev, u32 stringset, u8 *data){ struct ixgbe_adapter *adapter = netdev_priv(netdev); u8 *p = data; int i; switch (stringset) { case ETH_SS_STATS: for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { memcpy(p, ixgbe_gstrings_stats[i].stat_string, ETH_GSTRING_LEN); p += ETH_GSTRING_LEN; } for (i = 0; i < adapter->num_tx_queues; i++) { sprintf(p, "tx_queue_%u_packets", i); p += ETH_GSTRING_LEN; sprintf(p, "tx_queue_%u_bytes", i); p += ETH_GSTRING_LEN; } for (i = 0; i < adapter->num_rx_queues; i++) { sprintf(p, "rx_queue_%u_packets", i); p += ETH_GSTRING_LEN; sprintf(p, "rx_queue_%u_bytes", i); p += ETH_GSTRING_LEN; }/* BUG_ON(p - data != IXGBE_STATS_LEN * ETH_GSTRING_LEN); */ break; }}static void ixgbe_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol){ wol->supported = 0; wol->wolopts = 0; return;}static int ixgbe_nway_reset(struct net_device *netdev){ struct ixgbe_adapter *adapter = netdev_priv(netdev); if (netif_running(netdev)) { ixgbe_down(adapter); ixgbe_reset(adapter); ixgbe_up(adapter); } return 0;}static int ixgbe_phys_id(struct net_device *netdev, u32 data){ struct ixgbe_adapter *adapter = netdev_priv(netdev); u32 led_reg = IXGBE_READ_REG(&adapter->hw, IXGBE_LEDCTL); u32 i; if (!data || data > 300) data = 300; for (i = 0; i < (data * 1000); i += 400) { ixgbe_led_on(&adapter->hw, IXGBE_LED_ON); msleep_interruptible(200); ixgbe_led_off(&adapter->hw, IXGBE_LED_ON); msleep_interruptible(200); } /* Restore LED settings */ IXGBE_WRITE_REG(&adapter->hw, IXGBE_LEDCTL, led_reg); return 0;}static int ixgbe_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec){ struct ixgbe_adapter *adapter = netdev_priv(netdev); if (adapter->rx_eitr == 0) ec->rx_coalesce_usecs = 0; else ec->rx_coalesce_usecs = 1000000 / adapter->rx_eitr; if (adapter->tx_eitr == 0) ec->tx_coalesce_usecs = 0; else ec->tx_coalesce_usecs = 1000000 / adapter->tx_eitr; ec->tx_max_coalesced_frames_irq = adapter->tx_ring[0].work_limit; return 0;}static int ixgbe_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec){ struct ixgbe_adapter *adapter = netdev_priv(netdev); if ((ec->rx_coalesce_usecs > IXGBE_MAX_ITR_USECS) || ((ec->rx_coalesce_usecs > 0) && (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS))) return -EINVAL; if ((ec->tx_coalesce_usecs > IXGBE_MAX_ITR_USECS) || ((ec->tx_coalesce_usecs > 0) && (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS))) return -EINVAL; /* convert to rate of irq's per second */ if (ec->rx_coalesce_usecs == 0) adapter->rx_eitr = 0; else adapter->rx_eitr = (1000000 / ec->rx_coalesce_usecs); if (ec->tx_coalesce_usecs == 0) adapter->tx_eitr = 0; else adapter->tx_eitr = (1000000 / ec->tx_coalesce_usecs); if (ec->tx_max_coalesced_frames_irq) adapter->tx_ring[0].work_limit = ec->tx_max_coalesced_frames_irq; if (netif_running(netdev)) { ixgbe_down(adapter); ixgbe_up(adapter); } return 0;}static struct ethtool_ops ixgbe_ethtool_ops = { .get_settings = ixgbe_get_settings, .set_settings = ixgbe_set_settings, .get_drvinfo = ixgbe_get_drvinfo, .get_regs_len = ixgbe_get_regs_len, .get_regs = ixgbe_get_regs, .get_wol = ixgbe_get_wol, .nway_reset = ixgbe_nway_reset, .get_link = ethtool_op_get_link, .get_eeprom_len = ixgbe_get_eeprom_len, .get_eeprom = ixgbe_get_eeprom, .get_ringparam = ixgbe_get_ringparam, .set_ringparam = ixgbe_set_ringparam, .get_pauseparam = ixgbe_get_pauseparam, .set_pauseparam = ixgbe_set_pauseparam, .get_rx_csum = ixgbe_get_rx_csum, .set_rx_csum = ixgbe_set_rx_csum, .get_tx_csum = ixgbe_get_tx_csum, .set_tx_csum = ixgbe_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, .get_msglevel = ixgbe_get_msglevel, .set_msglevel = ixgbe_set_msglevel, .get_tso = ethtool_op_get_tso, .set_tso = ixgbe_set_tso, .get_strings = ixgbe_get_strings, .phys_id = ixgbe_phys_id, .get_sset_count = ixgbe_get_sset_count, .get_ethtool_stats = ixgbe_get_ethtool_stats, .get_coalesce = ixgbe_get_coalesce, .set_coalesce = ixgbe_set_coalesce,};void ixgbe_set_ethtool_ops(struct net_device *netdev){ SET_ETHTOOL_OPS(netdev, &ixgbe_ethtool_ops);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -