comparison e1000_implement_the_frame_transmission_chunk.patch @ 90:4968acb39c7b

Finalize work on minimal TX
author Louis Opter <louis@lse.epitech.net>
date Mon, 15 Oct 2012 06:17:32 +0200
parents a9b47a2f8b98
children
comparison
equal deleted inserted replaced
89:a9b47a2f8b98 90:4968acb39c7b
1 # HG changeset patch 1 # HG changeset patch
2 # Parent 87ba2a19a59fb7be346ad40a57439b6b752b152e 2 # Parent 87ba2a19a59fb7be346ad40a57439b6b752b152e
3 rathaxes: start to queue up packets in the TX ring on the e1000 sample 3 rathaxes: add the transmission code for very simple packets in the e1000 sample
4
5 Very simple packets are those which don't need to be fragmented nor checksummed.
6
7 The transmission code is defined in different chunks/methods of the TxRing type.
8 An e1000::xmit method template has been added to call the different methods on
9 the TxRing object in the e1000::Context object. The interrupt handler has been
10 reworked to handle transmission interrupts and cleanup the TxRing accordingly.
11
12 In parallel to the transmission code, the Socket::SKBuff type is now a real
13 Rathaxes type with its own debug and DMA operations methods.
14
15 Also, sorry, this changeset is mixed with other changes:
16
17 - Small improvements everywhere now that the compiler uses CNorm unstrict;
18 - Add the Device::AbstractDevice type; this Rathaxes represents the generic type
19 used by the kernel to represent a device;
20 - Add the Socket::AbstractSKBuff type too to represent the SKBuff type used by
21 the kernel;
22 - Likewise the Ethernet::AbstractDevice type represents the type used by the
23 kernel for Ethernet devices;
24 - Socket::SKBuff is now a real Rathaxes type which aggregates a KernelSKBuff
25 object.
4 26
5 diff --git a/rathaxes/samples/e1000/CMakeLists.txt b/rathaxes/samples/e1000/CMakeLists.txt 27 diff --git a/rathaxes/samples/e1000/CMakeLists.txt b/rathaxes/samples/e1000/CMakeLists.txt
6 --- a/rathaxes/samples/e1000/CMakeLists.txt 28 --- a/rathaxes/samples/e1000/CMakeLists.txt
7 +++ b/rathaxes/samples/e1000/CMakeLists.txt 29 +++ b/rathaxes/samples/e1000/CMakeLists.txt
8 @@ -1,6 +1,22 @@ 30 @@ -1,6 +1,22 @@
36 --- /dev/null 58 --- /dev/null
37 +++ b/rathaxes/samples/e1000/device.blt 59 +++ b/rathaxes/samples/e1000/device.blt
38 @@ -0,0 +1,25 @@ 60 @@ -0,0 +1,25 @@
39 +with Device, LKM 61 +with Device, LKM
40 +{ 62 +{
41 + template type Device::Device() 63 + template type Device::AbstractDevice()
42 + { 64 + {
43 + chunk LKM::includes() 65 + chunk LKM::includes()
44 + { 66 + {
45 + #include <linux/device.h> 67 + #include <linux/device.h>
46 + 68 +
47 + static const ${Device::Device} force_rtx_device_decl; 69 + static const ${Device::AbstractDevice} force_rtx_device_decl;
48 + } 70 + }
49 + 71 +
50 + chunk decl() 72 + chunk decl()
51 + { 73 + {
52 + typedef struct device *rtx_device_p; 74 + typedef struct device *rtx_device_p;
66 --- /dev/null 88 --- /dev/null
67 +++ b/rathaxes/samples/e1000/device.rti 89 +++ b/rathaxes/samples/e1000/device.rti
68 @@ -0,0 +1,9 @@ 90 @@ -0,0 +1,9 @@
69 +interface Device : LKM 91 +interface Device : LKM
70 +{ 92 +{
71 + provided type Device 93 + provided type AbstractDevice
72 + { 94 + {
73 + chunk LKM::includes(); 95 + chunk LKM::includes();
74 + method decl(); 96 + method decl();
75 + method init(); 97 + method init();
76 + } 98 + }
186 + * Keep in mind that the head and tail fields are, obviously, not 208 + * Keep in mind that the head and tail fields are, obviously, not
187 + * synchronized with TDT/TDH on the device. 209 + * synchronized with TDT/TDH on the device.
188 */ 210 */
189 template type e1000::TxRing() 211 template type e1000::TxRing()
190 { 212 {
191 @@ -148,11 +151,88 @@ 213 @@ -148,11 +151,112 @@
192 struct rtx_e1000_tx_ring 214 struct rtx_e1000_tx_ring
193 { 215 {
194 unsigned int size; 216 unsigned int size;
195 - struct rtx_e1000_tx_descriptor *base; 217 - struct rtx_e1000_tx_descriptor *base;
196 - void* /* dma_addr_t */ dma_base; 218 - void* /* dma_addr_t */ dma_base;
197 + /* XXX: can't use ${e1000::TxDescriptor} here: */ 219 + /* XXX: can't use ${e1000::TxDescriptor} here: */
198 + struct rtx_e1000_tx_descriptor *base; /* rename to descs */ 220 + struct rtx_e1000_tx_descriptor *base; /* rename to descs */
199 + dma_addr_t dma_base; 221 + dma_addr_t dma_base;
200 + ${Socket::SKBuff} skbuffs[${config.tx_ring_size}]; 222 + ${Socket::SKBuff} skbuffs[${config.tx_ring_size}];
201 + unsigned int head; 223 + unsigned short head;
202 + unsigned int tail; 224 + unsigned short tail;
203 }; 225 };
204 } 226 }
205 227
206 + chunk LKM::prototypes() 228 + chunk LKM::prototypes()
207 + { 229 + {
230 + static void rtx_e1000_tx_ring_clean(struct rtx_e1000_tx_ring *);
208 + static unsigned int rtx_e1000_tx_ring_descriptors_remaining(struct rtx_e1000_tx_ring *); 231 + static unsigned int rtx_e1000_tx_ring_descriptors_remaining(struct rtx_e1000_tx_ring *);
209 + static int rtx_e1000_tx_ring_tso_cksum_offload(struct rtx_e1000_tx_ring *, struct rtx_socket_skbuff *); 232 + static int rtx_e1000_tx_ring_tso_cksum_offload(struct rtx_e1000_tx_ring *, struct rtx_socket_skbuff *);
210 + static void rtx_e1000_tx_ring_put(struct rtx_e1000_tx_ring *, struct rtx_socket_skbuff *); 233 + static void rtx_e1000_tx_ring_put(struct rtx_e1000_tx_ring *, struct rtx_socket_skbuff *);
211 + static void rtx_e1000_tx_ring_start_xmit(struct rtx_e1000_tx_ring *, const struct rtx_e1000_ctx *); 234 + static void rtx_e1000_tx_ring_start_xmit(struct rtx_e1000_tx_ring *, const struct rtx_e1000_ctx *);
212 + } 235 + }
213 + 236 +
214 + chunk LKM::code() 237 + chunk LKM::code()
215 + { 238 + {
239 + static void rtx_e1000_tx_ring_clean(struct rtx_e1000_tx_ring *self)
240 + {
241 + ${e1000::TxDescriptor} *tx_desc;
242 + bool done;
243 +
244 + for (; self->head != self->tail; self->head++)
245 + {
246 + tx_desc = &self->base[self->head];
247 + done = tx_desc->upper.fields.status & E1000_TXD_STAT_DD;
248 + if (!done)
249 + break ;
250 + }
251 +
252 + pr_info("%s: tx_ring_clean: moving head to %d/%d", ${config.name}, self->head, ${config.tx_ring_size});
253 + }
254 +
216 + static unsigned int rtx_e1000_tx_ring_descriptors_remaining(struct rtx_e1000_tx_ring *self) 255 + static unsigned int rtx_e1000_tx_ring_descriptors_remaining(struct rtx_e1000_tx_ring *self)
217 + { 256 + {
218 + if (self->tail == self->head) /* ring is empty */ 257 + if (self->tail == self->head) /* ring is empty */
219 + return 256; /* XXX: ${config.tx_ring_size}; */ 258 + return 256; /* XXX: ${config.tx_ring_size}; */
220 + if (self->tail > self->head) 259 + if (self->tail > self->head)
242 + */ 281 + */
243 + struct rtx_e1000_tx_descriptor *tx_desc = &self->base[self->tail]; 282 + struct rtx_e1000_tx_descriptor *tx_desc = &self->base[self->tail];
244 + tx_desc->lower.data = cpu_to_le32( 283 + tx_desc->lower.data = cpu_to_le32(
245 + E1000_TXD_CMD_EOP | 284 + E1000_TXD_CMD_EOP |
246 + E1000_TXD_CMD_IFCS | 285 + E1000_TXD_CMD_IFCS |
286 + E1000_TXD_CMD_RS |
247 + skb_headlen(skb->skbuff)); 287 + skb_headlen(skb->skbuff));
248 + tx_desc->upper.data = 0; 288 + tx_desc->upper.data = 0;
249 + tx_desc->buff_addr = cpu_to_le64(skb->dma_handle); 289 + tx_desc->buff_addr = cpu_to_le64(skb->dma_handle);
250 + memcpy(&self->skbuffs[self->tail], skb, sizeof(*skb)); 290 + memcpy(&self->skbuffs[self->tail], skb, sizeof(*skb));
251 + self->tail = (self->tail + 1) % 256 /* XXX: ${config.tx_ring_size} */; 291 + self->tail = (self->tail + 1) % ${config.tx_ring_size};
252 + } 292 + }
253 + 293 +
254 + static void rtx_e1000_tx_ring_start_xmit(struct rtx_e1000_tx_ring *self, const struct rtx_e1000_ctx *hw_ctx) 294 + static void rtx_e1000_tx_ring_start_xmit(struct rtx_e1000_tx_ring *self, const struct rtx_e1000_ctx *hw_ctx)
255 + { 295 + {
296 + pr_info("%s: start_xmit: moving tail to %d/%d", ${config.name}, self->tail, ${config.tx_ring_size});
256 + rtx_e1000_register_write32(hw_ctx, E1000_TDT, self->tail); 297 + rtx_e1000_register_write32(hw_ctx, E1000_TDT, self->tail);
257 + } 298 + }
258 + } 299 + }
259 + 300 +
301 + chunk clean()
302 + {
303 + rtx_e1000_tx_ring_clean(${self});
304 + }
305 +
260 + chunk descriptors_remaining() 306 + chunk descriptors_remaining()
261 + { 307 + {
262 + rtx_e1000_tx_ring_descriptors_remaining(${self}); 308 + rtx_e1000_tx_ring_descriptors_remaining(${self});
263 + } 309 + }
264 + 310 +
277 + } 323 + }
278 + 324 +
279 chunk ::init() 325 chunk ::init()
280 { 326 {
281 } 327 }
282 @@ -334,6 +414,45 @@ 328 @@ -334,6 +438,45 @@
283 } 329 }
284 } 330 }
285 331
286 + template type e1000::TxDescriptorFlags() 332 + template type e1000::TxDescriptorFlags()
287 + { 333 + {
323 + } 369 + }
324 + 370 +
325 template sequence e1000::create_device() 371 template sequence e1000::create_device()
326 { 372 {
327 chunk Ethernet::create_device(PCI::Device pdev, Ethernet::Device rtx_ether_ctx) 373 chunk Ethernet::create_device(PCI::Device pdev, Ethernet::Device rtx_ether_ctx)
328 @@ -376,8 +495,7 @@ 374 @@ -376,8 +519,7 @@
329 udelay(10); 375 udelay(10);
330 376
331 /* Now we can load its mac address (thanks minix code) */ 377 /* Now we can load its mac address (thanks minix code) */
332 - int i = 0; 378 - int i = 0;
333 - for (i = 0 /* < this is not generated! (cnorm bug) */; i < 3; ++i) 379 - for (i = 0 /* < this is not generated! (cnorm bug) */; i < 3; ++i)
334 + for (int i = 0; i < 3; ++i) 380 + for (int i = 0; i < 3; ++i)
335 { 381 {
336 rtx_e1000_register_write32(&${rtx_ether_ctx}->hw_ctx, E1000_EEPROM_READ, (i << 8) | 1); 382 rtx_e1000_register_write32(&${rtx_ether_ctx}->hw_ctx, E1000_EEPROM_READ, (i << 8) | 1);
337 383
338 @@ -420,6 +538,7 @@ 384 @@ -420,6 +562,7 @@
339 } 385 }
340 } 386 }
341 387
342 + /* TODO: make that a method of e1000::Context */ 388 + /* TODO: make that a method of e1000::Context */
343 template sequence e1000::print_status(Ethernet::Device ctx) 389 template sequence e1000::print_status(Ethernet::Device ctx)
344 { 390 {
345 chunk LKM::prototypes() 391 chunk LKM::prototypes()
346 @@ -466,17 +585,19 @@ 392 @@ -466,17 +609,19 @@
347 * ${e1000.init(E1000_STATUS); // didn't work, so we used the next line 393 * ${e1000.init(E1000_STATUS); // didn't work, so we used the next line
348 * reg_status = E1000_STATUS; 394 * reg_status = E1000_STATUS;
349 * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, reg_status)}; 395 * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, reg_status)};
350 + * 396 + *
351 + * TODO: make them methods of e1000::Context 397 + * TODO: make them methods of e1000::Context
363 - static unsigned int rtx_e1000_register_read32(struct rtx_e1000_ctx *ctx, unsigned int reg_offset) 409 - static unsigned int rtx_e1000_register_read32(struct rtx_e1000_ctx *ctx, unsigned int reg_offset)
364 + static unsigned int rtx_e1000_register_read32(const struct rtx_e1000_ctx *ctx, unsigned int reg_offset) 410 + static unsigned int rtx_e1000_register_read32(const struct rtx_e1000_ctx *ctx, unsigned int reg_offset)
365 { 411 {
366 return ioread32(ctx->ioaddr + reg_offset); 412 return ioread32(ctx->ioaddr + reg_offset);
367 } 413 }
368 @@ -492,12 +613,12 @@ 414 @@ -492,12 +637,12 @@
369 { 415 {
370 chunk LKM::prototypes() 416 chunk LKM::prototypes()
371 { 417 {
372 - static void rtx_e1000_register_write32(struct rtx_e1000_ctx *, unsigned int, unsigned int); 418 - static void rtx_e1000_register_write32(struct rtx_e1000_ctx *, unsigned int, unsigned int);
373 + static void rtx_e1000_register_write32(const struct rtx_e1000_ctx *, unsigned int, unsigned int); 419 + static void rtx_e1000_register_write32(const struct rtx_e1000_ctx *, unsigned int, unsigned int);
378 - static void rtx_e1000_register_write32(struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value) 424 - static void rtx_e1000_register_write32(struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value)
379 + static void rtx_e1000_register_write32(const struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value) 425 + static void rtx_e1000_register_write32(const struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value)
380 { 426 {
381 iowrite32(value, ctx->ioaddr + reg_offset); 427 iowrite32(value, ctx->ioaddr + reg_offset);
382 } 428 }
383 @@ -513,12 +634,12 @@ 429 @@ -513,12 +658,12 @@
384 { 430 {
385 chunk LKM::prototypes() 431 chunk LKM::prototypes()
386 { 432 {
387 - static void rtx_e1000_register_set32(struct rtx_e1000_ctx *, unsigned int, unsigned int); 433 - static void rtx_e1000_register_set32(struct rtx_e1000_ctx *, unsigned int, unsigned int);
388 + static void rtx_e1000_register_set32(const struct rtx_e1000_ctx *, unsigned int, unsigned int); 434 + static void rtx_e1000_register_set32(const struct rtx_e1000_ctx *, unsigned int, unsigned int);
393 - static void rtx_e1000_register_set32(struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value) 439 - static void rtx_e1000_register_set32(struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value)
394 + static void rtx_e1000_register_set32(const struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value) 440 + static void rtx_e1000_register_set32(const struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value)
395 { 441 {
396 iowrite32(rtx_e1000_register_read32(ctx, reg_offset) | value, ctx->ioaddr + reg_offset); 442 iowrite32(rtx_e1000_register_read32(ctx, reg_offset) | value, ctx->ioaddr + reg_offset);
397 } 443 }
398 @@ -534,12 +655,12 @@ 444 @@ -534,12 +679,12 @@
399 { 445 {
400 chunk LKM::prototypes() 446 chunk LKM::prototypes()
401 { 447 {
402 - static void rtx_e1000_register_unset32(struct rtx_e1000_ctx *, unsigned int, unsigned int); 448 - static void rtx_e1000_register_unset32(struct rtx_e1000_ctx *, unsigned int, unsigned int);
403 + static void rtx_e1000_register_unset32(const struct rtx_e1000_ctx *, unsigned int, unsigned int); 449 + static void rtx_e1000_register_unset32(const struct rtx_e1000_ctx *, unsigned int, unsigned int);
408 - static void rtx_e1000_register_unset32(struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value) 454 - static void rtx_e1000_register_unset32(struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value)
409 + static void rtx_e1000_register_unset32(const struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value) 455 + static void rtx_e1000_register_unset32(const struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value)
410 { 456 {
411 iowrite32(rtx_e1000_register_read32(ctx, reg_offset) & ~value, ctx->ioaddr + reg_offset); 457 iowrite32(rtx_e1000_register_read32(ctx, reg_offset) & ~value, ctx->ioaddr + reg_offset);
412 } 458 }
413 @@ -626,12 +747,18 @@ 459 @@ -626,12 +771,18 @@
414 } 460 }
415 } 461 }
416 462
417 + /* TODO: refactor 463 + /* TODO: refactor
418 + * 464 + *
429 - typedef unsigned long int dma_addr_t; 475 - typedef unsigned long int dma_addr_t;
430 - 476 -
431 /* 477 /*
432 * This part is documented in the Intel Gigabit Ethernet Controller 478 * This part is documented in the Intel Gigabit Ethernet Controller
433 * Software Developper manual. (You can find it in the doc/hardware 479 * Software Developper manual. (You can find it in the doc/hardware
434 @@ -663,6 +790,8 @@ 480 @@ -663,6 +814,8 @@
435 * E1000_CRCERRS to E1000_TSCTFC. 481 * E1000_CRCERRS to E1000_TSCTFC.
436 */ 482 */
437 483
438 + int i; 484 + int i;
439 + 485 +
440 rtx_e1000_register_set32(hw_ctx, E1000_CTRL, 486 rtx_e1000_register_set32(hw_ctx, E1000_CTRL,
441 E1000_CMD_ASDE | 487 E1000_CMD_ASDE |
442 E1000_CMD_SLU); 488 E1000_CMD_SLU);
443 @@ -676,7 +805,6 @@ 489 @@ -676,7 +829,6 @@
444 rtx_e1000_register_write32(hw_ctx, E1000_FCAL, 0); 490 rtx_e1000_register_write32(hw_ctx, E1000_FCAL, 0);
445 rtx_e1000_register_write32(hw_ctx, E1000_FCT, 0); 491 rtx_e1000_register_write32(hw_ctx, E1000_FCT, 0);
446 rtx_e1000_register_write32(hw_ctx, E1000_FCTTV, 0); 492 rtx_e1000_register_write32(hw_ctx, E1000_FCTTV, 0);
447 - int i = 0; /* CNorm workaround, the init part of for isn't generated */ 493 - int i = 0; /* CNorm workaround, the init part of for isn't generated */
448 for (i = 0; i != 64; ++i) 494 for (i = 0; i != 64; ++i)
449 rtx_e1000_register_write32(hw_ctx, E1000_CRCERRS + i * 4, 0); 495 rtx_e1000_register_write32(hw_ctx, E1000_CRCERRS + i * 4, 0);
450 496
451 @@ -719,7 +847,6 @@ 497 @@ -719,7 +871,6 @@
452 498
453 /* 2. Initialize the MTA */ 499 /* 2. Initialize the MTA */
454 500
455 - i = 0; /* CNorm workaround, the init part of for isn't generated */ 501 - i = 0; /* CNorm workaround, the init part of for isn't generated */
456 for (i = 0; i != 128; ++i) 502 for (i = 0; i != 128; ++i)
457 rtx_e1000_register_write32(hw_ctx, E1000_MTA + i * 4, 0); 503 rtx_e1000_register_write32(hw_ctx, E1000_MTA + i * 4, 0);
458 504
459 @@ -733,7 +860,7 @@ 505 @@ -733,7 +884,7 @@
460 hw_ctx->rx_ring.base = dma_alloc_coherent( 506 hw_ctx->rx_ring.base = dma_alloc_coherent(
461 &${ctx}->pci_dev->dev, 507 &${ctx}->pci_dev->dev,
462 hw_ctx->rx_ring.size, 508 hw_ctx->rx_ring.size,
463 - (dma_addr_t *)&hw_ctx->rx_ring.dma_base, 509 - (dma_addr_t *)&hw_ctx->rx_ring.dma_base,
464 + &hw_ctx->rx_ring.dma_base, 510 + &hw_ctx->rx_ring.dma_base,
465 GFP_KERNEL); 511 GFP_KERNEL);
466 if (!hw_ctx->rx_ring.base) 512 if (!hw_ctx->rx_ring.base)
467 { 513 {
468 @@ -747,41 +874,37 @@ 514 @@ -747,41 +898,37 @@
469 * Allocate the skbuffs, map them for DMA, and write their address 515 * Allocate the skbuffs, map them for DMA, and write their address
470 * in the corresponding descriptor. 516 * in the corresponding descriptor.
471 */ 517 */
472 - i = 0; 518 - i = 0;
473 for (i = 0; i != ${config.rx_ring_size}; ++i) 519 for (i = 0; i != ${config.rx_ring_size}; ++i)
516 + rtx_e1000_register_write32(hw_ctx, E1000_RDBAL, hw_ctx->rx_ring.dma_base & 0xffffffff); 562 + rtx_e1000_register_write32(hw_ctx, E1000_RDBAL, hw_ctx->rx_ring.dma_base & 0xffffffff);
517 + rtx_e1000_register_write32(hw_ctx, E1000_RDBAH, hw_ctx->rx_ring.dma_base >> 32); 563 + rtx_e1000_register_write32(hw_ctx, E1000_RDBAH, hw_ctx->rx_ring.dma_base >> 32);
518 rtx_e1000_register_write32(hw_ctx, E1000_RDLEN, hw_ctx->rx_ring.size); 564 rtx_e1000_register_write32(hw_ctx, E1000_RDLEN, hw_ctx->rx_ring.size);
519 565
520 /* 6. Setup RDH/RDT */ 566 /* 6. Setup RDH/RDT */
521 @@ -820,7 +943,7 @@ 567 @@ -820,7 +967,7 @@
522 hw_ctx->tx_ring.base = dma_alloc_coherent( 568 hw_ctx->tx_ring.base = dma_alloc_coherent(
523 &${ctx}->pci_dev->dev, 569 &${ctx}->pci_dev->dev,
524 hw_ctx->tx_ring.size, 570 hw_ctx->tx_ring.size,
525 - (dma_addr_t *)&hw_ctx->tx_ring.dma_base, 571 - (dma_addr_t *)&hw_ctx->tx_ring.dma_base,
526 + &hw_ctx->tx_ring.dma_base, 572 + &hw_ctx->tx_ring.dma_base,
527 GFP_KERNEL); 573 GFP_KERNEL);
528 if (!hw_ctx->rx_ring.base) 574 if (!hw_ctx->rx_ring.base)
529 { 575 {
530 @@ -831,13 +954,15 @@ 576 @@ -831,16 +978,18 @@
531 ${Log::info("setup_device: tx descriptors allocated")}; 577 ${Log::info("setup_device: tx descriptors allocated")};
532 578
533 /* 2. Save the emplacement and the size of the ring in TDBA/TDLEN */ 579 /* 2. Save the emplacement and the size of the ring in TDBA/TDLEN */
534 - rtx_e1000_register_write32(hw_ctx, E1000_TDBAL, (dma_addr_t)hw_ctx->tx_ring.dma_base & 0xffffffff); 580 - rtx_e1000_register_write32(hw_ctx, E1000_TDBAL, (dma_addr_t)hw_ctx->tx_ring.dma_base & 0xffffffff);
535 - rtx_e1000_register_write32(hw_ctx, E1000_TDBAH, (dma_addr_t)hw_ctx->tx_ring.dma_base >> 32); 581 - rtx_e1000_register_write32(hw_ctx, E1000_TDBAH, (dma_addr_t)hw_ctx->tx_ring.dma_base >> 32);
542 rtx_e1000_register_write32(hw_ctx, E1000_TDT, 0); 588 rtx_e1000_register_write32(hw_ctx, E1000_TDT, 0);
543 + hw_ctx->tx_ring.head = 0; 589 + hw_ctx->tx_ring.head = 0;
544 + hw_ctx->tx_ring.tail = 0; 590 + hw_ctx->tx_ring.tail = 0;
545 591
546 /* 4. Set TCTL.PSP and enable the transmitter */ 592 /* 4. Set TCTL.PSP and enable the transmitter */
547 rtx_e1000_register_set32(hw_ctx, E1000_TCTL, E1000_TCTL_PSP|E1000_TCTL_PSP); 593 - rtx_e1000_register_set32(hw_ctx, E1000_TCTL, E1000_TCTL_PSP|E1000_TCTL_PSP);
548 @@ -860,15 +985,15 @@ 594 + rtx_e1000_register_set32(hw_ctx, E1000_TCTL, E1000_TCTL_PSP|E1000_TCTL_EN);
595
596 ${Log::info("transmit registers configured and transmitter enabled")};
597
598 @@ -860,15 +1009,15 @@
549 { 599 {
550 dma_unmap_single( 600 dma_unmap_single(
551 &${ctx}->pci_dev->dev, 601 &${ctx}->pci_dev->dev,
552 - (dma_addr_t)hw_ctx->rx_ring.dma_skbuffs[i], 602 - (dma_addr_t)hw_ctx->rx_ring.dma_skbuffs[i],
553 + hw_ctx->rx_ring.skbuffs[i].dma_handle, 603 + hw_ctx->rx_ring.skbuffs[i].dma_handle,
562 - hw_ctx->rx_ring.base, (dma_addr_t)hw_ctx->rx_ring.dma_base); 612 - hw_ctx->rx_ring.base, (dma_addr_t)hw_ctx->rx_ring.dma_base);
563 + hw_ctx->rx_ring.base, hw_ctx->rx_ring.dma_base); 613 + hw_ctx->rx_ring.base, hw_ctx->rx_ring.dma_base);
564 err_rx_ring_alloc: 614 err_rx_ring_alloc:
565 return -ENOMEM; 615 return -ENOMEM;
566 616
567 @@ -876,12 +1001,15 @@ 617 @@ -876,12 +1025,15 @@
568 } 618 }
569 } 619 }
570 620
571 + /* TODO: 621 + /* TODO:
572 + * 622 + *
580 - typedef unsigned long int dma_addr_t; 630 - typedef unsigned long int dma_addr_t;
581 - 631 -
582 ${e1000::Context} *hw_ctx; 632 ${e1000::Context} *hw_ctx;
583 hw_ctx = &${ctx}->hw_ctx; 633 hw_ctx = &${ctx}->hw_ctx;
584 634
585 @@ -890,18 +1018,17 @@ 635 @@ -890,18 +1042,17 @@
586 * - Unmap and free the skbuffs; 636 * - Unmap and free the skbuffs;
587 * - Free the descriptors array. 637 * - Free the descriptors array.
588 */ 638 */
589 - int i = 0; 639 - int i = 0;
590 - for (i = 0; i != ${config.rx_ring_size}; ++i) 640 - for (i = 0; i != ${config.rx_ring_size}; ++i)
603 - hw_ctx->rx_ring.base, (dma_addr_t)hw_ctx->rx_ring.dma_base); 653 - hw_ctx->rx_ring.base, (dma_addr_t)hw_ctx->rx_ring.dma_base);
604 + hw_ctx->rx_ring.base, hw_ctx->rx_ring.dma_base); 654 + hw_ctx->rx_ring.base, hw_ctx->rx_ring.dma_base);
605 ${Log::info("free_rx_tx: rx ring free'ed")}; 655 ${Log::info("free_rx_tx: rx ring free'ed")};
606 656
607 /* 657 /*
608 @@ -909,7 +1036,7 @@ 658 @@ -909,7 +1060,7 @@
609 * - Free the descriptors array. 659 * - Free the descriptors array.
610 */ 660 */
611 dma_free_coherent(&${ctx}->pci_dev->dev, hw_ctx->tx_ring.size, 661 dma_free_coherent(&${ctx}->pci_dev->dev, hw_ctx->tx_ring.size,
612 - hw_ctx->tx_ring.base, (dma_addr_t)hw_ctx->tx_ring.dma_base); 662 - hw_ctx->tx_ring.base, (dma_addr_t)hw_ctx->tx_ring.dma_base);
613 + hw_ctx->tx_ring.base, hw_ctx->tx_ring.dma_base); 663 + hw_ctx->tx_ring.base, hw_ctx->tx_ring.dma_base);
614 ${Log::info("free_rx_tx: tx ring free'ed")}; 664 ${Log::info("free_rx_tx: tx ring free'ed")};
615 } 665 }
616 } 666 }
617 @@ -930,4 +1057,92 @@ 667 @@ -918,16 +1069,123 @@
668 {
669 chunk ::CALL()
670 {
671 - int intr;
672 -
673 - intr = rtx_e1000_register_read32(&${ctx}->hw_ctx, E1000_ICR);
674 - if (intr)
675 + unsigned int icr = rtx_e1000_register_read32(&${ctx}->hw_ctx, E1000_ICR);
676 + pr_info("%s: interrupt received, ICR: 0x%x", ${config.name}, icr);
677 + if (icr)
678 {
679 - if (intr & E1000_INTR_LSC)
680 - ${Log::info("cable link status changed")};
681 + if (icr & E1000_INTR_LSC)
682 + {
683 + ${Log::info("handle_interrupt: cable link status changed, dumping card status:")};
684 + ${e1000::print_status(ctx)};
685 + }
686 + if (icr & (E1000_INTR_TXQE|E1000_INTR_TXDW))
687 + {
688 + ${Log::info("handle_interrupt: TxRing: packet(s) sent")};
689 + /*
690 + * XXX Do a Rathaxes call (how can I bind
691 + * "&${ctx}->hw_ctx.tx_ring" to e1000::TxRing easily?)
692 + */
693 + rtx_e1000_tx_ring_clean(&${ctx}->hw_ctx.tx_ring);
694 + }
695 + if (icr & E1000_INTR_RXT0)
696 + {
697 + ${Log::info("handle_interrupt: RxRing: packet(s) received")};
698 + }
699 + if (icr & E1000_INTR_RXO)
700 + {
701 + ${Log::info("handle_interrupt: RxRing: overrun")};
702 + }
703
704 return IRQ_HANDLED;
618 } 705 }
619 } 706 }
620 } 707 }
621 + 708 +
622 + template sequence e1000::_xmit_tso_cksum_offload(Ethernet::Device ctx, Socket::SKBuff skb) 709 + template sequence e1000::_xmit_tso_cksum_offload(Ethernet::Device ctx, Socket::SKBuff skb)
624 + chunk ::CALL() 711 + chunk ::CALL()
625 + { 712 + {
626 + } 713 + }
627 + } 714 + }
628 + 715 +
629 + template sequence e1000::xmit(Ethernet::Device ctx, Socket::KernelSKBuff kernel_skb) 716 + template sequence e1000::xmit(Ethernet::Device ctx, Socket::AbstractSKBuff kernel_skb)
630 + { 717 + {
631 + chunk ::CALL() 718 + chunk ::CALL()
632 + { 719 + {
633 + /* 720 + /*
634 + * Put packets on the TX ring, must return NETDEV_TX_OK or 721 + * Put packets on the TX ring, must return NETDEV_TX_OK or
636 + */ 723 + */
637 + 724 +
638 + ${Socket::SKBuff} skb; 725 + ${Socket::SKBuff} skb;
639 + ${e1000::Context} *hw_ctx; 726 + ${e1000::Context} *hw_ctx;
640 + ${e1000::TxRing} *tx_ring; 727 + ${e1000::TxRing} *tx_ring;
641 + ${Device::Device} dev; 728 + ${Device::AbstractDevice} dev;
642 + 729 +
643 + ${local.skb.init(kernel_skb)}; 730 + ${local.skb.init(kernel_skb)};
644 + hw_ctx = &${ctx}->hw_ctx; 731 + hw_ctx = &${ctx}->hw_ctx;
645 + tx_ring = &hw_ctx->tx_ring; 732 + tx_ring = &hw_ctx->tx_ring;
646 + dev = &${ctx}->pci_dev->dev; 733 + dev = &${ctx}->pci_dev->dev;
708 + } 795 + }
709 } 796 }
710 diff --git a/rathaxes/samples/e1000/e1000.rti b/rathaxes/samples/e1000/e1000.rti 797 diff --git a/rathaxes/samples/e1000/e1000.rti b/rathaxes/samples/e1000/e1000.rti
711 --- a/rathaxes/samples/e1000/e1000.rti 798 --- a/rathaxes/samples/e1000/e1000.rti
712 +++ b/rathaxes/samples/e1000/e1000.rti 799 +++ b/rathaxes/samples/e1000/e1000.rti
713 @@ -31,8 +31,15 @@ 800 @@ -31,8 +31,19 @@
714 provided type TxRing 801 provided type TxRing
715 { 802 {
716 chunk LKM::includes(); 803 chunk LKM::includes();
717 + chunk LKM::prototypes(); 804 + chunk LKM::prototypes();
718 + chunk LKM::code(); 805 + chunk LKM::code();
719 method decl(); 806 method decl();
720 method init(); 807 method init();
721 + 808 +
809 + /* Clean the ring (i.e: move the head closer to the tail): */
810 + method clean();
811 + /* Return the number of clean descriptors left in the ring: */
722 + method descriptors_remaining(); 812 + method descriptors_remaining();
723 + method tso_cksum_offload(Socket::SKBuff); 813 + method tso_cksum_offload(Socket::SKBuff);
724 + method put(Socket::SKBuff); 814 + method put(Socket::SKBuff);
815 + /* Signal the device that new dirty descriptors are on the ring: */
725 + method start_xmit(e1000::Context); 816 + method start_xmit(e1000::Context);
726 } 817 }
727 818
728 /* 819 /*
729 @@ -51,6 +58,12 @@ 820 @@ -51,6 +62,12 @@
730 method decl(); 821 method decl();
731 } 822 }
732 823
733 + provided type TxDescriptorFlags 824 + provided type TxDescriptorFlags
734 + { 825 + {
737 + } 828 + }
738 + 829 +
739 provided sequence create_device() 830 provided sequence create_device()
740 { 831 {
741 provided chunk Ethernet::create_device(PCI::Device, Ethernet::Device); 832 provided chunk Ethernet::create_device(PCI::Device, Ethernet::Device);
742 @@ -109,6 +122,16 @@ 833 @@ -109,6 +126,16 @@
743 provided chunk ::CALL(); 834 provided chunk ::CALL();
744 } 835 }
745 836
746 + provided sequence _xmit_tso_cksum_offload(Ethernet::Device, Socket::SKBuff) 837 + provided sequence _xmit_tso_cksum_offload(Ethernet::Device, Socket::SKBuff)
747 + { 838 + {
748 + provided chunk ::CALL(); 839 + provided chunk ::CALL();
749 + } 840 + }
750 + 841 +
751 + provided sequence xmit(Ethernet::Device, Socket::KernelSKBuff) 842 + provided sequence xmit(Ethernet::Device, Socket::AbstractSKBuff)
752 + { 843 + {
753 + provided chunk ::CALL(); 844 + provided chunk ::CALL();
754 + } 845 + }
755 + 846 +
756 provided sequence register_read32(e1000::Context, e1000::Register) 847 provided sequence register_read32(e1000::Context, e1000::Register)
772 + 863 +
773 + chunk LKM::data() 864 + chunk LKM::data()
774 + { 865 + {
775 + static const struct 866 + static const struct
776 + { 867 + {
777 + const unsigned short id; 868 + unsigned short id;
778 + const char *name; 869 + const char *name;
779 + } rtx_ethernet_proto_table[] = 870 + } rtx_ethernet_proto_table[] =
780 + { 871 + {
781 + { ETH_P_IP, "IPv4" }, 872 + { ETH_P_IP, "IPv4" },
782 + { ETH_P_IPV6, "IPv6" }, 873 + { ETH_P_IPV6, "IPv6" },
783 + { ETH_P_ARP, "ARP" }, 874 + { ETH_P_ARP, "ARP" },
787 + chunk LKM::code() 878 + chunk LKM::code()
788 + { 879 + {
789 + static const char *rtx_ethernet_protocol_id_to_str(unsigned short proto_id) 880 + static const char *rtx_ethernet_protocol_id_to_str(unsigned short proto_id)
790 + { 881 + {
791 + for (int i = 0; 882 + for (int i = 0;
792 + i != sizeof(rtx_ethernet_proto_table[0]) / sizeof(rtx_ethernet_proto_table); 883 + i != sizeof(rtx_ethernet_proto_table) / sizeof(rtx_ethernet_proto_table[0]);
793 + i++) 884 + i++)
794 + if (proto_id == rtx_ethernet_proto_table[i].id) 885 + if (proto_id == rtx_ethernet_proto_table[i].id)
795 + return rtx_ethernet_proto_table[i].name; 886 + return rtx_ethernet_proto_table[i].name;
796 + 887 +
797 + return "Unknown"; 888 + return "Unknown";
864 @@ -92,7 +136,7 @@ 955 @@ -92,7 +136,7 @@
865 } 956 }
866 } 957 }
867 958
868 - template sequence Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb) 959 - template sequence Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb)
869 + template sequence Ethernet::send(Ethernet::Device dev, Socket::KernelSKBuff skb) 960 + template sequence Ethernet::send(Ethernet::Device dev, Socket::AbstractSKBuff skb)
870 { 961 {
871 chunk LKM::prototypes() 962 chunk LKM::prototypes()
872 { 963 {
873 @@ -101,13 +145,11 @@ 964 @@ -101,13 +145,11 @@
874 965
881 - ${cast local.skb as Socket::SKBuff}; 972 - ${cast local.skb as Socket::SKBuff};
882 - ${pointcut ::IMPLEMENTATION(local.dev, local.skb)}; 973 - ${pointcut ::IMPLEMENTATION(local.dev, local.skb)};
883 - 974 -
884 - return 0; 975 - return 0;
885 + ${Ethernet::Device} rtx_ethernet_dev = netdev_priv(net_dev); 976 + ${Ethernet::Device} rtx_ethernet_dev = netdev_priv(net_dev);
886 + ${cast local.kernel_skb as Socket::KernelSKBuff}; 977 + ${cast local.kernel_skb as Socket::AbstractSKBuff};
887 + ${pointcut ::IMPLEMENTATION(local.rtx_ethernet_dev, local.kernel_skb)}; 978 + ${pointcut ::IMPLEMENTATION(local.rtx_ethernet_dev, local.kernel_skb)};
888 } 979 }
889 } 980 }
890 } 981 }
891 @@ -123,9 +165,8 @@ 982 @@ -123,9 +165,8 @@
952 @@ -22,7 +36,7 @@ 1043 @@ -22,7 +36,7 @@
953 provided chunk LKM::code(); 1044 provided chunk LKM::code();
954 } 1045 }
955 1046
956 - required sequence send(Ethernet::Device dev, Socket::SKBuff skb) 1047 - required sequence send(Ethernet::Device dev, Socket::SKBuff skb)
957 + required sequence send(Ethernet::Device, Socket::KernelSKBuff) 1048 + required sequence send(Ethernet::Device, Socket::AbstractSKBuff)
958 { 1049 {
959 provided chunk LKM::prototypes(); 1050 provided chunk LKM::prototypes();
960 provided chunk LKM::code(); 1051 provided chunk LKM::code();
961 diff --git a/rathaxes/samples/e1000/lkm.rtx b/rathaxes/samples/e1000/lkm.rtx 1052 diff --git a/rathaxes/samples/e1000/lkm.rtx b/rathaxes/samples/e1000/lkm.rtx
962 --- a/rathaxes/samples/e1000/lkm.rtx 1053 --- a/rathaxes/samples/e1000/lkm.rtx
970 @@ -43,9 +43,10 @@ 1061 @@ -43,9 +43,10 @@
971 e1000::handle_interrupt(dev); 1062 e1000::handle_interrupt(dev);
972 } 1063 }
973 1064
974 - Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb) 1065 - Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb)
975 + Ethernet::send(Ethernet::Device dev, Socket::KernelSKBuff skb) 1066 + Ethernet::send(Ethernet::Device dev, Socket::AbstractSKBuff skb)
976 { 1067 {
977 Log::info("we have one packet to transmit!"); 1068 Log::info("we have one packet to transmit!");
978 + e1000::xmit(dev, skb); 1069 + e1000::xmit(dev, skb);
979 } 1070 }
980 1071
981 LKM::init() 1072 LKM::init()
982 @@ -79,4 +80,10 @@ 1073 @@ -66,8 +67,13 @@
1074 LKM::description = "Hello World Loadable Kernel Module (LKM)";
1075 LKM::license = "GPL";
1076
1077 + /*
1078 + * See section 5.2 of the Intel manual for all the values
1079 + * - 0x100e is for the 82540EM-A;
1080 + * - 0x100f, apparently found on vmware by default, is for the 82545EM-A.
1081 + */
1082 PCI::vendor_id = 0x8086;
1083 - PCI::product_id = 0x100e; /* e100f on vmware by default it seems */
1084 + PCI::product_id = 0x100e;
1085 PCI::set_master = true;
1086
1087 Ethernet::ifname = "rtx%d";
1088 @@ -79,4 +85,10 @@
983 * 4096, 8192 and 16384 bytes: 1089 * 4096, 8192 and 16384 bytes:
984 */ 1090 */
985 e1000::rx_buffer_len = 2048; 1091 e1000::rx_buffer_len = 2048;
986 + /* 1092 + /*
987 + * 4096 bytes maximum per transmit descriptor is used on Linux and FreeBSD, 1093 + * 4096 bytes maximum per transmit descriptor is used on Linux and FreeBSD,
988 + * 2048 on Minix and HelenOS, I can't find why. If I understand the Intel 1094 + * 2048 on Minix and HelenOS, I can't find why. If I understand the Intel
989 + * man correctly, the maximum should be 16288 (see section 3.3.3). 1095 + * manual correctly, the maximum should be 16288 (see section 3.3.3).
990 + */ 1096 + */
991 + e1000::tx_max_data_per_desc = 4096; 1097 + e1000::tx_max_data_per_desc = 4096;
992 } 1098 }
993 diff --git a/rathaxes/samples/e1000/socket.blt b/rathaxes/samples/e1000/socket.blt 1099 diff --git a/rathaxes/samples/e1000/socket.blt b/rathaxes/samples/e1000/socket.blt
994 --- a/rathaxes/samples/e1000/socket.blt 1100 --- a/rathaxes/samples/e1000/socket.blt
995 +++ b/rathaxes/samples/e1000/socket.blt 1101 +++ b/rathaxes/samples/e1000/socket.blt
996 @@ -1,20 +1,153 @@ 1102 @@ -1,20 +1,152 @@
997 -with Socket, LKM 1103 -with Socket, LKM
998 +with Socket, LKM, Device, Ethernet 1104 +with Socket, LKM, Device, Ethernet
999 { 1105 {
1000 + template type Socket::KernelSKBuff() 1106 + template type Socket::AbstractSKBuff()
1001 + { 1107 + {
1002 + chunk LKM::includes() 1108 + chunk LKM::includes()
1003 + { 1109 + {
1004 + #include <linux/skbuff.h> 1110 + #include <linux/skbuff.h>
1005 + 1111 +
1006 + static const ${Socket::KernelSKBuff} force_rtx_socket_kernel_skbuff_decl; 1112 + static const ${Socket::AbstractSKBuff} force_rtx_socket_kernel_skbuff_decl;
1007 + } 1113 + }
1008 + 1114 +
1009 + chunk ::decl() 1115 + chunk ::decl()
1010 + { 1116 + {
1011 + typedef struct sk_buff *rtx_socket_kernel_skbuff_p; 1117 + typedef struct sk_buff *rtx_socket_kernel_skbuff_p;
1059 + "none", "unnecessary", "complete", "partial" 1165 + "none", "unnecessary", "complete", "partial"
1060 + }; 1166 + };
1061 + struct skb_shared_info *shinfo = skb_shinfo(self->skbuff); 1167 + struct skb_shared_info *shinfo = skb_shinfo(self->skbuff);
1062 + 1168 +
1063 + pr_info( 1169 + pr_info(
1064 + "\t protocol = %#-5x (%s)\n" 1170 + "\t protocol = %#-5x (%s) ip_summed = %d (%s)\n"
1065 + "\t len = %-5u data_len = %-5u head_len = %-5u\n" 1171 + "\t len = %-5u data_len = %-5u head_len = %-5u\n"
1066 + "\t nr_frags = %u\n" 1172 + "\t nr_frags = %u\n"
1067 + "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u\n" 1173 + "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u",
1068 + "\tip_summed = %d (%s)",
1069 + ethernet_proto, rtx_ethernet_protocol_id_to_str(ethernet_proto) /* XXX: ${local.ethernet_proto.to_str()} */, 1174 + ethernet_proto, rtx_ethernet_protocol_id_to_str(ethernet_proto) /* XXX: ${local.ethernet_proto.to_str()} */,
1175 + self->skbuff->ip_summed, ip_summed_values[self->skbuff->ip_summed],
1070 + self->skbuff->len, self->skbuff->data_len, skb_headlen(self->skbuff), 1176 + self->skbuff->len, self->skbuff->data_len, skb_headlen(self->skbuff),
1071 + shinfo->nr_frags, shinfo->gso_size, shinfo->gso_segs, shinfo->gso_type, 1177 + shinfo->nr_frags, shinfo->gso_size, shinfo->gso_segs, shinfo->gso_type
1072 + self->skbuff->ip_summed, ip_summed_values[self->skbuff->ip_summed]
1073 + ); 1178 + );
1074 + } 1179 + }
1075 + 1180 +
1076 + static int rtx_socket_skbuff_map(struct rtx_socket_skbuff *self, 1181 + static int rtx_socket_skbuff_map(struct rtx_socket_skbuff *self,
1077 + struct device *dev, 1182 + struct device *dev,
1118 + /* 1223 + /*
1119 + * XXX: the rathaxes argument kernel_skb is not actually bound to the 1224 + * XXX: the rathaxes argument kernel_skb is not actually bound to the
1120 + * correct C variable from Ethernet::send() (so I named it as the C 1225 + * correct C variable from Ethernet::send() (so I named it as the C
1121 + * variable I needed) 1226 + * variable I needed)
1122 + */ 1227 + */
1123 + chunk ::init(Socket::KernelSKBuff kernel_skb) 1228 + chunk ::init(Socket::AbstractSKBuff kernel_skb)
1124 + { 1229 + {
1125 + ${self}.skbuff = kernel_skb; 1230 + ${self}.skbuff = kernel_skb;
1126 + ${self}.dma_handle = 0; 1231 + ${self}.dma_handle = 0;
1127 + } 1232 + }
1128 + 1233 +
1129 + chunk dump_infos() 1234 + chunk dump_infos()
1130 + { 1235 + {
1131 + rtx_socket_skbuff_dump_infos(${self}); 1236 + rtx_socket_skbuff_dump_infos(${self});
1132 + } 1237 + }
1133 + 1238 +
1134 + chunk map_to(Device::Device dev) 1239 + chunk map_to(Device::AbstractDevice dev)
1135 + { 1240 + {
1136 + rtx_socket_skbuff_map(${self}, ${dev}, DMA_TO_DEVICE); 1241 + rtx_socket_skbuff_map(${self}, ${dev}, DMA_TO_DEVICE);
1137 + } 1242 + }
1138 + 1243 +
1139 + chunk map_from(Device::Device dev) 1244 + chunk map_from(Device::AbstractDevice dev)
1140 + { 1245 + {
1141 + rtx_socket_skbuff_map(${self}, ${dev}, DMA_FROM_DEVICE); 1246 + rtx_socket_skbuff_map(${self}, ${dev}, DMA_FROM_DEVICE);
1142 + } 1247 + }
1143 + 1248 +
1144 + chunk unmap_to_and_free(Device::Device dev) 1249 + chunk unmap_to_and_free(Device::AbstractDevice dev)
1145 + { 1250 + {
1146 + rtx_socket_skbuff_unmap_and_free(${self}, ${dev}, DMA_TO_DEVICE); 1251 + rtx_socket_skbuff_unmap_and_free(${self}, ${dev}, DMA_TO_DEVICE);
1147 + } 1252 + }
1148 + 1253 +
1149 + chunk unmap_from_and_free(Device::Device dev) 1254 + chunk unmap_from_and_free(Device::AbstractDevice dev)
1150 + { 1255 + {
1151 + rtx_socket_skbuff_unmap_and_free(${self}, ${dev}, DMA_FROM_DEVICE); 1256 + rtx_socket_skbuff_unmap_and_free(${self}, ${dev}, DMA_FROM_DEVICE);
1152 } 1257 }
1153 1258
1154 map 1259 map
1155 diff --git a/rathaxes/samples/e1000/socket.rti b/rathaxes/samples/e1000/socket.rti 1260 diff --git a/rathaxes/samples/e1000/socket.rti b/rathaxes/samples/e1000/socket.rti
1156 --- a/rathaxes/samples/e1000/socket.rti 1261 --- a/rathaxes/samples/e1000/socket.rti
1157 +++ b/rathaxes/samples/e1000/socket.rti 1262 +++ b/rathaxes/samples/e1000/socket.rti
1158 @@ -1,8 +1,22 @@ 1263 @@ -1,8 +1,23 @@
1159 -interface Socket : LKM 1264 -interface Socket : LKM
1160 +interface Socket : LKM, Device 1265 +interface Socket : LKM, Device
1161 { 1266 {
1162 - provided type Socket::SKBuff { 1267 - provided type Socket::SKBuff {
1163 - chunk LKM::includes(); 1268 - chunk LKM::includes();
1164 - method decl(); 1269 - method decl();
1165 - method init(); 1270 - method init();
1166 + provided type KernelSKBuff 1271 + /* The SKBuff type from the kernel */
1272 + provided type AbstractSKBuff
1167 + { 1273 + {
1168 + chunk LKM::includes(); 1274 + chunk LKM::includes();
1169 + method decl(); 1275 + method decl();
1170 + } 1276 + }
1171 + 1277 +
1173 + { 1279 + {
1174 + chunk LKM::includes(); 1280 + chunk LKM::includes();
1175 + chunk LKM::prototypes(); 1281 + chunk LKM::prototypes();
1176 + chunk LKM::code(); 1282 + chunk LKM::code();
1177 + method decl(); 1283 + method decl();
1178 + method init(Socket::KernelSKBuff); 1284 + method init(Socket::AbstractSKBuff);
1179 + method dump_infos(); 1285 + method dump_infos();
1180 + method map_to(Device::Device); 1286 + method map_to(Device::AbstractDevice);
1181 + method map_from(Device::Device); 1287 + method map_from(Device::AbstractDevice);
1182 + method unmap_to_and_free(Device::Device); 1288 + method unmap_to_and_free(Device::AbstractDevice);
1183 + method unmap_from_and_free(Device::Device); 1289 + method unmap_from_and_free(Device::AbstractDevice);
1184 } 1290 }
1185 } 1291 }