hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
/*
 * Copyright (c) 2017 Microchip Technology Inc. All rights reserved.
 *
 * SPDX-License-Identifier:    GPL-2.0+
 */
 
#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(ETH_FRAME_LEN + 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);