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

Commit a64def41 authored by Lendacky, Thomas's avatar Lendacky, Thomas Committed by David S. Miller
Browse files

amd-xgbe: Prepare for introduction of clause 37 autoneg



Prepare for the future introduction of clause 37 auto-negotiation by
updating the current auto-negotiation related functions to identify
them as clause 73 functions. Move interrupt enablement to the
enable/disable auto-negotiation functions. Update what will be common
routines to check for the current type of AN and process accordingly.

Signed-off-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e57f7a3f
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -1052,6 +1052,11 @@
#endif
#endif


/* MDIO mask values */
/* MDIO mask values */
#define XGBE_AN_CL73_INT_CMPLT		BIT(0)
#define XGBE_AN_CL73_INC_LINK		BIT(1)
#define XGBE_AN_CL73_PG_RCV		BIT(2)
#define XGBE_AN_CL73_INT_MASK		0x07

#define XGBE_XNP_MCF_NULL_MESSAGE	0x001
#define XGBE_XNP_MCF_NULL_MESSAGE	0x001
#define XGBE_XNP_ACK_PROCESSED		BIT(12)
#define XGBE_XNP_ACK_PROCESSED		BIT(12)
#define XGBE_XNP_MP_FORMATTED		BIT(13)
#define XGBE_XNP_MP_FORMATTED		BIT(13)
+155 −80
Original line number Original line Diff line number Diff line
@@ -125,7 +125,33 @@
#include "xgbe.h"
#include "xgbe.h"
#include "xgbe-common.h"
#include "xgbe-common.h"


static void xgbe_an_enable_kr_training(struct xgbe_prv_data *pdata)
static void xgbe_an73_clear_interrupts(struct xgbe_prv_data *pdata)
{
	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);
}

static void xgbe_an73_disable_interrupts(struct xgbe_prv_data *pdata)
{
	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0);
}

static void xgbe_an73_enable_interrupts(struct xgbe_prv_data *pdata)
{
	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, XGBE_AN_CL73_INT_MASK);
}

static void xgbe_an_enable_interrupts(struct xgbe_prv_data *pdata)
{
	switch (pdata->an_mode) {
	case XGBE_AN_MODE_CL73:
		xgbe_an73_enable_interrupts(pdata);
		break;
	default:
		break;
	}
}

static void xgbe_an73_enable_kr_training(struct xgbe_prv_data *pdata)
{
{
	unsigned int reg;
	unsigned int reg;


@@ -135,7 +161,7 @@ static void xgbe_an_enable_kr_training(struct xgbe_prv_data *pdata)
	XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
	XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
}
}


