# HG changeset patch # User Louis Opter # Date 1347605915 -7200 # Node ID 5dda73e7d72896c537d68a0a76b814215699e4bc # Parent 6432998a8245fb4dbdb7183ca5f369a45b899fb1 Add my WIP on the actual tx diff -r 6432998a8245 -r 5dda73e7d728 e1000_implement_the_frame_transmission_chunk.patch --- 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] + ); + } +