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