diff mbox series

[1/2] net: rtl8169: add minimal support for 8125B variant

Message ID 20230425130659.62361-1-eugen.hristev@collabora.com
State Accepted
Commit bcbb64b1990cc1f3f8137c05fbc49b13fcb320ff
Delegated to: Ramon Fried
Headers show
Series [1/2] net: rtl8169: add minimal support for 8125B variant | expand

Commit Message

Eugen Hristev April 25, 2023, 1:06 p.m. UTC
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>
---
 drivers/net/rtl8169.c | 52 ++++++++++++++++++++++++++++++-------------
 1 file changed, 37 insertions(+), 15 deletions(-)

Comments

Eugen Hristev April 25, 2023, 1:17 p.m. UTC | #1
On 4/25/23 16:06, Eugen Hristev wrote:
> 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>
> ---

The one thing that impacts all the rtl chips is the way the pci BAR is 
now mapped.
I could not test this on another platform so help on this matter is 
appreciated.

Thanks!
Eugen

>   drivers/net/rtl8169.c | 52 ++++++++++++++++++++++++++++++-------------
>   1 file changed, 37 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c
> index c9c07a5a8ffe..2276a465e787 100644
> --- a/drivers/net/rtl8169.c
> +++ b/drivers/net/rtl8169.c
> @@ -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);
Ramon Fried April 25, 2023, 7:22 p.m. UTC | #2
On Tue, Apr 25, 2023 at 4:17 PM Eugen Hristev
<eugen.hristev@collabora.com> wrote:
>
> On 4/25/23 16:06, Eugen Hristev wrote:
> > 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>
> > ---
>
> The one thing that impacts all the rtl chips is the way the pci BAR is
> now mapped.
> I could not test this on another platform so help on this matter is
> appreciated.
>
> Thanks!
> Eugen
Let's wait a bit to see if someone can test it. why did you change the
mapping of the BAR ?
Eugen Hristev April 25, 2023, 7:47 p.m. UTC | #3
On 4/25/23 22:22, Ramon Fried wrote:
> On Tue, Apr 25, 2023 at 4:17 PM Eugen Hristev
> <eugen.hristev@collabora.com> wrote:
>>
>> On 4/25/23 16:06, Eugen Hristev wrote:
>>> 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>
>>> ---
>>
>> The one thing that impacts all the rtl chips is the way the pci BAR is
>> now mapped.
>> I could not test this on another platform so help on this matter is
>> appreciated.
>>
>> Thanks!
>> Eugen
> Let's wait a bit to see if someone can test it. why did you change the
> mapping of the BAR ?

It did not work with the old code. It provided a bad address, to some 
area which did not have the right registers.
I looked into similar drivers and they were using this call, which works 
perfectly for 8125b device

Eugen
Ramon Fried April 30, 2023, 7:44 p.m. UTC | #4
On Tue, Apr 25, 2023 at 10:47 PM Eugen Hristev
<eugen.hristev@collabora.com> wrote:
>
> On 4/25/23 22:22, Ramon Fried wrote:
> > On Tue, Apr 25, 2023 at 4:17 PM Eugen Hristev
> > <eugen.hristev@collabora.com> wrote:
> >>
> >> On 4/25/23 16:06, Eugen Hristev wrote:
> >>> 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>
> >>> ---
> >>
> >> The one thing that impacts all the rtl chips is the way the pci BAR is
> >> now mapped.
> >> I could not test this on another platform so help on this matter is
> >> appreciated.
> >>
> >> Thanks!
> >> Eugen
> > Let's wait a bit to see if someone can test it. why did you change the
> > mapping of the BAR ?
>
> It did not work with the old code. It provided a bad address, to some
> area which did not have the right registers.
> I looked into similar drivers and they were using this call, which works
> perfectly for 8125b device
>
> Eugen
Ok.
Hopefully nothing breaks.
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
Tom Rini May 6, 2023, 2:54 p.m. UTC | #5
On Tue, Apr 25, 2023 at 04:06:58PM +0300, Eugen Hristev wrote:

> 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>

Applied to u-boot/master, thanks!
Eugen Hristev May 17, 2023, 10:54 a.m. UTC | #6
On 4/30/23 22:44, Ramon Fried wrote:
> On Tue, Apr 25, 2023 at 10:47 PM Eugen Hristev
> <eugen.hristev@collabora.com> wrote:
>>
>> On 4/25/23 22:22, Ramon Fried wrote:
>>> On Tue, Apr 25, 2023 at 4:17 PM Eugen Hristev
>>> <eugen.hristev@collabora.com> wrote:
>>>>
>>>> On 4/25/23 16:06, Eugen Hristev wrote:
>>>>> 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>
>>>>> ---
>>>>
>>>> The one thing that impacts all the rtl chips is the way the pci BAR is
>>>> now mapped.
>>>> I could not test this on another platform so help on this matter is
>>>> appreciated.
>>>>
>>>> Thanks!
>>>> Eugen
>>> Let's wait a bit to see if someone can test it. why did you change the
>>> mapping of the BAR ?
>>
>> It did not work with the old code. It provided a bad address, to some
>> area which did not have the right registers.
>> I looked into similar drivers and they were using this call, which works
>> perfectly for 8125b device
>>
>> Eugen
> Ok.
> Hopefully nothing breaks.
> Reviewed-by: Ramon Fried <rfried.dev@gmail.com>


Hello Ramon,

I have a question if you don't mind, maybe you are better suited to 
answer this :

In the case of rtl8169 which is a pci express device, the probing is 
done on demand (pci enum) or with MISC_INIT_R, anyway, the probing is 
done *after* the board init is done, and in case of rockchip, the board 
init will check if there is any 'ethaddr' set, and if not, set the 
ethaddr by generating an unique cpuid-based MAC. This happens, no 
ethaddr is set, and the MAC is generated.
However, when the rtl8169 probes, it has ofcourse a different hardware 
written MAC, but the uboot subsystem will deny it, and claim ethaddr is 
already set, and it will call the 8169 driver to rewrite its MAC.
This then happens, and Uboot will use the initial ethaddr (the one 
generated) for any kind of packets.
While this is not a problem at first glance, when Linux boots, it will 
read the MAC from rtl8169 ROM (even if uboot attempted to rewrite its 
MAC, being a ROM, it will not be written), and Linux will use a 
different MAC now.
Do you have any idea on how to solve this problem ? I would like that 
once rtl8169 driver probes, the initial ethaddr would be overwritten.

Thanks !
diff mbox series

Patch

diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c
index c9c07a5a8ffe..2276a465e787 100644
--- a/drivers/net/rtl8169.c
+++ b/drivers/net/rtl8169.c
@@ -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);