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

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 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 program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
 
21
#include <linux/module.h>
22
#include <linux/kernel.h>
23
#include <asm/uaccess.h>
24
 
25
MODULE_LICENSE("GPL v2");
26
//#define FADE_DEBUG 1
27
#include <linux/device.h>
28
#include <linux/netdevice.h>
29
#include <linux/fs.h>
30
#include <linux/cdev.h>
31
#include <linux/poll.h>
32
#include <linux/mm.h>
33
#include <asm/io.h>
34
#include <linux/wait.h>
35
#include <linux/sched.h>
36
#include <asm/uaccess.h>  /* for put_user */
37
#include <linux/mutex.h>
38
 
39
#include "fpga_l3_fade.h"
40
 
41
#define SUCCESS 0
42
#define DEVICE_NAME "fpga_l3_fade"
43
 
44
 
45
/* Length of the user header in the packet
46
 * The following fields are BEFORE the user header
47
 * SRC+TGT - 12 bytes : source & destination
48
 * 0xFADE - 2 bytes : protocol ID
49
 *
50
 * Fields which belong to the user header:
51
 * 0x0100 - 2 bytes : protocol version - offset 0
52
 * For DATA - to PC
53
 * 0xA5A5 - 2 bytes : data ID 0 - offset 2
54
 * retry number - 2 bytes - offset 4
55
 * packet number - 4 bytes - offset 6
56
 * transm_delay - 4 bytes - offset 10
57
 * cmd_response - 12 bytes - offset 14
58
 *
59
 * Total: 26 bytes!
60 18 wzab
 * If the packet contains "flushed" buffer,
61
 * then data ID is 0xA5A6, and the last word
62
 * contains number of transmitted words.
63 15 wzab
 
64
 * For command response
65
 * 0xA55A : cmd_resp ID 2 bytes - offset 2
66
 * 0x0000 : filler - 2 bytes - offset 4
67
 * cmd_response - 12 bytes offset 6
68
 */
69
#define USER_HDR_LEN 26
70
 
71
/* Number of bytes of user data in a packet */
72
#define LOG2_USER_LEN 13
73
#define USER_LEN (1<<LOG2_USER_LEN) 
74
#define PAYL_LEN ( USER_HDR_LEN + USER_LEN )
75
 
76
/* Number of packets in window - this number depends on amount of RAM
77
 * in the FPGA - Packets in a widnow must fit in the FPGA RAM
78
 * Should be power of two! */
79 18 wzab
#define PKTS_IN_WINDOW (1<<4)
80 15 wzab
#define PKTS_IN_WINDOW_MASK (PKTS_IN_WINDOW-1)
81
 
82
/* Capacity of kernel buffer (mmapped into user space) measured in
83
 * number of windows - should be equal to power of two, to simplify
84
 * the modulo operation (replacing it by binary AND) */
85
#define WINDOWS_IN_BUFFER (1<<8)
86
 
87
#define MY_BUF_LEN (WINDOWS_IN_BUFFER * PKTS_IN_WINDOW * USER_LEN)
88
#define MY_BUF_LEN_MASK (MY_BUF_LEN-1)
89
 
90
 
91
/* Length of the acknowledment packet and command packets */
92
#define MY_ACK_LEN 64
93
 
94
/* Number of bytes to be copied from data packet to ack packet
95
 * It covers: retry_number, packet_number and transm_delay - 10 bytes
96
 */
97
#define MY_ACK_COPIED 10
98
 
99
/* The Ethernet type of our packet. This is NOT OFFICIALLY REGISTERED type,
100
 * however our protocol is:
101
 * 1. experimental,
102
 * 2. supposed to be used only in private networks
103
 */
104
#define MY_PROTO_ID 0xfade
105
#define MY_PROTO_VER 0x0100
106
 
107
static int max_slaves = 4;
108
module_param(max_slaves,int,0);
109
MODULE_PARM_DESC(max_slaves,"Maximum number of slave FPGA devices serviced by the system.");
110
 
111
static int proto_registered = 0; //Was the protocol registred? Should be deregistered at exit?
112
 
113
DEFINE_RWLOCK(slave_table_lock); //Used to protect table of slaves
114
 
115
/* Structure used to store offset of two currently serviced sets in the data buffer */
116
struct pkt_map {
117
  int num;
118
  int offset;
119
};
120
 
121
typedef struct
122
{
123
  // fields related to the circular buffer
124
  volatile int head;
125
  volatile int tail;
126
  rwlock_t ptrs_lock; //Used to protect the head and tail pointers
127
 
128
  unsigned char * buffer;
129
  struct mutex usercmd_lock;
130
  uint16_t cmd_code;
131
  uint16_t cmd_seq;
132
  uint8_t cmd_ack;
133
  uint8_t cmd_resp[12];
134
  rwlock_t pkts_rwlock; //Protects the pkts table and last_pkt
135
  uint32_t last_nack_pkt; /* Number of the last not acknowledged packet. This is also the number
136
                             of the first packet in the current transmission window */
137
  uint32_t pkts[PKTS_IN_WINDOW]; /* This array stores numbers of the last received packets in the
138
                                  * transmission window. It is used to avoid unnecessary copying of duplicated
139
                                  * packets into the receiver buffer */
140
  rwlock_t flags_lock; //Protects other fields of the slave_data struct
141 18 wzab
  uint32_t last_pkt_num; /* Number of the last "flushed" packet */
142
  uint32_t last_pkt_len; /* Number of words in the last "flushed" packet */
143 15 wzab
  char err_flag;
144 18 wzab
  char stopped_flag; /* Flag informing, that transmission has been already terminated */
145
  char eof_flag; /* Flag informing, that all packets are delivered after transmission is terminated */
146 15 wzab
  char active;
147
  char is_open;
148
  int rx_wakeup_thr;
149
  unsigned char mac[ETH_ALEN];
150
  struct net_device * dev;
151
} slave_data;
152
 
153 16 wzab
/* Auxiliary inline functions */
154
static inline uint16_t get_be_u16(char * buf)
155
{
156
  return be16_to_cpu(*(uint16_t *)buf);
157
}
158
 
