Hi,
These patches aim to modernize the FEC ethernet driver.
Greg, can you please confirm that the ifdef in patch 01/12 is indeed unused?
Sascha
The following changes since commit 0882e8dd3aad33eca41696d463bb896e6c8817eb:
Linus Torvalds (1):
Linux 2.6.30-rc2
are available in the git repository at:
git://git.pengutronix.de/git/sha/linux-2.6.git fec
Sascha Hauer (12):
fec: remove unused ifdef
fec: switch to writel/readl
fec: do not typedef struct types
fec: remove unnecessary cast
fec: Codingstyle cleanups
fec: refactor set_multicast_list() to make it more readable
fec: refactor init function
fec: align receive packets
fec: remove debugging printks
fec: switch to net_device_ops
FEC Buffer rework
fec: call fec_restart() in fec_open()
drivers/net/fec.c | 897 ++++++++++++++++++++++-------------------------------
drivers/net/fec.h | 112 ++-----
2 files changed, 402 insertions(+), 607 deletions(-)
--
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/fec.h | 44 --------------------------------------------
1 files changed, 0 insertions(+), 44 deletions(-)
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 76c64c9..c2f97f3 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -13,8 +13,6 @@
#define FEC_H
/****************************************************************************/
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
- defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
/*
* Just figures, Motorola would have to change the offsets for
* registers in the same peripheral device on different models
@@ -58,48 +56,6 @@ typedef struct fec {
unsigned long fec_r_buff_size; /* Maximum receive buff size */
} fec_t;
-#else
-
-/*
- * Define device register set address map.
- */
-typedef struct fec {
- unsigned long fec_ecntrl; /* Ethernet control reg */
- unsigned long fec_ievent; /* Interrupt even reg */
- unsigned long fec_imask; /* Interrupt mask reg */
- unsigned long fec_ivec; /* Interrupt vec status reg */
- unsigned long fec_r_des_active; /* Receive descriptor reg */
- unsigned long fec_x_des_active; /* Transmit descriptor reg */
- unsigned long fec_reserved1[10];
- unsigned long fec_mii_data; /* MII manage frame reg */
- unsigned long fec_mii_speed; /* MII speed control reg */
- unsigned long fec_reserved2[17];
- unsigned long fec_r_bound; /* FIFO receive bound reg */
- unsigned long fec_r_fstart; /* FIFO receive start reg */
- unsigned long fec_reserved3[4];
- unsigned long fec_x_wmrk; /* FIFO transmit water mark */
- unsigned long fec_reserved4;
- unsigned long fec_x_fstart; /* FIFO transmit start reg */
- unsigned long fec_reserved5[21];
- unsigned long fec_r_cntrl; /* Receive control reg */
- unsigned long fec_max_frm_len; /* Maximum frame length reg */
- unsigned long fec_reserved6[14];
- unsigned long fec_x_cntrl; /* Transmit ...Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/fec.c | 279 ++++++++++++++++++++++-------------------------------
drivers/net/fec.h | 60 +++++-------
2 files changed, 138 insertions(+), 201 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 682e7f0..3fa3fe4 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -165,7 +165,7 @@ typedef struct {
*/
struct fec_enet_private {
/* Hardware registers of the FEC device */
- volatile fec_t *hwp;
+ void __iomem *hwp;
struct net_device *netdev;
@@ -288,15 +288,11 @@ static int mii_queue(struct net_device *dev, int request,
static int
fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct fec_enet_private *fep;
- volatile fec_t *fecp;
+ struct fec_enet_private *fep = netdev_priv(dev);
volatile cbd_t *bdp;
unsigned short status;
unsigned long flags;
- fep = netdev_priv(dev);
- fecp = (volatile fec_t*)dev->base_addr;
-
if (!fep->link) {
/* Link is down or autonegotiation is in progress. */
return 1;
@@ -363,7 +359,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->trans_start = jiffies;
/* Trigger transmission start */
- fecp->fec_x_des_active = 0;
+ writel(0, fep->hwp + FEC_X_DES_ACTIVE);
/* If this was the last BD in the ring, start at the beginning again.
*/
@@ -436,29 +432,25 @@ static irqreturn_t
fec_enet_interrupt(int irq, void * dev_id)
{
struct net_device *dev = dev_id;
- volatile fec_t *fecp;
+ struct fec_enet_private *fep = netdev_priv(dev);
uint int_events;
irqreturn_t ret = IRQ_NONE;
- fecp = (volatile fec_t*)dev->base_addr;
-
- /* Get the interrupt events that caused us to be here.
- */
+ /* Get the interrupt events that caused us to be here. */
do {
- int_events = fecp->fec_ievent;
- fecp->fec_ievent = int_events;
+ int_events = readl(fep->hwp + FEC_IEVENT);
+ writel(int_events, fep->hwp + FEC_IEVENT);
- /* Handle receive event in its own ...Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/fec.c | 37 ++++++++++++++++++++-----------------
drivers/net/fec.h | 8 ++++----
2 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 3fa3fe4..fea8e27 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -180,10 +180,14 @@ struct fec_enet_private {
/* CPM dual port RAM relative addresses.
*/
dma_addr_t bd_dma;
- cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */
- cbd_t *tx_bd_base;
- cbd_t *cur_rx, *cur_tx; /* The next free ring entry */
- cbd_t *dirty_tx; /* The ring entries to be free()ed. */
+ /* Address of Rx and Tx buffers. */
+ struct bufdesc *rx_bd_base;
+ struct bufdesc *tx_bd_base;
+ /* The next free ring entry */
+ struct bufdesc *cur_rx, *cur_tx;
+ /* The ring entries to be free()ed. */
+ struct bufdesc *dirty_tx;
+
uint tx_full;
/* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
spinlock_t hw_lock;
@@ -289,7 +293,7 @@ static int
fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
- volatile cbd_t *bdp;
+ struct bufdesc *bdp;
unsigned short status;
unsigned long flags;
@@ -374,7 +378,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
}
- fep->cur_tx = (cbd_t *)bdp;
+ fep->cur_tx = bdp;
spin_unlock_irqrestore(&fep->hw_lock, flags);
@@ -391,7 +395,7 @@ fec_timeout(struct net_device *dev)
#ifndef final_version
{
int i;
- cbd_t *bdp;
+ struct bufdesc *bdp;
printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n",
(unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "",
@@ -471,7 +475,7 @@ static void
fec_enet_tx(struct net_device *dev)
{
struct fec_enet_private *fep;
- volatile cbd_t *bdp;
+ struct bufdesc *bdp;
unsigned short status;
struct sk_buff *skb;
@@ -534,7 +538,7 @@ fec_enet_tx(struct ...Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/fec.c | 14 +++++---------
1 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index fea8e27..3a43d96 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1661,11 +1661,10 @@ int __init fec_enet_init(struct net_device *dev, int index)
struct bufdesc *bdp, *cbd_base;
int i, j;
- /* Allocate memory for buffer descriptors.
- */
- mem_addr = (unsigned long)dma_alloc_coherent(NULL, PAGE_SIZE,
- &fep->bd_dma, GFP_KERNEL);
- if (mem_addr == 0) {
+ /* Allocate memory for buffer descriptors. */
+ cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma,
+ GFP_KERNEL);
+ if (!cbd_base) {
printk("FEC: allocate descriptor memory failed?\n");
return -ENOMEM;
}
@@ -1699,10 +1698,7 @@ int __init fec_enet_init(struct net_device *dev, int index)
}
#endif
- cbd_base = (struct bufdesc *)mem_addr;
-
- /* Set receive and transmit descriptor base.
- */
+ /* Set receive and transmit descriptor base. */
fep->rx_bd_base = cbd_base;
fep->tx_bd_base = cbd_base + RX_RING_SIZE;
--
1.6.2.1
--
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/fec.c | 354 +++++++++++++++++++++--------------------------------
1 files changed, 139 insertions(+), 215 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 3a43d96..ab8e66b 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -86,8 +86,7 @@ static unsigned char fec_mac_default[] = {
#endif
#endif /* CONFIG_M5272 */
-/* Forward declarations of some structures to support different PHYs
-*/
+/* Forward declarations of some structures to support different PHYs */
typedef struct {
uint mii_data;
@@ -123,8 +122,7 @@ typedef struct {
#error "FEC: descriptor ring size constants too large"
#endif
-/* Interrupt events/masks.
-*/
+/* Interrupt events/masks. */
#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
#define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */
#define FEC_ENET_BABT ((uint)0x20000000) /* Babbling transmitter */
@@ -177,15 +175,14 @@ struct fec_enet_private {
ushort skb_cur;
ushort skb_dirty;
- /* CPM dual port RAM relative addresses.
- */
+ /* CPM dual port RAM relative addresses */
dma_addr_t bd_dma;
- /* Address of Rx and Tx buffers. */
+ /* Address of Rx and Tx buffers */
struct bufdesc *rx_bd_base;
struct bufdesc *tx_bd_base;
/* The next free ring entry */
struct bufdesc *cur_rx, *cur_tx;
- /* The ring entries to be free()ed. */
+ /* The ring entries to be free()ed */
struct bufdesc *dirty_tx;
uint tx_full;
@@ -245,19 +242,16 @@ static mii_list_t *mii_tail;
static int mii_queue(struct net_device *dev, int request,
void (*func)(uint, struct net_device *));
-/* Make MII read/write commands for the FEC.
-*/
+/* Make MII read/write commands for the FEC */
#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18))
#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | \
(VAL & 0xffff))
#define mk_mii_end 0
-/* Transmitter timeout.
-*/
-#define ...Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/fec.c | 99 +++++++++++++++++++++++++++-------------------------
1 files changed, 51 insertions(+), 48 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index ab8e66b..b72df48 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1518,57 +1518,60 @@ static void set_multicast_list(struct net_device *dev)
tmp = readl(fep->hwp + FEC_R_CNTRL);
tmp |= 0x8;
writel(tmp, fep->hwp + FEC_R_CNTRL);
- } else {
- tmp = readl(fep->hwp + FEC_R_CNTRL);
- tmp &= ~0x8;
- writel(tmp, fep->hwp + FEC_R_CNTRL);
+ return;
+ }
- if (dev->flags & IFF_ALLMULTI) {
- /* Catch all multicast addresses, so set the
- * filter to all 1's
- */
- writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
- writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
- } else {
- /* Clear filter and add the addresses in hash register
- */
- writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
- writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
-
- dmi = dev->mc_list;
-
- for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) {
- /* Only support group multicast for now */
- if (!(dmi->dmi_addr[0] & 1))
- continue;
-
- /* calculate crc32 value of mac address */
- crc = 0xffffffff;
-
- for (i = 0; i < dmi->dmi_addrlen; i++) {
- data = dmi->dmi_addr[i];
- for (bit = 0; bit < 8; bit++, data >>= 1) {
- crc = (crc >> 1) ^
- (((crc ^ data) & 1) ? CRC32_POLY : 0);
- }
- }
-
- /* only upper 6 bits (HASH_BITS) are used
- * which point to specific bit in he hash registers
- */
- hash = (crc >> (32 - HASH_BITS)) & 0x3f;
-
- if (hash > 31) {
- tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
- tmp |= 1 << (hash - 32);
- writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
- } else {
- tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_LOW);
- tmp |= 1 << hash;
- writel(tmp, fep->hwp + ...fec_enet_init() does the hardware initialisation and then calls
fec_restart() which does the same initialisation again, so we
can safely remove the initialisation from fec_enet_init().
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/fec.c | 39 ++++-----------------------------------
1 files changed, 4 insertions(+), 35 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index b72df48..a3037ab 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1616,10 +1616,6 @@ int __init fec_enet_init(struct net_device *dev, int index)
fep->hwp = (void __iomem *)dev->base_addr;
fep->netdev = dev;
- /* Whack a reset. We should wait for this. */
- writel(1, fep->hwp + FEC_ECNTRL);
- udelay(10);
-
/* Set the Ethernet address */
#ifdef CONFIG_M5272
fec_get_mac(dev);
@@ -1641,11 +1637,6 @@ int __init fec_enet_init(struct net_device *dev, int index)
fep->rx_bd_base = cbd_base;
fep->tx_bd_base = cbd_base + RX_RING_SIZE;
- fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
- fep->cur_rx = fep->rx_bd_base;
-
- fep->skb_cur = fep->skb_dirty = 0;
-
/* Initialize the receive buffer descriptors. */
bdp = fep->rx_bd_base;
for (i=0; i<FEC_ENET_RX_PAGES; i++) {
@@ -1689,25 +1680,9 @@ int __init fec_enet_init(struct net_device *dev, int index)
bdp--;
bdp->cbd_sc |= BD_SC_WRAP;
- /* Set receive and transmit descriptor base */
- writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
- writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE,
- fep->hwp + FEC_X_DES_START);
-
#ifdef HAVE_mii_link_interrupt
fec_request_mii_intr(dev);
#endif
-
- writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
- writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
- writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE);
- writel(2, fep->hwp + FEC_ECNTRL);
- writel(0, fep->hwp + FEC_R_DES_ACTIVE);
-#ifndef CONFIG_M5272
- writel(0, fep->hwp + FEC_HASH_TABLE_HIGH);
- writel(0, fep->hwp + FEC_HASH_TABLE_LOW);
-#endif
-
/* The FEC ...Otherwise we get a lot of alignment errors
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/fec.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index a3037ab..be3226c 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -598,13 +598,14 @@ fec_enet_rx(struct net_device *dev)
* include that when passing upstream as it messes up
* bridging applications.
*/
- skb = dev_alloc_skb(pkt_len - 4);
+ skb = dev_alloc_skb(pkt_len - 4 + NET_IP_ALIGN);
- if (skb == NULL) {
+ if (unlikely(!skb)) {
printk("%s: Memory squeeze, dropping packet.\n",
dev->name);
dev->stats.rx_dropped++;
} else {
+ skb_reserve(skb, NET_IP_ALIGN);
skb_put(skb, pkt_len - 4); /* Make room */
skb_copy_to_linear_data(skb, data, pkt_len - 4);
skb->protocol = eth_type_trans(skb, dev);
--
1.6.2.1
--
These printks in fec_timeout do not give useful information in
a production kernel.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/fec.c | 33 ---------------------------------
1 files changed, 0 insertions(+), 33 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index be3226c..d96aba9 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -377,41 +377,8 @@ fec_timeout(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
- printk("%s: transmit timed out.\n", dev->name);
dev->stats.tx_errors++;
-#ifndef final_version
- {
- int i;
- struct bufdesc *bdp;
-
- printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n",
- (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "",
- (unsigned long)fep->dirty_tx,
- (unsigned long)fep->cur_rx);
-
- bdp = fep->tx_bd_base;
- printk(" tx: %u buffers\n", TX_RING_SIZE);
- for (i = 0 ; i < TX_RING_SIZE; i++) {
- printk(" %08x: %04x %04x %08x\n",
- (uint) bdp,
- bdp->cbd_sc,
- bdp->cbd_datlen,
- (int) bdp->cbd_bufaddr);
- bdp++;
- }
- bdp = fep->rx_bd_base;
- printk(" rx: %lu buffers\n", (unsigned long) RX_RING_SIZE);
- for (i = 0 ; i < RX_RING_SIZE; i++) {
- printk(" %08x: %04x %04x %08x\n",
- (uint) bdp,
- bdp->cbd_sc,
- bdp->cbd_datlen,
- (int) bdp->cbd_bufaddr);
- bdp++;
- }
- }
-#endif
fec_restart(dev, fep->full_duplex);
netif_wake_queue(dev);
}
--
1.6.2.1
--
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/fec.c | 36 ++++++++++++++++++++----------------
1 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index d96aba9..f4afbe9 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -210,17 +210,13 @@ struct fec_enet_private {
int full_duplex;
};
-static int fec_enet_open(struct net_device *dev);
-static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
static void fec_enet_mii(struct net_device *dev);
static irqreturn_t fec_enet_interrupt(int irq, void * dev_id);
static void fec_enet_tx(struct net_device *dev);
static void fec_enet_rx(struct net_device *dev);
static int fec_enet_close(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
static void fec_restart(struct net_device *dev, int duplex);
static void fec_stop(struct net_device *dev);
-static void fec_set_mac_address(struct net_device *dev);
/* MII processing. We keep this as simple as possible. Requests are
@@ -1411,7 +1407,6 @@ fec_enet_open(struct net_device *dev)
/* I should reset the ring buffers here, but I don't yet know
* a simple way to do that.
*/
- fec_set_mac_address(dev);
fep->sequence_done = 0;
fep->link = 0;
@@ -1544,19 +1539,35 @@ static void set_multicast_list(struct net_device *dev)
}
/* Set a MAC change in hardware. */
-static void
-fec_set_mac_address(struct net_device *dev)
+static int
+fec_set_mac_address(struct net_device *dev, void *p)
{
struct fec_enet_private *fep = netdev_priv(dev);
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
- /* Set station address. */
writel(dev->dev_addr[3] | (dev->dev_addr[2] << 8) |
(dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24),
fep->hwp + FEC_ADDR_LOW);
writel((dev->dev_addr[5] << 16) | (dev->dev_addr[4] << ...Allocate buffers in fec_open and free them again in fec_close. This makes
it possible to use this driver as a module.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/fec.c | 139 +++++++++++++++++++++++++++++++++-------------------
1 files changed, 88 insertions(+), 51 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index f4afbe9..0e1d268 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -172,6 +172,7 @@ struct fec_enet_private {
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
unsigned char *tx_bounce[TX_RING_SIZE];
struct sk_buff* tx_skbuff[TX_RING_SIZE];
+ struct sk_buff* rx_skbuff[RX_RING_SIZE];
ushort skb_cur;
ushort skb_dirty;
@@ -335,8 +336,8 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Push the data cache so the CPM does not get stale memory
* data.
*/
- dma_sync_single(NULL, bdp->cbd_bufaddr,
- bdp->cbd_datlen, DMA_TO_DEVICE);
+ bdp->cbd_bufaddr = dma_map_single(&dev->dev, skb->data,
+ FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
/* Send it on its way. Tell FEC it's ready, interrupt when done,
* it's the last BD of the frame, and to put the CRC on the end.
@@ -429,7 +430,11 @@ fec_enet_tx(struct net_device *dev)
bdp = fep->dirty_tx;
while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
- if (bdp == fep->cur_tx && fep->tx_full == 0) break;
+ if (bdp == fep->cur_tx && fep->tx_full == 0)
+ break;
+
+ dma_unmap_single(&dev->dev, bdp->cbd_bufaddr, FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
+ bdp->cbd_bufaddr = 0;
skb = fep->tx_skbuff[fep->skb_dirty];
/* Check for errors. */
@@ -553,8 +558,8 @@ fec_enet_rx(struct net_device *dev)
dev->stats.rx_bytes += pkt_len;
data = (__u8*)__va(bdp->cbd_bufaddr);
- dma_sync_single(NULL, (unsigned long)__pa(data),
- pkt_len - 4, DMA_FROM_DEVICE);
+ dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
+ DMA_FROM_DEVICE);
/* This does 16 byte ...We called fec_stop() in fec_enet_close(), thus we have to call
fec_restart() in fec_enet_open().
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/fec.c | 18 ++++++++----------
1 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 0e1d268..28db691 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1490,6 +1490,8 @@ fec_enet_open(struct net_device *dev)
fep->sequence_done = 0;
fep->link = 0;
+ fec_restart(dev, 1);
+
if (fep->phy) {
mii_do_cmd(dev, fep->phy->ack_int);
mii_do_cmd(dev, fep->phy->config);
@@ -1506,18 +1508,14 @@ fec_enet_open(struct net_device *dev)
schedule();
mii_do_cmd(dev, fep->phy->startup);
-
- /* Set the initial link state to true. A lot of hardware
- * based on this device does not implement a PHY interrupt,
- * so we are never notified of link change.
- */
- fep->link = 1;
- } else {
- fep->link = 1; /* lets just try it and see */
- /* no phy, go full duplex, it's most likely a hub chip */
- fec_restart(dev, 1);
}
+ /* Set the initial link state to true. A lot of hardware
+ * based on this device does not implement a PHY interrupt,
+ * so we are never notified of link change.
+ */
+ fep->link = 1;
+
netif_start_queue(dev);
fep->opened = 1;
return 0;
--
1.6.2.1
--
From: Sascha Hauer <s.hauer@pengutronix.de> Applied. --
From: Sascha Hauer <s.hauer@pengutronix.de> Applied. --
Hi Sascha, This is the only one that doesn't work for ColdFire. There is no dma_map_single() or dma_unmap_single() currently. I will fix that, so I am fine with this anyways. With all the other patches applied it still basically works on ColdFire (at least on initial testing on a 5208). I have seen a few spurious interrupts though with these changes applied, that didn't happen before. I will investigate further when get a few minutes. Regards -- ------------------------------------------------------------------------ Greg Ungerer -- Principal Engineer EMAIL: gerg@snapgear.com SnapGear Group, McAfee PHONE: +61 7 3435 2888 825 Stanley St, FAX: +61 7 3891 3630 Woolloongabba, QLD, 4102, Australia WEB: http://www.SnapGear.com --
Ok, thanks for testing Regards, Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | --
From: Sascha Hauer <s.hauer@pengutronix.de> Applied. --
From: Sascha Hauer <s.hauer@pengutronix.de> Applied. --
From: Sascha Hauer <s.hauer@pengutronix.de> Applied. --
From: Sascha Hauer <s.hauer@pengutronix.de> Applied. --
From: Sascha Hauer <s.hauer@pengutronix.de> Applied. --
From: Sascha Hauer <s.hauer@pengutronix.de> Applied. --
From: Sascha Hauer <s.hauer@pengutronix.de> Applied. --
From: Sascha Hauer <s.hauer@pengutronix.de> Applied. --
Since the second register set is used for M5272 we cannot remove it.
Here is an updated version.
Sascha
From 4330c85a8902007a6fb726333a85b9e981579992 Mon Sep 17 00:00:00 2001
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Wed, 15 Apr 2009 09:51:34 +0200
Subject: [PATCH 01/11] fec: switch to writel/readl
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/fec.c | 279 ++++++++++++++++++++++-------------------------------
drivers/net/fec.h | 119 +++++++++--------------
2 files changed, 161 insertions(+), 237 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 682e7f0..3fa3fe4 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -165,7 +165,7 @@ typedef struct {
*/
struct fec_enet_private {
/* Hardware registers of the FEC device */
- volatile fec_t *hwp;
+ void __iomem *hwp;
struct net_device *netdev;
@@ -288,15 +288,11 @@ static int mii_queue(struct net_device *dev, int request,
static int
fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct fec_enet_private *fep;
- volatile fec_t *fecp;
+ struct fec_enet_private *fep = netdev_priv(dev);
volatile cbd_t *bdp;
unsigned short status;
unsigned long flags;
- fep = netdev_priv(dev);
- fecp = (volatile fec_t*)dev->base_addr;
-
if (!fep->link) {
/* Link is down or autonegotiation is in progress. */
return 1;
@@ -363,7 +359,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->trans_start = jiffies;
/* Trigger transmission start */
- fecp->fec_x_des_active = 0;
+ writel(0, fep->hwp + FEC_X_DES_ACTIVE);
/* If this was the last BD in the ring, start at the beginning again.
*/
@@ -436,29 +432,25 @@ static irqreturn_t
fec_enet_interrupt(int irq, void * dev_id)
{
struct net_device *dev = dev_id;
- volatile fec_t *fecp;
+ struct fec_enet_private *fep = netdev_priv(dev);
uint int_events;
irqreturn_t ret = IRQ_NONE;
- fecp = (volatile fec_t*)dev->base_addr;
-
- /* ...From: Sascha Hauer <s.hauer@pengutronix.de> Applied. --
Hi Sascha, It is used for the CONFIG_M5272 case. The offsets to some registers are slightly different for the version of the FEC hardware in that SoC CPU. Regards -- ------------------------------------------------------------------------ Greg Ungerer -- Principal Engineer EMAIL: gerg@snapgear.com SnapGear Group, McAfee PHONE: +61 7 3435 2888 825 Stanley St, FAX: +61 7 3891 3630 Woolloongabba, QLD, 4102, Australia WEB: http://www.SnapGear.com --
Ok, then I'll skip the first patch and update the second one accordingly. Regards -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | --
