提交 45993653 编写于 作者: U Uwe Kleine-König

net/fec: reorder functions a bit allows removing forward declarations

Signed-off-by: NUwe Kleine-König <u.kleine-koenig@pengutronix.de>
上级 db8880bc
...@@ -205,13 +205,6 @@ struct fec_enet_private { ...@@ -205,13 +205,6 @@ struct fec_enet_private {
struct completion mdio_done; struct completion mdio_done;
}; };
static irqreturn_t fec_enet_interrupt(int irq, void * dev_id);
static void fec_enet_tx(struct net_device *ndev);
static void fec_enet_rx(struct net_device *ndev);
static int fec_enet_close(struct net_device *ndev);
static void fec_restart(struct net_device *ndev, int duplex);
static void fec_stop(struct net_device *ndev);
/* FEC MII MMFR bits definition */ /* FEC MII MMFR bits definition */
#define FEC_MMFR_ST (1 << 30) #define FEC_MMFR_ST (1 << 30)
#define FEC_MMFR_OP_READ (2 << 28) #define FEC_MMFR_OP_READ (2 << 28)
...@@ -335,53 +328,159 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -335,53 +328,159 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }
/* This function is called to start or restart the FEC during a link
* change. This only happens when switching between half and full
* duplex.
*/
static void static void
fec_timeout(struct net_device *ndev) fec_restart(struct net_device *ndev, int duplex)
{ {
struct fec_enet_private *fep = netdev_priv(ndev); struct fec_enet_private *fep = netdev_priv(ndev);
const struct platform_device_id *id_entry =
platform_get_device_id(fep->pdev);
int i;
u32 val, temp_mac[2];
ndev->stats.tx_errors++; /* Whack a reset. We should wait for this. */
writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
fec_restart(ndev, fep->full_duplex); /*
netif_wake_queue(ndev); * enet-mac reset will reset mac address registers too,
} * so need to reconfigure it.
*/
if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
memcpy(&temp_mac, ndev->dev_addr, ETH_ALEN);
writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW);
writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH);
}
static irqreturn_t /* Clear any outstanding interrupt. */
fec_enet_interrupt(int irq, void *dev_id) writel(0xffc00000, fep->hwp + FEC_IEVENT);
{
struct net_device *ndev = dev_id;
struct fec_enet_private *fep = netdev_priv(ndev);
uint int_events;
irqreturn_t ret = IRQ_NONE;
do { /* Reset all multicast. */
int_events = readl(fep->hwp + FEC_IEVENT); writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
writel(int_events, fep->hwp + FEC_IEVENT); writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
#ifndef CONFIG_M5272
writel(0, fep->hwp + FEC_HASH_TABLE_HIGH);
writel(0, fep->hwp + FEC_HASH_TABLE_LOW);
#endif
if (int_events & FEC_ENET_RXF) { /* Set maximum receive buffer size. */
ret = IRQ_HANDLED; writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE);
fec_enet_rx(ndev);
}
/* Transmit OK, or non-fatal error. Update the buffer /* Set receive and transmit descriptor base. */
* descriptors. FEC handles all errors, we just discover writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
* them as part of the transmit process. writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE,
*/ fep->hwp + FEC_X_DES_START);
if (int_events & FEC_ENET_TXF) {
ret = IRQ_HANDLED; fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
fec_enet_tx(ndev); fep->cur_rx = fep->rx_bd_base;
/* Reset SKB transmit buffers. */
fep->skb_cur = fep->skb_dirty = 0;
for (i = 0; i <= TX_RING_MOD_MASK; i++) {
if (fep->tx_skbuff[i]) {
dev_kfree_skb_any(fep->tx_skbuff[i]);
fep->tx_skbuff[i] = NULL;
} }
}
if (int_events & FEC_ENET_MII) { /* Enable MII mode */
ret = IRQ_HANDLED; if (duplex) {
complete(&fep->mdio_done); /* MII enable / FD enable */
writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL);
writel(0x04, fep->hwp + FEC_X_CNTRL);
} else {
/* MII enable / No Rcv on Xmit */
writel(OPT_FRAME_SIZE | 0x06, fep->hwp + FEC_R_CNTRL);
writel(0x0, fep->hwp + FEC_X_CNTRL);
}
fep->full_duplex = duplex;
/* Set MII speed */
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
/*
* The phy interface and speed need to get configured
* differently on enet-mac.
*/
if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
val = readl(fep->hwp + FEC_R_CNTRL);
/* MII or RMII */
if (fep->phy_interface == PHY_INTERFACE_MODE_RMII)
val |= (1 << 8);
else
val &= ~(1 << 8);
/* 10M or 100M */
if (fep->phy_dev && fep->phy_dev->speed == SPEED_100)
val &= ~(1 << 9);
else
val |= (1 << 9);
writel(val, fep->hwp + FEC_R_CNTRL);
} else {
#ifdef FEC_MIIGSK_ENR
if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
/* disable the gasket and wait */
writel(0, fep->hwp + FEC_MIIGSK_ENR);
while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
udelay(1);
/*
* configure the gasket:
* RMII, 50 MHz, no loopback, no echo
*/
writel(1, fep->hwp + FEC_MIIGSK_CFGR);
/* re-enable the gasket */
writel(2, fep->hwp + FEC_MIIGSK_ENR);
} }
} while (int_events); #endif
}
return ret; /* And last, enable the transmit and receive processing */
writel(2, fep->hwp + FEC_ECNTRL);
writel(0, fep->hwp + FEC_R_DES_ACTIVE);
/* Enable interrupts we wish to service */
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
}
static void
fec_stop(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
/* We cannot expect a graceful transmit stop without link !!! */
if (fep->link) {
writel(1, fep->hwp + FEC_X_CNTRL); /* Graceful transmit stop */
udelay(10);
if (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_GRA))
printk("fec_stop : Graceful transmit stop did not complete !\n");
}
/* Whack a reset. We should wait for this. */
writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
} }
static void
fec_timeout(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
ndev->stats.tx_errors++;
fec_restart(ndev, fep->full_duplex);
netif_wake_queue(ndev);
}
static void static void
fec_enet_tx(struct net_device *ndev) fec_enet_tx(struct net_device *ndev)
{ {
...@@ -576,6 +675,43 @@ fec_enet_rx(struct net_device *ndev) ...@@ -576,6 +675,43 @@ fec_enet_rx(struct net_device *ndev)
spin_unlock(&fep->hw_lock); spin_unlock(&fep->hw_lock);
} }
static irqreturn_t
fec_enet_interrupt(int irq, void *dev_id)
{
struct net_device *ndev = dev_id;
struct fec_enet_private *fep = netdev_priv(ndev);
uint int_events;
irqreturn_t ret = IRQ_NONE;
do {
int_events = readl(fep->hwp + FEC_IEVENT);
writel(int_events, fep->hwp + FEC_IEVENT);
if (int_events & FEC_ENET_RXF) {
ret = IRQ_HANDLED;
fec_enet_rx(ndev);
}
/* Transmit OK, or non-fatal error. Update the buffer
* descriptors. FEC handles all errors, we just discover
* them as part of the transmit process.
*/
if (int_events & FEC_ENET_TXF) {
ret = IRQ_HANDLED;
fec_enet_tx(ndev);
}
if (int_events & FEC_ENET_MII) {
ret = IRQ_HANDLED;
complete(&fep->mdio_done);
}
} while (int_events);
return ret;
}
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
static void __inline__ fec_get_mac(struct net_device *ndev) static void __inline__ fec_get_mac(struct net_device *ndev)
{ {
...@@ -1217,147 +1353,6 @@ static int fec_enet_init(struct net_device *ndev) ...@@ -1217,147 +1353,6 @@ static int fec_enet_init(struct net_device *ndev)
return 0; return 0;
} }
/* This function is called to start or restart the FEC during a link
* change. This only happens when switching between half and full
* duplex.
*/
static void
fec_restart(struct net_device *ndev, int duplex)
{
struct fec_enet_private *fep = netdev_priv(ndev);
const struct platform_device_id *id_entry =
platform_get_device_id(fep->pdev);
int i;
u32 val, temp_mac[2];
/* Whack a reset. We should wait for this. */
writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
/*
* enet-mac reset will reset mac address registers too,
* so need to reconfigure it.
*/
if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
memcpy(&temp_mac, ndev->dev_addr, ETH_ALEN);
writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW);
writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH);
}
/* Clear any outstanding interrupt. */
writel(0xffc00000, fep->hwp + FEC_IEVENT);
/* Reset all multicast. */
writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
#ifndef CONFIG_M5272
writel(0, fep->hwp + FEC_HASH_TABLE_HIGH);
writel(0, fep->hwp + FEC_HASH_TABLE_LOW);
#endif
/* Set maximum receive buffer size. */
writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE);
/* Set receive and transmit descriptor base. */
writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE,
fep->hwp + FEC_X_DES_START);
fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
fep->cur_rx = fep->rx_bd_base;
/* Reset SKB transmit buffers. */
fep->skb_cur = fep->skb_dirty = 0;
for (i = 0; i <= TX_RING_MOD_MASK; i++) {
if (fep->tx_skbuff[i]) {
dev_kfree_skb_any(fep->tx_skbuff[i]);
fep->tx_skbuff[i] = NULL;
}
}
/* Enable MII mode */
if (duplex) {
/* MII enable / FD enable */
writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL);
writel(0x04, fep->hwp + FEC_X_CNTRL);
} else {
/* MII enable / No Rcv on Xmit */
writel(OPT_FRAME_SIZE | 0x06, fep->hwp + FEC_R_CNTRL);
writel(0x0, fep->hwp + FEC_X_CNTRL);
}
fep->full_duplex = duplex;
/* Set MII speed */
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
/*
* The phy interface and speed need to get configured
* differently on enet-mac.
*/
if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
val = readl(fep->hwp + FEC_R_CNTRL);
/* MII or RMII */
if (fep->phy_interface == PHY_INTERFACE_MODE_RMII)
val |= (1 << 8);
else
val &= ~(1 << 8);
/* 10M or 100M */
if (fep->phy_dev && fep->phy_dev->speed == SPEED_100)
val &= ~(1 << 9);
else
val |= (1 << 9);
writel(val, fep->hwp + FEC_R_CNTRL);
} else {
#ifdef FEC_MIIGSK_ENR
if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
/* disable the gasket and wait */
writel(0, fep->hwp + FEC_MIIGSK_ENR);
while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
udelay(1);
/*
* configure the gasket:
* RMII, 50 MHz, no loopback, no echo
*/
writel(1, fep->hwp + FEC_MIIGSK_CFGR);
/* re-enable the gasket */
writel(2, fep->hwp + FEC_MIIGSK_ENR);
}
#endif
}
/* And last, enable the transmit and receive processing */
writel(2, fep->hwp + FEC_ECNTRL);
writel(0, fep->hwp + FEC_R_DES_ACTIVE);
/* Enable interrupts we wish to service */
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
}
static void
fec_stop(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
/* We cannot expect a graceful transmit stop without link !!! */
if (fep->link) {
writel(1, fep->hwp + FEC_X_CNTRL); /* Graceful transmit stop */
udelay(10);
if (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_GRA))
printk("fec_stop : Graceful transmit stop did not complete !\n");
}
/* Whack a reset. We should wait for this. */
writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
}
static int __devinit static int __devinit
fec_probe(struct platform_device *pdev) fec_probe(struct platform_device *pdev)
{ {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册