OpenCores
URL https://opencores.org/ocsvn/fade_ether_protocol/fade_ether_protocol/trunk

Subversion Repositories fade_ether_protocol

[/] [fade_ether_protocol/] [trunk/] [stable_jumbo_frames_version/] [linux/] [receiver2t_cmd.c] - Blame information for rev 40

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 wzab
/*
2
 * fpga_l3_fade - driver for L3 communication protocol with FPGA based system
3
 * Copyright (C) 2012 by Wojciech M. Zabolotny
4
 * Institute of Electronic Systems, Warsaw University of Technology
5
 *
6
 *  This code is PUBLIC DOMAIN
7
 */
8
 
9
#include<termios.h>
10
#include <sys/types.h>
11
#include <sys/stat.h>
12
#include <sys/mman.h>
13
#include <sys/ioctl.h>
14
#include <fcntl.h>
15
#include <poll.h>
16
#include <unistd.h>
17
#include <stdio.h>
18
#include <strings.h>
19
#include <stdlib.h>
20
#include <stdint.h>
21
#include <endian.h>
22
#include <sys/socket.h>
23
#include <linux/serial.h>
24
#include <sched.h>
25
#include "fpga_l3_fade.h"
26
#include <sys/time.h>
27
#include <pthread.h>
28
 
29
int frs[3]={-1,-1,-1};
30
int active[3]={0,0,0};
31
int leave[3]={0,0,0};
32
pthread_t ucmd_thread;
33
double tend=0.0;
34
#define nic0 "eth0"
35
 
36
void * user_cmd_thread(void * a1)
37
{
38
  uint16_t cmd;
39
  int i;
40
  int res;
41
  struct timeval tv;
42
  double tstart=0.0;
43
  sleep(5);
44
  for(i=0;i<=2;i++) {
45
    if(active[i]) {
46
      res = ioctl(frs[i],L3_V1_IOC_STARTMAC,NULL);
47
      printf("Result of startmac for slave %d : %d\n",i,res);
48
    }
49
  }
50
  gettimeofday(&tv, NULL);
51
  tstart=tv.tv_sec+1.0e-6*tv.tv_usec;
52
  //Send three commands to each slave
53
  //Waiting 10 seconds
54
  for(cmd=0x112; cmd<=0x114; cmd++) {
55
    sleep(5);
56
    //Send user command
57
    for(i=0;i<=2;i++) {
58
      if(active[i]) {
59
        int j;
60
        struct l3_v1_usercmd uc;
61
        uc.cmd=cmd;
62
        uc.arg=0x56789abc;
63
        uc.timeout=2;
64
        uc.nr_of_retries=20;
65
        res = ioctl(frs[i],L3_V1_IOC_USERCMD,&uc);
66
        printf("Result of usercmd for slave %d : %d\n",i,res);
67
        for(j=0;j<12;j++) {
68
          printf("%2.2x",(int)(uc.resp[j]));
69
        }
70
        printf("\n");
71
      }
72
    }
73
  }
74
  //Now check, how long it  will take to execute certain number of
75
  //user commands!
76
  {
77
    struct l3_v1_usercmd uc;
78
    int j;
79
    int res;
80
    int n_of_tries=100000;
81
    double tcmd1=0.0,tcmd2=0.0;
82
    gettimeofday(&tv, NULL);
83
    tcmd1=tv.tv_sec+1.0e-6*tv.tv_usec;
84
    for(j=0;j<n_of_tries;j++) {
85
      for(i=0;i<=2;i++) {
86
        if(active[i]) {
87
          uc.cmd=0x113;
88
          uc.arg=0x56789abc;
89
          uc.timeout=2;
90
          uc.nr_of_retries=20;
91
          res = ioctl(frs[i],L3_V1_IOC_USERCMD,&uc);
92
          if(res<0) {
93
             printf("Error in user command: %d in %d call\n", res, j);
94
             exit(1);
95
             }
96
          }
97
      }
98
    }
99
    gettimeofday(&tv, NULL);
100
    tcmd2=tv.tv_sec+1.0e-6*tv.tv_usec-tcmd1;
101
    printf("%d tries in %g seconds, %g commands per second\n",n_of_tries,tcmd2, n_of_tries/tcmd2);
102
  }
103
  //Wait for 500 seconds
104
  sleep(500);
105
  for(i=0;i<=2;i++) {
106
    if(active[i]) {
107
      res = ioctl(frs[i],L3_V1_IOC_STOPMAC,NULL);
108
      printf("Result of usercmd for slave %d : %d\n",i,res);
109
    }
110
  }
111
  gettimeofday(&tv, NULL);
112
  tend=tv.tv_sec+1.0e-6*tv.tv_usec;
113
  tend=tend-tstart;
114
}
115
 
