summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Manoil <claudiu.manoil@freescale.com>2014-04-24 09:17:22 (GMT)
committerJose Rivera <German.Rivera@freescale.com>2014-05-08 13:49:51 (GMT)
commit44cc9789d535e01339a68b63e633057f55704246 (patch)
tree02ea4fa8f2a4db80311ebb202c0e0f799de793dc
parent4888b87c99e103a1cf1cb3add39c4c8252249dc3 (diff)
downloadlinux-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/Kconfig1
-rw-r--r--drivers/net/ethernet/freescale/gianfar.c51
-rw-r--r--drivers/net/ethernet/freescale/gianfar.h7
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)