summaryrefslogtreecommitdiff
path: root/cmd/sbc_harness/hw/w5500.h
blob: bb629c5dc36dee3335b157f050be31d6e6ab8676 (plain)
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_ */