159
static inline uint32_t get_be_u32(char * buf)
160
{
161
  return be32_to_cpu(*(uint32_t *)buf);
162
}
163
 
164
static inline uint64_t get_be_u64(char * buf)
165
{
166
  return be64_to_cpu(*(uint64_t *)buf);
167
}
168
 
169
static inline void put_skb_u16(struct sk_buff * skb, uint16_t val)
170
{
171 18 wzab
  void * data = skb_put(skb,sizeof(val));
172 16 wzab
  * (uint16_t *) data = cpu_to_be16(val);
173
}
174
 
175
static inline void put_skb_u32(struct sk_buff * skb, uint32_t val)
176
{
177 18 wzab
  void * data = skb_put(skb,sizeof(val));
178 16 wzab
  * (uint32_t *) data = cpu_to_be32(val);
179
}
180
 
181
static inline void put_skb_u64(struct sk_buff * skb, uint64_t val)
182
{
183 18 wzab
  void * data = skb_put(skb,sizeof(val));
184 16 wzab
  * (uint64_t *) data = cpu_to_be64(val);
185
}
186
 
187 15 wzab
static slave_data * slave_table = NULL;
188
 
189
static int my_proto_rcv(struct sk_buff * skb, struct net_device * dev, struct packet_type * pt,
190
                        struct net_device * orig_dev);
191
 
192
static struct packet_type my_proto_pt __read_mostly = {
193
  .type = cpu_to_be16(MY_PROTO_ID),
194
  .dev = NULL,
195
  .func = my_proto_rcv,
196
};
197
 
198
// Prototypes of functions defined in module
199
void cleanup_my_proto1( void );
200
int init_my_proto1( void );
201
static int my_proto1_open(struct inode *inode, struct file *file);
202
static int my_proto1_release(struct inode *inode, struct file *file);
203
static long my_proto1_ioctl (struct file *filp,  unsigned int cmd, unsigned long arg);
204
int my_proto1_mmap(struct file *filp, struct vm_area_struct *vma);
205
unsigned int my_proto1_poll(struct file *filp,poll_table *wait);
206
 
207
//Wait queue for user application
208
DECLARE_WAIT_QUEUE_HEAD (read_queue);
209
//Wait queue for user commands
210
DECLARE_WAIT_QUEUE_HEAD (usercmd_queue);
211
dev_t my_dev=0;
212
struct cdev * my_cdev = NULL;
213
static struct class *class_my_proto = NULL;
214
 
215
struct file_operations Fops = {
216
  .owner = THIS_MODULE,
217
  .open=my_proto1_open,
218
  .release=my_proto1_release,  /* a.k.a. close */
219
  .poll = my_proto1_poll,
220
  .unlocked_ioctl=my_proto1_ioctl,
221
  .mmap=my_proto1_mmap
222
};
223
 
224 18 wzab
 
225
/* Function used to send the user command and wait for confirmation */
226
static inline
227
long send_cmd(slave_data * sd, uint16_t cmd, uint32_t arg, void * resp, int nof_retries, int timeout)
228
{
229
  long result = -ETIMEDOUT;
230 19 wzab
  //First check, if the Ethernet device is claimed, otherwise return an error
231
  if(sd->dev==NULL) return -ENODEV;
232 18 wzab
  //Each slave may perform only one user command, so first check, if no other thread
233
  //attempts to send the command
234
  if ( mutex_trylock(&sd->usercmd_lock)==0) return -EBUSY;
235
  //Mutex acquired, we can proceed
236
  //First allocate the sequence number for the command
237
  sd->cmd_seq += 1;
238
  sd->cmd_code = cmd;
239
  sd->cmd_ack = 1; //Mark, that we are waiting for response
240
  //Now in the loop we send the packet, requesting execution of the command
241
  //and then we wait for response with timeout
242
  while(nof_retries--) {
243
    //Send the packet 
244
    struct sk_buff *newskb = NULL;
245
    uint8_t * my_data = NULL;
246
    newskb = alloc_skb(LL_RESERVED_SPACE(sd->dev)+MY_ACK_LEN, GFP_KERNEL);
247
    skb_reserve(newskb,LL_RESERVED_SPACE(sd->dev));
248
    skb_reset_network_header(newskb);
249
    newskb->dev = sd->dev;
250
    newskb->protocol = htons(MY_PROTO_ID);
251
    //Build the MAC header for the new packet
252
    // Tu http://lxr.linux.no/linux+*/net/ipv4/arp.c#L586 jest pokazane jak zbudować pakiet!
253
    if (dev_hard_header(newskb,sd->dev,MY_PROTO_ID,&sd->mac,sd->dev->dev_addr,MY_ACK_LEN+ETH_HLEN) < 0)
254
      {
255
        kfree_skb(newskb);
256
        return -EINVAL;
257
      }
258
    //Put the protocol version id to the packet
259
    put_skb_u16(newskb,MY_PROTO_VER);
260
    //Put the command code
261
    put_skb_u16(newskb,cmd);
262
    //Put the sequence number
263
    put_skb_u16(newskb,sd->cmd_seq);
264
    //Put the argument
265
    put_skb_u32(newskb,arg);
266
    //Fill the packet
267
    my_data = skb_put(newskb,MY_ACK_LEN-10);
268
    memset(my_data,0xa5,MY_ACK_LEN-10);
269
    dev_queue_xmit(newskb);
270
    //Sleep with short timeout, waiting for response
271
    if(wait_event_timeout(usercmd_queue,sd->cmd_ack==2,timeout)) {
272
      //Response received
273
      //If target buffer provided, copy data to the userspace buffer
274
      if(resp) memcpy(resp,sd->cmd_resp,12);
275
      result = SUCCESS;
276
      break; //exit loop
277
    }
278
  }
279
  //We don't wait for response any more
280
  sd->cmd_ack = 0;
281
  mutex_unlock(&sd->usercmd_lock);
282
  return result;
283
}
284 21 wzab
/* Function used to send RESET command (without confirmation, as
285
the core is reinitialized and can't send confirmation) */
286
static inline
287
long send_reset(slave_data * sd)
288
{
289
  struct sk_buff *newskb = NULL;
290
  uint8_t * my_data = NULL;
291
  //First check, if the Ethernet device is claimed, otherwise return an error
292
  if(sd->dev==NULL) return -ENODEV;
293
  //Each slave may perform only one user command, so first check, if no other thread
294
  //attempts to send the command
295
  if ( mutex_trylock(&sd->usercmd_lock)==0) return -EBUSY;
296
  //Mutex acquired, we can proceed
297
  //First allocate the sequence number for the command
298
  sd->cmd_seq = 0;
299
  sd->cmd_code = FCMD_RESET;
300
  sd->cmd_ack = 0; //We don't wait for response
301
  //Send the packet 
302
  newskb = alloc_skb(LL_RESERVED_SPACE(sd->dev)+MY_ACK_LEN, GFP_KERNEL);
303
  skb_reserve(newskb,LL_RESERVED_SPACE(sd->dev));
304
  skb_reset_network_header(newskb);
305
  newskb->dev = sd->dev;
306
  newskb->protocol = htons(MY_PROTO_ID);
307
  //Build the MAC header for the new packet
308
  // Tu http://lxr.linux.no/linux+*/net/ipv4/arp.c#L586 jest pokazane jak zbudować pakiet!
309
  if (dev_hard_header(newskb,sd->dev,MY_PROTO_ID,&sd->mac,sd->dev->dev_addr,MY_ACK_LEN+ETH_HLEN) < 0)
310
    {
311
      kfree_skb(newskb);
312
      return -EINVAL;
313
    }
314
  //Put the protocol version id to the packet
315
  put_skb_u16(newskb,MY_PROTO_VER);
316
  //Put the command code
317
  put_skb_u16(newskb,sd->cmd_code);
318
  //Put the sequence number
319
  put_skb_u16(newskb,sd->cmd_seq);
320
  //Put the argument
321
  put_skb_u32(newskb,0);
322
  //Fill the packet
323
  my_data = skb_put(newskb,MY_ACK_LEN-10);
324
  memset(my_data,0xa5,MY_ACK_LEN-10);
325
  dev_queue_xmit(newskb);
326
  mutex_unlock(&sd->usercmd_lock);
327
  return SUCCESS;
328
}
329 18 wzab
 
