[U-Boot] [PATCH v4 2/2] usb: eth: add Realtek RTL8152B/RTL8153 DRIVER

Marek Vasut marex at denx.de
Thu Jan 14 06:37:06 CET 2016


On Thursday, January 14, 2016 at 06:22:07 AM, Ted Chen wrote:
> This patch adds driver support for the Realtek RTL8152B/RTL8153 USB
> network adapters.

[...]

> +static void rtl8152_wait_fifo_empty(struct r8152 *tp)
> +{
> +	int i;
> +	u32 ocp_data;
> +
> +	for (i = 0; i < FIFO_EMPTY_TIMEOUT; i++) {
> +		ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
> +		if ((ocp_data & FIFO_EMPTY) == FIFO_EMPTY)
> +			break;
> +
> +		mdelay(1);
> +	}
> +
> +	if (i == FIFO_EMPTY_TIMEOUT)
> +		debug("Timeout waiting for FIFO empty\n");
> +
> +	for (i = 0; i < FIFO_EMPTY_TIMEOUT; i++) {
> +		if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0) & TCR0_TX_EMPTY)
> +			break;
> +		mdelay(1);

You can implement something like wait_for_bit() here to avoid having multiple
copies of the same code.

> +	}
> +
> +	if (i == FIFO_EMPTY_TIMEOUT)
> +		debug("Timeout waiting for TX empty\n");
> +}
> +
> +static void rtl8152_nic_reset(struct r8152 *tp)
> +{
> +	int i;
> +
> +	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, PLA_CR_RST);
> +
> +	for (i = 0; i < NIC_RESET_TIMEOUT; i++) {
> +		if (!(ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR) & PLA_CR_RST))
> +			break;
> +
> +		mdelay(1);
> +	}

DTTO here.

> +	if (i == NIC_RESET_TIMEOUT)
> +		debug("Timeout waiting for NIC reset\n");
> +}
> +
> +static u8 rtl8152_get_speed(struct r8152 *tp)
> +{
> +	return ocp_read_byte(tp, MCU_TYPE_PLA, PLA_PHYSTATUS);
> +}

[...]

> +static void r8152b_get_version(struct r8152 *tp)
> +{
> +	u32 ocp_data;
> +	u16 version;
> +
> +	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR1);
> +	version = (u16)(ocp_data & VERSION_MASK);
> +
> +	switch (version) {
> +	case 0x4c00:
> +		tp->version = RTL_VER_01;

I'd implement this as a lookup table, it might be more readable.
What do you think ?

> +		break;
> +	case 0x4c10:
> +		tp->version = RTL_VER_02;
> +		break;
> +	case 0x5c00:
> +		tp->version = RTL_VER_03;
> +		tp->supports_gmii = 1;
> +		break;
> +	case 0x5c10:
> +		tp->version = RTL_VER_04;
> +		tp->supports_gmii = 1;
> +		break;
> +	case 0x5c20:
> +		tp->version = RTL_VER_05;
> +		tp->supports_gmii = 1;
> +		break;
> +	case 0x5c30:
> +		tp->version = RTL_VER_06;
> +		tp->supports_gmii = 1;
> +		break;
> +	case 0x4800:
> +		tp->version = RTL_VER_07;
> +		break;
> +	default:
> +		printf("Unknown version 0x%04x\n", version);
> +		break;
> +	}
> +}
> +


[...]

> +static void r8153_init(struct r8152 *tp)
> +{
> +	u32 ocp_data;
> +	int i;
> +
> +	r8153_disable_aldps(tp);
> +	r8153_u1u2en(tp, false);
> +
> +	for (i = 0; i < 500; i++) {
> +		if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) &
> +		    AUTOLOAD_DONE)
> +			break;
> +		mdelay(20);

Yet another ad-hoc wait_for_bit() implementation here.

