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 46

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 29 wzab
    // Here http://lxr.free-electrons.com/source/net/ipv4/arp.c?v=3.17#L608 it is shown how to build a packet!
253 18 wzab
    if (dev_hard_header(newskb,sd->dev,MY_PROTO_ID,&sd->mac,sd->dev->dev_addr,MY_ACK_LEN+ETH_HLEN) < 0)
254
      {
255 29 wzab
        mutex_unlock(&sd->usercmd_lock);
256 18 wzab
        kfree_skb(newskb);
257
        return -EINVAL;
258
      }
259
    //Put the protocol version id to the packet
260
    put_skb_u16(newskb,MY_PROTO_VER);
261
    //Put the command code
262
    put_skb_u16(newskb,cmd);
263
    //Put the sequence number
264
    put_skb_u16(newskb,sd->cmd_seq);
265
    //Put the argument
266
    put_skb_u32(newskb,arg);
267
    //Fill the packet
268
    my_data = skb_put(newskb,MY_ACK_LEN-10);
269
    memset(my_data,0xa5,MY_ACK_LEN-10);
270
    dev_queue_xmit(newskb);
271
    //Sleep with short timeout, waiting for response
272 30 wzab
    if(wait_event_interruptible_timeout(usercmd_queue,sd->cmd_ack==2,timeout)) {
273 18 wzab
      //Response received
274
      //If target buffer provided, copy data to the userspace buffer
275
      if(resp) memcpy(resp,sd->cmd_resp,12);
276
      result = SUCCESS;
277
      break; //exit loop
278
    }
279
  }
280
  //We don't wait for response any more
281
  sd->cmd_ack = 0;
282
  mutex_unlock(&sd->usercmd_lock);
283
  return result;
284
}
285 21 wzab
/* Function used to send RESET command (without confirmation, as
286
the core is reinitialized and can't send confirmation) */
287
static inline
288
long send_reset(slave_data * sd)
289
{
290
  struct sk_buff *newskb = NULL;
291
  uint8_t * my_data = NULL;
292
  //First check, if the Ethernet device is claimed, otherwise return an error
293
  if(sd->dev==NULL) return -ENODEV;
294
  //Each slave may perform only one user command, so first check, if no other thread
295
  //attempts to send the command
296
  if ( mutex_trylock(&sd->usercmd_lock)==0) return -EBUSY;
297
  //Mutex acquired, we can proceed
298
  //First allocate the sequence number for the command
299
  sd->cmd_seq = 0;
300
  sd->cmd_code = FCMD_RESET;
301
  sd->cmd_ack = 0; //We don't wait for response
302
  //Send the packet 
303
  newskb = alloc_skb(LL_RESERVED_SPACE(sd->dev)+MY_ACK_LEN, GFP_KERNEL);
304
  skb_reserve(newskb,LL_RESERVED_SPACE(sd->dev));
305
  skb_reset_network_header(newskb);
306
  newskb->dev = sd->dev;
307
  newskb->protocol = htons(MY_PROTO_ID);
308
  //Build the MAC header for the new packet
309 29 wzab
  // Here http://lxr.free-electrons.com/source/net/ipv4/arp.c?v=3.17#L608 it is shown how to build a packet!
310 21 wzab
  if (dev_hard_header(newskb,sd->dev,MY_PROTO_ID,&sd->mac,sd->dev->dev_addr,MY_ACK_LEN+ETH_HLEN) < 0)
311
    {
312 29 wzab
      mutex_unlock(&sd->usercmd_lock);
313 21 wzab
      kfree_skb(newskb);
314
      return -EINVAL;
315
    }
316
  //Put the protocol version id to the packet
317
  put_skb_u16(newskb,MY_PROTO_VER);
318
  //Put the command code
319
  put_skb_u16(newskb,sd->cmd_code);
320
  //Put the sequence number
321
  put_skb_u16(newskb,sd->cmd_seq);
322
  //Put the argument
323
  put_skb_u32(newskb,0);
324
  //Fill the packet
325
  my_data = skb_put(newskb,MY_ACK_LEN-10);
326
  memset(my_data,0xa5,MY_ACK_LEN-10);
327
  dev_queue_xmit(newskb);
328
  mutex_unlock(&sd->usercmd_lock);
329
  return SUCCESS;
330
}
331 18 wzab
 
332
/* Function free_mac may be safely called even if the MAC was not taken
333
   it checks sd->active to detect such situation
334
*/
335
static inline
336
long free_mac(slave_data *sd) {
337
  write_lock_bh(&slave_table_lock);
338
  if(sd->active) {
339
    /* Clear the MAC address */
340
    sd->active = 0;
341
    memset(&sd->mac,0,ETH_ALEN);
342
    write_unlock_bh(&slave_table_lock);
343
    /* Now send the "stop transmission" packet to the slave */
344
    /* Find the net device */
345
    if (!sd->dev) return -ENODEV;
346
    dev_put(sd->dev);
347
    sd->dev=NULL;
348
  } else {
349
    write_unlock_bh(&slave_table_lock);
350
  }
351
  return SUCCESS;
352
}
353
 
