Commit fa14b9b0 authored by David S. Miller's avatar David S. Miller

Merge branch '1GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue

Jeff Kirsher says:

====================
1GbE Intel Wired LAN Driver Updates 2020-05-18

This series contains updates to igc driver only.

Sasha adds ECN support for TSO by adding the NETIF_F_TSO_ECN flag, which
aligns with other Intel drivers.  Also cleaned up defines that are not
supported or used in the igc driver.

Andre does most of the changes with updating the log messages for igc
driver.

Vitaly adds support for EEPROM, register and link ethtool
self-tests.

v2: Fixed up the added ethtool self-tests based on feedback from the
    community.  Dropped the four patches that removed '\n' from log
    messages.
v3: Reverted the debug message changes in patch 2 for messages in
    igc_probe, also made reg_test[] static in patch 3 based on community
    feedback
v4: Updated the patch description for patch 2, which referred to changes
    that no longer existed in the patch
v5: Scrubbed patches 4-7 patch description, which also referred to
    changes that no longer existed in the patch
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5cdfe830 5ddb2747
...@@ -8,4 +8,4 @@ ...@@ -8,4 +8,4 @@
obj-$(CONFIG_IGC) += igc.o obj-$(CONFIG_IGC) += igc.o
igc-objs := igc_main.o igc_mac.o igc_i225.o igc_base.o igc_nvm.o igc_phy.o \ igc-objs := igc_main.o igc_mac.o igc_i225.o igc_base.o igc_nvm.o igc_phy.o \
igc_ethtool.o igc_ptp.o igc_dump.o igc_tsn.o igc_diag.o igc_ethtool.o igc_ptp.o igc_dump.o igc_tsn.o
...@@ -198,6 +198,8 @@ struct igc_adapter { ...@@ -198,6 +198,8 @@ struct igc_adapter {
unsigned long link_check_timeout; unsigned long link_check_timeout;
struct igc_info ei; struct igc_info ei;
u32 test_icr;
struct ptp_clock *ptp_clock; struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_caps; struct ptp_clock_info ptp_caps;
struct work_struct ptp_tx_work; struct work_struct ptp_tx_work;
...@@ -215,6 +217,8 @@ struct igc_adapter { ...@@ -215,6 +217,8 @@ struct igc_adapter {
void igc_up(struct igc_adapter *adapter); void igc_up(struct igc_adapter *adapter);
void igc_down(struct igc_adapter *adapter); void igc_down(struct igc_adapter *adapter);
int igc_open(struct net_device *netdev);
int igc_close(struct net_device *netdev);
int igc_setup_tx_resources(struct igc_ring *ring); int igc_setup_tx_resources(struct igc_ring *ring);
int igc_setup_rx_resources(struct igc_ring *ring); int igc_setup_rx_resources(struct igc_ring *ring);
void igc_free_tx_resources(struct igc_ring *ring); void igc_free_tx_resources(struct igc_ring *ring);
......
...@@ -26,7 +26,7 @@ static s32 igc_reset_hw_base(struct igc_hw *hw) ...@@ -26,7 +26,7 @@ static s32 igc_reset_hw_base(struct igc_hw *hw)
*/ */
ret_val = igc_disable_pcie_master(hw); ret_val = igc_disable_pcie_master(hw);
if (ret_val) if (ret_val)
hw_dbg("PCI-E Master disable polling has failed.\n"); hw_dbg("PCI-E Master disable polling has failed\n");
hw_dbg("Masking off all interrupts\n"); hw_dbg("Masking off all interrupts\n");
wr32(IGC_IMC, 0xffffffff); wr32(IGC_IMC, 0xffffffff);
...@@ -177,7 +177,7 @@ static s32 igc_init_phy_params_base(struct igc_hw *hw) ...@@ -177,7 +177,7 @@ static s32 igc_init_phy_params_base(struct igc_hw *hw)
*/ */
ret_val = hw->phy.ops.reset(hw); ret_val = hw->phy.ops.reset(hw);
if (ret_val) { if (ret_val) {
hw_dbg("Error resetting the PHY.\n"); hw_dbg("Error resetting the PHY\n");
goto out; goto out;
} }
...@@ -367,7 +367,7 @@ void igc_rx_fifo_flush_base(struct igc_hw *hw) ...@@ -367,7 +367,7 @@ void igc_rx_fifo_flush_base(struct igc_hw *hw)
} }
if (ms_wait == 10) if (ms_wait == 10)
pr_debug("Queue disable timed out after 10ms\n"); hw_dbg("Queue disable timed out after 10ms\n");
/* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all /* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
* incoming packets are rejected. Set enable and wait 2ms so that * incoming packets are rejected. Set enable and wait 2ms so that
......
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
/* Loop limit on how long we wait for auto-negotiation to complete */ /* Loop limit on how long we wait for auto-negotiation to complete */
#define COPPER_LINK_UP_LIMIT 10 #define COPPER_LINK_UP_LIMIT 10
#define PHY_AUTO_NEG_LIMIT 45 #define PHY_AUTO_NEG_LIMIT 45
#define PHY_FORCE_LIMIT 20
/* Number of 100 microseconds we wait for PCI Express master disable */ /* Number of 100 microseconds we wait for PCI Express master disable */
#define MASTER_DISABLE_TIMEOUT 800 #define MASTER_DISABLE_TIMEOUT 800
......
// 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;
}
/* 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
...@@ -47,6 +47,7 @@ static const struct igc_reg_info igc_reg_info_tbl[] = { ...@@ -47,6 +47,7 @@ static const struct igc_reg_info igc_reg_info_tbl[] = {
/* igc_regdump - register printout routine */ /* igc_regdump - register printout routine */
static void igc_regdump(struct igc_hw *hw, struct igc_reg_info *reginfo) 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; int n = 0;
char rname[16]; char rname[16];
u32 regs[8]; u32 regs[8];
...@@ -101,13 +102,14 @@ static void igc_regdump(struct igc_hw *hw, struct igc_reg_info *reginfo) ...@@ -101,13 +102,14 @@ static void igc_regdump(struct igc_hw *hw, struct igc_reg_info *reginfo)
regs[n] = rd32(IGC_TXDCTL(n)); regs[n] = rd32(IGC_TXDCTL(n));
break; break;
default: default:
pr_info("%-15s %08x\n", reginfo->name, rd32(reginfo->ofs)); netdev_info(dev, "%-15s %08x\n", reginfo->name,
rd32(reginfo->ofs));
return; return;
} }
snprintf(rname, 16, "%s%s", reginfo->name, "[0-3]"); snprintf(rname, 16, "%s%s", reginfo->name, "[0-3]");
pr_info("%-15s %08x %08x %08x %08x\n", rname, regs[0], regs[1], netdev_info(dev, "%-15s %08x %08x %08x %08x\n", rname, regs[0], regs[1],
regs[2], regs[3]); regs[2], regs[3]);
} }
/* igc_rings_dump - Tx-rings and Rx-rings */ /* igc_rings_dump - Tx-rings and Rx-rings */
...@@ -125,39 +127,34 @@ void igc_rings_dump(struct igc_adapter *adapter) ...@@ -125,39 +127,34 @@ void igc_rings_dump(struct igc_adapter *adapter)
if (!netif_msg_hw(adapter)) if (!netif_msg_hw(adapter))
return; return;
/* Print netdevice Info */ netdev_info(netdev, "Device info: state %016lX trans_start %016lX\n",
if (netdev) { netdev->state, dev_trans_start(netdev));
dev_info(&adapter->pdev->dev, "Net device Info\n");
pr_info("Device Name state trans_start\n");
pr_info("%-15s %016lX %016lX\n", netdev->name,
netdev->state, dev_trans_start(netdev));
}
/* Print TX Ring Summary */ /* Print TX Ring Summary */
if (!netdev || !netif_running(netdev)) if (!netif_running(netdev))
goto exit; goto exit;
dev_info(&adapter->pdev->dev, "TX Rings Summary\n"); netdev_info(netdev, "TX Rings Summary\n");
pr_info("Queue [NTU] [NTC] [bi(ntc)->dma ] leng ntw timestamp\n"); netdev_info(netdev, "Queue [NTU] [NTC] [bi(ntc)->dma ] leng ntw timestamp\n");
for (n = 0; n < adapter->num_tx_queues; n++) { for (n = 0; n < adapter->num_tx_queues; n++) {
struct igc_tx_buffer *buffer_info; struct igc_tx_buffer *buffer_info;
tx_ring = adapter->tx_ring[n]; tx_ring = adapter->tx_ring[n];
buffer_info = &tx_ring->tx_buffer_info[tx_ring->next_to_clean]; buffer_info = &tx_ring->tx_buffer_info[tx_ring->next_to_clean];
pr_info(" %5d %5X %5X %016llX %04X %p %016llX\n", netdev_info(netdev, "%5d %5X %5X %016llX %04X %p %016llX\n",
n, tx_ring->next_to_use, tx_ring->next_to_clean, n, tx_ring->next_to_use, tx_ring->next_to_clean,
(u64)dma_unmap_addr(buffer_info, dma), (u64)dma_unmap_addr(buffer_info, dma),
dma_unmap_len(buffer_info, len), dma_unmap_len(buffer_info, len),
buffer_info->next_to_watch, buffer_info->next_to_watch,
(u64)buffer_info->time_stamp); (u64)buffer_info->time_stamp);
} }
/* Print TX Rings */ /* Print TX Rings */
if (!netif_msg_tx_done(adapter)) if (!netif_msg_tx_done(adapter))
goto rx_ring_summary; goto rx_ring_summary;
dev_info(&adapter->pdev->dev, "TX Rings Dump\n"); netdev_info(netdev, "TX Rings Dump\n");
/* Transmit Descriptor Formats /* Transmit Descriptor Formats
* *
...@@ -172,10 +169,11 @@ void igc_rings_dump(struct igc_adapter *adapter) ...@@ -172,10 +169,11 @@ void igc_rings_dump(struct igc_adapter *adapter)
for (n = 0; n < adapter->num_tx_queues; n++) { for (n = 0; n < adapter->num_tx_queues; n++) {
tx_ring = adapter->tx_ring[n]; tx_ring = adapter->tx_ring[n];
pr_info("------------------------------------\n"); netdev_info(netdev, "------------------------------------\n");
pr_info("TX QUEUE INDEX = %d\n", tx_ring->queue_index); netdev_info(netdev, "TX QUEUE INDEX = %d\n",
pr_info("------------------------------------\n"); tx_ring->queue_index);
pr_info("T [desc] [address 63:0 ] [PlPOCIStDDM Ln] [bi->dma ] leng ntw timestamp bi->skb\n"); 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++) { for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
const char *next_desc; const char *next_desc;
...@@ -194,14 +192,14 @@ void igc_rings_dump(struct igc_adapter *adapter) ...@@ -194,14 +192,14 @@ void igc_rings_dump(struct igc_adapter *adapter)
else else
next_desc = ""; next_desc = "";
pr_info("T [0x%03X] %016llX %016llX %016llX %04X %p %016llX %p%s\n", netdev_info(netdev, "T [0x%03X] %016llX %016llX %016llX %04X %p %016llX %p%s\n",
i, le64_to_cpu(u0->a), i, le64_to_cpu(u0->a),
le64_to_cpu(u0->b), le64_to_cpu(u0->b),
(u64)dma_unmap_addr(buffer_info, dma), (u64)dma_unmap_addr(buffer_info, dma),
dma_unmap_len(buffer_info, len), dma_unmap_len(buffer_info, len),
buffer_info->next_to_watch, buffer_info->next_to_watch,
(u64)buffer_info->time_stamp, (u64)buffer_info->time_stamp,
buffer_info->skb, next_desc); buffer_info->skb, next_desc);
if (netif_msg_pktdata(adapter) && buffer_info->skb) if (netif_msg_pktdata(adapter) && buffer_info->skb)
print_hex_dump(KERN_INFO, "", print_hex_dump(KERN_INFO, "",
...@@ -214,19 +212,19 @@ void igc_rings_dump(struct igc_adapter *adapter) ...@@ -214,19 +212,19 @@ void igc_rings_dump(struct igc_adapter *adapter)
/* Print RX Rings Summary */ /* Print RX Rings Summary */
rx_ring_summary: rx_ring_summary:
dev_info(&adapter->pdev->dev, "RX Rings Summary\n"); netdev_info(netdev, "RX Rings Summary\n");
pr_info("Queue [NTU] [NTC]\n"); netdev_info(netdev, "Queue [NTU] [NTC]\n");
for (n = 0; n < adapter->num_rx_queues; n++) { for (n = 0; n < adapter->num_rx_queues; n++) {
rx_ring = adapter->rx_ring[n]; rx_ring = adapter->rx_ring[n];
pr_info(" %5d %5X %5X\n", netdev_info(netdev, "%5d %5X %5X\n", n, rx_ring->next_to_use,
n, rx_ring->next_to_use, rx_ring->next_to_clean); rx_ring->next_to_clean);
} }
/* Print RX Rings */ /* Print RX Rings */
if (!netif_msg_rx_status(adapter)) if (!netif_msg_rx_status(adapter))
goto exit; goto exit;
dev_info(&adapter->pdev->dev, "RX Rings Dump\n"); netdev_info(netdev, "RX Rings Dump\n");
/* Advanced Receive Descriptor (Read) Format /* Advanced Receive Descriptor (Read) Format
* 63 1 0 * 63 1 0
...@@ -251,11 +249,12 @@ void igc_rings_dump(struct igc_adapter *adapter) ...@@ -251,11 +249,12 @@ void igc_rings_dump(struct igc_adapter *adapter)
for (n = 0; n < adapter->num_rx_queues; n++) { for (n = 0; n < adapter->num_rx_queues; n++) {
rx_ring = adapter->rx_ring[n]; rx_ring = adapter->rx_ring[n];
pr_info("------------------------------------\n"); netdev_info(netdev, "------------------------------------\n");
pr_info("RX QUEUE INDEX = %d\n", rx_ring->queue_index); netdev_info(netdev, "RX QUEUE INDEX = %d\n",
pr_info("------------------------------------\n"); rx_ring->queue_index);
pr_info("R [desc] [ PktBuf A0] [ HeadBuf DD] [bi->dma ] [bi->skb] <-- Adv Rx Read format\n"); netdev_info(netdev, "------------------------------------\n");
pr_info("RWB[desc] [PcsmIpSHl PtRs] [vl er S cks ln] ---------------- [bi->skb] <-- Adv Rx Write-Back format\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++) { for (i = 0; i < rx_ring->count; i++) {
const char *next_desc; const char *next_desc;
...@@ -275,18 +274,18 @@ void igc_rings_dump(struct igc_adapter *adapter) ...@@ -275,18 +274,18 @@ void igc_rings_dump(struct igc_adapter *adapter)
if (staterr & IGC_RXD_STAT_DD) { if (staterr & IGC_RXD_STAT_DD) {
/* Descriptor Done */ /* Descriptor Done */
pr_info("%s[0x%03X] %016llX %016llX ---------------- %s\n", netdev_info(netdev, "%s[0x%03X] %016llX %016llX ---------------- %s\n",
"RWB", i, "RWB", i,
le64_to_cpu(u0->a), le64_to_cpu(u0->a),
le64_to_cpu(u0->b), le64_to_cpu(u0->b),
next_desc); next_desc);
} else { } else {
pr_info("%s[0x%03X] %016llX %016llX %016llX %s\n", netdev_info(netdev, "%s[0x%03X] %016llX %016llX %016llX %s\n",
"R ", i, "R ", i,
le64_to_cpu(u0->a), le64_to_cpu(u0->a),
le64_to_cpu(u0->b), le64_to_cpu(u0->b),
(u64)buffer_info->dma, (u64)buffer_info->dma,
next_desc); next_desc);
if (netif_msg_pktdata(adapter) && if (netif_msg_pktdata(adapter) &&
buffer_info->dma && buffer_info->page) { buffer_info->dma && buffer_info->page) {
...@@ -314,8 +313,8 @@ void igc_regs_dump(struct igc_adapter *adapter) ...@@ -314,8 +313,8 @@ void igc_regs_dump(struct igc_adapter *adapter)
struct igc_reg_info *reginfo; struct igc_reg_info *reginfo;
/* Print Registers */ /* Print Registers */
dev_info(&adapter->pdev->dev, "Register Dump\n"); netdev_info(adapter->netdev, "Register Dump\n");
pr_info(" Register Name Value\n"); netdev_info(adapter->netdev, "Register Name Value\n");
for (reginfo = (struct igc_reg_info *)igc_reg_info_tbl; for (reginfo = (struct igc_reg_info *)igc_reg_info_tbl;
reginfo->name; reginfo++) { reginfo->name; reginfo++) {
igc_regdump(hw, reginfo); igc_regdump(hw, reginfo);
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include "igc.h" #include "igc.h"
#include "igc_diag.h"
/* forward declaration */ /* forward declaration */
struct igc_stats { struct igc_stats {
...@@ -1154,8 +1155,8 @@ static int igc_set_rss_hash_opt(struct igc_adapter *adapter, ...@@ -1154,8 +1155,8 @@ static int igc_set_rss_hash_opt(struct igc_adapter *adapter,
if ((flags & UDP_RSS_FLAGS) && if ((flags & UDP_RSS_FLAGS) &&
!(adapter->flags & UDP_RSS_FLAGS)) !(adapter->flags & UDP_RSS_FLAGS))
dev_err(&adapter->pdev->dev, netdev_err(adapter->netdev,
"enabling UDP RSS: fragmented packets may arrive out of order to the stack above\n"); "Enabling UDP RSS: fragmented packets may arrive out of order to the stack above\n");
adapter->flags = flags; adapter->flags = flags;
...@@ -1194,7 +1195,8 @@ static int igc_rxnfc_write_etype_filter(struct igc_adapter *adapter, ...@@ -1194,7 +1195,8 @@ static int igc_rxnfc_write_etype_filter(struct igc_adapter *adapter,
break; break;
} }
if (i == MAX_ETYPE_FILTER) { if (i == MAX_ETYPE_FILTER) {
dev_err(&adapter->pdev->dev, "ethtool -N: etype filters are all used.\n"); netdev_err(adapter->netdev,
"ethtool -N: etype filters are all used\n");
return -EINVAL; return -EINVAL;
} }
...@@ -1235,7 +1237,8 @@ static int igc_rxnfc_write_vlan_prio_filter(struct igc_adapter *adapter, ...@@ -1235,7 +1237,8 @@ static int igc_rxnfc_write_vlan_prio_filter(struct igc_adapter *adapter,
/* check whether this vlan prio is already set */ /* check whether this vlan prio is already set */
if (vlapqf & IGC_VLAPQF_P_VALID(vlan_priority) && if (vlapqf & IGC_VLAPQF_P_VALID(vlan_priority) &&
queue_index != input->action) { queue_index != input->action) {
dev_err(&adapter->pdev->dev, "ethtool rxnfc set vlan prio filter failed.\n"); netdev_err(adapter->netdev,
"ethtool rxnfc set VLAN prio filter failed\n");
return -EEXIST; return -EEXIST;
} }
...@@ -1254,8 +1257,8 @@ int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input) ...@@ -1254,8 +1257,8 @@ int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
if (hw->mac.type == igc_i225 && if (hw->mac.type == igc_i225 &&
!(input->filter.match_flags & ~IGC_FILTER_FLAG_SRC_MAC_ADDR)) { !(input->filter.match_flags & ~IGC_FILTER_FLAG_SRC_MAC_ADDR)) {
dev_err(&adapter->pdev->dev, netdev_err(adapter->netdev,
"i225 doesn't support flow classification rules specifying only source addresses.\n"); "i225 doesn't support flow classification rules specifying only source addresses\n");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -1403,13 +1406,14 @@ static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter, ...@@ -1403,13 +1406,14 @@ static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter,
*/ */
if (fsp->ring_cookie == RX_CLS_FLOW_DISC || if (fsp->ring_cookie == RX_CLS_FLOW_DISC ||
fsp->ring_cookie >= adapter->num_rx_queues) { fsp->ring_cookie >= adapter->num_rx_queues) {
dev_err(&adapter->pdev->dev, "ethtool -N: The specified action is invalid\n"); netdev_err(netdev,
"ethtool -N: The specified action is invalid\n");
return -EINVAL; return -EINVAL;
} }
/* Don't allow indexes to exist outside of available space */ /* Don't allow indexes to exist outside of available space */
if (fsp->location >= IGC_MAX_RXNFC_FILTERS) { if (fsp->location >= IGC_MAX_RXNFC_FILTERS) {
dev_err(&adapter->pdev->dev, "Location out of range\n"); netdev_err(netdev, "Location out of range\n");
return -EINVAL; return -EINVAL;
} }
...@@ -1457,8 +1461,8 @@ static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter, ...@@ -1457,8 +1461,8 @@ static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter,
if (!memcmp(&input->filter, &rule->filter, if (!memcmp(&input->filter, &rule->filter,
sizeof(input->filter))) { sizeof(input->filter))) {
err = -EEXIST; err = -EEXIST;
dev_err(&adapter->pdev->dev, netdev_err(netdev,
"ethtool: this filter is already set\n"); "ethtool: this filter is already set\n");
goto err_out_w_lock; goto err_out_w_lock;
} }
} }
...@@ -1831,6 +1835,7 @@ static int igc_set_link_ksettings(struct net_device *netdev, ...@@ -1831,6 +1835,7 @@ static int igc_set_link_ksettings(struct net_device *netdev,
const struct ethtool_link_ksettings *cmd) const struct ethtool_link_ksettings *cmd)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
struct net_device *dev = adapter->netdev;
struct igc_hw *hw = &adapter->hw; struct igc_hw *hw = &adapter->hw;
u32 advertising; u32 advertising;
...@@ -1838,8 +1843,7 @@ static int igc_set_link_ksettings(struct net_device *netdev, ...@@ -1838,8 +1843,7 @@ static int igc_set_link_ksettings(struct net_device *netdev,
* cannot be changed * cannot be changed
*/ */
if (igc_check_reset_block(hw)) { if (igc_check_reset_block(hw)) {
dev_err(&adapter->pdev->dev, netdev_err(dev, "Cannot change link characteristics when reset is active\n");
"Cannot change link characteristics when reset is active.\n");
return -EINVAL; return -EINVAL;
} }
...@@ -1850,7 +1854,7 @@ static int igc_set_link_ksettings(struct net_device *netdev, ...@@ -1850,7 +1854,7 @@ static int igc_set_link_ksettings(struct net_device *netdev,
if (cmd->base.eth_tp_mdix_ctrl) { if (cmd->base.eth_tp_mdix_ctrl) {
if (cmd->base.eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO && if (cmd->base.eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO &&
cmd->base.autoneg != AUTONEG_ENABLE) { cmd->base.autoneg != AUTONEG_ENABLE) {
dev_err(&adapter->pdev->dev, "forcing MDI/MDI-X state is not supported when link speed and/or duplex are forced\n"); netdev_err(dev, "Forcing MDI/MDI-X state is not supported when link speed and/or duplex are forced\n");
return -EINVAL; return -EINVAL;
} }
} }
...@@ -1867,9 +1871,7 @@ static int igc_set_link_ksettings(struct net_device *netdev, ...@@ -1867,9 +1871,7 @@ static int igc_set_link_ksettings(struct net_device *netdev,
if (adapter->fc_autoneg) if (adapter->fc_autoneg)
hw->fc.requested_mode = igc_fc_default; hw->fc.requested_mode = igc_fc_default;
} else { } else {
/* calling this overrides forced MDI setting */ netdev_info(dev, "Force mode currently not supported\n");
dev_info(&adapter->pdev->dev,
"Force mode currently not supported\n");
} }
/* MDI-X => 2; MDI => 1; Auto => 3 */ /* MDI-X => 2; MDI => 1; Auto => 3 */
...@@ -1896,6 +1898,64 @@ static int igc_set_link_ksettings(struct net_device *netdev, ...@@ -1896,6 +1898,64 @@ static int igc_set_link_ksettings(struct net_device *netdev,
return 0; return 0;
} }
static void igc_diag_test(struct net_device *netdev,
struct ethtool_test *eth_test, u64 *data)
{
struct igc_adapter *adapter = netdev_priv(netdev);
bool if_running = netif_running(netdev);
if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
netdev_info(adapter->netdev, "Offline testing starting");
set_bit(__IGC_TESTING, &adapter->state);
/* Link test performed before hardware reset so autoneg doesn't
* interfere with test result
*/
if (!igc_link_test(adapter, &data[TEST_LINK]))
eth_test->flags |= ETH_TEST_FL_FAILED;
if (if_running)
igc_close(netdev);
else
igc_reset(adapter);
netdev_info(adapter->netdev, "Register testing starting");
if (!igc_reg_test(adapter, &data[TEST_REG]))
eth_test->flags |= ETH_TEST_FL_FAILED;
igc_reset(adapter);
netdev_info(adapter->netdev, "EEPROM testing starting");
if (!igc_eeprom_test(adapter, &data[TEST_EEP]))
eth_test->flags |= ETH_TEST_FL_FAILED;
igc_reset(adapter);
/* loopback and interrupt tests
* will be implemented in the future
*/
data[TEST_LOOP] = 0;
data[TEST_IRQ] = 0;
clear_bit(__IGC_TESTING, &adapter->state);
if (if_running)
igc_open(netdev);
} else {
netdev_info(adapter->netdev, "Online testing starting");
/* register, eeprom, intr and loopback tests not run online */
data[TEST_REG] = 0;
data[TEST_EEP] = 0;
data[TEST_IRQ] = 0;
data[TEST_LOOP] = 0;
if (!igc_link_test(adapter, &data[TEST_LINK]))
eth_test->flags |= ETH_TEST_FL_FAILED;
}
msleep_interruptible(4 * 1000);
}
static const struct ethtool_ops igc_ethtool_ops = { static const struct ethtool_ops igc_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_USECS, .supported_coalesce_params = ETHTOOL_COALESCE_USECS,
.get_drvinfo = igc_get_drvinfo, .get_drvinfo = igc_get_drvinfo,
...@@ -1933,6 +1993,7 @@ static const struct ethtool_ops igc_ethtool_ops = { ...@@ -1933,6 +1993,7 @@ static const struct ethtool_ops igc_ethtool_ops = {
.complete = igc_ethtool_complete, .complete = igc_ethtool_complete,
.get_link_ksettings = igc_get_link_ksettings, .get_link_ksettings = igc_get_link_ksettings,
.set_link_ksettings = igc_set_link_ksettings, .set_link_ksettings = igc_set_link_ksettings,
.self_test = igc_diag_test,
}; };
void igc_set_ethtool_ops(struct net_device *netdev) void igc_set_ethtool_ops(struct net_device *netdev)
......
This diff is collapsed.
...@@ -466,7 +466,7 @@ void igc_ptp_tx_hang(struct igc_adapter *adapter) ...@@ -466,7 +466,7 @@ void igc_ptp_tx_hang(struct igc_adapter *adapter)
* interrupt * interrupt
*/ */
rd32(IGC_TXSTMPH); rd32(IGC_TXSTMPH);
dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang\n"); netdev_warn(adapter->netdev, "Clearing Tx timestamp hang\n");
} }
} }
...@@ -529,7 +529,7 @@ static void igc_ptp_tx_work(struct work_struct *work) ...@@ -529,7 +529,7 @@ static void igc_ptp_tx_work(struct work_struct *work)
* interrupt * interrupt
*/ */
rd32(IGC_TXSTMPH); rd32(IGC_TXSTMPH);
dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang\n"); netdev_warn(adapter->netdev, "Clearing Tx timestamp hang\n");
return; return;
} }
...@@ -626,10 +626,9 @@ void igc_ptp_init(struct igc_adapter *adapter) ...@@ -626,10 +626,9 @@ void igc_ptp_init(struct igc_adapter *adapter)
&adapter->pdev->dev); &adapter->pdev->dev);
if (IS_ERR(adapter->ptp_clock)) { if (IS_ERR(adapter->ptp_clock)) {
adapter->ptp_clock = NULL; adapter->ptp_clock = NULL;
dev_err(&adapter->pdev->dev, "ptp_clock_register failed\n"); netdev_err(netdev, "ptp_clock_register failed\n");
} else if (adapter->ptp_clock) { } else if (adapter->ptp_clock) {
dev_info(&adapter->pdev->dev, "added PHC on %s\n", netdev_info(netdev, "PHC added\n");
adapter->netdev->name);
adapter->ptp_flags |= IGC_PTP_ENABLED; adapter->ptp_flags |= IGC_PTP_ENABLED;
} }
} }
...@@ -666,8 +665,7 @@ void igc_ptp_stop(struct igc_adapter *adapter) ...@@ -666,8 +665,7 @@ void igc_ptp_stop(struct igc_adapter *adapter)
if (adapter->ptp_clock) { if (adapter->ptp_clock) {
ptp_clock_unregister(adapter->ptp_clock); ptp_clock_unregister(adapter->ptp_clock);
dev_info(&adapter->pdev->dev, "removed PHC on %s\n", netdev_info(adapter->netdev, "PHC removed\n");
adapter->netdev->name);
adapter->ptp_flags &= ~IGC_PTP_ENABLED; adapter->ptp_flags &= ~IGC_PTP_ENABLED;
} }
} }
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#define IGC_FCRTL 0x02160 /* FC Receive Threshold Low - RW */ #define IGC_FCRTL 0x02160 /* FC Receive Threshold Low - RW */
#define IGC_FCRTH 0x02168 /* FC Receive Threshold High - RW */ #define IGC_FCRTH 0x02168 /* FC Receive Threshold High - RW */
#define IGC_FCRTV 0x02460 /* FC Refresh Timer Value - RW */ #define IGC_FCRTV 0x02460 /* FC Refresh Timer Value - RW */
#define IGC_FCSTS 0x02464 /* FC Status - RO */
/* PCIe Register Description */ /* PCIe Register Description */
#define IGC_GCR 0x05B00 /* PCIe control- RW */ #define IGC_GCR 0x05B00 /* PCIe control- RW */
...@@ -49,6 +48,7 @@ ...@@ -49,6 +48,7 @@
#define IGC_FACTPS 0x05B30 #define IGC_FACTPS 0x05B30
/* Interrupt Register Description */ /* Interrupt Register Description */
#define IGC_EICR 0x01580 /* Ext. Interrupt Cause read - W0 */
#define IGC_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */ #define IGC_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */
#define IGC_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */ #define IGC_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */
#define IGC_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */ #define IGC_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */
...@@ -119,6 +119,7 @@ ...@@ -119,6 +119,7 @@
#define IGC_RLPML 0x05004 /* Rx Long Packet Max Length */ #define IGC_RLPML 0x05004 /* Rx Long Packet Max Length */
#define IGC_RFCTL 0x05008 /* Receive Filter Control*/ #define IGC_RFCTL 0x05008 /* Receive Filter Control*/
#define IGC_MTA 0x05200 /* Multicast Table Array - RW Array */ #define IGC_MTA 0x05200 /* Multicast Table Array - RW Array */
#define IGC_RA 0x05400 /* Receive Address - RW Array */
#define IGC_UTA 0x0A000 /* Unicast Table Array - RW */ #define IGC_UTA 0x0A000 /* Unicast Table Array - RW */
#define IGC_RAL(_n) (0x05400 + ((_n) * 0x08)) #define IGC_RAL(_n) (0x05400 + ((_n) * 0x08))
#define IGC_RAH(_n) (0x05404 + ((_n) * 0x08)) #define IGC_RAH(_n) (0x05404 + ((_n) * 0x08))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment