#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/pgtable.h>
+#include <asm/cacheflush.h>
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \
defined(CONFIG_M5272) || defined(CONFIG_M528x) || \
#define FEC_FLASHMAC 0xf0006006
#elif defined(CONFIG_GILBARCONAP) || defined(CONFIG_SCALES)
#define FEC_FLASHMAC 0xf0006000
-#elif defined (CONFIG_MTD_KeyTechnology)
-#define FEC_FLASHMAC 0xffe04000
#elif defined(CONFIG_CANCam)
#define FEC_FLASHMAC 0xf0020000
#elif defined (CONFIG_M5272C3)
/* Hardware registers of the FEC device */
volatile fec_t *hwp;
+ struct net_device *netdev;
+
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
unsigned char *tx_bounce[TX_RING_SIZE];
struct sk_buff* tx_skbuff[TX_RING_SIZE];
cbd_t *tx_bd_base;
cbd_t *cur_rx, *cur_tx; /* The next free ring entry */
cbd_t *dirty_tx; /* The ring entries to be free()ed. */
- struct net_device_stats stats;
uint tx_full;
spinlock_t lock;
static void fec_enet_tx(struct net_device *dev);
static void fec_enet_rx(struct net_device *dev);
static int fec_enet_close(struct net_device *dev);
-static struct net_device_stats *fec_enet_get_stats(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
static void fec_restart(struct net_device *dev, int duplex);
static void fec_stop(struct net_device *dev);
*/
fep->tx_skbuff[fep->skb_cur] = skb;
- fep->stats.tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK;
/* Push the data cache so the CPM does not get stale memory
struct fec_enet_private *fep = netdev_priv(dev);
printk("%s: transmit timed out.\n", dev->name);
- fep->stats.tx_errors++;
+ dev->stats.tx_errors++;
#ifndef final_version
{
int i;
if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC |
BD_ENET_TX_RL | BD_ENET_TX_UN |
BD_ENET_TX_CSL)) {
- fep->stats.tx_errors++;
+ dev->stats.tx_errors++;
if (status & BD_ENET_TX_HB) /* No heartbeat */
- fep->stats.tx_heartbeat_errors++;
+ dev->stats.tx_heartbeat_errors++;
if (status & BD_ENET_TX_LC) /* Late collision */
- fep->stats.tx_window_errors++;
+ dev->stats.tx_window_errors++;
if (status & BD_ENET_TX_RL) /* Retrans limit */
- fep->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
if (status & BD_ENET_TX_UN) /* Underrun */
- fep->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
if (status & BD_ENET_TX_CSL) /* Carrier lost */
- fep->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
} else {
- fep->stats.tx_packets++;
+ dev->stats.tx_packets++;
}
#ifndef final_version
* but we eventually sent the packet OK.
*/
if (status & BD_ENET_TX_DEF)
- fep->stats.collisions++;
+ dev->stats.collisions++;
/* Free the sk buffer associated with this last transmit.
*/
/* Check for errors. */
if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
BD_ENET_RX_CR | BD_ENET_RX_OV)) {
- fep->stats.rx_errors++;
+ dev->stats.rx_errors++;
if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
/* Frame too long or too short. */
- fep->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
}
if (status & BD_ENET_RX_NO) /* Frame alignment */
- fep->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if (status & BD_ENET_RX_CR) /* CRC Error */
- fep->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
if (status & BD_ENET_RX_OV) /* FIFO overrun */
- fep->stats.rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
}
/* Report late collisions as a frame error.
* have in the buffer. So, just drop this frame on the floor.
*/
if (status & BD_ENET_RX_CL) {
- fep->stats.rx_errors++;
- fep->stats.rx_frame_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_frame_errors++;
goto rx_processing_done;
}
/* Process the incoming frame.
*/
- fep->stats.rx_packets++;
+ dev->stats.rx_packets++;
pkt_len = bdp->cbd_datlen;
- fep->stats.rx_bytes += pkt_len;
+ dev->stats.rx_bytes += pkt_len;
data = (__u8*)__va(bdp->cbd_bufaddr);
/* This does 16 byte alignment, exactly what we need.
if (skb == NULL) {
printk("%s: Memory squeeze, dropping packet.\n", dev->name);
- fep->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
} else {
skb_put(skb,pkt_len-4); /* Make room */
skb_copy_to_linear_data(skb, data, pkt_len-4);
if (mii_head) {
mii_tail->mii_next = mip;
mii_tail = mip;
- }
- else {
+ } else {
mii_head = mii_tail = mip;
fep->hwp->fec_mii_data = regval;
}
- }
- else {
+ } else {
retval = 1;
}
static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c)
{
- int k;
-
if(!c)
return;
- for(k = 0; (c+k)->mii_data != mk_mii_end; k++) {
- mii_queue(dev, (c+k)->mii_data, (c+k)->funct);
- }
+ for (; c->mii_data != mk_mii_end; c++)
+ mii_queue(dev, c->mii_data, c->funct);
}
static void mii_parse_sr(uint mii_reg, struct net_device *dev)
status |= PHY_STAT_FAULT;
if (mii_reg & 0x0020)
status |= PHY_STAT_ANC;
-
*s = status;
}
#endif
#if defined(CONFIG_M5272)
-
/*
* Code specific to Coldfire 5272 setup.
*/
icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR3);
*icrp = 0x00000ddd;
icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
- *icrp = (*icrp & 0x70777777) | 0x0d000000;
+ *icrp = 0x0d000000;
}
static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
{
volatile unsigned long *icrp;
icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
- *icrp = (*icrp & 0x70777777) | 0x08000000;
+ *icrp = 0x08000000;
}
static void __inline__ fec_phy_ack_intr(void)
volatile unsigned long *icrp;
/* Acknowledge the interrupt */
icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
- *icrp = (*icrp & 0x77777777) | 0x08000000;
+ *icrp = 0x0d000000;
}
static void __inline__ fec_localhw_setup(void)
*gpio_pehlpar = 0xc0;
}
#endif
+
+#if defined(CONFIG_M527x)
+ /* Set up gpio outputs for MII lines */
+ {
+ volatile u8 *gpio_par_fec;
+ volatile u16 *gpio_par_feci2c;
+
+ gpio_par_feci2c = (volatile u16 *)(MCF_IPSBAR + 0x100082);
+ /* Set up gpio outputs for FEC0 MII lines */
+ gpio_par_fec = (volatile u8 *)(MCF_IPSBAR + 0x100078);
+
+ *gpio_par_feci2c |= 0x0f00;
+ *gpio_par_fec |= 0xc0;
+
+#if defined(CONFIG_FEC2)
+ /* Set up gpio outputs for FEC1 MII lines */
+ gpio_par_fec = (volatile u8 *)(MCF_IPSBAR + 0x100079);
+
+ *gpio_par_feci2c |= 0x00a0;
+ *gpio_par_fec |= 0xc0;
+#endif /* CONFIG_FEC2 */
+ }
+#endif /* CONFIG_M527x */
}
static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
printk(".\n");
}
-static void mii_display_config(struct net_device *dev)
+static void mii_display_config(struct work_struct *work)
{
- struct fec_enet_private *fep = netdev_priv(dev);
+ struct fec_enet_private *fep = container_of(work, struct fec_enet_private, phy_task);
+ struct net_device *dev = fep->netdev;
uint status = fep->phy_status;
/*
fep->sequence_done = 1;
}
-static void mii_relink(struct net_device *dev)
+static void mii_relink(struct work_struct *work)
{
- struct fec_enet_private *fep = netdev_priv(dev);
+ struct fec_enet_private *fep = container_of(work, struct fec_enet_private, phy_task);
+ struct net_device *dev = fep->netdev;
int duplex;
/*
& (PHY_STAT_100FDX | PHY_STAT_10FDX))
duplex = 1;
fec_restart(dev, duplex);
- }
- else
+ } else
fec_stop(dev);
#if 0
return;
fep->mii_phy_task_queued = 1;
- INIT_WORK(&fep->phy_task, (void*)mii_relink, dev);
+ INIT_WORK(&fep->phy_task, mii_relink);
schedule_work(&fep->phy_task);
}
return;
fep->mii_phy_task_queued = 1;
- INIT_WORK(&fep->phy_task, (void*)mii_display_config, dev);
+ INIT_WORK(&fep->phy_task, mii_display_config);
schedule_work(&fep->phy_task);
}
fep->phy_id = phytype << 16;
mii_queue(dev, mk_mii_read(MII_REG_PHYIR2),
mii_discover_phy3);
- }
- else {
+ } else {
fep->phy_addr++;
mii_queue(dev, mk_mii_read(MII_REG_PHYIR1),
mii_discover_phy);
return 0;
}
-static struct net_device_stats *fec_enet_get_stats(struct net_device *dev)
-{
- struct fec_enet_private *fep = netdev_priv(dev);
-
- return &fep->stats;
-}
-
/* Set or clear the multicast filter for this adaptor.
* Skeleton taken from sunlance driver.
* The CPM Ethernet implementation allows Multicast as well as individual
fep->index = index;
fep->hwp = fecp;
+ fep->netdev = dev;
/* Whack a reset. We should wait for this.
*/
dev->tx_timeout = fec_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
dev->stop = fec_enet_close;
- dev->get_stats = fec_enet_get_stats;
dev->set_multicast_list = set_multicast_list;
for (i=0; i<NMII-1; i++)
if (duplex) {
fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;/* MII enable */
fecp->fec_x_cntrl = 0x04; /* FD enable */
- }
- else {
+ } else {
/* MII enable|No Rcv on Xmit */
fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x06;
fecp->fec_x_cntrl = 0x00;
{
struct net_device *dev;
int i, j, err;
+ DECLARE_MAC_BUF(mac);
printk("FEC ENET Version 0.2\n");
return -EIO;
}
- printk("%s: ethernet ", dev->name);
- for (j = 0; (j < 5); j++)
- printk("%02x:", dev->dev_addr[j]);
- printk("%02x\n", dev->dev_addr[5]);
+ printk("%s: ethernet %s\n",
+ dev->name, print_mac(mac, dev->dev_addr));
}
return 0;
}