354 15 wzab
static long my_proto1_ioctl (struct file *filp,
355
                             unsigned int cmd, unsigned long arg)
356
{
357
  slave_data * sd = filp->private_data;
358
  if (_IOC_TYPE(cmd) != L3_V1_IOC_MAGIC) {
359
    return -EINVAL;
360
  }
361
  switch (cmd) {
362
  case L3_V1_IOC_SETWAKEUP:
363
    if (arg > MY_BUF_LEN/2)
364
      return -EINVAL; //Don't allow to set too high read threshold!
365
    write_lock_bh(&sd->flags_lock);
366
    sd->rx_wakeup_thr = arg;
367
    write_unlock_bh(&sd->flags_lock);
368
    return 0;
369
  case L3_V1_IOC_GETBUFLEN:
370
    /* Inform the user application about the length of the buffer */
371
    return MY_BUF_LEN;
372
  case L3_V1_IOC_READPTRS:
373
    {
374
      void * res = (void *) arg;
375
      long res2;
376
      struct l3_v1_buf_pointers bp;
377
      if (!access_ok(VERIFY_WRITE,res,sizeof(bp))) {
378
        return -EFAULT;
379
      } else {
380
        read_lock_bh(&sd->ptrs_lock);
381
        bp.head=sd->head;
382
        bp.tail=sd->tail;
383 18 wzab
        bp.eof=sd->eof_flag;
384 15 wzab
        read_unlock_bh(&sd->ptrs_lock);
385
        res2 = __copy_to_user(res,&bp,sizeof(bp));
386
        if(res2)
387
          return -EFAULT;
388
        if (sd->err_flag)
389
          return -EIO; /* In this case user must him/herself
390
                          calculate the number of available bytes */
391
        else
392
          return (bp.head-bp.tail) & MY_BUF_LEN_MASK;
393
        /* Return the number of available bytes */
394
      }
395
    }
396
  case L3_V1_IOC_WRITEPTRS:
397
    /* Update the read pointer
398
     * The argument contains information about the number of bytes
399
     * consumed by the application
400
     */
401
    {
402
      int rptr;
403
      int wptr;
404
      int available_data;
405
      //We need to check if the amount of consumed data is correct
406
      write_lock_bh(&sd->ptrs_lock);
407
      wptr = sd->head;
408
      rptr = sd->tail;
409
      available_data = (wptr - rptr) & MY_BUF_LEN_MASK;
410
      if (arg>available_data)
411
        {
412
          write_unlock_bh(&sd->ptrs_lock);
413
          return -EINVAL;
414
        }
415
      //If the number of consumed bytes is correct, update the number of bytes
416
      sd->tail = (rptr + arg) & MY_BUF_LEN_MASK;
417
      write_unlock_bh(&sd->ptrs_lock);
418
      return SUCCESS;
419
    }
420
  case L3_V1_IOC_STARTMAC: //Open the slave
421
    {
422 18 wzab
      sd->stopped_flag = 0;
423
      sd->eof_flag = 0;
424
      //We just send a request to start transmission and wait for confirmation
425
      return send_cmd(sd,FCMD_START,0,NULL,100,2);
426 15 wzab
    }
427 18 wzab
  case L3_V1_IOC_STOPMAC: //Close the slave and reset it to stop transmission immediately
428
    {
429
      return send_cmd(sd,FCMD_STOP,0,NULL,100,2);
430
    }
431
  case L3_V1_IOC_RESETMAC: //Reset MAC so, that it stops transmission immediately
432
    {
433 21 wzab
      return send_reset(sd);
434 18 wzab
    }
435 15 wzab
  case L3_V1_IOC_GETMAC: //Open the slave
436
    {
437
      void * source = (void *) arg;
438
      struct l3_v1_slave sl;
439
      struct net_device *dev = NULL;
440
      long res2;
441
      if (!access_ok(VERIFY_READ,source,sizeof(sl))) {
442
        return -EFAULT;
443
      }
444
      /* First deactivate the slave to avoid situation where data are modified
445
       * while slave is active */
446
      if (sd->active) sd->active = 0;
447
      //Set the numbers of stored packets to MAX
448
      write_lock_bh(&sd->pkts_rwlock);
449
      memset(&sd->pkts,0xff,sizeof(sd->pkts));
450
      sd->last_nack_pkt=0;
451
      write_unlock_bh(&sd->pkts_rwlock);
452
      //Copy arguments from the user space
453
      res2 = __copy_from_user(&sl,source,sizeof(sl));
454
      if(res2) {
455
        return -EFAULT;
456
      }
457
      write_lock_bh(&slave_table_lock);
458
      /* Copy the MAC address */
459
      memcpy(&sd->mac,sl.mac,ETH_ALEN);
460
      sd->active = 1;
461
      write_unlock_bh(&slave_table_lock);
462
      /* Find the net device */
463
      sl.devname[IFNAMSIZ-1]=0; // Protect against incorrect device name
464
      if (sd->dev) {
465
        //Maybe there was no STOPMAC call after previous STARTMAC?
466
        dev_put(sd->dev);
467
        sd->dev=NULL;
468
      }
469
      dev = dev_get_by_name(&init_net,sl.devname);
470
      if (!dev) return -ENODEV;
471
      sd->dev = dev;
472
      return SUCCESS;
473
    }
474
  case L3_V1_IOC_FREEMAC: //Close the slave and reset it to stop transmission immediately
475
    {
476 18 wzab
      free_mac(sd);
477 15 wzab
      return SUCCESS;
478
    }
479
  case L3_V1_IOC_USERCMD: //Perform the user command
480
    {
481
      void * source = (void *) arg;
482
      long result = -EINVAL;
483
      struct l3_v1_usercmd ucmd;
484
      //First copy command data
485
      result = __copy_from_user(&ucmd,source,sizeof(ucmd));
486
      if(result) {
487
        return -EFAULT;
488
      }
489
      //Now we check if the command is valid user command
490
      if(ucmd.cmd < 0x0100) return -EINVAL;
491 18 wzab
      result = send_cmd(sd,ucmd.cmd, ucmd.arg, ucmd.resp, ucmd.nr_of_retries,ucmd.timeout);
492
      if(result<0) return result;
493
      result = __copy_to_user(source,&ucmd,sizeof(ucmd));
494 15 wzab
      return result;
495
    }
496
  }
497
  return -EINVAL;
498
}
499
/*
500
  Implementation of the poll method
501
*/
502
unsigned int my_proto1_poll(struct file *filp,poll_table *wait)
503
{
504
  unsigned int mask =0;
505
  slave_data * sd = filp->private_data;
506
  unsigned int data_available;
507
  poll_wait(filp,&read_queue,wait);
508
  read_lock_bh(&sd->ptrs_lock);
509
  data_available = (sd->head - sd->tail) & MY_BUF_LEN_MASK;
510 18 wzab
  if (data_available >= sd->rx_wakeup_thr) mask |= POLLIN |POLLRDNORM;
511
  if (sd->eof_flag) {
512
    if(data_available) mask |= POLLIN | POLLRDNORM;
513
    else mask |= POLLHUP;
514
  }
515 15 wzab
#ifdef FADE_DEBUG
516
  printk(KERN_INFO "poll head: %d tail: %d data: %d prog: %d.\n",sd->head,sd->tail,data_available,sd->rx_wakeup_thr);
517
#endif
518
  //Check if the error occured
519
  if (sd->err_flag) mask |= POLLERR;
520
  read_unlock_bh(&sd->ptrs_lock);
521
  return mask;
522
}
523
 
