Re: infinite spin in RT when booting with DHCP on

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Steve,

On 02/02/2012 07:10 PM, Steven Rostedt wrote:
That said, as I think I know the problem, can you try this patch to see
if it fixes things. This patch is a TOTAL HACK! Not for inclusion. It's
racy and buggy. I didn't even compile it because I couldn't get the
configs to enable FEC, and I was too lazy to set up my cross compiler to
test it. ;-)

Yes, this hack fixes things as long as I boot with the Ethernet cable plugged in. In this case the autonegotiation is launched and fec_enet_start_xmit() waits until it completes. From then on, the hack never triggers again (comp_set is 0) and disconnecting-reconnecting the cable or asking for a new DHCP address seems to work normally.

If I boot with the cable disconnected the driver seems to be trapped at the wait_for_completion() and connecting the cable later simply doesn't allow the autonegotiation to complete.

--
Héctor Palacios

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 885d8ba..9368dc2 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -231,6 +231,9 @@ static void *swap_buffer(void *bufaddr, int len)
  	return bufaddr;
  }

+static DECLARE_COMPLETION(kick_ksoftirq);
+static int comp_set;
+
  static netdev_tx_t
  fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
  {
@@ -243,6 +246,9 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
  	unsigned long flags;

  	if (!fep->link) {
+		if (comp_set)
+			wait_for_completion(&kick_ksoftirq);
+
  		/* Link is down or autonegotiation is in progress. */
  		return NETDEV_TX_BUSY;
  	}
@@ -794,6 +800,8 @@ static void fec_enet_adjust_link(struct net_device *ndev)
  	/* Link on or off change */
  	if (phy_dev->link != fep->link) {
  		fep->link = phy_dev->link;
+		complete(&kick_ksoftirq);
+		comp_set = 0;
  		if (phy_dev->link)
  			fec_restart(ndev, phy_dev->duplex);
  		else
@@ -914,6 +922,9 @@ static int fec_enet_mii_probe(struct net_device *ndev)
  	fep->link = 0;
  	fep->full_duplex = 0;

+	init_completion(&kick_ksoftirq);
+	comp_set = 1;
+
  	printk(KERN_INFO "%s: Freescale FEC PHY driver [%s] "
  		"(mii_bus:phy_addr=%s, irq=%d)\n", ndev->name,
  		fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev),


--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [RT Stable]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]

  Powered by Linux