net: rtl8169: add minimal support for 8125B variant

Add minimal support for 8125B version.
Changes are based on the Linux driver.
Tested on Radxa Rock 5B Rk3588 board.

Connection to a laptop worked fine in 100 Mbps mode.
1000 Mbps mode is not working at the moment.

Signed-off-by: Eugen Hristev <eugen.hristev@collabora.com>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
This commit is contained in:
Eugen Hristev 2023-04-25 16:06:58 +03:00 committed by Tom Rini
parent 4c516807f4
commit bcbb64b199

View file

@ -118,9 +118,9 @@ enum RTL8169_registers {
FLASH = 0x30,
ERSR = 0x36,
ChipCmd = 0x37,
TxPoll = 0x38,
IntrMask = 0x3C,
IntrStatus = 0x3E,
TxPoll_8169 = 0x38,
IntrMask_8169 = 0x3C,
IntrStatus_8169 = 0x3E,
TxConfig = 0x40,
RxConfig = 0x44,
RxMissed = 0x4C,
@ -148,6 +148,12 @@ enum RTL8169_registers {
FuncForceEvent = 0xFC,
};
enum RTL8125_registers {
IntrMask_8125 = 0x38,
IntrStatus_8125 = 0x3C,
TxPoll_8125 = 0x90,
};
enum RTL8169_register_content {
/*InterruptStatusBits */
SYSErr = 0x8000,
@ -263,6 +269,7 @@ static struct {
{"RTL-8101e", 0x34, 0xff7e1880,},
{"RTL-8100e", 0x32, 0xff7e1880,},
{"RTL-8168h/8111h", 0x54, 0xff7e1880,},
{"RTL-8125B", 0x64, 0xff7e1880,},
};
enum _DescStatusBit {
@ -347,6 +354,7 @@ static struct pci_device_id supported[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167) },
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168) },
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169) },
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8125) },
{}
};
@ -517,6 +525,7 @@ static int rtl_recv_common(struct udevice *dev, unsigned long dev_iobase,
/* return true if there's an ethernet packet ready to read */
/* nic->packet should contain data on return */
/* nic->packetlen should contain length of data */
struct pci_child_plat *pplat = dev_get_parent_plat(dev);
int cur_rx;
int length = 0;
@ -558,6 +567,10 @@ static int rtl_recv_common(struct udevice *dev, unsigned long dev_iobase,
return length;
} else {
u32 IntrStatus = IntrStatus_8169;
if (pplat->device == 0x8125)
IntrStatus = IntrStatus_8125;
ushort sts = RTL_R8(IntrStatus);
RTL_W8(IntrStatus, sts & ~(TxErr | RxErr | SYSErr));
udelay(100); /* wait */
@ -582,6 +595,7 @@ static int rtl_send_common(struct udevice *dev, unsigned long dev_iobase,
{
/* send the packet to destination */
struct pci_child_plat *pplat = dev_get_parent_plat(dev);
u32 to;
u8 *ptxb;
int entry = tpc->cur_tx % NUM_TX_DESC;
@ -618,7 +632,10 @@ static int rtl_send_common(struct udevice *dev, unsigned long dev_iobase,
((len > ETH_ZLEN) ? len : ETH_ZLEN));
}
rtl_flush_tx_desc(&tpc->TxDescArray[entry]);
RTL_W8(TxPoll, 0x40); /* set polling bit */
if (pplat->device == 0x8125)
RTL_W8(TxPoll_8125, 0x1); /* set polling bit */
else
RTL_W8(TxPoll_8169, 0x40); /* set polling bit */
tpc->cur_tx++;
to = currticks() + TX_TIMEOUT;
@ -824,21 +841,26 @@ static int rtl8169_eth_start(struct udevice *dev)
return 0;
}
static void rtl_halt_common(unsigned long dev_iobase)
static void rtl_halt_common(struct udevice *dev)
{
struct rtl8169_private *priv = dev_get_priv(dev);
struct pci_child_plat *pplat = dev_get_parent_plat(dev);
int i;
#ifdef DEBUG_RTL8169
printf ("%s\n", __FUNCTION__);
#endif
ioaddr = dev_iobase;
ioaddr = priv->iobase;
/* Stop the chip's Tx and Rx DMA processes. */
RTL_W8(ChipCmd, 0x00);
/* Disable interrupts by clearing the interrupt mask. */
RTL_W16(IntrMask, 0x0000);
if (pplat->device == 0x8125)
RTL_W16(IntrMask_8125, 0x0000);
else
RTL_W16(IntrMask_8169, 0x0000);
RTL_W32(RxMissed, 0);
@ -849,9 +871,7 @@ static void rtl_halt_common(unsigned long dev_iobase)
void rtl8169_eth_stop(struct udevice *dev)
{
struct rtl8169_private *priv = dev_get_priv(dev);
rtl_halt_common(priv->iobase);
rtl_halt_common(dev);
}
static int rtl8169_write_hwaddr(struct udevice *dev)
@ -1025,23 +1045,25 @@ static int rtl8169_eth_probe(struct udevice *dev)
struct pci_child_plat *pplat = dev_get_parent_plat(dev);
struct rtl8169_private *priv = dev_get_priv(dev);
struct eth_pdata *plat = dev_get_plat(dev);
u32 iobase;
int region;
int ret;
debug("rtl8169: REALTEK RTL8169 @0x%x\n", iobase);
switch (pplat->device) {
case 0x8168:
case 0x8125:
region = 2;
break;
default:
region = 1;
break;
}
dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0 + region * 4, &iobase);
iobase &= ~0xf;
priv->iobase = (int)dm_pci_mem_to_phys(dev, iobase);
priv->iobase = (ulong)dm_pci_map_bar(dev,
PCI_BASE_ADDRESS_0 + region * 4,
0, 0,
PCI_REGION_TYPE, PCI_REGION_MEM);
debug("rtl8169: REALTEK RTL8169 @0x%lx\n", priv->iobase);
ret = rtl_init(priv->iobase, dev->name, plat->enetaddr);
if (ret < 0) {
printf(pr_fmt("failed to initialize card: %d\n"), ret);