From: Florian Fainelli <f.fainelli@gmail.com>
To: shh.xie@gmail.com, netdev@vger.kernel.org, davem@davemloft.net
Cc: Shaohui Xie <Shaohui.Xie@freescale.com>
Subject: Re: [PATCH] net: phy: adds backplane driver for Freescale's PCS PHY
Date: Mon, 28 Dec 2015 19:54:03 -0800 [thread overview]
Message-ID: <568203DB.20701@gmail.com> (raw)
In-Reply-To: <1450431054-5227-1-git-send-email-shh.xie@gmail.com>
Le 18/12/2015 01:30, shh.xie@gmail.com a écrit :
[snip]
> +struct training_state_machine {
> + bool bin_m1_late_early;
> + bool bin_long_late_early;
> + bool bin_m1_stop;
> + bool bin_long_stop;
> + bool tx_complete;
> + bool an_ok;
> + bool link_up;
> + bool running;
> + bool sent_init;
> + int m1_min_max_cnt;
> + int long_min_max_cnt;
Can you change this into a succession of enum values to make it clear
how many states there are, and how to get from one to the other?
[snip]
> +
> +static void init_state_machine(struct training_state_machine *s_m)
> +{
> + s_m->bin_m1_late_early = true;
> + s_m->bin_long_late_early = false;
> + s_m->bin_m1_stop = false;
> + s_m->bin_long_stop = false;
> + s_m->tx_complete = false;
> + s_m->an_ok = false;
> + s_m->link_up = false;
> + s_m->running = false;
> + s_m->sent_init = false;
> + s_m->m1_min_max_cnt = 0;
> + s_m->long_min_max_cnt = 0;
That alone is a good indication that your state machine is not readable.
> +}
> +
> +void tune_tecr0(struct fsl_xgkr_inst *inst)
> +{
> + struct per_lane_ctrl_status *reg_base;
> + u32 val;
> +
> + reg_base = (struct per_lane_ctrl_status *)inst->reg_base;
Typical practice is not to cast a register base address into a pointer
to a structure, but instead use offsets to the base register address,
which is less error prone and more readable, anything that uses
inst->reg_base in this driver is modeled after a structure pattern,
please fix that.
> +
> + val = TECR0_INIT |
> + inst->adpt_eq << ZERO_COE_SHIFT |
> + inst->ratio_preq << PRE_COE_SHIFT |
> + inst->ratio_pst1q << POST_COE_SHIFT;
> +
> + /* reset the lane */
> + iowrite32be(ioread32be(®_base->gcr0) & ~GCR0_RESET_MASK,
> + ®_base->gcr0);
> + udelay(1);
> + iowrite32be(val, ®_base->tecr0);
> + udelay(1);
> + /* unreset the lane */
> + iowrite32be(ioread32be(®_base->gcr0) | GCR0_RESET_MASK,
> + ®_base->gcr0);
> + udelay(1);
Since this is a reset control register, you might want to explore using
the reset controller subsystem in case this register serves multiple
peripherals.
[snip]
I skipped through all the state machine logic, but you should consider
trying to simplify it using different enum values and a switch() case()
statements to make it easy to audit and understand.
> +
> +static int fsl_backplane_probe(struct phy_device *phydev)
> +{
> + struct fsl_xgkr_inst *xgkr_inst;
> + struct device_node *child, *parent, *lane_node;
> + const char *lane_name;
> + int len;
> + int ret;
> + u32 mode;
> + u32 lane[2];
> +
> + child = phydev->dev.of_node;
> + parent = of_get_parent(child);
> + if (!parent) {
> + dev_err(&phydev->dev, "could not get parent node");
> + return 0;
> + }
> +
> + lane_name = of_get_property(parent, "lane-instance", &len);
> + if (!lane_name)
> + return 0;
> +
> + if (strstr(lane_name, "1000BASE-KX"))
> + mode = BACKPLANE_1G_KX;
> + else
> + mode = BACKPLANE_10G_KR;
That seems like I could put whatever value in "lane-instance" and as
long as it contains 1000BASE-KX we are golden, that does not sound very
robust nor well defined.
> +
> + lane_node = of_parse_phandle(child, "lane-handle", 0);
> + if (lane_node) {
Treat this as an error so you can return early and reduce indentation.
> + struct resource res_lane;
> +
> + ret = of_address_to_resource(lane_node, 0, &res_lane);
> + if (ret) {
> + dev_err(&phydev->dev, "could not obtain memory map\n");
> + return ret;
> + }
> +
> + ret = of_property_read_u32_array(child, "lane-range",
> + (u32 *)&lane, 2);
> + if (ret) {
> + dev_info(&phydev->dev, "could not get lane-range\n");
> + return -EINVAL;
> + }
Is not the standard "ranges" property usable here?
> +
> + phydev->priv = devm_ioremap_nocache(&phydev->dev,
> + res_lane.start + lane[0],
> + lane[1]);
What about the "reg" property here?
> +
> + if (!phydev->priv) {
> + of_node_put(lane_node);
> + return -EINVAL;
> + }
> + of_node_put(lane_node);
> + } else {
> + return -EINVAL;
> + }
> +
> + if (mode == BACKPLANE_1G_KX) {
> + phydev->speed = SPEED_1000;
> + /* configure the lane for 1000BASE-KX */
> + lane_set_1gkx(phydev->priv);
> + return 0;
> + }
> +
> + xgkr_inst = kzalloc(sizeof(*xgkr_inst), GFP_KERNEL);
> + if (!xgkr_inst)
> + goto mem_err1;
devm_kzalloc()?
> +
> + xgkr_inst->reg_base = phydev->priv;
> + xgkr_inst->bus = phydev->bus;
> + xgkr_inst->phydev = phydev;
> + phydev->priv = xgkr_inst;
> +
> + if (mode == BACKPLANE_10G_KR) {
> + phydev->speed = SPEED_10000;
> + init_inst(xgkr_inst, 1);
> + INIT_DELAYED_WORK(&xgkr_inst->xgkr_wk, xgkr_wq_state_machine);
> + }
> +
> + return 0;
> +mem_err1:
> + dev_err(&phydev->dev, "failed to allocate memory\n");
> + return -ENOMEM;
> +}
> +
> +static int fsl_backplane_aneg_done(struct phy_device *phydev)
> +{
> + return 1;
> +}
> +
> +static int fsl_backplane_config_aneg(struct phy_device *phydev)
> +{
> + struct fsl_xgkr_inst *xgkr_inst = (struct fsl_xgkr_inst *)phydev->priv;
No casting needed from void *
[snip]
> +
> +static int fsl_backplane_read_status(struct phy_device *phydev)
> +{
> + int val;
> +
> + phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
> + val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
> +
> + if (val & AN_LNK_UP_MASK)
> + phydev->link = 1;
> + else
> + phydev->link = 0;
This sounds fairly generic, candidate for a helper function?
--
Florian
next prev parent reply other threads:[~2015-12-29 3:54 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-18 9:30 [PATCH] net: phy: adds backplane driver for Freescale's PCS PHY shh.xie
2015-12-18 11:32 ` kbuild test robot
2015-12-18 12:02 ` Andrew Lunn
2015-12-21 12:17 ` Shaohui Xie
2015-12-22 10:43 ` Andrew Lunn
2015-12-22 12:33 ` Shaohui Xie
2015-12-29 3:54 ` Florian Fainelli [this message]
2015-12-29 8:18 ` Shaohui Xie
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=568203DB.20701@gmail.com \
--to=f.fainelli@gmail.com \
--cc=Shaohui.Xie@freescale.com \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
--cc=shh.xie@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.