diff options
Diffstat (limited to 'core/legacynet/core.c')
-rw-r--r-- | core/legacynet/core.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/core/legacynet/core.c b/core/legacynet/core.c new file mode 100644 index 00000000..2163c693 --- /dev/null +++ b/core/legacynet/core.c @@ -0,0 +1,186 @@ +#include <syslinux/pxe_api.h> +#include <com32.h> +#include <core.h> +#include <net.h> +#include <pxe.h> +#include <minmax.h> + +/* Common receive buffer */ +static __lowmem char packet_buf[PKTBUF_SIZE] __aligned(16); + +extern uint16_t get_port(void); +extern void free_port(uint16_t); + +/** + * Open a socket + * + * @param:socket, the socket to open + * @param:proto, the protocol of the new connection + * + * @out: error code, 0 on success, -1 on failure + */ +int net_core_open(struct pxe_pvt_inode *socket __unused, + enum net_core_proto proto) +{ + struct net_private *priv = &socket->private; + + /* The legacy stack only supports UDP */ + if (proto != NET_CORE_UDP) + return -1; + + /* Allocate local UDP port number */ + priv->tftp_localport = get_port(); + + return 0; +} + +/** + * Close a socket + * + * @param:socket, the socket to open + */ +void net_core_close(struct pxe_pvt_inode *socket) +{ + struct net_private *priv = &socket->private; + + if (priv->tftp_localport) + free_port(priv->tftp_localport); +} + +/** + * Establish a connection on an open socket + * + * @param:socket, the open socket + * @param:ip, the ip address + * @param:port, the port number, host-byte order + */ +void net_core_connect(struct pxe_pvt_inode *socket, uint32_t ip, + uint16_t port) +{ + struct net_private *priv = &socket->private; + + socket->tftp_remoteport = htons(port); + priv->tftp_remoteip = ip; + +} + +/** + * Tear down a connection on an open socket + * + * @param:socket, the open socket + */ +void net_core_disconnect(struct pxe_pvt_inode *socket __unused) +{ +} + +/** + * Read data from the network stack + * + * @param:socket, the open socket + * @param:buf, location of buffer to store data + * @param:buf_len, size of buffer + + * @out: src_ip, ip address of the data source + * @out: src_port, port number of the data source, host-byte order + */ +int net_core_recv(struct pxe_pvt_inode *socket, void *buf, uint16_t *buf_len, + uint32_t *src_ip, uint16_t *src_port) +{ + static __lowmem struct s_PXENV_UDP_READ udp_read; + struct net_private *priv = &socket->private; + uint16_t bytes; + int err; + + udp_read.status = 0; + udp_read.buffer = FAR_PTR(packet_buf); + udp_read.buffer_size = PKTBUF_SIZE; + udp_read.dest_ip = IPInfo.myip; + udp_read.d_port = priv->tftp_localport; + + err = pxe_call(PXENV_UDP_READ, &udp_read); + if (err) + return err; + + if (udp_read.status) + return udp_read.status; + + bytes = min(udp_read.buffer_size, *buf_len); + memcpy(buf, packet_buf, bytes); + + *src_ip = udp_read.src_ip; + *src_port = ntohs(udp_read.s_port); + *buf_len = bytes; + + return 0; +} + +/** + * Send a UDP packet. + * + * @param:socket, the open socket + * @param:data, data buffer to send + * @param:len, size of data bufer + */ +void net_core_send(struct pxe_pvt_inode *socket, const void *data, size_t len) +{ + static __lowmem struct s_PXENV_UDP_WRITE udp_write; + struct net_private *priv = &socket->private; + void *lbuf; + uint16_t tid; + + lbuf = lmalloc(len); + if (!lbuf) + return; + + memcpy(lbuf, data, len); + + tid = priv->tftp_localport; /* TID(local port No) */ + udp_write.buffer = FAR_PTR(lbuf); + udp_write.ip = priv->tftp_remoteip; + udp_write.gw = gateway(udp_write.ip); + udp_write.src_port = tid; + udp_write.dst_port = socket->tftp_remoteport; + udp_write.buffer_size = len; + + pxe_call(PXENV_UDP_WRITE, &udp_write); + + lfree(lbuf); +} + +/** + * Network stack-specific initialization + * + * Initialize UDP stack + */ +void net_core_init(void) +{ + int err; + static __lowmem struct s_PXENV_UDP_OPEN udp_open; + udp_open.src_ip = IPInfo.myip; + err = pxe_call(PXENV_UDP_OPEN, &udp_open); + if (err || udp_open.status) { + printf("Failed to initialize UDP stack "); + printf("%d\n", udp_open.status); + kaboom(); + } +} + +void probe_undi(void) +{ +} + +void pxe_init_isr(void) +{ +} + +int reset_pxe(void) +{ + static __lowmem struct s_PXENV_UDP_CLOSE udp_close; + int err = 0; + + pxe_idle_cleanup(); + + pxe_call(PXENV_UDP_CLOSE, &udp_close); + + return err; +} |