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 49

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 48 wzab
#include <linux/version.h>
24 47 wzab
#include <linux/sched.h>
25 15 wzab
#include <asm/uaccess.h>
26
 
27
MODULE_LICENSE("GPL v2");
28
//#define FADE_DEBUG 1
29
#include <linux/device.h>
30
#include <linux/netdevice.h>
31
#include <linux/fs.h>
32
#include <linux/cdev.h>
33
#include <linux/poll.h>
34
#include <linux/mm.h>
35
#include <asm/io.h>
36
#include <linux/wait.h>
37
#include <linux/sched.h>
38
#include <asm/uaccess.h>  /* for put_user */
39
#include <linux/mutex.h>
40
 
41
#include "fpga_l3_fade.h"
42
 
43
#define SUCCESS 0
44
#define DEVICE_NAME "fpga_l3_fade"
45
 
46
 
47
/* Length of the user header in the packet
48
 * The following fields are BEFORE the user header
49
 * SRC+TGT - 12 bytes : source & destination
50
 * 0xFADE - 2 bytes : protocol ID
51 49 wzab
 *
52 15 wzab
 * Fields which belong to the user header:
53
 * 0x0100 - 2 bytes : protocol version - offset 0
54
 * For DATA - to PC
55
 * 0xA5A5 - 2 bytes : data ID 0 - offset 2
56
 * retry number - 2 bytes - offset 4
57
 * packet number - 4 bytes - offset 6
58
 * transm_delay - 4 bytes - offset 10
59
 * cmd_response - 12 bytes - offset 14
60 49 wzab
 *
61 15 wzab
 * Total: 26 bytes!
62 18 wzab
 * If the packet contains "flushed" buffer,
63
 * then data ID is 0xA5A6, and the last word
64
 * contains number of transmitted words.
65 15 wzab
 
66
 * For command response
67
 * 0xA55A : cmd_resp ID 2 bytes - offset 2
68
 * 0x0000 : filler - 2 bytes - offset 4
69
 * cmd_response - 12 bytes offset 6
70
 */
71
#define USER_HDR_LEN 26
72
 
73
/* Number of bytes of user data in a packet */
74
#define LOG2_USER_LEN 13
75 49 wzab
#define USER_LEN (1<<LOG2_USER_LEN)
76 15 wzab
#define PAYL_LEN ( USER_HDR_LEN + USER_LEN )
77
 
78
/* Number of packets in window - this number depends on amount of RAM
79
 * in the FPGA - Packets in a widnow must fit in the FPGA RAM
80
 * Should be power of two! */
81 18 wzab
#define PKTS_IN_WINDOW (1<<4)
82 15 wzab
#define PKTS_IN_WINDOW_MASK (PKTS_IN_WINDOW-1)
83
 
84
/* Capacity of kernel buffer (mmapped into user space) measured in
85
 * number of windows - should be equal to power of two, to simplify
86
 * the modulo operation (replacing it by binary AND) */
87
#define WINDOWS_IN_BUFFER (1<<8)
88
 
89
#define MY_BUF_LEN (WINDOWS_IN_BUFFER * PKTS_IN_WINDOW * USER_LEN)
90
#define MY_BUF_LEN_MASK (MY_BUF_LEN-1)
91
 
92
 
93
/* Length of the acknowledment packet and command packets */
94
#define MY_ACK_LEN 64
95
 
96 49 wzab
/* Number of bytes to be copied from data packet to ack packet
97 15 wzab
 * It covers: retry_number, packet_number and transm_delay - 10 bytes
98
 */
99
#define MY_ACK_COPIED 10
100
 
101
/* The Ethernet type of our packet. This is NOT OFFICIALLY REGISTERED type,
102
 * however our protocol is:
103
 * 1. experimental,
104
 * 2. supposed to be used only in private networks
105
 */
106
#define MY_PROTO_ID 0xfade
107
#define MY_PROTO_VER 0x0100
108
 
109
static int max_slaves = 4;
110
module_param(max_slaves,int,0);
111
MODULE_PARM_DESC(max_slaves,"Maximum number of slave FPGA devices serviced by the system.");
112
 
113
static int proto_registered = 0; //Was the protocol registred? Should be deregistered at exit?
114
 
115
DEFINE_RWLOCK(slave_table_lock); //Used to protect table of slaves
116
 
117
/* Structure used to store offset of two currently serviced sets in the data buffer */
118
struct pkt_map {
119 49 wzab
    int num;
120
    int offset;
121 15 wzab
};
122
 
123 49 wzab
typedef struct {
124
    // fields related to the circular buffer
125
    volatile int head;
126
    volatile int tail;
127
    rwlock_t ptrs_lock; //Used to protect the head and tail pointers
128 15 wzab
 
129 49 wzab
    unsigned char * buffer;
130
    struct mutex usercmd_lock;
131
    uint16_t cmd_code;
132
    uint16_t cmd_seq;
133
    uint8_t cmd_ack;
134
    uint8_t cmd_resp[12];
135
    rwlock_t pkts_rwlock; //Protects the pkts table and last_pkt
136
    uint32_t last_nack_pkt; /* Number of the last not acknowledged packet. This is also the number
137 15 wzab
                             of the first packet in the current transmission window */
138 49 wzab
    uint32_t pkts[PKTS_IN_WINDOW]; /* This array stores numbers of the last received packets in the
139 15 wzab
                                  * transmission window. It is used to avoid unnecessary copying of duplicated
140
                                  * packets into the receiver buffer */
141 49 wzab
    rwlock_t flags_lock; //Protects other fields of the slave_data struct
142
    uint32_t last_pkt_num; /* Number of the last "flushed" packet */
143
    uint32_t last_pkt_len; /* Number of words in the last "flushed" packet */
144
    char err_flag;
145
    char stopped_flag; /* Flag informing, that transmission has been already terminated */
146
    char eof_flag; /* Flag informing, that all packets are delivered after transmission is terminated */
147
    char active;
148
    char is_open;
149
    int rx_wakeup_thr;
150
    unsigned char mac[ETH_ALEN];
151
    struct net_device * dev;
152 15 wzab
} slave_data;
153
 
154 16 wzab
/* Auxiliary inline functions */
155
static inline uint16_t get_be_u16(char * buf)
156
{
157 49 wzab
    return be16_to_cpu(*(uint16_t *)buf);
158 16 wzab
}
159
 
160
static inline uint32_t get_be_u32(char * buf)
161
{
162 49 wzab
    return be32_to_cpu(*(uint32_t *)buf);
163 16 wzab
}
164
 
165
static inline uint64_t get_be_u64(char * buf)
166
{
167 49 wzab
    return be64_to_cpu(*(uint64_t *)buf);
168 16 wzab
}
169
 
170
static inline void put_skb_u16(struct sk_buff * skb, uint16_t val)
171
{
172 49 wzab
    void * data = skb_put(skb,sizeof(val));
173
    * (uint16_t *) data = cpu_to_be16(val);
174 16 wzab
}
175
 
176
static inline void put_skb_u32(struct sk_buff * skb, uint32_t val)
177
{
178 49 wzab
    void * data = skb_put(skb,sizeof(val));
179
    * (uint32_t *) data = cpu_to_be32(val);
180 16 wzab
}
181
 
182
static inline void put_skb_u64(struct sk_buff * skb, uint64_t val)
183
{
184 49 wzab
    void * data = skb_put(skb,sizeof(val));
185
    * (uint64_t *) data = cpu_to_be64(val);
186 16 wzab
}
187
 
188 15 wzab
static slave_data * slave_table = NULL;
189
 
190
static int my_proto_rcv(struct sk_buff * skb, struct net_device * dev, struct packet_type * pt,
191 49 wzab
                        struct net_device * orig_dev);
192 15 wzab
 
193
static struct packet_type my_proto_pt __read_mostly = {
194 49 wzab
    .type = cpu_to_be16(MY_PROTO_ID),
195
    .dev = NULL,
196
    .func = my_proto_rcv,
197 15 wzab
};
198
 
199
// Prototypes of functions defined in module
200
void cleanup_my_proto1( void );
201
int init_my_proto1( void );
202
static int my_proto1_open(struct inode *inode, struct file *file);
203
static int my_proto1_release(struct inode *inode, struct file *file);
204
static long my_proto1_ioctl (struct file *filp,  unsigned int cmd, unsigned long arg);
205
int my_proto1_mmap(struct file *filp, struct vm_area_struct *vma);
206
unsigned int my_proto1_poll(struct file *filp,poll_table *wait);
207
 
