Re: [PATCH net-next v9 08/13] net:ethernet:realtek:rtase: Implement net_device_ops

Andrew Lunn
2023-09-28T14:02:43Z

> +static int rtase_change_mtu(struct net_device *dev, int new_mtu)
> +{
> + struct rtase_private *tp = netdev_priv(dev);
> + int ret;
> +
> + dev->mtu = new_mtu;
> +
> + if (!netif_running(dev))
> + goto out;
> +
> + rtase_down(dev);
> +
> + rtase_set_rxbufsize(tp, dev);
> +
> + ret = rtase_init_ring(dev);
> +
> + if (ret)
> + return ret;

If this fails, what state is the interface in?

What you often see is that the new ring is first allocated. If that is
successful, you free the old rung. If the allocation fails, it does
not matter, you still have the old ring, and you keep using it.

> +
> + netif_stop_queue(dev);
> + netif_carrier_off(dev);
> + rtase_hw_config(dev);
> +
> + /* always link, so start to transmit & receive */
> + rtase_hw_start(dev);
> + netif_carrier_on(dev);
> + netif_wake_queue(dev);

I don't think you need to down/up the carrier when changing the MTU.

> +static void rtase_sw_reset(struct net_device *dev)
> +{
> + struct rtase_private *tp = netdev_priv(dev);
> + int ret;
> +
> + netif_stop_queue(dev);
> + netif_carrier_off(dev);
> + rtase_hw_reset(dev);
> +
> + /* let's wait a bit while any (async) irq lands on */
> + rtase_wait_for_quiescence(dev);
> + rtase_tx_clear(tp);
> + rtase_rx_clear(tp);
> +
> + ret = rtase_init_ring(dev);
> + if (ret)
> + netdev_alert(dev, "unable to init ring\n");
> +
> + rtase_hw_config(dev);
> + /* always link, so start to transmit & receive */
> + rtase_hw_start(dev);
> +
> + netif_carrier_on(dev);
> + netif_wake_queue(dev);
> +}
> +
> +static void rtase_tx_timeout(struct net_device *dev, unsigned int txqueue)
> +{
> + rtase_sw_reset(dev);

Do you actually see this happening? The timeout is set pretty high, i
think 5 seconds. If it does happen, it probably means you have a
hardware/firmware bug. So you want to be noisy here, so you get to
know about these problems, rather than silently work around them.

> +static int rtase_setup_tc(struct net_device *dev, enum tc_setup_type type,
> + void *type_data)
> +{
> + struct rtase_private *tp = netdev_priv(dev);
> + int ret = 0;
> +
> + switch (type) {
> + case TC_SETUP_QDISC_MQPRIO:
> + break;
> + case TC_SETUP_BLOCK:
> + break;

This looks odd. You silently return 0, doing nothing?

> + case TC_SETUP_QDISC_CBS:
> + ret = rtase_setup_tc_cbs(tp, type_data);
> + break;
> + default:
> + return -EOPNOTSUPP;
> + }
> +
> + return ret;
> +}
> +
> +static netdev_features_t rtase_fix_features(struct net_device *dev,
> + netdev_features_t features)
> +{
> + netdev_features_t features_fix = features;
> +
> + if (dev->mtu > MSS_MAX)
> + features_fix &= ~NETIF_F_ALL_TSO;
> +
> + if (dev->mtu > ETH_DATA_LEN) {
> + features_fix &= ~NETIF_F_ALL_TSO;
> + features_fix &= ~NETIF_F_CSUM_MASK;
> + }

So the hardware does not support TSO and checksumming for jumbo frames?

Andrew