mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Simon Horman <horms@kernel.org>
To: Justin Lai <justinlai0215@realtek.com>
Cc: kuba@kernel.org, davem@davemloft.net, edumazet@google.com,
	pabeni@redhat.com, linux-kernel@vger.kernel.org,
	netdev@vger.kernel.org, andrew@lunn.ch, pkshih@realtek.com,
	larry.chiu@realtek.com
Subject: Re: [PATCH net-next v11 05/13] net:ethernet:realtek:rtase: Implement hardware configuration function
Date: Thu, 16 Nov 2023 18:06:10 +0000	[thread overview]
Message-ID: <20231116180610.GG109951@vergenet.net> (raw)
In-Reply-To: <20231115133414.1221480-6-justinlai0215@realtek.com>

On Wed, Nov 15, 2023 at 09:34:06PM +0800, Justin Lai wrote:
> Implement rtase_hw_config to set default hardware settings, including
> setting interrupt mitigation, tx/rx DMA burst, interframe gap time,
> rx packet filter, near fifo threshold and fill descriptor ring and
> tally counter address, and enable flow control. When filling the
> rx descriptor ring, the first group of queues needs to be processed
> separately because the positions of the first group of queues are not
> regular with other subsequent groups. The other queues are all newly
> added features, but we want to retain the original design. So they were
> not put together.
> 
> Signed-off-by: Justin Lai <justinlai0215@realtek.com>

Hi Justin,

some minor feedback from my side.

* I think that "rtase: " would be a more appropriate prefix
  for the patches in this patch-set.

  Subject: [PATCH net-next vX m/n] rtase: ...

...

> diff --git a/drivers/net/ethernet/realtek/rtase/tt.c b/drivers/net/ethernet/realtek/rtase/tt.c

...

> new file mode 100644
> index 000000000000..5ea4d51fcc47
> --- /dev/null
> +++ b/drivers/net/ethernet/realtek/rtase/tt.c

...

