1#include <syslinux/pxe_api.h> 2#include <com32.h> 3#include <core.h> 4#include <net.h> 5#include <pxe.h> 6#include <minmax.h> 7 8/* Common receive buffer */ 9static __lowmem char packet_buf[PKTBUF_SIZE] __aligned(16); 10 11extern uint16_t get_port(void); 12extern void free_port(uint16_t); 13 14const struct url_scheme url_schemes[] = { 15 { "tftp", tftp_open, 0 }, 16 { NULL, NULL, 0 } 17}; 18 19/** 20 * Open a socket 21 * 22 * @param:socket, the socket to open 23 * 24 * @out: error code, 0 on success, -1 on failure 25 */ 26int core_udp_open(struct pxe_pvt_inode *socket __unused) 27{ 28 struct net_private_tftp *priv = &socket->net.tftp; 29 30 /* Allocate local UDP port number */ 31 priv->localport = get_port(); 32 33 return 0; 34} 35 36/** 37 * Close a socket 38 * 39 * @param:socket, the socket to open 40 */ 41void core_udp_close(struct pxe_pvt_inode *socket) 42{ 43 struct net_private_tftp *priv = &socket->net.tftp; 44 45 if (priv->localport) 46 free_port(priv->localport); 47} 48 49/** 50 * Establish a connection on an open socket 51 * 52 * @param:socket, the open socket 53 * @param:ip, the ip address 54 * @param:port, the port number, host-byte order 55 */ 56void core_udp_connect(struct pxe_pvt_inode *socket, uint32_t ip, 57 uint16_t port) 58{ 59 struct net_private_tftp *priv = &socket->net.tftp; 60 61 socket->tftp_remoteport = htons(port); 62 priv->remoteip = ip; 63 64} 65 66/** 67 * Tear down a connection on an open socket 68 * 69 * @param:socket, the open socket 70 */ 71void core_udp_disconnect(struct pxe_pvt_inode *socket __unused) 72{ 73} 74 75/** 76 * Read data from the network stack 77 * 78 * @param:socket, the open socket 79 * @param:buf, location of buffer to store data 80 * @param:buf_len, size of buffer 81 82 * @out: src_ip, ip address of the data source 83 * @out: src_port, port number of the data source, host-byte order 84 */ 85int core_udp_recv(struct pxe_pvt_inode *socket, void *buf, uint16_t *buf_len, 86 uint32_t *src_ip, uint16_t *src_port) 87{ 88 static __lowmem struct s_PXENV_UDP_READ udp_read; 89 struct net_private_tftp *priv = &socket->net.tftp; 90 uint16_t bytes; 91 int err; 92 93 udp_read.status = 0; 94 udp_read.buffer = FAR_PTR(packet_buf); 95 udp_read.buffer_size = PKTBUF_SIZE; 96 udp_read.dest_ip = IPInfo.myip; 97 udp_read.d_port = priv->localport; 98 99 err = pxe_call(PXENV_UDP_READ, &udp_read); 100 if (err) 101 return err; 102 103 if (udp_read.status) 104 return udp_read.status; 105 106 bytes = min(udp_read.buffer_size, *buf_len); 107 memcpy(buf, packet_buf, bytes); 108 109 *src_ip = udp_read.src_ip; 110 *src_port = ntohs(udp_read.s_port); 111 *buf_len = bytes; 112 113 return 0; 114} 115 116/** 117 * Send a UDP packet. 118 * 119 * @param:socket, the open socket 120 * @param:data, data buffer to send 121 * @param:len, size of data bufer 122 */ 123void core_udp_send(struct pxe_pvt_inode *socket, const void *data, size_t len) 124{ 125 static __lowmem struct s_PXENV_UDP_WRITE udp_write; 126 struct net_private_tftp *priv = &socket->net.tftp; 127 void *lbuf; 128 uint16_t tid; 129 130 lbuf = lmalloc(len); 131 if (!lbuf) 132 return; 133 134 memcpy(lbuf, data, len); 135 136 tid = priv->localport; /* TID(local port No) */ 137 udp_write.buffer = FAR_PTR(lbuf); 138 udp_write.ip = priv->remoteip; 139 udp_write.gw = gateway(udp_write.ip); 140 udp_write.src_port = tid; 141 udp_write.dst_port = socket->tftp_remoteport; 142 udp_write.buffer_size = len; 143 144 pxe_call(PXENV_UDP_WRITE, &udp_write); 145 146 lfree(lbuf); 147} 148 149/** 150 * Send a UDP packet to a destination 151 * 152 * @param:socket, the open socket 153 * @param:data, data buffer to send 154 * @param:len, size of data bufer 155 * @param:ip, the ip address 156 * @param:port, the port number, host-byte order 157 */ 158void core_udp_sendto(struct pxe_pvt_inode *socket, const void *data, size_t len, 159 uint32_t ip, uint16_t port) 160{ 161 static __lowmem struct s_PXENV_UDP_WRITE udp_write; 162 struct net_private_tftp *priv = &socket->net.tftp; 163 void *lbuf; 164 uint16_t tid; 165 166 lbuf = lmalloc(len); 167 if (!lbuf) 168 return; 169 170 memcpy(lbuf, data, len); 171 172 tid = priv->localport; /* TID(local port No) */ 173 udp_write.buffer = FAR_PTR(lbuf); 174 udp_write.ip = ip; 175 udp_write.gw = gateway(udp_write.ip); 176 udp_write.src_port = tid; 177 udp_write.dst_port = htons(port); 178 udp_write.buffer_size = len; 179 180 pxe_call(PXENV_UDP_WRITE, &udp_write); 181 182 lfree(lbuf); 183} 184 185 186/** 187 * Network stack-specific initialization 188 * 189 * Initialize UDP stack 190 */ 191void net_core_init(void) 192{ 193 int err; 194 static __lowmem struct s_PXENV_UDP_OPEN udp_open; 195 udp_open.src_ip = IPInfo.myip; 196 err = pxe_call(PXENV_UDP_OPEN, &udp_open); 197 if (err || udp_open.status) { 198 printf("Failed to initialize UDP stack "); 199 printf("%d\n", udp_open.status); 200 kaboom(); 201 } 202} 203 204void probe_undi(void) 205{ 206} 207 208void pxe_init_isr(void) 209{ 210} 211 212int reset_pxe(void) 213{ 214 static __lowmem struct s_PXENV_UDP_CLOSE udp_close; 215 int err = 0; 216 217 pxe_idle_cleanup(); 218 219 pxe_call(PXENV_UDP_CLOSE, &udp_close); 220 221 return err; 222} 223