330
/* Function free_mac may be safely called even if the MAC was not taken
331
   it checks sd->active to detect such situation
332
*/
333
static inline
334
long free_mac(slave_data *sd) {
335
  write_lock_bh(&slave_table_lock);
336
  if(sd->active) {
337
    /* Clear the MAC address */
338
    sd->active = 0;
339
    memset(&sd->mac,0,ETH_ALEN);
340
    write_unlock_bh(&slave_table_lock);
341
    /* Now send the "stop transmission" packet to the slave */
342
    /* Find the net device */
343
    if (!sd->dev) return -ENODEV;
344
    dev_put(sd->dev);
345
    sd->dev=NULL;
346
  } else {
347
    write_unlock_bh(&slave_table_lock);
348
  }
349
  return SUCCESS;
350
}
351
 
352 15 wzab
static long my_proto1_ioctl (struct file *filp,
353
                             unsigned int cmd, unsigned long arg)
354
{
355
  slave_data * sd = filp->private_data;
356
  if (_IOC_TYPE(cmd) != L3_V1_IOC_MAGIC) {
357
    return -EINVAL;
358
  }
359
  switch (cmd) {
360
  case L3_V1_IOC_SETWAKEUP:
361
    if (arg > MY_BUF_LEN/2)
362
      return -EINVAL; //Don't allow to set too high read threshold!
363
    write_lock_bh(&sd->flags_lock);
364
    sd->rx_wakeup_thr = arg;
365
    write_unlock_bh(&sd->flags_lock);
366
    return 0;
367
  case L3_V1_IOC_GETBUFLEN:
368
    /* Inform the user application about the length of the buffer */
369
    return MY_BUF_LEN;
370
  case L3_V1_IOC_READPTRS:
371
    {
372
      void * res = (void *) arg;
373
      long res2;
374
      struct l3_v1_buf_pointers bp;
375
      if (!access_ok(VERIFY_WRITE,res,sizeof(bp))) {
376
        return -EFAULT;
377
      } else {
378
        read_lock_bh(&sd->ptrs_lock);
379
        bp.head=sd->head;
380
        bp.tail=sd->tail;
381 18 wzab
        bp.eof=sd->eof_flag;
382 15 wzab
        read_unlock_bh(&sd->ptrs_lock);
383
        res2 = __copy_to_user(res,&bp,sizeof(bp));
384
        if(res2)
385
          return -EFAULT;
386
        if (sd->err_flag)
387
          return -EIO; /* In this case user must him/herself
388
                          calculate the number of available bytes */
389
        else
390
          return (bp.head-bp.tail) & MY_BUF_LEN_MASK;
391
        /* Return the number of available bytes */
392
      }
393
    }
394
  case L3_V1_IOC_WRITEPTRS:
395
    /* Update the read pointer
396
     * The argument contains information about the number of bytes
397
     * consumed by the application
398
     */
399
    {
400
      int rptr;
401
      int wptr;
402
      int available_data;
403
      //We need to check if the amount of consumed data is correct
404
      write_lock_bh(&sd->ptrs_lock);
405
      wptr = sd->head;
406
      rptr = sd->tail;
407
      available_data = (wptr - rptr) & MY_BUF_LEN_MASK;
408
      if (arg>available_data)
409
        {
410
          write_unlock_bh(&sd->ptrs_lock);
411
          return -EINVAL;
412
        }
413
      //If the number of consumed bytes is correct, update the number of bytes
414
      sd->tail = (rptr + arg) & MY_BUF_LEN_MASK;
415
      write_unlock_bh(&sd->ptrs_lock);
416
      return SUCCESS;
417
    }
418
  case L3_V1_IOC_STARTMAC: //Open the slave
419
    {
420 18 wzab
      sd->stopped_flag = 0;
421
      sd->eof_flag = 0;
422
      //We just send a request to start transmission and wait for confirmation
423
      return send_cmd(sd,FCMD_START,0,NULL,100,2);
424 15 wzab
    }
425 18 wzab
  case L3_V1_IOC_STOPMAC: //Close the slave and reset it to stop transmission immediately
426
    {
427
      return send_cmd(sd,FCMD_STOP,0,NULL,100,2);
428
    }
429
  case L3_V1_IOC_RESETMAC: //Reset MAC so, that it stops transmission immediately
430
    {
431 21 wzab
      return send_reset(sd);
432 18 wzab
    }
433 15 wzab
  case L3_V1_IOC_GETMAC: //Open the slave
434
    {
435
      void * source = (void *) arg;
436
      struct l3_v1_slave sl;
437
      struct net_device *dev = NULL;
438
      long res2;
439
      if (!access_ok(VERIFY_READ,source,sizeof(sl))) {
440
        return -EFAULT;
441
      }
442
      /* First deactivate the slave to avoid situation where data are modified
443
       * while slave is active */
444
      if (sd->active) sd->active = 0;
445
      //Set the numbers of stored packets to MAX
446
      write_lock_bh(&sd->pkts_rwlock);
447
      memset(&sd->pkts,0xff,sizeof(sd->pkts));
448
      sd->last_nack_pkt=0;
449
      write_unlock_bh(&sd->pkts_rwlock);
450
      //Copy arguments from the user space
451
      res2 = __copy_from_user(&sl,source,sizeof(sl));
452
      if(res2) {
453
        return -EFAULT;
454
      }
455
      write_lock_bh(&slave_table_lock);
456
      /* Copy the MAC address */
457
      memcpy(&sd->mac,sl.mac,ETH_ALEN);
458
      sd->active = 1;
459
      write_unlock_bh(&slave_table_lock);
460
      /* Find the net device */
461
      sl.devname[IFNAMSIZ-1]=0; // Protect against incorrect device name
462
      if (sd->dev) {
463
        //Maybe there was no STOPMAC call after previous STARTMAC?
464
        dev_put(sd->dev);
465
        sd->dev=NULL;
466
      }
467
      dev = dev_get_by_name(&init_net,sl.devname);
468
      if (!dev) return -ENODEV;
469
      sd->dev = dev;
470
      return SUCCESS;
471
    }
472
  case L3_V1_IOC_FREEMAC: //Close the slave and reset it to stop transmission immediately
473
    {
474 18 wzab
      free_mac(sd);
475 15 wzab
      return SUCCESS;
476
    }
477
  case L3_V1_IOC_USERCMD: //Perform the user command
478
    {
479
      void * source = (void *) arg;
480
      long result = -EINVAL;
481
      struct l3_v1_usercmd ucmd;
482
      //First copy command data
483
      result = __copy_from_user(&ucmd,source,sizeof(ucmd));
484
      if(result) {
485
        return -EFAULT;
486
      }
487
      //Now we check if the command is valid user command
488
      if(ucmd.cmd < 0x0100) return -EINVAL;
489 18 wzab
      result = send_cmd(sd,ucmd.cmd, ucmd.arg, ucmd.resp, ucmd.nr_of_retries,ucmd.timeout);
490
      if(result<0) return result;
491
      result = __copy_to_user(source,&ucmd,sizeof(ucmd));
492 15 wzab
      return result;
493
    }
494
  }
495
  return -EINVAL;
496
}
497
/*
498
  Implementation of the poll method
499
*/
500
unsigned int my_proto1_poll(struct file *filp,poll_table *wait)
501
{
502
  unsigned int mask =0;
503
  slave_data * sd = filp->private_data;
504
  unsigned int data_available;
505
  poll_wait(filp,&read_queue,wait);
506
  read_lock_bh(&sd->ptrs_lock);
507
  data_available = (sd->head - sd->tail) & MY_BUF_LEN_MASK;
508 18 wzab
  if (data_available >= sd->rx_wakeup_thr) mask |= POLLIN |POLLRDNORM;
509
  if (sd->eof_flag) {
510
    if(data_available) mask |= POLLIN | POLLRDNORM;
511
    else mask |= POLLHUP;
512
  }
513 15 wzab
#ifdef FADE_DEBUG
514
  printk(KERN_INFO "poll head: %d tail: %d data: %d prog: %d.\n",sd->head,sd->tail,data_available,sd->rx_wakeup_thr);
515
#endif
516
  //Check if the error occured
517
  if (sd->err_flag) mask |= POLLERR;
518
  read_unlock_bh(&sd->ptrs_lock);
519
  return mask;
520
}
521
 
