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 | * |