Added support for newer cards that have the DP83840A PHY chip.

Fixed a bug in fxp_mdi_write - a hex number was missing a preceding 0x
and this was causing the routine to not wait for a PHY write to complete.
Added support for link0, link1, and link2 flags to toggle auto-
negotiation, 10/100, and half/full duplex:

link0	disable auto-negotiation

	When set, these flags then have meaning:

	-link1	10Mbps
	link1	100Mbps
	-link2	half duplex
	link2	full duplex

...needs a manual page.
This commit is contained in:
David Greenman 1997-03-21 08:00:13 +00:00
parent 8cd3868fee
commit 6ebc315326
4 changed files with 92 additions and 18 deletions

View File

@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: if_fxp.c,v 1.29 1997/02/22 09:44:05 peter Exp $
* $Id: if_fxp.c,v 1.30 1997/03/17 11:08:14 davidg Exp $
*/
/*
@ -962,12 +962,39 @@ fxp_init(xsc)
/*
* Toggle a few bits in the DP83840 PHY.
*/
if (sc->phy_primary_device == FXP_PHY_DP83840) {
if (sc->phy_primary_device == FXP_PHY_DP83840 ||
sc->phy_primary_device == FXP_PHY_DP83840A) {
fxp_mdi_write(sc->csr, sc->phy_primary_addr, FXP_DP83840_PCR,
fxp_mdi_read(sc->csr, sc->phy_primary_addr, FXP_DP83840_PCR) |
FXP_DP83840_PCR_LED4_MODE | /* LED4 always indicates duplex */
FXP_DP83840_PCR_F_CONNECT | /* force link disconnect bypass */
FXP_DP83840_PCR_BIT10); /* XXX I have no idea */
/*
* If link0 is set, disable auto-negotiation and then:
* If link1 is unset = 10Mbps
* If link1 is set = 100Mbps
* If link2 is unset = half duplex
* If link2 is set = full duplex
*/
if (ifp->if_flags & IFF_LINK0) {
int flags;
flags = (ifp->if_flags & IFF_LINK1) ?
FXP_DP83840_BMCR_SPEED_100M : 0;
flags |= (ifp->if_flags & IFF_LINK2) ?
FXP_DP83840_BMCR_FULLDUPLEX : 0;
fxp_mdi_write(sc->csr, sc->phy_primary_addr, FXP_DP83840_BMCR,
(fxp_mdi_read(sc->csr, sc->phy_primary_addr, FXP_DP83840_BMCR) &
~(FXP_DP83840_BMCR_AUTOEN | FXP_DP83840_BMCR_SPEED_100M |
FXP_DP83840_BMCR_FULLDUPLEX)) | flags);
} else {
fxp_mdi_write(sc->csr, sc->phy_primary_addr, FXP_DP83840_BMCR,
(fxp_mdi_read(sc->csr, sc->phy_primary_addr, FXP_DP83840_BMCR) |
FXP_DP83840_BMCR_AUTOEN));
}
} else {
printf("fxp%d: warning: unsupported PHY, type = %d, addr = %d\n",
ifp->if_unit, sc->phy_primary_device, sc->phy_primary_addr);
}
ifp->if_flags |= IFF_RUNNING;
@ -1042,23 +1069,24 @@ fxp_add_rfabuf(sc, oldm)
return (m == oldm);
}
static int
static volatile int
fxp_mdi_read(csr, phy, reg)
struct fxp_csr *csr;
int phy;
int reg;
{
int count = 10000;
int value;
csr->mdi_control = (FXP_MDI_READ << 26) | (reg << 16) | (phy << 21);
while ((csr->mdi_control & 0x10000000) == 0 && count--)
DELAY(1);
while (((value = csr->mdi_control) & 0x10000000) == 0 && count--)
DELAY(10);
if (count <= 0)
printf("fxp_mdi_read: timed out\n");
return (csr->mdi_control & 0xffff);
return (value & 0xffff);
}
static void
@ -1073,8 +1101,8 @@ fxp_mdi_write(csr, phy, reg, value)
csr->mdi_control = (FXP_MDI_WRITE << 26) | (reg << 16) | (phy << 21)
| (value & 0xffff);
while ((csr->mdi_control & 10000000) == 0 && count--)
DELAY(1);
while ((csr->mdi_control & 0x10000000) == 0 && count--)
DELAY(10);
if (count <= 0)
printf("fxp_mdi_write: timed out\n");

View File

