changeset 90:4968acb39c7b

Finalize work on minimal TX
author Louis Opter <louis@lse.epitech.net>
date Mon, 15 Oct 2012 06:17:32 +0200
parents a9b47a2f8b98
children 9f06d7fb2542
files e1000_implement_the_frame_transmission_chunk.patch
diffstat 1 files changed, 170 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/e1000_implement_the_frame_transmission_chunk.patch	Thu Oct 04 19:33:43 2012 +0200
+++ b/e1000_implement_the_frame_transmission_chunk.patch	Mon Oct 15 06:17:32 2012 +0200
@@ -1,6 +1,28 @@
 # HG changeset patch
 # Parent 87ba2a19a59fb7be346ad40a57439b6b752b152e
-rathaxes: start to queue up packets in the TX ring on the e1000 sample
+rathaxes: add the transmission code for very simple packets in the e1000 sample
+
+Very simple packets are those which don't need to be fragmented nor checksummed.
+
+The transmission code is defined in different chunks/methods of the TxRing type.
+An e1000::xmit method template has been added to call the different methods on
+the TxRing object in the e1000::Context object. The interrupt handler has been
+reworked to handle transmission interrupts and cleanup the TxRing accordingly.
+
+In parallel to the transmission code, the Socket::SKBuff type is now a real
+Rathaxes type with its own debug and DMA operations methods.
+
+Also, sorry, this changeset is mixed with other changes:
+
+- Small improvements everywhere now that the compiler uses CNorm unstrict;
+- Add the Device::AbstractDevice type; this Rathaxes represents the generic type
+  used by the kernel to represent a device;
+- Add the Socket::AbstractSKBuff type too to represent the SKBuff type used by
+  the kernel;
+- Likewise the Ethernet::AbstractDevice type represents the type used by the
+  kernel for Ethernet devices;
+- Socket::SKBuff is now a real Rathaxes type which aggregates a KernelSKBuff
+  object.
 
 diff --git a/rathaxes/samples/e1000/CMakeLists.txt b/rathaxes/samples/e1000/CMakeLists.txt
 --- a/rathaxes/samples/e1000/CMakeLists.txt
