From ec9a40881732c834fe7ffe224981a35043e6a725 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Mon, 10 Jun 2019 18:21:50 +0200 Subject: [PATCH 1/5] r8169: improve setting interrupt mask So far several places in the code deal with setting the interrupt mask for the respective chip versions. Improve this by having one function for this only. In addition don't set RxFIFOOver for all 8101 chip versions like in the vendor driver. Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/r8169_main.c | 28 +++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 8b7d45ff1d03..c62e6845fe9b 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -5136,20 +5136,11 @@ static void rtl_hw_start_8168(struct rtl8169_private *tp) { RTL_W8(tp, MaxTxPacketSize, TxPacketMax); - /* Workaround for RxFIFO overflow. */ - if (tp->mac_version == RTL_GIGA_MAC_VER_11) { - tp->irq_mask |= RxFIFOOver; - tp->irq_mask &= ~RxOverflow; - } - rtl_hw_config(tp); } static void rtl_hw_start_8101(struct rtl8169_private *tp) { - if (tp->mac_version >= RTL_GIGA_MAC_VER_30) - tp->irq_mask &= ~RxFIFOOver; - if (tp->mac_version == RTL_GIGA_MAC_VER_13 || tp->mac_version == RTL_GIGA_MAC_VER_16) pcie_capability_set_word(tp->pci_dev, PCI_EXP_DEVCTL, @@ -6491,29 +6482,38 @@ static const struct net_device_ops rtl_netdev_ops = { static const struct rtl_cfg_info { void (*hw_start)(struct rtl8169_private *tp); - u16 irq_mask; unsigned int has_gmii:1; const struct rtl_coalesce_info *coalesce_info; } rtl_cfg_infos [] = { [RTL_CFG_0] = { .hw_start = rtl_hw_start_8169, - .irq_mask = SYSErr | LinkChg | RxOverflow | RxFIFOOver, .has_gmii = 1, .coalesce_info = rtl_coalesce_info_8169, }, [RTL_CFG_1] = { .hw_start = rtl_hw_start_8168, - .irq_mask = LinkChg | RxOverflow, .has_gmii = 1, .coalesce_info = rtl_coalesce_info_8168_8136, }, [RTL_CFG_2] = { .hw_start = rtl_hw_start_8101, - .irq_mask = LinkChg | RxOverflow | RxFIFOOver, .coalesce_info = rtl_coalesce_info_8168_8136, } }; +static void rtl_set_irq_mask(struct rtl8169_private *tp) +{ + tp->irq_mask = RTL_EVENT_NAPI | LinkChg; + + if (tp->mac_version <= RTL_GIGA_MAC_VER_06) + tp->irq_mask |= SYSErr | RxOverflow | RxFIFOOver; + else if (tp->mac_version == RTL_GIGA_MAC_VER_11) + /* special workaround needed */ + tp->irq_mask |= RxFIFOOver; + else + tp->irq_mask |= RxOverflow; +} + static int rtl_alloc_irq(struct rtl8169_private *tp) { unsigned int flags; @@ -6874,8 +6874,8 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) jumbo_max = rtl_jumbo_max(tp); dev->max_mtu = jumbo_max; + rtl_set_irq_mask(tp); tp->hw_start = cfg->hw_start; - tp->irq_mask = RTL_EVENT_NAPI | cfg->irq_mask; tp->coalesce_info = cfg->coalesce_info; tp->fw_name = rtl_chip_infos[chipset].fw_name; From bc73241e29cc93822513071589b3eb6c5671c567 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Mon, 10 Jun 2019 18:22:33 +0200 Subject: [PATCH 2/5] r8169: rename CPCMD_QUIRK_MASK and apply it on all chip versions CPCMD_QUIRK_MASK isn't specific to certain chip versions. The vendor driver applies this mask to all 8168 versions. Therefore remove QUIRK from the mask name and apply it on all chip versions. Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/r8169_main.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index c62e6845fe9b..9a03b7a09217 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -490,6 +490,7 @@ enum rtl_register_content { PCIDAC = (1 << 4), PCIMulRW = (1 << 3), #define INTT_MASK GENMASK(1, 0) +#define CPCMD_MASK (Normal_mode | RxVlan | RxChkSum | INTT_MASK) /* rtl8169_PHYstatus */ TBI_Enable = 0x80, @@ -573,7 +574,6 @@ enum rtl_rx_desc_bit { }; #define RsvdMask 0x3fffc000 -#define CPCMD_QUIRK_MASK (Normal_mode | RxVlan | RxChkSum | INTT_MASK) struct TxDesc { __le32 opts1; @@ -4210,6 +4210,9 @@ static void rtl_hw_start(struct rtl8169_private *tp) { rtl_unlock_config_regs(tp); + tp->cp_cmd &= CPCMD_MASK; + RTL_W16(tp, CPlusCmd, tp->cp_cmd); + tp->hw_start(tp); rtl_set_rx_max_size(tp); @@ -4377,9 +4380,6 @@ static void rtl_hw_start_8168bb(struct rtl8169_private *tp) { RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); - tp->cp_cmd &= CPCMD_QUIRK_MASK; - RTL_W16(tp, CPlusCmd, tp->cp_cmd); - if (tp->dev->mtu <= ETH_DATA_LEN) { rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B | PCI_EXP_DEVCTL_NOSNOOP_EN); @@ -4405,9 +4405,6 @@ static void __rtl_hw_start_8168cp(struct rtl8169_private *tp) rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); rtl_disable_clock_request(tp); - - tp->cp_cmd &= CPCMD_QUIRK_MASK; - RTL_W16(tp, CPlusCmd, tp->cp_cmd); } static void rtl_hw_start_8168cp_1(struct rtl8169_private *tp) @@ -4435,9 +4432,6 @@ static void rtl_hw_start_8168cp_2(struct rtl8169_private *tp) if (tp->dev->mtu <= ETH_DATA_LEN) rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); - - tp->cp_cmd &= CPCMD_QUIRK_MASK; - RTL_W16(tp, CPlusCmd, tp->cp_cmd); } static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp) @@ -4453,9 +4447,6 @@ static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp) if (tp->dev->mtu <= ETH_DATA_LEN) rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); - - tp->cp_cmd &= CPCMD_QUIRK_MASK; - RTL_W16(tp, CPlusCmd, tp->cp_cmd); } static void rtl_hw_start_8168c_1(struct rtl8169_private *tp) @@ -4511,9 +4502,6 @@ static void rtl_hw_start_8168d(struct rtl8169_private *tp) if (tp->dev->mtu <= ETH_DATA_LEN) rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); - - tp->cp_cmd &= CPCMD_QUIRK_MASK; - RTL_W16(tp, CPlusCmd, tp->cp_cmd); } static void rtl_hw_start_8168dp(struct rtl8169_private *tp) @@ -5148,9 +5136,6 @@ static void rtl_hw_start_8101(struct rtl8169_private *tp) RTL_W8(tp, MaxTxPacketSize, TxPacketMax); - tp->cp_cmd &= CPCMD_QUIRK_MASK; - RTL_W16(tp, CPlusCmd, tp->cp_cmd); - rtl_hw_config(tp); } From 6c19156e29957ae5defbba12fd73b2a11da0854e Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Mon, 10 Jun 2019 18:23:30 +0200 Subject: [PATCH 3/5] r8169: remove callback hw_start from struct rtl_cfg_info After the latest changes we don't need separate functions rtl_hw_start_8168 and rtl_hw_start_8101 any longer. This allows us to simplify the code. For this change we need to move rtl_hw_start() and rtl_hw_start_8169(). rtl_hw_start_8169() is unchanged. Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/r8169_main.c | 117 ++++++++++------------ 1 file changed, 53 insertions(+), 64 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 9a03b7a09217..4a53276da5ed 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -652,8 +652,6 @@ struct rtl8169_private { const struct rtl_coalesce_info *coalesce_info; struct clk *clk; - void (*hw_start)(struct rtl8169_private *tp); - struct { DECLARE_BITMAP(flags, RTL_FLAG_MAX); struct mutex mutex; @@ -4206,56 +4204,6 @@ static void rtl_set_rx_mode(struct net_device *dev) RTL_W32(tp, RxConfig, tmp); } -static void rtl_hw_start(struct rtl8169_private *tp) -{ - rtl_unlock_config_regs(tp); - - tp->cp_cmd &= CPCMD_MASK; - RTL_W16(tp, CPlusCmd, tp->cp_cmd); - - tp->hw_start(tp); - - rtl_set_rx_max_size(tp); - rtl_set_rx_tx_desc_registers(tp); - rtl_lock_config_regs(tp); - - /* disable interrupt coalescing */ - RTL_W16(tp, IntrMitigate, 0x0000); - /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ - RTL_R8(tp, IntrMask); - RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb); - rtl_init_rxcfg(tp); - rtl_set_tx_config_registers(tp); - - rtl_set_rx_mode(tp->dev); - /* no early-rx interrupts */ - RTL_W16(tp, MultiIntr, RTL_R16(tp, MultiIntr) & 0xf000); - rtl_irq_enable(tp); -} - -static void rtl_hw_start_8169(struct rtl8169_private *tp) -{ - if (tp->mac_version == RTL_GIGA_MAC_VER_05) - pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08); - - RTL_W8(tp, EarlyTxThres, NoEarlyTx); - - tp->cp_cmd |= PCIMulRW; - - if (tp->mac_version == RTL_GIGA_MAC_VER_02 || - tp->mac_version == RTL_GIGA_MAC_VER_03) { - netif_dbg(tp, drv, tp->dev, - "Set MAC Reg C+CR Offset 0xe0. Bit 3 and Bit 14 MUST be 1\n"); - tp->cp_cmd |= (1 << 14); - } - - RTL_W16(tp, CPlusCmd, tp->cp_cmd); - - rtl8169_set_magic_reg(tp, tp->mac_version); - - RTL_W32(tp, RxMissed, 0); -} - DECLARE_RTL_COND(rtl_csiar_cond) { return RTL_R32(tp, CSIAR) & CSIAR_FLAG; @@ -5121,13 +5069,6 @@ static void rtl_hw_config(struct rtl8169_private *tp) } static void rtl_hw_start_8168(struct rtl8169_private *tp) -{ - RTL_W8(tp, MaxTxPacketSize, TxPacketMax); - - rtl_hw_config(tp); -} - -static void rtl_hw_start_8101(struct rtl8169_private *tp) { if (tp->mac_version == RTL_GIGA_MAC_VER_13 || tp->mac_version == RTL_GIGA_MAC_VER_16) @@ -5139,6 +5080,59 @@ static void rtl_hw_start_8101(struct rtl8169_private *tp) rtl_hw_config(tp); } +static void rtl_hw_start_8169(struct rtl8169_private *tp) +{ + if (tp->mac_version == RTL_GIGA_MAC_VER_05) + pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08); + + RTL_W8(tp, EarlyTxThres, NoEarlyTx); + + tp->cp_cmd |= PCIMulRW; + + if (tp->mac_version == RTL_GIGA_MAC_VER_02 || + tp->mac_version == RTL_GIGA_MAC_VER_03) { + netif_dbg(tp, drv, tp->dev, + "Set MAC Reg C+CR Offset 0xe0. Bit 3 and Bit 14 MUST be 1\n"); + tp->cp_cmd |= (1 << 14); + } + + RTL_W16(tp, CPlusCmd, tp->cp_cmd); + + rtl8169_set_magic_reg(tp, tp->mac_version); + + RTL_W32(tp, RxMissed, 0); +} + +static void rtl_hw_start(struct rtl8169_private *tp) +{ + rtl_unlock_config_regs(tp); + + tp->cp_cmd &= CPCMD_MASK; + RTL_W16(tp, CPlusCmd, tp->cp_cmd); + + if (tp->mac_version <= RTL_GIGA_MAC_VER_06) + rtl_hw_start_8169(tp); + else + rtl_hw_start_8168(tp); + + rtl_set_rx_max_size(tp); + rtl_set_rx_tx_desc_registers(tp); + rtl_lock_config_regs(tp); + + /* disable interrupt coalescing */ + RTL_W16(tp, IntrMitigate, 0x0000); + /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ + RTL_R8(tp, IntrMask); + RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb); + rtl_init_rxcfg(tp); + rtl_set_tx_config_registers(tp); + + rtl_set_rx_mode(tp->dev); + /* no early-rx interrupts */ + RTL_W16(tp, MultiIntr, RTL_R16(tp, MultiIntr) & 0xf000); + rtl_irq_enable(tp); +} + static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) { struct rtl8169_private *tp = netdev_priv(dev); @@ -6466,22 +6460,18 @@ static const struct net_device_ops rtl_netdev_ops = { }; static const struct rtl_cfg_info { - void (*hw_start)(struct rtl8169_private *tp); unsigned int has_gmii:1; const struct rtl_coalesce_info *coalesce_info; } rtl_cfg_infos [] = { [RTL_CFG_0] = { - .hw_start = rtl_hw_start_8169, .has_gmii = 1, .coalesce_info = rtl_coalesce_info_8169, }, [RTL_CFG_1] = { - .hw_start = rtl_hw_start_8168, .has_gmii = 1, .coalesce_info = rtl_coalesce_info_8168_8136, }, [RTL_CFG_2] = { - .hw_start = rtl_hw_start_8101, .coalesce_info = rtl_coalesce_info_8168_8136, } }; @@ -6860,7 +6850,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->max_mtu = jumbo_max; rtl_set_irq_mask(tp); - tp->hw_start = cfg->hw_start; tp->coalesce_info = cfg->coalesce_info; tp->fw_name = rtl_chip_infos[chipset].fw_name; From 9fa0a8e1e15aa23da625ff2259afdd512aa048ec Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Mon, 10 Jun 2019 18:24:25 +0200 Subject: [PATCH 4/5] r8169: remove member coalesce_info from struct rtl_cfg_info To prepare removal of struct rtl_cfg_info, set the coalesce config based on the chip version number. Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/r8169_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 4a53276da5ed..65ae575ba342 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -6461,18 +6461,14 @@ static const struct net_device_ops rtl_netdev_ops = { static const struct rtl_cfg_info { unsigned int has_gmii:1; - const struct rtl_coalesce_info *coalesce_info; } rtl_cfg_infos [] = { [RTL_CFG_0] = { .has_gmii = 1, - .coalesce_info = rtl_coalesce_info_8169, }, [RTL_CFG_1] = { .has_gmii = 1, - .coalesce_info = rtl_coalesce_info_8168_8136, }, [RTL_CFG_2] = { - .coalesce_info = rtl_coalesce_info_8168_8136, } }; @@ -6850,7 +6846,11 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->max_mtu = jumbo_max; rtl_set_irq_mask(tp); - tp->coalesce_info = cfg->coalesce_info; + + if (tp->mac_version <= RTL_GIGA_MAC_VER_06) + tp->coalesce_info = rtl_coalesce_info_8169; + else + tp->coalesce_info = rtl_coalesce_info_8168_8136; tp->fw_name = rtl_chip_infos[chipset].fw_name; From 145a40e87e0bcab4ed03d9bad793963590e5b70d Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Mon, 10 Jun 2019 18:25:29 +0200 Subject: [PATCH 5/5] r8169: remove struct rtl_cfg_info Simplify the code by removing struct rtl_cfg_info. Only info we need per PCI ID is whether it supports GBit or not. Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/r8169_main.c | 56 ++++++++--------------- 1 file changed, 19 insertions(+), 37 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 65ae575ba342..ca26cd659ed3 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -73,6 +73,8 @@ static const int multicast_filter_limit = 32; #define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) #define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc)) +#define RTL_CFG_NO_GBIT 1 + /* write/read MMIO register */ #define RTL_W8(tp, reg, val8) writeb((val8), tp->mmio_addr + (reg)) #define RTL_W16(tp, reg, val16) writew((val16), tp->mmio_addr + (reg)) @@ -200,32 +202,26 @@ static const struct { [RTL_GIGA_MAC_VER_51] = {"RTL8168ep/8111ep" }, }; -enum cfg_version { - RTL_CFG_0 = 0x00, - RTL_CFG_1, - RTL_CFG_2 -}; - static const struct pci_device_id rtl8169_pci_tbl[] = { - { PCI_VDEVICE(REALTEK, 0x2502), RTL_CFG_1 }, - { PCI_VDEVICE(REALTEK, 0x2600), RTL_CFG_1 }, - { PCI_VDEVICE(REALTEK, 0x8129), RTL_CFG_0 }, - { PCI_VDEVICE(REALTEK, 0x8136), RTL_CFG_2 }, - { PCI_VDEVICE(REALTEK, 0x8161), RTL_CFG_1 }, - { PCI_VDEVICE(REALTEK, 0x8167), RTL_CFG_0 }, - { PCI_VDEVICE(REALTEK, 0x8168), RTL_CFG_1 }, - { PCI_VDEVICE(NCUBE, 0x8168), RTL_CFG_1 }, - { PCI_VDEVICE(REALTEK, 0x8169), RTL_CFG_0 }, + { PCI_VDEVICE(REALTEK, 0x2502) }, + { PCI_VDEVICE(REALTEK, 0x2600) }, + { PCI_VDEVICE(REALTEK, 0x8129) }, + { PCI_VDEVICE(REALTEK, 0x8136), RTL_CFG_NO_GBIT }, + { PCI_VDEVICE(REALTEK, 0x8161) }, + { PCI_VDEVICE(REALTEK, 0x8167) }, + { PCI_VDEVICE(REALTEK, 0x8168) }, + { PCI_VDEVICE(NCUBE, 0x8168) }, + { PCI_VDEVICE(REALTEK, 0x8169) }, { PCI_VENDOR_ID_DLINK, 0x4300, - PCI_VENDOR_ID_DLINK, 0x4b10, 0, 0, RTL_CFG_1 }, - { PCI_VDEVICE(DLINK, 0x4300), RTL_CFG_0 }, - { PCI_VDEVICE(DLINK, 0x4302), RTL_CFG_0 }, - { PCI_VDEVICE(AT, 0xc107), RTL_CFG_0 }, - { PCI_VDEVICE(USR, 0x0116), RTL_CFG_0 }, + PCI_VENDOR_ID_DLINK, 0x4b10, 0, 0 }, + { PCI_VDEVICE(DLINK, 0x4300), }, + { PCI_VDEVICE(DLINK, 0x4302), }, + { PCI_VDEVICE(AT, 0xc107), }, + { PCI_VDEVICE(USR, 0x0116), }, { PCI_VENDOR_ID_LINKSYS, 0x1032, - PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 }, + PCI_ANY_ID, 0x0024, 0, 0 }, { 0x0001, 0x8168, - PCI_ANY_ID, 0x2410, 0, 0, RTL_CFG_2 }, + PCI_ANY_ID, 0x2410, 0, 0, RTL_CFG_NO_GBIT }, {} }; @@ -6459,19 +6455,6 @@ static const struct net_device_ops rtl_netdev_ops = { }; -static const struct rtl_cfg_info { - unsigned int has_gmii:1; -} rtl_cfg_infos [] = { - [RTL_CFG_0] = { - .has_gmii = 1, - }, - [RTL_CFG_1] = { - .has_gmii = 1, - }, - [RTL_CFG_2] = { - } -}; - static void rtl_set_irq_mask(struct rtl8169_private *tp) { tp->irq_mask = RTL_EVENT_NAPI | LinkChg; @@ -6695,7 +6678,6 @@ static int rtl_get_ether_clk(struct rtl8169_private *tp) static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data; /* align to u16 for is_valid_ether_addr() */ u8 mac_addr[ETH_ALEN] __aligned(2) = {}; struct rtl8169_private *tp; @@ -6713,7 +6695,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->dev = dev; tp->pci_dev = pdev; tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT); - tp->supports_gmii = cfg->has_gmii; + tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1; /* Get the *optional* external "ether_clk" used on some boards */ rc = rtl_get_ether_clk(tp);