208
//Wait queue for user application
209
DECLARE_WAIT_QUEUE_HEAD (read_queue);
210
//Wait queue for user commands
211
DECLARE_WAIT_QUEUE_HEAD (usercmd_queue);
212
dev_t my_dev=0;
213
struct cdev * my_cdev = NULL;
214
static struct class *class_my_proto = NULL;
215
 
216
struct file_operations Fops = {
217 49 wzab
    .owner = THIS_MODULE,
218
    .open=my_proto1_open,
219
    .release=my_proto1_release,  /* a.k.a. close */
220
    .poll = my_proto1_poll,
221
    .unlocked_ioctl=my_proto1_ioctl,
222
    .mmap=my_proto1_mmap
223 15 wzab
};
224
 
225 18 wzab
 
226
/* Function used to send the user command and wait for confirmation */
227
static inline
228
long send_cmd(slave_data * sd, uint16_t cmd, uint32_t arg, void * resp, int nof_retries, int timeout)
229
{
230 49 wzab
    long result = -ETIMEDOUT;
231
    //First check, if the Ethernet device is claimed, otherwise return an error
232
    if(sd->dev==NULL) return -ENODEV;
233
    //Each slave may perform only one user command, so first check, if no other thread
234
    //attempts to send the command
235
    if ( mutex_trylock(&sd->usercmd_lock)==0) return -EBUSY;
236
    //Mutex acquired, we can proceed
237
    //First allocate the sequence number for the command
238
    sd->cmd_seq += 1;
239
    sd->cmd_code = cmd;
240
    sd->cmd_ack = 1; //Mark, that we are waiting for response
241
    //Now in the loop we send the packet, requesting execution of the command
242
    //and then we wait for response with timeout
243
    while(nof_retries--) {
244
        //Send the packet
245
        struct sk_buff *newskb = NULL;
246
        uint8_t * my_data = NULL;
247
        newskb = alloc_skb(LL_RESERVED_SPACE(sd->dev)+MY_ACK_LEN, GFP_KERNEL);
248
        skb_reserve(newskb,LL_RESERVED_SPACE(sd->dev));
249
        skb_reset_network_header(newskb);
250
        newskb->dev = sd->dev;
251
        newskb->protocol = htons(MY_PROTO_ID);
252
        //Build the MAC header for the new packet
253
        // Here http://lxr.free-electrons.com/source/net/ipv4/arp.c?v=3.17#L608 it is shown how to build a packet!
254
        if (dev_hard_header(newskb,sd->dev,MY_PROTO_ID,&sd->mac,sd->dev->dev_addr,MY_ACK_LEN+ETH_HLEN) < 0) {
255
            mutex_unlock(&sd->usercmd_lock);
256
            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
        if(wait_event_interruptible_timeout(usercmd_queue,sd->cmd_ack==2,timeout)) {
273
            //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
/* 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 18 wzab
    struct sk_buff *newskb = NULL;
291
    uint8_t * my_data = NULL;
292 49 wzab
    //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 18 wzab
    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 49 wzab
    if (dev_hard_header(newskb,sd->dev,MY_PROTO_ID,&sd->mac,sd->dev->dev_addr,MY_ACK_LEN+ETH_HLEN) < 0) {
311 29 wzab
        mutex_unlock(&sd->usercmd_lock);
312 49 wzab
        kfree_skb(newskb);
313
        return -EINVAL;
314
    }
315 18 wzab
    //Put the protocol version id to the packet
316
    put_skb_u16(newskb,MY_PROTO_VER);
317
    //Put the command code
318 49 wzab
    put_skb_u16(newskb,sd->cmd_code);
319 18 wzab
    //Put the sequence number
320
    put_skb_u16(newskb,sd->cmd_seq);
321
    //Put the argument
322 49 wzab
    put_skb_u32(newskb,0);
323 18 wzab
    //Fill the packet
324
    my_data = skb_put(newskb,MY_ACK_LEN-10);
325
    memset(my_data,0xa5,MY_ACK_LEN-10);
326
    dev_queue_xmit(newskb);
327 49 wzab
    mutex_unlock(&sd->usercmd_lock);
328
    return SUCCESS;
329 18 wzab
}
330
 
331
/* Function free_mac may be safely called even if the MAC was not taken
332 49 wzab
   it checks sd->active to detect such situation
333 18 wzab
*/
334
static inline
335 49 wzab
long free_mac(slave_data *sd)
336
{
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 18 wzab
}
353
 
354 15 wzab
static long my_proto1_ioctl (struct file *filp,
355 49 wzab
                             unsigned int cmd, unsigned long arg)
356 15 wzab
{
357 49 wzab
    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
        void * res = (void *) arg;
374
        long res2;
375
        struct l3_v1_buf_pointers bp;
376 48 wzab
#if LINUX_VERSION_CODE >= 0x50000
377 49 wzab
        if (!access_ok(res,sizeof(bp))) {
378 48 wzab
#else
379 49 wzab
        if (!access_ok(VERIFY_WRITE,res,sizeof(bp))) {
380 48 wzab
#endif
381 49 wzab
            return -EFAULT;
382
        } else {
383
            read_lock_bh(&sd->ptrs_lock);
384
            bp.head=sd->head;
385
            bp.tail=sd->tail;
386
            bp.eof=sd->eof_flag;
387
            read_unlock_bh(&sd->ptrs_lock);
388
            res2 = __copy_to_user(res,&bp,sizeof(bp));
389
            if(res2)
390
                return -EFAULT;
391
            if (sd->err_flag)
392
                return -EIO; /* In this case user must him/herself
393
 calculate the number of available bytes */
394
            else
395
                return (bp.head-bp.tail) & MY_BUF_LEN_MASK;
396
            /* Return the number of available bytes */
397
        }
398 15 wzab
    }
399 49 wzab
    case L3_V1_IOC_WRITEPTRS:
400
        /* Update the read pointer
401
         * The argument contains information about the number of bytes
402
         * consumed by the application
403
         */
404 15 wzab
    {
405 49 wzab
        int rptr;
406
        int wptr;
407
        int available_data;
408
        //We need to check if the amount of consumed data is correct
409
        write_lock_bh(&sd->ptrs_lock);
410
        wptr = sd->head;
411
        rptr = sd->tail;
412
        available_data = (wptr - rptr) & MY_BUF_LEN_MASK;
413
        if (arg>available_data) {
414
            write_unlock_bh(&sd->ptrs_lock);
415
            return -EINVAL;
416
        }
417
        //If the number of consumed bytes is correct, update the number of bytes
418
        sd->tail = (rptr + arg) & MY_BUF_LEN_MASK;
419
        write_unlock_bh(&sd->ptrs_lock);
420
        return SUCCESS;
421 15 wzab
    }
422 49 wzab
    case L3_V1_IOC_STARTMAC: { //Open the slave
423
        sd->stopped_flag = 0;
424
        sd->eof_flag = 0;
425
        //We just send a request to start transmission and wait for confirmation
426
        return send_cmd(sd,FCMD_START,0,NULL,100,2);
427 15 wzab
    }
428 49 wzab
    case L3_V1_IOC_STOPMAC: { //Close the slave and reset it to stop transmission immediately
429
        return send_cmd(sd,FCMD_STOP,0,NULL,100,2);
430 18 wzab
    }
431 49 wzab
    case L3_V1_IOC_RESETMAC: { //Reset MAC so, that it stops transmission immediately
432
        return send_reset(sd);
433 18 wzab
    }
434 49 wzab
    case L3_V1_IOC_GETMAC: { //Open the slave
435
        void * source = (void *) arg;
436
        struct l3_v1_slave sl;
437
        struct net_device *dev = NULL;
438
        long res2;
439 48 wzab
#if LINUX_VERSION_CODE >= 0x50000
440 49 wzab
        if (!access_ok(source,sizeof(sl))) {
441
#else
442
        if (!access_ok(VERIFY_READ,source,sizeof(sl))) {
443 48 wzab
#endif
444 49 wzab
            return -EFAULT;
445
        }
446
        /* First deactivate the slave to avoid situation where data are modified
447
         * while slave is active */
448
        if (sd->active) sd->active = 0;
449
        //Set the numbers of stored packets to MAX
450
        write_lock_bh(&sd->pkts_rwlock);
451
        memset(&sd->pkts,0xff,sizeof(sd->pkts));
452
        sd->last_nack_pkt=0;
453
        write_unlock_bh(&sd->pkts_rwlock);
454
        //Copy arguments from the user space
455
        res2 = __copy_from_user(&sl,source,sizeof(sl));
456
        if(res2) {
457
            return -EFAULT;
458
        }
459
        write_lock_bh(&slave_table_lock);
460
        /* Copy the MAC address */
461
        memcpy(&sd->mac,sl.mac,ETH_ALEN);
462
        sd->active = 1;
463
        write_unlock_bh(&slave_table_lock);
464
        /* Find the net device */
465
        sl.devname[IFNAMSIZ-1]=0; // Protect against incorrect device name
466
        if (sd->dev) {
467
            //Maybe there was no STOPMAC call after previous STARTMAC?
468
            dev_put(sd->dev);
469
            sd->dev=NULL;
470
        }
471
        dev = dev_get_by_name(&init_net,sl.devname);
472
        if (!dev) return -ENODEV;
473
        sd->dev = dev;
474
        return SUCCESS;
475 15 wzab
    }
476 49 wzab
    case L3_V1_IOC_FREEMAC: { //Close the slave and reset it to stop transmission immediately
477
        free_mac(sd);
478
        return SUCCESS;
479 15 wzab
    }
480 49 wzab
    case L3_V1_IOC_USERCMD: { //Perform the user command
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
        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
        return result;
495 15 wzab
    }
496
}
497 49 wzab
return -EINVAL;
498
}
499 15 wzab
/*
500
  Implementation of the poll method
501
*/
502
unsigned int my_proto1_poll(struct file *filp,poll_table *wait)
503
{
504 49 wzab
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
if (data_available >= sd->rx_wakeup_thr) mask |= POLLIN |POLLRDNORM;
511
if (sd->eof_flag) {
512 18 wzab
    if(data_available) mask |= POLLIN | POLLRDNORM;
513
    else mask |= POLLHUP;
514 49 wzab
}
515 15 wzab
#ifdef FADE_DEBUG
516 49 wzab
printk(KERN_INFO "poll head: %d tail: %d data: %d prog: %d.\n",sd->head,sd->tail,data_available,sd->rx_wakeup_thr);
517 15 wzab
#endif
518 49 wzab
//Check if the error occured
519
if (sd->err_flag) mask |= POLLERR;
520
read_unlock_bh(&sd->ptrs_lock);
521
return mask;
522 15 wzab
}
523
 
524
/* Module initialization  */
525
int init_my_proto1( void )
526
{
527 49 wzab
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 15 wzab
    printk(KERN_ERR "Error creating my_proto class.\n");
533
    res=PTR_ERR(class_my_proto);
534
    goto err1;
535 49 wzab
}
536
/* Allocate the device number */
537
res=alloc_chrdev_region(&my_dev, 0, max_slaves, DEVICE_NAME);
538
if (res) {
539 15 wzab
    printk (KERN_ERR "Alocation of the device number for %s failed\n",
540 49 wzab
            DEVICE_NAME);
541 15 wzab
    goto err1;
542 49 wzab
};
543
/* Allocate the character device structure */
544
my_cdev = cdev_alloc( );
545
if (my_cdev == NULL) {
546 15 wzab
    printk (KERN_ERR "Allocation of cdev for %s failed\n",
547 49 wzab
            DEVICE_NAME);
548 15 wzab
    goto err1;
549 49 wzab
}
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 15 wzab
    printk (KERN_ERR "Registration of the device number for %s failed\n",
556 49 wzab
            DEVICE_NAME);
557 15 wzab
    goto err1;
558 49 wzab
};
559
/* Create our devices in the system */
560
for (i=0; i<max_slaves; i++) {
561 15 wzab
    device_create(class_my_proto,NULL,MKDEV(MAJOR(my_dev),MINOR(my_dev)+i),NULL,"l3_fpga%d",i);
562 49 wzab
}
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 15 wzab
    /* Perform initialization, which should be done only once, when the module
571 49 wzab
     * is loaded. Other actions may be needed, when the transmission from
572 15 wzab
     * 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 49 wzab
//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 15 wzab
 
592
module_init(init_my_proto1);
593
 
594
/* Clean-up when removing the module */
595
void cleanup_my_proto1( void )
596
{
597 49 wzab
/* Unregister the protocol sniffer */
598
if (proto_registered) dev_remove_pack(&my_proto_pt);
599
/* Free the slave table */
600
if (slave_table) {
601 15 wzab
    int i;
602 49 wzab
    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 15 wzab
    }
615
    kfree(slave_table);
616
    slave_table=NULL;
617 49 wzab
}
618
/* Remove device from the class */
619
if (my_dev && class_my_proto) {
620 15 wzab
    int i;
621 49 wzab
    for (i=0; i<max_slaves; i++) {
622
        device_destroy(class_my_proto,MKDEV(MAJOR(my_dev),MINOR(my_dev)+i));
623 15 wzab
    }
624 49 wzab
}
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 15 wzab
    class_destroy(class_my_proto);
633
    class_my_proto=NULL;
634 49 wzab
}
635 15 wzab
 
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 49 wzab
                    struct net_device * orig_dev)
649 15 wzab
{
650 49 wzab
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
uint32_t pkt_pos, needed_space, buf_free;
664
//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 15 wzab
#ifdef FADE_DEBUG
669 49 wzab
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 15 wzab
#endif
673 49 wzab
read_lock_bh(&slave_table_lock);
674
for (ns=0; ns<max_slaves; ns++) {
675 15 wzab
#ifdef FADE_DEBUG
676
    printk("slv: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x  act: %d\n",
677 49 wzab
           (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 15 wzab
#endif
681
    if (
682 49 wzab
        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 15 wzab
    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 49 wzab
        goto error;
702 15 wzab
    //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 49 wzab
}
713
sd = &slave_table[ns]; //To speed up access to the data describing state of the slave
714 15 wzab
#ifdef FADE_DEBUG
715 49 wzab
printk(KERN_INFO " Received packet!\n");
716 15 wzab
#endif
717 49 wzab
//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
if (unlikely(get_be_u16(&tmp_buf[0]) != MY_PROTO_VER)) goto wrong_pkt_type_error;
724
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 49 wzab
        //We are waiting for response
729
        printk(KERN_INFO "we were waiting for command response packet");
730
        if ((get_be_u16(&tmp_buf[6]) == sd->cmd_code) &&
731
            (get_be_u16(&tmp_buf[8]) == sd->cmd_seq)) {
732
            //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 15 wzab
    }
741
    kfree_skb(skb);
742
    return NET_RX_SUCCESS;
743 49 wzab
}
744
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 49 wzab
}
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 15 wzab
    //We are waiting for response
756 16 wzab
    if ((get_be_u16(&tmp_buf[14]) == sd->cmd_code) &&
757 49 wzab
        (get_be_u16(&tmp_buf[16]) == sd->cmd_seq)) {
758
        //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 15 wzab
    }
765 49 wzab
}
766
packet_number = get_be_u32(&tmp_buf[6]);
767 15 wzab
#ifdef FADE_DEBUG
768 49 wzab
printk(KERN_INFO "pkt=%d\n",(int)packet_number);
769 15 wzab
#endif
770 49 wzab
/* 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
//Check if this packet was received before
776
is_duplicate=(sd->pkts[packet_number & PKTS_IN_WINDOW_MASK] == packet_number) ? 1 : 0;
777
read_unlock_bh(&sd->pkts_rwlock);
778
if (unlikely((pkt_dist<0) || (pkt_dist>=PKTS_IN_WINDOW))) {
779 18 wzab
    //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 49 wzab
        // This is a packet which was already confirmed, but probably ACK was lost
783 15 wzab
#ifdef FADE_DEBUG
784 49 wzab
        printk(KERN_INFO "Packet already confirmed: pkt=%d expect=%d last=%d\n",packet_number, sd->pkts[packet_number], sd->last_nack_pkt);
785 15 wzab
#endif
786 49 wzab
        ack_packet = 1;
787
        goto confirm;
788 15 wzab
    } else {
789 49 wzab
        /* 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
        goto error2;
793 15 wzab
    }
794 49 wzab
}
795
//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 18 wzab
    //Packet already confirmed, probably the ACK was lost, so simply generate the ACK
800
    ack_packet = 1;
801
    goto confirm;
802 49 wzab
}
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 18 wzab
#ifdef FADE_DEBUG
812 49 wzab
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 18 wzab
#endif
815 49 wzab
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 18 wzab
    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 49 wzab
}
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 18 wzab
#ifdef FADE_DEBUG
826 49 wzab
printk(KERN_INFO " skb_copy_bits: %d", res);
827 18 wzab
#endif
828 49 wzab
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 18 wzab
    //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 49 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 18 wzab
    /* If our packet was the last, which prevented shifting of the head pointer,
848
     * we can try now to move the head pointer.
849 49 wzab
     * We browse the pkts table, looking for the first packet with incorrect number
850 18 wzab
     * 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 49 wzab
        if (sd->pkts[(sd->last_nack_pkt + count) & PKTS_IN_WINDOW_MASK] != chk_packet_num) break; //Packet not confirmed
856
        chk_packet_num++;
857 18 wzab
    }
858
    sd->last_nack_pkt += count;
859
    write_unlock_bh(&sd->pkts_rwlock);
860
    /* Now we can move the head position */
861 49 wzab
    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 18 wzab
    } else {
870 49 wzab
        //Flushed packet, set head right after the end of the packet
871
        write_lock_bh(&sd->ptrs_lock);
872
        sd->head = ((sd->last_nack_pkt-1)*USER_LEN+8*sd->last_pkt_len) & MY_BUF_LEN_MASK;
873
        //We have consumed the last, "flushed" buffer, so now we can set the eof flag
874
        sd-> eof_flag = 1;
875
        //printk(KERN_ALERT "set eof flag!");
876
        //And we wake up the reading process
877
        wake_up_interruptible(&read_queue);
878 18 wzab
    } //if - stopped_flag
879
    write_unlock_bh(&sd->ptrs_lock);
880 49 wzab
} else { // if - last_nack_pkt
881 18 wzab
    write_unlock_bh(&sd->pkts_rwlock);
882 49 wzab
}
883
confirm:
884
//Send the confirmation if required
885
if (likely(ack_packet)) {
886 15 wzab
    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 49 wzab
        goto error;
895 15 wzab
    //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 49 wzab
           newskb->network_header,newskb->tail, sd->tail, sd->head) ;
