Mercurial > archived > louis > epitech > mq > rathaxes
comparison e1000_implement_the_frame_transmission_chunk.patch @ 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 |
comparison
equal
deleted
inserted
replaced
84:6432998a8245 | 85:5dda73e7d728 |
---|---|
1 # HG changeset patch | 1 # HG changeset patch |
2 # Parent 72f11dd4265bb367278f34b23ecb5afa0f7f6fb7 | 2 # Parent 41aa481c1ba8a54a7291ac2630f2eebc50022f33 |
3 rathaxes: start to queue up packets in the TX ring on the e1000 sample | 3 rathaxes: start to queue up packets in the TX ring on the e1000 sample |
4 | 4 |
5 diff --git a/maintainers/CMakeScripts/Templates/MakefileLKM.in b/maintainers/CMakeScripts/Templates/MakefileLKM.in | 5 diff --git a/maintainers/CMakeScripts/Templates/MakefileLKM.in b/maintainers/CMakeScripts/Templates/MakefileLKM.in |
6 --- a/maintainers/CMakeScripts/Templates/MakefileLKM.in | 6 --- a/maintainers/CMakeScripts/Templates/MakefileLKM.in |
7 +++ b/maintainers/CMakeScripts/Templates/MakefileLKM.in | 7 +++ b/maintainers/CMakeScripts/Templates/MakefileLKM.in |
14 KDIR = /lib/modules/$(shell uname -r)/build | 14 KDIR = /lib/modules/$(shell uname -r)/build |
15 obj-m := @LKM_OBJECTS@ | 15 obj-m := @LKM_OBJECTS@ |
16 diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/e1000.blt | 16 diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/e1000.blt |
17 --- a/rathaxes/samples/e1000/e1000.blt | 17 --- a/rathaxes/samples/e1000/e1000.blt |
18 +++ b/rathaxes/samples/e1000/e1000.blt | 18 +++ b/rathaxes/samples/e1000/e1000.blt |
19 @@ -964,4 +964,20 @@ | 19 @@ -964,4 +964,52 @@ |
20 } | 20 } |
21 } | 21 } |
22 } | 22 } |
23 + | 23 + |
24 + template sequence e1000::xmit(Ethernet::Device ctx, Socket::SKBuff skb) | 24 + template sequence e1000::xmit(Ethernet::Device ctx, Socket::SKBuff skb) |
25 + { | 25 + { |
26 + chunk ::CALL() | 26 + chunk ::CALL() |
27 + { | 27 + { |
28 + typedef unsigned long int dma_addr_t; | |
29 + | |
28 + (void)1; // Issue 10 | 30 + (void)1; // Issue 10 |
29 + /* | 31 + /* |
30 + * Put packets on the TX ring, must return NETDEV_TX_OK or | 32 + * Put packets on the TX ring, must return NETDEV_TX_OK or |
31 + * NETDEV_TX_BUSY. | 33 + * NETDEV_TX_BUSY. |
32 + */ | 34 + */ |
33 + { | 35 + { |
34 + ${Log::info("xmit: skbuff details:")}; | 36 + ${Log::info("xmit: skbuff details:")}; |
35 + ${skb.dump_infos()}; | 37 + ${skb.dump_infos()}; |
36 + } | 38 + } |
39 + | |
40 + /* | |
41 + * The transmission is going to be several steps: | |
42 + * - TCP Segmentation Offload & Checksum Offloading: pick a | |
43 + * descriptor from the tx ring and fill it as a context descriptor | |
44 + * to allow the card to slice into several packets according to | |
45 + * the MSS; | |
46 + * - DMA Map the skbuff data as slices of 4096; | |
47 + * - Signal the hardware that data is available via a tx desc. | |
48 + */ | |
49 + | |
50 + if (skb_is_gso(${skb}) || ${skb}->ip_summed == CHECKSUM_PARTIAL) | |
51 + { | |
52 + ${Log::info("xmit: the packet needs to be fragmented and/or checksummed but this not implemented yet!")}; | |
53 + return NETDEV_TX_OK; | |
54 + } | |
55 + | |
56 + /* XXX ${ctx} expands into skb */ | |
57 + dma_addr_t buff_addr = dma_map_single( | |
58 + &${ctx}->pci_dev->dev, | |
59 + ${skb}->data, | |
60 + skb_headlen(${skb}), | |
61 + DMA_TO_DEVICE); | |
62 + if (dma_mapping_error(&${ctx}->pci_dev->dev, buff_addr)) | |
63 + { | |
64 + ${Log::info("xmit: can't DMA map a SKBuff")}; | |
65 + /* now what, should I free the skb? */ | |
66 + } | |
67 + | |
68 + return NETDEV_TX_OK; | |
37 + } | 69 + } |
38 + } | 70 + } |
39 } | 71 } |
40 diff --git a/rathaxes/samples/e1000/e1000.rti b/rathaxes/samples/e1000/e1000.rti | 72 diff --git a/rathaxes/samples/e1000/e1000.rti b/rathaxes/samples/e1000/e1000.rti |
41 --- a/rathaxes/samples/e1000/e1000.rti | 73 --- a/rathaxes/samples/e1000/e1000.rti |
88 + i != sizeof(rtx_ethernet_proto_table[0]) / sizeof(rtx_ethernet_proto_table); | 120 + i != sizeof(rtx_ethernet_proto_table[0]) / sizeof(rtx_ethernet_proto_table); |
89 + i++) | 121 + i++) |
90 + if (proto_id == rtx_ethernet_proto_table[i].id) | 122 + if (proto_id == rtx_ethernet_proto_table[i].id) |
91 + return rtx_ethernet_proto_table[i].name; | 123 + return rtx_ethernet_proto_table[i].name; |
92 + | 124 + |
93 + return "Other"; | 125 + return "Unknown"; |
94 + } | 126 + } |
95 + } | 127 + } |
96 + | 128 + |
97 + chunk to_str() | 129 + chunk to_str() |
98 + { | 130 + { |
127 - chunk ::init(Ethernet::Net net_dev, PCI::Device pci_dev) | 159 - chunk ::init(Ethernet::Net net_dev, PCI::Device pci_dev) |
128 + chunk ::init(Ethernet::AbstractDevice net_dev, PCI::Device pci_dev) | 160 + chunk ::init(Ethernet::AbstractDevice net_dev, PCI::Device pci_dev) |
129 { | 161 { |
130 ${self} = netdev_priv(${net_dev}); | 162 ${self} = netdev_priv(${net_dev}); |
131 /* | 163 /* |
164 @@ -100,11 +140,11 @@ | |
165 { | |
166 static int rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev) | |
167 { | |
168 - ${cast local.dev as Ethernet::Device}; | |
169 + struct rtx_ethernet_dev* rtx_ethernet_dev = netdev_priv(dev); | |
170 + | |
171 + ${cast local.rtx_ethernet_dev as Ethernet::Device}; | |
172 ${cast local.skb as Socket::SKBuff}; | |
173 - ${pointcut ::IMPLEMENTATION(local.dev, local.skb)}; | |
174 - | |
175 - return 0; | |
176 + ${pointcut ::IMPLEMENTATION(local.rtx_ethernet_dev, local.skb)}; | |
177 } | |
178 } | |
179 } | |
132 diff --git a/rathaxes/samples/e1000/ethernet.rti b/rathaxes/samples/e1000/ethernet.rti | 180 diff --git a/rathaxes/samples/e1000/ethernet.rti b/rathaxes/samples/e1000/ethernet.rti |
133 --- a/rathaxes/samples/e1000/ethernet.rti | 181 --- a/rathaxes/samples/e1000/ethernet.rti |
134 +++ b/rathaxes/samples/e1000/ethernet.rti | 182 +++ b/rathaxes/samples/e1000/ethernet.rti |
135 @@ -1,11 +1,28 @@ | 183 @@ -1,11 +1,28 @@ |
136 interface Ethernet : Socket, PCI, LKM | 184 interface Ethernet : Socket, PCI, LKM |
171 Log::info("we have one packet to transmit!"); | 219 Log::info("we have one packet to transmit!"); |
172 + e1000::xmit(dev, skb); | 220 + e1000::xmit(dev, skb); |
173 } | 221 } |
174 | 222 |
175 LKM::init() | 223 LKM::init() |
224 @@ -79,4 +80,10 @@ | |
225 * 4096, 8192 and 16384 bytes: | |
226 */ | |
227 e1000::rx_buffer_len = 2048; | |
228 + /* | |
229 + * 4096 bytes maximum per transmit descriptor is used on Linux and FreeBSD, | |
230 + * 2048 on Minix and HelenOS, I can't find why. If I understand the Intel | |
231 + * man correctly, the maximum should be 16288 (see section 3.3.3). | |
232 + */ | |
233 + e1000::tx_max_data_per_desc = 4096; | |
234 } | |
176 diff --git a/rathaxes/samples/e1000/socket.blt b/rathaxes/samples/e1000/socket.blt | 235 diff --git a/rathaxes/samples/e1000/socket.blt b/rathaxes/samples/e1000/socket.blt |
177 --- a/rathaxes/samples/e1000/socket.blt | 236 --- a/rathaxes/samples/e1000/socket.blt |
178 +++ b/rathaxes/samples/e1000/socket.blt | 237 +++ b/rathaxes/samples/e1000/socket.blt |
179 @@ -1,4 +1,4 @@ | 238 @@ -1,4 +1,4 @@ |
180 -with Socket, LKM | 239 -with Socket, LKM |
181 +with Socket, LKM, Ethernet | 240 +with Socket, LKM, Ethernet |
182 { | 241 { |
183 template type Socket::SKBuff() | 242 template type Socket::SKBuff() |
184 { | 243 { |
185 @@ -17,6 +17,32 @@ | 244 @@ -17,6 +17,34 @@ |
186 { | 245 { |
187 } | 246 } |
188 | 247 |
189 + chunk ::dump_infos() | 248 + chunk ::dump_infos() |
190 + { | 249 + { |
194 + * arguments yet. | 253 + * arguments yet. |
195 + */ | 254 + */ |
196 + unsigned short ethernet_proto = be16_to_cpu(${self}->protocol); | 255 + unsigned short ethernet_proto = be16_to_cpu(${self}->protocol); |
197 + ${cast local.ethernet_proto as Ethernet::ProtocolId}; | 256 + ${cast local.ethernet_proto as Ethernet::ProtocolId}; |
198 + | 257 + |
258 + static const char * const ip_summed_values[] = { | |
259 + "none", "unnecessary", "complete", "partial" | |
260 + }; | |
261 + | |
199 + pr_info( | 262 + pr_info( |
200 + "\tprotocol = %#-5x (%s)\n" | 263 + "\t protocol = %#-5x (%s)\n" |
201 + "\t len = %-5u data_len = %-5u head_len = %-5u\n" | 264 + "\t len = %-5u data_len = %-5u head_len = %-5u\n" |
202 + "\tnr_frags = %u\n" | 265 + "\t nr_frags = %u\n" |
203 + "\tgso_size = %-5u gso_segs = %-5u gso_type = %-5u\n", | 266 + "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u\n" |
267 + "\tip_summed = %d\n (%s)", | |
204 + ethernet_proto, "", // XXX: ${local.ethernet_proto.to_str()}, | 268 + ethernet_proto, "", // XXX: ${local.ethernet_proto.to_str()}, |
205 + ${self}->len, | 269 + ${self}->len, ${self}->data_len, skb_headlen(${self}), |
206 + ${self}->data_len, | |
207 + skb_headlen(${self}), | |
208 + skb_shinfo(${self})->nr_frags, | 270 + skb_shinfo(${self})->nr_frags, |
209 + skb_shinfo(${self})->gso_size, | 271 + skb_shinfo(${self})->gso_size, skb_shinfo(${self})->gso_segs, skb_shinfo(${self})->gso_type, |
210 + skb_shinfo(${self})->gso_segs, | 272 + ${self}->ip_summed, ip_summed_values[${self}->ip_summed] |
211 + skb_shinfo(${self})->gso_type | |
212 + ); | 273 + ); |
213 + } | 274 + } |
214 + | 275 + |
215 map | 276 map |
216 { | 277 { |