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