reader: Use switch statement in work function
authorReto Buerki <reet@codelabs.ch>
Fri, 22 May 2015 12:04:11 +0000 (14:04 +0200)
committerReto Buerki <reet@codelabs.ch>
Thu, 11 Jun 2015 07:11:37 +0000 (09:11 +0200)
reader.c

index b970ff4..3e79c2c 100644 (file)
--- a/reader.c
+++ b/reader.c
@@ -78,7 +78,6 @@ static int get_skb(struct sk_buff **skb, struct dev_info *dev_info)
 }
 
 /**
- * @ingroup reader
  * @brief Reader work queue function
  *
  * This work queue function will query the memory region for new data.
@@ -106,22 +105,18 @@ static void muennet_reader_work(struct work_struct *work)
                struct iphdr *ipv4_hdr;
                struct ipv6hdr *ipv6_hdr;
 
-               /*
-                * fetch an skb, either a new one or the previous one if
-                * still available. re-schedule if no memory is
-                * available
-                */
                if (get_skb(&skb, dev_info)) {
                        netdev_warn(dev_info->dev,
                                    "Failed to allocate skb\n");
-                       goto schedule;
+                       break;
                }
 
                result = muen_channel_read(dev_info->channel_in,
                                           &dev_info->reader,
                                           skb->data);
 
-               if (result == MUCHANNEL_EPOCH_CHANGED) {
+               switch (result) {
+               case MUCHANNEL_EPOCH_CHANGED:
                        /* TODO: Check protocol */
                        dev_info->reader_element_size = dev_info->reader.size;
 
@@ -129,88 +124,80 @@ static void muennet_reader_work(struct work_struct *work)
                                netdev_err(dev_info->dev,
                                           "Element size to big %zu\n",
                                           dev_info->reader_element_size);
-                               result = MUCHANNEL_INCOMPATIBLE_INTERFACE;
                                dev_info->reader_element_size = 0;
                                goto schedule;
                        } else {
                                consume_skb(skb);
                                skb = NULL;
-
-                               if (get_skb(&skb, dev_info)) {
-                                       netdev_warn(dev_info->dev,
-                                                   "Failed to allocate skb after consume\n");
-                                       goto schedule;
-                               }
                        }
-               }
+                       break;
 
-               /* check if data is present */
-               if (result == MUCHANNEL_NO_DATA ||
-                               result == MUCHANNEL_INACTIVE)
-                       goto schedule;
-
-               /* check if overrun by writer */
-               if (result == MUCHANNEL_OVERRUN_DETECTED) {
-                       netdev_info(dev_info->dev,
-                                   "Reader overrun detected\n");
+               case MUCHANNEL_OVERRUN_DETECTED:
                        dev_info->stats.rx_errors++;
                        dev_info->stats.rx_over_errors++;
-                       goto schedule;
-               }
+                       dev_kfree_skb(skb);
+                       break;
+
+               case MUCHANNEL_SUCCESS:
+                       /* check if net_hdr flag is given */
+                       if (dev_info->flags & MUENNET_HDR) {
+                               struct net_hdr *hdr =
+                                       (struct net_hdr *)skb->data;
+
+                               skb->mark = hdr->mark;
+                               skb_reserve(skb, sizeof(struct net_hdr));
+                               switch (hdr->protocol) {
+                               case IPPROTO_IPIP:
+                                       protocol = htons(ETH_P_IP);
+                                       break;
+                               case IPPROTO_IPV6:
+                                       protocol = htons(ETH_P_IPV6);
+                                       break;
+                               }
+                       }
 
-               /* check if net_hdr flag is given */
-               if (dev_info->flags & MUENNET_HDR) {
-                       struct net_hdr *hdr = (struct net_hdr *)skb->data;
-
-                       skb->mark = hdr->mark;
-                       skb_reserve(skb, sizeof(struct net_hdr));
-                       switch (hdr->protocol) {
-                       case IPPROTO_IPIP:
-                               protocol = htons(ETH_P_IP);
-                               break;
-                       case IPPROTO_IPV6:
-                               protocol = htons(ETH_P_IPV6);
-                               break;
+                       /* read the data to determine the protocol */
+                       ipv4_hdr = (void *)skb->data;
+                       ipv6_hdr = (void *)skb->data;
+
+                       /* determine the payload length */
+                       if (protocol == htons(ETH_P_IP))
+                               len = be16_to_cpu(ipv4_hdr->tot_len);
+                       else if (protocol == htons(ETH_P_IPV6))
+                               len = be16_to_cpu(ipv6_hdr->payload_len) + 40;
+                       else
+                               len = dev_info->reader_element_size;
+
+                       if (len > dev_info->reader_element_size ||
+                                       len > skb_tailroom(skb)) {
+                               netdev_warn(dev_info->dev,
+                                           "Invalid length: %u\n",
+                                           (unsigned int)len);
+                               dev_info->stats.rx_errors++;
+                               dev_info->stats.rx_frame_errors++;
+                               goto schedule;
                        }
-               }
 
-               /* read the data to determine the protocol */
-               ipv4_hdr = (void *)skb->data;
-               ipv6_hdr = (void *)skb->data;
+                       /*
+                        * now the skb is ready to be processed, but correct
+                        * some data first
+                        */
+                       skb->dev = dev_info->dev;
+                       skb_put(skb, len);
+                       skb->protocol = protocol;
 
-               /* determine the payload length */
-               if (protocol == htons(ETH_P_IP))
-                       len = be16_to_cpu(ipv4_hdr->tot_len);
-               else if (protocol == htons(ETH_P_IPV6))
-                       len = be16_to_cpu(ipv6_hdr->payload_len) + 40;
-               else
-                       len = dev_info->reader_element_size;
+                       /* process and update stats */
+                       netif_rx_ni(skb);
+                       dev_info->stats.rx_packets++;
+                       dev_info->stats.rx_bytes += skb->len;
 
-               if (len > dev_info->reader_element_size ||
-                               len > skb_tailroom(skb)) {
-                       netdev_warn(dev_info->dev,
-                                   "Invalid length: %u\n",
-                                   (unsigned int)len);
-                       dev_info->stats.rx_errors++;
-                       dev_info->stats.rx_frame_errors++;
+                       /* now mark the skb as processed */
+                       skb = NULL;
+                       break;
+
+               default:
                        goto schedule;
                }
-
-               /*
-                * now the skb is ready to be processed, but correct
-                * some data first
-                */
-               skb->dev = dev_info->dev;
-               skb_put(skb, len);
-               skb->protocol = protocol;
-
-               /* process and update stats */
-               netif_rx_ni(skb);
-               dev_info->stats.rx_packets++;
-               dev_info->stats.rx_bytes += skb->len;
-
-               /* now mark the skb as processed */
-               skb = NULL;
        }
 
 schedule: