Mercurial > archived > louis > epitech > mq > rathaxes
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 } |