forked from luck/tmp_suning_uos_patched
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>
This commit is contained in:
parent
a865d22d59
commit
8c5ad0dae9
|
@ -7,4 +7,5 @@
|
|||
|
||||
obj-$(CONFIG_IGC) += igc.o
|
||||
|
||||
igc-objs := igc_main.o igc_mac.o igc_i225.o igc_base.o igc_nvm.o igc_phy.o
|
||||
igc-objs := igc_main.o igc_mac.o igc_i225.o igc_base.o igc_nvm.o igc_phy.o \
|
||||
igc_ethtool.o
|
||||
|
|
|
@ -13,19 +13,43 @@
|
|||
|
||||
#include "igc_hw.h"
|
||||
|
||||
/* main */
|
||||
/* forward declaration */
|
||||
void igc_set_ethtool_ops(struct net_device *);
|
||||
|
||||
struct igc_adapter;
|
||||
struct igc_ring;
|
||||
|
||||
void igc_up(struct igc_adapter *adapter);
|
||||
void igc_down(struct igc_adapter *adapter);
|
||||
int igc_setup_tx_resources(struct igc_ring *ring);
|
||||
int igc_setup_rx_resources(struct igc_ring *ring);
|
||||
void igc_free_tx_resources(struct igc_ring *ring);
|
||||
void igc_free_rx_resources(struct igc_ring *ring);
|
||||
unsigned int igc_get_max_rss_queues(struct igc_adapter *adapter);
|
||||
void igc_set_flag_queue_pairs(struct igc_adapter *adapter,
|
||||
const u32 max_rss_queues);
|
||||
int igc_reinit_queues(struct igc_adapter *adapter);
|
||||
bool igc_has_link(struct igc_adapter *adapter);
|
||||
void igc_reset(struct igc_adapter *adapter);
|
||||
int igc_set_spd_dplx(struct igc_adapter *adapter, u32 spd, u8 dplx);
|
||||
|
||||
extern char igc_driver_name[];
|
||||
extern char igc_driver_version[];
|
||||
|
||||
#define IGC_REGS_LEN 740
|
||||
#define IGC_RETA_SIZE 128
|
||||
|
||||
/* Interrupt defines */
|
||||
#define IGC_START_ITR 648 /* ~6000 ints/sec */
|
||||
#define IGC_FLAG_HAS_MSI BIT(0)
|
||||
#define IGC_FLAG_QUEUE_PAIRS BIT(4)
|
||||
#define IGC_FLAG_QUEUE_PAIRS BIT(3)
|
||||
#define IGC_FLAG_DMAC BIT(4)
|
||||
#define IGC_FLAG_NEED_LINK_UPDATE BIT(9)
|
||||
#define IGC_FLAG_MEDIA_RESET BIT(10)
|
||||
#define IGC_FLAG_MAS_ENABLE BIT(12)
|
||||
#define IGC_FLAG_HAS_MSIX BIT(13)
|
||||
#define IGC_FLAG_VLAN_PROMISC BIT(15)
|
||||
#define IGC_FLAG_RX_LEGACY BIT(16)
|
||||
|
||||
#define IGC_START_ITR 648 /* ~6000 ints/sec */
|
||||
#define IGC_4K_ITR 980
|
||||
|
@ -60,6 +84,7 @@ extern char igc_driver_version[];
|
|||
#define IGC_RXBUFFER_2048 2048
|
||||
#define IGC_RXBUFFER_3072 3072
|
||||
|
||||
#define AUTO_ALL_MODES 0
|
||||
#define IGC_RX_HDR_LEN IGC_RXBUFFER_256
|
||||
|
||||
/* RX and TX descriptor control thresholds.
|
||||
|
@ -340,6 +365,8 @@ struct igc_adapter {
|
|||
|
||||
struct igc_mac_addr *mac_table;
|
||||
|
||||
u8 rss_indir_tbl[IGC_RETA_SIZE];
|
||||
|
||||
unsigned long link_check_timeout;
|
||||
struct igc_info ei;
|
||||
};
|
||||
|
@ -418,6 +445,9 @@ static inline s32 igc_read_phy_reg(struct igc_hw *hw, u32 offset, u16 *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* forward declaration */
|
||||
void igc_reinit_locked(struct igc_adapter *);
|
||||
|
||||
#define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring))
|
||||
|
||||
#define IGC_TXD_DCMD (IGC_ADVTXD_DCMD_EOP | IGC_ADVTXD_DCMD_RS)
|
||||
|
|
|
@ -131,6 +131,7 @@ static s32 igc_init_nvm_params_base(struct igc_hw *hw)
|
|||
if (size > 15)
|
||||
size = 15;
|
||||
|
||||
nvm->type = igc_nvm_eeprom_spi;
|
||||
nvm->word_size = BIT(size);
|
||||
nvm->opcode_bits = 8;
|
||||
nvm->delay_usec = 1;
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
#ifndef _IGC_DEFINES_H_
|
||||
#define _IGC_DEFINES_H_
|
||||
|
||||
/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
|
||||
#define REQ_TX_DESCRIPTOR_MULTIPLE 8
|
||||
#define REQ_RX_DESCRIPTOR_MULTIPLE 8
|
||||
|
||||
#define IGC_CTRL_EXT_DRV_LOAD 0x10000000 /* Drv loaded bit for FW */
|
||||
|
||||
/* PCI Bus Info */
|
||||
|
|
1032
drivers/net/ethernet/intel/igc/igc_ethtool.c
Normal file
1032
drivers/net/ethernet/intel/igc/igc_ethtool.c
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -55,6 +55,7 @@ enum igc_media_type {
|
|||
|
||||
enum igc_nvm_type {
|
||||
igc_nvm_unknown = 0,
|
||||
igc_nvm_eeprom_spi,
|
||||
igc_nvm_flash_hw,
|
||||
igc_nvm_invm,
|
||||
};
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#define DRV_VERSION "0.0.1-k"
|
||||
#define DRV_SUMMARY "Intel(R) 2.5G Ethernet Linux Driver"
|
||||
|
||||
#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK)
|
||||
|
||||
static int debug = -1;
|
||||
|
||||
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
|
||||
|
@ -66,7 +68,7 @@ enum latency_range {
|
|||
latency_invalid = 255
|
||||
};
|
||||
|
||||
static void igc_reset(struct igc_adapter *adapter)
|
||||
void igc_reset(struct igc_adapter *adapter)
|
||||
{
|
||||
struct pci_dev *pdev = adapter->pdev;
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
|
@ -150,7 +152,7 @@ static void igc_get_hw_control(struct igc_adapter *adapter)
|
|||
*
|
||||
* Free all transmit software resources
|
||||
*/
|
||||
static void igc_free_tx_resources(struct igc_ring *tx_ring)
|
||||
void igc_free_tx_resources(struct igc_ring *tx_ring)
|
||||
{
|
||||
igc_clean_tx_ring(tx_ring);
|
||||
|
||||
|
@ -261,7 +263,7 @@ static void igc_clean_all_tx_rings(struct igc_adapter *adapter)
|
|||
*
|
||||
* Return 0 on success, negative on failure
|
||||
*/
|
||||
static int igc_setup_tx_resources(struct igc_ring *tx_ring)
|
||||
int igc_setup_tx_resources(struct igc_ring *tx_ring)
|
||||
{
|
||||
struct device *dev = tx_ring->dev;
|
||||
int size = 0;
|
||||
|
@ -381,7 +383,7 @@ static void igc_clean_all_rx_rings(struct igc_adapter *adapter)
|
|||
*
|
||||
* Free all receive software resources
|
||||
*/
|
||||
static void igc_free_rx_resources(struct igc_ring *rx_ring)
|
||||
void igc_free_rx_resources(struct igc_ring *rx_ring)
|
||||
{
|
||||
igc_clean_rx_ring(rx_ring);
|
||||
|
||||
|
@ -418,7 +420,7 @@ static void igc_free_all_rx_resources(struct igc_adapter *adapter)
|
|||
*
|
||||
* Returns 0 on success, negative on failure
|
||||
*/
|
||||
static int igc_setup_rx_resources(struct igc_ring *rx_ring)
|
||||
int igc_setup_rx_resources(struct igc_ring *rx_ring)
|
||||
{
|
||||
struct device *dev = rx_ring->dev;
|
||||
int size, desc_len;
|
||||
|
@ -1703,7 +1705,7 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)
|
|||
* igc_up - Open the interface and prepare it to handle traffic
|
||||
* @adapter: board private structure
|
||||
*/
|
||||
static void igc_up(struct igc_adapter *adapter)
|
||||
void igc_up(struct igc_adapter *adapter)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
int i = 0;
|
||||
|
@ -1748,7 +1750,7 @@ static void igc_nfc_filter_exit(struct igc_adapter *adapter)
|
|||
* igc_down - Close the interface
|
||||
* @adapter: board private structure
|
||||
*/
|
||||
static void igc_down(struct igc_adapter *adapter)
|
||||
void igc_down(struct igc_adapter *adapter)
|
||||
{
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
|
@ -1810,7 +1812,7 @@ static void igc_down(struct igc_adapter *adapter)
|
|||
igc_clean_all_rx_rings(adapter);
|
||||
}
|
||||
|
||||
static void igc_reinit_locked(struct igc_adapter *adapter)
|
||||
void igc_reinit_locked(struct igc_adapter *adapter)
|
||||
{
|
||||
WARN_ON(in_interrupt());
|
||||
while (test_and_set_bit(__IGC_RESETTING, &adapter->state))
|
||||
|
@ -1922,7 +1924,7 @@ static void igc_configure(struct igc_adapter *adapter)
|
|||
|
||||
/**
|
||||
* igc_rar_set_index - Sync RAL[index] and RAH[index] registers with MAC table
|
||||
* @adapter: Pointer to adapter structure
|
||||
* @adapter: address of board private structure
|
||||
* @index: Index of the RAR entry which need to be synced with MAC table
|
||||
*/
|
||||
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)
|
|||
* igc_has_link - check shared code for link and determine up/down
|
||||
* @adapter: pointer to driver private info
|
||||
*/
|
||||
static bool igc_has_link(struct igc_adapter *adapter)
|
||||
bool igc_has_link(struct igc_adapter *adapter)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
bool link_active = false;
|
||||
|
@ -3501,6 +3503,57 @@ u32 igc_rd32(struct igc_hw *hw, u32 reg)
|
|||
return value;
|
||||
}
|
||||
|
||||
int igc_set_spd_dplx(struct igc_adapter *adapter, u32 spd, u8 dplx)
|
||||
{
|
||||
struct pci_dev *pdev = adapter->pdev;
|
||||
struct igc_mac_info *mac = &adapter->hw.mac;
|
||||
|
||||
mac->autoneg = 0;
|
||||
|
||||
/* Make sure dplx is at most 1 bit and lsb of speed is not set
|
||||
* for the switch() below to work
|
||||
*/
|
||||
if ((spd & 1) || (dplx & ~1))
|
||||
goto err_inval;
|
||||
|
||||
switch (spd + dplx) {
|
||||
case SPEED_10 + DUPLEX_HALF:
|
||||
mac->forced_speed_duplex = ADVERTISE_10_HALF;
|
||||
break;
|
||||
case SPEED_10 + DUPLEX_FULL:
|
||||
mac->forced_speed_duplex = ADVERTISE_10_FULL;
|
||||
break;
|
||||
case SPEED_100 + DUPLEX_HALF:
|
||||
mac->forced_speed_duplex = ADVERTISE_100_HALF;
|
||||
break;
|
||||
case SPEED_100 + DUPLEX_FULL:
|
||||
mac->forced_speed_duplex = ADVERTISE_100_FULL;
|
||||
break;
|
||||
case SPEED_1000 + DUPLEX_FULL:
|
||||
mac->autoneg = 1;
|
||||
adapter->hw.phy.autoneg_advertised = ADVERTISE_1000_FULL;
|
||||
break;
|
||||
case SPEED_1000 + DUPLEX_HALF: /* not supported */
|
||||
goto err_inval;
|
||||
case SPEED_2500 + DUPLEX_FULL:
|
||||
mac->autoneg = 1;
|
||||
adapter->hw.phy.autoneg_advertised = ADVERTISE_2500_FULL;
|
||||
break;
|
||||
case SPEED_2500 + DUPLEX_HALF: /* not supported */
|
||||
default:
|
||||
goto err_inval;
|
||||
}
|
||||
|
||||
/* clear MDI, MDI(-X) override is only allowed when autoneg enabled */
|
||||
adapter->hw.phy.mdix = AUTO_ALL_MODES;
|
||||
|
||||
return 0;
|
||||
|
||||
err_inval:
|
||||
dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_probe - Device Initialization Routine
|
||||
* @pdev: PCI device information struct
|
||||
|
@ -3568,7 +3621,7 @@ static int igc_probe(struct pci_dev *pdev,
|
|||
hw = &adapter->hw;
|
||||
hw->back = adapter;
|
||||
adapter->port_num = hw->bus.func;
|
||||
adapter->msg_enable = GENMASK(debug - 1, 0);
|
||||
adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
|
||||
|
||||
err = pci_save_state(pdev);
|
||||
if (err)
|
||||
|
@ -3584,7 +3637,7 @@ static int igc_probe(struct pci_dev *pdev,
|
|||
hw->hw_addr = adapter->io_addr;
|
||||
|
||||
netdev->netdev_ops = &igc_netdev_ops;
|
||||
|
||||
igc_set_ethtool_ops(netdev);
|
||||
netdev->watchdog_timeo = 5 * HZ;
|
||||
|
||||
netdev->mem_start = pci_resource_start(pdev, 0);
|
||||
|
@ -3744,8 +3797,8 @@ static struct pci_driver igc_driver = {
|
|||
.remove = igc_remove,
|
||||
};
|
||||
|
||||
static void igc_set_flag_queue_pairs(struct igc_adapter *adapter,
|
||||
const u32 max_rss_queues)
|
||||
void igc_set_flag_queue_pairs(struct igc_adapter *adapter,
|
||||
const u32 max_rss_queues)
|
||||
{
|
||||
/* Determine if we need to pair queues. */
|
||||
/* 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,
|
|||
adapter->flags &= ~IGC_FLAG_QUEUE_PAIRS;
|
||||
}
|
||||
|
||||
static unsigned int igc_get_max_rss_queues(struct igc_adapter *adapter)
|
||||
unsigned int igc_get_max_rss_queues(struct igc_adapter *adapter)
|
||||
{
|
||||
unsigned int max_rss_queues;
|
||||
|
||||
|
@ -3836,6 +3889,32 @@ static int igc_sw_init(struct igc_adapter *adapter)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_reinit_queues - return error
|
||||
* @adapter: pointer to adapter structure
|
||||
*/
|
||||
int igc_reinit_queues(struct igc_adapter *adapter)
|
||||
{
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
struct pci_dev *pdev = adapter->pdev;
|
||||
int err = 0;
|
||||
|
||||
if (netif_running(netdev))
|
||||
igc_close(netdev);
|
||||
|
||||
igc_reset_interrupt_capability(adapter);
|
||||
|
||||
if (igc_init_interrupt_scheme(adapter, true)) {
|
||||
dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (netif_running(netdev))
|
||||
err = igc_open(netdev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_get_hw_dev - return device
|
||||
* @hw: pointer to hardware structure
|
||||
|
|
|
@ -80,6 +80,9 @@
|
|||
/* MSI-X Table Register Descriptions */
|
||||
#define IGC_PBACL 0x05B68 /* MSIx PBA Clear - R/W 1 to clear */
|
||||
|
||||
/* Redirection Table - RW Array */
|
||||
#define IGC_RETA(_i) (0x05C00 + ((_i) * 4))
|
||||
|
||||
/* Receive Register Descriptions */
|
||||
#define IGC_RCTL 0x00100 /* Rx Control - RW */
|
||||
#define IGC_SRRCTL(_n) (0x0C00C + ((_n) * 0x40))
|
||||
|
|
Loading…
Reference in New Issue
Block a user