Commit 07a4bc51 authored by Ong Boon Leong's avatar Ong Boon Leong Committed by David S. Miller

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: default avatarOng Boon Leong <boon.leong.ong@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 29c35da1
...@@ -125,22 +125,26 @@ static struct xpcs_id { ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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,27 +602,33 @@ static int xpcs_config(struct mdio_xpcs_args *xpcs, ...@@ -590,27 +602,33 @@ 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 (ret) if (state->an_enabled) {
return ret; ret = xpcs_config_aneg_c73(xpcs);
if (ret)
return ret;
}
break;
default:
return -1;
} }
return 0; return 0;
} }
static int xpcs_get_state(struct mdio_xpcs_args *xpcs, static int xpcs_get_state_c73(struct mdio_xpcs_args *xpcs,
struct phylink_link_state *state) struct phylink_link_state *state)
{ {
int ret; int ret;
/* Link needs to be read first ... */ /* Link needs to be read first ... */
state->link = xpcs_read_link(xpcs, state->an_enabled) > 0 ? 1 : 0; state->link = xpcs_read_link_c73(xpcs, state->an_enabled) > 0 ? 1 : 0;
/* ... and then we check the faults. */ /* ... and then we check the faults. */
ret = xpcs_read_fault(xpcs, state); ret = xpcs_read_fault_c73(xpcs, state);
if (ret) { if (ret) {
ret = xpcs_soft_reset(xpcs, MDIO_MMD_PCS); ret = xpcs_soft_reset(xpcs);
if (ret) if (ret)
return ret; return ret;
...@@ -619,10 +637,10 @@ static int xpcs_get_state(struct mdio_xpcs_args *xpcs, ...@@ -619,10 +637,10 @@ static int xpcs_get_state(struct mdio_xpcs_args *xpcs,
return xpcs_config(xpcs, state); return xpcs_config(xpcs, state);
} }
if (state->an_enabled && xpcs_aneg_done(xpcs, state)) { if (state->an_enabled && xpcs_aneg_done_c73(xpcs, state)) {
state->an_complete = true; state->an_complete = true;
xpcs_read_lpa(xpcs, state); xpcs_read_lpa_c73(xpcs, state);
xpcs_resolve_lpa(xpcs, state); xpcs_resolve_lpa_c73(xpcs, state);
} else if (state->an_enabled) { } else if (state->an_enabled) {
state->link = 0; state->link = 0;
} else if (state->link) { } else if (state->link) {
...@@ -632,6 +650,24 @@ static int xpcs_get_state(struct mdio_xpcs_args *xpcs, ...@@ -632,6 +650,24 @@ static int xpcs_get_state(struct mdio_xpcs_args *xpcs,
return 0; return 0;
} }
static int xpcs_get_state(struct mdio_xpcs_args *xpcs,
struct phylink_link_state *state)
{
int ret;
switch (xpcs->an_mode) {
case DW_AN_C73:
ret = xpcs_get_state_c73(xpcs, state);
if (ret)
return ret;
break;
default:
return -1;
}
return 0;
}
static int xpcs_link_up(struct mdio_xpcs_args *xpcs, int speed, static int xpcs_link_up(struct mdio_xpcs_args *xpcs, int speed,
phy_interface_t interface) phy_interface_t interface)
{ {
...@@ -676,6 +712,8 @@ static bool xpcs_check_features(struct mdio_xpcs_args *xpcs, ...@@ -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) ...@@ -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 @@ ...@@ -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 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment