mirror of
https://gitlab.com/etherlab.org/ethercat.git
synced 2026-02-06 20:01:44 +08:00
Merge branch 'igc_6.1' into devel-1.6
This commit is contained in:
@@ -21,99 +21,196 @@
|
||||
|
||||
include $(top_srcdir)/Makefile.kbuild
|
||||
|
||||
EXTRiA_DIST = igc-6.6-ethercat.h \
|
||||
igc_base-6.6-orig.h \
|
||||
igc_diag-6.6-orig.c \
|
||||
igc_ethtool-6.6-orig.c \
|
||||
igc_i225-6.6-orig.c \
|
||||
igc_mac-6.6-orig.c \
|
||||
igc_nvm-6.6-ethercat.h \
|
||||
igc_phy-6.6-orig.c \
|
||||
igc_regs-6.6-orig.h \
|
||||
igc_xdp-6.6-ethercat.c \
|
||||
igc-6.6-orig.h \
|
||||
igc_defines-6.6-ethercat.h \
|
||||
igc_diag-6.6-orig.h \
|
||||
igc_hw-6.6-ethercat.h \
|
||||
igc_i225-6.6-orig.h \
|
||||
igc_mac-6.6-orig.h \
|
||||
igc_nvm-6.6-orig.c \
|
||||
igc_phy-6.6-orig.h \
|
||||
igc_tsn-6.6-ethercat.c \
|
||||
igc_xdp-6.6-ethercat.h \
|
||||
igc_base-6.6-ethercat.c \
|
||||
igc_defines-6.6-orig.h \
|
||||
igc_dump-6.6-ethercat.c \
|
||||
igc_hw-6.6-orig.h \
|
||||
igc_main-6.6-ethercat.c \
|
||||
igc_nvm-6.6-orig.h \
|
||||
igc_ptp-6.6-ethercat.c \
|
||||
igc_tsn-6.6-ethercat.h \
|
||||
igc_xdp-6.6-orig.c\
|
||||
igc_base-6.6-ethercat.h \
|
||||
igc_diag-6.6-ethercat.c \
|
||||
igc_dump-6.6-orig.c \
|
||||
igc_i225-6.6-ethercat.c \
|
||||
igc_mac-6.6-ethercat.c \
|
||||
igc_main-6.6-orig.c \
|
||||
igc_phy-6.6-ethercat.c \
|
||||
igc_ptp-6.6-orig.c \
|
||||
igc_tsn-6.6-orig.c \
|
||||
igc_xdp-6.6-orig.h\
|
||||
igc_base-6.6-orig.c \
|
||||
igc_diag-6.6-ethercat.h \
|
||||
igc_ethtool-6.6-ethercat.c \
|
||||
igc_i225-6.6-ethercat.h \
|
||||
igc_mac-6.6-ethercat.h \
|
||||
igc_nvm-6.6-ethercat.c \
|
||||
igc_phy-6.6-ethercat.h \
|
||||
igc_regs-6.6-ethercat.h \
|
||||
igc_tsn-6.6-orig.h \
|
||||
EXTRA_DIST = \
|
||||
igc-5.14-ethercat.h \
|
||||
igc-5.14-orig.h \
|
||||
igc-6.1-ethercat.h \
|
||||
igc-6.1-orig.h \
|
||||
igc-6.4-ethercat.h \
|
||||
igc_base-6.4-orig.h \
|
||||
igc_diag-6.4-orig.c \
|
||||
igc_ethtool-6.4-orig.c \
|
||||
igc_i225-6.4-orig.c \
|
||||
igc_mac-6.4-orig.c \
|
||||
igc_nvm-6.4-ethercat.h \
|
||||
igc_phy-6.4-orig.c \
|
||||
igc_regs-6.4-orig.h \
|
||||
igc_xdp-6.4-ethercat.c \
|
||||
igc-6.4-orig.h \
|
||||
igc_defines-6.4-ethercat.h \
|
||||
igc_diag-6.4-orig.h \
|
||||
igc_hw-6.4-ethercat.h \
|
||||
igc_i225-6.4-orig.h \
|
||||
igc_mac-6.4-orig.h \
|
||||
igc_nvm-6.4-orig.c \
|
||||
igc_phy-6.4-orig.h \
|
||||
igc_tsn-6.4-ethercat.c \
|
||||
igc_xdp-6.4-ethercat.h \
|
||||
igc-6.6-ethercat.h \
|
||||
igc-6.6-orig.h \
|
||||
igc_base-5.14-ethercat.c \
|
||||
igc_base-5.14-ethercat.h \
|
||||
igc_base-5.14-orig.c \
|
||||
igc_base-5.14-orig.h \
|
||||
igc_base-6.1-ethercat.c \
|
||||
igc_base-6.1-ethercat.h \
|
||||
igc_base-6.1-orig.c \
|
||||
igc_base-6.1-orig.h \
|
||||
igc_base-6.4-ethercat.c \
|
||||
igc_defines-6.4-orig.h \
|
||||
igc_dump-6.4-ethercat.c \
|
||||
igc_hw-6.4-orig.h \
|
||||
igc_main-6.4-ethercat.c \
|
||||
igc_nvm-6.4-orig.h \
|
||||
igc_ptp-6.4-ethercat.c \
|
||||
igc_tsn-6.4-ethercat.h \
|
||||
igc_xdp-6.4-orig.c\
|
||||
igc_base-6.4-ethercat.h \
|
||||
igc_diag-6.4-ethercat.c \
|
||||
igc_dump-6.4-orig.c \
|
||||
igc_i225-6.4-ethercat.c \
|
||||
igc_mac-6.4-ethercat.c \
|
||||
igc_main-6.4-orig.c \
|
||||
igc_phy-6.4-ethercat.c \
|
||||
igc_ptp-6.4-orig.c \
|
||||
igc_tsn-6.4-orig.c \
|
||||
igc_xdp-6.4-orig.h\
|
||||
igc_base-6.4-orig.c \
|
||||
igc_base-6.4-orig.h \
|
||||
igc_base-6.6-ethercat.c \
|
||||
igc_base-6.6-ethercat.h \
|
||||
igc_base-6.6-orig.c \
|
||||
igc_base-6.6-orig.h \
|
||||
igc_defines-5.14-ethercat.h \
|
||||
igc_defines-5.14-orig.h \
|
||||
igc_defines-6.1-ethercat.h \
|
||||
igc_defines-6.1-orig.h \
|
||||
igc_defines-6.4-ethercat.h \
|
||||
igc_defines-6.4-orig.h \
|
||||
igc_defines-6.6-ethercat.h \
|
||||
igc_defines-6.6-orig.h \
|
||||
igc_diag-5.14-ethercat.c \
|
||||
igc_diag-5.14-ethercat.h \
|
||||
igc_diag-5.14-orig.c \
|
||||
igc_diag-5.14-orig.h \
|
||||
igc_diag-6.1-ethercat.c \
|
||||
igc_diag-6.1-ethercat.h \
|
||||
igc_diag-6.1-orig.c \
|
||||
igc_diag-6.1-orig.h \
|
||||
igc_diag-6.4-ethercat.c \
|
||||
igc_diag-6.4-ethercat.h \
|
||||
igc_diag-6.4-orig.c \
|
||||
igc_diag-6.4-orig.h \
|
||||
igc_diag-6.6-ethercat.c \
|
||||
igc_diag-6.6-ethercat.h \
|
||||
igc_diag-6.6-orig.c \
|
||||
igc_diag-6.6-orig.h \
|
||||
igc_dump-5.14-ethercat.c \
|
||||
igc_dump-5.14-orig.c \
|
||||
igc_dump-6.1-ethercat.c \
|
||||
igc_dump-6.1-orig.c \
|
||||
igc_dump-6.4-ethercat.c \
|
||||
igc_dump-6.4-orig.c \
|
||||
igc_dump-6.6-ethercat.c \
|
||||
igc_dump-6.6-orig.c \
|
||||
igc_ethtool-5.14-ethercat.c \
|
||||
igc_ethtool-5.14-orig.c \
|
||||
igc_ethtool-6.1-ethercat.c \
|
||||
igc_ethtool-6.1-orig.c \
|
||||
igc_ethtool-6.4-ethercat.c \
|
||||
igc_ethtool-6.4-orig.c \
|
||||
igc_ethtool-6.6-ethercat.c \
|
||||
igc_ethtool-6.6-orig.c \
|
||||
igc_hw-5.14-ethercat.h \
|
||||
igc_hw-5.14-orig.h \
|
||||
igc_hw-6.1-ethercat.h \
|
||||
igc_hw-6.1-orig.h \
|
||||
igc_hw-6.4-ethercat.h \
|
||||
igc_hw-6.4-orig.h \
|
||||
igc_hw-6.6-ethercat.h \
|
||||
igc_hw-6.6-orig.h \
|
||||
igc_i225-5.14-ethercat.c \
|
||||
igc_i225-5.14-ethercat.h \
|
||||
igc_i225-5.14-orig.c \
|
||||
igc_i225-5.14-orig.h \
|
||||
igc_i225-6.1-ethercat.c \
|
||||
igc_i225-6.1-ethercat.h \
|
||||
igc_i225-6.1-orig.c \
|
||||
igc_i225-6.1-orig.h \
|
||||
igc_i225-6.4-ethercat.c \
|
||||
igc_i225-6.4-ethercat.h \
|
||||
igc_i225-6.4-orig.c \
|
||||
igc_i225-6.4-orig.h \
|
||||
igc_i225-6.6-ethercat.c \
|
||||
igc_i225-6.6-ethercat.h \
|
||||
igc_i225-6.6-orig.c \
|
||||
igc_i225-6.6-orig.h \
|
||||
igc_mac-5.14-ethercat.c \
|
||||
igc_mac-5.14-ethercat.h \
|
||||
igc_mac-5.14-orig.c \
|
||||
igc_mac-5.14-orig.h \
|
||||
igc_mac-6.1-ethercat.c \
|
||||
igc_mac-6.1-ethercat.h \
|
||||
igc_mac-6.1-orig.c \
|
||||
igc_mac-6.1-orig.h \
|
||||
igc_mac-6.4-ethercat.c \
|
||||
igc_mac-6.4-ethercat.h \
|
||||
igc_mac-6.4-orig.c \
|
||||
igc_mac-6.4-orig.h \
|
||||
igc_mac-6.6-ethercat.c \
|
||||
igc_mac-6.6-ethercat.h \
|
||||
igc_mac-6.6-orig.c \
|
||||
igc_mac-6.6-orig.h \
|
||||
igc_main-5.14-ethercat.c \
|
||||
igc_main-5.14-orig.c \
|
||||
igc_main-6.1-ethercat.c \
|
||||
igc_main-6.1-orig.c \
|
||||
igc_main-6.4-ethercat.c \
|
||||
igc_main-6.4-orig.c \
|
||||
igc_main-6.6-ethercat.c \
|
||||
igc_main-6.6-orig.c \
|
||||
igc_nvm-5.14-ethercat.c \
|
||||
igc_nvm-5.14-ethercat.h \
|
||||
igc_nvm-5.14-orig.c \
|
||||
igc_nvm-5.14-orig.h \
|
||||
igc_nvm-6.1-ethercat.c \
|
||||
igc_nvm-6.1-ethercat.h \
|
||||
igc_nvm-6.1-orig.c \
|
||||
igc_nvm-6.1-orig.h \
|
||||
igc_nvm-6.4-ethercat.c \
|
||||
igc_nvm-6.4-ethercat.h \
|
||||
igc_nvm-6.4-orig.c \
|
||||
igc_nvm-6.4-orig.h \
|
||||
igc_nvm-6.6-ethercat.c \
|
||||
igc_nvm-6.6-ethercat.h \
|
||||
igc_nvm-6.6-orig.c \
|
||||
igc_nvm-6.6-orig.h \
|
||||
igc_phy-5.14-ethercat.c \
|
||||
igc_phy-5.14-ethercat.h \
|
||||
igc_phy-5.14-orig.c \
|
||||
igc_phy-5.14-orig.h \
|
||||
igc_phy-6.1-ethercat.c \
|
||||
igc_phy-6.1-ethercat.h \
|
||||
igc_phy-6.1-orig.c \
|
||||
igc_phy-6.1-orig.h \
|
||||
igc_phy-6.4-ethercat.c \
|
||||
igc_phy-6.4-ethercat.h \
|
||||
igc_phy-6.4-orig.c \
|
||||
igc_phy-6.4-orig.h \
|
||||
igc_phy-6.6-ethercat.c \
|
||||
igc_phy-6.6-ethercat.h \
|
||||
igc_phy-6.6-orig.c \
|
||||
igc_phy-6.6-orig.h \
|
||||
igc_ptp-5.14-ethercat.c \
|
||||
igc_ptp-5.14-orig.c \
|
||||
igc_ptp-6.1-ethercat.c \
|
||||
igc_ptp-6.1-orig.c \
|
||||
igc_ptp-6.4-ethercat.c \
|
||||
igc_ptp-6.4-orig.c \
|
||||
igc_ptp-6.6-ethercat.c \
|
||||
igc_ptp-6.6-orig.c \
|
||||
igc_regs-5.14-ethercat.h \
|
||||
igc_regs-5.14-orig.h \
|
||||
igc_regs-6.1-ethercat.h \
|
||||
igc_regs-6.1-orig.h \
|
||||
igc_regs-6.4-ethercat.h \
|
||||
igc_tsn-6.4-orig.h
|
||||
igc_regs-6.4-orig.h \
|
||||
igc_regs-6.6-ethercat.h \
|
||||
igc_regs-6.6-orig.h \
|
||||
igc_tsn-5.14-ethercat.c \
|
||||
igc_tsn-5.14-ethercat.h \
|
||||
igc_tsn-5.14-orig.c \
|
||||
igc_tsn-5.14-orig.h \
|
||||
igc_tsn-6.1-ethercat.c \
|
||||
igc_tsn-6.1-ethercat.h \
|
||||
igc_tsn-6.1-orig.c \
|
||||
igc_tsn-6.1-orig.h \
|
||||
igc_tsn-6.4-ethercat.c \
|
||||
igc_tsn-6.4-ethercat.h \
|
||||
igc_tsn-6.4-orig.c \
|
||||
igc_tsn-6.4-orig.h \
|
||||
igc_tsn-6.6-ethercat.c \
|
||||
igc_tsn-6.6-ethercat.h \
|
||||
igc_tsn-6.6-orig.c \
|
||||
igc_tsn-6.6-orig.h \
|
||||
igc_xdp-5.14-ethercat.c \
|
||||
igc_xdp-5.14-ethercat.h \
|
||||
igc_xdp-5.14-orig.c \
|
||||
igc_xdp-5.14-orig.h \
|
||||
igc_xdp-6.1-ethercat.c \
|
||||
igc_xdp-6.1-ethercat.h \
|
||||
igc_xdp-6.1-orig.c \
|
||||
igc_xdp-6.1-orig.h \
|
||||
igc_xdp-6.4-ethercat.c \
|
||||
igc_xdp-6.4-ethercat.h \
|
||||
igc_xdp-6.4-orig.c \
|
||||
igc_xdp-6.4-orig.h \
|
||||
igc_xdp-6.6-ethercat.c \
|
||||
igc_xdp-6.6-ethercat.h \
|
||||
igc_xdp-6.6-orig.c \
|
||||
igc_xdp-6.6-orig.h
|
||||
|
||||
627
devices/igc/igc-5.14-ethercat.h
Normal file
627
devices/igc/igc-5.14-ethercat.h
Normal file
File diff suppressed because it is too large
Load Diff
611
devices/igc/igc-5.14-orig.h
Normal file
611
devices/igc/igc-5.14-orig.h
Normal file
File diff suppressed because it is too large
Load Diff
656
devices/igc/igc-6.1-ethercat.h
Normal file
656
devices/igc/igc-6.1-ethercat.h
Normal file
File diff suppressed because it is too large
Load Diff
649
devices/igc/igc-6.1-orig.h
Normal file
649
devices/igc/igc-6.1-orig.h
Normal file
File diff suppressed because it is too large
Load Diff
433
devices/igc/igc_base-5.14-ethercat.c
Normal file
433
devices/igc/igc_base-5.14-ethercat.c
Normal file
@@ -0,0 +1,433 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "igc_hw-5.14-ethercat.h"
|
||||
#include "igc_i225-5.14-ethercat.h"
|
||||
#include "igc_mac-5.14-ethercat.h"
|
||||
#include "igc_base-5.14-ethercat.h"
|
||||
#include "igc-5.14-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);
|
||||
|
||||
/* Verify phy id and set remaining function pointers */
|
||||
switch (phy->id) {
|
||||
case I225_I_PHY_ID:
|
||||
phy->type = igc_phy_i225;
|
||||
break;
|
||||
default:
|
||||
ret_val = -IGC_ERR_PHY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
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.14-ethercat.h
Normal file
92
devices/igc/igc_base-5.14-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 */
|
||||
433
devices/igc/igc_base-5.14-orig.c
Normal file
433
devices/igc/igc_base-5.14-orig.c
Normal file
@@ -0,0 +1,433 @@
|
||||
// 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);
|
||||
|
||||
/* Verify phy id and set remaining function pointers */
|
||||
switch (phy->id) {
|
||||
case I225_I_PHY_ID:
|
||||
phy->type = igc_phy_i225;
|
||||
break;
|
||||
default:
|
||||
ret_val = -IGC_ERR_PHY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
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.14-orig.h
Normal file
92
devices/igc/igc_base-5.14-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 */
|
||||
419
devices/igc/igc_base-6.1-ethercat.c
Normal file
419
devices/igc/igc_base-6.1-ethercat.c
Normal file
@@ -0,0 +1,419 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "igc_hw-6.1-ethercat.h"
|
||||
#include "igc_i225-6.1-ethercat.h"
|
||||
#include "igc_mac-6.1-ethercat.h"
|
||||
#include "igc_base-6.1-ethercat.h"
|
||||
#include "igc-6.1-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_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;
|
||||
|
||||
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);
|
||||
|
||||
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_I226_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-6.1-ethercat.h
Normal file
92
devices/igc/igc_base-6.1-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 */
|
||||
419
devices/igc/igc_base-6.1-orig.c
Normal file
419
devices/igc/igc_base-6.1-orig.c
Normal file
@@ -0,0 +1,419 @@
|
||||
// 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_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;
|
||||
|
||||
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);
|
||||
|
||||
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_I226_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-6.1-orig.h
Normal file
92
devices/igc/igc_base-6.1-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 */
|
||||
596
devices/igc/igc_defines-5.14-ethercat.h
Normal file
596
devices/igc/igc_defines-5.14-ethercat.h
Normal file
File diff suppressed because it is too large
Load Diff
596
devices/igc/igc_defines-5.14-orig.h
Normal file
596
devices/igc/igc_defines-5.14-orig.h
Normal file
File diff suppressed because it is too large
Load Diff
673
devices/igc/igc_defines-6.1-ethercat.h
Normal file
673
devices/igc/igc_defines-6.1-ethercat.h
Normal file
File diff suppressed because it is too large
Load Diff
673
devices/igc/igc_defines-6.1-orig.h
Normal file
673
devices/igc/igc_defines-6.1-orig.h
Normal file
File diff suppressed because it is too large
Load Diff
186
devices/igc/igc_diag-5.14-ethercat.c
Normal file
186
devices/igc/igc_diag-5.14-ethercat.c
Normal file
@@ -0,0 +1,186 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2020 Intel Corporation */
|
||||
|
||||
#include "igc-5.14-ethercat.h"
|
||||
#include "igc_diag-5.14-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.14-ethercat.h
Normal file
30
devices/igc/igc_diag-5.14-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.14-orig.c
Normal file
186
devices/igc/igc_diag-5.14-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.14-orig.h
Normal file
30
devices/igc/igc_diag-5.14-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
|
||||
186
devices/igc/igc_diag-6.1-ethercat.c
Normal file
186
devices/igc/igc_diag-6.1-ethercat.c
Normal file
@@ -0,0 +1,186 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2020 Intel Corporation */
|
||||
|
||||
#include "igc-6.1-ethercat.h"
|
||||
#include "igc_diag-6.1-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-6.1-ethercat.h
Normal file
30
devices/igc/igc_diag-6.1-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-6.1-orig.c
Normal file
186
devices/igc/igc_diag-6.1-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-6.1-orig.h
Normal file
30
devices/igc/igc_diag-6.1-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.14-ethercat.c
Normal file
318
devices/igc/igc_dump-5.14-ethercat.c
Normal file
@@ -0,0 +1,318 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#include "igc-5.14-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.14-orig.c
Normal file
318
devices/igc/igc_dump-5.14-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);
|
||||
}
|
||||
}
|
||||
318
devices/igc/igc_dump-6.1-ethercat.c
Normal file
318
devices/igc/igc_dump-6.1-ethercat.c
Normal file
@@ -0,0 +1,318 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2018 Intel Corporation */
|
||||
|
||||
#include "igc-6.1-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-6.1-orig.c
Normal file
318
devices/igc/igc_dump-6.1-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);
|
||||
}
|
||||
}
|
||||
1986
devices/igc/igc_ethtool-5.14-ethercat.c
Normal file
1986
devices/igc/igc_ethtool-5.14-ethercat.c
Normal file
File diff suppressed because it is too large
Load Diff
1951
devices/igc/igc_ethtool-5.14-orig.c
Normal file
1951
devices/igc/igc_ethtool-5.14-orig.c
Normal file
File diff suppressed because it is too large
Load Diff
1980
devices/igc/igc_ethtool-6.1-ethercat.c
Normal file
1980
devices/igc/igc_ethtool-6.1-ethercat.c
Normal file
File diff suppressed because it is too large
Load Diff
1980
devices/igc/igc_ethtool-6.1-orig.c
Normal file
1980
devices/igc/igc_ethtool-6.1-orig.c
Normal file
File diff suppressed because it is too large
Load Diff
298
devices/igc/igc_hw-5.14-ethercat.h
Normal file
298
devices/igc/igc_hw-5.14-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.14-ethercat.h"
|
||||
#include "igc_defines-5.14-ethercat.h"
|
||||
#include "igc_mac-5.14-ethercat.h"
|
||||
#include "igc_phy-5.14-ethercat.h"
|
||||
#include "igc_nvm-5.14-ethercat.h"
|
||||
#include "igc_i225-5.14-ethercat.h"
|
||||
#include "igc_base-5.14-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.14-orig.h
Normal file
298
devices/igc/igc_hw-5.14-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_ */
|
||||
287
devices/igc/igc_hw-6.1-ethercat.h
Normal file
287
devices/igc/igc_hw-6.1-ethercat.h
Normal file
@@ -0,0 +1,287 @@
|
||||
/* 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-6.1-ethercat.h"
|
||||
#include "igc_defines-6.1-ethercat.h"
|
||||
#include "igc_mac-6.1-ethercat.h"
|
||||
#include "igc_phy-6.1-ethercat.h"
|
||||
#include "igc_nvm-6.1-ethercat.h"
|
||||
#include "igc_i225-6.1-ethercat.h"
|
||||
#include "igc_base-6.1-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_I226_LMVP 0x5503
|
||||
#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_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,
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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_ */
|
||||
287
devices/igc/igc_hw-6.1-orig.h
Normal file
287
devices/igc/igc_hw-6.1-orig.h
Normal file
@@ -0,0 +1,287 @@
|
||||
/* 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_I226_LMVP 0x5503
|
||||
#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_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,
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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_ */
|
||||
645
devices/igc/igc_i225-5.14-ethercat.c
Normal file
645
devices/igc/igc_i225-5.14-ethercat.c
Normal file
File diff suppressed because it is too large
Load Diff
16
devices/igc/igc_i225-5.14-ethercat.h
Normal file
16
devices/igc/igc_i225-5.14-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
|
||||
645
devices/igc/igc_i225-5.14-orig.c
Normal file
645
devices/igc/igc_i225-5.14-orig.c
Normal file
File diff suppressed because it is too large
Load Diff
16
devices/igc/igc_i225-5.14-orig.h
Normal file
16
devices/igc/igc_i225-5.14-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
|
||||
650
devices/igc/igc_i225-6.1-ethercat.c
Normal file
650
devices/igc/igc_i225-6.1-ethercat.c
Normal file
File diff suppressed because it is too large
Load Diff
16
devices/igc/igc_i225-6.1-ethercat.h
Normal file
16
devices/igc/igc_i225-6.1-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
|
||||
650
devices/igc/igc_i225-6.1-orig.c
Normal file
650
devices/igc/igc_i225-6.1-orig.c
Normal file
File diff suppressed because it is too large
Load Diff
16
devices/igc/igc_i225-6.1-orig.h
Normal file
16
devices/igc/igc_i225-6.1-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.14-ethercat.c
Normal file
881
devices/igc/igc_mac-5.14-ethercat.c
Normal file
File diff suppressed because it is too large
Load Diff
39
devices/igc/igc_mac-5.14-ethercat.h
Normal file
39
devices/igc/igc_mac-5.14-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.14-ethercat.h"
|
||||
#include "igc_phy-5.14-ethercat.h"
|
||||
#include "igc_defines-5.14-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.14-orig.c
Normal file
881
devices/igc/igc_mac-5.14-orig.c
Normal file
File diff suppressed because it is too large
Load Diff
39
devices/igc/igc_mac-5.14-orig.h
Normal file
39
devices/igc/igc_mac-5.14-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
|
||||
881
devices/igc/igc_mac-6.1-ethercat.c
Normal file
881
devices/igc/igc_mac-6.1-ethercat.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user