changeset 85:5dda73e7d728

Add my WIP on the actual tx
author Louis Opter <louis@lse.epitech.net>
date Fri, 14 Sep 2012 08:58:35 +0200
parents 6432998a8245
children c99e69966dd3
files e1000_implement_the_frame_transmission_chunk.patch
diffstat 1 files changed, 75 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/e1000_implement_the_frame_transmission_chunk.patch	Mon Jul 09 06:44:51 2012 +0200
+++ b/e1000_implement_the_frame_transmission_chunk.patch	Fri Sep 14 08:58:35 2012 +0200
@@ -1,5 +1,5 @@
 # HG changeset patch
-# Parent 72f11dd4265bb367278f34b23ecb5afa0f7f6fb7
+# Parent 41aa481c1ba8a54a7291ac2630f2eebc50022f33
 rathaxes: start to queue up packets in the TX ring on the e1000 sample
 
 diff --git a/maintainers/CMakeScripts/Templates/MakefileLKM.in b/maintainers/CMakeScripts/Templates/MakefileLKM.in
@@ -16,7 +16,7 @@
 diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/e1000.blt
 --- a/rathaxes/samples/e1000/e1000.blt
 +++ b/rathaxes/samples/e1000/e1000.blt
-@@ -964,4 +964,20 @@
+@@ -964,4 +964,52 @@
              }
          }
      }
@@ -25,6 +25,8 @@
 +    {
 +        chunk   ::CALL()
 +        {
++            typedef unsigned long int   dma_addr_t;
++
 +            (void)1; // Issue 10
 +            /*
 +             * Put packets on the TX ring, must return NETDEV_TX_OK or
@@ -34,6 +36,36 @@
 +                ${Log::info("xmit: skbuff details:")};
 +                ${skb.dump_infos()};
 +            }
++
++            /*
++             * The transmission is going to be several steps:
++             * - TCP Segmentation Offload & Checksum Offloading: pick a
++             *   descriptor from the tx ring and fill it as a context descriptor
++             *   to allow the card to slice into several packets according to
++             *   the MSS;
++             * - DMA Map the skbuff data as slices of 4096;
++             * - Signal the hardware that data is available via a tx desc.
++             */
++
++            if (skb_is_gso(${skb}) || ${skb}->ip_summed == CHECKSUM_PARTIAL)
++            {
++                ${Log::info("xmit: the packet needs to be fragmented and/or checksummed but this not implemented yet!")};
++                return NETDEV_TX_OK;
++            }
++
++            /* XXX ${ctx} expands into skb */
++            dma_addr_t buff_addr = dma_map_single(
++                    &${ctx}->pci_dev->dev,
++                    ${skb}->data,
++                    skb_headlen(${skb}),
++                    DMA_TO_DEVICE);
++            if (dma_mapping_error(&${ctx}->pci_dev->dev, buff_addr))
++            {
++                ${Log::info("xmit: can't DMA map a SKBuff")};
++                /* now what, should I free the skb? */
++            }
++
++            return NETDEV_TX_OK;
 +        }
 +    }
  }
@@ -90,7 +122,7 @@
 +                    if (proto_id == rtx_ethernet_proto_table[i].id)
 +                        return rtx_ethernet_proto_table[i].name;
 +
-+                return "Other";
++                return "Unknown";
 +            }
 +        }
 +
@@ -129,6 +161,22 @@
          {
              ${self} = netdev_priv(${net_dev});
              /*
+@@ -100,11 +140,11 @@
+         {
+             static int  rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev)
+             {
+-                ${cast local.dev as Ethernet::Device};
++                struct rtx_ethernet_dev* rtx_ethernet_dev = netdev_priv(dev);
++
++                ${cast local.rtx_ethernet_dev as Ethernet::Device};
+                 ${cast local.skb as Socket::SKBuff};
+-                ${pointcut ::IMPLEMENTATION(local.dev, local.skb)};
+-
+-                return 0;
++                ${pointcut ::IMPLEMENTATION(local.rtx_ethernet_dev, local.skb)};
+             }
+         }
+     }
 diff --git a/rathaxes/samples/e1000/ethernet.rti b/rathaxes/samples/e1000/ethernet.rti
 --- a/rathaxes/samples/e1000/ethernet.rti
 +++ b/rathaxes/samples/e1000/ethernet.rti
@@ -173,6 +221,17 @@
      }
  
      LKM::init()
+@@ -79,4 +80,10 @@
+      * 4096, 8192 and 16384 bytes:
+      */
+     e1000::rx_buffer_len = 2048;
++    /*
++     * 4096 bytes maximum per transmit descriptor is used on Linux and FreeBSD,
++     * 2048 on Minix and HelenOS, I can't find why. If I understand the Intel
++     * man correctly, the maximum should be 16288 (see section 3.3.3).
++     */
++     e1000::tx_max_data_per_desc = 4096;
+ }
 diff --git a/rathaxes/samples/e1000/socket.blt b/rathaxes/samples/e1000/socket.blt
 --- a/rathaxes/samples/e1000/socket.blt
 +++ b/rathaxes/samples/e1000/socket.blt
@@ -182,7 +241,7 @@
  {
      template type Socket::SKBuff()
      {
-@@ -17,6 +17,32 @@
+@@ -17,6 +17,34 @@
          {
          }
  
@@ -196,19 +255,21 @@
 +            unsigned short ethernet_proto = be16_to_cpu(${self}->protocol);
 +            ${cast local.ethernet_proto as Ethernet::ProtocolId};
 +
++            static const char * const ip_summed_values[] = {
++                "none", "unnecessary", "complete", "partial"
++            };
++
 +            pr_info(
-+                    "\tprotocol = %#-5x (%s)\n"
-+                    "\t     len = %-5u data_len = %-5u head_len = %-5u\n"
-+                    "\tnr_frags = %u\n"
-+                    "\tgso_size = %-5u gso_segs = %-5u gso_type = %-5u\n",
++                    "\t protocol = %#-5x (%s)\n"
++                    "\t      len = %-5u data_len = %-5u head_len = %-5u\n"
++                    "\t nr_frags = %u\n"
++                    "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u\n"
++                    "\tip_summed = %d\n (%s)",
 +                    ethernet_proto, "", // XXX: ${local.ethernet_proto.to_str()},
-+                    ${self}->len,
-+                    ${self}->data_len,
-+                    skb_headlen(${self}),
++                    ${self}->len, ${self}->data_len, skb_headlen(${self}),
 +                    skb_shinfo(${self})->nr_frags,
-+                    skb_shinfo(${self})->gso_size,
-+                    skb_shinfo(${self})->gso_segs,
-+                    skb_shinfo(${self})->gso_type
++                    skb_shinfo(${self})->gso_size, skb_shinfo(${self})->gso_segs, skb_shinfo(${self})->gso_type,
++                    ${self}->ip_summed, ip_summed_values[${self}->ip_summed]
 +            );
 +        }
 +