524
/* Module initialization  */
525
int init_my_proto1( void )
526
{
527
  int res;
528
  int i;
529
  /* Create the device class for udev */
530
  class_my_proto = class_create(THIS_MODULE, "my_proto");
531
  if (IS_ERR(class_my_proto)) {
532
    printk(KERN_ERR "Error creating my_proto class.\n");
533
    res=PTR_ERR(class_my_proto);
534
    goto err1;
535
  }
536
  /* Allocate the device number */
537
  res=alloc_chrdev_region(&my_dev, 0, max_slaves, DEVICE_NAME);
538
  if (res) {
539
    printk (KERN_ERR "Alocation of the device number for %s failed\n",
540
            DEVICE_NAME);
541
    goto err1;
542
  };
543
  /* Allocate the character device structure */
544
  my_cdev = cdev_alloc( );
545
  if (my_cdev == NULL) {
546
    printk (KERN_ERR "Allocation of cdev for %s failed\n",
547
            DEVICE_NAME);
548
    goto err1;
549
  }
550
  my_cdev->ops = &Fops;
551
  my_cdev->owner = THIS_MODULE;
552
  /* Add the character device to the system */
553
  res=cdev_add(my_cdev, my_dev, max_slaves);
554
  if (res) {
555
    printk (KERN_ERR "Registration of the device number for %s failed\n",
556
            DEVICE_NAME);
557
    goto err1;
558
  };
559
  /* Create our devices in the system */
560
  for (i=0;i<max_slaves;i++) {
561
    device_create(class_my_proto,NULL,MKDEV(MAJOR(my_dev),MINOR(my_dev)+i),NULL,"l3_fpga%d",i);
562
  }
563
  printk (KERN_ERR "%s The major device number is %d.\n",
564
          "Registration is a success.",
565
          MAJOR(my_dev));
566
  //Prepare the table of slaves
567
  slave_table = kzalloc(sizeof(slave_data)*max_slaves, GFP_KERNEL);
568
  if (!slave_table) return -ENOMEM;
569
  for (i=0;i<max_slaves;i++) {
570
    /* Perform initialization, which should be done only once, when the module
571
     * is loaded. Other actions may be needed, when the transmission from
572
     * particular slave is started. This will be done in IOCTL STARTMAC
573
     */
574
    slave_data * sd = &slave_table[i];
575
    sd->active=0; //Entry not used
576
    sd->dev=NULL;
577
    rwlock_init(&sd->pkts_rwlock);
578
    rwlock_init(&sd->ptrs_lock);
579
    rwlock_init(&sd->flags_lock);
580
    mutex_init(&sd->usercmd_lock);
581
  }
582
  //Install our protocol sniffer
583
  dev_add_pack(&my_proto_pt);
584
  proto_registered = 1;
585
  return SUCCESS;
586
 err1:
587
  /* In case of error free all allocated resources */
588
  cleanup_my_proto1();
589
  return res;
590
}
591
 
