mirror of
https://github.com/AuxXxilium/r8169.git
synced 2024-11-23 23:10:59 +07:00
r8169: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
This commit is contained in:
parent
670e669178
commit
3ca1a3b749
46
Makefile
46
Makefile
@ -1,20 +1,44 @@
|
|||||||
|
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
################################################################################
|
||||||
#
|
#
|
||||||
# Makefile for the Realtek network device drivers.
|
# r8169 is the Linux device driver released for Realtek Gigabit Ethernet
|
||||||
|
# controllers with PCI-Express interface.
|
||||||
#
|
#
|
||||||
|
# Author:
|
||||||
|
# Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
|
||||||
|
# Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
|
||||||
|
# Copyright (c) a lot of people too. Please respect their work.
|
||||||
|
#
|
||||||
|
################################################################################
|
||||||
|
|
||||||
CONFIG_R8169 = m
|
################################################################################
|
||||||
|
# This product is covered by one or more of the following patents:
|
||||||
|
# US6,570,884, US6,115,776, and US6,327,625.
|
||||||
|
################################################################################
|
||||||
|
|
||||||
ENABLE_INCLUDE_R8168 = n
|
# Set the kernel build directory
|
||||||
ENABLE_INCLUDE_R8125 = n
|
KDIR ?= "/lib/modules/$(shell uname -r)/build"
|
||||||
|
# Directory for module updates
|
||||||
|
MUPDATE ?= "/lib/modules/$(shell uname -r)/updates"
|
||||||
|
# Hash for signing
|
||||||
|
HASH = sha3-512
|
||||||
|
obj-m := r8169.o
|
||||||
|
r8169-objs := r8169_main.o r8169_firmware.o r8169_phy_config.o r8169_leds.o
|
||||||
|
|
||||||
ifeq ($(ENABLE_INCLUDE_R8168), y)
|
all:
|
||||||
EXTRA_CFLAGS += -DINCLUDE_R8168
|
$(MAKE) -C $(KDIR) M=$(PWD) modules
|
||||||
|
|
||||||
|
modules_install:
|
||||||
|
$(MAKE) -C $(KDIR) M=$(PWD) modules_install
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(MAKE) -C $(KDIR) M=$(PWD) clean
|
||||||
|
ifdef $(MUPDATE)
|
||||||
|
$(MAKE) -c $(KDIR) M=$(MUPDATE) clean
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(ENABLE_INCLUDE_R8125), y)
|
sign:
|
||||||
EXTRA_CFLAGS += -DINCLUDE_R8125
|
/usr/src/linux/scripts/sign-file $(HASH) /usr/src/linux/certs/signing_key.pem /usr/src/linux/certs/signing_key.x509 r8169.ko
|
||||||
endif
|
|
||||||
|
|
||||||
r8169-objs += r8169_main.o r8169_firmware.o r8169_phy_config.o
|
.PHONY: all modules_install clean sign
|
||||||
obj-$(CONFIG_R8169) += r8169.o
|
|
||||||
|
13
r8169.h
13
r8169.h
@ -8,6 +8,7 @@
|
|||||||
* See MAINTAINERS file for support contact information.
|
* See MAINTAINERS file for support contact information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/netdevice.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/phy.h>
|
#include <linux/phy.h>
|
||||||
|
|
||||||
@ -71,9 +72,21 @@ enum mac_version {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct rtl8169_private;
|
struct rtl8169_private;
|
||||||
|
struct r8169_led_classdev;
|
||||||
|
|
||||||
void r8169_apply_firmware(struct rtl8169_private *tp);
|
void r8169_apply_firmware(struct rtl8169_private *tp);
|
||||||
u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp);
|
u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp);
|
||||||
u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr);
|
u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr);
|
||||||
void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
|
void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
|
||||||
enum mac_version ver);
|
enum mac_version ver);
|
||||||
|
|
||||||
|
void r8169_get_led_name(struct rtl8169_private *tp, int idx,
|
||||||
|
char *buf, int buf_len);
|
||||||
|
int rtl8168_get_led_mode(struct rtl8169_private *tp);
|
||||||
|
int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
|
||||||
|
struct r8169_led_classdev *rtl8168_init_leds(struct net_device *ndev);
|
||||||
|
void r8169_remove_leds(struct r8169_led_classdev *leds);
|
||||||
|
|
||||||
|
int r8169_get_wolparam(void);
|
||||||
|
|
||||||
|
void r8169_set_wolparam(int state);
|
||||||
|
@ -151,9 +151,6 @@ void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
|
|||||||
u32 regno = (action & 0x0fff0000) >> 16;
|
u32 regno = (action & 0x0fff0000) >> 16;
|
||||||
enum rtl_fw_opcode opcode = action >> 28;
|
enum rtl_fw_opcode opcode = action >> 28;
|
||||||
|
|
||||||
if (!action)
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case PHY_READ:
|
case PHY_READ:
|
||||||
predata = fw_read(tp, regno);
|
predata = fw_read(tp, regno);
|
||||||
|
168
r8169_leds.c
Normal file
168
r8169_leds.c
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/* r8169_leds.c: Realtek 8169/8168/8101/8125 ethernet driver.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Heiner Kallweit <hkallweit1@gmail.com>
|
||||||
|
*
|
||||||
|
* See MAINTAINERS file for support contact information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/leds.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <uapi/linux/uleds.h>
|
||||||
|
|
||||||
|
#include "r8169.h"
|
||||||
|
|
||||||
|
#define RTL8168_LED_CTRL_OPTION2 BIT(15)
|
||||||
|
#define RTL8168_LED_CTRL_ACT BIT(3)
|
||||||
|
#define RTL8168_LED_CTRL_LINK_1000 BIT(2)
|
||||||
|
#define RTL8168_LED_CTRL_LINK_100 BIT(1)
|
||||||
|
#define RTL8168_LED_CTRL_LINK_10 BIT(0)
|
||||||
|
|
||||||
|
#define RTL8168_NUM_LEDS 3
|
||||||
|
|
||||||
|
#define RTL8168_SUPPORTED_MODES \
|
||||||
|
(BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK_100) | \
|
||||||
|
BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_RX) | \
|
||||||
|
BIT(TRIGGER_NETDEV_TX))
|
||||||
|
|
||||||
|
struct r8169_led_classdev {
|
||||||
|
struct led_classdev led;
|
||||||
|
struct net_device *ndev;
|
||||||
|
int index;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define lcdev_to_r8169_ldev(lcdev) container_of(lcdev, struct r8169_led_classdev, led)
|
||||||
|
|
||||||
|
static int rtl8168_led_hw_control_is_supported(struct led_classdev *led_cdev,
|
||||||
|
unsigned long flags)
|
||||||
|
{
|
||||||
|
struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
|
||||||
|
struct rtl8169_private *tp = netdev_priv(ldev->ndev);
|
||||||
|
int shift = ldev->index * 4;
|
||||||
|
bool rx, tx;
|
||||||
|
|
||||||
|
if (flags & ~RTL8168_SUPPORTED_MODES)
|
||||||
|
goto nosupp;
|
||||||
|
|
||||||
|
rx = flags & BIT(TRIGGER_NETDEV_RX);
|
||||||
|
tx = flags & BIT(TRIGGER_NETDEV_TX);
|
||||||
|
if (rx != tx)
|
||||||
|
goto nosupp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
nosupp:
|
||||||
|
/* Switch LED off to indicate that mode isn't supported */
|
||||||
|
rtl8168_led_mod_ctrl(tp, 0x000f << shift, 0);
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8168_led_hw_control_set(struct led_classdev *led_cdev,
|
||||||
|
unsigned long flags)
|
||||||
|
{
|
||||||
|
struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
|
||||||
|
struct rtl8169_private *tp = netdev_priv(ldev->ndev);
|
||||||
|
int shift = ldev->index * 4;
|
||||||
|
u16 mode = 0;
|
||||||
|
|
||||||
|
if (flags & BIT(TRIGGER_NETDEV_LINK_10))
|
||||||
|
mode |= RTL8168_LED_CTRL_LINK_10;
|
||||||
|
if (flags & BIT(TRIGGER_NETDEV_LINK_100))
|
||||||
|
mode |= RTL8168_LED_CTRL_LINK_100;
|
||||||
|
if (flags & BIT(TRIGGER_NETDEV_LINK_1000))
|
||||||
|
mode |= RTL8168_LED_CTRL_LINK_1000;
|
||||||
|
if (flags & BIT(TRIGGER_NETDEV_TX))
|
||||||
|
mode |= RTL8168_LED_CTRL_ACT;
|
||||||
|
|
||||||
|
return rtl8168_led_mod_ctrl(tp, 0x000f << shift, mode << shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8168_led_hw_control_get(struct led_classdev *led_cdev,
|
||||||
|
unsigned long *flags)
|
||||||
|
{
|
||||||
|
struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
|
||||||
|
struct rtl8169_private *tp = netdev_priv(ldev->ndev);
|
||||||
|
int shift = ldev->index * 4;
|
||||||
|
int mode;
|
||||||
|
|
||||||
|
mode = rtl8168_get_led_mode(tp);
|
||||||
|
if (mode < 0)
|
||||||
|
return mode;
|
||||||
|
|
||||||
|
if (mode & RTL8168_LED_CTRL_OPTION2) {
|
||||||
|
rtl8168_led_mod_ctrl(tp, RTL8168_LED_CTRL_OPTION2, 0);
|
||||||
|
netdev_notice(ldev->ndev, "Deactivating unsupported Option2 LED mode\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = (mode >> shift) & 0x000f;
|
||||||
|
|
||||||
|
if (mode & RTL8168_LED_CTRL_ACT)
|
||||||
|
*flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX);
|
||||||
|
|
||||||
|
if (mode & RTL8168_LED_CTRL_LINK_10)
|
||||||
|
*flags |= BIT(TRIGGER_NETDEV_LINK_10);
|
||||||
|
if (mode & RTL8168_LED_CTRL_LINK_100)
|
||||||
|
*flags |= BIT(TRIGGER_NETDEV_LINK_100);
|
||||||
|
if (mode & RTL8168_LED_CTRL_LINK_1000)
|
||||||
|
*flags |= BIT(TRIGGER_NETDEV_LINK_1000);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct device *
|
||||||
|
r8169_led_hw_control_get_device(struct led_classdev *led_cdev)
|
||||||
|
{
|
||||||
|
struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
|
||||||
|
|
||||||
|
return &ldev->ndev->dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl8168_setup_ldev(struct r8169_led_classdev *ldev,
|
||||||
|
struct net_device *ndev, int index)
|
||||||
|
{
|
||||||
|
struct rtl8169_private *tp = netdev_priv(ndev);
|
||||||
|
struct led_classdev *led_cdev = &ldev->led;
|
||||||
|
char led_name[LED_MAX_NAME_SIZE];
|
||||||
|
|
||||||
|
ldev->ndev = ndev;
|
||||||
|
ldev->index = index;
|
||||||
|
|
||||||
|
r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE);
|
||||||
|
led_cdev->name = led_name;
|
||||||
|
led_cdev->default_trigger = "netdev";
|
||||||
|
led_cdev->hw_control_trigger = "netdev";
|
||||||
|
led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN;
|
||||||
|
led_cdev->hw_control_is_supported = rtl8168_led_hw_control_is_supported;
|
||||||
|
led_cdev->hw_control_set = rtl8168_led_hw_control_set;
|
||||||
|
led_cdev->hw_control_get = rtl8168_led_hw_control_get;
|
||||||
|
led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
|
||||||
|
|
||||||
|
/* ignore errors */
|
||||||
|
led_classdev_register(&ndev->dev, led_cdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct r8169_led_classdev *rtl8168_init_leds(struct net_device *ndev)
|
||||||
|
{
|
||||||
|
struct r8169_led_classdev *leds;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
leds = kcalloc(RTL8168_NUM_LEDS + 1, sizeof(*leds), GFP_KERNEL);
|
||||||
|
if (!leds)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < RTL8168_NUM_LEDS; i++)
|
||||||
|
rtl8168_setup_ldev(leds + i, ndev, i);
|
||||||
|
|
||||||
|
return leds;
|
||||||
|
}
|
||||||
|
|
||||||
|
void r8169_remove_leds(struct r8169_led_classdev *leds)
|
||||||
|
{
|
||||||
|
if (!leds)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (struct r8169_led_classdev *l = leds; l->ndev; l++)
|
||||||
|
led_classdev_unregister(&l->led);
|
||||||
|
|
||||||
|
kfree(leds);
|
||||||
|
}
|
413
r8169_main.c
413
r8169_main.c
@ -56,10 +56,6 @@
|
|||||||
#define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw"
|
#define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw"
|
||||||
#define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw"
|
#define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw"
|
||||||
|
|
||||||
/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
|
|
||||||
The RTL chips use a 64 element hash table based on the Ethernet CRC. */
|
|
||||||
#define MC_FILTER_LIMIT 32
|
|
||||||
|
|
||||||
#define TX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */
|
#define TX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */
|
||||||
#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */
|
#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */
|
||||||
|
|
||||||
@ -89,6 +85,10 @@
|
|||||||
#define JUMBO_7K (7 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN)
|
#define JUMBO_7K (7 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN)
|
||||||
#define JUMBO_9K (9 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN)
|
#define JUMBO_9K (9 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN)
|
||||||
|
|
||||||
|
static int wol_param = 1;
|
||||||
|
module_param(wol_param, int, 0);
|
||||||
|
MODULE_PARM_DESC(wol_param, "Current state of system WOL");
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *fw_name;
|
const char *fw_name;
|
||||||
@ -142,56 +142,27 @@ static const struct {
|
|||||||
[RTL_GIGA_MAC_VER_63] = {"RTL8125B", FIRMWARE_8125B_2},
|
[RTL_GIGA_MAC_VER_63] = {"RTL8125B", FIRMWARE_8125B_2},
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
author: Realtek and the Linux r8168 crew <netdev@vger.kernel.org>
|
|
||||||
srcversion: D2B16DB8E92DC6B16FB1E04
|
|
||||||
alias: pci:v00001186d00004300sv00001186sd00004B10bc*sc*i*
|
|
||||||
alias: pci:v000010ECd00002600sv*sd*bc*sc*i*
|
|
||||||
alias: pci:v000010ECd00002502sv*sd*bc*sc*i*
|
|
||||||
alias: pci:v000010ECd00008161sv*sd*bc*sc*i*
|
|
||||||
alias: pci:v000010ECd00008168sv*sd*bc*sc*i*
|
|
||||||
|
|
||||||
author: Realtek and the Linux r8125 crew <netdev@vger.kernel.org>
|
|
||||||
srcversion: 80AA932EEAEA9E2392B4B5E
|
|
||||||
alias: pci:v000010ECd00005000sv*sd*bc*sc*i*
|
|
||||||
alias: pci:v000010ECd00008126sv*sd*bc*sc*i*
|
|
||||||
alias: pci:v000010ECd00003000sv*sd*bc*sc*i*
|
|
||||||
alias: pci:v000010ECd00008162sv*sd*bc*sc*i*
|
|
||||||
alias: pci:v000010ECd00008125sv*sd*bc*sc*i*
|
|
||||||
*/
|
|
||||||
static const struct pci_device_id rtl8169_pci_tbl[] = {
|
static const struct pci_device_id rtl8169_pci_tbl[] = {
|
||||||
#ifdef INCLUDE_R8168
|
|
||||||
{ PCI_VDEVICE(REALTEK, 0x2502) },
|
{ PCI_VDEVICE(REALTEK, 0x2502) },
|
||||||
{ PCI_VDEVICE(REALTEK, 0x2600) },
|
{ PCI_VDEVICE(REALTEK, 0x2600) },
|
||||||
#endif
|
|
||||||
{ PCI_VDEVICE(REALTEK, 0x8129) },
|
{ PCI_VDEVICE(REALTEK, 0x8129) },
|
||||||
{ PCI_VDEVICE(REALTEK, 0x8136), RTL_CFG_NO_GBIT },
|
{ PCI_VDEVICE(REALTEK, 0x8136), RTL_CFG_NO_GBIT },
|
||||||
#ifdef INCLUDE_R8168
|
|
||||||
{ PCI_VDEVICE(REALTEK, 0x8161) },
|
{ PCI_VDEVICE(REALTEK, 0x8161) },
|
||||||
#endif
|
|
||||||
#ifdef INCLUDE_R8125
|
|
||||||
{ PCI_VDEVICE(REALTEK, 0x8162) },
|
{ PCI_VDEVICE(REALTEK, 0x8162) },
|
||||||
#endif
|
|
||||||
{ PCI_VDEVICE(REALTEK, 0x8167) },
|
{ PCI_VDEVICE(REALTEK, 0x8167) },
|
||||||
#ifdef INCLUDE_R8168
|
|
||||||
{ PCI_VDEVICE(REALTEK, 0x8168) },
|
{ PCI_VDEVICE(REALTEK, 0x8168) },
|
||||||
#endif
|
|
||||||
{ PCI_VDEVICE(NCUBE, 0x8168) },
|
{ PCI_VDEVICE(NCUBE, 0x8168) },
|
||||||
{ PCI_VDEVICE(REALTEK, 0x8169) },
|
{ PCI_VDEVICE(REALTEK, 0x8169) },
|
||||||
#ifdef INCLUDE_R8168
|
|
||||||
{ PCI_VENDOR_ID_DLINK, 0x4300,
|
{ PCI_VENDOR_ID_DLINK, 0x4300,
|
||||||
PCI_VENDOR_ID_DLINK, 0x4b10, 0, 0 },
|
PCI_VENDOR_ID_DLINK, 0x4b10, 0, 0 },
|
||||||
#endif
|
|
||||||
{ PCI_VDEVICE(DLINK, 0x4300) },
|
{ PCI_VDEVICE(DLINK, 0x4300) },
|
||||||
{ PCI_VDEVICE(DLINK, 0x4302) },
|
{ PCI_VDEVICE(DLINK, 0x4302) },
|
||||||
{ PCI_VDEVICE(AT, 0xc107) },
|
{ PCI_VDEVICE(AT, 0xc107) },
|
||||||
{ PCI_VDEVICE(USR, 0x0116) },
|
{ PCI_VDEVICE(USR, 0x0116) },
|
||||||
{ PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024 },
|
{ PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024 },
|
||||||
{ 0x0001, 0x8168, PCI_ANY_ID, 0x2410 },
|
{ 0x0001, 0x8168, PCI_ANY_ID, 0x2410 },
|
||||||
#ifdef INCLUDE_R8125
|
|
||||||
{ PCI_VDEVICE(REALTEK, 0x8125) },
|
{ PCI_VDEVICE(REALTEK, 0x8125) },
|
||||||
{ PCI_VDEVICE(REALTEK, 0x3000) },
|
{ PCI_VDEVICE(REALTEK, 0x3000) },
|
||||||
#endif
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -225,6 +196,7 @@ enum rtl_registers {
|
|||||||
/* No threshold before first PCI xfer */
|
/* No threshold before first PCI xfer */
|
||||||
#define RX_FIFO_THRESH (7 << RXCFG_FIFO_SHIFT)
|
#define RX_FIFO_THRESH (7 << RXCFG_FIFO_SHIFT)
|
||||||
#define RX_EARLY_OFF (1 << 11)
|
#define RX_EARLY_OFF (1 << 11)
|
||||||
|
#define RX_PAUSE_SLOT_ON (1 << 11) /* 8125b and later */
|
||||||
#define RXCFG_DMA_SHIFT 8
|
#define RXCFG_DMA_SHIFT 8
|
||||||
/* Unlimited maximum PCI burst. */
|
/* Unlimited maximum PCI burst. */
|
||||||
#define RX_DMA_BURST (7 << RXCFG_DMA_SHIFT)
|
#define RX_DMA_BURST (7 << RXCFG_DMA_SHIFT)
|
||||||
@ -317,6 +289,7 @@ enum rtl8168_8101_registers {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum rtl8168_registers {
|
enum rtl8168_registers {
|
||||||
|
LED_CTRL = 0x18,
|
||||||
LED_FREQ = 0x1a,
|
LED_FREQ = 0x1a,
|
||||||
EEE_LED = 0x1b,
|
EEE_LED = 0x1b,
|
||||||
ERIDR = 0x70,
|
ERIDR = 0x70,
|
||||||
@ -608,6 +581,7 @@ struct rtl8169_tc_offsets {
|
|||||||
enum rtl_flag {
|
enum rtl_flag {
|
||||||
RTL_FLAG_TASK_ENABLED = 0,
|
RTL_FLAG_TASK_ENABLED = 0,
|
||||||
RTL_FLAG_TASK_RESET_PENDING,
|
RTL_FLAG_TASK_RESET_PENDING,
|
||||||
|
RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE,
|
||||||
RTL_FLAG_TASK_TX_TIMEOUT,
|
RTL_FLAG_TASK_TX_TIMEOUT,
|
||||||
RTL_FLAG_MAX
|
RTL_FLAG_MAX
|
||||||
};
|
};
|
||||||
@ -647,12 +621,14 @@ struct rtl8169_private {
|
|||||||
|
|
||||||
raw_spinlock_t config25_lock;
|
raw_spinlock_t config25_lock;
|
||||||
raw_spinlock_t mac_ocp_lock;
|
raw_spinlock_t mac_ocp_lock;
|
||||||
|
struct mutex led_lock; /* serialize LED ctrl RMW access */
|
||||||
|
|
||||||
raw_spinlock_t cfg9346_usage_lock;
|
raw_spinlock_t cfg9346_usage_lock;
|
||||||
int cfg9346_usage_count;
|
int cfg9346_usage_count;
|
||||||
|
|
||||||
unsigned supports_gmii:1;
|
unsigned supports_gmii:1;
|
||||||
unsigned aspm_manageable:1;
|
unsigned aspm_manageable:1;
|
||||||
|
unsigned dash_enabled:1;
|
||||||
dma_addr_t counters_phys_addr;
|
dma_addr_t counters_phys_addr;
|
||||||
struct rtl8169_counters *counters;
|
struct rtl8169_counters *counters;
|
||||||
struct rtl8169_tc_offsets tc_offset;
|
struct rtl8169_tc_offsets tc_offset;
|
||||||
@ -662,6 +638,8 @@ struct rtl8169_private {
|
|||||||
const char *fw_name;
|
const char *fw_name;
|
||||||
struct rtl_fw *rtl_fw;
|
struct rtl_fw *rtl_fw;
|
||||||
|
|
||||||
|
struct r8169_led_classdev *leds;
|
||||||
|
|
||||||
u32 ocp_base;
|
u32 ocp_base;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -818,6 +796,62 @@ static const struct rtl_cond name = { \
|
|||||||
\
|
\
|
||||||
static bool name ## _check(struct rtl8169_private *tp)
|
static bool name ## _check(struct rtl8169_private *tp)
|
||||||
|
|
||||||
|
int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val)
|
||||||
|
{
|
||||||
|
struct device *dev = tp_to_dev(tp);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = pm_runtime_resume_and_get(dev);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
mutex_lock(&tp->led_lock);
|
||||||
|
RTL_W16(tp, LED_CTRL, (RTL_R16(tp, LED_CTRL) & ~mask) | val);
|
||||||
|
mutex_unlock(&tp->led_lock);
|
||||||
|
|
||||||
|
pm_runtime_put_sync(dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtl8168_get_led_mode(struct rtl8169_private *tp)
|
||||||
|
{
|
||||||
|
struct device *dev = tp_to_dev(tp);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = pm_runtime_resume_and_get(dev);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = RTL_R16(tp, LED_CTRL);
|
||||||
|
|
||||||
|
pm_runtime_put_sync(dev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void r8169_get_led_name(struct rtl8169_private *tp, int idx,
|
||||||
|
char *buf, int buf_len)
|
||||||
|
{
|
||||||
|
struct pci_dev *pdev = tp->pci_dev;
|
||||||
|
char pdom[8], pfun[8];
|
||||||
|
int domain;
|
||||||
|
|
||||||
|
domain = pci_domain_nr(pdev->bus);
|
||||||
|
if (domain)
|
||||||
|
snprintf(pdom, sizeof(pdom), "P%d", domain);
|
||||||
|
else
|
||||||
|
pdom[0] = '\0';
|
||||||
|
|
||||||
|
if (pdev->multifunction)
|
||||||
|
snprintf(pfun, sizeof(pfun), "f%d", PCI_FUNC(pdev->devfn));
|
||||||
|
else
|
||||||
|
pfun[0] = '\0';
|
||||||
|
|
||||||
|
snprintf(buf, buf_len, "en%sp%ds%d%s-%d::lan", pdom, pdev->bus->number,
|
||||||
|
PCI_SLOT(pdev->devfn), pfun, idx);
|
||||||
|
}
|
||||||
|
|
||||||
static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type)
|
static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type)
|
||||||
{
|
{
|
||||||
/* based on RTL8168FP_OOBMAC_BASE in vendor driver */
|
/* based on RTL8168FP_OOBMAC_BASE in vendor driver */
|
||||||
@ -1227,17 +1261,40 @@ static void rtl8168ep_stop_cmac(struct rtl8169_private *tp)
|
|||||||
RTL_W8(tp, IBCR0, RTL_R8(tp, IBCR0) & ~0x01);
|
RTL_W8(tp, IBCR0, RTL_R8(tp, IBCR0) & ~0x01);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rtl_dash_loop_wait(struct rtl8169_private *tp,
|
||||||
|
const struct rtl_cond *c,
|
||||||
|
unsigned long usecs, int n, bool high)
|
||||||
|
{
|
||||||
|
if (!tp->dash_enabled)
|
||||||
|
return;
|
||||||
|
rtl_loop_wait(tp, c, usecs, n, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl_dash_loop_wait_high(struct rtl8169_private *tp,
|
||||||
|
const struct rtl_cond *c,
|
||||||
|
unsigned long d, int n)
|
||||||
|
{
|
||||||
|
rtl_dash_loop_wait(tp, c, d, n, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl_dash_loop_wait_low(struct rtl8169_private *tp,
|
||||||
|
const struct rtl_cond *c,
|
||||||
|
unsigned long d, int n)
|
||||||
|
{
|
||||||
|
rtl_dash_loop_wait(tp, c, d, n, false);
|
||||||
|
}
|
||||||
|
|
||||||
static void rtl8168dp_driver_start(struct rtl8169_private *tp)
|
static void rtl8168dp_driver_start(struct rtl8169_private *tp)
|
||||||
{
|
{
|
||||||
r8168dp_oob_notify(tp, OOB_CMD_DRIVER_START);
|
r8168dp_oob_notify(tp, OOB_CMD_DRIVER_START);
|
||||||
rtl_loop_wait_high(tp, &rtl_dp_ocp_read_cond, 10000, 10);
|
rtl_dash_loop_wait_high(tp, &rtl_dp_ocp_read_cond, 10000, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtl8168ep_driver_start(struct rtl8169_private *tp)
|
static void rtl8168ep_driver_start(struct rtl8169_private *tp)
|
||||||
{
|
{
|
||||||
r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_START);
|
r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_START);
|
||||||
r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01);
|
r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01);
|
||||||
rtl_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 10);
|
rtl_dash_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtl8168_driver_start(struct rtl8169_private *tp)
|
static void rtl8168_driver_start(struct rtl8169_private *tp)
|
||||||
@ -1251,7 +1308,7 @@ static void rtl8168_driver_start(struct rtl8169_private *tp)
|
|||||||
static void rtl8168dp_driver_stop(struct rtl8169_private *tp)
|
static void rtl8168dp_driver_stop(struct rtl8169_private *tp)
|
||||||
{
|
{
|
||||||
r8168dp_oob_notify(tp, OOB_CMD_DRIVER_STOP);
|
r8168dp_oob_notify(tp, OOB_CMD_DRIVER_STOP);
|
||||||
rtl_loop_wait_low(tp, &rtl_dp_ocp_read_cond, 10000, 10);
|
rtl_dash_loop_wait_low(tp, &rtl_dp_ocp_read_cond, 10000, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtl8168ep_driver_stop(struct rtl8169_private *tp)
|
static void rtl8168ep_driver_stop(struct rtl8169_private *tp)
|
||||||
@ -1259,7 +1316,7 @@ static void rtl8168ep_driver_stop(struct rtl8169_private *tp)
|
|||||||
rtl8168ep_stop_cmac(tp);
|
rtl8168ep_stop_cmac(tp);
|
||||||
r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_STOP);
|
r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_STOP);
|
||||||
r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01);
|
r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01);
|
||||||
rtl_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10);
|
rtl_dash_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtl8168_driver_stop(struct rtl8169_private *tp)
|
static void rtl8168_driver_stop(struct rtl8169_private *tp)
|
||||||
@ -1282,14 +1339,26 @@ static bool r8168ep_check_dash(struct rtl8169_private *tp)
|
|||||||
return r8168ep_ocp_read(tp, 0x128) & BIT(0);
|
return r8168ep_ocp_read(tp, 0x128) & BIT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum rtl_dash_type rtl_check_dash(struct rtl8169_private *tp)
|
static bool rtl_dash_is_enabled(struct rtl8169_private *tp)
|
||||||
|
{
|
||||||
|
switch (tp->dash_type) {
|
||||||
|
case RTL_DASH_DP:
|
||||||
|
return r8168dp_check_dash(tp);
|
||||||
|
case RTL_DASH_EP:
|
||||||
|
return r8168ep_check_dash(tp);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum rtl_dash_type rtl_get_dash_type(struct rtl8169_private *tp)
|
||||||
{
|
{
|
||||||
switch (tp->mac_version) {
|
switch (tp->mac_version) {
|
||||||
case RTL_GIGA_MAC_VER_28:
|
case RTL_GIGA_MAC_VER_28:
|
||||||
case RTL_GIGA_MAC_VER_31:
|
case RTL_GIGA_MAC_VER_31:
|
||||||
return r8168dp_check_dash(tp) ? RTL_DASH_DP : RTL_DASH_NONE;
|
return RTL_DASH_DP;
|
||||||
case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53:
|
case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53:
|
||||||
return r8168ep_check_dash(tp) ? RTL_DASH_EP : RTL_DASH_NONE;
|
return RTL_DASH_EP;
|
||||||
default:
|
default:
|
||||||
return RTL_DASH_NONE;
|
return RTL_DASH_NONE;
|
||||||
}
|
}
|
||||||
@ -1408,6 +1477,14 @@ static void rtl_link_chg_patch(struct rtl8169_private *tp)
|
|||||||
|
|
||||||
#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
|
#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
|
||||||
|
|
||||||
|
int r8169_get_wolparam(void) {
|
||||||
|
return wol_param;
|
||||||
|
}
|
||||||
|
|
||||||
|
void r8169_set_wolparam(int state) {
|
||||||
|
wol_param = state;
|
||||||
|
}
|
||||||
|
|
||||||
static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
||||||
{
|
{
|
||||||
struct rtl8169_private *tp = netdev_priv(dev);
|
struct rtl8169_private *tp = netdev_priv(dev);
|
||||||
@ -1482,7 +1559,7 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
|
|||||||
|
|
||||||
device_set_wakeup_enable(tp_to_dev(tp), wolopts);
|
device_set_wakeup_enable(tp_to_dev(tp), wolopts);
|
||||||
|
|
||||||
if (tp->dash_type == RTL_DASH_NONE) {
|
if (!tp->dash_enabled) {
|
||||||
rtl_set_d3_pll_down(tp, !wolopts);
|
rtl_set_d3_pll_down(tp, !wolopts);
|
||||||
tp->dev->wol_enabled = wolopts ? 1 : 0;
|
tp->dev->wol_enabled = wolopts ? 1 : 0;
|
||||||
}
|
}
|
||||||
@ -2247,6 +2324,9 @@ u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp)
|
|||||||
|
|
||||||
static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag)
|
static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag)
|
||||||
{
|
{
|
||||||
|
if (!test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
|
||||||
|
return;
|
||||||
|
|
||||||
set_bit(flag, tp->wk.flags);
|
set_bit(flag, tp->wk.flags);
|
||||||
schedule_work(&tp->wk.work);
|
schedule_work(&tp->wk.work);
|
||||||
}
|
}
|
||||||
@ -2321,9 +2401,13 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
|
|||||||
case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_53:
|
case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_53:
|
||||||
RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
|
RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
|
||||||
break;
|
break;
|
||||||
case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
|
case RTL_GIGA_MAC_VER_61:
|
||||||
RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
|
RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
|
||||||
break;
|
break;
|
||||||
|
case RTL_GIGA_MAC_VER_63:
|
||||||
|
RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST |
|
||||||
|
RX_PAUSE_SLOT_ON);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
RTL_W32(tp, RxConfig, RX128_INT_EN | RX_DMA_BURST);
|
RTL_W32(tp, RxConfig, RX128_INT_EN | RX_DMA_BURST);
|
||||||
break;
|
break;
|
||||||
@ -2541,7 +2625,7 @@ static void rtl_wol_enable_rx(struct rtl8169_private *tp)
|
|||||||
|
|
||||||
static void rtl_prepare_power_down(struct rtl8169_private *tp)
|
static void rtl_prepare_power_down(struct rtl8169_private *tp)
|
||||||
{
|
{
|
||||||
if (tp->dash_type != RTL_DASH_NONE)
|
if (tp->dash_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
|
if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
|
||||||
@ -2611,8 +2695,9 @@ static void rtl_set_rx_mode(struct net_device *dev)
|
|||||||
|
|
||||||
if (dev->flags & IFF_PROMISC) {
|
if (dev->flags & IFF_PROMISC) {
|
||||||
rx_mode |= AcceptAllPhys;
|
rx_mode |= AcceptAllPhys;
|
||||||
} else if (netdev_mc_count(dev) > MC_FILTER_LIMIT ||
|
} else if (!(dev->flags & IFF_MULTICAST)) {
|
||||||
dev->flags & IFF_ALLMULTI ||
|
rx_mode &= ~AcceptMulticast;
|
||||||
|
} else if (dev->flags & IFF_ALLMULTI ||
|
||||||
tp->mac_version == RTL_GIGA_MAC_VER_35) {
|
tp->mac_version == RTL_GIGA_MAC_VER_35) {
|
||||||
/* accept all multicasts */
|
/* accept all multicasts */
|
||||||
} else if (netdev_mc_empty(dev)) {
|
} else if (netdev_mc_empty(dev)) {
|
||||||
@ -3114,6 +3199,33 @@ static void rtl_hw_start_8168g_2(struct rtl8169_private *tp)
|
|||||||
rtl_ephy_init(tp, e_info_8168g_2);
|
rtl_ephy_init(tp, e_info_8168g_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rtl8411b_fix_phy_down(struct rtl8169_private *tp)
|
||||||
|
{
|
||||||
|
static const u16 fix_data[] = {
|
||||||
|
/* 0xf800 */ 0xe008, 0xe00a, 0xe00c, 0xe00e, 0xe027, 0xe04f, 0xe05e, 0xe065,
|
||||||
|
/* 0xf810 */ 0xc602, 0xbe00, 0x0000, 0xc502, 0xbd00, 0x074c, 0xc302, 0xbb00,
|
||||||
|
/* 0xf820 */ 0x080a, 0x6420, 0x48c2, 0x8c20, 0xc516, 0x64a4, 0x49c0, 0xf009,
|
||||||
|
/* 0xf830 */ 0x74a2, 0x8ca5, 0x74a0, 0xc50e, 0x9ca2, 0x1c11, 0x9ca0, 0xe006,
|
||||||
|
/* 0xf840 */ 0x74f8, 0x48c4, 0x8cf8, 0xc404, 0xbc00, 0xc403, 0xbc00, 0x0bf2,
|
||||||
|
/* 0xf850 */ 0x0c0a, 0xe434, 0xd3c0, 0x49d9, 0xf01f, 0xc526, 0x64a5, 0x1400,
|
||||||
|
/* 0xf860 */ 0xf007, 0x0c01, 0x8ca5, 0x1c15, 0xc51b, 0x9ca0, 0xe013, 0xc519,
|
||||||
|
/* 0xf870 */ 0x74a0, 0x48c4, 0x8ca0, 0xc516, 0x74a4, 0x48c8, 0x48ca, 0x9ca4,
|
||||||
|
/* 0xf880 */ 0xc512, 0x1b00, 0x9ba0, 0x1b1c, 0x483f, 0x9ba2, 0x1b04, 0xc508,
|
||||||
|
/* 0xf890 */ 0x9ba0, 0xc505, 0xbd00, 0xc502, 0xbd00, 0x0300, 0x051e, 0xe434,
|
||||||
|
/* 0xf8a0 */ 0xe018, 0xe092, 0xde20, 0xd3c0, 0xc50f, 0x76a4, 0x49e3, 0xf007,
|
||||||
|
/* 0xf8b0 */ 0x49c0, 0xf103, 0xc607, 0xbe00, 0xc606, 0xbe00, 0xc602, 0xbe00,
|
||||||
|
/* 0xf8c0 */ 0x0c4c, 0x0c28, 0x0c2c, 0xdc00, 0xc707, 0x1d00, 0x8de2, 0x48c1,
|
||||||
|
/* 0xf8d0 */ 0xc502, 0xbd00, 0x00aa, 0xe0c0, 0xc502, 0xbd00, 0x0132
|
||||||
|
};
|
||||||
|
unsigned long flags;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
raw_spin_lock_irqsave(&tp->mac_ocp_lock, flags);
|
||||||
|
for (i = 0; i < ARRAY_SIZE(fix_data); i++)
|
||||||
|
__r8168_mac_ocp_write(tp, 0xf800 + 2 * i, fix_data[i]);
|
||||||
|
raw_spin_unlock_irqrestore(&tp->mac_ocp_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
static void rtl_hw_start_8411_2(struct rtl8169_private *tp)
|
static void rtl_hw_start_8411_2(struct rtl8169_private *tp)
|
||||||
{
|
{
|
||||||
static const struct ephy_info e_info_8411_2[] = {
|
static const struct ephy_info e_info_8411_2[] = {
|
||||||
@ -3147,117 +3259,7 @@ static void rtl_hw_start_8411_2(struct rtl8169_private *tp)
|
|||||||
mdelay(3);
|
mdelay(3);
|
||||||
r8168_mac_ocp_write(tp, 0xFC26, 0x0000);
|
r8168_mac_ocp_write(tp, 0xFC26, 0x0000);
|
||||||
|
|
||||||
r8168_mac_ocp_write(tp, 0xF800, 0xE008);
|
rtl8411b_fix_phy_down(tp);
|
||||||
r8168_mac_ocp_write(tp, 0xF802, 0xE00A);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF804, 0xE00C);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF806, 0xE00E);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF808, 0xE027);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF80A, 0xE04F);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF80C, 0xE05E);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF80E, 0xE065);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF810, 0xC602);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF812, 0xBE00);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF814, 0x0000);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF816, 0xC502);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF818, 0xBD00);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF81A, 0x074C);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF81C, 0xC302);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF81E, 0xBB00);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF820, 0x080A);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF822, 0x6420);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF824, 0x48C2);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF826, 0x8C20);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF828, 0xC516);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF82A, 0x64A4);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF82C, 0x49C0);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF82E, 0xF009);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF830, 0x74A2);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF832, 0x8CA5);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF834, 0x74A0);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF836, 0xC50E);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF838, 0x9CA2);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF83A, 0x1C11);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF83C, 0x9CA0);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF83E, 0xE006);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF840, 0x74F8);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF842, 0x48C4);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF844, 0x8CF8);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF846, 0xC404);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF848, 0xBC00);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF84A, 0xC403);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF84C, 0xBC00);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF84E, 0x0BF2);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF850, 0x0C0A);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF852, 0xE434);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF854, 0xD3C0);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF856, 0x49D9);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF858, 0xF01F);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF85A, 0xC526);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF85C, 0x64A5);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF85E, 0x1400);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF860, 0xF007);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF862, 0x0C01);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF864, 0x8CA5);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF866, 0x1C15);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF868, 0xC51B);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF86A, 0x9CA0);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF86C, 0xE013);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF86E, 0xC519);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF870, 0x74A0);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF872, 0x48C4);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF874, 0x8CA0);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF876, 0xC516);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF878, 0x74A4);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF87A, 0x48C8);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF87C, 0x48CA);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF87E, 0x9CA4);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF880, 0xC512);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF882, 0x1B00);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF884, 0x9BA0);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF886, 0x1B1C);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF888, 0x483F);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF88A, 0x9BA2);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF88C, 0x1B04);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF88E, 0xC508);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF890, 0x9BA0);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF892, 0xC505);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF894, 0xBD00);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF896, 0xC502);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF898, 0xBD00);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF89A, 0x0300);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF89C, 0x051E);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF89E, 0xE434);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8A0, 0xE018);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8A2, 0xE092);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8A4, 0xDE20);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8A6, 0xD3C0);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8A8, 0xC50F);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8AA, 0x76A4);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8AC, 0x49E3);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8AE, 0xF007);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8B0, 0x49C0);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8B2, 0xF103);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8B4, 0xC607);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8B6, 0xBE00);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8B8, 0xC606);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8BA, 0xBE00);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8BC, 0xC602);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8BE, 0xBE00);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8C0, 0x0C4C);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8C2, 0x0C28);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8C4, 0x0C2C);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8C6, 0xDC00);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8C8, 0xC707);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8CA, 0x1D00);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8CC, 0x8DE2);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8CE, 0x48C1);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8D0, 0xC502);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8D2, 0xBD00);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8D4, 0x00AA);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8D6, 0xE0C0);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8D8, 0xC502);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8DA, 0xBD00);
|
|
||||||
r8168_mac_ocp_write(tp, 0xF8DC, 0x0132);
|
|
||||||
|
|
||||||
r8168_mac_ocp_write(tp, 0xFC26, 0x8000);
|
r8168_mac_ocp_write(tp, 0xFC26, 0x8000);
|
||||||
|
|
||||||
@ -4393,7 +4395,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp,
|
|||||||
unsigned int entry = dirty_tx % NUM_TX_DESC;
|
unsigned int entry = dirty_tx % NUM_TX_DESC;
|
||||||
u32 status;
|
u32 status;
|
||||||
|
|
||||||
status = le32_to_cpu(tp->TxDescArray[entry].opts1);
|
status = le32_to_cpu(READ_ONCE(tp->TxDescArray[entry].opts1));
|
||||||
if (status & DescOwn)
|
if (status & DescOwn)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4423,7 +4425,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp,
|
|||||||
* If skb is NULL then we come here again once a tx irq is
|
* If skb is NULL then we come here again once a tx irq is
|
||||||
* triggered after the last fragment is marked transmitted.
|
* triggered after the last fragment is marked transmitted.
|
||||||
*/
|
*/
|
||||||
if (tp->cur_tx != dirty_tx && skb)
|
if (READ_ONCE(tp->cur_tx) != dirty_tx && skb)
|
||||||
rtl8169_doorbell(tp);
|
rtl8169_doorbell(tp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4456,7 +4458,7 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, int budget
|
|||||||
dma_addr_t addr;
|
dma_addr_t addr;
|
||||||
u32 status;
|
u32 status;
|
||||||
|
|
||||||
status = le32_to_cpu(desc->opts1);
|
status = le32_to_cpu(READ_ONCE(desc->opts1));
|
||||||
if (status & DescOwn)
|
if (status & DescOwn)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4569,8 +4571,7 @@ static void rtl_task(struct work_struct *work)
|
|||||||
|
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
|
|
||||||
if (!netif_running(tp->dev) ||
|
if (!test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
|
||||||
!test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
|
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
if (test_and_clear_bit(RTL_FLAG_TASK_TX_TIMEOUT, tp->wk.flags)) {
|
if (test_and_clear_bit(RTL_FLAG_TASK_TX_TIMEOUT, tp->wk.flags)) {
|
||||||
@ -4596,6 +4597,8 @@ static void rtl_task(struct work_struct *work)
|
|||||||
reset:
|
reset:
|
||||||
rtl_reset_work(tp);
|
rtl_reset_work(tp);
|
||||||
netif_wake_queue(tp->dev);
|
netif_wake_queue(tp->dev);
|
||||||
|
} else if (test_and_clear_bit(RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE, tp->wk.flags)) {
|
||||||
|
rtl_reset_work(tp);
|
||||||
}
|
}
|
||||||
out_unlock:
|
out_unlock:
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
@ -4625,7 +4628,11 @@ static void r8169_phylink_handler(struct net_device *ndev)
|
|||||||
if (netif_carrier_ok(ndev)) {
|
if (netif_carrier_ok(ndev)) {
|
||||||
rtl_link_chg_patch(tp);
|
rtl_link_chg_patch(tp);
|
||||||
pm_request_resume(d);
|
pm_request_resume(d);
|
||||||
|
netif_wake_queue(tp->dev);
|
||||||
} else {
|
} else {
|
||||||
|
/* In few cases rx is broken after link-down otherwise */
|
||||||
|
if (rtl_is_8125(tp))
|
||||||
|
rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE);
|
||||||
pm_runtime_idle(d);
|
pm_runtime_idle(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4669,10 +4676,16 @@ static void rtl8169_down(struct rtl8169_private *tp)
|
|||||||
rtl8169_cleanup(tp);
|
rtl8169_cleanup(tp);
|
||||||
rtl_disable_exit_l1(tp);
|
rtl_disable_exit_l1(tp);
|
||||||
rtl_prepare_power_down(tp);
|
rtl_prepare_power_down(tp);
|
||||||
|
|
||||||
|
if (tp->dash_type != RTL_DASH_NONE)
|
||||||
|
rtl8168_driver_stop(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtl8169_up(struct rtl8169_private *tp)
|
static void rtl8169_up(struct rtl8169_private *tp)
|
||||||
{
|
{
|
||||||
|
if (tp->dash_type != RTL_DASH_NONE)
|
||||||
|
rtl8168_driver_start(tp);
|
||||||
|
|
||||||
pci_set_master(tp->pci_dev);
|
pci_set_master(tp->pci_dev);
|
||||||
phy_init_hw(tp->phydev);
|
phy_init_hw(tp->phydev);
|
||||||
phy_resume(tp->phydev);
|
phy_resume(tp->phydev);
|
||||||
@ -4695,7 +4708,7 @@ static int rtl8169_close(struct net_device *dev)
|
|||||||
rtl8169_down(tp);
|
rtl8169_down(tp);
|
||||||
rtl8169_rx_clear(tp);
|
rtl8169_rx_clear(tp);
|
||||||
|
|
||||||
cancel_work_sync(&tp->wk.work);
|
cancel_work(&tp->wk.work);
|
||||||
|
|
||||||
free_irq(tp->irq, tp);
|
free_irq(tp->irq, tp);
|
||||||
|
|
||||||
@ -4890,7 +4903,7 @@ static int rtl8169_runtime_idle(struct device *device)
|
|||||||
{
|
{
|
||||||
struct rtl8169_private *tp = dev_get_drvdata(device);
|
struct rtl8169_private *tp = dev_get_drvdata(device);
|
||||||
|
|
||||||
if (tp->dash_type != RTL_DASH_NONE)
|
if (tp->dash_enabled)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
if (!netif_running(tp->dev) || !netif_carrier_ok(tp->dev))
|
if (!netif_running(tp->dev) || !netif_carrier_ok(tp->dev))
|
||||||
@ -4916,8 +4929,7 @@ static void rtl_shutdown(struct pci_dev *pdev)
|
|||||||
/* Restore original MAC address */
|
/* Restore original MAC address */
|
||||||
rtl_rar_set(tp, tp->dev->perm_addr);
|
rtl_rar_set(tp, tp->dev->perm_addr);
|
||||||
|
|
||||||
if (system_state == SYSTEM_POWER_OFF &&
|
if (system_state == SYSTEM_POWER_OFF && !tp->dash_enabled) {
|
||||||
tp->dash_type == RTL_DASH_NONE) {
|
|
||||||
pci_wake_from_d3(pdev, tp->saved_wolopts);
|
pci_wake_from_d3(pdev, tp->saved_wolopts);
|
||||||
pci_set_power_state(pdev, PCI_D3hot);
|
pci_set_power_state(pdev, PCI_D3hot);
|
||||||
}
|
}
|
||||||
@ -4930,6 +4942,11 @@ static void rtl_remove_one(struct pci_dev *pdev)
|
|||||||
if (pci_dev_run_wake(pdev))
|
if (pci_dev_run_wake(pdev))
|
||||||
pm_runtime_get_noresume(&pdev->dev);
|
pm_runtime_get_noresume(&pdev->dev);
|
||||||
|
|
||||||
|
cancel_work_sync(&tp->wk.work);
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_R8169_LEDS))
|
||||||
|
r8169_remove_leds(tp->leds);
|
||||||
|
|
||||||
unregister_netdev(tp->dev);
|
unregister_netdev(tp->dev);
|
||||||
|
|
||||||
if (tp->dash_type != RTL_DASH_NONE)
|
if (tp->dash_type != RTL_DASH_NONE)
|
||||||
@ -5050,6 +5067,15 @@ static int r8169_mdio_register(struct rtl8169_private *tp)
|
|||||||
struct mii_bus *new_bus;
|
struct mii_bus *new_bus;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* On some boards with this chip version the BIOS is buggy and misses
|
||||||
|
* to reset the PHY page selector. This results in the PHY ID read
|
||||||
|
* accessing registers on a different page, returning a more or
|
||||||
|
* less random value. Fix this by resetting the page selector first.
|
||||||
|
*/
|
||||||
|
if (tp->mac_version == RTL_GIGA_MAC_VER_25 ||
|
||||||
|
tp->mac_version == RTL_GIGA_MAC_VER_26)
|
||||||
|
r8169_mdio_write(tp, 0x1f, 0);
|
||||||
|
|
||||||
new_bus = devm_mdiobus_alloc(&pdev->dev);
|
new_bus = devm_mdiobus_alloc(&pdev->dev);
|
||||||
if (!new_bus)
|
if (!new_bus)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -5203,6 +5229,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
int jumbo_max, region, rc;
|
int jumbo_max, region, rc;
|
||||||
enum mac_version chipset;
|
enum mac_version chipset;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
u32 txconfig;
|
||||||
u16 xid;
|
u16 xid;
|
||||||
|
|
||||||
dev = devm_alloc_etherdev(&pdev->dev, sizeof (*tp));
|
dev = devm_alloc_etherdev(&pdev->dev, sizeof (*tp));
|
||||||
@ -5221,6 +5248,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
raw_spin_lock_init(&tp->cfg9346_usage_lock);
|
raw_spin_lock_init(&tp->cfg9346_usage_lock);
|
||||||
raw_spin_lock_init(&tp->config25_lock);
|
raw_spin_lock_init(&tp->config25_lock);
|
||||||
raw_spin_lock_init(&tp->mac_ocp_lock);
|
raw_spin_lock_init(&tp->mac_ocp_lock);
|
||||||
|
mutex_init(&tp->led_lock);
|
||||||
|
|
||||||
dev->tstats = devm_netdev_alloc_pcpu_stats(&pdev->dev,
|
dev->tstats = devm_netdev_alloc_pcpu_stats(&pdev->dev,
|
||||||
struct pcpu_sw_netstats);
|
struct pcpu_sw_netstats);
|
||||||
@ -5234,38 +5262,35 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
|
|
||||||
/* enable device (incl. PCI PM wakeup and hotplug setup) */
|
/* enable device (incl. PCI PM wakeup and hotplug setup) */
|
||||||
rc = pcim_enable_device(pdev);
|
rc = pcim_enable_device(pdev);
|
||||||
if (rc < 0) {
|
if (rc < 0)
|
||||||
dev_err(&pdev->dev, "enable failure\n");
|
return dev_err_probe(&pdev->dev, rc, "enable failure\n");
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pcim_set_mwi(pdev) < 0)
|
if (pcim_set_mwi(pdev) < 0)
|
||||||
dev_info(&pdev->dev, "Mem-Wr-Inval unavailable\n");
|
dev_info(&pdev->dev, "Mem-Wr-Inval unavailable\n");
|
||||||
|
|
||||||
/* use first MMIO region */
|
/* use first MMIO region */
|
||||||
region = ffs(pci_select_bars(pdev, IORESOURCE_MEM)) - 1;
|
region = ffs(pci_select_bars(pdev, IORESOURCE_MEM)) - 1;
|
||||||
if (region < 0) {
|
if (region < 0)
|
||||||
dev_err(&pdev->dev, "no MMIO resource found\n");
|
return dev_err_probe(&pdev->dev, -ENODEV, "no MMIO resource found\n");
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = pcim_iomap_regions(pdev, BIT(region), KBUILD_MODNAME);
|
rc = pcim_iomap_regions(pdev, BIT(region), KBUILD_MODNAME);
|
||||||
if (rc < 0) {
|
if (rc < 0)
|
||||||
dev_err(&pdev->dev, "cannot remap MMIO, aborting\n");
|
return dev_err_probe(&pdev->dev, rc, "cannot remap MMIO, aborting\n");
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
tp->mmio_addr = pcim_iomap_table(pdev)[region];
|
tp->mmio_addr = pcim_iomap_table(pdev)[region];
|
||||||
|
|
||||||
xid = (RTL_R32(tp, TxConfig) >> 20) & 0xfcf;
|
txconfig = RTL_R32(tp, TxConfig);
|
||||||
|
if (txconfig == ~0U)
|
||||||
|
return dev_err_probe(&pdev->dev, -EIO, "PCI read failed\n");
|
||||||
|
|
||||||
|
xid = (txconfig >> 20) & 0xfcf;
|
||||||
|
|
||||||
/* Identify chip attached to board */
|
/* Identify chip attached to board */
|
||||||
chipset = rtl8169_get_mac_version(xid, tp->supports_gmii);
|
chipset = rtl8169_get_mac_version(xid, tp->supports_gmii);
|
||||||
if (chipset == RTL_GIGA_MAC_NONE) {
|
if (chipset == RTL_GIGA_MAC_NONE)
|
||||||
dev_err(&pdev->dev, "unknown chip XID %03x, contact r8169 maintainers (see MAINTAINERS file)\n", xid);
|
return dev_err_probe(&pdev->dev, -ENODEV,
|
||||||
return -ENODEV;
|
"unknown chip XID %03x, contact r8169 maintainers (see MAINTAINERS file)\n",
|
||||||
}
|
xid);
|
||||||
|
|
||||||
tp->mac_version = chipset;
|
tp->mac_version = chipset;
|
||||||
|
|
||||||
/* Disable ASPM L1 as that cause random device stop working
|
/* Disable ASPM L1 as that cause random device stop working
|
||||||
@ -5277,7 +5302,8 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L1);
|
rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L1);
|
||||||
tp->aspm_manageable = !rc;
|
tp->aspm_manageable = !rc;
|
||||||
|
|
||||||
tp->dash_type = rtl_check_dash(tp);
|
tp->dash_type = rtl_get_dash_type(tp);
|
||||||
|
tp->dash_enabled = rtl_dash_is_enabled(tp);
|
||||||
|
|
||||||
tp->cp_cmd = RTL_R16(tp, CPlusCmd) & CPCMD_MASK;
|
tp->cp_cmd = RTL_R16(tp, CPlusCmd) & CPCMD_MASK;
|
||||||
|
|
||||||
@ -5294,10 +5320,9 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
rtl_hw_reset(tp);
|
rtl_hw_reset(tp);
|
||||||
|
|
||||||
rc = rtl_alloc_irq(tp);
|
rc = rtl_alloc_irq(tp);
|
||||||
if (rc < 0) {
|
if (rc < 0)
|
||||||
dev_err(&pdev->dev, "Can't allocate interrupt\n");
|
return dev_err_probe(&pdev->dev, rc, "Can't allocate interrupt\n");
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
tp->irq = pci_irq_vector(pdev, 0);
|
tp->irq = pci_irq_vector(pdev, 0);
|
||||||
|
|
||||||
INIT_WORK(&tp->wk.work, rtl_task);
|
INIT_WORK(&tp->wk.work, rtl_task);
|
||||||
@ -5349,7 +5374,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
/* configure chip for default features */
|
/* configure chip for default features */
|
||||||
rtl8169_set_features(dev, dev->features);
|
rtl8169_set_features(dev, dev->features);
|
||||||
|
|
||||||
if (tp->dash_type == RTL_DASH_NONE) {
|
if (!tp->dash_enabled) {
|
||||||
rtl_set_d3_pll_down(tp, true);
|
rtl_set_d3_pll_down(tp, true);
|
||||||
} else {
|
} else {
|
||||||
rtl_set_d3_pll_down(tp, false);
|
rtl_set_d3_pll_down(tp, false);
|
||||||
@ -5380,6 +5405,11 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_R8169_LEDS) &&
|
||||||
|
tp->mac_version > RTL_GIGA_MAC_VER_06 &&
|
||||||
|
tp->mac_version < RTL_GIGA_MAC_VER_61)
|
||||||
|
tp->leds = rtl8168_init_leds(dev);
|
||||||
|
|
||||||
netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
|
netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
|
||||||
rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
|
rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
|
||||||
|
|
||||||
@ -5389,13 +5419,14 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
"ok" : "ko");
|
"ok" : "ko");
|
||||||
|
|
||||||
if (tp->dash_type != RTL_DASH_NONE) {
|
if (tp->dash_type != RTL_DASH_NONE) {
|
||||||
netdev_info(dev, "DASH enabled\n");
|
netdev_info(dev, "DASH %s\n",
|
||||||
|
tp->dash_enabled ? "enabled" : "disabled");
|
||||||
rtl8168_driver_start(tp);
|
rtl8168_driver_start(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pci_dev_run_wake(pdev))
|
if (pci_dev_run_wake(pdev))
|
||||||
pm_runtime_put_sync(&pdev->dev);
|
pm_runtime_put_sync(&pdev->dev);
|
||||||
|
printk(KERN_INFO "Intializing module_parameter: wol_param = %d\n", wol_param);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user