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/] [receiver2t4.c] - Blame information for rev 40

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 39 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
//Define number of slaves
30
#define N_S (4)
31
int frs[N_S]={-1,-1,-1,-1};
32
int active[N_S]={0,0,0,0};
33
int leave[N_S]={0,0,0,0};
34
pthread_t ucmd_thread;
35
double tend=0.0;
36
#define nic0 "enp130s0f0"
37
#define nic1 "enp130s0f1"
38
#define nic2 "enp132s0f0"
39
#define nic3 "enp132s0f1"
40
void * user_cmd_thread(void * a1)
41
{
42
  uint16_t cmd;
43
  int i;
44
  int res;
45
  struct timeval tv;
46
  double tstart=0.0;
47
  sleep(2);
48
  for(i=0;i<N_S;i++) {
49
    if(active[i]) {
50
      res = ioctl(frs[i],L3_V1_IOC_STARTMAC,NULL);
51
      printf("Result of startmac for slave %d : %d\n",i,res);
52
    }
53
  }
54
  gettimeofday(&tv, NULL);
55
  tstart=tv.tv_sec+1.0e-6*tv.tv_usec;
56
  //Send three commands to each slave
57
  //Waiting 10 seconds
58
  for(cmd=0x112; cmd<=0x114; cmd++) {
59
    sleep(10);
60
    //Send user command
61
    for(i=0;i<N_S;i++) {
62
      if(active[i]) {
63
        int j;
64
        struct l3_v1_usercmd uc;
65
        uc.cmd=cmd;
66
        uc.arg=0x56789abc;
67
        uc.timeout=2;
68
        uc.nr_of_retries=20;
69
        res = ioctl(frs[i],L3_V1_IOC_USERCMD,&uc);
70
        printf("Result of usercmd for slave %d : %d\n",i,res);
71
        for(j=0;j<12;j++) {
72
          printf("%2.2x",(int)(uc.resp[j]));
73
        }
74
        printf("\n");
75
      }
76
    }
77
  }
78
  //Wait for 500 seconds
79
  sleep(100);
80
  //sleep(100);
81
  for(i=0;i<N_S;i++) {
82
    if(active[i]) {
83
      res = ioctl(frs[i],L3_V1_IOC_STOPMAC,NULL);
84
      printf("Result of usercmd for slave %d : %d\n",i,res);
85
    }
86
  }
87
  gettimeofday(&tv, NULL);
88
  tend=tv.tv_sec+1.0e-6*tv.tv_usec;
89
  tend=tend-tstart;
90
}
91
 
