]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan.c
Do not enter unnecessary subdirectories
[frescor/fna.git] / src_frescan / frescan.c
1 /*!
2  * @file frescan.c
3  *
4  * @brief the FRESCAN protocol
5  *
6  * @version 0.01
7  *
8  * @date 20-Feb-2008
9  *
10  * @author
11  *      Daniel Sangorrin
12  *
13  * @comments
14  *
15  * This file contains the implementation of the FRESCAN protocol
16  *
17  * @license
18  *
19 //----------------------------------------------------------------------
20 //  Copyright (C) 2006 - 2009 by the FRESCOR consortium:
21 //
22 //    Universidad de Cantabria,              SPAIN
23 //    University of York,                    UK
24 //    Scuola Superiore Sant'Anna,            ITALY
25 //    Kaiserslautern University,             GERMANY
26 //    Univ. Politecnica  Valencia,           SPAIN
27 //    Czech Technical University in Prague,  CZECH REPUBLIC
28 //    ENEA                                   SWEDEN
29 //    Thales Communication S.A.              FRANCE
30 //    Visual Tools S.A.                      SPAIN
31 //    Rapita Systems Ltd                     UK
32 //    Evidence                               ITALY
33 //
34 //    See http://www.frescor.org
35 //
36 //        The FRESCOR project (FP6/2005/IST/5-034026) is funded
37 //        in part by the European Union Sixth Framework Programme
38 //        The European Union is not liable of any use that may be
39 //        made of this code.
40 //
41 //
42 //  based on previous work (FSF) done in the FIRST project
43 //
44 //   Copyright (C) 2005  Mälardalen University, SWEDEN
45 //                       Scuola Superiore S.Anna, ITALY
46 //                       Universidad de Cantabria, SPAIN
47 //                       University of York, UK
48 //
49 // This file is part of FNA (Frescor Network Adaptation)
50 //
51 // FNA is free software; you can redistribute it and/or modify it
52 // under terms of the GNU General Public License as published by the
53 // Free Software Foundation; either version 2, or (at your option) any
54 // later version.  FNA is distributed in the hope that it will be
55 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
56 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
57 // General Public License for more details. You should have received a
58 // copy of the GNU General Public License along with FNA; see file
59 // COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
60 // Cambridge, MA 02139, USA.
61 //
62 // As a special exception, including FNA header files in a file,
63 // instantiating FNA generics or templates, or linking other files
64 // with FNA objects to produce an executable application, does not
65 // by itself cause the resulting executable application to be covered
66 // by the GNU General Public License. This exception does not
67 // however invalidate any other reasons why the executable file might be
68 // covered by the GNU Public License.
69 // -----------------------------------------------------------------------
70  *
71  */
72
73 #include <sys/marte_configuration_parameters.h> // PATH_MX
74 #include <fcntl.h>  // open
75 #include <unistd.h> // ioctl
76 #include <stdlib.h> // malloc
77 #include <string.h> // memcpy
78 #include <assert.h>
79
80 #include <drivers/can.h>       // can_chip_t, can_frame_t
81 #include "frescan.h"           // frescan_init_params_t, frescan_send_params_t
82 #include "frescan_queues.h"    // init, enqueue, requeue
83 #include "frescan_data.h"      // init, frescan_data
84 #include "frescan_servers.h"   // init, frame_sent
85 #include "frescan_debug.h"     // DEBUG
86 #include "frescan_id.h"        // frescan_id_set_field, frescan_id_get_field
87 #include "frescan_hw_buffer.h" // frescan_hw_buffer_update
88 #include "frescan_packets.h"
89
90 static int frescan_hook_frame_recv (const struct can_chip_t *chip,
91                                     struct can_frame_t *frame);
92
93 static int frescan_hook_frame_sent(const struct can_chip_t *chip);
94
95 static int frescan_hook_frame_aborted(const struct can_chip_t *chip);
96
97 /**
98  * frescan_init - initializes the network and the internal structures
99  *
100  * @params: the initialization parameters
101  *
102  * This function initializes the frescan network protocol.
103  *
104  * First it opens and configures the corresponding CAN chip device. For the
105  * CAN chip acceptance filter we use a dual filter configuration. The first
106  * filter is to set my local address address and the second one is to allow
107  * broadcast messages.
108  *
109  * Once the CAN chip is configured we call the initialization functions of
110  * the rest of modules of frescan.
111  *
112  */
113
114 int frescan_init(frescan_init_params_t *params)
115 {
116         int fd, ret;
117         char can_path[PATH_MX];
118         struct ioctl_filters_t ioctl_filters;
119         struct can_filter_t filters[2];
120
121         snprintf(can_path, PATH_MX, "/dev/can%u", params->net);
122
123         DEBUG(FRESCAN_INIT_ENABLE_DEBUG, "open %s\n", can_path);
124
125         fd = open (can_path, O_RDWR);
126         if (fd == -1) {
127                 FRESCAN_ERROR ("could not open /dev/can%u\n", params->net);
128                 FRESCAN_ERROR ("hint: check driver or card installation\n");
129                 return -1;
130         }
131
132         DEBUG(FRESCAN_INIT_ENABLE_DEBUG, "set acceptance filters\n");
133
134         filters[0].mask = 0xFFFFFFFF;
135         frescan_id_set_field(&filters[0].mask, FRESCAN_FIELD_DEST,0x00);
136         filters[0].code = 0;
137         frescan_id_set_field(&filters[0].code, FRESCAN_FIELD_DEST,params->node);
138
139         filters[1].mask = filters[0].mask;
140         filters[1].code = 0;
141         frescan_id_set_field(&filters[1].code,
142                              FRESCAN_FIELD_DEST,
143                              FRESCAN_BROADCAST_ADDR);
144
145         ioctl_filters.filters = filters;
146         ioctl_filters.len = 2;
147
148         ret = ioctl(fd, CAN_IOCTL_SET_FILTERS, &ioctl_filters);
149         if (ret == -1) {
150                 FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_FILTERS failed /dev/can%u\n",
151                        params->net);
152                 return -1;
153         }
154
155         DEBUG(FRESCAN_INIT_ENABLE_DEBUG, "set tx, rx, abort hooks\n");
156
157         ret = ioctl(fd, CAN_IOCTL_SET_TX_HOOK, frescan_hook_frame_sent);
158         if (ret == -1) {
159                 FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_TX_HOOK failed /dev/can%u\n",
160                        params->net);
161                 return -1;
162         }
163
164         ret = ioctl(fd, CAN_IOCTL_SET_RX_HOOK, frescan_hook_frame_recv);
165         if (ret == -1) {
166                 FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_RX_HOOK failed /dev/can%u\n",
167                        params->net);
168                 return -1;
169         }
170
171         ret = ioctl(fd, CAN_IOCTL_SET_AB_HOOK, frescan_hook_frame_aborted);
172         if (ret == -1) {
173                 FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_AB_HOOK failed /dev/can%u\n",
174                        params->net);
175                 return -1;
176         }
177
178         DEBUG(FRESCAN_INIT_ENABLE_DEBUG, "init the rest of modules\n");
179
180         ret = frescan_data_init(fd, params);
181         if (ret != 0) {
182                 FRESCAN_ERROR("could not initialize the global data\n");
183                 return -1;
184         }
185
186         ret = frescan_packets_init();
187         if (ret != 0) {
188                 FRESCAN_ERROR("could not initialize the packets pool\n");
189                 return -1;
190         }
191
192         ret = frescan_queues_init(&frescan_data[params->net].queues, params);
193         if (ret != 0) {
194                 FRESCAN_ERROR("could not initialize the queues\n");
195                 return -1;
196         }
197
198         ret = frescan_servers_init(params->net);
199         if (ret != 0) {
200                 FRESCAN_ERROR("could not initialize the servers\n");
201                 return -1;
202         }
203
204         return 0;
205 }
206
207 /**
208  * frescan_send - send a message
209  *
210  * @params: the parameters needed by the protocol to send the message
211  * @msg: the message buffer
212  * @size: the size of the message
213  *
214  * This is one of the main functions of the protocol and it provides the
215  * means to send a message through the protocol stack.
216  */
217
218 int frescan_send(const frescan_send_params_t *params,
219                  const uint8_t *msg,
220                  const size_t size)
221 {
222         int ret;
223         frescan_packet_t *packet;
224         frescan_prio_queue_t *pqueue;
225
226         DEBUG(FRESCAN_SEND_ENABLE_DEBUG || FRESCAN_FRAG_ENABLE_DEBUG,
227               "checking arguments (msg size=%d)\n", size);
228
229         if ((params == NULL) || (msg == NULL) || (size == 0)) {
230                 FRESCAN_ERROR("arguments are not ok\n");
231                 return -1;
232         }
233
234         DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "allocating a packet\n");
235
236         FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
237         packet = frescan_packets_alloc();
238         FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
239
240         if (packet == NULL) {
241                 FRESCAN_ERROR("could not allocate packet\n");
242                 return -1;
243         }
244         packet->flags = params->flags; // set the flags (to remember them)
245
246         DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "allocating a frame\n");
247
248         FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
249         packet->frame = can_framespool_alloc();
250         FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
251
252         if (packet->frame == NULL) {
253                 FRESCAN_ERROR("could not allocate frame\n");
254                 return -1;
255         }
256
257         DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "set values for the frame header\n");
258         packet->frame->is_extended_format = true;
259         packet->frame->is_rtr = false;
260
261         if (params->flags & FRESCAN_FP) {
262                 // NOTE: frag id for fp is: FRESCAN_MX_IDS, so the servers can
263                 // have IDs in the range (0 .. FRESCAN_MX_IDS-1)
264                 frescan_id_set_field(&packet->frame->id,
265                                      FRESCAN_FIELD_FRAG_ID,
266                                      (uint32_t)FRESCAN_MX_IDS);
267
268                 frescan_id_set_field(&packet->frame->id,
269                                       FRESCAN_FIELD_PRIO,
270                                       (uint32_t)params->prio);
271         } else {
272                 // NOTE: the priority is put when the packet is dequeued
273                 // and it is the priority of th server
274                 frescan_id_set_field(&packet->frame->id,
275                                      FRESCAN_FIELD_FRAG_ID,
276                                      (uint32_t)params->ss);
277         }
278
279         frescan_id_set_field(&packet->frame->id,
280                              FRESCAN_FIELD_DEST,
281                              (uint32_t)params->to);
282
283         frescan_id_set_field(&packet->frame->id,
284                              FRESCAN_FIELD_SRC,
285                              (uint32_t)frescan_data[params->net].local_node);
286
287         frescan_id_set_field(&packet->frame->id,
288                               FRESCAN_FIELD_CHAN,
289                               (uint32_t)params->channel);
290
291         DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "set the packet data bytes\n");
292         if (params->flags & FRESCAN_ASYNC) {
293                 // allocate a buffer and copy the data
294                 // NOTE: instead of this we could use a chain of frames but
295                 // i think it would be inefficient since each one can only
296                 // hold 8 user bytes and we need to write its headers.
297                 FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
298                 packet->buffer_head = (uint8_t *)malloc(size*sizeof(uint8_t)); // TODO: FREE IT!!!
299                 FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
300                 memcpy(packet->buffer_head, msg, size);
301         } else {
302                 packet->buffer_head = (uint8_t *)msg;
303         }
304
305         packet->buffer_read_pointer = packet->buffer_head;
306         packet->buffer_pending_bytes = size;
307         pqueue = frescan_data[params->net].queues.tx_fp_queue;
308
309         DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "enqueue the packet\n");
310         if (packet->flags & FRESCAN_FP) {
311                 FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
312                 ret = frescan_pqueue_enqueue(pqueue, packet, params->prio);
313                 FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
314
315                 if (ret != 0) {
316                         FRESCAN_ERROR("could not enqueue the packet\n");
317                         return -1;
318                 }
319         } else {
320                 FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
321                 ret = frescan_servers_enqueue(params->net, params->ss, packet);
322                 FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
323
324                 if (ret != 0) {
325                         FRESCAN_ERROR("could not enqueue the packet\n");
326                         return -1;
327                 }
328         }
329
330         FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
331         ret = frescan_hw_buffer_update(params->net);
332         FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
333
334         if (ret != 0) {
335                 FRESCAN_ERROR("could not update hw buffer\n");
336                 return -1;
337         }
338
339         return 0;
340 }
341
342 /**
343  * frescan_recv - receive a message
344  *
345  * @params: the parameters needed by the protocol to receive the message
346  * @msg: the message buffer
347  * @size: the size of the message buffer
348  * @recv_bytes: the number of bytes received
349  * @from: the node that sent the message
350  * @prio: the priority of the message
351  *
352  * This is one of the main functions of the protocol and it provides the
353  * means to receive a message through the protocol stack.
354  */
355
356 int frescan_recv(const frescan_recv_params_t *params,
357                  uint8_t *msg,
358                  const size_t size,
359                  size_t *recv_bytes,
360                  frescan_node_t *from,
361                  frescan_prio_t *prio)
362 {
363         int ret;
364         frescan_prio_queue_t *pqueue;
365         bool blocking;
366         frescan_packet_t *head, *packet;
367
368         if (params->flags & FRESCAN_SYNC) {
369                 DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
370                       "receive a packet in blocking mode\n");
371                 blocking = true;
372         } else {
373                 DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
374                       "receive a packet in non-blocking mode\n");
375                 blocking = false;
376         }
377
378         pqueue = frescan_data[params->net].queues.rx_channel_queues
379                                                              [params->channel];
380
381         ret = frescan_pqueue_dequeue(pqueue, &head, prio, blocking);
382         if (ret != 0) {
383                 FRESCAN_ERROR ("could not dequeue packet\n");
384                 return -1;
385         }
386
387         if (head == NULL) {
388                 if (blocking == false) {
389                         DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
390                               "blocking false, no packets\n");
391                         *recv_bytes = 0;
392                         return 0;
393                 } else {
394                         FRESCAN_ERROR ("blocking true, and packet = null\n");
395                         return -1;
396                 }
397         }
398
399         DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
400               "traverse the list of packets for this message\n");
401
402         *recv_bytes = 0;
403
404         FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
405
406         list_for_each_entry(packet, &head->msg_list, msg_list) {
407                 // TODO: memory checks, delete the packets
408                 memcpy(msg + *recv_bytes,
409                        packet->frame->data,
410                        packet->frame->dlc);
411                 *recv_bytes += packet->frame->dlc;
412
413                 *from = (frescan_node_t)frescan_id_get_field(packet->frame->id,
414                                                              FRESCAN_FIELD_SRC);
415                 DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
416                       "ID Packet, dlc: %u, frame pool pos: %u, from:%u\n",
417                       packet->frame->dlc, packet->frame->pool_pos, *from);
418
419                 ret = can_framespool_free(packet->frame);
420                 if (ret != 0) {
421                         FRESCAN_ERROR("could not free frame\n");
422                         return -1;
423                 }
424
425                 ret = frescan_packets_free(packet);
426                 if (ret != 0) {
427                         FRESCAN_ERROR("could not free packet\n");
428                         return -1;
429                 }
430         }
431
432         ret = frescan_packets_free(head);
433
434         FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
435
436         if (ret != 0) {
437                 FRESCAN_ERROR("could not free head packet\n");
438                 return -1;
439         }
440
441         DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
442               "received bytes: %u\n", *recv_bytes);
443
444         return 0;
445 }
446
447
448 /**
449  * frescan_hook_frame_recv - frame received hook
450  *
451  * This function will be called by the CAN driver's IRQ handler when a frame
452  * is received so we can store it in an appropiate queue.
453  *
454  * NOTE: in the future it could consist simply of signaling a semaphore to
455  * let a bottom half thread do the hard work.
456  */
457
458
459 static int frescan_hook_frame_recv (const struct can_chip_t *chip,
460                                     struct can_frame_t *frame)
461 {
462         int i, ret;
463         uint32_t prio, dest, src, channel, frag_id, frag_flag;
464         frescan_packet_t *packet, *head;
465         frescan_prio_queue_t *pqueue;
466         int net;
467
468         net = chip->minor;
469
470         DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG, "received a frame, net=%d\n", net);
471         DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG || FRESCAN_FRAG_ENABLE_DEBUG,
472               "%s %s, id=0x%X, dlc=%u, pool:%u\n",
473               (frame->is_extended_format) ? "Ext" : "Stnd",
474               (frame->is_rtr) ? "RTR Frame" : "DATA Frame",
475               frame->id,
476               frame->dlc,
477               frame->pool_pos);
478
479         for (i=0; i<frame->dlc; i++) {
480                 DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG,
481                       "data[%d] = 0x%X;\n", i, frame->data[i]);
482         }
483
484         prio      = frescan_id_get_field(frame->id, FRESCAN_FIELD_PRIO);
485         dest      = frescan_id_get_field(frame->id, FRESCAN_FIELD_DEST);
486         src       = frescan_id_get_field(frame->id, FRESCAN_FIELD_SRC);
487         channel   = frescan_id_get_field(frame->id, FRESCAN_FIELD_CHAN);
488         frag_id   = frescan_id_get_field(frame->id, FRESCAN_FIELD_FRAG_ID);
489         frag_flag = frescan_id_get_field(frame->id, FRESCAN_FIELD_FRAG_FLAG);
490
491         DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG || FRESCAN_FRAG_ENABLE_DEBUG,
492               "prio:%u dest:%u src:%u chan:%u id:%u flag:%u\n",
493               prio, dest, src, channel, frag_id, frag_flag);
494         DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG,
495               "enqueue the packet in ID queue\n");
496
497         packet = frescan_packets_alloc();
498         if (packet == NULL) {
499                 FRESCAN_ERROR("could not allocate packet\n");
500                 return -1;
501         }
502
503         packet->frame = frame;
504
505         if (frag_id == FRESCAN_MX_IDS) {
506                 head = frescan_data[net].id_fp_queues[src][prio];
507         } else {
508                 head = frescan_data[net].id_queues[src][frag_id];
509         }
510
511         if (head == NULL) {
512                 DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG ||
513                                 FRESCAN_FRAG_ENABLE_DEBUG,
514                 "allocate head for id=%u\n", frag_id);
515                 head = frescan_packets_alloc();
516                 if (head == NULL) {
517                         FRESCAN_ERROR("could not allocate packet\n");
518                         return -1;
519                 }
520
521                 INIT_LIST_HEAD(&head->msg_list);
522
523                 if (frag_id == FRESCAN_MX_IDS) {
524                         frescan_data[net].id_fp_queues[src][prio] = head;
525                 } else {
526                         frescan_data[net].id_queues[src][frag_id] = head;
527                 }
528         }
529
530         list_add_tail(&packet->msg_list, &head->msg_list);
531
532         if (frag_flag == false) {
533                 DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG ||
534                                 FRESCAN_FRAG_ENABLE_DEBUG,
535                 "message complete, move msg to channel\n");
536                 // TODO: select the highest priority??
537                 pqueue = frescan_data[net].queues.rx_channel_queues[channel];
538                 ret = frescan_pqueue_enqueue(pqueue, head, prio);
539                 if (ret != 0) {
540                         FRESCAN_ERROR("could not enqueue message in channel queue\n");
541                         return -1;
542                 }
543
544                 if (frag_id == FRESCAN_MX_IDS) {
545                         frescan_data[net].id_fp_queues[src][prio] = NULL;
546                 } else {
547                         frescan_data[net].id_queues[src][frag_id] = NULL;
548                 }
549
550         } else {
551                 DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG ||
552                                 FRESCAN_FRAG_ENABLE_DEBUG,
553                 "message not complete, wait for more fragments\n");
554         }
555
556         // NOTE: don't forget to free the frame and the packet when it is
557         // read by the user application
558
559         return 0;
560 };
561
562 /**
563  * frescan_hook_frame_sent - frame sent hook
564  *
565  * This function will be called by the CAN driver's IRQ handler when a frame
566  * is sent through the CAN bus so we can enqueue another one, signal a
567  * semaphore, consume sporadic server capacity...
568  */
569
570 static int frescan_hook_frame_sent(const struct can_chip_t *chip)
571 {
572         int ret;
573         frescan_packet_t *packet;
574         frescan_prio_queue_t *pqueue;
575         frescan_prio_t prio;
576         frescan_ss_t id;
577
578         packet = frescan_data[chip->minor].last_packet;
579         assert(packet != NULL);
580
581         id = frescan_id_get_field(packet->frame->id,
582                                   FRESCAN_FIELD_FRAG_ID);
583
584         DEBUG(FRESCAN_SENT_HOOK_ENABLE_DEBUG,
585               "frame sent, minor:%u flags:0x%X frag_id:0x%X\n",
586               chip->minor, packet->flags, id);
587
588         if (packet->flags & FRESCAN_SS) {
589                 DEBUG(FRESCAN_SENT_HOOK_ENABLE_DEBUG,
590                       "calling frame_sent + program repl for id:%u\n", id);
591
592                 ret = frescan_servers_frame_sent(chip->minor, id, packet);
593                 if (ret != 0) {
594                         FRESCAN_ERROR("could not let the server a frame was sent\n");
595                         return -1;
596                 }
597         }
598
599         DEBUG(FRESCAN_SENT_HOOK_ENABLE_DEBUG || FRESCAN_FRAG_ENABLE_DEBUG,
600               "last packet buffer_pending_bytes=%u\n",
601               packet->buffer_pending_bytes);
602
603         if (packet->buffer_pending_bytes > 0) {
604                 if (packet->flags & FRESCAN_FP) {
605                         prio = frescan_id_get_field(packet->frame->id,
606                                         FRESCAN_FIELD_PRIO);
607
608                         DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
609                               "requeue fp packet, prio:%u\n", prio);
610
611                         pqueue = frescan_data[chip->minor].queues.tx_fp_queue;
612                         ret = frescan_pqueue_requeue(pqueue, packet, prio);
613                         if (ret != 0) {
614                                 FRESCAN_ERROR("could not requeue the packet packet:%p flags:0x%X\n", packet, packet->flags);
615                                 return -1;
616                         }
617                 } else if (packet->flags & FRESCAN_SS) {
618                         DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
619                               "requeue server %u packet\n", id);
620                         ret = frescan_servers_requeue(chip->minor, id, packet);
621                         if (ret != 0) {
622                                 FRESCAN_ERROR("could not requeue the packet\n");
623                                 return -1;
624                         }
625                 } else {
626                         FRESCAN_ERROR("flags are not correct\n");
627                         return -1;
628                 }
629         } else {
630                 DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
631                       "all packet fragmets sent, freeing the packet\n");
632
633                 ret = can_framespool_free(packet->frame);
634                 if (ret != 0)  {
635                         FRESCAN_ERROR ("could not free the frame\n");
636                         return ret;
637                 }
638
639                 ret = frescan_packets_free(packet);
640                 if (ret != 0)  {
641                         FRESCAN_ERROR ("could not free the packet\n");
642                         return ret;
643                 }
644
645                 // TODO: signal semaphore for send_sync
646         }
647
648         frescan_data[chip->minor].last_packet = NULL;
649
650         ret = frescan_hw_buffer_update(chip->minor);
651         if (ret != 0) {
652                 FRESCAN_ERROR("could not update hw buffer\n");
653                 return -1;
654         }
655
656         return 0;
657 };
658
659 /**
660  * frescan_hook_frame_aborted - frame frame aborted hook
661  *
662  * This function will be called by the CAN driver's IRQ handler when a frame
663  * is aborted (because another frame with higher priority is waiting). We
664  * have to requeue the frame and update the buffer.
665  */
666
667 static int frescan_hook_frame_aborted(const struct can_chip_t *chip)
668 {
669         int ret;
670         frescan_packet_t *packet;
671         frescan_prio_queue_t *pqueue;
672         frescan_prio_t prio;
673         frescan_ss_t id;
674
675         packet = frescan_data[chip->minor].last_packet;
676
677         id = frescan_id_get_field(packet->frame->id,
678                                   FRESCAN_FIELD_FRAG_ID);
679
680         DEBUG(FRESCAN_SENT_HOOK_ENABLE_DEBUG,
681               "frame aborted, minor:%u flags:0x%X frag_id:0x%X\n",
682               chip->minor, packet->flags, id);
683
684         if (packet->flags & FRESCAN_FP) {
685                 prio = frescan_id_get_field(packet->frame->id,
686                                             FRESCAN_FIELD_PRIO);
687
688                 DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
689                       "requeue fp packet, prio:%u\n", prio);
690
691                 pqueue = frescan_data[chip->minor].queues.tx_fp_queue;
692                 ret = frescan_pqueue_requeue(pqueue, packet, prio);
693                 if (ret != 0) {
694                         FRESCAN_ERROR("could not requeue the packet\n");
695                         return -1;
696                 }
697         } else if (packet->flags & FRESCAN_SS) {
698                 DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
699                       "requeue server %u packet\n", id);
700
701                 ret = frescan_servers_requeue(chip->minor, id, packet);
702                 if (ret != 0) {
703                         FRESCAN_ERROR("could not requeue the packet\n");
704                         return -1;
705                 }
706         } else {
707                 FRESCAN_ERROR("flags are not correct\n");
708                 return -1;
709         }
710
711         frescan_data[chip->minor].last_packet = NULL;
712
713         ret = frescan_hw_buffer_update(chip->minor);
714         if (ret != 0) {
715                 FRESCAN_ERROR("could not update hw buffer\n");
716                 return -1;
717         }
718
719         return 0;
720 }