> +static void rtase_tx_clear_range(struct rtase_ring *ring, u32 start, u32 n)
> +{
> +	const struct rtase_private *tp = ring->ivec->tp;
> +	struct net_device *dev = tp->dev;
> +	struct tx_desc *desc_base = ring->desc;
> +	u32 i;

nit: Please consider using reverse xmas tree - longest line to shortest -
     for new Networking code.

...

> +static u32 rtase_tx_csum(struct sk_buff *skb, const struct net_device *dev)
> +{
> +	u8 ip_protocol;
> +	u32 csum_cmd;
> +
> +	switch (vlan_get_protocol(skb)) {
> +	case htons(ETH_P_IP):
> +		csum_cmd = TX_IPCS_C;
> +		ip_protocol = ip_hdr(skb)->protocol;
> +		break;
> +
> +	case htons(ETH_P_IPV6):
> +		csum_cmd = TX_IPV6F_C;
> +		ip_protocol = ipv6_hdr(skb)->nexthdr;
> +		break;
> +
> +	default:
> +		ip_protocol = IPPROTO_RAW;
> +		break;

If the default branch is taken in this switch statement,
then csum_cmd is used uninitialised below.

As flagged by a clang-16 W=1 build

> +	}
> +
> +	if (ip_protocol == IPPROTO_TCP)
> +		csum_cmd |= TX_TCPCS_C;
> +	else if (ip_protocol == IPPROTO_UDP)
> +		csum_cmd |= TX_UDPCS_C;
> +	else
> +		WARN_ON_ONCE(1);
> +
> +	csum_cmd |= u32_encode_bits(skb_transport_offset(skb), TCPHO_MASK);
> +
> +	return csum_cmd;
> +}
> +
> +static int rtase_xmit_frags(struct rtase_ring *ring, struct sk_buff *skb,
> +			    u32 opts1, u32 opts2)
> +{
> +	const struct skb_shared_info *info = skb_shinfo(skb);
> +	const struct rtase_private *tp = ring->ivec->tp;
> +	const u8 nr_frags = info->nr_frags;
> +	struct tx_desc *txd = NULL;
> +	u32 cur_frag, entry;
> +	u64 pkt_len_cnt = 0;

pkt_len_cnt is initialised here...

> +
> +	entry = ring->cur_idx;
> +	for (cur_frag = 0; cur_frag < nr_frags; cur_frag++) {
> +		const skb_frag_t *frag = &info->frags[cur_frag];
> +		dma_addr_t mapping;
> +		u32 status, len;
> +		void *addr;
> +
> +		entry = (entry + 1) % NUM_DESC;
> +
> +		txd = ring->desc + sizeof(struct tx_desc) * entry;
> +		len = skb_frag_size(frag);
> +		addr = skb_frag_address(frag);
> +		mapping = dma_map_single(&tp->pdev->dev, addr, len,
> +					 DMA_TO_DEVICE);
> +
> +		if (unlikely(dma_mapping_error(&tp->pdev->dev, mapping))) {
> +			if (unlikely(net_ratelimit()))
> +				netdev_err(tp->dev,
> +					   "Failed to map TX fragments DMA!\n");
> +
> +			goto err_out;
> +		}
> +
> +		if (((entry + 1) % NUM_DESC) == 0)
> +			status = (opts1 | len | RING_END);
> +		else
> +			status = opts1 | len;
> +
> +		if (cur_frag == (nr_frags - 1)) {
> +			ring->skbuff[entry] = skb;
> +			status |= TX_LAST_FRAG;
> +		}
> +
> +		ring->mis.len[entry] = len;
> +		txd->addr = cpu_to_le64(mapping);
> +		txd->opts2 = cpu_to_le32(opts2);
> +
> +		/* make sure the operating fields have been updated */
> +		wmb();
> +		txd->opts1 = cpu_to_le32(status);
> +		pkt_len_cnt += len;

... and incremented here. But is otherwise unused.

As flagged by a clang-16 W=1 build.

> +	}
> +
> +	return cur_frag;
> +
> +err_out:
> +	rtase_tx_clear_range(ring, ring->cur_idx + 1, cur_frag);
> +	return -EIO;
> +}

...

> +static void rtase_dump_state(const struct net_device *dev)
> +{
> +	const struct rtase_private *tp = netdev_priv(dev);
> +	const struct rtase_counters *counters;
> +	int max_reg_size = RTASE_PCI_REGS_SIZE;
> +	const struct rtase_ring *ring;
> +	u32 dword_rd;
> +	int n = 0;
> +
> +	ring = &tp->tx_ring[0];
> +	netdev_err(dev, "Tx descriptor info:\n");
> +	netdev_err(dev, "Tx curIdx = 0x%x\n", ring->cur_idx);
> +	netdev_err(dev, "Tx dirtyIdx = 0x%x\n", ring->dirty_idx);
> +	netdev_err(dev, "Tx phyAddr = 0x%llx\n", ring->phy_addr);
> +
> +	ring = &tp->rx_ring[0];
> +	netdev_err(dev, "Rx descriptor info:\n");
> +	netdev_err(dev, "Rx curIdx = 0x%x\n", ring->cur_idx);
> +	netdev_err(dev, "Rx dirtyIdx = 0x%x\n", ring->dirty_idx);
> +	netdev_err(dev, "Rx phyAddr = 0x%llx\n", ring->phy_addr);
> +
> +	netdev_err(dev, "Device Registers:\n");
> +	netdev_err(dev, "Chip Command = 0x%02x\n", rtase_r8(tp, RTASE_CHIP_CMD));
> +	netdev_err(dev, "IMR = %08x\n", rtase_r32(tp, RTASE_IMR0));
> +	netdev_err(dev, "ISR = %08x\n", rtase_r32(tp, RTASE_ISR0));
> +	netdev_err(dev, "Boot Ctrl Reg(0xE004) = %04x\n",
> +		   rtase_r16(tp, RTASE_BOOT_CTL));
> +	netdev_err(dev, "EPHY ISR(0xE014) = %04x\n",
> +		   rtase_r16(tp, RTASE_EPHY_ISR));
> +	netdev_err(dev, "EPHY IMR(0xE016) = %04x\n",
> +		   rtase_r16(tp, RTASE_EPHY_IMR));
> +	netdev_err(dev, "CLKSW SET REG(0xE018) = %04x\n",
> +		   rtase_r16(tp, RTASE_CLKSW_SET));
> +
> +	netdev_err(dev, "Dump PCI Registers:\n");
> +
> +	while (n < max_reg_size) {
> +		if ((n % RTASE_DWORD_MOD) == 0)
> +			netdev_err(tp->dev, "0x%03x:\n", n);
> +
> +		pci_read_config_dword(tp->pdev, n, &dword_rd);
> +		netdev_err(tp->dev, "%08x\n", dword_rd);
> +		n += 4;
> +	}
> +
> +	netdev_err(dev, "Dump tally counter:\n");
> +	counters = tp->tally_vaddr;
> +	rtase_dump_tally_counter(tp);
> +
> +	netdev_err(dev, "tx_packets %lld\n",
> +		   le64_to_cpu(counters->tx_packets));

tx_packets is __le16 not __le64, so I think you want:

	netdev_err(dev, "rx_missed %d\n",
		   le16_to_cpu(counters->rx_missed));

Likewise for align_errors, tx_aborted, and tx_underun.

As flagged by Sparse

> +	netdev_err(dev, "rx_packets %lld\n",
> +		   le64_to_cpu(counters->rx_packets));
> +	netdev_err(dev, "tx_errors %lld\n",
> +		   le64_to_cpu(counters->tx_errors));
> +	netdev_err(dev, "rx_missed %lld\n",
> +		   le64_to_cpu(counters->rx_missed));
> +	netdev_err(dev, "align_errors %lld\n",
> +		   le64_to_cpu(counters->align_errors));
> +	netdev_err(dev, "tx_one_collision %lld\n",
> +		   le64_to_cpu(counters->tx_one_collision));

Similarly, tx_one_collision is __le32 not __le64, so I think you want:
.
	netdev_err(dev, "tx_one_collision %d\n",
		   le32_to_cpu(counters->tx_one_collision));

Likewise for tx_multi_collision, and rx_multicast.

There area also similar problems in rtase_main.c:rtase_dump_state(),
added elsewhere in this patch-set.

> +	netdev_err(dev, "tx_multi_collision %lld\n",
> +		   le64_to_cpu(counters->tx_multi_collision));
> +	netdev_err(dev, "rx_unicast %lld\n",
> +		   le64_to_cpu(counters->rx_unicast));
> +	netdev_err(dev, "rx_broadcast %lld\n",
> +		   le64_to_cpu(counters->rx_broadcast));
> +	netdev_err(dev, "rx_multicast %lld\n",
> +		   le64_to_cpu(counters->rx_multicast));
> +	netdev_err(dev, "tx_aborted %lld\n",
> +		   le64_to_cpu(counters->tx_aborted));
> +	netdev_err(dev, "tx_underun %lld\n",
> +		   le64_to_cpu(counters->tx_underun));
> +}

...

> +static const char rtase_gstrings[][ETH_GSTRING_LEN] = {
> +	"tx_packets",
> +	"rx_packets",
> +	"tx_errors",
> +	"rx_errors",
> +	"rx_missed",
> +	"align_errors",
> +	"tx_single_collisions",
> +	"tx_multi_collisions",
> +	"unicast",
> +	"broadcast",
> +	"multicast",
> +	"tx_aborted",
> +	"tx_underrun",
> +};
> +
> +static void rtase_get_strings(struct net_device *dev, u32 stringset, u8 *data)
> +{
> +	switch (stringset) {
> +	case ETH_SS_STATS:
> +		memcpy(data, *rtase_gstrings, sizeof(rtase_gstrings));

Compilers don't think this is seem correct, because *rtase_gsrings is the
first element of that array, rather than the entire array. And thus
is only ETH_GSTRING_LEN bytes long, rather than n * ETH_GSTRING_LEN bytes
long.

I think what you want is (compile tested only!):

		memcpy(data, rtase_gstrings, sizeof(rtase_gstrings));

Flagged by a clang-16 W=1 build.

> +		break;
> +	}
> +}

...

> +static int rtase_init_board(struct pci_dev *pdev, struct net_device **dev_out,
> +			    void __iomem **ioaddr_out)
> +{
> +	struct net_device *dev;
> +	void __iomem *ioaddr;
> +	int ret = -ENOMEM;
> +
> +	/* dev zeroed in alloc_etherdev */
> +	dev = alloc_etherdev_mq(sizeof(struct rtase_private),
> +				RTASE_FUNC_TXQ_NUM);
> +	if (!dev)
> +		goto err_out;
> +
> +	SET_NETDEV_DEV(dev, &pdev->dev);
> +
> +	ret = pci_enable_device(pdev);
> +	if (ret < 0)
> +		goto err_out_free_dev;
> +
> +	/* make sure PCI base addr 1 is MMIO */
> +	if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
> +		ret = -ENODEV;
> +		goto err_out_disable;
> +	}
> +
> +	/* check for weird/broken PCI region reporting */
> +	if (pci_resource_len(pdev, 2) < RTASE_REGS_SIZE) {
> +		ret = -ENODEV;
> +		goto err_out_disable;
> +	}
> +
> +	ret = pci_request_regions(pdev, KBUILD_MODNAME);
> +	if (ret < 0)
> +		goto err_out_disable;
> +
> +	if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)))
> +		dev->features |= NETIF_F_HIGHDMA;
> +	else if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))
> +		goto err_out_free_res;
> +	else
> +		dev_info(&pdev->dev, "DMA_BIT_MASK: 32\n");
> +
> +	pci_set_master(pdev);
> +
> +	/* ioremap MMIO region */
> +	ioaddr = ioremap(pci_resource_start(pdev, 2),
> +			 pci_resource_len(pdev, 2));
> +	if (!ioaddr) {
> +		ret = -EIO;
> +		goto err_out_free_res;
> +	}
> +
> +	*ioaddr_out = ioaddr;
> +	*dev_out = dev;
> +	goto out;

