diff options
| author | Ingo Molnar <mingo@kernel.org> | 2012-04-14 13:18:27 +0200 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2012-04-14 13:19:04 +0200 |
| commit | 6ac1ef482d7ae0c690f1640bf6eb818ff9a2d91e (patch) | |
| tree | 021cc9f6b477146fcebe6f3be4752abfa2ba18a9 /drivers/net/ethernet/freescale | |
| parent | 682968e0c425c60f0dde37977e5beb2b12ddc4cc (diff) | |
| parent | a385ec4f11bdcf81af094c03e2444ee9b7fad2e5 (diff) | |
Merge branch 'perf/core' into perf/uprobes
Merge in latest upstream (and the latest perf development tree),
to prepare for tooling changes, and also to pick up v3.4 MM
changes that the uprobes code needs to take care of.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/net/ethernet/freescale')
| -rw-r--r-- | drivers/net/ethernet/freescale/fec.c | 21 | ||||
| -rw-r--r-- | drivers/net/ethernet/freescale/fec_mpc52xx.c | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/freescale/fec_mpc52xx.h | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/freescale/fs_enet/fec.h | 6 | ||||
| -rw-r--r-- | drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c | 32 | ||||
| -rw-r--r-- | drivers/net/ethernet/freescale/fs_enet/mac-fec.c | 9 | ||||
| -rw-r--r-- | drivers/net/ethernet/freescale/fsl_pq_mdio.c | 12 | ||||
| -rw-r--r-- | drivers/net/ethernet/freescale/gianfar.c | 63 | ||||
| -rw-r--r-- | drivers/net/ethernet/freescale/gianfar.h | 7 | ||||
| -rw-r--r-- | drivers/net/ethernet/freescale/gianfar_ethtool.c | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/freescale/gianfar_ptp.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/freescale/gianfar_sysfs.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/freescale/ucc_geth.c | 466 |
13 files changed, 340 insertions, 290 deletions
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index e92ef1bd732a..a12b3f5bc025 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -711,7 +711,7 @@ fec_enet_rx(struct net_device *ndev) * include that when passing upstream as it messes up * bridging applications. */ - skb = dev_alloc_skb(pkt_len - 4 + NET_IP_ALIGN); + skb = netdev_alloc_skb(ndev, pkt_len - 4 + NET_IP_ALIGN); if (unlikely(!skb)) { printk("%s: Memory squeeze, dropping packet.\n", @@ -1210,7 +1210,7 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) bdp = fep->rx_bd_base; for (i = 0; i < RX_RING_SIZE; i++) { - skb = dev_alloc_skb(FEC_ENET_RX_FRSIZE); + skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE); if (!skb) { fec_enet_free_buffers(ndev); return -ENOMEM; @@ -1739,21 +1739,6 @@ static struct platform_driver fec_driver = { .remove = __devexit_p(fec_drv_remove), }; -static int __init -fec_enet_module_init(void) -{ - printk(KERN_INFO "FEC Ethernet Driver\n"); - - return platform_driver_register(&fec_driver); -} - -static void __exit -fec_enet_cleanup(void) -{ - platform_driver_unregister(&fec_driver); -} - -module_exit(fec_enet_cleanup); -module_init(fec_enet_module_init); +module_platform_driver(fec_driver); MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx.c b/drivers/net/ethernet/freescale/fec_mpc52xx.c index 30745b56fe5d..7b34d8c698da 100644 --- a/drivers/net/ethernet/freescale/fec_mpc52xx.c +++ b/drivers/net/ethernet/freescale/fec_mpc52xx.c @@ -160,7 +160,7 @@ static int mpc52xx_fec_alloc_rx_buffers(struct net_device *dev, struct bcom_task struct sk_buff *skb; while (!bcom_queue_full(rxtsk)) { - skb = dev_alloc_skb(FEC_RX_BUFFER_SIZE); + skb = netdev_alloc_skb(dev, FEC_RX_BUFFER_SIZE); if (!skb) return -EAGAIN; @@ -416,7 +416,7 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id) /* skbs are allocated on open, so now we allocate a new one, * and remove the old (with the packet) */ - skb = dev_alloc_skb(FEC_RX_BUFFER_SIZE); + skb = netdev_alloc_skb(dev, FEC_RX_BUFFER_SIZE); if (!skb) { /* Can't get a new one : reuse the same & drop pkt */ dev_notice(&dev->dev, "Low memory - dropped packet.\n"); diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx.h b/drivers/net/ethernet/freescale/fec_mpc52xx.h index 41d2dffde55b..10afa54dd062 100644 --- a/drivers/net/ethernet/freescale/fec_mpc52xx.h +++ b/drivers/net/ethernet/freescale/fec_mpc52xx.h @@ -1,5 +1,5 @@ /* - * drivers/drivers/net/fec_mpc52xx/fec.h + * drivers/net/ethernet/freescale/fec_mpc52xx.h * * Driver for the MPC5200 Fast Ethernet Controller * diff --git a/drivers/net/ethernet/freescale/fs_enet/fec.h b/drivers/net/ethernet/freescale/fs_enet/fec.h index e980527e2b99..b9fe5bde432a 100644 --- a/drivers/net/ethernet/freescale/fs_enet/fec.h +++ b/drivers/net/ethernet/freescale/fs_enet/fec.h @@ -23,6 +23,10 @@ #define FEC_ECNTRL_ETHER_EN 0x00000002 #define FEC_ECNTRL_RESET 0x00000001 +/* RMII mode enabled only when MII_MODE bit is set too. */ +#define FEC_RCNTRL_RMII_MODE (0x00000100 | \ + FEC_RCNTRL_MII_MODE | FEC_RCNTRL_FCE) +#define FEC_RCNTRL_FCE 0x00000020 #define FEC_RCNTRL_BC_REJ 0x00000010 #define FEC_RCNTRL_PROM 0x00000008 #define FEC_RCNTRL_MII_MODE 0x00000004 @@ -33,8 +37,6 @@ #define FEC_TCNTRL_HBC 0x00000002 #define FEC_TCNTRL_GTS 0x00000001 - - /* * Delay to wait for FEC reset command to complete (in us) */ diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c index 910a8e18a9ae..e4e6cd2c5f82 100644 --- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c +++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c @@ -154,7 +154,7 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget) if (pkt_len <= fpi->rx_copybreak) { /* +2 to make IP header L1 cache aligned */ - skbn = dev_alloc_skb(pkt_len + 2); + skbn = netdev_alloc_skb(dev, pkt_len + 2); if (skbn != NULL) { skb_reserve(skbn, 2); /* align IP header */ skb_copy_from_linear_data(skb, @@ -165,7 +165,7 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget) skbn = skbt; } } else { - skbn = dev_alloc_skb(ENET_RX_FRSIZE); + skbn = netdev_alloc_skb(dev, ENET_RX_FRSIZE); if (skbn) skb_align(skbn, ENET_RX_ALIGN); @@ -286,7 +286,7 @@ static int fs_enet_rx_non_napi(struct net_device *dev) if (pkt_len <= fpi->rx_copybreak) { /* +2 to make IP header L1 cache aligned */ - skbn = dev_alloc_skb(pkt_len + 2); + skbn = netdev_alloc_skb(dev, pkt_len + 2); if (skbn != NULL) { skb_reserve(skbn, 2); /* align IP header */ skb_copy_from_linear_data(skb, @@ -297,7 +297,7 @@ static int fs_enet_rx_non_napi(struct net_device *dev) skbn = skbt; } } else { - skbn = dev_alloc_skb(ENET_RX_FRSIZE); + skbn = netdev_alloc_skb(dev, ENET_RX_FRSIZE); if (skbn) skb_align(skbn, ENET_RX_ALIGN); @@ -504,7 +504,7 @@ void fs_init_bds(struct net_device *dev) * 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); + skb = netdev_alloc_skb(dev, ENET_RX_FRSIZE); if (skb == NULL) { dev_warn(fep->dev, "Memory squeeze, unable to allocate skb\n"); @@ -592,7 +592,7 @@ static struct sk_buff *tx_skb_align_workaround(struct net_device *dev, struct fs_enet_private *fep = netdev_priv(dev); /* Alloc new skb */ - new_skb = dev_alloc_skb(skb->len + 4); + new_skb = netdev_alloc_skb(dev, skb->len + 4); if (!new_skb) { if (net_ratelimit()) { dev_warn(fep->dev, @@ -790,16 +790,20 @@ static int fs_init_phy(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); struct phy_device *phydev; + phy_interface_t iface; fep->oldlink = 0; fep->oldspeed = 0; fep->oldduplex = -1; + iface = fep->fpi->use_rmii ? + PHY_INTERFACE_MODE_RMII : PHY_INTERFACE_MODE_MII; + phydev = of_phy_connect(dev, fep->fpi->phy_node, &fs_adjust_link, 0, - PHY_INTERFACE_MODE_MII); + iface); if (!phydev) { phydev = of_phy_connect_fixed_link(dev, &fs_adjust_link, - PHY_INTERFACE_MODE_MII); + iface); } if (!phydev) { dev_err(&dev->dev, "Could not attach to PHY\n"); @@ -1007,6 +1011,7 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev) struct fs_platform_info *fpi; const u32 *data; const u8 *mac_addr; + const char *phy_connection_type; int privsize, len, ret = -ENODEV; match = of_match_device(fs_enet_match, &ofdev->dev); @@ -1035,6 +1040,13 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev) NULL))) goto out_free_fpi; + if (of_device_is_compatible(ofdev->dev.of_node, "fsl,mpc5125-fec")) { + phy_connection_type = of_get_property(ofdev->dev.of_node, + "phy-connection-type", NULL); + if (phy_connection_type && !strcmp("rmii", phy_connection_type)) + fpi->use_rmii = 1; + } + privsize = sizeof(*fep) + sizeof(struct sk_buff **) * (fpi->rx_ring + fpi->tx_ring); @@ -1150,6 +1162,10 @@ static struct of_device_id fs_enet_match[] = { .compatible = "fsl,mpc5121-fec", .data = (void *)&fs_fec_ops, }, + { + .compatible = "fsl,mpc5125-fec", + .data = (void *)&fs_fec_ops, + }, #else { .compatible = "fsl,pq1-fec-enet", diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c index b9fbc83d64a7..9ae6cdbcac2e 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c +++ b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c @@ -322,10 +322,11 @@ static void restart(struct net_device *dev) FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ #else /* - * Only set MII mode - do not touch maximum frame length + * Only set MII/RMII mode - do not touch maximum frame length * configured before. */ - FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); + FS(fecp, r_cntrl, fpi->use_rmii ? + FEC_RCNTRL_RMII_MODE : FEC_RCNTRL_MII_MODE); #endif /* * adjust to duplex mode @@ -381,7 +382,9 @@ static void stop(struct net_device *dev) /* shut down FEC1? that's where the mii bus is */ if (fpi->has_phy) { - FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ + FS(fecp, r_cntrl, fpi->use_rmii ? + FEC_RCNTRL_RMII_MODE : + FEC_RCNTRL_MII_MODE); /* MII/RMII enable */ FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); FW(fecp, ievent, FEC_ENET_MII); FW(fecp, mii_speed, feci->mii_speed); diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c index 9eb815941df5..f7f0bf5d037b 100644 --- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c +++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c @@ -356,13 +356,13 @@ static int fsl_pq_mdio_probe(struct platform_device *ofdev) if (prop) tbiaddr = *prop; - } - if (tbiaddr == -1) { - err = -EBUSY; - goto err_free_irqs; - } else { - out_be32(tbipa, tbiaddr); + if (tbiaddr == -1) { + err = -EBUSY; + goto err_free_irqs; + } else { + out_be32(tbipa, tbiaddr); + } } err = of_mdiobus_register(new_bus, np); diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 39d160d353a4..e7bed5303997 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -1,5 +1,5 @@ /* - * drivers/net/gianfar.c + * drivers/net/ethernet/freescale/gianfar.c * * Gianfar Ethernet Driver * This driver is designed for the non-CPM ethernet controllers @@ -104,10 +104,7 @@ #include "fsl_pq_mdio.h" #define TX_TIMEOUT (1*HZ) -#undef BRIEF_GFAR_ERRORS -#undef VERBOSE_GFAR_ERRORS -const char gfar_driver_name[] = "Gianfar Ethernet"; const char gfar_driver_version[] = "1.3"; static int gfar_enet_open(struct net_device *dev); @@ -971,7 +968,6 @@ static int gfar_probe(struct platform_device *ofdev) struct gfar_private *priv = NULL; struct gfar __iomem *regs = NULL; int err = 0, i, grp_idx = 0; - int len_devname; u32 rstat = 0, tstat = 0, rqueue = 0, tqueue = 0; u32 isrg = 0; u32 __iomem *baddr; @@ -1172,40 +1168,16 @@ static int gfar_probe(struct platform_device *ofdev) priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); /* fill out IRQ number and name fields */ - len_devname = strlen(dev->name); for (i = 0; i < priv->num_grps; i++) { - strncpy(&priv->gfargrp[i].int_name_tx[0], dev->name, - len_devname); if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { - strncpy(&priv->gfargrp[i].int_name_tx[len_devname], - "_g", sizeof("_g")); - priv->gfargrp[i].int_name_tx[ - strlen(priv->gfargrp[i].int_name_tx)] = i+48; - strncpy(&priv->gfargrp[i].int_name_tx[strlen( - priv->gfargrp[i].int_name_tx)], - "_tx", sizeof("_tx") + 1); - - strncpy(&priv->gfargrp[i].int_name_rx[0], dev->name, - len_devname); - strncpy(&priv->gfargrp[i].int_name_rx[len_devname], - "_g", sizeof("_g")); - priv->gfargrp[i].int_name_rx[ - strlen(priv->gfargrp[i].int_name_rx)] = i+48; - strncpy(&priv->gfargrp[i].int_name_rx[strlen( - priv->gfargrp[i].int_name_rx)], - "_rx", sizeof("_rx") + 1); - - strncpy(&priv->gfargrp[i].int_name_er[0], dev->name, - len_devname); - strncpy(&priv->gfargrp[i].int_name_er[len_devname], - "_g", sizeof("_g")); - priv->gfargrp[i].int_name_er[strlen( - priv->gfargrp[i].int_name_er)] = i+48; - strncpy(&priv->gfargrp[i].int_name_er[strlen(\ - priv->gfargrp[i].int_name_er)], - "_er", sizeof("_er") + 1); + sprintf(priv->gfargrp[i].int_name_tx, "%s%s%c%s", + dev->name, "_g", '0' + i, "_tx"); + sprintf(priv->gfargrp[i].int_name_rx, "%s%s%c%s", + dev->name, "_g", '0' + i, "_rx"); + sprintf(priv->gfargrp[i].int_name_er, "%s%s%c%s", + dev->name, "_g", '0' + i, "_er"); } else - priv->gfargrp[i].int_name_tx[len_devname] = '\0'; + strcpy(priv->gfargrp[i].int_name_tx, dev->name); } /* Initialize the filer table */ @@ -1755,9 +1727,12 @@ static void free_skb_resources(struct gfar_private *priv) /* Go through all the buffer descriptors and free their data buffers */ for (i = 0; i < priv->num_tx_queues; i++) { + struct netdev_queue *txq; tx_queue = priv->tx_queue[i]; + txq = netdev_get_tx_queue(tx_queue->dev, tx_queue->qindex); if(tx_queue->tx_skbuff) free_skb_tx_queue(tx_queue); + netdev_tx_reset_queue(txq); } for (i = 0; i < priv->num_rx_queues; i++) { @@ -2217,6 +2192,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb); } + netdev_tx_sent_queue(txq, skb->len); + /* * We can work in parallel with gfar_clean_tx_ring(), except * when modifying num_txbdfree. Note that we didn't grab the lock @@ -2460,6 +2437,7 @@ static void gfar_align_skb(struct sk_buff *skb) static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) { struct net_device *dev = tx_queue->dev; + struct netdev_queue *txq; struct gfar_private *priv = netdev_priv(dev); struct gfar_priv_rx_q *rx_queue = NULL; struct txbd8 *bdp, *next = NULL; @@ -2471,10 +2449,13 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) int frags = 0, nr_txbds = 0; int i; int howmany = 0; + int tqi = tx_queue->qindex; + unsigned int bytes_sent = 0; u32 lstatus; size_t buflen; - rx_queue = priv->rx_queue[tx_queue->qindex]; + rx_queue = priv->rx_queue[tqi]; + txq = netdev_get_tx_queue(dev, tqi); bdp = tx_queue->dirty_tx; skb_dirtytx = tx_queue->skb_dirtytx; @@ -2533,6 +2514,8 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) bdp = next_txbd(bdp, base, tx_ring_size); } + bytes_sent += skb->len; + /* * If there's room in the queue (limit it to rx_buffer_size) * we add this skb back into the pool, if it's the right size @@ -2557,13 +2540,15 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) } /* If we freed a buffer, we can restart transmission, if necessary */ - if (__netif_subqueue_stopped(dev, tx_queue->qindex) && tx_queue->num_txbdfree) - netif_wake_subqueue(dev, tx_queue->qindex); + if (netif_tx_queue_stopped(txq) && tx_queue->num_txbdfree) + netif_wake_subqueue(dev, tqi); /* Update dirty indicators */ tx_queue->skb_dirtytx = skb_dirtytx; tx_queue->dirty_tx = bdp; + netdev_tx_completed_queue(txq, howmany, bytes_sent); + return howmany; } diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 40c33a7554c0..4c9f8d487dbb 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h @@ -1,5 +1,5 @@ /* - * drivers/net/gianfar.h + * drivers/net/ethernet/freescale/gianfar.h * * Gianfar Ethernet Driver * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560 @@ -78,11 +78,8 @@ struct ethtool_rx_list { #define INCREMENTAL_BUFFER_SIZE 512 #define PHY_INIT_TIMEOUT 100000 -#define GFAR_PHY_CHANGE_TIME 2 -#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.2, " #define DRV_NAME "gfar-enet" -extern const char gfar_driver_name[]; extern const char gfar_driver_version[]; /* MAXIMUM NUMBER OF QUEUES SUPPORTED */ @@ -520,7 +517,7 @@ extern const char gfar_driver_version[]; #define RXFCB_PERR_MASK 0x000c #define RXFCB_PERR_BADL3 0x0008 -#define GFAR_INT_NAME_MAX IFNAMSIZ + 4 +#define GFAR_INT_NAME_MAX (IFNAMSIZ + 6) /* '_g#_xx' */ struct txbd8 { diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c index 5a3b2e5b2880..8d74efd04bb9 100644 --- a/drivers/net/ethernet/freescale/gianfar_ethtool.c +++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c @@ -1,5 +1,5 @@ /* - * drivers/net/gianfar_ethtool.c + * drivers/net/ethernet/freescale/gianfar_ethtool.c * * Gianfar Ethernet Driver * Ethtool support for Gianfar Enet @@ -58,7 +58,7 @@ static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rv static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals); static void gfar_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo); -static char stat_gstrings[][ETH_GSTRING_LEN] = { +static const char stat_gstrings[][ETH_GSTRING_LEN] = { "rx-dropped-by-kernel", "rx-large-frame-errors", "rx-short-frame-errors", diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c index 83e0ed757e33..5fd620bec15c 100644 --- a/drivers/net/ethernet/freescale/gianfar_ptp.c +++ b/drivers/net/ethernet/freescale/gianfar_ptp.c @@ -564,6 +564,6 @@ static struct platform_driver gianfar_ptp_driver = { module_platform_driver(gianfar_ptp_driver); -MODULE_AUTHOR("Richard Cochran <richard.cochran@omicron.at>"); +MODULE_AUTHOR("Richard Cochran <richardcochran@gmail.com>"); MODULE_DESCRIPTION("PTP clock using the eTSEC"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/freescale/gianfar_sysfs.c b/drivers/net/ethernet/freescale/gianfar_sysfs.c index 64f4094ac7f1..cd14a4d449c2 100644 --- a/drivers/net/ethernet/freescale/gianfar_sysfs.c +++ b/drivers/net/ethernet/freescale/gianfar_sysfs.c @@ -1,5 +1,5 @@ /* - * drivers/net/gianfar_sysfs.c + * drivers/net/ethernet/freescale/gianfar_sysfs.c * * Gianfar Ethernet Driver * This driver is designed for the non-CPM ethernet controllers diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index ba2dc083bfc0..17a46e76123f 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -214,8 +214,9 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, skb = __skb_dequeue(&ugeth->rx_recycle); if (!skb) - skb = dev_alloc_skb(ugeth->ug_info->uf_info.max_rx_buf_length + - UCC_GETH_RX_DATA_BUF_ALIGNMENT); + skb = netdev_alloc_skb(ugeth->ndev, + ugeth->ug_info->uf_info.max_rx_buf_length + + UCC_GETH_RX_DATA_BUF_ALIGNMENT); if (skb == NULL) return NULL; @@ -227,8 +228,6 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, (((unsigned)skb->data) & (UCC_GETH_RX_DATA_BUF_ALIGNMENT - 1))); - skb->dev = ugeth->ndev; - out_be32(&((struct qe_bd __iomem *)bd)->buf, dma_map_single(ugeth->dev, skb->data, @@ -1857,11 +1856,93 @@ static int ugeth_82xx_filtering_clear_addr_in_paddr(struct ucc_geth_private *uge return hw_clear_addr_in_paddr(ugeth, paddr_num);/* clear in hardware */ } -static void ucc_geth_memclean(struct ucc_geth_private *ugeth) +static void ucc_geth_free_rx(struct ucc_geth_private *ugeth) +{ + struct ucc_geth_info *ug_info; + struct ucc_fast_info *uf_info; + u16 i, j; + u8 __iomem *bd; + + + ug_info = ugeth->ug_info; + uf_info = &ug_info->uf_info; + + for (i = 0; i < ugeth->ug_info->numQueuesRx; i++) { + if (ugeth->p_rx_bd_ring[i]) { + /* Return existing data buffers in ring */ + bd = ugeth->p_rx_bd_ring[i]; + for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) { + if (ugeth->rx_skbuff[i][j]) { + dma_unmap_single(ugeth->dev, + in_be32(&((struct qe_bd __iomem *)bd)->buf), + ugeth->ug_info-> + uf_info.max_rx_buf_length + + UCC_GETH_RX_DATA_BUF_ALIGNMENT, + DMA_FROM_DEVICE); + dev_kfree_skb_any( + ugeth->rx_skbuff[i][j]); + ugeth->rx_skbuff[i][j] = NULL; + } + bd += sizeof(struct qe_bd); + } + + kfree(ugeth->rx_skbuff[i]); + + if (ugeth->ug_info->uf_info.bd_mem_part == + MEM_PART_SYSTEM) + kfree((void *)ugeth->rx_bd_ring_offset[i]); + else if (ugeth->ug_info->uf_info.bd_mem_part == + MEM_PART_MURAM) + qe_muram_free(ugeth->rx_bd_ring_offset[i]); + ugeth->p_rx_bd_ring[i] = NULL; + } + } + +} + +static void ucc_geth_free_tx(struct ucc_geth_private *ugeth) { + struct ucc_geth_info *ug_info; + struct ucc_fast_info *uf_info; u16 i, j; u8 __iomem *bd; + ug_info = ugeth->ug_info; + uf_info = &ug_info->uf_info; + + for (i = 0; i < ugeth->ug_info->numQueuesTx; i++) { + bd = ugeth->p_tx_bd_ring[i]; + if (!bd) + continue; + for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) { + if (ugeth->tx_skbuff[i][j]) { + dma_unmap_single(ugeth->dev, + in_be32(&((struct qe_bd __iomem *)bd)->buf), + (in_be32((u32 __iomem *)bd) & + BD_LENGTH_MASK), + DMA_TO_DEVICE); + dev_kfree_skb_any(ugeth->tx_skbuff[i][j]); + ugeth->tx_skbuff[i][j] = NULL; + } + } + + kfree(ugeth->tx_skbuff[i]); + + if (ugeth->p_tx_bd_ring[i]) { + if (ugeth->ug_info->uf_info.bd_mem_part == + MEM_PART_SYSTEM) + kfree((void *)ugeth->tx_bd_ring_offset[i]); + else if (ugeth->ug_info->uf_info.bd_mem_part == + MEM_PART_MURAM) + qe_muram_free(ugeth->tx_bd_ring_offset[i]); + ugeth->p_tx_bd_ring[i] = NULL; + } + } + +} + +static void ucc_geth_memclean(struct ucc_geth_private *ugeth) +{ if (!ugeth) return; @@ -1928,64 +2009,8 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth) kfree(ugeth->p_init_enet_param_shadow); ugeth->p_init_enet_param_shadow = NULL; } - for (i = 0; i < ugeth->ug_info->numQueuesTx; i++) { - bd = ugeth->p_tx_bd_ring[i]; - if (!bd) - continue; - for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) { - if (ugeth->tx_skbuff[i][j]) { - dma_unmap_single(ugeth->dev, - in_be32(&((struct qe_bd __iomem *)bd)->buf), - (in_be32((u32 __iomem *)bd) & - BD_LENGTH_MASK), - DMA_TO_DEVICE); - dev_kfree_skb_any(ugeth->tx_skbuff[i][j]); - ugeth->tx_skbuff[i][j] = NULL; - } - } - - kfree(ugeth->tx_skbuff[i]); - - if (ugeth->p_tx_bd_ring[i]) { - if (ugeth->ug_info->uf_info.bd_mem_part == - MEM_PART_SYSTEM) - kfree((void *)ugeth->tx_bd_ring_offset[i]); - else if (ugeth->ug_info->uf_info.bd_mem_part == - MEM_PART_MURAM) - qe_muram_free(ugeth->tx_bd_ring_offset[i]); - ugeth->p_tx_bd_ring[i] = NULL; - } - } - for (i = 0; i < ugeth->ug_info->numQueuesRx; i++) { - if (ugeth->p_rx_bd_ring[i]) { - /* Return existing data buffers in ring */ - bd = ugeth->p_rx_bd_ring[i]; - for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) { - if (ugeth->rx_skbuff[i][j]) { - dma_unmap_single(ugeth->dev, - in_be32(&((struct qe_bd __iomem *)bd)->buf), - ugeth->ug_info-> - uf_info.max_rx_buf_length + - UCC_GETH_RX_DATA_BUF_ALIGNMENT, - DMA_FROM_DEVICE); - dev_kfree_skb_any( - ugeth->rx_skbuff[i][j]); - ugeth->rx_skbuff[i][j] = NULL; - } - bd += sizeof(struct qe_bd); - } - - kfree(ugeth->rx_skbuff[i]); - - if (ugeth->ug_info->uf_info.bd_mem_part == - MEM_PART_SYSTEM) - kfree((void *)ugeth->rx_bd_ring_offset[i]); - else if (ugeth->ug_info->uf_info.bd_mem_part == - MEM_PART_MURAM) - qe_muram_free(ugeth->rx_bd_ring_offset[i]); - ugeth->p_rx_bd_ring[i] = NULL; - } - } + ucc_geth_free_tx(ugeth); + ucc_geth_free_rx(ugeth); while (!list_empty(&ugeth->group_hash_q)) put_enet_addr_container(ENET_ADDR_CONT_ENTRY (dequeue(&ugeth->group_hash_q))); @@ -2211,6 +2236,171 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth) return 0; } +static int ucc_geth_alloc_tx(struct ucc_geth_private *ugeth) +{ + struct ucc_geth_info *ug_info; + struct ucc_fast_info *uf_info; + int length; + u16 i, j; + u8 __iomem *bd; + + ug_info = ugeth->ug_info; + uf_info = &ug_info->uf_info; + + /* Allocate Tx bds */ + for (j = 0; j < ug_info->numQueuesTx; j++) { + /* Allocate in multiple of + UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT, + according to spec */ + length = ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)) + / UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) + * UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT; + if ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)) % + UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) + length += UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT; + if (uf_info->bd_mem_part == MEM_PART_SYSTEM) { + u32 align = 4; + if (UCC_GETH_TX_BD_RING_ALIGNMENT > 4) + align = UCC_GETH_TX_BD_RING_ALIGNMENT; + ugeth->tx_bd_ring_offset[j] = + (u32) kmalloc((u32) (length + align), GFP_KERNEL); + + if (ugeth->tx_bd_ring_offset[j] != 0) + ugeth->p_tx_bd_ring[j] = + (u8 __iomem *)((ugeth->tx_bd_ring_offset[j] + + align) & ~(align - 1)); + } else if (uf_info->bd_mem_part == MEM_PART_MURAM) { + ugeth->tx_bd_ring_offset[j] = + qe_muram_alloc(length, + UCC_GETH_TX_BD_RING_ALIGNMENT); + if (!IS_ERR_VALUE(ugeth->tx_bd_ring_offset[j])) + ugeth->p_tx_bd_ring[j] = + (u8 __iomem *) qe_muram_addr(ugeth-> + tx_bd_ring_offset[j]); + } + if (!ugeth->p_tx_bd_ring[j]) { + if (netif_msg_ifup(ugeth)) + ugeth_err + ("%s: Can not allocate memory for Tx bd rings.", + __func__); + return -ENOMEM; + } + /* Zero unused end of bd ring, according to spec */ + memset_io((void __iomem *)(ugeth->p_tx_bd_ring[j] + + ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)), 0, + length - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)); + } + + /* Init Tx bds */ + for (j = 0; j < ug_info->numQueuesTx; j++) { + /* Setup the skbuff rings */ + ugeth->tx_skbuff[j] = kmalloc(sizeof(struct sk_buff *) * + ugeth->ug_info->bdRingLenTx[j], + GFP_KERNEL); + + if (ugeth->tx_skbuff[j] == NULL) { + if (netif_msg_ifup(ugeth)) + ugeth_err("%s: Could not allocate tx_skbuff", + __func__); + return -ENOMEM; + } + + for (i = 0; i < ugeth->ug_info->bdRingLenTx[j]; i++) + ugeth->tx_skbuff[j][i] = NULL; + + ugeth->skb_curtx[j] = ugeth->skb_dirtytx[j] = 0; + bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j]; + for (i = 0; i < ug_info->bdRingLenTx[j]; i++) { + /* clear bd buffer */ + out_be32(&((struct qe_bd __iomem *)bd)->buf, 0); + /* set bd status and length */ + out_be32((u32 __iomem *)bd, 0); + bd += sizeof(struct qe_bd); + } + bd -= sizeof(struct qe_bd); + /* set bd status and length */ + out_be32((u32 __iomem *)bd, T_W); /* for last BD set Wrap bit */ + } + + return 0; +} + +static int ucc_geth_alloc_rx(struct ucc_geth_private *ugeth) +{ + struct ucc_geth_info *ug_info; + struct ucc_fast_info *uf_info; + int length; + u16 i, j; + u8 __iomem *bd; + + ug_info = ugeth->ug_info; + uf_info = &ug_info->uf_info; + + /* Allocate Rx bds */ + for (j = 0; j < ug_info->numQueuesRx; j++) { + length = ug_info->bdRingLenRx[j] * sizeof(struct qe_bd); + if (uf_info->bd_mem_part == MEM_PART_SYSTEM) { + u32 align = 4; + if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4) + align = UCC_GETH_RX_BD_RING_ALIGNMENT; + ugeth->rx_bd_ring_offset[j] = + (u32) kmalloc((u32) (length + align), GFP_KERNEL); + if (ugeth->rx_bd_ring_offset[j] != 0) + ugeth->p_rx_bd_ring[j] = + (u8 __iomem *)((ugeth->rx_bd_ring_offset[j] + + align) & ~(align - 1)); + } else if (uf_info->bd_mem_part == MEM_PART_MURAM) { + ugeth->rx_bd_ring_offset[j] = + qe_muram_alloc(length, + UCC_GETH_RX_BD_RING_ALIGNMENT); + if (!IS_ERR_VALUE(ugeth->rx_bd_ring_offset[j])) + ugeth->p_rx_bd_ring[j] = + (u8 __iomem *) qe_muram_addr(ugeth-> + rx_bd_ring_offset[j]); + } + if (!ugeth->p_rx_bd_ring[j]) { + if (netif_msg_ifup(ugeth)) + ugeth_err + ("%s: Can not allocate memory for Rx bd rings.", + __func__); + return -ENOMEM; + } + } + + /* Init Rx bds */ + for (j = 0; j < ug_info->numQueuesRx; j++) { + /* Setup the skbuff rings */ + ugeth->rx_skbuff[j] = kmalloc(sizeof(struct sk_buff *) * + ugeth->ug_info->bdRingLenRx[j], + GFP_KERNEL); + + if (ugeth->rx_skbuff[j] == NULL) { + if (netif_msg_ifup(ugeth)) + ugeth_err("%s: Could not allocate rx_skbuff", + __func__); + return -ENOMEM; + } + + for (i = 0; i < ugeth->ug_info->bdRingLenRx[j]; i++) + ugeth->rx_skbuff[j][i] = NULL; + + ugeth->skb_currx[j] = 0; + bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j]; + for (i = 0; i < ug_info->bdRingLenRx[j]; i++) { + /* set bd status and length */ + out_be32((u32 __iomem *)bd, R_I); + /* clear bd buffer */ + out_be32(&((struct qe_bd __iomem *)bd)->buf, 0); + bd += sizeof(struct qe_bd); + } + bd -= sizeof(struct qe_bd); + /* set bd status and length */ + out_be32((u32 __iomem *)bd, R_W); /* for last BD set Wrap bit */ + } + + return 0; +} + static int ucc_geth_startup(struct ucc_geth_private *ugeth) { struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt; @@ -2223,11 +2413,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) int ret_val = -EINVAL; u32 remoder = UCC_GETH_REMODER_INIT; u32 init_enet_pram_offset, cecr_subblock, command; - u32 ifstat, i, j, size, l2qt, l3qt, length; + u32 ifstat, i, j, size, l2qt, l3qt; u16 temoder = UCC_GETH_TEMODER_INIT; u16 test; u8 function_code = 0; - u8 __iomem *bd; u8 __iomem *endOfRing; u8 numThreadsRxNumerical, numThreadsTxNumerical; @@ -2367,142 +2556,13 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE), 0, &uf_regs->upsmr, &ug_regs->uescr); - /* Allocate Tx bds */ - for (j = 0; j < ug_info->numQueuesTx; j++) { - /* Allocate in multiple of - UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT, - according to spec */ - length = ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)) - / UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) - * UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT; - if ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)) % - UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) - length += UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT; - if (uf_info->bd_mem_part == MEM_PART_SYSTEM) { - u32 align = 4; - if (UCC_GETH_TX_BD_RING_ALIGNMENT > 4) - align = UCC_GETH_TX_BD_RING_ALIGNMENT; - ugeth->tx_bd_ring_offset[j] = - (u32) kmalloc((u32) (length + align), GFP_KERNEL); - - if (ugeth->tx_bd_ring_offset[j] != 0) - ugeth->p_tx_bd_ring[j] = - (u8 __iomem *)((ugeth->tx_bd_ring_offset[j] + - align) & ~(align - 1)); - } else if (uf_info->bd_mem_part == MEM_PART_MURAM) { - ugeth->tx_bd_ring_offset[j] = - qe_muram_alloc(length, - UCC_GETH_TX_BD_RING_ALIGNMENT); - if (!IS_ERR_VALUE(ugeth->tx_bd_ring_offset[j])) - ugeth->p_tx_bd_ring[j] = - (u8 __iomem *) qe_muram_addr(ugeth-> - tx_bd_ring_offset[j]); - } - if (!ugeth->p_tx_bd_ring[j]) { - if (netif_msg_ifup(ugeth)) - ugeth_err - ("%s: Can not allocate memory for Tx bd rings.", - __func__); - return -ENOMEM; - } - /* Zero unused end of bd ring, according to spec */ - memset_io((void __iomem *)(ugeth->p_tx_bd_ring[j] + - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)), 0, - length - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)); - } - - /* Allocate Rx bds */ - for (j = 0; j < ug_info->numQueuesRx; j++) { - length = ug_info->bdRingLenRx[j] * sizeof(struct qe_bd); - if (uf_info->bd_mem_part == MEM_PART_SYSTEM) { - u32 align = 4; - if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4) - align = UCC_GETH_RX_BD_RING_ALIGNMENT; - ugeth->rx_bd_ring_offset[j] = - (u32) kmalloc((u32) (length + align), GFP_KERNEL); - if (ugeth->rx_bd_ring_offset[j] != 0) - ugeth->p_rx_bd_ring[j] = - (u8 __iomem *)((ugeth->rx_bd_ring_offset[j] + - align) & ~(align - 1)); - } else if (uf_info->bd_mem_part == MEM_PART_MURAM) { - ugeth->rx_bd_ring_offset[j] = - qe_muram_alloc(length, - UCC_GETH_RX_BD_RING_ALIGNMENT); - if (!IS_ERR_VALUE(ugeth->rx_bd_ring_offset[j])) - ugeth->p_rx_bd_ring[j] = - (u8 __iomem *) qe_muram_addr(ugeth-> - rx_bd_ring_offset[j]); - } - if (!ugeth->p_rx_bd_ring[j]) { - if (netif_msg_ifup(ugeth)) - ugeth_err - ("%s: Can not allocate memory for Rx bd rings.", - __func__); - return -ENOMEM; - } - } - - /* Init Tx bds */ - for (j = 0; j < ug_info->numQueuesTx; j++) { - /* Setup the skbuff rings */ - ugeth->tx_skbuff[j] = kmalloc(sizeof(struct sk_buff *) * - ugeth->ug_info->bdRingLenTx[j], - GFP_KERNEL); - - if (ugeth->tx_skbuff[j] == NULL) { - if (netif_msg_ifup(ugeth)) - ugeth_err("%s: Could not allocate tx_skbuff", - __func__); - return -ENOMEM; - } - - for (i = 0; i < ugeth->ug_info->bdRingLenTx[j]; i++) - ugeth->tx_skbuff[j][i] = NULL; - - ugeth->skb_curtx[j] = ugeth->skb_dirtytx[j] = 0; - bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j]; - for (i = 0; i < ug_info->bdRingLenTx[j]; i++) { - /* clear bd buffer */ - out_be32(&((struct qe_bd __iomem *)bd)->buf, 0); - /* set bd status and length */ - out_be32((u32 __iomem *)bd, 0); - bd += sizeof(struct qe_bd); - } - bd -= sizeof(struct qe_bd); - /* set bd status and length */ - out_be32((u32 __iomem *)bd, T_W); /* for last BD set Wrap bit */ - } - - /* Init Rx bds */ - for (j = 0; j < ug_info->numQueuesRx; j++) { - /* Setup the skbuff rings */ - ugeth->rx_skbuff[j] = kmalloc(sizeof(struct sk_buff *) * - ugeth->ug_info->bdRingLenRx[j], - GFP_KERNEL); - - if (ugeth->rx_skbuff[j] == NULL) { - if (netif_msg_ifup(ugeth)) - ugeth_err("%s: Could not allocate rx_skbuff", - __func__); - return -ENOMEM; - } - - for (i = 0; i < ugeth->ug_info->bdRingLenRx[j]; i++) - ugeth->rx_skbuff[j][i] = NULL; + ret_val = ucc_geth_alloc_tx(ugeth); + if (ret_val != 0) + return ret_val; - ugeth->skb_currx[j] = 0; - bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j]; - for (i = 0; i < ug_info->bdRingLenRx[j]; i++) { - /* set bd status and length */ - out_be32((u32 __iomem *)bd, R_I); - /* clear bd buffer */ - out_be32(&((struct qe_bd __iomem *)bd)->buf, 0); - bd += sizeof(struct qe_bd); - } - bd -= sizeof(struct qe_bd); - /* set bd status and length */ - out_be32((u32 __iomem *)bd, R_W); /* for last BD set Wrap bit */ - } + ret_val = ucc_geth_alloc_rx(ugeth); + if (ret_val != 0) + return ret_val; /* * Global PRAM @@ -3885,6 +3945,8 @@ static int ucc_geth_probe(struct platform_device* ofdev) } if (max_speed == SPEED_1000) { + unsigned int snums = qe_get_num_of_snums(); + /* configure muram FIFOs for gigabit operation */ ug_info->uf_info.urfs = UCC_GETH_URFS_GIGA_INIT; ug_info->uf_info.urfet = UCC_GETH_URFET_GIGA_INIT; @@ -3894,11 +3956,11 @@ static int ucc_geth_probe(struct platform_device* ofdev) ug_info->uf_info.utftt = UCC_GETH_UTFTT_GIGA_INIT; ug_info->numThreadsTx = UCC_GETH_NUM_OF_THREADS_4; - /* If QE's snum number is 46 which means we need to support + /* If QE's snum number is 46/76 which means we need to support * 4 UECs at 1000Base-T simultaneously, we need to allocate * more Threads to Rx. */ - if (qe_get_num_of_snums() == 46) + if ((snums == 76) || (snums == 46)) ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_6; else ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4; |
