From 7079d3359713aec00ee38a569a241eacbf2178ae Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 28 Jul 2011 10:24:42 +0200 Subject: net i.MX fec: make multi instance safe The driver uses a static int once variable to alloc the rx packets. remove this to make the driver multi instance safe. While at it, remove the crappy selfmade alignment. dma_alloc_coherent returns sufficiently aligned memory. Signed-off-by: Sascha Hauer --- drivers/net/fec_imx.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c index fcb8cc5bdc..552d2814d9 100644 --- a/drivers/net/fec_imx.c +++ b/drivers/net/fec_imx.c @@ -200,25 +200,11 @@ static void imx28_fix_endianess_rd(uint32_t *buf, unsigned wlen) static int fec_rbd_init(struct fec_priv *fec, int count, int size) { int ix; - static int once = 0; - unsigned long p = 0; - - if (!once) { - /* reserve data memory and consider alignment */ - p = (unsigned long)dma_alloc_coherent(size * count + DB_DATA_ALIGNMENT); - p += DB_DATA_ALIGNMENT - 1; - p &= ~(DB_DATA_ALIGNMENT - 1); - } for (ix = 0; ix < count; ix++) { - if (!once) { - writel(virt_to_phys((void *)p), &fec->rbd_base[ix].data_pointer); - p += size; - } writew(FEC_RBD_EMPTY, &fec->rbd_base[ix].status); writew(0, &fec->rbd_base[ix].data_length); } - once = 1; /* malloc done now (and once) */ /* * mark the last RBD to close the ring */ @@ -592,6 +578,24 @@ static int fec_recv(struct eth_device *dev) return len; } +static int fec_alloc_receive_packets(struct fec_priv *fec, int count, int size) +{ + void *p; + int i; + + /* reserve data memory and consider alignment */ + p = dma_alloc_coherent(size * count); + if (!p) + return -ENOMEM; + + for (i = 0; i < count; i++) { + writel(virt_to_phys(p), &fec->rbd_base[i].data_pointer); + p += size; + } + + return 0; +} + static int fec_probe(struct device_d *dev) { struct fec_platform_data *pdata = (struct fec_platform_data *)dev->platform_data; @@ -638,6 +642,8 @@ static int fec_probe(struct device_d *dev) writel((uint32_t)virt_to_phys(fec->tbd_base), fec->regs + FEC_ETDSR); writel((uint32_t)virt_to_phys(fec->rbd_base), fec->regs + FEC_ERDSR); + fec_alloc_receive_packets(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE); + fec->xcv_type = pdata->xcv_type; if (fec->xcv_type != SEVENWIRE) { -- cgit v1.2.3