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
|
/* hw/w5500.h - libnet implementation for the WIZnet W5500 chip
*
* Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-Licence-Identifier: AGPL-3.0-or-later
*/
#ifndef _HW_W5500_H_
#define _HW_W5500_H_
#include <libnet/libnet.h>
#include "hw/spi.h"
struct _w5500_listener;
struct _w5500_conn {
struct libnet_conn_vtable *vtable;
struct _w5500_listener *parent_listener;
};
struct _w5500_listener {
struct libnet_listener_vtable *vtable;
struct w5500 *chip;
uint8_t socknum;
struct _w5500_conn active_conn;
};
struct w5500 {
struct spi *spidev;
uint pin_reset;
struct _w5500_listener _listeners[8];
uint16_t _next_local_port;
};
/**
* Initialize a WIZnet W5500 Ethernet-and-TCP/IP-offload chip.
*
* The W5500 has 3 channels of communication with the MCU:
*
* - An SPI-based RPC protocol:
* + mode: mode 0 or mode 3
* + bit-order: MSB-first
* + clock frequency: 33.3MHz - 80MHz
* - An interrupt pin that it pulls low when an event happens (to let
* the MCU know that it should do an SPI RPC "get" to see what
* happened.)
* - A reset pin that the MCU can pull low to reset the W5500.
*/
#define w5500_init(self, name, spi, pin_intr, pin_reset, eth_addr) do { \
bi_decl(bi_2pins_with_names(pin_intr, name" interrupt", \
pin_reset, name" reset")); \
_w5500_init(self, spi, pin_intr, pin_reset, eth_addr); \
} while (0)
void _w5500_init(struct w5500 *self,
struct spi* spi, uint pin_intr, uint pin_reset,
struct eth_addr addr);
/**
* TODO.
*/
void w5500_reset(struct w5500 *self);
struct w5500_netcfg {
struct ip4_addr gateway_addr;
struct ip4_addr subnet_mask;
struct ip4_addr addr;
};
/**
* TODO.
*/
void w5500_netcfg(struct w5500 *self, struct w5500_netcfg cfg);
struct libnet_listener *w5500_listen(struct w5500 *self, uint8_t socknum, uint16_t port);
#endif /* _HW_W5500_H_ */
|