92
void main(int argc, char * argv[])
93
{
94
  struct l3_v1_buf_pointers bp;
95
  struct l3_v1_slave sl[N_S] = {
96
    {
97
      .mac = {0xde, 0xad, 0xfa, 0xde, 0x05,0xe2},
98
      .devname = nic1
99
    },
100
    {
101
      .mac = {0xde, 0xad, 0xfa, 0xde, 0x04,0xe2},
102
      .devname = nic0
103
    }, //OK
104
    {
105
      .mac = {0xde, 0xad, 0xfa, 0xde, 0x07,0xe2},
106
      .devname = nic3
107
    },
108
    {
109
      .mac = {0xde, 0xad, 0xfa, 0xde, 0x06,0xe2},
110
      .devname = nic2
111
    }
112
  };
113
  int i,j;
114
  int res;
115
  int blen[N_S];
116
  uint64_t data[N_S] = {0,0,0,0};
117
  long long total_len[N_S]={0,0,0,0};
118
  unsigned char * v[N_S];
119
  int stop;
120
  struct sched_param s;
121
  s.sched_priority = 90;
122
  //Read active channels
123
  for(i=1;i<argc;i++) {
124
    int n = atoi(argv[i]);
125
    if ((n>=0) && (n<N_S))
126
      active[n]=1;
127
  }
128
  printf("sched=%d\n",sched_setscheduler(0,SCHED_RR,&s));
129
  //Prepare all slaves to work
130
  for(i=0;i<N_S;i++) {
131
    char devname[30];
132
    sprintf(devname,"/dev/l3_fpga%d",i);
133
    frs[i]=open(devname,O_RDONLY);
134
    if(frs[i]<0) {
135
      printf("I can't open device %s\b",devname);
136
      perror("");
137
      exit(1);
138
    }
139
    //Get the length of the buffer
140
    blen[i] = ioctl(frs[i],L3_V1_IOC_GETBUFLEN,NULL);
141
    //Set the wakeup threshold
142
    res=ioctl(frs[i],L3_V1_IOC_SETWAKEUP,20000000);
143
    printf("length of buffer: %d, result of set wakeup: %d\n",blen[i],res);
144
    v[i]=(unsigned char *)mmap(0,blen[i],PROT_READ,MAP_PRIVATE,frs[i],0);
145
    if(!v[i]) {
146
      printf("mmap for device %s failed\n",devname);
147
      exit(1);
148
    }
149
  }
150
  //Connect to appropriate FPGAs
151
  for(i=0;i<N_S;i++) {
152
    if(active[i]) {
153
      res = ioctl(frs[i],L3_V1_IOC_GETMAC,&sl[i]);
154
      printf("Result of get for slave %d : %d\n",i,res);
155
      if(res<0) {
156
        printf("I couldn't bind Ethernet device %s\n",sl[i].devname);
157
        exit(1);
158
      }
159
    } else {
160
      leave[i]=1;
161
    }
162
  }
163
  //Send FADE reset command, so that FADE core is in predictable state
164
  for(i=0;i<N_S;i++) {
165
    if(active[i]) {
166
      int j;
167
      for(j=0;j<3;j++) {
168
        //Do it three times in case if one packet gets lost...
169
        res = ioctl(frs[i],L3_V1_IOC_RESETMAC,&sl[i]);
170
        if(res<0) {
171
          printf("I couldn't RESET Ethernet device %d\n",i);
172
          exit(1);
173
        }
174
      }
175
    } else {
176
      leave[i]=1;
177
    }
178
  }
179
  //Start the second thread, which uses user commands
180
  pthread_create(&ucmd_thread, NULL, user_cmd_thread, NULL);
181
  int first_served=0;
182
  do{
183
    struct pollfd pfd[N_S];
184
    int ptr=0;
185
    int len=0;
186
    int pres;
187
    for(i=0;i<N_S;i++) {
188
      pfd[i].fd = active[i] ? frs[i] : -1;
189
      pfd[i].events = POLLIN;
190
      pfd[i].revents = 0;
191
    }
192
    //Wait for data using "poll"
193
    pres = poll(pfd,N_S,1000);
194
    if(pres<0) {
195
      perror("Error in poll:");
196
      exit(1);
197
    }
198
    first_served = (first_served+1) % N_S; //Rotate priority of slaves
199
    for(j=0;j<N_S;j++) {
200
      i=(j+first_served) % N_S;
201
      if(pfd[i].revents) {
202
        int ofs=0;
203
        len = ioctl(frs[i],L3_V1_IOC_READPTRS,&bp);
204
        if(bp.eof) leave[i]=1;
205
        //OK. The data are read, let's analyze them
206
        while (bp.head != bp.tail)  {
207
          uint64_t c;
208
          c = be64toh(*(uint64_t *)(v[i]+bp.tail));
209
          bp.tail=(bp.tail+8) & (blen[i]-1); //Adjust tail pointer modulo blen[i]
210
          if (__builtin_expect((c != data[i]), 0)) {
211
            printf("Error! received: %llx expected: %llx position: %8.8x\n",c,data[i],total_len[i]+ofs);
212
            exit(1);
213
          }
214
          data[i] += 0x1234567809abcdefL;
215
          ofs++;
216
        }
217
        total_len[i] += len;
218
        //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);
219
        ioctl(frs[i],L3_V1_IOC_WRITEPTRS,len);
220
      }
221
    }
222
    fflush(stdout);
223
  } while ((leave[0] && leave[1] && leave[2] && leave[3]) == 0); //Should depend on N_S!
224
  pthread_join(ucmd_thread, NULL);
225
  for(i=0;i<N_S;i++) {
226
    if(active[i]) {
227
      res = ioctl(frs[i],L3_V1_IOC_FREEMAC,0);
228
    }
229
    munmap(v[i],blen[i]);
230
    close(frs[i]);
231
  }
232
  fprintf(stderr,"act0:%d act1:%d act2:%d act3:%d \n",active[0],active[1],active[2], active[3]);
233
  for(i=0;i<N_S;i++) {
234
    fprintf(stderr,"total data %d=%lld time=%g throughput=%g [Mb/s]\n",i,total_len[i], tend, total_len[i]/tend*8.0);
235
  }
236
}

powered by: WebSVN 2.1.0

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