522
/* Module initialization  */
523
int init_my_proto1( void )
524
{
525
  int res;
526
  int i;
527
  /* Create the device class for udev */
528
  class_my_proto = class_create(THIS_MODULE, "my_proto");
529
  if (IS_ERR(class_my_proto)) {
530
    printk(KERN_ERR "Error creating my_proto class.\n");
531
    res=PTR_ERR(class_my_proto);
532
    goto err1;
533
  }
534
  /* Allocate the device number */
535
  res=alloc_chrdev_region(&my_dev, 0, max_slaves, DEVICE_NAME);
536
  if (res) {
537
    printk (KERN_ERR "Alocation of the device number for %s failed\n",
538
            DEVICE_NAME);
539
    goto err1;
540
  };
541
  /* Allocate the character device structure */
542
  my_cdev = cdev_alloc( );
543
  if (my_cdev == NULL) {
544
    printk (KERN_ERR "Allocation of cdev for %s failed\n",
545
            DEVICE_NAME);
546
    goto err1;
547
  }
548
  my_cdev->ops = &Fops;
549
  my_cdev->owner = THIS_MODULE;
550
  /* Add the character device to the system */
551
  res=cdev_add(my_cdev, my_dev, max_slaves);
552
  if (res) {
553
    printk (KERN_ERR "Registration of the device number for %s failed\n",
554
            DEVICE_NAME);
555
    goto err1;
556
  };
557
  /* Create our devices in the system */
558
  for (i=0;i<max_slaves;i++) {
559
    device_create(class_my_proto,NULL,MKDEV(MAJOR(my_dev),MINOR(my_dev)+i),NULL,"l3_fpga%d",i);
560
  }
561
  printk (KERN_ERR "%s The major device number is %d.\n",
562
          "Registration is a success.",
563
          MAJOR(my_dev));
564
  //Prepare the table of slaves
565
  slave_table = kzalloc(sizeof(slave_data)*max_slaves, GFP_KERNEL);
566
  if (!slave_table) return -ENOMEM;
567
  for (i=0;i<max_slaves;i++) {
568
    /* Perform initialization, which should be done only once, when the module
569
     * is loaded. Other actions may be needed, when the transmission from
570
     * particular slave is started. This will be done in IOCTL STARTMAC
571
     */
572
    slave_data * sd = &slave_table[i];
573
    sd->active=0; //Entry not used
574
    sd->dev=NULL;
575
    rwlock_init(&sd->pkts_rwlock);
576
    rwlock_init(&sd->ptrs_lock);
577
    rwlock_init(&sd->flags_lock);
578
    mutex_init(&sd->usercmd_lock);
579
  }
580
  //Install our protocol sniffer
581
  dev_add_pack(&my_proto_pt);
582
  proto_registered = 1;
583
  return SUCCESS;
584
 err1:
585
  /* In case of error free all allocated resources */
586
  cleanup_my_proto1();
587
  return res;
588
}
589
 
