From: Sabrina Dubroca <sd@queasysnail.net>
To: "Radu Pirea (NXP OSS)" <radu-nicolae.pirea@oss.nxp.com>
Cc: andrew@lunn.ch, hkallweit1@gmail.com, linux@armlinux.org.uk,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, richardcochran@gmail.com,
sebastian.tobuschat@nxp.com, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [RFC net-next v2 3/5] net: phy: nxp-c45-tja11xx add MACsec support
Date: Fri, 25 Aug 2023 14:52:57 +0200 [thread overview]
Message-ID: <ZOikKUjRvces_vVj@hog> (raw)
In-Reply-To: <20230824091615.191379-4-radu-nicolae.pirea@oss.nxp.com>
[Some of the questions I'm asking are probably dumb since I don't know
anything about phy drivers. Sorry if that's the case.]
General code organization nit: I think it would be easier to review
the code if helpers functions were grouped by the type of object they
work on. All the RXSA-related functions together, all the TXSA
functions together, same for RXSC and then TXSC/SecY. Right now I see
some RXSA functions in a group of TXSA functions, another in the
middle of a group of RXSC functions. It makes navigating through the
code a bit less convenient.
Another nit: for consistency, it would be nice to stick to either
"tx_sa" or "txsa" (same for rxsa and rxsc) in function names.
2023-08-24, 12:16:13 +0300, Radu Pirea (NXP OSS) wrote:
> +static int nxp_c45_macsec_write(struct phy_device *phydev, u16 reg, u32 val)
> +{
> + WARN_ON_ONCE(reg % 4);
> +
> + reg = reg / 2;
> + phy_write_mmd(phydev, MDIO_MMD_VEND2,
> + VEND1_MACSEC_BASE + reg, val);
> + phy_write_mmd(phydev, MDIO_MMD_VEND2,
> + VEND1_MACSEC_BASE + reg + 1, val >> 16);
Can these calls fail? ie, do you need to handle errors like in
nxp_c45_macsec_read (and then in callers of nxp_c45_macsec_write)?
I see that no caller of nxp_c45_macsec_read actually checks the return
value, so maybe those errors don't matter.
[...]
> +void nxp_c45_macsec_config_init(struct phy_device *phydev)
> +{
> + if (!phydev->macsec_ops)
> + return;
> +
> + phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PORT_FUNC_ENABLES,
> + MACSEC_EN | ADAPTER_EN);
The calls to phy_set_bits_mmd() in nxp_c45_config_intr() have error
handling. Does this need error handling as well?
[...]
> +static bool nxp_c45_port_valid(struct nxp_c45_secy *phy_secy, u16 port)
> +{
> + if (phy_secy->secy->tx_sc.end_station &&
> + __be16_to_cpu((__force __be16)port) != 1)
> + return false;
> +
> + return true;
> +}
> +
> +static bool nxp_c45_rx_sc_valid(struct nxp_c45_secy *phy_secy,
> + struct macsec_rx_sc *rx_sc)
> +{
> + u16 port = (__force u64)rx_sc->sci >> (ETH_ALEN * 8);
u64 sci = be64_to_cpu((__force __be64)rx_sc->sci);
u16 port = (u16)sci;
And then drop the __be16_to_cpu conversion from nxp_c45_port_valid
> +
> + if (phy_secy->point_to_point && phy_secy->secy_id != 0)
> + return false;
> +
> + return nxp_c45_port_valid(phy_secy, port);
> +}
> +
> +static bool nxp_c45_secy_cfg_valid(struct nxp_c45_secy *phy_secy, bool can_ptp)
> +{
> + u16 port = (__force u64)phy_secy->secy->sci >> (ETH_ALEN * 8);
u64 sci = be64_to_cpu((__force __be64)rx_sc->sci);
u16 port = (u16)sci;
> + if (phy_secy->secy->tx_sc.scb)
> + return false;
[...]
> +static int nxp_c45_update_tx_sc_secy_cfg(struct phy_device *phydev,
> + struct nxp_c45_secy *phy_secy)
> +{
[...]
> + phydev_dbg(phydev, "scb %s\n",
> + phy_secy->secy->tx_sc.scb ? "on" : "off");
> + if (phy_secy->secy->tx_sc.scb)
> + cfg |= MACSEC_TXSC_CFG_SCI;
> + else
> + cfg &= ~MACSEC_TXSC_CFG_SCI;
Should that be called MACSEC_TXSC_CFG_SCB? I had to check that it
wasn't using the wrong constant, using "SCI" for "SCB" (when SCI is
already a well-defined thing in macsec) confused me.
> +
> + nxp_c45_macsec_write(phydev, MACSEC_TXSC_CFG, cfg);
> +
> + return 0;
> +}
> +
[...]
> +static int nxp_c45_set_rxsa_key(struct macsec_context *ctx, bool key_a)
> +{
> + u32 *salt = (u32 *)ctx->sa.rx_sa->key.salt.bytes;
> + const struct nxp_c45_macsec_sa_regs *sa_regs;
> + u32 ssci = (__force u32)ctx->sa.rx_sa->ssci;
> + u32 key_size = ctx->secy->key_len / 4;
> + u32 salt_size = MACSEC_SALT_LEN / 4;
> + u32 *key = (u32 *)ctx->sa.key;
> + u32 reg;
> + int i;
> +
> + sa_regs = nxp_c45_get_macsec_sa_regs(key_a);
> +
> + for (i = 0; i < key_size; i++) {
> + reg = sa_regs->rxsa_ka + i * 4;
> + nxp_c45_macsec_write(ctx->phydev, reg,
> + (__force u32)cpu_to_be32(key[i]));
> + }
> +
> + if (ctx->secy->xpn) {
> + for (i = 0; i < salt_size; i++) {
> + reg = sa_regs->rxsa_salt + (2 - i) * 4;
> + nxp_c45_macsec_write(ctx->phydev, reg,
> + (__force u32)cpu_to_be32(salt[i]));
> + }
> + nxp_c45_macsec_write(ctx->phydev, sa_regs->rxsa_ssci,
> + (__force u32)cpu_to_be32(ssci));
> + }
This looks basically identical to nxp_c45_txsa_set_key except for the
registers it writes to. It could be turned into 2 or 3 small helpers
(one for the key, then salt and ssci).
> +
> + nxp_c45_set_rxsa_key_cfg(ctx, key_a, false);
> +
> + return 0;
> +}
[...]
> +static int nxp_c45_mdo_add_secy(struct macsec_context *ctx)
> +{
> + struct phy_device *phydev = ctx->phydev;
> + struct nxp_c45_phy *priv = phydev->priv;
> + u64 sci = (__force u64)ctx->secy->sci;
> + struct nxp_c45_secy *phy_secy;
> + bool can_ptp;
> + int idx;
> + u32 reg;
> +
> + phydev_dbg(ctx->phydev, "add secy SCI %llu\n", ctx->secy->sci);
nit: %016llx feels more natural for SCIs since they can be broken down
into address+port.
And since it's stored in network byte order, you'll want to convert it
via be64_to_cpu before you print it out.
I'd suggest doing that directly into the sci variable:
u64 sci = be64_to_cpu((__force __be64)ctx->secy->sci);
and then adapt the uses of sci further down.
Feel free to move the sci_to_cpu function from
drivers/net/netdevsim/macsec.c to include/net/macsec.h and reuse it.
[...]
> +static int nxp_c45_mdo_upd_secy(struct macsec_context *ctx)
> +{
[...]
> + if (phy_secy->enabled_an != ctx->secy->tx_sc.encoding_sa) {
> + old_tx_sa = phy_secy->tx_sa[phy_secy->enabled_an];
> + phy_secy->enabled_an = ctx->secy->tx_sc.encoding_sa;
> + new_tx_sa = phy_secy->tx_sa[phy_secy->enabled_an];
> + if (!new_tx_sa) {
> + nxp_c45_tx_sa_disable(phydev, phy_secy);
> + goto disable_old_tx_sa;
> + }
> +
> + if (!new_tx_sa->tx_sa->active) {
> + nxp_c45_tx_sa_disable(phydev, phy_secy);
> + goto disable_old_tx_sa;
> + }
You can combine those two conditions into
if (!new_tx_sa || !new_tx_sa->tx_sa->active) {
nxp_c45_tx_sa_disable(phydev, phy_secy);
goto disable_old_tx_sa;
}
> +
> + new_tx_sa->is_key_a = phy_secy->tx_sa_key_a;
> + phy_secy->tx_sa_key_a = phy_secy->tx_sa_key_a;
Is this missing a ! on the right side?
Maybe worth creating a "next_sa_key_id" helper (or something like
that) that returns the current value and updates tx_sa_key_a, since
you use this pattern a few times.
[...]
> +static int nxp_c45_mdo_add_rxsc(struct macsec_context *ctx)
> +{
> + struct phy_device *phydev = ctx->phydev;
> + struct nxp_c45_phy *priv = phydev->priv;
> + struct nxp_c45_secy *phy_secy;
> + struct nxp_c45_rx_sc *rx_sc;
> +
> + phydev_dbg(phydev, "add RX SC %s\n",
> + ctx->rx_sc->active ? "enabled" : "disabled");
If the HW/driver supports multiple TXSC/RXSC on the same device, it
would probably be helpful to add their SCIs to this debug message (and
the update/delete ones, also for the mdo_*_rxsa and mdo_*_txsa
functions).
[...]
> +static int nxp_c45_mdo_add_rxsa(struct macsec_context *ctx)
> +{
[...]
> + if (!rx_sc->rx_sa_b) {
> + phydev_dbg(phydev, "add RX SA B %u %s\n",
> + an, rx_sa->active ? "enabled" : "disabled");
> + nxp_c45_set_rxsa_key(ctx, false);
> + rx_sc->rx_sa_b = rx_sa;
> + return 0;
> + }
> +
> + return -ENOMEM;
maybe -ENOSPC would fit better?
> +}
> +
[...]
> +static int nxp_c45_mdo_add_txsa(struct macsec_context *ctx)
> +{
[...]
> + if (phy_secy->tx_sa[sa])
> + return -EBUSY;
> +
> + tx_sa = kzalloc(sizeof(*tx_sa), GFP_KERNEL);
missing NULL check
[...]
> +static int nxp_c45_mdo_del_txsa(struct macsec_context *ctx)
> +{
[...]
> +
> + phy_secy->tx_sa[sa] = NULL;
> + kfree(tx_sa);
tx_sa contains the key, so this needs to be kfree_sensitive, or add a
memzero_explicit(tx_sa->key) before freeing. Or if possible, don't
copy the key at all into tx_sa.
similar changes in the mscc driver:
1b16b3fdf675 ("net: phy: mscc: macsec: clear encryption keys when freeing a flow")
0dc33c65835d ("net: phy: mscc: macsec: do not copy encryption keys")
[...]
> diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
> index 7ab080ff02df..5bf7caa4e63d 100644
> --- a/drivers/net/phy/nxp-c45-tja11xx.c
> +++ b/drivers/net/phy/nxp-c45-tja11xx.c
[...]
> @@ -1218,12 +1201,25 @@ static int nxp_c45_start_op(struct phy_device *phydev)
>
> static int nxp_c45_config_intr(struct phy_device *phydev)
> {
> - if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
> + int ret;
> +
> + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
> + ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
> + VEND1_PORT_FUNC_IRQ_EN, MACSEC_IRQS);
> + if (ret)
> + return ret;
> +
> return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
> VEND1_PHY_IRQ_EN, PHY_IRQ_LINK_EVENT);
Maybe a dumb question: should we be clearing the MACSEC_IRQS bits when
this 2nd call to phy_set_bits_mmd fails? (and same below, reset when
the 2nd clear fails)
> - else
> - return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
> - VEND1_PHY_IRQ_EN, PHY_IRQ_LINK_EVENT);
> + }
> +
> + ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
> + VEND1_PORT_FUNC_IRQ_EN, MACSEC_IRQS);
> + if (ret)
> + return ret;
> +
> + return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
> + VEND1_PHY_IRQ_EN, PHY_IRQ_LINK_EVENT);
> }
[...]
> @@ -1666,6 +1666,20 @@ static int nxp_c45_probe(struct phy_device *phydev)
> }
>
> no_ptp_support:
> + macsec_ability = !!(phy_abilities & MACSEC_ABILITY);
> + if (!macsec_ability) {
> + phydev_info(phydev, "the phy does not support MACsec\n");
> + goto no_macsec_support;
> + }
> +
> + if (IS_ENABLED(CONFIG_MACSEC)) {
> + ret = nxp_c45_macsec_probe(phydev);
I don't know how this probing is handled so maybe another dumb
question: if that fails, are we going to leak resources allocated
earlier? (devm_kzalloc for example)
> + phydev_dbg(phydev, "MACsec support enabled.");
> + } else {
> + phydev_dbg(phydev, "MACsec support not enabled even if the phy supports it");
> + }
> +
> +no_macsec_support:
>
> return ret;
> }
--
Sabrina
next prev parent reply other threads:[~2023-08-25 12:54 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-24 9:16 [RFC net-next v2 0/5] Add MACsec support for TJA11XX C45 PHYs Radu Pirea (NXP OSS)
2023-08-24 9:16 ` [RFC net-next v2 1/5] net: macsec: documentation for macsec_context and macsec_ops Radu Pirea (NXP OSS)
2023-08-24 13:26 ` Antoine Tenart
2023-08-24 9:16 ` [RFC net-next v2 2/5] net: macsec: introduce mdo_insert_tx_tag Radu Pirea (NXP OSS)
2023-08-24 14:54 ` Sabrina Dubroca
2023-08-25 10:01 ` Radu Pirea (OSS)
2023-08-24 9:16 ` [RFC net-next v2 3/5] net: phy: nxp-c45-tja11xx add MACsec support Radu Pirea (NXP OSS)
2023-08-25 12:52 ` Sabrina Dubroca [this message]
2023-08-25 13:29 ` Andrew Lunn
2023-08-25 13:44 ` Radu Pirea (OSS)
2023-08-25 13:50 ` Andrew Lunn
2023-08-25 14:12 ` Radu Pirea (OSS)
2023-08-30 12:06 ` Russell King (Oracle)
2023-08-28 10:43 ` Sabrina Dubroca
2023-08-27 8:03 ` Simon Horman
2023-08-24 9:16 ` [RFC net-next v2 4/5] net: phy: nxp-c45-tja11xx: add MACsec statistics Radu Pirea (NXP OSS)
2023-08-25 13:41 ` Sabrina Dubroca
2023-08-25 14:22 ` Radu Pirea (OSS)
2023-08-24 9:16 ` [RFC net-next v2 5/5] net: phy: nxp-c45-tja11xx: implement mdo_insert_tx_tag Radu Pirea (NXP OSS)
2023-08-27 8:05 ` Simon Horman
2023-08-28 10:17 ` Sabrina Dubroca
2023-08-28 13:46 ` Radu Pirea (OSS)
2023-08-30 11:35 ` Sabrina Dubroca
2023-09-01 9:09 ` Radu Pirea
2023-09-01 9:27 ` Russell King (Oracle)
2023-09-01 11:31 ` Radu Pirea (OSS)
2023-09-01 12:45 ` Russell King (Oracle)
2023-09-01 10:07 ` Sabrina Dubroca
2023-09-01 10:32 ` Russell King (Oracle)
2023-09-01 13:56 ` Sabrina Dubroca
2023-09-01 11:58 ` Radu Pirea (OSS)
2023-09-01 13:57 ` Sabrina Dubroca
2023-09-01 14:22 ` Radu Pirea (OSS)
2023-09-01 15:37 ` Sabrina Dubroca
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=ZOikKUjRvces_vVj@hog \
--to=sd@queasysnail.net \
--cc=andrew@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=hkallweit1@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=radu-nicolae.pirea@oss.nxp.com \
--cc=richardcochran@gmail.com \
--cc=sebastian.tobuschat@nxp.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.