[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240613174808.67eb994c@kernel.org>
Date: Thu, 13 Jun 2024 17:48:08 -0700
From: Jakub Kicinski <kuba@...nel.org>
To: FUJITA Tomonori <fujita.tomonori@...il.com>
Cc: netdev@...r.kernel.org, andrew@...n.ch, horms@...nel.org,
jiri@...nulli.us, pabeni@...hat.com, linux@...linux.org.uk,
hfdevel@....net, naveenm@...vell.com, jdamato@...tly.com
Subject: Re: [PATCH net-next v10 4/7] net: tn40xx: add basic Tx handling
On Tue, 11 Jun 2024 13:52:14 +0900 FUJITA Tomonori wrote:
> + /* 1. load MAC (obsolete) */
> + /* 2. disable Rx (and Tx) */
> + tn40_write_reg(priv, TN40_REG_GMAC_RXF_A, 0);
> + mdelay(100);
Why mdelay()? 100ms of CPU spinning in a loop is not great.
I only see calls to tn40_sw_reset() from open and close, both
of which can sleep so you should be able to use msleep().
You can test with CONFIG_DEBUG_ATOMIC_SLEEP enabled to confirm.
> + /* 3. Disable port */
> + tn40_write_reg(priv, TN40_REG_DIS_PORT, 1);
> + /* 4. Disable queue */
> + tn40_write_reg(priv, TN40_REG_DIS_QU, 1);
> + /* 5. Wait until hw is disabled */
> + for (i = 0; i < 50; i++) {
> + if (tn40_read_reg(priv, TN40_REG_RST_PORT) & 1)
> + break;
> + mdelay(10);
read_poll_timeout() ?
> + }
> + if (i == 50)
> + netdev_err(priv->ndev, "SW reset timeout. continuing anyway\n");
> + if (unlikely(vid >= 4096)) {
can the core actually call with an invalid vid? I don't thinks so..
> + struct tn40_priv *priv = netdev_priv(ndev);
> +
> + u32 rxf_val = TN40_GMAC_RX_FILTER_AM | TN40_GMAC_RX_FILTER_AB |
> + TN40_GMAC_RX_FILTER_OSEN | TN40_GMAC_RX_FILTER_TXFC;
> + int i;
> +
nit: no empty lines between variable declarations
> + u8 hash;
> + struct netdev_hw_addr *mclist;
> + u32 reg, val;
nit: declaration lines longest to shortest within a block
> +static void tn40_get_stats(struct net_device *ndev,
> + struct rtnl_link_stats64 *stats)
> +{
> + struct tn40_priv *priv = netdev_priv(ndev);
> +
> + netdev_stats_to_stats64(stats, &priv->net_stats);
You should hold the stats in driver priv, probably:
from struct net_device:
struct net_device_stats stats; /* not used by modern drivers */
> +static int tn40_priv_init(struct tn40_priv *priv)
> +{
> + int ret;
> +
> + tn40_set_link_speed(priv, 0);
> +
> + ret = tn40_hw_reset(priv);
> + if (ret)
> + return ret;
But probe already called reset, is there a reason to reset multiple
times? Would be good to add some reason why in a comment (if you know)
> + /* Set GPIO[9:0] to output 0 */
> + tn40_write_reg(priv, 0x51E0, 0x30010006); /* GPIO_OE_ WR CMD */
> + tn40_write_reg(priv, 0x51F0, 0x0); /* GPIO_OE_ DATA */
> + tn40_write_reg(priv, TN40_REG_MDIO_CMD_STAT, 0x3ec8);
> +
> + // we use tx descriptors to load a firmware.
nit: stick to a single style of comments? ;)
> + ret = tn40_create_tx_ring(priv);
> + if (ret)
> + return ret;
> + ret = tn40_fw_load(priv);
> + tn40_destroy_tx_ring(priv);
Powered by blists - more mailing lists