nit: I think it's slightly more idiomatic to simply return 0 here,
     and drop the out label below.

> +
> +err_out_free_res:
> +	pci_release_regions(pdev);
> +
> +err_out_disable:
> +	pci_disable_device(pdev);
> +
> +err_out_free_dev:
> +	free_netdev(dev);
> +
> +err_out:
> +	*ioaddr_out = NULL;
> +	*dev_out = NULL;
> +
> +out:
> +	return ret;
> +}

...

> diff --git a/drivers/net/ethernet/realtek/rtase/tt.h b/drivers/net/ethernet/realtek/rtase/tt.h
> new file mode 100644
> index 000000000000..9239c518c504
> --- /dev/null
> +++ b/drivers/net/ethernet/realtek/rtase/tt.h
> @@ -0,0 +1,353 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
> +/*
> + *  rtase is the Linux device driver released for Realtek Automotive Switch
> + *  controllers with PCI-Express interface.
> + *
> + *  Copyright(c) 2023 Realtek Semiconductor Corp.
> + */
> +
> +#ifndef _RTASE_H_
> +#define _RTASE_H_

If the code in tt.h is only used in tt.c, then perhaps the
code can simply be moved into tt.c.

...

  parent reply	other threads:[~2023-11-16 18:06 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-15 13:34 [PATCH net-next v11 00/13] Add Realtek automotive PCIe driver Justin Lai
2023-11-15 13:34 ` [PATCH net-next v11 01/13] net:ethernet:realtek:rtase: Add pci table supported in this module Justin Lai
2023-11-15 13:34 ` [PATCH net-next v11 02/13] net:ethernet:realtek:rtase: Implement the .ndo_open function Justin Lai
2023-11-15 13:34 ` [PATCH net-next v11 03/13] net:ethernet:realtek:rtase: Implement the rtase_down function Justin Lai
2023-11-15 13:34 ` [PATCH net-next v11 04/13] net:ethernet:realtek:rtase: Implement the interrupt routine and rtase_poll Justin Lai
2023-11-15 13:34 ` [PATCH net-next v11 05/13] net:ethernet:realtek:rtase: Implement hardware configuration function Justin Lai
2023-11-15 15:02   ` Heiner Kallweit
2023-11-21 11:54     ` Justin Lai
2023-11-16 18:06   ` Simon Horman [this message]
2023-11-23  3:48     ` Justin Lai
2023-11-18 22:50   ` Jakub Kicinski
2023-11-20 13:22     ` Justin Lai
2023-11-15 13:34 ` [PATCH net-next v11 06/13] net:ethernet:realtek:rtase: Implement .ndo_start_xmit function Justin Lai
2023-11-15 13:34 ` [PATCH net-next v11 07/13] net:ethernet:realtek:rtase: Implement a function to receive packets Justin Lai
2023-11-15 13:34 ` [PATCH net-next v11 08/13] net:ethernet:realtek:rtase: Implement net_device_ops Justin Lai
2023-11-15 13:34 ` [PATCH net-next v11 09/13] net:ethernet:realtek:rtase: Implement pci_driver suspend and resume function Justin Lai
2023-11-15 15:02   ` Heiner Kallweit
2023-11-21  9:30     ` Justin Lai
2023-11-15 13:34 ` [PATCH net-next v11 10/13] net:ethernet:realtek:rtase: Implement ethtool function Justin Lai
2023-11-15 15:02   ` Heiner Kallweit
2023-11-23  3:16     ` Justin Lai
2023-11-15 13:34 ` [PATCH net-next v11 11/13] net:ethernet:realtek:rtase: Add a Makefile in the rtase folder Justin Lai
2023-11-15 13:34 ` [PATCH net-next v11 12/13] net:ethernet:realtek: Update the Makefile and Kconfig in the realtek folder Justin Lai
2023-11-15 19:58   ` kernel test robot
2023-11-21 10:00   ` kernel test robot
2023-11-15 13:34 ` [PATCH net-next v11 13/13] MAINTAINERS: Add the rtase ethernet driver entry Justin Lai
2023-11-16 17:57 ` [PATCH net-next v11 00/13] Add Realtek automotive PCIe driver Simon Horman
2023-11-21  9:35   ` Justin Lai

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=20231116180610.GG109951@vergenet.net \
    --to=horms@kernel.org \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=justinlai0215@realtek.com \
    --cc=kuba@kernel.org \
    --cc=larry.chiu@realtek.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=pkshih@realtek.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®