diff options
| author | Sasha Neftin <sasha.neftin@intel.com> | 2019-01-30 12:13:14 -0500 |
|---|---|---|
| committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2019-02-05 20:35:46 -0500 |
| commit | 8c5ad0dae93c9931dc32b9f4a98e73922c6ab2e0 (patch) | |
| tree | 0828df855962356ec80cc26337248bf6e1edba7c /drivers/net/ethernet/intel/igc/igc_main.c | |
| parent | a865d22d593ff1310665d582e08ec78b3632cca8 (diff) | |
igc: Add ethtool support
This patch adds basic ethtool support to the device to allow
for configuration.
Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/igc/igc_main.c')
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc_main.c | 109 |
1 files changed, 94 insertions, 15 deletions
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index f20183037fb2..11c75433fe22 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c | |||
| @@ -12,6 +12,8 @@ | |||
| 12 | #define DRV_VERSION "0.0.1-k" | 12 | #define DRV_VERSION "0.0.1-k" |
| 13 | #define DRV_SUMMARY "Intel(R) 2.5G Ethernet Linux Driver" | 13 | #define DRV_SUMMARY "Intel(R) 2.5G Ethernet Linux Driver" |
| 14 | 14 | ||
| 15 | #define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK) | ||
| 16 | |||
| 15 | static int debug = -1; | 17 | static int debug = -1; |
| 16 | 18 | ||
| 17 | MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>"); | 19 | MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>"); |
| @@ -66,7 +68,7 @@ enum latency_range { | |||
| 66 | latency_invalid = 255 | 68 | latency_invalid = 255 |
| 67 | }; | 69 | }; |
| 68 | 70 | ||
| 69 | static void igc_reset(struct igc_adapter *adapter) | 71 | void igc_reset(struct igc_adapter *adapter) |
| 70 | { | 72 | { |
| 71 | struct pci_dev *pdev = adapter->pdev; | 73 | struct pci_dev *pdev = adapter->pdev; |
| 72 | struct igc_hw *hw = &adapter->hw; | 74 | struct igc_hw *hw = &adapter->hw; |
| @@ -150,7 +152,7 @@ static void igc_get_hw_control(struct igc_adapter *adapter) | |||
| 150 | * | 152 | * |
| 151 | * Free all transmit software resources | 153 | * Free all transmit software resources |
| 152 | */ | 154 | */ |
| 153 | static void igc_free_tx_resources(struct igc_ring *tx_ring) | 155 | void igc_free_tx_resources(struct igc_ring *tx_ring) |
| 154 | { | 156 | { |
| 155 | igc_clean_tx_ring(tx_ring); | 157 | igc_clean_tx_ring(tx_ring); |
| 156 | 158 | ||
| @@ -261,7 +263,7 @@ static void igc_clean_all_tx_rings(struct igc_adapter *adapter) | |||
| 261 | * | 263 | * |
| 262 | * Return 0 on success, negative on failure | 264 | * Return 0 on success, negative on failure |
| 263 | */ | 265 | */ |
| 264 | static int igc_setup_tx_resources(struct igc_ring *tx_ring) | 266 | int igc_setup_tx_resources(struct igc_ring *tx_ring) |
| 265 | { | 267 | { |
| 266 | struct device *dev = tx_ring->dev; | 268 | struct device *dev = tx_ring->dev; |
| 267 | int size = 0; | 269 | int size = 0; |
| @@ -381,7 +383,7 @@ static void igc_clean_all_rx_rings(struct igc_adapter *adapter) | |||
| 381 | * | 383 | * |
| 382 | * Free all receive software resources | 384 | * Free all receive software resources |
| 383 | */ | 385 | */ |
| 384 | static void igc_free_rx_resources(struct igc_ring *rx_ring) | 386 | void igc_free_rx_resources(struct igc_ring *rx_ring) |
| 385 | { | 387 | { |
| 386 | igc_clean_rx_ring(rx_ring); | 388 | igc_clean_rx_ring(rx_ring); |
| 387 | 389 | ||
| @@ -418,7 +420,7 @@ static void igc_free_all_rx_resources(struct igc_adapter *adapter) | |||
| 418 | * | 420 | * |
| 419 | * Returns 0 on success, negative on failure | 421 | * Returns 0 on success, negative on failure |
| 420 | */ | 422 | */ |
| 421 | static int igc_setup_rx_resources(struct igc_ring *rx_ring) | 423 | int igc_setup_rx_resources(struct igc_ring *rx_ring) |
| 422 | { | 424 | { |
| 423 | struct device *dev = rx_ring->dev; | 425 | struct device *dev = rx_ring->dev; |
| 424 | int size, desc_len; | 426 | int size, desc_len; |
| @@ -1703,7 +1705,7 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget) | |||
| 1703 | * igc_up - Open the interface and prepare it to handle traffic | 1705 | * igc_up - Open the interface and prepare it to handle traffic |
| 1704 | * @adapter: board private structure | 1706 | * @adapter: board private structure |
| 1705 | */ | 1707 | */ |
| 1706 | static void igc_up(struct igc_adapter *adapter) | 1708 | void igc_up(struct igc_adapter *adapter) |
| 1707 | { | 1709 | { |
| 1708 | struct igc_hw *hw = &adapter->hw; | 1710 | struct igc_hw *hw = &adapter->hw; |
| 1709 | int i = 0; | 1711 | int i = 0; |
| @@ -1748,7 +1750,7 @@ static void igc_nfc_filter_exit(struct igc_adapter *adapter) | |||
| 1748 | * igc_down - Close the interface | 1750 | * igc_down - Close the interface |
| 1749 | * @adapter: board private structure | 1751 | * @adapter: board private structure |
| 1750 | */ | 1752 | */ |
| 1751 | static void igc_down(struct igc_adapter *adapter) | 1753 | void igc_down(struct igc_adapter *adapter) |
| 1752 | { | 1754 | { |
| 1753 | struct net_device *netdev = adapter->netdev; | 1755 | struct net_device *netdev = adapter->netdev; |
| 1754 | struct igc_hw *hw = &adapter->hw; | 1756 | struct igc_hw *hw = &adapter->hw; |
| @@ -1810,7 +1812,7 @@ static void igc_down(struct igc_adapter *adapter) | |||
| 1810 | igc_clean_all_rx_rings(adapter); | 1812 | igc_clean_all_rx_rings(adapter); |
| 1811 | } | 1813 | } |
| 1812 | 1814 | ||
| 1813 | static void igc_reinit_locked(struct igc_adapter *adapter) | 1815 | void igc_reinit_locked(struct igc_adapter *adapter) |
| 1814 | { | 1816 | { |
| 1815 | WARN_ON(in_interrupt()); | 1817 | WARN_ON(in_interrupt()); |
| 1816 | while (test_and_set_bit(__IGC_RESETTING, &adapter->state)) | 1818 | while (test_and_set_bit(__IGC_RESETTING, &adapter->state)) |
| @@ -1922,7 +1924,7 @@ static void igc_configure(struct igc_adapter *adapter) | |||
| 1922 | 1924 | ||
| 1923 | /** | 1925 | /** |
| 1924 | * igc_rar_set_index - Sync RAL[index] and RAH[index] registers with MAC table | 1926 | * igc_rar_set_index - Sync RAL[index] and RAH[index] registers with MAC table |
| 1925 | * @adapter: Pointer to adapter structure | 1927 | * @adapter: address of board private structure |
| 1926 | * @index: Index of the RAR entry which need to be synced with MAC table | 1928 | * @index: Index of the RAR entry which need to be synced with MAC table |
| 1927 | */ | 1929 | */ |
| 1928 | static void igc_rar_set_index(struct igc_adapter *adapter, u32 index) | 1930 | static void igc_rar_set_index(struct igc_adapter *adapter, u32 index) |
| @@ -2298,7 +2300,7 @@ static void igc_update_phy_info(struct timer_list *t) | |||
| 2298 | * igc_has_link - check shared code for link and determine up/down | 2300 | * igc_has_link - check shared code for link and determine up/down |
| 2299 | * @adapter: pointer to driver private info | 2301 | * @adapter: pointer to driver private info |
| 2300 | */ | 2302 | */ |
| 2301 | static bool igc_has_link(struct igc_adapter *adapter) | 2303 | bool igc_has_link(struct igc_adapter *adapter) |
| 2302 | { | 2304 | { |
| 2303 | struct igc_hw *hw = &adapter->hw; | 2305 | struct igc_hw *hw = &adapter->hw; |
| 2304 | bool link_active = false; | 2306 | bool link_active = false; |
| @@ -3501,6 +3503,57 @@ u32 igc_rd32(struct igc_hw *hw, u32 reg) | |||
| 3501 | return value; | 3503 | return value; |
| 3502 | } | 3504 | } |
| 3503 | 3505 | ||
| 3506 | int igc_set_spd_dplx(struct igc_adapter *adapter, u32 spd, u8 dplx) | ||
| 3507 | { | ||
| 3508 | struct pci_dev *pdev = adapter->pdev; | ||
| 3509 | struct igc_mac_info *mac = &adapter->hw.mac; | ||
| 3510 | |||
| 3511 | mac->autoneg = 0; | ||
| 3512 | |||
| 3513 | /* Make sure dplx is at most 1 bit and lsb of speed is not set | ||
| 3514 | * for the switch() below to work | ||
| 3515 | */ | ||
| 3516 | if ((spd & 1) || (dplx & ~1)) | ||
| 3517 | goto err_inval; | ||
| 3518 | |||
| 3519 | switch (spd + dplx) { | ||
| 3520 | case SPEED_10 + DUPLEX_HALF: | ||
| 3521 | mac->forced_speed_duplex = ADVERTISE_10_HALF; | ||
| 3522 | break; | ||
| 3523 | case SPEED_10 + DUPLEX_FULL: | ||
| 3524 | mac->forced_speed_duplex = ADVERTISE_10_FULL; | ||
| 3525 | break; | ||
| 3526 | case SPEED_100 + DUPLEX_HALF: | ||
| 3527 | mac->forced_speed_duplex = ADVERTISE_100_HALF; | ||
| 3528 | break; | ||
| 3529 | case SPEED_100 + DUPLEX_FULL: | ||
| 3530 | mac->forced_speed_duplex = ADVERTISE_100_FULL; | ||
| 3531 | break; | ||
| 3532 | case SPEED_1000 + DUPLEX_FULL: | ||
| 3533 | mac->autoneg = 1; | ||
| 3534 | adapter->hw.phy.autoneg_advertised = ADVERTISE_1000_FULL; | ||
| 3535 | break; | ||
| 3536 | case SPEED_1000 + DUPLEX_HALF: /* not supported */ | ||
| 3537 | goto err_inval; | ||
| 3538 | case SPEED_2500 + DUPLEX_FULL: | ||
| 3539 | mac->autoneg = 1; | ||
| 3540 | adapter->hw.phy.autoneg_advertised = ADVERTISE_2500_FULL; | ||
| 3541 | break; | ||
| 3542 | case SPEED_2500 + DUPLEX_HALF: /* not supported */ | ||
| 3543 | default: | ||
| 3544 | goto err_inval; | ||
| 3545 | } | ||
| 3546 | |||
| 3547 | /* clear MDI, MDI(-X) override is only allowed when autoneg enabled */ | ||
| 3548 | adapter->hw.phy.mdix = AUTO_ALL_MODES; | ||
| 3549 | |||
| 3550 | return 0; | ||
| 3551 | |||
| 3552 | err_inval: | ||
| 3553 | dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n"); | ||
| 3554 | return -EINVAL; | ||
| 3555 | } | ||
| 3556 | |||
| 3504 | /** | 3557 | /** |
| 3505 | * igc_probe - Device Initialization Routine | 3558 | * igc_probe - Device Initialization Routine |
| 3506 | * @pdev: PCI device information struct | 3559 | * @pdev: PCI device information struct |
| @@ -3568,7 +3621,7 @@ static int igc_probe(struct pci_dev *pdev, | |||
| 3568 | hw = &adapter->hw; | 3621 | hw = &adapter->hw; |
| 3569 | hw->back = adapter; | 3622 | hw->back = adapter; |
| 3570 | adapter->port_num = hw->bus.func; | 3623 | adapter->port_num = hw->bus.func; |
| 3571 | adapter->msg_enable = GENMASK(debug - 1, 0); | 3624 | adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); |
| 3572 | 3625 | ||
| 3573 | err = pci_save_state(pdev); | 3626 | err = pci_save_state(pdev); |
| 3574 | if (err) | 3627 | if (err) |
| @@ -3584,7 +3637,7 @@ static int igc_probe(struct pci_dev *pdev, | |||
| 3584 | hw->hw_addr = adapter->io_addr; | 3637 | hw->hw_addr = adapter->io_addr; |
| 3585 | 3638 | ||
| 3586 | netdev->netdev_ops = &igc_netdev_ops; | 3639 | netdev->netdev_ops = &igc_netdev_ops; |
| 3587 | 3640 | igc_set_ethtool_ops(netdev); | |
| 3588 | netdev->watchdog_timeo = 5 * HZ; | 3641 | netdev->watchdog_timeo = 5 * HZ; |
| 3589 | 3642 | ||
| 3590 | netdev->mem_start = pci_resource_start(pdev, 0); | 3643 | netdev->mem_start = pci_resource_start(pdev, 0); |
| @@ -3744,8 +3797,8 @@ static struct pci_driver igc_driver = { | |||
| 3744 | .remove = igc_remove, | 3797 | .remove = igc_remove, |
| 3745 | }; | 3798 | }; |
| 3746 | 3799 | ||
| 3747 | static void igc_set_flag_queue_pairs(struct igc_adapter *adapter, | 3800 | void igc_set_flag_queue_pairs(struct igc_adapter *adapter, |
| 3748 | const u32 max_rss_queues) | 3801 | const u32 max_rss_queues) |
| 3749 | { | 3802 | { |
| 3750 | /* Determine if we need to pair queues. */ | 3803 | /* Determine if we need to pair queues. */ |
| 3751 | /* If rss_queues > half of max_rss_queues, pair the queues in | 3804 | /* If rss_queues > half of max_rss_queues, pair the queues in |
| @@ -3757,7 +3810,7 @@ static void igc_set_flag_queue_pairs(struct igc_adapter *adapter, | |||
| 3757 | adapter->flags &= ~IGC_FLAG_QUEUE_PAIRS; | 3810 | adapter->flags &= ~IGC_FLAG_QUEUE_PAIRS; |
| 3758 | } | 3811 | } |
| 3759 | 3812 | ||
| 3760 | static unsigned int igc_get_max_rss_queues(struct igc_adapter *adapter) | 3813 | unsigned int igc_get_max_rss_queues(struct igc_adapter *adapter) |
| 3761 | { | 3814 | { |
| 3762 | unsigned int max_rss_queues; | 3815 | unsigned int max_rss_queues; |
| 3763 | 3816 | ||
| @@ -3837,6 +3890,32 @@ static int igc_sw_init(struct igc_adapter *adapter) | |||
| 3837 | } | 3890 | } |
| 3838 | 3891 | ||
| 3839 | /** | 3892 | /** |
| 3893 | * igc_reinit_queues - return error | ||
| 3894 | * @adapter: pointer to adapter structure | ||
| 3895 | */ | ||
| 3896 | int igc_reinit_queues(struct igc_adapter *adapter) | ||
| 3897 | { | ||
| 3898 | struct net_device *netdev = adapter->netdev; | ||
| 3899 | struct pci_dev *pdev = adapter->pdev; | ||
| 3900 | int err = 0; | ||
| 3901 | |||
| 3902 | if (netif_running(netdev)) | ||
| 3903 | igc_close(netdev); | ||
| 3904 | |||
| 3905 | igc_reset_interrupt_capability(adapter); | ||
| 3906 | |||
| 3907 | if (igc_init_interrupt_scheme(adapter, true)) { | ||
| 3908 | dev_err(&pdev->dev, "Unable to allocate memory for queues\n"); | ||
| 3909 | return -ENOMEM; | ||
| 3910 | } | ||
| 3911 | |||
| 3912 | if (netif_running(netdev)) | ||
| 3913 | err = igc_open(netdev); | ||
| 3914 | |||
| 3915 | return err; | ||
| 3916 | } | ||
| 3917 | |||
| 3918 | /** | ||
| 3840 | * igc_get_hw_dev - return device | 3919 | * igc_get_hw_dev - return device |
| 3841 | * @hw: pointer to hardware structure | 3920 | * @hw: pointer to hardware structure |
| 3842 | * | 3921 | * |
