Skip to content

Commit

Permalink
net: bcmgenet: Workaround for Pi 4B network issue
Browse files Browse the repository at this point in the history
Some combinations of Pi 4Bs and Ethernet switches don't reliably get a
DCHP-assigned IP address, leaving the unit with a self=assigned 169.254
address.

Forcing renegotiation has been found to be an effective workaround, so
add an automatic renegotiation after the link comes up for the first
time; enable it with genet.force_reneg=y - by default it is disabled.

See: raspberrypi#3108

Signed-off-by: Phil Elwell <phil@raspberrypi.org>
  • Loading branch information
Phil Elwell committed Aug 5, 2019
1 parent a08305b commit 6bcff20
Showing 1 changed file with 22 additions and 0 deletions.
22 changes: 22 additions & 0 deletions drivers/net/ethernet/broadcom/genet/bcmgenet.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@
#define GENET_RDMA_REG_OFF (priv->hw_params->rdma_offset + \
TOTAL_DESC * DMA_DESC_SIZE)

static bool force_reneg = false;
module_param(force_reneg, bool, 0444);
MODULE_PARM_DESC(force_reneg, "Force a renegotiation after the initial link-up");

static inline void bcmgenet_writel(u32 value, void __iomem *offset)
{
/* MIPS chips strapped for BE will automagically configure the
Expand Down Expand Up @@ -2610,6 +2614,7 @@ static void bcmgenet_irq_task(struct work_struct *work)
unsigned int status;
struct bcmgenet_priv *priv = container_of(
work, struct bcmgenet_priv, bcmgenet_irq_work);
static int first_link = 1;

netif_dbg(priv, intr, priv->dev, "%s\n", __func__);

Expand All @@ -2622,6 +2627,23 @@ static void bcmgenet_irq_task(struct work_struct *work)
if (status & UMAC_IRQ_LINK_EVENT) {
priv->dev->phydev->link = !!(status & UMAC_IRQ_LINK_UP);
phy_mac_interrupt(priv->dev->phydev);

if (priv->dev->phydev->link && first_link) {
first_link = 0;
/*
* HACK: Some Pi4Bs, when paired with some switches,
* come up in a strange state where they are unable to
* transmit, causing them to fail to get an IP address.
* Although the failure mechanism is not yet understood,
* forcing renegotiation at this point has been shown
* to be effective in avoiding the problem.
*/
if (force_reneg) {
dev_info(&priv->pdev->dev,
"Forcing renegotiation\n");
genphy_restart_aneg(priv->dev->phydev);
}
}
}
}

Expand Down

0 comments on commit 6bcff20

Please sign in to comment.