907 15 wzab
#endif
908
    dev_queue_xmit(newskb);
909 49 wzab
}
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 15 wzab
    write_lock_bh(&sd->flags_lock);
917
    sd->err_flag |= FADE_ERR_INCORRECT_PACKET_TYPE;
918
    write_unlock_bh(&sd->flags_lock);
919 49 wzab
} else {
920 15 wzab
    printk(KERN_ERR "FADE: wrong_pkt_type_error called with null sd");
921
}
922 49 wzab
error:
923
if (newskb) kfree_skb(newskb);
924
error2:
925
if (skb) kfree_skb(skb);
926
return NET_RX_DROP;
927
}
928 15 wzab
 
929
/*
930
  Implementation of the "device open" function
931
*/
932
static int my_proto1_open(struct inode *inode,
933 49 wzab
                      struct file *file)
934 15 wzab
{
935 49 wzab
int i;
936
slave_data * sd = NULL;
937
unsigned long flags;
938
i=iminor(inode)-MINOR(my_dev);
939
if (i >= max_slaves) {
940 15 wzab
    printk(KERN_WARNING "Trying to access %s slave with too high minor number: %d\n",
941 49 wzab
           DEVICE_NAME, i);
942 15 wzab
    return -ENODEV;
943 49 wzab
}
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 49 wzab
//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
sd->eof_flag = 0;
960
sd->stopped_flag = 0;
961
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 15 wzab
 
971
 
972
static int my_proto1_release(struct inode *inode,
973 49 wzab
                         struct file *file)
974 15 wzab
{
975 49 wzab
slave_data * sd = file->private_data;
976
//#ifdef FADE_DEBUG
977
printk (KERN_INFO "device_release(%p,%p)\n", inode, file);
978
//#endif
979
//Release resources associated with servicing of the particular device
980
if (sd) {
981 15 wzab
    if (sd->is_open) {
982 49 wzab
        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
        printk (KERN_INFO "freed MAC\n");
985
        free_mac(sd); //It also sets sd->active to 0!
986
        if (sd->buffer) {
987
            printk (KERN_INFO "freed buffer\n");
988
            vfree(sd->buffer);
989
            sd->buffer = NULL;
990
        }
991 15 wzab
    }
992
}
993 49 wzab
return SUCCESS;
994
}
995 15 wzab
 
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 49 wzab
my_proto1_vma_open,
1005
my_proto1_vma_close,
1006 15 wzab
};
1007
 
1008
/*
1009
  mmap method implementation
1010
*/
1011
int my_proto1_mmap(struct file *filp,
1012 49 wzab
               struct vm_area_struct *vma)
1013 15 wzab
{
1014 49 wzab
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 15 wzab
    return -EINVAL;
1019 49 wzab
remap_vmalloc_range(vma,sd->buffer, 0);
1020
vma->vm_ops = &my_proto1_vm_ops;
1021
my_proto1_vma_open(vma); //No open(vma) was called, we have called it ourselves
1022
return 0;
1023 15 wzab
}
1024
 

powered by: WebSVN 2.1.0

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