mirror of
https://gitlab.com/etherlab.org/ethercat.git
synced 2026-02-05 19:39:50 +08:00
Merge branch 'igc_5.15' into 'stable-1.5'
Add igc for 5.15.40 See merge request etherlab.org/ethercat!128
This commit is contained in:
@@ -30,6 +30,8 @@ include $(top_srcdir)/Makefile.kbuild
|
||||
EXTRA_DIST = \
|
||||
igc-5.14-ethercat.h \
|
||||
igc-5.14-orig.h \
|
||||
igc-5.15-ethercat.h \
|
||||
igc-5.15-orig.h \
|
||||
igc-6.1-ethercat.h \
|
||||
igc-6.1-orig.h \
|
||||
igc-6.4-ethercat.h \
|
||||
@@ -40,6 +42,11 @@ EXTRA_DIST = \
|
||||
igc_base-5.14-ethercat.h \
|
||||
igc_base-5.14-orig.c \
|
||||
igc_base-5.14-orig.h \
|
||||
igc_base-5.15-ethercat.c \
|
||||
igc_base-5.15-ethercat.h \
|
||||
igc_base-5.15-orig.h \
|
||||
igc_base-5.15-orig.c \
|
||||
igc_base-5.15-orig.h \
|
||||
igc_base-6.1-ethercat.c \
|
||||
igc_base-6.1-ethercat.h \
|
||||
igc_base-6.1-orig.c \
|
||||
@@ -54,6 +61,8 @@ EXTRA_DIST = \
|
||||
igc_base-6.6-orig.h \
|
||||
igc_defines-5.14-ethercat.h \
|
||||
igc_defines-5.14-orig.h \
|
||||
igc_defines-5.15-ethercat.h \
|
||||
igc_defines-5.15-orig.h \
|
||||
igc_defines-6.1-ethercat.h \
|
||||
igc_defines-6.1-orig.h \
|
||||
igc_defines-6.4-ethercat.h \
|
||||
@@ -64,6 +73,10 @@ EXTRA_DIST = \
|
||||
igc_diag-5.14-ethercat.h \
|
||||
igc_diag-5.14-orig.c \
|
||||
igc_diag-5.14-orig.h \
|
||||
igc_diag-5.15-ethercat.c \
|
||||
igc_diag-5.15-ethercat.h \
|
||||
igc_diag-5.15-orig.c \
|
||||
igc_diag-5.15-orig.h \
|
||||
igc_diag-6.1-ethercat.c \
|
||||
igc_diag-6.1-ethercat.h \
|
||||
igc_diag-6.1-orig.c \
|
||||
@@ -78,6 +91,8 @@ EXTRA_DIST = \
|
||||
igc_diag-6.6-orig.h \
|
||||
igc_dump-5.14-ethercat.c \
|
||||
igc_dump-5.14-orig.c \
|
||||
igc_dump-5.15-ethercat.c \
|
||||
igc_dump-5.15-orig.c \
|
||||
igc_dump-6.1-ethercat.c \
|
||||
igc_dump-6.1-orig.c \
|
||||
igc_dump-6.4-ethercat.c \
|
||||
@@ -86,6 +101,8 @@ EXTRA_DIST = \
|
||||
igc_dump-6.6-orig.c \
|
||||
igc_ethtool-5.14-ethercat.c \
|
||||
igc_ethtool-5.14-orig.c \
|
||||
igc_ethtool-5.15-ethercat.c \
|
||||
igc_ethtool-5.15-orig.c \
|
||||
igc_ethtool-6.1-ethercat.c \
|
||||
igc_ethtool-6.1-orig.c \
|
||||
igc_ethtool-6.4-ethercat.c \
|
||||
@@ -94,6 +111,8 @@ EXTRA_DIST = \
|
||||
igc_ethtool-6.6-orig.c \
|
||||
igc_hw-5.14-ethercat.h \
|
||||
igc_hw-5.14-orig.h \
|
||||
igc_hw-5.15-ethercat.h \
|
||||
igc_hw-5.15-orig.h \
|
||||
igc_hw-6.1-ethercat.h \
|
||||
igc_hw-6.1-orig.h \
|
||||
igc_hw-6.4-ethercat.h \
|
||||
@@ -104,6 +123,10 @@ EXTRA_DIST = \
|
||||
igc_i225-5.14-ethercat.h \
|
||||
igc_i225-5.14-orig.c \
|
||||
igc_i225-5.14-orig.h \
|
||||
igc_i225-5.15-ethercat.c \
|
||||
igc_i225-5.15-ethercat.h \
|
||||
igc_i225-5.15-orig.c \
|
||||
igc_i225-5.15-orig.h \
|
||||
igc_i225-6.1-ethercat.c \
|
||||
igc_i225-6.1-ethercat.h \
|
||||
igc_i225-6.1-orig.c \
|
||||
@@ -120,6 +143,10 @@ EXTRA_DIST = \
|
||||
igc_mac-5.14-ethercat.h \
|
||||
igc_mac-5.14-orig.c \
|
||||
igc_mac-5.14-orig.h \
|
||||
igc_mac-5.15-ethercat.c \
|
||||
igc_mac-5.15-ethercat.h \
|
||||
igc_mac-5.15-orig.c \
|
||||
igc_mac-5.15-orig.h \
|
||||
igc_mac-6.1-ethercat.c \
|
||||
igc_mac-6.1-ethercat.h \
|
||||
igc_mac-6.1-orig.c \
|
||||
@@ -134,6 +161,8 @@ EXTRA_DIST = \
|
||||
igc_mac-6.6-orig.h \
|
||||
igc_main-5.14-ethercat.c \
|
||||
igc_main-5.14-orig.c \
|
||||
igc_main-5.15-ethercat.c \
|
||||
igc_main-5.15-orig.c \
|
||||
igc_main-6.1-ethercat.c \
|
||||
igc_main-6.1-orig.c \
|
||||
igc_main-6.4-ethercat.c \
|
||||
@@ -144,6 +173,10 @@ EXTRA_DIST = \
|
||||
igc_nvm-5.14-ethercat.h \
|
||||
igc_nvm-5.14-orig.c \
|
||||
igc_nvm-5.14-orig.h \
|
||||
igc_nvm-5.15-ethercat.c \
|
||||
igc_nvm-5.15-ethercat.h \
|
||||
igc_nvm-5.15-orig.h \
|
||||
igc_nvm-5.15-orig.c \
|
||||
igc_nvm-6.1-ethercat.c \
|
||||
igc_nvm-6.1-ethercat.h \
|
||||
igc_nvm-6.1-orig.c \
|
||||
@@ -160,6 +193,10 @@ EXTRA_DIST = \
|
||||
igc_phy-5.14-ethercat.h \
|
||||
igc_phy-5.14-orig.c \
|
||||
igc_phy-5.14-orig.h \
|
||||
igc_phy-5.15-ethercat.c \
|
||||
igc_phy-5.15-ethercat.h \
|
||||
igc_phy-5.15-orig.h \
|
||||
igc_phy-5.15-orig.c \
|
||||
igc_phy-6.1-ethercat.c \
|
||||
igc_phy-6.1-ethercat.h \
|
||||
igc_phy-6.1-orig.c \
|
||||
@@ -174,6 +211,8 @@ EXTRA_DIST = \
|
||||
igc_phy-6.6-orig.h \
|
||||
igc_ptp-5.14-ethercat.c \
|
||||
igc_ptp-5.14-orig.c \
|
||||
igc_ptp-5.15-ethercat.c \
|
||||
igc_ptp-5.15-orig.c \
|
||||
igc_ptp-6.1-ethercat.c \
|
||||
igc_ptp-6.1-orig.c \
|
||||
igc_ptp-6.4-ethercat.c \
|
||||
@@ -182,6 +221,8 @@ EXTRA_DIST = \
|
||||
igc_ptp-6.6-orig.c \
|
||||
igc_regs-5.14-ethercat.h \
|
||||
igc_regs-5.14-orig.h \
|
||||
igc_regs-5.15-ethercat.h \
|
||||
igc_regs-5.15-orig.h \
|
||||
igc_regs-6.1-ethercat.h \
|
||||
igc_regs-6.1-orig.h \
|
||||
igc_regs-6.4-ethercat.h \
|
||||
@@ -192,6 +233,10 @@ EXTRA_DIST = \
|
||||
igc_tsn-5.14-ethercat.h \
|
||||
igc_tsn-5.14-orig.c \
|
||||
igc_tsn-5.14-orig.h \
|
||||
igc_tsn-5.15-ethercat.c \
|
||||
igc_tsn-5.15-ethercat.h \
|
||||
igc_tsn-5.15-orig.h \
|
||||
igc_tsn-5.15-orig.c \
|
||||
igc_tsn-6.1-ethercat.c \
|
||||
igc_tsn-6.1-ethercat.h \
|
||||
igc_tsn-6.1-orig.c \
|
||||
@@ -208,6 +253,10 @@ EXTRA_DIST = \
|
||||
igc_xdp-5.14-ethercat.h \
|
||||
igc_xdp-5.14-orig.c \
|
||||
igc_xdp-5.14-orig.h \
|
||||
igc_xdp-5.15-ethercat.c \
|
||||
igc_xdp-5.15-ethercat.h \
|
||||
igc_xdp-5.15-orig.h \
|
||||
igc_xdp-5.15-orig.c \
|
||||
igc_xdp-6.1-ethercat.c \
|
||||
igc_xdp-6.1-ethercat.h \
|
||||
igc_xdp-6.1-orig.c \
|
||||
|
||||
663
devices/igc/igc-5.15-ethercat.h
Normal file
663
devices/igc/igc-5.15-ethercat.h
Normal file
File diff suppressed because it is too large
Load Diff
647
devices/igc/igc-5.15-orig.h
Normal file
647
devices/igc/igc-5.15-orig.h
Normal file
File diff suppressed because it is too large
Load Diff
425
devices/igc/igc_base-5.15-ethercat.c
Normal file
425
devices/igc/igc_base-5.15-ethercat.c
Normal file
@@ -0,0 +1,425 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "igc_hw-5.15-ethercat.h"
|
||||
#include "igc_i225-5.15-ethercat.h"
|
||||
#include "igc_mac-5.15-ethercat.h"
|
||||
#include "igc_base-5.15-ethercat.h"
|
||||
#include "igc-5.15-ethercat.h"
|
||||
|
||||
/**
|
||||
* igc_reset_hw_base - Reset hardware
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* This resets the hardware into a known state. This is a
|
||||
* function pointer entry point called by the api module.
|
||||
*/
|
||||
static s32 igc_reset_hw_base(struct igc_hw *hw)
|
||||
{
|
||||
s32 ret_val;
|
||||
u32 ctrl;
|
||||
|
||||
/* Prevent the PCI-E bus from sticking if there is no TLP connection
|
||||
* on the last TLP read/write transaction when MAC is reset.
|
||||
*/
|
||||
ret_val = igc_disable_pcie_master(hw);
|
||||
if (ret_val)
|
||||
hw_dbg("PCI-E Master disable polling has failed\n");
|
||||
|
||||
hw_dbg("Masking off all interrupts\n");
|
||||
wr32(IGC_IMC, 0xffffffff);
|
||||
|
||||
wr32(IGC_RCTL, 0);
|
||||
wr32(IGC_TCTL, IGC_TCTL_PSP);
|
||||
wrfl();
|
||||
|
||||
usleep_range(10000, 20000);
|
||||
|
||||
ctrl = rd32(IGC_CTRL);
|
||||
|
||||
hw_dbg("Issuing a global reset to MAC\n");
|
||||
wr32(IGC_CTRL, ctrl | IGC_CTRL_DEV_RST);
|
||||
|
||||
ret_val = igc_get_auto_rd_done(hw);
|
||||
if (ret_val) {
|
||||
/* When auto config read does not complete, do not
|
||||
* return with an error. This can happen in situations
|
||||
* where there is no eeprom and prevents getting link.
|
||||
*/
|
||||
hw_dbg("Auto Read Done did not complete\n");
|
||||
}
|
||||
|
||||
/* Clear any pending interrupt events. */
|
||||
wr32(IGC_IMC, 0xffffffff);
|
||||
rd32(IGC_ICR);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_init_nvm_params_base - Init NVM func ptrs.
|
||||
* @hw: pointer to the HW structure
|
||||
*/
|
||||
static s32 igc_init_nvm_params_base(struct igc_hw *hw)
|
||||
{
|
||||
struct igc_nvm_info *nvm = &hw->nvm;
|
||||
u32 eecd = rd32(IGC_EECD);
|
||||
u16 size;
|
||||
|
||||
size = (u16)((eecd & IGC_EECD_SIZE_EX_MASK) >>
|
||||
IGC_EECD_SIZE_EX_SHIFT);
|
||||
|
||||
/* Added to a constant, "size" becomes the left-shift value
|
||||
* for setting word_size.
|
||||
*/
|
||||
size += NVM_WORD_SIZE_BASE_SHIFT;
|
||||
|
||||
/* Just in case size is out of range, cap it to the largest
|
||||
* EEPROM size supported
|
||||
*/
|
||||
if (size > 15)
|
||||
size = 15;
|
||||
|
||||
nvm->type = igc_nvm_eeprom_spi;
|
||||
nvm->word_size = BIT(size);
|
||||
nvm->opcode_bits = 8;
|
||||
nvm->delay_usec = 1;
|
||||
|
||||
nvm->page_size = eecd & IGC_EECD_ADDR_BITS ? 32 : 8;
|
||||
nvm->address_bits = eecd & IGC_EECD_ADDR_BITS ?
|
||||
16 : 8;
|
||||
|
||||
if (nvm->word_size == BIT(15))
|
||||
nvm->page_size = 128;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_setup_copper_link_base - Configure copper link settings
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Configures the link for auto-neg or forced speed and duplex. Then we check
|
||||
* for link, once link is established calls to configure collision distance
|
||||
* and flow control are called.
|
||||
*/
|
||||
static s32 igc_setup_copper_link_base(struct igc_hw *hw)
|
||||
{
|
||||
s32 ret_val = 0;
|
||||
u32 ctrl;
|
||||
|
||||
ctrl = rd32(IGC_CTRL);
|
||||
ctrl |= IGC_CTRL_SLU;
|
||||
ctrl &= ~(IGC_CTRL_FRCSPD | IGC_CTRL_FRCDPX);
|
||||
wr32(IGC_CTRL, ctrl);
|
||||
|
||||
ret_val = igc_setup_copper_link(hw);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_init_mac_params_base - Init MAC func ptrs.
|
||||
* @hw: pointer to the HW structure
|
||||
*/
|
||||
static s32 igc_init_mac_params_base(struct igc_hw *hw)
|
||||
{
|
||||
struct igc_dev_spec_base *dev_spec = &hw->dev_spec._base;
|
||||
struct igc_mac_info *mac = &hw->mac;
|
||||
|
||||
/* Set mta register count */
|
||||
mac->mta_reg_count = 128;
|
||||
mac->rar_entry_count = IGC_RAR_ENTRIES;
|
||||
|
||||
/* reset */
|
||||
mac->ops.reset_hw = igc_reset_hw_base;
|
||||
|
||||
mac->ops.acquire_swfw_sync = igc_acquire_swfw_sync_i225;
|
||||
mac->ops.release_swfw_sync = igc_release_swfw_sync_i225;
|
||||
|
||||
/* Allow a single clear of the SW semaphore on I225 */
|
||||
if (mac->type == igc_i225)
|
||||
dev_spec->clear_semaphore_once = true;
|
||||
|
||||
/* physical interface link setup */
|
||||
mac->ops.setup_physical_interface = igc_setup_copper_link_base;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_init_phy_params_base - Init PHY func ptrs.
|
||||
* @hw: pointer to the HW structure
|
||||
*/
|
||||
static s32 igc_init_phy_params_base(struct igc_hw *hw)
|
||||
{
|
||||
struct igc_phy_info *phy = &hw->phy;
|
||||
s32 ret_val = 0;
|
||||
|
||||
if (hw->phy.media_type != igc_media_type_copper) {
|
||||
phy->type = igc_phy_none;
|
||||
goto out;
|
||||
}
|
||||
|
||||
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT_2500;
|
||||
phy->reset_delay_us = 100;
|
||||
|
||||
/* set lan id */
|
||||
hw->bus.func = (rd32(IGC_STATUS) & IGC_STATUS_FUNC_MASK) >>
|
||||
IGC_STATUS_FUNC_SHIFT;
|
||||
|
||||
/* Make sure the PHY is in a good state. Several people have reported
|
||||
* firmware leaving the PHY's page select register set to something
|
||||
* other than the default of zero, which causes the PHY ID read to
|
||||
* access something other than the intended register.
|
||||
*/
|
||||
ret_val = hw->phy.ops.reset(hw);
|
||||
if (ret_val) {
|
||||
hw_dbg("Error resetting the PHY\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret_val = igc_get_phy_id(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
igc_check_for_copper_link(hw);
|
||||
|
||||
phy->type = igc_phy_i225;
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static s32 igc_get_invariants_base(struct igc_hw *hw)
|
||||
{
|
||||
struct igc_mac_info *mac = &hw->mac;
|
||||
s32 ret_val = 0;
|
||||
|
||||
switch (hw->device_id) {
|
||||
case IGC_DEV_ID_I225_LM:
|
||||
case IGC_DEV_ID_I225_V:
|
||||
case IGC_DEV_ID_I225_I:
|
||||
case IGC_DEV_ID_I220_V:
|
||||
case IGC_DEV_ID_I225_K:
|
||||
case IGC_DEV_ID_I225_K2:
|
||||
case IGC_DEV_ID_I226_K:
|
||||
case IGC_DEV_ID_I225_LMVP:
|
||||
case IGC_DEV_ID_I225_IT:
|
||||
case IGC_DEV_ID_I226_LM:
|
||||
case IGC_DEV_ID_I226_V:
|
||||
case IGC_DEV_ID_I226_IT:
|
||||
case IGC_DEV_ID_I221_V:
|
||||
case IGC_DEV_ID_I226_BLANK_NVM:
|
||||
case IGC_DEV_ID_I225_BLANK_NVM:
|
||||
mac->type = igc_i225;
|
||||
break;
|
||||
default:
|
||||
return -IGC_ERR_MAC_INIT;
|
||||
}
|
||||
|
||||
hw->phy.media_type = igc_media_type_copper;
|
||||
|
||||
/* mac initialization and operations */
|
||||
ret_val = igc_init_mac_params_base(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* NVM initialization */
|
||||
ret_val = igc_init_nvm_params_base(hw);
|
||||
switch (hw->mac.type) {
|
||||
case igc_i225:
|
||||
ret_val = igc_init_nvm_params_i225(hw);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* setup PHY parameters */
|
||||
ret_val = igc_init_phy_params_base(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_acquire_phy_base - Acquire rights to access PHY
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Acquire access rights to the correct PHY. This is a
|
||||
* function pointer entry point called by the api module.
|
||||
*/
|
||||
static s32 igc_acquire_phy_base(struct igc_hw *hw)
|
||||
{
|
||||
u16 mask = IGC_SWFW_PHY0_SM;
|
||||
|
||||
return hw->mac.ops.acquire_swfw_sync(hw, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_release_phy_base - Release rights to access PHY
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* A wrapper to release access rights to the correct PHY. This is a
|
||||
* function pointer entry point called by the api module.
|
||||
*/
|
||||
static void igc_release_phy_base(struct igc_hw *hw)
|
||||
{
|
||||
u16 mask = IGC_SWFW_PHY0_SM;
|
||||
|
||||
hw->mac.ops.release_swfw_sync(hw, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_init_hw_base - Initialize hardware
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* This inits the hardware readying it for operation.
|
||||
*/
|
||||
static s32 igc_init_hw_base(struct igc_hw *hw)
|
||||
{
|
||||
struct igc_mac_info *mac = &hw->mac;
|
||||
u16 i, rar_count = mac->rar_entry_count;
|
||||
s32 ret_val = 0;
|
||||
|
||||
/* Setup the receive address */
|
||||
igc_init_rx_addrs(hw, rar_count);
|
||||
|
||||
/* Zero out the Multicast HASH table */
|
||||
hw_dbg("Zeroing the MTA\n");
|
||||
for (i = 0; i < mac->mta_reg_count; i++)
|
||||
array_wr32(IGC_MTA, i, 0);
|
||||
|
||||
/* Zero out the Unicast HASH table */
|
||||
hw_dbg("Zeroing the UTA\n");
|
||||
for (i = 0; i < mac->uta_reg_count; i++)
|
||||
array_wr32(IGC_UTA, i, 0);
|
||||
|
||||
/* Setup link and flow control */
|
||||
ret_val = igc_setup_link(hw);
|
||||
|
||||
/* Clear all of the statistics registers (clear on read). It is
|
||||
* important that we do this after we have tried to establish link
|
||||
* because the symbol error count will increment wildly if there
|
||||
* is no link.
|
||||
*/
|
||||
igc_clear_hw_cntrs_base(hw);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_power_down_phy_copper_base - Remove link during PHY power down
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* In the case of a PHY power down to save power, or to turn off link during a
|
||||
* driver unload, or wake on lan is not enabled, remove the link.
|
||||
*/
|
||||
void igc_power_down_phy_copper_base(struct igc_hw *hw)
|
||||
{
|
||||
/* If the management interface is not enabled, then power down */
|
||||
if (!(igc_enable_mng_pass_thru(hw) || igc_check_reset_block(hw)))
|
||||
igc_power_down_phy_copper(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_rx_fifo_flush_base - Clean rx fifo after Rx enable
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* After Rx enable, if manageability is enabled then there is likely some
|
||||
* bad data at the start of the fifo and possibly in the DMA fifo. This
|
||||
* function clears the fifos and flushes any packets that came in as rx was
|
||||
* being enabled.
|
||||
*/
|
||||
void igc_rx_fifo_flush_base(struct igc_hw *hw)
|
||||
{
|
||||
u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
|
||||
int i, ms_wait;
|
||||
|
||||
/* disable IPv6 options as per hardware errata */
|
||||
rfctl = rd32(IGC_RFCTL);
|
||||
rfctl |= IGC_RFCTL_IPV6_EX_DIS;
|
||||
wr32(IGC_RFCTL, rfctl);
|
||||
|
||||
if (!(rd32(IGC_MANC) & IGC_MANC_RCV_TCO_EN))
|
||||
return;
|
||||
|
||||
/* Disable all Rx queues */
|
||||
for (i = 0; i < 4; i++) {
|
||||
rxdctl[i] = rd32(IGC_RXDCTL(i));
|
||||
wr32(IGC_RXDCTL(i),
|
||||
rxdctl[i] & ~IGC_RXDCTL_QUEUE_ENABLE);
|
||||
}
|
||||
/* Poll all queues to verify they have shut down */
|
||||
for (ms_wait = 0; ms_wait < 10; ms_wait++) {
|
||||
usleep_range(1000, 2000);
|
||||
rx_enabled = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
rx_enabled |= rd32(IGC_RXDCTL(i));
|
||||
if (!(rx_enabled & IGC_RXDCTL_QUEUE_ENABLE))
|
||||
break;
|
||||
}
|
||||
|
||||
if (ms_wait == 10)
|
||||
hw_dbg("Queue disable timed out after 10ms\n");
|
||||
|
||||
/* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
|
||||
* incoming packets are rejected. Set enable and wait 2ms so that
|
||||
* any packet that was coming in as RCTL.EN was set is flushed
|
||||
*/
|
||||
wr32(IGC_RFCTL, rfctl & ~IGC_RFCTL_LEF);
|
||||
|
||||
rlpml = rd32(IGC_RLPML);
|
||||
wr32(IGC_RLPML, 0);
|
||||
|
||||
rctl = rd32(IGC_RCTL);
|
||||
temp_rctl = rctl & ~(IGC_RCTL_EN | IGC_RCTL_SBP);
|
||||
temp_rctl |= IGC_RCTL_LPE;
|
||||
|
||||
wr32(IGC_RCTL, temp_rctl);
|
||||
wr32(IGC_RCTL, temp_rctl | IGC_RCTL_EN);
|
||||
wrfl();
|
||||
usleep_range(2000, 3000);
|
||||
|
||||
/* Enable Rx queues that were previously enabled and restore our
|
||||
* previous state
|
||||
*/
|
||||
for (i = 0; i < 4; i++)
|
||||
wr32(IGC_RXDCTL(i), rxdctl[i]);
|
||||
wr32(IGC_RCTL, rctl);
|
||||
wrfl();
|
||||
|
||||
wr32(IGC_RLPML, rlpml);
|
||||
wr32(IGC_RFCTL, rfctl);
|
||||
|
||||
/* Flush receive errors generated by workaround */
|
||||
rd32(IGC_ROC);
|
||||
rd32(IGC_RNBC);
|
||||
rd32(IGC_MPC);
|
||||
}
|
||||
|
||||
static struct igc_mac_operations igc_mac_ops_base = {
|
||||
.init_hw = igc_init_hw_base,
|
||||
.check_for_link = igc_check_for_copper_link,
|
||||
.rar_set = igc_rar_set,
|
||||
.read_mac_addr = igc_read_mac_addr,
|
||||
.get_speed_and_duplex = igc_get_speed_and_duplex_copper,
|
||||
};
|
||||
|
||||
static const struct igc_phy_operations igc_phy_ops_base = {
|
||||
.acquire = igc_acquire_phy_base,
|
||||
.release = igc_release_phy_base,
|
||||
.reset = igc_phy_hw_reset,
|
||||
.read_reg = igc_read_phy_reg_gpy,
|
||||
.write_reg = igc_write_phy_reg_gpy,
|
||||
};
|
||||
|
||||
const struct igc_info igc_base_info = {
|
||||
.get_invariants = igc_get_invariants_base,
|
||||
.mac_ops = &igc_mac_ops_base,
|
||||
.phy_ops = &igc_phy_ops_base,
|
||||
};
|
||||
92
devices/igc/igc_base-5.15-ethercat.h
Normal file
92
devices/igc/igc_base-5.15-ethercat.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#ifndef _IGC_BASE_H_
|
||||
#define _IGC_BASE_H_
|
||||
|
||||
/* forward declaration */
|
||||
void igc_rx_fifo_flush_base(struct igc_hw *hw);
|
||||
void igc_power_down_phy_copper_base(struct igc_hw *hw);
|
||||
|
||||
/* Transmit Descriptor - Advanced */
|
||||
union igc_adv_tx_desc {
|
||||
struct {
|
||||
__le64 buffer_addr; /* Address of descriptor's data buf */
|
||||
__le32 cmd_type_len;
|
||||
__le32 olinfo_status;
|
||||
} read;
|
||||
struct {
|
||||
__le64 rsvd; /* Reserved */
|
||||
__le32 nxtseq_seed;
|
||||
__le32 status;
|
||||
} wb;
|
||||
};
|
||||
|
||||
/* Context descriptors */
|
||||
struct igc_adv_tx_context_desc {
|
||||
__le32 vlan_macip_lens;
|
||||
__le32 launch_time;
|
||||
__le32 type_tucmd_mlhl;
|
||||
__le32 mss_l4len_idx;
|
||||
};
|
||||
|
||||
/* Adv Transmit Descriptor Config Masks */
|
||||
#define IGC_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 Timestamp packet */
|
||||
#define IGC_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */
|
||||
#define IGC_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
|
||||
#define IGC_ADVTXD_DCMD_EOP 0x01000000 /* End of Packet */
|
||||
#define IGC_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
|
||||
#define IGC_ADVTXD_DCMD_RS 0x08000000 /* Report Status */
|
||||
#define IGC_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */
|
||||
#define IGC_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */
|
||||
#define IGC_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
|
||||
#define IGC_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
|
||||
|
||||
#define IGC_RAR_ENTRIES 16
|
||||
|
||||
/* Receive Descriptor - Advanced */
|
||||
union igc_adv_rx_desc {
|
||||
struct {
|
||||
__le64 pkt_addr; /* Packet buffer address */
|
||||
__le64 hdr_addr; /* Header buffer address */
|
||||
} read;
|
||||
struct {
|
||||
struct {
|
||||
union {
|
||||
__le32 data;
|
||||
struct {
|
||||
__le16 pkt_info; /*RSS type, Pkt type*/
|
||||
/* Split Header, header buffer len */
|
||||
__le16 hdr_info;
|
||||
} hs_rss;
|
||||
} lo_dword;
|
||||
union {
|
||||
__le32 rss; /* RSS Hash */
|
||||
struct {
|
||||
__le16 ip_id; /* IP id */
|
||||
__le16 csum; /* Packet Checksum */
|
||||
} csum_ip;
|
||||
} hi_dword;
|
||||
} lower;
|
||||
struct {
|
||||
__le32 status_error; /* ext status/error */
|
||||
__le16 length; /* Packet length */
|
||||
__le16 vlan; /* VLAN tag */
|
||||
} upper;
|
||||
} wb; /* writeback */
|
||||
};
|
||||
|
||||
/* Additional Transmit Descriptor Control definitions */
|
||||
#define IGC_TXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Tx Queue */
|
||||
#define IGC_TXDCTL_SWFLUSH 0x04000000 /* Transmit Software Flush */
|
||||
|
||||
/* Additional Receive Descriptor Control definitions */
|
||||
#define IGC_RXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Rx Queue */
|
||||
#define IGC_RXDCTL_SWFLUSH 0x04000000 /* Receive Software Flush */
|
||||
|
||||
/* SRRCTL bit definitions */
|
||||
#define IGC_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
|
||||
#define IGC_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
|
||||
#define IGC_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
|
||||
|
||||
#endif /* _IGC_BASE_H */
|
||||
425
devices/igc/igc_base-5.15-orig.c
Normal file
425
devices/igc/igc_base-5.15-orig.c
Normal file
@@ -0,0 +1,425 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "igc_hw.h"
|
||||
#include "igc_i225.h"
|
||||
#include "igc_mac.h"
|
||||
#include "igc_base.h"
|
||||
#include "igc.h"
|
||||
|
||||
/**
|
||||
* igc_reset_hw_base - Reset hardware
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* This resets the hardware into a known state. This is a
|
||||
* function pointer entry point called by the api module.
|
||||
*/
|
||||
static s32 igc_reset_hw_base(struct igc_hw *hw)
|
||||
{
|
||||
s32 ret_val;
|
||||
u32 ctrl;
|
||||
|
||||
/* Prevent the PCI-E bus from sticking if there is no TLP connection
|
||||
* on the last TLP read/write transaction when MAC is reset.
|
||||
*/
|
||||
ret_val = igc_disable_pcie_master(hw);
|
||||
if (ret_val)
|
||||
hw_dbg("PCI-E Master disable polling has failed\n");
|
||||
|
||||
hw_dbg("Masking off all interrupts\n");
|
||||
wr32(IGC_IMC, 0xffffffff);
|
||||
|
||||
wr32(IGC_RCTL, 0);
|
||||
wr32(IGC_TCTL, IGC_TCTL_PSP);
|
||||
wrfl();
|
||||
|
||||
usleep_range(10000, 20000);
|
||||
|
||||
ctrl = rd32(IGC_CTRL);
|
||||
|
||||
hw_dbg("Issuing a global reset to MAC\n");
|
||||
wr32(IGC_CTRL, ctrl | IGC_CTRL_DEV_RST);
|
||||
|
||||
ret_val = igc_get_auto_rd_done(hw);
|
||||
if (ret_val) {
|
||||
/* When auto config read does not complete, do not
|
||||
* return with an error. This can happen in situations
|
||||
* where there is no eeprom and prevents getting link.
|
||||
*/
|
||||
hw_dbg("Auto Read Done did not complete\n");
|
||||
}
|
||||
|
||||
/* Clear any pending interrupt events. */
|
||||
wr32(IGC_IMC, 0xffffffff);
|
||||
rd32(IGC_ICR);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_init_nvm_params_base - Init NVM func ptrs.
|
||||
* @hw: pointer to the HW structure
|
||||
*/
|
||||
static s32 igc_init_nvm_params_base(struct igc_hw *hw)
|
||||
{
|
||||
struct igc_nvm_info *nvm = &hw->nvm;
|
||||
u32 eecd = rd32(IGC_EECD);
|
||||
u16 size;
|
||||
|
||||
size = (u16)((eecd & IGC_EECD_SIZE_EX_MASK) >>
|
||||
IGC_EECD_SIZE_EX_SHIFT);
|
||||
|
||||
/* Added to a constant, "size" becomes the left-shift value
|
||||
* for setting word_size.
|
||||
*/
|
||||
size += NVM_WORD_SIZE_BASE_SHIFT;
|
||||
|
||||
/* Just in case size is out of range, cap it to the largest
|
||||
* EEPROM size supported
|
||||
*/
|
||||
if (size > 15)
|
||||
size = 15;
|
||||
|
||||
nvm->type = igc_nvm_eeprom_spi;
|
||||
nvm->word_size = BIT(size);
|
||||
nvm->opcode_bits = 8;
|
||||
nvm->delay_usec = 1;
|
||||
|
||||
nvm->page_size = eecd & IGC_EECD_ADDR_BITS ? 32 : 8;
|
||||
nvm->address_bits = eecd & IGC_EECD_ADDR_BITS ?
|
||||
16 : 8;
|
||||
|
||||
if (nvm->word_size == BIT(15))
|
||||
nvm->page_size = 128;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_setup_copper_link_base - Configure copper link settings
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Configures the link for auto-neg or forced speed and duplex. Then we check
|
||||
* for link, once link is established calls to configure collision distance
|
||||
* and flow control are called.
|
||||
*/
|
||||
static s32 igc_setup_copper_link_base(struct igc_hw *hw)
|
||||
{
|
||||
s32 ret_val = 0;
|
||||
u32 ctrl;
|
||||
|
||||
ctrl = rd32(IGC_CTRL);
|
||||
ctrl |= IGC_CTRL_SLU;
|
||||
ctrl &= ~(IGC_CTRL_FRCSPD | IGC_CTRL_FRCDPX);
|
||||
wr32(IGC_CTRL, ctrl);
|
||||
|
||||
ret_val = igc_setup_copper_link(hw);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_init_mac_params_base - Init MAC func ptrs.
|
||||
* @hw: pointer to the HW structure
|
||||
*/
|
||||
static s32 igc_init_mac_params_base(struct igc_hw *hw)
|
||||
{
|
||||
struct igc_dev_spec_base *dev_spec = &hw->dev_spec._base;
|
||||
struct igc_mac_info *mac = &hw->mac;
|
||||
|
||||
/* Set mta register count */
|
||||
mac->mta_reg_count = 128;
|
||||
mac->rar_entry_count = IGC_RAR_ENTRIES;
|
||||
|
||||
/* reset */
|
||||
mac->ops.reset_hw = igc_reset_hw_base;
|
||||
|
||||
mac->ops.acquire_swfw_sync = igc_acquire_swfw_sync_i225;
|
||||
mac->ops.release_swfw_sync = igc_release_swfw_sync_i225;
|
||||
|
||||
/* Allow a single clear of the SW semaphore on I225 */
|
||||
if (mac->type == igc_i225)
|
||||
dev_spec->clear_semaphore_once = true;
|
||||
|
||||
/* physical interface link setup */
|
||||
mac->ops.setup_physical_interface = igc_setup_copper_link_base;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_init_phy_params_base - Init PHY func ptrs.
|
||||
* @hw: pointer to the HW structure
|
||||
*/
|
||||
static s32 igc_init_phy_params_base(struct igc_hw *hw)
|
||||
{
|
||||
struct igc_phy_info *phy = &hw->phy;
|
||||
s32 ret_val = 0;
|
||||
|
||||
if (hw->phy.media_type != igc_media_type_copper) {
|
||||
phy->type = igc_phy_none;
|
||||
goto out;
|
||||
}
|
||||
|
||||
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT_2500;
|
||||
phy->reset_delay_us = 100;
|
||||
|
||||
/* set lan id */
|
||||
hw->bus.func = (rd32(IGC_STATUS) & IGC_STATUS_FUNC_MASK) >>
|
||||
IGC_STATUS_FUNC_SHIFT;
|
||||
|
||||
/* Make sure the PHY is in a good state. Several people have reported
|
||||
* firmware leaving the PHY's page select register set to something
|
||||
* other than the default of zero, which causes the PHY ID read to
|
||||
* access something other than the intended register.
|
||||
*/
|
||||
ret_val = hw->phy.ops.reset(hw);
|
||||
if (ret_val) {
|
||||
hw_dbg("Error resetting the PHY\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret_val = igc_get_phy_id(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
igc_check_for_copper_link(hw);
|
||||
|
||||
phy->type = igc_phy_i225;
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static s32 igc_get_invariants_base(struct igc_hw *hw)
|
||||
{
|
||||
struct igc_mac_info *mac = &hw->mac;
|
||||
s32 ret_val = 0;
|
||||
|
||||
switch (hw->device_id) {
|
||||
case IGC_DEV_ID_I225_LM:
|
||||
case IGC_DEV_ID_I225_V:
|
||||
case IGC_DEV_ID_I225_I:
|
||||
case IGC_DEV_ID_I220_V:
|
||||
case IGC_DEV_ID_I225_K:
|
||||
case IGC_DEV_ID_I225_K2:
|
||||
case IGC_DEV_ID_I226_K:
|
||||
case IGC_DEV_ID_I225_LMVP:
|
||||
case IGC_DEV_ID_I225_IT:
|
||||
case IGC_DEV_ID_I226_LM:
|
||||
case IGC_DEV_ID_I226_V:
|
||||
case IGC_DEV_ID_I226_IT:
|
||||
case IGC_DEV_ID_I221_V:
|
||||
case IGC_DEV_ID_I226_BLANK_NVM:
|
||||
case IGC_DEV_ID_I225_BLANK_NVM:
|
||||
mac->type = igc_i225;
|
||||
break;
|
||||
default:
|
||||
return -IGC_ERR_MAC_INIT;
|
||||
}
|
||||
|
||||
hw->phy.media_type = igc_media_type_copper;
|
||||
|
||||
/* mac initialization and operations */
|
||||
ret_val = igc_init_mac_params_base(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* NVM initialization */
|
||||
ret_val = igc_init_nvm_params_base(hw);
|
||||
switch (hw->mac.type) {
|
||||
case igc_i225:
|
||||
ret_val = igc_init_nvm_params_i225(hw);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* setup PHY parameters */
|
||||
ret_val = igc_init_phy_params_base(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_acquire_phy_base - Acquire rights to access PHY
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Acquire access rights to the correct PHY. This is a
|
||||
* function pointer entry point called by the api module.
|
||||
*/
|
||||
static s32 igc_acquire_phy_base(struct igc_hw *hw)
|
||||
{
|
||||
u16 mask = IGC_SWFW_PHY0_SM;
|
||||
|
||||
return hw->mac.ops.acquire_swfw_sync(hw, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_release_phy_base - Release rights to access PHY
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* A wrapper to release access rights to the correct PHY. This is a
|
||||
* function pointer entry point called by the api module.
|
||||
*/
|
||||
static void igc_release_phy_base(struct igc_hw *hw)
|
||||
{
|
||||
u16 mask = IGC_SWFW_PHY0_SM;
|
||||
|
||||
hw->mac.ops.release_swfw_sync(hw, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_init_hw_base - Initialize hardware
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* This inits the hardware readying it for operation.
|
||||
*/
|
||||
static s32 igc_init_hw_base(struct igc_hw *hw)
|
||||
{
|
||||
struct igc_mac_info *mac = &hw->mac;
|
||||
u16 i, rar_count = mac->rar_entry_count;
|
||||
s32 ret_val = 0;
|
||||
|
||||
/* Setup the receive address */
|
||||
igc_init_rx_addrs(hw, rar_count);
|
||||
|
||||
/* Zero out the Multicast HASH table */
|
||||
hw_dbg("Zeroing the MTA\n");
|
||||
for (i = 0; i < mac->mta_reg_count; i++)
|
||||
array_wr32(IGC_MTA, i, 0);
|
||||
|
||||
/* Zero out the Unicast HASH table */
|
||||
hw_dbg("Zeroing the UTA\n");
|
||||
for (i = 0; i < mac->uta_reg_count; i++)
|
||||
array_wr32(IGC_UTA, i, 0);
|
||||
|
||||
/* Setup link and flow control */
|
||||
ret_val = igc_setup_link(hw);
|
||||
|
||||
/* Clear all of the statistics registers (clear on read). It is
|
||||
* important that we do this after we have tried to establish link
|
||||
* because the symbol error count will increment wildly if there
|
||||
* is no link.
|
||||
*/
|
||||
igc_clear_hw_cntrs_base(hw);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_power_down_phy_copper_base - Remove link during PHY power down
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* In the case of a PHY power down to save power, or to turn off link during a
|
||||
* driver unload, or wake on lan is not enabled, remove the link.
|
||||
*/
|
||||
void igc_power_down_phy_copper_base(struct igc_hw *hw)
|
||||
{
|
||||
/* If the management interface is not enabled, then power down */
|
||||
if (!(igc_enable_mng_pass_thru(hw) || igc_check_reset_block(hw)))
|
||||
igc_power_down_phy_copper(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_rx_fifo_flush_base - Clean rx fifo after Rx enable
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* After Rx enable, if manageability is enabled then there is likely some
|
||||
* bad data at the start of the fifo and possibly in the DMA fifo. This
|
||||
* function clears the fifos and flushes any packets that came in as rx was
|
||||
* being enabled.
|
||||
*/
|
||||
void igc_rx_fifo_flush_base(struct igc_hw *hw)
|
||||
{
|
||||
u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
|
||||
int i, ms_wait;
|
||||
|
||||
/* disable IPv6 options as per hardware errata */
|
||||
rfctl = rd32(IGC_RFCTL);
|
||||
rfctl |= IGC_RFCTL_IPV6_EX_DIS;
|
||||
wr32(IGC_RFCTL, rfctl);
|
||||
|
||||
if (!(rd32(IGC_MANC) & IGC_MANC_RCV_TCO_EN))
|
||||
return;
|
||||
|
||||
/* Disable all Rx queues */
|
||||
for (i = 0; i < 4; i++) {
|
||||
rxdctl[i] = rd32(IGC_RXDCTL(i));
|
||||
wr32(IGC_RXDCTL(i),
|
||||
rxdctl[i] & ~IGC_RXDCTL_QUEUE_ENABLE);
|
||||
}
|
||||
/* Poll all queues to verify they have shut down */
|
||||
for (ms_wait = 0; ms_wait < 10; ms_wait++) {
|
||||
usleep_range(1000, 2000);
|
||||
rx_enabled = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
rx_enabled |= rd32(IGC_RXDCTL(i));
|
||||
if (!(rx_enabled & IGC_RXDCTL_QUEUE_ENABLE))
|
||||
break;
|
||||
}
|
||||
|
||||
if (ms_wait == 10)
|
||||
hw_dbg("Queue disable timed out after 10ms\n");
|
||||
|
||||
/* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
|
||||
* incoming packets are rejected. Set enable and wait 2ms so that
|
||||
* any packet that was coming in as RCTL.EN was set is flushed
|
||||
*/
|
||||
wr32(IGC_RFCTL, rfctl & ~IGC_RFCTL_LEF);
|
||||
|
||||
rlpml = rd32(IGC_RLPML);
|
||||
wr32(IGC_RLPML, 0);
|
||||
|
||||
rctl = rd32(IGC_RCTL);
|
||||
temp_rctl = rctl & ~(IGC_RCTL_EN | IGC_RCTL_SBP);
|
||||
temp_rctl |= IGC_RCTL_LPE;
|
||||
|
||||
wr32(IGC_RCTL, temp_rctl);
|
||||
wr32(IGC_RCTL, temp_rctl | IGC_RCTL_EN);
|
||||
wrfl();
|
||||
usleep_range(2000, 3000);
|
||||
|
||||
/* Enable Rx queues that were previously enabled and restore our
|
||||
* previous state
|
||||
*/
|
||||
for (i = 0; i < 4; i++)
|
||||
wr32(IGC_RXDCTL(i), rxdctl[i]);
|
||||
wr32(IGC_RCTL, rctl);
|
||||
wrfl();
|
||||
|
||||
wr32(IGC_RLPML, rlpml);
|
||||
wr32(IGC_RFCTL, rfctl);
|
||||
|
||||
/* Flush receive errors generated by workaround */
|
||||
rd32(IGC_ROC);
|
||||
rd32(IGC_RNBC);
|
||||
rd32(IGC_MPC);
|
||||
}
|
||||
|
||||
static struct igc_mac_operations igc_mac_ops_base = {
|
||||
.init_hw = igc_init_hw_base,
|
||||
.check_for_link = igc_check_for_copper_link,
|
||||
.rar_set = igc_rar_set,
|
||||
.read_mac_addr = igc_read_mac_addr,
|
||||
.get_speed_and_duplex = igc_get_speed_and_duplex_copper,
|
||||
};
|
||||
|
||||
static const struct igc_phy_operations igc_phy_ops_base = {
|
||||
.acquire = igc_acquire_phy_base,
|
||||
.release = igc_release_phy_base,
|
||||
.reset = igc_phy_hw_reset,
|
||||
.read_reg = igc_read_phy_reg_gpy,
|
||||
.write_reg = igc_write_phy_reg_gpy,
|
||||
};
|
||||
|
||||
const struct igc_info igc_base_info = {
|
||||
.get_invariants = igc_get_invariants_base,
|
||||
.mac_ops = &igc_mac_ops_base,
|
||||
.phy_ops = &igc_phy_ops_base,
|
||||
};
|
||||
92
devices/igc/igc_base-5.15-orig.h
Normal file
92
devices/igc/igc_base-5.15-orig.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#ifndef _IGC_BASE_H_
|
||||
#define _IGC_BASE_H_
|
||||
|
||||
/* forward declaration */
|
||||
void igc_rx_fifo_flush_base(struct igc_hw *hw);
|
||||
void igc_power_down_phy_copper_base(struct igc_hw *hw);
|
||||
|
||||
/* Transmit Descriptor - Advanced */
|
||||
union igc_adv_tx_desc {
|
||||
struct {
|
||||
__le64 buffer_addr; /* Address of descriptor's data buf */
|
||||
__le32 cmd_type_len;
|
||||
__le32 olinfo_status;
|
||||
} read;
|
||||
struct {
|
||||
__le64 rsvd; /* Reserved */
|
||||
__le32 nxtseq_seed;
|
||||
__le32 status;
|
||||
} wb;
|
||||
};
|
||||
|
||||
/* Context descriptors */
|
||||
struct igc_adv_tx_context_desc {
|
||||
__le32 vlan_macip_lens;
|
||||
__le32 launch_time;
|
||||
__le32 type_tucmd_mlhl;
|
||||
__le32 mss_l4len_idx;
|
||||
};
|
||||
|
||||
/* Adv Transmit Descriptor Config Masks */
|
||||
#define IGC_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 Timestamp packet */
|
||||
#define IGC_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */
|
||||
#define IGC_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
|
||||
#define IGC_ADVTXD_DCMD_EOP 0x01000000 /* End of Packet */
|
||||
#define IGC_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
|
||||
#define IGC_ADVTXD_DCMD_RS 0x08000000 /* Report Status */
|
||||
#define IGC_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */
|
||||
#define IGC_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */
|
||||
#define IGC_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
|
||||
#define IGC_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
|
||||
|
||||
#define IGC_RAR_ENTRIES 16
|
||||
|
||||
/* Receive Descriptor - Advanced */
|
||||
union igc_adv_rx_desc {
|
||||
struct {
|
||||
__le64 pkt_addr; /* Packet buffer address */
|
||||
__le64 hdr_addr; /* Header buffer address */
|
||||
} read;
|
||||
struct {
|
||||
struct {
|
||||
union {
|
||||
__le32 data;
|
||||
struct {
|
||||
__le16 pkt_info; /*RSS type, Pkt type*/
|
||||
/* Split Header, header buffer len */
|
||||
__le16 hdr_info;
|
||||
} hs_rss;
|
||||
} lo_dword;
|
||||
union {
|
||||
__le32 rss; /* RSS Hash */
|
||||
struct {
|
||||
__le16 ip_id; /* IP id */
|
||||
__le16 csum; /* Packet Checksum */
|
||||
} csum_ip;
|
||||
} hi_dword;
|
||||
} lower;
|
||||
struct {
|
||||
__le32 status_error; /* ext status/error */
|
||||
__le16 length; /* Packet length */
|
||||
__le16 vlan; /* VLAN tag */
|
||||
} upper;
|
||||
} wb; /* writeback */
|
||||
};
|
||||
|
||||
/* Additional Transmit Descriptor Control definitions */
|
||||
#define IGC_TXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Tx Queue */
|
||||
#define IGC_TXDCTL_SWFLUSH 0x04000000 /* Transmit Software Flush */
|
||||
|
||||
/* Additional Receive Descriptor Control definitions */
|
||||
#define IGC_RXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Rx Queue */
|
||||
#define IGC_RXDCTL_SWFLUSH 0x04000000 /* Receive Software Flush */
|
||||
|
||||
/* SRRCTL bit definitions */
|
||||
#define IGC_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
|
||||
#define IGC_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
|
||||
#define IGC_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
|
||||
|
||||
#endif /* _IGC_BASE_H */
|
||||
677
devices/igc/igc_defines-5.15-ethercat.h
Normal file
677
devices/igc/igc_defines-5.15-ethercat.h
Normal file
File diff suppressed because it is too large
Load Diff
677
devices/igc/igc_defines-5.15-orig.h
Normal file
677
devices/igc/igc_defines-5.15-orig.h
Normal file
File diff suppressed because it is too large
Load Diff
186
devices/igc/igc_diag-5.15-ethercat.c
Normal file
186
devices/igc/igc_diag-5.15-ethercat.c
Normal file
@@ -0,0 +1,186 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2020 Intel Corporation */
|
||||
|
||||
#include "igc-5.15-ethercat.h"
|
||||
#include "igc_diag-5.15-ethercat.h"
|
||||
|
||||
static struct igc_reg_test reg_test[] = {
|
||||
{ IGC_FCAL, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ IGC_FCAH, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
|
||||
{ IGC_FCT, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
|
||||
{ IGC_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ IGC_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 },
|
||||
{ IGC_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
|
||||
{ IGC_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
|
||||
{ IGC_FCRTH, 1, PATTERN_TEST, 0x0003FFF0, 0x0003FFF0 },
|
||||
{ IGC_FCTTV, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
|
||||
{ IGC_TIPG, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
|
||||
{ IGC_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ IGC_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 },
|
||||
{ IGC_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
|
||||
{ IGC_TDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
|
||||
{ IGC_RCTL, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
|
||||
{ IGC_RCTL, 1, SET_READ_TEST, 0x04CFB2FE, 0x003FFFFB },
|
||||
{ IGC_RCTL, 1, SET_READ_TEST, 0x04CFB2FE, 0xFFFFFFFF },
|
||||
{ IGC_TCTL, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
|
||||
{ IGC_RA, 16, TABLE64_TEST_LO,
|
||||
0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ IGC_RA, 16, TABLE64_TEST_HI,
|
||||
0x900FFFFF, 0xFFFFFFFF },
|
||||
{ IGC_MTA, 128, TABLE32_TEST,
|
||||
0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static bool reg_pattern_test(struct igc_adapter *adapter, u64 *data, int reg,
|
||||
u32 mask, u32 write)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
u32 pat, val, before;
|
||||
static const u32 test_pattern[] = {
|
||||
0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
|
||||
};
|
||||
|
||||
for (pat = 0; pat < ARRAY_SIZE(test_pattern); pat++) {
|
||||
before = rd32(reg);
|
||||
wr32(reg, test_pattern[pat] & write);
|
||||
val = rd32(reg);
|
||||
if (val != (test_pattern[pat] & write & mask)) {
|
||||
netdev_err(adapter->netdev,
|
||||
"pattern test reg %04X failed: got 0x%08X expected 0x%08X",
|
||||
reg, val, test_pattern[pat] & write & mask);
|
||||
*data = reg;
|
||||
wr32(reg, before);
|
||||
return false;
|
||||
}
|
||||
wr32(reg, before);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool reg_set_and_check(struct igc_adapter *adapter, u64 *data, int reg,
|
||||
u32 mask, u32 write)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
u32 val, before;
|
||||
|
||||
before = rd32(reg);
|
||||
wr32(reg, write & mask);
|
||||
val = rd32(reg);
|
||||
if ((write & mask) != (val & mask)) {
|
||||
netdev_err(adapter->netdev,
|
||||
"set/check reg %04X test failed: got 0x%08X expected 0x%08X",
|
||||
reg, (val & mask), (write & mask));
|
||||
*data = reg;
|
||||
wr32(reg, before);
|
||||
return false;
|
||||
}
|
||||
wr32(reg, before);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool igc_reg_test(struct igc_adapter *adapter, u64 *data)
|
||||
{
|
||||
struct igc_reg_test *test = reg_test;
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
u32 value, before, after;
|
||||
u32 i, toggle, b = false;
|
||||
|
||||
/* Because the status register is such a special case,
|
||||
* we handle it separately from the rest of the register
|
||||
* tests. Some bits are read-only, some toggle, and some
|
||||
* are writeable.
|
||||
*/
|
||||
toggle = 0x6800D3;
|
||||
before = rd32(IGC_STATUS);
|
||||
value = before & toggle;
|
||||
wr32(IGC_STATUS, toggle);
|
||||
after = rd32(IGC_STATUS) & toggle;
|
||||
if (value != after) {
|
||||
netdev_err(adapter->netdev,
|
||||
"failed STATUS register test got: 0x%08X expected: 0x%08X",
|
||||
after, value);
|
||||
*data = 1;
|
||||
return false;
|
||||
}
|
||||
/* restore previous status */
|
||||
wr32(IGC_STATUS, before);
|
||||
|
||||
/* Perform the remainder of the register test, looping through
|
||||
* the test table until we either fail or reach the null entry.
|
||||
*/
|
||||
while (test->reg) {
|
||||
for (i = 0; i < test->array_len; i++) {
|
||||
switch (test->test_type) {
|
||||
case PATTERN_TEST:
|
||||
b = reg_pattern_test(adapter, data,
|
||||
test->reg + (i * 0x40),
|
||||
test->mask,
|
||||
test->write);
|
||||
break;
|
||||
case SET_READ_TEST:
|
||||
b = reg_set_and_check(adapter, data,
|
||||
test->reg + (i * 0x40),
|
||||
test->mask,
|
||||
test->write);
|
||||
break;
|
||||
case TABLE64_TEST_LO:
|
||||
b = reg_pattern_test(adapter, data,
|
||||
test->reg + (i * 8),
|
||||
test->mask,
|
||||
test->write);
|
||||
break;
|
||||
case TABLE64_TEST_HI:
|
||||
b = reg_pattern_test(adapter, data,
|
||||
test->reg + 4 + (i * 8),
|
||||
test->mask,
|
||||
test->write);
|
||||
break;
|
||||
case TABLE32_TEST:
|
||||
b = reg_pattern_test(adapter, data,
|
||||
test->reg + (i * 4),
|
||||
test->mask,
|
||||
test->write);
|
||||
break;
|
||||
}
|
||||
if (!b)
|
||||
return false;
|
||||
}
|
||||
test++;
|
||||
}
|
||||
*data = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool igc_eeprom_test(struct igc_adapter *adapter, u64 *data)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
|
||||
*data = 0;
|
||||
|
||||
if (hw->nvm.ops.validate(hw) != IGC_SUCCESS) {
|
||||
*data = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool igc_link_test(struct igc_adapter *adapter, u64 *data)
|
||||
{
|
||||
bool link_up;
|
||||
|
||||
*data = 0;
|
||||
|
||||
/* add delay to give enough time for autonegotioation to finish */
|
||||
if (adapter->hw.mac.autoneg)
|
||||
ssleep(5);
|
||||
|
||||
link_up = igc_has_link(adapter);
|
||||
if (!link_up) {
|
||||
*data = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
30
devices/igc/igc_diag-5.15-ethercat.h
Normal file
30
devices/igc/igc_diag-5.15-ethercat.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2020 Intel Corporation */
|
||||
|
||||
bool igc_reg_test(struct igc_adapter *adapter, u64 *data);
|
||||
bool igc_eeprom_test(struct igc_adapter *adapter, u64 *data);
|
||||
bool igc_link_test(struct igc_adapter *adapter, u64 *data);
|
||||
|
||||
struct igc_reg_test {
|
||||
u16 reg;
|
||||
u8 array_len;
|
||||
u8 test_type;
|
||||
u32 mask;
|
||||
u32 write;
|
||||
};
|
||||
|
||||
/* In the hardware, registers are laid out either singly, in arrays
|
||||
* spaced 0x40 bytes apart, or in contiguous tables. We assume
|
||||
* most tests take place on arrays or single registers (handled
|
||||
* as a single-element array) and special-case the tables.
|
||||
* Table tests are always pattern tests.
|
||||
*
|
||||
* We also make provision for some required setup steps by specifying
|
||||
* registers to be written without any read-back testing.
|
||||
*/
|
||||
|
||||
#define PATTERN_TEST 1
|
||||
#define SET_READ_TEST 2
|
||||
#define TABLE32_TEST 3
|
||||
#define TABLE64_TEST_LO 4
|
||||
#define TABLE64_TEST_HI 5
|
||||
186
devices/igc/igc_diag-5.15-orig.c
Normal file
186
devices/igc/igc_diag-5.15-orig.c
Normal file
@@ -0,0 +1,186 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2020 Intel Corporation */
|
||||
|
||||
#include "igc.h"
|
||||
#include "igc_diag.h"
|
||||
|
||||
static struct igc_reg_test reg_test[] = {
|
||||
{ IGC_FCAL, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ IGC_FCAH, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
|
||||
{ IGC_FCT, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
|
||||
{ IGC_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ IGC_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 },
|
||||
{ IGC_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
|
||||
{ IGC_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
|
||||
{ IGC_FCRTH, 1, PATTERN_TEST, 0x0003FFF0, 0x0003FFF0 },
|
||||
{ IGC_FCTTV, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
|
||||
{ IGC_TIPG, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
|
||||
{ IGC_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ IGC_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 },
|
||||
{ IGC_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
|
||||
{ IGC_TDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
|
||||
{ IGC_RCTL, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
|
||||
{ IGC_RCTL, 1, SET_READ_TEST, 0x04CFB2FE, 0x003FFFFB },
|
||||
{ IGC_RCTL, 1, SET_READ_TEST, 0x04CFB2FE, 0xFFFFFFFF },
|
||||
{ IGC_TCTL, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
|
||||
{ IGC_RA, 16, TABLE64_TEST_LO,
|
||||
0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ IGC_RA, 16, TABLE64_TEST_HI,
|
||||
0x900FFFFF, 0xFFFFFFFF },
|
||||
{ IGC_MTA, 128, TABLE32_TEST,
|
||||
0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static bool reg_pattern_test(struct igc_adapter *adapter, u64 *data, int reg,
|
||||
u32 mask, u32 write)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
u32 pat, val, before;
|
||||
static const u32 test_pattern[] = {
|
||||
0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
|
||||
};
|
||||
|
||||
for (pat = 0; pat < ARRAY_SIZE(test_pattern); pat++) {
|
||||
before = rd32(reg);
|
||||
wr32(reg, test_pattern[pat] & write);
|
||||
val = rd32(reg);
|
||||
if (val != (test_pattern[pat] & write & mask)) {
|
||||
netdev_err(adapter->netdev,
|
||||
"pattern test reg %04X failed: got 0x%08X expected 0x%08X",
|
||||
reg, val, test_pattern[pat] & write & mask);
|
||||
*data = reg;
|
||||
wr32(reg, before);
|
||||
return false;
|
||||
}
|
||||
wr32(reg, before);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool reg_set_and_check(struct igc_adapter *adapter, u64 *data, int reg,
|
||||
u32 mask, u32 write)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
u32 val, before;
|
||||
|
||||
before = rd32(reg);
|
||||
wr32(reg, write & mask);
|
||||
val = rd32(reg);
|
||||
if ((write & mask) != (val & mask)) {
|
||||
netdev_err(adapter->netdev,
|
||||
"set/check reg %04X test failed: got 0x%08X expected 0x%08X",
|
||||
reg, (val & mask), (write & mask));
|
||||
*data = reg;
|
||||
wr32(reg, before);
|
||||
return false;
|
||||
}
|
||||
wr32(reg, before);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool igc_reg_test(struct igc_adapter *adapter, u64 *data)
|
||||
{
|
||||
struct igc_reg_test *test = reg_test;
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
u32 value, before, after;
|
||||
u32 i, toggle, b = false;
|
||||
|
||||
/* Because the status register is such a special case,
|
||||
* we handle it separately from the rest of the register
|
||||
* tests. Some bits are read-only, some toggle, and some
|
||||
* are writeable.
|
||||
*/
|
||||
toggle = 0x6800D3;
|
||||
before = rd32(IGC_STATUS);
|
||||
value = before & toggle;
|
||||
wr32(IGC_STATUS, toggle);
|
||||
after = rd32(IGC_STATUS) & toggle;
|
||||
if (value != after) {
|
||||
netdev_err(adapter->netdev,
|
||||
"failed STATUS register test got: 0x%08X expected: 0x%08X",
|
||||
after, value);
|
||||
*data = 1;
|
||||
return false;
|
||||
}
|
||||
/* restore previous status */
|
||||
wr32(IGC_STATUS, before);
|
||||
|
||||
/* Perform the remainder of the register test, looping through
|
||||
* the test table until we either fail or reach the null entry.
|
||||
*/
|
||||
while (test->reg) {
|
||||
for (i = 0; i < test->array_len; i++) {
|
||||
switch (test->test_type) {
|
||||
case PATTERN_TEST:
|
||||
b = reg_pattern_test(adapter, data,
|
||||
test->reg + (i * 0x40),
|
||||
test->mask,
|
||||
test->write);
|
||||
break;
|
||||
case SET_READ_TEST:
|
||||
b = reg_set_and_check(adapter, data,
|
||||
test->reg + (i * 0x40),
|
||||
test->mask,
|
||||
test->write);
|
||||
break;
|
||||
case TABLE64_TEST_LO:
|
||||
b = reg_pattern_test(adapter, data,
|
||||
test->reg + (i * 8),
|
||||
test->mask,
|
||||
test->write);
|
||||
break;
|
||||
case TABLE64_TEST_HI:
|
||||
b = reg_pattern_test(adapter, data,
|
||||
test->reg + 4 + (i * 8),
|
||||
test->mask,
|
||||
test->write);
|
||||
break;
|
||||
case TABLE32_TEST:
|
||||
b = reg_pattern_test(adapter, data,
|
||||
test->reg + (i * 4),
|
||||
test->mask,
|
||||
test->write);
|
||||
break;
|
||||
}
|
||||
if (!b)
|
||||
return false;
|
||||
}
|
||||
test++;
|
||||
}
|
||||
*data = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool igc_eeprom_test(struct igc_adapter *adapter, u64 *data)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
|
||||
*data = 0;
|
||||
|
||||
if (hw->nvm.ops.validate(hw) != IGC_SUCCESS) {
|
||||
*data = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool igc_link_test(struct igc_adapter *adapter, u64 *data)
|
||||
{
|
||||
bool link_up;
|
||||
|
||||
*data = 0;
|
||||
|
||||
/* add delay to give enough time for autonegotioation to finish */
|
||||
if (adapter->hw.mac.autoneg)
|
||||
ssleep(5);
|
||||
|
||||
link_up = igc_has_link(adapter);
|
||||
if (!link_up) {
|
||||
*data = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
30
devices/igc/igc_diag-5.15-orig.h
Normal file
30
devices/igc/igc_diag-5.15-orig.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2020 Intel Corporation */
|
||||
|
||||
bool igc_reg_test(struct igc_adapter *adapter, u64 *data);
|
||||
bool igc_eeprom_test(struct igc_adapter *adapter, u64 *data);
|
||||
bool igc_link_test(struct igc_adapter *adapter, u64 *data);
|
||||
|
||||
struct igc_reg_test {
|
||||
u16 reg;
|
||||
u8 array_len;
|
||||
u8 test_type;
|
||||
u32 mask;
|
||||
u32 write;
|
||||
};
|
||||
|
||||
/* In the hardware, registers are laid out either singly, in arrays
|
||||
* spaced 0x40 bytes apart, or in contiguous tables. We assume
|
||||
* most tests take place on arrays or single registers (handled
|
||||
* as a single-element array) and special-case the tables.
|
||||
* Table tests are always pattern tests.
|
||||
*
|
||||
* We also make provision for some required setup steps by specifying
|
||||
* registers to be written without any read-back testing.
|
||||
*/
|
||||
|
||||
#define PATTERN_TEST 1
|
||||
#define SET_READ_TEST 2
|
||||
#define TABLE32_TEST 3
|
||||
#define TABLE64_TEST_LO 4
|
||||
#define TABLE64_TEST_HI 5
|
||||
318
devices/igc/igc_dump-5.15-ethercat.c
Normal file
318
devices/igc/igc_dump-5.15-ethercat.c
Normal file
@@ -0,0 +1,318 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#include "igc-5.15-ethercat.h"
|
||||
|
||||
struct igc_reg_info {
|
||||
u32 ofs;
|
||||
char *name;
|
||||
};
|
||||
|
||||
static const struct igc_reg_info igc_reg_info_tbl[] = {
|
||||
/* General Registers */
|
||||
{IGC_CTRL, "CTRL"},
|
||||
{IGC_STATUS, "STATUS"},
|
||||
{IGC_CTRL_EXT, "CTRL_EXT"},
|
||||
{IGC_MDIC, "MDIC"},
|
||||
|
||||
/* Interrupt Registers */
|
||||
{IGC_ICR, "ICR"},
|
||||
|
||||
/* RX Registers */
|
||||
{IGC_RCTL, "RCTL"},
|
||||
{IGC_RDLEN(0), "RDLEN"},
|
||||
{IGC_RDH(0), "RDH"},
|
||||
{IGC_RDT(0), "RDT"},
|
||||
{IGC_RXDCTL(0), "RXDCTL"},
|
||||
{IGC_RDBAL(0), "RDBAL"},
|
||||
{IGC_RDBAH(0), "RDBAH"},
|
||||
|
||||
/* TX Registers */
|
||||
{IGC_TCTL, "TCTL"},
|
||||
{IGC_TDBAL(0), "TDBAL"},
|
||||
{IGC_TDBAH(0), "TDBAH"},
|
||||
{IGC_TDLEN(0), "TDLEN"},
|
||||
{IGC_TDH(0), "TDH"},
|
||||
{IGC_TDT(0), "TDT"},
|
||||
{IGC_TXDCTL(0), "TXDCTL"},
|
||||
|
||||
/* List Terminator */
|
||||
{}
|
||||
};
|
||||
|
||||
/* igc_regdump - register printout routine */
|
||||
static void igc_regdump(struct igc_hw *hw, struct igc_reg_info *reginfo)
|
||||
{
|
||||
struct net_device *dev = igc_get_hw_dev(hw);
|
||||
int n = 0;
|
||||
char rname[16];
|
||||
u32 regs[8];
|
||||
|
||||
switch (reginfo->ofs) {
|
||||
case IGC_RDLEN(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_RDLEN(n));
|
||||
break;
|
||||
case IGC_RDH(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_RDH(n));
|
||||
break;
|
||||
case IGC_RDT(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_RDT(n));
|
||||
break;
|
||||
case IGC_RXDCTL(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_RXDCTL(n));
|
||||
break;
|
||||
case IGC_RDBAL(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_RDBAL(n));
|
||||
break;
|
||||
case IGC_RDBAH(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_RDBAH(n));
|
||||
break;
|
||||
case IGC_TDBAL(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_TDBAL(n));
|
||||
break;
|
||||
case IGC_TDBAH(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_TDBAH(n));
|
||||
break;
|
||||
case IGC_TDLEN(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_TDLEN(n));
|
||||
break;
|
||||
case IGC_TDH(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_TDH(n));
|
||||
break;
|
||||
case IGC_TDT(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_TDT(n));
|
||||
break;
|
||||
case IGC_TXDCTL(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_TXDCTL(n));
|
||||
break;
|
||||
default:
|
||||
netdev_info(dev, "%-15s %08x\n", reginfo->name,
|
||||
rd32(reginfo->ofs));
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(rname, 16, "%s%s", reginfo->name, "[0-3]");
|
||||
netdev_info(dev, "%-15s %08x %08x %08x %08x\n", rname, regs[0], regs[1],
|
||||
regs[2], regs[3]);
|
||||
}
|
||||
|
||||
/* igc_rings_dump - Tx-rings and Rx-rings */
|
||||
void igc_rings_dump(struct igc_adapter *adapter)
|
||||
{
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
struct my_u0 { __le64 a; __le64 b; } *u0;
|
||||
union igc_adv_tx_desc *tx_desc;
|
||||
union igc_adv_rx_desc *rx_desc;
|
||||
struct igc_ring *tx_ring;
|
||||
struct igc_ring *rx_ring;
|
||||
u32 staterr;
|
||||
u16 i, n;
|
||||
|
||||
if (!netif_msg_hw(adapter))
|
||||
return;
|
||||
|
||||
netdev_info(netdev, "Device info: state %016lX trans_start %016lX\n",
|
||||
netdev->state, dev_trans_start(netdev));
|
||||
|
||||
/* Print TX Ring Summary */
|
||||
if (!netif_running(netdev))
|
||||
goto exit;
|
||||
|
||||
netdev_info(netdev, "TX Rings Summary\n");
|
||||
netdev_info(netdev, "Queue [NTU] [NTC] [bi(ntc)->dma ] leng ntw timestamp\n");
|
||||
for (n = 0; n < adapter->num_tx_queues; n++) {
|
||||
struct igc_tx_buffer *buffer_info;
|
||||
|
||||
tx_ring = adapter->tx_ring[n];
|
||||
buffer_info = &tx_ring->tx_buffer_info[tx_ring->next_to_clean];
|
||||
|
||||
netdev_info(netdev, "%5d %5X %5X %016llX %04X %p %016llX\n",
|
||||
n, tx_ring->next_to_use, tx_ring->next_to_clean,
|
||||
(u64)dma_unmap_addr(buffer_info, dma),
|
||||
dma_unmap_len(buffer_info, len),
|
||||
buffer_info->next_to_watch,
|
||||
(u64)buffer_info->time_stamp);
|
||||
}
|
||||
|
||||
/* Print TX Rings */
|
||||
if (!netif_msg_tx_done(adapter))
|
||||
goto rx_ring_summary;
|
||||
|
||||
netdev_info(netdev, "TX Rings Dump\n");
|
||||
|
||||
/* Transmit Descriptor Formats
|
||||
*
|
||||
* Advanced Transmit Descriptor
|
||||
* +--------------------------------------------------------------+
|
||||
* 0 | Buffer Address [63:0] |
|
||||
* +--------------------------------------------------------------+
|
||||
* 8 | PAYLEN | PORTS |CC|IDX | STA | DCMD |DTYP|MAC|RSV| DTALEN |
|
||||
* +--------------------------------------------------------------+
|
||||
* 63 46 45 40 39 38 36 35 32 31 24 15 0
|
||||
*/
|
||||
|
||||
for (n = 0; n < adapter->num_tx_queues; n++) {
|
||||
tx_ring = adapter->tx_ring[n];
|
||||
netdev_info(netdev, "------------------------------------\n");
|
||||
netdev_info(netdev, "TX QUEUE INDEX = %d\n",
|
||||
tx_ring->queue_index);
|
||||
netdev_info(netdev, "------------------------------------\n");
|
||||
netdev_info(netdev, "T [desc] [address 63:0 ] [PlPOCIStDDM Ln] [bi->dma ] leng ntw timestamp bi->skb\n");
|
||||
|
||||
for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
|
||||
const char *next_desc;
|
||||
struct igc_tx_buffer *buffer_info;
|
||||
|
||||
tx_desc = IGC_TX_DESC(tx_ring, i);
|
||||
buffer_info = &tx_ring->tx_buffer_info[i];
|
||||
u0 = (struct my_u0 *)tx_desc;
|
||||
if (i == tx_ring->next_to_use &&
|
||||
i == tx_ring->next_to_clean)
|
||||
next_desc = " NTC/U";
|
||||
else if (i == tx_ring->next_to_use)
|
||||
next_desc = " NTU";
|
||||
else if (i == tx_ring->next_to_clean)
|
||||
next_desc = " NTC";
|
||||
else
|
||||
next_desc = "";
|
||||
|
||||
netdev_info(netdev, "T [0x%03X] %016llX %016llX %016llX %04X %p %016llX %p%s\n",
|
||||
i, le64_to_cpu(u0->a),
|
||||
le64_to_cpu(u0->b),
|
||||
(u64)dma_unmap_addr(buffer_info, dma),
|
||||
dma_unmap_len(buffer_info, len),
|
||||
buffer_info->next_to_watch,
|
||||
(u64)buffer_info->time_stamp,
|
||||
buffer_info->skb, next_desc);
|
||||
|
||||
if (netif_msg_pktdata(adapter) && buffer_info->skb)
|
||||
print_hex_dump(KERN_INFO, "",
|
||||
DUMP_PREFIX_ADDRESS,
|
||||
16, 1, buffer_info->skb->data,
|
||||
dma_unmap_len(buffer_info, len),
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print RX Rings Summary */
|
||||
rx_ring_summary:
|
||||
netdev_info(netdev, "RX Rings Summary\n");
|
||||
netdev_info(netdev, "Queue [NTU] [NTC]\n");
|
||||
for (n = 0; n < adapter->num_rx_queues; n++) {
|
||||
rx_ring = adapter->rx_ring[n];
|
||||
netdev_info(netdev, "%5d %5X %5X\n", n, rx_ring->next_to_use,
|
||||
rx_ring->next_to_clean);
|
||||
}
|
||||
|
||||
/* Print RX Rings */
|
||||
if (!netif_msg_rx_status(adapter))
|
||||
goto exit;
|
||||
|
||||
netdev_info(netdev, "RX Rings Dump\n");
|
||||
|
||||
/* Advanced Receive Descriptor (Read) Format
|
||||
* 63 1 0
|
||||
* +-----------------------------------------------------+
|
||||
* 0 | Packet Buffer Address [63:1] |A0/NSE|
|
||||
* +----------------------------------------------+------+
|
||||
* 8 | Header Buffer Address [63:1] | DD |
|
||||
* +-----------------------------------------------------+
|
||||
*
|
||||
*
|
||||
* Advanced Receive Descriptor (Write-Back) Format
|
||||
*
|
||||
* 63 48 47 32 31 30 21 20 17 16 4 3 0
|
||||
* +------------------------------------------------------+
|
||||
* 0 | Packet IP |SPH| HDR_LEN | RSV|Packet| RSS |
|
||||
* | Checksum Ident | | | | Type | Type |
|
||||
* +------------------------------------------------------+
|
||||
* 8 | VLAN Tag | Length | Extended Error | Extended Status |
|
||||
* +------------------------------------------------------+
|
||||
* 63 48 47 32 31 20 19 0
|
||||
*/
|
||||
|
||||
for (n = 0; n < adapter->num_rx_queues; n++) {
|
||||
rx_ring = adapter->rx_ring[n];
|
||||
netdev_info(netdev, "------------------------------------\n");
|
||||
netdev_info(netdev, "RX QUEUE INDEX = %d\n",
|
||||
rx_ring->queue_index);
|
||||
netdev_info(netdev, "------------------------------------\n");
|
||||
netdev_info(netdev, "R [desc] [ PktBuf A0] [ HeadBuf DD] [bi->dma ] [bi->skb] <-- Adv Rx Read format\n");
|
||||
netdev_info(netdev, "RWB[desc] [PcsmIpSHl PtRs] [vl er S cks ln] ---------------- [bi->skb] <-- Adv Rx Write-Back format\n");
|
||||
|
||||
for (i = 0; i < rx_ring->count; i++) {
|
||||
const char *next_desc;
|
||||
struct igc_rx_buffer *buffer_info;
|
||||
|
||||
buffer_info = &rx_ring->rx_buffer_info[i];
|
||||
rx_desc = IGC_RX_DESC(rx_ring, i);
|
||||
u0 = (struct my_u0 *)rx_desc;
|
||||
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
|
||||
|
||||
if (i == rx_ring->next_to_use)
|
||||
next_desc = " NTU";
|
||||
else if (i == rx_ring->next_to_clean)
|
||||
next_desc = " NTC";
|
||||
else
|
||||
next_desc = "";
|
||||
|
||||
if (staterr & IGC_RXD_STAT_DD) {
|
||||
/* Descriptor Done */
|
||||
netdev_info(netdev, "%s[0x%03X] %016llX %016llX ---------------- %s\n",
|
||||
"RWB", i,
|
||||
le64_to_cpu(u0->a),
|
||||
le64_to_cpu(u0->b),
|
||||
next_desc);
|
||||
} else {
|
||||
netdev_info(netdev, "%s[0x%03X] %016llX %016llX %016llX %s\n",
|
||||
"R ", i,
|
||||
le64_to_cpu(u0->a),
|
||||
le64_to_cpu(u0->b),
|
||||
(u64)buffer_info->dma,
|
||||
next_desc);
|
||||
|
||||
if (netif_msg_pktdata(adapter) &&
|
||||
buffer_info->dma && buffer_info->page) {
|
||||
print_hex_dump(KERN_INFO, "",
|
||||
DUMP_PREFIX_ADDRESS,
|
||||
16, 1,
|
||||
page_address
|
||||
(buffer_info->page) +
|
||||
buffer_info->page_offset,
|
||||
igc_rx_bufsz(rx_ring),
|
||||
true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
/* igc_regs_dump - registers dump */
|
||||
void igc_regs_dump(struct igc_adapter *adapter)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
struct igc_reg_info *reginfo;
|
||||
|
||||
/* Print Registers */
|
||||
netdev_info(adapter->netdev, "Register Dump\n");
|
||||
netdev_info(adapter->netdev, "Register Name Value\n");
|
||||
for (reginfo = (struct igc_reg_info *)igc_reg_info_tbl;
|
||||
reginfo->name; reginfo++) {
|
||||
igc_regdump(hw, reginfo);
|
||||
}
|
||||
}
|
||||
318
devices/igc/igc_dump-5.15-orig.c
Normal file
318
devices/igc/igc_dump-5.15-orig.c
Normal file
@@ -0,0 +1,318 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#include "igc.h"
|
||||
|
||||
struct igc_reg_info {
|
||||
u32 ofs;
|
||||
char *name;
|
||||
};
|
||||
|
||||
static const struct igc_reg_info igc_reg_info_tbl[] = {
|
||||
/* General Registers */
|
||||
{IGC_CTRL, "CTRL"},
|
||||
{IGC_STATUS, "STATUS"},
|
||||
{IGC_CTRL_EXT, "CTRL_EXT"},
|
||||
{IGC_MDIC, "MDIC"},
|
||||
|
||||
/* Interrupt Registers */
|
||||
{IGC_ICR, "ICR"},
|
||||
|
||||
/* RX Registers */
|
||||
{IGC_RCTL, "RCTL"},
|
||||
{IGC_RDLEN(0), "RDLEN"},
|
||||
{IGC_RDH(0), "RDH"},
|
||||
{IGC_RDT(0), "RDT"},
|
||||
{IGC_RXDCTL(0), "RXDCTL"},
|
||||
{IGC_RDBAL(0), "RDBAL"},
|
||||
{IGC_RDBAH(0), "RDBAH"},
|
||||
|
||||
/* TX Registers */
|
||||
{IGC_TCTL, "TCTL"},
|
||||
{IGC_TDBAL(0), "TDBAL"},
|
||||
{IGC_TDBAH(0), "TDBAH"},
|
||||
{IGC_TDLEN(0), "TDLEN"},
|
||||
{IGC_TDH(0), "TDH"},
|
||||
{IGC_TDT(0), "TDT"},
|
||||
{IGC_TXDCTL(0), "TXDCTL"},
|
||||
|
||||
/* List Terminator */
|
||||
{}
|
||||
};
|
||||
|
||||
/* igc_regdump - register printout routine */
|
||||
static void igc_regdump(struct igc_hw *hw, struct igc_reg_info *reginfo)
|
||||
{
|
||||
struct net_device *dev = igc_get_hw_dev(hw);
|
||||
int n = 0;
|
||||
char rname[16];
|
||||
u32 regs[8];
|
||||
|
||||
switch (reginfo->ofs) {
|
||||
case IGC_RDLEN(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_RDLEN(n));
|
||||
break;
|
||||
case IGC_RDH(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_RDH(n));
|
||||
break;
|
||||
case IGC_RDT(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_RDT(n));
|
||||
break;
|
||||
case IGC_RXDCTL(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_RXDCTL(n));
|
||||
break;
|
||||
case IGC_RDBAL(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_RDBAL(n));
|
||||
break;
|
||||
case IGC_RDBAH(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_RDBAH(n));
|
||||
break;
|
||||
case IGC_TDBAL(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_TDBAL(n));
|
||||
break;
|
||||
case IGC_TDBAH(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_TDBAH(n));
|
||||
break;
|
||||
case IGC_TDLEN(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_TDLEN(n));
|
||||
break;
|
||||
case IGC_TDH(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_TDH(n));
|
||||
break;
|
||||
case IGC_TDT(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_TDT(n));
|
||||
break;
|
||||
case IGC_TXDCTL(0):
|
||||
for (n = 0; n < 4; n++)
|
||||
regs[n] = rd32(IGC_TXDCTL(n));
|
||||
break;
|
||||
default:
|
||||
netdev_info(dev, "%-15s %08x\n", reginfo->name,
|
||||
rd32(reginfo->ofs));
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(rname, 16, "%s%s", reginfo->name, "[0-3]");
|
||||
netdev_info(dev, "%-15s %08x %08x %08x %08x\n", rname, regs[0], regs[1],
|
||||
regs[2], regs[3]);
|
||||
}
|
||||
|
||||
/* igc_rings_dump - Tx-rings and Rx-rings */
|
||||
void igc_rings_dump(struct igc_adapter *adapter)
|
||||
{
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
struct my_u0 { __le64 a; __le64 b; } *u0;
|
||||
union igc_adv_tx_desc *tx_desc;
|
||||
union igc_adv_rx_desc *rx_desc;
|
||||
struct igc_ring *tx_ring;
|
||||
struct igc_ring *rx_ring;
|
||||
u32 staterr;
|
||||
u16 i, n;
|
||||
|
||||
if (!netif_msg_hw(adapter))
|
||||
return;
|
||||
|
||||
netdev_info(netdev, "Device info: state %016lX trans_start %016lX\n",
|
||||
netdev->state, dev_trans_start(netdev));
|
||||
|
||||
/* Print TX Ring Summary */
|
||||
if (!netif_running(netdev))
|
||||
goto exit;
|
||||
|
||||
netdev_info(netdev, "TX Rings Summary\n");
|
||||
netdev_info(netdev, "Queue [NTU] [NTC] [bi(ntc)->dma ] leng ntw timestamp\n");
|
||||
for (n = 0; n < adapter->num_tx_queues; n++) {
|
||||
struct igc_tx_buffer *buffer_info;
|
||||
|
||||
tx_ring = adapter->tx_ring[n];
|
||||
buffer_info = &tx_ring->tx_buffer_info[tx_ring->next_to_clean];
|
||||
|
||||
netdev_info(netdev, "%5d %5X %5X %016llX %04X %p %016llX\n",
|
||||
n, tx_ring->next_to_use, tx_ring->next_to_clean,
|
||||
(u64)dma_unmap_addr(buffer_info, dma),
|
||||
dma_unmap_len(buffer_info, len),
|
||||
buffer_info->next_to_watch,
|
||||
(u64)buffer_info->time_stamp);
|
||||
}
|
||||
|
||||
/* Print TX Rings */
|
||||
if (!netif_msg_tx_done(adapter))
|
||||
goto rx_ring_summary;
|
||||
|
||||
netdev_info(netdev, "TX Rings Dump\n");
|
||||
|
||||
/* Transmit Descriptor Formats
|
||||
*
|
||||
* Advanced Transmit Descriptor
|
||||
* +--------------------------------------------------------------+
|
||||
* 0 | Buffer Address [63:0] |
|
||||
* +--------------------------------------------------------------+
|
||||
* 8 | PAYLEN | PORTS |CC|IDX | STA | DCMD |DTYP|MAC|RSV| DTALEN |
|
||||
* +--------------------------------------------------------------+
|
||||
* 63 46 45 40 39 38 36 35 32 31 24 15 0
|
||||
*/
|
||||
|
||||
for (n = 0; n < adapter->num_tx_queues; n++) {
|
||||
tx_ring = adapter->tx_ring[n];
|
||||
netdev_info(netdev, "------------------------------------\n");
|
||||
netdev_info(netdev, "TX QUEUE INDEX = %d\n",
|
||||
tx_ring->queue_index);
|
||||
netdev_info(netdev, "------------------------------------\n");
|
||||
netdev_info(netdev, "T [desc] [address 63:0 ] [PlPOCIStDDM Ln] [bi->dma ] leng ntw timestamp bi->skb\n");
|
||||
|
||||
for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
|
||||
const char *next_desc;
|
||||
struct igc_tx_buffer *buffer_info;
|
||||
|
||||
tx_desc = IGC_TX_DESC(tx_ring, i);
|
||||
buffer_info = &tx_ring->tx_buffer_info[i];
|
||||
u0 = (struct my_u0 *)tx_desc;
|
||||
if (i == tx_ring->next_to_use &&
|
||||
i == tx_ring->next_to_clean)
|
||||
next_desc = " NTC/U";
|
||||
else if (i == tx_ring->next_to_use)
|
||||
next_desc = " NTU";
|
||||
else if (i == tx_ring->next_to_clean)
|
||||
next_desc = " NTC";
|
||||
else
|
||||
next_desc = "";
|
||||
|
||||
netdev_info(netdev, "T [0x%03X] %016llX %016llX %016llX %04X %p %016llX %p%s\n",
|
||||
i, le64_to_cpu(u0->a),
|
||||
le64_to_cpu(u0->b),
|
||||
(u64)dma_unmap_addr(buffer_info, dma),
|
||||
dma_unmap_len(buffer_info, len),
|
||||
buffer_info->next_to_watch,
|
||||
(u64)buffer_info->time_stamp,
|
||||
buffer_info->skb, next_desc);
|
||||
|
||||
if (netif_msg_pktdata(adapter) && buffer_info->skb)
|
||||
print_hex_dump(KERN_INFO, "",
|
||||
DUMP_PREFIX_ADDRESS,
|
||||
16, 1, buffer_info->skb->data,
|
||||
dma_unmap_len(buffer_info, len),
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print RX Rings Summary */
|
||||
rx_ring_summary:
|
||||
netdev_info(netdev, "RX Rings Summary\n");
|
||||
netdev_info(netdev, "Queue [NTU] [NTC]\n");
|
||||
for (n = 0; n < adapter->num_rx_queues; n++) {
|
||||
rx_ring = adapter->rx_ring[n];
|
||||
netdev_info(netdev, "%5d %5X %5X\n", n, rx_ring->next_to_use,
|
||||
rx_ring->next_to_clean);
|
||||
}
|
||||
|
||||
/* Print RX Rings */
|
||||
if (!netif_msg_rx_status(adapter))
|
||||
goto exit;
|
||||
|
||||
netdev_info(netdev, "RX Rings Dump\n");
|
||||
|
||||
/* Advanced Receive Descriptor (Read) Format
|
||||
* 63 1 0
|
||||
* +-----------------------------------------------------+
|
||||
* 0 | Packet Buffer Address [63:1] |A0/NSE|
|
||||
* +----------------------------------------------+------+
|
||||
* 8 | Header Buffer Address [63:1] | DD |
|
||||
* +-----------------------------------------------------+
|
||||
*
|
||||
*
|
||||
* Advanced Receive Descriptor (Write-Back) Format
|
||||
*
|
||||
* 63 48 47 32 31 30 21 20 17 16 4 3 0
|
||||
* +------------------------------------------------------+
|
||||
* 0 | Packet IP |SPH| HDR_LEN | RSV|Packet| RSS |
|
||||
* | Checksum Ident | | | | Type | Type |
|
||||
* +------------------------------------------------------+
|
||||
* 8 | VLAN Tag | Length | Extended Error | Extended Status |
|
||||
* +------------------------------------------------------+
|
||||
* 63 48 47 32 31 20 19 0
|
||||
*/
|
||||
|
||||
for (n = 0; n < adapter->num_rx_queues; n++) {
|
||||
rx_ring = adapter->rx_ring[n];
|
||||
netdev_info(netdev, "------------------------------------\n");
|
||||
netdev_info(netdev, "RX QUEUE INDEX = %d\n",
|
||||
rx_ring->queue_index);
|
||||
netdev_info(netdev, "------------------------------------\n");
|
||||
netdev_info(netdev, "R [desc] [ PktBuf A0] [ HeadBuf DD] [bi->dma ] [bi->skb] <-- Adv Rx Read format\n");
|
||||
netdev_info(netdev, "RWB[desc] [PcsmIpSHl PtRs] [vl er S cks ln] ---------------- [bi->skb] <-- Adv Rx Write-Back format\n");
|
||||
|
||||
for (i = 0; i < rx_ring->count; i++) {
|
||||
const char *next_desc;
|
||||
struct igc_rx_buffer *buffer_info;
|
||||
|
||||
buffer_info = &rx_ring->rx_buffer_info[i];
|
||||
rx_desc = IGC_RX_DESC(rx_ring, i);
|
||||
u0 = (struct my_u0 *)rx_desc;
|
||||
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
|
||||
|
||||
if (i == rx_ring->next_to_use)
|
||||
next_desc = " NTU";
|
||||
else if (i == rx_ring->next_to_clean)
|
||||
next_desc = " NTC";
|
||||
else
|
||||
next_desc = "";
|
||||
|
||||
if (staterr & IGC_RXD_STAT_DD) {
|
||||
/* Descriptor Done */
|
||||
netdev_info(netdev, "%s[0x%03X] %016llX %016llX ---------------- %s\n",
|
||||
"RWB", i,
|
||||
le64_to_cpu(u0->a),
|
||||
le64_to_cpu(u0->b),
|
||||
next_desc);
|
||||
} else {
|
||||
netdev_info(netdev, "%s[0x%03X] %016llX %016llX %016llX %s\n",
|
||||
"R ", i,
|
||||
le64_to_cpu(u0->a),
|
||||
le64_to_cpu(u0->b),
|
||||
(u64)buffer_info->dma,
|
||||
next_desc);
|
||||
|
||||
if (netif_msg_pktdata(adapter) &&
|
||||
buffer_info->dma && buffer_info->page) {
|
||||
print_hex_dump(KERN_INFO, "",
|
||||
DUMP_PREFIX_ADDRESS,
|
||||
16, 1,
|
||||
page_address
|
||||
(buffer_info->page) +
|
||||
buffer_info->page_offset,
|
||||
igc_rx_bufsz(rx_ring),
|
||||
true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
/* igc_regs_dump - registers dump */
|
||||
void igc_regs_dump(struct igc_adapter *adapter)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
struct igc_reg_info *reginfo;
|
||||
|
||||
/* Print Registers */
|
||||
netdev_info(adapter->netdev, "Register Dump\n");
|
||||
netdev_info(adapter->netdev, "Register Name Value\n");
|
||||
for (reginfo = (struct igc_reg_info *)igc_reg_info_tbl;
|
||||
reginfo->name; reginfo++) {
|
||||
igc_regdump(hw, reginfo);
|
||||
}
|
||||
}
|
||||
1974
devices/igc/igc_ethtool-5.15-ethercat.c
Normal file
1974
devices/igc/igc_ethtool-5.15-ethercat.c
Normal file
File diff suppressed because it is too large
Load Diff
1974
devices/igc/igc_ethtool-5.15-orig.c
Normal file
1974
devices/igc/igc_ethtool-5.15-orig.c
Normal file
File diff suppressed because it is too large
Load Diff
298
devices/igc/igc_hw-5.15-ethercat.h
Normal file
298
devices/igc/igc_hw-5.15-ethercat.h
Normal file
@@ -0,0 +1,298 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#ifndef _IGC_HW_H_
|
||||
#define _IGC_HW_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
#include "igc_regs-5.15-ethercat.h"
|
||||
#include "igc_defines-5.15-ethercat.h"
|
||||
#include "igc_mac-5.15-ethercat.h"
|
||||
#include "igc_phy-5.15-ethercat.h"
|
||||
#include "igc_nvm-5.15-ethercat.h"
|
||||
#include "igc_i225-5.15-ethercat.h"
|
||||
#include "igc_base-5.15-ethercat.h"
|
||||
|
||||
#define IGC_DEV_ID_I225_LM 0x15F2
|
||||
#define IGC_DEV_ID_I225_V 0x15F3
|
||||
#define IGC_DEV_ID_I225_I 0x15F8
|
||||
#define IGC_DEV_ID_I220_V 0x15F7
|
||||
#define IGC_DEV_ID_I225_K 0x3100
|
||||
#define IGC_DEV_ID_I225_K2 0x3101
|
||||
#define IGC_DEV_ID_I226_K 0x3102
|
||||
#define IGC_DEV_ID_I225_LMVP 0x5502
|
||||
#define IGC_DEV_ID_I225_IT 0x0D9F
|
||||
#define IGC_DEV_ID_I226_LM 0x125B
|
||||
#define IGC_DEV_ID_I226_V 0x125C
|
||||
#define IGC_DEV_ID_I226_IT 0x125D
|
||||
#define IGC_DEV_ID_I221_V 0x125E
|
||||
#define IGC_DEV_ID_I226_BLANK_NVM 0x125F
|
||||
#define IGC_DEV_ID_I225_BLANK_NVM 0x15FD
|
||||
|
||||
/* Function pointers for the MAC. */
|
||||
struct igc_mac_operations {
|
||||
s32 (*check_for_link)(struct igc_hw *hw);
|
||||
s32 (*reset_hw)(struct igc_hw *hw);
|
||||
s32 (*init_hw)(struct igc_hw *hw);
|
||||
s32 (*setup_physical_interface)(struct igc_hw *hw);
|
||||
void (*rar_set)(struct igc_hw *hw, u8 *address, u32 index);
|
||||
s32 (*read_mac_addr)(struct igc_hw *hw);
|
||||
s32 (*get_speed_and_duplex)(struct igc_hw *hw, u16 *speed,
|
||||
u16 *duplex);
|
||||
s32 (*acquire_swfw_sync)(struct igc_hw *hw, u16 mask);
|
||||
void (*release_swfw_sync)(struct igc_hw *hw, u16 mask);
|
||||
};
|
||||
|
||||
enum igc_mac_type {
|
||||
igc_undefined = 0,
|
||||
igc_i225,
|
||||
igc_num_macs /* List is 1-based, so subtract 1 for true count. */
|
||||
};
|
||||
|
||||
enum igc_phy_type {
|
||||
igc_phy_unknown = 0,
|
||||
igc_phy_none,
|
||||
igc_phy_i225,
|
||||
};
|
||||
|
||||
enum igc_media_type {
|
||||
igc_media_type_unknown = 0,
|
||||
igc_media_type_copper = 1,
|
||||
igc_num_media_types
|
||||
};
|
||||
|
||||
enum igc_nvm_type {
|
||||
igc_nvm_unknown = 0,
|
||||
igc_nvm_eeprom_spi,
|
||||
igc_nvm_flash_hw,
|
||||
igc_nvm_invm,
|
||||
};
|
||||
|
||||
struct igc_info {
|
||||
s32 (*get_invariants)(struct igc_hw *hw);
|
||||
struct igc_mac_operations *mac_ops;
|
||||
const struct igc_phy_operations *phy_ops;
|
||||
struct igc_nvm_operations *nvm_ops;
|
||||
};
|
||||
|
||||
extern const struct igc_info igc_base_info;
|
||||
|
||||
struct igc_mac_info {
|
||||
struct igc_mac_operations ops;
|
||||
|
||||
u8 addr[ETH_ALEN];
|
||||
u8 perm_addr[ETH_ALEN];
|
||||
|
||||
enum igc_mac_type type;
|
||||
|
||||
u32 mc_filter_type;
|
||||
|
||||
u16 mta_reg_count;
|
||||
u16 uta_reg_count;
|
||||
|
||||
u32 mta_shadow[MAX_MTA_REG];
|
||||
u16 rar_entry_count;
|
||||
|
||||
u8 forced_speed_duplex;
|
||||
|
||||
bool asf_firmware_present;
|
||||
bool arc_subsystem_valid;
|
||||
|
||||
bool autoneg;
|
||||
bool autoneg_failed;
|
||||
bool get_link_status;
|
||||
};
|
||||
|
||||
struct igc_nvm_operations {
|
||||
s32 (*acquire)(struct igc_hw *hw);
|
||||
s32 (*read)(struct igc_hw *hw, u16 offset, u16 i, u16 *data);
|
||||
void (*release)(struct igc_hw *hw);
|
||||
s32 (*write)(struct igc_hw *hw, u16 offset, u16 i, u16 *data);
|
||||
s32 (*update)(struct igc_hw *hw);
|
||||
s32 (*validate)(struct igc_hw *hw);
|
||||
};
|
||||
|
||||
struct igc_phy_operations {
|
||||
s32 (*acquire)(struct igc_hw *hw);
|
||||
s32 (*check_reset_block)(struct igc_hw *hw);
|
||||
s32 (*force_speed_duplex)(struct igc_hw *hw);
|
||||
s32 (*get_phy_info)(struct igc_hw *hw);
|
||||
s32 (*read_reg)(struct igc_hw *hw, u32 address, u16 *data);
|
||||
void (*release)(struct igc_hw *hw);
|
||||
s32 (*reset)(struct igc_hw *hw);
|
||||
s32 (*write_reg)(struct igc_hw *hw, u32 address, u16 data);
|
||||
};
|
||||
|
||||
struct igc_nvm_info {
|
||||
struct igc_nvm_operations ops;
|
||||
enum igc_nvm_type type;
|
||||
|
||||
u16 word_size;
|
||||
u16 delay_usec;
|
||||
u16 address_bits;
|
||||
u16 opcode_bits;
|
||||
u16 page_size;
|
||||
};
|
||||
|
||||
struct igc_phy_info {
|
||||
struct igc_phy_operations ops;
|
||||
|
||||
enum igc_phy_type type;
|
||||
|
||||
u32 addr;
|
||||
u32 id;
|
||||
u32 reset_delay_us; /* in usec */
|
||||
u32 revision;
|
||||
|
||||
enum igc_media_type media_type;
|
||||
|
||||
u16 autoneg_advertised;
|
||||
u16 autoneg_mask;
|
||||
|
||||
u8 mdix;
|
||||
|
||||
bool is_mdix;
|
||||
bool speed_downgraded;
|
||||
bool autoneg_wait_to_complete;
|
||||
};
|
||||
|
||||
struct igc_bus_info {
|
||||
u16 func;
|
||||
u16 pci_cmd_word;
|
||||
};
|
||||
|
||||
enum igc_fc_mode {
|
||||
igc_fc_none = 0,
|
||||
igc_fc_rx_pause,
|
||||
igc_fc_tx_pause,
|
||||
igc_fc_full,
|
||||
igc_fc_default = 0xFF
|
||||
};
|
||||
|
||||
struct igc_fc_info {
|
||||
u32 high_water; /* Flow control high-water mark */
|
||||
u32 low_water; /* Flow control low-water mark */
|
||||
u16 pause_time; /* Flow control pause timer */
|
||||
bool send_xon; /* Flow control send XON */
|
||||
bool strict_ieee; /* Strict IEEE mode */
|
||||
enum igc_fc_mode current_mode; /* Type of flow control */
|
||||
enum igc_fc_mode requested_mode;
|
||||
};
|
||||
|
||||
struct igc_dev_spec_base {
|
||||
bool clear_semaphore_once;
|
||||
bool eee_enable;
|
||||
};
|
||||
|
||||
struct igc_hw {
|
||||
void *back;
|
||||
|
||||
u8 __iomem *hw_addr;
|
||||
unsigned long io_base;
|
||||
|
||||
struct igc_mac_info mac;
|
||||
struct igc_fc_info fc;
|
||||
struct igc_nvm_info nvm;
|
||||
struct igc_phy_info phy;
|
||||
|
||||
struct igc_bus_info bus;
|
||||
|
||||
union {
|
||||
struct igc_dev_spec_base _base;
|
||||
} dev_spec;
|
||||
|
||||
u16 device_id;
|
||||
u16 subsystem_vendor_id;
|
||||
u16 subsystem_device_id;
|
||||
u16 vendor_id;
|
||||
|
||||
u8 revision_id;
|
||||
};
|
||||
|
||||
/* Statistics counters collected by the MAC */
|
||||
struct igc_hw_stats {
|
||||
u64 crcerrs;
|
||||
u64 algnerrc;
|
||||
u64 symerrs;
|
||||
u64 rxerrc;
|
||||
u64 mpc;
|
||||
u64 scc;
|
||||
u64 ecol;
|
||||
u64 mcc;
|
||||
u64 latecol;
|
||||
u64 colc;
|
||||
u64 dc;
|
||||
u64 tncrs;
|
||||
u64 sec;
|
||||
u64 cexterr;
|
||||
u64 rlec;
|
||||
u64 xonrxc;
|
||||
u64 xontxc;
|
||||
u64 xoffrxc;
|
||||
u64 xofftxc;
|
||||
u64 fcruc;
|
||||
u64 prc64;
|
||||
u64 prc127;
|
||||
u64 prc255;
|
||||
u64 prc511;
|
||||
u64 prc1023;
|
||||
u64 prc1522;
|
||||
u64 tlpic;
|
||||
u64 rlpic;
|
||||
u64 gprc;
|
||||
u64 bprc;
|
||||
u64 mprc;
|
||||
u64 gptc;
|
||||
u64 gorc;
|
||||
u64 gotc;
|
||||
u64 rnbc;
|
||||
u64 ruc;
|
||||
u64 rfc;
|
||||
u64 roc;
|
||||
u64 rjc;
|
||||
u64 mgprc;
|
||||
u64 mgpdc;
|
||||
u64 mgptc;
|
||||
u64 tor;
|
||||
u64 tot;
|
||||
u64 tpr;
|
||||
u64 tpt;
|
||||
u64 ptc64;
|
||||
u64 ptc127;
|
||||
u64 ptc255;
|
||||
u64 ptc511;
|
||||
u64 ptc1023;
|
||||
u64 ptc1522;
|
||||
u64 mptc;
|
||||
u64 bptc;
|
||||
u64 tsctc;
|
||||
u64 tsctfc;
|
||||
u64 iac;
|
||||
u64 htdpmc;
|
||||
u64 rpthc;
|
||||
u64 hgptc;
|
||||
u64 hgorc;
|
||||
u64 hgotc;
|
||||
u64 lenerrs;
|
||||
u64 scvpc;
|
||||
u64 hrmpc;
|
||||
u64 doosync;
|
||||
u64 o2bgptc;
|
||||
u64 o2bspc;
|
||||
u64 b2ospc;
|
||||
u64 b2ogprc;
|
||||
};
|
||||
|
||||
struct net_device *igc_get_hw_dev(struct igc_hw *hw);
|
||||
#define hw_dbg(format, arg...) \
|
||||
netdev_dbg(igc_get_hw_dev(hw), format, ##arg)
|
||||
|
||||
s32 igc_read_pcie_cap_reg(struct igc_hw *hw, u32 reg, u16 *value);
|
||||
s32 igc_write_pcie_cap_reg(struct igc_hw *hw, u32 reg, u16 *value);
|
||||
void igc_read_pci_cfg(struct igc_hw *hw, u32 reg, u16 *value);
|
||||
void igc_write_pci_cfg(struct igc_hw *hw, u32 reg, u16 *value);
|
||||
|
||||
#endif /* _IGC_HW_H_ */
|
||||
298
devices/igc/igc_hw-5.15-orig.h
Normal file
298
devices/igc/igc_hw-5.15-orig.h
Normal file
@@ -0,0 +1,298 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#ifndef _IGC_HW_H_
|
||||
#define _IGC_HW_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
#include "igc_regs.h"
|
||||
#include "igc_defines.h"
|
||||
#include "igc_mac.h"
|
||||
#include "igc_phy.h"
|
||||
#include "igc_nvm.h"
|
||||
#include "igc_i225.h"
|
||||
#include "igc_base.h"
|
||||
|
||||
#define IGC_DEV_ID_I225_LM 0x15F2
|
||||
#define IGC_DEV_ID_I225_V 0x15F3
|
||||
#define IGC_DEV_ID_I225_I 0x15F8
|
||||
#define IGC_DEV_ID_I220_V 0x15F7
|
||||
#define IGC_DEV_ID_I225_K 0x3100
|
||||
#define IGC_DEV_ID_I225_K2 0x3101
|
||||
#define IGC_DEV_ID_I226_K 0x3102
|
||||
#define IGC_DEV_ID_I225_LMVP 0x5502
|
||||
#define IGC_DEV_ID_I225_IT 0x0D9F
|
||||
#define IGC_DEV_ID_I226_LM 0x125B
|
||||
#define IGC_DEV_ID_I226_V 0x125C
|
||||
#define IGC_DEV_ID_I226_IT 0x125D
|
||||
#define IGC_DEV_ID_I221_V 0x125E
|
||||
#define IGC_DEV_ID_I226_BLANK_NVM 0x125F
|
||||
#define IGC_DEV_ID_I225_BLANK_NVM 0x15FD
|
||||
|
||||
/* Function pointers for the MAC. */
|
||||
struct igc_mac_operations {
|
||||
s32 (*check_for_link)(struct igc_hw *hw);
|
||||
s32 (*reset_hw)(struct igc_hw *hw);
|
||||
s32 (*init_hw)(struct igc_hw *hw);
|
||||
s32 (*setup_physical_interface)(struct igc_hw *hw);
|
||||
void (*rar_set)(struct igc_hw *hw, u8 *address, u32 index);
|
||||
s32 (*read_mac_addr)(struct igc_hw *hw);
|
||||
s32 (*get_speed_and_duplex)(struct igc_hw *hw, u16 *speed,
|
||||
u16 *duplex);
|
||||
s32 (*acquire_swfw_sync)(struct igc_hw *hw, u16 mask);
|
||||
void (*release_swfw_sync)(struct igc_hw *hw, u16 mask);
|
||||
};
|
||||
|
||||
enum igc_mac_type {
|
||||
igc_undefined = 0,
|
||||
igc_i225,
|
||||
igc_num_macs /* List is 1-based, so subtract 1 for true count. */
|
||||
};
|
||||
|
||||
enum igc_phy_type {
|
||||
igc_phy_unknown = 0,
|
||||
igc_phy_none,
|
||||
igc_phy_i225,
|
||||
};
|
||||
|
||||
enum igc_media_type {
|
||||
igc_media_type_unknown = 0,
|
||||
igc_media_type_copper = 1,
|
||||
igc_num_media_types
|
||||
};
|
||||
|
||||
enum igc_nvm_type {
|
||||
igc_nvm_unknown = 0,
|
||||
igc_nvm_eeprom_spi,
|
||||
igc_nvm_flash_hw,
|
||||
igc_nvm_invm,
|
||||
};
|
||||
|
||||
struct igc_info {
|
||||
s32 (*get_invariants)(struct igc_hw *hw);
|
||||
struct igc_mac_operations *mac_ops;
|
||||
const struct igc_phy_operations *phy_ops;
|
||||
struct igc_nvm_operations *nvm_ops;
|
||||
};
|
||||
|
||||
extern const struct igc_info igc_base_info;
|
||||
|
||||
struct igc_mac_info {
|
||||
struct igc_mac_operations ops;
|
||||
|
||||
u8 addr[ETH_ALEN];
|
||||
u8 perm_addr[ETH_ALEN];
|
||||
|
||||
enum igc_mac_type type;
|
||||
|
||||
u32 mc_filter_type;
|
||||
|
||||
u16 mta_reg_count;
|
||||
u16 uta_reg_count;
|
||||
|
||||
u32 mta_shadow[MAX_MTA_REG];
|
||||
u16 rar_entry_count;
|
||||
|
||||
u8 forced_speed_duplex;
|
||||
|
||||
bool asf_firmware_present;
|
||||
bool arc_subsystem_valid;
|
||||
|
||||
bool autoneg;
|
||||
bool autoneg_failed;
|
||||
bool get_link_status;
|
||||
};
|
||||
|
||||
struct igc_nvm_operations {
|
||||
s32 (*acquire)(struct igc_hw *hw);
|
||||
s32 (*read)(struct igc_hw *hw, u16 offset, u16 i, u16 *data);
|
||||
void (*release)(struct igc_hw *hw);
|
||||
s32 (*write)(struct igc_hw *hw, u16 offset, u16 i, u16 *data);
|
||||
s32 (*update)(struct igc_hw *hw);
|
||||
s32 (*validate)(struct igc_hw *hw);
|
||||
};
|
||||
|
||||
struct igc_phy_operations {
|
||||
s32 (*acquire)(struct igc_hw *hw);
|
||||
s32 (*check_reset_block)(struct igc_hw *hw);
|
||||
s32 (*force_speed_duplex)(struct igc_hw *hw);
|
||||
s32 (*get_phy_info)(struct igc_hw *hw);
|
||||
s32 (*read_reg)(struct igc_hw *hw, u32 address, u16 *data);
|
||||
void (*release)(struct igc_hw *hw);
|
||||
s32 (*reset)(struct igc_hw *hw);
|
||||
s32 (*write_reg)(struct igc_hw *hw, u32 address, u16 data);
|
||||
};
|
||||
|
||||
struct igc_nvm_info {
|
||||
struct igc_nvm_operations ops;
|
||||
enum igc_nvm_type type;
|
||||
|
||||
u16 word_size;
|
||||
u16 delay_usec;
|
||||
u16 address_bits;
|
||||
u16 opcode_bits;
|
||||
u16 page_size;
|
||||
};
|
||||
|
||||
struct igc_phy_info {
|
||||
struct igc_phy_operations ops;
|
||||
|
||||
enum igc_phy_type type;
|
||||
|
||||
u32 addr;
|
||||
u32 id;
|
||||
u32 reset_delay_us; /* in usec */
|
||||
u32 revision;
|
||||
|
||||
enum igc_media_type media_type;
|
||||
|
||||
u16 autoneg_advertised;
|
||||
u16 autoneg_mask;
|
||||
|
||||
u8 mdix;
|
||||
|
||||
bool is_mdix;
|
||||
bool speed_downgraded;
|
||||
bool autoneg_wait_to_complete;
|
||||
};
|
||||
|
||||
struct igc_bus_info {
|
||||
u16 func;
|
||||
u16 pci_cmd_word;
|
||||
};
|
||||
|
||||
enum igc_fc_mode {
|
||||
igc_fc_none = 0,
|
||||
igc_fc_rx_pause,
|
||||
igc_fc_tx_pause,
|
||||
igc_fc_full,
|
||||
igc_fc_default = 0xFF
|
||||
};
|
||||
|
||||
struct igc_fc_info {
|
||||
u32 high_water; /* Flow control high-water mark */
|
||||
u32 low_water; /* Flow control low-water mark */
|
||||
u16 pause_time; /* Flow control pause timer */
|
||||
bool send_xon; /* Flow control send XON */
|
||||
bool strict_ieee; /* Strict IEEE mode */
|
||||
enum igc_fc_mode current_mode; /* Type of flow control */
|
||||
enum igc_fc_mode requested_mode;
|
||||
};
|
||||
|
||||
struct igc_dev_spec_base {
|
||||
bool clear_semaphore_once;
|
||||
bool eee_enable;
|
||||
};
|
||||
|
||||
struct igc_hw {
|
||||
void *back;
|
||||
|
||||
u8 __iomem *hw_addr;
|
||||
unsigned long io_base;
|
||||
|
||||
struct igc_mac_info mac;
|
||||
struct igc_fc_info fc;
|
||||
struct igc_nvm_info nvm;
|
||||
struct igc_phy_info phy;
|
||||
|
||||
struct igc_bus_info bus;
|
||||
|
||||
union {
|
||||
struct igc_dev_spec_base _base;
|
||||
} dev_spec;
|
||||
|
||||
u16 device_id;
|
||||
u16 subsystem_vendor_id;
|
||||
u16 subsystem_device_id;
|
||||
u16 vendor_id;
|
||||
|
||||
u8 revision_id;
|
||||
};
|
||||
|
||||
/* Statistics counters collected by the MAC */
|
||||
struct igc_hw_stats {
|
||||
u64 crcerrs;
|
||||
u64 algnerrc;
|
||||
u64 symerrs;
|
||||
u64 rxerrc;
|
||||
u64 mpc;
|
||||
u64 scc;
|
||||
u64 ecol;
|
||||
u64 mcc;
|
||||
u64 latecol;
|
||||
u64 colc;
|
||||
u64 dc;
|
||||
u64 tncrs;
|
||||
u64 sec;
|
||||
u64 cexterr;
|
||||
u64 rlec;
|
||||
u64 xonrxc;
|
||||
u64 xontxc;
|
||||
u64 xoffrxc;
|
||||
u64 xofftxc;
|
||||
u64 fcruc;
|
||||
u64 prc64;
|
||||
u64 prc127;
|
||||
u64 prc255;
|
||||
u64 prc511;
|
||||
u64 prc1023;
|
||||
u64 prc1522;
|
||||
u64 tlpic;
|
||||
u64 rlpic;
|
||||
u64 gprc;
|
||||
u64 bprc;
|
||||
u64 mprc;
|
||||
u64 gptc;
|
||||
u64 gorc;
|
||||
u64 gotc;
|
||||
u64 rnbc;
|
||||
u64 ruc;
|
||||
u64 rfc;
|
||||
u64 roc;
|
||||
u64 rjc;
|
||||
u64 mgprc;
|
||||
u64 mgpdc;
|
||||
u64 mgptc;
|
||||
u64 tor;
|
||||
u64 tot;
|
||||
u64 tpr;
|
||||
u64 tpt;
|
||||
u64 ptc64;
|
||||
u64 ptc127;
|
||||
u64 ptc255;
|
||||
u64 ptc511;
|
||||
u64 ptc1023;
|
||||
u64 ptc1522;
|
||||
u64 mptc;
|
||||
u64 bptc;
|
||||
u64 tsctc;
|
||||
u64 tsctfc;
|
||||
u64 iac;
|
||||
u64 htdpmc;
|
||||
u64 rpthc;
|
||||
u64 hgptc;
|
||||
u64 hgorc;
|
||||
u64 hgotc;
|
||||
u64 lenerrs;
|
||||
u64 scvpc;
|
||||
u64 hrmpc;
|
||||
u64 doosync;
|
||||
u64 o2bgptc;
|
||||
u64 o2bspc;
|
||||
u64 b2ospc;
|
||||
u64 b2ogprc;
|
||||
};
|
||||
|
||||
struct net_device *igc_get_hw_dev(struct igc_hw *hw);
|
||||
#define hw_dbg(format, arg...) \
|
||||
netdev_dbg(igc_get_hw_dev(hw), format, ##arg)
|
||||
|
||||
s32 igc_read_pcie_cap_reg(struct igc_hw *hw, u32 reg, u16 *value);
|
||||
s32 igc_write_pcie_cap_reg(struct igc_hw *hw, u32 reg, u16 *value);
|
||||
void igc_read_pci_cfg(struct igc_hw *hw, u32 reg, u16 *value);
|
||||
void igc_write_pci_cfg(struct igc_hw *hw, u32 reg, u16 *value);
|
||||
|
||||
#endif /* _IGC_HW_H_ */
|
||||
652
devices/igc/igc_i225-5.15-ethercat.c
Normal file
652
devices/igc/igc_i225-5.15-ethercat.c
Normal file
File diff suppressed because it is too large
Load Diff
16
devices/igc/igc_i225-5.15-ethercat.h
Normal file
16
devices/igc/igc_i225-5.15-ethercat.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#ifndef _IGC_I225_H_
|
||||
#define _IGC_I225_H_
|
||||
|
||||
s32 igc_acquire_swfw_sync_i225(struct igc_hw *hw, u16 mask);
|
||||
void igc_release_swfw_sync_i225(struct igc_hw *hw, u16 mask);
|
||||
|
||||
s32 igc_init_nvm_params_i225(struct igc_hw *hw);
|
||||
bool igc_get_flash_presence_i225(struct igc_hw *hw);
|
||||
s32 igc_set_eee_i225(struct igc_hw *hw, bool adv2p5G, bool adv1G,
|
||||
bool adv100M);
|
||||
s32 igc_set_ltr_i225(struct igc_hw *hw, bool link);
|
||||
|
||||
#endif
|
||||
652
devices/igc/igc_i225-5.15-orig.c
Normal file
652
devices/igc/igc_i225-5.15-orig.c
Normal file
File diff suppressed because it is too large
Load Diff
16
devices/igc/igc_i225-5.15-orig.h
Normal file
16
devices/igc/igc_i225-5.15-orig.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#ifndef _IGC_I225_H_
|
||||
#define _IGC_I225_H_
|
||||
|
||||
s32 igc_acquire_swfw_sync_i225(struct igc_hw *hw, u16 mask);
|
||||
void igc_release_swfw_sync_i225(struct igc_hw *hw, u16 mask);
|
||||
|
||||
s32 igc_init_nvm_params_i225(struct igc_hw *hw);
|
||||
bool igc_get_flash_presence_i225(struct igc_hw *hw);
|
||||
s32 igc_set_eee_i225(struct igc_hw *hw, bool adv2p5G, bool adv1G,
|
||||
bool adv100M);
|
||||
s32 igc_set_ltr_i225(struct igc_hw *hw, bool link);
|
||||
|
||||
#endif
|
||||
881
devices/igc/igc_mac-5.15-ethercat.c
Normal file
881
devices/igc/igc_mac-5.15-ethercat.c
Normal file
File diff suppressed because it is too large
Load Diff
39
devices/igc/igc_mac-5.15-ethercat.h
Normal file
39
devices/igc/igc_mac-5.15-ethercat.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#ifndef _IGC_MAC_H_
|
||||
#define _IGC_MAC_H_
|
||||
|
||||
#include "igc_hw-5.15-ethercat.h"
|
||||
#include "igc_phy-5.15-ethercat.h"
|
||||
#include "igc_defines-5.15-ethercat.h"
|
||||
|
||||
/* forward declaration */
|
||||
s32 igc_disable_pcie_master(struct igc_hw *hw);
|
||||
s32 igc_check_for_copper_link(struct igc_hw *hw);
|
||||
s32 igc_config_fc_after_link_up(struct igc_hw *hw);
|
||||
s32 igc_force_mac_fc(struct igc_hw *hw);
|
||||
void igc_init_rx_addrs(struct igc_hw *hw, u16 rar_count);
|
||||
s32 igc_setup_link(struct igc_hw *hw);
|
||||
void igc_clear_hw_cntrs_base(struct igc_hw *hw);
|
||||
s32 igc_get_auto_rd_done(struct igc_hw *hw);
|
||||
void igc_put_hw_semaphore(struct igc_hw *hw);
|
||||
void igc_rar_set(struct igc_hw *hw, u8 *addr, u32 index);
|
||||
void igc_config_collision_dist(struct igc_hw *hw);
|
||||
|
||||
s32 igc_get_speed_and_duplex_copper(struct igc_hw *hw, u16 *speed,
|
||||
u16 *duplex);
|
||||
|
||||
bool igc_enable_mng_pass_thru(struct igc_hw *hw);
|
||||
void igc_update_mc_addr_list(struct igc_hw *hw,
|
||||
u8 *mc_addr_list, u32 mc_addr_count);
|
||||
|
||||
enum igc_mng_mode {
|
||||
igc_mng_mode_none = 0,
|
||||
igc_mng_mode_asf,
|
||||
igc_mng_mode_pt,
|
||||
igc_mng_mode_ipmi,
|
||||
igc_mng_mode_host_if_only
|
||||
};
|
||||
|
||||
#endif
|
||||
881
devices/igc/igc_mac-5.15-orig.c
Normal file
881
devices/igc/igc_mac-5.15-orig.c
Normal file
File diff suppressed because it is too large
Load Diff
39
devices/igc/igc_mac-5.15-orig.h
Normal file
39
devices/igc/igc_mac-5.15-orig.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#ifndef _IGC_MAC_H_
|
||||
#define _IGC_MAC_H_
|
||||
|
||||
#include "igc_hw.h"
|
||||
#include "igc_phy.h"
|
||||
#include "igc_defines.h"
|
||||
|
||||
/* forward declaration */
|
||||
s32 igc_disable_pcie_master(struct igc_hw *hw);
|
||||
s32 igc_check_for_copper_link(struct igc_hw *hw);
|
||||
s32 igc_config_fc_after_link_up(struct igc_hw *hw);
|
||||
s32 igc_force_mac_fc(struct igc_hw *hw);
|
||||
void igc_init_rx_addrs(struct igc_hw *hw, u16 rar_count);
|
||||
s32 igc_setup_link(struct igc_hw *hw);
|
||||
void igc_clear_hw_cntrs_base(struct igc_hw *hw);
|
||||
s32 igc_get_auto_rd_done(struct igc_hw *hw);
|
||||
void igc_put_hw_semaphore(struct igc_hw *hw);
|
||||
void igc_rar_set(struct igc_hw *hw, u8 *addr, u32 index);
|
||||
void igc_config_collision_dist(struct igc_hw *hw);
|
||||
|
||||
s32 igc_get_speed_and_duplex_copper(struct igc_hw *hw, u16 *speed,
|
||||
u16 *duplex);
|
||||
|
||||
bool igc_enable_mng_pass_thru(struct igc_hw *hw);
|
||||
void igc_update_mc_addr_list(struct igc_hw *hw,
|
||||
u8 *mc_addr_list, u32 mc_addr_count);
|
||||
|
||||
enum igc_mng_mode {
|
||||
igc_mng_mode_none = 0,
|
||||
igc_mng_mode_asf,
|
||||
igc_mng_mode_pt,
|
||||
igc_mng_mode_ipmi,
|
||||
igc_mng_mode_host_if_only
|
||||
};
|
||||
|
||||
#endif
|
||||
7111
devices/igc/igc_main-5.15-ethercat.c
Normal file
7111
devices/igc/igc_main-5.15-ethercat.c
Normal file
File diff suppressed because it is too large
Load Diff
6966
devices/igc/igc_main-5.15-orig.c
Normal file
6966
devices/igc/igc_main-5.15-orig.c
Normal file
File diff suppressed because it is too large
Load Diff
215
devices/igc/igc_nvm-5.15-ethercat.c
Normal file
215
devices/igc/igc_nvm-5.15-ethercat.c
Normal file
@@ -0,0 +1,215 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#include "igc_mac-5.15-ethercat.h"
|
||||
#include "igc_nvm-5.15-ethercat.h"
|
||||
|
||||
/**
|
||||
* igc_poll_eerd_eewr_done - Poll for EEPROM read/write completion
|
||||
* @hw: pointer to the HW structure
|
||||
* @ee_reg: EEPROM flag for polling
|
||||
*
|
||||
* Polls the EEPROM status bit for either read or write completion based
|
||||
* upon the value of 'ee_reg'.
|
||||
*/
|
||||
static s32 igc_poll_eerd_eewr_done(struct igc_hw *hw, int ee_reg)
|
||||
{
|
||||
s32 ret_val = -IGC_ERR_NVM;
|
||||
u32 attempts = 100000;
|
||||
u32 i, reg = 0;
|
||||
|
||||
for (i = 0; i < attempts; i++) {
|
||||
if (ee_reg == IGC_NVM_POLL_READ)
|
||||
reg = rd32(IGC_EERD);
|
||||
else
|
||||
reg = rd32(IGC_EEWR);
|
||||
|
||||
if (reg & IGC_NVM_RW_REG_DONE) {
|
||||
ret_val = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
udelay(5);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_acquire_nvm - Generic request for access to EEPROM
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
|
||||
* Return successful if access grant bit set, else clear the request for
|
||||
* EEPROM access and return -IGC_ERR_NVM (-1).
|
||||
*/
|
||||
s32 igc_acquire_nvm(struct igc_hw *hw)
|
||||
{
|
||||
s32 timeout = IGC_NVM_GRANT_ATTEMPTS;
|
||||
u32 eecd = rd32(IGC_EECD);
|
||||
s32 ret_val = 0;
|
||||
|
||||
wr32(IGC_EECD, eecd | IGC_EECD_REQ);
|
||||
eecd = rd32(IGC_EECD);
|
||||
|
||||
while (timeout) {
|
||||
if (eecd & IGC_EECD_GNT)
|
||||
break;
|
||||
udelay(5);
|
||||
eecd = rd32(IGC_EECD);
|
||||
timeout--;
|
||||
}
|
||||
|
||||
if (!timeout) {
|
||||
eecd &= ~IGC_EECD_REQ;
|
||||
wr32(IGC_EECD, eecd);
|
||||
hw_dbg("Could not acquire NVM grant\n");
|
||||
ret_val = -IGC_ERR_NVM;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_release_nvm - Release exclusive access to EEPROM
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Stop any current commands to the EEPROM and clear the EEPROM request bit.
|
||||
*/
|
||||
void igc_release_nvm(struct igc_hw *hw)
|
||||
{
|
||||
u32 eecd;
|
||||
|
||||
eecd = rd32(IGC_EECD);
|
||||
eecd &= ~IGC_EECD_REQ;
|
||||
wr32(IGC_EECD, eecd);
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_read_nvm_eerd - Reads EEPROM using EERD register
|
||||
* @hw: pointer to the HW structure
|
||||
* @offset: offset of word in the EEPROM to read
|
||||
* @words: number of words to read
|
||||
* @data: word read from the EEPROM
|
||||
*
|
||||
* Reads a 16 bit word from the EEPROM using the EERD register.
|
||||
*/
|
||||
s32 igc_read_nvm_eerd(struct igc_hw *hw, u16 offset, u16 words, u16 *data)
|
||||
{
|
||||
struct igc_nvm_info *nvm = &hw->nvm;
|
||||
u32 i, eerd = 0;
|
||||
s32 ret_val = 0;
|
||||
|
||||
/* A check for invalid values: offset too large, too many words,
|
||||
* and not enough words.
|
||||
*/
|
||||
if (offset >= nvm->word_size || (words > (nvm->word_size - offset)) ||
|
||||
words == 0) {
|
||||
hw_dbg("nvm parameter(s) out of bounds\n");
|
||||
ret_val = -IGC_ERR_NVM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < words; i++) {
|
||||
eerd = ((offset + i) << IGC_NVM_RW_ADDR_SHIFT) +
|
||||
IGC_NVM_RW_REG_START;
|
||||
|
||||
wr32(IGC_EERD, eerd);
|
||||
ret_val = igc_poll_eerd_eewr_done(hw, IGC_NVM_POLL_READ);
|
||||
if (ret_val)
|
||||
break;
|
||||
|
||||
data[i] = (rd32(IGC_EERD) >> IGC_NVM_RW_REG_DATA);
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_read_mac_addr - Read device MAC address
|
||||
* @hw: pointer to the HW structure
|
||||
*/
|
||||
s32 igc_read_mac_addr(struct igc_hw *hw)
|
||||
{
|
||||
u32 rar_high;
|
||||
u32 rar_low;
|
||||
u16 i;
|
||||
|
||||
rar_high = rd32(IGC_RAH(0));
|
||||
rar_low = rd32(IGC_RAL(0));
|
||||
|
||||
for (i = 0; i < IGC_RAL_MAC_ADDR_LEN; i++)
|
||||
hw->mac.perm_addr[i] = (u8)(rar_low >> (i * 8));
|
||||
|
||||
for (i = 0; i < IGC_RAH_MAC_ADDR_LEN; i++)
|
||||
hw->mac.perm_addr[i + 4] = (u8)(rar_high >> (i * 8));
|
||||
|
||||
for (i = 0; i < ETH_ALEN; i++)
|
||||
hw->mac.addr[i] = hw->mac.perm_addr[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_validate_nvm_checksum - Validate EEPROM checksum
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Calculates the EEPROM checksum by reading/adding each word of the EEPROM
|
||||
* and then verifies that the sum of the EEPROM is equal to 0xBABA.
|
||||
*/
|
||||
s32 igc_validate_nvm_checksum(struct igc_hw *hw)
|
||||
{
|
||||
u16 checksum = 0;
|
||||
u16 i, nvm_data;
|
||||
s32 ret_val = 0;
|
||||
|
||||
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
|
||||
ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
|
||||
if (ret_val) {
|
||||
hw_dbg("NVM Read Error\n");
|
||||
goto out;
|
||||
}
|
||||
checksum += nvm_data;
|
||||
}
|
||||
|
||||
if (checksum != (u16)NVM_SUM) {
|
||||
hw_dbg("NVM Checksum Invalid\n");
|
||||
ret_val = -IGC_ERR_NVM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_update_nvm_checksum - Update EEPROM checksum
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Updates the EEPROM checksum by reading/adding each word of the EEPROM
|
||||
* up to the checksum. Then calculates the EEPROM checksum and writes the
|
||||
* value to the EEPROM.
|
||||
*/
|
||||
s32 igc_update_nvm_checksum(struct igc_hw *hw)
|
||||
{
|
||||
u16 checksum = 0;
|
||||
u16 i, nvm_data;
|
||||
s32 ret_val;
|
||||
|
||||
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
|
||||
ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
|
||||
if (ret_val) {
|
||||
hw_dbg("NVM Read Error while updating checksum.\n");
|
||||
goto out;
|
||||
}
|
||||
checksum += nvm_data;
|
||||
}
|
||||
checksum = (u16)NVM_SUM - checksum;
|
||||
ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);
|
||||
if (ret_val)
|
||||
hw_dbg("NVM Write Error while updating checksum.\n");
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
14
devices/igc/igc_nvm-5.15-ethercat.h
Normal file
14
devices/igc/igc_nvm-5.15-ethercat.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#ifndef _IGC_NVM_H_
|
||||
#define _IGC_NVM_H_
|
||||
|
||||
s32 igc_acquire_nvm(struct igc_hw *hw);
|
||||
void igc_release_nvm(struct igc_hw *hw);
|
||||
s32 igc_read_mac_addr(struct igc_hw *hw);
|
||||
s32 igc_read_nvm_eerd(struct igc_hw *hw, u16 offset, u16 words, u16 *data);
|
||||
s32 igc_validate_nvm_checksum(struct igc_hw *hw);
|
||||
s32 igc_update_nvm_checksum(struct igc_hw *hw);
|
||||
|
||||
#endif
|
||||
215
devices/igc/igc_nvm-5.15-orig.c
Normal file
215
devices/igc/igc_nvm-5.15-orig.c
Normal file
@@ -0,0 +1,215 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#include "igc_mac.h"
|
||||
#include "igc_nvm.h"
|
||||
|
||||
/**
|
||||
* igc_poll_eerd_eewr_done - Poll for EEPROM read/write completion
|
||||
* @hw: pointer to the HW structure
|
||||
* @ee_reg: EEPROM flag for polling
|
||||
*
|
||||
* Polls the EEPROM status bit for either read or write completion based
|
||||
* upon the value of 'ee_reg'.
|
||||
*/
|
||||
static s32 igc_poll_eerd_eewr_done(struct igc_hw *hw, int ee_reg)
|
||||
{
|
||||
s32 ret_val = -IGC_ERR_NVM;
|
||||
u32 attempts = 100000;
|
||||
u32 i, reg = 0;
|
||||
|
||||
for (i = 0; i < attempts; i++) {
|
||||
if (ee_reg == IGC_NVM_POLL_READ)
|
||||
reg = rd32(IGC_EERD);
|
||||
else
|
||||
reg = rd32(IGC_EEWR);
|
||||
|
||||
if (reg & IGC_NVM_RW_REG_DONE) {
|
||||
ret_val = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
udelay(5);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_acquire_nvm - Generic request for access to EEPROM
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
|
||||
* Return successful if access grant bit set, else clear the request for
|
||||
* EEPROM access and return -IGC_ERR_NVM (-1).
|
||||
*/
|
||||
s32 igc_acquire_nvm(struct igc_hw *hw)
|
||||
{
|
||||
s32 timeout = IGC_NVM_GRANT_ATTEMPTS;
|
||||
u32 eecd = rd32(IGC_EECD);
|
||||
s32 ret_val = 0;
|
||||
|
||||
wr32(IGC_EECD, eecd | IGC_EECD_REQ);
|
||||
eecd = rd32(IGC_EECD);
|
||||
|
||||
while (timeout) {
|
||||
if (eecd & IGC_EECD_GNT)
|
||||
break;
|
||||
udelay(5);
|
||||
eecd = rd32(IGC_EECD);
|
||||
timeout--;
|
||||
}
|
||||
|
||||
if (!timeout) {
|
||||
eecd &= ~IGC_EECD_REQ;
|
||||
wr32(IGC_EECD, eecd);
|
||||
hw_dbg("Could not acquire NVM grant\n");
|
||||
ret_val = -IGC_ERR_NVM;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_release_nvm - Release exclusive access to EEPROM
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Stop any current commands to the EEPROM and clear the EEPROM request bit.
|
||||
*/
|
||||
void igc_release_nvm(struct igc_hw *hw)
|
||||
{
|
||||
u32 eecd;
|
||||
|
||||
eecd = rd32(IGC_EECD);
|
||||
eecd &= ~IGC_EECD_REQ;
|
||||
wr32(IGC_EECD, eecd);
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_read_nvm_eerd - Reads EEPROM using EERD register
|
||||
* @hw: pointer to the HW structure
|
||||
* @offset: offset of word in the EEPROM to read
|
||||
* @words: number of words to read
|
||||
* @data: word read from the EEPROM
|
||||
*
|
||||
* Reads a 16 bit word from the EEPROM using the EERD register.
|
||||
*/
|
||||
s32 igc_read_nvm_eerd(struct igc_hw *hw, u16 offset, u16 words, u16 *data)
|
||||
{
|
||||
struct igc_nvm_info *nvm = &hw->nvm;
|
||||
u32 i, eerd = 0;
|
||||
s32 ret_val = 0;
|
||||
|
||||
/* A check for invalid values: offset too large, too many words,
|
||||
* and not enough words.
|
||||
*/
|
||||
if (offset >= nvm->word_size || (words > (nvm->word_size - offset)) ||
|
||||
words == 0) {
|
||||
hw_dbg("nvm parameter(s) out of bounds\n");
|
||||
ret_val = -IGC_ERR_NVM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < words; i++) {
|
||||
eerd = ((offset + i) << IGC_NVM_RW_ADDR_SHIFT) +
|
||||
IGC_NVM_RW_REG_START;
|
||||
|
||||
wr32(IGC_EERD, eerd);
|
||||
ret_val = igc_poll_eerd_eewr_done(hw, IGC_NVM_POLL_READ);
|
||||
if (ret_val)
|
||||
break;
|
||||
|
||||
data[i] = (rd32(IGC_EERD) >> IGC_NVM_RW_REG_DATA);
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_read_mac_addr - Read device MAC address
|
||||
* @hw: pointer to the HW structure
|
||||
*/
|
||||
s32 igc_read_mac_addr(struct igc_hw *hw)
|
||||
{
|
||||
u32 rar_high;
|
||||
u32 rar_low;
|
||||
u16 i;
|
||||
|
||||
rar_high = rd32(IGC_RAH(0));
|
||||
rar_low = rd32(IGC_RAL(0));
|
||||
|
||||
for (i = 0; i < IGC_RAL_MAC_ADDR_LEN; i++)
|
||||
hw->mac.perm_addr[i] = (u8)(rar_low >> (i * 8));
|
||||
|
||||
for (i = 0; i < IGC_RAH_MAC_ADDR_LEN; i++)
|
||||
hw->mac.perm_addr[i + 4] = (u8)(rar_high >> (i * 8));
|
||||
|
||||
for (i = 0; i < ETH_ALEN; i++)
|
||||
hw->mac.addr[i] = hw->mac.perm_addr[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_validate_nvm_checksum - Validate EEPROM checksum
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Calculates the EEPROM checksum by reading/adding each word of the EEPROM
|
||||
* and then verifies that the sum of the EEPROM is equal to 0xBABA.
|
||||
*/
|
||||
s32 igc_validate_nvm_checksum(struct igc_hw *hw)
|
||||
{
|
||||
u16 checksum = 0;
|
||||
u16 i, nvm_data;
|
||||
s32 ret_val = 0;
|
||||
|
||||
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
|
||||
ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
|
||||
if (ret_val) {
|
||||
hw_dbg("NVM Read Error\n");
|
||||
goto out;
|
||||
}
|
||||
checksum += nvm_data;
|
||||
}
|
||||
|
||||
if (checksum != (u16)NVM_SUM) {
|
||||
hw_dbg("NVM Checksum Invalid\n");
|
||||
ret_val = -IGC_ERR_NVM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_update_nvm_checksum - Update EEPROM checksum
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Updates the EEPROM checksum by reading/adding each word of the EEPROM
|
||||
* up to the checksum. Then calculates the EEPROM checksum and writes the
|
||||
* value to the EEPROM.
|
||||
*/
|
||||
s32 igc_update_nvm_checksum(struct igc_hw *hw)
|
||||
{
|
||||
u16 checksum = 0;
|
||||
u16 i, nvm_data;
|
||||
s32 ret_val;
|
||||
|
||||
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
|
||||
ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
|
||||
if (ret_val) {
|
||||
hw_dbg("NVM Read Error while updating checksum.\n");
|
||||
goto out;
|
||||
}
|
||||
checksum += nvm_data;
|
||||
}
|
||||
checksum = (u16)NVM_SUM - checksum;
|
||||
ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);
|
||||
if (ret_val)
|
||||
hw_dbg("NVM Write Error while updating checksum.\n");
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
14
devices/igc/igc_nvm-5.15-orig.h
Normal file
14
devices/igc/igc_nvm-5.15-orig.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#ifndef _IGC_NVM_H_
|
||||
#define _IGC_NVM_H_
|
||||
|
||||
s32 igc_acquire_nvm(struct igc_hw *hw);
|
||||
void igc_release_nvm(struct igc_hw *hw);
|
||||
s32 igc_read_mac_addr(struct igc_hw *hw);
|
||||
s32 igc_read_nvm_eerd(struct igc_hw *hw, u16 offset, u16 words, u16 *data);
|
||||
s32 igc_validate_nvm_checksum(struct igc_hw *hw);
|
||||
s32 igc_update_nvm_checksum(struct igc_hw *hw);
|
||||
|
||||
#endif
|
||||
805
devices/igc/igc_phy-5.15-ethercat.c
Normal file
805
devices/igc/igc_phy-5.15-ethercat.c
Normal file
File diff suppressed because it is too large
Load Diff
22
devices/igc/igc_phy-5.15-ethercat.h
Normal file
22
devices/igc/igc_phy-5.15-ethercat.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#ifndef _IGC_PHY_H_
|
||||
#define _IGC_PHY_H_
|
||||
|
||||
#include "igc_mac-5.15-ethercat.h"
|
||||
|
||||
s32 igc_check_reset_block(struct igc_hw *hw);
|
||||
s32 igc_phy_hw_reset(struct igc_hw *hw);
|
||||
s32 igc_get_phy_id(struct igc_hw *hw);
|
||||
s32 igc_phy_has_link(struct igc_hw *hw, u32 iterations,
|
||||
u32 usec_interval, bool *success);
|
||||
s32 igc_check_downshift(struct igc_hw *hw);
|
||||
s32 igc_setup_copper_link(struct igc_hw *hw);
|
||||
void igc_power_up_phy_copper(struct igc_hw *hw);
|
||||
void igc_power_down_phy_copper(struct igc_hw *hw);
|
||||
s32 igc_write_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 data);
|
||||
s32 igc_read_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 *data);
|
||||
u16 igc_read_phy_fw_version(struct igc_hw *hw);
|
||||
|
||||
#endif
|
||||
805
devices/igc/igc_phy-5.15-orig.c
Normal file
805
devices/igc/igc_phy-5.15-orig.c
Normal file
File diff suppressed because it is too large
Load Diff
22
devices/igc/igc_phy-5.15-orig.h
Normal file
22
devices/igc/igc_phy-5.15-orig.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#ifndef _IGC_PHY_H_
|
||||
#define _IGC_PHY_H_
|
||||
|
||||
#include "igc_mac.h"
|
||||
|
||||
s32 igc_check_reset_block(struct igc_hw *hw);
|
||||
s32 igc_phy_hw_reset(struct igc_hw *hw);
|
||||
s32 igc_get_phy_id(struct igc_hw *hw);
|
||||
s32 igc_phy_has_link(struct igc_hw *hw, u32 iterations,
|
||||
u32 usec_interval, bool *success);
|
||||
s32 igc_check_downshift(struct igc_hw *hw);
|
||||
s32 igc_setup_copper_link(struct igc_hw *hw);
|
||||
void igc_power_up_phy_copper(struct igc_hw *hw);
|
||||
void igc_power_down_phy_copper(struct igc_hw *hw);
|
||||
s32 igc_write_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 data);
|
||||
s32 igc_read_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 *data);
|
||||
u16 igc_read_phy_fw_version(struct igc_hw *hw);
|
||||
|
||||
#endif
|
||||
1119
devices/igc/igc_ptp-5.15-ethercat.c
Normal file
1119
devices/igc/igc_ptp-5.15-ethercat.c
Normal file
File diff suppressed because it is too large
Load Diff
1119
devices/igc/igc_ptp-5.15-orig.c
Normal file
1119
devices/igc/igc_ptp-5.15-orig.c
Normal file
File diff suppressed because it is too large
Load Diff
321
devices/igc/igc_regs-5.15-ethercat.h
Normal file
321
devices/igc/igc_regs-5.15-ethercat.h
Normal file
@@ -0,0 +1,321 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#ifndef _IGC_REGS_H_
|
||||
#define _IGC_REGS_H_
|
||||
|
||||
/* General Register Descriptions */
|
||||
#define IGC_CTRL 0x00000 /* Device Control - RW */
|
||||
#define IGC_STATUS 0x00008 /* Device Status - RO */
|
||||
#define IGC_EECD 0x00010 /* EEPROM/Flash Control - RW */
|
||||
#define IGC_CTRL_EXT 0x00018 /* Extended Device Control - RW */
|
||||
#define IGC_MDIC 0x00020 /* MDI Control - RW */
|
||||
#define IGC_CONNSW 0x00034 /* Copper/Fiber switch control - RW */
|
||||
#define IGC_VET 0x00038 /* VLAN Ether Type - RW */
|
||||
#define IGC_I225_PHPM 0x00E14 /* I225 PHY Power Management */
|
||||
#define IGC_GPHY_VERSION 0x0001E /* I225 gPHY Firmware Version */
|
||||
|
||||
/* Internal Packet Buffer Size Registers */
|
||||
#define IGC_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */
|
||||
#define IGC_TXPBS 0x03404 /* Tx Packet Buffer Size - RW */
|
||||
|
||||
/* NVM Register Descriptions */
|
||||
#define IGC_EERD 0x12014 /* EEprom mode read - RW */
|
||||
#define IGC_EEWR 0x12018 /* EEprom mode write - RW */
|
||||
|
||||
/* Flow Control Register Descriptions */
|
||||
#define IGC_FCAL 0x00028 /* FC Address Low - RW */
|
||||
#define IGC_FCAH 0x0002C /* FC Address High - RW */
|
||||
#define IGC_FCT 0x00030 /* FC Type - RW */
|
||||
#define IGC_FCTTV 0x00170 /* FC Transmit Timer - RW */
|
||||
#define IGC_FCRTL 0x02160 /* FC Receive Threshold Low - RW */
|
||||
#define IGC_FCRTH 0x02168 /* FC Receive Threshold High - RW */
|
||||
#define IGC_FCRTV 0x02460 /* FC Refresh Timer Value - RW */
|
||||
|
||||
/* Semaphore registers */
|
||||
#define IGC_SW_FW_SYNC 0x05B5C /* SW-FW Synchronization - RW */
|
||||
#define IGC_SWSM 0x05B50 /* SW Semaphore */
|
||||
#define IGC_FWSM 0x05B54 /* FW Semaphore */
|
||||
|
||||
/* Function Active and Power State to MNG */
|
||||
#define IGC_FACTPS 0x05B30
|
||||
|
||||
/* Interrupt Register Description */
|
||||
#define IGC_EICR 0x01580 /* Ext. Interrupt Cause read - W0 */
|
||||
#define IGC_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */
|
||||
#define IGC_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */
|
||||
#define IGC_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */
|
||||
#define IGC_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */
|
||||
#define IGC_EIAM 0x01530 /* Ext. Interrupt Auto Mask - RW */
|
||||
#define IGC_ICR 0x01500 /* Intr Cause Read - RC/W1C */
|
||||
#define IGC_ICS 0x01504 /* Intr Cause Set - WO */
|
||||
#define IGC_IMS 0x01508 /* Intr Mask Set/Read - RW */
|
||||
#define IGC_IMC 0x0150C /* Intr Mask Clear - WO */
|
||||
#define IGC_IAM 0x01510 /* Intr Ack Auto Mask- RW */
|
||||
/* Intr Throttle - RW */
|
||||
#define IGC_EITR(_n) (0x01680 + (0x4 * (_n)))
|
||||
/* Interrupt Vector Allocation - RW */
|
||||
#define IGC_IVAR0 0x01700
|
||||
#define IGC_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */
|
||||
#define IGC_GPIE 0x01514 /* General Purpose Intr Enable - RW */
|
||||
|
||||
/* MSI-X Table Register Descriptions */
|
||||
#define IGC_PBACL 0x05B68 /* MSIx PBA Clear - R/W 1 to clear */
|
||||
|
||||
/* RSS registers */
|
||||
#define IGC_MRQC 0x05818 /* Multiple Receive Control - RW */
|
||||
|
||||
/* Filtering Registers */
|
||||
#define IGC_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
|
||||
#define IGC_FHFT(_n) (0x09000 + (256 * (_n))) /* Flexible Host Filter */
|
||||
#define IGC_FHFT_EXT(_n) (0x09A00 + (256 * (_n))) /* Flexible Host Filter Extended */
|
||||
#define IGC_FHFTSL 0x05804 /* Flex Filter indirect table select */
|
||||
|
||||
/* ETQF register bit definitions */
|
||||
#define IGC_ETQF_FILTER_ENABLE BIT(26)
|
||||
#define IGC_ETQF_QUEUE_ENABLE BIT(31)
|
||||
#define IGC_ETQF_QUEUE_SHIFT 16
|
||||
#define IGC_ETQF_QUEUE_MASK 0x00070000
|
||||
#define IGC_ETQF_ETYPE_MASK 0x0000FFFF
|
||||
|
||||
/* FHFT register bit definitions */
|
||||
#define IGC_FHFT_LENGTH_MASK GENMASK(7, 0)
|
||||
#define IGC_FHFT_QUEUE_SHIFT 8
|
||||
#define IGC_FHFT_QUEUE_MASK GENMASK(10, 8)
|
||||
#define IGC_FHFT_PRIO_SHIFT 16
|
||||
#define IGC_FHFT_PRIO_MASK GENMASK(18, 16)
|
||||
#define IGC_FHFT_IMM_INT BIT(24)
|
||||
#define IGC_FHFT_DROP BIT(25)
|
||||
|
||||
/* FHFTSL register bit definitions */
|
||||
#define IGC_FHFTSL_FTSL_SHIFT 0
|
||||
#define IGC_FHFTSL_FTSL_MASK GENMASK(1, 0)
|
||||
|
||||
/* Redirection Table - RW Array */
|
||||
#define IGC_RETA(_i) (0x05C00 + ((_i) * 4))
|
||||
/* RSS Random Key - RW Array */
|
||||
#define IGC_RSSRK(_i) (0x05C80 + ((_i) * 4))
|
||||
|
||||
/* Receive Register Descriptions */
|
||||
#define IGC_RCTL 0x00100 /* Rx Control - RW */
|
||||
#define IGC_SRRCTL(_n) (0x0C00C + ((_n) * 0x40))
|
||||
#define IGC_PSRTYPE(_i) (0x05480 + ((_i) * 4))
|
||||
#define IGC_RDBAL(_n) (0x0C000 + ((_n) * 0x40))
|
||||
#define IGC_RDBAH(_n) (0x0C004 + ((_n) * 0x40))
|
||||
#define IGC_RDLEN(_n) (0x0C008 + ((_n) * 0x40))
|
||||
#define IGC_RDH(_n) (0x0C010 + ((_n) * 0x40))
|
||||
#define IGC_RDT(_n) (0x0C018 + ((_n) * 0x40))
|
||||
#define IGC_RXDCTL(_n) (0x0C028 + ((_n) * 0x40))
|
||||
#define IGC_RQDPC(_n) (0x0C030 + ((_n) * 0x40))
|
||||
#define IGC_RXCSUM 0x05000 /* Rx Checksum Control - RW */
|
||||
#define IGC_RLPML 0x05004 /* Rx Long Packet Max Length */
|
||||
#define IGC_RFCTL 0x05008 /* Receive Filter Control*/
|
||||
#define IGC_MTA 0x05200 /* Multicast Table Array - RW Array */
|
||||
#define IGC_RA 0x05400 /* Receive Address - RW Array */
|
||||
#define IGC_UTA 0x0A000 /* Unicast Table Array - RW */
|
||||
#define IGC_RAL(_n) (0x05400 + ((_n) * 0x08))
|
||||
#define IGC_RAH(_n) (0x05404 + ((_n) * 0x08))
|
||||
#define IGC_VLANPQF 0x055B0 /* VLAN Priority Queue Filter - RW */
|
||||
|
||||
/* Transmit Register Descriptions */
|
||||
#define IGC_TCTL 0x00400 /* Tx Control - RW */
|
||||
#define IGC_TIPG 0x00410 /* Tx Inter-packet gap - RW */
|
||||
#define IGC_TDBAL(_n) (0x0E000 + ((_n) * 0x40))
|
||||
#define IGC_TDBAH(_n) (0x0E004 + ((_n) * 0x40))
|
||||
#define IGC_TDLEN(_n) (0x0E008 + ((_n) * 0x40))
|
||||
#define IGC_TDH(_n) (0x0E010 + ((_n) * 0x40))
|
||||
#define IGC_TDT(_n) (0x0E018 + ((_n) * 0x40))
|
||||
#define IGC_TXDCTL(_n) (0x0E028 + ((_n) * 0x40))
|
||||
|
||||
/* MMD Register Descriptions */
|
||||
#define IGC_MMDAC 13 /* MMD Access Control */
|
||||
#define IGC_MMDAAD 14 /* MMD Access Address/Data */
|
||||
|
||||
/* Statistics Register Descriptions */
|
||||
#define IGC_CRCERRS 0x04000 /* CRC Error Count - R/clr */
|
||||
#define IGC_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
|
||||
#define IGC_RXERRC 0x0400C /* Receive Error Count - R/clr */
|
||||
#define IGC_MPC 0x04010 /* Missed Packet Count - R/clr */
|
||||
#define IGC_SCC 0x04014 /* Single Collision Count - R/clr */
|
||||
#define IGC_ECOL 0x04018 /* Excessive Collision Count - R/clr */
|
||||
#define IGC_MCC 0x0401C /* Multiple Collision Count - R/clr */
|
||||
#define IGC_LATECOL 0x04020 /* Late Collision Count - R/clr */
|
||||
#define IGC_COLC 0x04028 /* Collision Count - R/clr */
|
||||
#define IGC_RERC 0x0402C /* Receive Error Count - R/clr */
|
||||
#define IGC_DC 0x04030 /* Defer Count - R/clr */
|
||||
#define IGC_TNCRS 0x04034 /* Tx-No CRS - R/clr */
|
||||
#define IGC_HTDPMC 0x0403C /* Host Transmit Discarded by MAC - R/clr */
|
||||
#define IGC_RLEC 0x04040 /* Receive Length Error Count - R/clr */
|
||||
#define IGC_XONRXC 0x04048 /* XON Rx Count - R/clr */
|
||||
#define IGC_XONTXC 0x0404C /* XON Tx Count - R/clr */
|
||||
#define IGC_XOFFRXC 0x04050 /* XOFF Rx Count - R/clr */
|
||||
#define IGC_XOFFTXC 0x04054 /* XOFF Tx Count - R/clr */
|
||||
#define IGC_FCRUC 0x04058 /* Flow Control Rx Unsupported Count- R/clr */
|
||||
#define IGC_PRC64 0x0405C /* Packets Rx (64 bytes) - R/clr */
|
||||
#define IGC_PRC127 0x04060 /* Packets Rx (65-127 bytes) - R/clr */
|
||||
#define IGC_PRC255 0x04064 /* Packets Rx (128-255 bytes) - R/clr */
|
||||
#define IGC_PRC511 0x04068 /* Packets Rx (255-511 bytes) - R/clr */
|
||||
#define IGC_PRC1023 0x0406C /* Packets Rx (512-1023 bytes) - R/clr */
|
||||
#define IGC_PRC1522 0x04070 /* Packets Rx (1024-1522 bytes) - R/clr */
|
||||
#define IGC_GPRC 0x04074 /* Good Packets Rx Count - R/clr */
|
||||
#define IGC_BPRC 0x04078 /* Broadcast Packets Rx Count - R/clr */
|
||||
#define IGC_MPRC 0x0407C /* Multicast Packets Rx Count - R/clr */
|
||||
#define IGC_GPTC 0x04080 /* Good Packets Tx Count - R/clr */
|
||||
#define IGC_GORCL 0x04088 /* Good Octets Rx Count Low - R/clr */
|
||||
#define IGC_GORCH 0x0408C /* Good Octets Rx Count High - R/clr */
|
||||
#define IGC_GOTCL 0x04090 /* Good Octets Tx Count Low - R/clr */
|
||||
#define IGC_GOTCH 0x04094 /* Good Octets Tx Count High - R/clr */
|
||||
#define IGC_RNBC 0x040A0 /* Rx No Buffers Count - R/clr */
|
||||
#define IGC_RUC 0x040A4 /* Rx Undersize Count - R/clr */
|
||||
#define IGC_RFC 0x040A8 /* Rx Fragment Count - R/clr */
|
||||
#define IGC_ROC 0x040AC /* Rx Oversize Count - R/clr */
|
||||
#define IGC_RJC 0x040B0 /* Rx Jabber Count - R/clr */
|
||||
#define IGC_MGTPRC 0x040B4 /* Management Packets Rx Count - R/clr */
|
||||
#define IGC_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
|
||||
#define IGC_MGTPTC 0x040BC /* Management Packets Tx Count - R/clr */
|
||||
#define IGC_TORL 0x040C0 /* Total Octets Rx Low - R/clr */
|
||||
#define IGC_TORH 0x040C4 /* Total Octets Rx High - R/clr */
|
||||
#define IGC_TOTL 0x040C8 /* Total Octets Tx Low - R/clr */
|
||||
#define IGC_TOTH 0x040CC /* Total Octets Tx High - R/clr */
|
||||
#define IGC_TPR 0x040D0 /* Total Packets Rx - R/clr */
|
||||
#define IGC_TPT 0x040D4 /* Total Packets Tx - R/clr */
|
||||
#define IGC_PTC64 0x040D8 /* Packets Tx (64 bytes) - R/clr */
|
||||
#define IGC_PTC127 0x040DC /* Packets Tx (65-127 bytes) - R/clr */
|
||||
#define IGC_PTC255 0x040E0 /* Packets Tx (128-255 bytes) - R/clr */
|
||||
#define IGC_PTC511 0x040E4 /* Packets Tx (256-511 bytes) - R/clr */
|
||||
#define IGC_PTC1023 0x040E8 /* Packets Tx (512-1023 bytes) - R/clr */
|
||||
#define IGC_PTC1522 0x040EC /* Packets Tx (1024-1522 Bytes) - R/clr */
|
||||
#define IGC_MPTC 0x040F0 /* Multicast Packets Tx Count - R/clr */
|
||||
#define IGC_BPTC 0x040F4 /* Broadcast Packets Tx Count - R/clr */
|
||||
#define IGC_TSCTC 0x040F8 /* TCP Segmentation Context Tx - R/clr */
|
||||
#define IGC_IAC 0x04100 /* Interrupt Assertion Count */
|
||||
#define IGC_RPTHC 0x04104 /* Rx Packets To Host */
|
||||
#define IGC_TLPIC 0x04148 /* EEE Tx LPI Count */
|
||||
#define IGC_RLPIC 0x0414C /* EEE Rx LPI Count */
|
||||
#define IGC_HGPTC 0x04118 /* Host Good Packets Tx Count */
|
||||
#define IGC_RXDMTC 0x04120 /* Rx Descriptor Minimum Threshold Count */
|
||||
#define IGC_HGORCL 0x04128 /* Host Good Octets Received Count Low */
|
||||
#define IGC_HGORCH 0x0412C /* Host Good Octets Received Count High */
|
||||
#define IGC_HGOTCL 0x04130 /* Host Good Octets Transmit Count Low */
|
||||
#define IGC_HGOTCH 0x04134 /* Host Good Octets Transmit Count High */
|
||||
#define IGC_LENERRS 0x04138 /* Length Errors Count */
|
||||
|
||||
/* Time sync registers */
|
||||
#define IGC_TSICR 0x0B66C /* Time Sync Interrupt Cause */
|
||||
#define IGC_TSIM 0x0B674 /* Time Sync Interrupt Mask Register */
|
||||
#define IGC_TSAUXC 0x0B640 /* Timesync Auxiliary Control register */
|
||||
#define IGC_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
|
||||
#define IGC_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */
|
||||
#define IGC_TSYNCRXCFG 0x05F50 /* Time Sync Rx Configuration - RW */
|
||||
#define IGC_TSSDP 0x0003C /* Time Sync SDP Configuration Register - RW */
|
||||
#define IGC_TRGTTIML0 0x0B644 /* Target Time Register 0 Low - RW */
|
||||
#define IGC_TRGTTIMH0 0x0B648 /* Target Time Register 0 High - RW */
|
||||
#define IGC_TRGTTIML1 0x0B64C /* Target Time Register 1 Low - RW */
|
||||
#define IGC_TRGTTIMH1 0x0B650 /* Target Time Register 1 High - RW */
|
||||
#define IGC_FREQOUT0 0x0B654 /* Frequency Out 0 Control Register - RW */
|
||||
#define IGC_FREQOUT1 0x0B658 /* Frequency Out 1 Control Register - RW */
|
||||
#define IGC_AUXSTMPL0 0x0B65C /* Auxiliary Time Stamp 0 Register Low - RO */
|
||||
#define IGC_AUXSTMPH0 0x0B660 /* Auxiliary Time Stamp 0 Register High - RO */
|
||||
#define IGC_AUXSTMPL1 0x0B664 /* Auxiliary Time Stamp 1 Register Low - RO */
|
||||
#define IGC_AUXSTMPH1 0x0B668 /* Auxiliary Time Stamp 1 Register High - RO */
|
||||
|
||||
#define IGC_IMIR(_i) (0x05A80 + ((_i) * 4)) /* Immediate Interrupt */
|
||||
#define IGC_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate INTR Ext*/
|
||||
|
||||
#define IGC_FTQF(_n) (0x059E0 + (4 * (_n))) /* 5-tuple Queue Fltr */
|
||||
|
||||
/* Transmit Scheduling Registers */
|
||||
#define IGC_TQAVCTRL 0x3570
|
||||
#define IGC_TXQCTL(_n) (0x3344 + 0x4 * (_n))
|
||||
#define IGC_BASET_L 0x3314
|
||||
#define IGC_BASET_H 0x3318
|
||||
#define IGC_QBVCYCLET 0x331C
|
||||
#define IGC_QBVCYCLET_S 0x3320
|
||||
|
||||
#define IGC_STQT(_n) (0x3324 + 0x4 * (_n))
|
||||
#define IGC_ENDQT(_n) (0x3334 + 0x4 * (_n))
|
||||
#define IGC_DTXMXPKTSZ 0x355C
|
||||
|
||||
#define IGC_TQAVCC(_n) (0x3004 + ((_n) * 0x40))
|
||||
#define IGC_TQAVHC(_n) (0x300C + ((_n) * 0x40))
|
||||
|
||||
/* System Time Registers */
|
||||
#define IGC_SYSTIML 0x0B600 /* System time register Low - RO */
|
||||
#define IGC_SYSTIMH 0x0B604 /* System time register High - RO */
|
||||
#define IGC_SYSTIMR 0x0B6F8 /* System time register Residue */
|
||||
#define IGC_TIMINCA 0x0B608 /* Increment attributes register - RW */
|
||||
|
||||
#define IGC_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */
|
||||
#define IGC_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */
|
||||
|
||||
#define IGC_TIMADJ 0x0B60C /* Time Adjustment Offset Register */
|
||||
|
||||
/* PCIe Registers */
|
||||
#define IGC_PTM_CTRL 0x12540 /* PTM Control */
|
||||
#define IGC_PTM_STAT 0x12544 /* PTM Status */
|
||||
#define IGC_PTM_CYCLE_CTRL 0x1254C /* PTM Cycle Control */
|
||||
|
||||
/* PTM Time registers */
|
||||
#define IGC_PTM_T1_TIM0_L 0x12558 /* T1 on Timer 0 Low */
|
||||
#define IGC_PTM_T1_TIM0_H 0x1255C /* T1 on Timer 0 High */
|
||||
|
||||
#define IGC_PTM_CURR_T2_L 0x1258C /* Current T2 Low */
|
||||
#define IGC_PTM_CURR_T2_H 0x12590 /* Current T2 High */
|
||||
#define IGC_PTM_PREV_T2_L 0x12584 /* Previous T2 Low */
|
||||
#define IGC_PTM_PREV_T2_H 0x12588 /* Previous T2 High */
|
||||
#define IGC_PTM_PREV_T4M1 0x12578 /* T4 Minus T1 on previous PTM Cycle */
|
||||
#define IGC_PTM_CURR_T4M1 0x1257C /* T4 Minus T1 on this PTM Cycle */
|
||||
#define IGC_PTM_PREV_T3M2 0x12580 /* T3 Minus T2 on previous PTM Cycle */
|
||||
#define IGC_PTM_TDELAY 0x12594 /* PTM PCIe Link Delay */
|
||||
|
||||
#define IGC_PCIE_DIG_DELAY 0x12550 /* PCIe Digital Delay */
|
||||
#define IGC_PCIE_PHY_DELAY 0x12554 /* PCIe PHY Delay */
|
||||
|
||||
/* Management registers */
|
||||
#define IGC_MANC 0x05820 /* Management Control - RW */
|
||||
|
||||
/* Shadow Ram Write Register - RW */
|
||||
#define IGC_SRWR 0x12018
|
||||
|
||||
/* Wake Up registers */
|
||||
#define IGC_WUC 0x05800 /* Wakeup Control - RW */
|
||||
#define IGC_WUFC 0x05808 /* Wakeup Filter Control - RW */
|
||||
#define IGC_WUS 0x05810 /* Wakeup Status - R/W1C */
|
||||
#define IGC_WUPL 0x05900 /* Wakeup Packet Length - RW */
|
||||
#define IGC_WUFC_EXT 0x0580C /* Wakeup Filter Control Register Extended - RW */
|
||||
|
||||
/* Wake Up packet memory */
|
||||
#define IGC_WUPM_REG(_i) (0x05A00 + ((_i) * 4))
|
||||
|
||||
/* Energy Efficient Ethernet "EEE" registers */
|
||||
#define IGC_EEER 0x0E30 /* Energy Efficient Ethernet "EEE"*/
|
||||
#define IGC_IPCNFG 0x0E38 /* Internal PHY Configuration */
|
||||
#define IGC_EEE_SU 0x0E34 /* EEE Setup */
|
||||
|
||||
/* LTR registers */
|
||||
#define IGC_LTRC 0x01A0 /* Latency Tolerance Reporting Control */
|
||||
#define IGC_DMACR 0x02508 /* DMA Coalescing Control Register */
|
||||
#define IGC_LTRMINV 0x5BB0 /* LTR Minimum Value */
|
||||
#define IGC_LTRMAXV 0x5BB4 /* LTR Maximum Value */
|
||||
|
||||
/* forward declaration */
|
||||
struct igc_hw;
|
||||
u32 igc_rd32(struct igc_hw *hw, u32 reg);
|
||||
|
||||
/* write operations, indexed using DWORDS */
|
||||
#define wr32(reg, val) \
|
||||
do { \
|
||||
u8 __iomem *hw_addr = READ_ONCE((hw)->hw_addr); \
|
||||
writel((val), &hw_addr[(reg)]); \
|
||||
} while (0)
|
||||
|
||||
#define rd32(reg) (igc_rd32(hw, reg))
|
||||
|
||||
#define wrfl() ((void)rd32(IGC_STATUS))
|
||||
|
||||
#define array_wr32(reg, offset, value) \
|
||||
wr32((reg) + ((offset) << 2), (value))
|
||||
|
||||
#define array_rd32(reg, offset) (igc_rd32(hw, (reg) + ((offset) << 2)))
|
||||
|
||||
#endif
|
||||
321
devices/igc/igc_regs-5.15-orig.h
Normal file
321
devices/igc/igc_regs-5.15-orig.h
Normal file
@@ -0,0 +1,321 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#ifndef _IGC_REGS_H_
|
||||
#define _IGC_REGS_H_
|
||||
|
||||
/* General Register Descriptions */
|
||||
#define IGC_CTRL 0x00000 /* Device Control - RW */
|
||||
#define IGC_STATUS 0x00008 /* Device Status - RO */
|
||||
#define IGC_EECD 0x00010 /* EEPROM/Flash Control - RW */
|
||||
#define IGC_CTRL_EXT 0x00018 /* Extended Device Control - RW */
|
||||
#define IGC_MDIC 0x00020 /* MDI Control - RW */
|
||||
#define IGC_CONNSW 0x00034 /* Copper/Fiber switch control - RW */
|
||||
#define IGC_VET 0x00038 /* VLAN Ether Type - RW */
|
||||
#define IGC_I225_PHPM 0x00E14 /* I225 PHY Power Management */
|
||||
#define IGC_GPHY_VERSION 0x0001E /* I225 gPHY Firmware Version */
|
||||
|
||||
/* Internal Packet Buffer Size Registers */
|
||||
#define IGC_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */
|
||||
#define IGC_TXPBS 0x03404 /* Tx Packet Buffer Size - RW */
|
||||
|
||||
/* NVM Register Descriptions */
|
||||
#define IGC_EERD 0x12014 /* EEprom mode read - RW */
|
||||
#define IGC_EEWR 0x12018 /* EEprom mode write - RW */
|
||||
|
||||
/* Flow Control Register Descriptions */
|
||||
#define IGC_FCAL 0x00028 /* FC Address Low - RW */
|
||||
#define IGC_FCAH 0x0002C /* FC Address High - RW */
|
||||
#define IGC_FCT 0x00030 /* FC Type - RW */
|
||||
#define IGC_FCTTV 0x00170 /* FC Transmit Timer - RW */
|
||||
#define IGC_FCRTL 0x02160 /* FC Receive Threshold Low - RW */
|
||||
#define IGC_FCRTH 0x02168 /* FC Receive Threshold High - RW */
|
||||
#define IGC_FCRTV 0x02460 /* FC Refresh Timer Value - RW */
|
||||
|
||||
/* Semaphore registers */
|
||||
#define IGC_SW_FW_SYNC 0x05B5C /* SW-FW Synchronization - RW */
|
||||
#define IGC_SWSM 0x05B50 /* SW Semaphore */
|
||||
#define IGC_FWSM 0x05B54 /* FW Semaphore */
|
||||
|
||||
/* Function Active and Power State to MNG */
|
||||
#define IGC_FACTPS 0x05B30
|
||||
|
||||
/* Interrupt Register Description */
|
||||
#define IGC_EICR 0x01580 /* Ext. Interrupt Cause read - W0 */
|
||||
#define IGC_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */
|
||||
#define IGC_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */
|
||||
#define IGC_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */
|
||||
#define IGC_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */
|
||||
#define IGC_EIAM 0x01530 /* Ext. Interrupt Auto Mask - RW */
|
||||
#define IGC_ICR 0x01500 /* Intr Cause Read - RC/W1C */
|
||||
#define IGC_ICS 0x01504 /* Intr Cause Set - WO */
|
||||
#define IGC_IMS 0x01508 /* Intr Mask Set/Read - RW */
|
||||
#define IGC_IMC 0x0150C /* Intr Mask Clear - WO */
|
||||
#define IGC_IAM 0x01510 /* Intr Ack Auto Mask- RW */
|
||||
/* Intr Throttle - RW */
|
||||
#define IGC_EITR(_n) (0x01680 + (0x4 * (_n)))
|
||||
/* Interrupt Vector Allocation - RW */
|
||||
#define IGC_IVAR0 0x01700
|
||||
#define IGC_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */
|
||||
#define IGC_GPIE 0x01514 /* General Purpose Intr Enable - RW */
|
||||
|
||||
/* MSI-X Table Register Descriptions */
|
||||
#define IGC_PBACL 0x05B68 /* MSIx PBA Clear - R/W 1 to clear */
|
||||
|
||||
/* RSS registers */
|
||||
#define IGC_MRQC 0x05818 /* Multiple Receive Control - RW */
|
||||
|
||||
/* Filtering Registers */
|
||||
#define IGC_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
|
||||
#define IGC_FHFT(_n) (0x09000 + (256 * (_n))) /* Flexible Host Filter */
|
||||
#define IGC_FHFT_EXT(_n) (0x09A00 + (256 * (_n))) /* Flexible Host Filter Extended */
|
||||
#define IGC_FHFTSL 0x05804 /* Flex Filter indirect table select */
|
||||
|
||||
/* ETQF register bit definitions */
|
||||
#define IGC_ETQF_FILTER_ENABLE BIT(26)
|
||||
#define IGC_ETQF_QUEUE_ENABLE BIT(31)
|
||||
#define IGC_ETQF_QUEUE_SHIFT 16
|
||||
#define IGC_ETQF_QUEUE_MASK 0x00070000
|
||||
#define IGC_ETQF_ETYPE_MASK 0x0000FFFF
|
||||
|
||||
/* FHFT register bit definitions */
|
||||
#define IGC_FHFT_LENGTH_MASK GENMASK(7, 0)
|
||||
#define IGC_FHFT_QUEUE_SHIFT 8
|
||||
#define IGC_FHFT_QUEUE_MASK GENMASK(10, 8)
|
||||
#define IGC_FHFT_PRIO_SHIFT 16
|
||||
#define IGC_FHFT_PRIO_MASK GENMASK(18, 16)
|
||||
#define IGC_FHFT_IMM_INT BIT(24)
|
||||
#define IGC_FHFT_DROP BIT(25)
|
||||
|
||||
/* FHFTSL register bit definitions */
|
||||
#define IGC_FHFTSL_FTSL_SHIFT 0
|
||||
#define IGC_FHFTSL_FTSL_MASK GENMASK(1, 0)
|
||||
|
||||
/* Redirection Table - RW Array */
|
||||
#define IGC_RETA(_i) (0x05C00 + ((_i) * 4))
|
||||
/* RSS Random Key - RW Array */
|
||||
#define IGC_RSSRK(_i) (0x05C80 + ((_i) * 4))
|
||||
|
||||
/* Receive Register Descriptions */
|
||||
#define IGC_RCTL 0x00100 /* Rx Control - RW */
|
||||
#define IGC_SRRCTL(_n) (0x0C00C + ((_n) * 0x40))
|
||||
#define IGC_PSRTYPE(_i) (0x05480 + ((_i) * 4))
|
||||
#define IGC_RDBAL(_n) (0x0C000 + ((_n) * 0x40))
|
||||
#define IGC_RDBAH(_n) (0x0C004 + ((_n) * 0x40))
|
||||
#define IGC_RDLEN(_n) (0x0C008 + ((_n) * 0x40))
|
||||
#define IGC_RDH(_n) (0x0C010 + ((_n) * 0x40))
|
||||
#define IGC_RDT(_n) (0x0C018 + ((_n) * 0x40))
|
||||
#define IGC_RXDCTL(_n) (0x0C028 + ((_n) * 0x40))
|
||||
#define IGC_RQDPC(_n) (0x0C030 + ((_n) * 0x40))
|
||||
#define IGC_RXCSUM 0x05000 /* Rx Checksum Control - RW */
|
||||
#define IGC_RLPML 0x05004 /* Rx Long Packet Max Length */
|
||||
#define IGC_RFCTL 0x05008 /* Receive Filter Control*/
|
||||
#define IGC_MTA 0x05200 /* Multicast Table Array - RW Array */
|
||||
#define IGC_RA 0x05400 /* Receive Address - RW Array */
|
||||
#define IGC_UTA 0x0A000 /* Unicast Table Array - RW */
|
||||
#define IGC_RAL(_n) (0x05400 + ((_n) * 0x08))
|
||||
#define IGC_RAH(_n) (0x05404 + ((_n) * 0x08))
|
||||
#define IGC_VLANPQF 0x055B0 /* VLAN Priority Queue Filter - RW */
|
||||
|
||||
/* Transmit Register Descriptions */
|
||||
#define IGC_TCTL 0x00400 /* Tx Control - RW */
|
||||
#define IGC_TIPG 0x00410 /* Tx Inter-packet gap - RW */
|
||||
#define IGC_TDBAL(_n) (0x0E000 + ((_n) * 0x40))
|
||||
#define IGC_TDBAH(_n) (0x0E004 + ((_n) * 0x40))
|
||||
#define IGC_TDLEN(_n) (0x0E008 + ((_n) * 0x40))
|
||||
#define IGC_TDH(_n) (0x0E010 + ((_n) * 0x40))
|
||||
#define IGC_TDT(_n) (0x0E018 + ((_n) * 0x40))
|
||||
#define IGC_TXDCTL(_n) (0x0E028 + ((_n) * 0x40))
|
||||
|
||||
/* MMD Register Descriptions */
|
||||
#define IGC_MMDAC 13 /* MMD Access Control */
|
||||
#define IGC_MMDAAD 14 /* MMD Access Address/Data */
|
||||
|
||||
/* Statistics Register Descriptions */
|
||||
#define IGC_CRCERRS 0x04000 /* CRC Error Count - R/clr */
|
||||
#define IGC_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
|
||||
#define IGC_RXERRC 0x0400C /* Receive Error Count - R/clr */
|
||||
#define IGC_MPC 0x04010 /* Missed Packet Count - R/clr */
|
||||
#define IGC_SCC 0x04014 /* Single Collision Count - R/clr */
|
||||
#define IGC_ECOL 0x04018 /* Excessive Collision Count - R/clr */
|
||||
#define IGC_MCC 0x0401C /* Multiple Collision Count - R/clr */
|
||||
#define IGC_LATECOL 0x04020 /* Late Collision Count - R/clr */
|
||||
#define IGC_COLC 0x04028 /* Collision Count - R/clr */
|
||||
#define IGC_RERC 0x0402C /* Receive Error Count - R/clr */
|
||||
#define IGC_DC 0x04030 /* Defer Count - R/clr */
|
||||
#define IGC_TNCRS 0x04034 /* Tx-No CRS - R/clr */
|
||||
#define IGC_HTDPMC 0x0403C /* Host Transmit Discarded by MAC - R/clr */
|
||||
#define IGC_RLEC 0x04040 /* Receive Length Error Count - R/clr */
|
||||
#define IGC_XONRXC 0x04048 /* XON Rx Count - R/clr */
|
||||
#define IGC_XONTXC 0x0404C /* XON Tx Count - R/clr */
|
||||
#define IGC_XOFFRXC 0x04050 /* XOFF Rx Count - R/clr */
|
||||
#define IGC_XOFFTXC 0x04054 /* XOFF Tx Count - R/clr */
|
||||
#define IGC_FCRUC 0x04058 /* Flow Control Rx Unsupported Count- R/clr */
|
||||
#define IGC_PRC64 0x0405C /* Packets Rx (64 bytes) - R/clr */
|
||||
#define IGC_PRC127 0x04060 /* Packets Rx (65-127 bytes) - R/clr */
|
||||
#define IGC_PRC255 0x04064 /* Packets Rx (128-255 bytes) - R/clr */
|
||||
#define IGC_PRC511 0x04068 /* Packets Rx (255-511 bytes) - R/clr */
|
||||
#define IGC_PRC1023 0x0406C /* Packets Rx (512-1023 bytes) - R/clr */
|
||||
#define IGC_PRC1522 0x04070 /* Packets Rx (1024-1522 bytes) - R/clr */
|
||||
#define IGC_GPRC 0x04074 /* Good Packets Rx Count - R/clr */
|
||||
#define IGC_BPRC 0x04078 /* Broadcast Packets Rx Count - R/clr */
|
||||
#define IGC_MPRC 0x0407C /* Multicast Packets Rx Count - R/clr */
|
||||
#define IGC_GPTC 0x04080 /* Good Packets Tx Count - R/clr */
|
||||
#define IGC_GORCL 0x04088 /* Good Octets Rx Count Low - R/clr */
|
||||
#define IGC_GORCH 0x0408C /* Good Octets Rx Count High - R/clr */
|
||||
#define IGC_GOTCL 0x04090 /* Good Octets Tx Count Low - R/clr */
|
||||
#define IGC_GOTCH 0x04094 /* Good Octets Tx Count High - R/clr */
|
||||
#define IGC_RNBC 0x040A0 /* Rx No Buffers Count - R/clr */
|
||||
#define IGC_RUC 0x040A4 /* Rx Undersize Count - R/clr */
|
||||
#define IGC_RFC 0x040A8 /* Rx Fragment Count - R/clr */
|
||||
#define IGC_ROC 0x040AC /* Rx Oversize Count - R/clr */
|
||||
#define IGC_RJC 0x040B0 /* Rx Jabber Count - R/clr */
|
||||
#define IGC_MGTPRC 0x040B4 /* Management Packets Rx Count - R/clr */
|
||||
#define IGC_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
|
||||
#define IGC_MGTPTC 0x040BC /* Management Packets Tx Count - R/clr */
|
||||
#define IGC_TORL 0x040C0 /* Total Octets Rx Low - R/clr */
|
||||
#define IGC_TORH 0x040C4 /* Total Octets Rx High - R/clr */
|
||||
#define IGC_TOTL 0x040C8 /* Total Octets Tx Low - R/clr */
|
||||
#define IGC_TOTH 0x040CC /* Total Octets Tx High - R/clr */
|
||||
#define IGC_TPR 0x040D0 /* Total Packets Rx - R/clr */
|
||||
#define IGC_TPT 0x040D4 /* Total Packets Tx - R/clr */
|
||||
#define IGC_PTC64 0x040D8 /* Packets Tx (64 bytes) - R/clr */
|
||||
#define IGC_PTC127 0x040DC /* Packets Tx (65-127 bytes) - R/clr */
|
||||
#define IGC_PTC255 0x040E0 /* Packets Tx (128-255 bytes) - R/clr */
|
||||
#define IGC_PTC511 0x040E4 /* Packets Tx (256-511 bytes) - R/clr */
|
||||
#define IGC_PTC1023 0x040E8 /* Packets Tx (512-1023 bytes) - R/clr */
|
||||
#define IGC_PTC1522 0x040EC /* Packets Tx (1024-1522 Bytes) - R/clr */
|
||||
#define IGC_MPTC 0x040F0 /* Multicast Packets Tx Count - R/clr */
|
||||
#define IGC_BPTC 0x040F4 /* Broadcast Packets Tx Count - R/clr */
|
||||
#define IGC_TSCTC 0x040F8 /* TCP Segmentation Context Tx - R/clr */
|
||||
#define IGC_IAC 0x04100 /* Interrupt Assertion Count */
|
||||
#define IGC_RPTHC 0x04104 /* Rx Packets To Host */
|
||||
#define IGC_TLPIC 0x04148 /* EEE Tx LPI Count */
|
||||
#define IGC_RLPIC 0x0414C /* EEE Rx LPI Count */
|
||||
#define IGC_HGPTC 0x04118 /* Host Good Packets Tx Count */
|
||||
#define IGC_RXDMTC 0x04120 /* Rx Descriptor Minimum Threshold Count */
|
||||
#define IGC_HGORCL 0x04128 /* Host Good Octets Received Count Low */
|
||||
#define IGC_HGORCH 0x0412C /* Host Good Octets Received Count High */
|
||||
#define IGC_HGOTCL 0x04130 /* Host Good Octets Transmit Count Low */
|
||||
#define IGC_HGOTCH 0x04134 /* Host Good Octets Transmit Count High */
|
||||
#define IGC_LENERRS 0x04138 /* Length Errors Count */
|
||||
|
||||
/* Time sync registers */
|
||||
#define IGC_TSICR 0x0B66C /* Time Sync Interrupt Cause */
|
||||
#define IGC_TSIM 0x0B674 /* Time Sync Interrupt Mask Register */
|
||||
#define IGC_TSAUXC 0x0B640 /* Timesync Auxiliary Control register */
|
||||
#define IGC_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
|
||||
#define IGC_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */
|
||||
#define IGC_TSYNCRXCFG 0x05F50 /* Time Sync Rx Configuration - RW */
|
||||
#define IGC_TSSDP 0x0003C /* Time Sync SDP Configuration Register - RW */
|
||||
#define IGC_TRGTTIML0 0x0B644 /* Target Time Register 0 Low - RW */
|
||||
#define IGC_TRGTTIMH0 0x0B648 /* Target Time Register 0 High - RW */
|
||||
#define IGC_TRGTTIML1 0x0B64C /* Target Time Register 1 Low - RW */
|
||||
#define IGC_TRGTTIMH1 0x0B650 /* Target Time Register 1 High - RW */
|
||||
#define IGC_FREQOUT0 0x0B654 /* Frequency Out 0 Control Register - RW */
|
||||
#define IGC_FREQOUT1 0x0B658 /* Frequency Out 1 Control Register - RW */
|
||||
#define IGC_AUXSTMPL0 0x0B65C /* Auxiliary Time Stamp 0 Register Low - RO */
|
||||
#define IGC_AUXSTMPH0 0x0B660 /* Auxiliary Time Stamp 0 Register High - RO */
|
||||
#define IGC_AUXSTMPL1 0x0B664 /* Auxiliary Time Stamp 1 Register Low - RO */
|
||||
#define IGC_AUXSTMPH1 0x0B668 /* Auxiliary Time Stamp 1 Register High - RO */
|
||||
|
||||
#define IGC_IMIR(_i) (0x05A80 + ((_i) * 4)) /* Immediate Interrupt */
|
||||
#define IGC_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate INTR Ext*/
|
||||
|
||||
#define IGC_FTQF(_n) (0x059E0 + (4 * (_n))) /* 5-tuple Queue Fltr */
|
||||
|
||||
/* Transmit Scheduling Registers */
|
||||
#define IGC_TQAVCTRL 0x3570
|
||||
#define IGC_TXQCTL(_n) (0x3344 + 0x4 * (_n))
|
||||
#define IGC_BASET_L 0x3314
|
||||
#define IGC_BASET_H 0x3318
|
||||
#define IGC_QBVCYCLET 0x331C
|
||||
#define IGC_QBVCYCLET_S 0x3320
|
||||
|
||||
#define IGC_STQT(_n) (0x3324 + 0x4 * (_n))
|
||||
#define IGC_ENDQT(_n) (0x3334 + 0x4 * (_n))
|
||||
#define IGC_DTXMXPKTSZ 0x355C
|
||||
|
||||
#define IGC_TQAVCC(_n) (0x3004 + ((_n) * 0x40))
|
||||
#define IGC_TQAVHC(_n) (0x300C + ((_n) * 0x40))
|
||||
|
||||
/* System Time Registers */
|
||||
#define IGC_SYSTIML 0x0B600 /* System time register Low - RO */
|
||||
#define IGC_SYSTIMH 0x0B604 /* System time register High - RO */
|
||||
#define IGC_SYSTIMR 0x0B6F8 /* System time register Residue */
|
||||
#define IGC_TIMINCA 0x0B608 /* Increment attributes register - RW */
|
||||
|
||||
#define IGC_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */
|
||||
#define IGC_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */
|
||||
|
||||
#define IGC_TIMADJ 0x0B60C /* Time Adjustment Offset Register */
|
||||
|
||||
/* PCIe Registers */
|
||||
#define IGC_PTM_CTRL 0x12540 /* PTM Control */
|
||||
#define IGC_PTM_STAT 0x12544 /* PTM Status */
|
||||
#define IGC_PTM_CYCLE_CTRL 0x1254C /* PTM Cycle Control */
|
||||
|
||||
/* PTM Time registers */
|
||||
#define IGC_PTM_T1_TIM0_L 0x12558 /* T1 on Timer 0 Low */
|
||||
#define IGC_PTM_T1_TIM0_H 0x1255C /* T1 on Timer 0 High */
|
||||
|
||||
#define IGC_PTM_CURR_T2_L 0x1258C /* Current T2 Low */
|
||||
#define IGC_PTM_CURR_T2_H 0x12590 /* Current T2 High */
|
||||
#define IGC_PTM_PREV_T2_L 0x12584 /* Previous T2 Low */
|
||||
#define IGC_PTM_PREV_T2_H 0x12588 /* Previous T2 High */
|
||||
#define IGC_PTM_PREV_T4M1 0x12578 /* T4 Minus T1 on previous PTM Cycle */
|
||||
#define IGC_PTM_CURR_T4M1 0x1257C /* T4 Minus T1 on this PTM Cycle */
|
||||
#define IGC_PTM_PREV_T3M2 0x12580 /* T3 Minus T2 on previous PTM Cycle */
|
||||
#define IGC_PTM_TDELAY 0x12594 /* PTM PCIe Link Delay */
|
||||
|
||||
#define IGC_PCIE_DIG_DELAY 0x12550 /* PCIe Digital Delay */
|
||||
#define IGC_PCIE_PHY_DELAY 0x12554 /* PCIe PHY Delay */
|
||||
|
||||
/* Management registers */
|
||||
#define IGC_MANC 0x05820 /* Management Control - RW */
|
||||
|
||||
/* Shadow Ram Write Register - RW */
|
||||
#define IGC_SRWR 0x12018
|
||||
|
||||
/* Wake Up registers */
|
||||
#define IGC_WUC 0x05800 /* Wakeup Control - RW */
|
||||
#define IGC_WUFC 0x05808 /* Wakeup Filter Control - RW */
|
||||
#define IGC_WUS 0x05810 /* Wakeup Status - R/W1C */
|
||||
#define IGC_WUPL 0x05900 /* Wakeup Packet Length - RW */
|
||||
#define IGC_WUFC_EXT 0x0580C /* Wakeup Filter Control Register Extended - RW */
|
||||
|
||||
/* Wake Up packet memory */
|
||||
#define IGC_WUPM_REG(_i) (0x05A00 + ((_i) * 4))
|
||||
|
||||
/* Energy Efficient Ethernet "EEE" registers */
|
||||
#define IGC_EEER 0x0E30 /* Energy Efficient Ethernet "EEE"*/
|
||||
#define IGC_IPCNFG 0x0E38 /* Internal PHY Configuration */
|
||||
#define IGC_EEE_SU 0x0E34 /* EEE Setup */
|
||||
|
||||
/* LTR registers */
|
||||
#define IGC_LTRC 0x01A0 /* Latency Tolerance Reporting Control */
|
||||
#define IGC_DMACR 0x02508 /* DMA Coalescing Control Register */
|
||||
#define IGC_LTRMINV 0x5BB0 /* LTR Minimum Value */
|
||||
#define IGC_LTRMAXV 0x5BB4 /* LTR Maximum Value */
|
||||
|
||||
/* forward declaration */
|
||||
struct igc_hw;
|
||||
u32 igc_rd32(struct igc_hw *hw, u32 reg);
|
||||
|
||||
/* write operations, indexed using DWORDS */
|
||||
#define wr32(reg, val) \
|
||||
do { \
|
||||
u8 __iomem *hw_addr = READ_ONCE((hw)->hw_addr); \
|
||||
writel((val), &hw_addr[(reg)]); \
|
||||
} while (0)
|
||||
|
||||
#define rd32(reg) (igc_rd32(hw, reg))
|
||||
|
||||
#define wrfl() ((void)rd32(IGC_STATUS))
|
||||
|
||||
#define array_wr32(reg, offset, value) \
|
||||
wr32((reg) + ((offset) << 2), (value))
|
||||
|
||||
#define array_rd32(reg, offset) (igc_rd32(hw, (reg) + ((offset) << 2)))
|
||||
|
||||
#endif
|
||||
267
devices/igc/igc_tsn-5.15-ethercat.c
Normal file
267
devices/igc/igc_tsn-5.15-ethercat.c
Normal file
@@ -0,0 +1,267 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2019 Intel Corporation */
|
||||
|
||||
#include "igc-5.15-ethercat.h"
|
||||
#include "igc_tsn-5.15-ethercat.h"
|
||||
|
||||
static bool is_any_launchtime(struct igc_adapter *adapter)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adapter->num_tx_queues; i++) {
|
||||
struct igc_ring *ring = adapter->tx_ring[i];
|
||||
|
||||
if (ring->launchtime_enable)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_cbs_enabled(struct igc_adapter *adapter)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adapter->num_tx_queues; i++) {
|
||||
struct igc_ring *ring = adapter->tx_ring[i];
|
||||
|
||||
if (ring->cbs_enable)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static unsigned int igc_tsn_new_flags(struct igc_adapter *adapter)
|
||||
{
|
||||
unsigned int new_flags = adapter->flags & ~IGC_FLAG_TSN_ANY_ENABLED;
|
||||
|
||||
if (adapter->base_time)
|
||||
new_flags |= IGC_FLAG_TSN_QBV_ENABLED;
|
||||
|
||||
if (is_any_launchtime(adapter))
|
||||
new_flags |= IGC_FLAG_TSN_QBV_ENABLED;
|
||||
|
||||
if (is_cbs_enabled(adapter))
|
||||
new_flags |= IGC_FLAG_TSN_QAV_ENABLED;
|
||||
|
||||
return new_flags;
|
||||
}
|
||||
|
||||
/* Returns the TSN specific registers to their default values after
|
||||
* the adapter is reset.
|
||||
*/
|
||||
static int igc_tsn_disable_offload(struct igc_adapter *adapter)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
u32 tqavctrl;
|
||||
int i;
|
||||
|
||||
wr32(IGC_TXPBS, I225_TXPBSIZE_DEFAULT);
|
||||
wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_DEFAULT);
|
||||
|
||||
tqavctrl = rd32(IGC_TQAVCTRL);
|
||||
tqavctrl &= ~(IGC_TQAVCTRL_TRANSMIT_MODE_TSN |
|
||||
IGC_TQAVCTRL_ENHANCED_QAV);
|
||||
wr32(IGC_TQAVCTRL, tqavctrl);
|
||||
|
||||
for (i = 0; i < adapter->num_tx_queues; i++) {
|
||||
wr32(IGC_TXQCTL(i), 0);
|
||||
wr32(IGC_STQT(i), 0);
|
||||
wr32(IGC_ENDQT(i), NSEC_PER_SEC);
|
||||
}
|
||||
|
||||
wr32(IGC_QBVCYCLET_S, 0);
|
||||
wr32(IGC_QBVCYCLET, NSEC_PER_SEC);
|
||||
|
||||
adapter->flags &= ~IGC_FLAG_TSN_QBV_ENABLED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int igc_tsn_enable_offload(struct igc_adapter *adapter)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
u32 tqavctrl, baset_l, baset_h;
|
||||
u32 sec, nsec, cycle;
|
||||
ktime_t base_time, systim;
|
||||
int i;
|
||||
|
||||
cycle = adapter->cycle_time;
|
||||
base_time = adapter->base_time;
|
||||
|
||||
wr32(IGC_TSAUXC, 0);
|
||||
wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_TSN);
|
||||
wr32(IGC_TXPBS, IGC_TXPBSIZE_TSN);
|
||||
|
||||
tqavctrl = rd32(IGC_TQAVCTRL);
|
||||
tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV;
|
||||
wr32(IGC_TQAVCTRL, tqavctrl);
|
||||
|
||||
wr32(IGC_QBVCYCLET_S, cycle);
|
||||
wr32(IGC_QBVCYCLET, cycle);
|
||||
|
||||
for (i = 0; i < adapter->num_tx_queues; i++) {
|
||||
struct igc_ring *ring = adapter->tx_ring[i];
|
||||
u32 txqctl = 0;
|
||||
u16 cbs_value;
|
||||
u32 tqavcc;
|
||||
|
||||
wr32(IGC_STQT(i), ring->start_time);
|
||||
wr32(IGC_ENDQT(i), ring->end_time);
|
||||
|
||||
if (adapter->base_time) {
|
||||
/* If we have a base_time we are in "taprio"
|
||||
* mode and we need to be strict about the
|
||||
* cycles: only transmit a packet if it can be
|
||||
* completed during that cycle.
|
||||
*/
|
||||
txqctl |= IGC_TXQCTL_STRICT_CYCLE |
|
||||
IGC_TXQCTL_STRICT_END;
|
||||
}
|
||||
|
||||
if (ring->launchtime_enable)
|
||||
txqctl |= IGC_TXQCTL_QUEUE_MODE_LAUNCHT;
|
||||
|
||||
/* Skip configuring CBS for Q2 and Q3 */
|
||||
if (i > 1)
|
||||
goto skip_cbs;
|
||||
|
||||
if (ring->cbs_enable) {
|
||||
if (i == 0)
|
||||
txqctl |= IGC_TXQCTL_QAV_SEL_CBS0;
|
||||
else
|
||||
txqctl |= IGC_TXQCTL_QAV_SEL_CBS1;
|
||||
|
||||
/* According to i225 datasheet section 7.5.2.7, we
|
||||
* should set the 'idleSlope' field from TQAVCC
|
||||
* register following the equation:
|
||||
*
|
||||
* value = link-speed 0x7736 * BW * 0.2
|
||||
* ---------- * ----------------- (E1)
|
||||
* 100Mbps 2.5
|
||||
*
|
||||
* Note that 'link-speed' is in Mbps.
|
||||
*
|
||||
* 'BW' is the percentage bandwidth out of full
|
||||
* link speed which can be found with the
|
||||
* following equation. Note that idleSlope here
|
||||
* is the parameter from this function
|
||||
* which is in kbps.
|
||||
*
|
||||
* BW = idleSlope
|
||||
* ----------------- (E2)
|
||||
* link-speed * 1000
|
||||
*
|
||||
* That said, we can come up with a generic
|
||||
* equation to calculate the value we should set
|
||||
* it TQAVCC register by replacing 'BW' in E1 by E2.
|
||||
* The resulting equation is:
|
||||
*
|
||||
* value = link-speed * 0x7736 * idleSlope * 0.2
|
||||
* ------------------------------------- (E3)
|
||||
* 100 * 2.5 * link-speed * 1000
|
||||
*
|
||||
* 'link-speed' is present in both sides of the
|
||||
* fraction so it is canceled out. The final
|
||||
* equation is the following:
|
||||
*
|
||||
* value = idleSlope * 61036
|
||||
* ----------------- (E4)
|
||||
* 2500000
|
||||
*
|
||||
* NOTE: For i225, given the above, we can see
|
||||
* that idleslope is represented in
|
||||
* 40.959433 kbps units by the value at
|
||||
* the TQAVCC register (2.5Gbps / 61036),
|
||||
* which reduces the granularity for
|
||||
* idleslope increments.
|
||||
*
|
||||
* In i225 controller, the sendSlope and loCredit
|
||||
* parameters from CBS are not configurable
|
||||
* by software so we don't do any
|
||||
* 'controller configuration' in respect to
|
||||
* these parameters.
|
||||
*/
|
||||
cbs_value = DIV_ROUND_UP_ULL(ring->idleslope
|
||||
* 61036ULL, 2500000);
|
||||
|
||||
tqavcc = rd32(IGC_TQAVCC(i));
|
||||
tqavcc &= ~IGC_TQAVCC_IDLESLOPE_MASK;
|
||||
tqavcc |= cbs_value | IGC_TQAVCC_KEEP_CREDITS;
|
||||
wr32(IGC_TQAVCC(i), tqavcc);
|
||||
|
||||
wr32(IGC_TQAVHC(i),
|
||||
0x80000000 + ring->hicredit * 0x7735);
|
||||
} else {
|
||||
/* Disable any CBS for the queue */
|
||||
txqctl &= ~(IGC_TXQCTL_QAV_SEL_MASK);
|
||||
|
||||
/* Set idleSlope to zero. */
|
||||
tqavcc = rd32(IGC_TQAVCC(i));
|
||||
tqavcc &= ~(IGC_TQAVCC_IDLESLOPE_MASK |
|
||||
IGC_TQAVCC_KEEP_CREDITS);
|
||||
wr32(IGC_TQAVCC(i), tqavcc);
|
||||
|
||||
/* Set hiCredit to zero. */
|
||||
wr32(IGC_TQAVHC(i), 0);
|
||||
}
|
||||
skip_cbs:
|
||||
wr32(IGC_TXQCTL(i), txqctl);
|
||||
}
|
||||
|
||||
nsec = rd32(IGC_SYSTIML);
|
||||
sec = rd32(IGC_SYSTIMH);
|
||||
|
||||
systim = ktime_set(sec, nsec);
|
||||
|
||||
if (ktime_compare(systim, base_time) > 0) {
|
||||
s64 n;
|
||||
|
||||
n = div64_s64(ktime_sub_ns(systim, base_time), cycle);
|
||||
base_time = ktime_add_ns(base_time, (n + 1) * cycle);
|
||||
}
|
||||
|
||||
baset_h = div_s64_rem(base_time, NSEC_PER_SEC, &baset_l);
|
||||
|
||||
wr32(IGC_BASET_H, baset_h);
|
||||
wr32(IGC_BASET_L, baset_l);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int igc_tsn_reset(struct igc_adapter *adapter)
|
||||
{
|
||||
unsigned int new_flags;
|
||||
int err = 0;
|
||||
|
||||
new_flags = igc_tsn_new_flags(adapter);
|
||||
|
||||
if (!(new_flags & IGC_FLAG_TSN_ANY_ENABLED))
|
||||
return igc_tsn_disable_offload(adapter);
|
||||
|
||||
err = igc_tsn_enable_offload(adapter);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
adapter->flags = new_flags;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int igc_tsn_offload_apply(struct igc_adapter *adapter)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (netif_running(adapter->netdev)) {
|
||||
schedule_work(&adapter->reset_task);
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = igc_tsn_enable_offload(adapter);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
adapter->flags = igc_tsn_new_flags(adapter);
|
||||
return 0;
|
||||
}
|
||||
10
devices/igc/igc_tsn-5.15-ethercat.h
Normal file
10
devices/igc/igc_tsn-5.15-ethercat.h
Normal file
@@ -0,0 +1,10 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2020 Intel Corporation */
|
||||
|
||||
#ifndef _IGC_TSN_H_
|
||||
#define _IGC_TSN_H_
|
||||
|
||||
int igc_tsn_offload_apply(struct igc_adapter *adapter);
|
||||
int igc_tsn_reset(struct igc_adapter *adapter);
|
||||
|
||||
#endif /* _IGC_BASE_H */
|
||||
267
devices/igc/igc_tsn-5.15-orig.c
Normal file
267
devices/igc/igc_tsn-5.15-orig.c
Normal file
@@ -0,0 +1,267 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2019 Intel Corporation */
|
||||
|
||||
#include "igc.h"
|
||||
#include "igc_tsn.h"
|
||||
|
||||
static bool is_any_launchtime(struct igc_adapter *adapter)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adapter->num_tx_queues; i++) {
|
||||
struct igc_ring *ring = adapter->tx_ring[i];
|
||||
|
||||
if (ring->launchtime_enable)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_cbs_enabled(struct igc_adapter *adapter)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adapter->num_tx_queues; i++) {
|
||||
struct igc_ring *ring = adapter->tx_ring[i];
|
||||
|
||||
if (ring->cbs_enable)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static unsigned int igc_tsn_new_flags(struct igc_adapter *adapter)
|
||||
{
|
||||
unsigned int new_flags = adapter->flags & ~IGC_FLAG_TSN_ANY_ENABLED;
|
||||
|
||||
if (adapter->base_time)
|
||||
new_flags |= IGC_FLAG_TSN_QBV_ENABLED;
|
||||
|
||||
if (is_any_launchtime(adapter))
|
||||
new_flags |= IGC_FLAG_TSN_QBV_ENABLED;
|
||||
|
||||
if (is_cbs_enabled(adapter))
|
||||
new_flags |= IGC_FLAG_TSN_QAV_ENABLED;
|
||||
|
||||
return new_flags;
|
||||
}
|
||||
|
||||
/* Returns the TSN specific registers to their default values after
|
||||
* the adapter is reset.
|
||||
*/
|
||||
static int igc_tsn_disable_offload(struct igc_adapter *adapter)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
u32 tqavctrl;
|
||||
int i;
|
||||
|
||||
wr32(IGC_TXPBS, I225_TXPBSIZE_DEFAULT);
|
||||
wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_DEFAULT);
|
||||
|
||||
tqavctrl = rd32(IGC_TQAVCTRL);
|
||||
tqavctrl &= ~(IGC_TQAVCTRL_TRANSMIT_MODE_TSN |
|
||||
IGC_TQAVCTRL_ENHANCED_QAV);
|
||||
wr32(IGC_TQAVCTRL, tqavctrl);
|
||||
|
||||
for (i = 0; i < adapter->num_tx_queues; i++) {
|
||||
wr32(IGC_TXQCTL(i), 0);
|
||||
wr32(IGC_STQT(i), 0);
|
||||
wr32(IGC_ENDQT(i), NSEC_PER_SEC);
|
||||
}
|
||||
|
||||
wr32(IGC_QBVCYCLET_S, 0);
|
||||
wr32(IGC_QBVCYCLET, NSEC_PER_SEC);
|
||||
|
||||
adapter->flags &= ~IGC_FLAG_TSN_QBV_ENABLED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int igc_tsn_enable_offload(struct igc_adapter *adapter)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
u32 tqavctrl, baset_l, baset_h;
|
||||
u32 sec, nsec, cycle;
|
||||
ktime_t base_time, systim;
|
||||
int i;
|
||||
|
||||
cycle = adapter->cycle_time;
|
||||
base_time = adapter->base_time;
|
||||
|
||||
wr32(IGC_TSAUXC, 0);
|
||||
wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_TSN);
|
||||
wr32(IGC_TXPBS, IGC_TXPBSIZE_TSN);
|
||||
|
||||
tqavctrl = rd32(IGC_TQAVCTRL);
|
||||
tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV;
|
||||
wr32(IGC_TQAVCTRL, tqavctrl);
|
||||
|
||||
wr32(IGC_QBVCYCLET_S, cycle);
|
||||
wr32(IGC_QBVCYCLET, cycle);
|
||||
|
||||
for (i = 0; i < adapter->num_tx_queues; i++) {
|
||||
struct igc_ring *ring = adapter->tx_ring[i];
|
||||
u32 txqctl = 0;
|
||||
u16 cbs_value;
|
||||
u32 tqavcc;
|
||||
|
||||
wr32(IGC_STQT(i), ring->start_time);
|
||||
wr32(IGC_ENDQT(i), ring->end_time);
|
||||
|
||||
if (adapter->base_time) {
|
||||
/* If we have a base_time we are in "taprio"
|
||||
* mode and we need to be strict about the
|
||||
* cycles: only transmit a packet if it can be
|
||||
* completed during that cycle.
|
||||
*/
|
||||
txqctl |= IGC_TXQCTL_STRICT_CYCLE |
|
||||
IGC_TXQCTL_STRICT_END;
|
||||
}
|
||||
|
||||
if (ring->launchtime_enable)
|
||||
txqctl |= IGC_TXQCTL_QUEUE_MODE_LAUNCHT;
|
||||
|
||||
/* Skip configuring CBS for Q2 and Q3 */
|
||||
if (i > 1)
|
||||
goto skip_cbs;
|
||||
|
||||
if (ring->cbs_enable) {
|
||||
if (i == 0)
|
||||
txqctl |= IGC_TXQCTL_QAV_SEL_CBS0;
|
||||
else
|
||||
txqctl |= IGC_TXQCTL_QAV_SEL_CBS1;
|
||||
|
||||
/* According to i225 datasheet section 7.5.2.7, we
|
||||
* should set the 'idleSlope' field from TQAVCC
|
||||
* register following the equation:
|
||||
*
|
||||
* value = link-speed 0x7736 * BW * 0.2
|
||||
* ---------- * ----------------- (E1)
|
||||
* 100Mbps 2.5
|
||||
*
|
||||
* Note that 'link-speed' is in Mbps.
|
||||
*
|
||||
* 'BW' is the percentage bandwidth out of full
|
||||
* link speed which can be found with the
|
||||
* following equation. Note that idleSlope here
|
||||
* is the parameter from this function
|
||||
* which is in kbps.
|
||||
*
|
||||
* BW = idleSlope
|
||||
* ----------------- (E2)
|
||||
* link-speed * 1000
|
||||
*
|
||||
* That said, we can come up with a generic
|
||||
* equation to calculate the value we should set
|
||||
* it TQAVCC register by replacing 'BW' in E1 by E2.
|
||||
* The resulting equation is:
|
||||
*
|
||||
* value = link-speed * 0x7736 * idleSlope * 0.2
|
||||
* ------------------------------------- (E3)
|
||||
* 100 * 2.5 * link-speed * 1000
|
||||
*
|
||||
* 'link-speed' is present in both sides of the
|
||||
* fraction so it is canceled out. The final
|
||||
* equation is the following:
|
||||
*
|
||||
* value = idleSlope * 61036
|
||||
* ----------------- (E4)
|
||||
* 2500000
|
||||
*
|
||||
* NOTE: For i225, given the above, we can see
|
||||
* that idleslope is represented in
|
||||
* 40.959433 kbps units by the value at
|
||||
* the TQAVCC register (2.5Gbps / 61036),
|
||||
* which reduces the granularity for
|
||||
* idleslope increments.
|
||||
*
|
||||
* In i225 controller, the sendSlope and loCredit
|
||||
* parameters from CBS are not configurable
|
||||
* by software so we don't do any
|
||||
* 'controller configuration' in respect to
|
||||
* these parameters.
|
||||
*/
|
||||
cbs_value = DIV_ROUND_UP_ULL(ring->idleslope
|
||||
* 61036ULL, 2500000);
|
||||
|
||||
tqavcc = rd32(IGC_TQAVCC(i));
|
||||
tqavcc &= ~IGC_TQAVCC_IDLESLOPE_MASK;
|
||||
tqavcc |= cbs_value | IGC_TQAVCC_KEEP_CREDITS;
|
||||
wr32(IGC_TQAVCC(i), tqavcc);
|
||||
|
||||
wr32(IGC_TQAVHC(i),
|
||||
0x80000000 + ring->hicredit * 0x7735);
|
||||
} else {
|
||||
/* Disable any CBS for the queue */
|
||||
txqctl &= ~(IGC_TXQCTL_QAV_SEL_MASK);
|
||||
|
||||
/* Set idleSlope to zero. */
|
||||
tqavcc = rd32(IGC_TQAVCC(i));
|
||||
tqavcc &= ~(IGC_TQAVCC_IDLESLOPE_MASK |
|
||||
IGC_TQAVCC_KEEP_CREDITS);
|
||||
wr32(IGC_TQAVCC(i), tqavcc);
|
||||
|
||||
/* Set hiCredit to zero. */
|
||||
wr32(IGC_TQAVHC(i), 0);
|
||||
}
|
||||
skip_cbs:
|
||||
wr32(IGC_TXQCTL(i), txqctl);
|
||||
}
|
||||
|
||||
nsec = rd32(IGC_SYSTIML);
|
||||
sec = rd32(IGC_SYSTIMH);
|
||||
|
||||
systim = ktime_set(sec, nsec);
|
||||
|
||||
if (ktime_compare(systim, base_time) > 0) {
|
||||
s64 n;
|
||||
|
||||
n = div64_s64(ktime_sub_ns(systim, base_time), cycle);
|
||||
base_time = ktime_add_ns(base_time, (n + 1) * cycle);
|
||||
}
|
||||
|
||||
baset_h = div_s64_rem(base_time, NSEC_PER_SEC, &baset_l);
|
||||
|
||||
wr32(IGC_BASET_H, baset_h);
|
||||
wr32(IGC_BASET_L, baset_l);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int igc_tsn_reset(struct igc_adapter *adapter)
|
||||
{
|
||||
unsigned int new_flags;
|
||||
int err = 0;
|
||||
|
||||
new_flags = igc_tsn_new_flags(adapter);
|
||||
|
||||
if (!(new_flags & IGC_FLAG_TSN_ANY_ENABLED))
|
||||
return igc_tsn_disable_offload(adapter);
|
||||
|
||||
err = igc_tsn_enable_offload(adapter);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
adapter->flags = new_flags;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int igc_tsn_offload_apply(struct igc_adapter *adapter)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (netif_running(adapter->netdev)) {
|
||||
schedule_work(&adapter->reset_task);
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = igc_tsn_enable_offload(adapter);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
adapter->flags = igc_tsn_new_flags(adapter);
|
||||
return 0;
|
||||
}
|
||||
10
devices/igc/igc_tsn-5.15-orig.h
Normal file
10
devices/igc/igc_tsn-5.15-orig.h
Normal file
@@ -0,0 +1,10 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2020 Intel Corporation */
|
||||
|
||||
#ifndef _IGC_TSN_H_
|
||||
#define _IGC_TSN_H_
|
||||
|
||||
int igc_tsn_offload_apply(struct igc_adapter *adapter);
|
||||
int igc_tsn_reset(struct igc_adapter *adapter);
|
||||
|
||||
#endif /* _IGC_BASE_H */
|
||||
146
devices/igc/igc_xdp-5.15-ethercat.c
Normal file
146
devices/igc/igc_xdp-5.15-ethercat.c
Normal file
@@ -0,0 +1,146 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2020, Intel Corporation. */
|
||||
|
||||
#include <net/xdp_sock_drv.h>
|
||||
#include <linux/if_vlan.h>
|
||||
|
||||
#include "igc-5.15-ethercat.h"
|
||||
#include "igc_xdp-5.15-ethercat.h"
|
||||
|
||||
int igc_xdp_set_prog(struct igc_adapter *adapter, struct bpf_prog *prog,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct net_device *dev = adapter->netdev;
|
||||
bool if_running = netif_running(dev);
|
||||
struct bpf_prog *old_prog;
|
||||
|
||||
if (dev->mtu > ETH_DATA_LEN) {
|
||||
/* For now, the driver doesn't support XDP functionality with
|
||||
* jumbo frames so we return error.
|
||||
*/
|
||||
NL_SET_ERR_MSG_MOD(extack, "Jumbo frames not supported");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (if_running)
|
||||
igc_close(dev);
|
||||
|
||||
old_prog = xchg(&adapter->xdp_prog, prog);
|
||||
if (old_prog)
|
||||
bpf_prog_put(old_prog);
|
||||
|
||||
if (if_running)
|
||||
igc_open(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int igc_xdp_enable_pool(struct igc_adapter *adapter,
|
||||
struct xsk_buff_pool *pool, u16 queue_id)
|
||||
{
|
||||
struct net_device *ndev = adapter->netdev;
|
||||
struct device *dev = &adapter->pdev->dev;
|
||||
struct igc_ring *rx_ring, *tx_ring;
|
||||
struct napi_struct *napi;
|
||||
bool needs_reset;
|
||||
u32 frame_size;
|
||||
int err;
|
||||
|
||||
if (queue_id >= adapter->num_rx_queues ||
|
||||
queue_id >= adapter->num_tx_queues)
|
||||
return -EINVAL;
|
||||
|
||||
frame_size = xsk_pool_get_rx_frame_size(pool);
|
||||
if (frame_size < ETH_FRAME_LEN + VLAN_HLEN * 2) {
|
||||
/* When XDP is enabled, the driver doesn't support frames that
|
||||
* span over multiple buffers. To avoid that, we check if xsk
|
||||
* frame size is big enough to fit the max ethernet frame size
|
||||
* + vlan double tagging.
|
||||
*/
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
err = xsk_pool_dma_map(pool, dev, IGC_RX_DMA_ATTR);
|
||||
if (err) {
|
||||
netdev_err(ndev, "Failed to map xsk pool\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
needs_reset = netif_running(adapter->netdev) && igc_xdp_is_enabled(adapter);
|
||||
|
||||
rx_ring = adapter->rx_ring[queue_id];
|
||||
tx_ring = adapter->tx_ring[queue_id];
|
||||
/* Rx and Tx rings share the same napi context. */
|
||||
napi = &rx_ring->q_vector->napi;
|
||||
|
||||
if (needs_reset) {
|
||||
igc_disable_rx_ring(rx_ring);
|
||||
igc_disable_tx_ring(tx_ring);
|
||||
napi_disable(napi);
|
||||
}
|
||||
|
||||
set_bit(IGC_RING_FLAG_AF_XDP_ZC, &rx_ring->flags);
|
||||
set_bit(IGC_RING_FLAG_AF_XDP_ZC, &tx_ring->flags);
|
||||
|
||||
if (needs_reset) {
|
||||
napi_enable(napi);
|
||||
igc_enable_rx_ring(rx_ring);
|
||||
igc_enable_tx_ring(tx_ring);
|
||||
|
||||
err = igc_xsk_wakeup(ndev, queue_id, XDP_WAKEUP_RX);
|
||||
if (err) {
|
||||
xsk_pool_dma_unmap(pool, IGC_RX_DMA_ATTR);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int igc_xdp_disable_pool(struct igc_adapter *adapter, u16 queue_id)
|
||||
{
|
||||
struct igc_ring *rx_ring, *tx_ring;
|
||||
struct xsk_buff_pool *pool;
|
||||
struct napi_struct *napi;
|
||||
bool needs_reset;
|
||||
|
||||
if (queue_id >= adapter->num_rx_queues ||
|
||||
queue_id >= adapter->num_tx_queues)
|
||||
return -EINVAL;
|
||||
|
||||
pool = xsk_get_pool_from_qid(adapter->netdev, queue_id);
|
||||
if (!pool)
|
||||
return -EINVAL;
|
||||
|
||||
needs_reset = netif_running(adapter->netdev) && igc_xdp_is_enabled(adapter);
|
||||
|
||||
rx_ring = adapter->rx_ring[queue_id];
|
||||
tx_ring = adapter->tx_ring[queue_id];
|
||||
/* Rx and Tx rings share the same napi context. */
|
||||
napi = &rx_ring->q_vector->napi;
|
||||
|
||||
if (needs_reset) {
|
||||
igc_disable_rx_ring(rx_ring);
|
||||
igc_disable_tx_ring(tx_ring);
|
||||
napi_disable(napi);
|
||||
}
|
||||
|
||||
xsk_pool_dma_unmap(pool, IGC_RX_DMA_ATTR);
|
||||
clear_bit(IGC_RING_FLAG_AF_XDP_ZC, &rx_ring->flags);
|
||||
clear_bit(IGC_RING_FLAG_AF_XDP_ZC, &tx_ring->flags);
|
||||
|
||||
if (needs_reset) {
|
||||
napi_enable(napi);
|
||||
igc_enable_rx_ring(rx_ring);
|
||||
igc_enable_tx_ring(tx_ring);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int igc_xdp_setup_pool(struct igc_adapter *adapter, struct xsk_buff_pool *pool,
|
||||
u16 queue_id)
|
||||
{
|
||||
return pool ? igc_xdp_enable_pool(adapter, pool, queue_id) :
|
||||
igc_xdp_disable_pool(adapter, queue_id);
|
||||
}
|
||||
17
devices/igc/igc_xdp-5.15-ethercat.h
Normal file
17
devices/igc/igc_xdp-5.15-ethercat.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2020, Intel Corporation. */
|
||||
|
||||
#ifndef _IGC_XDP_H_
|
||||
#define _IGC_XDP_H_
|
||||
|
||||
int igc_xdp_set_prog(struct igc_adapter *adapter, struct bpf_prog *prog,
|
||||
struct netlink_ext_ack *extack);
|
||||
int igc_xdp_setup_pool(struct igc_adapter *adapter, struct xsk_buff_pool *pool,
|
||||
u16 queue_id);
|
||||
|
||||
static inline bool igc_xdp_is_enabled(struct igc_adapter *adapter)
|
||||
{
|
||||
return !!adapter->xdp_prog;
|
||||
}
|
||||
|
||||
#endif /* _IGC_XDP_H_ */
|
||||
145
devices/igc/igc_xdp-5.15-orig.c
Normal file
145
devices/igc/igc_xdp-5.15-orig.c
Normal file
@@ -0,0 +1,145 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2020, Intel Corporation. */
|
||||
|
||||
#include <net/xdp_sock_drv.h>
|
||||
|
||||
#include "igc.h"
|
||||
#include "igc_xdp.h"
|
||||
|
||||
int igc_xdp_set_prog(struct igc_adapter *adapter, struct bpf_prog *prog,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct net_device *dev = adapter->netdev;
|
||||
bool if_running = netif_running(dev);
|
||||
struct bpf_prog *old_prog;
|
||||
|
||||
if (dev->mtu > ETH_DATA_LEN) {
|
||||
/* For now, the driver doesn't support XDP functionality with
|
||||
* jumbo frames so we return error.
|
||||
*/
|
||||
NL_SET_ERR_MSG_MOD(extack, "Jumbo frames not supported");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (if_running)
|
||||
igc_close(dev);
|
||||
|
||||
old_prog = xchg(&adapter->xdp_prog, prog);
|
||||
if (old_prog)
|
||||
bpf_prog_put(old_prog);
|
||||
|
||||
if (if_running)
|
||||
igc_open(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int igc_xdp_enable_pool(struct igc_adapter *adapter,
|
||||
struct xsk_buff_pool *pool, u16 queue_id)
|
||||
{
|
||||
struct net_device *ndev = adapter->netdev;
|
||||
struct device *dev = &adapter->pdev->dev;
|
||||
struct igc_ring *rx_ring, *tx_ring;
|
||||
struct napi_struct *napi;
|
||||
bool needs_reset;
|
||||
u32 frame_size;
|
||||
int err;
|
||||
|
||||
if (queue_id >= adapter->num_rx_queues ||
|
||||
queue_id >= adapter->num_tx_queues)
|
||||
return -EINVAL;
|
||||
|
||||
frame_size = xsk_pool_get_rx_frame_size(pool);
|
||||
if (frame_size < ETH_FRAME_LEN + VLAN_HLEN * 2) {
|
||||
/* When XDP is enabled, the driver doesn't support frames that
|
||||
* span over multiple buffers. To avoid that, we check if xsk
|
||||
* frame size is big enough to fit the max ethernet frame size
|
||||
* + vlan double tagging.
|
||||
*/
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
err = xsk_pool_dma_map(pool, dev, IGC_RX_DMA_ATTR);
|
||||
if (err) {
|
||||
netdev_err(ndev, "Failed to map xsk pool\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
needs_reset = netif_running(adapter->netdev) && igc_xdp_is_enabled(adapter);
|
||||
|
||||
rx_ring = adapter->rx_ring[queue_id];
|
||||
tx_ring = adapter->tx_ring[queue_id];
|
||||
/* Rx and Tx rings share the same napi context. */
|
||||
napi = &rx_ring->q_vector->napi;
|
||||
|
||||
if (needs_reset) {
|
||||
igc_disable_rx_ring(rx_ring);
|
||||
igc_disable_tx_ring(tx_ring);
|
||||
napi_disable(napi);
|
||||
}
|
||||
|
||||
set_bit(IGC_RING_FLAG_AF_XDP_ZC, &rx_ring->flags);
|
||||
set_bit(IGC_RING_FLAG_AF_XDP_ZC, &tx_ring->flags);
|
||||
|
||||
if (needs_reset) {
|
||||
napi_enable(napi);
|
||||
igc_enable_rx_ring(rx_ring);
|
||||
igc_enable_tx_ring(tx_ring);
|
||||
|
||||
err = igc_xsk_wakeup(ndev, queue_id, XDP_WAKEUP_RX);
|
||||
if (err) {
|
||||
xsk_pool_dma_unmap(pool, IGC_RX_DMA_ATTR);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int igc_xdp_disable_pool(struct igc_adapter *adapter, u16 queue_id)
|
||||
{
|
||||
struct igc_ring *rx_ring, *tx_ring;
|
||||
struct xsk_buff_pool *pool;
|
||||
struct napi_struct *napi;
|
||||
bool needs_reset;
|
||||
|
||||
if (queue_id >= adapter->num_rx_queues ||
|
||||
queue_id >= adapter->num_tx_queues)
|
||||
return -EINVAL;
|
||||
|
||||
pool = xsk_get_pool_from_qid(adapter->netdev, queue_id);
|
||||
if (!pool)
|
||||
return -EINVAL;
|
||||
|
||||
needs_reset = netif_running(adapter->netdev) && igc_xdp_is_enabled(adapter);
|
||||
|
||||
rx_ring = adapter->rx_ring[queue_id];
|
||||
tx_ring = adapter->tx_ring[queue_id];
|
||||
/* Rx and Tx rings share the same napi context. */
|
||||
napi = &rx_ring->q_vector->napi;
|
||||
|
||||
if (needs_reset) {
|
||||
igc_disable_rx_ring(rx_ring);
|
||||
igc_disable_tx_ring(tx_ring);
|
||||
napi_disable(napi);
|
||||
}
|
||||
|
||||
xsk_pool_dma_unmap(pool, IGC_RX_DMA_ATTR);
|
||||
clear_bit(IGC_RING_FLAG_AF_XDP_ZC, &rx_ring->flags);
|
||||
clear_bit(IGC_RING_FLAG_AF_XDP_ZC, &tx_ring->flags);
|
||||
|
||||
if (needs_reset) {
|
||||
napi_enable(napi);
|
||||
igc_enable_rx_ring(rx_ring);
|
||||
igc_enable_tx_ring(tx_ring);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int igc_xdp_setup_pool(struct igc_adapter *adapter, struct xsk_buff_pool *pool,
|
||||
u16 queue_id)
|
||||
{
|
||||
return pool ? igc_xdp_enable_pool(adapter, pool, queue_id) :
|
||||
igc_xdp_disable_pool(adapter, queue_id);
|
||||
}
|
||||
17
devices/igc/igc_xdp-5.15-orig.h
Normal file
17
devices/igc/igc_xdp-5.15-orig.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2020, Intel Corporation. */
|
||||
|
||||
#ifndef _IGC_XDP_H_
|
||||
#define _IGC_XDP_H_
|
||||
|
||||
int igc_xdp_set_prog(struct igc_adapter *adapter, struct bpf_prog *prog,
|
||||
struct netlink_ext_ack *extack);
|
||||
int igc_xdp_setup_pool(struct igc_adapter *adapter, struct xsk_buff_pool *pool,
|
||||
u16 queue_id);
|
||||
|
||||
static inline bool igc_xdp_is_enabled(struct igc_adapter *adapter)
|
||||
{
|
||||
return !!adapter->xdp_prog;
|
||||
}
|
||||
|
||||
#endif /* _IGC_XDP_H_ */
|
||||
Reference in New Issue
Block a user