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