Merge branch 'for-next/net'
Conflicts: drivers/net/dm9k.c
This commit is contained in:
commit
a3dfea9af8
|
@ -80,6 +80,7 @@ config DRIVER_NET_EP93XX
|
|||
|
||||
config DRIVER_NET_ETHOC
|
||||
bool "OpenCores ethernet MAC driver"
|
||||
select PHYLIB
|
||||
help
|
||||
This option enables support for the OpenCores 10/100 Mbps
|
||||
Ethernet MAC core.
|
||||
|
|
|
@ -402,7 +402,7 @@ static int tse_eth_rx(struct eth_device *edev)
|
|||
ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK) {
|
||||
|
||||
packet_length = rx_desc->actual_bytes_transferred;
|
||||
net_receive(NetRxPackets[0], packet_length);
|
||||
net_receive(edev, NetRxPackets[0], packet_length);
|
||||
|
||||
/* Clear Run */
|
||||
rx_sgdma->control = (rx_sgdma->control & (~ALT_SGDMA_CONTROL_RUN_MSK));
|
||||
|
|
|
@ -217,7 +217,7 @@ static int ar231x_eth_recv(struct eth_device *edev)
|
|||
u16 length =
|
||||
((status >> DMA_RX_LEN_SHIFT) & 0x3fff)
|
||||
- CRC_LEN;
|
||||
net_receive((void *)rxdsc->buffer_ptr, length);
|
||||
net_receive(edev, (void *)rxdsc->buffer_ptr, length);
|
||||
}
|
||||
/* Clean descriptor. now it is owned by DMA. */
|
||||
priv->next_rxdsc = (struct ar231x_descr *)rxdsc->next_dsc_ptr;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
|
||||
#include <asm/mmu.h>
|
||||
#include <clock.h>
|
||||
#include <common.h>
|
||||
#include <net.h>
|
||||
#include <io.h>
|
||||
|
@ -209,9 +210,6 @@ static int arc_emac_open(struct eth_device *edev)
|
|||
arc_reg_set(priv, R_RX_RING, (unsigned int)priv->rxbd);
|
||||
arc_reg_set(priv, R_TX_RING, (unsigned int)priv->txbd);
|
||||
|
||||
/* Enable interrupts */
|
||||
arc_reg_set(priv, R_ENABLE, RXINT_MASK | ERR_MASK);
|
||||
|
||||
/* Set CONTROL */
|
||||
arc_reg_set(priv, R_CTRL,
|
||||
(RX_BD_NUM << 24) | /* RX BD table length */
|
||||
|
@ -304,7 +302,7 @@ static int arc_emac_recv(struct eth_device *edev)
|
|||
dma_inv_range((unsigned long)rxbd->data,
|
||||
(unsigned long)rxbd->data + pktlen);
|
||||
|
||||
net_receive((unsigned char *)rxbd->data, pktlen);
|
||||
net_receive(edev, (unsigned char *)rxbd->data, pktlen);
|
||||
|
||||
rxbd->info = cpu_to_le32(FOR_EMAC | PKTSIZE);
|
||||
}
|
||||
|
@ -316,9 +314,6 @@ static void arc_emac_halt(struct eth_device *edev)
|
|||
{
|
||||
struct arc_emac_priv *priv = edev->priv;
|
||||
|
||||
/* Disable interrupts */
|
||||
arc_reg_clr(priv, R_ENABLE, RXINT_MASK | ERR_MASK);
|
||||
|
||||
/* Disable EMAC */
|
||||
arc_reg_clr(priv, R_CTRL, EN_MASK);
|
||||
}
|
||||
|
@ -342,26 +337,18 @@ static int arc_emac_set_ethaddr(struct eth_device *edev, unsigned char *mac)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Number of seconds we wait for "MDIO complete" flag to appear */
|
||||
#define ARC_MDIO_COMPLETE_POLL_COUNT 1
|
||||
|
||||
static int arc_mdio_complete_wait(struct arc_emac_priv *priv)
|
||||
{
|
||||
unsigned int i;
|
||||
uint64_t start = get_time_ns();
|
||||
|
||||
for (i = 0; i < ARC_MDIO_COMPLETE_POLL_COUNT * 40; i++) {
|
||||
unsigned int status = arc_reg_get(priv, R_STATUS);
|
||||
|
||||
status &= MDIO_MASK;
|
||||
|
||||
if (status) {
|
||||
while (!is_timeout(start, 1000 * MSECOND)) {
|
||||
if (arc_reg_get(priv, R_STATUS) & MDIO_MASK) {
|
||||
/* Reset "MDIO complete" flag */
|
||||
arc_reg_set(priv, R_STATUS, status);
|
||||
arc_reg_set(priv, R_STATUS, MDIO_MASK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mdelay(25);
|
||||
}
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -447,6 +434,9 @@ static int arc_emac_probe(struct device_d *dev)
|
|||
/* Set poll rate so that it polls every 1 ms */
|
||||
arc_reg_set(priv, R_POLLRATE, clock_frequency / 1000000);
|
||||
|
||||
/* Disable interrupts */
|
||||
arc_reg_set(priv, R_ENABLE, 0);
|
||||
|
||||
mdiobus_register(miibus);
|
||||
eth_register(edev);
|
||||
|
||||
|
|
|
@ -224,7 +224,7 @@ static int at91_ether_rx(struct eth_device *edev)
|
|||
|
||||
size = rbfp->size & RBF_SIZE;
|
||||
|
||||
net_receive((unsigned char *)(rbfp->addr & RBF_ADDR), size);
|
||||
net_receive(edev, (unsigned char *)(rbfp->addr & RBF_ADDR), size);
|
||||
|
||||
rbfp->addr &= ~RBF_OWNER;
|
||||
if (rbfp->addr & RBF_WRAP)
|
||||
|
|
|
@ -178,11 +178,11 @@ struct cpsw_slave {
|
|||
struct cpsw_slave_regs *regs;
|
||||
struct cpsw_sliver_regs *sliver;
|
||||
int slave_num;
|
||||
u32 mac_control;
|
||||
int phy_id;
|
||||
phy_interface_t phy_if;
|
||||
struct eth_device edev;
|
||||
struct cpsw_priv *cpsw;
|
||||
struct device_d dev;
|
||||
};
|
||||
|
||||
struct cpdma_desc {
|
||||
|
@ -540,9 +540,8 @@ static inline void soft_reset(struct cpsw_priv *priv, void *reg)
|
|||
static int cpsw_get_hwaddr(struct eth_device *edev, unsigned char *mac)
|
||||
{
|
||||
struct cpsw_slave *slave = edev->priv;
|
||||
struct cpsw_priv *priv = slave->cpsw;
|
||||
|
||||
dev_dbg(priv->dev, "* %s\n", __func__);
|
||||
dev_dbg(&slave->dev, "* %s\n", __func__);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -552,7 +551,7 @@ static int cpsw_set_hwaddr(struct eth_device *edev, unsigned char *mac)
|
|||
struct cpsw_slave *slave = edev->priv;
|
||||
struct cpsw_priv *priv = slave->cpsw;
|
||||
|
||||
dev_dbg(priv->dev, "* %s\n", __func__);
|
||||
dev_dbg(&slave->dev, "* %s\n", __func__);
|
||||
|
||||
memcpy(&priv->mac_addr, mac, sizeof(priv->mac_addr));
|
||||
|
||||
|
@ -568,14 +567,11 @@ static void cpsw_slave_update_link(struct cpsw_slave *slave,
|
|||
struct phy_device *phydev = slave->edev.phydev;
|
||||
u32 mac_control = 0;
|
||||
|
||||
dev_dbg(priv->dev, "* %s\n", __func__);
|
||||
dev_dbg(&slave->dev, "* %s\n", __func__);
|
||||
|
||||
if (!phydev)
|
||||
return;
|
||||
|
||||
if (slave->slave_num)
|
||||
return;
|
||||
|
||||
if (phydev->link) {
|
||||
*link = 1;
|
||||
mac_control = BIT(5); /* MIIEN */
|
||||
|
@ -590,26 +586,22 @@ static void cpsw_slave_update_link(struct cpsw_slave *slave,
|
|||
mac_control |= BIT(0); /* FULLDUPLEXEN */
|
||||
}
|
||||
|
||||
if (mac_control == slave->mac_control)
|
||||
return;
|
||||
|
||||
if (mac_control) {
|
||||
dev_dbg(priv->dev, "link up on port %d, speed %d, %s duplex\n",
|
||||
slave->slave_num, phydev->speed,
|
||||
dev_dbg(&slave->dev, "link up, speed %d, %s duplex\n",
|
||||
phydev->speed,
|
||||
(phydev->duplex == DUPLEX_FULL) ? "full" : "half");
|
||||
} else {
|
||||
dev_dbg(priv->dev, "link down on port %d\n", slave->slave_num);
|
||||
dev_dbg(&slave->dev, "link down\n");
|
||||
}
|
||||
|
||||
writel(mac_control, &slave->sliver->mac_control);
|
||||
slave->mac_control = mac_control;
|
||||
}
|
||||
|
||||
static int cpsw_update_link(struct cpsw_slave *slave, struct cpsw_priv *priv)
|
||||
{
|
||||
int link = 0;
|
||||
|
||||
dev_dbg(priv->dev, "* %s\n", __func__);
|
||||
dev_dbg(&slave->dev, "* %s\n", __func__);
|
||||
|
||||
cpsw_slave_update_link(slave, priv, &link);
|
||||
|
||||
|
@ -621,7 +613,7 @@ static void cpsw_adjust_link(struct eth_device *edev)
|
|||
struct cpsw_slave *slave = edev->priv;
|
||||
struct cpsw_priv *priv = slave->cpsw;
|
||||
|
||||
dev_dbg(priv->dev, "* %s\n", __func__);
|
||||
dev_dbg(&slave->dev, "* %s\n", __func__);
|
||||
|
||||
cpsw_update_link(slave, priv);
|
||||
}
|
||||
|
@ -638,7 +630,7 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv)
|
|||
{
|
||||
u32 slave_port;
|
||||
|
||||
dev_dbg(priv->dev, "* %s\n", __func__);
|
||||
dev_dbg(&slave->dev, "* %s\n", __func__);
|
||||
|
||||
soft_reset(priv, &slave->sliver->soft_reset);
|
||||
|
||||
|
@ -649,8 +641,6 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv)
|
|||
/* setup max packet size, and mac address */
|
||||
writel(PKT_MAX, &slave->sliver->rx_maxlen);
|
||||
|
||||
slave->mac_control = 0; /* no link yet */
|
||||
|
||||
/* enable forwarding */
|
||||
slave_port = cpsw_get_slave_port(priv, slave->slave_num);
|
||||
cpsw_ale_port_state(priv, slave_port, ALE_PORT_STATE_FORWARD);
|
||||
|
@ -769,7 +759,7 @@ static int cpsw_open(struct eth_device *edev)
|
|||
struct cpsw_priv *priv = slave->cpsw;
|
||||
int i, ret;
|
||||
|
||||
dev_dbg(priv->dev, "* %s\n", __func__);
|
||||
dev_dbg(&slave->dev, "* %s\n", __func__);
|
||||
|
||||
ret = phy_device_connect(edev, &priv->miibus, slave->phy_id,
|
||||
cpsw_adjust_link, 0, slave->phy_if);
|
||||
|
@ -801,8 +791,8 @@ static int cpsw_open(struct eth_device *edev)
|
|||
ALE_SECURE);
|
||||
cpsw_ale_add_mcast(priv, ethbdaddr, 1 << priv->host_port);
|
||||
|
||||
cpsw_slave_init(&priv->slaves[0], priv);
|
||||
cpsw_update_link(&priv->slaves[0], priv);
|
||||
cpsw_slave_init(slave, priv);
|
||||
cpsw_update_link(slave, priv);
|
||||
|
||||
/* init descriptor pool */
|
||||
for (i = 0; i < NUM_DESCS; i++) {
|
||||
|
@ -842,7 +832,7 @@ static int cpsw_open(struct eth_device *edev)
|
|||
ret = cpdma_submit(priv, &priv->rx_chan, NetRxPackets[i],
|
||||
PKTSIZE);
|
||||
if (ret < 0) {
|
||||
dev_err(priv->dev, "error %d submitting rx desc\n", ret);
|
||||
dev_err(&slave->dev, "error %d submitting rx desc\n", ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -855,6 +845,8 @@ static void cpsw_halt(struct eth_device *edev)
|
|||
struct cpsw_slave *slave = edev->priv;
|
||||
struct cpsw_priv *priv = slave->cpsw;
|
||||
|
||||
dev_dbg(priv->dev, "* %s slave %d\n", __func__, slave->slave_num);
|
||||
|
||||
writel(0, priv->dma_regs + CPDMA_TXCONTROL);
|
||||
writel(0, priv->dma_regs + CPDMA_RXCONTROL);
|
||||
|
||||
|
@ -872,12 +864,12 @@ static int cpsw_send(struct eth_device *edev, void *packet, int length)
|
|||
void *buffer;
|
||||
int ret, len;
|
||||
|
||||
dev_dbg(priv->dev, "* %s\n", __func__);
|
||||
dev_dbg(&slave->dev, "* %s slave %d\n", __func__, slave->slave_num);
|
||||
|
||||
/* first reap completed packets */
|
||||
while (cpdma_process(priv, &priv->tx_chan, &buffer, &len) >= 0);
|
||||
|
||||
dev_dbg(priv->dev, "%s: %i bytes @ 0x%p\n", __func__, length, packet);
|
||||
dev_dbg(&slave->dev, "%s: %i bytes @ 0x%p\n", __func__, length, packet);
|
||||
|
||||
dma_flush_range((ulong) packet, (ulong)packet + length);
|
||||
|
||||
|
@ -895,7 +887,7 @@ static int cpsw_recv(struct eth_device *edev)
|
|||
|
||||
while (cpdma_process(priv, &priv->rx_chan, &buffer, &len) >= 0) {
|
||||
dma_inv_range((ulong)buffer, (ulong)buffer + len);
|
||||
net_receive(buffer, len);
|
||||
net_receive(edev, buffer, len);
|
||||
cpdma_submit(priv, &priv->rx_chan, buffer, PKTSIZE);
|
||||
}
|
||||
|
||||
|
@ -916,8 +908,17 @@ static int cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
|
|||
{
|
||||
void *regs = priv->regs;
|
||||
struct eth_device *edev = &slave->edev;
|
||||
struct device_d *dev = &slave->dev;
|
||||
int ret;
|
||||
|
||||
dev_dbg(priv->dev, "* %s\n", __func__);
|
||||
sprintf(dev->name, "cpsw-slave");
|
||||
dev->id = slave->slave_num;
|
||||
dev->parent = priv->dev;
|
||||
ret = register_device(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_dbg(&slave->dev, "* %s\n", __func__);
|
||||
|
||||
slave->slave_num = slave_num;
|
||||
slave->regs = regs + priv->slave_ofs + priv->slave_size * slave_num;
|
||||
|
@ -932,7 +933,7 @@ static int cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
|
|||
edev->recv = cpsw_recv;
|
||||
edev->get_ethaddr = cpsw_get_hwaddr;
|
||||
edev->set_ethaddr = cpsw_set_hwaddr;
|
||||
edev->parent = priv->dev;
|
||||
edev->parent = dev;
|
||||
|
||||
return eth_register(edev);
|
||||
}
|
||||
|
@ -1077,6 +1078,7 @@ static int cpsw_probe_dt(struct cpsw_priv *priv)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
slave->dev.device_node = child;
|
||||
slave->phy_id = phy_id[1];
|
||||
slave->phy_if = of_get_phy_mode(child);
|
||||
slave->slave_num = i;
|
||||
|
@ -1091,9 +1093,6 @@ static int cpsw_probe_dt(struct cpsw_priv *priv)
|
|||
cpsw_gmii_sel_am335x(slave);
|
||||
}
|
||||
|
||||
/* Only one slave supported by this driver */
|
||||
priv->num_slaves = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1105,7 +1104,7 @@ int cpsw_probe(struct device_d *dev)
|
|||
uint64_t start;
|
||||
uint32_t phy_mask;
|
||||
struct cpsw_data *cpsw_data;
|
||||
int ret;
|
||||
int i, ret;
|
||||
|
||||
dev_dbg(dev, "* %s\n", __func__);
|
||||
|
||||
|
@ -1197,9 +1196,11 @@ int cpsw_probe(struct device_d *dev)
|
|||
|
||||
mdiobus_register(&priv->miibus);
|
||||
|
||||
ret = cpsw_slave_setup(&priv->slaves[0], 0, priv);
|
||||
if (ret)
|
||||
goto out;
|
||||
for (i = 0; i < priv->num_slaves; i++) {
|
||||
ret = cpsw_slave_setup(&priv->slaves[i], i, priv);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out:
|
||||
|
|
|
@ -309,7 +309,7 @@ static int cs8900_recv(struct eth_device *dev)
|
|||
if (len & 1) {
|
||||
*addr++ = readw(priv->regs + CS8900_RTDATA0);
|
||||
}
|
||||
net_receive(NetRxPackets[0], len);
|
||||
net_receive(dev, NetRxPackets[0], len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
|
|
@ -462,7 +462,7 @@ static int davinci_emac_recv(struct eth_device *edev)
|
|||
dev_dbg(priv->dev, "| emac_recv got packet (length %i)\n", len);
|
||||
dma_inv_range((ulong)pkt,
|
||||
(ulong)readl(rx_curr_desc + EMAC_DESC_BUFFER) + len);
|
||||
net_receive(pkt, len);
|
||||
net_receive(edev, pkt, len);
|
||||
ret = len;
|
||||
}
|
||||
|
||||
|
|
|
@ -356,7 +356,7 @@ static int dwc_ether_rx(struct eth_device *dev)
|
|||
dma_inv_range((unsigned long)desc_p->dmamac_addr,
|
||||
(unsigned long)desc_p->dmamac_addr + length);
|
||||
|
||||
net_receive(desc_p->dmamac_addr, length);
|
||||
net_receive(dev, desc_p->dmamac_addr, length);
|
||||
|
||||
desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
|
||||
|
||||
|
|
|
@ -634,7 +634,7 @@ static int dm9k_eth_rx(struct eth_device *edev)
|
|||
dev_dbg(dev, "Receiving packet\n");
|
||||
dm9k_rd(priv->buswidth, priv->iodata, priv->pckt, rx_len);
|
||||
dev_dbg(dev, "passing %u bytes packet to upper layer\n", rx_len);
|
||||
net_receive(priv->pckt, rx_len);
|
||||
net_receive(edev, priv->pckt, rx_len);
|
||||
return 0;
|
||||
} else {
|
||||
dev_dbg(dev, "Discarding packet\n");
|
||||
|
|
|
@ -344,7 +344,7 @@ static int ep93xx_eth_rcv_packet(struct eth_device *edev)
|
|||
* used when we pass the data off to the protocol
|
||||
* layer via net_receive().
|
||||
*/
|
||||
net_receive((uchar *)priv->rx_dq.current->word1,
|
||||
net_receive(edev, (uchar *)priv->rx_dq.current->word1,
|
||||
RX_STATUS_FRAME_LEN(priv->rx_sq.current));
|
||||
pr_debug("reporting %d bytes...\n",
|
||||
RX_STATUS_FRAME_LEN(priv->rx_sq.current));
|
||||
|
|
|
@ -178,6 +178,8 @@ struct ethoc {
|
|||
|
||||
u32 num_rx;
|
||||
u32 cur_rx;
|
||||
|
||||
struct mii_bus miibus;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -369,7 +371,7 @@ static int ethoc_rx(struct eth_device *edev, int limit)
|
|||
|
||||
size -= 4; /* strip the CRC */
|
||||
invalidate_dcache_range(bd.addr, bd.addr + PKTSIZE);
|
||||
net_receive((unsigned char *)bd.addr, size);
|
||||
net_receive(edev, (unsigned char *)bd.addr, size);
|
||||
}
|
||||
|
||||
/* clear the buffer descriptor so it can be reused */
|
||||
|
@ -481,6 +483,54 @@ static int ethoc_send_packet(struct eth_device *edev, void *packet, int length)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ethoc_mdio_read(struct mii_bus *bus, int phy, int reg)
|
||||
{
|
||||
struct ethoc *priv = bus->priv;
|
||||
u64 start;
|
||||
u32 data;
|
||||
|
||||
ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(phy, reg));
|
||||
ethoc_write(priv, MIICOMMAND, MIICOMMAND_READ);
|
||||
|
||||
start = get_time_ns();
|
||||
while (ethoc_read(priv, MIISTATUS) & MIISTATUS_BUSY) {
|
||||
if (is_timeout(start, 2 * MSECOND)) {
|
||||
dev_err(bus->parent, "PHY command timeout\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
data = ethoc_read(priv, MIIRX_DATA);
|
||||
|
||||
/* reset MII command register */
|
||||
ethoc_write(priv, MIICOMMAND, 0);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static int ethoc_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
|
||||
{
|
||||
struct ethoc *priv = bus->priv;
|
||||
u64 start;
|
||||
|
||||
ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(phy, reg));
|
||||
ethoc_write(priv, MIITX_DATA, val);
|
||||
ethoc_write(priv, MIICOMMAND, MIICOMMAND_WRITE);
|
||||
|
||||
start = get_time_ns();
|
||||
while (ethoc_read(priv, MIISTATUS) & MIISTATUS_BUSY) {
|
||||
if (is_timeout(start, 2 * MSECOND)) {
|
||||
dev_err(bus->parent, "PHY command timeout\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/* reset MII command register */
|
||||
ethoc_write(priv, MIICOMMAND, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ethoc_probe(struct device_d *dev)
|
||||
{
|
||||
struct eth_device *edev;
|
||||
|
@ -493,6 +543,11 @@ static int ethoc_probe(struct device_d *dev)
|
|||
priv = edev->priv;
|
||||
priv->iobase = dev_request_mem_region(dev, 0);
|
||||
|
||||
priv->miibus.read = ethoc_mdio_read;
|
||||
priv->miibus.write = ethoc_mdio_write;
|
||||
priv->miibus.priv = priv;
|
||||
priv->miibus.parent = dev;
|
||||
|
||||
edev->init = ethoc_init_dev;
|
||||
edev->open = ethoc_open;
|
||||
edev->send = ethoc_send_packet;
|
||||
|
@ -503,6 +558,8 @@ static int ethoc_probe(struct device_d *dev)
|
|||
edev->set_ethaddr = ethoc_set_ethaddr;
|
||||
edev->parent = dev;
|
||||
|
||||
mdiobus_register(&priv->miibus);
|
||||
|
||||
eth_register(edev);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -581,7 +581,7 @@ static int fec_recv(struct eth_device *dev)
|
|||
*/
|
||||
frame = phys_to_virt(readl(&rbd->data_pointer));
|
||||
frame_length = readw(&rbd->data_length) - 4;
|
||||
net_receive(frame->data, frame_length);
|
||||
net_receive(dev, frame->data, frame_length);
|
||||
len = frame_length;
|
||||
} else {
|
||||
if (bd_status & FEC_RBD_ERR) {
|
||||
|
|
|
@ -622,7 +622,7 @@ static int mpc5xxx_fec_recv(struct eth_device *dev)
|
|||
*/
|
||||
memcpy(buff, frame->head, 14);
|
||||
memcpy(buff + 14, frame->data, frame_length);
|
||||
net_receive(buff, frame_length);
|
||||
net_receive(dev, buff, frame_length);
|
||||
len = frame_length;
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -413,7 +413,7 @@ static int gfar_recv(struct eth_device *edev)
|
|||
|
||||
/* Send the packet up if there were no errors */
|
||||
if (!(priv->rxbd[priv->rxidx].status & RXBD_STATS)) {
|
||||
net_receive(NetRxPackets[priv->rxidx], length - 4);
|
||||
net_receive(edev, NetRxPackets[priv->rxidx], length - 4);
|
||||
} else {
|
||||
dev_err(dev, "Got error %x\n",
|
||||
(priv->rxbd[priv->rxidx].status & RXBD_STATS));
|
||||
|
|
|
@ -693,7 +693,7 @@ static int ks8851_rx_frame(struct ks_net *ks)
|
|||
if (RxStatus & RXFSHR_RXFV) {
|
||||
/* Pass to upper layer */
|
||||
dev_dbg(dev, "passing packet to upper layer\n\n");
|
||||
net_receive(NetRxPackets[0], RxLen);
|
||||
net_receive(&ks->edev, NetRxPackets[0], RxLen);
|
||||
return RxLen;
|
||||
} else if (RxStatus & RXFSHR_ERR) {
|
||||
dev_err(dev, "RxStatus error 0x%04x\n", RxStatus & RXFSHR_ERR);
|
||||
|
|
|
@ -187,7 +187,7 @@ static int gem_recv(struct eth_device *edev)
|
|||
status = macb->rx_ring[macb->rx_tail].ctrl;
|
||||
length = MACB_BFEXT(RX_FRMLEN, status);
|
||||
buffer = macb->rx_buffer + macb->rx_buffer_size * macb->rx_tail;
|
||||
net_receive(buffer, length);
|
||||
net_receive(edev, buffer, length);
|
||||
macb->rx_ring[macb->rx_tail].addr &= ~MACB_BIT(RX_USED);
|
||||
barrier();
|
||||
|
||||
|
@ -237,7 +237,7 @@ static int macb_recv(struct eth_device *edev)
|
|||
buffer = (void *)NetRxPackets[0];
|
||||
}
|
||||
|
||||
net_receive(buffer, length);
|
||||
net_receive(edev, buffer, length);
|
||||
if (++rx_tail >= macb->rx_ring_size)
|
||||
rx_tail = 0;
|
||||
reclaim_rx_buffers(macb, rx_tail);
|
||||
|
|
|
@ -110,7 +110,7 @@ static int netx_eth_rx (struct eth_device *edev)
|
|||
/* get data */
|
||||
memcpy((void*)NetRxPackets[0], (void *)(SRAM_BASE(seg) + frameno * 1560), len);
|
||||
/* pass to barebox */
|
||||
net_receive(NetRxPackets[0], len);
|
||||
net_receive(edev, NetRxPackets[0], len);
|
||||
|
||||
PFIFO_REG(PFIFO_BASE(EMPTY_PTR_FIFO(xcno))) =
|
||||
FIFO_PTR_SEGMENT(seg) |
|
||||
|
|
|
@ -303,7 +303,7 @@ static int port_recv(struct eth_device *edev)
|
|||
ALIGN(PKTSIZE, 8));
|
||||
|
||||
/* received packet is padded with two null bytes */
|
||||
net_receive(rxdesc->buf_ptr + 0x2, rxdesc->byte_cnt - 0x2);
|
||||
net_receive(edev, rxdesc->buf_ptr + 0x2, rxdesc->byte_cnt - 0x2);
|
||||
ret = 0;
|
||||
|
||||
recv_err:
|
||||
|
|
|
@ -49,7 +49,7 @@ int phy_update_status(struct phy_device *dev)
|
|||
dev->adjust_link(edev);
|
||||
|
||||
if (dev->link)
|
||||
pr_info("%dMbps %s duplex link detected\n", dev->speed,
|
||||
dev_info(&edev->dev, "%dMbps %s duplex link detected\n", dev->speed,
|
||||
dev->duplex ? "full" : "half");
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1169,7 +1169,7 @@ static int smc91c111_eth_rx(struct eth_device *edev)
|
|||
|
||||
if (!is_error) {
|
||||
/* Pass the packet up to the protocol layers. */
|
||||
net_receive(NetRxPackets[0], packet_length);
|
||||
net_receive(edev, NetRxPackets[0], packet_length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -478,7 +478,7 @@ static int smc911x_eth_rx(struct eth_device *edev)
|
|||
dev_err(&edev->dev, "dropped bad packet. Status: 0x%08x\n",
|
||||
status);
|
||||
else
|
||||
net_receive(NetRxPackets[0], pktlen);
|
||||
net_receive(edev, NetRxPackets[0], pktlen);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -45,7 +45,7 @@ int tap_eth_rx (struct eth_device *edev)
|
|||
length = linux_read_nonblock(priv->fd, NetRxPackets[0], PKTSIZE);
|
||||
|
||||
if (length > 0)
|
||||
net_receive(NetRxPackets[0], length);
|
||||
net_receive(edev, NetRxPackets[0], length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -431,7 +431,7 @@ static int asix_rx_fixup(struct usbnet *dev, void *buf, int len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
net_receive(buf, size);
|
||||
net_receive(&dev->edev, buf, size);
|
||||
|
||||
buf += ((size + 1) & 0xfffe);
|
||||
len -= ((size + 1) & 0xfffe);
|
||||
|
|
|
@ -793,11 +793,11 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, void *buf, int len)
|
|||
|
||||
/* last frame in this batch */
|
||||
if (len == size) {
|
||||
net_receive(buf, len - 4);
|
||||
net_receive(&dev->edev, buf, len - 4);
|
||||
return 1;
|
||||
}
|
||||
|
||||
net_receive(packet, len - 4);
|
||||
net_receive(&dev->edev, packet, len - 4);
|
||||
}
|
||||
|
||||
len -= size;
|
||||
|
|
|
@ -138,7 +138,7 @@ static int usbnet_recv(struct eth_device *edev)
|
|||
if (info->rx_fixup)
|
||||
return info->rx_fixup(dev, rx_buf, alen);
|
||||
else
|
||||
net_receive(rx_buf, alen);
|
||||
net_receive(edev, rx_buf, alen);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -617,7 +617,7 @@ static int xgmac_recv(struct eth_device *edev)
|
|||
|
||||
length = desc_get_rx_frame_len(rxdesc);
|
||||
|
||||
net_receive(desc_get_buf_addr(rxdesc), length);
|
||||
net_receive(edev, desc_get_buf_addr(rxdesc), length);
|
||||
|
||||
/* set descriptor back to owned by XGMAC */
|
||||
desc_set_rx_owner(rxdesc);
|
||||
|
|
|
@ -68,7 +68,7 @@ struct eth_device {
|
|||
int eth_register(struct eth_device* dev); /* Register network device */
|
||||
void eth_unregister(struct eth_device* dev); /* Unregister network device */
|
||||
|
||||
int eth_send(void *packet, int length); /* Send a packet */
|
||||
int eth_send(struct eth_device *edev, void *packet, int length); /* Send a packet */
|
||||
int eth_rx(void); /* Check for received packets */
|
||||
|
||||
/* associate a MAC address to a ethernet device. Should be called by
|
||||
|
@ -413,12 +413,13 @@ struct eth_device *eth_get_byname(const char *name);
|
|||
*
|
||||
* Return 0 if the packet is successfully handled. Can be ignored
|
||||
*/
|
||||
int net_receive(unsigned char *pkt, int len);
|
||||
int net_receive(struct eth_device *edev, unsigned char *pkt, int len);
|
||||
|
||||
struct net_connection {
|
||||
struct ethernet *et;
|
||||
struct iphdr *ip;
|
||||
struct udphdr *udp;
|
||||
struct eth_device *edev;
|
||||
struct icmphdr *icmp;
|
||||
unsigned char *packet;
|
||||
struct list_head list;
|
||||
|
|
81
net/eth.c
81
net/eth.c
|
@ -131,11 +131,6 @@ void of_eth_register_ethaddr(struct device_node *node, const char *ethaddr)
|
|||
|
||||
void eth_set_current(struct eth_device *eth)
|
||||
{
|
||||
if (eth_current && eth_current->active) {
|
||||
eth_current->halt(eth_current);
|
||||
eth_current->active = 0;
|
||||
}
|
||||
|
||||
eth_current = eth;
|
||||
}
|
||||
|
||||
|
@ -178,83 +173,92 @@ int eth_complete(struct string_list *sl, char *instr)
|
|||
/*
|
||||
* Check for link if we haven't done so for longer.
|
||||
*/
|
||||
static int eth_carrier_check(int force)
|
||||
static int eth_carrier_check(struct eth_device *edev, int force)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_PHYLIB))
|
||||
return 0;
|
||||
|
||||
if (!eth_current->phydev)
|
||||
if (!edev->phydev)
|
||||
return 0;
|
||||
|
||||
if (force)
|
||||
phy_wait_aneg_done(eth_current->phydev);
|
||||
phy_wait_aneg_done(edev->phydev);
|
||||
|
||||
if (force || is_timeout(last_link_check, 5 * SECOND) ||
|
||||
!eth_current->phydev->link) {
|
||||
ret = phy_update_status(eth_current->phydev);
|
||||
!edev->phydev->link) {
|
||||
ret = phy_update_status(edev->phydev);
|
||||
if (ret)
|
||||
return ret;
|
||||
last_link_check = get_time_ns();
|
||||
}
|
||||
|
||||
return eth_current->phydev->link ? 0 : -ENETDOWN;
|
||||
return edev->phydev->link ? 0 : -ENETDOWN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we have a current ethernet device and
|
||||
* eventually open it if we have to.
|
||||
*/
|
||||
static int eth_check_open(void)
|
||||
static int eth_check_open(struct eth_device *edev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!eth_current)
|
||||
return -ENODEV;
|
||||
|
||||
if (eth_current->active)
|
||||
if (edev->active)
|
||||
return 0;
|
||||
|
||||
ret = eth_current->open(eth_current);
|
||||
ret = edev->open(eth_current);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
eth_current->active = 1;
|
||||
edev->active = 1;
|
||||
|
||||
return eth_carrier_check(1);
|
||||
return eth_carrier_check(edev, 1);
|
||||
}
|
||||
|
||||
int eth_send(void *packet, int length)
|
||||
int eth_send(struct eth_device *edev, void *packet, int length)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = eth_check_open();
|
||||
ret = eth_check_open(edev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = eth_carrier_check(0);
|
||||
ret = eth_carrier_check(edev, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
led_trigger_network(LED_TRIGGER_NET_TX);
|
||||
|
||||
return eth_current->send(eth_current, packet, length);
|
||||
return edev->send(eth_current, packet, length);
|
||||
}
|
||||
|
||||
static int __eth_rx(struct eth_device *edev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = eth_check_open(edev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = eth_carrier_check(edev, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return edev->recv(eth_current);
|
||||
}
|
||||
|
||||
int eth_rx(void)
|
||||
{
|
||||
int ret;
|
||||
struct eth_device *edev;
|
||||
|
||||
ret = eth_check_open();
|
||||
if (ret)
|
||||
return ret;
|
||||
list_for_each_entry(edev, &netdev_list, list) {
|
||||
if (edev->active)
|
||||
__eth_rx(edev);
|
||||
}
|
||||
|
||||
ret = eth_carrier_check(0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return eth_current->recv(eth_current);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eth_set_ethaddr(struct param_d *param, void *priv)
|
||||
|
@ -326,12 +330,21 @@ int eth_register(struct eth_device *edev)
|
|||
}
|
||||
|
||||
strcpy(edev->dev.name, "eth");
|
||||
edev->dev.id = DEVICE_ID_DYNAMIC;
|
||||
|
||||
if (edev->parent)
|
||||
edev->dev.parent = edev->parent;
|
||||
|
||||
register_device(&edev->dev);
|
||||
if (edev->dev.parent && edev->dev.parent->device_node) {
|
||||
edev->dev.id = of_alias_get_id(edev->dev.parent->device_node, "ethernet");
|
||||
if (edev->dev.id < 0)
|
||||
edev->dev.id = DEVICE_ID_DYNAMIC;
|
||||
} else {
|
||||
edev->dev.id = DEVICE_ID_DYNAMIC;
|
||||
}
|
||||
|
||||
ret = register_device(&edev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_add_param_ip(dev, "ipaddr", NULL, NULL, &edev->ipaddr, edev);
|
||||
dev_add_param_ip(dev, "serverip", NULL, NULL, &edev->serverip, edev);
|
||||
|
|
|
@ -58,6 +58,8 @@ int ifup(const char *name, unsigned flags)
|
|||
if (edev && edev->ipaddr && !(flags & IFUP_FLAG_FORCE))
|
||||
return 0;
|
||||
|
||||
eth_set_current(edev);
|
||||
|
||||
env_push_context();
|
||||
|
||||
setenv("ip", "");
|
||||
|
|
21
net/net.c
21
net/net.c
|
@ -241,7 +241,7 @@ static int arp_request(IPaddr_t dest, unsigned char *ether)
|
|||
|
||||
arp_ether = ether;
|
||||
|
||||
ret = eth_send(arp_packet, ETHER_HDR_SIZE + ARP_HDR_SIZE);
|
||||
ret = eth_send(edev, arp_packet, ETHER_HDR_SIZE + ARP_HDR_SIZE);
|
||||
if (ret)
|
||||
return ret;
|
||||
arp_start = get_time_ns();
|
||||
|
@ -253,7 +253,7 @@ static int arp_request(IPaddr_t dest, unsigned char *ether)
|
|||
if (is_timeout(arp_start, 3 * SECOND)) {
|
||||
printf("T ");
|
||||
arp_start = get_time_ns();
|
||||
ret = eth_send(arp_packet, ETHER_HDR_SIZE + ARP_HDR_SIZE);
|
||||
ret = eth_send(edev, arp_packet, ETHER_HDR_SIZE + ARP_HDR_SIZE);
|
||||
if (ret)
|
||||
return ret;
|
||||
retries++;
|
||||
|
@ -358,6 +358,7 @@ static struct net_connection *net_new(IPaddr_t dest, rx_handler_f *handler,
|
|||
con = xzalloc(sizeof(*con));
|
||||
con->packet = net_alloc_packet();
|
||||
con->priv = ctx;
|
||||
con->edev = edev;
|
||||
memset(con->packet, 0, PKTSIZE);
|
||||
|
||||
con->et = (struct ethernet *)con->packet;
|
||||
|
@ -437,7 +438,7 @@ static int net_ip_send(struct net_connection *con, int len)
|
|||
con->ip->check = 0;
|
||||
con->ip->check = ~net_checksum((unsigned char *)con->ip, sizeof(struct iphdr));
|
||||
|
||||
return eth_send(con->packet, ETHER_HDR_SIZE + sizeof(struct iphdr) + len);
|
||||
return eth_send(con->edev, con->packet, ETHER_HDR_SIZE + sizeof(struct iphdr) + len);
|
||||
}
|
||||
|
||||
int net_udp_send(struct net_connection *con, int len)
|
||||
|
@ -480,7 +481,7 @@ static int net_answer_arp(unsigned char *pkt, int len)
|
|||
if (!packet)
|
||||
return 0;
|
||||
memcpy(packet, pkt, ETHER_HDR_SIZE + ARP_HDR_SIZE);
|
||||
ret = eth_send(packet, ETHER_HDR_SIZE + ARP_HDR_SIZE);
|
||||
ret = eth_send(edev, packet, ETHER_HDR_SIZE + ARP_HDR_SIZE);
|
||||
free(packet);
|
||||
|
||||
return ret;
|
||||
|
@ -497,9 +498,8 @@ static void net_bad_packet(unsigned char *pkt, int len)
|
|||
#endif
|
||||
}
|
||||
|
||||
static int net_handle_arp(unsigned char *pkt, int len)
|
||||
static int net_handle_arp(struct eth_device *edev, unsigned char *pkt, int len)
|
||||
{
|
||||
struct eth_device *edev = eth_get_current();
|
||||
struct arprequest *arp;
|
||||
|
||||
debug("%s: got arp\n", __func__);
|
||||
|
@ -580,10 +580,9 @@ static int net_handle_icmp(unsigned char *pkt, int len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int net_handle_ip(unsigned char *pkt, int len)
|
||||
static int net_handle_ip(struct eth_device *edev, unsigned char *pkt, int len)
|
||||
{
|
||||
struct iphdr *ip = (struct iphdr *)(pkt + ETHER_HDR_SIZE);
|
||||
struct eth_device *edev = eth_get_current();
|
||||
IPaddr_t tmp;
|
||||
|
||||
debug("%s\n", __func__);
|
||||
|
@ -619,7 +618,7 @@ bad:
|
|||
return 0;
|
||||
}
|
||||
|
||||
int net_receive(unsigned char *pkt, int len)
|
||||
int net_receive(struct eth_device *edev, unsigned char *pkt, int len)
|
||||
{
|
||||
struct ethernet *et = (struct ethernet *)pkt;
|
||||
int et_protlen = ntohs(et->et_protlen);
|
||||
|
@ -634,10 +633,10 @@ int net_receive(unsigned char *pkt, int len)
|
|||
|
||||
switch (et_protlen) {
|
||||
case PROT_ARP:
|
||||
ret = net_handle_arp(pkt, len);
|
||||
ret = net_handle_arp(edev, pkt, len);
|
||||
break;
|
||||
case PROT_IP:
|
||||
ret = net_handle_ip(pkt, len);
|
||||
ret = net_handle_ip(edev, pkt, len);
|
||||
break;
|
||||
default:
|
||||
debug("%s: got unknown protocol type: %d\n", __func__, et_protlen);
|
||||
|
|
Loading…
Reference in New Issue