blob: 2011fd31f41aa8b5a7c2ba7f08fb56acf8fcee50 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Joe Hershberger6ab76992015-03-22 17:09:13 -05002/*
3 * Copyright (c) 2015 National Instruments
4 *
5 * (C) Copyright 2015
6 * Joe Hershberger <joe.hershberger@ni.com>
Joe Hershberger6ab76992015-03-22 17:09:13 -05007 */
8
Joe Hershberger6ab76992015-03-22 17:09:13 -05009#include <dm.h>
Simon Glass0f2af882020-05-10 11:40:05 -060010#include <log.h>
Joe Hershberger6ab76992015-03-22 17:09:13 -050011#include <malloc.h>
Joe Hershberger2260f132018-09-26 16:48:55 -050012#include <asm/eth.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060013#include <asm/global_data.h>
Joe Hershbergerbe711422015-04-21 13:57:19 -050014#include <asm/test.h>
Jerome Forissier04c4f332025-04-15 23:17:40 +020015#include <asm/types.h>
16
17/*
18 * Structure definitions for network protocols. Since this file is used for
19 * both NET and NET_LWIP, and given that the two network stacks do have
20 * conflicting types (for instance struct icmp_hdr), it is on purpose that the
21 * structures are defined locally with minimal dependencies -- <asm/types.h> is
22 * included for the bit types and that's it.
23 */
24
25#define ETHADDR_LEN 6
26#define IP4_LEN 4
27
28struct ethhdr {
29 u8 dst[ETHADDR_LEN];
30 u8 src[ETHADDR_LEN];
31 u16 protlen;
32} __attribute__((packed));
33
34#define ETHHDR_SIZE (sizeof(struct ethhdr))
35
36struct arphdr {
37 u16 htype;
38 u16 ptype;
39 u8 hlen;
40 u8 plen;
41 u16 op;
42} __attribute__((packed));
43
44#define ARPHDR_SIZE (sizeof(struct arphdr))
45
46#define ARP_REQUEST 1
47#define ARP_REPLY 2
48
49struct arpdata {
50 u8 sha[ETHADDR_LEN];
51 u32 spa;
52 u8 tha[ETHADDR_LEN];
53 u32 tpa;
54} __attribute__((packed));
55
56#define ARPDATA_SIZE (sizeof(struct arpdata))
57
58struct iphdr {
59 u8 hl_v;
60 u8 tos;
61 u16 len;
62 u16 id;
63 u16 off;
64 u8 ttl;
65 u8 prot;
66 u16 sum;
67 u32 src;
68 u32 dst;
69} __attribute__((packed));
70
71#define IPHDR_SIZE (sizeof(struct iphdr))
72
73struct icmphdr {
74 u8 type;
75 u8 code;
76 u16 checksum;
77 u16 id;
78 u16 sequence;
79} __attribute__((packed));
80
81#define ICMPHDR_SIZE (sizeof(struct icmphdr))
82
83#define ICMP_ECHO_REQUEST 8
84#define ICMP_ECHO_REPLY 0
85#define IPPROTO_ICMP 1
Joe Hershberger6ab76992015-03-22 17:09:13 -050086
87DECLARE_GLOBAL_DATA_PTR;
88
Jerome Forissier04c4f332025-04-15 23:17:40 +020089static const u8 null_ethaddr[6];
Joe Hershbergerbe711422015-04-21 13:57:19 -050090static bool skip_timeout;
Joe Hershbergera630b6c2015-03-22 17:09:19 -050091
92/*
93 * sandbox_eth_disable_response()
94 *
95 * index - The alias index (also DM seq number)
96 * disable - If non-zero, ignore sent packets and don't send mock response
97 */
98void sandbox_eth_disable_response(int index, bool disable)
99{
Joe Hershbergere4411ec2018-09-26 16:48:53 -0500100 struct udevice *dev;
101 struct eth_sandbox_priv *priv;
102 int ret;
103
104 ret = uclass_get_device(UCLASS_ETH, index, &dev);
105 if (ret)
106 return;
107
108 priv = dev_get_priv(dev);
109 priv->disabled = disable;
Joe Hershbergera630b6c2015-03-22 17:09:19 -0500110}
111
Joe Hershbergerbe711422015-04-21 13:57:19 -0500112/*
113 * sandbox_eth_skip_timeout()
114 *
115 * When the first packet read is attempted, fast-forward time
116 */
117void sandbox_eth_skip_timeout(void)
118{
119 skip_timeout = true;
120}
121
Joe Hershberger878123d2018-09-26 16:48:54 -0500122/*
123 * sandbox_eth_arp_req_to_reply()
124 *
125 * Check for an arp request to be sent. If so, inject a reply
126 *
127 * returns 0 if injected, -EAGAIN if not
128 */
129int sandbox_eth_arp_req_to_reply(struct udevice *dev, void *packet,
130 unsigned int len)
Joe Hershberger6ab76992015-03-22 17:09:13 -0500131{
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500132 struct eth_sandbox_priv *priv = dev_get_priv(dev);
Jerome Forissier04c4f332025-04-15 23:17:40 +0200133 struct ethhdr *eth = packet;
134 struct arphdr *arp;
135 struct arpdata *arpd;
136 struct ethhdr *eth_recv;
137 struct arphdr *arp_recv;
138 struct arpdata *arp_recvd;
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500139
Jerome Forissier04c4f332025-04-15 23:17:40 +0200140 if (ntohs(eth->protlen) != PROT_ARP)
Joe Hershberger878123d2018-09-26 16:48:54 -0500141 return -EAGAIN;
Joe Hershberger6ab76992015-03-22 17:09:13 -0500142
Jerome Forissier04c4f332025-04-15 23:17:40 +0200143 arp = packet + ETHHDR_SIZE;
Joe Hershberger878123d2018-09-26 16:48:54 -0500144
Jerome Forissier04c4f332025-04-15 23:17:40 +0200145 if (ntohs(arp->op) != ARP_REQUEST)
Joe Hershberger878123d2018-09-26 16:48:54 -0500146 return -EAGAIN;
147
Joe Hershberger46d2b6e2018-09-26 16:48:57 -0500148 /* Don't allow the buffer to overrun */
149 if (priv->recv_packets >= PKTBUFSRX)
150 return 0;
151
Joe Hershberger878123d2018-09-26 16:48:54 -0500152 /* store this as the assumed IP of the fake host */
Jerome Forissier04c4f332025-04-15 23:17:40 +0200153 arpd = (struct arpdata *)(arp + 1);
154 priv->fake_host_ipaddr.s_addr = arpd->tpa;
Joe Hershberger878123d2018-09-26 16:48:54 -0500155
156 /* Formulate a fake response */
Joe Hershberger46d2b6e2018-09-26 16:48:57 -0500157 eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
Jerome Forissier04c4f332025-04-15 23:17:40 +0200158 memcpy(eth_recv->dst, eth->src, ETHADDR_LEN);
159 memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN);
160 eth_recv->protlen = htons(PROT_ARP);
Joe Hershberger878123d2018-09-26 16:48:54 -0500161
Jerome Forissier04c4f332025-04-15 23:17:40 +0200162 arp_recv = (void *)eth_recv + ETHHDR_SIZE;
163 arp_recv->htype = htons(ARP_ETHER);
164 arp_recv->ptype = htons(PROT_IP);
165 arp_recv->hlen = ETHADDR_LEN;
166 arp_recv->plen = IP4_LEN;
167 arp_recv->op = htons(ARP_REPLY);
168 arp_recvd = (struct arpdata *)(arp_recv + 1);
169 memcpy(&arp_recvd->sha, priv->fake_host_hwaddr, ETHADDR_LEN);
170 arp_recvd->spa = priv->fake_host_ipaddr.s_addr;
171 memcpy(&arp_recvd->tha, &arpd->sha, ETHADDR_LEN);
172 arp_recvd->tpa = arpd->spa;
Joe Hershberger878123d2018-09-26 16:48:54 -0500173
Jerome Forissier04c4f332025-04-15 23:17:40 +0200174 priv->recv_packet_length[priv->recv_packets] = ETHHDR_SIZE +
175 ARPHDR_SIZE + ARPDATA_SIZE;
Joe Hershberger46d2b6e2018-09-26 16:48:57 -0500176 ++priv->recv_packets;
Joe Hershberger64c6c1e2018-07-02 14:47:49 -0500177
Joe Hershberger6ab76992015-03-22 17:09:13 -0500178 return 0;
179}
180
Joe Hershberger878123d2018-09-26 16:48:54 -0500181/*
182 * sandbox_eth_ping_req_to_reply()
183 *
184 * Check for a ping request to be sent. If so, inject a reply
185 *
186 * returns 0 if injected, -EAGAIN if not
187 */
188int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet,
189 unsigned int len)
Joe Hershberger6ab76992015-03-22 17:09:13 -0500190{
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500191 struct eth_sandbox_priv *priv = dev_get_priv(dev);
Jerome Forissier04c4f332025-04-15 23:17:40 +0200192 struct ethhdr *eth = packet;
193 struct iphdr *ip;
194 struct icmphdr *icmp;
195 struct ethhdr *eth_recv;
196 struct iphdr *ipr;
197 struct icmphdr *icmpr;
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500198
Jerome Forissier04c4f332025-04-15 23:17:40 +0200199 if (ntohs(eth->protlen) != PROT_IP)
Joe Hershberger878123d2018-09-26 16:48:54 -0500200 return -EAGAIN;
Joe Hershberger6ab76992015-03-22 17:09:13 -0500201
Jerome Forissier04c4f332025-04-15 23:17:40 +0200202 ip = packet + ETHHDR_SIZE;
Joe Hershbergera630b6c2015-03-22 17:09:19 -0500203
Jerome Forissier04c4f332025-04-15 23:17:40 +0200204 if (ip->prot != IPPROTO_ICMP)
Joe Hershberger878123d2018-09-26 16:48:54 -0500205 return -EAGAIN;
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500206
Jerome Forissier04c4f332025-04-15 23:17:40 +0200207 icmp = (struct icmphdr *)(ip + 1);
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500208
Joe Hershberger878123d2018-09-26 16:48:54 -0500209 if (icmp->type != ICMP_ECHO_REQUEST)
210 return -EAGAIN;
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500211
Joe Hershberger46d2b6e2018-09-26 16:48:57 -0500212 /* Don't allow the buffer to overrun */
213 if (priv->recv_packets >= PKTBUFSRX)
214 return 0;
215
Joe Hershberger878123d2018-09-26 16:48:54 -0500216 /* reply to the ping */
Joe Hershberger46d2b6e2018-09-26 16:48:57 -0500217 eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
Joe Hershberger878123d2018-09-26 16:48:54 -0500218 memcpy(eth_recv, packet, len);
Jerome Forissier04c4f332025-04-15 23:17:40 +0200219 ipr = (void *)eth_recv + ETHHDR_SIZE;
220 icmpr = (struct icmphdr *)(ipr + 1);
221 memcpy(eth_recv->dst, eth->src, ETHADDR_LEN);
222 memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN);
223 ipr->sum = 0;
224 ipr->off = 0;
225 ipr->dst = ip->src;
226 ipr->src = priv->fake_host_ipaddr.s_addr;
227 ipr->sum = compute_ip_checksum(ipr, IPHDR_SIZE);
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500228
Joe Hershberger878123d2018-09-26 16:48:54 -0500229 icmpr->type = ICMP_ECHO_REPLY;
230 icmpr->checksum = 0;
Jerome Forissier04c4f332025-04-15 23:17:40 +0200231 icmpr->checksum = compute_ip_checksum(icmpr, ICMPHDR_SIZE);
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500232
Joe Hershberger46d2b6e2018-09-26 16:48:57 -0500233 priv->recv_packet_length[priv->recv_packets] = len;
234 ++priv->recv_packets;
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500235
Joe Hershberger878123d2018-09-26 16:48:54 -0500236 return 0;
237}
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500238
Joe Hershberger2260f132018-09-26 16:48:55 -0500239/*
Joe Hershberger54418d02018-09-26 16:49:00 -0500240 * sandbox_eth_recv_arp_req()
241 *
242 * Inject an ARP request for this target
243 *
244 * returns 0 if injected, -EOVERFLOW if not
245 */
246int sandbox_eth_recv_arp_req(struct udevice *dev)
247{
248 struct eth_sandbox_priv *priv = dev_get_priv(dev);
Jerome Forissier04c4f332025-04-15 23:17:40 +0200249 struct ethhdr *eth_recv;
250 struct arphdr *arp_recv;
251 struct arpdata *arp_recvd;
Joe Hershberger54418d02018-09-26 16:49:00 -0500252
253 /* Don't allow the buffer to overrun */
254 if (priv->recv_packets >= PKTBUFSRX)
255 return -EOVERFLOW;
256
257 /* Formulate a fake request */
258 eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
Jerome Forissier04c4f332025-04-15 23:17:40 +0200259 memcpy(eth_recv->dst, net_bcast_ethaddr, ETHADDR_LEN);
260 memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN);
261 eth_recv->protlen = htons(PROT_ARP);
Joe Hershberger54418d02018-09-26 16:49:00 -0500262
Jerome Forissier04c4f332025-04-15 23:17:40 +0200263 arp_recv = (void *)eth_recv + ETHHDR_SIZE;
264 arp_recv->htype = htons(ARP_ETHER);
265 arp_recv->ptype = htons(PROT_IP);
266 arp_recv->hlen = ETHADDR_LEN;
267 arp_recv->plen = IP4_LEN;
268 arp_recv->op = htons(ARP_REQUEST);
269 arp_recvd = (struct arpdata *)(arp_recv + 1);
270 memcpy(&arp_recvd->sha, priv->fake_host_hwaddr, ETHADDR_LEN);
271 arp_recvd->spa = priv->fake_host_ipaddr.s_addr;
272 memcpy(&arp_recvd->tha, null_ethaddr, ETHADDR_LEN);
273 arp_recvd->tpa = net_ip.s_addr;
Joe Hershberger54418d02018-09-26 16:49:00 -0500274
275 priv->recv_packet_length[priv->recv_packets] =
Jerome Forissier04c4f332025-04-15 23:17:40 +0200276 ETHHDR_SIZE + ARPHDR_SIZE + ARPDATA_SIZE;
Joe Hershberger54418d02018-09-26 16:49:00 -0500277 ++priv->recv_packets;
278
279 return 0;
280}
281
282/*
Joe Hershberger9716dc12018-09-26 16:49:01 -0500283 * sandbox_eth_recv_ping_req()
284 *
285 * Inject a ping request for this target
286 *
287 * returns 0 if injected, -EOVERFLOW if not
288 */
289int sandbox_eth_recv_ping_req(struct udevice *dev)
290{
291 struct eth_sandbox_priv *priv = dev_get_priv(dev);
Jerome Forissier04c4f332025-04-15 23:17:40 +0200292 struct eth_pdata *pdata = dev_get_plat(dev);
293 struct ethhdr *eth_recv;
294 struct iphdr *ipr;
295 struct icmphdr *icmpr;
Joe Hershberger9716dc12018-09-26 16:49:01 -0500296
297 /* Don't allow the buffer to overrun */
298 if (priv->recv_packets >= PKTBUFSRX)
299 return -EOVERFLOW;
300
301 /* Formulate a fake ping */
302 eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
303
Jerome Forissier04c4f332025-04-15 23:17:40 +0200304 memcpy(eth_recv->dst, pdata->enetaddr, ETHADDR_LEN);
305 memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN);
306 eth_recv->protlen = htons(PROT_IP);
Joe Hershberger9716dc12018-09-26 16:49:01 -0500307
Jerome Forissier04c4f332025-04-15 23:17:40 +0200308 ipr = (void *)eth_recv + ETHHDR_SIZE;
309 ipr->hl_v = 0x45;
310 ipr->len = htons(IPHDR_SIZE + ICMPHDR_SIZE);
311 ipr->off = htons(IP_FLAGS_DFRAG);
312 ipr->prot = IPPROTO_ICMP;
313 ipr->sum = 0;
314 ipr->src = priv->fake_host_ipaddr.s_addr;
315 ipr->dst = net_ip.s_addr;
316 ipr->sum = compute_ip_checksum(ipr, IPHDR_SIZE);
Joe Hershberger9716dc12018-09-26 16:49:01 -0500317
Jerome Forissier04c4f332025-04-15 23:17:40 +0200318 icmpr = (struct icmphdr *)(ipr + 1);
Joe Hershberger9716dc12018-09-26 16:49:01 -0500319
320 icmpr->type = ICMP_ECHO_REQUEST;
321 icmpr->code = 0;
322 icmpr->checksum = 0;
Jerome Forissier04c4f332025-04-15 23:17:40 +0200323 icmpr->id = 0;
324 icmpr->sequence = htons(1);
325 icmpr->checksum = compute_ip_checksum(icmpr, ICMPHDR_SIZE);
Joe Hershberger9716dc12018-09-26 16:49:01 -0500326
327 priv->recv_packet_length[priv->recv_packets] =
Jerome Forissier04c4f332025-04-15 23:17:40 +0200328 ETHHDR_SIZE + IPHDR_SIZE + ICMPHDR_SIZE;
Joe Hershberger9716dc12018-09-26 16:49:01 -0500329 ++priv->recv_packets;
330
331 return 0;
332}
333
334/*
Joe Hershberger2260f132018-09-26 16:48:55 -0500335 * sb_default_handler()
336 *
337 * perform typical responses to simple ping
338 *
339 * dev - device pointer
340 * pkt - "sent" packet buffer
341 * len - length of packet
342 */
343static int sb_default_handler(struct udevice *dev, void *packet,
344 unsigned int len)
345{
346 if (!sandbox_eth_arp_req_to_reply(dev, packet, len))
347 return 0;
348 if (!sandbox_eth_ping_req_to_reply(dev, packet, len))
349 return 0;
350
351 return 0;
352}
353
354/*
355 * sandbox_eth_set_tx_handler()
356 *
357 * Set a custom response to a packet being sent through the sandbox eth test
358 * driver
359 *
360 * index - interface to set the handler for
361 * handler - The func ptr to call on send. If NULL, set to default handler
362 */
363void sandbox_eth_set_tx_handler(int index, sandbox_eth_tx_hand_f *handler)
364{
365 struct udevice *dev;
366 struct eth_sandbox_priv *priv;
367 int ret;
368
369 ret = uclass_get_device(UCLASS_ETH, index, &dev);
370 if (ret)
371 return;
372
373 priv = dev_get_priv(dev);
374 if (handler)
375 priv->tx_handler = handler;
376 else
377 priv->tx_handler = sb_default_handler;
378}
379
Joe Hershberger11b85032018-09-26 16:48:59 -0500380/*
381 * Set priv ptr
382 *
383 * priv - priv void ptr to store in the device
384 */
385void sandbox_eth_set_priv(int index, void *priv)
386{
387 struct udevice *dev;
388 struct eth_sandbox_priv *dev_priv;
389 int ret;
390
391 ret = uclass_get_device(UCLASS_ETH, index, &dev);
392 if (ret)
393 return;
394
395 dev_priv = dev_get_priv(dev);
396
397 dev_priv->priv = priv;
398}
399
Joe Hershberger878123d2018-09-26 16:48:54 -0500400static int sb_eth_start(struct udevice *dev)
401{
402 struct eth_sandbox_priv *priv = dev_get_priv(dev);
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500403
Joe Hershberger878123d2018-09-26 16:48:54 -0500404 debug("eth_sandbox: Start\n");
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500405
Joe Hershberger46d2b6e2018-09-26 16:48:57 -0500406 priv->recv_packets = 0;
407 for (int i = 0; i < PKTBUFSRX; i++) {
408 priv->recv_packet_buffer[i] = net_rx_packets[i];
409 priv->recv_packet_length[i] = 0;
410 }
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500411
Joe Hershberger6ab76992015-03-22 17:09:13 -0500412 return 0;
413}
414
Joe Hershberger878123d2018-09-26 16:48:54 -0500415static int sb_eth_send(struct udevice *dev, void *packet, int length)
416{
417 struct eth_sandbox_priv *priv = dev_get_priv(dev);
418
419 debug("eth_sandbox: Send packet %d\n", length);
420
421 if (priv->disabled)
422 return 0;
423
Joe Hershberger2260f132018-09-26 16:48:55 -0500424 return priv->tx_handler(dev, packet, length);
Joe Hershberger878123d2018-09-26 16:48:54 -0500425}
426
Simon Glassdc6eda32015-07-06 16:47:49 -0600427static int sb_eth_recv(struct udevice *dev, int flags, uchar **packetp)
Joe Hershberger6ab76992015-03-22 17:09:13 -0500428{
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500429 struct eth_sandbox_priv *priv = dev_get_priv(dev);
430
Joe Hershbergerbe711422015-04-21 13:57:19 -0500431 if (skip_timeout) {
Neil Armstrong77c0dbc2019-04-11 17:01:23 +0200432 timer_test_add_offset(11000UL);
Joe Hershbergerbe711422015-04-21 13:57:19 -0500433 skip_timeout = false;
434 }
435
Joe Hershberger46d2b6e2018-09-26 16:48:57 -0500436 if (priv->recv_packets) {
437 int lcl_recv_packet_length = priv->recv_packet_length[0];
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500438
Joe Hershberger46d2b6e2018-09-26 16:48:57 -0500439 debug("eth_sandbox: received packet[%d], %d waiting\n",
440 lcl_recv_packet_length, priv->recv_packets - 1);
441 *packetp = priv->recv_packet_buffer[0];
Joe Hershbergere4d7cb12015-03-22 17:09:14 -0500442 return lcl_recv_packet_length;
443 }
Joe Hershberger6ab76992015-03-22 17:09:13 -0500444 return 0;
445}
446
Joe Hershberger46d2b6e2018-09-26 16:48:57 -0500447static int sb_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
448{
449 struct eth_sandbox_priv *priv = dev_get_priv(dev);
450 int i;
451
452 if (!priv->recv_packets)
453 return 0;
454
455 --priv->recv_packets;
456 for (i = 0; i < priv->recv_packets; i++) {
457 priv->recv_packet_length[i] = priv->recv_packet_length[i + 1];
458 memcpy(priv->recv_packet_buffer[i],
459 priv->recv_packet_buffer[i + 1],
460 priv->recv_packet_length[i + 1]);
461 }
462 priv->recv_packet_length[priv->recv_packets] = 0;
463
464 return 0;
465}
466
Joe Hershberger6ab76992015-03-22 17:09:13 -0500467static void sb_eth_stop(struct udevice *dev)
468{
469 debug("eth_sandbox: Stop\n");
470}
471
472static int sb_eth_write_hwaddr(struct udevice *dev)
473{
Simon Glassfa20e932020-12-03 16:55:20 -0700474 struct eth_pdata *pdata = dev_get_plat(dev);
Sean Anderson5d7af612022-05-05 13:11:33 -0400475 struct eth_sandbox_priv *priv = dev_get_priv(dev);
Joe Hershberger6ab76992015-03-22 17:09:13 -0500476
477 debug("eth_sandbox %s: Write HW ADDR - %pM\n", dev->name,
478 pdata->enetaddr);
Jerome Forissier04c4f332025-04-15 23:17:40 +0200479 memcpy(priv->fake_host_hwaddr, pdata->enetaddr, ETHADDR_LEN);
Joe Hershberger6ab76992015-03-22 17:09:13 -0500480 return 0;
481}
482
483static const struct eth_ops sb_eth_ops = {
484 .start = sb_eth_start,
485 .send = sb_eth_send,
486 .recv = sb_eth_recv,
Joe Hershberger46d2b6e2018-09-26 16:48:57 -0500487 .free_pkt = sb_eth_free_pkt,
Joe Hershberger6ab76992015-03-22 17:09:13 -0500488 .stop = sb_eth_stop,
489 .write_hwaddr = sb_eth_write_hwaddr,
490};
491
492static int sb_eth_remove(struct udevice *dev)
493{
494 return 0;
495}
496
Simon Glassaad29ae2020-12-03 16:55:21 -0700497static int sb_eth_of_to_plat(struct udevice *dev)
Joe Hershberger6ab76992015-03-22 17:09:13 -0500498{
Simon Glassfa20e932020-12-03 16:55:20 -0700499 struct eth_pdata *pdata = dev_get_plat(dev);
Joe Hershberger64c6c1e2018-07-02 14:47:49 -0500500 struct eth_sandbox_priv *priv = dev_get_priv(dev);
Joe Hershberger64c6c1e2018-07-02 14:47:49 -0500501
502 pdata->iobase = dev_read_addr(dev);
Joe Hershbergere4411ec2018-09-26 16:48:53 -0500503 priv->disabled = false;
Joe Hershberger2260f132018-09-26 16:48:55 -0500504 priv->tx_handler = sb_default_handler;
Joe Hershberger6ab76992015-03-22 17:09:13 -0500505
Joe Hershberger6ab76992015-03-22 17:09:13 -0500506 return 0;
507}
508
509static const struct udevice_id sb_eth_ids[] = {
510 { .compatible = "sandbox,eth" },
511 { }
512};
513
514U_BOOT_DRIVER(eth_sandbox) = {
515 .name = "eth_sandbox",
516 .id = UCLASS_ETH,
517 .of_match = sb_eth_ids,
Simon Glassaad29ae2020-12-03 16:55:21 -0700518 .of_to_plat = sb_eth_of_to_plat,
Joe Hershberger6ab76992015-03-22 17:09:13 -0500519 .remove = sb_eth_remove,
520 .ops = &sb_eth_ops,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700521 .priv_auto = sizeof(struct eth_sandbox_priv),
Simon Glass71fa5b42020-12-03 16:55:18 -0700522 .plat_auto = sizeof(struct eth_pdata),
Joe Hershberger6ab76992015-03-22 17:09:13 -0500523};