116
void main(int argc, char * argv[])
117
{
118
  struct l3_v1_buf_pointers bp;
119
  struct l3_v1_slave sl[3] = {
120
    {
121
      .mac = {0xde, 0xad, 0xba, 0xbe, 0xbe,0xef},
122
      .devname = nic0
123
    },
124
    {
125
      .mac = {0xde, 0xad, 0xba, 0xbe, 0xbe,0xe1},
126
      .devname = nic0
127
    },
128
    {
129
      .mac = {0xde, 0xad, 0xba, 0xbe, 0xbe,0xe2},
130
      .devname = nic0
131
    }
132
  };
133
  int i,j;
134
  int res;
135
  int blen[3];
136
  uint64_t data[3] = {0,0,0};
137
  long long total_len[3]={0,0,0};
138
  unsigned char * v[3];
139
  int stop;
140
  struct sched_param s;
141
  s.sched_priority = 90;
142
  //Read active channels
143
  for(i=1;i<argc;i++) {
144
    int n = atoi(argv[i]);
145
    if ((n>=0) && (n<=2))
146
      active[n]=1;
147
  }
148
  printf("sched=%d\n",sched_setscheduler(0,SCHED_RR,&s));
149
  //Prepare all slaves to work
150
  for(i=0;i<3;i++) {
151
    char devname[30];
152
    sprintf(devname,"/dev/l3_fpga%d",i);
153
    frs[i]=open(devname,O_RDONLY);
154
    if(frs[i]<0) {
155
      printf("I can't open device %s\b",devname);
156
      perror("");
157
      exit(1);
158
    }
159
    //Get the length of the buffer
160
    blen[i] = ioctl(frs[i],L3_V1_IOC_GETBUFLEN,NULL);
161
    //Set the wakeup threshold
162
    res=ioctl(frs[i],L3_V1_IOC_SETWAKEUP,2000000);
163
    printf("length of buffer: %d, result of set wakeup: %d\n",blen[i],res);
164
    v[i]=(unsigned char *)mmap(0,blen[i],PROT_READ,MAP_PRIVATE,frs[i],0);
165
    if(!v[i]) {
166
      printf("mmap for device %s failed\n",devname);
167
      exit(1);
168
    }
169
  }
170
  //Connect to appropriate FPGAs
171
  for(i=0;i<=2;i++) {
172
    if(active[i]) {
173
      res = ioctl(frs[i],L3_V1_IOC_GETMAC,&sl[i]);
174
      printf("Result of get for slave %d : %d\n",i,res);
175
      if(res<0) {
176
        printf("I couldn't bind Ethernet device %s\n",sl[i].devname);
177
        exit(1);
178
      }
179
    } else {
180
      leave[i]=1;
181
    }
182
  }
183
  //Send FADE reset command, so that FADE core is in predictable state
184
  for(i=0;i<=2;i++) {
185
    if(active[i]) {
186
      int j;
187
      for(j=0;j<3;j++) {
188
        res = ioctl(frs[i],L3_V1_IOC_RESETMAC,&sl[i]);
189
        if(res<0) {
190
          printf("I couldn't RESET Ethernet device %d\n",i);
191
          exit(1);
192
        }
193
      }
194
    } else {
195
      leave[i]=1;
196
    }
197
  }
198
  //Start the second thread, which uses user commands
199
  pthread_create(&ucmd_thread, NULL, user_cmd_thread, NULL);
200
  int first_served=0;
201
  do{
202
    struct pollfd pfd[3];
203
    int ptr=0;
204
    int len=0;
205
    int pres;
206
    for(i=0;i<3;i++) {
207
      pfd[i].fd = active[i] ? frs[i] : -1;
208
      pfd[i].events = POLLIN;
209
      pfd[i].revents = 0;
210
    }
211
    //Wait for data using "poll"
212
    pres = poll(pfd,3,1000);
213
    if(pres<0) {
214
      perror("Error in poll:");
215
      exit(1);
216
    }
217
    first_served = (first_served+1) %3; //Rotate priority of slaves
218
    for(j=0;j<3;j++) {
219
      i=(j+first_served) % 3;
220
      if(pfd[i].revents) {
221
        int ofs=0;
222
        len = ioctl(frs[i],L3_V1_IOC_READPTRS,&bp);
223
        if(bp.eof) leave[i]=1;
224
        //OK. The data are read, let's analyze them
225
        while (bp.head != bp.tail)  {
226
          uint64_t c;
227
          c = be64toh(*(uint64_t *)(v[i]+bp.tail));
228
          bp.tail=(bp.tail+8) & (blen[i]-1); //Adjust tail pointer modulo blen[i]
229
          if (__builtin_expect((c != data[i]), 0)) {
230
            printf("Error! received: %llx expected: %llx position: %8.8x\n",c,data[i],total_len[i]+ofs);
231
            exit(1);
232
          }
233
          data[i] += 0x1234567809abcdefL;
234
          ofs++;
235
        }
236
        total_len[i] += len;
237
        //printf("i=%d len=%d total=%lld head:%d tail: %d revents=%d eof=%d\n",i,len,total_len[i],bp.head, bp.tail,pfd[i].revents,(int)bp.eof);
238
        ioctl(frs[i],L3_V1_IOC_WRITEPTRS,len);
239
      }
240
    }
241
    fflush(stdout);
242
  } while ((leave[0] && leave[1] && leave[2]) == 0);
243
  pthread_join(ucmd_thread, NULL);
244
  for(i=0;i<=2;i++) {
245
    if(active[i]) {
246
      res = ioctl(frs[i],L3_V1_IOC_FREEMAC,0);
247
    }
248
    munmap(v[i],blen[i]);
249
    close(frs[i]);
250
  }
251
  fprintf(stderr,"act0:%d act1:%d act2:%d\n",active[0],active[1],active[2]);
252
  for(i=0;i<3;i++) {
253
    fprintf(stderr,"total data %d=%lld time=%g throughput=%g [Mb/s]\n",i,total_len[i], tend, total_len[i]/tend*8.0);
254
  }
255
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.