/*
* Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
*
- * Copyright (c) 2003 Intracom S.A.
+ * Copyright (c) 2003 Intracom S.A.
* by Pantelis Antoniou <panto@intracom.gr>
- *
- * 2005 (c) MontaVista Software, Inc.
+ *
+ * 2005 (c) MontaVista Software, Inc.
* Vitaly Bordug <vbordug@ru.mvista.com>
*
* Heavily based on original FEC driver by Dan Malek <dan@embeddededge.com>
* and modifications by Joakim Tjernlund <joakim.tjernlund@lumentis.se>
*
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
MODULE_PARM_DESC(fs_enet_debug,
"Freescale bitmapped debugging message enable value");
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void fs_enet_netpoll(struct net_device *dev);
+#endif
static void fs_set_multicast_list(struct net_device *dev)
{
dev->name);
/*
- * Check for errors.
+ * Check for errors.
*/
if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL |
BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) {
CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY);
/*
- * Update BD pointer to next entry.
+ * Update BD pointer to next entry.
*/
if ((sc & BD_ENET_RX_WRAP) == 0)
bdp++;
dev->name);
/*
- * Check for errors.
+ * Check for errors.
*/
if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL |
BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) {
CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY);
/*
- * Update BD pointer to next entry.
+ * Update BD pointer to next entry.
*/
if ((sc & BD_ENET_RX_WRAP) == 0)
bdp++;
int dirtyidx, do_wake, do_restart;
u16 sc;
- spin_lock(&fep->lock);
+ spin_lock(&fep->tx_lock);
bdp = fep->dirty_tx;
do_wake = do_restart = 0;
skb = fep->tx_skbuff[dirtyidx];
/*
- * Check for errors.
+ * Check for errors.
*/
if (sc & (BD_ENET_TX_HB | BD_ENET_TX_LC |
BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) {
skb->len, DMA_TO_DEVICE);
/*
- * Free the sk buffer associated with this last transmit.
+ * Free the sk buffer associated with this last transmit.
*/
dev_kfree_skb_irq(skb);
fep->tx_skbuff[dirtyidx] = NULL;
/*
- * Update pointer to next buffer descriptor to be transmitted.
+ * Update pointer to next buffer descriptor to be transmitted.
*/
if ((sc & BD_ENET_TX_WRAP) == 0)
bdp++;
if (do_restart)
(*fep->ops->tx_restart)(dev);
- spin_unlock(&fep->lock);
+ spin_unlock(&fep->tx_lock);
if (do_wake)
netif_wake_queue(dev);
fep->cur_rx = fep->rx_bd_base;
/*
- * Initialize the receive buffer descriptors.
+ * Initialize the receive buffer descriptors.
*/
for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) {
skb = dev_alloc_skb(ENET_RX_FRSIZE);
((i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP));
}
/*
- * if we failed, fillup remainder
+ * if we failed, fillup remainder
*/
for (; i < fep->rx_ring; i++, bdp++) {
fep->rx_skbuff[i] = NULL;
}
/*
- * ...and the same for transmit.
+ * ...and the same for transmit.
*/
for (i = 0, bdp = fep->tx_bd_base; i < fep->tx_ring; i++, bdp++) {
fep->tx_skbuff[i] = NULL;
int i;
/*
- * Reset SKB transmit buffers.
+ * Reset SKB transmit buffers.
*/
for (i = 0, bdp = fep->tx_bd_base; i < fep->tx_ring; i++, bdp++) {
if ((skb = fep->tx_skbuff[i]) == NULL)
}
/*
- * Reset SKB receive buffers
+ * Reset SKB receive buffers
*/
for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) {
if ((skb = fep->rx_skbuff[i]) == NULL)
spin_lock_irqsave(&fep->tx_lock, flags);
/*
- * Fill in a Tx ring entry
+ * Fill in a Tx ring entry
*/
bdp = fep->cur_tx;
curidx = bdp - fep->tx_bd_base;
/*
- * Clear all of the status flags.
+ * Clear all of the status flags.
*/
CBDC_SC(bdp, BD_ENET_TX_STATS);
/*
- * Save skb pointer.
+ * Save skb pointer.
*/
fep->tx_skbuff[curidx] = skb;
fep->stats.tx_bytes += skb->len;
/*
- * Push the data cache so the CPM does not get stale memory data.
+ * Push the data cache so the CPM does not get stale memory data.
*/
CBDW_BUFADDR(bdp, dma_map_single(fep->dev,
skb->data, skb->len, DMA_TO_DEVICE));
dev->trans_start = jiffies;
/*
- * If this was the last BD in the ring, start at the beginning again.
+ * If this was the last BD in the ring, start at the beginning again.
*/
if ((CBDR_SC(bdp) & BD_ENET_TX_WRAP) == 0)
fep->cur_tx++;
phy_stop(fep->phydev);
spin_lock_irqsave(&fep->lock, flags);
+ spin_lock(&fep->tx_lock);
(*fep->ops->stop)(dev);
+ spin_unlock(&fep->tx_lock);
spin_unlock_irqrestore(&fep->lock, flags);
/* release any irqs */
.get_link = ethtool_op_get_link,
.get_msglevel = fs_get_msglevel,
.set_msglevel = fs_set_msglevel,
- .get_tx_csum = ethtool_op_get_tx_csum,
.set_tx_csum = ethtool_op_set_tx_csum, /* local! */
- .get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
.get_regs = fs_get_regs,
};
spin_lock_init(&fep->tx_lock);
/*
- * Set the Ethernet address.
+ * Set the Ethernet address.
*/
for (i = 0; i < 6; i++)
ndev->dev_addr[i] = fpi->macaddr[i];
-
+
r = (*fep->ops->allocate_bd)(ndev);
-
+
if (fep->ring_base == NULL) {
printk(KERN_ERR DRV_MODULE_NAME
": %s buffer descriptor alloc failed (%d).\n", ndev->name, r);
fep->rx_ring = fpi->rx_ring;
/*
- * The FEC Ethernet specific entries in the device structure.
+ * The FEC Ethernet specific entries in the device structure.
*/
ndev->open = fs_enet_open;
ndev->hard_start_xmit = fs_enet_start_xmit;
ndev->stop = fs_enet_close;
ndev->get_stats = fs_enet_get_stats;
ndev->set_multicast_list = fs_set_multicast_list;
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ ndev->poll_controller = fs_enet_netpoll;
+#endif
+
netif_napi_add(ndev, &fep->napi,
fs_enet_rx_napi, fpi->napi_weight);
err:
cleanup_immap();
return r;
-
+
}
static void __exit fs_cleanup(void)
cleanup_immap();
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void fs_enet_netpoll(struct net_device *dev)
+{
+ disable_irq(dev->irq);
+ fs_enet_interrupt(dev->irq, dev, NULL);
+ enable_irq(dev->irq);
+}
+#endif
+
/**************************************************************************************/
module_init(fs_init);