static void xgbe_an_disable_kr_training(struct xgbe_prv_data *pdata)
static void xgbe_an73_disable_kr_training(struct xgbe_prv_data *pdata)
{
{
	unsigned int reg;
	unsigned int reg;


@@ -148,7 +174,7 @@ static void xgbe_an_disable_kr_training(struct xgbe_prv_data *pdata)
static void xgbe_kr_mode(struct xgbe_prv_data *pdata)
static void xgbe_kr_mode(struct xgbe_prv_data *pdata)
{
{
	/* Enable KR training */
	/* Enable KR training */
	xgbe_an_enable_kr_training(pdata);
	xgbe_an73_enable_kr_training(pdata);


	/* Set MAC to 10G speed */
	/* Set MAC to 10G speed */
	pdata->hw_if.set_speed(pdata, SPEED_10000);
	pdata->hw_if.set_speed(pdata, SPEED_10000);
@@ -160,7 +186,7 @@ static void xgbe_kr_mode(struct xgbe_prv_data *pdata)
static void xgbe_kx_2500_mode(struct xgbe_prv_data *pdata)
static void xgbe_kx_2500_mode(struct xgbe_prv_data *pdata)
{
{
	/* Disable KR training */
	/* Disable KR training */
	xgbe_an_disable_kr_training(pdata);
	xgbe_an73_disable_kr_training(pdata);


	/* Set MAC to 2.5G speed */
	/* Set MAC to 2.5G speed */
	pdata->hw_if.set_speed(pdata, SPEED_2500);
	pdata->hw_if.set_speed(pdata, SPEED_2500);
@@ -172,7 +198,7 @@ static void xgbe_kx_2500_mode(struct xgbe_prv_data *pdata)
static void xgbe_kx_1000_mode(struct xgbe_prv_data *pdata)
static void xgbe_kx_1000_mode(struct xgbe_prv_data *pdata)
{
{
	/* Disable KR training */
	/* Disable KR training */
	xgbe_an_disable_kr_training(pdata);
	xgbe_an73_disable_kr_training(pdata);


	/* Set MAC to 1G speed */
	/* Set MAC to 1G speed */
	pdata->hw_if.set_speed(pdata, SPEED_1000);
	pdata->hw_if.set_speed(pdata, SPEED_1000);
@@ -232,7 +258,8 @@ static bool xgbe_use_mode(struct xgbe_prv_data *pdata,
	return pdata->phy_if.phy_impl.use_mode(pdata, mode);
	return pdata->phy_if.phy_impl.use_mode(pdata, mode);
}
}


static void xgbe_set_an(struct xgbe_prv_data *pdata, bool enable, bool restart)
static void xgbe_an73_set(struct xgbe_prv_data *pdata, bool enable,
			  bool restart)
{
{
	unsigned int reg;
	unsigned int reg;


@@ -248,21 +275,45 @@ static void xgbe_set_an(struct xgbe_prv_data *pdata, bool enable, bool restart)
	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_CTRL1, reg);
	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_CTRL1, reg);
}
}


static void xgbe_restart_an(struct xgbe_prv_data *pdata)
static void xgbe_an73_restart(struct xgbe_prv_data *pdata)
{
{
	xgbe_set_an(pdata, true, true);
	xgbe_an73_enable_interrupts(pdata);
	xgbe_an73_set(pdata, true, true);


	netif_dbg(pdata, link, pdata->netdev, "AN enabled/restarted\n");
	netif_dbg(pdata, link, pdata->netdev, "CL73 AN enabled/restarted\n");
}
}


static void xgbe_disable_an(struct xgbe_prv_data *pdata)
static void xgbe_an73_disable(struct xgbe_prv_data *pdata)
{
{
	xgbe_set_an(pdata, false, false);
	xgbe_an73_set(pdata, false, false);
	xgbe_an73_disable_interrupts(pdata);

	netif_dbg(pdata, link, pdata->netdev, "CL73 AN disabled\n");
}

static void xgbe_an_restart(struct xgbe_prv_data *pdata)
{
	switch (pdata->an_mode) {
	case XGBE_AN_MODE_CL73:
		xgbe_an73_restart(pdata);
		break;
	default:
		break;
	}
}


	netif_dbg(pdata, link, pdata->netdev, "AN disabled\n");
static void xgbe_an_disable(struct xgbe_prv_data *pdata)
{
	switch (pdata->an_mode) {
	case XGBE_AN_MODE_CL73:
		xgbe_an73_disable(pdata);
		break;
	default:
		break;
	}
}
}


static enum xgbe_an xgbe_an_tx_training(struct xgbe_prv_data *pdata,
static enum xgbe_an xgbe_an73_tx_training(struct xgbe_prv_data *pdata,
					  enum xgbe_rx *state)
					  enum xgbe_rx *state)
{
{
	unsigned int ad_reg, lp_reg, reg;
	unsigned int ad_reg, lp_reg, reg;
@@ -304,7 +355,7 @@ static enum xgbe_an xgbe_an_tx_training(struct xgbe_prv_data *pdata,
	return XGBE_AN_PAGE_RECEIVED;
	return XGBE_AN_PAGE_RECEIVED;
}
}


static enum xgbe_an xgbe_an_tx_xnp(struct xgbe_prv_data *pdata,
static enum xgbe_an xgbe_an73_tx_xnp(struct xgbe_prv_data *pdata,
				     enum xgbe_rx *state)
				     enum xgbe_rx *state)
{
{
	u16 msg;
	u16 msg;
@@ -321,7 +372,7 @@ static enum xgbe_an xgbe_an_tx_xnp(struct xgbe_prv_data *pdata,
	return XGBE_AN_PAGE_RECEIVED;
	return XGBE_AN_PAGE_RECEIVED;
}
}


static enum xgbe_an xgbe_an_rx_bpa(struct xgbe_prv_data *pdata,
static enum xgbe_an xgbe_an73_rx_bpa(struct xgbe_prv_data *pdata,
				     enum xgbe_rx *state)
				     enum xgbe_rx *state)
{
{
	unsigned int link_support;
	unsigned int link_support;
@@ -341,11 +392,11 @@ static enum xgbe_an xgbe_an_rx_bpa(struct xgbe_prv_data *pdata,


	return ((ad_reg & XGBE_XNP_NP_EXCHANGE) ||
	return ((ad_reg & XGBE_XNP_NP_EXCHANGE) ||
		(lp_reg & XGBE_XNP_NP_EXCHANGE))
		(lp_reg & XGBE_XNP_NP_EXCHANGE))
	       ? xgbe_an_tx_xnp(pdata, state)
	       ? xgbe_an73_tx_xnp(pdata, state)
	       : xgbe_an_tx_training(pdata, state);
	       : xgbe_an73_tx_training(pdata, state);
}
}


static enum xgbe_an xgbe_an_rx_xnp(struct xgbe_prv_data *pdata,
static enum xgbe_an xgbe_an73_rx_xnp(struct xgbe_prv_data *pdata,
				     enum xgbe_rx *state)
				     enum xgbe_rx *state)
{
{
	unsigned int ad_reg, lp_reg;
	unsigned int ad_reg, lp_reg;
@@ -356,11 +407,11 @@ static enum xgbe_an xgbe_an_rx_xnp(struct xgbe_prv_data *pdata,


	return ((ad_reg & XGBE_XNP_NP_EXCHANGE) ||
	return ((ad_reg & XGBE_XNP_NP_EXCHANGE) ||
		(lp_reg & XGBE_XNP_NP_EXCHANGE))
		(lp_reg & XGBE_XNP_NP_EXCHANGE))
	       ? xgbe_an_tx_xnp(pdata, state)
	       ? xgbe_an73_tx_xnp(pdata, state)
	       : xgbe_an_tx_training(pdata, state);
	       : xgbe_an73_tx_training(pdata, state);
}
}


static enum xgbe_an xgbe_an_page_received(struct xgbe_prv_data *pdata)
static enum xgbe_an xgbe_an73_page_received(struct xgbe_prv_data *pdata)
{
{
	enum xgbe_rx *state;
	enum xgbe_rx *state;
	unsigned long an_timeout;
	unsigned long an_timeout;
@@ -379,7 +430,7 @@ static enum xgbe_an xgbe_an_page_received(struct xgbe_prv_data *pdata)
			pdata->an_start = jiffies;
			pdata->an_start = jiffies;


			netif_dbg(pdata, link, pdata->netdev,
			netif_dbg(pdata, link, pdata->netdev,
				  "AN timed out, resetting state\n");
				  "CL73 AN timed out, resetting state\n");
		}
		}
	}
	}


@@ -388,11 +439,11 @@ static enum xgbe_an xgbe_an_page_received(struct xgbe_prv_data *pdata)


	switch (*state) {
	switch (*state) {
	case XGBE_RX_BPA:
	case XGBE_RX_BPA:
		ret = xgbe_an_rx_bpa(pdata, state);
		ret = xgbe_an73_rx_bpa(pdata, state);
		break;
		break;


	case XGBE_RX_XNP:
	case XGBE_RX_XNP:
		ret = xgbe_an_rx_xnp(pdata, state);
		ret = xgbe_an73_rx_xnp(pdata, state);
		break;
		break;


	default:
	default:
@@ -402,7 +453,7 @@ static enum xgbe_an xgbe_an_page_received(struct xgbe_prv_data *pdata)
	return ret;
	return ret;
}
}


static enum xgbe_an xgbe_an_incompat_link(struct xgbe_prv_data *pdata)
static enum xgbe_an xgbe_an73_incompat_link(struct xgbe_prv_data *pdata)
{
{
	/* Be sure we aren't looping trying to negotiate */
	/* Be sure we aren't looping trying to negotiate */
	if (xgbe_in_kr_mode(pdata)) {
	if (xgbe_in_kr_mode(pdata)) {
@@ -424,23 +475,19 @@ static enum xgbe_an xgbe_an_incompat_link(struct xgbe_prv_data *pdata)
			return XGBE_AN_NO_LINK;
			return XGBE_AN_NO_LINK;
	}
	}


	xgbe_disable_an(pdata);
	xgbe_an73_disable(pdata);


	xgbe_switch_mode(pdata);
	xgbe_switch_mode(pdata);


	xgbe_restart_an(pdata);
	xgbe_an73_restart(pdata);


	return XGBE_AN_INCOMPAT_LINK;
	return XGBE_AN_INCOMPAT_LINK;
}
}


static irqreturn_t xgbe_an_isr(int irq, void *data)
static void xgbe_an73_isr(struct xgbe_prv_data *pdata)
{
{
	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;

	netif_dbg(pdata, intr, pdata->netdev, "AN interrupt received\n");

	/* Disable AN interrupts */
	/* Disable AN interrupts */
	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0);
	xgbe_an73_disable_interrupts(pdata);


	/* Save the interrupt(s) that fired */
	/* Save the interrupt(s) that fired */
	pdata->an_int = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INT);
	pdata->an_int = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INT);
@@ -452,8 +499,22 @@ static irqreturn_t xgbe_an_isr(int irq, void *data)
		queue_work(pdata->an_workqueue, &pdata->an_irq_work);
		queue_work(pdata->an_workqueue, &pdata->an_irq_work);
	} else {
	} else {
		/* Enable AN interrupts */
		/* Enable AN interrupts */
		XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK,
		xgbe_an73_enable_interrupts(pdata);
			    XGBE_AN_INT_MASK);
	}
}

static irqreturn_t xgbe_an_isr(int irq, void *data)
{
	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;

	netif_dbg(pdata, intr, pdata->netdev, "AN interrupt received\n");

	switch (pdata->an_mode) {
	case XGBE_AN_MODE_CL73:
		xgbe_an73_isr(pdata);
		break;
	default:
		break;
	}
	}


	return IRQ_HANDLED;
	return IRQ_HANDLED;
@@ -492,28 +553,23 @@ static const char *xgbe_state_as_string(enum xgbe_an state)
	}
	}
}
}


