xref: /openbmc/u-boot/drivers/usb/eth/lan7x.h (revision 0223462b373b975d970fa86e5e1a7eadd1d41820)
183d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0+ */
2d2c31979SYuiko Oshino /*
3d2c31979SYuiko Oshino  * Copyright (c) 2017 Microchip Technology Inc. All rights reserved.
4d2c31979SYuiko Oshino  */
5d2c31979SYuiko Oshino 
6d2c31979SYuiko Oshino #include <console.h>
7d2c31979SYuiko Oshino #include <watchdog.h>
8d2c31979SYuiko Oshino 
9d2c31979SYuiko Oshino /* USB Vendor Requests */
10d2c31979SYuiko Oshino #define USB_VENDOR_REQUEST_WRITE_REGISTER	0xA0
11d2c31979SYuiko Oshino #define USB_VENDOR_REQUEST_READ_REGISTER	0xA1
12d2c31979SYuiko Oshino #define USB_VENDOR_REQUEST_GET_STATS		0xA2
13d2c31979SYuiko Oshino 
14d2c31979SYuiko Oshino /* Tx Command A */
15d2c31979SYuiko Oshino #define TX_CMD_A_FCS			BIT(22)
16d2c31979SYuiko Oshino #define TX_CMD_A_LEN_MASK		0x000FFFFF
17d2c31979SYuiko Oshino 
18d2c31979SYuiko Oshino /* Rx Command A */
19d2c31979SYuiko Oshino #define RX_CMD_A_RXE			BIT(18)
20d2c31979SYuiko Oshino #define RX_CMD_A_LEN_MASK		0x00003FFF
21d2c31979SYuiko Oshino 
22d2c31979SYuiko Oshino /* SCSRs */
23d2c31979SYuiko Oshino #define ID_REV				0x00
24d2c31979SYuiko Oshino #define ID_REV_CHIP_ID_MASK		0xFFFF0000
25d2c31979SYuiko Oshino #define ID_REV_CHIP_ID_7500		0x7500
26d2c31979SYuiko Oshino #define ID_REV_CHIP_ID_7800		0x7800
27d2c31979SYuiko Oshino #define ID_REV_CHIP_ID_7850		0x7850
28d2c31979SYuiko Oshino 
29d2c31979SYuiko Oshino #define INT_STS				0x0C
30d2c31979SYuiko Oshino 
31d2c31979SYuiko Oshino #define HW_CFG				0x010
32d2c31979SYuiko Oshino #define HW_CFG_LRST			BIT(1)
33d2c31979SYuiko Oshino 
34d2c31979SYuiko Oshino #define PMT_CTL				0x014
35d2c31979SYuiko Oshino #define PMT_CTL_PHY_PWRUP		BIT(10)
36d2c31979SYuiko Oshino #define PMT_CTL_READY			BIT(7)
37d2c31979SYuiko Oshino #define PMT_CTL_PHY_RST			BIT(4)
38d2c31979SYuiko Oshino 
39d2c31979SYuiko Oshino #define E2P_CMD				0x040
40d2c31979SYuiko Oshino #define E2P_CMD_EPC_BUSY		BIT(31)
41d2c31979SYuiko Oshino #define E2P_CMD_EPC_CMD_READ		0x00000000
42d2c31979SYuiko Oshino #define E2P_CMD_EPC_TIMEOUT		BIT(10)
43d2c31979SYuiko Oshino #define E2P_CMD_EPC_ADDR_MASK		0x000001FF
44d2c31979SYuiko Oshino 
45d2c31979SYuiko Oshino #define E2P_DATA			0x044
46d2c31979SYuiko Oshino 
47d2c31979SYuiko Oshino #define RFE_CTL_BCAST_EN		BIT(10)
48d2c31979SYuiko Oshino #define RFE_CTL_DA_PERFECT		BIT(1)
49d2c31979SYuiko Oshino 
50d2c31979SYuiko Oshino #define FCT_RX_CTL_EN			BIT(31)
51d2c31979SYuiko Oshino 
52d2c31979SYuiko Oshino #define FCT_TX_CTL_EN			BIT(31)
53d2c31979SYuiko Oshino 
54d2c31979SYuiko Oshino #define MAC_CR				0x100
55d2c31979SYuiko Oshino #define MAC_CR_ADP			BIT(13)
56d2c31979SYuiko Oshino #define MAC_CR_AUTO_DUPLEX		BIT(12)
57d2c31979SYuiko Oshino #define MAC_CR_AUTO_SPEED		BIT(11)
58d2c31979SYuiko Oshino 
59d2c31979SYuiko Oshino #define MAC_RX				0x104
60d2c31979SYuiko Oshino #define MAC_RX_FCS_STRIP		BIT(4)
61d2c31979SYuiko Oshino #define MAC_RX_RXEN			BIT(0)
62d2c31979SYuiko Oshino 
63d2c31979SYuiko Oshino #define MAC_TX				0x108
64d2c31979SYuiko Oshino #define MAC_TX_TXEN			BIT(0)
65d2c31979SYuiko Oshino 
66d2c31979SYuiko Oshino #define FLOW				0x10C
67d2c31979SYuiko Oshino #define FLOW_CR_TX_FCEN			BIT(30)
68d2c31979SYuiko Oshino #define FLOW_CR_RX_FCEN			BIT(29)
69d2c31979SYuiko Oshino 
70d2c31979SYuiko Oshino #define RX_ADDRH			0x118
71d2c31979SYuiko Oshino #define RX_ADDRL			0x11C
72d2c31979SYuiko Oshino 
73d2c31979SYuiko Oshino #define MII_ACC				0x120
74d2c31979SYuiko Oshino #define MII_ACC_MII_READ		0x00000000
75d2c31979SYuiko Oshino #define MII_ACC_MII_WRITE		0x00000002
76d2c31979SYuiko Oshino #define MII_ACC_MII_BUSY		BIT(0)
77d2c31979SYuiko Oshino 
78d2c31979SYuiko Oshino #define MII_DATA			0x124
79d2c31979SYuiko Oshino 
80d2c31979SYuiko Oshino #define SS_USB_PKT_SIZE			1024
81d2c31979SYuiko Oshino #define HS_USB_PKT_SIZE			512
82d2c31979SYuiko Oshino #define FS_USB_PKT_SIZE			64
83d2c31979SYuiko Oshino 
84d2c31979SYuiko Oshino #define MAX_RX_FIFO_SIZE		(12 * 1024)
85d2c31979SYuiko Oshino #define MAX_TX_FIFO_SIZE		(12 * 1024)
86d2c31979SYuiko Oshino #define DEFAULT_BULK_IN_DELAY		0x0800
87d2c31979SYuiko Oshino 
88d2c31979SYuiko Oshino #define EEPROM_INDICATOR		0xA5
89d2c31979SYuiko Oshino #define EEPROM_MAC_OFFSET		0x01
90d2c31979SYuiko Oshino 
91d2c31979SYuiko Oshino /* Some extra defines */
92d2c31979SYuiko Oshino #define LAN7X_INTERNAL_PHY_ID		1
93d2c31979SYuiko Oshino 
94d2c31979SYuiko Oshino #define LAN7X_MAC_RX_MAX_SIZE(mtu) \
95d2c31979SYuiko Oshino 	((mtu) << 16)			/* Max frame size */
96d2c31979SYuiko Oshino #define LAN7X_MAC_RX_MAX_SIZE_DEFAULT \
97*dda52510SBin Meng 	LAN7X_MAC_RX_MAX_SIZE(PKTSIZE_ALIGN + 4 /* VLAN */ + 4 /* CRC */)
98d2c31979SYuiko Oshino 
99d2c31979SYuiko Oshino /* Timeouts */
100d2c31979SYuiko Oshino #define USB_CTRL_SET_TIMEOUT_MS		5000
101d2c31979SYuiko Oshino #define USB_CTRL_GET_TIMEOUT_MS		5000
102d2c31979SYuiko Oshino #define USB_BULK_SEND_TIMEOUT_MS	5000
103d2c31979SYuiko Oshino #define USB_BULK_RECV_TIMEOUT_MS	5000
104d2c31979SYuiko Oshino #define TIMEOUT_RESOLUTION_MS		50
105d2c31979SYuiko Oshino #define PHY_CONNECT_TIMEOUT_MS		5000
106d2c31979SYuiko Oshino 
107d2c31979SYuiko Oshino #define RX_URB_SIZE	2048
108d2c31979SYuiko Oshino 
109d2c31979SYuiko Oshino /* driver private */
110d2c31979SYuiko Oshino struct lan7x_private {
111d2c31979SYuiko Oshino 	struct ueth_data ueth;
112d2c31979SYuiko Oshino 	u32 chipid;		/* Chip or device ID */
113d2c31979SYuiko Oshino 	struct mii_dev *mdiobus;
114d2c31979SYuiko Oshino 	struct phy_device *phydev;
115d2c31979SYuiko Oshino };
116d2c31979SYuiko Oshino 
117d2c31979SYuiko Oshino /*
118d2c31979SYuiko Oshino  * Lan7x infrastructure commands
119d2c31979SYuiko Oshino  */
120d2c31979SYuiko Oshino 
121d2c31979SYuiko Oshino int lan7x_write_reg(struct usb_device *udev, u32 index, u32 data);
122d2c31979SYuiko Oshino 
123d2c31979SYuiko Oshino int lan7x_read_reg(struct usb_device *udev, u32 index, u32 *data);
124d2c31979SYuiko Oshino 
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)125d2c31979SYuiko Oshino static inline int lan7x_wait_for_bit(struct usb_device *udev,
126d2c31979SYuiko Oshino 				     const char *prefix, const u32 reg,
127d2c31979SYuiko Oshino 				     const u32 mask, const bool set,
128d2c31979SYuiko Oshino 				     const unsigned int timeout_ms,
129d2c31979SYuiko Oshino 				     const bool breakable)
130d2c31979SYuiko Oshino {
131d2c31979SYuiko Oshino 	u32 val;
132d2c31979SYuiko Oshino 	unsigned long start = get_timer(0);
133d2c31979SYuiko Oshino 
134d2c31979SYuiko Oshino 	while (1) {
135d2c31979SYuiko Oshino 		lan7x_read_reg(udev, reg, &val);
136d2c31979SYuiko Oshino 
137d2c31979SYuiko Oshino 		if (!set)
138d2c31979SYuiko Oshino 			val = ~val;
139d2c31979SYuiko Oshino 
140d2c31979SYuiko Oshino 		if ((val & mask) == mask)
141d2c31979SYuiko Oshino 			return 0;
142d2c31979SYuiko Oshino 
143d2c31979SYuiko Oshino 		if (get_timer(start) > timeout_ms)
144d2c31979SYuiko Oshino 			break;
145d2c31979SYuiko Oshino 
146d2c31979SYuiko Oshino 		if (breakable && ctrlc()) {
147d2c31979SYuiko Oshino 			puts("Abort\n");
148d2c31979SYuiko Oshino 			return -EINTR;
149d2c31979SYuiko Oshino 		}
150d2c31979SYuiko Oshino 
151d2c31979SYuiko Oshino 		udelay(1);
152d2c31979SYuiko Oshino 		WATCHDOG_RESET();
153d2c31979SYuiko Oshino 	}
154d2c31979SYuiko Oshino 
155d2c31979SYuiko Oshino 	debug("%s: Timeout (reg=0x%x mask=%08x wait_set=%i)\n", prefix, reg,
156d2c31979SYuiko Oshino 	      mask, set);
157d2c31979SYuiko Oshino 
158d2c31979SYuiko Oshino 	return -ETIMEDOUT;
159d2c31979SYuiko Oshino }
160d2c31979SYuiko Oshino 
161d2c31979SYuiko Oshino int lan7x_mdio_read(struct usb_device *udev, int phy_id, int idx);
162d2c31979SYuiko Oshino 
163d2c31979SYuiko Oshino void lan7x_mdio_write(struct usb_device *udev, int phy_id, int idx,
164d2c31979SYuiko Oshino 		      int regval);
165d2c31979SYuiko Oshino 
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)166d2c31979SYuiko Oshino static inline int lan7x_mdio_wait_for_bit(struct usb_device *udev,
167d2c31979SYuiko Oshino 					  const char *prefix,
168d2c31979SYuiko Oshino 					  int phy_id, const u32 reg,
169d2c31979SYuiko Oshino 					  const u32 mask, const bool set,
170d2c31979SYuiko Oshino 					  const unsigned int timeout_ms,
171d2c31979SYuiko Oshino 					  const bool breakable)
172d2c31979SYuiko Oshino {
173d2c31979SYuiko Oshino 	u32 val;
174d2c31979SYuiko Oshino 	unsigned long start = get_timer(0);
175d2c31979SYuiko Oshino 
176d2c31979SYuiko Oshino 	while (1) {
177d2c31979SYuiko Oshino 		val = lan7x_mdio_read(udev, phy_id, reg);
178d2c31979SYuiko Oshino 
179d2c31979SYuiko Oshino 		if (!set)
180d2c31979SYuiko Oshino 			val = ~val;
181d2c31979SYuiko Oshino 
182d2c31979SYuiko Oshino 		if ((val & mask) == mask)
183d2c31979SYuiko Oshino 			return 0;
184d2c31979SYuiko Oshino 
185d2c31979SYuiko Oshino 		if (get_timer(start) > timeout_ms)
186d2c31979SYuiko Oshino 			break;
187d2c31979SYuiko Oshino 
188d2c31979SYuiko Oshino 		if (breakable && ctrlc()) {
189d2c31979SYuiko Oshino 			puts("Abort\n");
190d2c31979SYuiko Oshino 			return -EINTR;
191d2c31979SYuiko Oshino 		}
192d2c31979SYuiko Oshino 
193d2c31979SYuiko Oshino 		udelay(1);
194d2c31979SYuiko Oshino 		WATCHDOG_RESET();
195d2c31979SYuiko Oshino 	}
196d2c31979SYuiko Oshino 
197d2c31979SYuiko Oshino 	debug("%s: Timeout (reg=0x%x mask=%08x wait_set=%i)\n", prefix, reg,
198d2c31979SYuiko Oshino 	      mask, set);
199d2c31979SYuiko Oshino 
200d2c31979SYuiko Oshino 	return -ETIMEDOUT;
201d2c31979SYuiko Oshino }
202d2c31979SYuiko Oshino 
203d2c31979SYuiko Oshino int lan7x_phylib_register(struct udevice *udev);
204d2c31979SYuiko Oshino 
205d2c31979SYuiko Oshino int lan7x_eth_phylib_connect(struct udevice *udev, struct ueth_data *dev);
206d2c31979SYuiko Oshino 
207d2c31979SYuiko Oshino int lan7x_eth_phylib_config_start(struct udevice *udev);
208d2c31979SYuiko Oshino 
209d2c31979SYuiko Oshino int lan7x_pmt_phy_reset(struct usb_device *udev,
210d2c31979SYuiko Oshino 			struct ueth_data *dev);
211d2c31979SYuiko Oshino 
212d2c31979SYuiko Oshino int lan7x_update_flowcontrol(struct usb_device *udev,
213d2c31979SYuiko Oshino 			     struct ueth_data *dev,
214d2c31979SYuiko Oshino 			     uint32_t *flow, uint32_t *fct_flow);
215d2c31979SYuiko Oshino 
216d2c31979SYuiko Oshino int lan7x_read_eeprom_mac(unsigned char *enetaddr, struct usb_device *udev);
217d2c31979SYuiko Oshino 
218d2c31979SYuiko Oshino int lan7x_basic_reset(struct usb_device *udev,
219d2c31979SYuiko Oshino 		      struct ueth_data *dev);
220d2c31979SYuiko Oshino 
221d2c31979SYuiko Oshino void lan7x_eth_stop(struct udevice *dev);
222d2c31979SYuiko Oshino 
223d2c31979SYuiko Oshino int lan7x_eth_send(struct udevice *dev, void *packet, int length);
224d2c31979SYuiko Oshino 
225d2c31979SYuiko Oshino int lan7x_eth_recv(struct udevice *dev, int flags, uchar **packetp);
226d2c31979SYuiko Oshino 
227d2c31979SYuiko Oshino int lan7x_free_pkt(struct udevice *dev, uchar *packet, int packet_len);
228d2c31979SYuiko Oshino 
229d2c31979SYuiko Oshino int lan7x_eth_remove(struct udevice *dev);
230