natsemi cable length woes
Subsystems (2)
RFC 1/1 natsemi cable length woes
Here's a proposed patch that addresses a problem with natsemi NICs and long cables we've been chasing (*sigh*).
I'm interested in feedback on how to fix this sanely.
Olaf
------------------------------------------------------------------
From: Olaf Kirch <[email protected]>
Subject: natsemi: make cable length magic configurable
We had a customer report concerning problems with a Natsemi DP83815-D and long cables. With 100m cables, the network would be essentially dead, not a single packet would get through either way. We had to apply the patch below to make it work.
The patch adds a module parameter named "no_cable_magic" that does two things:
- Unconditionally set the DSPCFG register to the
fixed value. Without this change, the chip apparently never completes autonegotiation in the tested configuration.
This has been an unconditional assignment for a long time, until this was changed in 2.6.11 (there's an interesting explanation in the ChangeLog, bk commit is 5871b81bf2b5cf188deab0d414dce104fcb69ca6)
- skip the bit banging in {,un}do_cable_magic. It seems that
if we write the DSPCFG register as above, a rev D chip will report all cables as "short cables", which do_cable_magic detects, and trying to be helpful it will "fix" the attenuation coefficient.
I admit the use of a module parameter is ugly, but I didn't find a sane way to fix this - especially since the magic registers we're changing are kind of underdocumented.
drivers/net/natsemi.c | 11 ++++++++--- 1 files changed, 8 insertions(+), 3 deletions(-)
drivers/net/natsemi.c +8 -3
@@ -72,6 +72,7 @@static int debug =-1 ;static int mtu; +static int no_cable_magic;/* Maximum number of multicast addresses to filter (vs. rx-all-multicast). This chip uses a 512 element hash table based on the Ethernet CRC. */
@@ -139,6 +140,7 @@ MODULE_LICENSE("GPL");module_param (mtu, int,0 );module_param (debug, int,0 );module_param (rx_copybreak, int,0 ); +module_param (no_cable_magic, int,0 );module_param_array (options, int,NULL ,0 );module_param_array (full_duplex, int,NULL ,0 );MODULE_PARM_DESC (mtu,"DP8381x MTU (all boards)" );
@@ -148,6 +150,9 @@ MODULE_PARM_DESC(rx_copybreak,MODULE_PARM_DESC (options,"DP8381x: Bits 0-3: media type, bit 17: full duplex" );MODULE_PARM_DESC (full_duplex,"DP8381x full duplex setting(s) (1)" ); +MODULE_PARM_DESC (no_cable_magic, +"DP8381x: set no_cable_magic=1 to disable magic workaround for short cables " +"(may help with long cables:-)" );/* Theory of Operation
@@ -1147,7 +1152,7 @@ static void init_phy_fixup(struct net_dewritew (1 , ioaddr +PGSEL );writew (PMDCSR_VAL , ioaddr +PMDCSR );writew (TSTDAT_VAL , ioaddr +TSTDAT ); - np->dspcfg = (np->srr <=SRR_DP83815_C )? + np->dspcfg = (np->srr <=SRR_DP83815_C || no_cable_magic)?DSPCFG_VAL : (DSPCFG_COEF |readw (ioaddr +DSPCFG ));writew (np->dspcfg, ioaddr +DSPCFG );writew (SDCFG_VAL , ioaddr +SDCFG );
@@ -1511,7 +1516,7 @@ static void do_cable_magic(struct net_deif (dev->if_port !=PORT_TP )return ; -if (np->srr >=SRR_DP83816_A5 ) +if (np->srr >=SRR_DP83816_A5 || no_cable_magic)return ;/*
@@ -1556,7 +1561,7 @@ static void undo_cable_magic(struct net_if (dev->if_port !=PORT_TP )return ; -if (np->srr >=SRR_DP83816_A5 ) +if (np->srr >=SRR_DP83816_A5 || no_cable_magic)return ;writew (1 , ioaddr +PGSEL );
Signature · 2 lines
Olaf Kirch | --- o --- Nous sommes du soleil we love when we play [email protected] | / | \ sol.dhoop.naytheet.ah kin.ir.samse.qurax