static void xgbe_an_state_machine(struct work_struct *work)
static void xgbe_an73_state_machine(struct xgbe_prv_data *pdata)
{
{
	struct xgbe_prv_data *pdata = container_of(work,
						   struct xgbe_prv_data,
						   an_work);
	enum xgbe_an cur_state = pdata->an_state;
	enum xgbe_an cur_state = pdata->an_state;


	mutex_lock(&pdata->an_mutex);

	if (!pdata->an_int)
	if (!pdata->an_int)
		goto out;
		return;


next_int:
next_int:
	if (pdata->an_int & XGBE_AN_PG_RCV) {
	if (pdata->an_int & XGBE_AN_CL73_PG_RCV) {
		pdata->an_state = XGBE_AN_PAGE_RECEIVED;
		pdata->an_state = XGBE_AN_PAGE_RECEIVED;
		pdata->an_int &= ~XGBE_AN_PG_RCV;
		pdata->an_int &= ~XGBE_AN_CL73_PG_RCV;
	} else if (pdata->an_int & XGBE_AN_INC_LINK) {
	} else if (pdata->an_int & XGBE_AN_CL73_INC_LINK) {
		pdata->an_state = XGBE_AN_INCOMPAT_LINK;
		pdata->an_state = XGBE_AN_INCOMPAT_LINK;
		pdata->an_int &= ~XGBE_AN_INC_LINK;
		pdata->an_int &= ~XGBE_AN_CL73_INC_LINK;
	} else if (pdata->an_int & XGBE_AN_INT_CMPLT) {
	} else if (pdata->an_int & XGBE_AN_CL73_INT_CMPLT) {
		pdata->an_state = XGBE_AN_COMPLETE;
		pdata->an_state = XGBE_AN_COMPLETE;
		pdata->an_int &= ~XGBE_AN_INT_CMPLT;
		pdata->an_int &= ~XGBE_AN_CL73_INT_CMPLT;
	} else {
	} else {
		pdata->an_state = XGBE_AN_ERROR;
		pdata->an_state = XGBE_AN_ERROR;
	}
	}
@@ -521,7 +577,7 @@ static void xgbe_an_state_machine(struct work_struct *work)
	pdata->an_result = pdata->an_state;
	pdata->an_result = pdata->an_state;


again:
again:
	netif_dbg(pdata, link, pdata->netdev, "AN %s\n",
	netif_dbg(pdata, link, pdata->netdev, "CL73 AN %s\n",
		  xgbe_state_as_string(pdata->an_state));
		  xgbe_state_as_string(pdata->an_state));


	cur_state = pdata->an_state;
	cur_state = pdata->an_state;
@@ -532,14 +588,14 @@ static void xgbe_an_state_machine(struct work_struct *work)
		break;
		break;


	case XGBE_AN_PAGE_RECEIVED:
	case XGBE_AN_PAGE_RECEIVED:
		pdata->an_state = xgbe_an_page_received(pdata);
		pdata->an_state = xgbe_an73_page_received(pdata);
		pdata->an_supported++;
		pdata->an_supported++;
		break;
		break;


	case XGBE_AN_INCOMPAT_LINK:
	case XGBE_AN_INCOMPAT_LINK:
		pdata->an_supported = 0;
		pdata->an_supported = 0;
		pdata->parallel_detect = 0;
		pdata->parallel_detect = 0;
		pdata->an_state = xgbe_an_incompat_link(pdata);
		pdata->an_state = xgbe_an73_incompat_link(pdata);
		break;
		break;


	case XGBE_AN_COMPLETE:
	case XGBE_AN_COMPLETE:
@@ -558,14 +614,14 @@ static void xgbe_an_state_machine(struct work_struct *work)


	if (pdata->an_state == XGBE_AN_NO_LINK) {
	if (pdata->an_state == XGBE_AN_NO_LINK) {
		pdata->an_int = 0;
		pdata->an_int = 0;
		XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);
		xgbe_an73_clear_interrupts(pdata);
	} else if (pdata->an_state == XGBE_AN_ERROR) {
	} else if (pdata->an_state == XGBE_AN_ERROR) {
		netdev_err(pdata->netdev,
		netdev_err(pdata->netdev,
			   "error during auto-negotiation, state=%u\n",
			   "error during auto-negotiation, state=%u\n",
			   cur_state);
			   cur_state);


		pdata->an_int = 0;
		pdata->an_int = 0;
		XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);
		xgbe_an73_clear_interrupts(pdata);
	}
	}


	if (pdata->an_state >= XGBE_AN_COMPLETE) {
	if (pdata->an_state >= XGBE_AN_COMPLETE) {
@@ -575,7 +631,7 @@ static void xgbe_an_state_machine(struct work_struct *work)
		pdata->kx_state = XGBE_RX_BPA;
		pdata->kx_state = XGBE_RX_BPA;
		pdata->an_start = 0;
		pdata->an_start = 0;


		netif_dbg(pdata, link, pdata->netdev, "AN result: %s\n",
		netif_dbg(pdata, link, pdata->netdev, "CL73 AN result: %s\n",
			  xgbe_state_as_string(pdata->an_result));
			  xgbe_state_as_string(pdata->an_result));
	}
	}


