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

Commit cfa51b9d authored by Maxim Levitsky's avatar Maxim Levitsky Committed by Jeff Garzik
Browse files

dmfe: Fix link detection



Add link detection

Signed-off-by: default avatarMaxim Levitsky <maximlevitsky@gmail.com>
Cc: Valerie Henson <val_henson@linux.intel.com>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 4dc68f3d
Loading
Loading
Loading
Loading
+40 −18
Original line number Original line Diff line number Diff line
@@ -248,7 +248,6 @@ struct dmfe_board_info {
	u8 media_mode;			/* user specify media mode */
	u8 media_mode;			/* user specify media mode */
	u8 op_mode;			/* real work media mode */
	u8 op_mode;			/* real work media mode */
	u8 phy_addr;
	u8 phy_addr;
	u8 link_failed;			/* Ever link failed */
	u8 wait_reset;			/* Hardware failed, need to reset */
	u8 wait_reset;			/* Hardware failed, need to reset */
	u8 dm910x_chk_mode;		/* Operating mode check */
	u8 dm910x_chk_mode;		/* Operating mode check */
	u8 first_in_callback;		/* Flag to record state */
	u8 first_in_callback;		/* Flag to record state */
@@ -447,6 +446,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
	dev->poll_controller = &poll_dmfe;
	dev->poll_controller = &poll_dmfe;
#endif
#endif
	dev->ethtool_ops = &netdev_ethtool_ops;
	dev->ethtool_ops = &netdev_ethtool_ops;
	netif_carrier_off(dev);
	spin_lock_init(&db->lock);
	spin_lock_init(&db->lock);


	pci_read_config_dword(pdev, 0x50, &pci_pmr);
	pci_read_config_dword(pdev, 0x50, &pci_pmr);
@@ -541,7 +541,6 @@ static int dmfe_open(struct DEVICE *dev)
	db->tx_packet_cnt = 0;
	db->tx_packet_cnt = 0;
	db->tx_queue_cnt = 0;
	db->tx_queue_cnt = 0;
	db->rx_avail_cnt = 0;
	db->rx_avail_cnt = 0;
	db->link_failed = 1;
	db->wait_reset = 0;
	db->wait_reset = 0;


	db->first_in_callback = 0;
	db->first_in_callback = 0;
@@ -1082,6 +1081,7 @@ static void netdev_get_drvinfo(struct net_device *dev,


static const struct ethtool_ops netdev_ethtool_ops = {
static const struct ethtool_ops netdev_ethtool_ops = {
	.get_drvinfo		= netdev_get_drvinfo,
	.get_drvinfo		= netdev_get_drvinfo,
	.get_link               = ethtool_op_get_link,
};
};


/*
/*
@@ -1097,6 +1097,8 @@ static void dmfe_timer(unsigned long data)
	struct dmfe_board_info *db = netdev_priv(dev);
	struct dmfe_board_info *db = netdev_priv(dev);
 	unsigned long flags;
 	unsigned long flags;


	int link_ok, link_ok_phy;

	DMFE_DBUG(0, "dmfe_timer()", 0);
	DMFE_DBUG(0, "dmfe_timer()", 0);
	spin_lock_irqsave(&db->lock, flags);
	spin_lock_irqsave(&db->lock, flags);


@@ -1168,15 +1170,35 @@ static void dmfe_timer(unsigned long data)
		(db->chip_revision == 0x02000010)) ) {
		(db->chip_revision == 0x02000010)) ) {
		/* DM9102A Chip */
		/* DM9102A Chip */
		if (tmp_cr12 & 2)
		if (tmp_cr12 & 2)
			tmp_cr12 = 0x0;		/* Link failed */
			link_ok = 0;
		else
			link_ok = 1;
	}
	else
	else
			tmp_cr12 = 0x3;	/* Link OK */
		/*0x43 is used instead of 0x3 because bit 6 should represent
			link status of external PHY */
		link_ok = (tmp_cr12 & 0x43) ? 1 : 0;


	/* If chip reports that link is failed it could be because external
		PHY link status pin is not conected correctly to chip
		To be sure ask PHY too.
	*/

	/* need a dummy read because of PHY's register latch*/
	phy_read (db->ioaddr, db->phy_addr, 1, db->chip_id);
	link_ok_phy = (phy_read (db->ioaddr,
		       db->phy_addr, 1, db->chip_id) & 0x4) ? 1 : 0;

	if (link_ok_phy != link_ok) {
		DMFE_DBUG (0, "PHY and chip report different link status", 0);
		link_ok = link_ok | link_ok_phy;
 	}
 	}


	if ( !(tmp_cr12 & 0x3) && !db->link_failed ) {
	if ( !link_ok && netif_carrier_ok(dev)) {
		/* Link Failed */
		/* Link Failed */
		DMFE_DBUG(0, "Link Failed", tmp_cr12);
		DMFE_DBUG(0, "Link Failed", tmp_cr12);
		db->link_failed = 1;
		netif_carrier_off(dev);


		/* For Force 10/100M Half/Full mode: Enable Auto-Nego mode */
		/* For Force 10/100M Half/Full mode: Enable Auto-Nego mode */
		/* AUTO or force 1M Homerun/Longrun don't need */
		/* AUTO or force 1M Homerun/Longrun don't need */
@@ -1191,17 +1213,17 @@ static void dmfe_timer(unsigned long data)
			db->cr6_data&=~0x00000200;	/* bit9=0, HD mode */
			db->cr6_data&=~0x00000200;	/* bit9=0, HD mode */
			update_cr6(db->cr6_data, db->ioaddr);
			update_cr6(db->cr6_data, db->ioaddr);
		}
		}
	} else
	} else if (!netif_carrier_ok(dev)) {
		if ((tmp_cr12 & 0x3) && db->link_failed) {

		DMFE_DBUG(0, "Link link OK", tmp_cr12);
		DMFE_DBUG(0, "Link link OK", tmp_cr12);
			db->link_failed = 0;


		/* Auto Sense Speed */
		/* Auto Sense Speed */
			if ( (db->media_mode & DMFE_AUTO) &&
		if ( !(db->media_mode & DMFE_AUTO) || !dmfe_sense_speed(db)) {
				dmfe_sense_speed(db) )
			netif_carrier_on(dev);
				db->link_failed = 1;
			SHOW_MEDIA_TYPE(db->op_mode);
		}

		dmfe_process_mode(db);
		dmfe_process_mode(db);
			/* SHOW_MEDIA_TYPE(db->op_mode); */
	}
	}


	/* HPNA remote command check */
	/* HPNA remote command check */
@@ -1248,7 +1270,7 @@ static void dmfe_dynamic_reset(struct DEVICE *dev)
	db->tx_packet_cnt = 0;
	db->tx_packet_cnt = 0;
	db->tx_queue_cnt = 0;
	db->tx_queue_cnt = 0;
	db->rx_avail_cnt = 0;
	db->rx_avail_cnt = 0;
	db->link_failed = 1;
	netif_carrier_off(dev);
	db->wait_reset = 0;
	db->wait_reset = 0;


	/* Re-initilize DM910X board */
	/* Re-initilize DM910X board */