Thread (9 messages) 9 messages, 2 authors, 2026-03-24

Re: [net-next,v3,2/2] r8152: Add support for the RTL8157 hardware

From: Birger Koblitz <hidden>
Date: 2026-03-24 16:55:46
Also in: linux-usb, lkml

On 24/03/2026 11:55 am, Paolo Abeni wrote:
quoted
+static u32 ocp_adv_read(struct r8152 *tp, u16 cmd, u16 addr, u32 *data)
+{
+	int ret;
+
+	ret = wait_cmd_ready(tp);
+	if (ret)
+		return ret;
+
+	ocp_write_word(tp, MCU_TYPE_USB, USB_ADV_ADDR, addr);
+
+	ocp_write_word(tp, MCU_TYPE_USB, USB_ADV_CMD, cmd);
+
+	ret = wait_cmd_ready(tp);
+	if (ret)
+		return ret;
+
+	ret = ocp_read_dword(tp, MCU_TYPE_USB, USB_ADV_DATA, data);
+
+	return ret;
+}
Should ocp_adv_read() return int instead of u32? The function returns
'int ret' which can be 0 or -ETIMEDOUT from wait_cmd_ready(), but the
function signature declares u32. The companion function ocp_adv_write()
and all callers (rtl_bmu_read, rtl_ip_read) correctly use 'int ret' and
check 'ret < 0' for errors.
This is a clear mistake. I will change the return type to "int" and 
submit a new patch version. As a side remark, however, the patch-code 
you refer to, here, is not what I submitted. My submission can be found 
here:
https://lkml.org/lkml/2026/3/20/831

It reads:
+
+static u32 ocp_adv_read(struct r8152 *tp, u16 cmd, u16 addr, u32 *data)
+{
+	int ret;
+
+	ret = wait_cmd_ready(tp, USB_ADV_CMD);
+	if (ret < 0)
+		goto out;
+
+	ocp_write_word(tp, MCU_TYPE_USB, USB_ADV_ADDR, addr);
+
+	cmd |= ADV_CMD_BUSY;
+	ocp_write_word(tp, MCU_TYPE_USB, USB_ADV_CMD, cmd);
+
+	ret = wait_cmd_ready(tp, USB_ADV_CMD);
+	if (ret < 0)
+		goto out;
+
+	*data = ocp_read_dword(tp, MCU_TYPE_USB, USB_ADV_DATA);
+
+out:
+	return ret;
+}

Note that the call parameters of ocp_read_dword are different. It 
appears that the AI is mixing the patch I submitted with the out-of-tree 
driver the patch is based on.
quoted
+static int r8152_tx_csum(void *d, struct sk_buff *skb, u32 len)
  {
  	u32 mss = skb_shinfo(skb)->gso_size;
+	struct rx_desc *desc = d;
Is this the correct descriptor type? r8152_tx_csum() casts the void *d
parameter to 'struct rx_desc *desc' but this function handles TX
descriptors. The sibling TX functions (r8152_tx_vlan_tag, r8152_tx_len)
use 'struct tx_desc *'. The bug is latent because both struct tx_desc
and struct rx_desc have opts1 and opts2 at identical offsets.
This is a typo. I will fix it to tx_desc.
quoted
@@ -2923,13 +3283,14 @@ static netdev_features_t rtl8152_features_check(struct sk_buff *skb,
  						 netdev_features_t features)
  {
  	u32 mss = skb_shinfo(skb)->gso_size;
  	int max_offset = mss ? GTTCPHO_MAX : TCPHO_MAX;

  	if ((mss || skb->ip_summed == CHECKSUM_PARTIAL) &&
  	    skb_transport_offset(skb) > max_offset)
  		features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
  	else if ((skb->len + sizeof(struct tx_desc)) > agg_buf_sz)
  		features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);

  	return features;
  }
Does this match the RTL8157 limits? rtl8152_features_check() uses
TCPHO_MAX (0x7ff = 2047) for non-GSO checksummed packets on all chip
versions, but the new RTL8157 (RTL_VER_16) hardware has a smaller limit
TCPHO_MAX_2 (0x3ff = 1023) as checked in r8157_tx_csum(). For RTL8157,
packets with transport offsets between 1024 and 2047 will pass
features_check, but r8157_tx_csum will reject them and fall back to
r8152_csum_workaround, producing netif_warn messages.
I do not have any further information on the TCPHO_MAX value for the 
RTL8157 other than what is found in the out-of-tree driver. However, if 
this is explicitly changed, it must be assumed the lower limit is 
correct. I will fix this to read:

static netdev_features_t
rtl8152_features_check(struct sk_buff *skb, struct net_device *dev,
		       netdev_features_t features)
{
	struct r8152 *tp = netdev_priv(dev);
	u32 mss = skb_shinfo(skb)->gso_size;
	int max_offset;

	if (tp->version < RTL_VER_16)
		max_offset = mss ? GTTCPHO_MAX : TCPHO_MAX;
	else
		max_offset = mss ? GTTCPHO_MAX : TCPHO_MAX_2;

	if ((mss || skb->ip_summed == CHECKSUM_PARTIAL) &&
	    skb_transport_offset(skb) > max_offset)

in order to be on the safe side.
[ ... ]
quoted
@@ -8252,25 +8711,27 @@ static void r8156b_init(struct r8152 *tp)
  	u16 data;
  	u8 speed;

+	tp->coalesce = 15000;	/* 15 us */
+	data = r8153_phy_status(tp, 0);
+
  	if (test_bit(RTL8152_UNPLUG, &tp->flags))
  		return;

-	tp->coalesce = 15000;	/* 15 us */
  	r8153b_u1u2en(tp, false);

  	r8156_fc_parameter(tp);
-	rtl_tally_reset(tp);

+	if (tp->version < RTL_VER_13)
+		r8156_mdio_force_mode(tp);
[ ... ]
quoted
+	if (tp->version >= RTL_VER_13 && tp->version <= RTL_VER_15)
+		ocp_word_set_bits(tp, MCU_TYPE_USB, USB_U2P3_CTRL, RX_DETECT8);
Are the version guards correct for RTL8156B? When merging r8156b_init into
r8156_init, the condition 'tp->version >= RTL_VER_13 && tp->version <=
RTL_VER_15' excludes RTL_VER_12. Before this patch, RTL_VER_12 was handled
by r8156b_init which executed these code paths unconditionally. The commit
message states VER_12 is RTL8156B hardware.

Three specific behavioral changes for RTL_VER_12: (1) RX_DETECT8 is no
longer set on USB_U2P3_CTRL (shown above), (2) the flow control
initialization block (SLOT_EN clear, FLOW_CTRL_EN set, FC_TIMER, FW_CTRL,
FW_TASK) is skipped later, and (3) the PHY_STAT_EXT_INIT path
ocp_reg_clr_bits(tp, 0xa466, BIT(0)) is skipped because 'tp->version >=
RTL_VER_13' excludes VER_12.

Should these be 'tp->version >= RTL_VER_12' instead to preserve the old
r8156b_init behavior for RTL_VER_12 hardware?

[ ... ]
Indeed, it appears that I had excluded RTL_VER_12 incorrectly for the 
RTL8156b. I will replace RTL_VER_13 in the comparisons with RTL_VER_12.

Again, the AI appears to refer to code that I did not submit. The patch 
I submitted does no longer have a r8156b_init function, however it is 
mentioned as present in the patch you cite.

B.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help