@@ -585,14 +641,29 @@ static void xgbe_an_state_machine(struct work_struct *work)
	if (pdata->an_int)
	if (pdata->an_int)
		goto next_int;
		goto next_int;


out:
	xgbe_an73_enable_interrupts(pdata);
	/* Enable AN interrupts on the way out */
}
	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, XGBE_AN_INT_MASK);

static void xgbe_an_state_machine(struct work_struct *work)
{
	struct xgbe_prv_data *pdata = container_of(work,
						   struct xgbe_prv_data,
						   an_work);

	mutex_lock(&pdata->an_mutex);

	switch (pdata->an_mode) {
	case XGBE_AN_MODE_CL73:
		xgbe_an73_state_machine(pdata);
		break;
	default:
		break;
	}


	mutex_unlock(&pdata->an_mutex);
	mutex_unlock(&pdata->an_mutex);
}
}


static void xgbe_an_init(struct xgbe_prv_data *pdata)
static void xgbe_an73_init(struct xgbe_prv_data *pdata)
{
{
	unsigned int reg;
	unsigned int reg;


@@ -637,7 +708,20 @@ static void xgbe_an_init(struct xgbe_prv_data *pdata)


	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);


	netif_dbg(pdata, link, pdata->netdev, "AN initialized\n");
	netif_dbg(pdata, link, pdata->netdev, "CL73 AN initialized\n");
}