592
module_init(init_my_proto1);
593
 
594
/* Clean-up when removing the module */
595
void cleanup_my_proto1( void )
596
{
597
  /* Unregister the protocol sniffer */
598
  if (proto_registered) dev_remove_pack(&my_proto_pt);
599
  /* Free the slave table */
600
  if (slave_table) {
601
    int i;
602
    for (i=0;i<max_slaves;i++) {
603
      if (slave_table[i].buffer) {
604
        vfree(slave_table[i].buffer);
605
        slave_table[i].buffer = NULL;
606
      }
607
      if (slave_table[i].dev) {
608
        dev_put(slave_table[i].dev);
609
        slave_table[i].dev=NULL;
610
      }
611
      if (slave_table[i].active) {
612
        slave_table[i].active = 0;
613
      }
614
    }
615
    kfree(slave_table);
616
    slave_table=NULL;
617
  }
618
  /* Remove device from the class */
619
  if (my_dev && class_my_proto) {
620
    int i;
621
    for (i=0;i<max_slaves;i++) {
622
      device_destroy(class_my_proto,MKDEV(MAJOR(my_dev),MINOR(my_dev)+i));
623
    }
624
  }
625
  /* Deregister device */
626
  if (my_cdev) cdev_del(my_cdev);
627
  my_cdev=NULL;
628
  /* Free the device number */
629
  unregister_chrdev_region(my_dev, max_slaves);
630
  /* Deregister class */
631
  if (class_my_proto) {
632
    class_destroy(class_my_proto);
633
    class_my_proto=NULL;
634
  }
635
 
636
}
637
module_exit(cleanup_my_proto1);
638
/*
639
  Function, which receives my packet, copies the data and acknowledges the packet
640
  as soon as possible...
641
  I've tried to allow this function to handle multiple packets in parallel
642
  in the SMP system, however I've used rwlocks for that.
643
  Probably it should be improved, according to the last tendency to avoid
644
  rwlocks in the kernel...
645
*/
646
 
647
static int my_proto_rcv(struct sk_buff * skb, struct net_device * dev, struct packet_type * pt,
648
                        struct net_device * orig_dev)