@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: if_fxpreg.h,v 1.6 1997/02/22 09:44:06 peter Exp $
* $Id: if_fxpreg.h,v 1.7 1997/03/17 11:08:16 davidg Exp $
*/
#define FXP_VENDORID_INTEL 0x8086
@ -292,6 +292,15 @@ struct fxp_stats {
#define FXP_PHY_DP83840 4
#define FXP_PHY_80C240 5
#define FXP_PHY_80C24 6
#define FXP_PHY_DP83840A 10
/*
* DP84830 PHY, BMCR Basic Mode Control Register
*/
#define FXP_DP83840_BMCR 0x0
#define FXP_DP83840_BMCR_FULLDUPLEX 0x0100
#define FXP_DP83840_BMCR_AUTOEN 0x1000
#define FXP_DP83840_BMCR_SPEED_100M 0x2000
/*
* DP84830 PHY, PCS Configuration Register

View File

@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: if_fxp.c,v 1.29 1997/02/22 09:44:05 peter Exp $
* $Id: if_fxp.c,v 1.30 1997/03/17 11:08:14 davidg Exp $
*/
/*
@ -962,12 +962,39 @@ fxp_init(xsc)
/*
* Toggle a few bits in the DP83840 PHY.
*/
if (sc->phy_primary_device == FXP_PHY_DP83840) {
if (sc->phy_primary_device == FXP_PHY_DP83840 ||
sc->phy_primary_device == FXP_PHY_DP83840A) {
fxp_mdi_write(sc->csr, sc->phy_primary_addr, FXP_DP83840_PCR,
fxp_mdi_read(sc->csr, sc->phy_primary_addr, FXP_DP83840_PCR) |
FXP_DP83840_PCR_LED4_MODE | /* LED4 always indicates duplex */
FXP_DP83840_PCR_F_CONNECT | /* force link disconnect bypass */
FXP_DP83840_PCR_BIT10); /* XXX I have no idea */
/*
* If link0 is set, disable auto-negotiation and then:
* If link1 is unset = 10Mbps
* If link1 is set = 100Mbps
* If link2 is unset = half duplex
* If link2 is set = full duplex
*/
if (ifp->if_flags & IFF_LINK0) {
int flags;
flags = (ifp->if_flags & IFF_LINK1) ?
FXP_DP83840_BMCR_SPEED_100M : 0;
flags |= (ifp->if_flags & IFF_LINK2) ?
FXP_DP83840_BMCR_FULLDUPLEX : 0;
fxp_mdi_write(sc->csr, sc->phy_primary_addr, FXP_DP83840_BMCR,
(fxp_mdi_read(sc->csr, sc->phy_primary_addr, FXP_DP83840_BMCR) &
~(FXP_DP83840_BMCR_AUTOEN | FXP_DP83840_BMCR_SPEED_100M |
FXP_DP83840_BMCR_FULLDUPLEX)) | flags);
} else {
fxp_mdi_write(sc->csr, sc->phy_primary_addr, FXP_DP83840_BMCR,
(fxp_mdi_read(sc->csr, sc->phy_primary_addr, FXP_DP83840_BMCR) |
FXP_DP83840_BMCR_AUTOEN));
}
} else {
printf("fxp%d: warning: unsupported PHY, type = %d, addr = %d\n",
ifp->if_unit, sc->phy_primary_device, sc->phy_primary_addr);
}
ifp->if_flags |= IFF_RUNNING;
@ -1042,23 +1069,24 @@ fxp_add_rfabuf(sc, oldm)
return (m == oldm);
}
static int
static volatile int
fxp_mdi_read(csr, phy, reg)
struct fxp_csr *csr;
int phy;
int reg;
{
int count = 10000;
int value;
csr->mdi_control = (FXP_MDI_READ << 26) | (reg << 16) | (phy << 21);
while ((csr->mdi_control & 0x10000000) == 0 && count--)
DELAY(1);
while (((value = csr->mdi_control) & 0x10000000) == 0 && count--)
DELAY(10);
if (count <= 0)
printf("fxp_mdi_read: timed out\n");
return (csr->mdi_control & 0xffff);
return (value & 0xffff);
}
static void
@ -1073,8 +1101,8 @@ fxp_mdi_write(csr, phy, reg, value)
csr->mdi_control = (FXP_MDI_WRITE << 26) | (reg << 16) | (phy << 21)
| (value & 0xffff);
while ((csr->mdi_control & 10000000) == 0 && count--)
DELAY(1);
while ((csr->mdi_control & 0x10000000) == 0 && count--)
DELAY(10);
if (count <= 0)
printf("fxp_mdi_write: timed out\n");

View File

@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: if_fxpreg.h,v 1.6 1997/02/22 09:44:06 peter Exp $
* $Id: if_fxpreg.h,v 1.7 1997/03/17 11:08:16 davidg Exp $
*/
#define FXP_VENDORID_INTEL 0x8086
@ -292,6 +292,15 @@ struct fxp_stats {
#define FXP_PHY_DP83840 4
#define FXP_PHY_80C240 5
#define FXP_PHY_80C24 6
#define FXP_PHY_DP83840A 10
/*
* DP84830 PHY, BMCR Basic Mode Control Register
*/
#define FXP_DP83840_BMCR 0x0
#define FXP_DP83840_BMCR_FULLDUPLEX 0x0100
#define FXP_DP83840_BMCR_AUTOEN 0x1000
#define FXP_DP83840_BMCR_SPEED_100M 0x2000
/*
* DP84830 PHY, PCS Configuration Register