static void xgbe_an_init(struct xgbe_prv_data *pdata)
{
	/* Set up advertisement registers based on current settings */
	pdata->an_mode = pdata->phy_if.phy_impl.an_mode(pdata);
	switch (pdata->an_mode) {
	case XGBE_AN_MODE_CL73:
		xgbe_an73_init(pdata);
		break;
	default:
		break;
	}
}
}


static const char *xgbe_phy_fc_string(struct xgbe_prv_data *pdata)
static const char *xgbe_phy_fc_string(struct xgbe_prv_data *pdata)
@@ -732,7 +816,7 @@ static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata)
	netif_dbg(pdata, link, pdata->netdev, "fixed PHY configuration\n");
	netif_dbg(pdata, link, pdata->netdev, "fixed PHY configuration\n");


	/* Disable auto-negotiation */
	/* Disable auto-negotiation */
	xgbe_disable_an(pdata);
	xgbe_an_disable(pdata);


	/* Set specified mode for specified speed */
	/* Set specified mode for specified speed */
	mode = pdata->phy_if.phy_impl.get_mode(pdata, pdata->phy.speed);
	mode = pdata->phy_if.phy_impl.get_mode(pdata, pdata->phy.speed);
@@ -781,10 +865,10 @@ static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata)
	}
	}


	/* Disable and stop any in progress auto-negotiation */
	/* Disable and stop any in progress auto-negotiation */
	xgbe_disable_an(pdata);
	xgbe_an_disable(pdata);


	/* Clear any auto-negotitation interrupts */
	/* Clear any auto-negotitation interrupts */
	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);
	xgbe_an73_clear_interrupts(pdata);


	pdata->an_result = XGBE_AN_READY;
	pdata->an_result = XGBE_AN_READY;
	pdata->an_state = XGBE_AN_READY;
	pdata->an_state = XGBE_AN_READY;