649
{
650
  struct sk_buff *newskb = NULL;
651
  struct ethhdr * rcv_hdr = NULL;
652
  //unsigned int head;
653
  //unsigned int tail;
654
  int is_duplicate = 0;
655
  int res;
656
  uint32_t packet_number;
657
  int ns; //Number of slave
658
  slave_data * sd = NULL;
659
  int32_t pkt_dist;
660
  char * my_data = NULL;
661
  unsigned char tmp_buf[USER_HDR_LEN];
662
  char ack_packet = 0; //Should we acknowledge the packet?
663 18 wzab
  uint32_t pkt_pos, needed_space, buf_free;
664 15 wzab
  //Extract the MAC header from the received packet
665
  rcv_hdr=eth_hdr(skb);
666
  //First we try to identify the sender so we search the table of active slaves
667
  //The table is protected during the search, so it should not be changed
668
#ifdef FADE_DEBUG
669
  printk("snd: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",(int)rcv_hdr->h_source[0],
670
         (int)rcv_hdr->h_source[1],(int)rcv_hdr->h_source[2],(int)rcv_hdr->h_source[3],
671
         (int)rcv_hdr->h_source[4],(int)rcv_hdr->h_source[5]);
672
#endif
673
  read_lock_bh(&slave_table_lock);
674
  for (ns=0;ns<max_slaves;ns++) {
675
#ifdef FADE_DEBUG
676
    printk("slv: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x  act: %d\n",
677
           (int)slave_table[ns].mac[0],(int)slave_table[ns].mac[1],(int)slave_table[ns].mac[2],
678
           (int)slave_table[ns].mac[3],(int)slave_table[ns].mac[4],(int)slave_table[ns].mac[5],
679
           (int)slave_table[ns].active);
680
#endif
681
    if (
682
        slave_table[ns].active!=0 &&
683
        memcmp(slave_table[ns].mac,rcv_hdr->h_source, sizeof(slave_table[0].mac))==0
684
        ) break;
685
  }
686
  read_unlock_bh(&slave_table_lock);
687
  //Now we know which slave sent us the packet (ns<max_slaves) or that
688
  //the packet came from an unknown slave (ns==max_slaves)
689
  if (unlikely(ns==max_slaves)) {
690
    printk(KERN_WARNING " Received packet from incorrect slave!\n");
691
    //Sender is not opened, so ignore the packet, and send
692
    //to the sender request to stop the transmission immediately
693
    newskb = alloc_skb(LL_RESERVED_SPACE(dev)+MY_ACK_LEN, GFP_ATOMIC);
694
    skb_reserve(newskb,LL_RESERVED_SPACE(dev));
695
    skb_reset_network_header(newskb);
696
    newskb->dev = dev;
697
    newskb->protocol = htons(MY_PROTO_ID);
698
    //Build the MAC header for the new packet
699 29 wzab
    // Here http://lxr.free-electrons.com/source/net/ipv4/arp.c?v=3.17#L608 it is shown how to build a packet!
700 15 wzab
    if (dev_hard_header(newskb,dev,MY_PROTO_ID,&rcv_hdr->h_source,&rcv_hdr->h_dest,MY_ACK_LEN+ETH_HLEN) < 0)
701
      goto error;
702
    //Put the protocol version id to the packet
703 16 wzab
    put_skb_u16(newskb,MY_PROTO_VER);
704 18 wzab
    //Put the "restart" command to the packet, which should force it to stop transmission
705
    //immediately
706
    put_skb_u16(newskb,FCMD_RESET);
707 15 wzab
    my_data = skb_put(newskb,MY_ACK_LEN - 4);
708
    memset(my_data,0xa5,MY_ACK_LEN - 4);
709
    dev_queue_xmit(newskb);
710
    kfree_skb(skb);
711
    return NET_RX_DROP;
712
  }
713
  sd = &slave_table[ns]; //To speed up access to the data describing state of the slave
714
#ifdef FADE_DEBUG
715
  printk(KERN_INFO " Received packet!\n");
716
#endif
717
  //Now we should analyze the origin and meaning of the packet
718
  //To avoid problems with scattered packets, we copy initial part of data to the buffer
719
  //using the skb_copy_bits
720
  skb_copy_bits(skb,0,tmp_buf,USER_HDR_LEN);
721
  /* We extract the information from the user header
722
   * First we check if this is correct version of the protocol */
723 18 wzab
  if (unlikely(get_be_u16(&tmp_buf[0]) != MY_PROTO_VER)) goto wrong_pkt_type_error;
724 16 wzab
  if (unlikely(get_be_u16(&tmp_buf[2]) == 0xa55a)) {
725 15 wzab
    //This is a command response packet
726
    printk(KERN_INFO " received command response packet");
727
    if(sd->cmd_ack==1) {
728
      //We are waiting for response
729
      printk(KERN_INFO "we were waiting for command response packet");
730 16 wzab
      if ((get_be_u16(&tmp_buf[6]) == sd->cmd_code) &&
731 18 wzab
          (get_be_u16(&tmp_buf[8]) == sd->cmd_seq)){
732 15 wzab
        //This is a response for the right command
733
        //copy the response to the slave data
734
        printk(KERN_INFO "It was response for the right command");
735
        memcpy(&sd->cmd_resp,&tmp_buf[6],12);
736
        sd->cmd_ack=2;
737
        //Wake up the waiting process
738
        wake_up_interruptible(&usercmd_queue);
739
      }
740
    }
741
    kfree_skb(skb);
742
    return NET_RX_SUCCESS;
743
  }
744 18 wzab
  if (unlikely((get_be_u16(&tmp_buf[2]) != 0xa5a5) &&
745
               (get_be_u16(&tmp_buf[2]) != 0xa5a6))
746
      ) {
747 15 wzab
    //This is not a data packet
748
    goto wrong_pkt_type_error;
749
  }
750
  /* Now we handle the data packet
751
     PLEASE NOTE, THAT THIS MUST TIGHTLY CORRESPOND
752
     TO YOUR FPGA IMPLEMENTATION! */
753
  //Check, if we need to read a command response
754
  if(sd->cmd_ack==1) {
755
    //We are waiting for response
756 16 wzab
    if ((get_be_u16(&tmp_buf[14]) == sd->cmd_code) &&
757
        (get_be_u16(&tmp_buf[16]) == sd->cmd_seq)) {
758 15 wzab
      //This is a response for the right command
759
      //copy the response to the slave data
760
      memcpy(&sd->cmd_resp,&tmp_buf[14],12);
761
      sd->cmd_ack=2;
762
      //Wake up the waiting process
763
      wake_up_interruptible(&usercmd_queue);
764
    }
765
  }
766 16 wzab
  packet_number = get_be_u32(&tmp_buf[6]);
767 15 wzab
#ifdef FADE_DEBUG
768
  printk(KERN_INFO "pkt=%d\n",(int)packet_number);
769
#endif
770
  /* To know if this is a new packet, we compare the packet number
771
   * in the received packet with the number of the last unconfirmed packet,
772
   * calculating the difference between those two numbers: */
773
  read_lock_bh(&sd->pkts_rwlock);
774
  pkt_dist=(int32_t) packet_number - (int32_t) sd->last_nack_pkt;
775 18 wzab
  //Check if this packet was received before
776 15 wzab
  is_duplicate=(sd->pkts[packet_number & PKTS_IN_WINDOW_MASK] == packet_number) ? 1 : 0;
777
  read_unlock_bh(&sd->pkts_rwlock);
778 18 wzab
  if (unlikely((pkt_dist<0) || (pkt_dist>=PKTS_IN_WINDOW))) {
779
    //This is a "too old" packet, or packet "from the future", which should not be transimtted
780
    //by the FPGA
781 15 wzab
    if (pkt_dist<0) {
782 18 wzab
      // This is a packet which was already confirmed, but probably ACK was lost
783 15 wzab
#ifdef FADE_DEBUG
784
      printk(KERN_INFO "Packet already confirmed: pkt=%d expect=%d last=%d\n",packet_number, sd->pkts[packet_number], sd->last_nack_pkt);
785
#endif
786 18 wzab
      ack_packet = 1;
787
      goto confirm;
788 15 wzab
    } else {
789
      /* This is a packet with too high set number (packet "from the future"
790
       * it my be a symptom of serious communication problem! */
791
      printk(KERN_ERR "Packet from the future! number: %d last_confirmed: %d\n", packet_number, sd->last_nack_pkt);
792 18 wzab
      goto error2;
793 15 wzab
    }
794
  }
795 18 wzab
  //If we get there, it means, that:
796
  //   pkt_dist >= 0 and pkt_dist < PKTS_IN_WINDOW
797
  // So this is an expected data packet.
798
  if(is_duplicate) {
799
    //Packet already confirmed, probably the ACK was lost, so simply generate the ACK
800
    ack_packet = 1;
801
    goto confirm;
802
  }
803
  //Packet not confirmed yet. Confirm it only after all processing is successfully completed
804
  pkt_pos=(packet_number<<LOG2_USER_LEN) & MY_BUF_LEN_MASK;
805
  //We must be sure, that the pointers do not change during this check
806
  read_lock_bh(&sd->ptrs_lock);
807
  //Calculate free space needed to copy the packet
808
  needed_space = (pkt_pos+USER_LEN-1-(sd->head)) & MY_BUF_LEN_MASK;
809
  //Calculate the amount of free space in the buffer
810
  buf_free = (sd->tail - sd->head -1 ) & MY_BUF_LEN_MASK;
811
#ifdef FADE_DEBUG
812
  printk(KERN_INFO "packet_nr: %d Free buffer: %d needed space: %d head=%d last_nack=%d\n",
813
         packet_number, needed_space, buf_free, sd->head, sd->last_nack_pkt);
814
#endif
815
  read_unlock_bh(&sd->ptrs_lock);
816
  if (unlikely( buf_free <= needed_space )) goto error2; //No place for copying, drop the packet
817
  // Check the length of the package
818
  if (unlikely(skb->len != PAYL_LEN)) {
819
    printk(KERN_ERR "Error! Length of data should be %d but is %d!\n",PAYL_LEN, skb->len);
820
    sd->err_flag |= FADE_ERR_INCORRECT_LENGTH;
821
    goto error2;
822
  }
823
  // We can safely copy all the packet to the buffer:
824
  res = skb_copy_bits(skb,USER_HDR_LEN,&(sd->buffer[pkt_pos]),USER_LEN);
825
#ifdef FADE_DEBUG
826
  printk(KERN_INFO " skb_copy_bits: %d", res);
827
#endif
828
  if (res<0) goto error2; //Unsuccessfull copying
829
  //Packet was copied, so note, that we should confirm it
830
  ack_packet=1;
831
  /* When packet is copied, we can check if this is the last "flushed" packet */
832
  if (get_be_u16(&tmp_buf[2])==0xa5a6) {
833
    //Flushed packet, store its number and length (should it be protected with spinlock?)
834
    sd->last_pkt_num = packet_number;
835
    //Copy the length, truncating it from 64 bits
836 46 wzab
    sd->last_pkt_len = get_be_u64(&(sd->buffer[pkt_pos+USER_LEN-sizeof(uint64_t)]));
837 18 wzab
    //We have received the "flushed" buffer, mark that transmission is stopped
838
    sd->stopped_flag = 1;
839 20 wzab
    //printk(KERN_INFO "set stopped flag");
840 18 wzab
  }
841
  /* We modify the number of the copied packet in the pkts array, to avoid
842
   * unnecessary copying if we receive a duplicate
843
   * To modify the pkts table, we must close pkts_rwlock for writing */
844
  write_lock_bh(&sd->pkts_rwlock);
845
  sd->pkts[packet_number & PKTS_IN_WINDOW_MASK]= packet_number;
846
  if (packet_number == sd->last_nack_pkt) {
847
    /* If our packet was the last, which prevented shifting of the head pointer,
848
     * we can try now to move the head pointer.
849
     * We browse the pkts table, looking for the first packet with incorrect number
850
     * i.e. the packet which was not received and not confimed yet
851
     */
852
    uint32_t chk_packet_num = packet_number+1;
853
    uint32_t count=0;
854
    while (++count < PKTS_IN_WINDOW) {
855
      if (sd->pkts[(sd->last_nack_pkt + count) & PKTS_IN_WINDOW_MASK] != chk_packet_num) break; //Packet not confirmed
856
      chk_packet_num++;
857
    }
858
    sd->last_nack_pkt += count;
859
    write_unlock_bh(&sd->pkts_rwlock);
860
    /* Now we can move the head position */
861
    if(likely((sd->stopped_flag == 0) ||
862
              ((uint32_t)(sd->last_nack_pkt-1) != sd->last_pkt_num))) {
863
      //Normal packet, set head right after the last serviced packet
864
      write_lock_bh(&sd->ptrs_lock);
865
      sd->head = (sd->last_nack_pkt*USER_LEN) & MY_BUF_LEN_MASK;
866
      //Now try to wake up the reading process
867
      if (((sd->head - sd->tail) & MY_BUF_LEN_MASK) >= sd->rx_wakeup_thr)
868
        wake_up_interruptible(&read_queue);
869
    } else {
870
      //Flushed packet, set head right after the end of the packet
871
      write_lock_bh(&sd->ptrs_lock);
872 46 wzab
      sd->head = ((sd->last_nack_pkt-1)*USER_LEN+8*sd->last_pkt_len) & MY_BUF_LEN_MASK;
873 18 wzab
      //We have consumed the last, "flushed" buffer, so now we can set the eof flag
874
      sd-> eof_flag = 1;
875 20 wzab
      //printk(KERN_ALERT "set eof flag!");
876 18 wzab
      //And we wake up the reading process
877
      wake_up_interruptible(&read_queue);
878
    } //if - stopped_flag
879
    write_unlock_bh(&sd->ptrs_lock);
880
  } else { // if - last_nack_pkt 
881
    write_unlock_bh(&sd->pkts_rwlock);
882
  }
883
 confirm:
884
  //Send the confirmation if required
885 15 wzab
  if (likely(ack_packet)) {
886
    newskb = alloc_skb(LL_RESERVED_SPACE(dev)+MY_ACK_LEN, GFP_ATOMIC);
887
    skb_reserve(newskb,LL_RESERVED_SPACE(dev));
888
    skb_reset_network_header(newskb);
889
    newskb->dev = dev;
890
    newskb->protocol = htons(MY_PROTO_ID);
891
    //Build the MAC header for the new packet
892 29 wzab
    // Here http://lxr.free-electrons.com/source/net/ipv4/arp.c?v=3.17#L608 it is shown how to build a packet!
893 15 wzab
    if (dev_hard_header(newskb,dev,MY_PROTO_ID,&rcv_hdr->h_source,&rcv_hdr->h_dest,MY_ACK_LEN+ETH_HLEN) < 0)
894
      goto error;
895
    //Put the protocol version id to the packet
896 18 wzab
    put_skb_u16(newskb,MY_PROTO_VER);
897 15 wzab
    //Put the "ACKNOWLEDGE" type
898 18 wzab
    put_skb_u16(newskb,FCMD_ACK);
899 15 wzab
    //Copy the begining of the received packet to the acknowledge packet
900
    my_data = skb_put(newskb,MY_ACK_COPIED);
901
    res = skb_copy_bits(skb,4,my_data,MY_ACK_COPIED);
902
    my_data = skb_put(newskb,MY_ACK_LEN -MY_ACK_COPIED-4);
903
    memset(my_data,0xa5,MY_ACK_LEN - MY_ACK_COPIED-4);
904
#ifdef FADE_DEBUG
905
    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,
906
           newskb->network_header,newskb->tail, sd->tail, sd->head) ;
907
#endif
908
    dev_queue_xmit(newskb);
909
  }
