diff --git a/apps/netio.c b/apps/netio.c index 4df88f8f..66f875c5 100644 --- a/apps/netio.c +++ b/apps/netio.c @@ -24,8 +24,14 @@ #include #include +#ifdef CONFIG_ROCKCREEK +#include +#include +#include +#endif + /* - * This implements a netio server. + * This implements a netio server and client (only TCP version). * The client sends a command word (4 bytes) then a data length word (4 bytes). * If the command is "receive", the server is to consume "data length" bytes into * a circular buffer until the first byte is non-zero, then it is to consume @@ -56,9 +62,12 @@ typedef struct #define DEFAULTPORT 0x494F /* "IO" */ #define TMAXSIZE 65536 +static int tSizes[] = {1024, 2048, 4096, 8192, 16384, 32767}; +static size_t ntSizes = sizeof(tSizes) / sizeof(int); static int nPort = DEFAULTPORT; static const int sobufsize = 131072; static struct in_addr addr_local; +static struct in_addr addr_server; static int send_data(int socket, void *buffer, size_t size, int flags) { @@ -131,7 +140,7 @@ static int TCPServer(void* arg) if ((cBuffer = InitBuffer(TMAXSIZE)) == NULL) { kprintf("Netio: Not enough memory\n"); - return -EINVAL; + return -1; } if ((server = socket(PF_INET, SOCK_STREAM, 0)) < 0) { @@ -280,10 +289,170 @@ static int TCPServer(void* arg) return 0; } +int TCP_Bench(void) +{ + char *cBuffer; + CONTROL ctl; + long long nData; + int i; + struct sockaddr_in sa_server; + int server; + int rc, err; + int nByte; + uint64_t start, end; + uint32_t freq = get_cpu_frequency(); /* in MHz */ + + if ((cBuffer = InitBuffer(TMAXSIZE)) == NULL) + { + kprintf("Netio: Not enough memory\n"); + return -1; + } + + if ((server = socket(PF_INET, SOCK_STREAM, 0)) < 0) + { + kprintf("socket failed: %d\n", server); + kfree(cBuffer, TMAXSIZE); + return -2; + } + + setsockopt(server, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize)); + setsockopt(server, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize)); + + sa_server.sin_family = AF_INET; + sa_server.sin_port = htons(nPort); + sa_server.sin_addr = addr_server; + + if ((err = connect(server, (struct sockaddr *) &sa_server, sizeof(sa_server))) < 0) + { + kprintf("connect failed: %d\n", err); + closesocket(server); + kfree(cBuffer, TMAXSIZE); + return -2; + } + + kprintf("\nTCP connection established.\n"); + + for (i = 0; i < ntSizes; i++) + { + kprintf("Packet size %s bytes: ", PacketSize(tSizes[i])); + + /* tell the server we will send it data now */ + + ctl.cmd = htonl(CMD_C2S); + ctl.data = htonl(tSizes[i]); + + if (send_data(server, (void *) &ctl, CTLSIZE, 0)) + break; + + /* 1 - Tx test */ + + start = rdtsc(); + nData = 0; + cBuffer[0] = 0; + + do + { + //GenerateRandomData(cBuffer, tSizes[i]); + + for (nByte = 0; nByte < tSizes[i]; ) + { + rc = send(server, cBuffer + nByte, tSizes[i] - nByte, 0); + + if (rc < 0) + { + kprintf("send failed: %d\n", rc); + break; + } + + if (rc > 0) + nByte += rc; + } + + nData += tSizes[i]; + end = rdtsc(); + } while((end-start)/freq < 6000000ULL /* = 6s */); + + kprintf("%llu KBytes/s\n", (nData/1024ULL)/((end-start)/(1000000ULL*freq))); + + kprintf(" Tx, "); + + cBuffer[0] = 1; + + if (send_data(server, cBuffer, tSizes[i], 0)) + break; + + /* tell the server we expect him to send us data now */ + + ctl.cmd = htonl(CMD_S2C); + ctl.data = htonl(tSizes[i]); + + if (send_data(server, (void *) &ctl, CTLSIZE, 0)) + break; + + /* 2 - Rx test */ + + start = rdtsc(); + nData = 0; + cBuffer[0] = 0; + rc = 0; + + do + { + for (nByte = 0; nByte < tSizes[i]; ) + { + rc = recv(server, cBuffer + nByte, tSizes[i] - nByte, 0); + + if (rc < 0) + { + kprintf("recv failed: %d\n", rc); + break; + } + + if (rc > 0) + nByte += rc; + } + + nData += tSizes[i]; + } while (cBuffer[0] == 0 && rc > 0); + + end = rdtsc(); + kprintf("%llu KBytes/s\n", (nData/1024ULL)/((end-start)/(1000000ULL*freq))); + + kprintf(" Rx.\n"); + } + + ctl.cmd = htonl(CMD_QUIT); + ctl.data = 0; + + send_data(server, (void *) &ctl, CTLSIZE, 0); + + kprintf("Done.\n"); + + closesocket(server); + kfree(cBuffer, TMAXSIZE); + + return 0; +} + int netio_init(void) { - addr_local.s_addr = INADDR_ANY; + int err = 0; - return create_kernel_task(NULL, TCPServer, NULL, NORMAL_PRIO); + addr_local.s_addr = INADDR_ANY; + //addr_server.s_addr = inet_addr("192.168.28.254"); + addr_server.s_addr = inet_addr("192.168.0.2"); + +#ifdef CONFIG_ROCKCREEK + if (RCCE_ue() == 1) { + err = create_kernel_task(NULL, TCPServer, NULL, NORMAL_PRIO); + } else if (RCCE_ue() == 0) { + sleep(3); + err = TCP_Bench(); + } +#else + err = create_kernel_task(NULL, TCPServer, NULL, NORMAL_PRIO); +#endif + + return err; } #endif