@@ -794,11 +878,8 @@ static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata)
	/* Re-enable auto-negotiation interrupt */
	/* Re-enable auto-negotiation interrupt */
	enable_irq(pdata->an_irq);
	enable_irq(pdata->an_irq);


	/* Set up advertisement registers based on current settings */
	xgbe_an_init(pdata);
	xgbe_an_init(pdata);

	xgbe_an_restart(pdata);
	/* Enable and start auto-negotiation */
	xgbe_restart_an(pdata);


	return 0;
	return 0;
}
}
@@ -926,10 +1007,7 @@ static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
	pdata->phy_started = 0;
	pdata->phy_started = 0;


	/* Disable auto-negotiation */
	/* Disable auto-negotiation */
	xgbe_disable_an(pdata);
	xgbe_an_disable(pdata);

	/* Disable auto-negotiation interrupts */
	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0);


	devm_free_irq(pdata->dev, pdata->an_irq, pdata);
	devm_free_irq(pdata->dev, pdata->an_irq, pdata);


@@ -977,11 +1055,8 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata)
	/* Indicate the PHY is up and running */
	/* Indicate the PHY is up and running */
	pdata->phy_started = 1;
	pdata->phy_started = 1;


	/* Set up advertisement registers based on current settings */
	xgbe_an_init(pdata);
	xgbe_an_init(pdata);

	xgbe_an_enable_interrupts(pdata);
	/* Enable auto-negotiation interrupts */
	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0x07);


	return xgbe_phy_config_aneg(pdata);
	return xgbe_phy_config_aneg(pdata);