> +	}
> +
> +	for (i = 0; i < 500; i++) {
> +		ocp_data = ocp_reg_read(tp, OCP_PHY_STATUS) & PHY_STAT_MASK;
> +		if (ocp_data == PHY_STAT_LAN_ON || ocp_data == PHY_STAT_PWRDN)
> +			break;
> +		mdelay(20);

And here ...

> +	}
> +
> +	r8153_u2p3en(tp, false);
> +
> +	if (tp->version == RTL_VER_04) {
> +		ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_SSPHYLINK2);
> +		ocp_data &= ~pwd_dn_scale_mask;
> +		ocp_data |= pwd_dn_scale(96);
> +		ocp_write_word(tp, MCU_TYPE_USB, USB_SSPHYLINK2, ocp_data);
> +
> +		ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_USB2PHY);
> +		ocp_data |= USB2PHY_L1 | USB2PHY_SUSPEND;
> +		ocp_write_byte(tp, MCU_TYPE_USB, USB_USB2PHY, ocp_data);
> +	} else if (tp->version == RTL_VER_05) {
> +		ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_DMY_REG0);
> +		ocp_data &= ~ECM_ALDPS;
> +		ocp_write_byte(tp, MCU_TYPE_PLA, PLA_DMY_REG0, ocp_data);
> +
> +		ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY1);
> +		if (ocp_read_word(tp, MCU_TYPE_USB, USB_BURST_SIZE) == 0)
> +			ocp_data &= ~DYNAMIC_BURST;
> +		else
> +			ocp_data |= DYNAMIC_BURST;
> +		ocp_write_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY1, ocp_data);
> +	} else if (tp->version == RTL_VER_06) {
> +		ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY1);
> +		if (ocp_read_word(tp, MCU_TYPE_USB, USB_BURST_SIZE) == 0)
> +			ocp_data &= ~DYNAMIC_BURST;
> +		else
> +			ocp_data |= DYNAMIC_BURST;
> +		ocp_write_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY1, ocp_data);
> +	}
> +
> +	ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY2);
> +	ocp_data |= EP4_FULL_FC;
> +	ocp_write_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY2, ocp_data);
> +
> +	ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_WDT11_CTRL);
> +	ocp_data &= ~TIMER11_EN;
> +	ocp_write_word(tp, MCU_TYPE_USB, USB_WDT11_CTRL, ocp_data);
> +
> +	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE);
> +	ocp_data &= ~LED_MODE_MASK;
> +	ocp_write_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE, ocp_data);
> +
> +	ocp_data = FIFO_EMPTY_1FB | ROK_EXIT_LPM;
> +	if (tp->version == RTL_VER_04 && tp->udev->speed != USB_SPEED_SUPER)
> +		ocp_data |= LPM_TIMER_500MS;
> +	else
> +		ocp_data |= LPM_TIMER_500US;
> +	ocp_write_byte(tp, MCU_TYPE_USB, USB_LPM_CTRL, ocp_data);
> +
> +	ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_AFE_CTRL2);
> +	ocp_data &= ~SEN_VAL_MASK;
> +	ocp_data |= SEN_VAL_NORMAL | SEL_RXIDLE;
> +	ocp_write_word(tp, MCU_TYPE_USB, USB_AFE_CTRL2, ocp_data);
> +
> +	ocp_write_word(tp, MCU_TYPE_USB, USB_CONNECT_TIMER, 0x0001);
> +
> +	r8153_power_cut_en(tp, false);
> +
> +	r8152b_enable_fc(tp);
> +	rtl_tally_reset(tp);
> +}
> +
> +static void rtl8152_unload(struct r8152 *tp)
> +{
> +	if (tp->version != RTL_VER_01)
> +		r8152_power_cut_en(tp, true);
> +}
> +
> +static void rtl8153_unload(struct r8152 *tp)
> +{
> +	r8153_power_cut_en(tp, false);
> +}

[...]

> diff --git a/drivers/usb/eth/r8152_fw.c b/drivers/usb/eth/r8152_fw.c
> new file mode 100644
> index 0000000..8dc8cad
> --- /dev/null
> +++ b/drivers/usb/eth/r8152_fw.c

[...]

> +static void patch4(struct r8152 *tp)

Please make this consistent and name it with r8153_ prefix. Some more
obvious name would help too, patch4 doesn't tell me anything about the
function or what it does.

> +{
> +	u8 data;
> +
> +	data = ocp_read_byte(tp, MCU_TYPE_USB, 0xd429);
> +	data |= 0x80;
> +	ocp_write_byte(tp, MCU_TYPE_USB, 0xd429, data);
> +	ocp_write_word(tp, MCU_TYPE_USB, 0xc0ce, 0x0210);
> +	data = ocp_read_byte(tp, MCU_TYPE_USB, 0xd429);
> +	data &= ~0x80;
> +	ocp_write_byte(tp, MCU_TYPE_USB, 0xd429, data);
> +}

[...]

> +static void r8153_wdt1_end(struct r8152 *tp)
> +{

This is, again, ad-hoc implementation of wait_for_bit() alike.

> +	int i;
> +
> +	for (i = 0; i < 104; i++) {
> +		if (!(ocp_read_byte(tp, MCU_TYPE_USB, 0xe404) & 1))
> +			break;
> +		mdelay(2);
> +	}
> +}

[...]

Thanks!


More information about the U-Boot mailing list