Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 21b645e4 authored by Al Viro's avatar Al Viro Committed by Jeff Garzik
Browse files

dl2k: ANAR, ANLPAR fixes



same story, different registers...

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent d50956af
Loading
Loading
Loading
Loading
+42 −32
Original line number Diff line number Diff line
@@ -1453,7 +1453,7 @@ mii_wait_link (struct net_device *dev, int wait)
static int
mii_get_media (struct net_device *dev)
{
	ANAR_t negotiate;
	__u16 negotiate;
	BMSR_t bmsr;
	MSCR_t mscr;
	MSSR_t mssr;
@@ -1469,7 +1469,7 @@ mii_get_media (struct net_device *dev)
			/* Auto-Negotiation not completed */
			return -1;
		}
		negotiate.image = mii_read (dev, phy_addr, MII_ANAR) &
		negotiate = mii_read (dev, phy_addr, MII_ANAR) &
			mii_read (dev, phy_addr, MII_ANLPAR);
		mscr.image = mii_read (dev, phy_addr, MII_MSCR);
		mssr.image = mii_read (dev, phy_addr, MII_MSSR);
@@ -1481,27 +1481,27 @@ mii_get_media (struct net_device *dev)
			np->speed = 1000;
			np->full_duplex = 0;
			printk (KERN_INFO "Auto 1000 Mbps, Half duplex\n");
		} else if (negotiate.bits.media_100BX_FD) {
		} else if (negotiate & MII_ANAR_100BX_FD) {
			np->speed = 100;
			np->full_duplex = 1;
			printk (KERN_INFO "Auto 100 Mbps, Full duplex\n");
		} else if (negotiate.bits.media_100BX_HD) {
		} else if (negotiate & MII_ANAR_100BX_HD) {
			np->speed = 100;
			np->full_duplex = 0;
			printk (KERN_INFO "Auto 100 Mbps, Half duplex\n");
		} else if (negotiate.bits.media_10BT_FD) {
		} else if (negotiate & MII_ANAR_10BT_FD) {
			np->speed = 10;
			np->full_duplex = 1;
			printk (KERN_INFO "Auto 10 Mbps, Full duplex\n");
		} else if (negotiate.bits.media_10BT_HD) {
		} else if (negotiate & MII_ANAR_10BT_HD) {
			np->speed = 10;
			np->full_duplex = 0;
			printk (KERN_INFO "Auto 10 Mbps, Half duplex\n");
		}
		if (negotiate.bits.pause) {
		if (negotiate & MII_ANAR_PAUSE) {
			np->tx_flow &= 1;
			np->rx_flow &= 1;
		} else if (negotiate.bits.asymmetric) {
		} else if (negotiate & MII_ANAR_ASYMMETRIC) {
			np->tx_flow = 0;
			np->rx_flow &= 1;
		}
@@ -1542,7 +1542,7 @@ mii_set_media (struct net_device *dev)
	PHY_SCR_t pscr;
	__u16 bmcr;
	BMSR_t bmsr;
	ANAR_t anar;
	__u16 anar;
	int phy_addr;
	struct netdev_private *np;
	np = netdev_priv(dev);
@@ -1552,15 +1552,24 @@ mii_set_media (struct net_device *dev)
	if (np->an_enable) {
		/* Advertise capabilities */
		bmsr.image = mii_read (dev, phy_addr, MII_BMSR);
		anar.image = mii_read (dev, phy_addr, MII_ANAR);
		anar.bits.media_100BX_FD = bmsr.bits.media_100BX_FD;
		anar.bits.media_100BX_HD = bmsr.bits.media_100BX_HD;
		anar.bits.media_100BT4 = bmsr.bits.media_100BT4;
		anar.bits.media_10BT_FD = bmsr.bits.media_10BT_FD;
		anar.bits.media_10BT_HD = bmsr.bits.media_10BT_HD;
		anar.bits.pause = 1;
		anar.bits.asymmetric = 1;
		mii_write (dev, phy_addr, MII_ANAR, anar.image);
		anar = mii_read (dev, phy_addr, MII_ANAR) &
			     ~MII_ANAR_100BX_FD &
			     ~MII_ANAR_100BX_HD &
			     ~MII_ANAR_100BT4 &
			     ~MII_ANAR_10BT_FD &
			     ~MII_ANAR_10BT_HD;
		if (bmsr.bits.media_100BX_FD)
			anar |= MII_ANAR_100BX_FD;
		if (bmsr.bits.media_100BX_HD)
			anar |= MII_ANAR_100BX_HD;
		if (bmsr.bits.media_100BT4)
			anar |= MII_ANAR_100BT4;
		if (bmsr.bits.media_10BT_FD)
			anar |= MII_ANAR_10BT_FD;
		if (bmsr.bits.media_10BT_HD)
			anar |= MII_ANAR_10BT_HD;
		anar |= MII_ANAR_PAUSE | MII_ANAR_ASYMMETRIC;
		mii_write (dev, phy_addr, MII_ANAR, anar);

		/* Enable Auto crossover */
		pscr.image = mii_read (dev, phy_addr, MII_PHY_SCR);
@@ -1621,7 +1630,7 @@ mii_set_media (struct net_device *dev)
static int
mii_get_media_pcs (struct net_device *dev)
{
	ANAR_PCS_t negotiate;
	__u16 negotiate;
	BMSR_t bmsr;
	int phy_addr;
	struct netdev_private *np;
@@ -1635,20 +1644,20 @@ mii_get_media_pcs (struct net_device *dev)
			/* Auto-Negotiation not completed */
			return -1;
		}
		negotiate.image = mii_read (dev, phy_addr, PCS_ANAR) &
		negotiate = mii_read (dev, phy_addr, PCS_ANAR) &
			mii_read (dev, phy_addr, PCS_ANLPAR);
		np->speed = 1000;
		if (negotiate.bits.full_duplex) {
		if (negotiate & PCS_ANAR_FULL_DUPLEX) {
			printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n");
			np->full_duplex = 1;
		} else {
			printk (KERN_INFO "Auto 1000 Mbps, half duplex\n");
			np->full_duplex = 0;
		}
		if (negotiate.bits.pause) {
		if (negotiate & PCS_ANAR_PAUSE) {
			np->tx_flow &= 1;
			np->rx_flow &= 1;
		} else if (negotiate.bits.asymmetric) {
		} else if (negotiate & PCS_ANAR_ASYMMETRIC) {
			np->tx_flow = 0;
			np->rx_flow &= 1;
		}
@@ -1679,7 +1688,7 @@ mii_set_media_pcs (struct net_device *dev)
{
	__u16 bmcr;
	ESR_t esr;
	ANAR_PCS_t anar;
	__u16 anar;
	int phy_addr;
	struct netdev_private *np;
	np = netdev_priv(dev);
@@ -1689,14 +1698,15 @@ mii_set_media_pcs (struct net_device *dev)
	if (np->an_enable) {
		/* Advertise capabilities */
		esr.image = mii_read (dev, phy_addr, PCS_ESR);
		anar.image = mii_read (dev, phy_addr, MII_ANAR);
		anar.bits.half_duplex =
			esr.bits.media_1000BT_HD | esr.bits.media_1000BX_HD;
		anar.bits.full_duplex =
			esr.bits.media_1000BT_FD | esr.bits.media_1000BX_FD;
		anar.bits.pause = 1;
		anar.bits.asymmetric = 1;
		mii_write (dev, phy_addr, MII_ANAR, anar.image);
		anar = mii_read (dev, phy_addr, MII_ANAR) &
			~PCS_ANAR_HALF_DUPLEX &
			~PCS_ANAR_FULL_DUPLEX;
		if (esr.bits.media_1000BT_HD | esr.bits.media_1000BX_HD)
			anar |= PCS_ANAR_HALF_DUPLEX;
		if (esr.bits.media_1000BT_FD | esr.bits.media_1000BX_FD)
			anar |= PCS_ANAR_FULL_DUPLEX;
		anar |= PCS_ANAR_PAUSE | PCS_ANAR_ASYMMETRIC;
		mii_write (dev, phy_addr, MII_ANAR, anar);

		/* Soft reset PHY */
		mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET);
+0 −66
Original line number Diff line number Diff line
@@ -357,24 +357,6 @@ enum _mii_bmsr {
};

/* ANAR */
typedef union t_MII_ANAR {
	u16 image;
	struct {
		u16 selector:5;	// bit 4:0
		u16 media_10BT_HD:1;	// bit 5
		u16 media_10BT_FD:1;	// bit 6
		u16 media_100BX_HD:1;	// bit 7
		u16 media_100BX_FD:1;	// bit 8
		u16 media_100BT4:1;	// bit 9
		u16 pause:1;	// bit 10
		u16 asymmetric:1;	// bit 11
		u16 _bit12:1;	// bit 12
		u16 remote_fault:1;	// bit 13
		u16 _bit14:1;	// bit 14
		u16 next_page:1;	// bit 15
	} bits;
} ANAR_t, *PANAR_t;

enum _mii_anar {
	MII_ANAR_NEXT_PAGE = 0x8000,
	MII_ANAR_REMOTE_FAULT = 0x4000,
@@ -390,24 +372,6 @@ enum _mii_anar {
};

/* ANLPAR */
typedef union t_MII_ANLPAR {
	u16 image;
	struct {
		u16 selector:5;	// bit 4:0
		u16 media_10BT_HD:1;	// bit 5
		u16 media_10BT_FD:1;	// bit 6
		u16 media_100BX_HD:1;	// bit 7
		u16 media_100BX_FD:1;	// bit 8
		u16 media_100BT4:1;	// bit 9
		u16 pause:1;	// bit 10
		u16 asymmetric:1;	// bit 11
		u16 _bit12:1;	// bit 12
		u16 remote_fault:1;	// bit 13
		u16 _bit14:1;	// bit 14
		u16 next_page:1;	// bit 15
	} bits;
} ANLPAR_t, *PANLPAR_t;

enum _mii_anlpar {
	MII_ANLPAR_NEXT_PAGE = MII_ANAR_NEXT_PAGE,
	MII_ANLPAR_REMOTE_FAULT = MII_ANAR_REMOTE_FAULT,
@@ -539,21 +503,6 @@ typedef enum t_MII_ADMIN_STATUS {
/* PCS control and status registers bitmap as the same as MII */
/* PCS Extended Status register bitmap as the same as MII */
/* PCS ANAR */
typedef union t_PCS_ANAR {
	u16 image;
	struct {
		u16 _bit_4_0:5;		// bit 4:0
		u16 full_duplex:1;	// bit 5
		u16 half_duplex:1;	// bit 6
		u16 asymmetric:1;	// bit 7
		u16 pause:1;		// bit 8
		u16 _bit_11_9:3;	// bit 11:9
		u16 remote_fault:2;	// bit 13:12
		u16 _bit_14:1;		// bit 14
		u16 next_page:1;	// bit 15
	} bits;
} ANAR_PCS_t, *PANAR_PCS_t;

enum _pcs_anar {
	PCS_ANAR_NEXT_PAGE = 0x8000,
	PCS_ANAR_REMOTE_FAULT = 0x3000,
@@ -563,21 +512,6 @@ enum _pcs_anar {
	PCS_ANAR_FULL_DUPLEX = 0x0020,
};
/* PCS ANLPAR */
typedef union t_PCS_ANLPAR {
	u16 image;
	struct {
		u16 _bit_4_0:5;		// bit 4:0
		u16 full_duplex:1;	// bit 5
		u16 half_duplex:1;	// bit 6
		u16 asymmetric:1;	// bit 7
		u16 pause:1;		// bit 8
		u16 _bit_11_9:3;	// bit 11:9
		u16 remote_fault:2;	// bit 13:12
		u16 _bit_14:1;		// bit 14
		u16 next_page:1;	// bit 15
	} bits;
} ANLPAR_PCS_t, *PANLPAR_PCS_t;

enum _pcs_anlpar {
	PCS_ANLPAR_NEXT_PAGE = PCS_ANAR_NEXT_PAGE,
	PCS_ANLPAR_REMOTE_FAULT = PCS_ANAR_REMOTE_FAULT,