From db2d737d63c5b501eb103d5e5c96499cc792c420 Mon Sep 17 00:00:00 2001 From: Sasha Neftin Date: Tue, 26 Jul 2022 17:36:25 +0300 Subject: [PATCH 1/6] e1000e: Separate MTP board type from ADP We have the same LAN controller on different PCH's. Separate MTP board type from an ADP which will allow for specific fixes to be applied for MTP platforms. Signed-off-by: Sasha Neftin Tested-by: Naama Meir Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/e1000e/e1000.h | 4 +++- drivers/net/ethernet/intel/e1000e/ich8lan.c | 20 ++++++++++++++++++++ drivers/net/ethernet/intel/e1000e/netdev.c | 17 +++++++++-------- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index e8a9a9610ac6..a187582d2299 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -116,7 +116,8 @@ enum e1000_boards { board_pch_spt, board_pch_cnp, board_pch_tgp, - board_pch_adp + board_pch_adp, + board_pch_mtp }; struct e1000_ps_page { @@ -504,6 +505,7 @@ extern const struct e1000_info e1000_pch_spt_info; extern const struct e1000_info e1000_pch_cnp_info; extern const struct e1000_info e1000_pch_tgp_info; extern const struct e1000_info e1000_pch_adp_info; +extern const struct e1000_info e1000_pch_mtp_info; extern const struct e1000_info e1000_es2_info; void e1000e_ptp_init(struct e1000_adapter *adapter); diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 9466f65a6da7..e8f7cb9d8724 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -6041,3 +6041,23 @@ const struct e1000_info e1000_pch_adp_info = { .phy_ops = &ich8_phy_ops, .nvm_ops = &spt_nvm_ops, }; + +const struct e1000_info e1000_pch_mtp_info = { + .mac = e1000_pch_mtp, + .flags = FLAG_IS_ICH + | FLAG_HAS_WOL + | FLAG_HAS_HW_TIMESTAMP + | FLAG_HAS_CTRLEXT_ON_LOAD + | FLAG_HAS_AMT + | FLAG_HAS_FLASH + | FLAG_HAS_JUMBO_FRAMES + | FLAG_APME_IN_WUC, + .flags2 = FLAG2_HAS_PHY_STATS + | FLAG2_HAS_EEE, + .pba = 26, + .max_hw_frame_size = 9022, + .get_variants = e1000_get_variants_ich8lan, + .mac_ops = &ich8_mac_ops, + .phy_ops = &ich8_phy_ops, + .nvm_ops = &spt_nvm_ops, +}; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 49e926959ad3..4dc862399f0c 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -53,6 +53,7 @@ static const struct e1000_info *e1000_info_tbl[] = { [board_pch_cnp] = &e1000_pch_cnp_info, [board_pch_tgp] = &e1000_pch_tgp_info, [board_pch_adp] = &e1000_pch_adp_info, + [board_pch_mtp] = &e1000_pch_mtp_info, }; struct e1000_reg_info { @@ -7905,14 +7906,14 @@ static const struct pci_device_id e1000_pci_tbl[] = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V17), board_pch_adp }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_LM22), board_pch_adp }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_V22), board_pch_adp }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM18), board_pch_adp }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V18), board_pch_adp }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM19), board_pch_adp }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V19), board_pch_adp }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM20), board_pch_adp }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V20), board_pch_adp }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM21), board_pch_adp }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V21), board_pch_adp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM18), board_pch_mtp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V18), board_pch_mtp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM19), board_pch_mtp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V19), board_pch_mtp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM20), board_pch_mtp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V20), board_pch_mtp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM21), board_pch_mtp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V21), board_pch_mtp }, { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */ }; From 0c9183ce61bc5e546fc06d1f3237120778a81192 Mon Sep 17 00:00:00 2001 From: Sasha Neftin Date: Thu, 29 Sep 2022 11:08:59 +0300 Subject: [PATCH 2/6] e1000e: Add support for the next LOM generation Add devices IDs for the next LOM generations that will be available on the next Intel Client platforms. This patch provides the initial support for these devices. Signed-off-by: Sasha Neftin Tested-by: Naama Meir Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/e1000e/ethtool.c | 2 ++ drivers/net/ethernet/intel/e1000e/hw.h | 9 +++++++++ drivers/net/ethernet/intel/e1000e/ich8lan.c | 7 +++++++ drivers/net/ethernet/intel/e1000e/netdev.c | 10 ++++++++++ drivers/net/ethernet/intel/e1000e/ptp.c | 1 + 5 files changed, 29 insertions(+) diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 51a5afe9df2f..59e82d131d88 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -908,6 +908,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: + case e1000_pch_ptp: mask |= BIT(18); break; default: @@ -1575,6 +1576,7 @@ static void e1000_loopback_cleanup(struct e1000_adapter *adapter) case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: + case e1000_pch_ptp: fext_nvm11 = er32(FEXTNVM11); fext_nvm11 &= ~E1000_FEXTNVM11_DISABLE_MULR_FIX; ew32(FEXTNVM11, fext_nvm11); diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h index bcf680e83811..29f9fae35f42 100644 --- a/drivers/net/ethernet/intel/e1000e/hw.h +++ b/drivers/net/ethernet/intel/e1000e/hw.h @@ -114,6 +114,14 @@ struct e1000_hw; #define E1000_DEV_ID_PCH_LNP_I219_V20 0x550F #define E1000_DEV_ID_PCH_LNP_I219_LM21 0x5510 #define E1000_DEV_ID_PCH_LNP_I219_V21 0x5511 +#define E1000_DEV_ID_PCH_ARL_I219_LM24 0x57A0 +#define E1000_DEV_ID_PCH_ARL_I219_V24 0x57A1 +#define E1000_DEV_ID_PCH_PTP_I219_LM25 0x57B3 +#define E1000_DEV_ID_PCH_PTP_I219_V25 0x57B4 +#define E1000_DEV_ID_PCH_PTP_I219_LM26 0x57B5 +#define E1000_DEV_ID_PCH_PTP_I219_V26 0x57B6 +#define E1000_DEV_ID_PCH_PTP_I219_LM27 0x57B7 +#define E1000_DEV_ID_PCH_PTP_I219_V27 0x57B8 #define E1000_REVISION_4 4 @@ -141,6 +149,7 @@ enum e1000_mac_type { e1000_pch_adp, e1000_pch_mtp, e1000_pch_lnp, + e1000_pch_ptp, }; enum e1000_media_type { diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index e8f7cb9d8724..0c7fd10312c8 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -322,6 +322,7 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw) case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: + case e1000_pch_ptp: if (e1000_phy_is_accessible_pchlan(hw)) break; @@ -468,6 +469,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: + case e1000_pch_ptp: /* In case the PHY needs to be in mdio slow mode, * set slow mode and try to get the PHY id again. */ @@ -714,6 +716,7 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: + case e1000_pch_ptp: case e1000_pchlan: /* check management mode */ mac->ops.check_mng_mode = e1000_check_mng_mode_pchlan; @@ -1681,6 +1684,7 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: + case e1000_pch_ptp: rc = e1000_init_phy_params_pchlan(hw); break; default: @@ -2137,6 +2141,7 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: + case e1000_pch_ptp: sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; break; default: @@ -3182,6 +3187,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: + case e1000_pch_ptp: bank1_offset = nvm->flash_bank_size; act_offset = E1000_ICH_NVM_SIG_WORD; @@ -4122,6 +4128,7 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: + case e1000_pch_ptp: word = NVM_COMPAT; valid_csum_mask = NVM_COMPAT_VALID_CSUM; break; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 4dc862399f0c..edc8aa9822ee 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -3553,6 +3553,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca) case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: + case e1000_pch_ptp: if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) { /* Stable 24MHz frequency */ incperiod = INCPERIOD_24MHZ; @@ -4068,6 +4069,7 @@ void e1000e_reset(struct e1000_adapter *adapter) case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: + case e1000_pch_ptp: fc->refresh_time = 0xFFFF; fc->pause_time = 0xFFFF; @@ -7914,6 +7916,14 @@ static const struct pci_device_id e1000_pci_tbl[] = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V20), board_pch_mtp }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM21), board_pch_mtp }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V21), board_pch_mtp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ARL_I219_LM24), board_pch_mtp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ARL_I219_V24), board_pch_mtp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_PTP_I219_LM25), board_pch_mtp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_PTP_I219_V25), board_pch_mtp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_PTP_I219_LM26), board_pch_mtp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_PTP_I219_V26), board_pch_mtp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_PTP_I219_LM27), board_pch_mtp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_PTP_I219_V27), board_pch_mtp }, { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */ }; diff --git a/drivers/net/ethernet/intel/e1000e/ptp.c b/drivers/net/ethernet/intel/e1000e/ptp.c index 6e5a1720e6cd..def4566a916f 100644 --- a/drivers/net/ethernet/intel/e1000e/ptp.c +++ b/drivers/net/ethernet/intel/e1000e/ptp.c @@ -287,6 +287,7 @@ void e1000e_ptp_init(struct e1000_adapter *adapter) case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: + case e1000_pch_ptp: if ((hw->mac.type < e1000_pch_lpt) || (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI)) { adapter->ptp_clock_info.max_adj = 24000000 - 1; From 7bab8828e1ec33e579a664c4262053e16e9cc936 Mon Sep 17 00:00:00 2001 From: Sasha Neftin Date: Wed, 21 Sep 2022 10:59:37 +0300 Subject: [PATCH 3/6] e1000e: Add e1000e trace module Add tracepoints to the driver via a new file e1000e_trace.h and some new trace calls added in interesting places in the driver. Add some tracing for s0ix flows to help in a debug of shared resources with the CSME firmware. The idea here is that tracepoints have such low performance cost when disabled that we can leave these in the upstream driver. Performance not affected, and this can be very useful for debugging and adding new trace events to paths in the future. Usage: echo "e1000e_trace:*" > /sys/kernel/debug/tracing/set_event echo 1 > /sys/kernel/debug/tracing/events/e1000e_trace/enable Signed-off-by: Sasha Neftin Tested-by: Naama Meir Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/e1000e/Makefile | 3 ++ .../net/ethernet/intel/e1000e/e1000e_trace.h | 42 +++++++++++++++++++ drivers/net/ethernet/intel/e1000e/netdev.c | 4 ++ 3 files changed, 49 insertions(+) create mode 100644 drivers/net/ethernet/intel/e1000e/e1000e_trace.h diff --git a/drivers/net/ethernet/intel/e1000e/Makefile b/drivers/net/ethernet/intel/e1000e/Makefile index 44e58b6e7660..0baa15503c38 100644 --- a/drivers/net/ethernet/intel/e1000e/Makefile +++ b/drivers/net/ethernet/intel/e1000e/Makefile @@ -5,6 +5,9 @@ # Makefile for the Intel(R) PRO/1000 ethernet driver # +ccflags-y += -I$(src) +subdir-ccflags-y += -I$(src) + obj-$(CONFIG_E1000E) += e1000e.o e1000e-objs := 82571.o ich8lan.o 80003es2lan.o \ diff --git a/drivers/net/ethernet/intel/e1000e/e1000e_trace.h b/drivers/net/ethernet/intel/e1000e/e1000e_trace.h new file mode 100644 index 000000000000..19d3cf4d924e --- /dev/null +++ b/drivers/net/ethernet/intel/e1000e/e1000e_trace.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2022, Intel Corporation. */ +/* Modeled on trace-events-sample.h */ +/* The trace subsystem name for e1000e will be "e1000e_trace". + * + * This file is named e1000e_trace.h. + * + * Since this include file's name is different from the trace + * subsystem name, we'll have to define TRACE_INCLUDE_FILE at the end + * of this file. + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM e1000e_trace + +#if !defined(_TRACE_E1000E_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_E1000E_TRACE_H + +#include + +TRACE_EVENT(e1000e_trace_mac_register, + TP_PROTO(uint32_t reg), + TP_ARGS(reg), + TP_STRUCT__entry(__field(uint32_t, reg)), + TP_fast_assign(__entry->reg = reg;), + TP_printk("event: TraceHub e1000e mac register: 0x%08x", + __entry->reg) +); + +#endif +/* This must be outside ifdef _E1000E_TRACE_H */ +/* This trace include file is not located in the .../include/trace + * with the kernel tracepoint definitions, because we're a loadable + * module. + */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE e1000e_trace + +#include diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index edc8aa9822ee..f0e015673f48 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -28,6 +28,8 @@ #include #include "e1000.h" +#define CREATE_TRACE_POINTS +#include "e1000e_trace.h" char e1000e_driver_name[] = "e1000e"; @@ -6351,6 +6353,7 @@ static void e1000e_s0ix_entry_flow(struct e1000_adapter *adapter) mac_data = er32(H2ME); mac_data |= E1000_H2ME_START_DPG; mac_data &= ~E1000_H2ME_EXIT_DPG; + trace_e1000e_trace_mac_register(mac_data); ew32(H2ME, mac_data); } else { /* Request driver configure the device to S0ix */ @@ -6505,6 +6508,7 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter) mac_data = er32(H2ME); mac_data &= ~E1000_H2ME_START_DPG; mac_data |= E1000_H2ME_EXIT_DPG; + trace_e1000e_trace_mac_register(mac_data); ew32(H2ME, mac_data); /* Poll up to 2.5 seconds for ME to unconfigure DPG. From ab400b0dd4ec186e483abc667358b4135ab94f1a Mon Sep 17 00:00:00 2001 From: Anirudh Venkataramanan Date: Fri, 30 Sep 2022 15:33:24 -0700 Subject: [PATCH 4/6] e1000e: Remove unnecessary use of kmap_atomic() alloc_rx_buf() allocates ps_page->page and buffer_info->page using either GFP_ATOMIC or GFP_KERNEL. Memory allocated with GFP_KERNEL/GFP_ATOMIC can't come from highmem and so there's no need to kmap() them. Just use page_address(). I don't have access to a 32-bit system so did some limited testing on qemu (qemu-system-i386 -m 4096 -smp 4 -device e1000e) with a 32-bit Debian 11.04 image. Cc: Ira Weiny Cc: Fabio M. De Francesco Cc: Jesse Brandeburg Cc: Tony Nguyen Suggested-by: Ira Weiny Suggested-by: Fabio M. De Francesco Signed-off-by: Anirudh Venkataramanan Tested-by: Naama Meir Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/e1000e/netdev.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index f0e015673f48..36bc4fd91ef4 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -1391,26 +1391,18 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done, /* page alloc/put takes too long and effects small * packet throughput, so unsplit small packets and - * save the alloc/put only valid in softirq (napi) - * context to call kmap_* + * save the alloc/put */ if (l1 && (l1 <= copybreak) && ((length + l1) <= adapter->rx_ps_bsize0)) { - u8 *vaddr; - ps_page = &buffer_info->ps_pages[0]; - /* there is no documentation about how to call - * kmap_atomic, so we can't hold the mapping - * very long - */ dma_sync_single_for_cpu(&pdev->dev, ps_page->dma, PAGE_SIZE, DMA_FROM_DEVICE); - vaddr = kmap_atomic(ps_page->page); - memcpy(skb_tail_pointer(skb), vaddr, l1); - kunmap_atomic(vaddr); + memcpy(skb_tail_pointer(skb), + page_address(ps_page->page), l1); dma_sync_single_for_device(&pdev->dev, ps_page->dma, PAGE_SIZE, @@ -1610,11 +1602,9 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done, */ if (length <= copybreak && skb_tailroom(skb) >= length) { - u8 *vaddr; - vaddr = kmap_atomic(buffer_info->page); - memcpy(skb_tail_pointer(skb), vaddr, + memcpy(skb_tail_pointer(skb), + page_address(buffer_info->page), length); - kunmap_atomic(vaddr); /* re-use the page, so don't erase * buffer_info->page */ From 3e7b52e0eb9ef7e67c26072cb1c7a49a5cc356f5 Mon Sep 17 00:00:00 2001 From: Anirudh Venkataramanan Date: Mon, 19 Sep 2022 11:09:48 -0700 Subject: [PATCH 5/6] e1000: Remove unnecessary use of kmap_atomic() buffer_info->rxbuf.page accessed in e1000_clean_jumbo_rx_irq() is allocated using GFP_ATOMIC. Pages allocated with GFP_ATOMIC can't come from highmem and so there's no need to kmap() them. Just use page_address(). I don't have access to a 32-bit system so did some limited testing on qemu (qemu-system-i386 -m 4096 -smp 4 -device e1000e) with a 32-bit Debian 11.04 image. Cc: Ira Weiny Cc: Fabio M. De Francesco Cc: Jesse Brandeburg Cc: Tony Nguyen Suggested-by: Ira Weiny Suggested-by: Fabio M. De Francesco Signed-off-by: Anirudh Venkataramanan Reviewed-by: Ira Weiny Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/e1000/e1000_main.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 61e60e4de600..da6e303ad99b 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -4229,8 +4229,6 @@ process_skb: */ p = buffer_info->rxbuf.page; if (length <= copybreak) { - u8 *vaddr; - if (likely(!(netdev->features & NETIF_F_RXFCS))) length -= 4; skb = e1000_alloc_rx_skb(adapter, @@ -4238,10 +4236,9 @@ process_skb: if (!skb) break; - vaddr = kmap_atomic(p); - memcpy(skb_tail_pointer(skb), vaddr, - length); - kunmap_atomic(vaddr); + memcpy(skb_tail_pointer(skb), + page_address(p), length); + /* re-use the page, so don't erase * buffer_info->rxbuf.page */ From 790835fcc0cb9992349ae3c9010dbc7321aaa24d Mon Sep 17 00:00:00 2001 From: Muhammad Husaini Zulkifli Date: Wed, 21 Sep 2022 10:49:40 +0800 Subject: [PATCH 6/6] igc: Correct the launchtime offset The launchtime offset should be corrected according to sections 7.5.2.6 Transmit Scheduling Latency of the Intel Ethernet I225/I226 Software User Manual. Software can compensate the latency between the transmission scheduling and the time that packet is transmitted to the network by setting this GTxOffset register. Without setting this register, there may be a significant delay between the packet scheduling and the network point. This patch helps to reduce the latency for each of the link speed. Before: 10Mbps : 11000 - 13800 nanosecond 100Mbps : 1300 - 1700 nanosecond 1000Mbps : 190 - 600 nanosecond 2500Mbps : 1400 - 1700 nanosecond After: 10Mbps : less than 750 nanosecond 100Mbps : less than 192 nanosecond 1000Mbps : less than 128 nanosecond 2500Mbps : less than 128 nanosecond Test Setup: Talker : Use l2_tai.c to generate the launchtime into packet payload. Listener: Use timedump.c to compute the delta between packet arrival and LaunchTime packet payload. Signed-off-by: Vinicius Costa Gomes Signed-off-by: Muhammad Husaini Zulkifli Acked-by: Sasha Neftin Acked-by: Paul Menzel Tested-by: Naama Meir Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/igc/igc_defines.h | 9 ++++++ drivers/net/ethernet/intel/igc/igc_main.c | 7 +++++ drivers/net/ethernet/intel/igc/igc_regs.h | 1 + drivers/net/ethernet/intel/igc/igc_tsn.c | 30 ++++++++++++++++++++ drivers/net/ethernet/intel/igc/igc_tsn.h | 1 + 5 files changed, 48 insertions(+) diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h index 4f9d7f013a95..f7311aeb293b 100644 --- a/drivers/net/ethernet/intel/igc/igc_defines.h +++ b/drivers/net/ethernet/intel/igc/igc_defines.h @@ -400,6 +400,15 @@ #define IGC_DTXMXPKTSZ_TSN 0x19 /* 1600 bytes of max TX DMA packet size */ #define IGC_DTXMXPKTSZ_DEFAULT 0x98 /* 9728-byte Jumbo frames */ +/* Transmit Scheduling Latency */ +/* Latency between transmission scheduling (LaunchTime) and the time + * the packet is transmitted to the network in nanosecond. + */ +#define IGC_TXOFFSET_SPEED_10 0x000034BC +#define IGC_TXOFFSET_SPEED_100 0x00000578 +#define IGC_TXOFFSET_SPEED_1000 0x0000012C +#define IGC_TXOFFSET_SPEED_2500 0x00000578 + /* Time Sync Interrupt Causes */ #define IGC_TSICR_SYS_WRAP BIT(0) /* SYSTIM Wrap around. */ #define IGC_TSICR_TXTS BIT(1) /* Transmit Timestamp. */ diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 5d307b6e660b..1586e1e435c6 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -5381,6 +5381,13 @@ static void igc_watchdog_task(struct work_struct *work) break; } + /* Once the launch time has been set on the wire, there + * is a delay before the link speed can be determined + * based on link-up activity. Write into the register + * as soon as we know the correct link speed. + */ + igc_tsn_adjust_txtime_offset(adapter); + if (adapter->link_speed != SPEED_1000) goto no_wait; diff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h index c0d8214148d1..01c86d36856d 100644 --- a/drivers/net/ethernet/intel/igc/igc_regs.h +++ b/drivers/net/ethernet/intel/igc/igc_regs.h @@ -224,6 +224,7 @@ /* Transmit Scheduling Registers */ #define IGC_TQAVCTRL 0x3570 #define IGC_TXQCTL(_n) (0x3344 + 0x4 * (_n)) +#define IGC_GTXOFFSET 0x3310 #define IGC_BASET_L 0x3314 #define IGC_BASET_H 0x3318 #define IGC_QBVCYCLET 0x331C diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.c b/drivers/net/ethernet/intel/igc/igc_tsn.c index 0fce22de2ab8..f975ed807da1 100644 --- a/drivers/net/ethernet/intel/igc/igc_tsn.c +++ b/drivers/net/ethernet/intel/igc/igc_tsn.c @@ -48,6 +48,35 @@ static unsigned int igc_tsn_new_flags(struct igc_adapter *adapter) return new_flags; } +void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter) +{ + struct igc_hw *hw = &adapter->hw; + u16 txoffset; + + if (!is_any_launchtime(adapter)) + return; + + switch (adapter->link_speed) { + case SPEED_10: + txoffset = IGC_TXOFFSET_SPEED_10; + break; + case SPEED_100: + txoffset = IGC_TXOFFSET_SPEED_100; + break; + case SPEED_1000: + txoffset = IGC_TXOFFSET_SPEED_1000; + break; + case SPEED_2500: + txoffset = IGC_TXOFFSET_SPEED_2500; + break; + default: + txoffset = 0; + break; + } + + wr32(IGC_GTXOFFSET, txoffset); +} + /* Returns the TSN specific registers to their default values after * the adapter is reset. */ @@ -57,6 +86,7 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter) u32 tqavctrl; int i; + wr32(IGC_GTXOFFSET, 0); wr32(IGC_TXPBS, I225_TXPBSIZE_DEFAULT); wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_DEFAULT); diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.h b/drivers/net/ethernet/intel/igc/igc_tsn.h index 1512307f5a52..b53e6af560b7 100644 --- a/drivers/net/ethernet/intel/igc/igc_tsn.h +++ b/drivers/net/ethernet/intel/igc/igc_tsn.h @@ -6,5 +6,6 @@ int igc_tsn_offload_apply(struct igc_adapter *adapter); int igc_tsn_reset(struct igc_adapter *adapter); +void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter); #endif /* _IGC_BASE_H */