Commit 1f863ce5 authored by Jiawen Wu's avatar Jiawen Wu Committed by Paolo Abeni
Browse files

net: txgbe: optimize the flow to setup PHY for AML devices



To adapt to new firmware for AML devices, the driver should send the
"SET_LINK_CMD" to the firmware only once when switching PHY interface
mode, and no longer needs to re-trigger PHY configuration based on the
RX signal interrupt (TXGBE_GPIOBIT_3).

In previous firmware versions, the PHY was configured only after receiving
"SET_LINK_CMD", and might remain incomplete if the RX signal was lost.
To handle this case, the driver used TXGBE_GPIOBIT_3 interrupt to resend
the command. This workaround is no longer necessary with the new firmware.

And the unknown link speed is permitted in the mailbox buffer.

Signed-off-by: default avatarJiawen Wu <jiawenwu@trustnetic.com>
Link: https://patch.msgid.link/20251014061726.36660-3-jiawenwu@trustnetic.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent af3fce9f
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -1271,8 +1271,6 @@ struct wx {

	/* PHY stuff */
	bool notify_down;
	int adv_speed;
	int adv_duplex;
	unsigned int link;
	int speed;
	int duplex;
+14 −36
Original line number Diff line number Diff line
@@ -19,8 +19,8 @@ void txgbe_gpio_init_aml(struct wx *wx)
{
	u32 status;

	wr32(wx, WX_GPIO_INTTYPE_LEVEL, TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3);
	wr32(wx, WX_GPIO_INTEN, TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3);
	wr32(wx, WX_GPIO_INTTYPE_LEVEL, TXGBE_GPIOBIT_2);
	wr32(wx, WX_GPIO_INTEN, TXGBE_GPIOBIT_2);

	status = rd32(wx, WX_GPIO_INTSTATUS);
	for (int i = 0; i < 6; i++) {
@@ -42,11 +42,6 @@ irqreturn_t txgbe_gpio_irq_handler_aml(int irq, void *data)
		wr32(wx, WX_GPIO_EOI, TXGBE_GPIOBIT_2);
		wx_service_event_schedule(wx);
	}
	if (status & TXGBE_GPIOBIT_3) {
		set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags);
		wx_service_event_schedule(wx);
		wr32(wx, WX_GPIO_EOI, TXGBE_GPIOBIT_3);
	}

	wr32(wx, WX_GPIO_INTMASK, 0);
	return IRQ_HANDLED;
@@ -96,6 +91,9 @@ static int txgbe_set_phy_link_hostif(struct wx *wx, int speed, int autoneg, int
	case SPEED_10000:
		buffer.speed = TXGBE_LINK_SPEED_10GB_FULL;
		break;
	default:
		buffer.speed = TXGBE_LINK_SPEED_UNKNOWN;
		break;
	}

	buffer.fec_mode = TXGBE_PHY_FEC_AUTO;
@@ -106,19 +104,18 @@ static int txgbe_set_phy_link_hostif(struct wx *wx, int speed, int autoneg, int
					 WX_HI_COMMAND_TIMEOUT, true);
}

static void txgbe_get_link_capabilities(struct wx *wx)
static void txgbe_get_link_capabilities(struct wx *wx, int *speed, int *duplex)
{
	struct txgbe *txgbe = wx->priv;

	if (test_bit(PHY_INTERFACE_MODE_25GBASER, txgbe->sfp_interfaces))
		wx->adv_speed = SPEED_25000;
		*speed = SPEED_25000;
	else if (test_bit(PHY_INTERFACE_MODE_10GBASER, txgbe->sfp_interfaces))
		wx->adv_speed = SPEED_10000;
		*speed = SPEED_10000;
	else
		wx->adv_speed = SPEED_UNKNOWN;
		*speed = SPEED_UNKNOWN;

	wx->adv_duplex = wx->adv_speed == SPEED_UNKNOWN ?
			 DUPLEX_HALF : DUPLEX_FULL;
	*duplex = *speed == SPEED_UNKNOWN ? DUPLEX_HALF : DUPLEX_FULL;
}

static void txgbe_get_phy_link(struct wx *wx, int *speed)
@@ -138,23 +135,11 @@ static void txgbe_get_phy_link(struct wx *wx, int *speed)

int txgbe_set_phy_link(struct wx *wx)
{
	int speed, err;
	u32 gpio;
	int speed, duplex, err;

	/* Check RX signal */
	gpio = rd32(wx, WX_GPIO_EXT);
	if (gpio & TXGBE_GPIOBIT_3)
		return -ENODEV;
	txgbe_get_link_capabilities(wx, &speed, &duplex);

	txgbe_get_link_capabilities(wx);
	if (wx->adv_speed == SPEED_UNKNOWN)
		return -ENODEV;

	txgbe_get_phy_link(wx, &speed);
	if (speed == wx->adv_speed)
		return 0;

	err = txgbe_set_phy_link_hostif(wx, wx->adv_speed, 0, wx->adv_duplex);
	err = txgbe_set_phy_link_hostif(wx, speed, 0, duplex);
	if (err) {
		wx_err(wx, "Failed to setup link\n");
		return err;
@@ -230,14 +215,7 @@ int txgbe_identify_sfp(struct wx *wx)
		return -ENODEV;
	}

	err = txgbe_sfp_to_linkmodes(wx, id);
	if (err)
		return err;

	if (gpio & TXGBE_GPIOBIT_3)
		set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags);

	return 0;
	return txgbe_sfp_to_linkmodes(wx, id);
}

void txgbe_setup_link(struct wx *wx)
+1 −0
Original line number Diff line number Diff line
@@ -314,6 +314,7 @@ void txgbe_up(struct wx *wx);
int txgbe_setup_tc(struct net_device *dev, u8 tc);
void txgbe_do_reset(struct net_device *netdev);

#define TXGBE_LINK_SPEED_UNKNOWN        0
#define TXGBE_LINK_SPEED_10GB_FULL      4
#define TXGBE_LINK_SPEED_25GB_FULL      0x10