Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,129 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Realtek device configuration
#
config NET_VENDOR_REALTEK
bool "Realtek devices"
default y
depends on PCI
help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
kernel: saying N will just cause the configurator to skip all
the questions about Realtek devices. If you say Y, you will be asked for
your specific card in the following questions.
if NET_VENDOR_REALTEK
config 8139CP
tristate "RealTek RTL-8139 C+ PCI Fast Ethernet Adapter support"
depends on PCI
select CRC32
select MII
help
This is a driver for the Fast Ethernet PCI network cards based on
the RTL8139C+ chips. If you have one of those, say Y here.
To compile this driver as a module, choose M here: the module
will be called 8139cp. This is recommended.
config 8139TOO
tristate "RealTek RTL-8129/8130/8139 PCI Fast Ethernet Adapter support"
depends on PCI
select CRC32
select MII
help
This is a driver for the Fast Ethernet PCI network cards based on
the RTL 8129/8130/8139 chips. If you have one of those, say Y here.
To compile this driver as a module, choose M here: the module
will be called 8139too. This is recommended.
config 8139TOO_PIO
bool "Use PIO instead of MMIO"
default y
depends on 8139TOO && !NO_IOPORT_MAP
help
This instructs the driver to use programmed I/O ports (PIO) instead
of PCI shared memory (MMIO). This can possibly solve some problems
in case your mainboard has memory consistency issues. If unsure,
say N.
config 8139TOO_TUNE_TWISTER
bool "Support for uncommon RTL-8139 rev. K (automatic channel equalization)"
depends on 8139TOO
help
This implements a function which might come in handy in case you
are using low quality on long cabling. It is required for RealTek
RTL-8139 revision K boards, and totally unused otherwise. It tries
to match the transceiver to the cable characteristics. This is
experimental since hardly documented by the manufacturer.
If unsure, say Y.
config 8139TOO_8129
bool "Support for older RTL-8129/8130 boards"
depends on 8139TOO
help
This enables support for the older and uncommon RTL-8129 and
RTL-8130 chips, which support MII via an external transceiver,
instead of an internal one. Disabling this option will save some
memory by making the code size smaller. If unsure, say Y.
config 8139_OLD_RX_RESET
bool "Use older RX-reset method"
depends on 8139TOO
help
The 8139too driver was recently updated to contain a more rapid
reset sequence, in the face of severe receive errors. This "new"
RX-reset method should be adequate for all boards. But if you
experience problems, you can enable this option to restore the
old RX-reset behavior. If unsure, say N.
config R8169
tristate "Realtek 8169/8168/8101/8125 ethernet support"
depends on PCI
select FW_LOADER
select CRC32
select PHYLIB
select REALTEK_PHY
help
Say Y here if you have a Realtek Ethernet adapter belonging to
the following families:
RTL8169 Gigabit Ethernet
RTL8168 Gigabit Ethernet
RTL8101 Fast Ethernet
RTL8125 2.5GBit Ethernet
To compile this driver as a module, choose M here: the module
will be called r8169. This is recommended.
config R8169_LEDS
bool "Support for controlling the NIC LEDs"
depends on R8169 && LEDS_TRIGGER_NETDEV
depends on !(R8169=y && LEDS_CLASS=m)
help
Optional support for controlling the NIC LED's with the netdev
LED trigger.
config RTASE
tristate "Realtek Automotive Switch 9054/9068/9072/9075/9068/9071 PCIe Interface support"
depends on PCI
select CRC32
select PAGE_POOL
help
Say Y here and it will be compiled and linked with the kernel
if you have a Realtek Ethernet adapter belonging to the
following families:
RTL9054 5GBit Ethernet
RTL9068 5GBit Ethernet
RTL9072 5GBit Ethernet
RTL9075 5GBit Ethernet
RTL9068 5GBit Ethernet
RTL9071 5GBit Ethernet
To compile this driver as a module, choose M here: the module
will be called rtase. This is recommended.
endif # NET_VENDOR_REALTEK
@@ -0,0 +1,11 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Makefile for the Realtek network device drivers.
#
obj-$(CONFIG_8139CP) += 8139cp.o
obj-$(CONFIG_8139TOO) += 8139too.o
r8169-y += r8169_main.o r8169_firmware.o r8169_phy_config.o
r8169-$(CONFIG_R8169_LEDS) += r8169_leds.o
obj-$(CONFIG_R8169) += r8169.o
obj-$(CONFIG_RTASE) += rtase/
@@ -0,0 +1,97 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169.h: RealTek 8169/8168/8101 ethernet driver.
*
* 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.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/netdevice.h>
#include <linux/types.h>
#include <linux/phy.h>
enum mac_version {
/* support for ancient RTL_GIGA_MAC_VER_01 has been removed */
RTL_GIGA_MAC_VER_02,
RTL_GIGA_MAC_VER_03,
RTL_GIGA_MAC_VER_04,
RTL_GIGA_MAC_VER_05,
RTL_GIGA_MAC_VER_06,
RTL_GIGA_MAC_VER_07,
RTL_GIGA_MAC_VER_08,
RTL_GIGA_MAC_VER_09,
RTL_GIGA_MAC_VER_10,
/* support for RTL_GIGA_MAC_VER_11 has been removed */
/* RTL_GIGA_MAC_VER_12 was handled the same as VER_17 */
/* RTL_GIGA_MAC_VER_13 was merged with VER_10 */
RTL_GIGA_MAC_VER_14,
/* RTL_GIGA_MAC_VER_16 was merged with VER_10 */
RTL_GIGA_MAC_VER_17,
RTL_GIGA_MAC_VER_18,
RTL_GIGA_MAC_VER_19,
RTL_GIGA_MAC_VER_20,
RTL_GIGA_MAC_VER_21,
RTL_GIGA_MAC_VER_22,
RTL_GIGA_MAC_VER_23,
RTL_GIGA_MAC_VER_24,
RTL_GIGA_MAC_VER_25,
RTL_GIGA_MAC_VER_26,
/* support for RTL_GIGA_MAC_VER_27 has been removed */
RTL_GIGA_MAC_VER_28,
RTL_GIGA_MAC_VER_29,
RTL_GIGA_MAC_VER_30,
RTL_GIGA_MAC_VER_31,
RTL_GIGA_MAC_VER_32,
RTL_GIGA_MAC_VER_33,
RTL_GIGA_MAC_VER_34,
RTL_GIGA_MAC_VER_35,
RTL_GIGA_MAC_VER_36,
RTL_GIGA_MAC_VER_37,
RTL_GIGA_MAC_VER_38,
RTL_GIGA_MAC_VER_39,
RTL_GIGA_MAC_VER_40,
/* support for RTL_GIGA_MAC_VER_41 has been removed */
RTL_GIGA_MAC_VER_42,
RTL_GIGA_MAC_VER_43,
RTL_GIGA_MAC_VER_44,
/* support for RTL_GIGA_MAC_VER_45 has been removed */
RTL_GIGA_MAC_VER_46,
/* support for RTL_GIGA_MAC_VER_47 has been removed */
RTL_GIGA_MAC_VER_48,
/* support for RTL_GIGA_MAC_VER_49 has been removed */
/* support for RTL_GIGA_MAC_VER_50 has been removed */
RTL_GIGA_MAC_VER_51,
RTL_GIGA_MAC_VER_52,
/* support for RTL_GIGA_MAC_VER_60 has been removed */
RTL_GIGA_MAC_VER_61,
RTL_GIGA_MAC_VER_63,
RTL_GIGA_MAC_VER_64,
RTL_GIGA_MAC_VER_65,
RTL_GIGA_MAC_VER_66,
RTL_GIGA_MAC_VER_70,
RTL_GIGA_MAC_VER_80,
RTL_GIGA_MAC_NONE,
RTL_GIGA_MAC_VER_LAST = RTL_GIGA_MAC_NONE - 1,
RTL_GIGA_MAC_VER_EXTENDED
};
struct rtl8169_private;
struct r8169_led_classdev;
void r8169_apply_firmware(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);
void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
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);
int rtl8125_get_led_mode(struct rtl8169_private *tp, int index);
int rtl8125_set_led_mode(struct rtl8169_private *tp, int index, u16 mode);
struct r8169_led_classdev *rtl8125_init_leds(struct net_device *ndev);
void r8169_remove_leds(struct r8169_led_classdev *leds);
@@ -0,0 +1,233 @@
// SPDX-License-Identifier: GPL-2.0-only
/* r8169_firmware.c: RealTek 8169/8168/8101 ethernet driver.
*
* 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.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/delay.h>
#include <linux/firmware.h>
#include "r8169_firmware.h"
enum rtl_fw_opcode {
PHY_READ = 0x0,
PHY_DATA_OR = 0x1,
PHY_DATA_AND = 0x2,
PHY_BJMPN = 0x3,
PHY_MDIO_CHG = 0x4,
PHY_CLEAR_READCOUNT = 0x7,
PHY_WRITE = 0x8,
PHY_READCOUNT_EQ_SKIP = 0x9,
PHY_COMP_EQ_SKIPN = 0xa,
PHY_COMP_NEQ_SKIPN = 0xb,
PHY_WRITE_PREVIOUS = 0xc,
PHY_SKIPN = 0xd,
PHY_DELAY_MS = 0xe,
};
struct fw_info {
u32 magic;
char version[RTL_VER_SIZE];
__le32 fw_start;
__le32 fw_len;
u8 chksum;
} __packed;
#define FW_OPCODE_SIZE sizeof_field(struct rtl_fw_phy_action, code[0])
static bool rtl_fw_format_ok(struct rtl_fw *rtl_fw)
{
const struct firmware *fw = rtl_fw->fw;
struct fw_info *fw_info = (struct fw_info *)fw->data;
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
if (fw->size < FW_OPCODE_SIZE)
return false;
if (!fw_info->magic) {
size_t i, size, start;
u8 checksum = 0;
if (fw->size < sizeof(*fw_info))
return false;
for (i = 0; i < fw->size; i++)
checksum += fw->data[i];
if (checksum != 0)
return false;
start = le32_to_cpu(fw_info->fw_start);
if (start > fw->size)
return false;
size = le32_to_cpu(fw_info->fw_len);
if (size > (fw->size - start) / FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, fw_info->version);
pa->code = (__le32 *)(fw->data + start);
pa->size = size;
} else {
if (fw->size % FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, rtl_fw->fw_name, RTL_VER_SIZE);
pa->code = (__le32 *)fw->data;
pa->size = fw->size / FW_OPCODE_SIZE;
}
return true;
}
static bool rtl_fw_data_ok(struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 val = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
switch (action >> 28) {
case PHY_READ:
case PHY_DATA_OR:
case PHY_DATA_AND:
case PHY_CLEAR_READCOUNT:
case PHY_WRITE:
case PHY_WRITE_PREVIOUS:
case PHY_DELAY_MS:
break;
case PHY_MDIO_CHG:
if (val > 1)
goto out;
break;
case PHY_BJMPN:
if (regno > index)
goto out;
break;
case PHY_READCOUNT_EQ_SKIP:
if (index + 2 >= pa->size)
goto out;
break;
case PHY_COMP_EQ_SKIPN:
case PHY_COMP_NEQ_SKIPN:
case PHY_SKIPN:
if (index + 1 + regno >= pa->size)
goto out;
break;
default:
dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action);
return false;
}
}
return true;
out:
dev_err(rtl_fw->dev, "Out of range of firmware\n");
return false;
}
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
rtl_fw_write_t fw_write = rtl_fw->phy_write;
rtl_fw_read_t fw_read = rtl_fw->phy_read;
int predata = 0, count = 0;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 data = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
enum rtl_fw_opcode opcode = action >> 28;
switch (opcode) {
case PHY_READ:
predata = fw_read(tp, regno);
count++;
break;
case PHY_DATA_OR:
predata |= data;
break;
case PHY_DATA_AND:
predata &= data;
break;
case PHY_BJMPN:
index -= (regno + 1);
break;
case PHY_MDIO_CHG:
if (data) {
fw_write = rtl_fw->mac_mcu_write;
fw_read = rtl_fw->mac_mcu_read;
} else {
fw_write = rtl_fw->phy_write;
fw_read = rtl_fw->phy_read;
}
break;
case PHY_CLEAR_READCOUNT:
count = 0;
break;
case PHY_WRITE:
fw_write(tp, regno, data);
break;
case PHY_READCOUNT_EQ_SKIP:
if (count == data)
index++;
break;
case PHY_COMP_EQ_SKIPN:
if (predata == data)
index += regno;
break;
case PHY_COMP_NEQ_SKIPN:
if (predata != data)
index += regno;
break;
case PHY_WRITE_PREVIOUS:
fw_write(tp, regno, predata);
break;
case PHY_SKIPN:
index += regno;
break;
case PHY_DELAY_MS:
msleep(data);
break;
}
}
}
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw)
{
release_firmware(rtl_fw->fw);
}
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw)
{
int rc;
rc = firmware_request_nowarn(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev);
if (rc < 0)
goto out;
if (!rtl_fw_format_ok(rtl_fw) || !rtl_fw_data_ok(rtl_fw)) {
release_firmware(rtl_fw->fw);
rc = -EINVAL;
goto out;
}
return 0;
out:
dev_warn(rtl_fw->dev, "Unable to load firmware %s (%d)\n",
rtl_fw->fw_name, rc);
return rc;
}
@@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169_firmware.h: RealTek 8169/8168/8101 ethernet driver.
*
* 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.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/device.h>
#include <linux/firmware.h>
struct rtl8169_private;
typedef void (*rtl_fw_write_t)(struct rtl8169_private *tp, int reg, int val);
typedef int (*rtl_fw_read_t)(struct rtl8169_private *tp, int reg);
#define RTL_VER_SIZE 32
struct rtl_fw {
rtl_fw_write_t phy_write;
rtl_fw_read_t phy_read;
rtl_fw_write_t mac_mcu_write;
rtl_fw_read_t mac_mcu_read;
const struct firmware *fw;
const char *fw_name;
struct device *dev;
char version[RTL_VER_SIZE];
struct rtl_fw_phy_action {
__le32 *code;
size_t size;
} phy_action;
};
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw);
@@ -0,0 +1,275 @@
// 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 RTL8125_LED_CTRL_ACT BIT(9)
#define RTL8125_LED_CTRL_LINK_2500 BIT(5)
#define RTL8125_LED_CTRL_LINK_1000 BIT(3)
#define RTL8125_LED_CTRL_LINK_100 BIT(1)
#define RTL8125_LED_CTRL_LINK_10 BIT(0)
#define RTL8168_NUM_LEDS 3
#define RTL8125_NUM_LEDS 4
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 bool r8169_trigger_mode_is_valid(unsigned long flags)
{
bool rx, tx;
if (flags & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
return false;
if (flags & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
return false;
rx = flags & BIT(TRIGGER_NETDEV_RX);
tx = flags & BIT(TRIGGER_NETDEV_TX);
return rx == tx;
}
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;
if (!r8169_trigger_mode_is_valid(flags)) {
/* Switch LED off to indicate that mode isn't supported */
rtl8168_led_mod_ctrl(tp, 0x000f << shift, 0);
return -EOPNOTSUPP;
}
return 0;
}
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->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 = kzalloc_objs(*leds, RTL8168_NUM_LEDS + 1);
if (!leds)
return NULL;
for (i = 0; i < RTL8168_NUM_LEDS; i++)
rtl8168_setup_ldev(leds + i, ndev, i);
return leds;
}
static int rtl8125_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);
if (!r8169_trigger_mode_is_valid(flags)) {
/* Switch LED off to indicate that mode isn't supported */
rtl8125_set_led_mode(tp, ldev->index, 0);
return -EOPNOTSUPP;
}
return 0;
}
static int rtl8125_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);
u16 mode = 0;
if (flags & BIT(TRIGGER_NETDEV_LINK_10))
mode |= RTL8125_LED_CTRL_LINK_10;
if (flags & BIT(TRIGGER_NETDEV_LINK_100))
mode |= RTL8125_LED_CTRL_LINK_100;
if (flags & BIT(TRIGGER_NETDEV_LINK_1000))
mode |= RTL8125_LED_CTRL_LINK_1000;
if (flags & BIT(TRIGGER_NETDEV_LINK_2500))
mode |= RTL8125_LED_CTRL_LINK_2500;
if (flags & (BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX)))
mode |= RTL8125_LED_CTRL_ACT;
return rtl8125_set_led_mode(tp, ldev->index, mode);
}
static int rtl8125_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 mode;
mode = rtl8125_get_led_mode(tp, ldev->index);
if (mode < 0)
return mode;
if (mode & RTL8125_LED_CTRL_LINK_10)
*flags |= BIT(TRIGGER_NETDEV_LINK_10);
if (mode & RTL8125_LED_CTRL_LINK_100)
*flags |= BIT(TRIGGER_NETDEV_LINK_100);
if (mode & RTL8125_LED_CTRL_LINK_1000)
*flags |= BIT(TRIGGER_NETDEV_LINK_1000);
if (mode & RTL8125_LED_CTRL_LINK_2500)
*flags |= BIT(TRIGGER_NETDEV_LINK_2500);
if (mode & RTL8125_LED_CTRL_ACT)
*flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX);
return 0;
}
static void rtl8125_setup_led_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->hw_control_trigger = "netdev";
led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN;
led_cdev->hw_control_is_supported = rtl8125_led_hw_control_is_supported;
led_cdev->hw_control_set = rtl8125_led_hw_control_set;
led_cdev->hw_control_get = rtl8125_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 *rtl8125_init_leds(struct net_device *ndev)
{
struct r8169_led_classdev *leds;
int i;
leds = kzalloc_objs(*leds, RTL8125_NUM_LEDS + 1);
if (!leds)
return NULL;
for (i = 0; i < RTL8125_NUM_LEDS; i++)
rtl8125_setup_led_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);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,10 @@
# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved.
#
# Makefile for the Realtek PCIe driver
#
obj-$(CONFIG_RTASE) += rtase.o
rtase-objs := rtase_main.o
@@ -0,0 +1,374 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* rtase is the Linux device driver released for Realtek Automotive Switch
* controllers with PCI-Express interface.
*
* Copyright(c) 2024 Realtek Semiconductor Corp.
*/
#ifndef RTASE_H
#define RTASE_H
#define RTASE_HW_VER_MASK 0x7C800000
#define RTASE_HW_VER_906X_7XA 0x00800000
#define RTASE_HW_VER_906X_7XC 0x04000000
#define RTASE_HW_VER_907XD_V1 0x04800000
#define RTASE_HW_VER_907XD_VA 0x08000000
#define RTASE_RX_DMA_BURST_256 4
#define RTASE_TX_DMA_BURST_UNLIMITED 7
#define RTASE_RX_BUF_SIZE (PAGE_SIZE - \
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
#define RTASE_MAX_JUMBO_SIZE (RTASE_RX_BUF_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN)
/* 3 means InterFrameGap = the shortest one */
#define RTASE_INTERFRAMEGAP 0x03
#define RTASE_REGS_SIZE 256
#define RTASE_PCI_REGS_SIZE 0x100
#define RTASE_MULTICAST_FILTER_MASK GENMASK(30, 26)
#define RTASE_VLAN_FILTER_ENTRY_NUM 32
#define RTASE_NUM_TX_QUEUE 8
#define RTASE_NUM_RX_QUEUE 4
#define RTASE_TXQ_CTRL 1
#define RTASE_FUNC_TXQ_NUM 1
#define RTASE_FUNC_RXQ_NUM 1
#define RTASE_INTERRUPT_NUM 1
#define RTASE_MITI_TIME_COUNT_MASK GENMASK(3, 0)
#define RTASE_MITI_TIME_UNIT_MASK GENMASK(7, 4)
#define RTASE_MITI_DEFAULT_TIME 128
#define RTASE_MITI_MAX_TIME 491520
#define RTASE_MITI_PKT_NUM_COUNT_MASK GENMASK(11, 8)
#define RTASE_MITI_PKT_NUM_UNIT_MASK GENMASK(13, 12)
#define RTASE_MITI_DEFAULT_PKT_NUM 64
#define RTASE_MITI_MAX_PKT_NUM_IDX 3
#define RTASE_MITI_MAX_PKT_NUM_UNIT 16
#define RTASE_MITI_MAX_PKT_NUM 240
#define RTASE_MITI_COUNT_BIT_NUM 4
#define RTASE_NUM_MSIX 4
#define RTASE_DWORD_MOD 16
/*****************************************************************************/
enum rtase_registers {
RTASE_MAC0 = 0x0000,
RTASE_MAC4 = 0x0004,
RTASE_MAR0 = 0x0008,
RTASE_MAR1 = 0x000C,
RTASE_DTCCR0 = 0x0010,
RTASE_DTCCR4 = 0x0014,
#define RTASE_COUNTER_RESET BIT(0)
#define RTASE_COUNTER_DUMP BIT(3)
RTASE_FCR = 0x0018,
#define RTASE_FCR_RXQ_MASK GENMASK(5, 4)
RTASE_LBK_CTRL = 0x001A,
#define RTASE_LBK_ATLD BIT(1)
#define RTASE_LBK_CLR BIT(0)
RTASE_TX_DESC_ADDR0 = 0x0020,
RTASE_TX_DESC_ADDR4 = 0x0024,
RTASE_TX_DESC_COMMAND = 0x0028,
#define RTASE_TX_DESC_CMD_CS BIT(15)
#define RTASE_TX_DESC_CMD_WE BIT(14)
RTASE_BOOT_CTL = 0x6004,
RTASE_CLKSW_SET = 0x6018,
RTASE_CHIP_CMD = 0x0037,
#define RTASE_STOP_REQ BIT(7)
#define RTASE_STOP_REQ_DONE BIT(6)
#define RTASE_RE BIT(3)
#define RTASE_TE BIT(2)
RTASE_IMR0 = 0x0038,
RTASE_ISR0 = 0x003C,
#define RTASE_TOK7 BIT(30)
#define RTASE_TOK6 BIT(28)
#define RTASE_TOK5 BIT(26)
#define RTASE_TOK4 BIT(24)
#define RTASE_FOVW BIT(6)
#define RTASE_RDU BIT(4)
#define RTASE_TOK BIT(2)
#define RTASE_ROK BIT(0)
RTASE_IMR1 = 0x0800,
RTASE_ISR1 = 0x0802,
#define RTASE_Q_TOK BIT(4)
#define RTASE_Q_RDU BIT(1)
#define RTASE_Q_ROK BIT(0)
RTASE_EPHY_ISR = 0x6014,
RTASE_EPHY_IMR = 0x6016,
RTASE_TX_CONFIG_0 = 0x0040,
#define RTASE_TX_INTER_FRAME_GAP_MASK GENMASK(25, 24)
/* DMA burst value (0-7) is shift this many bits */
#define RTASE_TX_DMA_MASK GENMASK(10, 8)
RTASE_RX_CONFIG_0 = 0x0044,
#define RTASE_RX_SINGLE_FETCH BIT(14)
#define RTASE_RX_SINGLE_TAG BIT(13)
#define RTASE_RX_MX_DMA_MASK GENMASK(10, 8)
#define RTASE_ACPT_FLOW BIT(7)
#define RTASE_ACCEPT_ERR BIT(5)
#define RTASE_ACCEPT_RUNT BIT(4)
#define RTASE_ACCEPT_BROADCAST BIT(3)
#define RTASE_ACCEPT_MULTICAST BIT(2)
#define RTASE_ACCEPT_MYPHYS BIT(1)
#define RTASE_ACCEPT_ALLPHYS BIT(0)
#define RTASE_ACCEPT_MASK (RTASE_ACPT_FLOW | RTASE_ACCEPT_ERR | \
RTASE_ACCEPT_RUNT | RTASE_ACCEPT_BROADCAST | \
RTASE_ACCEPT_MULTICAST | RTASE_ACCEPT_MYPHYS | \
RTASE_ACCEPT_ALLPHYS)
RTASE_RX_CONFIG_1 = 0x0046,
#define RTASE_RX_MAX_FETCH_DESC_MASK GENMASK(15, 11)
#define RTASE_RX_NEW_DESC_FORMAT_EN BIT(8)
#define RTASE_OUTER_VLAN_DETAG_EN BIT(7)
#define RTASE_INNER_VLAN_DETAG_EN BIT(6)
#define RTASE_PCIE_NEW_FLOW BIT(2)
#define RTASE_PCIE_RELOAD_EN BIT(0)
RTASE_EEM = 0x0050,
#define RTASE_EEM_UNLOCK 0xC0
RTASE_TDFNR = 0x0057,
RTASE_TPPOLL = 0x0090,
RTASE_PDR = 0x00B0,
RTASE_FIFOR = 0x00D3,
#define RTASE_TX_FIFO_EMPTY BIT(5)
#define RTASE_RX_FIFO_EMPTY BIT(4)
RTASE_RMS = 0x00DA,
RTASE_CPLUS_CMD = 0x00E0,
#define RTASE_FORCE_RXFLOW_EN BIT(11)
#define RTASE_FORCE_TXFLOW_EN BIT(10)
#define RTASE_RX_CHKSUM BIT(5)
RTASE_GPHY_STD_00 = 0x6024,
#define RTASE_RXFLOW_EN BIT(7)
#define RTASE_TXFLOW_EN BIT(6)
RTASE_Q0_RX_DESC_ADDR0 = 0x00E4,
RTASE_Q0_RX_DESC_ADDR4 = 0x00E8,
RTASE_Q1_RX_DESC_ADDR0 = 0x4000,
RTASE_Q1_RX_DESC_ADDR4 = 0x4004,
RTASE_MTPS = 0x00EC,
#define RTASE_TAG_NUM_SEL_MASK GENMASK(10, 8)
RTASE_MISC = 0x00F2,
#define RTASE_RX_DV_GATE_EN BIT(3)
RTASE_TFUN_CTRL = 0x0400,
#define RTASE_TX_NEW_DESC_FORMAT_EN BIT(0)
RTASE_TX_CONFIG_1 = 0x203E,
#define RTASE_TC_MODE_MASK GENMASK(11, 10)
RTASE_TOKSEL = 0x2046,
RTASE_TXQCRDT_0 = 0x2500,
RTASE_RFIFONFULL = 0x4406,
RTASE_INT_MITI_TX = 0x0A00,
RTASE_INT_MITI_RX = 0x0A80,
RTASE_VLAN_ENTRY_0 = 0xAC80,
};
enum rtase_desc_status_bit {
RTASE_DESC_OWN = BIT(31), /* Descriptor is owned by NIC */
RTASE_RING_END = BIT(30), /* End of descriptor ring */
};
enum rtase_sw_flag_content {
RTASE_SWF_MSI_ENABLED = BIT(1),
RTASE_SWF_MSIX_ENABLED = BIT(2),
};
enum rtase_parse_result {
RTASE_PARSE_OK,
RTASE_PARSE_SKIP,
RTASE_PARSE_DROP,
};
#define RSVD_MASK 0x3FFFC000
struct rtase_tx_desc {
__le32 opts1;
__le32 opts2;
__le64 addr;
__le32 opts3;
__le32 reserved1;
__le32 reserved2;
__le32 reserved3;
} __packed;
/*------ offset 0 of tx descriptor ------*/
#define RTASE_TX_FIRST_FRAG BIT(29) /* Tx First segment of a packet */
#define RTASE_TX_LAST_FRAG BIT(28) /* Tx Final segment of a packet */
#define RTASE_GIANT_SEND_V4 BIT(26) /* TCP Giant Send Offload V4 (GSOv4) */
#define RTASE_GIANT_SEND_V6 BIT(25) /* TCP Giant Send Offload V6 (GSOv6) */
#define RTASE_TX_VLAN_TAG BIT(17) /* Add VLAN tag */
/*------ offset 4 of tx descriptor ------*/
#define RTASE_TX_UDPCS_C BIT(31) /* Calculate UDP/IP checksum */
#define RTASE_TX_TCPCS_C BIT(30) /* Calculate TCP/IP checksum */
#define RTASE_TX_IPCS_C BIT(29) /* Calculate IP checksum */
#define RTASE_TX_IPV6F_C BIT(28) /* Indicate it is an IPv6 packet */
union rtase_rx_desc {
struct {
__le64 header_buf_addr;
__le32 reserved1;
__le32 opts_header_len;
__le64 addr;
__le32 reserved2;
__le32 opts1;
} __packed desc_cmd;
struct {
__le32 reserved1;
__le32 reserved2;
__le32 rss;
__le32 opts4;
__le32 reserved3;
__le32 opts3;
__le32 opts2;
__le32 opts1;
} __packed desc_status;
} __packed;
/*------ offset 28 of rx descriptor ------*/
#define RTASE_RX_FIRST_FRAG BIT(25) /* Rx First segment of a packet */
#define RTASE_RX_LAST_FRAG BIT(24) /* Rx Final segment of a packet */
#define RTASE_RX_RES BIT(20)
#define RTASE_RX_RUNT BIT(19)
#define RTASE_RX_RWT BIT(18)
#define RTASE_RX_CRC BIT(17)
#define RTASE_RX_V6F BIT(31)
#define RTASE_RX_V4F BIT(30)
#define RTASE_RX_UDPT BIT(29)
#define RTASE_RX_TCPT BIT(28)
#define RTASE_RX_IPF BIT(26) /* IP checksum failed */
#define RTASE_RX_UDPF BIT(25) /* UDP/IP checksum failed */
#define RTASE_RX_TCPF BIT(24) /* TCP/IP checksum failed */
#define RTASE_RX_VLAN_TAG BIT(16) /* VLAN tag available */
#define RTASE_NUM_DESC 1024
#define RTASE_TX_BUDGET_DEFAULT 256
#define RTASE_TX_RING_DESC_SIZE (RTASE_NUM_DESC * sizeof(struct rtase_tx_desc))
#define RTASE_RX_RING_DESC_SIZE (RTASE_NUM_DESC * sizeof(union rtase_rx_desc))
#define RTASE_TX_STOP_THRS (MAX_SKB_FRAGS + 1)
#define RTASE_TX_START_THRS (2 * RTASE_TX_STOP_THRS)
#define RTASE_VLAN_TAG_MASK GENMASK(15, 0)
#define RTASE_RX_PKT_SIZE_MASK GENMASK(13, 0)
/* txqos hardware definitions */
#define RTASE_1T_CLOCK 64
#define RTASE_1T_POWER 10000000
#define RTASE_IDLESLOPE_INT_SHIFT 25
#define RTASE_IDLESLOPE_INT_MASK GENMASK(31, 25)
#define RTASE_IVEC_NAME_SIZE (IFNAMSIZ + 10)
struct rtase_int_vector {
struct rtase_private *tp;
unsigned int irq;
char name[RTASE_IVEC_NAME_SIZE];
u16 index;
u16 imr_addr;
u16 isr_addr;
u32 imr;
struct list_head ring_list;
struct napi_struct napi;
int (*poll)(struct napi_struct *napi, int budget);
};
struct rtase_ring {
struct rtase_int_vector *ivec;
void *desc;
dma_addr_t phy_addr;
u32 cur_idx;
u32 dirty_idx;
u16 index;
u8 type;
struct sk_buff *skbuff[RTASE_NUM_DESC];
void *data_buf[RTASE_NUM_DESC];
union {
u32 len[RTASE_NUM_DESC];
dma_addr_t data_phy_addr[RTASE_NUM_DESC];
} mis;
struct list_head ring_entry;
int (*ring_handler)(struct rtase_ring *ring, int budget);
u64 alloc_fail;
};
struct rtase_txqos {
int hicredit;
int locredit;
int idleslope;
int sendslope;
};
struct rtase_stats {
u64 tx_dropped;
u64 rx_dropped;
u64 multicast;
u64 rx_errors;
u64 rx_length_errors;
u64 rx_crc_errors;
};
struct rtase_private {
void __iomem *mmio_addr;
u32 sw_flag;
struct pci_dev *pdev;
struct net_device *dev;
u32 rx_buf_sz;
struct page_pool *page_pool;
struct rtase_ring tx_ring[RTASE_NUM_TX_QUEUE];
struct rtase_txqos tx_qos[RTASE_NUM_TX_QUEUE];
struct rtase_ring rx_ring[RTASE_NUM_RX_QUEUE];
struct rtase_counters *tally_vaddr;
dma_addr_t tally_paddr;
u32 vlan_filter_ctrl;
u16 vlan_filter_vid[RTASE_VLAN_FILTER_ENTRY_NUM];
struct msix_entry msix_entry[RTASE_NUM_MSIX];
struct rtase_int_vector int_vector[RTASE_NUM_MSIX];
struct rtase_stats stats;
u16 tx_queue_ctrl;
u16 func_tx_queue_num;
u16 func_rx_queue_num;
u16 int_nums;
u16 tx_int_mit;
u16 rx_int_mit;
u32 hw_ver;
};
#define RTASE_LSO_64K 64000
#define RTASE_NIC_MAX_PHYS_BUF_COUNT_LSO2 (16 * 4)
#define RTASE_TCPHO_MASK GENMASK(24, 18)
#define RTASE_MSS_MASK GENMASK(28, 18)
#define RTASE_MIN_PAD_LEN 47
#endif /* RTASE_H */
File diff suppressed because it is too large Load Diff