diff options
author | Claudiu Manoil <claudiu.manoil@freescale.com> | 2014-04-24 09:17:22 (GMT) |
---|---|---|
committer | Jose Rivera <German.Rivera@freescale.com> | 2014-05-08 13:49:51 (GMT) |
commit | 44cc9789d535e01339a68b63e633057f55704246 (patch) | |
tree | 02ea4fa8f2a4db80311ebb202c0e0f799de793dc | |
parent | 4888b87c99e103a1cf1cb3add39c4c8252249dc3 (diff) | |
download | linux-fsl-qoriq-44cc9789d535e01339a68b63e633057f55704246.tar.xz |
gianfar: Add BD rings allocation to L2 SRAM
When this option is enabled the driver will try to allocate
the buffer descriptors (BDs) to the L2 SRAM memory, using
the powerpc/85xx cache-sram support API for the P1/P2 QorIQ
platforms. For this to work, the size and address of the
SRAM region must be provided as kernel boot params.
Should the attempt to allocate in L2 SRAM fail, the driver
falls back to normal allocation of BDs as before (to DDR).
The gfar_l2sram_en driver module param is provided to allow
to disable the allocation to L2 SRAM at driver level
(enabled by default).
Change-Id: I087e97baf289111a0841fdf69592c56d3a9a0310
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
Reviewed-on: http://git.am.freescale.net:8181/11624
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Jianhua Xie <jianhua.xie@freescale.com>
Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
-rw-r--r-- | drivers/net/ethernet/freescale/Kconfig | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.c | 51 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.h | 7 |
3 files changed, 46 insertions, 13 deletions
diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig index 80c9bb7..bc51248 100644 --- a/drivers/net/ethernet/freescale/Kconfig +++ b/drivers/net/ethernet/freescale/Kconfig @@ -88,6 +88,7 @@ config UGETH_TX_ON_DEMAND config GIANFAR tristate "Gianfar Ethernet" depends on FSL_SOC + select FSL_85XX_CACHE_SRAM select FSL_PQ_MDIO select PHYLIB select CRC32 diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 933ba9a..9844e1a 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -105,6 +105,10 @@ #include "gianfar.h" +#ifdef CONFIG_FSL_85XX_CACHE_SRAM +#include <asm/fsl_85xx_cache_sram.h> +#endif + #ifdef CONFIG_AS_FASTPATH #include "asf_gianfar.h" #endif @@ -156,6 +160,11 @@ static void gfar_set_mac_for_addr(struct net_device *dev, int num, const u8 *addr); static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +bool gfar_l2sram_en = true; +module_param(gfar_l2sram_en, bool, 0444); +MODULE_PARM_DESC(gfar_l2sram_en, + "Enable allocation to L2 SRAM."); + MODULE_AUTHOR("Freescale Semiconductor, Inc"); MODULE_DESCRIPTION("Gianfar Ethernet Driver"); MODULE_LICENSE("GPL"); @@ -228,8 +237,9 @@ static int gfar_init_bds(struct net_device *ndev) static int gfar_alloc_skb_resources(struct net_device *ndev) { - void *vaddr; + void *vaddr = NULL; dma_addr_t addr; + phys_addr_t paddr; int i, j, k; struct gfar_private *priv = netdev_priv(ndev); struct device *dev = priv->dev; @@ -245,12 +255,23 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) priv->total_rx_ring_size += priv->rx_queue[i]->rx_ring_size; /* Allocate memory for the buffer descriptors */ - vaddr = dma_alloc_coherent(dev, - (priv->total_tx_ring_size * - sizeof(struct txbd8)) + - (priv->total_rx_ring_size * - sizeof(struct rxbd8)), - &addr, GFP_KERNEL); + if (priv->bd_l2sram_en) { + vaddr = mpc85xx_cache_sram_alloc(BD_RING_REG_SZ(priv), + &paddr, L1_CACHE_BYTES); + if (vaddr) + addr = phys_to_dma(dev, paddr); + else { + netif_dbg(priv, ifup, ndev, "%s, %s\n", + "Could not allocate BDs to SRAM", + "fallback to DDR"); + priv->bd_l2sram_en = 0; + } + } + + if (!priv->bd_l2sram_en) + vaddr = dma_alloc_coherent(dev, BD_RING_REG_SZ(priv), + &addr, GFP_KERNEL); + if (!vaddr) return -ENOMEM; @@ -846,6 +867,11 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) goto err_grp_init; } + if (gfar_l2sram_en) { + /* try to alloc the BD rings to L2 SRAM */ + priv->bd_l2sram_en = 1; + } + stash = of_get_property(np, "bd-stash", NULL); if (stash) { @@ -2096,11 +2122,12 @@ static void free_skb_resources(struct gfar_private *priv) free_skb_rx_queue(rx_queue); } - dma_free_coherent(priv->dev, - sizeof(struct txbd8) * priv->total_tx_ring_size + - sizeof(struct rxbd8) * priv->total_rx_ring_size, - priv->tx_queue[0]->tx_bd_base, - priv->tx_queue[0]->tx_bd_dma_base); + if (priv->bd_l2sram_en) + mpc85xx_cache_sram_free(priv->tx_queue[0]->tx_bd_base); + else + dma_free_coherent(priv->dev, BD_RING_REG_SZ(priv), + priv->tx_queue[0]->tx_bd_base, + priv->tx_queue[0]->tx_bd_dma_base); } void gfar_start(struct gfar_private *priv) diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 1d1b9b1..5f7a98d 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h @@ -1323,7 +1323,9 @@ struct gfar_private { /* Flow control flags */ pause_aneg_en:1, tx_pause_en:1, - rx_pause_en:1; + rx_pause_en:1, + /* L2 SRAM alloc of BDs */ + bd_l2sram_en:1; /* The total tx and rx ring size for the enabled queues */ unsigned int total_tx_ring_size; @@ -1355,6 +1357,9 @@ struct gfar_private { unsigned int ftp_rqfcr[MAX_FILER_IDX + 1]; }; +#define BD_RING_REG_SZ(priv) ( \ + sizeof(struct txbd8) * (priv)->total_tx_ring_size + \ + sizeof(struct rxbd8) * (priv)->total_rx_ring_size) static inline int gfar_has_errata(struct gfar_private *priv, enum gfar_errata err) |