590
module_init(init_my_proto1);
591
 
592
/* Clean-up when removing the module */
593
void cleanup_my_proto1( void )
594
{
595
  /* Unregister the protocol sniffer */
596
  if (proto_registered) dev_remove_pack(&my_proto_pt);
597
  /* Free the slave table */
598
  if (slave_table) {
599
    int i;
600
    for (i=0;i<max_slaves;i++) {
601
      if (slave_table[i].buffer) {
602
        vfree(slave_table[i].buffer);
603
        slave_table[i].buffer = NULL;
604
      }
605
      if (slave_table[i].dev) {
606
        dev_put(slave_table[i].dev);
607
        slave_table[i].dev=NULL;
608
      }
609
      if (slave_table[i].active) {
610
        slave_table[i].active = 0;
611
      }
612
    }
613
    kfree(slave_table);
614
    slave_table=NULL;
615
  }
616
  /* Remove device from the class */
617
  if (my_dev && class_my_proto) {
618
    int i;
619
    for (i=0;i<max_slaves;i++) {
620
      device_destroy(class_my_proto,MKDEV(MAJOR(my_dev),MINOR(my_dev)+i));
621
    }
622
  }
623
  /* Deregister device */
624
  if (my_cdev) cdev_del(my_cdev);
625
  my_cdev=NULL;
626
  /* Free the device number */
627
  unregister_chrdev_region(my_dev, max_slaves);
628
  /* Deregister class */
629
  if (class_my_proto) {
630
    class_destroy(class_my_proto);
631
    class_my_proto=NULL;
632
  }
633
 
634
}
635
module_exit(cleanup_my_proto1);
636
/*
637
  Function, which receives my packet, copies the data and acknowledges the packet
638
  as soon as possible...
639
  I've tried to allow this function to handle multiple packets in parallel
640
  in the SMP system, however I've used rwlocks for that.
641
  Probably it should be improved, according to the last tendency to avoid
642
  rwlocks in the kernel...
643
*/
644
 
645
static int my_proto_rcv(struct sk_buff * skb, struct net_device * dev, struct packet_type * pt,
646
                        struct net_device * orig_dev)