910
  kfree_skb(skb);
911
  return NET_RX_SUCCESS;
912
 wrong_pkt_type_error:
913
  //This code should be called with sd initialized,
914
  //but to avoid kernel panic, check if sd was set
915
  if(sd) {
916
    write_lock_bh(&sd->flags_lock);
917
    sd->err_flag |= FADE_ERR_INCORRECT_PACKET_TYPE;
918
    write_unlock_bh(&sd->flags_lock);
919
  } else {
920
    printk(KERN_ERR "FADE: wrong_pkt_type_error called with null sd");
921
  }
922
 error:
923
  if (newskb) kfree_skb(newskb);
924 18 wzab
 error2:
925 15 wzab
  if (skb) kfree_skb(skb);
926
  return NET_RX_DROP;
927
}
928
 
929
/*
930
  Implementation of the "device open" function
931
*/
932
static int my_proto1_open(struct inode *inode,
933
                          struct file *file)
934
{
935
  int i;
936
  slave_data * sd = NULL;
937
  unsigned long flags;
938
  i=iminor(inode)-MINOR(my_dev);
939
  if (i >= max_slaves) {
940
    printk(KERN_WARNING "Trying to access %s slave with too high minor number: %d\n",
941
           DEVICE_NAME, i);
942
    return -ENODEV;
943
  }
944
  read_lock_irqsave(&slave_table_lock,flags);
945
  sd = &slave_table[i];
946
  //Each device may be opened only once!
947
  if (sd->is_open) {
948 28 wzab
    read_unlock_irqrestore(&slave_table_lock,flags);
949 15 wzab
    return -EBUSY;
950
  }
951
  //Prepare slave_table for operation
952
  read_unlock_irqrestore(&slave_table_lock,flags);
953
  sd->buffer = vmalloc_user(MY_BUF_LEN);
954
  if (!sd->buffer) return -ENOMEM;
955
  //Set the MAC address to 0
956
  memset(sd->mac,0,sizeof(sd->mac));
957
  sd->head = 0;
958
  sd->tail = 0;
959 18 wzab
  sd->eof_flag = 0;
960
  sd->stopped_flag = 0;
961 15 wzab
  sd->err_flag = 0;
962
  sd->last_nack_pkt = 0;
963
  sd->rx_wakeup_thr = 1;
964
  sd->active = 0;
965
  sd->cmd_seq = 0;
966
  sd->is_open = 1;
967
  file->private_data=sd;
968
  return SUCCESS;
969
}
970
 
