[PATCH v2] usb: net: Add support for the Realtek RTL8152B/RTL8153

Oleksij Rempel o.rempel at pengutronix.de
Wed Oct 20 03:32:53 PDT 2021


Hello Ahmad,

Thank you for review.

On Wed, Oct 20, 2021 at 09:25:09AM +0200, Ahmad Fatoum wrote:
> Hello Oleksij,
> 
> On 20.10.21 08:42, Oleksij Rempel wrote:
> > This adds support for the Realtek RTL8152B/RTL8153 ethernet converter chip.
> > This driver is based on U-Boot version v2021.10 with port to barebox
> > internal frameworks.
> > 
> > Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
> > ---
> >  drivers/net/usb/Kconfig    |    7 +
...
> > +static int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size,
> > +			 void *data)
> > +{
> > +	void *buf;
> > +	int ret;
> > +
> > +	buf = xmalloc(size);
> 
> Should be dma_alloc to get proper alignment, as USB host drivers may map it
> for streaming DMA. You could allocate a 64 byte bounce buffer once at start
> and reuse it here instead of allocating on each control msg.

done.

> > +	if (!buf)
> > +		return -ENOMEM;
> 
> No need to check xmalloc return btw.

done

> > +
> > +	ret = usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0),
> > +			      RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
> > +			      value, index, buf, size, 500);
> > +	memcpy(data, buf, size);
> > +
> > +	free(buf);
> > +
> > +	return ret;
> > +}

...

> > +static int r8152_wait_for_bit(struct r8152 *tp, bool ocp_reg, u16 type,
> > +			      u16 index, const u32 mask, bool set,
> > +			      unsigned int timeout)
> > +{
> > +	u32 val;
> > +	u64 start;
> > +
> > +	start = get_time_ns();
> > +	do {
> > +		if (ocp_reg)
> > +			val = ocp_reg_read(tp, index);
> > +		else
> > +			val = ocp_read_dword(tp, type, index);
> > +
> > +		if (!set)
> > +			val = ~val;
> > +
> > +		if ((val & mask) == mask)
> > +			return 0;
> > +
> > +		mdelay(1);
> 
> That's a very short delay IMO. I am not sure, spamming that
> often actually produces better results. In __net_poll Sascha says:
> 
> "The timeout can't be arbitrarily small, 2ms is the smallest
> we can do with the 1ms USB frame size.". Does this apply
> here as well?

yes, done.

> > +	} while (!is_timeout(start, timeout * MSECOND));
> > +
> > +	debug("%s: Timeout (index=%04x mask=%08x timeout=%d)\n",
> > +	      __func__, index, mask, timeout);
> > +
> > +	return -ETIMEDOUT;
> > +}
> > +
> > +static void r8152b_reset_packet_filter(struct r8152 *tp)
> > +{
> > +	u32 ocp_data;
> > +
> > +	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_FMC);
> > +	ocp_data &= ~FMC_FCR_MCU_EN;
> > +	ocp_write_word(tp, MCU_TYPE_PLA, PLA_FMC, ocp_data);
> > +	ocp_data |= FMC_FCR_MCU_EN;
> > +	ocp_write_word(tp, MCU_TYPE_PLA, PLA_FMC, ocp_data);
> > +}
> > +
> > +static void rtl8152_wait_fifo_empty(struct r8152 *tp)
> > +{
> > +	int ret;
> > +
> > +	ret = r8152_wait_for_bit(tp, 0, MCU_TYPE_PLA, PLA_PHY_PWR,
> > +				 PLA_PHY_PWR_TXEMP, 1, R8152_WAIT_TIMEOUT);
> > +	if (ret)
> > +		debug("Timeout waiting for FIFO empty\n");
> 
> Please use dev_dbg here and everywhere else, so it's immediately
> known where they originate from.

done

> > +
> > +	ret = r8152_wait_for_bit(tp, 0, MCU_TYPE_PLA, PLA_TCR0,
> > +				 TCR0_TX_EMPTY, 1, R8152_WAIT_TIMEOUT);
> > +	if (ret)
> > +		debug("Timeout waiting for TX empty\n");
> > +}
> > +
...
> > +static int r8152_init_common(struct r8152 *tp, struct usbnet *dev)
> > +{
> > +	bool timeout = false;
> > +	int link_detected;
> > +	u64 start;
> > +	u8 speed;
> > +
> > +	debug("** %s()\n", __func__);
> > +
> > +	printf("Waiting for Ethernet connection... ");
> > +	start = get_time_ns();
> > +	do {
> > +		speed = rtl8152_get_speed(tp);
> > +
> > +		link_detected = speed & LINK_STATUS;
> > +		if (!link_detected) {
> > +			mdelay(TIMEOUT_RESOLUTION);
> > +			if (is_timeout(start, PHY_CONNECT_TIMEOUT * MSECOND))
> > +				timeout = true;
> 
> return an error code?

done

> > +		}
> > +	} while (!link_detected && !timeout);
> > +
> > +	if (link_detected) {
> > +		tp->rtl_ops.enable(tp);
> > +
> > +		if (!timeout)
> > +			printf("done.\n");
> 
> timeout == true => link_detected == false, so this condition is
> never false. Just early exit above.

done

> > +	} else {
> > +		printf("unable to connect.\n");
> 
> dev_warn, so it includes device name and is written to log (dmesg/pstore).

done

> > +	}
> > +
> > +	return 0;
> 
> You check this code although it's always zero, so you never act on
> the unabel to connect.

fixed

> > +static int r8153_pre_ram_code(struct r8152 *tp, u16 patch_key)
> > +{
> > +	u16 data;
> > +	int i;
> > +
> > +	data = ocp_reg_read(tp, 0xb820);
> > +	data |= 0x0010;
> > +	ocp_reg_write(tp, 0xb820, data);
> > +
> > +	for (i = 0, data = 0; !data && i < 5000; i++) {
> > +		mdelay(2);
> 
> That's up to 10 seconds

converted to is_timeout()

> > +		data = ocp_reg_read(tp, 0xb800) & 0x0040;
> > +	}
> > +
> > +	sram_write(tp, 0x8146, patch_key);
> > +	sram_write(tp, 0xb82e, 0x0001);
> > +
> > +	return -EBUSY;
> 
> This is ignored. At least a message why it took 10 seconds
> would be nice.

hm, this return value makes no sense. I added warning and converted
function to void.

> > +}
> > +
> > +static int r8153_post_ram_code(struct r8152 *tp)
> > +{
> > +	u16 data;
> > +
> > +	sram_write(tp, 0x0000, 0x0000);
> > +
> > +	data = ocp_reg_read(tp, 0xb82e);
> > +	data &= ~0x0001;
> > +	ocp_reg_write(tp, 0xb82e, data);
> > +
> > +	sram_write(tp, 0x8146, 0x0000);
> > +
> > +	data = ocp_reg_read(tp, 0xb820);
> > +	data &= ~0x0010;
> > +	ocp_reg_write(tp, 0xb820, data);
> > +
> > +	ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, tp->ocp_base);
> > +
> > +	return 0;
> > +}
> > +
> > +static void r8153_wdt1_end(struct r8152 *tp)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < 104; i++) {
> > +		if (!(ocp_read_byte(tp, MCU_TYPE_USB, 0xe404) & 1))
> > +			break;
> > +		mdelay(2);

converted to is_timeout()

> > +	}
> > +}
> > +
> > +void r8152b_firmware(struct r8152 *tp)
> > +{
> > +	int i;
> > +
 
Regards,
Oleksij
-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



More information about the barebox mailing list