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 18

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

powered by: WebSVN 2.1.0

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