Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b28f389d authored by Matt Carlson's avatar Matt Carlson Committed by David S. Miller
Browse files

tg3: Reduce UMP event collision window



The tg3 driver needs to submit a few phy register values to the UMP
firmware each time the link state changes.  Up until now, the driver
would wait for the previous event to complete, then proceed to gather
data through a series of phy accesses.  Since phy accesses are
relatively slow, it is possible for another thread to attempt to submit
its own event while the UMP code is still construction its message.

This patch seeks to minimize the collision window as much as possible by
preloading the phy data.

Signed-off-by: default avatarMatt Carlson <mcarlson@broadcom.com>
Reviewed-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 42278224
Loading
Loading
Loading
Loading
+26 −16
Original line number Diff line number Diff line
@@ -1453,33 +1453,23 @@ static void tg3_wait_for_event_ack(struct tg3 *tp)
}

/* tp->lock is held. */
static void tg3_ump_link_report(struct tg3 *tp)
static void tg3_phy_gather_ump_data(struct tg3 *tp, u32 *data)
{
	u32 reg;
	u32 val;

	if (!tg3_flag(tp, 5780_CLASS) || !tg3_flag(tp, ENABLE_ASF))
		return;

	tg3_wait_for_event_ack(tp);

	tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_LINK_UPDATE);

	tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 14);
	u32 reg, val;

	val = 0;
	if (!tg3_readphy(tp, MII_BMCR, &reg))
		val = reg << 16;
	if (!tg3_readphy(tp, MII_BMSR, &reg))
		val |= (reg & 0xffff);
	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, val);
	*data++ = val;

	val = 0;
	if (!tg3_readphy(tp, MII_ADVERTISE, &reg))
		val = reg << 16;
	if (!tg3_readphy(tp, MII_LPA, &reg))
		val |= (reg & 0xffff);
	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 4, val);
	*data++ = val;

	val = 0;
	if (!(tp->phy_flags & TG3_PHYFLG_MII_SERDES)) {
@@ -1488,13 +1478,33 @@ static void tg3_ump_link_report(struct tg3 *tp)
		if (!tg3_readphy(tp, MII_STAT1000, &reg))
			val |= (reg & 0xffff);
	}
	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 8, val);
	*data++ = val;

	if (!tg3_readphy(tp, MII_PHYADDR, &reg))
		val = reg << 16;
	else
		val = 0;
	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val);
	*data++ = val;
}

/* tp->lock is held. */
static void tg3_ump_link_report(struct tg3 *tp)
{
	u32 data[4];

	if (!tg3_flag(tp, 5780_CLASS) || !tg3_flag(tp, ENABLE_ASF))
		return;

	tg3_phy_gather_ump_data(tp, data);

	tg3_wait_for_event_ack(tp);

	tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_LINK_UPDATE);
	tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 14);
	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 0x0, data[0]);
	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 0x4, data[1]);
	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 0x8, data[2]);
	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 0xc, data[3]);

	tg3_generate_fw_event(tp);
}