u32 num_rx;
u32 cur_rx;
void __iomem *iobase;
+ void __iomem *packet;
+ phys_addr_t packet_phys;
};
/**
static int ethoc_init_ring(struct ethoc *priv)
{
struct ethoc_bd bd;
+ phys_addr_t addr = priv->packet_phys;
int i;
priv->cur_tx = 0;
bd.addr = 0;
for (i = 0; i < priv->num_tx; i++) {
+ if (addr) {
+ bd.addr = addr;
+ addr += PKTSIZE_ALIGN;
+ }
if (i == priv->num_tx - 1)
bd.stat |= TX_BD_WRAP;
bd.stat = RX_BD_EMPTY | RX_BD_IRQ;
for (i = 0; i < priv->num_rx; i++) {
- bd.addr = virt_to_phys(net_rx_packets[i]);
+ if (addr) {
+ bd.addr = addr;
+ addr += PKTSIZE_ALIGN;
+ } else {
+ bd.addr = virt_to_phys(net_rx_packets[i]);
+ }
if (i == priv->num_rx - 1)
bd.stat |= RX_BD_WRAP;
int size = bd.stat >> 16;
size -= 4; /* strip the CRC */
- *packetp = net_rx_packets[i];
+ if (priv->packet)
+ *packetp = priv->packet + entry * PKTSIZE_ALIGN;
+ else
+ *packetp = net_rx_packets[i];
return size;
} else {
return 0;
bd.stat |= TX_BD_PAD;
else
bd.stat &= ~TX_BD_PAD;
- bd.addr = virt_to_phys(packet);
+ if (priv->packet) {
+ void *p = priv->packet + entry * PKTSIZE_ALIGN;
+
+ memcpy(p, packet, length);
+ packet = p;
+ } else {
+ bd.addr = virt_to_phys(packet);
+ }
flush_dcache_range((ulong)packet, (ulong)packet + length);
bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK);
bd.stat |= TX_BD_LEN(length);
struct ethoc_bd bd;
u32 i = priv->cur_rx % priv->num_rx;
u32 entry = priv->num_tx + i;
+ void *src;
ethoc_read_bd(priv, entry, &bd);
+ if (priv->packet)
+ src = priv->packet + entry * PKTSIZE_ALIGN;
+ else
+ src = net_rx_packets[i];
/* clear the buffer descriptor so it can be reused */
- flush_dcache_range((ulong)net_rx_packets[i],
- (ulong)net_rx_packets[i] + PKTSIZE_ALIGN);
+ flush_dcache_range((ulong)src,
+ (ulong)src + PKTSIZE_ALIGN);
bd.stat &= ~RX_BD_STATS;
bd.stat |= RX_BD_EMPTY;
ethoc_write_bd(priv, entry, &bd);
static int ethoc_ofdata_to_platdata(struct udevice *dev)
{
struct ethoc_eth_pdata *pdata = dev_get_platdata(dev);
+ fdt_addr_t addr;
pdata->eth_pdata.iobase = dev_get_addr(dev);
+ addr = dev_get_addr_index(dev, 1);
+ if (addr != FDT_ADDR_T_NONE)
+ pdata->packet_base = addr;
return 0;
}
struct ethoc *priv = dev_get_priv(dev);
priv->iobase = ioremap(pdata->eth_pdata.iobase, ETHOC_IOSIZE);
+ if (pdata->packet_base) {
+ priv->packet_phys = pdata->packet_base;
+ priv->packet = ioremap(pdata->packet_base,
+ (1 + PKTBUFSRX) * PKTSIZE_ALIGN);
+ }
return 0;
}