net: pcs: rearrange C73 functions to prepare for C37 support later
The current implementation for XPCS is validated for C73, so we rename them to have _c73 suffix and introduce a set of functions to use an_mode flag to switch between C73 and C37 AN later. Signed-off-by: Ong Boon Leong <boon.leong.ong@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
29c35da103
commit
07a4bc51fc
@ -125,22 +125,26 @@ static struct xpcs_id {
|
|||||||
u32 mask;
|
u32 mask;
|
||||||
const int *supported;
|
const int *supported;
|
||||||
const phy_interface_t *interface;
|
const phy_interface_t *interface;
|
||||||
|
int an_mode;
|
||||||
} xpcs_id_list[] = {
|
} xpcs_id_list[] = {
|
||||||
{
|
{
|
||||||
.id = SYNOPSYS_XPCS_USXGMII_ID,
|
.id = SYNOPSYS_XPCS_USXGMII_ID,
|
||||||
.mask = SYNOPSYS_XPCS_MASK,
|
.mask = SYNOPSYS_XPCS_MASK,
|
||||||
.supported = xpcs_usxgmii_features,
|
.supported = xpcs_usxgmii_features,
|
||||||
.interface = xpcs_usxgmii_interfaces,
|
.interface = xpcs_usxgmii_interfaces,
|
||||||
|
.an_mode = DW_AN_C73,
|
||||||
}, {
|
}, {
|
||||||
.id = SYNOPSYS_XPCS_10GKR_ID,
|
.id = SYNOPSYS_XPCS_10GKR_ID,
|
||||||
.mask = SYNOPSYS_XPCS_MASK,
|
.mask = SYNOPSYS_XPCS_MASK,
|
||||||
.supported = xpcs_10gkr_features,
|
.supported = xpcs_10gkr_features,
|
||||||
.interface = xpcs_10gkr_interfaces,
|
.interface = xpcs_10gkr_interfaces,
|
||||||
|
.an_mode = DW_AN_C73,
|
||||||
}, {
|
}, {
|
||||||
.id = SYNOPSYS_XPCS_XLGMII_ID,
|
.id = SYNOPSYS_XPCS_XLGMII_ID,
|
||||||
.mask = SYNOPSYS_XPCS_MASK,
|
.mask = SYNOPSYS_XPCS_MASK,
|
||||||
.supported = xpcs_xlgmii_features,
|
.supported = xpcs_xlgmii_features,
|
||||||
.interface = xpcs_xlgmii_interfaces,
|
.interface = xpcs_xlgmii_interfaces,
|
||||||
|
.an_mode = DW_AN_C73,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -195,9 +199,17 @@ static int xpcs_poll_reset(struct mdio_xpcs_args *xpcs, int dev)
|
|||||||
return (ret & MDIO_CTRL1_RESET) ? -ETIMEDOUT : 0;
|
return (ret & MDIO_CTRL1_RESET) ? -ETIMEDOUT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xpcs_soft_reset(struct mdio_xpcs_args *xpcs, int dev)
|
static int xpcs_soft_reset(struct mdio_xpcs_args *xpcs)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, dev;
|
||||||
|
|
||||||
|
switch (xpcs->an_mode) {
|
||||||
|
case DW_AN_C73:
|
||||||
|
dev = MDIO_MMD_PCS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
ret = xpcs_write(xpcs, dev, MDIO_CTRL1, MDIO_CTRL1_RESET);
|
ret = xpcs_write(xpcs, dev, MDIO_CTRL1, MDIO_CTRL1_RESET);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -212,8 +224,8 @@ static int xpcs_soft_reset(struct mdio_xpcs_args *xpcs, int dev)
|
|||||||
dev_warn(&(__xpcs)->bus->dev, ##__args); \
|
dev_warn(&(__xpcs)->bus->dev, ##__args); \
|
||||||
})
|
})
|
||||||
|
|
||||||
static int xpcs_read_fault(struct mdio_xpcs_args *xpcs,
|
static int xpcs_read_fault_c73(struct mdio_xpcs_args *xpcs,
|
||||||
struct phylink_link_state *state)
|
struct phylink_link_state *state)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -263,7 +275,7 @@ static int xpcs_read_fault(struct mdio_xpcs_args *xpcs,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xpcs_read_link(struct mdio_xpcs_args *xpcs, bool an)
|
static int xpcs_read_link_c73(struct mdio_xpcs_args *xpcs, bool an)
|
||||||
{
|
{
|
||||||
bool link = true;
|
bool link = true;
|
||||||
int ret;
|
int ret;
|
||||||
@ -357,7 +369,7 @@ static int xpcs_config_usxgmii(struct mdio_xpcs_args *xpcs, int speed)
|
|||||||
return xpcs_write_vpcs(xpcs, MDIO_CTRL1, ret | DW_USXGMII_RST);
|
return xpcs_write_vpcs(xpcs, MDIO_CTRL1, ret | DW_USXGMII_RST);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xpcs_config_aneg_c73(struct mdio_xpcs_args *xpcs)
|
static int _xpcs_config_aneg_c73(struct mdio_xpcs_args *xpcs)
|
||||||
{
|
{
|
||||||
int ret, adv;
|
int ret, adv;
|
||||||
|
|
||||||
@ -401,11 +413,11 @@ static int xpcs_config_aneg_c73(struct mdio_xpcs_args *xpcs)
|
|||||||
return xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV1, adv);
|
return xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV1, adv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xpcs_config_aneg(struct mdio_xpcs_args *xpcs)
|
static int xpcs_config_aneg_c73(struct mdio_xpcs_args *xpcs)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = xpcs_config_aneg_c73(xpcs);
|
ret = _xpcs_config_aneg_c73(xpcs);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -418,8 +430,8 @@ static int xpcs_config_aneg(struct mdio_xpcs_args *xpcs)
|
|||||||
return xpcs_write(xpcs, MDIO_MMD_AN, MDIO_CTRL1, ret);
|
return xpcs_write(xpcs, MDIO_MMD_AN, MDIO_CTRL1, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xpcs_aneg_done(struct mdio_xpcs_args *xpcs,
|
static int xpcs_aneg_done_c73(struct mdio_xpcs_args *xpcs,
|
||||||
struct phylink_link_state *state)
|
struct phylink_link_state *state)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -434,7 +446,7 @@ static int xpcs_aneg_done(struct mdio_xpcs_args *xpcs,
|
|||||||
|
|
||||||
/* Check if Aneg outcome is valid */
|
/* Check if Aneg outcome is valid */
|
||||||
if (!(ret & DW_C73_AN_ADV_SF)) {
|
if (!(ret & DW_C73_AN_ADV_SF)) {
|
||||||
xpcs_config_aneg(xpcs);
|
xpcs_config_aneg_c73(xpcs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,8 +456,8 @@ static int xpcs_aneg_done(struct mdio_xpcs_args *xpcs,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xpcs_read_lpa(struct mdio_xpcs_args *xpcs,
|
static int xpcs_read_lpa_c73(struct mdio_xpcs_args *xpcs,
|
||||||
struct phylink_link_state *state)
|
struct phylink_link_state *state)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -493,8 +505,8 @@ static int xpcs_read_lpa(struct mdio_xpcs_args *xpcs,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xpcs_resolve_lpa(struct mdio_xpcs_args *xpcs,
|
static void xpcs_resolve_lpa_c73(struct mdio_xpcs_args *xpcs,
|
||||||
struct phylink_link_state *state)
|
struct phylink_link_state *state)
|
||||||
{
|
{
|
||||||
int max_speed = xpcs_get_max_usxgmii_speed(state->lp_advertising);
|
int max_speed = xpcs_get_max_usxgmii_speed(state->lp_advertising);
|
||||||
|
|
||||||
@ -590,10 +602,49 @@ static int xpcs_config(struct mdio_xpcs_args *xpcs,
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (state->an_enabled) {
|
switch (xpcs->an_mode) {
|
||||||
ret = xpcs_config_aneg(xpcs);
|
case DW_AN_C73:
|
||||||
|
if (state->an_enabled) {
|
||||||
|
ret = xpcs_config_aneg_c73(xpcs);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xpcs_get_state_c73(struct mdio_xpcs_args *xpcs,
|
||||||
|
struct phylink_link_state *state)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Link needs to be read first ... */
|
||||||
|
state->link = xpcs_read_link_c73(xpcs, state->an_enabled) > 0 ? 1 : 0;
|
||||||
|
|
||||||
|
/* ... and then we check the faults. */
|
||||||
|
ret = xpcs_read_fault_c73(xpcs, state);
|
||||||
|
if (ret) {
|
||||||
|
ret = xpcs_soft_reset(xpcs);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
state->link = 0;
|
||||||
|
|
||||||
|
return xpcs_config(xpcs, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->an_enabled && xpcs_aneg_done_c73(xpcs, state)) {
|
||||||
|
state->an_complete = true;
|
||||||
|
xpcs_read_lpa_c73(xpcs, state);
|
||||||
|
xpcs_resolve_lpa_c73(xpcs, state);
|
||||||
|
} else if (state->an_enabled) {
|
||||||
|
state->link = 0;
|
||||||
|
} else if (state->link) {
|
||||||
|
xpcs_resolve_pma(xpcs, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -604,29 +655,14 @@ static int xpcs_get_state(struct mdio_xpcs_args *xpcs,
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Link needs to be read first ... */
|
switch (xpcs->an_mode) {
|
||||||
state->link = xpcs_read_link(xpcs, state->an_enabled) > 0 ? 1 : 0;
|
case DW_AN_C73:
|
||||||
|
ret = xpcs_get_state_c73(xpcs, state);
|
||||||
/* ... and then we check the faults. */
|
|
||||||
ret = xpcs_read_fault(xpcs, state);
|
|
||||||
if (ret) {
|
|
||||||
ret = xpcs_soft_reset(xpcs, MDIO_MMD_PCS);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
break;
|
||||||
state->link = 0;
|
default:
|
||||||
|
return -1;
|
||||||
return xpcs_config(xpcs, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->an_enabled && xpcs_aneg_done(xpcs, state)) {
|
|
||||||
state->an_complete = true;
|
|
||||||
xpcs_read_lpa(xpcs, state);
|
|
||||||
xpcs_resolve_lpa(xpcs, state);
|
|
||||||
} else if (state->an_enabled) {
|
|
||||||
state->link = 0;
|
|
||||||
} else if (state->link) {
|
|
||||||
xpcs_resolve_pma(xpcs, state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -676,6 +712,8 @@ static bool xpcs_check_features(struct mdio_xpcs_args *xpcs,
|
|||||||
for (i = 0; match->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++)
|
for (i = 0; match->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++)
|
||||||
set_bit(match->supported[i], xpcs->supported);
|
set_bit(match->supported[i], xpcs->supported);
|
||||||
|
|
||||||
|
xpcs->an_mode = match->an_mode;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,7 +730,7 @@ static int xpcs_probe(struct mdio_xpcs_args *xpcs, phy_interface_t interface)
|
|||||||
match = entry;
|
match = entry;
|
||||||
|
|
||||||
if (xpcs_check_features(xpcs, match, interface))
|
if (xpcs_check_features(xpcs, match, interface))
|
||||||
return xpcs_soft_reset(xpcs, MDIO_MMD_PCS);
|
return xpcs_soft_reset(xpcs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,10 +10,14 @@
|
|||||||
#include <linux/phy.h>
|
#include <linux/phy.h>
|
||||||
#include <linux/phylink.h>
|
#include <linux/phylink.h>
|
||||||
|
|
||||||
|
/* AN mode */
|
||||||
|
#define DW_AN_C73 1
|
||||||
|
|
||||||
struct mdio_xpcs_args {
|
struct mdio_xpcs_args {
|
||||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
|
__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
|
||||||
struct mii_bus *bus;
|
struct mii_bus *bus;
|
||||||
int addr;
|
int addr;
|
||||||
|
int an_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mdio_xpcs_ops {
|
struct mdio_xpcs_ops {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user