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. For users and applications that need to minimise boot time,
add a module parameter (genet.force_reneg) to control the renegotiation
step - by default it is enabled.

See: raspberrypi#3108

Signed-off-by: Phil Elwell <phil@raspberrypi.org>
  • Loading branch information
Phil Elwell committed Aug 5, 2019
1 parent dee4361 commit 80f24a4
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 = true;
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 80f24a4

Please sign in to comment.