[PATCH] mv643xx_eth: fix byte order when checksum offload is enabled

2008-01-19 Thread Dale Farnsworth
From: Byron Bradley [EMAIL PROTECTED]

The Marvell Orion system on chips have an integrated mv643xx MAC.
On these little endian ARM devices mv643xx will oops when checksum
offload is enabled. Swapping the byte order of the protocol and
checksum solves this problem.

Signed-off-by: Byron Bradley [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]
Cc: Manish Lachwani [EMAIL PROTECTED]
Cc: Tzachi Perelstein [EMAIL PROTECTED]

---

Byron Bradley wrote:
 This patch has only been tested on two Marvell Orion based boards so it
 should be considered only very lightly tested. It applies against
 2.6.24-rc8-mm1.

Dale Farnsworth:
Looks good to me and I successfully booted it on a big-endian prpmc2800 board.

Jeff, please pick this up.  My mv643xx queue is otherwise empty.

Thanks,
-Dale

 drivers/net/mv643xx_eth.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 651c269..5d16a5d 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1689,7 +1689,7 @@ static void eth_tx_submit_descs_for_skb(struct 
mv643xx_private *mp,
desc-buf_ptr = dma_map_single(NULL, skb-data, length, DMA_TO_DEVICE);
 
if (skb-ip_summed == CHECKSUM_PARTIAL) {
-   BUG_ON(skb-protocol != ETH_P_IP);
+   BUG_ON(skb-protocol != htons(ETH_P_IP));
 
cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM |
   ETH_GEN_IP_V_4_CHECKSUM  |
@@ -1698,10 +1698,10 @@ static void eth_tx_submit_descs_for_skb(struct 
mv643xx_private *mp,
switch (ip_hdr(skb)-protocol) {
case IPPROTO_UDP:
cmd_sts |= ETH_UDP_FRAME;
-   desc-l4i_chk = udp_hdr(skb)-check;
+   desc-l4i_chk = htons(udp_hdr(skb)-check);
break;
case IPPROTO_TCP:
-   desc-l4i_chk = tcp_hdr(skb)-check;
+   desc-l4i_chk = htons(tcp_hdr(skb)-check);
break;
default:
BUG();
-- 
1.5.4.rc2.38.gd6da3


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] mv643xx_eth: fix byte order when checksum offload is enabled

2008-01-19 Thread Dale Farnsworth
OK, after digesting Al Viro's comments on this, I agree with him
and retract this.  These multiple byte swaps sure are confusing.

Byron, would you please resubmit?

Thanks,
-Dale

On Sat, Jan 19, 2008 at 01:23:01PM -0700, Dale Farnsworth wrote:
 From: Byron Bradley [EMAIL PROTECTED]
 
 The Marvell Orion system on chips have an integrated mv643xx MAC.
 On these little endian ARM devices mv643xx will oops when checksum
 offload is enabled. Swapping the byte order of the protocol and
 checksum solves this problem.
 
 Signed-off-by: Byron Bradley [EMAIL PROTECTED]
 Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]
 Cc: Manish Lachwani [EMAIL PROTECTED]
 Cc: Tzachi Perelstein [EMAIL PROTECTED]
 
 ---
 
 Byron Bradley wrote:
  This patch has only been tested on two Marvell Orion based boards so it
  should be considered only very lightly tested. It applies against
  2.6.24-rc8-mm1.
 
 Dale Farnsworth:
 Looks good to me and I successfully booted it on a big-endian prpmc2800 board.
 
 Jeff, please pick this up.  My mv643xx queue is otherwise empty.
 
 Thanks,
 -Dale
 
  drivers/net/mv643xx_eth.c |6 +++---
  1 files changed, 3 insertions(+), 3 deletions(-)
 
 diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
 index 651c269..5d16a5d 100644
 --- a/drivers/net/mv643xx_eth.c
 +++ b/drivers/net/mv643xx_eth.c
 @@ -1689,7 +1689,7 @@ static void eth_tx_submit_descs_for_skb(struct 
 mv643xx_private *mp,
   desc-buf_ptr = dma_map_single(NULL, skb-data, length, DMA_TO_DEVICE);
  
   if (skb-ip_summed == CHECKSUM_PARTIAL) {
 - BUG_ON(skb-protocol != ETH_P_IP);
 + BUG_ON(skb-protocol != htons(ETH_P_IP));
  
   cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM |
  ETH_GEN_IP_V_4_CHECKSUM  |
 @@ -1698,10 +1698,10 @@ static void eth_tx_submit_descs_for_skb(struct 
 mv643xx_private *mp,
   switch (ip_hdr(skb)-protocol) {
   case IPPROTO_UDP:
   cmd_sts |= ETH_UDP_FRAME;
 - desc-l4i_chk = udp_hdr(skb)-check;
 + desc-l4i_chk = htons(udp_hdr(skb)-check);
   break;
   case IPPROTO_TCP:
 - desc-l4i_chk = tcp_hdr(skb)-check;
 + desc-l4i_chk = htons(tcp_hdr(skb)-check);
   break;
   default:
   BUG();
 -- 
 1.5.4.rc2.38.gd6da3
 
 
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] add modalias info to mv643xx_eth.ko

2008-01-18 Thread Dale Farnsworth
On Fri, Jan 18, 2008 at 10:38:05AM +0100, Olaf Hering wrote:
 mv643xx_eth has an platform modalias file in sysfs.
 But the module itself has no alias: line. Autoloading fails
 without the alias info in the module.
 
 Signed-off-by: Olaf Hering [EMAIL PROTECTED]

Acked-by: Dale Farnsworth [EMAIL PROTECTED]
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] pegasos_eth.c: Fix compile error over MV643XX_ defines

2007-10-30 Thread Dale Farnsworth
On Tue, Oct 30, 2007 at 10:36:06AM +0100, Sven Luther wrote:
 On Tue, Oct 30, 2007 at 03:44:59AM -0400, Luis R. Rodriguez wrote:
  On 10/29/07, Dale Farnsworth [EMAIL PROTECTED] wrote:
   On Mon, Oct 29, 2007 at 05:27:29PM -0400, Luis R. Rodriguez wrote:
This commit made an incorrect assumption:
--
Author: Lennert Buytenhek [EMAIL PROTECTED]
 Date:   Fri Oct 19 04:10:10 2007 +0200
   
mv643xx_eth: Move ethernet register definitions into private header
   
Move the mv643xx's ethernet-related register definitions from
include/linux/mv643xx.h into drivers/net/mv643xx_eth.h, since
they aren't of any use outside the ethernet driver.
   
Signed-off-by: Lennert Buytenhek [EMAIL PROTECTED]
Acked-by: Tzachi Perelstein [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]
--
   
arch/powerpc/platforms/chrp/pegasos_eth.c made use of a 3 defines there.
   
[EMAIL PROTECTED]:~/devel/wireless-2.6$ git-describe
   
v2.6.24-rc1-138-g0119130
   
This patch fixes this by internalizing 3 defines onto pegasos which are
simply no longer available elsewhere. Without this your compile will 
fail
  
   That compile failure was fixed in commit
   30e69bf4cce16d4c2dcfd629a60fcd8e1aba9fee by Al Viro.
  
   However, as I examine that commit, I see that it defines offsets from
   the eth block in the chip, rather than the full chip registeri block
   as the Pegasos 2 code expects.  So, I think it fixes the compile
   failure, but leaves the Pegasos 2 broken.
  
   Luis, do you have Pegasos 2 hardware?  Can you (or anyone) verify that
   the following patch is needed for the Pegasos 2?
  
  Nope, sorry.
 
 I am busy right now, but have various pegasos machines available for
 testing. What exactly should i test ? 

Thanks Sven.

Test whether an Ethernet port works at all.  I think it's currently
broken, but should work with the patch I supplied.

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] pegasos_eth.c: Fix compile error over MV643XX_ defines

2007-10-29 Thread Dale Farnsworth
On Mon, Oct 29, 2007 at 05:27:29PM -0400, Luis R. Rodriguez wrote:
 This commit made an incorrect assumption:
 --
 Author: Lennert Buytenhek [EMAIL PROTECTED]
  Date:   Fri Oct 19 04:10:10 2007 +0200
 
 mv643xx_eth: Move ethernet register definitions into private header
 
 Move the mv643xx's ethernet-related register definitions from
 include/linux/mv643xx.h into drivers/net/mv643xx_eth.h, since
 they aren't of any use outside the ethernet driver.
 
 Signed-off-by: Lennert Buytenhek [EMAIL PROTECTED]
 Acked-by: Tzachi Perelstein [EMAIL PROTECTED]
 Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]
 --
 
 arch/powerpc/platforms/chrp/pegasos_eth.c made use of a 3 defines there.
 
 [EMAIL PROTECTED]:~/devel/wireless-2.6$ git-describe 
 
 v2.6.24-rc1-138-g0119130
 
 This patch fixes this by internalizing 3 defines onto pegasos which are
 simply no longer available elsewhere. Without this your compile will fail

That compile failure was fixed in commit
30e69bf4cce16d4c2dcfd629a60fcd8e1aba9fee by Al Viro.

However, as I examine that commit, I see that it defines offsets from
the eth block in the chip, rather than the full chip registeri block
as the Pegasos 2 code expects.  So, I think it fixes the compile
failure, but leaves the Pegasos 2 broken.

Luis, do you have Pegasos 2 hardware?  Can you (or anyone) verify that
the following patch is needed for the Pegasos 2?

Thanks,
-Dale

-

mv643xx_eth: Fix MV643XX_ETH offsets used by Pegasos 2

In the mv643xx_eth driver, we now use offsets from the ethernet
register block within the chip, but the pegasos 2 platform still
needs offsets from the full chip's register base address.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]
---
 include/linux/mv643xx_eth.h |6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h
index 8df230a..30e11aa 100644
--- a/include/linux/mv643xx_eth.h
+++ b/include/linux/mv643xx_eth.h
@@ -8,9 +8,9 @@
 #define MV643XX_ETH_NAME   mv643xx_eth
 #define MV643XX_ETH_SHARED_REGS0x2000
 #define MV643XX_ETH_SHARED_REGS_SIZE   0x2000
-#define MV643XX_ETH_BAR_4  0x220
-#define MV643XX_ETH_SIZE_REG_4 0x224
-#define MV643XX_ETH_BASE_ADDR_ENABLE_REG   0x0290
+#define MV643XX_ETH_BAR_4  0x2220
+#define MV643XX_ETH_SIZE_REG_4 0x2224
+#define MV643XX_ETH_BASE_ADDR_ENABLE_REG   0x2290
 
 struct mv643xx_eth_platform_data {
int port_number;
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4.2] FEC - fast ethernet controller for mpc52xx

2007-10-26 Thread Dale Farnsworth
On Fri, Oct 26, 2007 at 01:59:09PM +0200, Domen Puncer wrote:
 +static irqreturn_t mpc52xx_fec_tx_interrupt(int irq, void *dev_id)
 +{
 + struct net_device *dev = dev_id;
 + struct mpc52xx_fec_priv *priv = netdev_priv(dev);
 +
 + spin_lock(priv-lock);
 +
 + while (bcom_buffer_done(priv-tx_dmatsk)) {
 + struct sk_buff *skb;
 + struct bcom_fec_bd *bd;
 + skb = bcom_retrieve_buffer(priv-tx_dmatsk, NULL,
 + (struct bcom_bd **)bd);
 + /* Here (and in rx routines) would be a good place for
 +  * dma_unmap_single(), but bcom doesn't return bcom_bd of the
 +  * finished transfer, and _unmap is empty on this platfrom.
 +  */

Oops, you forgot to remove the above comment.  :)

Otherwise,
Acked-by: Dale Farnsworth [EMAIL PROTECTED]

Domen, thanks for all your work on this.  It's good to see it finally go in.

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4] FEC - fast ethernet controller for mpc52xx

2007-10-25 Thread Dale Farnsworth
,
 +  * and remove the old (with the packet) */
 + skb = dev_alloc_skb(FEC_RX_BUFFER_SIZE);
 + if (skb) {
 + /* Process the received skb */
 + int length = status  BCOM_FEC_RX_BD_LEN_MASK;

skb-dev = dev;

 +
 + skb_put(rskb, length - 4);  /* length without CRC32 
 */
 +
 + rskb-dev = dev;

Above line is no longer needed since we set rskb-dev on skb allocation.

 + rskb-protocol = eth_type_trans(rskb, dev);
 +
 + netif_rx(rskb);
 + dev-last_rx = jiffies;
 + } else {
 + /* Can't get a new one : reuse the same  drop pkt */
 + dev_notice(dev-dev, Memory squeeze, dropping 
 packet.\n);
 + dev-stats.rx_dropped++;
 +
 + skb = rskb;
 + }
 +
 + bd = (struct bcom_fec_bd *)
 + bcom_prepare_next_buffer(priv-rx_dmatsk);
 +
 + bd-status = FEC_RX_BUFFER_SIZE;
 + bd-skb_pa = dma_map_single(dev-dev, rskb-data,
 + FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE);
 +
 + bcom_submit_next_buffer(priv-rx_dmatsk, skb);
 + }
 +
 + return IRQ_HANDLED;
 +}

-Dale Farnsworth
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4] FEC - fast ethernet controller for mpc52xx

2007-10-25 Thread Dale Farnsworth
On Thu, Oct 25, 2007 at 09:41:14PM +0200, Domen Puncer wrote:
 On 25/10/07 11:57 -0700, Dale Farnsworth wrote:
  Domen wrote:
use your platform's dma mapping functions, rather than virt_to_phys()

it might be the exact same implementation, inside the platform 
internals, but drivers should not be using this directly.
   
   I've replaced this with dma_map_single(), unmatched with
   dma_unmap_single(), since bestcomm doesn't have a way to do that
   and it's blank on ppc32 anyway.
   
   Is this OK? PPC guys?
  
  Even though dma_unmap_single() may be a no-op, calls to
  dma_map_single() must be matched with calls to dma_unmap_single().
  
  Perhaps with the additions below:
  
   +static void mpc52xx_fec_free_rx_buffers(struct bcom_task *s)
   +{
   + struct sk_buff *skb;
   +
   + while (!bcom_queue_empty(s)) {
   + skb = bcom_retrieve_buffer(s, NULL, NULL);
  
  dma_unmap_single(skb-dev-dev, skb-data,
   FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE);
 
 It looks to me like dma_unmap_single takes the mapped address
 (what dma_map_single returned), and not the address we're mapping
 (skb-data).

Yeah.  Sorry.  That won't be so easy.  We'll either need to
squirrel away the mapped address, or change the interface to
bcom_retrieve_buffers() so we can get the address.

IMO, it's still a requirement that we call dma_unmap_single() for
each call to dma_map_single().

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Please pull bug-fixes branch of linux-2.6-mv643xx_eth.git

2007-10-23 Thread Dale Farnsworth

The following changes since commit e8b8c977734193adedf2b0f607d6252c78e86394:
  Linus Torvalds (1):
Revert kconfig: tristate choices with mixed tristate and boolean 
values

are available in the git repository at:

  git://farnsworth.org/dale/linux-2.6-mv643xx_eth.git bug-fixes

Dale Farnsworth (1):
  mv643xx_eth: Hook up mv643xx_get_sset_count

 drivers/net/mv643xx_eth.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

It may be also viewed at:
http://www.farnsworth.org/git?p=dale/linux-2.6-mv643xx_eth.git;a=shortlog;h=bug-fixes

Thanks,
-Dale

Here is the single commit:

Author: Dale Farnsworth [EMAIL PROTECTED]
Date:   Sat Oct 20 12:16:27 2007 -0700

mv643xx_eth: Hook up mv643xx_get_sset_count

Commit b9f2c044 replaced mv643xx_get_stats_count() with
mv643xx_get_sset_count(), but forgot to hook it up.

drivers/net/mv643xx_eth.c:2678: warning: mv643xx_get_sset_count defined but 
not used

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 84f2d63..54e4828 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -2742,6 +2742,7 @@ static const struct ethtool_ops mv643xx_ethtool_ops = {
.get_drvinfo= mv643xx_get_drvinfo,
.get_link   = mv643xx_eth_get_link,
.set_sg = ethtool_op_set_sg,
+   .get_sset_count = mv643xx_get_sset_count,
.get_ethtool_stats  = mv643xx_get_ethtool_stats,
.get_strings= mv643xx_get_strings,
.nway_reset = mv643xx_eth_nway_restart,
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Please pull features branch of linux-2.6-mv643xx_eth.git

2007-10-23 Thread Dale Farnsworth

The following changes since commit e8b8c977734193adedf2b0f607d6252c78e86394:
  Linus Torvalds (1):
Revert kconfig: tristate choices with mixed tristate and boolean 
values

are available in the git repository at:

  git://farnsworth.org/dale/linux-2.6-mv643xx_eth.git features

Dale Farnsworth (1):
  mv643xx_eth: Remove obsolete checksum offload comment

Lennert Buytenhek (9):
  mv643xx_eth: Split off mv643xx_eth platform device data
  mv643xx_eth: Move ethernet register definitions into private header
  mv643xx_eth: Disable RX/TX byte swapping on little-endian systems
  mv643xx_eth: Enable use on Orion platforms
  mv643xx_eth: Remove SHARED_REGS register address bias
  mv643xx_eth: Remove MV643XX_ETH_ register prefix
  mv643xx_eth: Clean up mv643xx_eth.h
  mv643xx_eth: Remove unused register defines
  mv643xx_eth: Merge drivers/net/mv643xx_eth.h into mv643xx_eth.c

 drivers/net/Kconfig |   13 +-
 drivers/net/mv643xx_eth.c   |  806 +++
 drivers/net/mv643xx_eth.h   |  370 
 include/linux/mv643xx.h |  328 +--
 include/linux/mv643xx_eth.h |   31 ++
 5 files changed, 709 insertions(+), 839 deletions(-)
 delete mode 100644 drivers/net/mv643xx_eth.h
 create mode 100644 include/linux/mv643xx_eth.h

It may also be viewed at:
http://www.farnsworth.org/git?p=dale/linux-2.6-mv643xx_eth.git;a=shortlog;h=features

Of course, it would be nice to get this into 2.6.24, but as a feature
addition, it could wait.

Thanks,
-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/8] [MV643XX_ETH] Move ethernet register definitions into private header

2007-10-19 Thread Dale Farnsworth
On Fri, Oct 19, 2007 at 01:09:57PM +0200, Lennert Buytenhek wrote:
 On Fri, Oct 19, 2007 at 09:30:48AM +0100, Christoph Hellwig wrote:
  Isn't it a little too confusing to have two headers with the same name,
  one in drivers/net and one in include/linux?
 
 Perhaps we can fold the drivers/net one into drivers/net/mv643xx_eth.c?
 Since nothing else includes drivers/net/mv643xx_eth.h anyway, there's
 not much point in having it separate.

Sounds good to me.  Please add a patch to do so.

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH,RFC] Marvell Orion SoC ethernet driver

2007-10-17 Thread Dale Farnsworth
In article [EMAIL PROTECTED] you write:
 Interesting.  After some asking around, it appears that the mv643xx
 ethernet silicon block is indeed very similar to the ethernet silicon
 block found the in Orion ARM SoCs.
 
 We'll work on getting Orion to use mv643xx_eth.  Thanks for pointing
 this out.

Cool.  I'd be very receptive to any cleanups you might provide for the
mv643xx_eth driver.

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mv643xx_eth: Do not modify struct netdev tx_queue_len

2007-10-01 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

This driver erroneously zeros dev-tx_queue_len, since
mp-tx_ring_size has not yet been initialized.  Actually,
the driver shouldn't modify tx_queue_len at all and should
leave the value set by alloc_etherdev(), currently 1000.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]
---
Jeff, this bug was just reported today, or I would have batched
it with the one I sent you last week.  It's an obvious bugfix,
so I'm not going to hold it in my queue.

 drivers/net/mv643xx_eth.c |1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 34288fe..3153356 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1357,7 +1357,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
 #endif
 
dev-watchdog_timeo = 2 * HZ;
-   dev-tx_queue_len = mp-tx_ring_size;
dev-base_addr = 0;
dev-change_mtu = mv643xx_eth_change_mtu;
dev-do_ioctl = mv643xx_eth_do_ioctl;
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mv643xx_eth: Check ETH_INT_CAUSE_STATE bit

2007-09-28 Thread Dale Farnsworth
Commit 468d09f8946d40228c56de26fe4874b2f98067ed masked the state
interrupt (bit 20 of the cause register). This results in Radstone's
PPC7D repeatedly re-entering the interrupt routine, locking up the
board. The following patch returns the required handling for this
interrupt. 

Signed-off-by: Martyn Welch [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---
Jeff, this is a bug fix.

 drivers/net/mv643xx_eth.c |2 +-
 drivers/net/mv643xx_eth.h |4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 1799eee..1785d15 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -534,7 +534,7 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void 
*dev_id)
}
 