647
{
648
  struct sk_buff *newskb = NULL;
649
  struct ethhdr * rcv_hdr = NULL;
650
  //unsigned int head;
651
  //unsigned int tail;
652
  int is_duplicate = 0;
653
  int res;
654
  uint32_t packet_number;
655
  int ns; //Number of slave
656
  slave_data * sd = NULL;
657
  int32_t pkt_dist;
658
  char * my_data = NULL;
659
  unsigned char tmp_buf[USER_HDR_LEN];
660
  char ack_packet = 0; //Should we acknowledge the packet?
661 18 wzab
  uint32_t pkt_pos, needed_space, buf_free;
662 15 wzab
  //Extract the MAC header from the received packet
663
  rcv_hdr=eth_hdr(skb);
664
  //First we try to identify the sender so we search the table of active slaves
665
  //The table is protected during the search, so it should not be changed
666
#ifdef FADE_DEBUG
667
  printk("snd: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",(int)rcv_hdr->h_source[0],
668
         (int)rcv_hdr->h_source[1],(int)rcv_hdr->h_source[2],(int)rcv_hdr->h_source[3],
669
         (int)rcv_hdr->h_source[4],(int)rcv_hdr->h_source[5]);
670
#endif
671
  read_lock_bh(&slave_table_lock);
672
  for (ns=0;ns<max_slaves;ns++) {
673
#ifdef FADE_DEBUG
674
    printk("slv: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x  act: %d\n",
675
           (int)slave_table[ns].mac[0],(int)slave_table[ns].mac[1],(int)slave_table[ns].mac[2],
676
           (int)slave_table[ns].mac[3],(int)slave_table[ns].mac[4],(int)slave_table[ns].mac[5],
677
           (int)slave_table[ns].active);
678
#endif
679
    if (
680
        slave_table[ns].active!=0 &&
681
        memcmp(slave_table[ns].mac,rcv_hdr->h_source, sizeof(slave_table[0].mac))==0
682
        ) break;
683
  }
684
  read_unlock_bh(&slave_table_lock);
685
  //Now we know which slave sent us the packet (ns<max_slaves) or that
686
  //the packet came from an unknown slave (ns==max_slaves)
687
  if (unlikely(ns==max_slaves)) {
688
    printk(KERN_WARNING " Received packet from incorrect slave!\n");
689
    //Sender is not opened, so ignore the packet, and send
690
    //to the sender request to stop the transmission immediately
691
    newskb = alloc_skb(LL_RESERVED_SPACE(dev)+MY_ACK_LEN, GFP_ATOMIC);
692
    skb_reserve(newskb,LL_RESERVED_SPACE(dev));
693
    skb_reset_network_header(newskb);
694
    newskb->dev = dev;
695
    newskb->protocol = htons(MY_PROTO_ID);
696
    //Build the MAC header for the new packet
697
    // Here is shown how to build a packet: http://lxr.linux.no/linux+*/net/ipv4/arp.c#L586
698
    if (dev_hard_header(newskb,dev,MY_PROTO_ID,&rcv_hdr->h_source,&rcv_hdr->h_dest,MY_ACK_LEN+ETH_HLEN) < 0)
699
      goto error;
700
    //Put the protocol version id to the packet
701 16 wzab
    put_skb_u16(newskb,MY_PROTO_VER);
702 18 wzab
    //Put the "restart" command to the packet, which should force it to stop transmission
703
    //immediately
704
    put_skb_u16(newskb,FCMD_RESET);
705 15 wzab
    my_data = skb_put(newskb,MY_ACK_LEN - 4);
706
    memset(my_data,0xa5,MY_ACK_LEN - 4);
707
    dev_queue_xmit(newskb);
708
    kfree_skb(skb);
709
    return NET_RX_DROP;
710
  }
711
  sd = &slave_table[ns]; //To speed up access to the data describing state of the slave
712
#ifdef FADE_DEBUG
713
  printk(KERN_INFO " Received packet!\n");
714
#endif
715
  //Now we should analyze the origin and meaning of the packet
716
  //To avoid problems with scattered packets, we copy initial part of data to the buffer
717
  //using the skb_copy_bits
718
  skb_copy_bits(skb,0,tmp_buf,USER_HDR_LEN);
719
  /* We extract the information from the user header
720
   * First we check if this is correct version of the protocol */
721 18 wzab
  if (unlikely(get_be_u16(&tmp_buf[0]) != MY_PROTO_VER)) goto wrong_pkt_type_error;
722 16 wzab
  if (unlikely(get_be_u16(&tmp_buf[2]) == 0xa55a)) {
723 15 wzab
    //This is a command response packet
724
    printk(KERN_INFO " received command response packet");
725
    if(sd->cmd_ack==1) {
726
      //We are waiting for response
727
      printk(KERN_INFO "we were waiting for command response packet");
728 16 wzab
      if ((get_be_u16(&tmp_buf[6]) == sd->cmd_code) &&
729 18 wzab
          (get_be_u16(&tmp_buf[8]) == sd->cmd_seq)){
730 15 wzab
        //This is a response for the right command
731
        //copy the response to the slave data
732
        printk(KERN_INFO "It was response for the right command");
733
        memcpy(&sd->cmd_resp,&tmp_buf[6],12);
734
        sd->cmd_ack=2;
735
        //Wake up the waiting process
736
        wake_up_interruptible(&usercmd_queue);
737
      }
738
    }
739
    kfree_skb(skb);
740
    return NET_RX_SUCCESS;
741
  }
742 18 wzab
  if (unlikely((get_be_u16(&tmp_buf[2]) != 0xa5a5) &&
743
               (get_be_u16(&tmp_buf[2]) != 0xa5a6))
744
      ) {
745 15 wzab
    //This is not a data packet
746
    goto wrong_pkt_type_error;
747
  }
748
  /* Now we handle the data packet
749
     PLEASE NOTE, THAT THIS MUST TIGHTLY CORRESPOND
750
     TO YOUR FPGA IMPLEMENTATION! */
751
  //Check, if we need to read a command response
752
  if(sd->cmd_ack==1) {
753
    //We are waiting for response
754 16 wzab
    if ((get_be_u16(&tmp_buf[14]) == sd->cmd_code) &&
755
        (get_be_u16(&tmp_buf[16]) == sd->cmd_seq)) {
756 15 wzab
      //This is a response for the right command
757
      //copy the response to the slave data
758
      memcpy(&sd->cmd_resp,&tmp_buf[14],12);
759
      sd->cmd_ack=2;
760
      //Wake up the waiting process
761
      wake_up_interruptible(&usercmd_queue);
762
    }
763
  }
764 16 wzab
  packet_number = get_be_u32(&tmp_buf[6]);
765 15 wzab
#ifdef FADE_DEBUG
766
  printk(KERN_INFO "pkt=%d\n",(int)packet_number);
767
#endif
768
  /* To know if this is a new packet, we compare the packet number
769
   * in the received packet with the number of the last unconfirmed packet,
770
   * calculating the difference between those two numbers: */
771
  read_lock_bh(&sd->pkts_rwlock);
772
  pkt_dist=(int32_t) packet_number - (int32_t) sd->last_nack_pkt;
773 18 wzab
  //Check if this packet was received before
774 15 wzab
  is_duplicate=(sd->pkts[packet_number & PKTS_IN_WINDOW_MASK] == packet_number) ? 1 : 0;
775
  read_unlock_bh(&sd->pkts_rwlock);
776 18 wzab
  if (unlikely((pkt_dist<0) || (pkt_dist>=PKTS_IN_WINDOW))) {
777
    //This is a "too old" packet, or packet "from the future", which should not be transimtted
778
    //by the FPGA
779 15 wzab
    if (pkt_dist<0) {
780 18 wzab
      // This is a packet which was already confirmed, but probably ACK was lost
781 15 wzab
#ifdef FADE_DEBUG
782
      printk(KERN_INFO "Packet already confirmed: pkt=%d expect=%d last=%d\n",packet_number, sd->pkts[packet_number], sd->last_nack_pkt);
783
#endif
784 18 wzab
      ack_packet = 1;
785
      goto confirm;
786 15 wzab
    } else {
787
      /* This is a packet with too high set number (packet "from the future"
788
       * it my be a symptom of serious communication problem! */
789
      printk(KERN_ERR "Packet from the future! number: %d last_confirmed: %d\n", packet_number, sd->last_nack_pkt);
790 18 wzab
      goto error2;
791 15 wzab
    }
792
  }
793 18 wzab
  //If we get there, it means, that:
794
  //   pkt_dist >= 0 and pkt_dist < PKTS_IN_WINDOW
795
  // So this is an expected data packet.
796
  if(is_duplicate) {
797
    //Packet already confirmed, probably the ACK was lost, so simply generate the ACK
798
    ack_packet = 1;
799
    goto confirm;
800
  }
801
  //Packet not confirmed yet. Confirm it only after all processing is successfully completed
802
  pkt_pos=(packet_number<<LOG2_USER_LEN) & MY_BUF_LEN_MASK;
803
  //We must be sure, that the pointers do not change during this check
804
  read_lock_bh(&sd->ptrs_lock);
805
  //Calculate free space needed to copy the packet
806
  needed_space = (pkt_pos+USER_LEN-1-(sd->head)) & MY_BUF_LEN_MASK;
807
  //Calculate the amount of free space in the buffer
808
  buf_free = (sd->tail - sd->head -1 ) & MY_BUF_LEN_MASK;
809
#ifdef FADE_DEBUG
810
  printk(KERN_INFO "packet_nr: %d Free buffer: %d needed space: %d head=%d last_nack=%d\n",
811
         packet_number, needed_space, buf_free, sd->head, sd->last_nack_pkt);
812
#endif
813
  read_unlock_bh(&sd->ptrs_lock);
814
  if (unlikely( buf_free <= needed_space )) goto error2; //No place for copying, drop the packet
815
  // Check the length of the package
816
  if (unlikely(skb->len != PAYL_LEN)) {
817
    printk(KERN_ERR "Error! Length of data should be %d but is %d!\n",PAYL_LEN, skb->len);
818
    sd->err_flag |= FADE_ERR_INCORRECT_LENGTH;
819
    goto error2;
820
  }
821
  // We can safely copy all the packet to the buffer:
822
  res = skb_copy_bits(skb,USER_HDR_LEN,&(sd->buffer[pkt_pos]),USER_LEN);
823
#ifdef FADE_DEBUG
824
  printk(KERN_INFO " skb_copy_bits: %d", res);
825
#endif
826
  if (res<0) goto error2; //Unsuccessfull copying
827
  //Packet was copied, so note, that we should confirm it
828
  ack_packet=1;
829
  /* When packet is copied, we can check if this is the last "flushed" packet */
830
  if (get_be_u16(&tmp_buf[2])==0xa5a6) {
831
    //Flushed packet, store its number and length (should it be protected with spinlock?)
832
    sd->last_pkt_num = packet_number;
833
    //Copy the length, truncating it from 64 bits
834
    sd->last_pkt_len = (uint32_t) * (uint64_t *) &(sd->buffer[pkt_pos+USER_LEN-sizeof(uint64_t)]);
835
    //We have received the "flushed" buffer, mark that transmission is stopped
836
    sd->stopped_flag = 1;
837 20 wzab
    //printk(KERN_INFO "set stopped flag");
838 18 wzab
  }
839
  /* We modify the number of the copied packet in the pkts array, to avoid
840
   * unnecessary copying if we receive a duplicate
841
   * To modify the pkts table, we must close pkts_rwlock for writing */
842
  write_lock_bh(&sd->pkts_rwlock);
843
  sd->pkts[packet_number & PKTS_IN_WINDOW_MASK]= packet_number;
844
  if (packet_number == sd->last_nack_pkt) {
845
    /* If our packet was the last, which prevented shifting of the head pointer,
846
     * we can try now to move the head pointer.
847
     * We browse the pkts table, looking for the first packet with incorrect number
848
     * i.e. the packet which was not received and not confimed yet
849
     */
850
    uint32_t chk_packet_num = packet_number+1;
851
    uint32_t count=0;
852
    while (++count < PKTS_IN_WINDOW) {
853
      if (sd->pkts[(sd->last_nack_pkt + count) & PKTS_IN_WINDOW_MASK] != chk_packet_num) break; //Packet not confirmed
854
      chk_packet_num++;
855
    }
856
    sd->last_nack_pkt += count;
857
    write_unlock_bh(&sd->pkts_rwlock);
858
    /* Now we can move the head position */
859
    if(likely((sd->stopped_flag == 0) ||
860
              ((uint32_t)(sd->last_nack_pkt-1) != sd->last_pkt_num))) {
861
      //Normal packet, set head right after the last serviced packet
862
      write_lock_bh(&sd->ptrs_lock);
863
      sd->head = (sd->last_nack_pkt*USER_LEN) & MY_BUF_LEN_MASK;
864
      //Now try to wake up the reading process
865
      if (((sd->head - sd->tail) & MY_BUF_LEN_MASK) >= sd->rx_wakeup_thr)
866
        wake_up_interruptible(&read_queue);
867
    } else {
868
      //Flushed packet, set head right after the end of the packet
869
      write_lock_bh(&sd->ptrs_lock);
870
      sd->head = ((sd->last_nack_pkt-1)*USER_LEN+sd->last_pkt_len) & MY_BUF_LEN_MASK;
871
      //We have consumed the last, "flushed" buffer, so now we can set the eof flag
872
      sd-> eof_flag = 1;
873 20 wzab
      //printk(KERN_ALERT "set eof flag!");
874 18 wzab
      //And we wake up the reading process
875
      wake_up_interruptible(&read_queue);
876
    } //if - stopped_flag
877
    write_unlock_bh(&sd->ptrs_lock);
878
  } else { // if - last_nack_pkt 
879
    write_unlock_bh(&sd->pkts_rwlock);
880
  }
881
 confirm:
882
  //Send the confirmation if required
883 15 wzab
  if (likely(ack_packet)) {
884
    newskb = alloc_skb(LL_RESERVED_SPACE(dev)+MY_ACK_LEN, GFP_ATOMIC);
885
    skb_reserve(newskb,LL_RESERVED_SPACE(dev));
886
    skb_reset_network_header(newskb);
887
    newskb->dev = dev;
888
    newskb->protocol = htons(MY_PROTO_ID);
889
    //Build the MAC header for the new packet
890
    // Tu http://lxr.linux.no/linux+*/net/ipv4/arp.c#L586 jest pokazane jak zbudować pakiet!
891
    if (dev_hard_header(newskb,dev,MY_PROTO_ID,&rcv_hdr->h_source,&rcv_hdr->h_dest,MY_ACK_LEN+ETH_HLEN) < 0)
892
      goto error;
893
    //Put the protocol version id to the packet
894 18 wzab
    put_skb_u16(newskb,MY_PROTO_VER);
895 15 wzab
    //Put the "ACKNOWLEDGE" type
896 18 wzab
    put_skb_u16(newskb,FCMD_ACK);
897 15 wzab
    //Copy the begining of the received packet to the acknowledge packet
898
    my_data = skb_put(newskb,MY_ACK_COPIED);
899
    res = skb_copy_bits(skb,4,my_data,MY_ACK_COPIED);
900
    my_data = skb_put(newskb,MY_ACK_LEN -MY_ACK_COPIED-4);
901
    memset(my_data,0xa5,MY_ACK_LEN - MY_ACK_COPIED-4);
902
#ifdef FADE_DEBUG
903
    printk(KERN_INFO " skb_nh: %x, skb_dt: %x, skb_nh2: %x, skb_t: %x\n tail: %d head: %d\n",skb_network_header(newskb),newskb->data,
904
           newskb->network_header,newskb->tail, sd->tail, sd->head) ;
905
#endif
906
    dev_queue_xmit(newskb);
907
  }
908
  kfree_skb(skb);
909
  return NET_RX_SUCCESS;
910
 wrong_pkt_type_error:
911
  //This code should be called with sd initialized,
912
  //but to avoid kernel panic, check if sd was set
913
  if(sd) {
914
    write_lock_bh(&sd->flags_lock);
915
    sd->err_flag |= FADE_ERR_INCORRECT_PACKET_TYPE;
916
    write_unlock_bh(&sd->flags_lock);
917
  } else {
918
    printk(KERN_ERR "FADE: wrong_pkt_type_error called with null sd");
919
  }
920
 error:
921
  if (newskb) kfree_skb(newskb);
922 18 wzab
 error2:
923 15 wzab
  if (skb) kfree_skb(skb);
924
  return NET_RX_DROP;
925
}
926
 
