[U-Boot] [PATCH 2/2] usb: eth: add Realtek RTL8152B/RTL8153 driver
Marek Vasut
marex at denx.de
Sat Nov 14 02:13:56 CET 2015
On Friday, November 13, 2015 at 05:03:01 PM, Stephen Warren wrote:
> From: Ted Chen <tedchen at realtek.com>
Hi,
> This patch adds driver support for the Realtek RTL8152B/RTL8153 USB
> network adapters.
>
> Signed-off-by: Ted Chen <tedchen at realtek.com>
> [swarren, fixed a few compiler warnings]
> [swarren, with permission, converted license header to SPDX]
> [swarren, removed printf() spew during probe()]
> Signed-off-by: Stephen Warren <swarren at nvidia.com>
[...]
> new file mode 100644
> index 000000000000..7ab08bef4111
> --- /dev/null
> +++ b/drivers/usb/eth/r8152.c
> @@ -0,0 +1,3809 @@
> +/*
> + * Copyright (c) 2015 Realtek Semiconductor Corp. All rights reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0
> + *
> + * This product is covered by one or more of the following patents:
> + * US6,570,884, US6,115,776, and US6,327,625.
Why do we even care, does this have any significance ?
> + */
> +
> +#include <common.h>
> +#include <errno.h>
> +#include <malloc.h>
> +#include <usb.h>
> +#include <usb/lin_gadget_compat.h>
> +#include <linux/mii.h>
> +#include <linux/bitops.h>
> +#include "usb_ether.h"
> +
> +#define DRIVER_VERSION "v1.0 (2015/09/17)"
This macro is unused, please remove it.
> +#define PATENTS "This product is covered by one or more of the "
\
> + "following patents:\n" \
> + "\t\tUS6,570,884, US6,115,776, and US6,327,625.\n"
DTTO
[...]
> +/* OCP_EEE_CONFIG1 */
> +#define RG_TXLPI_MSK_HFDUP 0x8000
> +#define RG_MATCLR_EN 0x4000
> +#define EEE_10_CAP 0x2000
> +#define EEE_NWAY_EN 0x1000
> +#define TX_QUIET_EN 0x0200
> +#define RX_QUIET_EN 0x0100
> +#define sd_rise_time_mask 0x0070
> +#define sd_rise_time(x) (min(x, 7) << 4) /* bit 4 ~ 6 */
Should be min((x).....) , the x should be in parenthesis, please fix globally.
> +#define RG_RXLPI_MSK_HFDUP 0x0008
> +#define SDFALLTIME 0x0007 /* bit 0 ~ 2 */
> +
> +/* OCP_EEE_CONFIG2 */
> +#define RG_LPIHYS_NUM 0x7000 /* bit 12 ~ 15 */
> +#define RG_DACQUIET_EN 0x0400
> +#define RG_LDVQUIET_EN 0x0200
> +#define RG_CKRSEL 0x0020
> +#define RG_EEEPRG_EN 0x0010
> +
> +/* OCP_EEE_CONFIG3 */
> +#define fast_snr_mask 0xff80
> +#define fast_snr(x) (min(x, 0x1ff) << 7) /* bit 7 ~ 15 */
DTTO.
> +#define RG_LFS_SEL 0x0060 /* bit 6 ~ 5 */
> +#define MSK_PH 0x0006 /* bit 0 ~ 3 */
[...]
> +struct tally_counter {
> + __le64 tx_packets;
Shouldn't this be standard u64 ?
> + __le64 rx_packets;
> + __le64 tx_errors;
> + __le32 rx_errors;
> + __le16 rx_missed;
> + __le16 align_errors;
> + __le32 tx_one_collision;
> + __le32 tx_multi_collision;
> + __le64 rx_unicast;
> + __le64 rx_broadcast;
> + __le32 rx_multicast;
> + __le16 tx_aborted;
> + __le16 tx_underrun;
> +};
[...]
> +struct r8152;
This forward declaration can be removed.
> +struct r8152 {
> + struct usb_device *udev;
> + struct usb_interface *intf;
> + bool supports_gmii;
> +
> + struct rtl_ops {
> + void (*init)(struct r8152 *);
> + int (*enable)(struct r8152 *);
> + void (*disable)(struct r8152 *);
> + void (*up)(struct r8152 *);
> + void (*down)(struct r8152 *);
> + void (*unload)(struct r8152 *);
> + } rtl_ops;
> +
> + u32 coalesce;
> + u16 ocp_base;
> +
> + u8 version;
> +};
[...]
> +#define agg_buf_sz 2048
> +
> +/* local vars */
> +static int curr_eth_dev; /* index for name of next device detected */
Shouldn't we remove this for the sake of using DM ?
> +#define R8152_BASE_NAME "r8152"
> +
> +
> +struct r8152_dongle {
> + unsigned short vendor;
> + unsigned short product;
> +};
[...]
> +#define msleep(a) udelay(a * 1000)
That's called mdelay(), so please remove this and use mdelay()
> +#define BIT(nr) (1UL << (nr))
Don't we have a generic declaration of this bit macro ?
> +static
> +int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void
> *data) +{
> + int ret;
> + void *tmp;
> +
> + tmp = kmalloc(size, GFP_KERNEL);
> + if (!tmp)
> + return -ENOMEM;
Allocating the structure on stack would be faster than doing this
malloc-free dance, right? Please fix globally.
> + ret = usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0),
> + RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
> + value, index, tmp, size, 500);
> + if (ret < 0)
> + memset(data, 0xff, size);
> + else
> + memcpy(data, tmp, size);
> +
> + kfree(tmp);
> +
> + return ret;
> +}
[...]
> +static int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen,
> + u16 size, void *data, u16 type)
> +{
> + int ret;
> + u16 byteen_start, byteen_end, byen;
> + u16 limit = 512;
> +
> + /* both size and indix must be 4 bytes align */
> + if ((size & 3) || !size || (index & 3) || !data)
> + return -EPERM;
> +
> + if ((u32)index + (u32)size > 0xffff)
Please review unnecessary typecast before next submission and remove them.
> + return -EPERM;
> +
> + byteen_start = byteen & BYTE_EN_START_MASK;
> + byteen_end = byteen & BYTE_EN_END_MASK;
> +
> + byen = byteen_start | (byteen_start << 4);
> + ret = set_registers(tp, index, type | byen, 4, data);
> + if (ret < 0)
> + goto error1;
> +
> + index += 4;
> + data += 4;
> + size -= 4;
[...]
> +static void rtl_disable(struct r8152 *tp)
> +{
> + u32 ocp_data;
> + int i;
> +
> + ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
> + ocp_data &= ~RCR_ACPT_ALL;
> + ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
> +
> + rxdy_gated_en(tp, true);
> +
> + for (i = 0; i < 1000; i++) {
> + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
> + if ((ocp_data & FIFO_EMPTY) == FIFO_EMPTY)
> + break;
> +
> + udelay(2000);
> + }
Is this a poor-man's attempt at implementing wait-for-bit sort of functionality?
If so, I'm concerned about the case where that bit is never set/unset, since
this case is not handled by the code.
Also, you can fix udelay(2000) to mdelay(2), but this sort of wait-for-bit
should prefferably use get_timer() instead.
> + for (i = 0; i < 1000; i++) {
> + if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0) & TCR0_TX_EMPTY)
> + break;
> + udelay(2000);
> + }
> +
> + rtl8152_nic_reset(tp);
> +}
[...]
> +static void r8152b_firmware(struct r8152 *tp)
> +{
> + if (tp->version == RTL_VER_01) {
> + int i;
> + static u8 pla_patch_a[] = {
> + 0x08, 0xe0, 0x40, 0xe0,
> + 0x78, 0xe0, 0x85, 0xe0,
[...]
I think it might be better to pull this firmware blob into either a separate
header file or into global variable. Also, it would make sense to reformat
this array such that there would be more elements on a line (8 or 16), so
that the declaration makes better use of horizontal space.
> + 0x00, 0x00, 0x02, 0xc6,
> + 0x00, 0xbe, 0x00, 0x00,
> + 0x00, 0x00, 0x00, 0x00 };
> +
> + rtl_clear_bp(tp);
> +
> + generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch_a2),
> + pla_patch_a2, MCU_TYPE_PLA);
> +
> + ocp_write_word(tp, MCU_TYPE_PLA, 0xfc26, 0x8000);
> +
> + ocp_write_word(tp, MCU_TYPE_PLA, 0xfc28, 0x17a5);
> + ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2a, 0x13ad);
> + ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2c, 0x184d);
> + ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2e, 0x01e1);
> + }
> +}
[...]
> +static void r8153_firmware(struct r8152 *tp)
> +{
> + if (tp->version == RTL_VER_03) {
> + r8153_clear_bp(tp);
> +
> + r8153_pre_ram_code(tp, 0x7000);
> + sram_write(tp, 0xb820, 0x0290);
> + sram_write(tp, 0xa012, 0x0000);
> + sram_write(tp, 0xa014, 0x2c04);
> + ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x2c18);
> + ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x2c45);
> + ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x2c45);
DTTO here, a nice loop over an array would be helpful.
[...]
> + ocp_write_word(tp, MCU_TYPE_USB, 0xfc32, 0x0000);
> + ocp_write_word(tp, MCU_TYPE_USB, 0xfc34, 0x0000);
> + ocp_write_word(tp, MCU_TYPE_USB, 0xfc36, 0x0000);
> + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x000c);
> + }
> +}
[...]
The beginning looked really crude, but the rest of the driver looked much
better then. Thanks!
More information about the U-Boot
mailing list