/* PHY status changed */
-   if (eth_int_cause_ext  ETH_INT_CAUSE_PHY) {
+   if (eth_int_cause_ext  (ETH_INT_CAUSE_PHY | ETH_INT_CAUSE_STATE)) {
struct ethtool_cmd cmd;
 
if (mii_link_ok(mp-mii)) {
diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h
index 82f8c0c..565b966 100644
--- a/drivers/net/mv643xx_eth.h
+++ b/drivers/net/mv643xx_eth.h
@@ -64,7 +64,9 @@
 #define ETH_INT_CAUSE_TX_ERROR (ETH_TX_QUEUES_ENABLED  8)
 #define ETH_INT_CAUSE_TX   (ETH_INT_CAUSE_TX_DONE | ETH_INT_CAUSE_TX_ERROR)
 #define ETH_INT_CAUSE_PHY  0x0001
-#define ETH_INT_UNMASK_ALL_EXT (ETH_INT_CAUSE_TX | ETH_INT_CAUSE_PHY)
+#define ETH_INT_CAUSE_STATE0x0010
+#define ETH_INT_UNMASK_ALL_EXT (ETH_INT_CAUSE_TX | ETH_INT_CAUSE_PHY | \
+   ETH_INT_CAUSE_STATE)
 
 #define ETH_INT_MASK_ALL   0x
 #define ETH_INT_MASK_ALL_EXT   0x

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mv643xx_eth: Fix tx_bytes stats calculation

2007-09-14 Thread Dale Farnsworth
Reported by Corey Minyard [EMAIL PROTECTED]

---
 drivers/net/mv643xx_eth.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 1799eee..6a117e9 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1222,7 +1222,7 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, 
struct net_device *dev)
spin_lock_irqsave(mp-lock, flags);
 
eth_tx_submit_descs_for_skb(mp, skb);
-   stats-tx_bytes = skb-len;
+   stats-tx_bytes += skb-len;
stats-tx_packets++;
dev-trans_start = jiffies;
 
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: kernel crashes inside MV643xx driver

2007-09-05 Thread Dale Farnsworth
On Wed, Sep 05, 2007 at 08:24:52AM -0700, Andrew Morton wrote:
  On Mon, 20 Aug 2007 14:38:57 +0800 gshan [EMAIL PROTECTED] wrote:
  Hi All,
  
  After I started the NFS server, it crashed:
  
  3Badness in local_bh_enable at 
  /home/cli4/sandbox/main/TelicaRoot/components/mvlinux/cge/devkit/lsp/7xx/linux/kernel/softirq.c:195
  Badness in local_bh_enable at 
  /home/cli4/sandbox/main/TelicaRoot/components/mvlinux/cge/devkit/lsp/7xx/linux/kernel/softirq.c:195
  Call trace:
   [c0005340] check_bug_trap+0xbc/0x11c
   [c0005604] ProgramCheckException+0x264/0x2bc
   [c0004ac4] ret_from_except_full+0x0/0x4c
   [c0022ae4] local_bh_enable+0x18/0x80
   [c024648c] skb_copy_bits+0x168/0x3b8
   [c024db44] __skb_linearize+0x90/0x150
   [c020e8a4] mv643xx_eth_start_xmit+0x4c0/0x5bc
   [c025c934] qdisc_restart+0xac/0x2bc
   [c024de9c] dev_queue_xmit+0x298/0x34c
   [c0269814] ip_finish_output+0x140/0x2b8
   [c026a3ac] ip_fragment+0x3cc/0x6e0
   [c026bac8] ip_push_pending_frames+0x3dc/0x46c
   [c0289ec4] udp_push_pending_frames+0x10c/0x1cc
   [c028a7c4] udp_sendpage+0x104/0x188
   [c0292fc8] inet_sendpage+0x90/0xb8
  
  I searched the webs and found the similar problems:
  http://www.mail-archive.com/netdev@vger.kernel.org/msg05199.html
  http://oss.sgi.com/archives/netdev/2005-09/msg00025.html
  
  Who knew there are fixes for the problem?
  
 
 Well that got a tremendous response, didn't it?
 
 What do you mean by crashed?  The above is a warning and the system
 should have survived.
 
 Which kernel version is being used?

That is the key question.  From the pathnames, I suspect that gshan is
using a MontaVista version.  I'm still (especially) interested, since
MontaVista pays me.

BTW, I never received the original message on netdev or linux-kernel.
Hmm.  Thanks to Andrew for replying.

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Merge GT/MV642xx Support into MV643xx Driver [5/8]

2007-07-19 Thread Dale Farnsworth
On Thu, Jul 19, 2007 at 04:54:45AM +, Steven J. Hill wrote:
 Fix 'mv643xx_eth_tx_timeout_task' function prototype.
 
 Signed-off-by: Steven J. Hill [EMAIL PROTECTED]
 ---
 
 --- linux-2.6.22.1/drivers/net/mv643xx_eth.c  2007-07-18 21:45:13.0 
 -0500
 +++ linux-2.6.22.1-rci/drivers/net/mv643xx_eth.c  2007-07-18 
 21:44:07.0 -0500
 @@ -317,11 +315,9 @@
   *
   * Actual routine to reset the adapter when a timeout on Tx has occurred
   */
 -static void mv643xx_eth_tx_timeout_task(struct work_struct *ugly)
 +static void mv643xx_eth_tx_timeout_task(struct net_device *dev)
  {
 - struct mv643xx_private *mp = container_of(ugly, struct mv643xx_private,
 -   tx_timeout_task);
 - struct net_device *dev = mp-mii.dev; /* yuck */
 + struct mv643xx_private *mp = netdev_priv(dev);
  
   if (!netif_running(dev))
   return;

Applying this patch results yields a new compiler warning:
drivers/net/mv643xx_eth.c: In function `mv643xx_eth_probe':
drivers/net/mv643xx_eth.c:1375: warning: assignment from incompatible pointer 
type

I think we're stuck with the struct work_struct argument.

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Merge GT/MV642xx Support into MV643xx Driver [4/8]

2007-07-19 Thread Dale Farnsworth
On Thu, Jul 19, 2007 at 04:53:31AM +, Steven J. Hill wrote:
 Add main 642xx support to 'drivers/net/mv643xx_eth.c' file.

As Christoph said, this quantity of ifdefs really hurt the
maintainability.  Refactoring is needed.  Also, since in arch/powerpc
we want to have a single kernel support both MV64[34]60 and GT64260
(determined at runtime) and their register sets are so different, I
think the best approach is to have a separate module for the GT64260.

Also, please follow Documentation/SubmittingPatches.  Good subjects,
diffstats and diff -p would have been helpful in reviewing this series.

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Merge GT/MV642xx Support into MV643xx Driver [6/8]

2007-07-19 Thread Dale Farnsworth
On Thu, Jul 19, 2007 at 04:55:36AM +, Steven J. Hill wrote:
 Fix the TX bytes statistics counter to, um, actually count.
 
 Signed-off-by: Steven J. Hill [EMAIL PROTECTED]
 ---

 --- linux-2.6.22.1/drivers/net/mv643xx_eth.c  2007-07-18 21:51:49.0 
 -0500
 +++ linux-2.6.22.1-rci/drivers/net/mv643xx_eth.c  2007-07-18 
 21:44:07.0 -0500
 @@ -1506,7 +1511,7 @@
   spin_lock_irqsave(mp-lock, flags);
  
   eth_tx_submit_descs_for_skb(mp, skb);
 - stats-tx_bytes = skb-len;
 + stats-tx_bytes += skb-len;
   stats-tx_packets++;
   dev-trans_start = jiffies;
  

Good fix, thanks.  Please resubmit per the guidelines in
Documentation/SubmittingPatches.

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Merge GT/MV642xx Support into MV643xx Driver [7/8]

2007-07-19 Thread Dale Farnsworth
On Thu, Jul 19, 2007 at 04:56:51AM +, Steven J. Hill wrote:
 Get rid of global PHY spinlock.

You have replaced the use of the global PHY spinlock with a per-port spinlock.
However, the SMI register is shared by all ports.  The global lock is
needed to prevent simultaneous updates of the register by drivers for
multiple ports.

NAK

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Merge GT/MV642xx Support into MV643xx Driver [8/8]

2007-07-19 Thread Dale Farnsworth
On Thu, Jul 19, 2007 at 05:02:04AM +, Steven J. Hill wrote:
 Fix long standing panic with regards to descriptors and locking.
 
 Signed-off-by: Steven J. Hill [EMAIL PROTECTED]
 ---
 
 diff -ur linux-2.6.22.1/drivers/net/mv643xx_eth.c 
 linux-2.6.22.1-rci/drivers/net/mv643xx_eth.c
 --- linux-2.6.22.1/drivers/net/mv643xx_eth.c  2007-07-18 22:55:11.0 
 -0500
 +++ linux-2.6.22.1-rci/drivers/net/mv643xx_eth.c  2007-07-18 
 22:39:37.0 -0500
 @@ -350,13 +350,6 @@
  
   while (mp-tx_desc_count  0) {
   spin_lock_irqsave(mp-lock, flags);
 -
 - /* tx_desc_count might have changed before acquiring the lock */
 - if (mp-tx_desc_count = 0) {
 - spin_unlock_irqrestore(mp-lock, flags);
 - return released;
 - }
 -

The code you remove above is needed to protect against a nasty bug.
It was added in January and needs to stay in.

 @@ -367,7 +360,7 @@
  
   if (!force  (cmd_sts  ETH_BUFFER_OWNED_BY_DMA)) {
   spin_unlock_irqrestore(mp-lock, flags);
 - return released;
 + continue;
   }

No.  Continuing at that point results in the driver spinning, wasting
cpu while polling for the hardware to release the DMA descriptor.

 @@ -1488,7 +1481,19 @@
   BUG_ON(netif_queue_stopped(dev));
   BUG_ON(skb == NULL);
  
 - if (mp-tx_ring_size - mp-tx_desc_count  MAX_DESCS_PER_SKB) {
 + if (mp-tx_ring_size - mp-tx_desc_count = MAX_DESCS_PER_SKB) {
 + /*
 +  * We are completely out of TX descriptors, however,
 +  * if 'tx_used_desc_q' is zero, most likely the port
 +  * has been configured and is up, but there is no link.
 +  * We attempt to free a single descriptor to keep the
 +  * 'sendto' call and rest of the stack happy. If this
 +  * check is taken out, expect an error and kernel panic
 +  * from 'kernel/softirq.c:141' inside 'local_bh_enable'.
 +  */
 + if (mp-tx_used_desc_q == 0)
 + mv643xx_eth_free_all_tx_descs(dev);

I don't understand the bug, but regardless, we need a better fix.
Freeing all the descriptors when the HW xmit queue is full is not
a solution.

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Merge GT/MV642xx Support into MV643xx Driver [7/8]

2007-07-19 Thread Dale Farnsworth
On Thu, Jul 19, 2007 at 09:10:26PM -0500, Steven J. Hill wrote:
 Dale Farnsworth wrote:
  
  You have replaced the use of the global PHY spinlock with a per-port 
  spinlock.
  However, the SMI register is shared by all ports.  The global lock is
  needed to prevent simultaneous updates of the register by drivers for
  multiple ports.
  
  NAK
 
 Are you sure? Notice that a majority of the spinlocks were changed to disable
 IRQs. Secondly, the lowest level mv_read/mv_write functions have to acquire
 the big mv64x60_lock before they can read or write registers. I see the PHY
 spinlock as being an additional and unnecessary lock to contend with. Am I
 make an improper assumption?

I'm sure.  (Of course, I could be wrong.)  On an SMP (or fully
preemptive) system, disabling IRQs doesn't provide sufficient
protection.  Nor does a per-port spinlock, since multiple ports
share the single register.  It seems to me that a driver-scope
lock is required.

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/5 2.6.21-rc7] l2tp: pppol2tp changes to existing ppp kernel headers

2007-04-23 Thread Dale Farnsworth
James Chapman wrote:
 [L2TP]: Modify kernel headers for L2TP.

Since the Subject: line becomes the first line of the commit comments,
the above line is redundant.

 This patch adds L2TP definitions to existing PPP and socket headers.
 
 Signed-off-by: James Chapman [EMAIL PROTECTED]
 
 ---
 
 Add struct sockaddr_pppol2tp to carry L2TP-specific address
 information for the PPPoX (PPPoL2TP) socket. Unfortunately we can't
 use the union inside struct sockaddr_pppox because the L2TP-specific
 data is larger than the current size of the union and we must preserve
 the size of struct sockaddr_pppox for binary compatibility.
 
 Also add an ioctl to allow userspace to obtain L2TP counters and state
 from the kernel.

In my opinion, the above info is sufficiently useful to be included
commit comments.

-Dale Farnsworth
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Fix use of uninitialized field in mv643xx_eth

2007-03-23 Thread Dale Farnsworth
On Fri, Mar 23, 2007 at 01:30:02PM +0100, Gabriel Paubert wrote:
 In this driver, the default ethernet address is first set by by calling
 eth_port_uc_addr_get() which reads the relevant registers of the 
 corresponding port as initially set by firmware. However that function 
 used the port_num field accessed through the private area of net_dev 
 before it was set.  

Gabriel, you're right.  I introduced the bug and I'm sorry for your
trouble.

 The result was that one board I have ended up with the unicast address 
 set to 00:00:00:00:00:00 (only port 1 is connected on this board). The
 problem appeared after commit 84dd619e4dc3b0b1c40dafd98c90fd950bce7bc5.
 
 This patch fixes the bug by making eth_port_uc_get_addr() more similar 
 to eth_port_uc_set_addr(), i.e., by using the port number as the first
 parameter instead of a pointer to struct net_device.
 
 Signed-off-by: Gabriel Paubert [EMAIL PROTECTED]
 
 --
 
 The minimal patch I first tried consisted in just moving mp-port_num
 to before the call to eth_port_uc_get_addr().

Hmm.  That should have fixed it.  I reproduced the problem here and
this fixed it for me:

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 1ee27c3..643ea31 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1379,7 +1379,7 @@ #endif
 
spin_lock_init(mp-lock);
 
-   port_num = pd-port_number;
+   port_num = mp-port_num = pd-port_number;
 
/* set default config values */
eth_port_uc_addr_get(dev, dev-dev_addr);
@@ -1411,8 +1411,6 @@ #endif
duplex = pd-duplex;
speed = pd-speed;
 
-   mp-port_num = port_num;
-
/* Hook up MII support for ethtool */
mp-mii.dev = dev;
mp-mii.mdio_read = mv643xx_mdio_read;

Would you please confirm that this fixes it for you?  If so, I'll submit
it upstream as coming from you, since you did all the work.  OK?

 The other question is why
 the driver never gets the info from the device tree on this PPC board,
 but that's for another list despite the fact I lost some time looking 
 for bugs in the OF interface before stumbling on this use of a field
 before it was initialized.

Probably just because the mac address in the hardware was correct and
it didn't seem necessary to overwrite it.

Thank you,
-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] mv643xx_eth: Fix use of uninitialized port_num field

2007-03-23 Thread Dale Farnsworth
From: Gabriel Paubert [EMAIL PROTECTED]

In this driver, the default ethernet address is first set by by calling
eth_port_uc_addr_get() which reads the relevant registers of the
corresponding port as initially set by firmware. However that function
used the port_num field accessed through the private area of net_dev
before it was set.

The result was that one board I have ended up with the unicast address
set to 00:00:00:00:00:00 (only port 1 is connected on this board). The
problem appeared after commit 84dd619e4dc3b0b1c40dafd98c90fd950bce7bc5.

This patch fixes the bug by setting mp-port_num prior to calling
eth_port_uc_get_addr().

Signed-off-by: Gabriel Paubert [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]
---

This fixes a serious bug and should expeditiously pushed upstream.

 drivers/net/mv643xx_eth.c |4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 1ee27c3..643ea31 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1379,7 +1379,7 @@ #endif
 
spin_lock_init(mp-lock);
 
-   port_num = pd-port_number;
+   port_num = mp-port_num = pd-port_number;
 
/* set default config values */
eth_port_uc_addr_get(dev, dev-dev_addr);
@@ -1411,8 +1411,6 @@ #endif
duplex = pd-duplex;
speed = pd-speed;
 
-   mp-port_num = port_num;
-
/* Hook up MII support for ethtool */
mp-mii.dev = dev;
mp-mii.mdio_read = mv643xx_mdio_read;
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] mv643xx_eth: make eth_port_uc_addr_{get,set}() calls symmetric

2007-03-23 Thread Dale Farnsworth
From: Gabriel Paubert [EMAIL PROTECTED]

There is no good reason for the asymmetry in the parameters of
eth_port_uc_addr_get() and eth_port_uc_addr_set().  Make them
symmetric.  Remove some gratuitous block comments while we're here.

Signed-off-by: Gabriel Paubert [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]
---
This is a clean-up patch that needn't be rushed upstream.  -Dale

 drivers/net/mv643xx_eth.c |   59 +++-
 drivers/net/mv643xx_eth.h |4 --
 2 files changed, 13 insertions(+), 50 deletions(-)

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 643ea31..f58d96e 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -51,8 +51,8 @@ #include asm/delay.h
 #include mv643xx_eth.h
 
 /* Static function declarations */
-static void eth_port_uc_addr_get(struct net_device *dev,
-   unsigned char *MacAddr);
+static void eth_port_uc_addr_get(unsigned int port_num, unsigned char *p_addr);
+static void eth_port_uc_addr_set(unsigned int port_num, unsigned char *p_addr);
 static void eth_port_set_multicast_list(struct net_device *);
 static void mv643xx_eth_port_enable_tx(unsigned int port_num,
unsigned int queues);
@@ -1382,7 +1382,7 @@ #endif
port_num = mp-port_num = pd-port_number;
 
/* set default config values */
-   eth_port_uc_addr_get(dev, dev-dev_addr);
+   eth_port_uc_addr_get(port_num, dev-dev_addr);
mp-rx_ring_size = MV643XX_ETH_PORT_DEFAULT_RECEIVE_QUEUE_SIZE;
mp-tx_ring_size = MV643XX_ETH_PORT_DEFAULT_TRANSMIT_QUEUE_SIZE;
 
@@ -1826,26 +1826,9 @@ static void eth_port_start(struct net_de
 }
 
 /*
- * eth_port_uc_addr_set - This function Set the port Unicast address.
- *
- * DESCRIPTION:
- * This function Set the port Ethernet MAC address.
- *
- * INPUT:
- * unsigned inteth_port_numPort number.
- * char *  p_addr  Address to be set
- *
- * OUTPUT:
- * Set MAC address low and high registers. also calls
- * eth_port_set_filter_table_entry() to set the unicast
- * table with the proper information.
- *
- * RETURN:
- * N/A.
- *
+ * eth_port_uc_addr_set - Write a MAC address into the port's hw registers
  */
-static void eth_port_uc_addr_set(unsigned int eth_port_num,
-   unsigned char *p_addr)
+static void eth_port_uc_addr_set(unsigned int port_num, unsigned char *p_addr)
 {
unsigned int mac_h;
unsigned int mac_l;
@@ -1855,40 +1838,24 @@ static void eth_port_uc_addr_set(unsigne
mac_h = (p_addr[0]  24) | (p_addr[1]  16) | (p_addr[2]  8) |
(p_addr[3]  0);
 
-   mv_write(MV643XX_ETH_MAC_ADDR_LOW(eth_port_num), mac_l);
-   mv_write(MV643XX_ETH_MAC_ADDR_HIGH(eth_port_num), mac_h);
+   mv_write(MV643XX_ETH_MAC_ADDR_LOW(port_num), mac_l);
+   mv_write(MV643XX_ETH_MAC_ADDR_HIGH(port_num), mac_h);
 
-   /* Accept frames of this address */
-   table = MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE(eth_port_num);
+   /* Accept frames with this address */
+   table = MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE(port_num);
eth_port_set_filter_table_entry(table, p_addr[5]  0x0f);
 }
 
 /*
- * eth_port_uc_addr_get - This function retrieves the port Unicast address
- * (MAC address) from the ethernet hw registers.
- *
- * DESCRIPTION:
- * This function retrieves the port Ethernet MAC address.
- *
- * INPUT:
- * unsigned inteth_port_numPort number.
- * char*MacAddrpointer where the MAC address is stored
- *
- * OUTPUT:
- * Copy the MAC address to the location pointed to by MacAddr
- *
- * RETURN:
- * N/A.
- *
+ * eth_port_uc_addr_get - Read the MAC address from the port's hw registers
  */
-static void eth_port_uc_addr_get(struct net_device *dev, unsigned char *p_addr)
+static void eth_port_uc_addr_get(unsigned int port_num, unsigned char *p_addr)
 {
-   struct mv643xx_private *mp = netdev_priv(dev);
unsigned int mac_h;
unsigned int mac_l;
 
-   mac_h = mv_read(MV643XX_ETH_MAC_ADDR_HIGH(mp-port_num));
-   mac_l = mv_read(MV643XX_ETH_MAC_ADDR_LOW(mp-port_num));
+   mac_h = mv_read(MV643XX_ETH_MAC_ADDR_HIGH(port_num));
+   mac_l = mv_read(MV643XX_ETH_MAC_ADDR_LOW(port_num));
 
p_addr[0] = (mac_h  24)  0xff;
p_addr[1] = (mac_h  16)  0xff;
diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h
index 7d4e90c..82f8c0c 100644
--- a/drivers/net/mv643xx_eth.h
+++ b/drivers/net/mv643xx_eth.h
@@ -346,10 +346,6 @@ static void eth_port_init(struct mv643xx
 static void eth_port_reset(unsigned int eth_port_num);
 static void eth_port_start(struct net_device *dev);
 
-/* Port MAC address routines */
-static void eth_port_uc_addr_set(unsigned int eth_port_num

[PATCH] mv643xx_eth: add mv643xx_eth_shutdown function

2007-03-20 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

mv643xx_eth_shutdown is needed for kexec.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---
 drivers/net/mv643xx_eth.c |   14 ++
 1 file changed, 14 insertions(+)

Index: linux-2.6-powerpc-df/drivers/net/mv643xx_eth.c
===
--- linux-2.6-powerpc-df.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6-powerpc-df/drivers/net/mv643xx_eth.c
@@ -1516,9 +1516,23 @@ static int mv643xx_eth_shared_remove(str
return 0;
 }
 
+static void mv643xx_eth_shutdown(struct platform_device *pdev)
+{
+   struct net_device *dev = platform_get_drvdata(pdev);
+   struct mv643xx_private *mp = netdev_priv(dev);
+   unsigned int port_num = mp-port_num;
+
+   /* Mask all interrupts on ethernet port */
+   mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), 0);
+   mv_read (MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
+
+   eth_port_reset(port_num);
+}
+
 static struct platform_driver mv643xx_eth_driver = {
.probe = mv643xx_eth_probe,
.remove = mv643xx_eth_remove,
+   .shutdown = mv643xx_eth_shutdown,
.driver = {
.name = MV643XX_ETH_NAME,
},
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mv643xx: Clear pending interrupts before calling request_irq

2007-03-07 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]
Acked-by: Giridhar Pemmasani [EMAIL PROTECTED]

---

Giri, thank you very much for reporting the problem and confirming
the fix.

Jeff, please apply.

Andrew, this patch supersedes the -mm patch:
mv643xx-ethernet-driver-irq-registration-fix.patch

 drivers/net/mv643xx_eth.c |   10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 3e045a6..192b390 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -787,6 +787,12 @@ static int mv643xx_eth_open(struct net_device *dev)
unsigned int size;
int err;
 
+   /* Clear any pending ethernet port interrupts */
+   mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
+   mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
+   /* wait for previous write to complete */
+   mv_read (MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num));
+
err = request_irq(dev-irq, mv643xx_eth_int_handler,
IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev-name, dev);
if (err) {
@@ -875,10 +881,6 @@ static int mv643xx_eth_open(struct net_device *dev)
 
mv643xx_eth_rx_refill_descs(dev);   /* Fill RX ring with skb's */
 
-   /* Clear any pending ethernet port interrupts */
-   mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
-   mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
-
eth_port_start(dev);
 
/* Interrupt Coalescing */


-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [patch 18/19] mv643xx ethernet driver IRQ registration fix

2007-03-06 Thread Dale Farnsworth
On Tue, Mar 06, 2007 at 02:42:02AM -0800, [EMAIL PROTECTED] wrote:
 From: Giridhar Pemmasani [EMAIL PROTECTED]
 
 During initialization, mv643xx driver registers IRQ before setting up tx/rx
 rings.  This causes kernel oops because mv643xx_poll, which gets called
 right after registering IRQ, calls netif_rx_complete, which accesses the rx
 ring (I don't have the oops message anymore; I just remember this sequence
 of calls).  Attached (tested) patch first initializes the rx/tx rings and
 then registers the IRQ.

I believe a better fix is to disable any pending interrupt sources
before calling request_irq().  I sent the patch below to Giri for
confirmation, but haven't heard back.  I should've copied Andrew.

Giri, have you had a chance to test this alternative patch?

Thanks,
-Dale

 Date: Fri, 2 Mar 2007 17:03:53 -0700
 To: Giridhar Pemmasani [EMAIL PROTECTED]
 Message-ID: [EMAIL PROTECTED]
 In-Reply-To: [EMAIL PROTECTED]
 
 On Fri, Mar 02, 2007 at 04:52:06AM +, Giridhar Pemmasani wrote:
  During initialization, mv643xx driver registers IRQ before setting up tx/rx
  rings. This causes kernel oops because mv643xx_poll, which gets called
  right after registering IRQ, calls netif_rx_complete, which accesses the rx
  ring (I don't have the oops message anymore; I just remember this sequence
  of calls). Attached (tested) patch first initializes the rx/tx rings and
  then registers the IRQ.
  
  Giri
  
  Signed-off-by: Giridhar Pemmasani [EMAIL PROTECTED]
 
 Giridhar, does the following patch fix your problem, in place of the
 patch you supplied?
 
 -Dale

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 3e045a6..192b390 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -787,6 +787,12 @@ static int mv643xx_eth_open(struct net_device *dev)
unsigned int size;
int err;
 
+   /* Clear any pending ethernet port interrupts */
+   mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
+   mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
+   /* wait for previous write to complete */
+   mv_read (MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num));
+
err = request_irq(dev-irq, mv643xx_eth_int_handler,
IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev-name, dev);
if (err) {
@@ -875,10 +881,6 @@ static int mv643xx_eth_open(struct net_device *dev)
 
mv643xx_eth_rx_refill_descs(dev);   /* Fill RX ring with skb's */
 
-   /* Clear any pending ethernet port interrupts */
-   mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
-   mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
-
eth_port_start(dev);
 
/* Interrupt Coalescing */

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] mv643xx_eth: move mac_addr inside mv643xx_eth_platform_data

2007-03-01 Thread Dale Farnsworth
The information contained within platform_data should be self-contained.
Replace the pointer to a MAC address with the actual MAC address in
struct mv643xx_eth_platform_data.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---

Replaced explicit mac address comparison with a call to is_valid_ether_addr(),
as suggested by Stephen Hemminger [EMAIL PROTECTED].

 arch/mips/momentum/jaguar_atx/platform.c |   20 
 arch/mips/momentum/ocelot_3/platform.c   |   20 
 arch/mips/momentum/ocelot_c/platform.c   |   12 ++--
 drivers/net/mv643xx_eth.c|2 +-
 include/linux/mv643xx.h  |2 +-
 5 files changed, 12 insertions(+), 44 deletions(-)

Index: b/drivers/net/mv643xx_eth.c
===
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1380,7 +1380,7 @@ static int mv643xx_eth_probe(struct plat
 
pd = pdev-dev.platform_data;
if (pd) {
-   if (pd-mac_addr)
+   if (is_valid_ether_addr(pd-mac_addr))
memcpy(dev-dev_addr, pd-mac_addr, 6);
 
if (pd-phy_addr || pd-force_phy_addr)
Index: b/include/linux/mv643xx.h
===
--- a/include/linux/mv643xx.h
+++ b/include/linux/mv643xx.h
@@ -1289,7 +1289,6 @@ struct mv64xxx_i2c_pdata {
 #define MV643XX_ETH_NAME   mv643xx_eth
 
 struct mv643xx_eth_platform_data {
-   char*mac_addr;  /* pointer to mac address */
u16 force_phy_addr; /* force override if phy_addr == 0 */
u16 phy_addr;
 
@@ -1304,6 +1303,7 @@ struct mv643xx_eth_platform_data {
u32 tx_sram_size;
u32 rx_sram_addr;
u32 rx_sram_size;
+   u8  mac_addr[6];/* mac address if non-zero*/
 };
 
 #endif /* __ASM_MV643XX_H */
Index: b/arch/mips/momentum/jaguar_atx/platform.c
===
--- a/arch/mips/momentum/jaguar_atx/platform.c
+++ b/arch/mips/momentum/jaguar_atx/platform.c
@@ -47,11 +47,7 @@ static struct resource mv64x60_eth0_reso
},
 };
 
-static char eth0_mac_addr[ETH_ALEN];
-
 static struct mv643xx_eth_platform_data eth0_pd = {
-   .mac_addr   = eth0_mac_addr,
-
.tx_sram_addr   = MV_SRAM_BASE_ETH0,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -80,11 +76,7 @@ static struct resource mv64x60_eth1_reso
},
 };
 
-static char eth1_mac_addr[ETH_ALEN];
-
 static struct mv643xx_eth_platform_data eth1_pd = {
-   .mac_addr   = eth1_mac_addr,
-
.tx_sram_addr   = MV_SRAM_BASE_ETH1,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -113,11 +105,7 @@ static struct resource mv64x60_eth2_reso
},
 };
 
-static char eth2_mac_addr[ETH_ALEN];
-
-static struct mv643xx_eth_platform_data eth2_pd = {
-   .mac_addr   = eth2_mac_addr,
-};
+static struct mv643xx_eth_platform_data eth2_pd;
 
 static struct platform_device eth2_device = {
.name   = MV643XX_ETH_NAME,
@@ -200,9 +188,9 @@ static int __init mv643xx_eth_add_pds(vo
int ret;
 
get_mac(mac);
-   eth_mac_add(eth0_mac_addr, mac, 0);
-   eth_mac_add(eth1_mac_addr, mac, 1);
-   eth_mac_add(eth2_mac_addr, mac, 2);
+   eth_mac_add(eth0_pd.mac_addr, mac, 0);
+   eth_mac_add(eth1_pd.mac_addr, mac, 1);
+   eth_mac_add(eth2_pd.mac_addr, mac, 2);
ret = platform_add_devices(mv643xx_eth_pd_devs,
ARRAY_SIZE(mv643xx_eth_pd_devs));
 
Index: b/arch/mips/momentum/ocelot_3/platform.c
===
--- a/arch/mips/momentum/ocelot_3/platform.c
+++ b/arch/mips/momentum/ocelot_3/platform.c
@@ -47,11 +47,7 @@ static struct resource mv64x60_eth0_reso
},
 };
 
-static char eth0_mac_addr[ETH_ALEN];
-
 static struct mv643xx_eth_platform_data eth0_pd = {
-   .mac_addr   = eth0_mac_addr,
-
.tx_sram_addr   = MV_SRAM_BASE_ETH0,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -80,11 +76,7 @@ static struct resource mv64x60_eth1_reso
},
 };
 
-static char eth1_mac_addr[ETH_ALEN];
-
 static struct mv643xx_eth_platform_data eth1_pd = {
-   .mac_addr   = eth1_mac_addr,
-
.tx_sram_addr   = MV_SRAM_BASE_ETH1,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -113,11 +105,7 @@ static struct resource mv64x60_eth2_reso
},
 };
 
-static char eth2_mac_addr[ETH_ALEN];
-
-static struct mv643xx_eth_platform_data eth2_pd = {
-   .mac_addr   = eth2_mac_addr,
-};
+static struct mv643xx_eth_platform_data eth2_pd;
 
 static struct platform_device eth2_device = {
.name

[PATCH 2/2] mv643xx_eth: Place explicit port number in mv643xx_eth_platform_data

2007-03-01 Thread Dale Farnsworth
We were using the platform_device.id field to identify which ethernet
port is used for mv643xx_eth device.  This is not generally correct.
It will be incorrect, for example, if a hardware platform uses a single
port but not the first port.  Here, we add an explicit port_number field
to struct mv643xx_eth_platform_data.

This makes the mv643xx_eth_platform_data structure required, but that
isn't an issue since all users currently provide it already.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---

 arch/mips/momentum/jaguar_atx/platform.c  |8 ++
 arch/mips/momentum/ocelot_3/platform.c|8 ++
 arch/mips/momentum/ocelot_c/platform.c|4 +
 arch/powerpc/platforms/chrp/pegasos_eth.c |2 
 arch/ppc/syslib/mv64x60.c |   12 +++-
 drivers/net/mv643xx_eth.c |   59 ++--
 include/linux/mv643xx.h   |1 
 7 files changed, 62 insertions(+), 32 deletions(-)

diff --git a/arch/mips/momentum/jaguar_atx/platform.c 
b/arch/mips/momentum/jaguar_atx/platform.c
index 035ea51..003d3ee 100644
Index: b/arch/mips/momentum/jaguar_atx/platform.c
===
--- a/arch/mips/momentum/jaguar_atx/platform.c
+++ b/arch/mips/momentum/jaguar_atx/platform.c
@@ -48,6 +48,8 @@ static struct resource mv64x60_eth0_reso
 };
 
 static struct mv643xx_eth_platform_data eth0_pd = {
+   .port_number= 0,
+
.tx_sram_addr   = MV_SRAM_BASE_ETH0,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -77,6 +79,8 @@ static struct resource mv64x60_eth1_reso
 };
 
 static struct mv643xx_eth_platform_data eth1_pd = {
+   .port_number= 1,
+
.tx_sram_addr   = MV_SRAM_BASE_ETH1,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -105,7 +109,9 @@ static struct resource mv64x60_eth2_reso
},
 };
 
-static struct mv643xx_eth_platform_data eth2_pd;
+static struct mv643xx_eth_platform_data eth2_pd = {
+   .port_number= 2,
+};
 
 static struct platform_device eth2_device = {
.name   = MV643XX_ETH_NAME,
Index: b/arch/mips/momentum/ocelot_3/platform.c
===
--- a/arch/mips/momentum/ocelot_3/platform.c
+++ b/arch/mips/momentum/ocelot_3/platform.c
@@ -48,6 +48,8 @@ static struct resource mv64x60_eth0_reso
 };
 
 static struct mv643xx_eth_platform_data eth0_pd = {
+   .port_number= 0,
+
.tx_sram_addr   = MV_SRAM_BASE_ETH0,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -77,6 +79,8 @@ static struct resource mv64x60_eth1_reso
 };
 
 static struct mv643xx_eth_platform_data eth1_pd = {
+   .port_number= 1,
+
.tx_sram_addr   = MV_SRAM_BASE_ETH1,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -105,7 +109,9 @@ static struct resource mv64x60_eth2_reso
},
 };
 
-static struct mv643xx_eth_platform_data eth2_pd;
+static struct mv643xx_eth_platform_data eth2_pd = {
+   .port_number= 2,
+};
 
 static struct platform_device eth2_device = {
.name   = MV643XX_ETH_NAME,
Index: b/arch/mips/momentum/ocelot_c/platform.c
===
--- a/arch/mips/momentum/ocelot_c/platform.c
+++ b/arch/mips/momentum/ocelot_c/platform.c
@@ -47,6 +47,8 @@ static struct resource mv64x60_eth0_reso
 };
 
 static struct mv643xx_eth_platform_data eth0_pd = {
+   .port_number= 0,
+
.tx_sram_addr   = MV_SRAM_BASE_ETH0,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -76,6 +78,8 @@ static struct resource mv64x60_eth1_reso
 };
 
 static struct mv643xx_eth_platform_data eth1_pd = {
+   .port_number= 1,
+
.tx_sram_addr   = MV_SRAM_BASE_ETH1,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
Index: b/arch/powerpc/platforms/chrp/pegasos_eth.c
===
--- a/arch/powerpc/platforms/chrp/pegasos_eth.c
+++ b/arch/powerpc/platforms/chrp/pegasos_eth.c
@@ -58,6 +58,7 @@ static struct resource mv643xx_eth0_reso
 
 
 static struct mv643xx_eth_platform_data eth0_pd = {
+   .port_number= 0,
.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0,
.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
@@ -87,6 +88,7 @@ static struct resource mv643xx_eth1_reso
 };
 
 static struct mv643xx_eth_platform_data eth1_pd = {
+   .port_number= 1,
.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1,
.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
Index: b/arch/ppc/syslib/mv64x60.c

[PATCH 1/2] mv643xx_eth: move mac_addr inside of mv643xx_eth_platform_data

2007-02-28 Thread Dale Farnsworth
The information contained within platform_data should be self-contained.
Replace the pointer to a MAC address with the actual MAC address in
struct mv643xx_eth_platform_data.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

Index: b/drivers/net/mv643xx_eth.c
===
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1380,7 +1380,9 @@ static int mv643xx_eth_probe(struct plat
 
pd = pdev-dev.platform_data;
if (pd) {
-   if (pd-mac_addr)
+   static u8 zero_mac_addr[6] = { 0 };
+
+   if (memcmp(pd-mac_addr, zero_mac_addr, 6) != 0)
memcpy(dev-dev_addr, pd-mac_addr, 6);
 
if (pd-phy_addr || pd-force_phy_addr)
Index: b/include/linux/mv643xx.h
===
--- a/include/linux/mv643xx.h
+++ b/include/linux/mv643xx.h
@@ -1289,7 +1289,6 @@ struct mv64xxx_i2c_pdata {
 #define MV643XX_ETH_NAME   mv643xx_eth
 
 struct mv643xx_eth_platform_data {
-   char*mac_addr;  /* pointer to mac address */
u16 force_phy_addr; /* force override if phy_addr == 0 */
u16 phy_addr;
 
@@ -1304,6 +1303,7 @@ struct mv643xx_eth_platform_data {
u32 tx_sram_size;
u32 rx_sram_addr;
u32 rx_sram_size;
+   u8  mac_addr[6];/* mac address if non-zero*/
 };
 
 #endif /* __ASM_MV643XX_H */
Index: b/arch/mips/momentum/jaguar_atx/platform.c
===
--- a/arch/mips/momentum/jaguar_atx/platform.c
+++ b/arch/mips/momentum/jaguar_atx/platform.c
@@ -47,11 +47,7 @@ static struct resource mv64x60_eth0_reso
},
 };
 
-static char eth0_mac_addr[ETH_ALEN];
-
 static struct mv643xx_eth_platform_data eth0_pd = {
-   .mac_addr   = eth0_mac_addr,
-
.tx_sram_addr   = MV_SRAM_BASE_ETH0,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -80,11 +76,7 @@ static struct resource mv64x60_eth1_reso
},
 };
 
-static char eth1_mac_addr[ETH_ALEN];
-
 static struct mv643xx_eth_platform_data eth1_pd = {
-   .mac_addr   = eth1_mac_addr,
-
.tx_sram_addr   = MV_SRAM_BASE_ETH1,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -113,11 +105,7 @@ static struct resource mv64x60_eth2_reso
},
 };
 
-static char eth2_mac_addr[ETH_ALEN];
-
-static struct mv643xx_eth_platform_data eth2_pd = {
-   .mac_addr   = eth2_mac_addr,
-};
+static struct mv643xx_eth_platform_data eth2_pd;
 
 static struct platform_device eth2_device = {
.name   = MV643XX_ETH_NAME,
@@ -200,9 +188,9 @@ static int __init mv643xx_eth_add_pds(vo
int ret;
 
get_mac(mac);
-   eth_mac_add(eth0_mac_addr, mac, 0);
-   eth_mac_add(eth1_mac_addr, mac, 1);
-   eth_mac_add(eth2_mac_addr, mac, 2);
+   eth_mac_add(eth0_pd.mac_addr, mac, 0);
+   eth_mac_add(eth1_pd.mac_addr, mac, 1);
+   eth_mac_add(eth2_pd.mac_addr, mac, 2);
ret = platform_add_devices(mv643xx_eth_pd_devs,
ARRAY_SIZE(mv643xx_eth_pd_devs));
 
Index: b/arch/mips/momentum/ocelot_3/platform.c
===
--- a/arch/mips/momentum/ocelot_3/platform.c
+++ b/arch/mips/momentum/ocelot_3/platform.c
@@ -47,11 +47,7 @@ static struct resource mv64x60_eth0_reso
},
 };
 
-static char eth0_mac_addr[ETH_ALEN];
-
 static struct mv643xx_eth_platform_data eth0_pd = {
-   .mac_addr   = eth0_mac_addr,
-
.tx_sram_addr   = MV_SRAM_BASE_ETH0,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -80,11 +76,7 @@ static struct resource mv64x60_eth1_reso
},
 };
 
-static char eth1_mac_addr[ETH_ALEN];
-
 static struct mv643xx_eth_platform_data eth1_pd = {
-   .mac_addr   = eth1_mac_addr,
-
.tx_sram_addr   = MV_SRAM_BASE_ETH1,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -113,11 +105,7 @@ static struct resource mv64x60_eth2_reso
},
 };
 
-static char eth2_mac_addr[ETH_ALEN];
-
-static struct mv643xx_eth_platform_data eth2_pd = {
-   .mac_addr   = eth2_mac_addr,
-};
+static struct mv643xx_eth_platform_data eth2_pd;
 
 static struct platform_device eth2_device = {
.name   = MV643XX_ETH_NAME,
@@ -200,9 +188,9 @@ static int __init mv643xx_eth_add_pds(vo
int ret;
 
get_mac(mac);
-   eth_mac_add(eth0_mac_addr, mac, 0);
-   eth_mac_add(eth1_mac_addr, mac, 1);
-   eth_mac_add(eth2_mac_addr, mac, 2);
+   eth_mac_add(eth0_pd.mac_addr, mac, 0);
+   eth_mac_add(eth1_pd.mac_addr, mac, 1);
+   eth_mac_add(eth2_pd.mac_addr, mac, 2);
ret

Re: [PATCH 2/2] mv643xx_eth: Place explicit port number in mv643xx_eth_platform_data

2007-02-28 Thread Dale Farnsworth
We had been using the platform_device.id field to identify which ethernet
port is used for mv643xx_eth device.  This is not correct in general.
It will be incorrect, for example, if a hardware platform uses a single
port but not the first port.  Here, we add an explicit port_number field
to struct mv643xx_eth_platform_data.

This makes the mv643xx_eth_platform_data structure required, but that
isn't an issue since all users currently provide it already.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

diff --git a/arch/mips/momentum/jaguar_atx/platform.c 
b/arch/mips/momentum/jaguar_atx/platform.c
Index: b/arch/mips/momentum/jaguar_atx/platform.c
===
--- a/arch/mips/momentum/jaguar_atx/platform.c
+++ b/arch/mips/momentum/jaguar_atx/platform.c
@@ -48,6 +48,8 @@ static struct resource mv64x60_eth0_reso
 };
 
 static struct mv643xx_eth_platform_data eth0_pd = {
+   .port_number= 0,
+
.tx_sram_addr   = MV_SRAM_BASE_ETH0,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -77,6 +79,8 @@ static struct resource mv64x60_eth1_reso
 };
 
 static struct mv643xx_eth_platform_data eth1_pd = {
+   .port_number= 1,
+
.tx_sram_addr   = MV_SRAM_BASE_ETH1,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -105,7 +109,9 @@ static struct resource mv64x60_eth2_reso
},
 };
 
-static struct mv643xx_eth_platform_data eth2_pd;
+static struct mv643xx_eth_platform_data eth2_pd = {
+   .port_number= 2,
+};
 
 static struct platform_device eth2_device = {
.name   = MV643XX_ETH_NAME,
Index: b/arch/mips/momentum/ocelot_3/platform.c
===
--- a/arch/mips/momentum/ocelot_3/platform.c
+++ b/arch/mips/momentum/ocelot_3/platform.c
@@ -48,6 +48,8 @@ static struct resource mv64x60_eth0_reso
 };
 
 static struct mv643xx_eth_platform_data eth0_pd = {
+   .port_number= 0,
+
.tx_sram_addr   = MV_SRAM_BASE_ETH0,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -77,6 +79,8 @@ static struct resource mv64x60_eth1_reso
 };
 
 static struct mv643xx_eth_platform_data eth1_pd = {
+   .port_number= 1,
+
.tx_sram_addr   = MV_SRAM_BASE_ETH1,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -105,7 +109,9 @@ static struct resource mv64x60_eth2_reso
},
 };
 
-static struct mv643xx_eth_platform_data eth2_pd;
+static struct mv643xx_eth_platform_data eth2_pd = {
+   .port_number= 2,
+};
 
 static struct platform_device eth2_device = {
.name   = MV643XX_ETH_NAME,
Index: b/arch/mips/momentum/ocelot_c/platform.c
===
--- a/arch/mips/momentum/ocelot_c/platform.c
+++ b/arch/mips/momentum/ocelot_c/platform.c
@@ -47,6 +47,8 @@ static struct resource mv64x60_eth0_reso
 };
 
 static struct mv643xx_eth_platform_data eth0_pd = {
+   .port_number= 0,
+
.tx_sram_addr   = MV_SRAM_BASE_ETH0,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
@@ -76,6 +78,8 @@ static struct resource mv64x60_eth1_reso
 };
 
 static struct mv643xx_eth_platform_data eth1_pd = {
+   .port_number= 1,
+
.tx_sram_addr   = MV_SRAM_BASE_ETH1,
.tx_sram_size   = MV_SRAM_TXRING_SIZE,
.tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
Index: b/arch/powerpc/platforms/chrp/pegasos_eth.c
===
--- a/arch/powerpc/platforms/chrp/pegasos_eth.c
+++ b/arch/powerpc/platforms/chrp/pegasos_eth.c
@@ -58,6 +58,7 @@ static struct resource mv643xx_eth0_reso
 
 
 static struct mv643xx_eth_platform_data eth0_pd = {
+   .port_number= 0,
.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0,
.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
@@ -87,6 +88,7 @@ static struct resource mv643xx_eth1_reso
 };
 
 static struct mv643xx_eth_platform_data eth1_pd = {
+   .port_number= 1,
.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1,
.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
Index: b/arch/ppc/syslib/mv64x60.c
===
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -339,7 +339,9 @@ static struct resource mv64x60_eth0_reso
},
 };
 
-static struct mv643xx_eth_platform_data eth0_pd;
+static struct mv643xx_eth_platform_data eth0_pd = {
+   .port_number= 0,
+};
 
 static struct platform_device eth0_device = {
.name   = MV643XX_ETH_NAME,
@@ -362,7 +364,9 @@ static struct resource mv64x60_eth1_reso
},
 };
 
-static struct

Re: [PATCH 1/2] mv643xx_eth: move mac_addr inside of mv643xx_eth_platform_data

2007-02-28 Thread Dale Farnsworth
On Wed, Feb 28, 2007 at 03:11:03PM -0800, Stephen Hemminger wrote:
 On Wed, 28 Feb 2007 15:40:31 -0700
 Dale Farnsworth [EMAIL PROTECTED] wrote:
 
  The information contained within platform_data should be self-contained.
  Replace the pointer to a MAC address with the actual MAC address in
  struct mv643xx_eth_platform_data.
  
  Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]
  
  Index: b/drivers/net/mv643xx_eth.c
  ===
  --- a/drivers/net/mv643xx_eth.c
  +++ b/drivers/net/mv643xx_eth.c
  @@ -1380,7 +1380,9 @@ static int mv643xx_eth_probe(struct plat
   
  pd = pdev-dev.platform_data;
  if (pd) {
  -   if (pd-mac_addr)
  +   static u8 zero_mac_addr[6] = { 0 };
  +
  +   if (memcmp(pd-mac_addr, zero_mac_addr, 6) != 0)
  memcpy(dev-dev_addr, pd-mac_addr, 6);
 
 
 is_zero_ether_addr() is faster/cleaner for this

Thanks.  I follow up with a modified patch in a day or two.

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC][NET] Alignment in mv643xx_eth

2007-02-26 Thread Dale Farnsworth
On Mon, Feb 26, 2007 at 07:52:06PM +, Ralf Baechle wrote:
 The driver contains this little piece of candy:
 
 #if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_NOT_COHERENT_CACHE)
 #define ETH_DMA_ALIGN   L1_CACHE_BYTES
 #else
 #define ETH_DMA_ALIGN   8
 #endif
 
 Any reason why we're not using dma_get_cache_alignment() instead?

Not that I can think of.

ACK.

Dale Farnsworth
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Eliminate user-selectable CONFIG_MV643XX_ETH_[012]

2007-02-20 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

Remove the use of CONFIG_MV643XX_ETH_[012] variables on most
platforms.  Instead, platform-specific code enables the ports
supported by the hardware.  After this patch, these config
variables are only used in arch/ppc, so also move them from
drivers/net/Kconfig to arch/ppc/Kconfig.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---
It was a mis-feature that the supported ports were ever user-selectable.
Which ports the hardware supports should be specified by platform-specific
code, not by the user.

 arch/mips/momentum/jaguar_atx/platform.c |   21 -
 arch/mips/momentum/ocelot_3/platform.c   |   21 -
 arch/mips/momentum/ocelot_c/platform.c   |   14 --
 arch/ppc/Kconfig |   15 +++
 drivers/net/Kconfig  |   21 -
 5 files changed, 15 insertions(+), 77 deletions(-)

Index: b/arch/mips/momentum/jaguar_atx/platform.c
===
--- a/arch/mips/momentum/jaguar_atx/platform.c
+++ b/arch/mips/momentum/jaguar_atx/platform.c
@@ -38,8 +38,6 @@ static struct platform_device mv643xx_et
 #define MV64x60_IRQ_ETH_1 49
 #define MV64x60_IRQ_ETH_2 50
 
-#ifdef CONFIG_MV643XX_ETH_0
-
 static struct resource mv64x60_eth0_resources[] = {
[0] = {
.name   = eth0 irq,
@@ -72,9 +70,6 @@ static struct platform_device eth0_devic
.platform_data = eth0_pd,
},
 };
-#endif /* CONFIG_MV643XX_ETH_0 */
-
-#ifdef CONFIG_MV643XX_ETH_1
 
 static struct resource mv64x60_eth1_resources[] = {
[0] = {
@@ -108,9 +103,6 @@ static struct platform_device eth1_devic
.platform_data = eth1_pd,
},
 };
-#endif /* CONFIG_MV643XX_ETH_1 */
-
-#ifdef CONFIG_MV643XX_ETH_2
 
 static struct resource mv64x60_eth2_resources[] = {
[0] = {
@@ -136,19 +128,12 @@ static struct platform_device eth2_devic
.platform_data = eth2_pd,
},
 };
-#endif /* CONFIG_MV643XX_ETH_2 */
 
 static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
mv643xx_eth_shared_device,
-#ifdef CONFIG_MV643XX_ETH_0
eth0_device,
-#endif
-#ifdef CONFIG_MV643XX_ETH_1
eth1_device,
-#endif
-#ifdef CONFIG_MV643XX_ETH_2
eth2_device,
-#endif
 };
 
 static u8 __init exchange_bit(u8 val, u8 cs)
@@ -215,15 +200,9 @@ static int __init mv643xx_eth_add_pds(vo
int ret;
 
get_mac(mac);
-#ifdef CONFIG_MV643XX_ETH_0
eth_mac_add(eth1_mac_addr, mac, 0);
-#endif
-#ifdef CONFIG_MV643XX_ETH_1
eth_mac_add(eth1_mac_addr, mac, 1);
-#endif
-#ifdef CONFIG_MV643XX_ETH_2
eth_mac_add(eth2_mac_addr, mac, 2);
-#endif
ret = platform_add_devices(mv643xx_eth_pd_devs,
ARRAY_SIZE(mv643xx_eth_pd_devs));
 
Index: b/arch/mips/momentum/ocelot_3/platform.c
===
--- a/arch/mips/momentum/ocelot_3/platform.c
+++ b/arch/mips/momentum/ocelot_3/platform.c
@@ -38,8 +38,6 @@ static struct platform_device mv643xx_et
 #define MV64x60_IRQ_ETH_1 49
 #define MV64x60_IRQ_ETH_2 50
 
-#ifdef CONFIG_MV643XX_ETH_0
-
 static struct resource mv64x60_eth0_resources[] = {
[0] = {
.name   = eth0 irq,
@@ -72,9 +70,6 @@ static struct platform_device eth0_devic
.platform_data = eth0_pd,
},
 };
-#endif /* CONFIG_MV643XX_ETH_0 */
-
-#ifdef CONFIG_MV643XX_ETH_1
 
 static struct resource mv64x60_eth1_resources[] = {
[0] = {
@@ -108,9 +103,6 @@ static struct platform_device eth1_devic
.platform_data = eth1_pd,
},
 };
-#endif /* CONFIG_MV643XX_ETH_1 */
-
-#ifdef CONFIG_MV643XX_ETH_2
 
 static struct resource mv64x60_eth2_resources[] = {
[0] = {
@@ -136,19 +128,12 @@ static struct platform_device eth2_devic
.platform_data = eth2_pd,
},
 };
-#endif /* CONFIG_MV643XX_ETH_2 */
 
 static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
mv643xx_eth_shared_device,
-#ifdef CONFIG_MV643XX_ETH_0
eth0_device,
-#endif
-#ifdef CONFIG_MV643XX_ETH_1
eth1_device,
-#endif
-#ifdef CONFIG_MV643XX_ETH_2
eth2_device,
-#endif
 };
 
 static u8 __init exchange_bit(u8 val, u8 cs)
@@ -215,15 +200,9 @@ static int __init mv643xx_eth_add_pds(vo
int ret;
 
get_mac(mac);
-#ifdef CONFIG_MV643XX_ETH_0
eth_mac_add(eth1_mac_addr, mac, 0);
-#endif
-#ifdef CONFIG_MV643XX_ETH_1
eth_mac_add(eth1_mac_addr, mac, 1);
-#endif
-#ifdef CONFIG_MV643XX_ETH_2
eth_mac_add(eth2_mac_addr, mac, 2);
-#endif
ret = platform_add_devices(mv643xx_eth_pd_devs,
ARRAY_SIZE(mv643xx_eth_pd_devs));
 
Index: b/arch/mips/momentum/ocelot_c/platform.c
===
--- a/arch/mips/momentum/ocelot_c/platform.c
+++ b/arch/mips/momentum/ocelot_c/platform.c

[PATCH] mv643xx_eth: Fix race condition in mv643xx_eth_free_tx_descs

2007-01-23 Thread Dale Farnsworth
From Dale Farnsworth [EMAIL PROTECTED]

mv643xx_eth: Fix race condition in mv643xx_eth_free_tx_descs

This bug was found and isolated by Thibaut VARENE [EMAIL PROTECTED]
and Jarek Poplawski [EMAIL PROTECTED].  This patch is a modification of their
fixes.  We acquire and release the lock for each descriptor that is freed
to minimize the time the lock is held.

---

 drivers/net/mv643xx_eth.c |   11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index c41ae42..b3bf864 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -314,6 +314,13 @@ int mv643xx_eth_free_tx_descs(struct net
 
while (mp-tx_desc_count  0) {
spin_lock_irqsave(mp-lock, flags);
+
+   /* tx_desc_count might have changed before acquiring the lock */
+   if (mp-tx_desc_count = 0) {
+   spin_unlock_irqrestore(mp-lock, flags);
+   return released;
+   }
+
tx_index = mp-tx_used_desc_q;
desc = mp-p_tx_desc_area[tx_index];
cmd_sts = desc-cmd_sts;
@@ -332,13 +339,13 @@ int mv643xx_eth_free_tx_descs(struct net
if (skb)
mp-tx_skb[tx_index] = NULL;
 
-   spin_unlock_irqrestore(mp-lock, flags);
-
if (cmd_sts  ETH_ERROR_SUMMARY) {
printk(%s: Error in TX\n, dev-name);
mp-stats.tx_errors++;
}
 
+   spin_unlock_irqrestore(mp-lock, flags);
+
if (cmd_sts  ETH_TX_FIRST_DESC)
dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE);
else
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Re: kernel BUG in eth_alloc_tx_desc_index at drivers/net/mv643xx_eth.c:1069!

2007-01-22 Thread Dale Farnsworth
Jarek and Thibaut,

Thank you both very much for your work finding and fixing this bug.
Jarek, can you verify that the following patch fixes the problem you
were seeing?

-Dale

- Patch follows -

From: Dale Farnsworth [EMAIL PROTECTED]

mv643xx_eth: Fix race condition in mv643xx_eth_free_tx_descs

The bug was found and isolated by Thibaut VARENE [EMAIL PROTECTED]
and Jarek Poplawski [EMAIL PROTECTED].  This patch is a modification of their
fixes.  We acquire and release the lock for each descriptor that is freed
to minimize the time the lock is held.

---

 drivers/net/mv643xx_eth.c |7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index c41ae42..0d32381 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -314,6 +314,13 @@ int mv643xx_eth_free_tx_descs(struct net
 
while (mp-tx_desc_count  0) {
spin_lock_irqsave(mp-lock, flags);
+
+   /* maybe tx_desc_count changed before the lock was acquired */
+   if (mp-tx_desc_count = 0) {
+   spin_unlock_irqrestore(mp-lock, flags);
+   return released;
+   }
+
tx_index = mp-tx_used_desc_q;
desc = mp-p_tx_desc_area[tx_index];
cmd_sts = desc-cmd_sts;
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: kernel BUG in eth_alloc_tx_desc_index at drivers/net/mv643xx_eth.c:1069!

2007-01-09 Thread Dale Farnsworth
On Tue, Jan 09, 2007 at 06:44:49PM +0100, Thibaut VARENE wrote:
 On 1/9/07, Jarek Poplawski [EMAIL PROTECTED] wrote:
 On Tue, Jan 09, 2007 at 11:27:59AM +0100, Thibaut VARENE wrote:
 ...
  I suspected both and changed both the disk and the ram for quality
  parts, that I tested afterwards. Both passed thorough tests.
 
  Finally, using the other NIC on the box (a VIA Rhine II, 100Mbps),
  works absolutely fine.
 
 If you are not tired, I'd suggest two more tests:
 
 I volunteered to help :)

Thank you Thibaut.  Please try the following patch:

From: Dale Farnsworth [EMAIL PROTECTED]

Reserve one unused descriptor in the TX ring
to facilitate testing for when the ring is full.

---

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

 drivers/net/mv643xx_eth.c |   10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 9997081..72f82ba 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -289,7 +289,7 @@ static void mv643xx_eth_tx_timeout_task(
eth_port_reset(mp-port_num);
eth_port_start(dev);
 
-   if (mp-tx_ring_size - mp-tx_desc_count = MAX_DESCS_PER_SKB)
+   if (mp-tx_ring_size - mp-tx_desc_count  MAX_DESCS_PER_SKB)
netif_wake_queue(dev);
 }
 
@@ -356,7 +356,7 @@ static void mv643xx_eth_free_completed_t
struct mv643xx_private *mp = netdev_priv(dev);
 
if (mv643xx_eth_free_tx_descs(dev, 0) 
-   mp-tx_ring_size - mp-tx_desc_count = MAX_DESCS_PER_SKB)
+   mp-tx_ring_size - mp-tx_desc_count  MAX_DESCS_PER_SKB)
netif_wake_queue(dev);
 }
 
@@ -536,7 +536,7 @@ static irqreturn_t mv643xx_eth_int_handl
   ETH_TX_QUEUES_ENABLED);
if (!netif_carrier_ok(dev)) {
netif_carrier_on(dev);
-   if (mp-tx_ring_size - mp-tx_desc_count =
+   if (mp-tx_ring_size - mp-tx_desc_count 
MAX_DESCS_PER_SKB)
netif_wake_queue(dev);
}
@@ -1194,7 +1194,7 @@ static int mv643xx_eth_start_xmit(struct
BUG_ON(netif_queue_stopped(dev));
BUG_ON(skb == NULL);
 
-   if (mp-tx_ring_size - mp-tx_desc_count  MAX_DESCS_PER_SKB) {
+   if (mp-tx_ring_size - mp-tx_desc_count = MAX_DESCS_PER_SKB) {
printk(KERN_ERR %s: transmit with queue full\n, dev-name);
netif_stop_queue(dev);
return 1;
@@ -1216,7 +1216,7 @@ static int mv643xx_eth_start_xmit(struct
stats-tx_packets++;
dev-trans_start = jiffies;
 
-   if (mp-tx_ring_size - mp-tx_desc_count  MAX_DESCS_PER_SKB)
+   if (mp-tx_ring_size - mp-tx_desc_count = MAX_DESCS_PER_SKB)
netif_stop_queue(dev);
 
spin_unlock_irqrestore(mp-lock, flags);
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] mv643xx add missing brackets

2006-11-30 Thread Dale Farnsworth
On Thu, Nov 30, 2006 at 10:35:37AM +0100, Mariusz Kozlowski wrote:
 Hello,
 
   This patch adds missing brackets.
 
 Signed-off-by: Mariusz Kozlowski [EMAIL PROTECTED]
 
  include/linux/mv643xx.h |4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)
 
 --- linux-2.6.19-rc6-mm2-a/include/linux/mv643xx.h2006-11-16 
 05:03:40.0 +0100
 +++ linux-2.6.19-rc6-mm2-b/include/linux/mv643xx.h2006-11-30 
 01:10:53.0 +0100
 @@ -724,7 +724,7 @@
  #define MV643XX_ETH_RX_FIFO_URGENT_THRESHOLD_REG(port) (0x2470 + 
 (port10))
  #define MV643XX_ETH_TX_FIFO_URGENT_THRESHOLD_REG(port) (0x2474 + 
 (port10))
  #define MV643XX_ETH_RX_MINIMAL_FRAME_SIZE_REG(port)(0x247c + 
 (port10))
 -#define MV643XX_ETH_RX_DISCARDED_FRAMES_COUNTER(port)  (0x2484 + 
 (port10)
 +#define MV643XX_ETH_RX_DISCARDED_FRAMES_COUNTER(port)  (0x2484 + 
 (port10))

Good.  Thanks.

  #define MV643XX_ETH_PORT_DEBUG_0_REG(port) (0x248c + 
 (port10))
  #define MV643XX_ETH_PORT_DEBUG_1_REG(port) (0x2490 + 
 (port10))
  #define MV643XX_ETH_PORT_INTERNAL_ADDR_ERROR_REG(port) (0x2494 + 
 (port10))
 @@ -1135,7 +1135,7 @@ struct mv64xxx_i2c_pdata {
  #define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_1   (119)
  #define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_2   (120)
  #define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_3   ((120) | (119))
 -#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_4   ((121)
 +#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_4   ((121))

Mariusz, please remove the extra parenthesis instead of adding
an extra one, like:
#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_4  (121)
and resubmit.

Thanks,
-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mv643xx_eth: fix unbalanced parentheses in macros

2006-11-30 Thread Dale Farnsworth
From: Mariusz Kozlowski [EMAIL PROTECTED]

Signed-off-by: Mariusz Kozlowski [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---
 include/linux/mv643xx.h |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- linux-2.6.19-rc6-mm2-a/include/linux/mv643xx.h  2006-11-16 
05:03:40.0 +0100
+++ linux-2.6.19-rc6-mm2-b/include/linux/mv643xx.h  2006-11-30 
11:30:14.0 +0100
@@ -724,7 +724,7 @@
 #define MV643XX_ETH_RX_FIFO_URGENT_THRESHOLD_REG(port) (0x2470 + 
(port10))
 #define MV643XX_ETH_TX_FIFO_URGENT_THRESHOLD_REG(port) (0x2474 + 
(port10))
 #define MV643XX_ETH_RX_MINIMAL_FRAME_SIZE_REG(port)(0x247c + 
(port10))
-#define MV643XX_ETH_RX_DISCARDED_FRAMES_COUNTER(port)  (0x2484 + 
(port10)
+#define MV643XX_ETH_RX_DISCARDED_FRAMES_COUNTER(port)  (0x2484 + 
(port10))
 #define MV643XX_ETH_PORT_DEBUG_0_REG(port) (0x248c + 
(port10))
 #define MV643XX_ETH_PORT_DEBUG_1_REG(port) (0x2490 + 
(port10))
 #define MV643XX_ETH_PORT_INTERNAL_ADDR_ERROR_REG(port) (0x2494 + 
(port10))
@@ -1135,7 +1135,7 @@ struct mv64xxx_i2c_pdata {
 #define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_1 (119)
 #define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_2 (120)
 #define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_3 ((120) | (119))
-#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_4 ((121)
+#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_4 (121)
 #define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_5 ((121) | (119))
 #define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_6 ((121) | (120))
 #define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_7 ((121) | (120) | (119))
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFT] mv643xxx_eth_start_xmit oops

2006-11-10 Thread Dale Farnsworth
In article [EMAIL PROTECTED] you write:
Ueimor [EMAIL PROTECTED] wrote:
 Stephen Hemminger [EMAIL PROTECTED] :
 [...]
  diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
 [...]
 
 It seems to propagate a leak from the initial codebase.

Can you provide more detail about the leak?

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mv643xx_eth: Fix ethtool stats

2006-10-03 Thread Dale Farnsworth
From: Maxime Bizon [EMAIL PROTECTED]

Some stats reported by ethtool -S on mv643xx_eth device are cleared
between each call.  This patch fixes it.

Signed-off-by: Maxime Bizon [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---

Thanks Maxime.

--- linux-2.6.18/drivers/net/mv643xx_eth.c.orig 2006-10-03 18:29:14.0 
+0200
+++ linux-2.6.18/drivers/net/mv643xx_eth.c  2006-10-03 18:29:42.0 
+0200
@@ -2156,7 +2156,7 @@
for (offset = ETH_MIB_BAD_OCTETS_RECEIVED;
offset = ETH_MIB_FRAMES_1024_TO_MAX_OCTETS;
offset += 4)
-   *(u32 *)((char *)p + offset) = read_mib(mp, offset);
+   *(u32 *)((char *)p + offset) += read_mib(mp, offset);
 
p-good_octets_sent += read_mib(mp, ETH_MIB_GOOD_OCTETS_SENT_LOW);
p-good_octets_sent +=
@@ -2165,7 +2165,7 @@
for (offset = ETH_MIB_GOOD_FRAMES_SENT;
offset = ETH_MIB_LATE_COLLISION;
offset += 4)
-   *(u32 *)((char *)p + offset) = read_mib(mp, offset);
+   *(u32 *)((char *)p + offset) += read_mib(mp, offset);
 }
 
 /*
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] mv643xx_eth: restrict to 32-bit PPC_MULTIPLATFORM

2006-09-20 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

No 64-bit PPC_MULTIPLATFORM platforms use the mv643xx_eth driver,
so build it only on PPC32.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]
Acked-by: Sven Luther [EMAIL PROTECTED]

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index a2bd811..2154ae2 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2262,7 +2262,7 @@ config UGETH_HAS_GIGA
 
 config MV643XX_ETH
tristate MV-643XX Ethernet support
-   depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || 
MOMENCO_OCELOT_3 || PPC_MULTIPLATFORM
+   depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || 
MOMENCO_OCELOT_3 || (PPC_MULTIPLATFORM  PPC32)
select MII
help
  This driver supports the gigabit Ethernet on the Marvell MV643XX
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] mv643xx_eth: Fix typo: RX_SKB_SIZE == ETH_RX_SKB_SIZE

2006-09-20 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

Bug was introduced in commit 71d28725548be203e8b8f6ad63b1f64fd7f02d4d.
How embarrassing.  It wasn't caught because dma_umap_single()
is defined away on arch/ppc and 32-bit arch/powerpc.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---

Arggh.  (And that's not pirate talk.)

This isn't urgent since dma_unmap_single() is defined away for ppc32
both in arch/ppc and arch/powerpc.  It was caught on ppc64 arch/powerpc,
but isn't needed by any ppc64 platforms.

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index eeab1df..59de3e7 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -385,7 +385,7 @@ static int mv643xx_eth_receive_queue(str
struct pkt_info pkt_info;
 
while (budget--  0  eth_port_receive(mp, pkt_info) == ETH_OK) {
-   dma_unmap_single(NULL, pkt_info.buf_ptr, RX_SKB_SIZE,
+   dma_unmap_single(NULL, pkt_info.buf_ptr, ETH_RX_SKB_SIZE,
DMA_FROM_DEVICE);
mp-rx_desc_count--;
received_packets++;
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


PATCH mv643xx_eth: Unmap DMA buffers in receive path

2006-09-13 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

Fix a missing call to dma_unmap_single() in the receive path.  Without
this call, errors have been observed on non-cache-coherent systems.

Signed-off-by Dale Farnsworth [EMAIL PROTECTED]

---

 ACK, but
 error: patch failed: drivers/net/mv643xx_eth.c:402
 error: drivers/net/mv643xx_eth.c: patch does not apply

Sorry.  Patch was against an old version.
This one's current.

-Dale

 drivers/net/mv643xx_eth.c |2 ++
  1 file changed, 2 insertions(+)


diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 760c61b..eeab1df 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -385,6 +385,8 @@ static int mv643xx_eth_receive_queue(str
struct pkt_info pkt_info;
 
while (budget--  0  eth_port_receive(mp, pkt_info) == ETH_OK) {
+   dma_unmap_single(NULL, pkt_info.buf_ptr, RX_SKB_SIZE,
+   DMA_FROM_DEVICE);
mp-rx_desc_count--;
received_packets++;
 
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


mv643xx_eth: Unmap DMA buffers in receive path

2006-09-12 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

Fix a missing call to dma_unmap_single() in the receive path.  Without
this call, errors have been observed on non-cache-coherent systems.

Signed-off-by Dale Farnsworth [EMAIL PROTECTED]

---

 drivers/net/mv643xx_eth.c |2 ++
 1 file changed, 2 insertions(+)

Index: linux-2.6.10/drivers/net/mv643xx_eth.c
===
--- linux-2.6.10.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6.10/drivers/net/mv643xx_eth.c
@@ -402,6 +402,8 @@ static int mv643xx_eth_receive_queue(str
 #else
while (eth_port_receive(mp, pkt_info) == ETH_OK) {
 #endif
+   dma_unmap_single(NULL, pkt_info.buf_ptr, RX_SKB_SIZE,
+   DMA_FROM_DEVICE);
mp-rx_desc_count--;
received_packets++;
 
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Bug report for MV643XX driver

2006-08-09 Thread Dale Farnsworth
On Wed, Aug 09, 2006 at 10:47:28AM -0400, Stuart Peloquin wrote:
 Kernel oops during heavy load downloads with the MV643XX driver on a PegII.  
 I've replicated the problem on 2.6.17_gentoo-4, vanilla 2.6.17.1, vanilla 
 2.6.18_rc3.  When downloading a large file from any fast mirror (I tested 
 getting around 2.0MB/s) the system crashes after a random amount of time.  
 Usually after 30seconds to a couple of minutes.
 
 I took pictures of the call trace, I'm sorry about the quality, they were 
 taken with a phone camera.  They can be viewed at 
 http://web.mit.edu/peloquin/marvell

Thanks for the report Stuart.  I'm investigating this now.  Would you
mind sending me the config file used to build the kernel?  Also, which
version of gcc are you using?

Thanks,
-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Bug report for MV643XX driver

2006-08-09 Thread Dale Farnsworth
On Wed, Aug 09, 2006 at 12:53:27PM -0400, Stuart Peloquin wrote:
 Hi Dale,
 
 Thank you for responding quickly.
 
 This is with gcc 4.1.1 and the config file has been added to the web  
 directory at http://web.mit.edu/peloquin/marvell/
 
 Please let me know if I can provide anything else.

Can you test with an earlier version of the toolchain?  Maybe gcc-3.3?

Just this week I rebuilt a kernel for one of my Debian x86 server boxes
with gcc-4.1, and the tulip driver died early on.  When I rebuilt with
gcc-3.3, all was well.  I haven't had time to look for the details yet.

I'm not saying that gcc-4.1 is buggy, but this will help us narrow it
down.

BTW, I'm up against a deadline on another project, so I won't be able
to devote a lot of time to this today.

Thanks,
-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] mv643xx_eth: Fix tx_timeout to only conditionally wake tx queue

2006-04-11 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

After resetting the hardware on a tx_timeout, call netif_wake_queue()
only if we have free tx descriptors.

Also, attempt to recover if mv643xx_eth_start_xmit() is called when
there are fewer free tx descriptors than expected.

The BUG_ON() call we are replacing was hit on a tx_timeout that
called netif_wake_queue(), indirectly via netif_device_attach(),
even though we did not have enough free tx descriptors.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---

 drivers/net/mv643xx_eth.c |   17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
@@ -281,10 +281,16 @@ static void mv643xx_eth_tx_timeout_task(
 {
struct mv643xx_private *mp = netdev_priv(dev);
 
-   netif_device_detach(dev);
+   if (!netif_running(dev))
+   return;
+
+   netif_stop_queue(dev);
+
eth_port_reset(mp-port_num);
eth_port_start(dev);
-   netif_device_attach(dev);
+
+   if (mp-tx_ring_size - mp-tx_desc_count = MAX_DESCS_PER_SKB)
+   netif_wake_queue(dev);
 }
 
 /**
@@ -1186,7 +1192,12 @@ static int mv643xx_eth_start_xmit(struct
 
BUG_ON(netif_queue_stopped(dev));
BUG_ON(skb == NULL);
-   BUG_ON(mp-tx_ring_size - mp-tx_desc_count  MAX_DESCS_PER_SKB);
+
+   if (mp-tx_ring_size - mp-tx_desc_count  MAX_DESCS_PER_SKB) {
+   printk(KERN_ERR %s: transmit with queue full\n, dev-name);
+   netif_stop_queue(dev);
+   return 1;
+   }
 
if (has_tiny_unaligned_frags(skb)) {
if ((skb_linearize(skb, GFP_ATOMIC) != 0)) {

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] mv643xx_eth: Always free completed tx descs on tx interrupt

2006-04-05 Thread Dale Farnsworth
From: Brent Cook [EMAIL PROTECTED]

Fix the tx interrupt handler to free completed tx descriptors even
when NAPI is enabled.  Otherwise, the tx queue would fill up resulting
in poor performance and NETDEV WATCHDOG: iface: transmit timed out
messages.

Signed-off-by: Brent Cook [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---

 drivers/net/mv643xx_eth.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: current/drivers/net/mv643xx_eth.c
===
--- current/drivers/net/mv643xx_eth.c   (revision 51)
+++ current/drivers/net/mv643xx_eth.c   (working copy)
@@ -552,9 +552,9 @@
 #else
if (eth_int_cause  ETH_INT_CAUSE_RX)
mv643xx_eth_receive_queue(dev, INT_MAX);
+#endif
if (eth_int_cause_ext  ETH_INT_CAUSE_TX)
mv643xx_eth_free_completed_tx_descs(dev);
-#endif
 
/*
 * If no real interrupt occured, exit.

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] mv643xx_eth: Fix tx_timeout to only conditionally wake tx queue

2006-04-05 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

After resetting the hardware on a tx_timeout, call netif_wake_queue()
only if we have free tx descriptors.

Also, attempt to recover if mv643xx_eth_start_xmit() is called when
there are fewer free tx descriptors than expected.

The BUG_ON() call we are replacing was hit on a tx_timeout that
called netif_wake_queue(), indirectly via netif_device_attach(),
even though we did not have enough free tx descriptors.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---

 drivers/net/mv643xx_eth.c |   17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
@@ -281,10 +281,16 @@ static void mv643xx_eth_tx_timeout_task(
 {
struct mv643xx_private *mp = netdev_priv(dev);
 
-   netif_device_detach(dev);
+   if (!netif_running(dev))
+   return;
+
+   netif_stop_queue(dev);
+
eth_port_reset(mp-port_num);
eth_port_start(dev);
-   netif_device_attach(dev);
+
+   if (mp-tx_ring_size - mp-tx_desc_count = MAX_DESCS_PER_SKB)
+   netif_wake_queue(dev);
 }
 
 /**
@@ -1186,7 +1192,12 @@ static int mv643xx_eth_start_xmit(struct
 
BUG_ON(netif_queue_stopped(dev));
BUG_ON(skb == NULL);
-   BUG_ON(mp-tx_ring_size - mp-tx_desc_count  MAX_DESCS_PER_SKB);
+
+   if (mp-tx_ring_size - mp-tx_desc_count  MAX_DESCS_PER_SKB) {
+   printk(KERN_ERR %s: transmit with queue full\n, dev-name);
+   netif_stop_queue(dev);
+   return 1;
+   }
 
if (has_tiny_unaligned_frags(skb)) {
if ((skb_linearize(skb, GFP_ATOMIC) != 0)) {
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch] mv643xx_eth: Cache align skb-data if CONFIG_NOT_COHERENT_CACHE

2006-03-21 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

When I/O is non-cache-coherent, we need to ensure that the I/O buffers
we use don't share cache lines with other data.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---

This patch fixes red zone error messages that appear when CONFIG_SLAB_DEBUG=y.

 drivers/net/mv643xx_eth.h |   18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.h
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.h
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.h
@@ -42,13 +42,23 @@
 #define MAX_DESCS_PER_SKB  1
 #endif
 
+/*
+ * The MV643XX HW requires 8-byte alignment.  However, when I/O
+ * is non-cache-coherent, we need to ensure that the I/O buffers
+ * we use don't share cache lines with other data.
+ */
+#if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_NOT_COHERENT_CACHE)
+#define ETH_DMA_ALIGN  L1_CACHE_BYTES
+#else
+#define ETH_DMA_ALIGN  8
+#endif
+
 #define ETH_VLAN_HLEN  4
 #define ETH_FCS_LEN4
-#define ETH_DMA_ALIGN  8   /* hw requires 8-byte alignment */
-#define ETH_HW_IP_ALIGN2   /* hw aligns IP header */
+#define ETH_HW_IP_ALIGN2   /* hw aligns IP header 
*/
 #define ETH_WRAPPER_LEN(ETH_HW_IP_ALIGN + ETH_HLEN + \
-   ETH_VLAN_HLEN + ETH_FCS_LEN)
-#define ETH_RX_SKB_SIZE((dev-mtu + ETH_WRAPPER_LEN + 7)  
~0x7)
+   ETH_VLAN_HLEN + ETH_FCS_LEN)
+#define ETH_RX_SKB_SIZE(dev-mtu + ETH_WRAPPER_LEN + 
ETH_DMA_ALIGN)
 
 #define ETH_RX_QUEUES_ENABLED  (1  0)/* use only Q0 for receive */
 #define ETH_TX_QUEUES_ENABLED  (1  0)/* use only Q0 for transmit */
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 00/10] mv643xx_eth: patches for post 2.6.16 -- 2005-03-03

2006-03-03 Thread Dale Farnsworth
Please queue the following patches for post 2.6.16 release.

  01 Remove duplicate includes of linux/in.h and linux/ip.h
  02 Fix misplaced parenthesis in mv643xx_eth_port_disable_rx
  03 Rename channels to queues
  04 Select CONFIG_MII on CONFIG_MV643XX_ETH
  05 Refactor tx command queuing code
  06 Refactor/clean up tx queue handling
  07 Move #defines of constants to mv643xx_eth.h
  08 Clean up interrupt handling
  09 Remove non-working feature: task level rx queue refill
  10 Remove BIT0-BIT31 #defines

Thanks,
Dale Farnsworth
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 09/10] mv643xx_eth: Remove non-working feature: task level rx queue refill

2006-03-03 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

The task level rx queue refill feature hasn't ever worked
(at least in 2.6) and is of dubious value.  Remove it.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---

 drivers/net/mv643xx_eth.c |   59 +++-
 drivers/net/mv643xx_eth.h |8 
 2 files changed, 12 insertions(+), 55 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
@@ -132,25 +132,21 @@ static int mv643xx_eth_change_mtu(struct
 }
 
 /*
- * mv643xx_eth_rx_task
+ * mv643xx_eth_rx_refill_descs
  *
  * Fills / refills RX queue on a certain gigabit ethernet port
  *
  * Input : pointer to ethernet interface network device structure
  * Output :N/A
  */
-static void mv643xx_eth_rx_task(void *data)
+static void mv643xx_eth_rx_refill_descs(struct net_device *dev)
 {
-   struct net_device *dev = (struct net_device *)data;
struct mv643xx_private *mp = netdev_priv(dev);
struct pkt_info pkt_info;
struct sk_buff *skb;
int unaligned;
 
-   if (test_and_set_bit(0, mp-rx_task_busy))
-   panic(%s: Error in test_set_bit / clear_bit, dev-name);
-
-   while (mp-rx_desc_count  (mp-rx_ring_size - 5)) {
+   while (mp-rx_desc_count  mp-rx_ring_size) {
skb = dev_alloc_skb(ETH_RX_SKB_SIZE + ETH_DMA_ALIGN);
if (!skb)
break;
@@ -170,29 +166,19 @@ static void mv643xx_eth_rx_task(void *da
}
skb_reserve(skb, ETH_HW_IP_ALIGN);
}
-   clear_bit(0, mp-rx_task_busy);
/*
 * If RX ring is empty of SKB, set a timer to try allocating
-* again in a later time .
+* again at a later time.
 */
-   if ((mp-rx_desc_count == 0)  (mp-rx_timer_flag == 0)) {
+   if (mp-rx_desc_count == 0) {
printk(KERN_INFO %s: Rx ring is empty\n, dev-name);
-   /* After 100mSec */
-   mp-timeout.expires = jiffies + (HZ / 10);
+   mp-timeout.expires = jiffies + (HZ / 10);  /* 100 mSec */
add_timer(mp-timeout);
-   mp-rx_timer_flag = 1;
-   }
-#ifdef MV643XX_RX_QUEUE_FILL_ON_TASK
-   else {
-   /* Return interrupts */
-   mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(mp-port_num),
-   INT_UNMASK_ALL);
}
-#endif
 }
 
 /*
- * mv643xx_eth_rx_task_timer_wrapper
+ * mv643xx_eth_rx_refill_descs_timer_wrapper
  *
  * Timer routine to wake up RX queue filling task. This function is
  * used only in case the RX queue is empty, and all alloc_skb has
@@ -201,13 +187,9 @@ static void mv643xx_eth_rx_task(void *da
  * Input : pointer to ethernet interface network device structure
  * Output :N/A
  */
-static void mv643xx_eth_rx_task_timer_wrapper(unsigned long data)
+static inline void mv643xx_eth_rx_refill_descs_timer_wrapper(unsigned long 
data)
 {
-   struct net_device *dev = (struct net_device *)data;
-   struct mv643xx_private *mp = netdev_priv(dev);
-
-   mp-rx_timer_flag = 0;
-   mv643xx_eth_rx_task((void *)data);
+   mv643xx_eth_rx_refill_descs((struct net_device *)data);
 }
 
 /*
@@ -451,6 +433,7 @@ static int mv643xx_eth_receive_queue(str
}
dev-last_rx = jiffies;
}
+   mv643xx_eth_rx_refill_descs(dev);   /* Fill RX ring with skb's */
 
return received_packets;
 }
@@ -531,18 +514,6 @@ static irqreturn_t mv643xx_eth_int_handl
eth_int_cause_ext = mv_read(
MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num)) 
ETH_INT_UNMASK_ALL_EXT;
-#ifdef MV643XX_RX_QUEUE_FILL_ON_TASK
-   /* Mask all interrupts on ethernet port */
-   mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
-   INT_MASK_ALL);
-   /* wait for previous write to take effect */
-   mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
-
-   queue_task(mp-rx_task, tq_immediate);
-   mark_bh(IMMEDIATE_BH);
-#else
-   mp-rx_task.func(dev);
-#endif
mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num),
~eth_int_cause_ext);
}
@@ -810,15 +781,10 @@ static int mv643xx_eth_open(struct net_d
 
eth_port_init(mp);
 
-   INIT_WORK(mp-rx_task, (void (*)(void *))mv643xx_eth_rx_task, dev);
-
memset(mp-timeout, 0, sizeof(struct timer_list));
-   mp-timeout.function = mv643xx_eth_rx_task_timer_wrapper;
+   mp-timeout.function = mv643xx_eth_rx_refill_descs_timer_wrapper;
mp-timeout.data = (unsigned long)dev

[Patch 01/11] mv643xx_eth: Fix spinlock recursion bug

2006-01-27 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

This patch eliminates a spinlock recursion bug introduced recently.
Since eth_port_send() is always called with the lock held, we simply
remove the locking inside the function itself.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---
 drivers/net/mv643xx_eth.c |   13 -
 1 file changed, 13 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c   2006-01-18 
11:12:07.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c2006-01-18 
11:13:44.0 -0700
@@ -2617,7 +2617,6 @@
struct eth_tx_desc *current_descriptor;
struct eth_tx_desc *first_descriptor;
u32 command;
-   unsigned long flags;
 
/* Do not process Tx ring in case of Tx ring resource error */
if (mp-tx_resource_err)
@@ -2634,8 +2633,6 @@
return ETH_ERROR;
}
 
-   spin_lock_irqsave(mp-lock, flags);
-
mp-tx_ring_skbs++;
BUG_ON(mp-tx_ring_skbs  mp-tx_ring_size);
 
@@ -2685,15 +2682,11 @@
mp-tx_resource_err = 1;
mp-tx_curr_desc_q = tx_first_desc;
 
-   spin_unlock_irqrestore(mp-lock, flags);
-
return ETH_QUEUE_LAST_RESOURCE;
}
 
mp-tx_curr_desc_q = tx_next_desc;
 
-   spin_unlock_irqrestore(mp-lock, flags);
-
return ETH_OK;
 }
 #else
@@ -2704,14 +2697,11 @@
int tx_desc_used;
struct eth_tx_desc *current_descriptor;
unsigned int command_status;
-   unsigned long flags;
 
/* Do not process Tx ring in case of Tx ring resource error */
if (mp-tx_resource_err)
return ETH_QUEUE_FULL;
 
-   spin_lock_irqsave(mp-lock, flags);
-
mp-tx_ring_skbs++;
BUG_ON(mp-tx_ring_skbs  mp-tx_ring_size);
 
@@ -2742,12 +2732,9 @@
/* Check for ring index overlap in the Tx desc ring */
if (tx_desc_curr == tx_desc_used) {
mp-tx_resource_err = 1;
-
-   spin_unlock_irqrestore(mp-lock, flags);
return ETH_QUEUE_LAST_RESOURCE;
}
 
-   spin_unlock_irqrestore(mp-lock, flags);
return ETH_OK;
 }
 #endif
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 00/11] mv643xx_eth: patch series of 2005-01-27

2006-01-27 Thread Dale Farnsworth
I'll followup to this posting with the latest mv643xx_eth patches:

01 Fix spinlock recursion bug   bug fix
02 Update dev-last_rx on packet receivebug fix
03 whitespace cleanup   cleanup
04 fix for building as a module bug fix
05 Remove needless mp-port_mac_addrcleanup
06 Merge unicast and multicast address filtering code   cleanup
07 Rename mp-tx_ring_skbs to mp-tx_desc_count cleanup
08 Make port queue enable/disable code consistent   cleanup
09 mv643xx: use MII library for PHY management  feature
10 mv643xx: use MII library for ethtool functions   feature
11 Clean up platform_data configuration cleanup

Please apply.

Thanks,
Dale Farnsworth
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 05/11] mv643xx_eth: Remove needless mp-port_mac_addr

2006-01-27 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

mp-port_mac_addr is just a redundant copy of dev-dev_addr, so remove it.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---
 drivers/net/mv643xx_eth.c |   18 +++---
 drivers/net/mv643xx_eth.h |3 +--
 2 files changed, 8 insertions(+), 13 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
@@ -243,8 +243,7 @@ static void mv643xx_eth_update_mac_addre
unsigned int port_num = mp-port_num;
 
eth_port_init_mac_tables(port_num);
-   memcpy(mp-port_mac_addr, dev-dev_addr, 6);
-   eth_port_uc_addr_set(port_num, mp-port_mac_addr);
+   eth_port_uc_addr_set(port_num, dev-dev_addr);
 }
 
 /*
@@ -320,7 +319,7 @@ static void mv643xx_eth_tx_timeout_task(
 
netif_device_detach(dev);
eth_port_reset(mp-port_num);
-   eth_port_start(mp);
+   eth_port_start(dev);
netif_device_attach(dev);
 }
 
@@ -750,9 +749,6 @@ static int mv643xx_eth_open(struct net_d
/* Stop RX Queues */
mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0xff00);
 
-   /* Set the MAC Address */
-   memcpy(mp-port_mac_addr, dev-dev_addr, 6);
-
eth_port_init(mp);
 
INIT_WORK(mp-rx_task, (void (*)(void *))mv643xx_eth_rx_task, dev);
@@ -838,7 +834,7 @@ static int mv643xx_eth_open(struct net_d
 
mv643xx_eth_rx_task(dev);   /* Fill RX ring with skb's */
 
-   eth_port_start(mp);
+   eth_port_start(dev);
 
/* Interrupt Coalescing */
 
@@ -1706,7 +1702,6 @@ MODULE_DESCRIPTION(Ethernet driver for 
  * Prior to calling the initialization routine eth_port_init() the user
  * must set the following fields under mv643xx_private struct:
  * port_numUser Ethernet port number.
- * port_mac_addr[6]User defined port MAC address.
  * port_config User port configuration value.
  * port_config_extend  User port config extend value.
  * port_sdma_configUser port SDMA config value.
@@ -1796,7 +1791,7 @@ static void eth_port_init(struct mv643xx
  * and ether_init_rx_desc_ring for Rx queues).
  *
  * INPUT:
- * struct mv643xx_private *mp  Ethernet port control struct
+ * dev - a pointer to the required interface
  *
  * OUTPUT:
  * Ethernet port is ready to receive and transmit.
@@ -1804,8 +1799,9 @@ static void eth_port_init(struct mv643xx
  * RETURN:
  * None.
  */
-static void eth_port_start(struct mv643xx_private *mp)
+static void eth_port_start(struct net_device *dev)
 {
+   struct mv643xx_private *mp = netdev_priv(dev);
unsigned int port_num = mp-port_num;
int tx_curr_desc, rx_curr_desc;
 
@@ -1820,7 +1816,7 @@ static void eth_port_start(struct mv643x
(u32)((struct eth_rx_desc *)mp-rx_desc_dma + rx_curr_desc));
 
/* Add the assigned Ethernet address to the port's address table */
-   eth_port_uc_addr_set(port_num, mp-port_mac_addr);
+   eth_port_uc_addr_set(port_num, dev-dev_addr);
 
/* Assign port configuration and command. */
mv_write(MV643XX_ETH_PORT_CONFIG_REG(port_num), mp-port_config);
Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.h
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.h
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.h
@@ -324,7 +324,6 @@ struct mv643xx_mib_counters {
 
 struct mv643xx_private {
int port_num;   /* User Ethernet port number*/
-   u8 port_mac_addr[6];/* User defined port MAC address.*/
u32 port_config;/* User port configuration value*/
u32 port_config_extend; /* User port config extend value*/
u32 port_sdma_config;   /* User port SDMA config value  */
@@ -405,7 +404,7 @@ struct mv643xx_private {
 /* Port operation control routines */
 static void eth_port_init(struct mv643xx_private *mp);
 static void eth_port_reset(unsigned int eth_port_num);
-static void eth_port_start(struct mv643xx_private *mp);
+static void eth_port_start(struct net_device *dev);
 
 /* Port MAC address routines */
 static void eth_port_uc_addr_set(unsigned int eth_port_num,

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 04/11] mv643xx_eth: Fix for building as a module

2006-01-27 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

Enable mv643xx_eth driver to work when built as a module on
mv64x60-based embedded systems.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---
 arch/ppc/syslib/mv64x60.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Index: linux-2.6-mv643xx_enet/arch/ppc/syslib/mv64x60.c
===
--- linux-2.6-mv643xx_enet.orig/arch/ppc/syslib/mv64x60.c   2005-12-27 
16:06:41.0 -0700
+++ linux-2.6-mv643xx_enet/arch/ppc/syslib/mv64x60.c2006-01-17 
11:45:08.0 -0700
@@ -313,7 +313,7 @@
 };
 #endif
 
-#ifdef CONFIG_MV643XX_ETH
+#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
 static struct resource mv64x60_eth_shared_resources[] = {
[0] = {
.name   = ethernet shared base,
@@ -456,7 +456,7 @@
mpsc0_device,
mpsc1_device,
 #endif
-#ifdef CONFIG_MV643XX_ETH
+#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
mv64x60_eth_shared_device,
 #endif
 #ifdef CONFIG_MV643XX_ETH_0

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 02/11] mv643xx_eth: Update dev-last_rx on packet receive

2006-01-27 Thread Dale Farnsworth
From: Paolo Galtieri [EMAIL PROTECTED]

Update dev-last_rx on packet receive

This fix corrects errors seen during configuration of the bonding driver.

Signed-off-by: Paolo Galtieri [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---
 drivers/net/mv643xx_eth.c |1 +
 1 file changed, 1 insertion(+)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
@@ -445,6 +445,7 @@ static int mv643xx_eth_receive_queue(str
netif_rx(skb);
 #endif
}
+   dev-last_rx = jiffies;
}
 
return received_packets;

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 06/11] mv643xx_eth: Merge unicast and multicast address filtering code

2006-01-27 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

Remove duplicated code by having unicast and multicast code use
a common filter table function: eth_port_set_filter_table_entry().

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---
 drivers/net/mv643xx_eth.c |   84 +++-
 drivers/net/mv643xx_eth.h |4 -
 2 files changed, 9 insertions(+), 79 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c   2006-01-17 
15:42:36.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c2006-01-17 
15:44:50.0 -0700
@@ -1735,8 +1735,7 @@
 static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr);
 
 /* Ethernet Port routines */
-static int eth_port_uc_addr(unsigned int eth_port_num, unsigned char uc_nibble,
-   int option);
+static void eth_port_set_filter_table_entry(int table, unsigned char entry);
 
 /*
  * eth_port_init - Initialize the Ethernet port driver
@@ -1864,8 +1863,9 @@
  * char *  p_addr  Address to be set
  *
  * OUTPUT:
- * Set MAC address low and high registers. also calls eth_port_uc_addr()
- * To set the unicast table with the proper information.
+ * Set MAC address low and high registers. also calls
+ * eth_port_set_filter_table_entry() to set the unicast
+ * table with the proper information.
  *
  * RETURN:
  * N/A.
@@ -1876,6 +1876,7 @@
 {
unsigned int mac_h;
unsigned int mac_l;
+   int table;
 
mac_l = (p_addr[4]  8) | (p_addr[5]);
mac_h = (p_addr[0]  24) | (p_addr[1]  16) | (p_addr[2]  8) |
@@ -1885,9 +1886,8 @@
mv_write(MV643XX_ETH_MAC_ADDR_HIGH(eth_port_num), mac_h);
 
/* Accept frames of this address */
-   eth_port_uc_addr(eth_port_num, p_addr[5], ACCEPT_MAC_ADDR);
-
-   return;
+   table = MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE(eth_port_num);
+   eth_port_set_filter_table_entry(table, p_addr[5]  0x0f);
 }
 
 /*
@@ -1926,72 +1926,6 @@
 }
 
 /*
- * eth_port_uc_addr - This function Set the port unicast address table
- *
- * DESCRIPTION:
- * This function locates the proper entry in the Unicast table for the
- * specified MAC nibble and sets its properties according to function
- * parameters.
- *
- * INPUT:
- * unsigned inteth_port_numPort number.
- * unsigned char   uc_nibble   Unicast MAC Address last nibble.
- * int option  0 = Add, 1 = remove address.
- *
- * OUTPUT:
- * This function add/removes MAC addresses from the port unicast address
- * table.
- *
- * RETURN:
- * true is output succeeded.
- * false if option parameter is invalid.
- *
- */
-static int eth_port_uc_addr(unsigned int eth_port_num, unsigned char uc_nibble,
-   int option)
-{
-   unsigned int unicast_reg;
-   unsigned int tbl_offset;
-   unsigned int reg_offset;
-
-   /* Locate the Unicast table entry */
-   uc_nibble = (0xf  uc_nibble);
-   tbl_offset = (uc_nibble / 4) * 4;   /* Register offset from unicast 
table base */
-   reg_offset = uc_nibble % 4; /* Entry offset within the above 
register */
-
-   switch (option) {
-   case REJECT_MAC_ADDR:
-   /* Clear accepts frame bit at given unicast DA table entry */
-   unicast_reg = mv_read((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE
-   (eth_port_num) + tbl_offset));
-
-   unicast_reg = (0x0E  (8 * reg_offset));
-
-   mv_write((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE
-   (eth_port_num) + tbl_offset), unicast_reg);
-   break;
-
-   case ACCEPT_MAC_ADDR:
-   /* Set accepts frame bit at unicast DA filter table entry */
-   unicast_reg =
-   mv_read((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE
-   (eth_port_num) + tbl_offset));
-
-   unicast_reg |= (0x01  (8 * reg_offset));
-
-   mv_write((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE
-   (eth_port_num) + tbl_offset), unicast_reg);
-
-   break;
-
-   default:
-   return 0;
-   }
-
-   return 1;
-}
-
-/*
  * The entries in each table are indexed by a hash of a packet's MAC
  * address.  One bit in each entry determines whether the packet is
  * accepted.  There are 4 entries (each 8 bits wide) in each register
@@ -2203,8 +2137,8 @@
 
/* Clear DA filter unicast table (Ex_dFUT) */
for (table_index = 0; table_index = 0xC; table_index += 4)
-   mv_write((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE
-   (eth_port_num

[Patch 07/11] mv643xx_eth: Rename mp-tx_ring_skbs to mp-tx_desc_count

2006-01-27 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

tx_ring_skbs is actually a count of tx descriptors currently in use.
Since there may be multiple descriptors per skb, it is not the
same as the number of skbs in the ring.

Also change rx_ring_skbs to rx_desc_count to be consistent.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---
 drivers/net/mv643xx_eth.c |   51 ++--
 drivers/net/mv643xx_eth.h |8 ++---
 2 files changed, 30 insertions(+), 29 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
@@ -169,11 +169,11 @@ static void mv643xx_eth_rx_task(void *da
if (test_and_set_bit(0, mp-rx_task_busy))
panic(%s: Error in test_set_bit / clear_bit, dev-name);
 
-   while (mp-rx_ring_skbs  (mp-rx_ring_size - 5)) {
+   while (mp-rx_desc_count  (mp-rx_ring_size - 5)) {
skb = dev_alloc_skb(RX_SKB_SIZE + DMA_ALIGN);
if (!skb)
break;
-   mp-rx_ring_skbs++;
+   mp-rx_desc_count++;
unaligned = (u32)skb-data  (DMA_ALIGN - 1);
if (unaligned)
skb_reserve(skb, DMA_ALIGN - unaligned);
@@ -194,7 +194,7 @@ static void mv643xx_eth_rx_task(void *da
 * If RX ring is empty of SKB, set a timer to try allocating
 * again in a later time .
 */
-   if ((mp-rx_ring_skbs == 0)  (mp-rx_timer_flag == 0)) {
+   if ((mp-rx_desc_count == 0)  (mp-rx_timer_flag == 0)) {
printk(KERN_INFO %s: Rx ring is empty\n, dev-name);
/* After 100mSec */
mp-timeout.expires = jiffies + (HZ / 10);
@@ -394,7 +394,7 @@ static int mv643xx_eth_receive_queue(str
 #else
while (eth_port_receive(mp, pkt_info) == ETH_OK) {
 #endif
-   mp-rx_ring_skbs--;
+   mp-rx_desc_count--;
received_packets++;
 
/* Update statistics. Note byte count includes 4 byte CRC count 
*/
@@ -494,7 +494,7 @@ static irqreturn_t mv643xx_eth_int_handl
/* UDP change : We may need this */
if ((eth_int_cause_ext  0x) 
(mv643xx_eth_free_tx_queue(dev, eth_int_cause_ext) == 0) 
-   (mp-tx_ring_size  mp-tx_ring_skbs + MAX_DESCS_PER_SKB))
+   (mp-tx_ring_size  mp-tx_desc_count + MAX_DESCS_PER_SKB))
netif_wake_queue(dev);
 #ifdef MV643XX_NAPI
} else {
@@ -778,7 +778,7 @@ static int mv643xx_eth_open(struct net_d
}
 
/* Allocate TX ring */
-   mp-tx_ring_skbs = 0;
+   mp-tx_desc_count = 0;
size = mp-tx_ring_size * sizeof(struct eth_tx_desc);
mp-tx_desc_area_size = size;
 
@@ -803,7 +803,7 @@ static int mv643xx_eth_open(struct net_d
ether_init_tx_desc_ring(mp);
 
/* Allocate RX ring */
-   mp-rx_ring_skbs = 0;
+   mp-rx_desc_count = 0;
size = mp-rx_ring_size * sizeof(struct eth_rx_desc);
mp-rx_desc_area_size = size;
 
@@ -880,17 +880,17 @@ static void mv643xx_eth_free_tx_rings(st
mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), 0xff00);
 
/* Free outstanding skb's on TX rings */
-   for (curr = 0; mp-tx_ring_skbs  curr  mp-tx_ring_size; curr++) {
+   for (curr = 0; mp-tx_desc_count  curr  mp-tx_ring_size; curr++) {
skb = mp-tx_skb[curr];
if (skb) {
-   mp-tx_ring_skbs -= skb_shinfo(skb)-nr_frags;
+   mp-tx_desc_count -= skb_shinfo(skb)-nr_frags;
dev_kfree_skb(skb);
-   mp-tx_ring_skbs--;
+   mp-tx_desc_count--;
}
}
-   if (mp-tx_ring_skbs)
+   if (mp-tx_desc_count)
printk(%s: Error on Tx descriptor free - could not free %d
-descriptors\n, dev-name, mp-tx_ring_skbs);
+descriptors\n, dev-name, mp-tx_desc_count);
 
/* Free TX ring */
if (mp-tx_sram_size)
@@ -910,18 +910,18 @@ static void mv643xx_eth_free_rx_rings(st
mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0xff00);
 
/* Free preallocated skb's on RX rings */
-   for (curr = 0; mp-rx_ring_skbs  curr  mp-rx_ring_size; curr++) {
+   for (curr = 0; mp-rx_desc_count  curr  mp-rx_ring_size; curr++) {
if (mp-rx_skb[curr]) {
dev_kfree_skb(mp-rx_skb[curr]);
-   mp-rx_ring_skbs--;
+   mp-rx_desc_count--;
}
}
 
-   if (mp-rx_ring_skbs)
+   if (mp-rx_desc_count)
printk(KERN_ERR
%s: Error in freeing Rx Ring. %d skb's still
 stuck

[Patch 08/11] mv643xx_eth: Make port queue enable/disable code consistent

2006-01-27 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

Add and use the following functions:
mv643xx_eth_port_enable_tx()
mv643xx_eth_port_enable_rx()
mv643xx_eth_port_disable_tx()
mv643xx_eth_port_disable_rx()

so that ports are enabled/disabled consistently.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---
 drivers/net/mv643xx_eth.c |  133 +---
 1 file changed, 79 insertions(+), 54 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
@@ -83,6 +83,12 @@ static int eth_port_link_is_up(unsigned 
 static void eth_port_uc_addr_get(struct net_device *dev,
unsigned char *MacAddr);
 static void eth_port_set_multicast_list(struct net_device *);
+static void mv643xx_eth_port_enable_tx(unsigned int port_num,
+   unsigned int channels);
+static void mv643xx_eth_port_enable_rx(unsigned int port_num,
+   unsigned int channels);
+static unsigned int mv643xx_eth_port_disable_tx(unsigned int port_num);
+static unsigned int mv643xx_eth_port_disable_rx(unsigned int port_num);
 static int mv643xx_eth_open(struct net_device *);
 static int mv643xx_eth_stop(struct net_device *);
 static int mv643xx_eth_change_mtu(struct net_device *, int);
@@ -535,8 +541,7 @@ static irqreturn_t mv643xx_eth_int_handl
netif_carrier_on(dev);
netif_wake_queue(dev);
/* Start TX queue */
-   mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG
-   (port_num), 1);
+   mv643xx_eth_port_enable_tx(port_num, 
mp-port_tx_queue_command);
} else {
netif_carrier_off(dev);
netif_stop_queue(dev);
@@ -668,8 +673,8 @@ static void ether_init_rx_desc_ring(stru
 
mp-rx_desc_area_size = rx_desc_num * sizeof(struct eth_rx_desc);
 
-   /* Add the queue to the list of RX queues of this port */
-   mp-port_rx_queue_command |= 1;
+   /* Enable queue 0 for this port */
+   mp-port_rx_queue_command = 1;
 }
 
 /*
@@ -715,8 +720,8 @@ static void ether_init_tx_desc_ring(stru
 
mp-tx_desc_area_size = tx_desc_num * sizeof(struct eth_tx_desc);
 
-   /* Add the queue to the list of Tx queues of this port */
-   mp-port_tx_queue_command |= 1;
+   /* Enable queue 0 for this port */
+   mp-port_tx_queue_command = 1;
 }
 
 /*
@@ -747,9 +752,6 @@ static int mv643xx_eth_open(struct net_d
return -EAGAIN;
}
 
-   /* Stop RX Queues */
-   mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0xff00);
-
eth_port_init(mp);
 
INIT_WORK(mp-rx_task, (void (*)(void *))mv643xx_eth_rx_task, dev);
@@ -877,7 +879,7 @@ static void mv643xx_eth_free_tx_rings(st
struct sk_buff *skb;
 
/* Stop Tx Queues */
-   mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), 0xff00);
+   mv643xx_eth_port_disable_tx(port_num);
 
/* Free outstanding skb's on TX rings */
for (curr = 0; mp-tx_desc_count  curr  mp-tx_ring_size; curr++) {
@@ -907,7 +909,7 @@ static void mv643xx_eth_free_rx_rings(st
int curr;
 
/* Stop RX Queues */
-   mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0xff00);
+   mv643xx_eth_port_disable_rx(port_num);
 
/* Free preallocated skb's on RX rings */
for (curr = 0; mp-rx_desc_count  curr  mp-rx_ring_size; curr++) {
@@ -1719,13 +1721,6 @@ MODULE_DESCRIPTION(Ethernet driver for 
  * return_info Tx/Rx user resource return information.
  */
 
-/* defines */
-/* SDMA command macros */
-#define ETH_ENABLE_TX_QUEUE(eth_port) \
-   mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port), 1)
-
-/* locals */
-
 /* PHY routines */
 static int ethernet_phy_get(unsigned int eth_port_num);
 static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr);
@@ -1759,9 +1754,6 @@ static void eth_port_set_filter_table_en
  */
 static void eth_port_init(struct mv643xx_private *mp)
 {
-   mp-port_rx_queue_command = 0;
-   mp-port_tx_queue_command = 0;
-
mp-rx_resource_err = 0;
mp-tx_resource_err = 0;
 
@@ -1842,8 +1834,7 @@ static void eth_port_start(struct net_de
mp-port_sdma_config);
 
/* Enable port Rx. */
-   mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num),
-   mp-port_rx_queue_command);
+   mv643xx_eth_port_enable_rx(port_num, mp-port_rx_queue_command);
 
/* Disable port bandwidth limits by clearing MTU register

[Patch 09/11] mv643xx_eth: use MII library for PHY management

2006-01-27 Thread Dale Farnsworth
From: James Chapman [EMAIL PROTECTED]

Modify link up/down handling to use the functions from the MII
library.  Note that I track link state using the MII PHY registers
rather than the mv643xx chip's link state registers because I think
it's cleaner to use the MII library code rather than writing local
driver support code. It is also useful to make the actual MII
registers available to the user with maskable kernel printk messages
so the MII registers are being read anyway

Signed-off-by: James Chapman [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---
 drivers/net/mv643xx_eth.c |   64 +++-
 drivers/net/mv643xx_eth.h |2 +
 2 files changed, 43 insertions(+), 23 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.h
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.h
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.h
@@ -5,6 +5,7 @@
 #include linux/kernel.h
 #include linux/spinlock.h
 #include linux/workqueue.h
+#include linux/mii.h
 
 #include linux/mv643xx.h
 
@@ -393,6 +394,7 @@ struct mv643xx_private {
 
u32 rx_int_coal;
u32 tx_int_coal;
+   struct mii_if_info mii;
 };
 
 /* ethernet.h API list */
Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
@@ -79,7 +79,6 @@
 #define PHY_WAIT_MICRO_SECONDS 10
 
 /* Static function declarations */
-static int eth_port_link_is_up(unsigned int eth_port_num);
 static void eth_port_uc_addr_get(struct net_device *dev,
unsigned char *MacAddr);
 static void eth_port_set_multicast_list(struct net_device *);
@@ -97,8 +96,11 @@ static void eth_port_init_mac_tables(uns
 #ifdef MV643XX_NAPI
 static int mv643xx_poll(struct net_device *dev, int *budget);
 #endif
+static int ethernet_phy_get(unsigned int eth_port_num);
 static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr);
 static int ethernet_phy_detect(unsigned int eth_port_num);
+static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location);
+static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int 
location, int val);
 static struct ethtool_ops mv643xx_ethtool_ops;
 
 static char mv643xx_driver_name[] = mv643xx_eth;
@@ -537,14 +539,17 @@ static irqreturn_t mv643xx_eth_int_handl
}
/* PHY status changed */
if (eth_int_cause_ext  (BIT16 | BIT20)) {
-   if (eth_port_link_is_up(port_num)) {
-   netif_carrier_on(dev);
-   netif_wake_queue(dev);
-   /* Start TX queue */
-   mv643xx_eth_port_enable_tx(port_num, 
mp-port_tx_queue_command);
-   } else {
-   netif_carrier_off(dev);
+   if (mii_link_ok(mp-mii)) {
+   if (!netif_carrier_ok(dev)) {
+   netif_carrier_on(dev);
+   netif_wake_queue(dev);
+   /* Start TX queue */
+   mv643xx_eth_port_enable_tx(port_num,
+   mp-port_tx_queue_command);
+   }
+   } else if (netif_carrier_ok(dev)) {
netif_stop_queue(dev);
+   netif_carrier_off(dev);
}
}
 
@@ -1437,6 +1442,14 @@ static int mv643xx_eth_probe(struct plat
}
}
 
+   /* Hook up MII support for ethtool */
+   mp-mii.dev = dev;
+   mp-mii.mdio_read = mv643xx_mdio_read;
+   mp-mii.mdio_write = mv643xx_mdio_write;
+   mp-mii.phy_id = ethernet_phy_get(port_num);
+   mp-mii.phy_id_mask = 0x3f;
+   mp-mii.reg_num_mask = 0x1f;
+
err = ethernet_phy_detect(port_num);
if (err) {
pr_debug(MV643xx ethernet port %d: 
@@ -1445,6 +1458,8 @@ static int mv643xx_eth_probe(struct plat
return err;
}
 
+   mp-mii.supports_gmii = mii_check_gmii_support(mp-mii);
+
err = register_netdev(dev);
if (err)
goto out;
@@ -2419,21 +2434,6 @@ static int eth_port_autoneg_supported(un
return phy_reg_data0  0x1000;
 }
 
-static int eth_port_link_is_up(unsigned int eth_port_num)
-{
-   unsigned int phy_reg_data1;
-
-   eth_port_read_smi_reg(eth_port_num, 1, phy_reg_data1);
-
-   if (eth_port_autoneg_supported(eth_port_num)) {
-   if (phy_reg_data1  0x20)   /* auto-neg complete */
-   return 1;
-   } else if (phy_reg_data1  0x4) /* link up */
-   return 1;
-
-   return 0;
-}
-
 /*
  * eth_port_read_smi_reg - Read PHY registers
  *
@@ -2539,6 +2539,24 @@ out:
 }
 
 /*
+ * Wrappers

[Patch 11/11] mv643xx_eth: Clean up platform_data configuration

2006-01-27 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

We shouldn't expose the hardware register contents in platform_data.
The only things we allow the user to configure are autoneg, speed, and
duplex.  Add specific platform_data fields for these values and remove
the registers configs.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---
 arch/ppc/platforms/hdpu.c |5 +-
 drivers/net/mv643xx_eth.c |   71 ++--
 drivers/net/mv643xx_eth.h |4 --
 include/linux/mv643xx.h   |   24 
 4 files changed, 31 insertions(+), 73 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
@@ -266,13 +266,14 @@ static void mv643xx_eth_update_mac_addre
 static void mv643xx_eth_set_rx_mode(struct net_device *dev)
 {
struct mv643xx_private *mp = netdev_priv(dev);
+   u32 config_reg;
 
+   config_reg = mv_read(MV643XX_ETH_PORT_CONFIG_REG(mp-port_num));
if (dev-flags  IFF_PROMISC)
-   mp-port_config |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
+   config_reg |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
else
-   mp-port_config = ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
-
-   mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp-port_num), mp-port_config);
+   config_reg = ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
+   mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp-port_num), config_reg);
 
eth_port_set_multicast_list(dev);
 }
@@ -1454,9 +1455,8 @@ static int mv643xx_eth_probe(struct plat
struct resource *res;
int err;
struct ethtool_cmd cmd;
-   u32 pscr;
-   int duplex;
-   int speed;
+   int duplex = DUPLEX_HALF;
+   int speed = 0;  /* default to auto-negotiation */
 
dev = alloc_etherdev(sizeof(struct mv643xx_private));
if (!dev)
@@ -1515,33 +1515,17 @@ static int mv643xx_eth_probe(struct plat
 
/* set default config values */
eth_port_uc_addr_get(dev, dev-dev_addr);
-   mp-port_config = MV643XX_ETH_PORT_CONFIG_DEFAULT_VALUE;
-   mp-port_config_extend = MV643XX_ETH_PORT_CONFIG_EXTEND_DEFAULT_VALUE;
-   mp-port_sdma_config = MV643XX_ETH_PORT_SDMA_CONFIG_DEFAULT_VALUE;
-   mp-port_serial_control = MV643XX_ETH_PORT_SERIAL_CONTROL_DEFAULT_VALUE;
mp-rx_ring_size = MV643XX_ETH_PORT_DEFAULT_RECEIVE_QUEUE_SIZE;
mp-tx_ring_size = MV643XX_ETH_PORT_DEFAULT_TRANSMIT_QUEUE_SIZE;
 
pd = pdev-dev.platform_data;
if (pd) {
-   if (pd-mac_addr != NULL)
+   if (pd-mac_addr)
memcpy(dev-dev_addr, pd-mac_addr, 6);
 
if (pd-phy_addr || pd-force_phy_addr)
ethernet_phy_set(port_num, pd-phy_addr);
 
-   if (pd-port_config || pd-force_port_config)
-   mp-port_config = pd-port_config;
-
-   if (pd-port_config_extend || pd-force_port_config_extend)
-   mp-port_config_extend = pd-port_config_extend;
-
-   if (pd-port_sdma_config || pd-force_port_sdma_config)
-   mp-port_sdma_config = pd-port_sdma_config;
-
-   if (pd-port_serial_control || pd-force_port_serial_control)
-   mp-port_serial_control = pd-port_serial_control;
-
if (pd-rx_queue_size)
mp-rx_ring_size = pd-rx_queue_size;
 
@@ -1557,6 +1541,9 @@ static int mv643xx_eth_probe(struct plat
mp-rx_sram_size = pd-rx_sram_size;
mp-rx_sram_addr = pd-rx_sram_addr;
}
+
+   duplex = pd-duplex;
+   speed = pd-speed;
}
 
/* Hook up MII support for ethtool */
@@ -1575,28 +1562,7 @@ static int mv643xx_eth_probe(struct plat
goto out;
}
 
-   pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
-   pscr = ~MV643XX_ETH_SERIAL_PORT_ENABLE;
-   mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
-   pscr = mp-port_serial_control;
-   mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
-
-   if (!(pscr  MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX) 
-   !(pscr  MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII))
-   speed = 0;
-   else if (pscr  MV643XX_ETH_PORT_STATUS_GMII_1000)
-   speed = SPEED_1000;
-   else if (pscr  MV643XX_ETH_PORT_STATUS_MII_100)
-   speed = SPEED_100;
-   else
-   speed = SPEED_10;
-
-   if (pscr  MV643XX_ETH_PORT_STATUS_FULL_DUPLEX)
-   duplex = DUPLEX_FULL;
-   else
-   duplex = DUPLEX_HALF;
-
-   ethernet_phy_reset(mp-port_num);
+   ethernet_phy_reset(port_num);
mp-mii.supports_gmii = mii_check_gmii_support(mp-mii

[Patch 10/11] mv643xx_eth: use MII library for ethtool functions

2006-01-27 Thread Dale Farnsworth
From: James Chapman [EMAIL PROTECTED]

Use the common ethtool support functions of the MII library.
Add generic MII ioctl handler.
Add PHY parameter speed/duplex/negotiation initialization and modification.

Signed-off-by: James Chapman [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

---
 drivers/net/mv643xx_eth.c |  353 +---
 include/linux/mv643xx.h   |3 
 2 files changed, 214 insertions(+), 142 deletions(-)

This patch is from James, but heavily modified by me.  -Dale

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
@@ -101,6 +101,7 @@ static void ethernet_phy_set(unsigned in
 static int ethernet_phy_detect(unsigned int eth_port_num);
 static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location);
 static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int 
location, int val);
+static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int 
cmd);
 static struct ethtool_ops mv643xx_ethtool_ops;
 
 static char mv643xx_driver_name[] = mv643xx_eth;
@@ -457,6 +458,56 @@ static int mv643xx_eth_receive_queue(str
return received_packets;
 }
 
+/* Set the mv643xx port configuration register for the speed/duplex mode. */
+static void mv643xx_eth_update_pscr(struct net_device *dev,
+   struct ethtool_cmd *ecmd)
+{
+   struct mv643xx_private *mp = netdev_priv(dev);
+   int port_num = mp-port_num;
+   u32 o_pscr, n_pscr;
+   unsigned int channels;
+
+   o_pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
+   n_pscr = o_pscr;
+
+   /* clear speed, duplex and rx buffer size fields */
+   n_pscr = ~(MV643XX_ETH_SET_MII_SPEED_TO_100  |
+  MV643XX_ETH_SET_GMII_SPEED_TO_1000 |
+  MV643XX_ETH_SET_FULL_DUPLEX_MODE   |
+  MV643XX_ETH_MAX_RX_PACKET_MASK);
+
+   if (ecmd-duplex == DUPLEX_FULL)
+   n_pscr |= MV643XX_ETH_SET_FULL_DUPLEX_MODE;
+
+   if (ecmd-speed == SPEED_1000)
+   n_pscr |= MV643XX_ETH_SET_GMII_SPEED_TO_1000 |
+ MV643XX_ETH_MAX_RX_PACKET_9700BYTE;
+   else {
+   if (ecmd-speed == SPEED_100)
+   n_pscr |= MV643XX_ETH_SET_MII_SPEED_TO_100;
+   n_pscr |= MV643XX_ETH_MAX_RX_PACKET_1522BYTE;
+   }
+
+   if (n_pscr != o_pscr) {
+   if ((o_pscr  MV643XX_ETH_SERIAL_PORT_ENABLE) == 0)
+   mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
+   n_pscr);
+   else {
+   channels = mv643xx_eth_port_disable_tx(port_num);
+
+   o_pscr = ~MV643XX_ETH_SERIAL_PORT_ENABLE;
+   mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
+   o_pscr);
+   mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
+   n_pscr);
+   mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
+   n_pscr);
+   if (channels)
+   mv643xx_eth_port_enable_tx(port_num, channels);
+   }
+   }
+}
+
 /*
  * mv643xx_eth_int_handler
  *
@@ -539,13 +590,19 @@ static irqreturn_t mv643xx_eth_int_handl
}
/* PHY status changed */
if (eth_int_cause_ext  (BIT16 | BIT20)) {
+   struct ethtool_cmd cmd;
+
if (mii_link_ok(mp-mii)) {
+   mii_ethtool_gset(mp-mii, cmd);
+   mv643xx_eth_update_pscr(dev, cmd);
if (!netif_carrier_ok(dev)) {
netif_carrier_on(dev);
-   netif_wake_queue(dev);
-   /* Start TX queue */
-   mv643xx_eth_port_enable_tx(port_num,
-   mp-port_tx_queue_command);
+   if (mp-tx_ring_size  mp-tx_desc_count +
+   MAX_DESCS_PER_SKB) {
+   netif_wake_queue(dev);
+   /* Start TX queue */
+   mv643xx_eth_port_enable_tx(port_num, 
mp-port_tx_queue_command);
+   }
}
} else if (netif_carrier_ok(dev)) {
netif_stop_queue(dev);
@@ -729,6 +786,34 @@ static void ether_init_tx_desc_ring(stru
mp-port_tx_queue_command = 1;
 }
 
+static int

Re: [Patch 00/11] mv643xx_eth: patch series of 2005-01-27

2006-01-27 Thread Dale Farnsworth
On Fri, Jan 27, 2006 at 10:32:31AM -0500, Jeff Garzik wrote:
 Dale Farnsworth wrote:
 I'll followup to this posting with the latest mv643xx_eth patches:
 
  01 Fix spinlock recursion bug   bug fix
  02 Update dev-last_rx on packet receivebug fix
  03 whitespace cleanup   cleanup
  04 fix for building as a module bug fix
  05 Remove needless mp-port_mac_addrcleanup
  06 Merge unicast and multicast address filtering code   cleanup
  07 Rename mp-tx_ring_skbs to mp-tx_desc_count cleanup
  08 Make port queue enable/disable code consistent   cleanup
  09 mv643xx: use MII library for PHY management  feature
  10 mv643xx: use MII library for ethtool functions   feature
  11 Clean up platform_data configuration cleanup
 
 So... 1-4 in 2.6.16-rc, and the rest for 2.6.17?

Yes, that sounds good.

Thanks,
-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Patch 7/7] mv643xx_eth: use MII library for ethtool functions

2006-01-24 Thread Dale Farnsworth
On Fri, Jan 20, 2006 at 05:06:09PM -0700, I wrote:
 Use the common ethtool support functions of the MII library.
 Add generic MII ioctl handler.
 Add PHY parameter speed/duplex/negotiation initialization and modification.

I've seen a couple of unexplained network failures with this patch (7/7),
so I would ask that it not be applied yet.  Since it is related, please
hold off on patch 6 of the series as well.

Patches 1-5 should go in now, IMHO.

Thanks,
-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 1/7] mv643xx_eth: Fix spinlock recursion bug

2006-01-20 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

This patch eliminates a spinlock recursion bug I introduced recently.
Since eth_port_send() is always called with the lock held, we simply
remove the locking inside the function itself.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

 drivers/net/mv643xx_eth.c |   13 -
 1 file changed, 13 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c   2006-01-18 
11:12:07.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c2006-01-18 
11:13:44.0 -0700
@@ -2617,7 +2617,6 @@
struct eth_tx_desc *current_descriptor;
struct eth_tx_desc *first_descriptor;
u32 command;
-   unsigned long flags;
 
/* Do not process Tx ring in case of Tx ring resource error */
if (mp-tx_resource_err)
@@ -2634,8 +2633,6 @@
return ETH_ERROR;
}
 
-   spin_lock_irqsave(mp-lock, flags);
-
mp-tx_ring_skbs++;
BUG_ON(mp-tx_ring_skbs  mp-tx_ring_size);
 
@@ -2685,15 +2682,11 @@
mp-tx_resource_err = 1;
mp-tx_curr_desc_q = tx_first_desc;
 
-   spin_unlock_irqrestore(mp-lock, flags);
-
return ETH_QUEUE_LAST_RESOURCE;
}
 
mp-tx_curr_desc_q = tx_next_desc;
 
-   spin_unlock_irqrestore(mp-lock, flags);
-
return ETH_OK;
 }
 #else
@@ -2704,14 +2697,11 @@
int tx_desc_used;
struct eth_tx_desc *current_descriptor;
unsigned int command_status;
-   unsigned long flags;
 
/* Do not process Tx ring in case of Tx ring resource error */
if (mp-tx_resource_err)
return ETH_QUEUE_FULL;
 
-   spin_lock_irqsave(mp-lock, flags);
-
mp-tx_ring_skbs++;
BUG_ON(mp-tx_ring_skbs  mp-tx_ring_size);
 
@@ -2742,12 +2732,9 @@
/* Check for ring index overlap in the Tx desc ring */
if (tx_desc_curr == tx_desc_used) {
mp-tx_resource_err = 1;
-
-   spin_unlock_irqrestore(mp-lock, flags);
return ETH_QUEUE_LAST_RESOURCE;
}
 
-   spin_unlock_irqrestore(mp-lock, flags);
return ETH_OK;
 }
 #endif
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Patch 2/7] mv643xx_eth: whitespace cleanup

2006-01-20 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

 drivers/net/mv643xx_eth.c |   92 ++
 1 file changed, 45 insertions(+), 47 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
@@ -461,7 +461,7 @@ static int mv643xx_eth_receive_queue(str
  */
 
 static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id,
-   struct pt_regs *regs)
+   struct pt_regs *regs)
 {
struct net_device *dev = (struct net_device *)dev_id;
struct mv643xx_private *mp = netdev_priv(dev);
@@ -1047,16 +1047,15 @@ static int mv643xx_poll(struct net_devic
 
 static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb)
 {
-unsigned int frag;
-skb_frag_t *fragp;
+   unsigned int frag;
+   skb_frag_t *fragp;
 
-for (frag = 0; frag  skb_shinfo(skb)-nr_frags; frag++) {
-fragp = skb_shinfo(skb)-frags[frag];
-if (fragp-size = 8  fragp-page_offset  0x7)
-return 1;
-
-}
-return 0;
+   for (frag = 0; frag  skb_shinfo(skb)-nr_frags; frag++) {
+   fragp = skb_shinfo(skb)-frags[frag];
+   if (fragp-size = 8  fragp-page_offset  0x7)
+   return 1;
+   }
+   return 0;
 }
 
 
@@ -2137,26 +2136,26 @@ static void eth_port_set_multicast_list(
 */
if ((dev-flags  IFF_PROMISC) || (dev-flags  IFF_ALLMULTI)) {
for (table_index = 0; table_index = 0xFC; table_index += 4) {
-/* Set all entries in DA filter special multicast
- * table (Ex_dFSMT)
- * Set for ETH_Q0 for now
- * Bits
- * 0 Accept=1, Drop=0
- * 3-1  Queue   ETH_Q0=0
- * 7-4  Reserved = 0;
- */
-
mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + 
table_index, 0x01010101);
-
-/* Set all entries in DA filter other multicast
- * table (Ex_dFOMT)
- * Set for ETH_Q0 for now
- * Bits
- * 0 Accept=1, Drop=0
- * 3-1  Queue   ETH_Q0=0
- * 7-4  Reserved = 0;
- */
-
mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + 
table_index, 0x01010101);
-   }
+   /* Set all entries in DA filter special multicast
+* table (Ex_dFSMT)
+* Set for ETH_Q0 for now
+* Bits
+* 0  Accept=1, Drop=0
+* 3-1  QueueETH_Q0=0
+* 7-4  Reserved = 0;
+*/
+   
mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + 
table_index, 0x01010101);
+
+   /* Set all entries in DA filter other multicast
+* table (Ex_dFOMT)
+* Set for ETH_Q0 for now
+* Bits
+* 0  Accept=1, Drop=0
+* 3-1  QueueETH_Q0=0
+* 7-4  Reserved = 0;
+*/
+   
mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + 
table_index, 0x01010101);
+   }
return;
}
 
@@ -2885,8 +2884,10 @@ static ETH_FUNC_RET_STATUS eth_port_rece
p_pkt_info-return_info = mp-rx_skb[rx_curr_desc];
p_pkt_info-l4i_chk = p_rx_desc-buf_size;
 
-   /* Clean the return info field to indicate that the packet has been */
-   /* moved to the upper layers*/
+   /*
+* Clean the return info field to indicate that the
+* packet has been moved to the upper layers
+*/
mp-rx_skb[rx_curr_desc] = NULL;
 
/* Update current index in data structure */
@@ -2967,7 +2968,7 @@ struct mv643xx_stats {
 };
 
 #define MV643XX_STAT(m) sizeof(((struct mv643xx_private *)0)-m), \
- offsetof(struct mv643xx_private, m)
+   offsetof(struct mv643xx_private, m)
 
 static const struct mv643xx_stats mv643xx_gstrings_stats[] = {
{ rx_packets, MV643XX_STAT(stats.rx_packets) },
@@ -3118,9 +3119,8 @@ mv643xx_get_settings(struct net_device *
return 0;
 }
 
-static void
-mv643xx_get_drvinfo(struct

[Patch 3/7] mv643xx_eth: fix for building as a module

2006-01-20 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

Enable mv643xx_eth driver to work when built as a module on
mv64x60-based embedded systems.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

 arch/ppc/syslib/mv64x60.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Index: linux-2.6-mv643xx_enet/arch/ppc/syslib/mv64x60.c
===
--- linux-2.6-mv643xx_enet.orig/arch/ppc/syslib/mv64x60.c   2005-12-27 
16:06:41.0 -0700
+++ linux-2.6-mv643xx_enet/arch/ppc/syslib/mv64x60.c2006-01-17 
11:45:08.0 -0700
@@ -313,7 +313,7 @@
 };
 #endif
 
-#ifdef CONFIG_MV643XX_ETH
+#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
 static struct resource mv64x60_eth_shared_resources[] = {
[0] = {
.name   = ethernet shared base,
@@ -456,7 +456,7 @@
mpsc0_device,
mpsc1_device,
 #endif
-#ifdef CONFIG_MV643XX_ETH
+#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
mv64x60_eth_shared_device,
 #endif
 #ifdef CONFIG_MV643XX_ETH_0

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 6/7] mv643xx_eth: use MII library for PHY management

2006-01-20 Thread Dale Farnsworth
From: James Chapman [EMAIL PROTECTED]

Modify link up/down handling to use the functions from the MII
library.  Note that I track link state using the MII PHY registers
rather than the mv643xx chip's link state registers because I think
it's cleaner to use the MII library code rather than writing local
driver support code. It is also useful to make the actual MII
registers available to the user with maskable kernel printk messages
so the MII registers are being read anyway

Signed-off-by: James Chapman [EMAIL PROTECTED]
Acked-by: Dale Farnsworth [EMAIL PROTECTED]

 drivers/net/mv643xx_eth.c |   65 +-
 drivers/net/mv643xx_eth.h |2 +
 2 files changed, 44 insertions(+), 23 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.h
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.h   2006-01-18 
19:11:05.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.h2006-01-19 
11:39:52.0 -0700
@@ -5,6 +5,7 @@
 #include linux/kernel.h
 #include linux/spinlock.h
 #include linux/workqueue.h
+#include linux/mii.h
 
 #include linux/mv643xx.h
 
@@ -394,6 +395,7 @@
 
u32 rx_int_coal;
u32 tx_int_coal;
+   struct mii_if_info mii;
 };
 
 /* ethernet.h API list */
Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c   2006-01-18 
19:11:05.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c2006-01-19 
11:39:52.0 -0700
@@ -79,7 +79,6 @@
 #define PHY_WAIT_MICRO_SECONDS 10
 
 /* Static function declarations */
-static int eth_port_link_is_up(unsigned int eth_port_num);
 static void eth_port_uc_addr_get(struct net_device *dev,
unsigned char *MacAddr);
 static void eth_port_set_multicast_list(struct net_device *);
@@ -91,8 +90,11 @@
 #ifdef MV643XX_NAPI
 static int mv643xx_poll(struct net_device *dev, int *budget);
 #endif
+static int ethernet_phy_get(unsigned int eth_port_num);
 static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr);
 static int ethernet_phy_detect(unsigned int eth_port_num);
+static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location);
+static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int 
location, int val);
 static struct ethtool_ops mv643xx_ethtool_ops;
 
 static char mv643xx_driver_name[] = mv643xx_eth;
@@ -531,16 +533,21 @@
}
/* PHY status changed */
if (eth_int_cause_ext  (BIT16 | BIT20)) {
-   if (eth_port_link_is_up(port_num)) {
-   netif_carrier_on(dev);
+   struct ethtool_cmd cmd;
+
+   /* mii library handles link maintenance tasks */
+
+   mii_ethtool_gset(mp-mii, cmd);
+
+   if(mii_link_ok(mp-mii)  !netif_carrier_ok(dev)) {
netif_wake_queue(dev);
/* Start TX queue */
-   mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG
-   (port_num), 1);
-   } else {
-   netif_carrier_off(dev);
+   
mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), 1);
+
+   } else if(!mii_link_ok(mp-mii)  netif_carrier_ok(dev))
netif_stop_queue(dev);
-   }
+
+   mii_check_link(mp-mii);
}
 
/*
@@ -1383,6 +1390,15 @@
 #endif
 #endif
 
+   /* Hook up MII support for ethtool */
+   mp-mii.dev = dev;
+   mp-mii.mdio_read = mv643xx_mdio_read;
+   mp-mii.mdio_write = mv643xx_mdio_write;
+   mp-mii.phy_id = ethernet_phy_get(mp-port_num);
+   mp-mii.phy_id_mask = 0x3f;
+   mp-mii.reg_num_mask = 0x1f;
+   mp-mii.supports_gmii = 1;
+
/* Configure the timeout task */
INIT_WORK(mp-tx_timeout_task,
(void (*)(void *))mv643xx_eth_tx_timeout_task, dev);
@@ -2394,21 +2410,6 @@
return phy_reg_data0  0x1000;
 }
 
-static int eth_port_link_is_up(unsigned int eth_port_num)
-{
-   unsigned int phy_reg_data1;
-
-   eth_port_read_smi_reg(eth_port_num, 1, phy_reg_data1);
-
-   if (eth_port_autoneg_supported(eth_port_num)) {
-   if (phy_reg_data1  0x20)   /* auto-neg complete */
-   return 1;
-   } else if (phy_reg_data1  0x4) /* link up */
-   return 1;
-
-   return 0;
-}
-
 /*
  * eth_port_read_smi_reg - Read PHY registers
  *
@@ -2514,6 +2515,24 @@
 }
 
 /*
+ * Wrappers for MII support library.
+ */
+static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location)
+{
+   int val;
+   struct mv643xx_private *mp = netdev_priv(dev);
+
+   eth_port_read_smi_reg(mp-port_num, location

[Patch 7/7] mv643xx_eth: use MII library for ethtool functions

2006-01-20 Thread Dale Farnsworth
From: James Chapman [EMAIL PROTECTED]

Use the common ethtool support functions of the MII library.
Add generic MII ioctl handler.
Add PHY parameter speed/duplex/negotiation initialization and modification.

Signed-off-by: James Chapman [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

 arch/ppc/platforms/hdpu.c |5 
 drivers/net/mv643xx_eth.c |  429 --
 drivers/net/mv643xx_eth.h |4 
 include/linux/mv643xx.h   |   40 +---
 4 files changed, 246 insertions(+), 232 deletions(-)

---

I heavily modified James' original patch.  All bugs are mine.
-Dale

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
@@ -82,6 +82,8 @@
 static void eth_port_uc_addr_get(struct net_device *dev,
unsigned char *MacAddr);
 static void eth_port_set_multicast_list(struct net_device *);
+static void mv643xx_eth_port_disable_tx(unsigned int port_num);
+static void mv643xx_eth_port_disable_rx(unsigned int port_num);
 static int mv643xx_eth_open(struct net_device *);
 static int mv643xx_eth_stop(struct net_device *);
 static int mv643xx_eth_change_mtu(struct net_device *, int);
@@ -95,6 +97,7 @@ static void ethernet_phy_set(unsigned in
 static int ethernet_phy_detect(unsigned int eth_port_num);
 static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location);
 static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int 
location, int val);
+static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int 
cmd);
 static struct ethtool_ops mv643xx_ethtool_ops;
 
 static char mv643xx_driver_name[] = mv643xx_eth;
@@ -259,13 +262,14 @@ static void mv643xx_eth_update_mac_addre
 static void mv643xx_eth_set_rx_mode(struct net_device *dev)
 {
struct mv643xx_private *mp = netdev_priv(dev);
+   u32 config_reg;
 
+   config_reg = mv_read(MV643XX_ETH_PORT_CONFIG_REG(mp-port_num));
if (dev-flags  IFF_PROMISC)
-   mp-port_config |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
+   config_reg |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
else
-   mp-port_config = ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
-
-   mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp-port_num), mp-port_config);
+   config_reg = ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
+   mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp-port_num), config_reg);
 
eth_port_set_multicast_list(dev);
 }
@@ -450,6 +454,56 @@ static int mv643xx_eth_receive_queue(str
return received_packets;
 }
 
+/* Set the mv643xx port configuration register for the speed/duplex mode. */
+static void mv643xx_eth_update_pscr(struct net_device *dev,
+   struct ethtool_cmd *ecmd)
+{
+   struct mv643xx_private *mp = netdev_priv(dev);
+   int port_num = mp-port_num;
+   u32 pscr;
+
+   mv643xx_eth_port_disable_tx(port_num);
+
+   pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
+
+   /* disable port */
+   pscr = ~MV643XX_ETH_SERIAL_PORT_ENABLE;
+   mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
+
+   /* clear speed and duplex bits and default to 1518 byte rx buffer */
+   pscr = ~(MV643XX_ETH_SET_MII_SPEED_TO_100   |
+ MV643XX_ETH_SET_GMII_SPEED_TO_1000 |
+ MV643XX_ETH_SET_FULL_DUPLEX_MODE   |
+ (7  17));
+
+   /* disable the chip's autonegotiation, we use the mii library */
+   pscr |= MV643XX_ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL |
+   MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII|
+   MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX;
+
+   if (ecmd-duplex == DUPLEX_FULL)
+   pscr |= MV643XX_ETH_SET_FULL_DUPLEX_MODE;
+
+   switch (ecmd-speed) {
+   case SPEED_1000:
+   pscr |= MV643XX_ETH_SET_GMII_SPEED_TO_1000;
+   pscr |= (5  17);  /* 9700 byte rx buffer */
+   break;
+   case SPEED_100:
+   pscr |= MV643XX_ETH_SET_MII_SPEED_TO_100;
+   /* NOBREAK */
+   case SPEED_10:
+   pscr |= (1  17);  /* 1522 byte rx buffer */
+   break;
+   }
+
+   mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
+
+   /* re-enable port */
+   mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
+   pscr | MV643XX_ETH_SERIAL_PORT_ENABLE);
+}
+
 /*
  * mv643xx_eth_int_handler
  *
@@ -537,13 +591,14 @@ static irqreturn_t mv643xx_eth_int_handl
/* mii library handles link maintenance tasks */
 
mii_ethtool_gset(mp-mii, cmd);
-
-   if(mii_link_ok(mp-mii)  !netif_carrier_ok(dev

Re: [Patch 09/13] mv643xx_eth: Hold spinlocks only where needed

2006-01-18 Thread Dale Farnsworth
On Wed, Jan 18, 2006 at 04:26:00PM +0100, Olaf Hering wrote:
  On Mon, Jan 16, Dale Farnsworth wrote:
 
  This driver has historically held a spin_lock during the entire open
  and stop functions and while receiving multiple packets.  This is
  unecessarily long and holds locks during calls that may sleep.
  This patch reduces the size of windows where locks are held.
 
 I havent checked if this patch is the culprit, but 2.6.16-rc1-git1 does
 lockup after modprobe -v mv643xx_eth , dhcpcd eth2.
 Have to find a serial console for the pegasos, all I get on console is
 
 BUG: spinlock recursion on CPU#0, dhcpcd/2844
  lock: dd96f148, .magic: dead4ead, .owner: dhcpcd/2844, .owner_cpu:0
 BUG: spinlock lockup on CPU#0, dhcpdcd/2844, dd96f148

Thanks.  That patch is indeed the culprit.

I'll send a patch to Olaf for testing in the next hour or so.

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Patch 09/13] mv643xx_eth: Hold spinlocks only where needed

2006-01-18 Thread Dale Farnsworth
On Wed, Jan 18, 2006 at 04:26:00PM +0100, Olaf Hering wrote:
 I havent checked if this patch is the culprit, but 2.6.16-rc1-git1 does
 lockup after modprobe -v mv643xx_eth , dhcpcd eth2.
 Have to find a serial console for the pegasos, all I get on console is
 
 BUG: spinlock recursion on CPU#0, dhcpcd/2844
  lock: dd96f148, .magic: dead4ead, .owner: dhcpcd/2844, .owner_cpu:0
 BUG: spinlock lockup on CPU#0, dhcpdcd/2844, dd96f148

Olaf, would you please try the patch below.  It works for me.

Thanks,
-Dale

From: Dale Farnsworth [EMAIL PROTECTED]

This patch eliminates a spinlock recursion bug I introduced recently.
Since eth_port_send() is always called with the lock held, we simply
remove the locking inside the function itself.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

 mv643xx_eth.c |   13 -
 1 file changed, 13 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c   2006-01-18 
11:12:07.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c2006-01-18 
11:13:44.0 -0700
@@ -2617,7 +2617,6 @@
struct eth_tx_desc *current_descriptor;
struct eth_tx_desc *first_descriptor;
u32 command;
-   unsigned long flags;
 
/* Do not process Tx ring in case of Tx ring resource error */
if (mp-tx_resource_err)
@@ -2634,8 +2633,6 @@
return ETH_ERROR;
}
 
-   spin_lock_irqsave(mp-lock, flags);
-
mp-tx_ring_skbs++;
BUG_ON(mp-tx_ring_skbs  mp-tx_ring_size);
 
@@ -2685,15 +2682,11 @@
mp-tx_resource_err = 1;
mp-tx_curr_desc_q = tx_first_desc;
 
-   spin_unlock_irqrestore(mp-lock, flags);
-
return ETH_QUEUE_LAST_RESOURCE;
}
 
mp-tx_curr_desc_q = tx_next_desc;
 
-   spin_unlock_irqrestore(mp-lock, flags);
-
return ETH_OK;
 }
 #else
@@ -2704,14 +2697,11 @@
int tx_desc_used;
struct eth_tx_desc *current_descriptor;
unsigned int command_status;
-   unsigned long flags;
 
/* Do not process Tx ring in case of Tx ring resource error */
if (mp-tx_resource_err)
return ETH_QUEUE_FULL;
 
-   spin_lock_irqsave(mp-lock, flags);
-
mp-tx_ring_skbs++;
BUG_ON(mp-tx_ring_skbs  mp-tx_ring_size);
 
@@ -2742,12 +2732,9 @@
/* Check for ring index overlap in the Tx desc ring */
if (tx_desc_curr == tx_desc_used) {
mp-tx_resource_err = 1;
-
-   spin_unlock_irqrestore(mp-lock, flags);
return ETH_QUEUE_LAST_RESOURCE;
}
 
-   spin_unlock_irqrestore(mp-lock, flags);
return ETH_OK;
 }
 #endif

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 00/13] mv643xx_eth: Bug Fixes

2006-01-16 Thread Dale Farnsworth

This patch series for the Marvell mv643xx ethernet controller
contains primarily bug fixes.

 1. Add Dale Farnsworth as a maintainer
 2. 2.6.16 needs ip.h and in.h
Bug fix, from Olaf Hering [EMAIL PROTECTED]
 3. Fix dma_map/dma_unmap relations
Bug fix, from Paolo Galtieri [EMAIL PROTECTED]
 4. Fix a NULL pointer dereference
Bug fix, from Paolo Galtieri [EMAIL PROTECTED]
 5. Add multicast support
Feature addition
 6. Receive buffers require 8 byte alignment
Bug fix, reported by David Woodhouse [EMAIL PROTECTED]
 7. Fix handling of small, unaligned fragments
Bug fix, from Paul Janzen [EMAIL PROTECTED]
 8. iounmap the correct SRAM buffer
Bug fix
 9. Hold spinlocks only where needed
Bug fix
10. Request HW checksum generation only for IPv4
Bug fix, from Wolfram Joost [EMAIL PROTECTED]
11. Fix transmit skb accounting
Bug fix
12. Merge open and stop helper functions
Bug fix
13. Remove needless mask of extended intr register
Bug fix
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 02/13] mv643xx_eth: 2.6.16 needs ip.h and in.h

2006-01-16 Thread Dale Farnsworth
From: Olaf Hering [EMAIL PROTECTED]

Signed-off-by: Olaf Hering [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

 mv643xx_eth.c |2 ++
 1 file changed, 2 insertions(+)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c   2006-01-16 
10:48:49.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c2006-01-16 
10:49:27.0 -0700
@@ -35,6 +35,8 @@
 #include linux/tcp.h
 #include linux/udp.h
 #include linux/etherdevice.h
+#include linux/in.h
+#include linux/ip.h
 
 #include linux/bitops.h
 #include linux/delay.h
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 03/13] mv643xx_eth: Fix dma_map/dma_unmap relations

2006-01-16 Thread Dale Farnsworth
From: Paolo Galtieri [EMAIL PROTECTED]

If you do a dma_map_single you must do dma_unmap_single and if you do
a dma_map_page you must do a dma_unmap_page.

Signed-off-by: Paolo Galtieri [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

 mv643xx_eth.c |   51 +--
 1 file changed, 21 insertions(+), 30 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c   2006-01-16 
10:49:27.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c2006-01-16 
10:49:29.0 -0700
@@ -353,27 +353,19 @@
stats-tx_errors++;
}
 
-   /*
-* If return_info is different than 0, release the skb.
-* The case where return_info is not 0 is only in case
-* when transmitted a scatter/gather packet, where only
-* last skb releases the whole chain.
-*/
-   if (pkt_info.return_info) {
-   if (skb_shinfo(pkt_info.return_info)-nr_frags)
-   dma_unmap_page(NULL, pkt_info.buf_ptr,
-   pkt_info.byte_cnt,
-   DMA_TO_DEVICE);
-   else
-   dma_unmap_single(NULL, pkt_info.buf_ptr,
-   pkt_info.byte_cnt,
-   DMA_TO_DEVICE);
+   if (pkt_info.cmd_sts  ETH_TX_FIRST_DESC)
+   dma_unmap_single(NULL, pkt_info.buf_ptr,
+   pkt_info.byte_cnt,
+   DMA_TO_DEVICE);
+   else
+   dma_unmap_page(NULL, pkt_info.buf_ptr,
+   pkt_info.byte_cnt,
+   DMA_TO_DEVICE);
 
+   if (pkt_info.return_info) {
dev_kfree_skb_irq(pkt_info.return_info);
released = 0;
-   } else
-   dma_unmap_page(NULL, pkt_info.buf_ptr,
-   pkt_info.byte_cnt, DMA_TO_DEVICE);
+   }
}
 
spin_unlock(mp-lock);
@@ -1024,20 +1016,17 @@
struct pkt_info pkt_info;
 
while (eth_tx_return_desc(mp, pkt_info) == ETH_OK) {
-   if (pkt_info.return_info) {
-   if (skb_shinfo(pkt_info.return_info)-nr_frags)
-   dma_unmap_page(NULL, pkt_info.buf_ptr,
-   pkt_info.byte_cnt,
-   DMA_TO_DEVICE);
-   else
-   dma_unmap_single(NULL, pkt_info.buf_ptr,
-   pkt_info.byte_cnt,
-   DMA_TO_DEVICE);
+   if (pkt_info.cmd_sts  ETH_TX_FIRST_DESC)
+   dma_unmap_single(NULL, pkt_info.buf_ptr,
+   pkt_info.byte_cnt,
+   DMA_TO_DEVICE);
+   else
+   dma_unmap_page(NULL, pkt_info.buf_ptr,
+   pkt_info.byte_cnt,
+   DMA_TO_DEVICE);
 
+   if (pkt_info.return_info)
dev_kfree_skb_irq(pkt_info.return_info);
-   } else
-   dma_unmap_page(NULL, pkt_info.buf_ptr,
-   pkt_info.byte_cnt, DMA_TO_DEVICE);
}
 
if (netif_queue_stopped(dev) 

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 05/13] mv643xx_eth: Add multicast support

2006-01-16 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

This code is adapted from code in a ppc-specific version of the driver.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

 mv643xx_eth.c |  201 --
 1 file changed, 197 insertions(+), 4 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c   2006-01-16 
10:49:29.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c2006-01-16 
10:49:30.0 -0700
@@ -80,6 +80,7 @@
 static int eth_port_link_is_up(unsigned int eth_port_num);
 static void eth_port_uc_addr_get(struct net_device *dev,
unsigned char *MacAddr);
+static void eth_port_set_multicast_list(struct net_device *);
 static int mv643xx_eth_real_open(struct net_device *);
 static int mv643xx_eth_real_stop(struct net_device *);
 static int mv643xx_eth_change_mtu(struct net_device *, int);
@@ -269,6 +270,8 @@
mp-port_config = ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
 
mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp-port_num), mp-port_config);
+
+   eth_port_set_multicast_list(dev);
 }
 
 /*
@@ -2045,6 +2048,196 @@
 }
 
 /*
+ * The entries in each table are indexed by a hash of a packet's MAC
+ * address.  One bit in each entry determines whether the packet is
+ * accepted.  There are 4 entries (each 8 bits wide) in each register
+ * of the table.  The bits in each entry are defined as follows:
+ * 0   Accept=1, Drop=0
+ * 3-1 Queue   (ETH_Q0=0)
+ * 7-4 Reserved = 0;
+ */
+static void eth_port_set_filter_table_entry(int table, unsigned char entry)
+{
+   unsigned int table_reg;
+   unsigned int tbl_offset;
+   unsigned int reg_offset;
+
+   tbl_offset = (entry / 4) * 4;   /* Register offset of DA table entry */
+   reg_offset = entry % 4; /* Entry offset within the register */
+
+   /* Set accepts frame bit at specified table entry */
+   table_reg = mv_read(table + tbl_offset);
+   table_reg |= 0x01  (8 * reg_offset);
+   mv_write(table + tbl_offset, table_reg);
+}
+
+/*
+ * eth_port_mc_addr - Multicast address settings.
+ *
+ * The MV device supports multicast using two tables:
+ * 1) Special Multicast Table for MAC addresses of the form
+ *0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_FF).
+ *The MAC DA[7:0] bits are used as a pointer to the Special Multicast
+ *Table entries in the DA-Filter table.
+ * 2) Other Multicast Table for multicast of another type. A CRC-8bit
+ *is used as an index to the Other Multicast Table entries in the
+ *DA-Filter table.  This function calculates the CRC-8bit value.
+ * In either case, eth_port_set_filter_table_entry() is then called
+ * to set to set the actual table entry.
+ */
+static void eth_port_mc_addr(unsigned int eth_port_num, unsigned char *p_addr)
+{
+   unsigned int mac_h;
+   unsigned int mac_l;
+   unsigned char crc_result = 0;
+   int table;
+   int mac_array[48];
+   int crc[8];
+   int i;
+
+   if ((p_addr[0] == 0x01)  (p_addr[1] == 0x00) 
+   (p_addr[2] == 0x5E)  (p_addr[3] == 0x00)  (p_addr[4] == 0x00)) {
+   table = MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
+   (eth_port_num);
+   eth_port_set_filter_table_entry(table, p_addr[5]);
+   return;
+   }
+
+   /* Calculate CRC-8 out of the given address */
+   mac_h = (p_addr[0]  8) | (p_addr[1]);
+   mac_l = (p_addr[2]  24) | (p_addr[3]  16) |
+   (p_addr[4]  8) | (p_addr[5]  0);
+
+   for (i = 0; i  32; i++)
+   mac_array[i] = (mac_l  i)  0x1;
+   for (i = 32; i  48; i++)
+   mac_array[i] = (mac_h  (i - 32))  0x1;
+
+   crc[0] = mac_array[45] ^ mac_array[43] ^ mac_array[40] ^ mac_array[39] ^
+mac_array[35] ^ mac_array[34] ^ mac_array[31] ^ mac_array[30] ^
+mac_array[28] ^ mac_array[23] ^ mac_array[21] ^ mac_array[19] ^
+mac_array[18] ^ mac_array[16] ^ mac_array[14] ^ mac_array[12] ^
+mac_array[8]  ^ mac_array[7]  ^ mac_array[6]  ^ mac_array[0];
+
+   crc[1] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ mac_array[43] ^
+mac_array[41] ^ mac_array[39] ^ mac_array[36] ^ mac_array[34] ^
+mac_array[32] ^ mac_array[30] ^ mac_array[29] ^ mac_array[28] ^
+mac_array[24] ^ mac_array[23] ^ mac_array[22] ^ mac_array[21] ^
+mac_array[20] ^ mac_array[18] ^ mac_array[17] ^ mac_array[16] ^
+mac_array[15] ^ mac_array[14] ^ mac_array[13] ^ mac_array[12] ^
+mac_array[9]  ^ mac_array[6]  ^ mac_array[1]  ^ mac_array[0];
+
+   crc[2] = mac_array[47] ^ mac_array[46] ^ mac_array[44

[Patch 06/13] mv643xx_eth: Receive buffers require 8 byte alignment

2006-01-16 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

The Marvell mv643xx ethernet hardware requires that DMA buffers be
aligned to 8-byte boundaries.  This patch satisfies this requirement.
Buffers allocated by dev_alloc_skb() only have 4-byte alignment when
slab debugging is enabled.

Also, document that the 2-byte offset to align the IP packets on
receive is a hardware feature and is not tied to NET_IP_ALIGN.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

 mv643xx_eth.c |   12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c   2006-01-16 
10:49:30.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c2006-01-16 
10:49:31.0 -0700
@@ -57,7 +57,9 @@
 /* Constants */
 #define VLAN_HLEN  4
 #define FCS_LEN4
-#define WRAP   NET_IP_ALIGN + ETH_HLEN + VLAN_HLEN + FCS_LEN
+#define DMA_ALIGN  8   /* hw requires 8-byte alignment */
+#define HW_IP_ALIGN2   /* hw aligns IP header */
+#define WRAP   HW_IP_ALIGN + ETH_HLEN + VLAN_HLEN + FCS_LEN
 #define RX_SKB_SIZE((dev-mtu + WRAP + 7)  ~0x7)
 
 #define INT_CAUSE_UNMASK_ALL   0x0007
@@ -173,15 +175,19 @@
struct mv643xx_private *mp = netdev_priv(dev);
struct pkt_info pkt_info;
struct sk_buff *skb;
+   int unaligned;
 
if (test_and_set_bit(0, mp-rx_task_busy))
panic(%s: Error in test_set_bit / clear_bit, dev-name);
 
while (mp-rx_ring_skbs  (mp-rx_ring_size - 5)) {
-   skb = dev_alloc_skb(RX_SKB_SIZE);
+   skb = dev_alloc_skb(RX_SKB_SIZE + DMA_ALIGN);
if (!skb)
break;
mp-rx_ring_skbs++;
+   unaligned = (u32)skb-data  (DMA_ALIGN - 1);
+   if (unaligned)
+   skb_reserve(skb, DMA_ALIGN - unaligned);
pkt_info.cmd_sts = ETH_RX_ENABLE_INTERRUPT;
pkt_info.byte_cnt = RX_SKB_SIZE;
pkt_info.buf_ptr = dma_map_single(NULL, skb-data, RX_SKB_SIZE,
@@ -192,7 +198,7 @@
%s: Error allocating RX Ring\n, dev-name);
break;
}
-   skb_reserve(skb, 2);
+   skb_reserve(skb, HW_IP_ALIGN);
}
clear_bit(0, mp-rx_task_busy);
/*

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 07/13] mv643xx_eth: Fix handling of small, unaligned fragments

2006-01-16 Thread Dale Farnsworth
From: Paul Janzen [EMAIL PROTECTED]

Fix handling of small, unaligned fragments.
It also solves a potential deadlock if skb_linearize() returns -ENOMEM.

Signed-off-by: Paul Janzen [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

 mv643xx_eth.c |   54 +++---
 1 file changed, 31 insertions(+), 23 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c   2006-01-16 
10:49:31.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c2006-01-16 
10:49:32.0 -0700
@@ -1093,6 +1093,25 @@
 }
 #endif
 
+/* Hardware can't handle unaligned fragments smaller than 9 bytes.
+ * This helper function detects that case.
+ */
+
+static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb)
+{
+unsigned int frag;
+skb_frag_t *fragp;
+
+for (frag = 0; frag  skb_shinfo(skb)-nr_frags; frag++) {
+fragp = skb_shinfo(skb)-frags[frag];
+if (fragp-size = 8  fragp-page_offset  0x7)
+return 1;
+
+}
+return 0;
+}
+
+
 /*
  * mv643xx_eth_start_xmit
  *
@@ -1136,12 +1155,19 @@
return 1;
}
 
+#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
+   if (has_tiny_unaligned_frags(skb)) {
+   if ((skb_linearize(skb, GFP_ATOMIC) != 0)) {
+   stats-tx_dropped++;
+   printk(KERN_DEBUG %s: failed to linearize tiny 
+   unaligned fragment\n, dev-name);
+   return 1;
+   }
+   }
+
spin_lock_irqsave(mp-lock, flags);
 
-   /* Update packet info data structure -- DMA owned, first last */
-#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
if (!skb_shinfo(skb)-nr_frags) {
-linear:
if (skb-ip_summed != CHECKSUM_HW) {
/* Errata BTS #50, IHL must be 5 if no HW checksum */
pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT |
@@ -1183,26 +1209,6 @@
} else {
unsigned int frag;
 
-   /* Since hardware can't handle unaligned fragments smaller
-* than 9 bytes, if we find any, we linearize the skb
-* and start again.  When I've seen it, it's always been
-* the first frag (probably near the end of the page),
-* but we check all frags to be safe.
-*/
-   for (frag = 0; frag  skb_shinfo(skb)-nr_frags; frag++) {
-   skb_frag_t *fragp;
-
-   fragp = skb_shinfo(skb)-frags[frag];
-   if (fragp-size = 8  fragp-page_offset  0x7) {
-   skb_linearize(skb, GFP_ATOMIC);
-   printk(KERN_DEBUG %s: unaligned tiny fragment
-   %d of %d, fixed\n,
-   dev-name, frag,
-   skb_shinfo(skb)-nr_frags);
-   goto linear;
-   }
-   }
-
/* first frag which is skb header */
pkt_info.byte_cnt = skb_headlen(skb);
pkt_info.buf_ptr = dma_map_single(NULL, skb-data,
@@ -1288,6 +1294,8 @@
}
}
 #else
+   spin_lock_irqsave(mp-lock, flags);
+
pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | ETH_TX_FIRST_DESC |
ETH_TX_LAST_DESC;
pkt_info.l4i_chk = 0;

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 08/13] mv643xx_eth: iounmap the correct SRAM buffer

2006-01-16 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

 mv643xx_eth.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c   2006-01-16 
10:49:32.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c2006-01-16 
10:49:32.0 -0700
@@ -877,7 +877,7 @@
printk(KERN_ERR %s: Freeing previously allocated TX queues...,
dev-name);
if (mp-rx_sram_size)
-   iounmap(mp-p_rx_desc_area);
+   iounmap(mp-p_tx_desc_area);
else
dma_free_coherent(NULL, mp-tx_desc_area_size,
mp-p_tx_desc_area, mp-tx_desc_dma);

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 09/13] mv643xx_eth: Hold spinlocks only where needed

2006-01-16 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

This driver has historically held a spin_lock during the entire open
and stop functions and while receiving multiple packets.  This is
unecessarily long and holds locks during calls that may sleep.
This patch reduces the size of windows where locks are held.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

 mv643xx_eth.c |  172 ++
 1 file changed, 91 insertions(+), 81 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c   2006-01-16 
15:06:40.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c2006-01-16 
15:32:59.0 -0700
@@ -129,15 +129,8 @@
  */
 static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu)
 {
-   struct mv643xx_private *mp = netdev_priv(dev);
-   unsigned long flags;
-
-   spin_lock_irqsave(mp-lock, flags);
-
-   if ((new_mtu  9500) || (new_mtu  64)) {
-   spin_unlock_irqrestore(mp-lock, flags);
+   if ((new_mtu  9500) || (new_mtu  64))
return -EINVAL;
-   }
 
dev-mtu = new_mtu;
/*
@@ -157,7 +150,6 @@
dev-name);
}
 
-   spin_unlock_irqrestore(mp-lock, flags);
return 0;
 }
 
@@ -353,8 +345,6 @@
if (!(eth_int_cause_ext  (BIT0 | BIT8)))
return released;
 
-   spin_lock(mp-lock);
-
/* Check only queue 0 */
while (eth_tx_return_desc(mp, pkt_info) == ETH_OK) {
if (pkt_info.cmd_sts  BIT0) {
@@ -377,8 +367,6 @@
}
}
 
-   spin_unlock(mp-lock);
-
return released;
 }
 
@@ -518,6 +506,8 @@
mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), 0);
mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG
(port_num), 0);
+   /* ensure previous writes have taken effect */
+   
mv_read(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num));
__netif_rx_schedule(dev);
}
 #else
@@ -533,6 +523,9 @@
/* Unmask all interrupts on ethernet port */
mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
INT_CAUSE_MASK_ALL);
+   /* wait for previous write to take effect */
+   mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
+
queue_task(mp-rx_task, tq_immediate);
mark_bh(IMMEDIATE_BH);
 #else
@@ -657,34 +650,20 @@
unsigned int port_num = mp-port_num;
int err;
 
-   spin_lock_irq(mp-lock);
-
err = request_irq(dev-irq, mv643xx_eth_int_handler,
SA_SHIRQ | SA_SAMPLE_RANDOM, dev-name, dev);
-
if (err) {
printk(KERN_ERR Can not assign IRQ number to MV643XX_eth%d\n,
port_num);
-   err = -EAGAIN;
-   goto out;
+   return -EAGAIN;
}
 
if (mv643xx_eth_real_open(dev)) {
printk(%s: Error opening interface\n, dev-name);
+   free_irq(dev-irq, dev);
err = -EBUSY;
-   goto out_free;
}
 
-   spin_unlock_irq(mp-lock);
-
-   return 0;
-
-out_free:
-   free_irq(dev-irq, dev);
-
-out:
-   spin_unlock_irq(mp-lock);
-
return err;
 }
 
@@ -790,18 +769,6 @@
/* Stop RX Queues */
mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0xff00);
 
-   /* Clear the ethernet port interrupts */
-   mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
-   mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
-
-   /* Unmask RX buffer and TX end interrupt */
-   mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
-   INT_CAUSE_UNMASK_ALL);
-
-   /* Unmask phy and link status changes interrupts */
-   mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
-   INT_CAUSE_UNMASK_ALL_EXT);
-
/* Set the MAC Address */
memcpy(mp-port_mac_addr, dev-dev_addr, 6);
 
@@ -903,8 +870,17 @@
mp-tx_int_coal =
eth_port_set_tx_coal(port_num, 13300, MV643XX_TX_COAL);
 
-   netif_start_queue(dev);
+   /* Clear any pending ethernet port interrupts */
+   mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
+   mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
+
+   /* Unmask phy and link status changes interrupts */
+   mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
+   INT_CAUSE_UNMASK_ALL_EXT

[Patch 10/13] mv643xx_eth: Request HW checksum generation only for IPv4

2006-01-16 Thread Dale Farnsworth
From: Wolfram Joost [EMAIL PROTECTED]

This patch removes the NETIF_F_HW_CSUM flag to be able to use other protocols
than IPv4. Hardware checksums for IPv4 should continue to work because
NETIF_F_IP_CSUM is still set.  The sanity-check has been enhanced to check
the used protocol and to not access skb-iph for non-ipv4-packets.

Signed-off-by: Wolfram Joost [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

 mv643xx_eth.c |   19 +++
 1 file changed, 11 insertions(+), 8 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c   2006-01-16 
10:49:33.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c2006-01-16 
10:49:35.0 -0700
@@ -1148,7 +1148,6 @@
   5  ETH_TX_IHL_SHIFT;
pkt_info.l4i_chk = 0;
} else {
-
pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT |
   ETH_TX_FIRST_DESC |
   ETH_TX_LAST_DESC |
@@ -1156,14 +1155,16 @@
   ETH_GEN_IP_V_4_CHECKSUM |
   skb-nh.iph-ihl  ETH_TX_IHL_SHIFT;
/* CPU already calculated pseudo header checksum. */
-   if (skb-nh.iph-protocol == IPPROTO_UDP) {
+   if ((skb-protocol == ETH_P_IP) 
+   (skb-nh.iph-protocol == IPPROTO_UDP) ) {
pkt_info.cmd_sts |= ETH_UDP_FRAME;
pkt_info.l4i_chk = skb-h.uh-check;
-   } else if (skb-nh.iph-protocol == IPPROTO_TCP)
+   } else if ((skb-protocol == ETH_P_IP) 
+  (skb-nh.iph-protocol == IPPROTO_TCP))
pkt_info.l4i_chk = skb-h.th-check;
else {
printk(KERN_ERR
-   %s: chksum proto != TCP or UDP\n,
+   %s: chksum proto != IPv4 TCP or UDP\n,
dev-name);
spin_unlock_irqrestore(mp-lock, flags);
return 1;
@@ -1199,14 +1200,16 @@
   ETH_GEN_IP_V_4_CHECKSUM |
   skb-nh.iph-ihl  ETH_TX_IHL_SHIFT;
/* CPU already calculated pseudo header checksum. */
-   if (skb-nh.iph-protocol == IPPROTO_UDP) {
+   if ((skb-protocol == ETH_P_IP) 
+   (skb-nh.iph-protocol == IPPROTO_UDP)) {
pkt_info.cmd_sts |= ETH_UDP_FRAME;
pkt_info.l4i_chk = skb-h.uh-check;
-   } else if (skb-nh.iph-protocol == IPPROTO_TCP)
+   } else if ((skb-protocol == ETH_P_IP) 
+  (skb-nh.iph-protocol == IPPROTO_TCP))
pkt_info.l4i_chk = skb-h.th-check;
else {
printk(KERN_ERR
-   %s: chksum proto != TCP or UDP\n,
+   %s: chksum proto != IPv4 TCP or UDP\n,
dev-name);
spin_unlock_irqrestore(mp-lock, flags);
return 1;
@@ -1421,7 +1424,7 @@
 * Zero copy can only work if we use Discovery II memory. Else, we will
 * have to map the buffers to ISA memory which is only 16 MB
 */
-   dev-features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_HW_CSUM;
+   dev-features = NETIF_F_SG | NETIF_F_IP_CSUM;
 #endif
 #endif
 

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 11/13] mv643xx_eth: Fix transmit skb accounting

2006-01-16 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

 mv643xx_eth.c |7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c   2006-01-16 
15:33:10.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c2006-01-16 
15:33:11.0 -0700
@@ -889,14 +889,17 @@
struct mv643xx_private *mp = netdev_priv(dev);
unsigned int port_num = mp-port_num;
unsigned int curr;
+   struct sk_buff *skb;
 
/* Stop Tx Queues */
mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), 0xff00);
 
/* Free outstanding skb's on TX rings */
for (curr = 0; mp-tx_ring_skbs  curr  mp-tx_ring_size; curr++) {
-   if (mp-tx_skb[curr]) {
-   dev_kfree_skb(mp-tx_skb[curr]);
+   skb = mp-tx_skb[curr];
+   if (skb) {
+   mp-tx_ring_skbs -= skb_shinfo(skb)-nr_frags;
+   dev_kfree_skb(skb);
mp-tx_ring_skbs--;
}
}
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch 12/13] mv643xx_eth: Merge open and stop helper functions

2006-01-16 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

Move code from helper functions mv643xx_eth_real_open and mv643xx_eth_real_stop
as they are no longer needed.

Signed-off-by Dale Farnsworth [EMAIL PROTECTED]

 mv643xx_eth.c |  109 +++---
 1 file changed, 45 insertions(+), 64 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c   2006-01-16 
15:33:11.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c2006-01-16 
15:33:18.0 -0700
@@ -83,8 +83,8 @@
 static void eth_port_uc_addr_get(struct net_device *dev,
unsigned char *MacAddr);
 static void eth_port_set_multicast_list(struct net_device *);
-static int mv643xx_eth_real_open(struct net_device *);
-static int mv643xx_eth_real_stop(struct net_device *);
+static int mv643xx_eth_open(struct net_device *);
+static int mv643xx_eth_stop(struct net_device *);
 static int mv643xx_eth_change_mtu(struct net_device *, int);
 static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *);
 static void eth_port_init_mac_tables(unsigned int eth_port_num);
@@ -140,11 +140,8 @@
 * to memory is full, which might fail the open function.
 */
if (netif_running(dev)) {
-   if (mv643xx_eth_real_stop(dev))
-   printk(KERN_ERR
-   %s: Fatal error on stopping device\n,
-   dev-name);
-   if (mv643xx_eth_real_open(dev))
+   mv643xx_eth_stop(dev);
+   if (mv643xx_eth_open(dev))
printk(KERN_ERR
%s: Fatal error on opening device\n,
dev-name);
@@ -632,42 +629,6 @@
 }
 
 /*
- * mv643xx_eth_open
- *
- * This function is called when openning the network device. The function
- * should initialize all the hardware, initialize cyclic Rx/Tx
- * descriptors chain and buffers and allocate an IRQ to the network
- * device.
- *
- * Input : a pointer to the network device structure
- *
- * Output :zero of success , nonzero if fails.
- */
-
-static int mv643xx_eth_open(struct net_device *dev)
-{
-   struct mv643xx_private *mp = netdev_priv(dev);
-   unsigned int port_num = mp-port_num;
-   int err;
-
-   err = request_irq(dev-irq, mv643xx_eth_int_handler,
-   SA_SHIRQ | SA_SAMPLE_RANDOM, dev-name, dev);
-   if (err) {
-   printk(KERN_ERR Can not assign IRQ number to MV643XX_eth%d\n,
-   port_num);
-   return -EAGAIN;
-   }
-
-   if (mv643xx_eth_real_open(dev)) {
-   printk(%s: Error opening interface\n, dev-name);
-   free_irq(dev-irq, dev);
-   err = -EBUSY;
-   }
-
-   return err;
-}
-
-/*
  * ether_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory.
  *
  * DESCRIPTION:
@@ -759,12 +720,33 @@
mp-port_tx_queue_command |= 1;
 }
 
-/* Helper function for mv643xx_eth_open */
-static int mv643xx_eth_real_open(struct net_device *dev)
+/*
+ * mv643xx_eth_open
+ *
+ * This function is called when openning the network device. The function
+ * should initialize all the hardware, initialize cyclic Rx/Tx
+ * descriptors chain and buffers and allocate an IRQ to the network
+ * device.
+ *
+ * Input : a pointer to the network device structure
+ *
+ * Output :zero of success , nonzero if fails.
+ */
+
+static int mv643xx_eth_open(struct net_device *dev)
 {
struct mv643xx_private *mp = netdev_priv(dev);
unsigned int port_num = mp-port_num;
unsigned int size;
+   int err;
+
+   err = request_irq(dev-irq, mv643xx_eth_int_handler,
+   SA_SHIRQ | SA_SAMPLE_RANDOM, dev-name, dev);
+   if (err) {
+   printk(KERN_ERR Can not assign IRQ number to MV643XX_eth%d\n,
+   port_num);
+   return -EAGAIN;
+   }
 
/* Stop RX Queues */
mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0xff00);
@@ -788,14 +770,15 @@
GFP_KERNEL);
if (!mp-rx_skb) {
printk(KERN_ERR %s: Cannot allocate Rx skb ring\n, dev-name);
-   return -ENOMEM;
+   err = -ENOMEM;
+   goto out_free_irq;
}
mp-tx_skb = kmalloc(sizeof(*mp-tx_skb) * mp-tx_ring_size,
GFP_KERNEL);
if (!mp-tx_skb) {
printk(KERN_ERR %s: Cannot allocate Tx skb ring\n, dev-name);
-   kfree(mp-rx_skb);
-   return -ENOMEM;
+   err = -ENOMEM

[Patch 13/13] mv643xx_eth: Remove needless mask of extended intr register

2006-01-16 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

All interrupts controlled by the extended mask register are also
masked by a bit in the main mask register, so there is no need to
directly manipulate the extended mask register.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

 mv643xx_eth.c |   81 ++
 1 file changed, 26 insertions(+), 55 deletions(-)

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c   2006-01-16 
15:33:18.0 -0700
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c2006-01-16 
15:33:23.0 -0700
@@ -62,10 +62,10 @@
 #define WRAP   HW_IP_ALIGN + ETH_HLEN + VLAN_HLEN + FCS_LEN
 #define RX_SKB_SIZE((dev-mtu + WRAP + 7)  ~0x7)
 
-#define INT_CAUSE_UNMASK_ALL   0x0007
-#define INT_CAUSE_UNMASK_ALL_EXT   0x0011
-#define INT_CAUSE_MASK_ALL 0x
-#define INT_CAUSE_MASK_ALL_EXT 0x
+#define INT_UNMASK_ALL 0x0007
+#define INT_UNMASK_ALL_EXT 0x0011
+#define INT_MASK_ALL   0x
+#define INT_MASK_ALL_EXT   0x
 #define INT_CAUSE_CHECK_BITS   INT_CAUSE_UNMASK_ALL
 #define INT_CAUSE_CHECK_BITS_EXT   INT_CAUSE_UNMASK_ALL_EXT
 
@@ -205,7 +205,7 @@
else {
/* Return interrupts */
mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(mp-port_num),
-   INT_CAUSE_UNMASK_ALL);
+   INT_UNMASK_ALL);
}
 #endif
 }
@@ -470,12 +470,12 @@
 
/* Read interrupt cause registers */
eth_int_cause = mv_read(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num)) 
-   INT_CAUSE_UNMASK_ALL;
+   INT_UNMASK_ALL;
 
if (eth_int_cause  BIT1)
eth_int_cause_ext = mv_read(
MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num)) 
-   INT_CAUSE_UNMASK_ALL_EXT;
+   INT_UNMASK_ALL_EXT;
 
 #ifdef MV643XX_NAPI
if (!(eth_int_cause  0x0007fffd)) {
@@ -500,11 +500,10 @@
} else {
if (netif_rx_schedule_prep(dev)) {
/* Mask all the interrupts */
-   mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), 0);
-   mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG
-   (port_num), 0);
-   /* ensure previous writes have taken effect */
-   
mv_read(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num));
+   mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
+   INT_MASK_ALL);
+   /* wait for previous write to complete */
+   mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
__netif_rx_schedule(dev);
}
 #else
@@ -517,9 +516,9 @@
 * with skb's.
 */
 #ifdef MV643XX_RX_QUEUE_FILL_ON_TASK
-   /* Unmask all interrupts on ethernet port */
+   /* Mask all interrupts on ethernet port */
mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
-   INT_CAUSE_MASK_ALL);
+   INT_MASK_ALL);
/* wait for previous write to take effect */
mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
 
@@ -857,11 +856,10 @@
 
/* Unmask phy and link status changes interrupts */
mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
-   INT_CAUSE_UNMASK_ALL_EXT);
+   INT_UNMASK_ALL_EXT);
 
/* Unmask RX buffer and TX end interrupt */
-   mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
-   INT_CAUSE_UNMASK_ALL);
+   mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_UNMASK_ALL);
return 0;
 
 out_free_tx_skb:
@@ -950,13 +948,9 @@
struct mv643xx_private *mp = netdev_priv(dev);
unsigned int port_num = mp-port_num;
 
-   /* Mask RX buffer and TX end interrupt */
-   mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), 0);
-
-   /* Mask phy and link status changes interrupts */
-   mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), 0);
-
-   /* ensure previous writes have taken effect */
+   /* Mask all interrupts on ethernet port */
+   mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_MASK_ALL

Re: [PATCH] Re: mv643xx_eth_start_xmit: calls skb_linearize with interrupts off

2006-01-13 Thread Dale Farnsworth
On Mon, Jan 09, 2006 at 04:43:08AM +, Paul Janzen wrote:
 Paul Janzen [EMAIL PROTECTED] writes:
  In mv643xx_eth_start_xmit:
  [...]
  spin_lock_irqsave(mp-lock, flags);
  [...]
  /* Since hardware can't handle unaligned fragments smaller
   * than 9 bytes, if we find any, we linearize the skb
   * and start again. */
  [...]
  skb_linearize(skb, GFP_ATOMIC);
  [...]
 
  which ends up calling kunmap_skb_frag(vaddr), which, when
  CONFIG_HIGHMEM=y, calls local_bh_enable with interrupts off.
 
 A patch for this problem is enclosed.  I believe it also solves a
 potential deadlock if skb_linearize() returns -ENOMEM. 
 
 Signed-off-by: Paul Janzen [EMAIL PROTECTED]

Thank you Paul.  Good find and fix.  I have one question below.

 --- a/drivers/net/mv643xx_eth.c   2005-12-24 15:47:48.0 -0800
 +++ b/drivers/net/mv643xx_eth.c   2006-01-08 20:30:25.0 -0800
 @@ -1093,6 +1093,27 @@ static int mv643xx_poll(struct net_devic
  }
  #endif
  
 +/* Hardware can't handle unaligned fragments smaller than 9 bytes.
 + * This helper function detects that case.  When I've seen it, it's
 + * always been the first frag (probably near the end of the page), but
 + * we check all frags to be safe.
 + */

By the way, the above comment is mine, but since then, I have seen small,
unaligned fragments beyond the first frag, so I'll remove the last
sentence.

 +static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb)
 +{
 +unsigned int frag;
 +skb_frag_t *fragp;
 +
 +for (frag = 0; frag  skb_shinfo(skb)-nr_frags; frag++) {
 +fragp = skb_shinfo(skb)-frags[frag];
 +if (fragp-size = 8  fragp-page_offset  0x7) 
 +return 1;
 +
 +}
 +return 0;
 +}
 +
 +
  /*
   * mv643xx_eth_start_xmit
   *
 @@ -1136,12 +1157,22 @@ static int mv643xx_eth_start_xmit(struct
   return 1;
   }
  
 +if (has_tiny_unaligned_frags(skb)) {
 +if ((skb_linearize(skb, GFP_ATOMIC) != 0) 
 +|| has_tiny_unaligned_frags(skb)) { 

There is no way that skb_linearize can return without removing all frags
from the skb.  So the extra call to has_tiny_unaligned_frags() is
unnecessary, right?

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/4] mv643xx: Fix dma_map/dma_unmap calls

2005-12-28 Thread Dale Farnsworth
From: Paolo Galtieri [EMAIL PROTECTED]

Fix the dma_map/dma_unmap relationships and a NULL pointer dereference.
If you do a dma_map_single you must do dma_unmap_single and if you do
a dma_map_page you must do a dma_unmap_page.  The NULL pointer
dereference was caused because the buf_ptr and byte_cnt fields of the
pkt_info structure were not filled in by eth_tx_return_desc().

Signed-off-by: Paolo Galtieri [EMAIL PROTECTED]
Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
@@ -351,27 +351,19 @@ static int mv643xx_eth_free_tx_queue(str
stats-tx_errors++;
}
 
-   /*
-* If return_info is different than 0, release the skb.
-* The case where return_info is not 0 is only in case
-* when transmitted a scatter/gather packet, where only
-* last skb releases the whole chain.
-*/
-   if (pkt_info.return_info) {
-   if (skb_shinfo(pkt_info.return_info)-nr_frags)
-   dma_unmap_page(NULL, pkt_info.buf_ptr,
-   pkt_info.byte_cnt,
-   DMA_TO_DEVICE);
-   else
-   dma_unmap_single(NULL, pkt_info.buf_ptr,
-   pkt_info.byte_cnt,
-   DMA_TO_DEVICE);
+   if (pkt_info.cmd_sts  ETH_TX_FIRST_DESC)
+   dma_unmap_single(NULL, pkt_info.buf_ptr,
+   pkt_info.byte_cnt,
+   DMA_TO_DEVICE);
+   else
+   dma_unmap_page(NULL, pkt_info.buf_ptr,
+   pkt_info.byte_cnt,
+   DMA_TO_DEVICE);
 
+   if (pkt_info.return_info) {
dev_kfree_skb_irq(pkt_info.return_info);
released = 0;
-   } else
-   dma_unmap_page(NULL, pkt_info.buf_ptr,
-   pkt_info.byte_cnt, DMA_TO_DEVICE);
+   }
}
 
spin_unlock(mp-lock);
@@ -1022,20 +1014,17 @@ static void mv643xx_tx(struct net_device
struct pkt_info pkt_info;
 
while (eth_tx_return_desc(mp, pkt_info) == ETH_OK) {
-   if (pkt_info.return_info) {
-   if (skb_shinfo(pkt_info.return_info)-nr_frags)
-   dma_unmap_page(NULL, pkt_info.buf_ptr,
-   pkt_info.byte_cnt,
-   DMA_TO_DEVICE);
-   else
-   dma_unmap_single(NULL, pkt_info.buf_ptr,
-   pkt_info.byte_cnt,
-   DMA_TO_DEVICE);
+   if (pkt_info.cmd_sts  ETH_TX_FIRST_DESC)
+   dma_unmap_single(NULL, pkt_info.buf_ptr,
+   pkt_info.byte_cnt,
+   DMA_TO_DEVICE);
+   else
+   dma_unmap_page(NULL, pkt_info.buf_ptr,
+   pkt_info.byte_cnt,
+   DMA_TO_DEVICE);
 
+   if (pkt_info.return_info)
dev_kfree_skb_irq(pkt_info.return_info);
-   } else
-   dma_unmap_page(NULL, pkt_info.buf_ptr,
-   pkt_info.byte_cnt, DMA_TO_DEVICE);
}
 
if (netif_queue_stopped(dev) 
@@ -2669,6 +2658,8 @@ static ETH_FUNC_RET_STATUS eth_tx_return
/* Pass the packet information to the caller */
p_pkt_info-cmd_sts = command_status;
p_pkt_info-return_info = mp-tx_skb[tx_desc_used];
+   p_pkt_info-buf_ptr = p_tx_desc_used-buf_ptr;
+   p_pkt_info-byte_cnt = p_tx_desc_used-byte_cnt;
mp-tx_skb[tx_desc_used] = NULL;
 
/* Update the next descriptor to release. */
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/4] mv643xx: Align receive DMA buffers

2005-12-28 Thread Dale Farnsworth
From: Dale Farnsworth [EMAIL PROTECTED]

The Marvell mv643xx ethernet hardware requires that DMA buffers be
aligned to 8-byte boundaries.  This patch satisfies this requirement.
Buffers allocated by dev_alloc_skb() only have 4-byte alignment when
slab debugging is enabled.

Also, document that the 2-byte offset to align the IP packets on
receive is a hardware feature and is not tied to NET_IP_ALIGN.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
@@ -55,7 +55,9 @@
 /* Constants */
 #define VLAN_HLEN  4
 #define FCS_LEN4
-#define WRAP   NET_IP_ALIGN + ETH_HLEN + VLAN_HLEN + FCS_LEN
+#define DMA_ALIGN  8   /* hw requires 8-byte alignment */
+#define HW_IP_ALIGN2   /* hw aligns IP header */
+#define WRAP   HW_IP_ALIGN + ETH_HLEN + VLAN_HLEN + FCS_LEN
 #define RX_SKB_SIZE((dev-mtu + WRAP + 7)  ~0x7)
 
 #define INT_CAUSE_UNMASK_ALL   0x0007
@@ -171,15 +173,19 @@ static void mv643xx_eth_rx_task(void *da
struct mv643xx_private *mp = netdev_priv(dev);
struct pkt_info pkt_info;
struct sk_buff *skb;
+   int unaligned;
 
if (test_and_set_bit(0, mp-rx_task_busy))
panic(%s: Error in test_set_bit / clear_bit, dev-name);
 
while (mp-rx_ring_skbs  (mp-rx_ring_size - 5)) {
-   skb = dev_alloc_skb(RX_SKB_SIZE);
+   skb = dev_alloc_skb(RX_SKB_SIZE + DMA_ALIGN);
if (!skb)
break;
mp-rx_ring_skbs++;
+   unaligned = (u32)skb-data  (DMA_ALIGN - 1);
+   if (unaligned)
+   skb_reserve(skb, DMA_ALIGN - unaligned);
pkt_info.cmd_sts = ETH_RX_ENABLE_INTERRUPT;
pkt_info.byte_cnt = RX_SKB_SIZE;
pkt_info.buf_ptr = dma_map_single(NULL, skb-data, RX_SKB_SIZE,
@@ -190,7 +196,7 @@ static void mv643xx_eth_rx_task(void *da
%s: Error allocating RX Ring\n, dev-name);
break;
}
-   skb_reserve(skb, 2);
+   skb_reserve(skb, HW_IP_ALIGN);
}
clear_bit(0, mp-rx_task_busy);
/*
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] gianfar: add netpoll api support

2005-12-12 Thread Dale Farnsworth
In article [EMAIL PROTECTED] you write:
 On Mon, Dec 12, 2005 at 11:54:06AM -0700, Dale Farnsworth wrote:
 
  +#ifdef CONFIG_NET_POLL_CONTROLLER
  +/*
  + * Polling - used by netconsole and other diagnostic tools
  + * to allow network i/o with interrupts disabled.
  + */
  +static void gfar_netpoll(struct net_device *dev)
  +{
  +   struct gfar_private *priv = netdev_priv(dev);
  +
  +   if (priv-einfo-device_flags  FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
  +   disable_irq(priv-interruptReceive);
  +   disable_irq(priv-interruptTransmit);
  +   disable_irq(priv-interruptError);
  +   gfar_interrupt(priv-interruptTransmit, dev, NULL);
  +   enable_irq(priv-interruptError);
  +   enable_irq(priv-interruptTransmit);
  +   enable_irq(priv-interruptReceive);
  +   } else {
  +   disable_irq(priv-interruptTransmit);
  +   gfar_interrupt(priv-interruptTransmit, dev, NULL);
  +   enable_irq(priv-interruptTransmit);
  +   }
  +}
  +#endif
 
 Do the multiple interrupts need to be disabled/enabled in that order?
 I'm presuming that is why you replicated the code for the tx interrupt
 and for calling gfar_interrupt.
 
 Of course, I'm not sure that doing it some other way would be any less
 ugly either... :-)
 
 I do not object to this patch.  I'm just being curious.

I don't know that the order is critical.  Maybe Kumar can comment.

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] gianfar: add netpoll api support

2005-12-12 Thread Dale Farnsworth
On Tue, Dec 13, 2005 at 12:43:28AM +, Andy Fleming wrote:
 On Mon, Dec 12, 2005 at 11:54:06AM -0700, Dale Farnsworth wrote:
 
 +#ifdef CONFIG_NET_POLL_CONTROLLER
 +/*
 + * Polling - used by netconsole and other diagnostic tools
 + * to allow network i/o with interrupts disabled.
 + */
 +static void gfar_netpoll(struct net_device *dev)
 +{
 +  struct gfar_private *priv = netdev_priv(dev);
 +
 +  if (priv-einfo-device_flags  FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
 +  disable_irq(priv-interruptReceive);
 +  disable_irq(priv-interruptTransmit);
 +  disable_irq(priv-interruptError);
 +  gfar_interrupt(priv-interruptTransmit, dev, NULL);
 +  enable_irq(priv-interruptError);
 +  enable_irq(priv-interruptTransmit);
 +  enable_irq(priv-interruptReceive);
 +  } else {
 +  disable_irq(priv-interruptTransmit);
 +  gfar_interrupt(priv-interruptTransmit, dev, NULL);
 +  enable_irq(priv-interruptTransmit);
 +  }
 +}
 +#endif
 
 However, wouldn't it have simpler to mask the bits in the IMASK  
 register?

Hmm.  I think we need to ensure that we're not currently executing
one of the interrupt handlers and I don't see any simpler way than
calling disable_irq() for each one.

-Dale
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mv643xx: Disable per port bandwidth limits

2005-09-02 Thread Dale Farnsworth
The mv643xx chips support per port bandwith limits.  This patch
disables the bandwidth limits by clearing the MTU register.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

Index: linux-2.6.13-mm1-mv643xx-enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6.13-mm1-mv643xx-enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6.13-mm1-mv643xx-enet/drivers/net/mv643xx_eth.c
@@ -1868,6 +1868,9 @@ static void eth_port_start(struct mv643x
/* Enable port Rx. */
mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num),
mp-port_rx_queue_command);
+
+   /* Disable port bandwidth limits by clearing MTU register */
+   mv_write(MV643XX_ETH_MAXIMUM_TRANSMIT_UNIT(port_num), 0);
 }
 
 /*
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mv643xx: add netpoll api support

2005-09-02 Thread Dale Farnsworth
Add support for the netpoll api for use by netconsole, kgdb, etc.

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

Index: linux-2.6.13-mm1-mv643xx-enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6.13-mm1-mv643xx-enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6.13-mm1-mv643xx-enet/drivers/net/mv643xx_eth.c
@@ -58,11 +58,10 @@
 
 #define INT_CAUSE_UNMASK_ALL   0x0007
 #define INT_CAUSE_UNMASK_ALL_EXT   0x0011
-#ifdef MV643XX_RX_QUEUE_FILL_ON_TASK
 #define INT_CAUSE_MASK_ALL 0x
+#define INT_CAUSE_MASK_ALL_EXT 0x
 #define INT_CAUSE_CHECK_BITS   INT_CAUSE_UNMASK_ALL
 #define INT_CAUSE_CHECK_BITS_EXT   INT_CAUSE_UNMASK_ALL_EXT
-#endif
 
 #ifdef MV643XX_CHECKSUM_OFFLOAD_TX
 #define MAX_DESCS_PER_SKB  (MAX_SKB_FRAGS + 1)
@@ -1338,6 +1337,43 @@ static struct net_device_stats *mv643xx_
return mp-stats;
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static inline void mv643xx_enable_irq(struct mv643xx_private *mp)
+{
+   int port_num = mp-port_num;
+   unsigned long flags;
+
+   spin_lock_irqsave(mp-lock, flags);
+   mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
+   INT_CAUSE_UNMASK_ALL);
+   mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
+   INT_CAUSE_UNMASK_ALL_EXT);
+   spin_unlock_irqrestore(mp-lock, flags);
+}
+
+static inline void mv643xx_disable_irq(struct mv643xx_private *mp)
+{
+   int port_num = mp-port_num;
+   unsigned long flags;
+
+   spin_lock_irqsave(mp-lock, flags);
+   mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
+   INT_CAUSE_MASK_ALL);
+   mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
+   INT_CAUSE_MASK_ALL_EXT);
+   spin_unlock_irqrestore(mp-lock, flags);
+}
+
+static void mv643xx_netpoll(struct net_device *netdev)
+{
+   struct mv643xx_private *mp = netdev_priv(netdev);
+
+   mv643xx_disable_irq(mp);
+   mv643xx_eth_int_handler(netdev-irq, netdev, NULL);
+   mv643xx_enable_irq(mp);
+}
+#endif
+
 /*/
  * mv643xx_eth_probe
  *
@@ -1388,6 +1424,10 @@ static int mv643xx_eth_probe(struct devi
dev-weight = 64;
 #endif
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+   dev-poll_controller = mv643xx_netpoll;
+#endif
+
dev-watchdog_timeo = 2 * HZ;
dev-tx_queue_len = mp-tx_ring_size;
dev-base_addr = 0;
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mv643xx: fix skb memory leak

2005-09-01 Thread Dale Farnsworth
This patch fixes an skb memory leak under heavy receive load
(whenever the more packets have been received than the NAPI budget
allows to be processed).

Signed-off-by: Dale Farnsworth [EMAIL PROTECTED]

Index: linux-2.6.13-rc6-mm2-mv643xx-enet/drivers/net/mv643xx_eth.c
===
--- linux-2.6.13-rc6-mm2-mv643xx-enet.orig/drivers/net/mv643xx_eth.c
+++ linux-2.6.13-rc6-mm2-mv643xx-enet/drivers/net/mv643xx_eth.c
@@ -412,15 +412,13 @@ static int mv643xx_eth_receive_queue(str
struct pkt_info pkt_info;
 
 #ifdef MV643XX_NAPI
-   while (eth_port_receive(mp, pkt_info) == ETH_OK  budget  0) {
+   while (budget--  0  eth_port_receive(mp, pkt_info) == ETH_OK) {
 #else
while (eth_port_receive(mp, pkt_info) == ETH_OK) {
 #endif
mp-rx_ring_skbs--;
received_packets++;
-#ifdef MV643XX_NAPI
-   budget--;
-#endif
+
/* Update statistics. Note byte count includes 4 byte CRC count 
*/
stats-rx_packets++;
stats-rx_bytes += pkt_info.byte_cnt;
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html