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. ;-)
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