comparison rathaxes_sample_e1000_rewrite_device_dependent_code.patch @ 132:f2e4dd91dc6f

Wip, leave some "functions" empty but start some build tests
author Louis Opter <kalessin@kalessin.fr>
date Sun, 05 Jan 2014 18:21:41 +0100
parents c209851a82de
children dbb4a3b383cb
comparison
equal deleted inserted replaced
131:c209851a82de 132:f2e4dd91dc6f
4 4
5 diff --git a/notes.txt b/notes.txt 5 diff --git a/notes.txt b/notes.txt
6 new file mode 100644 6 new file mode 100644
7 --- /dev/null 7 --- /dev/null
8 +++ b/notes.txt 8 +++ b/notes.txt
9 @@ -0,0 +1,9 @@ 9 @@ -0,0 +1,26 @@
10 +Remarks for David & Lionel:
11 +
10 +- Too much changes to not start over; 12 +- Too much changes to not start over;
11 +- Lack of methods is extremely annoying and requires a lot of workarounds (e.g: 13 +- Lack of methods is extremely annoying and requires a lot of workarounds (e.g:
12 + see the register read/write/set/unset methods on e1000::Context); 14 + see the register read/write/set/unset methods on e1000::Context);
13 +- I'm using a pointcut inside the ethernet context "decl data_types" to inject 15 +- I'm using a pointcut inside the ethernet context "decl data_types" to inject
14 + my hardware context; it's impossible to get it back without hardcoding stuff, 16 + my hardware context; it's impossible to get it back without hardcoding stuff,
15 + because the ethernet subsystem isn't aware of the type of the field (so I 17 + because the ethernet subsystem isn't aware of the type of the field (so I
16 + can't write an attribute). Being able to just inject a type (instead of a 18 + can't write an attribute). Being able to just inject a type (instead of a
17 + whole structure field) might not be the best solution but would solve this 19 + whole structure field) might not be the best solution but would solve this
18 + issue/use case. 20 + issue/use case;
21 +- Can I use the same name for a pointcut and a sequence (e.g: Ethernet::send
22 + bot a sequence name and a pointcut same thing for the interrupt handler);
23 +- Lack of support for circular dependencies make some code annoying or
24 + incorrect (circular dependencies between abstract and concrete types via the
25 + attribute or circular dependencies between the rings and the hardware
26 + context).
27 +
28 +Todo/Totry:
29 +
30 +- Use the rtx_ether_ctx attribute on AbstractDevice to initialize Device
31 + objects in ethernet.bl;
32 +- Worry about the code being executed concurrently, e.g: what happens if the
33 + interrupt handler is called right before we disable it in the close path?
34 +
35 +Questions:
19 diff --git a/rathaxes/samples/e1000/CMakeLists.txt b/rathaxes/samples/e1000/CMakeLists.txt 36 diff --git a/rathaxes/samples/e1000/CMakeLists.txt b/rathaxes/samples/e1000/CMakeLists.txt
37 old mode 100755
38 new mode 100644
20 --- a/rathaxes/samples/e1000/CMakeLists.txt 39 --- a/rathaxes/samples/e1000/CMakeLists.txt
21 +++ b/rathaxes/samples/e1000/CMakeLists.txt 40 +++ b/rathaxes/samples/e1000/CMakeLists.txt
22 @@ -9,7 +9,6 @@ 41 @@ -17,9 +17,9 @@
23 pci.rti
24 socket.rti
25 ethernet.rti
26 - e1000.rti
27 BLT
28 log.blt
29 lkm.blt
30 @@ -17,9 +16,8 @@
31 dma.blt 42 dma.blt
32 pci.blt 43 pci.blt
33 socket.blt 44 socket.blt
34 - e1000.blt 45 - e1000.blt
35 ethernet.blt) 46 - ethernet.blt)
47 + ethernet.blt
48 + e1000.blt)
36 49
37 -IF (LINUX_KBUILD_DIR) 50 -IF (LINUX_KBUILD_DIR)
38 - ADD_RATHAXES_LKM(e1000 e1000_src) 51 - ADD_RATHAXES_LKM(e1000 e1000_src)
39 -ENDIF (LINUX_KBUILD_DIR) 52 -ENDIF (LINUX_KBUILD_DIR)
40 +#IF (LINUX_KBUILD_DIR) 53 +#IF (LINUX_KBUILD_DIR)
41 +# ADD_RATHAXES_LKM(e1000 e1000_src) 54 +# ADD_RATHAXES_LKM(e1000 e1000_src)
42 +#ENDIF (LINUX_KBUILD_DIR) 55 +#ENDIF (LINUX_KBUILD_DIR)
56 diff --git a/rathaxes/samples/e1000/dma.blt b/rathaxes/samples/e1000/dma.blt
57 old mode 100755
58 new mode 100644
59 diff --git a/rathaxes/samples/e1000/dma.rti b/rathaxes/samples/e1000/dma.rti
60 old mode 100755
61 new mode 100644
43 diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/e1000.blt 62 diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/e1000.blt
63 old mode 100755
64 new mode 100644
44 --- a/rathaxes/samples/e1000/e1000.blt 65 --- a/rathaxes/samples/e1000/e1000.blt
45 +++ b/rathaxes/samples/e1000/e1000.blt 66 +++ b/rathaxes/samples/e1000/e1000.blt
46 @@ -170,14 +170,15 @@ 67 @@ -1,8 +1,148 @@
47 for (i = 0; i != ${config.rx_ring_size}; ++i) 68 with e1000, Ethernet, Socket, DMA, PCI, LKM, Log, Builtin
48 { 69 {
49 ${Socket::SKBuff.ref} skbuff = &hw_ctx->rx_ring.skbuffs[i]; 70 - template type e1000::RxDescriptor()
50 - // XXX #46: ${rtx_ether_ctx.init_rx_skbuff(local.skbuff, config.rx_buffer_len)};
51 - if (rtx_ethernet_init_rx_skbuff(${local.skbuff}, ${config.rx_buffer_len}))
52 + // XXX #46: ${rtx_ether_ctx.alloc_rx_skbuff(local.skbuff, config.rx_buffer_len)};
53 + if (rtx_ethernet_alloc_rx_skbuff(${local.skbuff}, ${config.rx_buffer_len}))
54 {
55 ${Log::info("adapter_init_rx: cannot allocate a skbuff for the rx ring")};
56 goto err_skbuffs_alloc;
57 }
58 - // XXX #46: ${local.skbuff.map_from(rtx_ether_ctx.device)};
59 - if (rtx_socket_skbuff_map(${local.skbuff}, ${rtx_ether_ctx.device}, RTX_DMA_FROM_DEVICE))
60 + /* XXX: recuperer le dma handle et le placer correctement dans le descripteur. */
61 + ${DMA::map(local.rtx_ether_ctx.device, local.skbuff.data, local.skbuff.len, RTX_DMA_FROM_DEVICE)}
62 + if (${DMA::map(local.rtx_ether_ctx.device, local.skbuff.data, local.skbuff.len, RTX_DMA_FROM_DEVICE)})
63 {
64 ${Log::info("adapter_init_rx: cannot dma-map a skbuff for the rx ring")};
65 goto err_skbuffs_map;
66 diff --git a/rathaxes/samples/e1000/e1000ng.blt b/rathaxes/samples/e1000/e1000ng.blt
67 new file mode 100755
68 --- /dev/null
69 +++ b/rathaxes/samples/e1000/e1000ng.blt
70 @@ -0,0 +1,717 @@
71 +with e1000ng, Ethernet, Socket, DMA, PCI, LKM, Log, Builtin
72 +{
73 + template type e1000::Register() 71 + template type e1000::Register()
74 + { 72 {
73 - decl data_types()
75 + decl data_types() 74 + decl data_types()
76 + { 75 + {
77 + E1000_CTRL = 0x00000, /* Device Control - RW */ 76 + E1000_CTRL = 0x00000, /* Device Control - RW */
78 + E1000_CTRL_DUP = 0x00004, /* Device Control Duplicate (Shadow) - RW */ 77 + E1000_CTRL_DUP = 0x00004, /* Device Control Duplicate (Shadow) - RW */
79 + E1000_STATUS = 0x00008, /* Device Status - RO */ 78 + E1000_STATUS = 0x00008, /* Device Status - RO */
211 + } 210 + }
212 + 211 +
213 + template type e1000::RxDescriptor() 212 + template type e1000::RxDescriptor()
214 + { 213 + {
215 + decl data_types() 214 + decl data_types()
216 + { 215 {
217 + __le64 buff_addr; 216 __le64 buff_addr;
218 + __le16 length; 217 __le16 length;
219 + __le16 csum; 218 @@ -12,13 +152,39 @@
220 + unsigned char status; 219 __le16 special;
221 + unsigned char errors; 220 }
222 + __le16 special; 221
223 + } 222 - chunk LKM::includes()
224 +
225 + map 223 + map
226 + { 224 {
227 + } 225 - #include <linux/types.h>
226 }
228 + } 227 + }
229 + 228
229 - method init()
230 + // This is a generic tx descriptor for the e1000. When you use TCP 230 + // This is a generic tx descriptor for the e1000. When you use TCP
231 + // Segmentation Offload (TSO) the hardware actually uses two types of 231 + // Segmentation Offload (TSO) the hardware actually uses two types of
232 + // tx descriptors in its tx ring: 232 + // tx descriptors in its tx ring:
233 + // - context descriptors: this descriptor doesn't actually point to data to 233 + // - context descriptors: this descriptor doesn't actually point to data to
234 + // send but initialize the offloading engine for the data descriptor that 234 + // send but initialize the offloading engine for the data descriptor that
235 + // follow; 235 + // follow;
236 + // - data descriptors: this descriptor points to data from the skbuffs. 236 + // - data descriptors: this descriptor points to data from the skbuffs.
237 + template type e1000::TxDescriptor() 237 + template type e1000::TxDescriptor()
238 + { 238 + {
239 + decl data_types() 239 + decl data_types()
240 + { 240 {
241 + __le64 buff_addr; 241 + __le64 buff_addr;
242 + union { 242 + union {
243 + __le32 data; 243 + __le32 data;
244 + struct { 244 + struct {
245 + __le16 length; 245 + __le16 length;
253 + unsigned char status; 253 + unsigned char status;
254 + unsigned char csum_start; /* CSS */ 254 + unsigned char csum_start; /* CSS */
255 + __le16 special; 255 + __le16 special;
256 + } fields; 256 + } fields;
257 + } upper; 257 + } upper;
258 + } 258 }
259 + 259
260 + map 260 map
261 + { 261 @@ -26,44 +192,131 @@
262 + } 262 }
263 + } 263 }
264 + 264
265 - /*
266 - * This is a generic tx descriptor for the e1000. When you use TCP
267 - * Segmentation Offload (TSO) the hardware actually uses two types of
268 - * tx descriptors in its tx ring:
269 - * - context descriptors: this descriptor doesn't actually point to data to
270 - * send but initialize the offloading engine for the data descriptor that
271 - * follow;
272 - * - data descriptors: this descriptor points to data from the skbuffs.
273 - */
274 - template type e1000::TxDescriptor()
265 + template type e1000::Buffer() 275 + template type e1000::Buffer()
266 + { 276 {
277 - decl data_types()
267 + decl data_types() 278 + decl data_types()
268 + { 279 {
280 - __le64 buff_addr;
281 - union
282 - {
283 - __le32 data;
284 - struct
285 - {
286 - __le16 length;
287 - unsigned char csum_offset; /* CSO */
288 - unsigned char cmd;
289 - } fields;
290 - } lower;
291 - union
292 - {
293 - __le32 data;
294 - struct
295 - {
296 - unsigned char status;
297 - unsigned char csum_start; /* CSS */
298 - __le16 special;
299 - } fields;
300 - } upper;
269 + ${Socket::SKBuff} sk_buff; 301 + ${Socket::SKBuff} sk_buff;
270 + ${DMA::DMAHandle} dma; 302 + ${DMA::DMAHandle} dma;
271 + } 303 }
272 + 304
305 - method init()
273 + method init(Socket::SKBuff sk_buff, DMA::DMAHandle dma) 306 + method init(Socket::SKBuff sk_buff, DMA::DMAHandle dma)
274 + { 307 {
275 + ${self.sk_buff} = ${sk_buff}; 308 + ${self.sk_buff} = ${sk_buff};
276 + ${self.dma} = ${dma}; 309 + ${self.dma} = ${dma};
277 + } 310 + }
278 + 311 +
279 + map 312 + map
281 + sk_buff: ${self}->sk_buff; 314 + sk_buff: ${self}->sk_buff;
282 + dma: ${self}->dma; 315 + dma: ${self}->dma;
283 + } 316 + }
284 + } 317 + }
285 + 318 +
286 + template type e1000::MMIO 319 + template type e1000::MMIO()
287 + { 320 + {
288 + decl data_types() 321 + decl data_types()
289 + { 322 + {
290 + unsigned char *io; 323 + unsigned char *io;
291 + } 324 + }
326 + method init(Builtin::symbol io) 359 + method init(Builtin::symbol io)
327 + { 360 + {
328 + ${self.io} = ${io}; 361 + ${self.io} = ${io};
329 + } 362 + }
330 + 363 +
331 + method read32(${e1000::Register} reg) 364 + method read32(e1000::Register reg)
332 + { 365 + {
333 + ioread32(${self.io} + ${local.reg}); 366 + ioread32(${self.io} + ${local.reg});
334 + } 367 + }
335 + 368 +
336 + method write32(${e1000::Register} reg, ${Builtin::number} value) 369 + method write32(e1000::Register reg, Builtin::number value)
337 + { 370 + {
338 + iowrite32(${local.value}, ${self.io} + ${local.reg}); 371 + iowrite32(${local.value}, ${self.io} + ${local.reg});
339 + } 372 + }
340 + 373 +
341 + method set32(${e1000::Register} reg, ${Builtin::number} value) 374 + method set32(e1000::Register reg, Builtin::number value)
342 + { 375 + {
343 + iowrite32(ioread32(${self.io} + ${local.reg}) | value, ${self.io} + ${local.reg}); 376 + iowrite32(ioread32(${self.io} + ${local.reg}) | value, ${self.io} + ${local.reg});
344 + } 377 + }
345 + 378 +
346 + method unset32(${e1000::Register} reg, ${Builtin::number} value) 379 + method unset32(e1000::Register reg, Builtin::number value)
347 + { 380 + {
348 + iowrite32(ioread32(${self.io} + ${local.reg}) & ~value, ${self.io} + ${local.reg}); 381 + iowrite32(ioread32(${self.io} + ${local.reg}) & ~value, ${self.io} + ${local.reg});
349 + } 382 + }
350 + 383 +
351 + map 384 + map
385 + } 418 + }
386 + 419 +
387 + method init(e1000::MMIO io, Builtin::number desc_count, Builtin::number desc_size) 420 + method init(e1000::MMIO io, Builtin::number desc_count, Builtin::number desc_size)
388 + { 421 + {
389 + rtx_e1000_ring_init(&${self}, ${io}, ${desc_count}, ${desc_size}); 422 + rtx_e1000_ring_init(&${self}, ${io}, ${desc_count}, ${desc_size});
390 + } 423 }
391 + } 424
392 + 425 map
426 @@ -71,32 +324,27 @@
427 }
428 }
429
430 - /*
431 - * Ring of e1000::RxDescriptors and their corresponding skbuffs.
432 - *
433 - * - size: total size of the ring in bytes.
434 - * - base: address of the ring (we can't use the typedef here until we get
435 - * CNorm unstrict);
436 - * - dma_base: (physical) address of the ring where the device can access
437 - * the different descriptors;
438 - * - skbuffs: array of the skbuffs and their dma (physical) address
439 - * associated with each descriptor.
440 - */
441 - template type e1000::RxRing()
393 + template type e1000::RxRing() 442 + template type e1000::RxRing()
394 + { 443 {
444 - decl data_types()
395 + decl data_types() 445 + decl data_types()
396 + { 446 {
447 - unsigned int size;
448 - ${e1000::RxDescriptor.ref} base;
449 - dma_addr_t dma_base;
450 - ${Socket::SKBuff} skbuffs[${config.rx_ring_size}];
397 + ${e1000::Ring} ring; 451 + ${e1000::Ring} ring;
398 + } 452 }
399 + 453
454 - method init()
400 + chunk LKM::prototypes() 455 + chunk LKM::prototypes()
401 + { 456 {
402 + static int rtx_e1000_alloc_rx_ressources(${e1000::RxRing.ref}); 457 + static int rtx_e1000_alloc_rx_ressources(${e1000::RxRing.ref});
403 + } 458 }
404 + 459
460 - chunk Ethernet::adapter_init_rx(Ethernet::Device rtx_ether_ctx)
405 + chunk LKM::code() 461 + chunk LKM::code()
406 + { 462 + {
407 + static int rtx_e1000_alloc_rx_ressources(${e1000::RxRing.ref} self) 463 + static int rtx_e1000_alloc_rx_ressources(${e1000::RxRing.ref} self)
408 + { 464 + {
409 + return 0; 465 + return 0;
410 + } 466 + }
411 + } 467 + }
412 + 468 +
413 + chunk Ethernet::adapter_init_rx(Ethernet::Device rtx_ether_ctx) 469 + chunk Ethernet::adapter_init_rx(Ethernet::Device rtx_ether_ctx)
414 + { 470 {
415 + { 471 {
416 + ${e1000::Context.ref} hw_ctx = &${rtx_ether_ctx}->hw_ctx; 472 ${e1000::Context.ref} hw_ctx = &${rtx_ether_ctx}->hw_ctx;
417 + 473 @@ -167,18 +415,16 @@
418 + /* 474 * Allocate the skbuffs, map them for DMA, and write their address
419 + * Receive initialization (section 14.4): 475 * in the corresponding descriptor.
420 + * 476 */
421 + * 1. Program the receive address, in RAL/RAH; 477 - for (i = 0; i != ${config.rx_ring_size}; ++i)
422 + * 2. Initialize the Multicast Table Array; 478 - {
423 + * 3. Program the interrupt mask register (done in 479 + for (i = 0; i != ${config.rx_ring_size}; ++i) {
424 + * e1000::activate_device_interruption); 480 ${Socket::SKBuff.ref} skbuff = &hw_ctx->rx_ring.skbuffs[i];
425 + * 4. Allocate the receive descriptor ring and map it to make it 481 - // XXX #46: ${rtx_ether_ctx.init_rx_skbuff(local.skbuff, config.rx_buffer_len)};
426 + * accessible by the device; 482 - if (rtx_ethernet_init_rx_skbuff(${local.skbuff}, ${config.rx_buffer_len}))
427 + * 5. Write the start address of the ring in RDBAL/RDBAH and set 483 - {
428 + * RDLEN (Receive Descriptor Length) to the size of the ring;
429 + * 6. Set the RDH/RDT (Receive Descriptor Head/Tail) indexes to the
430 + * beginning and end of the ring;
431 + * 7. Make sure that RCTL.BSIZE and .BSEX are at 0 to configure the
432 + * receive buffer size to 2048 bytes (e1000::rx_buffer_len).
433 + * 8. Set RCTL.EN to enable the receiver.
434 + *
435 + * The ugly casts here are caused by the lack of CNorm unstrict.
436 + */
437 +
438 + int i;
439 +
440 + /* 1. Program the receive address */
441 +
442 + /* (We should use uint{32,16}_t but CNorm doesn't know them yet) */
443 + rtx_e1000_register_write32(hw_ctx, E1000_RAL,
444 + *(unsigned int *)(${rtx_ether_ctx.dev_addr}));
445 + /*
446 + * The 16 upper bits of RAH also store the AS bits (which should be
447 + * 0) and the AV bit (should be 1 to set the address as valid).
448 + */
449 + rtx_e1000_register_write32(hw_ctx, E1000_RAH,
450 + *(unsigned short *)(&${rtx_ether_ctx.dev_addr}[4]));
451 + rtx_e1000_register_set32(hw_ctx, E1000_RAH, E1000_RAH_AV);
452 +
453 + ${Log::info("adapter_init_rx: receive address programmed")};
454 +
455 + /* 2. Initialize the MTA */
456 +
457 + for (i = 0; i != 128; ++i)
458 + rtx_e1000_register_write32(hw_ctx, E1000_MTA + i * 4, 0);
459 +
460 + ${Log::info("adapter_init_rx: MTA init done")};
461 +
462 + /* 4. Setup the receive descriptor ring */
463 +
464 + /* Allocate the descriptors */
465 + hw_ctx->rx_ring.size = ${config.rx_ring_size} * sizeof(*hw_ctx->rx_ring.base);
466 + hw_ctx->rx_ring.size = ALIGN(hw_ctx->rx_ring.size, 4096);
467 + hw_ctx->rx_ring.base = ${DMA::alloc_coherent(
468 + rtx_ether_ctx.device,
469 + local.hw_ctx.rx_ring.size,
470 + local.hw_ctx.rx_ring.dma_base.dma_handle
471 + )};
472 + if (!hw_ctx->rx_ring.base)
473 + {
474 + ${Log::info("adapter_init_rx: cannot allocate the descriptors for the rx ring")};
475 + goto err_rx_ring_alloc;
476 + }
477 +
478 + ${Log::info("adapter_init_rx: rx descriptors allocated")};
479 +
480 + /*
481 + * Allocate the skbuffs, map them for DMA, and write their address
482 + * in the corresponding descriptor.
483 + */
484 + for (i = 0; i != ${config.rx_ring_size}; ++i)
485 + {
486 + ${Socket::SKBuff.ref} skbuff = &hw_ctx->rx_ring.skbuffs[i];
487 + // XXX #46: ${rtx_ether_ctx.alloc_rx_skbuff(local.skbuff, config.rx_buffer_len)}; 484 + // XXX #46: ${rtx_ether_ctx.alloc_rx_skbuff(local.skbuff, config.rx_buffer_len)};
488 + if (rtx_ethernet_alloc_rx_skbuff(${local.skbuff}, ${config.rx_buffer_len})) 485 + if (rtx_ethernet_alloc_rx_skbuff(${local.skbuff}, ${config.rx_buffer_len})) {
489 + { 486 ${Log::info("adapter_init_rx: cannot allocate a skbuff for the rx ring")};
490 + ${Log::info("adapter_init_rx: cannot allocate a skbuff for the rx ring")}; 487 goto err_skbuffs_alloc;
491 + goto err_skbuffs_alloc; 488 }
492 + } 489 - // XXX #46: ${local.skbuff.map_from(rtx_ether_ctx.device)};
490 - if (rtx_socket_skbuff_map(${local.skbuff}, ${rtx_ether_ctx.device}, RTX_DMA_FROM_DEVICE))
491 - {
493 + /* XXX: recuperer le dma handle et le placer correctement dans le descripteur. */ 492 + /* XXX: recuperer le dma handle et le placer correctement dans le descripteur. */
494 + ${DMA::map(local.rtx_ether_ctx.device, local.skbuff.data, local.skbuff.len, RTX_DMA_FROM_DEVICE)} 493 + ${DMA::map(local.rtx_ether_ctx.device, local.skbuff.data, local.skbuff.len, RTX_DMA_FROM_DEVICE)}
495 + if (${DMA::map(local.rtx_ether_ctx.device, local.skbuff.data, local.skbuff.len, RTX_DMA_FROM_DEVICE)}) 494 + if (${DMA::map(local.rtx_ether_ctx.device, local.skbuff.data, local.skbuff.len, RTX_DMA_FROM_DEVICE)}) {
496 + { 495 ${Log::info("adapter_init_rx: cannot dma-map a skbuff for the rx ring")};
497 + ${Log::info("adapter_init_rx: cannot dma-map a skbuff for the rx ring")}; 496 goto err_skbuffs_map;
498 + goto err_skbuffs_map; 497 }
499 + } 498 @@ -212,8 +458,7 @@
500 + hw_ctx->rx_ring.base[i].buff_addr = cpu_to_le64(${local.skbuff.sk_buff}); 499 goto init_rx_ok;
501 + } 500
502 + 501 err_skbuffs_alloc:
503 + // ${Log::info("adapter_init_rx: skbuffs allocated}; 502 - while (i--)
504 + pr_info("rtx_e1k: adapter_init_rx: skbuffs allocated, headlen=%d", skb_headlen((struct sk_buff *)hw_ctx->rx_ring.skbuffs[i - 1].skbuff)); 503 - {
505 +
506 + /* 5. Save the emplacement and the size of the ring in RDBA/RDLEN */
507 + rtx_e1000_register_write32(hw_ctx, E1000_RDBAL, hw_ctx->rx_ring.dma_base & 0xffffffff);
508 + rtx_e1000_register_write32(hw_ctx, E1000_RDBAH, hw_ctx->rx_ring.dma_base >> 32);
509 + rtx_e1000_register_write32(hw_ctx, E1000_RDLEN, hw_ctx->rx_ring.size);
510 +
511 + /* 6. Setup RDH/RDT */
512 + rtx_e1000_register_write32(hw_ctx, E1000_RDH, 0);
513 + rtx_e1000_register_write32(hw_ctx, E1000_RDT, ${config.rx_ring_size} - 1);
514 +
515 + /* 7. Configure the buffer size, */
516 + rtx_e1000_register_set32(hw_ctx, E1000_RCTL, E1000_RCTL_BSIZE_${config.rx_buffer_len});
517 +
518 + /* 8. Enable the receiver */
519 + rtx_e1000_register_set32(hw_ctx, E1000_RCTL, E1000_RCTL_EN);
520 +
521 + ${Log::info("adapter_init_rx: receive registers configured and receiver enabled")};
522 +
523 + /*
524 + * XXX: We can't return here since we are not in a function but
525 + * in a chunk of code (injected in a function).
526 + */
527 + goto init_rx_ok;
528 +
529 + err_skbuffs_alloc:
530 + while (i--) { 504 + while (i--) {
531 + dma_unmap_single( 505 dma_unmap_single(
532 + ${rtx_ether_ctx.device}, 506 ${rtx_ether_ctx.device},
533 + /* XXX Leaking cast because of the array: */ 507 /* XXX Leaking cast because of the array: */
534 + *((dma_addr_t *)&(hw_ctx->rx_ring.skbuffs[i].dma_handle)), 508 @@ -238,487 +483,87 @@
535 + ${config.rx_buffer_len}, 509 }
536 + DMA_FROM_DEVICE); 510 }
537 + err_skbuffs_map: 511
538 + /* XXX leaking cast: */ 512 - map
539 + dev_kfree_skb((struct sk_buff *)hw_ctx->rx_ring.skbuffs[i].skbuff);
540 + }
541 +
542 + dma_free_coherent(${rtx_ether_ctx.device}, hw_ctx->rx_ring.size,
543 + hw_ctx->rx_ring.base, hw_ctx->rx_ring.dma_base);
544 + err_rx_ring_alloc:
545 + /*
546 + * XXX: Likewise, if there is something else to rollback in the
547 + * enclosing function, this won't be done.
548 + */
549 + return -ENOMEM;
550 +
551 + init_rx_ok: (void)0; /* NOP, to make this a valid label. */
552 + }
553 + }
554 +
555 + method init(e1000::MMIO io, Builtin::number desc_count) 513 + method init(e1000::MMIO io, Builtin::number desc_count)
556 + { 514 {
515 - size: ((${self}).size);
516 - dma_base: ((${self}).dma_base);
517 - }
518 - }
519 -
520 - /*
521 - * Ring of e1000::TxDescriptors, this is a bit similar to the Rx ring except
522 - * that we don't really have to manage the skbuffs themselves (they are
523 - * given to use by the kernel).
524 - *
525 - * - size: total size of the ring in bytes.
526 - * - base: address of the ring (we can't use the typedef here until we get
527 - * CNorm unstrict);
528 - * - dma_base: (physical) address of the ring where the device can access
529 - * the different descriptors;
530 - * - skbuffs: the skbuffs associated with each descriptor of the ring;
531 - * - head: index on the head of the ring;
532 - * - tail: index on the tail of the ring.
533 - *
534 - * Keep in mind that the head and tail fields are, obviously, not
535 - * synchronized with TDT/TDH on the device.
536 - */
537 - template type e1000::TxRing()
538 - {
539 - decl data_types()
540 - {
541 - unsigned int size;
542 - /* XXX: can't use ${e1000::TxDescriptor} here: */
543 - ${e1000::TxDescriptor.ref} base; /* rename to descs */
544 - dma_addr_t dma_base;
545 - ${Socket::SKBuff} skbuffs[${config.tx_ring_size}];
546 - unsigned short head;
547 - unsigned short tail;
557 + ${self.ring.init(local.io, local.desc_count, self.desc_size)}; 548 + ${self.ring.init(local.io, local.desc_count, self.desc_size)};
558 + } 549 }
559 + 550
551 - chunk LKM::prototypes()
560 + method alloc() 552 + method alloc()
561 + { 553 {
554 - static void rtx_e1000_tx_ring_clean(${e1000::TxRing.ref});
555 - static unsigned int rtx_e1000_tx_ring_descriptors_remaining(${e1000::TxRing.ref});
556 - static int rtx_e1000_tx_ring_tso_cksum_offload(${e1000::TxRing.ref}, ${Socket::SKBuff.ref});
557 - static void rtx_e1000_tx_ring_put(${e1000::TxRing.ref}, ${Socket::SKBuff.ref});
558 - /* FIXME: See issue #54 */
559 - static void rtx_e1000_tx_ring_start_xmit(${e1000::TxRing.ref}, /*const*/ ${e1000::Context.ref});
560 - }
561 -
562 - chunk LKM::code()
563 - {
564 - static void rtx_e1000_tx_ring_clean(${e1000::TxRing.ref} self)
565 - {
566 - ${e1000::TxDescriptor.ref} tx_desc;
567 - bool done;
568 -
569 - for (; self->head != self->tail; self->head++)
570 - {
571 - tx_desc = &self->base[self->head];
572 - done = tx_desc->upper.fields.status & E1000_TXD_STAT_DD;
573 - if (!done)
574 - break ;
575 - }
576 -
577 - pr_info("%s: tx_ring_clean: moving head to %d/%d", ${config.name}, self->head, ${config.tx_ring_size});
578 - }
579 -
580 - static unsigned int rtx_e1000_tx_ring_descriptors_remaining(${e1000::TxRing.ref} self)
581 - {
582 - if (self->tail == self->head) /* ring is empty */
583 - return 256; /* XXX: ${config.tx_ring_size}; */
584 - if (self->tail > self->head)
585 - /* XXX: ${config.tx_ring_size} */
586 - return 256 - (self->tail - self->head);
587 - return self->head - self->tail;
588 - }
589 -
590 - static int rtx_e1000_tx_ring_tso_cksum_offload(${e1000::TxRing.ref} self, ${Socket::SKBuff.ref} skb)
591 - {
592 - ${Socket::AbstractSKBuff.ref} k_skb = skb->skbuff;
593 - return skb_is_gso(${local.k_skb.k_sk_buff}) || ${local.k_skb.k_sk_buff}->ip_summed == CHECKSUM_PARTIAL;
594 - }
595 -
596 - static void rtx_e1000_tx_ring_put(${e1000::TxRing.ref} self, ${Socket::SKBuff.ref} skb)
597 - {
598 - WARN_ON(!skb);
599 -
600 - /*
601 - * Mark it as the last buffer (EOP) and ask the card to
602 - * insert the Ethernet FCS (Frame Check Sequence).
603 - *
604 - * XXX: it sucks to use skb_headlen() here (this part of the
605 - * code shouldn't be aware of it and use something more
606 - * abstract.
607 - */
608 - ${Socket::AbstractSKBuff.ref} k_skb = skb->skbuff;
609 - ${e1000::TxDescriptor.ref} tx_desc = &self->base[self->tail];
610 - tx_desc->lower.data = cpu_to_le32(
611 - E1000_TXD_CMD_EOP |
612 - E1000_TXD_CMD_IFCS |
613 - E1000_TXD_CMD_RS |
614 - skb_headlen(${local.k_skb.k_sk_buff}));
615 - tx_desc->upper.data = 0;
616 - tx_desc->buff_addr = cpu_to_le64(${local.skb.dma_handle.k_dma_handle});
617 - memcpy(&self->skbuffs[self->tail], ${local.k_skb.k_sk_buff}, sizeof(*${local.k_skb.k_sk_buff}));
618 - self->tail = (self->tail + 1) % ${config.tx_ring_size};
619 - }
620 -
621 - /* FIXME: See issue #54 */
622 - static void rtx_e1000_tx_ring_start_xmit(${e1000::TxRing.ref} self, /*const*/ ${e1000::Context.ref} hw_ctx)
623 - {
624 - pr_info("%s: start_xmit: moving tail to %d/%d", ${config.name}, self->tail, ${config.tx_ring_size});
625 - rtx_e1000_register_write32(hw_ctx, E1000_TDT, self->tail);
626 - }
627 - }
628 -
629 - chunk Ethernet::adapter_init_tx(Ethernet::Device rtx_ether_ctx)
630 - {
631 - {
632 - ${e1000::Context.ref} hw_ctx = &${rtx_ether_ctx}->hw_ctx;
633 -
634 - /*
635 - * Transmission initialization (section 14.5):
636 - *
637 - * 1. Allocate the transmit descriptors ring and map it to make it
638 - * accessible by the device;
639 - * 2. Write the start address of the ring in TDBAL/TDBAH and set
640 - * TDLEN to the size of the ring;
641 - * 3. Set the TDH/TDT indexes to the beginning and end of the ring;
642 - * 4. Set TCTL.PSP to pad short packets and TCTL.EN to enable the
643 - * transmitter.
644 - */
645 -
646 - /* 1. Allocate the tx ring */
647 - hw_ctx->tx_ring.size = ${config.tx_ring_size} * sizeof(*hw_ctx->tx_ring.base);
648 - hw_ctx->tx_ring.size = ALIGN(hw_ctx->tx_ring.size, 4096);
649 - hw_ctx->tx_ring.base = dma_alloc_coherent(
650 - ${rtx_ether_ctx.device},
651 - hw_ctx->tx_ring.size,
652 - &hw_ctx->tx_ring.dma_base,
653 - GFP_KERNEL);
654 - if (!hw_ctx->rx_ring.base)
655 - {
656 - ${Log::info("adapter_init_tx: cannot allocate the descriptors for the tx ring")};
657 - /*
658 - * XXX: If there is something else to rollback in the enclosing
659 - * function, this won't be done.
660 - */
661 - return -ENOMEM;
662 - }
663 -
664 - ${Log::info("adapter_init_tx: tx descriptors allocated")};
665 -
666 - /* 2. Save the emplacement and the size of the ring in TDBA/TDLEN */
667 - rtx_e1000_register_write32(hw_ctx, E1000_TDBAL, hw_ctx->tx_ring.dma_base & 0xffffffff);
668 - rtx_e1000_register_write32(hw_ctx, E1000_TDBAH, hw_ctx->tx_ring.dma_base >> 32);
669 - rtx_e1000_register_write32(hw_ctx, E1000_TDLEN, hw_ctx->tx_ring.size);
670 -
671 - /* 3. Setup TDH/TDT to zero: the queue is empty */
672 - rtx_e1000_register_write32(hw_ctx, E1000_TDH, 0);
673 - rtx_e1000_register_write32(hw_ctx, E1000_TDT, 0);
674 - hw_ctx->tx_ring.head = 0;
675 - hw_ctx->tx_ring.tail = 0;
676 -
677 - /* 4. Set TCTL.PSP and enable the transmitter */
678 - rtx_e1000_register_set32(hw_ctx, E1000_TCTL, E1000_TCTL_PSP|E1000_TCTL_EN);
679 -
680 - ${Log::info("adapter_init_tx: transmit registers configured and transmitter enabled")};
681 - }
682 - }
683 -
684 - method clean()
685 - {
686 - rtx_e1000_tx_ring_clean(${self});
687 - }
688 -
689 - method descriptors_remaining()
690 - {
691 - rtx_e1000_tx_ring_descriptors_remaining(${self});
692 - }
693 -
694 - method tso_cksum_offload(Socket::SKBuff skb)
695 - {
696 - }
697 -
698 - method put(Socket::SKBuff skb)
699 - {
700 - rtx_e1000_tx_ring_put(${self}, &${skb});
701 - }
702 -
703 - method start_xmit(e1000::Context ctx)
704 - {
705 - rtx_e1000_tx_ring_start_xmit(${self}, ${ctx});
706 - }
707 -
708 - method init()
709 - {
562 + rtx_e1000_alloc_rx_ressources(${self}); 710 + rtx_e1000_alloc_rx_ressources(${self});
563 + } 711 }
564 + 712
565 + map 713 map
566 + { 714 {
567 + descs: ((${self})->descs); // TODO: fix cast pour directement avoir les descs 715 + descs: ((${self})->descs); // TODO: fix cast pour directement avoir les descs
568 + desc_size: sizeof(/* XXX ${e1000::RxDescriptor} */int); 716 + desc_size: sizeof(/* XXX ${e1000::RxDescriptor} */int);
569 + } 717 }
570 + } 718 }
571 + 719
720 - template type e1000::Context()
572 + template type e1000::TxRing() 721 + template type e1000::TxRing()
573 + { 722 {
723 - decl data_types()
574 + decl data_types() 724 + decl data_types()
575 + { 725 {
726 - int bars;
727 - unsigned char /* __iomem */ *ioaddr;
728 - ${e1000::RxRing.scalar} rx_ring;
729 - ${e1000::TxRing.scalar} tx_ring;
576 + ${e1000::Ring} ring; 730 + ${e1000::Ring} ring;
577 + } 731 }
578 + 732
733 - chunk Ethernet::HardwareContext()
579 + chunk LKM::prototypes() 734 + chunk LKM::prototypes()
580 + { 735 {
736 - /*
737 - * Force the generation of the structure in the "headers" part, we
738 - * have to do this since we do not use the structure in this blt
739 - * (we hacked a bit and used it in ethernet.blt directly).
740 - */
741 - ${e1000::Context} hw_ctx;
581 + static int rtx_e1000_alloc_tx_ressources(${e1000::TxRing.ref}); 742 + static int rtx_e1000_alloc_tx_ressources(${e1000::TxRing.ref});
582 + } 743 }
583 + 744
745 - chunk Ethernet::adapter_init_context(Ethernet::Device rtx_ether_ctx,
746 - Builtin::number bars,
747 - Builtin::symbol ioaddr)
584 + chunk LKM::code() 748 + chunk LKM::code()
585 + { 749 {
586 + static int rtx_e1000_alloc_tx_ressources(${e1000::TxRing.ref} self) 750 + static int rtx_e1000_alloc_tx_ressources(${e1000::TxRing.ref} self)
587 + { 751 {
752 - ${e1000::Context.ref} hw_ctx = &${rtx_ether_ctx}->hw_ctx;
753 - hw_ctx->bars = ${bars};
754 - hw_ctx->ioaddr = ${ioaddr};
588 + return 0; 755 + return 0;
589 + } 756 }
590 + } 757 }
591 + 758
759 - chunk Ethernet::adapter_reset(Ethernet::Device rtx_ether_ctx)
592 + method init(e1000::MMIO io, Builtin::number desc_count) 760 + method init(e1000::MMIO io, Builtin::number desc_count)
593 + { 761 {
762 - {
763 - /* XXX Naming this variable 'hw_ctx' kicks the decl out of the generated code */
764 - ${e1000::Context.ref} tmp_hw_ctx = &${rtx_ether_ctx}->hw_ctx;
765 - rtx_e1000_register_write32(tmp_hw_ctx, E1000_CTRL, E1000_CMD_RST);
766 - udelay(10);
767 - }
594 + ${self.ring.init(local.io, local.desc_count, self.desc_size)}; 768 + ${self.ring.init(local.io, local.desc_count, self.desc_size)};
595 + } 769 }
596 + 770
771 - chunk Ethernet::adapter_load_mac_address(Ethernet::Device rtx_ether_ctx)
597 + method alloc() 772 + method alloc()
598 + { 773 {
774 - {
775 - ${e1000::Context.ref} hw_ctx = &${rtx_ether_ctx}->hw_ctx;
776 - /* Shamelessly borrowed from Minix */
777 - for (int i = 0; i < 3; ++i)
778 - {
779 - rtx_e1000_register_write32(hw_ctx, E1000_EEPROM_READ, (i << 8) | 1);
780 - int value;
781 - do
782 - value = rtx_e1000_register_read32(hw_ctx, E1000_EEPROM_READ);
783 - while ((value & (1 << 4)) == 0);
784 - value >>= 16;
785 - /*
786 - * NOTE: I'm not sure if Ethernet::Device should be
787 - * accessed directly here. But since we need to take it in
788 - * parameter (so we can get back our e1000::Context) it
789 - * seems inadequate to set this in another way:
790 - */
791 - ${rtx_ether_ctx.dev_addr}[i * 2] = value & 0xff;
792 - ${rtx_ether_ctx.dev_addr}[i * 2 + 1] = (value >> 8) & 0xff;
793 - }
794 - ${Log::info("e1000::create: mac address loaded from the EEPROM")};
795 - }
796 - }
797 -
798 - chunk Ethernet::adapter_setup(Ethernet::Device rtx_ether_ctx)
799 - {
800 - {
801 - ${e1000::Context.ref} hw_ctx = &${rtx_ether_ctx}->hw_ctx;
802 -
803 - /*
804 - * "General Configuration" (section 14.3):
805 - *
806 - * - CTRL.ASDE/CTRL.SLU: Let the PHY handle the speed detection &
807 - * negociation;
808 - * - CTRL.LRST/FRCSPD: Unset them to initiate the auto-negociation;
809 - * - CTRL.PHY_RST: Unset it;
810 - * - CTRL.ILOS: Unset it (ILOS is Invert Loss Of Signal);
811 - * - CTRL.VME: Make sure it's not set to disable VLAN support;
812 - * - Set the control flow registers to 0;
813 - * - Finally, initialize all the statistic registers from
814 - * E1000_CRCERRS to E1000_TSCTFC.
815 - */
816 - rtx_e1000_register_set32(hw_ctx, E1000_CTRL,
817 - E1000_CMD_ASDE |
818 - E1000_CMD_SLU);
819 - rtx_e1000_register_unset32(hw_ctx, E1000_CTRL,
820 - E1000_CMD_LRST |
821 - E1000_CMD_FRCSPD |
822 - E1000_CMD_PHY_RST |
823 - E1000_CMD_ILOS |
824 - E1000_CMD_VME);
825 - rtx_e1000_register_write32(hw_ctx, E1000_FCAH, 0);
826 - rtx_e1000_register_write32(hw_ctx, E1000_FCAL, 0);
827 - rtx_e1000_register_write32(hw_ctx, E1000_FCT, 0);
828 - rtx_e1000_register_write32(hw_ctx, E1000_FCTTV, 0);
829 - /*
830 - * XXX: Using int i clashes with another int i from the
831 - * "parent" chunk:
832 - */
833 - for (int j = 0; j != 64; ++j)
834 - rtx_e1000_register_write32(hw_ctx, E1000_CRCERRS + j * 4, 0);
835 -
836 - ${Log::info("adapter_setup: general configuration done")};
837 - }
599 + rtx_e1000_alloc_tx_ressources(${self}); 838 + rtx_e1000_alloc_tx_ressources(${self});
600 + } 839 }
601 + 840
602 + map 841 map
603 + { 842 {
843 - rx_ring: ((${self})->rx_ring);
844 - //tx_ring: ((${self})->tx_ring); XXX Circular dep with Context
604 + descs: ((${self})->descs); // TODO: fix cast pour directement avoir les descs 845 + descs: ((${self})->descs); // TODO: fix cast pour directement avoir les descs
605 + desc_size: sizeof(/* XXX ${e1000::TxDescriptor} */int); 846 + desc_size: sizeof(/* XXX ${e1000::TxDescriptor} */int);
606 + } 847 }
607 + } 848 }
608 + 849
850 - template type e1000::Register()
609 + template type e1000::Context() 851 + template type e1000::Context()
610 + { 852 {
853 - decl data_types()
611 + decl data_types() 854 + decl data_types()
612 + { 855 {
856 - E1000_CTRL = 0x00000, /* Device Control - RW */
857 - E1000_CTRL_DUP = 0x00004, /* Device Control Duplicate (Shadow) - RW */
858 - E1000_STATUS = 0x00008, /* Device Status - RO */
859 - E1000_EEPROM_FLASH = 0x00010, /* EEPROM/Flash Control - RW */
860 - E1000_EEPROM_READ = 0x00014, /* EEPROM Read - RW */
861 - E1000_CTRL_EXT = 0x00018, /* Extended Device Control - RW */
862 - E1000_FLA = 0x0001C, /* Flash Access - RW */
863 - E1000_MDIC = 0x00020, /* MDI Control - RW */
864 - E1000_IMS = 0x000D0, /* Interrupt Mask Set */
865 - E1000_IMC = 0x000D8, /* Interrupt Mask Clear */
866 - E1000_ICR = 0x000C0, /* Interrupt Cause Read - R/clr */
867 - E1000_FCAL = 0x00028, /* Flow Control Address Low */
868 - E1000_FCAH = 0x0002c, /* Flow Control Address High */
869 - E1000_FCT = 0x00030, /* Flow Control Type */
870 - E1000_RCTL = 0x00100, /* Receive Control */
871 - E1000_FCTTV = 0x00170, /* Flow Control Transmit Timer Value */
872 - E1000_TCTL = 0x00400, /* Transmit Control */
873 - E1000_CRCERRS = 0x04000, /* CRC Error Count (base address of the statistic register spaces) */
874 - E1000_RAL = 0x05400, /* Receive Address Low */
875 - E1000_RAH = 0x05404, /* Receive Address High */
876 - E1000_MTA = 0x05200, /* Multicast Table Array */
877 - E1000_RDBAL = 0x02800, /* Receive Descriptor Base Address (Low 32 bits) */
878 - E1000_RDBAH = 0x02804, /* Receive Descriptor Base Address (High 32 bits) */
879 - E1000_RDLEN = 0x02808, /* Receive Descriptor Length */
880 - E1000_RDH = 0x02810, /* Receive Descriptor Head */
881 - E1000_RDT = 0x02818, /* Receive Descriptor Tail */
882 - E1000_TDBAL = 0x03800, /* Transmit Descriptor Base Address (Low 32 bits) */
883 - E1000_TDBAH = 0x03804, /* Transmit Descriptor Base Address (High 33 bits) */
884 - E1000_TDLEN = 0x03808, /* Transmit Descriptor Length */
885 - E1000_TDH = 0x03810, /* Transmit Descriptor Head */
886 - E1000_TDT = 0x03818, /* Transmit Descriptor Tail */
613 + ${e1000::MMIO} io; 887 + ${e1000::MMIO} io;
614 + ${e1000::TxRing} tx_ring; 888 + ${e1000::TxRing} tx_ring;
615 + ${e1000::RxRing} rx_ring; 889 + ${e1000::RxRing} rx_ring;
616 + } 890 }
617 + 891
892 - method init(Builtin::number value)
618 + chunk LKM::includes() 893 + chunk LKM::includes()
619 + { 894 {
895 - ${self} = ${value};
620 + #include <linux/types.h> 896 + #include <linux/types.h>
621 + } 897 }
622 + 898
899 - map
900 - {
901 - }
902 - }
903 -
904 - template type e1000::Commands()
905 - {
906 - decl data_types()
907 - {
908 - E1000_CMD_FD = 0x00000001, /* Full duplex.0=half; 1=full */
909 - E1000_CMD_BEM = 0x00000002, /* Endian Mode.0=little,1=big */
910 - E1000_CMD_PRIOR = 0x00000004, /* Priority on PCI. 0=rx,1=fair */
911 - E1000_CMD_GIO_MASTER_DISABLE = 0x00000004, /* Blocks new Master requests */
912 - E1000_CMD_LRST = 0x00000008, /* Link reset. 0=normal,1=reset */
913 - E1000_CMD_TME = 0x00000010, /* Test mode. 0=normal,1=test */
914 - E1000_CMD_SLE = 0x00000020, /* Serial Link on 0=dis,1=en */
915 - E1000_CMD_ASDE = 0x00000020, /* Auto-speed detect enable */
916 - E1000_CMD_SLU = 0x00000040, /* Set link up (Force Link) */
917 - E1000_CMD_ILOS = 0x00000080, /* Invert Loss-Of Signal */
918 - E1000_CMD_SPD_SEL = 0x00000300, /* Speed Select Mask */
919 - E1000_CMD_SPD_10 = 0x00000000, /* Force 10Mb */
920 - E1000_CMD_SPD_100 = 0x00000100, /* Force 100Mb */
921 - E1000_CMD_SPD_1000 = 0x00000200, /* Force 1Gb */
922 - E1000_CMD_BEM32 = 0x00000400, /* Big Endian 32 mode */
923 - E1000_CMD_FRCSPD = 0x00000800, /* Force Speed */
924 - E1000_CMD_FRCDPX = 0x00001000, /* Force Duplex */
925 - E1000_CMD_D_UD_EN = 0x00002000, /* Dock/Undock enable */
926 - E1000_CMD_D_UD_POLARITY = 0x00004000, /* Defined polarity of Dock/Undock indication in SDP[0] */
927 - E1000_CMD_FORCE_PHY_RESET = 0x00008000, /* Reset both PHY ports, through PHYRST_N pin */
928 - E1000_CMD_EXT_LINK_EN = 0x00010000, /* enable link status from external LINK_0 and LINK_1 pins */
929 - E1000_CMD_SWDPIN0 = 0x00040000, /* SWDPIN 0 value */
930 - E1000_CMD_SWDPIN1 = 0x00080000, /* SWDPIN 1 value */
931 - E1000_CMD_SWDPIN2 = 0x00100000, /* SWDPIN 2 value */
932 - E1000_CMD_SWDPIN3 = 0x00200000, /* SWDPIN 3 value */
933 - E1000_CMD_SWDPIO0 = 0x00400000, /* SWDPIN 0 Input or output */
934 - E1000_CMD_SWDPIO1 = 0x00800000, /* SWDPIN 1 input or output */
935 - E1000_CMD_SWDPIO2 = 0x01000000, /* SWDPIN 2 input or output */
936 - E1000_CMD_SWDPIO3 = 0x02000000, /* SWDPIN 3 input or output */
937 - E1000_CMD_RST = 0x04000000, /* Global reset */
938 - E1000_CMD_RFCE = 0x08000000, /* Receive Flow Control enable */
939 - E1000_CMD_TFCE = 0x10000000, /* Transmit flow control enable */
940 - E1000_CMD_RTE = 0x20000000, /* Routing tag enable */
941 - E1000_CMD_VME = 0x40000000, /* IEEE VLAN mode enable */
942 - E1000_CMD_PHY_RST = 0x80000000, /* PHY Reset */
943 - E1000_CMD_SW2FW_INT = 0x02000000, /* Initiate an interrupt to manageability engine */
944 - E1000_INTR_TXDW = 0x00000001, /* Transmit desc written back */
945 - E1000_INTR_TXQE = 0x00000002, /* Transmit Queue empty */
946 - E1000_INTR_LSC = 0x00000004, /* Link Status Change */
947 - E1000_INTR_RXSEQ = 0x00000008, /* rx sequence error */
948 - E1000_INTR_RXDMT0 = 0x00000010, /* rx desc min. threshold (0) */
949 - E1000_INTR_RXO = 0x00000040, /* rx overrun */
950 - E1000_INTR_RXT0 = 0x00000080, /* rx timer intr (ring 0) */
951 - E1000_INTR_MDAC = 0x00000200, /* MDIO access complete */
952 - E1000_RAH_AV = (1 << 31), /* Set the MAC Address as Valid */
953 - E1000_RCTL_EN = (1 << 1), /* Receiver Enable */
954 - E1000_RCTL_BSEX = (1 << 25), /* Buffer Size Extension */
955 - E1000_RCTL_BSIZE_256 = ((1 << 16) | (1 << 17)),
956 - E1000_RCTL_BSIZE_512 = (1 << 17),
957 - E1000_RCTL_BSIZE_1024 = (1 << 16),
958 - E1000_RCTL_BSIZE_2048 = 0,
959 - E1000_RCTL_BSIZE_4096 = (E1000_RCTL_BSEX | (1 << 16) | (1 << 17)),
960 - E1000_RCTL_BSIZE_8192 = (E1000_RCTL_BSEX | (1 << 17)),
961 - E1000_RCTL_BSIZE_16384 = (E1000_RCTL_BSEX | (1 << 16)),
962 - E1000_TCTL_EN = (1 << 1), /* Transmitter Enable */
963 - E1000_TCTL_PSP = (1 << 3), /* Pad Short Packet */
964 - }
965 -
966 - map
967 - {
968 - }
969 - }
970 -
971 - template type e1000::TxDescriptorFlags()
972 - {
973 - decl data_types()
974 - {
975 - E1000_TXD_DTYP_D = 0x00100000, /* Data Descriptor */
976 - E1000_TXD_DTYP_C = 0x00000000, /* Context Descriptor */
977 - E1000_TXD_POPTS_IXSM = 0x01, /* Insert IP checksum */
978 - E1000_TXD_POPTS_TXSM = 0x02, /* Insert TCP/UDP checksum */
979 - E1000_TXD_CMD_EOP = 0x01000000, /* End of Packet */
980 - E1000_TXD_CMD_IFCS = 0x02000000, /* Insert FCS (Ethernet CRC) */
981 - E1000_TXD_CMD_IC = 0x04000000, /* Insert Checksum */
982 - E1000_TXD_CMD_RS = 0x08000000, /* Report Status */
983 - E1000_TXD_CMD_RPS = 0x10000000, /* Report Packet Sent */
984 - E1000_TXD_CMD_DEXT = 0x20000000, /* Descriptor extension (0 = legacy) */
985 - E1000_TXD_CMD_VLE = 0x40000000, /* Add VLAN tag */
986 - E1000_TXD_CMD_IDE = 0x80000000, /* Enable Tidv register */
987 - E1000_TXD_STAT_DD = 0x00000001, /* Descriptor Done */
988 - E1000_TXD_STAT_EC = 0x00000002, /* Excess Collisions */
989 - E1000_TXD_STAT_LC = 0x00000004, /* Late Collisions */
990 - E1000_TXD_STAT_TU = 0x00000008, /* Transmit underrun */
991 - E1000_TXD_CMD_TCP = 0x01000000, /* TCP packet */
992 - E1000_TXD_CMD_IP = 0x02000000, /* IP packet */
993 - E1000_TXD_CMD_TSE = 0x04000000, /* TCP Seg enable */
994 - E1000_TXD_STAT_TC = 0x00000004, /* Tx Underrun */
995 - }
996 -
997 - map
998 - {
999 - }
1000 - }
1001 -
1002 - /* TODO: make that a method of e1000::Context */
1003 - template sequence e1000::print_status(Ethernet::Device rtx_ether_ctx)
1004 - {
1005 - chunk LKM::prototypes()
623 + chunk LKM::prototypes() 1006 + chunk LKM::prototypes()
624 + { 1007 {
625 + static void rtx_e1000_print_status(${e1000::Context.ref}); 1008 static void rtx_e1000_print_status(${e1000::Context.ref});
626 + } 1009 }
627 + 1010
1011 - chunk LKM::code()
628 + chunk LKM::code() 1012 + chunk LKM::code()
629 + { 1013 {
630 + static void rtx_e1000_print_status(${e1000::Context.ref} hw_ctx) 1014 static void rtx_e1000_print_status(${e1000::Context.ref} hw_ctx)
631 + { 1015 {
1016 - unsigned int status = rtx_e1000_register_read32(hw_ctx, E1000_STATUS);
1017 - ${Log::info("card status:")};
1018 - /*
1019 - * we can't use Log::info below because it just accept a string
1020 - * (as opposed to a format string with its parameters).
1021 - */
632 + unsigned int status = rtx_e1000_reg_read32(hw_ctx, E1000_STATUS); 1022 + unsigned int status = rtx_e1000_reg_read32(hw_ctx, E1000_STATUS);
633 + ${Log::info("card status:")}; 1023 + ${Log::info("card status:")};
634 + // XXX We can't use Log::info below because it just accept a 1024 + // XXX We can't use Log::info below because it just accept a
635 + // string (as opposed to a format string with its parameters): 1025 + // string (as opposed to a format string with its parameters):
636 + pr_info("\tRegister value: 0x%x\n", status); 1026 pr_info("\tRegister value: 0x%x\n", status);
637 + pr_info("\tMode: %s\n", (status & 1) ? "Full": "Half"); 1027 pr_info("\tMode: %s\n", (status & 1) ? "Full": "Half");
638 + pr_info("\tLink: %s\n", (status & 2) ? "Up" : "Down"); 1028 pr_info("\tLink: %s\n", (status & 2) ? "Up" : "Down");
639 + pr_info("\tTransmission: %s\n", (status & 4) ? "Paused" : "Ok"); 1029 @@ -727,300 +572,178 @@
640 + pr_info("\tInterface: %s\n", (status & 3) == 3 ? "Up" : "Down"); 1030 }
641 + } 1031 }
642 + } 1032
643 + 1033 - chunk ::CALL()
644 + chunk Ethernet::HardwareContext() 1034 + chunk Ethernet::HardwareContext()
645 + { 1035 {
1036 - rtx_e1000_print_status(&${rtx_ether_ctx}->hw_ctx);
1037 - }
1038 - }
1039 -
1040 - /*
1041 - * We should have been able to do something along those lines, but
1042 - * it didn't work so we made the call manually.
1043 - *
1044 - * Ideally:
1045 - * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, E1000_STATUS)};
1046 - *
1047 - * Ideally2, not sure about the syntax on the register parameter:
1048 - * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, ${e1000::Register.E1000_STATUS})};
1049 - *
1050 - * "Acceptable":
1051 - * ${e1000::Register} reg_status;
1052 - * ${e1000.init(E1000_STATUS); // didn't work, so we used the next line
1053 - * reg_status = E1000_STATUS;
1054 - * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, reg_status)};
1055 - *
1056 - * TODO: make them methods of e1000::Context
1057 - */
1058 - template sequence e1000::register_read32(e1000::Context ctx, e1000::Register reg_offset)
1059 - {
1060 - chunk LKM::prototypes()
1061 - {
1062 - /* FIXME: See issue #54 */
1063 - static unsigned int rtx_e1000_register_read32(/*const*/ ${e1000::Context.ref}, unsigned int);
646 + ${e1000::Context} hw_ctx; 1064 + ${e1000::Context} hw_ctx;
647 + } 1065 }
648 + 1066
1067 - chunk LKM::code()
649 + chunk Ethernet::adapter_init_context(Ethernet::Device rtx_ether_ctx, Builtin::symbol ioaddr) 1068 + chunk Ethernet::adapter_init_context(Ethernet::Device rtx_ether_ctx, Builtin::symbol ioaddr)
650 + { 1069 {
651 + { 1070 - /* FIXME: See issue #54 */
1071 - static unsigned int rtx_e1000_register_read32(/*const*/ ${e1000::Context.ref} ctx, unsigned int reg_offset)
1072 {
1073 - return ioread32(ctx->ioaddr + reg_offset);
652 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; 1074 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx;
653 + ${local.hw_ctx.io.init(local.ioaddr)}; 1075 + ${local.hw_ctx.io.init(local.ioaddr)};
654 + ${local.hw_ctx.rx_ring.init(local.hw_ctx.io, config.rx_ring_size)}; 1076 + ${local.hw_ctx.rx_ring.init(local.hw_ctx.io, config.rx_ring_size)};
655 + ${local.hw_ctx.tx_ring.init(local.hw_ctx.io, config.tx_ring_size)}; 1077 + ${local.hw_ctx.tx_ring.init(local.hw_ctx.io, config.tx_ring_size)};
656 + } 1078 }
657 + } 1079 }
658 + 1080
1081 - chunk ::CALL()
659 + chunk Ethernet::adapter_reset(Ethernet::Device rtx_ether_ctx) 1082 + chunk Ethernet::adapter_reset(Ethernet::Device rtx_ether_ctx)
660 + { 1083 {
661 + { 1084 - rtx_e1000_register_read32(${ctx}, ${reg_offset});
1085 - }
1086 - }
1087 -
1088 - template sequence e1000::register_write32(e1000::Context ctx, e1000::Register reg_offset, ::number value)
1089 - {
1090 - chunk LKM::prototypes()
1091 - {
1092 - /* FIXME: See issue #54 */
1093 - static void rtx_e1000_register_write32(/*const*/ ${e1000::Context.ref}, unsigned int, unsigned int);
1094 - }
1095 -
1096 - chunk LKM::code()
1097 - {
1098 - /* FIXME: See issue #54 */
1099 - static void rtx_e1000_register_write32(/*const*/ ${e1000::Context.ref} ctx, unsigned int reg_offset, unsigned int value)
1100 {
1101 - iowrite32(value, ctx->ioaddr + reg_offset);
662 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; 1102 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx;
663 + // XXX #46: ${local.hw_ctx.io.write32(E1000_CTRL, E1000_CMD_RST)}; 1103 + // XXX #46: ${local.hw_ctx.io.write32(E1000_CTRL, E1000_CMD_RST)};
664 + rtx_e1000_reg_write32(hw_ctx, E1000_CTRL, E1000_CMD_RST); 1104 + rtx_e1000_reg_write32(hw_ctx, E1000_CTRL, E1000_CMD_RST);
665 + udelay(10); // TODO: abstract this too... 1105 + udelay(10); // TODO: abstract this too...
666 + ${Log::info("adapter has been reset")}; 1106 + ${Log::info("adapter has been reset")};
667 + } 1107 }
668 + } 1108 }
669 + 1109
1110 - chunk ::CALL()
670 + chunk Ethernet::adapter_load_mac_address(Ethernet::Device rtx_ether_ctx) 1111 + chunk Ethernet::adapter_load_mac_address(Ethernet::Device rtx_ether_ctx)
671 + { 1112 {
1113 - rtx_e1000_register_write32(${ctx}, ${reg_offset}, ${value});
1114 - }
1115 - }
672 + { 1116 + {
673 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; 1117 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx;
674 + // Shamelessly borrowed from Minix 1118 + // Shamelessly borrowed from Minix
675 + for (int i = 0; i < 3; ++i) { 1119 + for (int i = 0; i < 3; ++i) {
676 + rtx_e1000_reg_write32(hw_ctx, E1000_EEPROM_READ, (i << 8) | 1); 1120 + rtx_e1000_reg_write32(hw_ctx, E1000_EEPROM_READ, (i << 8) | 1);
684 + // parameter (so we can get back our e1000::Context) it 1128 + // parameter (so we can get back our e1000::Context) it
685 + // seems inadequate to set this in another way: 1129 + // seems inadequate to set this in another way:
686 + ${local.rtx_ether_ctx.dev_addr}[i * 2] = value & 0xff; 1130 + ${local.rtx_ether_ctx.dev_addr}[i * 2] = value & 0xff;
687 + ${local.rtx_ether_ctx.dev_addr}[i * 2 + 1] = (value >> 8) & 0xff; 1131 + ${local.rtx_ether_ctx.dev_addr}[i * 2 + 1] = (value >> 8) & 0xff;
688 + } 1132 + }
689 + 1133
1134 - template sequence e1000::register_set32(e1000::Context ctx, e1000::Register reg_offset, ::number value)
1135 - {
1136 - chunk LKM::prototypes()
1137 - {
1138 - /* FIXME: See issue #54 */
1139 - static void rtx_e1000_register_set32(/*const*/ ${e1000::Context.ref}, unsigned int, unsigned int);
1140 - }
1141 -
1142 - chunk LKM::code()
1143 - {
1144 - /* FIXME: See issue #54 */
1145 - static void rtx_e1000_register_set32(/*const*/ ${e1000::Context.ref} ctx, unsigned int reg_offset, unsigned int value)
1146 - {
1147 - iowrite32(rtx_e1000_register_read32(ctx, reg_offset) | value, ctx->ioaddr + reg_offset);
690 + ${Log::info("mac address loaded from the EEPROM")}; 1148 + ${Log::info("mac address loaded from the EEPROM")};
691 + } 1149 }
692 + } 1150 }
693 + 1151
1152 - chunk ::CALL()
1153 + // For e1000, this part is documented in the Intel Gigabit Ethernet
1154 + // Controller Software Developper manual. (You can find it in the
1155 + // doc/hardware directory).
694 + chunk Ethernet::adapter_setup_rx_tx(Ethernet::Device rtx_ether_ctx) 1156 + chunk Ethernet::adapter_setup_rx_tx(Ethernet::Device rtx_ether_ctx)
695 + { 1157 {
1158 - rtx_e1000_register_set32(${ctx}, ${reg_offset}, ${value});
1159 - }
1160 - }
696 + { 1161 + {
697 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; 1162 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx;
698 + 1163
1164 - template sequence e1000::register_unset32(e1000::Context ctx, e1000::Register reg_offset, ::number value)
1165 - {
1166 - chunk LKM::prototypes()
1167 - {
1168 - /* FIXME: See issue #54 */
1169 - static void rtx_e1000_register_unset32(/*const*/ ${e1000::Context.ref}, unsigned int, unsigned int);
1170 - }
699 + // "General Configuration" (section 14.3): 1171 + // "General Configuration" (section 14.3):
700 + // 1172 + //
701 + // - CTRL.ASDE/CTRL.SLU: Let the PHY handle the speed detection & 1173 + // - CTRL.ASDE/CTRL.SLU: Let the PHY handle the speed detection &
702 + // negociation; 1174 + // negociation;
703 + // - CTRL.LRST/FRCSPD: Unset them to initiate the auto-negociation; 1175 + // - CTRL.LRST/FRCSPD: Unset them to initiate the auto-negociation;
720 + rtx_e1000_reg_write32(hw_ctx, E1000_FCAL, 0); 1192 + rtx_e1000_reg_write32(hw_ctx, E1000_FCAL, 0);
721 + rtx_e1000_reg_write32(hw_ctx, E1000_FCT, 0); 1193 + rtx_e1000_reg_write32(hw_ctx, E1000_FCT, 0);
722 + rtx_e1000_reg_write32(hw_ctx, E1000_FCTTV, 0); 1194 + rtx_e1000_reg_write32(hw_ctx, E1000_FCTTV, 0);
723 + for (int i = 0; i != 64; ++i) 1195 + for (int i = 0; i != 64; ++i)
724 + rtx_e1000_reg_write32(hw_ctx, E1000_CRCERRS + i * 4, 0); 1196 + rtx_e1000_reg_write32(hw_ctx, E1000_CRCERRS + i * 4, 0);
725 + 1197
1198 - chunk LKM::code()
1199 - {
1200 - /* FIXME: See issue #54 */
1201 - static void rtx_e1000_register_unset32(/*const*/ ${e1000::Context.ref} ctx, unsigned int reg_offset, unsigned int value)
1202 - {
1203 - iowrite32(rtx_e1000_register_read32(ctx, reg_offset) & ~value, ctx->ioaddr + reg_offset);
726 + ${Log::info("adapter_setup: general configuration done")}; 1204 + ${Log::info("adapter_setup: general configuration done")};
727 + } 1205 }
728 + } 1206 }
729 + 1207
1208 - chunk ::CALL()
730 + chunk Ethernet::adapter_enable_interrupts(Ethernet::Device) 1209 + chunk Ethernet::adapter_enable_interrupts(Ethernet::Device)
731 + { 1210 {
1211 - rtx_e1000_register_unset32(${ctx}, ${reg_offset}, ${value});
1212 - }
1213 - }
732 + { 1214 + {
733 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; 1215 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx;
734 + rtx_e1000_reg_write32( 1216 + rtx_e1000_reg_write32(
735 + hw_ctx, 1217 + hw_ctx,
736 + E1000_IMS, 1218 + E1000_IMS,
737 + E1000_INTR_TXDW|E1000_INTR_TXQE|E1000_INTR_LSC| 1219 + E1000_INTR_TXDW|E1000_INTR_TXQE|E1000_INTR_LSC|
738 + E1000_INTR_RXO|E1000_INTR_RXT0 1220 + E1000_INTR_RXO|E1000_INTR_RXT0
739 + ); 1221 + );
740 + 1222
1223 - template sequence activate_device_interruption(Ethernet::Device rtx_ether_ctx)
1224 - {
1225 - chunk ::CALL()
1226 - {
1227 - rtx_e1000_register_write32(&${rtx_ether_ctx}->hw_ctx, E1000_IMS,
1228 - E1000_INTR_TXDW |
1229 - E1000_INTR_TXQE |
1230 - E1000_INTR_LSC |
1231 - E1000_INTR_RXO |
1232 - E1000_INTR_RXT0);
1233 - }
1234 - }
1235 -
1236 - /* TODO:
1237 - *
1238 - * Refactor into two methods (one in RxRing and one in TxRing) and make use
1239 - * of the new methods in Socket::SKBuff.
1240 - */
1241 - template sequence free_rx_tx(Ethernet::Device rtx_ether_ctx)
1242 - {
1243 - chunk ::CALL()
1244 - {
1245 - /*
1246 - * XXX: Not generated if named "hw_ctx" (which is funny because
1247 - * it's used and works in the template right above this one):
1248 - */
1249 - ${e1000::Context.ref} hw_ctx_;
1250 - hw_ctx_ = &${rtx_ether_ctx}->hw_ctx;
1251 -
1252 - /*
1253 - * Free the rx ring:
1254 - * - Unmap and free the skbuffs;
1255 - * - Free the descriptors array.
1256 - */
1257 - for (int i = 0; i != ${config.rx_ring_size}; ++i)
1258 - {
1259 - /*
1260 - * XXX Leaking casts:
1261 - *
1262 - * We should go through the rtx types (Socket::SKBuff,
1263 - * AbstractSKBuff), but we can't because of the array here,
1264 - * which is not supported by the compiler.
1265 - */
1266 - dma_unmap_single(
1267 - ${rtx_ether_ctx.device},
1268 - *((dma_addr_t *)&(hw_ctx_->rx_ring.skbuffs[i].dma_handle)),
1269 - ${config.rx_buffer_len},
1270 - DMA_FROM_DEVICE);
1271 - dev_kfree_skb((struct sk_buff *)hw_ctx_->rx_ring.skbuffs[i].skbuff);
1272 - }
1273 - dma_free_coherent(${rtx_ether_ctx.device}, hw_ctx_->rx_ring.size,
1274 - hw_ctx_->rx_ring.base, hw_ctx_->rx_ring.dma_base);
1275 - ${Log::info("free_rx_tx: rx ring free'ed")};
1276 -
1277 - /*
1278 - * Free the tx ring:
1279 - * - Free the descriptors array.
1280 - */
1281 - dma_free_coherent(${rtx_ether_ctx.device}, hw_ctx_->tx_ring.size,
1282 - hw_ctx_->tx_ring.base, hw_ctx_->tx_ring.dma_base);
1283 - ${Log::info("free_rx_tx: tx ring free'ed")};
1284 - }
1285 - }
1286 -
1287 - template sequence handle_interrupt(Ethernet::Device rtx_ether_ctx)
1288 - {
1289 - chunk ::CALL()
1290 - {
1291 - unsigned int icr = rtx_e1000_register_read32(&${rtx_ether_ctx}->hw_ctx, E1000_ICR);
1292 - pr_info("%s: interrupt received, ICR: 0x%x", ${config.name}, icr);
1293 - if (icr)
1294 - {
1295 - if (icr & E1000_INTR_LSC)
1296 - {
1297 - ${Log::info("handle_interrupt: cable link status changed, dumping card status:")};
1298 - ${e1000::print_status(rtx_ether_ctx)};
1299 - }
1300 - if (icr & (E1000_INTR_TXQE|E1000_INTR_TXDW))
1301 - {
1302 - ${Log::info("handle_interrupt: TxRing: packet(s) sent")};
1303 - /*
1304 - * XXX Do a Rathaxes call (how can I bind
1305 - * "&${rtx_ether_ctx}->hw_ctx.tx_ring" to e1000::TxRing easily?)
1306 - */
1307 - rtx_e1000_tx_ring_clean(&${rtx_ether_ctx}->hw_ctx.tx_ring);
1308 - }
1309 - if (icr & E1000_INTR_RXT0)
1310 - {
1311 - ${Log::info("handle_interrupt: RxRing: packet(s) received")};
1312 - }
1313 - if (icr & E1000_INTR_RXO)
1314 - {
1315 - ${Log::info("handle_interrupt: RxRing: overrun")};
1316 - }
1317 -
1318 - return IRQ_HANDLED;
741 + // XXX We should probably move that elsewhere (it just used to 1319 + // XXX We should probably move that elsewhere (it just used to
742 + // be done right after we enabled interrupts when this was 1320 + // be done right after we enabled interrupts when this was
743 + // still in lkm.rtx): 1321 + // still in lkm.rtx):
744 + ${local.hw_ctx.print_status()}; 1322 + // XXX #46: ${local.hw_ctx.print_status()};
745 + } 1323 + rtx_e1000_print_status(hw_ctx);
746 + } 1324 }
747 + 1325 }
748 + chunk Ethernet::handle_interrupt(Ethernet::Device rtx_ether_ctx) 1326 - }
1327
1328 - template sequence e1000::xmit(Ethernet::Device rtx_ether_ctx, Socket::AbstractSKBuff kernel_skb)
1329 - {
1330 - chunk ::CALL()
1331 + chunk Ethernet::disable_interrupts(Ethernet::Device rtx_ether_ctx)
1332 {
1333 - /*
1334 - * Put packets on the TX ring, must return NETDEV_TX_OK or
1335 - * NETDEV_TX_BUSY.
1336 - */
1337 + { ${Log::info("adapter_disable_interrupts: TBD...")}; }
1338 + }
1339
1340 - ${Socket::SKBuff} skb;
1341 - ${e1000::Context.ref} hw_ctx;
1342 - ${e1000::TxRing.ref} tx_ring;
1343 - ${Device::AbstractDevice.ref} devp;
1344 + chunk Ethernet::adapter_handle_interrupt(Ethernet::Device rtx_ether_ctx)
749 + { 1345 + {
750 + { 1346 + {
751 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; 1347 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx;
752 + unsigned int icr = rtx_e1000_reg_read32(hw_ctx, E1000_ICR); 1348 + unsigned int icr = rtx_e1000_reg_read32(hw_ctx, E1000_ICR);
753 + pr_info("%s: interrupt received, ICR: 0x%x", ${config.name}, icr); 1349 + pr_info("%s: interrupt received, ICR: 0x%x", ${config.name}, icr);
754 + if (icr) { 1350 + if (icr) {
755 + if (icr & E1000_INTR_LSC) { 1351 + if (icr & E1000_INTR_LSC) {
756 + ${Log::info("handle_interrupt: cable link status changed, dumping card status:")}; 1352 + ${Log::info("handle_interrupt: cable link status changed, dumping card status:")};
757 + ${local.hw_ctx.print_status()}; 1353 + // XXX #46: ${local.hw_ctx.print_status()};
1354 + rtx_e1000_print_status(hw_ctx);
758 + } 1355 + }
759 + if (icr & (E1000_INTR_TXQE|E1000_INTR_TXDW)) { 1356 + if (icr & (E1000_INTR_TXQE|E1000_INTR_TXDW)) {
760 + ${Log::info("handle_interrupt: TxRing: packet(s) sent")}; 1357 + ${Log::info("handle_interrupt: TxRing: packet(s) sent")};
761 + } 1358 + }
762 + if (icr & E1000_INTR_RXT0) { 1359 + if (icr & E1000_INTR_RXT0) {
763 + ${Log::info("handle_interrupt: RxRing: packet(s) received")}; 1360 + ${Log::info("handle_interrupt: RxRing: packet(s) received")};
764 + } 1361 + }
765 + if (icr & E1000_INTR_RXO) { 1362 + if (icr & E1000_INTR_RXO) {
766 + ${Log::info("handle_interrupt: RxRing: overrun")}; 1363 + ${Log::info("handle_interrupt: RxRing: overrun")};
767 + } 1364 + }
768 + 1365
1366 - ${local.skb.init(kernel_skb)};
1367 - hw_ctx = &${rtx_ether_ctx}->hw_ctx;
1368 - tx_ring = &hw_ctx->tx_ring;
1369 - devp = (${Device::AbstractDevice.ref})${rtx_ether_ctx.device};
769 + // XXX: This sucks since we don't know the pointcut context: 1370 + // XXX: This sucks since we don't know the pointcut context:
770 + return IRQ_HANDLED; 1371 + return IRQ_HANDLED;
771 + } 1372 + }
772 + } 1373 + }
773 + } 1374 + }
774 + 1375
1376 - ${Log::info("xmit: skbuff details:")};
1377 - /*
1378 - * skb does not expand on the bound C variable (should be
1379 - * rtx_skbuff), which is funny because it works for the
1380 - * sequence template call right after.
1381 - */
1382 - /*
1383 - * XXX: doesn't work (I tried to pass self explicitely too):
1384 - * ${local.skb.dump_infos()};
1385 - */
1386 - rtx_socket_skbuff_dump_infos(&skb);
1387 + chunk Ethernet::adapter_xmit(Ethernet::Device rtx_ether_ctx, Socket::SKBuff rtx_skb)
1388 + {
1389 + { ${Log::info("adapter_xmit: TBD...")}; }
1390 + }
1391
1392 - /*
1393 - * The transmission is going to be several steps:
1394 - * 1. TCP Segmentation Offload & Checksum Offloading: pick a
1395 - * descriptor from the tx ring and fill it as a context
1396 - * descriptor to allow the card to slice into several packets
1397 - * according to the MSS;
1398 - * 2. DMA Map the skbuff data as slices of 4096;
1399 - * 3. Signal the hardware that data is available via a tx desc.
1400 - */
1401 + chunk Ethernet::adapter_disable_rx(Ethernet::Device rtx_ether_ctx)
1402 + {
1403 + { ${Log::info("adapter_disable_rx: TBD..")}; }
1404 + }
1405
1406 - /* XXX: same thing wanted to use: ${local.tx_ring.descriptors_remaining()} */
1407 - if (!rtx_e1000_tx_ring_descriptors_remaining(tx_ring))
1408 - return NETDEV_TX_BUSY;
1409 + chunk Ethernet::adpater_disable_tx(Ethernet::Device rtx_ether_ctx)
1410 + {
1411 + { ${Log::info("adapter_disable_tx: TBD..")}; }
1412 + }
1413
1414 - /* 1. Offloading */
1415 + chunk Ethernet::adapter_free_rx_tx(Ethernet::Device rtx_ether_ctx)
1416 + {
1417 + { ${Log::info("adapter_free_rx_tx: TBD..")}; }
1418 + }
1419
1420 - /* XXX: ${local.tx_ring.tso_cksum_offload(skb)}; */
1421 - if (rtx_e1000_tx_ring_tso_cksum_offload(tx_ring, &skb))
1422 - {
1423 - ${Log::info("xmit: the packet needs to be fragmented and/or checksummed but this not implemented yet!")};
1424 - goto err_offload;
1425 - }
1426
1427 - /* 2. Map the data */
775 + method print_status() 1428 + method print_status()
776 + { 1429 + {
777 + rtx_e1000_print_status(${self}); 1430 + rtx_e1000_print_status(${self});
778 + } 1431 + }
779 + 1432
1433 - /* XXX: ${local.skb.map_to(devp.k_device)}; */
1434 - if (rtx_socket_skbuff_map(&skb, ${devp.k_device}, DMA_TO_DEVICE))
1435 - {
1436 - ${Log::info("xmit: can't DMA map a SKbuff")};
1437 - goto err_skb_map_to;
1438 - }
1439 -
1440 - /* 3. Update the TX Ring and signal the hardware */
1441 -
1442 - /* XXX: ${local.tx_ring.put(skb)}; */
1443 - rtx_e1000_tx_ring_put(tx_ring, &skb);
1444 -
1445 - /* XXX: ${local.tx_ring.start_xmit(hw_ctx)}; */
1446 - rtx_e1000_tx_ring_start_xmit(tx_ring, hw_ctx);
1447 -
1448 - return NETDEV_TX_OK;
1449 -
1450 - err_offload:
1451 - err_skb_map_to:
1452 - /* XXX: ${local.skb.unmap_to_and_free(local.dev)}; */
1453 - rtx_socket_skbuff_unmap_and_free(&skb, ${devp.k_device}, DMA_TO_DEVICE);
1454 - return NETDEV_TX_OK;
780 + map 1455 + map
781 + { 1456 + {
782 + io: ${self}->io; 1457 + io: ${self}->io;
783 + rx_ring: ${self}->rx_ring; 1458 + rx_ring: ${self}->rx_ring;
784 + tx_ring: ${self}->tx_ring; 1459 + tx_ring: ${self}->tx_ring;
785 + } 1460 }
786 + } 1461 }
787 +} 1462 }
788 diff --git a/rathaxes/samples/e1000/e1000ng.rti b/rathaxes/samples/e1000/e1000ng.rti 1463 diff --git a/rathaxes/samples/e1000/e1000.rti b/rathaxes/samples/e1000/e1000.rti
789 new file mode 100755 1464 old mode 100755
790 --- /dev/null 1465 new mode 100644
791 +++ b/rathaxes/samples/e1000/e1000ng.rti 1466 --- a/rathaxes/samples/e1000/e1000.rti
792 @@ -0,0 +1,122 @@ 1467 +++ b/rathaxes/samples/e1000/e1000.rti
793 +interface e1000ng : Socket, Ethernet, DMA, PCI, LKM, Builtin 1468 @@ -1,157 +1,115 @@
794 +{ 1469 interface e1000 : Socket, Ethernet, DMA, PCI, LKM, Builtin
1470 {
1471 - required variable Builtin::number rx_ring_size;
1472 - required variable Builtin::number tx_ring_size;
1473 - required variable Builtin::number rx_buffer_len;
1474 - required variable Builtin::number tx_max_data_per_desc;
795 + required variable Builtin::number rx_ring_size; 1475 + required variable Builtin::number rx_ring_size;
796 + required variable Builtin::number tx_ring_size; 1476 + required variable Builtin::number tx_ring_size;
797 + required variable Builtin::number rx_buffer_len; 1477 + required variable Builtin::number rx_buffer_len;
798 + required variable Builtin::number tx_max_data_per_desc; 1478 + required variable Builtin::number tx_max_data_per_desc;
799 + 1479
1480 - provided type RxDescriptor
800 + // Hardware values/data structures, should probably be in the front-end: 1481 + // Hardware values/data structures, should probably be in the front-end:
801 + provided type Register { decl data_types(); } 1482 + provided type Register { decl data_types(); }
802 + provided type Command { decl data_types(); } 1483 + provided type Command { decl data_types(); }
803 + provided type TxDescriptorFlag { decl data_types(); } 1484 + provided type TxDescriptorFlag { decl data_types(); }
804 + provided type RxDescriptor { decl data_types(); } 1485 + provided type RxDescriptor { decl data_types(); }
805 + provided type TxDescriptor { decl data_types(); } 1486 + provided type TxDescriptor { decl data_types(); }
806 + 1487 +
807 + provided type Buffer 1488 + provided type Buffer
808 + { 1489 {
809 + decl data_types(); 1490 - chunk LKM::includes();
1491 decl data_types();
1492 - method init();
810 + 1493 +
811 + method init(Socket::SKBuff, DMA::DMAHandle); 1494 + method init(Socket::SKBuff, DMA::DMAHandle);
812 + 1495 +
813 + attribute Socket::SKBuff.ref sk_buff; 1496 + attribute Socket::SKBuff.ref sk_buff;
814 + attribute DMA::DMAHandle.ref dma; 1497 + attribute DMA::DMAHandle.ref dma;
815 + } 1498 }
816 + 1499
1500 - provided type TxDescriptor
817 + // I wish we could just leave those methods in the Context type but we also 1501 + // I wish we could just leave those methods in the Context type but we also
818 + // need them from the rings and that would mean a circular dependency 1502 + // need them from the rings and that would mean a circular dependency
819 + // between the context and the rings and Rathaxes can't handle it. 1503 + // between the context and the rings and Rathaxes can't handle it.
820 + provided type MMIO 1504 + provided type MMIO
821 + { 1505 {
822 + decl data_types(); 1506 decl data_types();
1507 - method init();
823 + 1508 +
824 + chunk LKM::prototypes(); 1509 + chunk LKM::prototypes();
825 + chunk LKM::code(); 1510 + chunk LKM::code();
826 + 1511 +
827 + method init(Builtin::symbol); 1512 + method init(Builtin::symbol);
828 + method read32(Register); 1513 + method read32(Register);
829 + method write32(Register, Builtin::number); 1514 + method write32(Register, Builtin::number);
830 + method set32(Register, Builtin::number); 1515 + method set32(Register, Builtin::number);
831 + method unset32(Register, Builtin::number); 1516 + method unset32(Register, Builtin::number);
832 + 1517 +
833 + attribute Builtin::symbol io; 1518 + attribute Builtin::symbol.scalar io;
834 + } 1519 + }
835 + 1520 +
836 + provided type Ring 1521 + provided type Ring
837 + { 1522 + {
838 + decl data_types(); 1523 + decl data_types();
840 + chunk LKM::prototypes(); 1525 + chunk LKM::prototypes();
841 + chunk LKM::code(); 1526 + chunk LKM::code();
842 + 1527 +
843 + method init(MMIO, Builtin::number, Builtin::number); 1528 + method init(MMIO, Builtin::number, Builtin::number);
844 + 1529 +
845 + attribute MMIO io; 1530 + attribute MMIO.scalar io;
846 + attribute DMA:DMAHandle dma; 1531 + attribute DMA::DMAHandle.scalar dma;
847 + attribute Builtin::number size; // Total size in bytes 1532 + attribute Builtin::number.scalar size; // Total size in bytes
848 + attribute Builtin::symbol.ref descs; 1533 + attribute Builtin::symbol.ref descs;
849 + attribute Buffer.ref buffs; 1534 + attribute Buffer.ref buffs;
850 + } 1535 }
851 + 1536
852 + provided type RxRing 1537 provided type RxRing
853 + { 1538 {
854 + decl data_types(); 1539 decl data_types();
855 + 1540 - method init();
1541
1542 - /* XXX: Callback that should be in the front-end: */
1543 - chunk Ethernet::adapter_init_rx(Ethernet::Device);
856 + chunk LKM::prototypes(); 1544 + chunk LKM::prototypes();
857 + chunk LKM::code(); 1545 + chunk LKM::code();
858 + 1546
1547 - attribute DMA::DMAHandle.scalar dma_base;
1548 - attribute Builtin::number.scalar size;
859 + method init(MMIO, Builtin::number); 1549 + method init(MMIO, Builtin::number);
860 + method alloc(); // Returns != 0 on failure 1550 + method alloc(); // Returns != 0 on failure
861 + 1551 +
862 + attribute RxDescriptor descs; 1552 + attribute RxDescriptor.scalar descs;
863 + } 1553 + }
864 + 1554 +
865 + provided type TxRing 1555 + provided type TxRing
866 + { 1556 + {
867 + decl data_types(); 1557 + decl data_types();
870 + chunk LKM::code(); 1560 + chunk LKM::code();
871 + 1561 +
872 + method init(MMIO, Builtin::number); 1562 + method init(MMIO, Builtin::number);
873 + method alloc(); // Returns != 0 on failure 1563 + method alloc(); // Returns != 0 on failure
874 + 1564 +
875 + attribute TxDescriptor descs; 1565 + attribute TxDescriptor.scalar descs;
876 + } 1566 }
877 + 1567
878 + provided type Context 1568 provided type Context
879 + { 1569 {
880 + decl data_types(); 1570 - chunk Ethernet::HardwareContext();
881 + 1571 decl data_types();
1572
1573 - /* XXX:
1574 - * These callbacks/Hooks which should probably be in the front-end.
1575 - * Also, I'm not too happy about the names, it's difficult to make
1576 - * the difference between the probe and open parts.
1577 - */
1578 - chunk Ethernet::adapter_init_context(Ethernet::Device,
1579 - Builtin::number,
1580 - Builtin::symbol);
882 + chunk LKM::includes(); 1581 + chunk LKM::includes();
883 + chunk LKM::prototypes(); 1582 + chunk LKM::prototypes();
884 + chunk LKM::code(); 1583 + chunk LKM::code();
885 + chunk Ethernet::HardwareContext(); 1584 + chunk Ethernet::HardwareContext();
886 + 1585 +
887 + // NOTE: Those callbacks/hooks should probably be in the front-end: 1586 + // NOTE: Those callbacks/hooks should probably be in the front-end:
888 + 1587 +
889 + // Init the hardware context structure, doesn't allocate anything.
890 + chunk Ethernet::adapter_init_context(Ethernet::Device, Builtin::symbol); 1588 + chunk Ethernet::adapter_init_context(Ethernet::Device, Builtin::symbol);
891 + 1589 chunk Ethernet::adapter_reset(Ethernet::Device);
892 + // Reset the adapter 1590 chunk Ethernet::adapter_load_mac_address(Ethernet::Device);
893 + chunk Ethernet::adapter_reset(Ethernet::Device); 1591 - chunk Ethernet::adapter_setup(Ethernet::Device);
894 +
895 + // Load the MAC address from the EEPROM and save it into the
896 + // dev_addr field/attribute of Ethernet::Device.
897 + chunk Ethernet::adapter_load_mac_address(Ethernet::Device);
898 +
899 + // Prepare the device and the resources for rx/tx.
900 + chunk Ethernet::adapter_setup_rx_tx(Ethernet::Device); 1592 + chunk Ethernet::adapter_setup_rx_tx(Ethernet::Device);
901 +
902 + // Enable interrupts.
903 + chunk Ethernet::adapter_enable_interrupts(Ethernet::Device); 1593 + chunk Ethernet::adapter_enable_interrupts(Ethernet::Device);
904 + 1594 + chunk Ethernet::adapter_disable_interrupts(Ethernet::Device);
905 + // Interrupt handler. 1595 + chunk Ethernet::adapter_handle_interrupt(Ethernet::Device);
906 + chunk Ethernet::handle_interrupt(Ethernet::Device); 1596 + chunk Ethernet::adapter_xmit(Ethernet::Device, Socket::SKBuff);
907 + 1597 + chunk Ethernet::adapter_disable_rx(Ethernet::Device);
1598 + chunk Ethernet::adapter_disable_tx(Ethernet::Device);
1599 + chunk Ethernet::adapter_free_rx_tx(Ethernet::Device);
1600
908 + method print_status(); 1601 + method print_status();
909 + 1602 +
910 + attribute MMIO io; 1603 + attribute MMIO.scalar io;
911 + attribute RxRing.scalar rx_ring; 1604 attribute RxRing.scalar rx_ring;
1605 - /* XXX: circular dependency with Contex: */
1606 - //attribute TxRing.scalar tx_ring;
1607 - }
1608 -
1609 - provided type TxRing
1610 - {
1611 - chunk LKM::prototypes();
1612 - chunk LKM::code();
1613 - decl data_types();
1614 - method init();
1615 -
1616 - /* XXX: Callback that should be in the front-end: */
1617 - chunk Ethernet::adapter_init_tx(Ethernet::Device);
1618 -
1619 - /* Clean the ring (i.e: move the head closer to the tail): */
1620 - method clean();
1621 - /* Return the number of clean descriptors left in the ring: */
1622 - method descriptors_remaining();
1623 - method tso_cksum_offload(Socket::SKBuff);
1624 - method put(Socket::SKBuff);
1625 - /* Signal the device that new dirty descriptors are on the ring: */
1626 - method start_xmit(e1000::Context);
1627 - }
1628 -
1629 - /*
1630 - * These two types should actually be registers definitions in the frontend:
1631 - */
1632 - provided type Register
1633 - {
1634 - decl data_types();
1635 - method init(Builtin::number);
1636 - }
1637 -
1638 - provided type Commands
1639 - {
1640 - decl data_types();
1641 - }
1642 -
1643 - provided type TxDescriptorFlags
1644 - {
1645 - decl data_types();
1646 - }
1647 -
1648 - /*
1649 - * This should take an e1000::Context as the first argument but this was
1650 - * not working as wished.
1651 - */
1652 - provided sequence print_status(Ethernet::Device)
1653 - {
1654 - provided chunk LKM::prototypes();
1655 - provided chunk LKM::code();
1656 - provided chunk ::CALL();
1657 - }
1658 -
1659 - provided sequence activate_device_interruption(Ethernet::Device)
1660 - {
1661 - provided chunk ::CALL();
1662 - }
1663 -
1664 - provided sequence set_up_device(Ethernet::Device)
1665 - {
1666 - provided chunk ::CALL();
1667 - }
1668 -
1669 - provided sequence free_rx_tx(Ethernet::Device dev)
1670 - {
1671 - provided chunk ::CALL();
1672 - }
1673 -
1674 - provided sequence handle_interrupt(Ethernet::Device)
1675 - {
1676 - provided chunk ::CALL();
1677 - }
1678 -
1679 - provided sequence xmit(Ethernet::Device, Socket::AbstractSKBuff)
1680 - {
1681 - provided chunk ::CALL();
1682 - }
1683 -
1684 - provided sequence register_read32(e1000::Context, e1000::Register)
1685 - {
1686 - provided chunk LKM::prototypes();
1687 - provided chunk LKM::code();
1688 - provided chunk ::CALL();
1689 - }
1690 -
1691 - provided sequence register_write32(e1000::Context, e1000::Register, ::number)
1692 - {
1693 - provided chunk LKM::prototypes();
1694 - provided chunk LKM::code();
1695 - provided chunk ::CALL();
1696 - }
1697 -
1698 - provided sequence register_set32(e1000::Context, e1000::Register, ::number)
1699 - {
1700 - provided chunk LKM::prototypes();
1701 - provided chunk LKM::code();
1702 - provided chunk ::CALL();
1703 - }
1704 -
1705 - provided sequence register_unset32(e1000::Context, e1000::Register, ::number)
1706 - {
1707 - provided chunk LKM::prototypes();
1708 - provided chunk LKM::code();
1709 - provided chunk ::CALL();
912 + attribute TxRing.scalar tx_ring; 1710 + attribute TxRing.scalar tx_ring;
913 + } 1711 }
914 +} 1712 }
915 diff --git a/rathaxes/samples/e1000/ethernet.blt b/rathaxes/samples/e1000/ethernet.blt 1713 diff --git a/rathaxes/samples/e1000/ethernet.blt b/rathaxes/samples/e1000/ethernet.blt
1714 old mode 100755
1715 new mode 100644
916 --- a/rathaxes/samples/e1000/ethernet.blt 1716 --- a/rathaxes/samples/e1000/ethernet.blt
917 +++ b/rathaxes/samples/e1000/ethernet.blt 1717 +++ b/rathaxes/samples/e1000/ethernet.blt
918 @@ -106,7 +106,7 @@ 1718 @@ -1,4 +1,4 @@
1719 -with Ethernet, PCI, LKM, Log, Builtin
1720 +with Ethernet, Socket, PCI, LKM, Log, Builtin
1721 {
1722 template type Ethernet::ProtocolId()
1723 {
1724 @@ -61,7 +61,7 @@
1725
1726 method init(Builtin::symbol dev)
1727 {
1728 - ${self} = (${Ethernet::AbstractDevice} *)${dev};
1729 + ${self} = (${Ethernet::AbstractDevice.ref})${dev};
1730 }
1731
1732 map
1733 @@ -104,9 +104,12 @@
1734 {
1735 static int rtx_ethernet_alloc_rx_skbuff(${Ethernet::Device.ref} self, ${Socket::SKBuff.ref} sk_buff, ${Builtin::number} size)
919 { 1736 {
920 ${Socket::AbstractSKBuff} k_sk_buff = netdev_alloc_skb(${local.self.net_device.k_net_dev}, ${local.size}); 1737 - ${Socket::AbstractSKBuff} k_sk_buff = netdev_alloc_skb(${local.self.net_device.k_net_dev}, ${local.size});
921 if (${local.k_sk_buff) { 1738 - if (${local.k_sk_buff) {
922 - ${local.sk_buff.init(local.k_sk_buff, local.size)}; 1739 - ${local.sk_buff.init(local.k_sk_buff, local.size)};
923 + ${local.sk_buff.init(local.k_sk_buff)}; 1740 + ${Socket::AbstractSKBuff.ref} k_skb = netdev_alloc_skb(${local.self.net_device.k_net_dev}, ${local.size});
1741 + if (${local.k_skb}) {
1742 + // XXX meh, can't use the init method since we get a copy
1743 + // of the pointer, so we have to do this which is
1744 + // inconsistent with the rest of code:
1745 + sk_buff->skbuff = k_skb;
924 return 0; 1746 return 0;
925 } 1747 }
926 return 1; 1748 return 1;
927 @@ -164,34 +164,30 @@ 1749 @@ -148,7 +151,7 @@
1750 }
1751 }
1752
1753 - template sequence Ethernet::open(Ethernet::Device dev)
1754 + template sequence Ethernet::open()
1755 {
1756 chunk LKM::includes()
1757 {
1758 @@ -164,60 +167,68 @@
928 { 1759 {
929 static int rtx_ethernet_open(struct net_device *dev) 1760 static int rtx_ethernet_open(struct net_device *dev)
930 { 1761 {
931 - /* 1762 - /*
932 - * XXX The casts are here because the compiler doesn't resolve 1763 - * XXX The casts are here because the compiler doesn't resolve
937 ${local.rtx_net_dev.init(local.dev)}; 1768 ${local.rtx_net_dev.init(local.dev)};
938 } 1769 }
939 ${Ethernet::Device.ref} rtx_ether_ctx = ${local.rtx_net_dev.rtx_ether_ctx}; 1770 ${Ethernet::Device.ref} rtx_ether_ctx = ${local.rtx_net_dev.rtx_ether_ctx};
940 1771
941 - int error; 1772 - int error;
942 + ${pointcut Ethernet::adapter_setup_rx_tx(local.rtx_ether_ctx)}; 1773 - {
943 +
944 {
945 - ${Log::info("installing the interrupt handler")}; 1774 - ${Log::info("installing the interrupt handler")};
946 + ${Log::info("Installing the interrupt handler")}; 1775 - }
947 }
948 - error = request_irq(${local.rtx_ether_ctx.irq}, 1776 - error = request_irq(${local.rtx_ether_ctx.irq},
949 - rtx_ethernet_interrupt_handler, 1777 - rtx_ethernet_interrupt_handler,
950 - IRQF_SHARED, 1778 - IRQF_SHARED,
951 - ${config.name}, 1779 - ${config.name},
952 - dev); 1780 - dev);
953 - if (error) 1781 - if (error)
954 - { 1782 - {
1783 + ${pointcut Ethernet::adapter_setup_rx_tx(local.rtx_ether_ctx)};
1784 +
1785 + ${Log::info("Installing the interrupt handler")};
955 + int error = request_irq( 1786 + int error = request_irq(
956 + ${local.rtx_ether_ctx.irq}, 1787 + ${local.rtx_ether_ctx.irq},
957 + rtx_ethernet_interrupt_handler, 1788 + rtx_ethernet_interrupt_handler,
958 + IRQF_SHARED, 1789 + IRQF_SHARED,
959 + ${config.name}, 1790 + ${config.name},
970 + 1801 +
971 + ${pointcut Ethernet::adapter_enable_interrupts(local.rtx_ether_ctx)}; 1802 + ${pointcut Ethernet::adapter_enable_interrupts(local.rtx_ether_ctx)};
972 1803
973 return 0; 1804 return 0;
974 } 1805 }
975 @@ -269,7 +265,7 @@ 1806 }
1807 +
1808 + /* XXX This chunk should be removed (see #26) */
1809 + chunk ::CALL()
1810 + {
1811 + }
1812 }
1813
1814 - template sequence Ethernet::send(Ethernet::Device dev, Socket::AbstractSKBuff skb)
1815 + template sequence Ethernet::send()
1816 {
1817 chunk LKM::prototypes()
1818 {
1819 - static int rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev);
1820 + static int rtx_ethernet_xmit(struct sk_buff *skb, struct net_device *dev);
1821 }
1822
1823 chunk LKM::code()
1824 {
1825 - static int rtx_ethernet_xmit(struct sk_buff* kernel_skb, struct net_device *net_dev)
1826 + static int rtx_ethernet_xmit(struct sk_buff *k_skb, struct net_device *net_dev)
1827 {
1828 ${Ethernet::Device.ref} rtx_ether_ctx = netdev_priv(net_dev);
1829 - ${Socket::AbstractSKBuff.ref} rtx_skb = (${Socket::AbstractSKBuff.ref}) kernel_skb;
1830 + ${Socket::SKBuff.ref} rtx_skb;
1831
1832 - ${pointcut ::IMPLEMENTATION(local.rtx_ether_ctx, local.rtx_skb)};
1833 + ${cast local.k_skb as Socket::AbstractSKBuff.ref};
1834 + ${local.rtx_skb.init(local.k_skb)};
1835 +
1836 + ${Log::info("we have one packet to transmit!")};
1837 + ${pointcut Ethernet::adapter_xmit(local.rtx_ether_ctx, local.rtx_skb)};
1838 }
1839 }
1840 +
1841 + /* XXX This chunk should be removed (see #26) */
1842 + chunk ::CALL()
1843 + {
1844 + }
1845 }
1846
1847 - template sequence Ethernet::close(Ethernet::Device dev)
1848 + template sequence Ethernet::close()
1849 {
1850 chunk LKM::prototypes()
1851 {
1852 @@ -226,31 +237,37 @@
1853
1854 chunk LKM::code()
1855 {
1856 - static int rtx_ethernet_close(struct net_device *dev)
1857 + static int rtx_ethernet_close(struct net_device *net_dev)
1858 {
1859 - ${Ethernet::AbstractDevice.ref} rtx_net_dev;
1860 - { /* XXX: I end up with a placeholder if I don't open a scope */
1861 - ${local.rtx_net_dev.init(local.dev)};
1862 - }
1863 + ${cast local.net_dev as Ethernet::AbstractDevice.ref};
1864 + ${Ethernet::Device.ref} rtx_ether_ctx = ${local.net_dev.rtx_ether_ctx};
1865
1866 - ${Ethernet::Device.ref} rtx_ether_ctx = ${local.rtx_net_dev.rtx_ether_ctx};
1867 + ${pointcut Ethernet::adapter_disable_rx(local.rtx_ether_ctx)};
1868
1869 - /* TODO: change this pointcut into a pointcut/adapter/callback: */
1870 - {
1871 - ${pointcut ::IMPLEMENTATION(local.rtx_ether_ctx)};
1872 - }
1873 + netif_tx_disable(net_dev);
1874 + ${pointcut Ethernet::adapter_disable_tx(local.rtx_ether_ctx)};
1875
1876 + ${pointcut Ethernet::adapter_disable_interrupts(local.rtx_ether_ctx)};
1877 free_irq(${local.rtx_ether_ctx.irq}, dev);
1878 - {
1879 - ${Log::info("interrupt handler free'ed")};
1880 - }
1881 + ${Log::info("interrupt handler free'ed")};
1882 +
1883 + // TODO/XXX: There is definitely more stuff to do around here
1884 + // (e.g: clean the rings, flush some stuff...)
1885 +
1886 + ${pointcut Ethernet::adapter_reset(local.rtx_ether_ctx)};
1887 + ${pointcut Ethernet::adapter_free_rx_tx(local.rtx_ether_ctx)};
1888
1889 return 0;
1890 }
1891 }
1892 +
1893 + /* XXX This chunk should be removed (see #26) */
1894 + chunk ::CALL()
1895 + {
1896 + }
1897 }
1898
1899 - template sequence Ethernet::interrupt_handler(Ethernet::Device dev)
1900 + template sequence Ethernet::interrupt_handler()
1901 {
1902 /*
1903 * We can't use the irqreturn_t type here because CNornm doesn't know
1904 @@ -269,11 +286,16 @@
976 ${Ethernet::Device.ref} rtx_ether_ctx; 1905 ${Ethernet::Device.ref} rtx_ether_ctx;
977 rtx_ether_ctx = ${local.rtx_net_dev.rtx_ether_ctx}; 1906 rtx_ether_ctx = ${local.rtx_net_dev.rtx_ether_ctx};
978 1907
979 - ${pointcut ::IMPLEMENTATION(local.rtx_ether_ctx)}; 1908 - ${pointcut ::IMPLEMENTATION(local.rtx_ether_ctx)};
980 + ${pointcut Ethernet::handle_interrupt(local.rtx_ether_ctx)}; 1909 + ${pointcut Ethernet::adapter_handle_interrupt(local.rtx_ether_ctx)};
981 1910
982 return IRQ_NONE; 1911 return IRQ_NONE;
983 } 1912 }
984 @@ -342,12 +338,8 @@ 1913 }
1914 +
1915 + /* XXX This chunk should be removed (see #26) */
1916 + chunk ::CALL()
1917 + {
1918 + }
1919 }
1920
1921 template sequence Ethernet::init()
1922 @@ -342,12 +364,8 @@
985 * XXX: the asssignments/casts are here to circumvent 1923 * XXX: the asssignments/casts are here to circumvent
986 * typing issues in the compiler (see previous XXX). 1924 * typing issues in the compiler (see previous XXX).
987 */ 1925 */
988 - int bars = ${rtx_pci_dev.bars}; 1926 - int bars = ${rtx_pci_dev.bars};
989 unsigned char /* __iomem */ *ioaddr = ${rtx_pci_dev.ioaddr}; 1927 unsigned char /* __iomem */ *ioaddr = ${rtx_pci_dev.ioaddr};
993 - local.ioaddr)}; 1931 - local.ioaddr)};
994 + ${pointcut Ethernet::adapter_init_context(local.rtx_ether_ctx, local.ioaddr)}; 1932 + ${pointcut Ethernet::adapter_init_context(local.rtx_ether_ctx, local.ioaddr)};
995 ${pointcut Ethernet::adapter_reset(local.rtx_ether_ctx)}; 1933 ${pointcut Ethernet::adapter_reset(local.rtx_ether_ctx)};
996 ${pointcut Ethernet::adapter_load_mac_address(local.rtx_ether_ctx)}; 1934 ${pointcut Ethernet::adapter_load_mac_address(local.rtx_ether_ctx)};
997 memcpy(${local.rtx_ether_ctx.perm_addr}, 1935 memcpy(${local.rtx_ether_ctx.perm_addr},
1936 @@ -355,7 +373,7 @@
1937 ${local.rtx_net_dev.k_net_dev}->addr_len);
1938 }
1939
1940 - /* This chunk should be removed (see #26) */
1941 + /* XXX This chunk should be removed (see #26) */
1942 chunk ::CALL()
1943 {
1944 }
1945 @@ -377,7 +395,7 @@
1946 free_netdev(${local.rtx_net_dev.k_net_dev});
1947 }
1948
1949 - /* This chunk should be removed (see #26) */
1950 + /* XXX This chunk should be removed (see #26) */
1951 chunk ::CALL()
1952 {
1953 }
998 diff --git a/rathaxes/samples/e1000/ethernet.rti b/rathaxes/samples/e1000/ethernet.rti 1954 diff --git a/rathaxes/samples/e1000/ethernet.rti b/rathaxes/samples/e1000/ethernet.rti
1955 old mode 100755
1956 new mode 100644
999 --- a/rathaxes/samples/e1000/ethernet.rti 1957 --- a/rathaxes/samples/e1000/ethernet.rti
1000 +++ b/rathaxes/samples/e1000/ethernet.rti 1958 +++ b/rathaxes/samples/e1000/ethernet.rti
1001 @@ -28,8 +28,12 @@ 1959 @@ -2,16 +2,16 @@
1960 {
1961 required variable Builtin::string ifname;
1962
1963 - provided type ProtocolId
1964 - {
1965 - chunk LKM::prototypes();
1966 - chunk LKM::data();
1967 - chunk LKM::code();
1968 - decl data_types();
1969 + provided type ProtocolId
1970 + {
1971 + chunk LKM::prototypes();
1972 + chunk LKM::data();
1973 + chunk LKM::code();
1974 + decl data_types();
1975
1976 - attribute Builtin::number.scalar id;
1977 - attribute Builtin::string.scalar str;
1978 - }
1979 + attribute Builtin::number.scalar id;
1980 + attribute Builtin::string.scalar str;
1981 + }
1982
1983 provided type AbstractDevice
1984 {
1985 @@ -28,72 +28,88 @@
1002 1986
1003 provided type Device 1987 provided type Device
1004 { 1988 {
1005 + decl data_types(); 1989 + decl data_types();
1006 + 1990 +
1010 + chunk LKM::code(); 1994 + chunk LKM::code();
1011 + 1995 +
1012 pointcut Ethernet::HardwareContext(); 1996 pointcut Ethernet::HardwareContext();
1013 1997
1014 method init(Ethernet::AbstractDevice, PCI::AbstractDevice); 1998 method init(Ethernet::AbstractDevice, PCI::AbstractDevice);
1015 @@ -51,7 +55,7 @@ 1999 - /*
2000 - * Alloc (the AbstractSKBuff inside) the given SKBuff and initialize
2001 - * the SKBuff, return 1 if the allocation failed, 0 on success.
2002 - */
2003 +
2004 + // Alloc (the AbstractSKBuff inside) the given SKBuff and initialize
2005 + // the SKBuff, return 1 if the allocation failed, 0 on success:
2006 method alloc_rx_skbuff(Socket::SKBuff, Builtin::number);
2007
2008 attribute Device::AbstractDevice.ref device;
2009 attribute PCI::AbstractDevice.ref pci_device;
2010 attribute Ethernet::AbstractDevice.ref net_device;
2011 - /*
2012 - * I'd like to use better names here, but I'd like to understand the
2013 - * difference between the two first:
2014 - */
2015 +
2016 + // I'd like to use better names here, but I'd like to understand the
2017 + // difference between the two first:
2018 attribute Builtin::symbol.ref perm_addr;
2019 attribute Builtin::symbol.ref dev_addr;
1016 attribute Builtin::symbol.scalar irq; 2020 attribute Builtin::symbol.scalar irq;
1017 } 2021 }
1018 2022
1019 - required sequence open(Ethernet::Device) 2023 - required sequence open(Ethernet::Device)
1020 + provided sequence open(Ethernet::Device) 2024 + provided sequence open()
1021 { 2025 {
1022 provided chunk LKM::includes(); 2026 - provided chunk LKM::includes();
1023 provided chunk LKM::prototypes(); 2027 - provided chunk LKM::prototypes();
1024 @@ -62,9 +66,8 @@ 2028 - provided chunk LKM::code();
1025 * Controller Software Developper manual. (You can find it in the 2029 + provided chunk LKM::includes();
1026 * doc/hardware directory). 2030 + provided chunk LKM::prototypes();
1027 */ 2031 + provided chunk LKM::code();
2032
2033 - /*
2034 - * For e1000, this part is documented in the Intel Gigabit Ethernet
2035 - * Controller Software Developper manual. (You can find it in the
2036 - * doc/hardware directory).
2037 - */
1028 - provided pointcut Ethernet::adapter_setup(Ethernet::Device); 2038 - provided pointcut Ethernet::adapter_setup(Ethernet::Device);
1029 - provided pointcut Ethernet::adapter_init_rx(Ethernet::Device); 2039 - provided pointcut Ethernet::adapter_init_rx(Ethernet::Device);
1030 - provided pointcut Ethernet::adapter_init_tx(Ethernet::Device); 2040 - provided pointcut Ethernet::adapter_init_tx(Ethernet::Device);
2041 + // Prepare the device and the resources for rx/tx:
1031 + provided pointcut Ethernet::adapter_setup_rx_tx(Ethernet::Device); 2042 + provided pointcut Ethernet::adapter_setup_rx_tx(Ethernet::Device);
2043 +
2044 + // Enable interrupts:
1032 + provided pointcut Ethernet::adapter_enable_interrupts(Ethernet::Device); 2045 + provided pointcut Ethernet::adapter_enable_interrupts(Ethernet::Device);
1033 } 2046 }
1034 2047
1035 required sequence send(Ethernet::Device, Socket::AbstractSKBuff) 2048 - required sequence send(Ethernet::Device, Socket::AbstractSKBuff)
1036 @@ -79,10 +82,12 @@ 2049 + provided sequence send()
1037 provided chunk LKM::code(); 2050 {
2051 - provided chunk LKM::prototypes();
2052 - provided chunk LKM::code();
2053 + provided chunk LKM::prototypes();
2054 + provided chunk LKM::code();
2055 +
2056 + // Put a packet on the tx ring and signal the device:
2057 + provided pointcut Ethernet::adapter_xmit(Ethernet::Device, Socket::SKBuff);
1038 } 2058 }
1039 2059
2060 - required sequence close(Ethernet::Device)
2061 + provided sequence close()
2062 {
2063 - provided chunk LKM::prototypes();
2064 - provided chunk LKM::code();
2065 + provided chunk LKM::prototypes();
2066 + provided chunk LKM::code();
2067 +
2068 + provided pointcut Ethernet::adapter_disable_rx(Ethernet::Device);
2069 + provided pointcut Ethernet::adapter_disable_tx(Ethernet::Device);
2070 + provided pointcut Ethernet::adapter_disable_interrupts(Ethernet::Device);
2071 +
2072 + // Clean and free all resources on the rx/tx rings:
2073 + provided pointcut Ethernet::adapter_free_rx_tx(Ethernet::Device);
2074 }
2075
1040 - required sequence interrupt_handler(Ethernet::Device) 2076 - required sequence interrupt_handler(Ethernet::Device)
1041 + provided sequence interrupt_handler(Ethernet::Device) 2077 + provided sequence interrupt_handler()
1042 { 2078 {
1043 provided chunk LKM::prototypes(); 2079 - provided chunk LKM::prototypes();
1044 provided chunk LKM::code(); 2080 - provided chunk LKM::code();
1045 + 2081 + provided chunk LKM::prototypes();
1046 + provided pointcut Ethernet::handle_interrupt(Ethernet::Device); 2082 + provided chunk LKM::code();
2083 +
2084 + // Interrupt handler:
2085 + provided pointcut Ethernet::adapter_handle_interrupt(Ethernet::Device);
1047 } 2086 }
1048 2087
1049 provided sequence init() 2088 - provided sequence init()
1050 @@ -90,9 +95,7 @@ 2089 + provided sequence init()
1051 provided chunk LKM::data(); 2090 {
1052 provided chunk PCI::pci_probe_hook(PCI::Device); 2091 - provided chunk LKM::data();
2092 - provided chunk PCI::pci_probe_hook(PCI::Device);
2093 + provided chunk LKM::data();
2094 + provided chunk PCI::pci_probe_hook(PCI::Device);
1053 2095
1054 - provided pointcut Ethernet::adapter_init_context(Ethernet::Device, 2096 - provided pointcut Ethernet::adapter_init_context(Ethernet::Device,
1055 - Builtin::number, 2097 - Builtin::number,
1056 - Builtin::symbol); 2098 - Builtin::symbol);
2099 + // Init the hardware context structure, doesn't allocate anything:
1057 + provided pointcut Ethernet::adapter_init_context(Ethernet::Device, Builtin::symbol); 2100 + provided pointcut Ethernet::adapter_init_context(Ethernet::Device, Builtin::symbol);
2101 +
2102 + // Reset the adapter:
1058 provided pointcut Ethernet::adapter_reset(Ethernet::Device); 2103 provided pointcut Ethernet::adapter_reset(Ethernet::Device);
2104 +
2105 + // Load the MAC address from the EEPROM and save it into the
2106 + // dev_addr field/attribute of Ethernet::Device:
1059 provided pointcut Ethernet::adapter_load_mac_address(Ethernet::Device); 2107 provided pointcut Ethernet::adapter_load_mac_address(Ethernet::Device);
1060 } 2108 }
2109
1061 diff --git a/rathaxes/samples/e1000/lkm.rtx b/rathaxes/samples/e1000/lkm.rtx 2110 diff --git a/rathaxes/samples/e1000/lkm.rtx b/rathaxes/samples/e1000/lkm.rtx
2111 old mode 100755
2112 new mode 100644
1062 --- a/rathaxes/samples/e1000/lkm.rtx 2113 --- a/rathaxes/samples/e1000/lkm.rtx
1063 +++ b/rathaxes/samples/e1000/lkm.rtx 2114 +++ b/rathaxes/samples/e1000/lkm.rtx
1064 @@ -1,34 +1,5 @@ 2115 @@ -1,40 +1,5 @@
1065 device LKM use LKM, PCI, Ethernet, Log, Socket 2116 device LKM use LKM, PCI, Ethernet, Log, Socket
1066 { 2117 {
1067 - Ethernet::open(Ethernet::Device dev) 2118 - Ethernet::open(Ethernet::Device dev)
1068 - { 2119 - {
1069 - Log::info("opening the device"); 2120 - Log::info("opening the device");
1091 - { 2142 - {
1092 - Log::info("got an interruption"); 2143 - Log::info("got an interruption");
1093 - e1000::handle_interrupt(dev); 2144 - e1000::handle_interrupt(dev);
1094 - } 2145 - }
1095 - 2146 -
1096 Ethernet::send(Ethernet::Device dev, Socket::AbstractSKBuff skb) 2147 - Ethernet::send(Ethernet::Device dev, Socket::AbstractSKBuff skb)
2148 - {
2149 - Log::info("we have one packet to transmit!");
2150 - e1000::xmit(dev, skb);
2151 - }
2152 -
2153 LKM::init()
1097 { 2154 {
1098 Log::info("we have one packet to transmit!"); 2155 Log::info("loading module");
2156 @@ -50,7 +15,7 @@
2157 {
2158 LKM::name = "rtx_e1k";
2159 LKM::author = "Rathaxes";
2160 - LKM::description = "Hello World Loadable Kernel Module (LKM)";
2161 + LKM::description = "Rathaxes Intel PCI Gigabit NIC sample driver";
2162 LKM::license = "GPL";
2163
2164 /*
2165 diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/old_e1000.blt
2166 old mode 100755
2167 new mode 100644
2168 copy from rathaxes/samples/e1000/e1000.blt
2169 copy to rathaxes/samples/e1000/old_e1000.blt
2170 --- a/rathaxes/samples/e1000/e1000.blt
2171 +++ b/rathaxes/samples/e1000/old_e1000.blt
2172 @@ -170,14 +170,15 @@
2173 for (i = 0; i != ${config.rx_ring_size}; ++i)
2174 {
2175 ${Socket::SKBuff.ref} skbuff = &hw_ctx->rx_ring.skbuffs[i];
2176 - // XXX #46: ${rtx_ether_ctx.init_rx_skbuff(local.skbuff, config.rx_buffer_len)};
2177 - if (rtx_ethernet_init_rx_skbuff(${local.skbuff}, ${config.rx_buffer_len}))
2178 + // XXX #46: ${rtx_ether_ctx.alloc_rx_skbuff(local.skbuff, config.rx_buffer_len)};
2179 + if (rtx_ethernet_alloc_rx_skbuff(${local.skbuff}, ${config.rx_buffer_len}))
2180 {
2181 ${Log::info("adapter_init_rx: cannot allocate a skbuff for the rx ring")};
2182 goto err_skbuffs_alloc;
2183 }
2184 - // XXX #46: ${local.skbuff.map_from(rtx_ether_ctx.device)};
2185 - if (rtx_socket_skbuff_map(${local.skbuff}, ${rtx_ether_ctx.device}, RTX_DMA_FROM_DEVICE))
2186 + /* XXX: recuperer le dma handle et le placer correctement dans le descripteur. */
2187 + ${DMA::map(local.rtx_ether_ctx.device, local.skbuff.data, local.skbuff.len, RTX_DMA_FROM_DEVICE)}
2188 + if (${DMA::map(local.rtx_ether_ctx.device, local.skbuff.data, local.skbuff.len, RTX_DMA_FROM_DEVICE)})
2189 {
2190 ${Log::info("adapter_init_rx: cannot dma-map a skbuff for the rx ring")};
2191 goto err_skbuffs_map;
2192 diff --git a/rathaxes/samples/e1000/e1000.rti b/rathaxes/samples/e1000/old_e1000.rti
2193 old mode 100755
2194 new mode 100644
2195 copy from rathaxes/samples/e1000/e1000.rti
2196 copy to rathaxes/samples/e1000/old_e1000.rti
1099 diff --git a/rathaxes/samples/e1000/socket.blt b/rathaxes/samples/e1000/socket.blt 2197 diff --git a/rathaxes/samples/e1000/socket.blt b/rathaxes/samples/e1000/socket.blt
2198 old mode 100755
2199 new mode 100644
1100 --- a/rathaxes/samples/e1000/socket.blt 2200 --- a/rathaxes/samples/e1000/socket.blt
1101 +++ b/rathaxes/samples/e1000/socket.blt 2201 +++ b/rathaxes/samples/e1000/socket.blt
1102 @@ -22,16 +22,12 @@ 2202 @@ -22,16 +22,12 @@
1103 { 2203 {
1104 decl data_types() 2204 decl data_types()
1115 - static int rtx_socket_skbuff_map(${Socket::SKBuff.ref}, ${Device::AbstractDevice.ref}, ${DMA::DMADirection.scalar}); 2215 - static int rtx_socket_skbuff_map(${Socket::SKBuff.ref}, ${Device::AbstractDevice.ref}, ${DMA::DMADirection.scalar});
1116 - static void rtx_socket_skbuff_unmap_and_free(${Socket::SKBuff.ref}, ${Device::AbstractDevice.ref}, ${DMA::DMADirection.scalar}); 2216 - static void rtx_socket_skbuff_unmap_and_free(${Socket::SKBuff.ref}, ${Device::AbstractDevice.ref}, ${DMA::DMADirection.scalar});
1117 } 2217 }
1118 2218
1119 chunk LKM::code() 2219 chunk LKM::code()
1120 @@ -63,85 +59,6 @@ 2220 @@ -52,98 +48,29 @@
1121 shinfo->nr_frags, shinfo->gso_size, shinfo->gso_segs, shinfo->gso_type 2221 * arguments yet.
2222 */
2223 pr_info(
2224 - "\t protocol = %#-5x (%s) ip_summed = %d (%s)\n"
2225 - "\t len = %-5u data_len = %-5u head_len = %-5u\n"
2226 - "\t nr_frags = %u\n"
2227 - "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u",
2228 - /* XXX: can't use ${local.ethernet_proto.id} here (issue #52): */
2229 - ethernet_proto.id, ${local.ethernet_proto.str},
2230 - ${local.self.sk_buff.k_sk_buff}->ip_summed, ip_summed_values[${local.self.sk_buff.k_sk_buff}->ip_summed],
2231 - ${local.self.sk_buff.k_sk_buff}->len, ${local.self.sk_buff.k_sk_buff}->data_len, skb_headlen(${local.self.sk_buff.k_sk_buff}),
2232 - shinfo->nr_frags, shinfo->gso_size, shinfo->gso_segs, shinfo->gso_type
2233 + "\t protocol = %#-5x (%s) ip_summed = %d (%s)\n"
2234 + "\t len = %-5u data_len = %-5u head_len = %-5u\n"
2235 + "\t nr_frags = %u\n"
2236 + "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u",
2237 + /* XXX: can't use ${local.ethernet_proto.id} here (issue #52): */
2238 + ethernet_proto.id, ${local.ethernet_proto.str},
2239 + ${local.self.sk_buff.k_sk_buff}->ip_summed, ip_summed_values[${local.self.sk_buff.k_sk_buff}->ip_summed],
2240 + ${local.self.sk_buff.k_sk_buff}->len, ${local.self.sk_buff.k_sk_buff}->data_len, skb_headlen(${local.self.sk_buff.k_sk_buff}),
2241 + shinfo->nr_frags, shinfo->gso_size, shinfo->gso_segs, shinfo->gso_type
1122 ); 2242 );
1123 } 2243 }
1124 - 2244 -
1125 - static int rtx_socket_skbuff_map(${Socket::SKBuff.ref} self, 2245 - static int rtx_socket_skbuff_map(${Socket::SKBuff.ref} self,
1126 - ${Device::AbstractDevice.ref} dev, 2246 - ${Device::AbstractDevice.ref} dev,
1161 - ${local.self.dma_handle} = 0; 2281 - ${local.self.dma_handle} = 0;
1162 - } 2282 - }
1163 - dev_kfree_skb_any(${local.self.sk_buff.k_sk_buff}); 2283 - dev_kfree_skb_any(${local.self.sk_buff.k_sk_buff});
1164 - ${local.self.sk_buff} = NULL; 2284 - ${local.self.sk_buff} = NULL;
1165 - } 2285 - }
1166 - } 2286 }
1167 - 2287
1168 - /* 2288 - /*
1169 - * XXX: the rathaxes argument kernel_skb is not actually bound to the 2289 - * XXX: the rathaxes argument kernel_skb is not actually bound to the
1170 - * correct C variable from Ethernet::send() (so I named it as the C 2290 - * correct C variable from Ethernet::send() (so I named it as the C
1171 - * variable I needed) 2291 - * variable I needed)
1172 - */ 2292 - */
1173 - method init(Socket::AbstractSKBuff kernel_skb, Builtin::number size) 2293 - method init(Socket::AbstractSKBuff kernel_skb, Builtin::number size)
1174 - { 2294 + method init(Socket::AbstractSKBuff k_skb)
2295 {
1175 - ${self.sk_buff} = ${kernel_skb}; 2296 - ${self.sk_buff} = ${kernel_skb};
1176 - ${self.size} = ${size}; 2297 - ${self.size} = ${size};
1177 - ${self.dma_handle} = 0; 2298 - ${self.dma_handle} = 0;
1178 - } 2299 + ${self} = (${Socket::SKBuff.ref})(${k_skb});
1179 - 2300 }
2301
1180 - method dump_infos() 2302 - method dump_infos()
1181 - { 2303 + method dump_infos()
1182 - rtx_socket_skbuff_dump_infos(${self}); 2304 {
1183 - } 2305 rtx_socket_skbuff_dump_infos(${self});
1184 - 2306 }
2307
1185 - method map_to(Device::AbstractDevice dev) 2308 - method map_to(Device::AbstractDevice dev)
1186 - { 2309 - {
1187 - rtx_socket_skbuff_map(${self}, ${dev}, RTX_DMA_TO_DEVICE); 2310 - rtx_socket_skbuff_map(${self}, ${dev}, RTX_DMA_TO_DEVICE);
1188 - } 2311 - }
1189 - 2312 -
1198 - } 2321 - }
1199 - 2322 -
1200 - method unmap_from_and_free(Device::AbstractDevice dev) 2323 - method unmap_from_and_free(Device::AbstractDevice dev)
1201 - { 2324 - {
1202 - rtx_socket_skbuff_unmap_and_free(${self}, ${dev}, RTX_DMA_FROM_DEVICE); 2325 - rtx_socket_skbuff_unmap_and_free(${self}, ${dev}, RTX_DMA_FROM_DEVICE);
1203 } 2326 - }
1204 2327 -
1205 map 2328 map
1206 @@ -151,13 +68,9 @@ 2329 {
2330 // Some work may have to be done here in order to access to some
2331 @@ -151,13 +78,9 @@
1207 // management can be abstracted from the user. But this is at least 2332 // management can be abstracted from the user. But this is at least
1208 // useful for internal use: 2333 // useful for internal use:
1209 sk_buff: (${self})->skbuff; 2334 sk_buff: (${self})->skbuff;
1210 - // XXX: We need to cast here so we can do things like 2335 - // XXX: We need to cast here so we can do things like
1211 - // var.dma_handle = 0; but the type shouldn't be hardcoded (at the 2336 - // var.dma_handle = 0; but the type shouldn't be hardcoded (at the
1219 + len: ((struct sk_buff *)((${self})->sk_buff))->len; 2344 + len: ((struct sk_buff *)((${self})->sk_buff))->len;
1220 } 2345 }
1221 } 2346 }
1222 } 2347 }
1223 diff --git a/rathaxes/samples/e1000/socket.rti b/rathaxes/samples/e1000/socket.rti 2348 diff --git a/rathaxes/samples/e1000/socket.rti b/rathaxes/samples/e1000/socket.rti
2349 old mode 100755
2350 new mode 100644
1224 --- a/rathaxes/samples/e1000/socket.rti 2351 --- a/rathaxes/samples/e1000/socket.rti
1225 +++ b/rathaxes/samples/e1000/socket.rti 2352 +++ b/rathaxes/samples/e1000/socket.rti
1226 @@ -12,20 +12,14 @@ 2353 @@ -12,20 +12,14 @@
1227 { 2354 {
1228 chunk LKM::prototypes(); 2355 chunk LKM::prototypes();