927
/*
928
  Implementation of the "device open" function
929
*/
930
static int my_proto1_open(struct inode *inode,
931
                          struct file *file)
932
{
933
  int i;
934
  slave_data * sd = NULL;
935
  unsigned long flags;
936
  i=iminor(inode)-MINOR(my_dev);
937
  if (i >= max_slaves) {
938
    printk(KERN_WARNING "Trying to access %s slave with too high minor number: %d\n",
939
           DEVICE_NAME, i);
940
    return -ENODEV;
941
  }
942
  read_lock_irqsave(&slave_table_lock,flags);
943
  sd = &slave_table[i];
944
  //Each device may be opened only once!
945
  if (sd->is_open) {
946 28 wzab
    read_unlock_irqrestore(&slave_table_lock,flags);
947 15 wzab
    return -EBUSY;
948
  }
949
  //Prepare slave_table for operation
950
  read_unlock_irqrestore(&slave_table_lock,flags);
951
  sd->buffer = vmalloc_user(MY_BUF_LEN);
952
  if (!sd->buffer) return -ENOMEM;
953
  //Set the MAC address to 0
954
  memset(sd->mac,0,sizeof(sd->mac));
955
  sd->head = 0;
956
  sd->tail = 0;
957 18 wzab
  sd->eof_flag = 0;
958
  sd->stopped_flag = 0;
959 15 wzab
  sd->err_flag = 0;
960
  sd->last_nack_pkt = 0;
961
  sd->rx_wakeup_thr = 1;
962
  sd->active = 0;
963
  sd->cmd_seq = 0;
964
  sd->is_open = 1;
965
  file->private_data=sd;
966
  return SUCCESS;
967
}
968
 