@@ -38,13 +60,13 @@
 @@ -0,0 +1,25 @@
 +with Device, LKM
 +{
-+    template type   Device::Device()
++    template type   Device::AbstractDevice()
 +    {
 +        chunk   LKM::includes()
 +        {
 +            #include <linux/device.h>
 +
-+            static const ${Device::Device}  force_rtx_device_decl;
++            static const ${Device::AbstractDevice}  force_rtx_device_decl;
 +        }
 +
 +        chunk   decl()
@@ -68,7 +90,7 @@
 @@ -0,0 +1,9 @@
 +interface Device : LKM
 +{
-+    provided type   Device
++    provided type   AbstractDevice
 +    {
 +        chunk       LKM::includes();
 +        method      decl();
@@ -188,7 +210,7 @@
       */
      template type   e1000::TxRing()
      {
-@@ -148,11 +151,88 @@
+@@ -148,11 +151,112 @@
              struct rtx_e1000_tx_ring
              {
                  unsigned int                    size;
@@ -198,13 +220,14 @@
 +                struct rtx_e1000_tx_descriptor  *base; /* rename to descs */
 +                dma_addr_t                      dma_base;
 +                ${Socket::SKBuff}               skbuffs[${config.tx_ring_size}];
-+                unsigned int                    head;
-+                unsigned int                    tail;
++                unsigned short                  head;
++                unsigned short                  tail;
              };
          }
  
 +        chunk   LKM::prototypes()
 +        {
++            static void         rtx_e1000_tx_ring_clean(struct rtx_e1000_tx_ring *);
 +            static unsigned int rtx_e1000_tx_ring_descriptors_remaining(struct rtx_e1000_tx_ring *);
 +            static int          rtx_e1000_tx_ring_tso_cksum_offload(struct rtx_e1000_tx_ring *, struct rtx_socket_skbuff *);
 +            static void         rtx_e1000_tx_ring_put(struct rtx_e1000_tx_ring *, struct rtx_socket_skbuff *);
@@ -213,6 +236,22 @@
 +
 +        chunk   LKM::code()
 +        {
++            static void         rtx_e1000_tx_ring_clean(struct rtx_e1000_tx_ring *self)
++            {
++                ${e1000::TxDescriptor}  *tx_desc;
++                bool                    done;
++
++                for (; self->head != self->tail; self->head++)
++                {
++                    tx_desc = &self->base[self->head];
++                    done = tx_desc->upper.fields.status & E1000_TXD_STAT_DD;
++                    if (!done)
++                        break ;
++                }
++
++                pr_info("%s: tx_ring_clean: moving head to %d/%d", ${config.name}, self->head, ${config.tx_ring_size});
++            }
++
 +            static unsigned int rtx_e1000_tx_ring_descriptors_remaining(struct rtx_e1000_tx_ring *self)
 +            {
 +                if (self->tail == self->head) /* ring is empty */
@@ -244,19 +283,26 @@
 +                tx_desc->lower.data = cpu_to_le32(
 +                        E1000_TXD_CMD_EOP  |
 +                        E1000_TXD_CMD_IFCS |
++                        E1000_TXD_CMD_RS   |
 +                        skb_headlen(skb->skbuff));
 +                tx_desc->upper.data = 0;
 +                tx_desc->buff_addr = cpu_to_le64(skb->dma_handle);
 +                memcpy(&self->skbuffs[self->tail], skb, sizeof(*skb));
-+                self->tail = (self->tail + 1) % 256 /* XXX: ${config.tx_ring_size} */;
++                self->tail = (self->tail + 1) % ${config.tx_ring_size};
 +            }
 +
 +            static void         rtx_e1000_tx_ring_start_xmit(struct rtx_e1000_tx_ring *self, const struct rtx_e1000_ctx *hw_ctx)
 +            {
++                pr_info("%s: start_xmit: moving tail to %d/%d", ${config.name}, self->tail, ${config.tx_ring_size});
 +                rtx_e1000_register_write32(hw_ctx, E1000_TDT, self->tail);
 +            }
 +        }
 +
++        chunk   clean()
++        {
++            rtx_e1000_tx_ring_clean(${self});
++        }
++
 +        chunk   descriptors_remaining()
 +        {
 +            rtx_e1000_tx_ring_descriptors_remaining(${self});
@@ -279,7 +325,7 @@
          chunk   ::init()
          {
          }
-@@ -334,6 +414,45 @@
+@@ -334,6 +438,45 @@
          }
      }
  
@@ -325,7 +371,7 @@
      template sequence   e1000::create_device()
      {
          chunk Ethernet::create_device(PCI::Device pdev, Ethernet::Device rtx_ether_ctx)
-@@ -376,8 +495,7 @@
+@@ -376,8 +519,7 @@
              udelay(10);
  
              /* Now we can load its mac address (thanks minix code) */
@@ -335,7 +381,7 @@
              {
                  rtx_e1000_register_write32(&${rtx_ether_ctx}->hw_ctx, E1000_EEPROM_READ, (i << 8) | 1);
  
-@@ -420,6 +538,7 @@
+@@ -420,6 +562,7 @@
          }
      }
  
@@ -343,7 +389,7 @@
      template sequence   e1000::print_status(Ethernet::Device ctx)
      {
          chunk   LKM::prototypes()
-@@ -466,17 +585,19 @@
+@@ -466,17 +609,19 @@
       * ${e1000.init(E1000_STATUS); // didn't work, so we used the next line
       * reg_status = E1000_STATUS;
       * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, reg_status)};
@@ -365,7 +411,7 @@
              {
                  return ioread32(ctx->ioaddr + reg_offset);
              }
-@@ -492,12 +613,12 @@
+@@ -492,12 +637,12 @@
      {
          chunk   LKM::prototypes()
          {
@@ -380,7 +426,7 @@
              {
                  iowrite32(value, ctx->ioaddr + reg_offset);
              }
-@@ -513,12 +634,12 @@
+@@ -513,12 +658,12 @@
      {
          chunk   LKM::prototypes()
          {
@@ -395,7 +441,7 @@
              {
                  iowrite32(rtx_e1000_register_read32(ctx, reg_offset) | value, ctx->ioaddr + reg_offset);
              }
-@@ -534,12 +655,12 @@
+@@ -534,12 +679,12 @@
      {
          chunk   LKM::prototypes()
          {
@@ -410,7 +456,7 @@
              {
                  iowrite32(rtx_e1000_register_read32(ctx, reg_offset) & ~value, ctx->ioaddr + reg_offset);
              }
-@@ -626,12 +747,18 @@
+@@ -626,12 +771,18 @@
          }
      }
  
@@ -431,7 +477,7 @@
              /*
               * This part is documented in the Intel Gigabit Ethernet Controller
               * Software Developper manual. (You can find it in the doc/hardware
-@@ -663,6 +790,8 @@
+@@ -663,6 +814,8 @@
               *   E1000_CRCERRS to E1000_TSCTFC.
               */
  
@@ -440,7 +486,7 @@
              rtx_e1000_register_set32(hw_ctx, E1000_CTRL,
                                       E1000_CMD_ASDE |
                                       E1000_CMD_SLU);
-@@ -676,7 +805,6 @@
+@@ -676,7 +829,6 @@
              rtx_e1000_register_write32(hw_ctx, E1000_FCAL, 0);
              rtx_e1000_register_write32(hw_ctx, E1000_FCT, 0);
              rtx_e1000_register_write32(hw_ctx, E1000_FCTTV, 0);
@@ -448,7 +494,7 @@
              for (i = 0; i != 64; ++i)
                  rtx_e1000_register_write32(hw_ctx, E1000_CRCERRS + i * 4, 0);
              
-@@ -719,7 +847,6 @@
+@@ -719,7 +871,6 @@
  
              /* 2. Initialize the MTA */
  
@@ -456,7 +502,7 @@
              for (i = 0; i != 128; ++i)
                  rtx_e1000_register_write32(hw_ctx, E1000_MTA + i * 4, 0);
  
-@@ -733,7 +860,7 @@
+@@ -733,7 +884,7 @@
              hw_ctx->rx_ring.base = dma_alloc_coherent(
                      &${ctx}->pci_dev->dev,
                      hw_ctx->rx_ring.size,
@@ -465,7 +511,7 @@
                      GFP_KERNEL);
              if (!hw_ctx->rx_ring.base)
              {
-@@ -747,41 +874,37 @@
+@@ -747,41 +898,37 @@
               * Allocate the skbuffs, map them for DMA, and write their address
               * in the corresponding descriptor.
               */
@@ -518,7 +564,7 @@
              rtx_e1000_register_write32(hw_ctx, E1000_RDLEN, hw_ctx->rx_ring.size);
  
              /* 6. Setup RDH/RDT */
-@@ -820,7 +943,7 @@
+@@ -820,7 +967,7 @@
              hw_ctx->tx_ring.base = dma_alloc_coherent(
                      &${ctx}->pci_dev->dev,
                      hw_ctx->tx_ring.size,
@@ -527,7 +573,7 @@
                      GFP_KERNEL);
              if (!hw_ctx->rx_ring.base)
              {
-@@ -831,13 +954,15 @@
+@@ -831,16 +978,18 @@
              ${Log::info("setup_device: tx descriptors allocated")};
  
              /* 2. Save the emplacement and the size of the ring in TDBA/TDLEN */
@@ -544,8 +590,12 @@
 +            hw_ctx->tx_ring.tail = 0;
  
              /* 4. Set TCTL.PSP and enable the transmitter */
-             rtx_e1000_register_set32(hw_ctx, E1000_TCTL, E1000_TCTL_PSP|E1000_TCTL_PSP);
-@@ -860,15 +985,15 @@
+-            rtx_e1000_register_set32(hw_ctx, E1000_TCTL, E1000_TCTL_PSP|E1000_TCTL_PSP);
++            rtx_e1000_register_set32(hw_ctx, E1000_TCTL, E1000_TCTL_PSP|E1000_TCTL_EN);
+ 
+             ${Log::info("transmit registers configured and transmitter enabled")};
+ 
+@@ -860,15 +1009,15 @@
              {
                  dma_unmap_single(
                          &${ctx}->pci_dev->dev,
@@ -564,7 +614,7 @@
          err_rx_ring_alloc:
              return -ENOMEM;
  
-@@ -876,12 +1001,15 @@
+@@ -876,12 +1025,15 @@
          }
      }
  
@@ -582,7 +632,7 @@
              ${e1000::Context} *hw_ctx;
              hw_ctx = &${ctx}->hw_ctx;
  
-@@ -890,18 +1018,17 @@
+@@ -890,18 +1042,17 @@
               * - Unmap and free the skbuffs;
               * - Free the descriptors array.
               */
@@ -605,7 +655,7 @@
              ${Log::info("free_rx_tx: rx ring free'ed")};
  
              /*
-@@ -909,7 +1036,7 @@
+@@ -909,7 +1060,7 @@
               * - Free the descriptors array.
               */
              dma_free_coherent(&${ctx}->pci_dev->dev, hw_ctx->tx_ring.size,
@@ -614,7 +664,44 @@
              ${Log::info("free_rx_tx: tx ring free'ed")};
          }
      }
-@@ -930,4 +1057,92 @@
+@@ -918,16 +1069,123 @@
+     {
+         chunk   ::CALL()
+         {
+-            int intr;
+-
+-            intr = rtx_e1000_register_read32(&${ctx}->hw_ctx, E1000_ICR);
+-            if (intr)
++            unsigned int icr = rtx_e1000_register_read32(&${ctx}->hw_ctx, E1000_ICR);
++            pr_info("%s: interrupt received, ICR: 0x%x", ${config.name}, icr);
++            if (icr)
+             {
+-                if (intr & E1000_INTR_LSC)
+-                    ${Log::info("cable link status changed")};
++                if (icr & E1000_INTR_LSC)
++                {
++                    ${Log::info("handle_interrupt: cable link status changed, dumping card status:")};
++                    ${e1000::print_status(ctx)};
++                }
++                if (icr & (E1000_INTR_TXQE|E1000_INTR_TXDW))
++                {
++                    ${Log::info("handle_interrupt: TxRing: packet(s) sent")};
++                    /*
++                     * XXX Do a Rathaxes call (how can I bind
++                     * "&${ctx}->hw_ctx.tx_ring" to e1000::TxRing easily?)
++                     */
++                    rtx_e1000_tx_ring_clean(&${ctx}->hw_ctx.tx_ring);
++                }
++                if (icr & E1000_INTR_RXT0)
++                {
++                    ${Log::info("handle_interrupt: RxRing: packet(s) received")};
++                }
++                if (icr & E1000_INTR_RXO)
++                {
++                    ${Log::info("handle_interrupt: RxRing: overrun")};
++                }
+ 
+                 return IRQ_HANDLED;
              }
          }
      }
@@ -626,7 +713,7 @@
 +        }
 +    }
 +
-+    template sequence   e1000::xmit(Ethernet::Device ctx, Socket::KernelSKBuff kernel_skb)
++    template sequence   e1000::xmit(Ethernet::Device ctx, Socket::AbstractSKBuff kernel_skb)
 +    {
 +        chunk   ::CALL()
 +        {
@@ -638,7 +725,7 @@
 +            ${Socket::SKBuff} skb;
 +            ${e1000::Context} *hw_ctx;
 +            ${e1000::TxRing} *tx_ring;
-+            ${Device::Device} dev;
++            ${Device::AbstractDevice} dev;
 +
 +            ${local.skb.init(kernel_skb)};
 +            hw_ctx = &${ctx}->hw_ctx;
@@ -710,7 +797,7 @@
 diff --git a/rathaxes/samples/e1000/e1000.rti b/rathaxes/samples/e1000/e1000.rti
 --- a/rathaxes/samples/e1000/e1000.rti
 +++ b/rathaxes/samples/e1000/e1000.rti
-@@ -31,8 +31,15 @@
+@@ -31,8 +31,19 @@
      provided type   TxRing
      {
          chunk       LKM::includes();
@@ -719,14 +806,18 @@
          method      decl();
          method      init();
 +
++        /* Clean the ring (i.e: move the head closer to the tail): */
++        method      clean();
++        /* Return the number of clean descriptors left in the ring: */
 +        method      descriptors_remaining();
 +        method      tso_cksum_offload(Socket::SKBuff);
 +        method      put(Socket::SKBuff);
++        /* Signal the device that new dirty descriptors are on the ring: */
 +        method      start_xmit(e1000::Context);
      }
  
      /*
-@@ -51,6 +58,12 @@
+@@ -51,6 +62,12 @@
          method      decl();
      }
  
@@ -739,7 +830,7 @@
      provided sequence   create_device()
      {
          provided chunk  Ethernet::create_device(PCI::Device, Ethernet::Device);
-@@ -109,6 +122,16 @@
+@@ -109,6 +126,16 @@
          provided chunk  ::CALL();
      }
  
@@ -748,7 +839,7 @@
 +        provided chunk  ::CALL();
 +    }
 +
-+    provided sequence   xmit(Ethernet::Device, Socket::KernelSKBuff)
++    provided sequence   xmit(Ethernet::Device, Socket::AbstractSKBuff)
 +    {
 +        provided chunk  ::CALL();
 +    }
@@ -774,8 +865,8 @@
 +        {
 +            static const struct
 +            {
-+                const unsigned short    id;
-+                const char              *name;
++                unsigned short  id;
++                const char      *name;
 +            } rtx_ethernet_proto_table[] =
 +            {
 +                { ETH_P_IP,     "IPv4"  },
@@ -789,7 +880,7 @@
 +            static const char   *rtx_ethernet_protocol_id_to_str(unsigned short proto_id)
 +            {
 +                for (int i = 0;
-+                     i != sizeof(rtx_ethernet_proto_table[0]) / sizeof(rtx_ethernet_proto_table);
++                     i != sizeof(rtx_ethernet_proto_table) / sizeof(rtx_ethernet_proto_table[0]);
 +                     i++)
 +                    if (proto_id == rtx_ethernet_proto_table[i].id)
 +                        return rtx_ethernet_proto_table[i].name;
@@ -866,7 +957,7 @@
      }
  
 -    template sequence   Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb)
-+    template sequence   Ethernet::send(Ethernet::Device dev, Socket::KernelSKBuff skb)
++    template sequence   Ethernet::send(Ethernet::Device dev, Socket::AbstractSKBuff skb)
      {
          chunk LKM::prototypes()
          {
@@ -883,7 +974,7 @@
 -
 -                return 0;
 +                ${Ethernet::Device} rtx_ethernet_dev = netdev_priv(net_dev);
-+                ${cast local.kernel_skb as Socket::KernelSKBuff};
++                ${cast local.kernel_skb as Socket::AbstractSKBuff};
 +                ${pointcut ::IMPLEMENTATION(local.rtx_ethernet_dev, local.kernel_skb)};
              }
          }
@@ -954,7 +1045,7 @@
      }
  
 -    required sequence   send(Ethernet::Device dev, Socket::SKBuff skb)
-+    required sequence   send(Ethernet::Device, Socket::KernelSKBuff)
++    required sequence   send(Ethernet::Device, Socket::AbstractSKBuff)
      {
          provided chunk  LKM::prototypes();
          provided chunk  LKM::code();
@@ -972,38 +1063,53 @@
      }
  
 -    Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb)
-+    Ethernet::send(Ethernet::Device dev, Socket::KernelSKBuff skb)
++    Ethernet::send(Ethernet::Device dev, Socket::AbstractSKBuff skb)
      {
          Log::info("we have one packet to transmit!");
 +        e1000::xmit(dev, skb);
      }
  
      LKM::init()
-@@ -79,4 +80,10 @@
+@@ -66,8 +67,13 @@
+     LKM::description = "Hello World Loadable Kernel Module (LKM)";
+     LKM::license = "GPL";
+ 
++    /*
++     * See section 5.2 of the Intel manual for all the values
++     * - 0x100e is for the 82540EM-A;
++     * - 0x100f, apparently found on vmware by default, is for the 82545EM-A.
++     */
+     PCI::vendor_id = 0x8086;
+-    PCI::product_id = 0x100e; /* e100f on vmware by default it seems */
++    PCI::product_id = 0x100e;
+     PCI::set_master = true;
+ 
+     Ethernet::ifname = "rtx%d";
+@@ -79,4 +85,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).
++     * manual 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
-@@ -1,20 +1,153 @@
+@@ -1,20 +1,152 @@
 -with Socket, LKM
 +with Socket, LKM, Device, Ethernet
  {
-+    template type Socket::KernelSKBuff()
++    template type Socket::AbstractSKBuff()
 +    {
 +        chunk LKM::includes()
 +        {
 +            #include <linux/skbuff.h>
 +
-+            static const ${Socket::KernelSKBuff} force_rtx_socket_kernel_skbuff_decl;
++            static const ${Socket::AbstractSKBuff} force_rtx_socket_kernel_skbuff_decl;
 +        }
 +
 +        chunk ::decl()
@@ -1061,15 +1167,14 @@
 +                struct skb_shared_info *shinfo = skb_shinfo(self->skbuff);
 +
 +                pr_info(
-+                        "\t protocol = %#-5x (%s)\n"
++                        "\t protocol = %#-5x (%s) ip_summed = %d (%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 (%s)",
++                        "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u",
 +                        ethernet_proto, rtx_ethernet_protocol_id_to_str(ethernet_proto) /* XXX: ${local.ethernet_proto.to_str()} */,
++                        self->skbuff->ip_summed, ip_summed_values[self->skbuff->ip_summed],
 +                        self->skbuff->len, self->skbuff->data_len, skb_headlen(self->skbuff),
-+                        shinfo->nr_frags, shinfo->gso_size, shinfo->gso_segs, shinfo->gso_type,
-+                        self->skbuff->ip_summed, ip_summed_values[self->skbuff->ip_summed]
++                        shinfo->nr_frags, shinfo->gso_size, shinfo->gso_segs, shinfo->gso_type
 +                );
 +            }
 +
@@ -1120,7 +1225,7 @@
 +         * correct C variable from Ethernet::send() (so I named it as the C
 +         * variable I needed)
 +         */
-+        chunk ::init(Socket::KernelSKBuff kernel_skb)
++        chunk ::init(Socket::AbstractSKBuff kernel_skb)
 +        {
 +            ${self}.skbuff = kernel_skb;
 +            ${self}.dma_handle = 0;
@@ -1131,22 +1236,22 @@
 +            rtx_socket_skbuff_dump_infos(${self});
 +        }
 +
-+        chunk   map_to(Device::Device dev)
++        chunk   map_to(Device::AbstractDevice dev)
 +        {
 +            rtx_socket_skbuff_map(${self}, ${dev}, DMA_TO_DEVICE);
 +        }
 +
-+        chunk   map_from(Device::Device dev)
++        chunk   map_from(Device::AbstractDevice dev)
 +        {
 +            rtx_socket_skbuff_map(${self}, ${dev}, DMA_FROM_DEVICE);
 +        }
 +
-+        chunk   unmap_to_and_free(Device::Device dev)
++        chunk   unmap_to_and_free(Device::AbstractDevice dev)
 +        {
 +            rtx_socket_skbuff_unmap_and_free(${self}, ${dev}, DMA_TO_DEVICE);
 +        }
 +
-+        chunk   unmap_from_and_free(Device::Device dev)
++        chunk   unmap_from_and_free(Device::AbstractDevice dev)
 +        {
 +            rtx_socket_skbuff_unmap_and_free(${self}, ${dev}, DMA_FROM_DEVICE);
          }
@@ -1155,7 +1260,7 @@
 diff --git a/rathaxes/samples/e1000/socket.rti b/rathaxes/samples/e1000/socket.rti
 --- a/rathaxes/samples/e1000/socket.rti
 +++ b/rathaxes/samples/e1000/socket.rti
-@@ -1,8 +1,22 @@
+@@ -1,8 +1,23 @@
 -interface Socket : LKM
 +interface Socket : LKM, Device
  {
@@ -1163,7 +1268,8 @@
 -        chunk   LKM::includes();
 -        method  decl();
 -        method  init();
-+    provided type   KernelSKBuff
++    /* The SKBuff type from the kernel */
++    provided type   AbstractSKBuff
 +    {
 +        chunk       LKM::includes();
 +        method      decl();
@@ -1175,11 +1281,11 @@
 +        chunk       LKM::prototypes();
 +        chunk       LKM::code();
 +        method      decl();
-+        method      init(Socket::KernelSKBuff);
++        method      init(Socket::AbstractSKBuff);
 +        method      dump_infos();
-+        method      map_to(Device::Device);
-+        method      map_from(Device::Device);
-+        method      unmap_to_and_free(Device::Device);
-+        method      unmap_from_and_free(Device::Device);
++        method      map_to(Device::AbstractDevice);
++        method      map_from(Device::AbstractDevice);
++        method      unmap_to_and_free(Device::AbstractDevice);
++        method      unmap_from_and_free(Device::AbstractDevice);
      }
  }