* [PATCH] FEC driver: patches for -next
@ 2009-04-15 11:32 Sascha Hauer
2009-04-15 11:32 ` [PATCH 01/12] fec: remove unused ifdef Sascha Hauer
2009-04-15 12:12 ` [PATCH] FEC driver: patches for -next Greg Ungerer
0 siblings, 2 replies; 29+ messages in thread
From: Sascha Hauer @ 2009-04-15 11:32 UTC (permalink / raw)
To: netdev; +Cc: Greg Ungerer
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(-)
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 01/12] fec: remove unused ifdef
2009-04-15 11:32 [PATCH] FEC driver: patches for -next Sascha Hauer
@ 2009-04-15 11:32 ` Sascha Hauer
2009-04-15 11:32 ` [PATCH 02/12] fec: switch to writel/readl Sascha Hauer
2009-04-15 12:12 ` [PATCH] FEC driver: patches for -next Greg Ungerer
1 sibling, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2009-04-15 11:32 UTC (permalink / raw)
To: netdev; +Cc: Greg Ungerer, Sascha Hauer
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 Control reg */
- unsigned long fec_reserved7[158];
- unsigned long fec_addr_low; /* Low 32bits MAC address */
- unsigned long fec_addr_high; /* High 16bits MAC address */
- unsigned long fec_grp_hash_table_high;/* High 32bits hash table */
- unsigned long fec_grp_hash_table_low; /* Low 32bits hash table */
- unsigned long fec_r_des_start; /* Receive descriptor ring */
- unsigned long fec_x_des_start; /* Transmit descriptor ring */
- unsigned long fec_r_buff_size; /* Maximum receive buff size */
- unsigned long reserved8[9];
- unsigned long fec_fifo_ram[112]; /* FIFO RAM buffer */
-} fec_t;
-
-#endif /* CONFIG_M5272 */
-
-
/*
* Define the buffer descriptor structure.
*/
--
1.6.2.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 02/12] fec: switch to writel/readl
2009-04-15 11:32 ` [PATCH 01/12] fec: remove unused ifdef Sascha Hauer
@ 2009-04-15 11:32 ` Sascha Hauer
2009-04-15 11:32 ` [PATCH 03/12] fec: do not typedef struct types Sascha Hauer
2009-04-15 13:11 ` [PATCH 02/12] fec: switch to writel/readl Sascha Hauer
0 siblings, 2 replies; 29+ messages in thread
From: Sascha Hauer @ 2009-04-15 11:32 UTC (permalink / raw)
To: netdev; +Cc: Greg Ungerer, Sascha Hauer
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 function.
- */
+ /* Handle receive event in its own function. */
if (int_events & FEC_ENET_RXF) {
ret = IRQ_HANDLED;
fec_enet_rx(dev);
}
/* Transmit OK, or non-fatal error. Update the buffer
- descriptors. FEC handles all errors, we just discover
- them as part of the transmit process.
- */
+ * descriptors. FEC handles all errors, we just discover
+ * them as part of the transmit process.
+ */
if (int_events & FEC_ENET_TXF) {
ret = IRQ_HANDLED;
fec_enet_tx(dev);
@@ -555,8 +547,7 @@ fec_enet_tx(struct net_device *dev)
static void
fec_enet_rx(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;
struct sk_buff *skb;
@@ -567,9 +558,6 @@ fec_enet_rx(struct net_device *dev)
flush_cache_all();
#endif
- fep = netdev_priv(dev);
- fecp = (volatile fec_t*)dev->base_addr;
-
spin_lock_irq(&fep->hw_lock);
/* First, grab all of the stats for the incoming packet.
@@ -665,7 +653,7 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
* incoming frames. On a heavily loaded network, we should be
* able to keep up at the expense of system resources.
*/
- fecp->fec_r_des_active = 0;
+ writel(0, fep->hwp + FEC_R_DES_ACTIVE);
#endif
} /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */
fep->cur_rx = (cbd_t *)bdp;
@@ -690,30 +678,25 @@ static void
fec_enet_mii(struct net_device *dev)
{
struct fec_enet_private *fep;
- volatile fec_t *ep;
mii_list_t *mip;
- uint mii_reg;
fep = netdev_priv(dev);
spin_lock_irq(&fep->mii_lock);
- ep = fep->hwp;
- mii_reg = ep->fec_mii_data;
-
if ((mip = mii_head) == NULL) {
printk("MII and no head!\n");
goto unlock;
}
if (mip->mii_func != NULL)
- (*(mip->mii_func))(mii_reg, dev);
+ (*(mip->mii_func))(readl(fep->hwp + FEC_MII_DATA), dev);
mii_head = mip->mii_next;
mip->mii_next = mii_free;
mii_free = mip;
if ((mip = mii_head) != NULL)
- ep->fec_mii_data = mip->mii_regval;
+ writel(mip->mii_regval, fep->hwp + FEC_MII_DATA);
unlock:
spin_unlock_irq(&fep->mii_lock);
@@ -745,7 +728,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
mii_tail = mip;
} else {
mii_head = mii_tail = mip;
- fep->hwp->fec_mii_data = regval;
+ writel(regval, fep->hwp + FEC_MII_DATA);
}
} else {
retval = 1;
@@ -1246,11 +1229,8 @@ static void __inline__ fec_phy_ack_intr(void)
static void __inline__ fec_get_mac(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
- volatile fec_t *fecp;
unsigned char *iap, tmpaddr[ETH_ALEN];
- fecp = fep->hwp;
-
if (FEC_FLASHMAC) {
/*
* Get MAC address from FLASH.
@@ -1264,8 +1244,8 @@ static void __inline__ fec_get_mac(struct net_device *dev)
(iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
iap = fec_mac_default;
} else {
- *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
- *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
+ *((unsigned long *) &tmpaddr[0]) = readl(fep->hwp + FEC_ADDR_LOW);
+ *((unsigned short *) &tmpaddr[4]) = (readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
iap = &tmpaddr[0];
}
@@ -1457,11 +1437,9 @@ static void
mii_discover_phy(uint mii_reg, struct net_device *dev)
{
struct fec_enet_private *fep;
- volatile fec_t *fecp;
uint phytype;
fep = netdev_priv(dev);
- fecp = fep->hwp;
if (fep->phy_addr < 32) {
if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) {
@@ -1479,7 +1457,8 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
} else {
printk("FEC: No PHY device found.\n");
/* Disable external MII interface */
- fecp->fec_mii_speed = fep->phy_speed = 0;
+ writel(0, fep->hwp + FEC_MII_SPEED);
+ fep->phy_speed = 0;
#ifdef HAVE_mii_link_interrupt
fec_disable_phy_intr();
#endif
@@ -1583,32 +1562,31 @@ fec_enet_close(struct net_device *dev)
static void set_multicast_list(struct net_device *dev)
{
- struct fec_enet_private *fep;
- volatile fec_t *ep;
+ struct fec_enet_private *fep = netdev_priv(dev);
struct dev_mc_list *dmi;
- unsigned int i, j, bit, data, crc;
+ unsigned int i, j, bit, data, crc, tmp;
unsigned char hash;
- fep = netdev_priv(dev);
- ep = fep->hwp;
-
if (dev->flags&IFF_PROMISC) {
- ep->fec_r_cntrl |= 0x0008;
+ tmp = readl(fep->hwp + FEC_R_CNTRL);
+ tmp |= 0x8;
+ writel(tmp, fep->hwp + FEC_R_CNTRL);
} else {
-
- ep->fec_r_cntrl &= ~0x0008;
+ tmp = readl(fep->hwp + FEC_R_CNTRL);
+ tmp &= ~0x8;
+ writel(tmp, fep->hwp + FEC_R_CNTRL);
if (dev->flags & IFF_ALLMULTI) {
/* Catch all multicast addresses, so set the
* filter to all 1's.
*/
- ep->fec_grp_hash_table_high = 0xffffffff;
- ep->fec_grp_hash_table_low = 0xffffffff;
+ 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.
*/
- ep->fec_grp_hash_table_high = 0;
- ep->fec_grp_hash_table_low = 0;
+ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
dmi = dev->mc_list;
@@ -1638,10 +1616,15 @@ static void set_multicast_list(struct net_device *dev)
*/
hash = (crc >> (32 - HASH_BITS)) & 0x3f;
- if (hash > 31)
- ep->fec_grp_hash_table_high |= 1 << (hash - 32);
- else
- ep->fec_grp_hash_table_low |= 1 << hash;
+ 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_GRP_HASH_TABLE_LOW);
+ }
}
}
}
@@ -1652,16 +1635,14 @@ static void set_multicast_list(struct net_device *dev)
static void
fec_set_mac_address(struct net_device *dev)
{
- volatile fec_t *fecp;
-
- fecp = ((struct fec_enet_private *)netdev_priv(dev))->hwp;
+ struct fec_enet_private *fep = netdev_priv(dev);
/* Set station address. */
- fecp->fec_addr_low = dev->dev_addr[3] | (dev->dev_addr[2] << 8) |
- (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24);
- fecp->fec_addr_high = (dev->dev_addr[5] << 16) |
- (dev->dev_addr[4] << 24);
-
+ 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] << 24),
+ fep + FEC_ADDR_HIGH);
}
/*
@@ -1675,7 +1656,6 @@ int __init fec_enet_init(struct net_device *dev, int index)
unsigned long mem_addr;
volatile cbd_t *bdp;
cbd_t *cbd_base;
- volatile fec_t *fecp;
int i, j;
/* Allocate memory for buffer descriptors.
@@ -1690,17 +1670,13 @@ int __init fec_enet_init(struct net_device *dev, int index)
spin_lock_init(&fep->hw_lock);
spin_lock_init(&fep->mii_lock);
- /* Create an Ethernet device instance.
- */
- fecp = (volatile fec_t *)dev->base_addr;
-
fep->index = index;
- fep->hwp = fecp;
+ fep->hwp = (void __iomem *)dev->base_addr;
fep->netdev = dev;
/* Whack a reset. We should wait for this.
*/
- fecp->fec_ecntrl = 1;
+ writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
/* Set the Ethernet address */
@@ -1709,12 +1685,12 @@ int __init fec_enet_init(struct net_device *dev, int index)
#else
{
unsigned long l;
- l = fecp->fec_addr_low;
+ l = readl(fep->hwp + FEC_ADDR_LOW);
dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24);
dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16);
dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8);
dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0);
- l = fecp->fec_addr_high;
+ l = readl(fep->hwp + FEC_ADDR_HIGH);
dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24);
dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16);
}
@@ -1784,22 +1760,22 @@ int __init fec_enet_init(struct net_device *dev, int index)
/* Set receive and transmit descriptor base.
*/
- fecp->fec_r_des_start = fep->bd_dma;
- fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
- * RX_RING_SIZE;
+ writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
+ writel((unsigned long)fep->bd_dma + sizeof(cbd_t) * RX_RING_SIZE,
+ fep->hwp + FEC_X_DES_START);
#ifdef HAVE_mii_link_interrupt
fec_request_mii_intr(dev);
#endif
- fecp->fec_grp_hash_table_high = 0;
- fecp->fec_grp_hash_table_low = 0;
- fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
- fecp->fec_ecntrl = 2;
- fecp->fec_r_des_active = 0;
+ 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
- fecp->fec_hash_table_high = 0;
- fecp->fec_hash_table_low = 0;
+ writel(0, fep->hwp + FEC_HASH_TABLE_HIGH);
+ writel(0, fep->hwp + FEC_HASH_TABLE_LOW);
#endif
/* The FEC Ethernet specific entries in the device structure. */
@@ -1815,20 +1791,21 @@ int __init fec_enet_init(struct net_device *dev, int index)
mii_free = mii_cmds;
/* setup MII interface */
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
- fecp->fec_x_cntrl = 0x00;
+ writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL);
+ writel(0, fep->hwp + FEC_X_CNTRL);
/*
* Set MII speed to 2.5 MHz
*/
fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999)
/ 2500000) / 2) & 0x3F) << 1;
- fecp->fec_mii_speed = fep->phy_speed;
+ writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
fec_restart(dev, 0);
/* Clear and enable interrupts */
- fecp->fec_ievent = 0xffc00000;
- fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
+ writel(0xffc00000, fep->hwp + FEC_IEVENT);
+ writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII,
+ fep->hwp + FEC_IMASK);
/* Queue up command to detect the PHY and initialize the
* remainder of the interface.
@@ -1847,47 +1824,36 @@ int __init fec_enet_init(struct net_device *dev, int index)
static void
fec_restart(struct net_device *dev, int duplex)
{
- struct fec_enet_private *fep;
+ struct fec_enet_private *fep = netdev_priv(dev);
volatile cbd_t *bdp;
- volatile fec_t *fecp;
int i;
- fep = netdev_priv(dev);
- fecp = fep->hwp;
-
- /* Whack a reset. We should wait for this.
- */
- fecp->fec_ecntrl = 1;
+ /* Whack a reset. We should wait for this. */
+ writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
- /* Clear any outstanding interrupt.
- */
- fecp->fec_ievent = 0xffc00000;
+ /* Clear any outstanding interrupt. */
+ writel(0xffc00000, fep->hwp + FEC_IEVENT);
- /* Set station address.
- */
+ /* Set station address. */
fec_set_mac_address(dev);
- /* Reset all multicast.
- */
- fecp->fec_grp_hash_table_high = 0;
- fecp->fec_grp_hash_table_low = 0;
+ /* Reset all multicast. */
+ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
- /* Set maximum receive buffer size.
- */
- fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
+ /* Set maximum receive buffer size. */
+ writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE);
- /* Set receive and transmit descriptor base.
- */
- fecp->fec_r_des_start = fep->bd_dma;
- fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
- * RX_RING_SIZE;
+ /* Set receive and transmit descriptor base. */
+ writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
+ writel((unsigned long)fep->bd_dma + sizeof(cbd_t) * RX_RING_SIZE,
+ fep->hwp + FEC_X_DES_START);
fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
fep->cur_rx = fep->rx_bd_base;
- /* Reset SKB transmit buffers.
- */
+ /* Reset SKB transmit buffers. */
fep->skb_cur = fep->skb_dirty = 0;
for (i=0; i<=TX_RING_MOD_MASK; i++) {
if (fep->tx_skbuff[i] != NULL) {
@@ -1896,96 +1862,81 @@ fec_restart(struct net_device *dev, int duplex)
}
}
- /* Initialize the receive buffer descriptors.
- */
+ /* Initialize the receive buffer descriptors. */
bdp = fep->rx_bd_base;
for (i=0; i<RX_RING_SIZE; i++) {
- /* Initialize the BD for every fragment in the page.
- */
+ /* Initialize the BD for every fragment in the page. */
bdp->cbd_sc = BD_ENET_RX_EMPTY;
bdp++;
}
- /* Set the last buffer to wrap.
- */
+ /* Set the last buffer to wrap. */
bdp--;
bdp->cbd_sc |= BD_SC_WRAP;
- /* ...and the same for transmmit.
- */
+ /* ...and the same for transmmit. */
bdp = fep->tx_bd_base;
for (i=0; i<TX_RING_SIZE; i++) {
- /* Initialize the BD for every fragment in the page.
- */
+ /* Initialize the BD for every fragment in the page. */
bdp->cbd_sc = 0;
bdp->cbd_bufaddr = 0;
bdp++;
}
- /* Set the last buffer to wrap.
- */
+ /* Set the last buffer to wrap. */
bdp--;
bdp->cbd_sc |= BD_SC_WRAP;
- /* Enable MII mode.
- */
+ /* Enable MII mode. */
if (duplex) {
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;/* MII enable */
- fecp->fec_x_cntrl = 0x04; /* FD enable */
+ /* MII enable / FD enable */
+ writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL);
+ writel(0x04, fep->hwp + FEC_X_CNTRL);
} else {
- /* MII enable|No Rcv on Xmit */
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x06;
- fecp->fec_x_cntrl = 0x00;
+ /* MII enable / No Rcv on Xmit */
+ writel(OPT_FRAME_SIZE | 0x06, fep->hwp + FEC_R_CNTRL);
+ writel(0x0, fep->hwp + FEC_X_CNTRL);
}
fep->full_duplex = duplex;
- /* Set MII speed.
- */
- fecp->fec_mii_speed = fep->phy_speed;
+ /* Set MII speed. */
+ writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
- /* And last, enable the transmit and receive processing.
- */
- fecp->fec_ecntrl = 2;
- fecp->fec_r_des_active = 0;
+ /* And last, enable the transmit and receive processing. */
+ writel(2, fep->hwp + FEC_ECNTRL);
+ writel(0, fep->hwp + FEC_R_DES_ACTIVE);
- /* Enable interrupts we wish to service.
- */
- fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
+ /* Enable interrupts we wish to service. */
+ writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII,
+ fep->hwp + FEC_IMASK);
}
static void
fec_stop(struct net_device *dev)
{
- volatile fec_t *fecp;
- struct fec_enet_private *fep;
-
- fep = netdev_priv(dev);
- fecp = fep->hwp;
+ struct fec_enet_private *fep = netdev_priv(dev);
/*
** We cannot expect a graceful transmit stop without link !!!
*/
- if (fep->link)
- {
- fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */
+ if (fep->link) {
+ writel(1, fep->hwp + FEC_X_CNTRL); /* Graceful transmit stop */
udelay(10);
- if (!(fecp->fec_ievent & FEC_ENET_GRA))
+ if (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_GRA))
printk("fec_stop : Graceful transmit stop did not complete !\n");
- }
+ }
- /* Whack a reset. We should wait for this.
- */
- fecp->fec_ecntrl = 1;
+ /* Whack a reset. We should wait for this. */
+ writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
- /* Clear outstanding MII command interrupts.
- */
- fecp->fec_ievent = FEC_ENET_MII;
+ /* Clear outstanding MII command interrupts. */
+ writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
- fecp->fec_imask = FEC_ENET_MII;
- fecp->fec_mii_speed = fep->phy_speed;
+ writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
+ writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
}
static int __devinit
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index c2f97f3..bb4dabc 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -18,43 +18,29 @@
* registers in the same peripheral device on different models
* of the ColdFire!
*/
-typedef struct fec {
- unsigned long fec_reserved0;
- unsigned long fec_ievent; /* Interrupt event reg */
- unsigned long fec_imask; /* Interrupt mask reg */
- unsigned long fec_reserved1;
- unsigned long fec_r_des_active; /* Receive descriptor reg */
- unsigned long fec_x_des_active; /* Transmit descriptor reg */
- unsigned long fec_reserved2[3];
- unsigned long fec_ecntrl; /* Ethernet control reg */
- unsigned long fec_reserved3[6];
- unsigned long fec_mii_data; /* MII manage frame reg */
- unsigned long fec_mii_speed; /* MII speed control reg */
- unsigned long fec_reserved4[7];
- unsigned long fec_mib_ctrlstat; /* MIB control/status reg */
- unsigned long fec_reserved5[7];
- unsigned long fec_r_cntrl; /* Receive control reg */
- unsigned long fec_reserved6[15];
- unsigned long fec_x_cntrl; /* Transmit Control reg */
- unsigned long fec_reserved7[7];
- unsigned long fec_addr_low; /* Low 32bits MAC address */
- unsigned long fec_addr_high; /* High 16bits MAC address */
- unsigned long fec_opd; /* Opcode + Pause duration */
- unsigned long fec_reserved8[10];
- unsigned long fec_hash_table_high; /* High 32bits hash table */
- unsigned long fec_hash_table_low; /* Low 32bits hash table */
- unsigned long fec_grp_hash_table_high;/* High 32bits hash table */
- unsigned long fec_grp_hash_table_low; /* Low 32bits hash table */
- unsigned long fec_reserved9[7];
- unsigned long fec_x_wmrk; /* FIFO transmit water mark */
- unsigned long fec_reserved10;
- unsigned long fec_r_bound; /* FIFO receive bound reg */
- unsigned long fec_r_fstart; /* FIFO receive start reg */
- unsigned long fec_reserved11[11];
- unsigned long fec_r_des_start; /* Receive descriptor ring */
- unsigned long fec_x_des_start; /* Transmit descriptor ring */
- unsigned long fec_r_buff_size; /* Maximum receive buff size */
-} fec_t;
+#define FEC_IEVENT 0x004 /* Interrupt event reg */
+#define FEC_IMASK 0x008 /* Interrupt mask reg */
+#define FEC_R_DES_ACTIVE 0x010 /* Receive descriptor reg */
+#define FEC_X_DES_ACTIVE 0x014 /* Transmit descriptor reg */
+#define FEC_ECNTRL 0x024 /* Ethernet control reg */
+#define FEC_MII_DATA 0x040 /* MII manage frame reg */
+#define FEC_MII_SPEED 0x044 /* MII speed control reg */
+#define FEC_MIB_CTRLSTAT 0x064 /* MIB control/status reg */
+#define FEC_R_CNTRL 0x084 /* Receive control reg */
+#define FEC_X_CNTRL 0x0c4 /* Transmit Control reg */
+#define FEC_ADDR_LOW 0x0e4 /* Low 32bits MAC address */
+#define FEC_ADDR_HIGH 0x0e8 /* High 16bits MAC address */
+#define FEC_OPD 0x0ec /* Opcode + Pause duration */
+#define FEC_HASH_TABLE_HIGH 0x118 /* High 32bits hash table */
+#define FEC_HASH_TABLE_LOW 0x11c /* Low 32bits hash table */
+#define FEC_GRP_HASH_TABLE_HIGH 0x120 /* High 32bits hash table */
+#define FEC_GRP_HASH_TABLE_LOW 0x124 /* Low 32bits hash table */
+#define FEC_X_WMRK 0x144 /* FIFO transmit water mark */
+#define FEC_R_BOUND 0x14c /* FIFO receive bound reg */
+#define FEC_R_FSTART 0x150 /* FIFO receive start reg */
+#define FEC_R_DES_START 0x180 /* Receive descriptor ring */
+#define FEC_X_DES_START 0x184 /* Transmit descriptor ring */
+#define FEC_R_BUFF_SIZE 0x188 /* Maximum receive buff size */
/*
* Define the buffer descriptor structure.
--
1.6.2.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 03/12] fec: do not typedef struct types
2009-04-15 11:32 ` [PATCH 02/12] fec: switch to writel/readl Sascha Hauer
@ 2009-04-15 11:32 ` Sascha Hauer
2009-04-15 11:32 ` [PATCH 04/12] fec: remove unnecessary cast Sascha Hauer
2009-04-16 9:36 ` [PATCH 03/12] fec: do not typedef struct types David Miller
2009-04-15 13:11 ` [PATCH 02/12] fec: switch to writel/readl Sascha Hauer
1 sibling, 2 replies; 29+ messages in thread
From: Sascha Hauer @ 2009-04-15 11:32 UTC (permalink / raw)
To: netdev; +Cc: Greg Ungerer, Sascha Hauer
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 net_device *dev)
netif_wake_queue(dev);
}
}
- fep->dirty_tx = (cbd_t *)bdp;
+ fep->dirty_tx = bdp;
spin_unlock_irq(&fep->hw_lock);
}
@@ -548,7 +552,7 @@ static void
fec_enet_rx(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
- volatile cbd_t *bdp;
+ struct bufdesc *bdp;
unsigned short status;
struct sk_buff *skb;
ushort pkt_len;
@@ -656,7 +660,7 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
writel(0, fep->hwp + FEC_R_DES_ACTIVE);
#endif
} /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */
- fep->cur_rx = (cbd_t *)bdp;
+ fep->cur_rx = bdp;
#if 0
/* Doing this here will allow us to process all frames in the
@@ -1654,8 +1658,7 @@ int __init fec_enet_init(struct net_device *dev, int index)
{
struct fec_enet_private *fep = netdev_priv(dev);
unsigned long mem_addr;
- volatile cbd_t *bdp;
- cbd_t *cbd_base;
+ struct bufdesc *bdp, *cbd_base;
int i, j;
/* Allocate memory for buffer descriptors.
@@ -1696,7 +1699,7 @@ int __init fec_enet_init(struct net_device *dev, int index)
}
#endif
- cbd_base = (cbd_t *)mem_addr;
+ cbd_base = (struct bufdesc *)mem_addr;
/* Set receive and transmit descriptor base.
*/
@@ -1761,7 +1764,7 @@ int __init fec_enet_init(struct net_device *dev, int index)
/* Set receive and transmit descriptor base.
*/
writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
- writel((unsigned long)fep->bd_dma + sizeof(cbd_t) * RX_RING_SIZE,
+ writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE,
fep->hwp + FEC_X_DES_START);
#ifdef HAVE_mii_link_interrupt
@@ -1825,7 +1828,7 @@ static void
fec_restart(struct net_device *dev, int duplex)
{
struct fec_enet_private *fep = netdev_priv(dev);
- volatile cbd_t *bdp;
+ struct bufdesc *bdp;
int i;
/* Whack a reset. We should wait for this. */
@@ -1847,7 +1850,7 @@ fec_restart(struct net_device *dev, int duplex)
/* Set receive and transmit descriptor base. */
writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
- writel((unsigned long)fep->bd_dma + sizeof(cbd_t) * RX_RING_SIZE,
+ writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE,
fep->hwp + FEC_X_DES_START);
fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index bb4dabc..9ebebd6 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -46,17 +46,17 @@
* Define the buffer descriptor structure.
*/
#ifdef CONFIG_ARCH_MXC
-typedef struct bufdesc {
+struct bufdesc {
unsigned short cbd_datlen; /* Data length */
unsigned short cbd_sc; /* Control and status info */
unsigned long cbd_bufaddr; /* Buffer address */
-} cbd_t;
+};
#else
-typedef struct bufdesc {
+struct bufdesc {
unsigned short cbd_sc; /* Control and status info */
unsigned short cbd_datlen; /* Data length */
unsigned long cbd_bufaddr; /* Buffer address */
-} cbd_t;
+};
#endif
/*
--
1.6.2.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 04/12] fec: remove unnecessary cast
2009-04-15 11:32 ` [PATCH 03/12] fec: do not typedef struct types Sascha Hauer
@ 2009-04-15 11:32 ` Sascha Hauer
2009-04-15 11:32 ` [PATCH 05/12] fec: Codingstyle cleanups Sascha Hauer
2009-04-16 9:36 ` [PATCH 04/12] fec: remove unnecessary cast David Miller
2009-04-16 9:36 ` [PATCH 03/12] fec: do not typedef struct types David Miller
1 sibling, 2 replies; 29+ messages in thread
From: Sascha Hauer @ 2009-04-15 11:32 UTC (permalink / raw)
To: netdev; +Cc: Greg Ungerer, Sascha Hauer
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
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 05/12] fec: Codingstyle cleanups
2009-04-15 11:32 ` [PATCH 04/12] fec: remove unnecessary cast Sascha Hauer
@ 2009-04-15 11:32 ` Sascha Hauer
2009-04-15 11:32 ` [PATCH 06/12] fec: refactor set_multicast_list() to make it more readable Sascha Hauer
2009-04-16 9:36 ` [PATCH 05/12] fec: Codingstyle cleanups David Miller
2009-04-16 9:36 ` [PATCH 04/12] fec: remove unnecessary cast David Miller
1 sibling, 2 replies; 29+ messages in thread
From: Sascha Hauer @ 2009-04-15 11:32 UTC (permalink / raw)
To: netdev; +Cc: Greg Ungerer, Sascha Hauer
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 TX_TIMEOUT (2*HZ)
+/* Transmitter timeout */
+#define TX_TIMEOUT (2 * HZ)
-/* Register definitions for the PHY.
-*/
+/* Register definitions for the PHY */
#define MII_REG_CR 0 /* Control Register */
#define MII_REG_SR 1 /* Status Register */
@@ -307,7 +301,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
bdp = fep->cur_tx;
status = bdp->cbd_sc;
-#ifndef final_version
+
if (status & BD_ENET_TX_READY) {
/* Ooops. All transmit buffers are full. Bail out.
* This should not happen, since dev->tbusy should be set.
@@ -316,21 +310,18 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irqrestore(&fep->hw_lock, flags);
return 1;
}
-#endif
- /* Clear all of the status flags.
- */
+ /* Clear all of the status flags */
status &= ~BD_ENET_TX_STATS;
- /* Set buffer length and buffer pointer.
- */
+ /* Set buffer length and buffer pointer */
bdp->cbd_bufaddr = __pa(skb->data);
bdp->cbd_datlen = skb->len;
/*
- * On some FEC implementations data must be aligned on
- * 4-byte boundaries. Use bounce buffers to copy data
- * and get it aligned. Ugh.
+ * On some FEC implementations data must be aligned on
+ * 4-byte boundaries. Use bounce buffers to copy data
+ * and get it aligned. Ugh.
*/
if (bdp->cbd_bufaddr & FEC_ALIGNMENT) {
unsigned int index;
@@ -339,8 +330,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]);
}
- /* Save skb pointer.
- */
+ /* Save skb pointer */
fep->tx_skbuff[fep->skb_cur] = skb;
dev->stats.tx_bytes += skb->len;
@@ -355,7 +345,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* 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.
*/
-
status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR
| BD_ENET_TX_LAST | BD_ENET_TX_TC);
bdp->cbd_sc = status;
@@ -365,13 +354,11 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Trigger transmission start */
writel(0, fep->hwp + FEC_X_DES_ACTIVE);
- /* If this was the last BD in the ring, start at the beginning again.
- */
- if (status & BD_ENET_TX_WRAP) {
+ /* If this was the last BD in the ring, start at the beginning again. */
+ if (status & BD_ENET_TX_WRAP)
bdp = fep->tx_bd_base;
- } else {
+ else
bdp++;
- }
if (bdp == fep->dirty_tx) {
fep->tx_full = 1;
@@ -429,9 +416,6 @@ fec_timeout(struct net_device *dev)
netif_wake_queue(dev);
}
-/* The interrupt handler.
- * This is called from the MPC core interrupt.
- */
static irqreturn_t
fec_enet_interrupt(int irq, void * dev_id)
{
@@ -440,12 +424,10 @@ fec_enet_interrupt(int irq, void * dev_id)
uint int_events;
irqreturn_t ret = IRQ_NONE;
- /* Get the interrupt events that caused us to be here. */
do {
int_events = readl(fep->hwp + FEC_IEVENT);
writel(int_events, fep->hwp + FEC_IEVENT);
- /* Handle receive event in its own function. */
if (int_events & FEC_ENET_RXF) {
ret = IRQ_HANDLED;
fec_enet_rx(dev);
@@ -506,31 +488,27 @@ fec_enet_tx(struct net_device *dev)
dev->stats.tx_packets++;
}
-#ifndef final_version
if (status & BD_ENET_TX_READY)
printk("HEY! Enet xmit interrupt and TX_READY.\n");
-#endif
+
/* Deferred means some collisions occurred during transmit,
* but we eventually sent the packet OK.
*/
if (status & BD_ENET_TX_DEF)
dev->stats.collisions++;
- /* Free the sk buffer associated with this last transmit.
- */
+ /* Free the sk buffer associated with this last transmit */
dev_kfree_skb_any(skb);
fep->tx_skbuff[fep->skb_dirty] = NULL;
fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK;
- /* Update pointer to next buffer descriptor to be transmitted.
- */
+ /* Update pointer to next buffer descriptor to be transmitted */
if (status & BD_ENET_TX_WRAP)
bdp = fep->tx_bd_base;
else
bdp++;
- /* Since we have freed up a buffer, the ring is no longer
- * full.
+ /* Since we have freed up a buffer, the ring is no longer full
*/
if (fep->tx_full) {
fep->tx_full = 0;
@@ -569,114 +547,93 @@ fec_enet_rx(struct net_device *dev)
*/
bdp = fep->cur_rx;
-while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
+ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
-#ifndef final_version
- /* Since we have allocated space to hold a complete frame,
- * the last indicator should be set.
- */
- if ((status & BD_ENET_RX_LAST) == 0)
- printk("FEC ENET: rcv is not +last\n");
-#endif
+ /* Since we have allocated space to hold a complete frame,
+ * the last indicator should be set.
+ */
+ if ((status & BD_ENET_RX_LAST) == 0)
+ printk("FEC ENET: rcv is not +last\n");
- if (!fep->opened)
- goto rx_processing_done;
+ if (!fep->opened)
+ goto rx_processing_done;
- /* Check for errors. */
- if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
+ /* Check for errors. */
+ if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
BD_ENET_RX_CR | BD_ENET_RX_OV)) {
- dev->stats.rx_errors++;
- if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
- /* Frame too long or too short. */
- dev->stats.rx_length_errors++;
+ dev->stats.rx_errors++;
+ if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
+ /* Frame too long or too short. */
+ dev->stats.rx_length_errors++;
+ }
+ if (status & BD_ENET_RX_NO) /* Frame alignment */
+ dev->stats.rx_frame_errors++;
+ if (status & BD_ENET_RX_CR) /* CRC Error */
+ dev->stats.rx_crc_errors++;
+ if (status & BD_ENET_RX_OV) /* FIFO overrun */
+ dev->stats.rx_fifo_errors++;
}
- if (status & BD_ENET_RX_NO) /* Frame alignment */
- dev->stats.rx_frame_errors++;
- if (status & BD_ENET_RX_CR) /* CRC Error */
- dev->stats.rx_crc_errors++;
- if (status & BD_ENET_RX_OV) /* FIFO overrun */
- dev->stats.rx_fifo_errors++;
- }
- /* Report late collisions as a frame error.
- * On this error, the BD is closed, but we don't know what we
- * have in the buffer. So, just drop this frame on the floor.
- */
- if (status & BD_ENET_RX_CL) {
- dev->stats.rx_errors++;
- dev->stats.rx_frame_errors++;
- goto rx_processing_done;
- }
+ /* Report late collisions as a frame error.
+ * On this error, the BD is closed, but we don't know what we
+ * have in the buffer. So, just drop this frame on the floor.
+ */
+ if (status & BD_ENET_RX_CL) {
+ dev->stats.rx_errors++;
+ dev->stats.rx_frame_errors++;
+ goto rx_processing_done;
+ }
- /* Process the incoming frame.
- */
- dev->stats.rx_packets++;
- pkt_len = bdp->cbd_datlen;
- dev->stats.rx_bytes += pkt_len;
- data = (__u8*)__va(bdp->cbd_bufaddr);
+ /* Process the incoming frame. */
+ dev->stats.rx_packets++;
+ pkt_len = bdp->cbd_datlen;
+ dev->stats.rx_bytes += pkt_len;
+ data = (__u8*)__va(bdp->cbd_bufaddr);
- dma_sync_single(NULL, (unsigned long)__pa(data),
+ dma_sync_single(NULL, (unsigned long)__pa(data),
pkt_len - 4, DMA_FROM_DEVICE);
- /* This does 16 byte alignment, exactly what we need.
- * The packet length includes FCS, but we don't want to
- * include that when passing upstream as it messes up
- * bridging applications.
- */
- skb = dev_alloc_skb(pkt_len-4);
-
- if (skb == NULL) {
- printk("%s: Memory squeeze, dropping packet.\n", dev->name);
- dev->stats.rx_dropped++;
- } else {
- 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);
- netif_rx(skb);
- }
- rx_processing_done:
-
- /* Clear the status flags for this buffer.
- */
- status &= ~BD_ENET_RX_STATS;
+ /* This does 16 byte alignment, exactly what we need.
+ * The packet length includes FCS, but we don't want to
+ * include that when passing upstream as it messes up
+ * bridging applications.
+ */
+ skb = dev_alloc_skb(pkt_len - 4);
- /* Mark the buffer empty.
- */
- status |= BD_ENET_RX_EMPTY;
- bdp->cbd_sc = status;
+ if (skb == NULL) {
+ printk("%s: Memory squeeze, dropping packet.\n",
+ dev->name);
+ dev->stats.rx_dropped++;
+ } else {
+ 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);
+ netif_rx(skb);
+ }
+rx_processing_done:
+ /* Clear the status flags for this buffer */
+ status &= ~BD_ENET_RX_STATS;
- /* Update BD pointer to next entry.
- */
- if (status & BD_ENET_RX_WRAP)
- bdp = fep->rx_bd_base;
- else
- bdp++;
+ /* Mark the buffer empty */
+ status |= BD_ENET_RX_EMPTY;
+ bdp->cbd_sc = status;
-#if 1
- /* Doing this here will keep the FEC running while we process
- * incoming frames. On a heavily loaded network, we should be
- * able to keep up at the expense of system resources.
- */
- writel(0, fep->hwp + FEC_R_DES_ACTIVE);
-#endif
- } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */
+ /* Update BD pointer to next entry */
+ if (status & BD_ENET_RX_WRAP)
+ bdp = fep->rx_bd_base;
+ else
+ bdp++;
+ /* Doing this here will keep the FEC running while we process
+ * incoming frames. On a heavily loaded network, we should be
+ * able to keep up at the expense of system resources.
+ */
+ writel(0, fep->hwp + FEC_R_DES_ACTIVE);
+ }
fep->cur_rx = bdp;
-#if 0
- /* Doing this here will allow us to process all frames in the
- * ring before the FEC is allowed to put more there. On a heavily
- * loaded network, some frames may be lost. Unfortunately, this
- * increases the interrupt overhead since we can potentially work
- * our way back to the interrupt return only to come right back
- * here.
- */
- fecp->fec_r_des_active = 0;
-#endif
-
spin_unlock_irq(&fep->hw_lock);
}
-
/* called from interrupt context */
static void
fec_enet_mii(struct net_device *dev)
@@ -714,8 +671,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
mii_list_t *mip;
int retval;
- /* Add PHY address to register command.
- */
+ /* Add PHY address to register command */
fep = netdev_priv(dev);
spin_lock_irqsave(&fep->mii_lock, flags);
@@ -1359,11 +1315,6 @@ static void mii_relink(struct work_struct *work)
fec_restart(dev, duplex);
} else
fec_stop(dev);
-
-#if 0
- enable_irq(fep->mii_irq);
-#endif
-
}
/* mii_queue_relink is called in interrupt context from mii_link_interrupt */
@@ -1372,12 +1323,12 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev)
struct fec_enet_private *fep = netdev_priv(dev);
/*
- ** We cannot queue phy_task twice in the workqueue. It
- ** would cause an endless loop in the workqueue.
- ** Fortunately, if the last mii_relink entry has not yet been
- ** executed now, it will do the job for the current interrupt,
- ** which is just what we want.
- */
+ * We cannot queue phy_task twice in the workqueue. It
+ * would cause an endless loop in the workqueue.
+ * Fortunately, if the last mii_relink entry has not yet been
+ * executed now, it will do the job for the current interrupt,
+ * which is just what we want.
+ */
if (fep->mii_phy_task_queued)
return;
@@ -1408,8 +1359,7 @@ phy_cmd_t const phy_cmd_config[] = {
{ mk_mii_end, }
};
-/* Read remainder of PHY ID.
-*/
+/* Read remainder of PHY ID. */
static void
mii_discover_phy3(uint mii_reg, struct net_device *dev)
{
@@ -1448,8 +1398,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
if (fep->phy_addr < 32) {
if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) {
- /* Got first part of ID, now get remainder.
- */
+ /* Got first part of ID, now get remainder */
fep->phy_id = phytype << 16;
mii_queue(dev, mk_mii_read(MII_REG_PHYIR2),
mii_discover_phy3);
@@ -1469,8 +1418,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
}
}
-/* This interrupt occurs when the PHY detects a link change.
-*/
+/* This interrupt occurs when the PHY detects a link change */
#ifdef HAVE_mii_link_interrupt
static irqreturn_t
mii_link_interrupt(int irq, void * dev_id)
@@ -1480,10 +1428,6 @@ mii_link_interrupt(int irq, void * dev_id)
fec_phy_ack_intr();
-#if 0
- disable_irq(fep->mii_irq); /* disable now, enable later */
-#endif
-
mii_do_cmd(dev, fep->phy->ack_int);
mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */
@@ -1534,7 +1478,7 @@ fec_enet_open(struct net_device *dev)
netif_start_queue(dev);
fep->opened = 1;
- return 0; /* Success */
+ return 0;
}
static int
@@ -1542,8 +1486,7 @@ fec_enet_close(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
- /* Don't know what to do yet.
- */
+ /* Don't know what to do yet. */
fep->opened = 0;
netif_stop_queue(dev);
fec_stop(dev);
@@ -1571,7 +1514,7 @@ static void set_multicast_list(struct net_device *dev)
unsigned int i, j, bit, data, crc, tmp;
unsigned char hash;
- if (dev->flags&IFF_PROMISC) {
+ if (dev->flags & IFF_PROMISC) {
tmp = readl(fep->hwp + FEC_R_CNTRL);
tmp |= 0x8;
writel(tmp, fep->hwp + FEC_R_CNTRL);
@@ -1582,42 +1525,37 @@ static void set_multicast_list(struct net_device *dev)
if (dev->flags & IFF_ALLMULTI) {
/* Catch all multicast addresses, so set the
- * filter to all 1's.
+ * 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.
- */
+ /* 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.
- */
+ 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
- */
+ /* calculate crc32 value of mac address */
crc = 0xffffffff;
- for (i = 0; i < dmi->dmi_addrlen; i++)
- {
+ for (i = 0; i < dmi->dmi_addrlen; i++) {
data = dmi->dmi_addr[i];
- for (bit = 0; bit < 8; bit++, data >>= 1)
- {
+ 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
- */
+ * which point to specific bit in he hash registers
+ */
hash = (crc >> (32 - HASH_BITS)) & 0x3f;
if (hash > 31) {
@@ -1634,8 +1572,7 @@ static void set_multicast_list(struct net_device *dev)
}
}
-/* Set a MAC change in hardware.
- */
+/* Set a MAC change in hardware. */
static void
fec_set_mac_address(struct net_device *dev)
{
@@ -1676,8 +1613,7 @@ 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.
- */
+ /* Whack a reset. We should wait for this. */
writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
@@ -1707,18 +1643,15 @@ int __init fec_enet_init(struct net_device *dev, int index)
fep->skb_cur = fep->skb_dirty = 0;
- /* Initialize the receive buffer descriptors.
- */
+ /* Initialize the receive buffer descriptors. */
bdp = fep->rx_bd_base;
for (i=0; i<FEC_ENET_RX_PAGES; i++) {
- /* Allocate a page.
- */
+ /* Allocate a page */
mem_addr = __get_free_page(GFP_KERNEL);
/* XXX: missing check for allocation failure */
- /* Initialize the BD for every fragment in the page.
- */
+ /* Initialize the BD for every fragment in the page */
for (j=0; j<FEC_ENET_RX_FRPPG; j++) {
bdp->cbd_sc = BD_ENET_RX_EMPTY;
bdp->cbd_bufaddr = __pa(mem_addr);
@@ -1727,13 +1660,11 @@ int __init fec_enet_init(struct net_device *dev, int index)
}
}
- /* Set the last buffer to wrap.
- */
+ /* Set the last buffer to wrap */
bdp--;
bdp->cbd_sc |= BD_SC_WRAP;
- /* ...and the same for transmmit.
- */
+ /* ...and the same for transmit */
bdp = fep->tx_bd_base;
for (i=0, j=FEC_ENET_TX_FRPPG; i<TX_RING_SIZE; i++) {
if (j >= FEC_ENET_TX_FRPPG) {
@@ -1745,20 +1676,17 @@ int __init fec_enet_init(struct net_device *dev, int index)
}
fep->tx_bounce[i] = (unsigned char *) mem_addr;
- /* Initialize the BD for every fragment in the page.
- */
+ /* Initialize the BD for every fragment in the page */
bdp->cbd_sc = 0;
bdp->cbd_bufaddr = 0;
bdp++;
}
- /* Set the last buffer to wrap.
- */
+ /* Set the last buffer to wrap */
bdp--;
bdp->cbd_sc |= BD_SC_WRAP;
- /* Set receive and transmit descriptor base.
- */
+ /* 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);
@@ -1777,7 +1705,7 @@ int __init fec_enet_init(struct net_device *dev, int index)
writel(0, fep->hwp + FEC_HASH_TABLE_LOW);
#endif
- /* The FEC Ethernet specific entries in the device structure. */
+ /* The FEC Ethernet specific entries in the device structure */
dev->open = fec_enet_open;
dev->hard_start_xmit = fec_enet_start_xmit;
dev->tx_timeout = fec_timeout;
@@ -1793,9 +1721,7 @@ int __init fec_enet_init(struct net_device *dev, int index)
writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL);
writel(0, fep->hwp + FEC_X_CNTRL);
- /*
- * Set MII speed to 2.5 MHz
- */
+ /* Set MII speed to 2.5 MHz */
fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999)
/ 2500000) / 2) & 0x3F) << 1;
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
@@ -1854,8 +1780,8 @@ fec_restart(struct net_device *dev, int duplex)
/* Reset SKB transmit buffers. */
fep->skb_cur = fep->skb_dirty = 0;
- for (i=0; i<=TX_RING_MOD_MASK; i++) {
- if (fep->tx_skbuff[i] != NULL) {
+ for (i = 0; i <= TX_RING_MOD_MASK; i++) {
+ if (fep->tx_skbuff[i]) {
dev_kfree_skb_any(fep->tx_skbuff[i]);
fep->tx_skbuff[i] = NULL;
}
@@ -1863,20 +1789,20 @@ fec_restart(struct net_device *dev, int duplex)
/* Initialize the receive buffer descriptors. */
bdp = fep->rx_bd_base;
- for (i=0; i<RX_RING_SIZE; i++) {
+ for (i = 0; i < RX_RING_SIZE; i++) {
/* Initialize the BD for every fragment in the page. */
bdp->cbd_sc = BD_ENET_RX_EMPTY;
bdp++;
}
- /* Set the last buffer to wrap. */
+ /* Set the last buffer to wrap */
bdp--;
bdp->cbd_sc |= BD_SC_WRAP;
- /* ...and the same for transmmit. */
+ /* ...and the same for transmit */
bdp = fep->tx_bd_base;
- for (i=0; i<TX_RING_SIZE; i++) {
+ for (i = 0; i < TX_RING_SIZE; i++) {
/* Initialize the BD for every fragment in the page. */
bdp->cbd_sc = 0;
@@ -1884,11 +1810,11 @@ fec_restart(struct net_device *dev, int duplex)
bdp++;
}
- /* Set the last buffer to wrap. */
+ /* Set the last buffer to wrap */
bdp--;
bdp->cbd_sc |= BD_SC_WRAP;
- /* Enable MII mode. */
+ /* Enable MII mode */
if (duplex) {
/* MII enable / FD enable */
writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL);
@@ -1900,14 +1826,14 @@ fec_restart(struct net_device *dev, int duplex)
}
fep->full_duplex = duplex;
- /* Set MII speed. */
+ /* Set MII speed */
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
- /* And last, enable the transmit and receive processing. */
+ /* And last, enable the transmit and receive processing */
writel(2, fep->hwp + FEC_ECNTRL);
writel(0, fep->hwp + FEC_R_DES_ACTIVE);
- /* Enable interrupts we wish to service. */
+ /* Enable interrupts we wish to service */
writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII,
fep->hwp + FEC_IMASK);
}
@@ -1917,9 +1843,7 @@ fec_stop(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
- /*
- ** We cannot expect a graceful transmit stop without link !!!
- */
+ /* We cannot expect a graceful transmit stop without link !!! */
if (fep->link) {
writel(1, fep->hwp + FEC_X_CNTRL); /* Graceful transmit stop */
udelay(10);
--
1.6.2.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 06/12] fec: refactor set_multicast_list() to make it more readable
2009-04-15 11:32 ` [PATCH 05/12] fec: Codingstyle cleanups Sascha Hauer
@ 2009-04-15 11:32 ` Sascha Hauer
2009-04-15 11:32 ` [PATCH 07/12] fec: refactor init function Sascha Hauer
2009-04-16 9:37 ` [PATCH 06/12] fec: refactor set_multicast_list() to make it more readable David Miller
2009-04-16 9:36 ` [PATCH 05/12] fec: Codingstyle cleanups David Miller
1 sibling, 2 replies; 29+ messages in thread
From: Sascha Hauer @ 2009-04-15 11:32 UTC (permalink / raw)
To: netdev; +Cc: Greg Ungerer, Sascha Hauer
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_GRP_HASH_TABLE_LOW);
- }
+ tmp = readl(fep->hwp + FEC_R_CNTRL);
+ tmp &= ~0x8;
+ writel(tmp, fep->hwp + FEC_R_CNTRL);
+
+ 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);
+
+ return;
+ }
+
+ /* 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_GRP_HASH_TABLE_LOW);
+ }
}
}
--
1.6.2.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 07/12] fec: refactor init function
2009-04-15 11:32 ` [PATCH 06/12] fec: refactor set_multicast_list() to make it more readable Sascha Hauer
@ 2009-04-15 11:32 ` Sascha Hauer
2009-04-15 11:32 ` [PATCH 08/12] fec: align receive packets Sascha Hauer
2009-04-16 9:37 ` [PATCH 07/12] fec: refactor init function David Miller
2009-04-16 9:37 ` [PATCH 06/12] fec: refactor set_multicast_list() to make it more readable David Miller
1 sibling, 2 replies; 29+ messages in thread
From: Sascha Hauer @ 2009-04-15 11:32 UTC (permalink / raw)
To: netdev; +Cc: Greg Ungerer, Sascha Hauer
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 Ethernet specific entries in the device structure */
dev->open = fec_enet_open;
dev->hard_start_xmit = fec_enet_start_xmit;
@@ -1720,21 +1695,11 @@ int __init fec_enet_init(struct net_device *dev, int index)
mii_cmds[i].mii_next = &mii_cmds[i+1];
mii_free = mii_cmds;
- /* setup MII interface */
- writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL);
- writel(0, fep->hwp + FEC_X_CNTRL);
-
/* Set MII speed to 2.5 MHz */
fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999)
/ 2500000) / 2) & 0x3F) << 1;
- writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
fec_restart(dev, 0);
- /* Clear and enable interrupts */
- writel(0xffc00000, fep->hwp + FEC_IEVENT);
- writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII,
- fep->hwp + FEC_IMASK);
-
/* Queue up command to detect the PHY and initialize the
* remainder of the interface.
*/
@@ -1769,6 +1734,10 @@ fec_restart(struct net_device *dev, int duplex)
/* Reset all multicast. */
writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+#ifndef CONFIG_M5272
+ writel(0, fep->hwp + FEC_HASH_TABLE_HIGH);
+ writel(0, fep->hwp + FEC_HASH_TABLE_LOW);
+#endif
/* Set maximum receive buffer size. */
writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE);
--
1.6.2.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 08/12] fec: align receive packets
2009-04-15 11:32 ` [PATCH 07/12] fec: refactor init function Sascha Hauer
@ 2009-04-15 11:32 ` Sascha Hauer
2009-04-15 11:32 ` [PATCH 09/12] fec: remove debugging printks Sascha Hauer
2009-04-16 9:37 ` [PATCH 08/12] fec: align receive packets David Miller
2009-04-16 9:37 ` [PATCH 07/12] fec: refactor init function David Miller
1 sibling, 2 replies; 29+ messages in thread
From: Sascha Hauer @ 2009-04-15 11:32 UTC (permalink / raw)
To: netdev; +Cc: Greg Ungerer, Sascha Hauer
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
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 09/12] fec: remove debugging printks
2009-04-15 11:32 ` [PATCH 08/12] fec: align receive packets Sascha Hauer
@ 2009-04-15 11:32 ` Sascha Hauer
2009-04-15 11:32 ` [PATCH 10/12] fec: switch to net_device_ops Sascha Hauer
2009-04-16 9:37 ` [PATCH 09/12] fec: remove debugging printks David Miller
2009-04-16 9:37 ` [PATCH 08/12] fec: align receive packets David Miller
1 sibling, 2 replies; 29+ messages in thread
From: Sascha Hauer @ 2009-04-15 11:32 UTC (permalink / raw)
To: netdev; +Cc: Greg Ungerer, Sascha Hauer
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
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 10/12] fec: switch to net_device_ops
2009-04-15 11:32 ` [PATCH 09/12] fec: remove debugging printks Sascha Hauer
@ 2009-04-15 11:32 ` Sascha Hauer
2009-04-15 11:32 ` [PATCH 11/12] FEC Buffer rework Sascha Hauer
2009-04-16 9:37 ` [PATCH 10/12] fec: switch to net_device_ops David Miller
2009-04-16 9:37 ` [PATCH 09/12] fec: remove debugging printks David Miller
1 sibling, 2 replies; 29+ messages in thread
From: Sascha Hauer @ 2009-04-15 11:32 UTC (permalink / raw)
To: netdev; +Cc: Greg Ungerer, Sascha Hauer
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] << 24),
fep + FEC_ADDR_HIGH);
+ return 0;
}
+static const struct net_device_ops fec_netdev_ops = {
+ .ndo_open = fec_enet_open,
+ .ndo_stop = fec_enet_close,
+ .ndo_start_xmit = fec_enet_start_xmit,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_tx_timeout = fec_timeout,
+ .ndo_set_mac_address = fec_set_mac_address,
+};
+
/*
* XXX: We need to clean up on failure exits here.
*
@@ -1652,12 +1663,8 @@ int __init fec_enet_init(struct net_device *dev, int index)
fec_request_mii_intr(dev);
#endif
/* The FEC Ethernet specific entries in the device structure */
- dev->open = fec_enet_open;
- dev->hard_start_xmit = fec_enet_start_xmit;
- dev->tx_timeout = fec_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
- dev->stop = fec_enet_close;
- dev->set_multicast_list = set_multicast_list;
+ dev->netdev_ops = &fec_netdev_ops;
for (i=0; i<NMII-1; i++)
mii_cmds[i].mii_next = &mii_cmds[i+1];
@@ -1696,9 +1703,6 @@ fec_restart(struct net_device *dev, int duplex)
/* Clear any outstanding interrupt. */
writel(0xffc00000, fep->hwp + FEC_IEVENT);
- /* Set station address. */
- fec_set_mac_address(dev);
-
/* Reset all multicast. */
writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
--
1.6.2.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 11/12] FEC Buffer rework
2009-04-15 11:32 ` [PATCH 10/12] fec: switch to net_device_ops Sascha Hauer
@ 2009-04-15 11:32 ` Sascha Hauer
2009-04-15 11:32 ` [PATCH 12/12] fec: call fec_restart() in fec_open() Sascha Hauer
` (2 more replies)
2009-04-16 9:37 ` [PATCH 10/12] fec: switch to net_device_ops David Miller
1 sibling, 3 replies; 29+ messages in thread
From: Sascha Hauer @ 2009-04-15 11:32 UTC (permalink / raw)
To: netdev; +Cc: Greg Ungerer, Sascha Hauer
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 alignment, exactly what we need.
* The packet length includes FCS, but we don't want to
@@ -574,6 +579,9 @@ fec_enet_rx(struct net_device *dev)
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
}
+
+ bdp->cbd_bufaddr = dma_map_single(NULL, data, bdp->cbd_datlen,
+ DMA_FROM_DEVICE);
rx_processing_done:
/* Clear the status flags for this buffer */
status &= ~BD_ENET_RX_STATS;
@@ -1399,15 +1407,86 @@ mii_link_interrupt(int irq, void * dev_id)
}
#endif
+static void fec_enet_free_buffers(struct net_device *dev)
+{
+ struct fec_enet_private *fep = netdev_priv(dev);
+ int i;
+ struct sk_buff *skb;
+ struct bufdesc *bdp;
+
+ bdp = fep->rx_bd_base;
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ skb = fep->rx_skbuff[i];
+
+ if (bdp->cbd_bufaddr)
+ dma_unmap_single(&dev->dev, bdp->cbd_bufaddr,
+ FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
+ if (skb)
+ dev_kfree_skb(skb);
+ bdp++;
+ }
+
+ bdp = fep->tx_bd_base;
+ for (i = 0; i < TX_RING_SIZE; i++)
+ kfree(fep->tx_bounce[i]);
+}
+
+static int fec_enet_alloc_buffers(struct net_device *dev)
+{
+ struct fec_enet_private *fep = netdev_priv(dev);
+ int i;
+ struct sk_buff *skb;
+ struct bufdesc *bdp;
+
+ bdp = fep->rx_bd_base;
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ skb = dev_alloc_skb(FEC_ENET_RX_FRSIZE);
+ if (!skb) {
+ fec_enet_free_buffers(dev);
+ return -ENOMEM;
+ }
+ fep->rx_skbuff[i] = skb;
+
+ bdp->cbd_bufaddr = dma_map_single(&dev->dev, skb->data,
+ FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
+ bdp->cbd_sc = BD_ENET_RX_EMPTY;
+ bdp++;
+ }
+
+ /* Set the last buffer to wrap. */
+ bdp--;
+ bdp->cbd_sc |= BD_SC_WRAP;
+
+ bdp = fep->tx_bd_base;
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
+
+ bdp->cbd_sc = 0;
+ bdp->cbd_bufaddr = 0;
+ bdp++;
+ }
+
+ /* Set the last buffer to wrap. */
+ bdp--;
+ bdp->cbd_sc |= BD_SC_WRAP;
+
+ return 0;
+}
+
static int
fec_enet_open(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
+ int ret;
/* I should reset the ring buffers here, but I don't yet know
* a simple way to do that.
*/
+ ret = fec_enet_alloc_buffers(dev);
+ if (ret)
+ return ret;
+
fep->sequence_done = 0;
fep->link = 0;
@@ -1454,6 +1533,8 @@ fec_enet_close(struct net_device *dev)
netif_stop_queue(dev);
fec_stop(dev);
+ fec_enet_free_buffers(dev);
+
return 0;
}
@@ -1576,9 +1657,8 @@ static const struct net_device_ops fec_netdev_ops = {
int __init fec_enet_init(struct net_device *dev, int index)
{
struct fec_enet_private *fep = netdev_priv(dev);
- unsigned long mem_addr;
- struct bufdesc *bdp, *cbd_base;
- int i, j;
+ struct bufdesc *cbd_base;
+ int i;
/* Allocate memory for buffer descriptors. */
cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma,
@@ -1616,49 +1696,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;
- /* Initialize the receive buffer descriptors. */
- bdp = fep->rx_bd_base;
- for (i=0; i<FEC_ENET_RX_PAGES; i++) {
-
- /* Allocate a page */
- mem_addr = __get_free_page(GFP_KERNEL);
- /* XXX: missing check for allocation failure */
-
- /* Initialize the BD for every fragment in the page */
- for (j=0; j<FEC_ENET_RX_FRPPG; j++) {
- bdp->cbd_sc = BD_ENET_RX_EMPTY;
- bdp->cbd_bufaddr = __pa(mem_addr);
- mem_addr += FEC_ENET_RX_FRSIZE;
- bdp++;
- }
- }
-
- /* Set the last buffer to wrap */
- bdp--;
- bdp->cbd_sc |= BD_SC_WRAP;
-
- /* ...and the same for transmit */
- bdp = fep->tx_bd_base;
- for (i=0, j=FEC_ENET_TX_FRPPG; i<TX_RING_SIZE; i++) {
- if (j >= FEC_ENET_TX_FRPPG) {
- mem_addr = __get_free_page(GFP_KERNEL);
- j = 1;
- } else {
- mem_addr += FEC_ENET_TX_FRSIZE;
- j++;
- }
- fep->tx_bounce[i] = (unsigned char *) mem_addr;
-
- /* Initialize the BD for every fragment in the page */
- bdp->cbd_sc = 0;
- bdp->cbd_bufaddr = 0;
- bdp++;
- }
-
- /* Set the last buffer to wrap */
- bdp--;
- bdp->cbd_sc |= BD_SC_WRAP;
-
#ifdef HAVE_mii_link_interrupt
fec_request_mii_intr(dev);
#endif
--
1.6.2.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 12/12] fec: call fec_restart() in fec_open()
2009-04-15 11:32 ` [PATCH 11/12] FEC Buffer rework Sascha Hauer
@ 2009-04-15 11:32 ` Sascha Hauer
2009-04-16 9:38 ` David Miller
2009-04-16 9:38 ` [PATCH 11/12] FEC Buffer rework David Miller
2009-04-17 10:07 ` Greg Ungerer
2 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2009-04-15 11:32 UTC (permalink / raw)
To: netdev; +Cc: Greg Ungerer, Sascha Hauer
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
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH] FEC driver: patches for -next
2009-04-15 11:32 [PATCH] FEC driver: patches for -next Sascha Hauer
2009-04-15 11:32 ` [PATCH 01/12] fec: remove unused ifdef Sascha Hauer
@ 2009-04-15 12:12 ` Greg Ungerer
2009-04-15 12:55 ` Sascha Hauer
1 sibling, 1 reply; 29+ messages in thread
From: Greg Ungerer @ 2009-04-15 12:12 UTC (permalink / raw)
To: Sascha Hauer; +Cc: netdev
Hi Sascha,
Sascha Hauer wrote:
> These patches aim to modernize the FEC ethernet driver.
> Greg, can you please confirm that the ifdef in patch 01/12 is indeed unused?
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
> 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(-)
>
--
------------------------------------------------------------------------
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
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] FEC driver: patches for -next
2009-04-15 12:12 ` [PATCH] FEC driver: patches for -next Greg Ungerer
@ 2009-04-15 12:55 ` Sascha Hauer
0 siblings, 0 replies; 29+ messages in thread
From: Sascha Hauer @ 2009-04-15 12:55 UTC (permalink / raw)
To: Greg Ungerer; +Cc: netdev
On Wed, Apr 15, 2009 at 10:12:05PM +1000, Greg Ungerer wrote:
>
> Hi Sascha,
>
> Sascha Hauer wrote:
>> These patches aim to modernize the FEC ethernet driver.
>> Greg, can you please confirm that the ifdef in patch 01/12 is indeed unused?
>
> 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.
Ok, then I'll skip the first patch and update the second one
accordingly.
Regards
Sascha
>
> Regards
> Greg
>
>
>> 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(-)
>>
>
>
> --
> ------------------------------------------------------------------------
> 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
>
--
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 |
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 02/12] fec: switch to writel/readl
2009-04-15 11:32 ` [PATCH 02/12] fec: switch to writel/readl Sascha Hauer
2009-04-15 11:32 ` [PATCH 03/12] fec: do not typedef struct types Sascha Hauer
@ 2009-04-15 13:11 ` Sascha Hauer
2009-04-16 9:36 ` David Miller
1 sibling, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2009-04-15 13:11 UTC (permalink / raw)
To: netdev; +Cc: Greg Ungerer
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;
-
- /* 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 function.
- */
+ /* Handle receive event in its own function. */
if (int_events & FEC_ENET_RXF) {
ret = IRQ_HANDLED;
fec_enet_rx(dev);
}
/* Transmit OK, or non-fatal error. Update the buffer
- descriptors. FEC handles all errors, we just discover
- them as part of the transmit process.
- */
+ * descriptors. FEC handles all errors, we just discover
+ * them as part of the transmit process.
+ */
if (int_events & FEC_ENET_TXF) {
ret = IRQ_HANDLED;
fec_enet_tx(dev);
@@ -555,8 +547,7 @@ fec_enet_tx(struct net_device *dev)
static void
fec_enet_rx(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;
struct sk_buff *skb;
@@ -567,9 +558,6 @@ fec_enet_rx(struct net_device *dev)
flush_cache_all();
#endif
- fep = netdev_priv(dev);
- fecp = (volatile fec_t*)dev->base_addr;
-
spin_lock_irq(&fep->hw_lock);
/* First, grab all of the stats for the incoming packet.
@@ -665,7 +653,7 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
* incoming frames. On a heavily loaded network, we should be
* able to keep up at the expense of system resources.
*/
- fecp->fec_r_des_active = 0;
+ writel(0, fep->hwp + FEC_R_DES_ACTIVE);
#endif
} /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */
fep->cur_rx = (cbd_t *)bdp;
@@ -690,30 +678,25 @@ static void
fec_enet_mii(struct net_device *dev)
{
struct fec_enet_private *fep;
- volatile fec_t *ep;
mii_list_t *mip;
- uint mii_reg;
fep = netdev_priv(dev);
spin_lock_irq(&fep->mii_lock);
- ep = fep->hwp;
- mii_reg = ep->fec_mii_data;
-
if ((mip = mii_head) == NULL) {
printk("MII and no head!\n");
goto unlock;
}
if (mip->mii_func != NULL)
- (*(mip->mii_func))(mii_reg, dev);
+ (*(mip->mii_func))(readl(fep->hwp + FEC_MII_DATA), dev);
mii_head = mip->mii_next;
mip->mii_next = mii_free;
mii_free = mip;
if ((mip = mii_head) != NULL)
- ep->fec_mii_data = mip->mii_regval;
+ writel(mip->mii_regval, fep->hwp + FEC_MII_DATA);
unlock:
spin_unlock_irq(&fep->mii_lock);
@@ -745,7 +728,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
mii_tail = mip;
} else {
mii_head = mii_tail = mip;
- fep->hwp->fec_mii_data = regval;
+ writel(regval, fep->hwp + FEC_MII_DATA);
}
} else {
retval = 1;
@@ -1246,11 +1229,8 @@ static void __inline__ fec_phy_ack_intr(void)
static void __inline__ fec_get_mac(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
- volatile fec_t *fecp;
unsigned char *iap, tmpaddr[ETH_ALEN];
- fecp = fep->hwp;
-
if (FEC_FLASHMAC) {
/*
* Get MAC address from FLASH.
@@ -1264,8 +1244,8 @@ static void __inline__ fec_get_mac(struct net_device *dev)
(iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
iap = fec_mac_default;
} else {
- *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
- *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
+ *((unsigned long *) &tmpaddr[0]) = readl(fep->hwp + FEC_ADDR_LOW);
+ *((unsigned short *) &tmpaddr[4]) = (readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
iap = &tmpaddr[0];
}
@@ -1457,11 +1437,9 @@ static void
mii_discover_phy(uint mii_reg, struct net_device *dev)
{
struct fec_enet_private *fep;
- volatile fec_t *fecp;
uint phytype;
fep = netdev_priv(dev);
- fecp = fep->hwp;
if (fep->phy_addr < 32) {
if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) {
@@ -1479,7 +1457,8 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
} else {
printk("FEC: No PHY device found.\n");
/* Disable external MII interface */
- fecp->fec_mii_speed = fep->phy_speed = 0;
+ writel(0, fep->hwp + FEC_MII_SPEED);
+ fep->phy_speed = 0;
#ifdef HAVE_mii_link_interrupt
fec_disable_phy_intr();
#endif
@@ -1583,32 +1562,31 @@ fec_enet_close(struct net_device *dev)
static void set_multicast_list(struct net_device *dev)
{
- struct fec_enet_private *fep;
- volatile fec_t *ep;
+ struct fec_enet_private *fep = netdev_priv(dev);
struct dev_mc_list *dmi;
- unsigned int i, j, bit, data, crc;
+ unsigned int i, j, bit, data, crc, tmp;
unsigned char hash;
- fep = netdev_priv(dev);
- ep = fep->hwp;
-
if (dev->flags&IFF_PROMISC) {
- ep->fec_r_cntrl |= 0x0008;
+ tmp = readl(fep->hwp + FEC_R_CNTRL);
+ tmp |= 0x8;
+ writel(tmp, fep->hwp + FEC_R_CNTRL);
} else {
-
- ep->fec_r_cntrl &= ~0x0008;
+ tmp = readl(fep->hwp + FEC_R_CNTRL);
+ tmp &= ~0x8;
+ writel(tmp, fep->hwp + FEC_R_CNTRL);
if (dev->flags & IFF_ALLMULTI) {
/* Catch all multicast addresses, so set the
* filter to all 1's.
*/
- ep->fec_grp_hash_table_high = 0xffffffff;
- ep->fec_grp_hash_table_low = 0xffffffff;
+ 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.
*/
- ep->fec_grp_hash_table_high = 0;
- ep->fec_grp_hash_table_low = 0;
+ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
dmi = dev->mc_list;
@@ -1638,10 +1616,15 @@ static void set_multicast_list(struct net_device *dev)
*/
hash = (crc >> (32 - HASH_BITS)) & 0x3f;
- if (hash > 31)
- ep->fec_grp_hash_table_high |= 1 << (hash - 32);
- else
- ep->fec_grp_hash_table_low |= 1 << hash;
+ 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_GRP_HASH_TABLE_LOW);
+ }
}
}
}
@@ -1652,16 +1635,14 @@ static void set_multicast_list(struct net_device *dev)
static void
fec_set_mac_address(struct net_device *dev)
{
- volatile fec_t *fecp;
-
- fecp = ((struct fec_enet_private *)netdev_priv(dev))->hwp;
+ struct fec_enet_private *fep = netdev_priv(dev);
/* Set station address. */
- fecp->fec_addr_low = dev->dev_addr[3] | (dev->dev_addr[2] << 8) |
- (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24);
- fecp->fec_addr_high = (dev->dev_addr[5] << 16) |
- (dev->dev_addr[4] << 24);
-
+ 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] << 24),
+ fep + FEC_ADDR_HIGH);
}
/*
@@ -1675,7 +1656,6 @@ int __init fec_enet_init(struct net_device *dev, int index)
unsigned long mem_addr;
volatile cbd_t *bdp;
cbd_t *cbd_base;
- volatile fec_t *fecp;
int i, j;
/* Allocate memory for buffer descriptors.
@@ -1690,17 +1670,13 @@ int __init fec_enet_init(struct net_device *dev, int index)
spin_lock_init(&fep->hw_lock);
spin_lock_init(&fep->mii_lock);
- /* Create an Ethernet device instance.
- */
- fecp = (volatile fec_t *)dev->base_addr;
-
fep->index = index;
- fep->hwp = fecp;
+ fep->hwp = (void __iomem *)dev->base_addr;
fep->netdev = dev;
/* Whack a reset. We should wait for this.
*/
- fecp->fec_ecntrl = 1;
+ writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
/* Set the Ethernet address */
@@ -1709,12 +1685,12 @@ int __init fec_enet_init(struct net_device *dev, int index)
#else
{
unsigned long l;
- l = fecp->fec_addr_low;
+ l = readl(fep->hwp + FEC_ADDR_LOW);
dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24);
dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16);
dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8);
dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0);
- l = fecp->fec_addr_high;
+ l = readl(fep->hwp + FEC_ADDR_HIGH);
dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24);
dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16);
}
@@ -1784,22 +1760,22 @@ int __init fec_enet_init(struct net_device *dev, int index)
/* Set receive and transmit descriptor base.
*/
- fecp->fec_r_des_start = fep->bd_dma;
- fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
- * RX_RING_SIZE;
+ writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
+ writel((unsigned long)fep->bd_dma + sizeof(cbd_t) * RX_RING_SIZE,
+ fep->hwp + FEC_X_DES_START);
#ifdef HAVE_mii_link_interrupt
fec_request_mii_intr(dev);
#endif
- fecp->fec_grp_hash_table_high = 0;
- fecp->fec_grp_hash_table_low = 0;
- fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
- fecp->fec_ecntrl = 2;
- fecp->fec_r_des_active = 0;
+ 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
- fecp->fec_hash_table_high = 0;
- fecp->fec_hash_table_low = 0;
+ writel(0, fep->hwp + FEC_HASH_TABLE_HIGH);
+ writel(0, fep->hwp + FEC_HASH_TABLE_LOW);
#endif
/* The FEC Ethernet specific entries in the device structure. */
@@ -1815,20 +1791,21 @@ int __init fec_enet_init(struct net_device *dev, int index)
mii_free = mii_cmds;
/* setup MII interface */
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
- fecp->fec_x_cntrl = 0x00;
+ writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL);
+ writel(0, fep->hwp + FEC_X_CNTRL);
/*
* Set MII speed to 2.5 MHz
*/
fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999)
/ 2500000) / 2) & 0x3F) << 1;
- fecp->fec_mii_speed = fep->phy_speed;
+ writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
fec_restart(dev, 0);
/* Clear and enable interrupts */
- fecp->fec_ievent = 0xffc00000;
- fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
+ writel(0xffc00000, fep->hwp + FEC_IEVENT);
+ writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII,
+ fep->hwp + FEC_IMASK);
/* Queue up command to detect the PHY and initialize the
* remainder of the interface.
@@ -1847,47 +1824,36 @@ int __init fec_enet_init(struct net_device *dev, int index)
static void
fec_restart(struct net_device *dev, int duplex)
{
- struct fec_enet_private *fep;
+ struct fec_enet_private *fep = netdev_priv(dev);
volatile cbd_t *bdp;
- volatile fec_t *fecp;
int i;
- fep = netdev_priv(dev);
- fecp = fep->hwp;
-
- /* Whack a reset. We should wait for this.
- */
- fecp->fec_ecntrl = 1;
+ /* Whack a reset. We should wait for this. */
+ writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
- /* Clear any outstanding interrupt.
- */
- fecp->fec_ievent = 0xffc00000;
+ /* Clear any outstanding interrupt. */
+ writel(0xffc00000, fep->hwp + FEC_IEVENT);
- /* Set station address.
- */
+ /* Set station address. */
fec_set_mac_address(dev);
- /* Reset all multicast.
- */
- fecp->fec_grp_hash_table_high = 0;
- fecp->fec_grp_hash_table_low = 0;
+ /* Reset all multicast. */
+ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
- /* Set maximum receive buffer size.
- */
- fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
+ /* Set maximum receive buffer size. */
+ writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE);
- /* Set receive and transmit descriptor base.
- */
- fecp->fec_r_des_start = fep->bd_dma;
- fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
- * RX_RING_SIZE;
+ /* Set receive and transmit descriptor base. */
+ writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
+ writel((unsigned long)fep->bd_dma + sizeof(cbd_t) * RX_RING_SIZE,
+ fep->hwp + FEC_X_DES_START);
fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
fep->cur_rx = fep->rx_bd_base;
- /* Reset SKB transmit buffers.
- */
+ /* Reset SKB transmit buffers. */
fep->skb_cur = fep->skb_dirty = 0;
for (i=0; i<=TX_RING_MOD_MASK; i++) {
if (fep->tx_skbuff[i] != NULL) {
@@ -1896,96 +1862,81 @@ fec_restart(struct net_device *dev, int duplex)
}
}
- /* Initialize the receive buffer descriptors.
- */
+ /* Initialize the receive buffer descriptors. */
bdp = fep->rx_bd_base;
for (i=0; i<RX_RING_SIZE; i++) {
- /* Initialize the BD for every fragment in the page.
- */
+ /* Initialize the BD for every fragment in the page. */
bdp->cbd_sc = BD_ENET_RX_EMPTY;
bdp++;
}
- /* Set the last buffer to wrap.
- */
+ /* Set the last buffer to wrap. */
bdp--;
bdp->cbd_sc |= BD_SC_WRAP;
- /* ...and the same for transmmit.
- */
+ /* ...and the same for transmmit. */
bdp = fep->tx_bd_base;
for (i=0; i<TX_RING_SIZE; i++) {
- /* Initialize the BD for every fragment in the page.
- */
+ /* Initialize the BD for every fragment in the page. */
bdp->cbd_sc = 0;
bdp->cbd_bufaddr = 0;
bdp++;
}
- /* Set the last buffer to wrap.
- */
+ /* Set the last buffer to wrap. */
bdp--;
bdp->cbd_sc |= BD_SC_WRAP;
- /* Enable MII mode.
- */
+ /* Enable MII mode. */
if (duplex) {
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;/* MII enable */
- fecp->fec_x_cntrl = 0x04; /* FD enable */
+ /* MII enable / FD enable */
+ writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL);
+ writel(0x04, fep->hwp + FEC_X_CNTRL);
} else {
- /* MII enable|No Rcv on Xmit */
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x06;
- fecp->fec_x_cntrl = 0x00;
+ /* MII enable / No Rcv on Xmit */
+ writel(OPT_FRAME_SIZE | 0x06, fep->hwp + FEC_R_CNTRL);
+ writel(0x0, fep->hwp + FEC_X_CNTRL);
}
fep->full_duplex = duplex;
- /* Set MII speed.
- */
- fecp->fec_mii_speed = fep->phy_speed;
+ /* Set MII speed. */
+ writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
- /* And last, enable the transmit and receive processing.
- */
- fecp->fec_ecntrl = 2;
- fecp->fec_r_des_active = 0;
+ /* And last, enable the transmit and receive processing. */
+ writel(2, fep->hwp + FEC_ECNTRL);
+ writel(0, fep->hwp + FEC_R_DES_ACTIVE);
- /* Enable interrupts we wish to service.
- */
- fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
+ /* Enable interrupts we wish to service. */
+ writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII,
+ fep->hwp + FEC_IMASK);
}
static void
fec_stop(struct net_device *dev)
{
- volatile fec_t *fecp;
- struct fec_enet_private *fep;
-
- fep = netdev_priv(dev);
- fecp = fep->hwp;
+ struct fec_enet_private *fep = netdev_priv(dev);
/*
** We cannot expect a graceful transmit stop without link !!!
*/
- if (fep->link)
- {
- fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */
+ if (fep->link) {
+ writel(1, fep->hwp + FEC_X_CNTRL); /* Graceful transmit stop */
udelay(10);
- if (!(fecp->fec_ievent & FEC_ENET_GRA))
+ if (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_GRA))
printk("fec_stop : Graceful transmit stop did not complete !\n");
- }
+ }
- /* Whack a reset. We should wait for this.
- */
- fecp->fec_ecntrl = 1;
+ /* Whack a reset. We should wait for this. */
+ writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
- /* Clear outstanding MII command interrupts.
- */
- fecp->fec_ievent = FEC_ENET_MII;
+ /* Clear outstanding MII command interrupts. */
+ writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
- fecp->fec_imask = FEC_ENET_MII;
- fecp->fec_mii_speed = fep->phy_speed;
+ writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
+ writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
}
static int __devinit
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 76c64c9..5474ba3 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -20,82 +20,55 @@
* registers in the same peripheral device on different models
* of the ColdFire!
*/
-typedef struct fec {
- unsigned long fec_reserved0;
- unsigned long fec_ievent; /* Interrupt event reg */
- unsigned long fec_imask; /* Interrupt mask reg */
- unsigned long fec_reserved1;
- unsigned long fec_r_des_active; /* Receive descriptor reg */
- unsigned long fec_x_des_active; /* Transmit descriptor reg */
- unsigned long fec_reserved2[3];
- unsigned long fec_ecntrl; /* Ethernet control reg */
- unsigned long fec_reserved3[6];
- unsigned long fec_mii_data; /* MII manage frame reg */
- unsigned long fec_mii_speed; /* MII speed control reg */
- unsigned long fec_reserved4[7];
- unsigned long fec_mib_ctrlstat; /* MIB control/status reg */
- unsigned long fec_reserved5[7];
- unsigned long fec_r_cntrl; /* Receive control reg */
- unsigned long fec_reserved6[15];
- unsigned long fec_x_cntrl; /* Transmit Control reg */
- unsigned long fec_reserved7[7];
- unsigned long fec_addr_low; /* Low 32bits MAC address */
- unsigned long fec_addr_high; /* High 16bits MAC address */
- unsigned long fec_opd; /* Opcode + Pause duration */
- unsigned long fec_reserved8[10];
- unsigned long fec_hash_table_high; /* High 32bits hash table */
- unsigned long fec_hash_table_low; /* Low 32bits hash table */
- unsigned long fec_grp_hash_table_high;/* High 32bits hash table */
- unsigned long fec_grp_hash_table_low; /* Low 32bits hash table */
- unsigned long fec_reserved9[7];
- unsigned long fec_x_wmrk; /* FIFO transmit water mark */
- unsigned long fec_reserved10;
- unsigned long fec_r_bound; /* FIFO receive bound reg */
- unsigned long fec_r_fstart; /* FIFO receive start reg */
- unsigned long fec_reserved11[11];
- unsigned long fec_r_des_start; /* Receive descriptor ring */
- unsigned long fec_x_des_start; /* Transmit descriptor ring */
- unsigned long fec_r_buff_size; /* Maximum receive buff size */
-} fec_t;
+#define FEC_IEVENT 0x004 /* Interrupt event reg */
+#define FEC_IMASK 0x008 /* Interrupt mask reg */
+#define FEC_R_DES_ACTIVE 0x010 /* Receive descriptor reg */
+#define FEC_X_DES_ACTIVE 0x014 /* Transmit descriptor reg */
+#define FEC_ECNTRL 0x024 /* Ethernet control reg */
+#define FEC_MII_DATA 0x040 /* MII manage frame reg */
+#define FEC_MII_SPEED 0x044 /* MII speed control reg */
+#define FEC_MIB_CTRLSTAT 0x064 /* MIB control/status reg */
+#define FEC_R_CNTRL 0x084 /* Receive control reg */
+#define FEC_X_CNTRL 0x0c4 /* Transmit Control reg */
+#define FEC_ADDR_LOW 0x0e4 /* Low 32bits MAC address */
+#define FEC_ADDR_HIGH 0x0e8 /* High 16bits MAC address */
+#define FEC_OPD 0x0ec /* Opcode + Pause duration */
+#define FEC_HASH_TABLE_HIGH 0x118 /* High 32bits hash table */
+#define FEC_HASH_TABLE_LOW 0x11c /* Low 32bits hash table */
+#define FEC_GRP_HASH_TABLE_HIGH 0x120 /* High 32bits hash table */
+#define FEC_GRP_HASH_TABLE_LOW 0x124 /* Low 32bits hash table */
+#define FEC_X_WMRK 0x144 /* FIFO transmit water mark */
+#define FEC_R_BOUND 0x14c /* FIFO receive bound reg */
+#define FEC_R_FSTART 0x150 /* FIFO receive start reg */
+#define FEC_R_DES_START 0x180 /* Receive descriptor ring */
+#define FEC_X_DES_START 0x184 /* Transmit descriptor ring */
+#define FEC_R_BUFF_SIZE 0x188 /* Maximum receive buff size */
#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 Control reg */
- unsigned long fec_reserved7[158];
- unsigned long fec_addr_low; /* Low 32bits MAC address */
- unsigned long fec_addr_high; /* High 16bits MAC address */
- unsigned long fec_grp_hash_table_high;/* High 32bits hash table */
- unsigned long fec_grp_hash_table_low; /* Low 32bits hash table */
- unsigned long fec_r_des_start; /* Receive descriptor ring */
- unsigned long fec_x_des_start; /* Transmit descriptor ring */
- unsigned long fec_r_buff_size; /* Maximum receive buff size */
- unsigned long reserved8[9];
- unsigned long fec_fifo_ram[112]; /* FIFO RAM buffer */
-} fec_t;
+#define FEC_ECNTRL; 0x000 /* Ethernet control reg */
+#define FEC_IEVENT; 0x004 /* Interrupt even reg */
+#define FEC_IMASK; 0x008 /* Interrupt mask reg */
+#define FEC_IVEC; 0x00c /* Interrupt vec status reg */
+#define FEC_R_DES_ACTIVE; 0x010 /* Receive descriptor reg */
+#define FEC_X_DES_ACTIVE; 0x01c /* Transmit descriptor reg */
+#define FEC_MII_DATA 0x040 /* MII manage frame reg */
+#define FEC_MII_SPEED 0x044 /* MII speed control reg */
+#define FEC_R_BOUND 0x08c /* FIFO receive bound reg */
+#define FEC_R_FSTART 0x090 /* FIFO receive start reg */
+#define FEC_X_WMRK 0x0a4 /* FIFO transmit water mark */
+#define FEC_X_FSTART 0x0ac /* FIFO transmit start reg */
+#define FEC_R_CNTRL 0x104 /* Receive control reg */
+#define FEC_MAX_FRM_LEN 0x108 /* Maximum frame length reg */
+#define FEC_X_CNTRL 0x144 /* Transmit Control reg */
+#define FEC_ADDR_LOW 0x3c0 /* Low 32bits MAC address */
+#define FEC_ADDR_HIGH 0x3c4 /* High 16bits MAC address */
+#define FEC_GRP_HASH_TABLE_HIGH 0x3c8 /* High 32bits hash table */
+#define FEC_GRP_HASH_TABLE_LOW 0x3cc /* Low 32bits hash table */
+#define FEC_R_DES_START 0x3d0 /* Receive descriptor ring */
+#define FEC_X_DES_START 0x3d4 /* Transmit descriptor ring */
+#define FEC_R_BUFF_SIZE 0x3d8 /* Maximum receive buff size */
+#define FEC_FIFO_RAM 0x400 /* FIFO RAM buffer */
#endif /* CONFIG_M5272 */
--
1.6.2.1
--
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 |
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH 02/12] fec: switch to writel/readl
2009-04-15 13:11 ` [PATCH 02/12] fec: switch to writel/readl Sascha Hauer
@ 2009-04-16 9:36 ` David Miller
0 siblings, 0 replies; 29+ messages in thread
From: David Miller @ 2009-04-16 9:36 UTC (permalink / raw)
To: s.hauer; +Cc: netdev, gerg
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Wed, 15 Apr 2009 15:11:30 +0200
> Since the second register set is used for M5272 we cannot remove it.
> Here is an updated version.
Applied.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 03/12] fec: do not typedef struct types
2009-04-15 11:32 ` [PATCH 03/12] fec: do not typedef struct types Sascha Hauer
2009-04-15 11:32 ` [PATCH 04/12] fec: remove unnecessary cast Sascha Hauer
@ 2009-04-16 9:36 ` David Miller
1 sibling, 0 replies; 29+ messages in thread
From: David Miller @ 2009-04-16 9:36 UTC (permalink / raw)
To: s.hauer; +Cc: netdev, gerg
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Wed, 15 Apr 2009 13:32:16 +0200
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Applied.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 04/12] fec: remove unnecessary cast
2009-04-15 11:32 ` [PATCH 04/12] fec: remove unnecessary cast Sascha Hauer
2009-04-15 11:32 ` [PATCH 05/12] fec: Codingstyle cleanups Sascha Hauer
@ 2009-04-16 9:36 ` David Miller
1 sibling, 0 replies; 29+ messages in thread
From: David Miller @ 2009-04-16 9:36 UTC (permalink / raw)
To: s.hauer; +Cc: netdev, gerg
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Wed, 15 Apr 2009 13:32:17 +0200
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Applied.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 05/12] fec: Codingstyle cleanups
2009-04-15 11:32 ` [PATCH 05/12] fec: Codingstyle cleanups Sascha Hauer
2009-04-15 11:32 ` [PATCH 06/12] fec: refactor set_multicast_list() to make it more readable Sascha Hauer
@ 2009-04-16 9:36 ` David Miller
1 sibling, 0 replies; 29+ messages in thread
From: David Miller @ 2009-04-16 9:36 UTC (permalink / raw)
To: s.hauer; +Cc: netdev, gerg
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Wed, 15 Apr 2009 13:32:18 +0200
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Applied.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 06/12] fec: refactor set_multicast_list() to make it more readable
2009-04-15 11:32 ` [PATCH 06/12] fec: refactor set_multicast_list() to make it more readable Sascha Hauer
2009-04-15 11:32 ` [PATCH 07/12] fec: refactor init function Sascha Hauer
@ 2009-04-16 9:37 ` David Miller
1 sibling, 0 replies; 29+ messages in thread
From: David Miller @ 2009-04-16 9:37 UTC (permalink / raw)
To: s.hauer; +Cc: netdev, gerg
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Wed, 15 Apr 2009 13:32:19 +0200
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Applied.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 07/12] fec: refactor init function
2009-04-15 11:32 ` [PATCH 07/12] fec: refactor init function Sascha Hauer
2009-04-15 11:32 ` [PATCH 08/12] fec: align receive packets Sascha Hauer
@ 2009-04-16 9:37 ` David Miller
1 sibling, 0 replies; 29+ messages in thread
From: David Miller @ 2009-04-16 9:37 UTC (permalink / raw)
To: s.hauer; +Cc: netdev, gerg
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Wed, 15 Apr 2009 13:32:20 +0200
> 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>
Applied.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 08/12] fec: align receive packets
2009-04-15 11:32 ` [PATCH 08/12] fec: align receive packets Sascha Hauer
2009-04-15 11:32 ` [PATCH 09/12] fec: remove debugging printks Sascha Hauer
@ 2009-04-16 9:37 ` David Miller
1 sibling, 0 replies; 29+ messages in thread
From: David Miller @ 2009-04-16 9:37 UTC (permalink / raw)
To: s.hauer; +Cc: netdev, gerg
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Wed, 15 Apr 2009 13:32:21 +0200
> Otherwise we get a lot of alignment errors
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Applied.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 09/12] fec: remove debugging printks
2009-04-15 11:32 ` [PATCH 09/12] fec: remove debugging printks Sascha Hauer
2009-04-15 11:32 ` [PATCH 10/12] fec: switch to net_device_ops Sascha Hauer
@ 2009-04-16 9:37 ` David Miller
1 sibling, 0 replies; 29+ messages in thread
From: David Miller @ 2009-04-16 9:37 UTC (permalink / raw)
To: s.hauer; +Cc: netdev, gerg
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Wed, 15 Apr 2009 13:32:22 +0200
> These printks in fec_timeout do not give useful information in
> a production kernel.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Applied.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 10/12] fec: switch to net_device_ops
2009-04-15 11:32 ` [PATCH 10/12] fec: switch to net_device_ops Sascha Hauer
2009-04-15 11:32 ` [PATCH 11/12] FEC Buffer rework Sascha Hauer
@ 2009-04-16 9:37 ` David Miller
1 sibling, 0 replies; 29+ messages in thread
From: David Miller @ 2009-04-16 9:37 UTC (permalink / raw)
To: s.hauer; +Cc: netdev, gerg
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Wed, 15 Apr 2009 13:32:23 +0200
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Applied.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 11/12] FEC Buffer rework
2009-04-15 11:32 ` [PATCH 11/12] FEC Buffer rework Sascha Hauer
2009-04-15 11:32 ` [PATCH 12/12] fec: call fec_restart() in fec_open() Sascha Hauer
@ 2009-04-16 9:38 ` David Miller
2009-04-17 10:07 ` Greg Ungerer
2 siblings, 0 replies; 29+ messages in thread
From: David Miller @ 2009-04-16 9:38 UTC (permalink / raw)
To: s.hauer; +Cc: netdev, gerg
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Wed, 15 Apr 2009 13:32:24 +0200
> 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>
Applied.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 12/12] fec: call fec_restart() in fec_open()
2009-04-15 11:32 ` [PATCH 12/12] fec: call fec_restart() in fec_open() Sascha Hauer
@ 2009-04-16 9:38 ` David Miller
0 siblings, 0 replies; 29+ messages in thread
From: David Miller @ 2009-04-16 9:38 UTC (permalink / raw)
To: s.hauer; +Cc: netdev, gerg
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Wed, 15 Apr 2009 13:32:25 +0200
> 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>
Applied.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 11/12] FEC Buffer rework
2009-04-15 11:32 ` [PATCH 11/12] FEC Buffer rework Sascha Hauer
2009-04-15 11:32 ` [PATCH 12/12] fec: call fec_restart() in fec_open() Sascha Hauer
2009-04-16 9:38 ` [PATCH 11/12] FEC Buffer rework David Miller
@ 2009-04-17 10:07 ` Greg Ungerer
2009-04-17 10:12 ` Sascha Hauer
2 siblings, 1 reply; 29+ messages in thread
From: Greg Ungerer @ 2009-04-17 10:07 UTC (permalink / raw)
To: Sascha Hauer; +Cc: netdev
Hi Sascha,
Sascha Hauer wrote:
> 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>
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
> ---
> 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 alignment, exactly what we need.
> * The packet length includes FCS, but we don't want to
> @@ -574,6 +579,9 @@ fec_enet_rx(struct net_device *dev)
> skb->protocol = eth_type_trans(skb, dev);
> netif_rx(skb);
> }
> +
> + bdp->cbd_bufaddr = dma_map_single(NULL, data, bdp->cbd_datlen,
> + DMA_FROM_DEVICE);
> rx_processing_done:
> /* Clear the status flags for this buffer */
> status &= ~BD_ENET_RX_STATS;
> @@ -1399,15 +1407,86 @@ mii_link_interrupt(int irq, void * dev_id)
> }
> #endif
>
> +static void fec_enet_free_buffers(struct net_device *dev)
> +{
> + struct fec_enet_private *fep = netdev_priv(dev);
> + int i;
> + struct sk_buff *skb;
> + struct bufdesc *bdp;
> +
> + bdp = fep->rx_bd_base;
> + for (i = 0; i < RX_RING_SIZE; i++) {
> + skb = fep->rx_skbuff[i];
> +
> + if (bdp->cbd_bufaddr)
> + dma_unmap_single(&dev->dev, bdp->cbd_bufaddr,
> + FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
> + if (skb)
> + dev_kfree_skb(skb);
> + bdp++;
> + }
> +
> + bdp = fep->tx_bd_base;
> + for (i = 0; i < TX_RING_SIZE; i++)
> + kfree(fep->tx_bounce[i]);
> +}
> +
> +static int fec_enet_alloc_buffers(struct net_device *dev)
> +{
> + struct fec_enet_private *fep = netdev_priv(dev);
> + int i;
> + struct sk_buff *skb;
> + struct bufdesc *bdp;
> +
> + bdp = fep->rx_bd_base;
> + for (i = 0; i < RX_RING_SIZE; i++) {
> + skb = dev_alloc_skb(FEC_ENET_RX_FRSIZE);
> + if (!skb) {
> + fec_enet_free_buffers(dev);
> + return -ENOMEM;
> + }
> + fep->rx_skbuff[i] = skb;
> +
> + bdp->cbd_bufaddr = dma_map_single(&dev->dev, skb->data,
> + FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
> + bdp->cbd_sc = BD_ENET_RX_EMPTY;
> + bdp++;
> + }
> +
> + /* Set the last buffer to wrap. */
> + bdp--;
> + bdp->cbd_sc |= BD_SC_WRAP;
> +
> + bdp = fep->tx_bd_base;
> + for (i = 0; i < TX_RING_SIZE; i++) {
> + fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
> +
> + bdp->cbd_sc = 0;
> + bdp->cbd_bufaddr = 0;
> + bdp++;
> + }
> +
> + /* Set the last buffer to wrap. */
> + bdp--;
> + bdp->cbd_sc |= BD_SC_WRAP;
> +
> + return 0;
> +}
> +
> static int
> fec_enet_open(struct net_device *dev)
> {
> struct fec_enet_private *fep = netdev_priv(dev);
> + int ret;
>
> /* I should reset the ring buffers here, but I don't yet know
> * a simple way to do that.
> */
>
> + ret = fec_enet_alloc_buffers(dev);
> + if (ret)
> + return ret;
> +
> fep->sequence_done = 0;
> fep->link = 0;
>
> @@ -1454,6 +1533,8 @@ fec_enet_close(struct net_device *dev)
> netif_stop_queue(dev);
> fec_stop(dev);
>
> + fec_enet_free_buffers(dev);
> +
> return 0;
> }
>
> @@ -1576,9 +1657,8 @@ static const struct net_device_ops fec_netdev_ops = {
> int __init fec_enet_init(struct net_device *dev, int index)
> {
> struct fec_enet_private *fep = netdev_priv(dev);
> - unsigned long mem_addr;
> - struct bufdesc *bdp, *cbd_base;
> - int i, j;
> + struct bufdesc *cbd_base;
> + int i;
>
> /* Allocate memory for buffer descriptors. */
> cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma,
> @@ -1616,49 +1696,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;
>
> - /* Initialize the receive buffer descriptors. */
> - bdp = fep->rx_bd_base;
> - for (i=0; i<FEC_ENET_RX_PAGES; i++) {
> -
> - /* Allocate a page */
> - mem_addr = __get_free_page(GFP_KERNEL);
> - /* XXX: missing check for allocation failure */
> -
> - /* Initialize the BD for every fragment in the page */
> - for (j=0; j<FEC_ENET_RX_FRPPG; j++) {
> - bdp->cbd_sc = BD_ENET_RX_EMPTY;
> - bdp->cbd_bufaddr = __pa(mem_addr);
> - mem_addr += FEC_ENET_RX_FRSIZE;
> - bdp++;
> - }
> - }
> -
> - /* Set the last buffer to wrap */
> - bdp--;
> - bdp->cbd_sc |= BD_SC_WRAP;
> -
> - /* ...and the same for transmit */
> - bdp = fep->tx_bd_base;
> - for (i=0, j=FEC_ENET_TX_FRPPG; i<TX_RING_SIZE; i++) {
> - if (j >= FEC_ENET_TX_FRPPG) {
> - mem_addr = __get_free_page(GFP_KERNEL);
> - j = 1;
> - } else {
> - mem_addr += FEC_ENET_TX_FRSIZE;
> - j++;
> - }
> - fep->tx_bounce[i] = (unsigned char *) mem_addr;
> -
> - /* Initialize the BD for every fragment in the page */
> - bdp->cbd_sc = 0;
> - bdp->cbd_bufaddr = 0;
> - bdp++;
> - }
> -
> - /* Set the last buffer to wrap */
> - bdp--;
> - bdp->cbd_sc |= BD_SC_WRAP;
> -
> #ifdef HAVE_mii_link_interrupt
> fec_request_mii_intr(dev);
> #endif
--
------------------------------------------------------------------------
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
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 11/12] FEC Buffer rework
2009-04-17 10:07 ` Greg Ungerer
@ 2009-04-17 10:12 ` Sascha Hauer
0 siblings, 0 replies; 29+ messages in thread
From: Sascha Hauer @ 2009-04-17 10:12 UTC (permalink / raw)
To: Greg Ungerer; +Cc: netdev
On Fri, Apr 17, 2009 at 08:07:26PM +1000, Greg Ungerer wrote:
>
> Hi Sascha,
>
> Sascha Hauer wrote:
>> 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>
>
> 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.
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 |
^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2009-04-17 10:12 UTC | newest]
Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-15 11:32 [PATCH] FEC driver: patches for -next Sascha Hauer
2009-04-15 11:32 ` [PATCH 01/12] fec: remove unused ifdef Sascha Hauer
2009-04-15 11:32 ` [PATCH 02/12] fec: switch to writel/readl Sascha Hauer
2009-04-15 11:32 ` [PATCH 03/12] fec: do not typedef struct types Sascha Hauer
2009-04-15 11:32 ` [PATCH 04/12] fec: remove unnecessary cast Sascha Hauer
2009-04-15 11:32 ` [PATCH 05/12] fec: Codingstyle cleanups Sascha Hauer
2009-04-15 11:32 ` [PATCH 06/12] fec: refactor set_multicast_list() to make it more readable Sascha Hauer
2009-04-15 11:32 ` [PATCH 07/12] fec: refactor init function Sascha Hauer
2009-04-15 11:32 ` [PATCH 08/12] fec: align receive packets Sascha Hauer
2009-04-15 11:32 ` [PATCH 09/12] fec: remove debugging printks Sascha Hauer
2009-04-15 11:32 ` [PATCH 10/12] fec: switch to net_device_ops Sascha Hauer
2009-04-15 11:32 ` [PATCH 11/12] FEC Buffer rework Sascha Hauer
2009-04-15 11:32 ` [PATCH 12/12] fec: call fec_restart() in fec_open() Sascha Hauer
2009-04-16 9:38 ` David Miller
2009-04-16 9:38 ` [PATCH 11/12] FEC Buffer rework David Miller
2009-04-17 10:07 ` Greg Ungerer
2009-04-17 10:12 ` Sascha Hauer
2009-04-16 9:37 ` [PATCH 10/12] fec: switch to net_device_ops David Miller
2009-04-16 9:37 ` [PATCH 09/12] fec: remove debugging printks David Miller
2009-04-16 9:37 ` [PATCH 08/12] fec: align receive packets David Miller
2009-04-16 9:37 ` [PATCH 07/12] fec: refactor init function David Miller
2009-04-16 9:37 ` [PATCH 06/12] fec: refactor set_multicast_list() to make it more readable David Miller
2009-04-16 9:36 ` [PATCH 05/12] fec: Codingstyle cleanups David Miller
2009-04-16 9:36 ` [PATCH 04/12] fec: remove unnecessary cast David Miller
2009-04-16 9:36 ` [PATCH 03/12] fec: do not typedef struct types David Miller
2009-04-15 13:11 ` [PATCH 02/12] fec: switch to writel/readl Sascha Hauer
2009-04-16 9:36 ` David Miller
2009-04-15 12:12 ` [PATCH] FEC driver: patches for -next Greg Ungerer
2009-04-15 12:55 ` Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).