969
 
970
static int my_proto1_release(struct inode *inode,
971
                             struct file *file)
972
{
973
  slave_data * sd = file->private_data;
974 18 wzab
  //#ifdef FADE_DEBUG
975 15 wzab
  printk (KERN_INFO "device_release(%p,%p)\n", inode, file);
976 18 wzab
  //#endif
977 15 wzab
  //Release resources associated with servicing of the particular device
978
  if (sd) {
979
    if (sd->is_open) {
980
      sd->is_open = 0; //It can be dangerous! Before freeing the buffer, we must be sure, that
981
      //no our packet is being processed!
982 18 wzab
      printk (KERN_INFO "freed MAC\n");
983
      free_mac(sd); //It also sets sd->active to 0!
984 15 wzab
      if (sd->buffer) {
985 18 wzab
        printk (KERN_INFO "freed buffer\n");
986 15 wzab
        vfree(sd->buffer);
987
        sd->buffer = NULL;
988
      }
989
    }
990
  }
991
  return SUCCESS;
992
}
993
 
994
/* Memory mapping */
995
void my_proto1_vma_open (struct vm_area_struct * area)
996
{  }
997
 
998
void my_proto1_vma_close (struct vm_area_struct * area)
999
{  }
1000
 
1001
static struct vm_operations_struct my_proto1_vm_ops = {
1002
  my_proto1_vma_open,
1003
  my_proto1_vma_close,
1004
};
1005
 
1006
/*
1007
  mmap method implementation
1008
*/
1009
int my_proto1_mmap(struct file *filp,
1010
                   struct vm_area_struct *vma)
1011
{
1012
  slave_data * sd = filp->private_data;
1013
  unsigned long vsize = vma->vm_end - vma->vm_start;
1014
  unsigned long psize = MY_BUF_LEN;
1015
  if (vsize>psize)
1016
    return -EINVAL;
1017
  remap_vmalloc_range(vma,sd->buffer, 0);
1018
  if (vma->vm_ops)
1019
    return -EINVAL; //It should never happen...
1020
  vma->vm_ops = &my_proto1_vm_ops;
1021
  my_proto1_vma_open(vma); //No open(vma) was called, we have called it ourselves
1022
  return 0;
1023
}
1024
 

powered by: WebSVN 2.1.0

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