# HG changeset patch # User Louis Opter # Date 1350274715 -7200 # Node ID 9f06d7fb2542b7a4cdb80aa9d744f0738425c627 # Parent 4968acb39c7b341e1a02b7234c63b4bbba69c71c Finish patches on the tx diff -r 4968acb39c7b -r 9f06d7fb2542 e1000_implement_the_frame_transmission_chunk.patch --- a/e1000_implement_the_frame_transmission_chunk.patch Mon Oct 15 06:17:32 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1291 +0,0 @@ -# HG changeset patch -# Parent 87ba2a19a59fb7be346ad40a57439b6b752b152e -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 -+++ b/rathaxes/samples/e1000/CMakeLists.txt -@@ -1,6 +1,22 @@ --ADD_RATHAXES_SOURCES(e1000_src lkm.rtx -- RTI builtin.rti log.rti lkm.rti pci.rti socket.rti ethernet.rti e1000.rti -- BLT log.blt lkm.blt pci.blt socket.blt ethernet.blt e1000.blt) -+ADD_RATHAXES_SOURCES(e1000_src -+ lkm.rtx -+ RTI -+ builtin.rti -+ log.rti -+ lkm.rti -+ device.rti -+ pci.rti -+ socket.rti -+ ethernet.rti -+ e1000.rti -+ BLT -+ log.blt -+ lkm.blt -+ pci.blt -+ device.blt -+ socket.blt -+ ethernet.blt -+ e1000.blt) - - IF (LINUX_KBUILD_DIR) - ADD_RATHAXES_LKM(e1000 e1000_src) -diff --git a/rathaxes/samples/e1000/device.blt b/rathaxes/samples/e1000/device.blt -new file mode 100644 ---- /dev/null -+++ b/rathaxes/samples/e1000/device.blt -@@ -0,0 +1,25 @@ -+with Device, LKM -+{ -+ template type Device::AbstractDevice() -+ { -+ chunk LKM::includes() -+ { -+ #include -+ -+ static const ${Device::AbstractDevice} force_rtx_device_decl; -+ } -+ -+ chunk decl() -+ { -+ typedef struct device *rtx_device_p; -+ } -+ -+ chunk init() -+ { -+ } -+ -+ map -+ { -+ } -+ } -+} -diff --git a/rathaxes/samples/e1000/device.rti b/rathaxes/samples/e1000/device.rti -new file mode 100644 ---- /dev/null -+++ b/rathaxes/samples/e1000/device.rti -@@ -0,0 +1,9 @@ -+interface Device : LKM -+{ -+ provided type AbstractDevice -+ { -+ chunk LKM::includes(); -+ method decl(); -+ method init(); -+ } -+} -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 -@@ -11,16 +11,15 @@ - - chunk ::decl() - { -- typedef struct rtx_e1000_rx_descriptor -+ struct rtx_e1000_rx_descriptor - { -- /* actual types are in comments */ -- unsigned long int /* __le64 */ buff_addr; -- unsigned short /* __le16 */ length; -- unsigned short /* __le16 */ csum; -- unsigned char status; -- unsigned char errors; -- unsigned short /* __le16 */ special; -- } *rtx_e1000_rx_descriptor_p; -+ __le64 buff_addr; -+ __le16 length; -+ __le16 csum; -+ unsigned char status; -+ unsigned char errors; -+ __le16 special; -+ }; - } - - chunk ::init() -@@ -50,30 +49,30 @@ - - chunk ::decl() - { -- typedef struct rtx_e1000_tx_descriptor -+ struct rtx_e1000_tx_descriptor - { -- unsigned long int /* __le64 */ buff_addr; -+ __le64 buff_addr; - union - { -- unsigned int /* __le32 */ data; -+ __le32 data; - struct - { -- unsigned short /* __le16 */ length; -- unsigned char csum_offset; /* CSO */ -- unsigned char cmd; -- } fields; -- } lower; -+ __le16 length; -+ unsigned char csum_offset; /* CSO */ -+ unsigned char cmd; -+ } fields; -+ } lower; - union - { -- unsigned int /* __le32 */ data; -+ __le32 data; - struct - { -- unsigned char status; -- unsigned char csum_start; /* CSS */ -- unsigned short /* __le16 */ special; -- } fields; -- } upper; -- } *rtx_e1000_tx_descriptor_p; -+ unsigned char status; -+ unsigned char csum_start; /* CSS */ -+ __le16 special; -+ } fields; -+ } upper; -+ }; - } - - chunk ::init() -@@ -93,9 +92,8 @@ - * CNorm unstrict); - * - dma_base: (physical) address of the ring where the device can access - * the different descriptors; -- * - skbuffs: array of the skbuffs associated with each descriptor; -- * - dma_skbuffs: (physical) address of each skbuff where the device can -- * write the received packets; -+ * - skbuffs: array of the skbuffs and their dma (physical) address -+ * associated with each descriptor. - */ - template type e1000::RxRing() - { -@@ -110,9 +108,8 @@ - { - unsigned int size; - struct rtx_e1000_rx_descriptor *base; -- void* /* dma_addr_t */ dma_base; -- struct sk_buff *skbuffs[256 /* ${config.rx_ring_size} */]; -- void* /* dma_addr_t */ dma_skbuffs[256 /* ${config.rx_ring_size} */]; -+ dma_addr_t dma_base; -+ ${Socket::SKBuff} skbuffs[${config.rx_ring_size}]; - }; - } - -@@ -134,7 +131,13 @@ - * - base: address of the ring (we can't use the typedef here until we get - * CNorm unstrict); - * - dma_base: (physical) address of the ring where the device can access -- * the different descriptors. -+ * the different descriptors; -+ * - skbuffs: the skbuffs associated with each descriptor of the ring; -+ * - head: index on the head of the ring; -+ * - tail: index on the tail of the ring. -+ * -+ * Keep in mind that the head and tail fields are, obviously, not -+ * synchronized with TDT/TDH on the device. - */ - template type e1000::TxRing() - { -@@ -148,11 +151,112 @@ - struct rtx_e1000_tx_ring - { - unsigned int size; -- struct rtx_e1000_tx_descriptor *base; -- void* /* dma_addr_t */ dma_base; -+ /* XXX: can't use ${e1000::TxDescriptor} here: */ -+ struct rtx_e1000_tx_descriptor *base; /* rename to descs */ -+ dma_addr_t dma_base; -+ ${Socket::SKBuff} skbuffs[${config.tx_ring_size}]; -+ 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 *); -+ static void rtx_e1000_tx_ring_start_xmit(struct rtx_e1000_tx_ring *, const struct rtx_e1000_ctx *); -+ } -+ -+ 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 */ -+ return 256; /* XXX: ${config.tx_ring_size}; */ -+ if (self->tail > self->head) -+ /* XXX: ${config.tx_ring_size} */ -+ return 256 - (self->tail - self->head); -+ return self->head - self->tail; -+ } -+ -+ static int rtx_e1000_tx_ring_tso_cksum_offload(struct rtx_e1000_tx_ring *self, struct rtx_socket_skbuff *skb) -+ { -+ return skb_is_gso(skb->skbuff) || skb->skbuff->ip_summed == CHECKSUM_PARTIAL; -+ } -+ -+ static void rtx_e1000_tx_ring_put(struct rtx_e1000_tx_ring *self, struct rtx_socket_skbuff *skb) -+ { -+ WARN_ON(!skb); -+ -+ /* -+ * Mark it as the last buffer (EOP) and ask the card to -+ * insert the Ethernet FCS (Frame Check Sequence). -+ * -+ * XXX: it sucks to use skb_headlen() here (this part of the -+ * code shouldn't be aware of it and use something more -+ * abstract. -+ */ -+ struct rtx_e1000_tx_descriptor *tx_desc = &self->base[self->tail]; -+ 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) % ${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}); -+ } -+ -+ chunk tso_cksum_offload(Socket::SKBuff skb) -+ { -+ } -+ -+ chunk put(Socket::SKBuff skb) -+ { -+ rtx_e1000_tx_ring_put(${self}, &${skb}); -+ } -+ -+ chunk start_xmit(e1000::Context ctx) -+ { -+ rtx_e1000_tx_ring_start_xmit(${self}, ${ctx}); -+ } -+ - chunk ::init() - { - } -@@ -334,6 +438,45 @@ - } - } - -+ template type e1000::TxDescriptorFlags() -+ { -+ chunk LKM::includes() -+ { -+ static const ${e1000::TxDescriptorFlags} force_enum_rtx_e1000_tx_descriptor_flags_decl; -+ } -+ -+ chunk ::decl() -+ { -+ enum rtx_e1000_tx_descriptor_flags -+ { -+ E1000_TXD_DTYP_D = 0x00100000, /* Data Descriptor */ -+ E1000_TXD_DTYP_C = 0x00000000, /* Context Descriptor */ -+ E1000_TXD_POPTS_IXSM = 0x01, /* Insert IP checksum */ -+ E1000_TXD_POPTS_TXSM = 0x02, /* Insert TCP/UDP checksum */ -+ E1000_TXD_CMD_EOP = 0x01000000, /* End of Packet */ -+ E1000_TXD_CMD_IFCS = 0x02000000, /* Insert FCS (Ethernet CRC) */ -+ E1000_TXD_CMD_IC = 0x04000000, /* Insert Checksum */ -+ E1000_TXD_CMD_RS = 0x08000000, /* Report Status */ -+ E1000_TXD_CMD_RPS = 0x10000000, /* Report Packet Sent */ -+ E1000_TXD_CMD_DEXT = 0x20000000, /* Descriptor extension (0 = legacy) */ -+ E1000_TXD_CMD_VLE = 0x40000000, /* Add VLAN tag */ -+ E1000_TXD_CMD_IDE = 0x80000000, /* Enable Tidv register */ -+ E1000_TXD_STAT_DD = 0x00000001, /* Descriptor Done */ -+ E1000_TXD_STAT_EC = 0x00000002, /* Excess Collisions */ -+ E1000_TXD_STAT_LC = 0x00000004, /* Late Collisions */ -+ E1000_TXD_STAT_TU = 0x00000008, /* Transmit underrun */ -+ E1000_TXD_CMD_TCP = 0x01000000, /* TCP packet */ -+ E1000_TXD_CMD_IP = 0x02000000, /* IP packet */ -+ E1000_TXD_CMD_TSE = 0x04000000, /* TCP Seg enable */ -+ E1000_TXD_STAT_TC = 0x00000004, /* Tx Underrun */ -+ }; -+ } -+ -+ map -+ { -+ } -+ } -+ - template sequence e1000::create_device() - { - chunk Ethernet::create_device(PCI::Device pdev, Ethernet::Device rtx_ether_ctx) -@@ -376,8 +519,7 @@ - udelay(10); - - /* Now we can load its mac address (thanks minix code) */ -- int i = 0; -- for (i = 0 /* < this is not generated! (cnorm bug) */; i < 3; ++i) -+ for (int i = 0; i < 3; ++i) - { - rtx_e1000_register_write32(&${rtx_ether_ctx}->hw_ctx, E1000_EEPROM_READ, (i << 8) | 1); - -@@ -420,6 +562,7 @@ - } - } - -+ /* TODO: make that a method of e1000::Context */ - template sequence e1000::print_status(Ethernet::Device ctx) - { - chunk LKM::prototypes() -@@ -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)}; -+ * -+ * TODO: make them methods of e1000::Context - */ - template sequence e1000::register_read32(e1000::Context ctx, e1000::Register reg_offset) - { - chunk LKM::prototypes() - { -- static unsigned int rtx_e1000_register_read32(struct rtx_e1000_ctx *, unsigned int); -+ static unsigned int rtx_e1000_register_read32(const struct rtx_e1000_ctx *, unsigned int); - } - - chunk LKM::code() - { -- static unsigned int rtx_e1000_register_read32(struct rtx_e1000_ctx *ctx, unsigned int reg_offset) -+ static unsigned int rtx_e1000_register_read32(const struct rtx_e1000_ctx *ctx, unsigned int reg_offset) - { - return ioread32(ctx->ioaddr + reg_offset); - } -@@ -492,12 +637,12 @@ - { - chunk LKM::prototypes() - { -- static void rtx_e1000_register_write32(struct rtx_e1000_ctx *, unsigned int, unsigned int); -+ static void rtx_e1000_register_write32(const struct rtx_e1000_ctx *, unsigned int, unsigned int); - } - - chunk LKM::code() - { -- static void rtx_e1000_register_write32(struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value) -+ static void rtx_e1000_register_write32(const struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value) - { - iowrite32(value, ctx->ioaddr + reg_offset); - } -@@ -513,12 +658,12 @@ - { - chunk LKM::prototypes() - { -- static void rtx_e1000_register_set32(struct rtx_e1000_ctx *, unsigned int, unsigned int); -+ static void rtx_e1000_register_set32(const struct rtx_e1000_ctx *, unsigned int, unsigned int); - } - - chunk LKM::code() - { -- static void rtx_e1000_register_set32(struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value) -+ static void rtx_e1000_register_set32(const struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value) - { - iowrite32(rtx_e1000_register_read32(ctx, reg_offset) | value, ctx->ioaddr + reg_offset); - } -@@ -534,12 +679,12 @@ - { - chunk LKM::prototypes() - { -- static void rtx_e1000_register_unset32(struct rtx_e1000_ctx *, unsigned int, unsigned int); -+ static void rtx_e1000_register_unset32(const struct rtx_e1000_ctx *, unsigned int, unsigned int); - } - - chunk LKM::code() - { -- static void rtx_e1000_register_unset32(struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value) -+ static void rtx_e1000_register_unset32(const struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value) - { - iowrite32(rtx_e1000_register_read32(ctx, reg_offset) & ~value, ctx->ioaddr + reg_offset); - } -@@ -626,12 +771,18 @@ - } - } - -+ /* TODO: refactor -+ * -+ * Split into two method methods: -+ * - e1000::RxRing::init_rx() -+ * - e1000::TxRing::init_tx() -+ * -+ * Also it should use the new methods in Socket::SKbuff. -+ */ - template sequence set_up_device(Ethernet::Device ctx) - { - chunk ::CALL() - { -- typedef unsigned long int dma_addr_t; -- - /* - * This part is documented in the Intel Gigabit Ethernet Controller - * Software Developper manual. (You can find it in the doc/hardware -@@ -663,6 +814,8 @@ - * E1000_CRCERRS to E1000_TSCTFC. - */ - -+ int i; -+ - rtx_e1000_register_set32(hw_ctx, E1000_CTRL, - E1000_CMD_ASDE | - E1000_CMD_SLU); -@@ -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); -- int i = 0; /* CNorm workaround, the init part of for isn't generated */ - for (i = 0; i != 64; ++i) - rtx_e1000_register_write32(hw_ctx, E1000_CRCERRS + i * 4, 0); - -@@ -719,7 +871,6 @@ - - /* 2. Initialize the MTA */ - -- i = 0; /* CNorm workaround, the init part of for isn't generated */ - for (i = 0; i != 128; ++i) - rtx_e1000_register_write32(hw_ctx, E1000_MTA + i * 4, 0); - -@@ -733,7 +884,7 @@ - hw_ctx->rx_ring.base = dma_alloc_coherent( - &${ctx}->pci_dev->dev, - hw_ctx->rx_ring.size, -- (dma_addr_t *)&hw_ctx->rx_ring.dma_base, -+ &hw_ctx->rx_ring.dma_base, - GFP_KERNEL); - if (!hw_ctx->rx_ring.base) - { -@@ -747,41 +898,37 @@ - * Allocate the skbuffs, map them for DMA, and write their address - * in the corresponding descriptor. - */ -- i = 0; - for (i = 0; i != ${config.rx_ring_size}; ++i) - { -- hw_ctx->rx_ring.skbuffs[i] = netdev_alloc_skb( -+ hw_ctx->rx_ring.skbuffs[i].skbuff = netdev_alloc_skb( - ${ctx}->net_dev, - ${config.rx_buffer_len}); -- if (!hw_ctx->rx_ring.skbuffs[i]) -+ if (!hw_ctx->rx_ring.skbuffs[i].skbuff) - { - ${Log::info("cannot allocate a skbuff for the rx ring")}; - goto err_skbuffs_alloc; - } -- hw_ctx->rx_ring.dma_skbuffs[i] = (void *)dma_map_single( -+ hw_ctx->rx_ring.skbuffs[i].dma_handle = dma_map_single( - &${ctx}->pci_dev->dev, -- hw_ctx->rx_ring.skbuffs[i]->data, -+ hw_ctx->rx_ring.skbuffs[i].skbuff->data, - ${config.rx_buffer_len}, - DMA_FROM_DEVICE); -- /* -- * Either this fails because, when compiling with gcc because -- * the last argument is not of the correct type (dma_addr_t). -- * Or it fails because of the lack of CNorm Unstrict. -- */ -- if (dma_mapping_error(&${ctx}->pci_dev->dev, (dma_addr_t)hw_ctx->rx_ring.dma_skbuffs[i])) -+ int dma_error = dma_mapping_error(&${ctx}->pci_dev->dev, -+ hw_ctx->rx_ring.skbuffs[i].dma_handle); -+ if (dma_error) - { - ${Log::info("cannot dma-map a skbuff for the rx ring")}; - goto err_skbuffs_map; - } -- hw_ctx->rx_ring.base[i].buff_addr = (unsigned long int)cpu_to_le64( -- hw_ctx->rx_ring.dma_skbuffs[i]); -+ hw_ctx->rx_ring.base[i].buff_addr = cpu_to_le64( -+ hw_ctx->rx_ring.skbuffs[i].skbuff); - } - - ${Log::info("setup_device: skbuffs allocated")}; - - /* 5. Save the emplacement and the size of the ring in RDBA/RDLEN */ -- rtx_e1000_register_write32(hw_ctx, E1000_RDBAL, (dma_addr_t)hw_ctx->rx_ring.dma_base & 0xffffffff); -- rtx_e1000_register_write32(hw_ctx, E1000_RDBAH, (dma_addr_t)hw_ctx->rx_ring.dma_base >> 32); -+ rtx_e1000_register_write32(hw_ctx, E1000_RDBAL, hw_ctx->rx_ring.dma_base & 0xffffffff); -+ rtx_e1000_register_write32(hw_ctx, E1000_RDBAH, hw_ctx->rx_ring.dma_base >> 32); - rtx_e1000_register_write32(hw_ctx, E1000_RDLEN, hw_ctx->rx_ring.size); - - /* 6. Setup RDH/RDT */ -@@ -820,7 +967,7 @@ - hw_ctx->tx_ring.base = dma_alloc_coherent( - &${ctx}->pci_dev->dev, - hw_ctx->tx_ring.size, -- (dma_addr_t *)&hw_ctx->tx_ring.dma_base, -+ &hw_ctx->tx_ring.dma_base, - GFP_KERNEL); - if (!hw_ctx->rx_ring.base) - { -@@ -831,16 +978,18 @@ - ${Log::info("setup_device: tx descriptors allocated")}; - - /* 2. Save the emplacement and the size of the ring in TDBA/TDLEN */ -- rtx_e1000_register_write32(hw_ctx, E1000_TDBAL, (dma_addr_t)hw_ctx->tx_ring.dma_base & 0xffffffff); -- rtx_e1000_register_write32(hw_ctx, E1000_TDBAH, (dma_addr_t)hw_ctx->tx_ring.dma_base >> 32); -+ rtx_e1000_register_write32(hw_ctx, E1000_TDBAL, hw_ctx->tx_ring.dma_base & 0xffffffff); -+ rtx_e1000_register_write32(hw_ctx, E1000_TDBAH, hw_ctx->tx_ring.dma_base >> 32); - rtx_e1000_register_write32(hw_ctx, E1000_TDLEN, hw_ctx->tx_ring.size); - - /* 3. Setup TDH/TDT to zero: the queue is empty */ - rtx_e1000_register_write32(hw_ctx, E1000_TDH, 0); - rtx_e1000_register_write32(hw_ctx, E1000_TDT, 0); -+ hw_ctx->tx_ring.head = 0; -+ 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); -+ 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, -- (dma_addr_t)hw_ctx->rx_ring.dma_skbuffs[i], -+ hw_ctx->rx_ring.skbuffs[i].dma_handle, - ${config.rx_buffer_len}, - DMA_FROM_DEVICE); - err_skbuffs_map: -- dev_kfree_skb(hw_ctx->rx_ring.skbuffs[i]); -+ dev_kfree_skb(hw_ctx->rx_ring.skbuffs[i].skbuff); - } - - dma_free_coherent(&${ctx}->pci_dev->dev, hw_ctx->rx_ring.size, -- hw_ctx->rx_ring.base, (dma_addr_t)hw_ctx->rx_ring.dma_base); -+ hw_ctx->rx_ring.base, hw_ctx->rx_ring.dma_base); - err_rx_ring_alloc: - return -ENOMEM; - -@@ -876,12 +1025,15 @@ - } - } - -+ /* TODO: -+ * -+ * Refactor into two methods (one in RxRing and one in TxRing) and make use -+ * of the new methods in Socket::SKBuff. -+ */ - template sequence free_rx_tx(Ethernet::Device ctx) - { - chunk ::CALL() - { -- typedef unsigned long int dma_addr_t; -- - ${e1000::Context} *hw_ctx; - hw_ctx = &${ctx}->hw_ctx; - -@@ -890,18 +1042,17 @@ - * - Unmap and free the skbuffs; - * - Free the descriptors array. - */ -- int i = 0; -- for (i = 0; i != ${config.rx_ring_size}; ++i) -+ for (int i = 0; i != ${config.rx_ring_size}; ++i) - { - dma_unmap_single( - &${ctx}->pci_dev->dev, -- (dma_addr_t)hw_ctx->rx_ring.dma_skbuffs[i], -+ (dma_addr_t)hw_ctx->rx_ring.skbuffs[i].dma_handle, - ${config.rx_buffer_len}, - DMA_FROM_DEVICE); -- dev_kfree_skb(hw_ctx->rx_ring.skbuffs[i]); -+ dev_kfree_skb(hw_ctx->rx_ring.skbuffs[i].skbuff); - } - dma_free_coherent(&${ctx}->pci_dev->dev, hw_ctx->rx_ring.size, -- hw_ctx->rx_ring.base, (dma_addr_t)hw_ctx->rx_ring.dma_base); -+ hw_ctx->rx_ring.base, hw_ctx->rx_ring.dma_base); - ${Log::info("free_rx_tx: rx ring free'ed")}; - - /* -@@ -909,7 +1060,7 @@ - * - Free the descriptors array. - */ - dma_free_coherent(&${ctx}->pci_dev->dev, hw_ctx->tx_ring.size, -- hw_ctx->tx_ring.base, (dma_addr_t)hw_ctx->tx_ring.dma_base); -+ hw_ctx->tx_ring.base, hw_ctx->tx_ring.dma_base); - ${Log::info("free_rx_tx: tx ring free'ed")}; - } - } -@@ -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; - } - } - } -+ -+ template sequence e1000::_xmit_tso_cksum_offload(Ethernet::Device ctx, Socket::SKBuff skb) -+ { -+ chunk ::CALL() -+ { -+ } -+ } -+ -+ template sequence e1000::xmit(Ethernet::Device ctx, Socket::AbstractSKBuff kernel_skb) -+ { -+ chunk ::CALL() -+ { -+ /* -+ * Put packets on the TX ring, must return NETDEV_TX_OK or -+ * NETDEV_TX_BUSY. -+ */ -+ -+ ${Socket::SKBuff} skb; -+ ${e1000::Context} *hw_ctx; -+ ${e1000::TxRing} *tx_ring; -+ ${Device::AbstractDevice} dev; -+ -+ ${local.skb.init(kernel_skb)}; -+ hw_ctx = &${ctx}->hw_ctx; -+ tx_ring = &hw_ctx->tx_ring; -+ dev = &${ctx}->pci_dev->dev; -+ -+ ${Log::info("xmit: skbuff details:")}; -+ /* -+ * skb is not expand on the bound C variable (should be rtx_skbuff), -+ * which is funny because it works for the sequence template call -+ * right after. -+ */ -+ /* -+ * XXX: doesn't work (I tried to pass self explicitely too): -+ * ${local.skb.dump_infos()}; -+ */ -+ rtx_socket_skbuff_dump_infos(&skb); -+ -+ /* -+ * The transmission is going to be several steps: -+ * 1. 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; -+ * 2. DMA Map the skbuff data as slices of 4096; -+ * 3. Signal the hardware that data is available via a tx desc. -+ */ -+ -+ /* XXX: same thing wanted to use: ${local.tx_ring.descriptors_remaining()} */ -+ if (!rtx_e1000_tx_ring_descriptors_remaining(tx_ring)) -+ return NETDEV_TX_BUSY; -+ -+ /* 1. Offloading */ -+ -+ /* XXX: ${local.tx_ring.tso_cksum_offload(skb)}; */ -+ if (rtx_e1000_tx_ring_tso_cksum_offload(tx_ring, &skb)) -+ { -+ ${Log::info("xmit: the packet needs to be fragmented and/or checksummed but this not implemented yet!")}; -+ goto err_offload; -+ } -+ -+ /* 2. Map the data */ -+ -+ /* XXX: ${local.skb.map_to(local.dev)}; */ -+ if (rtx_socket_skbuff_map(&skb, dev, DMA_TO_DEVICE)) -+ { -+ ${Log::info("xmit: can't DMA map a SKbuff")}; -+ goto err_skb_map_to; -+ } -+ -+ /* 3. Update the TX Ring and signal the hardware */ -+ -+ /* XXX: ${local.tx_ring.put(skb)}; */ -+ rtx_e1000_tx_ring_put(tx_ring, &skb); -+ -+ /* XXX: ${local.tx_ring.start_xmit(hw_ctx)}; */ -+ rtx_e1000_tx_ring_start_xmit(tx_ring, hw_ctx); -+ -+ return NETDEV_TX_OK; -+ -+ err_offload: -+ err_skb_map_to: -+ /* XXX: ${local.skb.unmap_to_and_free(local.dev)}; */ -+ rtx_socket_skbuff_unmap_and_free(&skb, dev, DMA_TO_DEVICE); -+ return NETDEV_TX_OK; -+ } -+ } - } -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,19 @@ - provided type TxRing - { - chunk LKM::includes(); -+ chunk LKM::prototypes(); -+ chunk LKM::code(); - 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 +62,12 @@ - method decl(); - } - -+ provided type TxDescriptorFlags -+ { -+ chunk LKM::includes(); -+ chunk ::decl(); -+ } -+ - provided sequence create_device() - { - provided chunk Ethernet::create_device(PCI::Device, Ethernet::Device); -@@ -109,6 +126,16 @@ - provided chunk ::CALL(); - } - -+ provided sequence _xmit_tso_cksum_offload(Ethernet::Device, Socket::SKBuff) -+ { -+ provided chunk ::CALL(); -+ } -+ -+ provided sequence xmit(Ethernet::Device, Socket::AbstractSKBuff) -+ { -+ provided chunk ::CALL(); -+ } -+ - provided sequence register_read32(e1000::Context, e1000::Register) - { - provided chunk LKM::prototypes(); -diff --git a/rathaxes/samples/e1000/ethernet.blt b/rathaxes/samples/e1000/ethernet.blt ---- a/rathaxes/samples/e1000/ethernet.blt -+++ b/rathaxes/samples/e1000/ethernet.blt -@@ -1,6 +1,56 @@ - with Ethernet, PCI, LKM, Log - { -- template type Ethernet::Net() -+ template type Ethernet::ProtocolId() -+ { -+ chunk LKM::prototypes() -+ { -+ static const char *rtx_ethernet_protocol_id_to_str(unsigned short); -+ } -+ -+ chunk LKM::data() -+ { -+ static const struct -+ { -+ unsigned short id; -+ const char *name; -+ } rtx_ethernet_proto_table[] = -+ { -+ { ETH_P_IP, "IPv4" }, -+ { ETH_P_IPV6, "IPv6" }, -+ { ETH_P_ARP, "ARP" }, -+ }; -+ } -+ -+ chunk LKM::code() -+ { -+ static const char *rtx_ethernet_protocol_id_to_str(unsigned short proto_id) -+ { -+ for (int i = 0; -+ 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; -+ -+ return "Unknown"; -+ } -+ } -+ -+ chunk decl() -+ { -+ typedef unsigned short rtx_ether_protocol_id; -+ } -+ -+ chunk to_str() -+ { -+ rtx_ethernet_protocol_id_to_str(${self}); -+ } -+ -+ map -+ { -+ } -+ } -+ -+ template type Ethernet::AbstractDevice() - { - chunk LKM::includes() - { -@@ -17,11 +67,6 @@ - } - } - -- /* -- * Unlike PCI::Device, Ethernet::Device doesn't match the struct net_device -- * from Linux. Ethernet::Device is the type that we use in the private -- * field of the struct net_device. -- */ - template type Ethernet::Device() - { - chunk LKM::includes() -@@ -47,15 +92,15 @@ - struct pci_dev *pci_dev; - struct net_device *net_dev; - -- /* while waiting on issue #8 */ -- //${e1000::Context} hw_ctx; -- // In the long-term, this may disappear for a new concept allowing -- // to embbed a descriptor defined and manipulated by the front-end -+ /* -+ * In the long-term, this may disappear for a new concept allowing -+ * to embbed a descriptor defined and manipulated by the front-end -+ */ - ${pointcut Ethernet::SubContext()}; - } *rtx_ethernet_dev_p; - } - -- chunk ::init(Ethernet::Net net_dev, PCI::Device pci_dev) -+ chunk ::init(Ethernet::AbstractDevice net_dev, PCI::Device pci_dev) - { - ${self} = netdev_priv(${net_dev}); - /* -@@ -82,9 +127,8 @@ - { - static int rtx_ethernet_open(struct net_device *dev) - { -- struct rtx_ethernet_dev* rtx_ether_dev = netdev_priv(dev); -+ ${Ethernet::Device} rtx_ether_dev = netdev_priv(dev); - -- ${cast local.rtx_ether_dev as Ethernet::Device}; - ${pointcut ::IMPLEMENTATION(local.rtx_ether_dev)}; - - return 0; -@@ -92,7 +136,7 @@ - } - } - -- template sequence Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb) -+ template sequence Ethernet::send(Ethernet::Device dev, Socket::AbstractSKBuff skb) - { - chunk LKM::prototypes() - { -@@ -101,13 +145,11 @@ - - chunk LKM::code() - { -- static int rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev) -+ static int rtx_ethernet_xmit(struct sk_buff* kernel_skb, struct net_device *net_dev) - { -- ${cast local.dev as Ethernet::Device}; -- ${cast local.skb as Socket::SKBuff}; -- ${pointcut ::IMPLEMENTATION(local.dev, local.skb)}; -- -- return 0; -+ ${Ethernet::Device} rtx_ethernet_dev = netdev_priv(net_dev); -+ ${cast local.kernel_skb as Socket::AbstractSKBuff}; -+ ${pointcut ::IMPLEMENTATION(local.rtx_ethernet_dev, local.kernel_skb)}; - } - } - } -@@ -123,9 +165,8 @@ - { - static int rtx_ethernet_close(struct net_device *dev) - { -- struct rtx_ethernet_dev* rtx_ether_dev = netdev_priv(dev); -+ ${Ethernet::Device} rtx_ether_dev = netdev_priv(dev); - -- ${cast local.rtx_ether_dev as Ethernet::Device}; - ${pointcut ::IMPLEMENTATION(local.rtx_ether_dev)}; - - return 0; -@@ -148,11 +189,8 @@ - { - static enum irqreturn rtx_ethernet_interrupt_handler(int irq, void *dev_id) - { -- struct rtx_ethernet_dev* rtx_ether_dev; -- struct rtx_e1000_ctx* ctx; -+ ${Ethernet::Device} rtx_ether_dev = dev_id; - -- rtx_ether_dev = dev_id; -- ${cast local.rtx_ether_dev as Ethernet::Device}; - ${pointcut ::IMPLEMENTATION(local.rtx_ether_dev)}; - - return IRQ_NONE; -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 -@@ -1,16 +1,30 @@ - interface Ethernet : Socket, PCI, LKM - { -- provided type Net -+ provided type ProtocolId -+ { -+ chunk LKM::prototypes(); -+ chunk LKM::data(); -+ chunk LKM::code(); -+ method decl(); -+ method to_str(); -+ } -+ -+ provided type AbstractDevice - { - chunk LKM::includes(); -- method decl(); -+ method decl(); - } - -+ /* -+ * Unlike PCI::Device, Ethernet::Device doesn't match the struct net_device -+ * from Linux. Ethernet::Device is the type that we use in the private -+ * field of the struct net_device. -+ */ - provided type Device - { - chunk LKM::includes(); - method decl(); -- method init(Ethernet::Net, PCI::Device); -+ method init(Ethernet::AbstractDevice, PCI::Device); - pointcut Ethernet::SubContext(); - } - -@@ -22,7 +36,7 @@ - provided chunk LKM::code(); - } - -- required sequence send(Ethernet::Device dev, Socket::SKBuff skb) -+ required sequence send(Ethernet::Device, Socket::AbstractSKBuff) - { - provided chunk LKM::prototypes(); - provided chunk LKM::code(); -diff --git a/rathaxes/samples/e1000/lkm.rtx b/rathaxes/samples/e1000/lkm.rtx ---- a/rathaxes/samples/e1000/lkm.rtx -+++ b/rathaxes/samples/e1000/lkm.rtx -@@ -1,4 +1,4 @@ --device LKM use LKM, PCI, Ethernet, Log -+device LKM use LKM, PCI, Ethernet, Log, Socket - { - Ethernet::open(Ethernet::Device dev) - { -@@ -43,9 +43,10 @@ - e1000::handle_interrupt(dev); - } - -- Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb) -+ Ethernet::send(Ethernet::Device dev, Socket::AbstractSKBuff skb) - { - Log::info("we have one packet to transmit!"); -+ e1000::xmit(dev, skb); - } - - LKM::init() -@@ -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 -+ * 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,152 @@ --with Socket, LKM -+with Socket, LKM, Device, Ethernet - { -+ template type Socket::AbstractSKBuff() -+ { -+ chunk LKM::includes() -+ { -+ #include -+ -+ static const ${Socket::AbstractSKBuff} force_rtx_socket_kernel_skbuff_decl; -+ } -+ -+ chunk ::decl() -+ { -+ typedef struct sk_buff *rtx_socket_kernel_skbuff_p; -+ } -+ -+ map -+ { -+ } -+ } -+ - template type Socket::SKBuff() - { - chunk LKM::includes() - { -- #include -- static const ${Socket::SKBuff} force_rtx_lnux_skbuf_decl; -+ static const ${Socket::SKBuff} force_rtx_socket_skbuff_decl; - } - - chunk ::decl() - { -- struct sk_buff; -+ struct rtx_socket_skbuff -+ { -+ struct sk_buff *skbuff; -+ dma_addr_t dma_handle; -+ }; - } - -- chunk ::init() -+ chunk LKM::prototypes() - { -+ static void rtx_socket_skbuff_dump_infos(struct rtx_socket_skbuff *); -+ static int rtx_socket_skbuff_map(struct rtx_socket_skbuff *, struct device *, enum dma_data_direction); -+ static void rtx_socket_skbuff_unmap_and_free(struct rtx_socket_skbuff *, struct device *, enum dma_data_direction); -+ } -+ -+ chunk LKM::code() -+ { -+ static void rtx_socket_skbuff_dump_infos(struct rtx_socket_skbuff *self) -+ { -+ WARN_ON(!self->skbuff); -+ -+ /* -+ * We should use a Rathaxes log abstraction instead of pr_info here, -+ * but Rathaxes doesn't support functions with a variable number of -+ * arguments yet. -+ */ -+ ${Ethernet::ProtocolId} ethernet_proto = be16_to_cpu(self->skbuff->protocol); -+ static const char * const ip_summed_values[] = { -+ "none", "unnecessary", "complete", "partial" -+ }; -+ struct skb_shared_info *shinfo = skb_shinfo(self->skbuff); -+ -+ pr_info( -+ "\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", -+ 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 -+ ); -+ } -+ -+ static int rtx_socket_skbuff_map(struct rtx_socket_skbuff *self, -+ struct device *dev, -+ enum dma_data_direction direction) -+ { -+ WARN_ON(!self->skbuff); -+ WARN_ON(!self->skbuff->data); -+ WARN_ON(self->dma_handle); -+ -+ self->dma_handle = dma_map_single( -+ dev, -+ self->skbuff->data, -+ skb_headlen(self->skbuff), -+ direction); -+ int err = dma_mapping_error(dev, self->dma_handle); -+ if (err) -+ { -+ self->dma_handle = 0; -+ return err; -+ } -+ return 0; -+ } -+ -+ static void rtx_socket_skbuff_unmap_and_free(struct rtx_socket_skbuff *self, -+ struct device *dev, -+ enum dma_data_direction direction) -+ { -+ WARN_ON(!self->skbuff); -+ WARN_ON(!self->skbuff->data); -+ -+ if (self->dma_handle) -+ { -+ dma_unmap_single(dev, -+ self->dma_handle, -+ skb_headlen(self->skbuff), -+ direction); -+ self->dma_handle = 0; -+ } -+ dev_kfree_skb_any(self->skbuff); -+ self->skbuff = 0; -+ } -+ } -+ -+ /* -+ * XXX: the rathaxes argument kernel_skb is not actually bound to the -+ * correct C variable from Ethernet::send() (so I named it as the C -+ * variable I needed) -+ */ -+ chunk ::init(Socket::AbstractSKBuff kernel_skb) -+ { -+ ${self}.skbuff = kernel_skb; -+ ${self}.dma_handle = 0; -+ } -+ -+ chunk dump_infos() -+ { -+ rtx_socket_skbuff_dump_infos(${self}); -+ } -+ -+ chunk map_to(Device::AbstractDevice dev) -+ { -+ rtx_socket_skbuff_map(${self}, ${dev}, DMA_TO_DEVICE); -+ } -+ -+ chunk map_from(Device::AbstractDevice dev) -+ { -+ rtx_socket_skbuff_map(${self}, ${dev}, DMA_FROM_DEVICE); -+ } -+ -+ 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::AbstractDevice dev) -+ { -+ rtx_socket_skbuff_unmap_and_free(${self}, ${dev}, DMA_FROM_DEVICE); - } - - map -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,23 @@ --interface Socket : LKM -+interface Socket : LKM, Device - { -- provided type Socket::SKBuff { -- chunk LKM::includes(); -- method decl(); -- method init(); -+ /* The SKBuff type from the kernel */ -+ provided type AbstractSKBuff -+ { -+ chunk LKM::includes(); -+ method decl(); -+ } -+ -+ provided type SKBuff -+ { -+ chunk LKM::includes(); -+ chunk LKM::prototypes(); -+ chunk LKM::code(); -+ method decl(); -+ method init(Socket::AbstractSKBuff); -+ method dump_infos(); -+ method map_to(Device::AbstractDevice); -+ method map_from(Device::AbstractDevice); -+ method unmap_to_and_free(Device::AbstractDevice); -+ method unmap_from_and_free(Device::AbstractDevice); - } - } diff -r 4968acb39c7b -r 9f06d7fb2542 maintainers_build_lkm_in_gnu99.patch --- a/maintainers_build_lkm_in_gnu99.patch Mon Oct 15 06:17:32 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -# HG changeset patch -# Parent c53df313fbe2c5f971327b697cfcf506941b9b80 -maintainers: use the gnu99 "standard" to build Linux kernel modules - -diff --git a/maintainers/CMakeScripts/Templates/MakefileLKM.in b/maintainers/CMakeScripts/Templates/MakefileLKM.in ---- a/maintainers/CMakeScripts/Templates/MakefileLKM.in -+++ b/maintainers/CMakeScripts/Templates/MakefileLKM.in -@@ -1,6 +1,6 @@ - # Disable this "coding-style" warning (seriously, you have to compile with - # -pedantic to get it...) --EXTRA_CFLAGS = -Wno-declaration-after-statement -+EXTRA_CFLAGS = -Wno-declaration-after-statement -std=gnu99 - - KDIR = /lib/modules/$(shell uname -r)/build - obj-m := @LKM_OBJECTS@ diff -r 4968acb39c7b -r 9f06d7fb2542 maintainers_remove_tarte_workaround.patch --- a/maintainers_remove_tarte_workaround.patch Mon Oct 15 06:17:32 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -# HG changeset patch -# Parent 05a7e20d2dc9dbce3f3877da1db7c743448c000e -maintainers: remove the workaround used to generate source without CNorm unstrict - -diff --git a/maintainers/CMakeScripts/UseRathaxes.cmake b/maintainers/CMakeScripts/UseRathaxes.cmake ---- a/maintainers/CMakeScripts/UseRathaxes.cmake -+++ b/maintainers/CMakeScripts/UseRathaxes.cmake -@@ -185,8 +185,6 @@ - - SET(KERNEL_OBJECT_NAME "${RATHAXES_SOURCE}_${SYSTEM}.ko") - ADD_CUSTOM_COMMAND(OUTPUT "${KERNEL_OBJECT_NAME}" -- # … -- COMMAND "sed" "-i" "/TARTE/ d" "${RATHAXES_SOURCE}_${SYSTEM}.c" - # The linux Makefile to build kernel module is quite - # picky about file location and its own name. Let's - # copy our source side by side with the Makefile: diff -r 4968acb39c7b -r 9f06d7fb2542 series --- a/series Mon Oct 15 06:17:32 2012 +0200 +++ b/series Mon Oct 15 06:18:35 2012 +0200 @@ -1,3 +0,0 @@ -maintainers_build_lkm_in_gnu99.patch -maintainers_remove_tarte_workaround.patch -e1000_implement_the_frame_transmission_chunk.patch