971
 
972
static int my_proto1_release(struct inode *inode,
973
                             struct file *file)
974
{
975
  slave_data * sd = file->private_data;
976 18 wzab
  //#ifdef FADE_DEBUG
977 15 wzab
  printk (KERN_INFO "device_release(%p,%p)\n", inode, file);
978 18 wzab
  //#endif
979 15 wzab
  //Release resources associated with servicing of the particular device
980
  if (sd) {
981
    if (sd->is_open) {
982
      sd->is_open = 0; //It can be dangerous! Before freeing the buffer, we must be sure, that
983
      //no our packet is being processed!
984 18 wzab
      printk (KERN_INFO "freed MAC\n");
985
      free_mac(sd); //It also sets sd->active to 0!
986 15 wzab
      if (sd->buffer) {
987 18 wzab
        printk (KERN_INFO "freed buffer\n");
988 15 wzab
        vfree(sd->buffer);
989
        sd->buffer = NULL;
990
      }
991
    }
992
  }
993
  return SUCCESS;
994
}
995
 
996
/* Memory mapping */
997
void my_proto1_vma_open (struct vm_area_struct * area)
998
{  }
999
 
1000
void my_proto1_vma_close (struct vm_area_struct * area)
1001
{  }
1002
 
1003
static struct vm_operations_struct my_proto1_vm_ops = {
1004
  my_proto1_vma_open,
1005
  my_proto1_vma_close,
1006
};
1007
 
1008
/*
1009
  mmap method implementation
1010
*/
1011
int my_proto1_mmap(struct file *filp,
1012
                   struct vm_area_struct *vma)
1013
{
1014
  slave_data * sd = filp->private_data;
1015
  unsigned long vsize = vma->vm_end - vma->vm_start;
1016
  unsigned long psize = MY_BUF_LEN;
1017
  if (vsize>psize)
1018
    return -EINVAL;
1019
  remap_vmalloc_range(vma,sd->buffer, 0);
1020
  if (vma->vm_ops)
1021
    return -EINVAL; //It should never happen...
1022
  vma->vm_ops = &my_proto1_vm_ops;
1023
  my_proto1_vma_open(vma); //No open(vma) was called, we have called it ourselves
1024
  return 0;
1025
}
1026
 

powered by: WebSVN 2.1.0

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