+// SPDX-License-Identifier: GPL-2.0+
/*
* rtl8169.c : U-Boot driver for the RealTek RTL8169
*
/**************************************************************************
* r8169.c: Etherboot device driver for the RealTek RTL-8169 Gigabit
* Written 2003 by Timothy Legge <tlegge@rogers.com>
-*
- * SPDX-License-Identifier: GPL-2.0+
*
* Portions of this code based on:
* r8169.c: A RealTek RTL-8169 Gigabit Ethernet driver
static struct rtl8169_private *tpc;
-static const u16 rtl8169_intr_mask =
- SYSErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver | TxErr |
- TxOK | RxErr | RxOK;
static const unsigned int rtl8169_rx_config =
(RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
/**************************************************************************
RECV - Receive a frame
***************************************************************************/
-static int rtl_recv_common(pci_dev_t bdf, unsigned long dev_iobase,
+#ifdef CONFIG_DM_ETH
+static int rtl_recv_common(struct udevice *dev, unsigned long dev_iobase,
+ uchar **packetp)
+#else
+static int rtl_recv_common(pci_dev_t dev, unsigned long dev_iobase,
uchar **packetp)
+#endif
{
/* return true if there's an ethernet packet ready to read */
/* nic->packet should contain data on return */
else
tpc->RxDescArray[cur_rx].status =
cpu_to_le32(OWNbit + RX_BUF_SIZE);
+#ifdef CONFIG_DM_ETH
tpc->RxDescArray[cur_rx].buf_addr = cpu_to_le32(
- pci_mem_to_phys(bdf, (pci_addr_t)(unsigned long)
+ dm_pci_mem_to_phys(dev,
+ (pci_addr_t)(unsigned long)
+ tpc->RxBufferRing[cur_rx]));
+#else
+ tpc->RxDescArray[cur_rx].buf_addr = cpu_to_le32(
+ pci_mem_to_phys(dev, (pci_addr_t)(unsigned long)
tpc->RxBufferRing[cur_rx]));
+#endif
rtl_flush_rx_desc(&tpc->RxDescArray[cur_rx]);
#ifdef CONFIG_DM_ETH
*packetp = rxdata;
{
struct rtl8169_private *priv = dev_get_priv(dev);
- return rtl_recv_common(dm_pci_get_bdf(dev), priv->iobase, packetp);
+ return rtl_recv_common(dev, priv->iobase, packetp);
}
#else
static int rtl_recv(struct eth_device *dev)
/**************************************************************************
SEND - Transmit a frame
***************************************************************************/
-static int rtl_send_common(pci_dev_t bdf, unsigned long dev_iobase,
+#ifdef CONFIG_DM_ETH
+static int rtl_send_common(struct udevice *dev, unsigned long dev_iobase,
void *packet, int length)
+#else
+static int rtl_send_common(pci_dev_t dev, unsigned long dev_iobase,
+ void *packet, int length)
+#endif
{
/* send the packet to destination */
/* point to the current txb incase multiple tx_rings are used */
ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE];
memcpy(ptxb, (char *)packet, (int)length);
- rtl_flush_buffer(ptxb, length);
while (len < ETH_ZLEN)
ptxb[len++] = '\0';
+ rtl_flush_buffer(ptxb, ALIGN(len, RTL8169_ALIGN));
+
tpc->TxDescArray[entry].buf_Haddr = 0;
+#ifdef CONFIG_DM_ETH
+ tpc->TxDescArray[entry].buf_addr = cpu_to_le32(
+ dm_pci_mem_to_phys(dev, (pci_addr_t)(unsigned long)ptxb));
+#else
tpc->TxDescArray[entry].buf_addr = cpu_to_le32(
- pci_mem_to_phys(bdf, (pci_addr_t)(unsigned long)ptxb));
+ pci_mem_to_phys(dev, (pci_addr_t)(unsigned long)ptxb));
+#endif
if (entry != (NUM_TX_DESC - 1)) {
tpc->TxDescArray[entry].status =
cpu_to_le32((OWNbit | FSbit | LSbit) |
puts("tx timeout/error\n");
printf("%s elapsed time : %lu\n", __func__, currticks()-stime);
#endif
- ret = 0;
+ ret = -ETIMEDOUT;
} else {
#ifdef DEBUG_RTL8169_TX
puts("tx done\n");
#endif
- ret = length;
+ ret = 0;
}
/* Delay to make net console (nc) work properly */
udelay(20);
{
struct rtl8169_private *priv = dev_get_priv(dev);
- return rtl_send_common(dm_pci_get_bdf(dev), priv->iobase, packet,
- length);
+ return rtl_send_common(dev, priv->iobase, packet, length);
}
#else
RTL_W32(MAR0 + 4, mc_filter[1]);
}
-static void rtl8169_hw_start(pci_dev_t bdf)
+#ifdef CONFIG_DM_ETH
+static void rtl8169_hw_start(struct udevice *dev)
+#else
+static void rtl8169_hw_start(pci_dev_t dev)
+#endif
{
u32 i;
tpc->cur_rx = 0;
- RTL_W32(TxDescStartAddrLow, pci_mem_to_phys(bdf,
+#ifdef CONFIG_DM_ETH
+ RTL_W32(TxDescStartAddrLow, dm_pci_mem_to_phys(dev,
(pci_addr_t)(unsigned long)tpc->TxDescArray));
+#else
+ RTL_W32(TxDescStartAddrLow, pci_mem_to_phys(dev,
+ (pci_addr_t)(unsigned long)tpc->TxDescArray));
+#endif
RTL_W32(TxDescStartAddrHigh, (unsigned long)0);
+#ifdef CONFIG_DM_ETH
+ RTL_W32(RxDescStartAddrLow, dm_pci_mem_to_phys(
+ dev, (pci_addr_t)(unsigned long)tpc->RxDescArray));
+#else
RTL_W32(RxDescStartAddrLow, pci_mem_to_phys(
- bdf, (pci_addr_t)(unsigned long)tpc->RxDescArray));
+ dev, (pci_addr_t)(unsigned long)tpc->RxDescArray));
+#endif
RTL_W32(RxDescStartAddrHigh, (unsigned long)0);
/* RTL-8169sc/8110sc or later version */
#endif
}
-static void rtl8169_init_ring(pci_dev_t bdf)
+#ifdef CONFIG_DM_ETH
+static void rtl8169_init_ring(struct udevice *dev)
+#else
+static void rtl8169_init_ring(pci_dev_t dev)
+#endif
{
int i;
cpu_to_le32(OWNbit + RX_BUF_SIZE);
tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE];
+#ifdef CONFIG_DM_ETH
+ tpc->RxDescArray[i].buf_addr = cpu_to_le32(dm_pci_mem_to_phys(
+ dev, (pci_addr_t)(unsigned long)tpc->RxBufferRing[i]));
+#else
tpc->RxDescArray[i].buf_addr = cpu_to_le32(pci_mem_to_phys(
- bdf, (pci_addr_t)(unsigned long)tpc->RxBufferRing[i]));
+ dev, (pci_addr_t)(unsigned long)tpc->RxBufferRing[i]));
+#endif
rtl_flush_rx_desc(&tpc->RxDescArray[i]);
}
#endif
}
-static void rtl8169_common_start(pci_dev_t bdf, unsigned char *enetaddr)
+#ifdef CONFIG_DM_ETH
+static void rtl8169_common_start(struct udevice *dev, unsigned char *enetaddr,
+ unsigned long dev_iobase)
+#else
+static void rtl8169_common_start(pci_dev_t dev, unsigned char *enetaddr,
+ unsigned long dev_iobase)
+#endif
{
int i;
printf ("%s\n", __FUNCTION__);
#endif
- rtl8169_init_ring(bdf);
- rtl8169_hw_start(bdf);
+ ioaddr = dev_iobase;
+
+ rtl8169_init_ring(dev);
+ rtl8169_hw_start(dev);
/* Construct a perfect filter frame with the mac address as first match
* and broadcast for all others */
for (i = 0; i < 192; i++)
static int rtl8169_eth_start(struct udevice *dev)
{
struct eth_pdata *plat = dev_get_platdata(dev);
+ struct rtl8169_private *priv = dev_get_priv(dev);
- rtl8169_common_start(dm_pci_get_bdf(dev), plat->enetaddr);
+ rtl8169_common_start(dev, plat->enetaddr, priv->iobase);
return 0;
}
static int rtl_reset(struct eth_device *dev, bd_t *bis)
{
rtl8169_common_start((pci_dev_t)(unsigned long)dev->priv,
- dev->enetaddr);
+ dev->enetaddr, dev->iobase);
return 0;
}
/* Force RTL8169 in 10/100/1000 Full/Half mode. */
if (option > 0) {
#ifdef DEBUG_RTL8169
- printf("%s: Force-mode Enabled.\n", dev->name);
+ printf("%s: Force-mode Enabled.\n", name);
#endif
Cap10_100 = 0, Cap1000 = 0;
switch (option) {
} else {
#ifdef DEBUG_RTL8169
printf("%s: Auto-negotiation Enabled.\n",
- dev->name);
+ name);
#endif
/* enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged */
mdio_write(PHY_AUTO_NEGO_REG,
if (option & _1000bpsF) {
#ifdef DEBUG_RTL8169
printf("%s: 1000Mbps Full-duplex operation.\n",
- dev->name);
+ name);
#endif
} else {
#ifdef DEBUG_RTL8169
printf("%s: %sMbps %s-duplex operation.\n",
- dev->name,
+ name,
(option & _100bps) ? "100" :
"10",
(option & FullDup) ? "Full" :
#ifdef DEBUG_RTL8169
printf
("%s: 1000Mbps Full-duplex operation, TBI Link %s!\n",
- dev->name,
+ name,
(RTL_R32(TBICSR) & TBILinkOK) ? "OK" : "Failed");
#endif
}
region = 1;
break;
}
- pci_read_config32(dm_pci_get_bdf(dev), PCI_BASE_ADDRESS_0 + region * 4,
- &iobase);
+ dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0 + region * 4, &iobase);
iobase &= ~0xf;
- priv->iobase = (int)pci_mem_to_phys(dm_pci_get_bdf(dev), iobase);
+ priv->iobase = (int)dm_pci_mem_to_phys(dev, iobase);
ret = rtl_init(priv->iobase, dev->name, plat->enetaddr);
if (ret < 0) {