@@ -1003,10 +1078,10 @@ static int xgbe_phy_reset(struct xgbe_prv_data *pdata)
		return ret;
		return ret;


	/* Disable auto-negotiation for now */
	/* Disable auto-negotiation for now */
	xgbe_disable_an(pdata);
	xgbe_an_disable(pdata);


	/* Clear auto-negotiation interrupts */
	/* Clear auto-negotiation interrupts */
	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);
	xgbe_an73_clear_interrupts(pdata);


	return 0;
	return 0;
}
}
+7 −0
Original line number Original line Diff line number Diff line
@@ -295,6 +295,11 @@ static enum xgbe_mode xgbe_phy_an_outcome(struct xgbe_prv_data *pdata)
	return mode;
	return mode;
}
}


static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata)
{
	return XGBE_AN_MODE_CL73;
}

static void xgbe_phy_pcs_power_cycle(struct xgbe_prv_data *pdata)
static void xgbe_phy_pcs_power_cycle(struct xgbe_prv_data *pdata)
{
{
	unsigned int reg;
	unsigned int reg;
@@ -814,6 +819,8 @@ void xgbe_init_function_ptrs_phy_v1(struct xgbe_phy_if *phy_if)
	phy_impl->switch_mode		= xgbe_phy_switch_mode;
	phy_impl->switch_mode		= xgbe_phy_switch_mode;
	phy_impl->cur_mode		= xgbe_phy_cur_mode;
	phy_impl->cur_mode		= xgbe_phy_cur_mode;


	phy_impl->an_mode		= xgbe_phy_an_mode;

	phy_impl->an_outcome		= xgbe_phy_an_outcome;
	phy_impl->an_outcome		= xgbe_phy_an_outcome;


	phy_impl->kr_training_pre	= xgbe_phy_kr_training_pre;
	phy_impl->kr_training_pre	= xgbe_phy_kr_training_pre;
+9 −5
Original line number Original line Diff line number Diff line
@@ -263,11 +263,6 @@
#define XGBE_AN_MS_TIMEOUT		500
#define XGBE_AN_MS_TIMEOUT		500
#define XGBE_LINK_TIMEOUT		10
#define XGBE_LINK_TIMEOUT		10


#define XGBE_AN_INT_CMPLT		0x01
#define XGBE_AN_INC_LINK		0x02
#define XGBE_AN_PG_RCV			0x04
#define XGBE_AN_INT_MASK		0x07

struct xgbe_prv_data;
struct xgbe_prv_data;


struct xgbe_packet_data {
struct xgbe_packet_data {
@@ -470,6 +465,11 @@ enum xgbe_speed {
	XGBE_SPEEDS,
	XGBE_SPEEDS,
};
};


enum xgbe_an_mode {
	XGBE_AN_MODE_CL73 = 0,
	XGBE_AN_MODE_NONE,
};

enum xgbe_an {
enum xgbe_an {
	XGBE_AN_READY = 0,
	XGBE_AN_READY = 0,
	XGBE_AN_PAGE_RECEIVED,
	XGBE_AN_PAGE_RECEIVED,
@@ -699,6 +699,9 @@ struct xgbe_phy_impl_if {
	/* Retrieve current mode */
	/* Retrieve current mode */
	enum xgbe_mode (*cur_mode)(struct xgbe_prv_data *);
	enum xgbe_mode (*cur_mode)(struct xgbe_prv_data *);


	/* Retrieve current auto-negotiation mode */
	enum xgbe_an_mode (*an_mode)(struct xgbe_prv_data *);

	/* Process results of auto-negotiation */
	/* Process results of auto-negotiation */
	enum xgbe_mode (*an_outcome)(struct xgbe_prv_data *);
	enum xgbe_mode (*an_outcome)(struct xgbe_prv_data *);


@@ -968,6 +971,7 @@ struct xgbe_prv_data {
	unsigned int parallel_detect;
	unsigned int parallel_detect;
	unsigned int fec_ability;
	unsigned int fec_ability;
	unsigned long an_start;
	unsigned long an_start;
	enum xgbe_an_mode an_mode;


	unsigned int lpm_ctrl;		/* CTRL1 for resume */
	unsigned int lpm_ctrl;		/* CTRL1 for resume */