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 16

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

powered by: WebSVN 2.1.0

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