123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- /* SPDX-License-Identifier: GPL-2.0+ */
- /*
- * Copyright (c) 2017 Microchip Technology Inc. All rights reserved.
- */
- #include <console.h>
- #include <watchdog.h>
- /* USB Vendor Requests */
- #define USB_VENDOR_REQUEST_WRITE_REGISTER 0xA0
- #define USB_VENDOR_REQUEST_READ_REGISTER 0xA1
- #define USB_VENDOR_REQUEST_GET_STATS 0xA2
- /* Tx Command A */
- #define TX_CMD_A_FCS BIT(22)
- #define TX_CMD_A_LEN_MASK 0x000FFFFF
- /* Rx Command A */
- #define RX_CMD_A_RXE BIT(18)
- #define RX_CMD_A_LEN_MASK 0x00003FFF
- /* SCSRs */
- #define ID_REV 0x00
- #define ID_REV_CHIP_ID_MASK 0xFFFF0000
- #define ID_REV_CHIP_ID_7500 0x7500
- #define ID_REV_CHIP_ID_7800 0x7800
- #define ID_REV_CHIP_ID_7850 0x7850
- #define INT_STS 0x0C
- #define HW_CFG 0x010
- #define HW_CFG_LRST BIT(1)
- #define PMT_CTL 0x014
- #define PMT_CTL_PHY_PWRUP BIT(10)
- #define PMT_CTL_READY BIT(7)
- #define PMT_CTL_PHY_RST BIT(4)
- #define E2P_CMD 0x040
- #define E2P_CMD_EPC_BUSY BIT(31)
- #define E2P_CMD_EPC_CMD_READ 0x00000000
- #define E2P_CMD_EPC_TIMEOUT BIT(10)
- #define E2P_CMD_EPC_ADDR_MASK 0x000001FF
- #define E2P_DATA 0x044
- #define RFE_CTL_BCAST_EN BIT(10)
- #define RFE_CTL_DA_PERFECT BIT(1)
- #define FCT_RX_CTL_EN BIT(31)
- #define FCT_TX_CTL_EN BIT(31)
- #define MAC_CR 0x100
- #define MAC_CR_ADP BIT(13)
- #define MAC_CR_AUTO_DUPLEX BIT(12)
- #define MAC_CR_AUTO_SPEED BIT(11)
- #define MAC_RX 0x104
- #define MAC_RX_FCS_STRIP BIT(4)
- #define MAC_RX_RXEN BIT(0)
- #define MAC_TX 0x108
- #define MAC_TX_TXEN BIT(0)
- #define FLOW 0x10C
- #define FLOW_CR_TX_FCEN BIT(30)
- #define FLOW_CR_RX_FCEN BIT(29)
- #define RX_ADDRH 0x118
- #define RX_ADDRL 0x11C
- #define MII_ACC 0x120
- #define MII_ACC_MII_READ 0x00000000
- #define MII_ACC_MII_WRITE 0x00000002
- #define MII_ACC_MII_BUSY BIT(0)
- #define MII_DATA 0x124
- #define SS_USB_PKT_SIZE 1024
- #define HS_USB_PKT_SIZE 512
- #define FS_USB_PKT_SIZE 64
- #define MAX_RX_FIFO_SIZE (12 * 1024)
- #define MAX_TX_FIFO_SIZE (12 * 1024)
- #define DEFAULT_BULK_IN_DELAY 0x0800
- #define EEPROM_INDICATOR 0xA5
- #define EEPROM_MAC_OFFSET 0x01
- /* Some extra defines */
- #define LAN7X_INTERNAL_PHY_ID 1
- #define LAN7X_MAC_RX_MAX_SIZE(mtu) \
- ((mtu) << 16) /* Max frame size */
- #define LAN7X_MAC_RX_MAX_SIZE_DEFAULT \
- LAN7X_MAC_RX_MAX_SIZE(PKTSIZE_ALIGN + 4 /* VLAN */ + 4 /* CRC */)
- /* Timeouts */
- #define USB_CTRL_SET_TIMEOUT_MS 5000
- #define USB_CTRL_GET_TIMEOUT_MS 5000
- #define USB_BULK_SEND_TIMEOUT_MS 5000
- #define USB_BULK_RECV_TIMEOUT_MS 5000
- #define TIMEOUT_RESOLUTION_MS 50
- #define PHY_CONNECT_TIMEOUT_MS 5000
- #define RX_URB_SIZE 2048
- /* driver private */
- struct lan7x_private {
- struct ueth_data ueth;
- u32 chipid; /* Chip or device ID */
- struct mii_dev *mdiobus;
- struct phy_device *phydev;
- };
- /*
- * Lan7x infrastructure commands
- */
- int lan7x_write_reg(struct usb_device *udev, u32 index, u32 data);
- int lan7x_read_reg(struct usb_device *udev, u32 index, u32 *data);
- static inline int lan7x_wait_for_bit(struct usb_device *udev,
- const char *prefix, const u32 reg,
- const u32 mask, const bool set,
- const unsigned int timeout_ms,
- const bool breakable)
- {
- u32 val;
- unsigned long start = get_timer(0);
- while (1) {
- lan7x_read_reg(udev, reg, &val);
- if (!set)
- val = ~val;
- if ((val & mask) == mask)
- return 0;
- if (get_timer(start) > timeout_ms)
- break;
- if (breakable && ctrlc()) {
- puts("Abort\n");
- return -EINTR;
- }
- udelay(1);
- WATCHDOG_RESET();
- }
- debug("%s: Timeout (reg=0x%x mask=%08x wait_set=%i)\n", prefix, reg,
- mask, set);
- return -ETIMEDOUT;
- }
- int lan7x_mdio_read(struct usb_device *udev, int phy_id, int idx);
- void lan7x_mdio_write(struct usb_device *udev, int phy_id, int idx,
- int regval);
- static inline int lan7x_mdio_wait_for_bit(struct usb_device *udev,
- const char *prefix,
- int phy_id, const u32 reg,
- const u32 mask, const bool set,
- const unsigned int timeout_ms,
- const bool breakable)
- {
- u32 val;
- unsigned long start = get_timer(0);
- while (1) {
- val = lan7x_mdio_read(udev, phy_id, reg);
- if (!set)
- val = ~val;
- if ((val & mask) == mask)
- return 0;
- if (get_timer(start) > timeout_ms)
- break;
- if (breakable && ctrlc()) {
- puts("Abort\n");
- return -EINTR;
- }
- udelay(1);
- WATCHDOG_RESET();
- }
- debug("%s: Timeout (reg=0x%x mask=%08x wait_set=%i)\n", prefix, reg,
- mask, set);
- return -ETIMEDOUT;
- }
- int lan7x_phylib_register(struct udevice *udev);
- int lan7x_eth_phylib_connect(struct udevice *udev, struct ueth_data *dev);
- int lan7x_eth_phylib_config_start(struct udevice *udev);
- int lan7x_pmt_phy_reset(struct usb_device *udev,
- struct ueth_data *dev);
- int lan7x_update_flowcontrol(struct usb_device *udev,
- struct ueth_data *dev,
- uint32_t *flow, uint32_t *fct_flow);
- int lan7x_read_eeprom_mac(unsigned char *enetaddr, struct usb_device *udev);
- int lan7x_basic_reset(struct usb_device *udev,
- struct ueth_data *dev);
- void lan7x_eth_stop(struct udevice *dev);
- int lan7x_eth_send(struct udevice *dev, void *packet, int length);
- int lan7x_eth_recv(struct udevice *dev, int flags, uchar **packetp);
- int lan7x_free_pkt(struct udevice *dev, uchar *packet, int packet_len);
- int lan7x_eth_remove(struct udevice *dev);
|