382 return; |
382 return; |
383 } |
383 } |
384 |
384 |
385 frame_type = EC_READ_U16(data) & 0x000F; |
385 frame_type = EC_READ_U16(data) & 0x000F; |
386 |
386 |
387 if (frame_type == 0x00) { // EoE Fragment Request |
387 if (frame_type != 0x00) { |
388 last_fragment = (EC_READ_U16(data) >> 8) & 0x0001; |
|
389 time_appended = (EC_READ_U16(data) >> 9) & 0x0001; |
|
390 fragment_number = EC_READ_U16(data + 2) & 0x003F; |
|
391 fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F; |
|
392 frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F; |
|
393 |
|
394 #if EOE_DEBUG_LEVEL > 0 |
|
395 EC_DBG("EoE RX fragment %i, offset %i, frame %i%s%s," |
|
396 " %i octets\n", fragment_number, fragment_offset, |
|
397 frame_number, |
|
398 last_fragment ? ", last fragment" : "", |
|
399 time_appended ? ", + timestamp" : "", |
|
400 time_appended ? rec_size - 8 : rec_size - 4); |
|
401 #endif |
|
402 |
|
403 #if EOE_DEBUG_LEVEL > 1 |
|
404 EC_DBG(""); |
|
405 for (i = 0; i < rec_size - 4; i++) { |
|
406 printk("%02X ", data[i + 4]); |
|
407 if ((i + 1) % 16 == 0) { |
|
408 printk("\n"); |
|
409 EC_DBG(""); |
|
410 } |
|
411 } |
|
412 printk("\n"); |
|
413 #endif |
|
414 |
|
415 data_size = time_appended ? rec_size - 8 : rec_size - 4; |
|
416 |
|
417 if (!fragment_number) { |
|
418 if (eoe->rx_skb) { |
|
419 EC_WARN("EoE RX freeing old socket buffer...\n"); |
|
420 dev_kfree_skb(eoe->rx_skb); |
|
421 } |
|
422 |
|
423 // new socket buffer |
|
424 if (!(eoe->rx_skb = dev_alloc_skb(fragment_offset * 32))) { |
|
425 if (printk_ratelimit()) |
|
426 EC_WARN("EoE RX low on mem. frame dropped.\n"); |
|
427 eoe->stats.rx_dropped++; |
|
428 eoe->state = ec_eoe_state_tx_start; |
|
429 return; |
|
430 } |
|
431 |
|
432 eoe->rx_skb_offset = 0; |
|
433 eoe->rx_skb_size = fragment_offset * 32; |
|
434 eoe->rx_expected_fragment = 0; |
|
435 } |
|
436 else { |
|
437 if (!eoe->rx_skb) { |
|
438 eoe->stats.rx_dropped++; |
|
439 eoe->state = ec_eoe_state_tx_start; |
|
440 return; |
|
441 } |
|
442 |
|
443 offset = fragment_offset * 32; |
|
444 if (offset != eoe->rx_skb_offset || |
|
445 offset + data_size > eoe->rx_skb_size || |
|
446 fragment_number != eoe->rx_expected_fragment) { |
|
447 eoe->stats.rx_errors++; |
|
448 eoe->state = ec_eoe_state_tx_start; |
|
449 dev_kfree_skb(eoe->rx_skb); |
|
450 eoe->rx_skb = NULL; |
|
451 return; |
|
452 } |
|
453 } |
|
454 |
|
455 // copy fragment into socket buffer |
|
456 memcpy(skb_put(eoe->rx_skb, data_size), data + 4, data_size); |
|
457 eoe->rx_skb_offset += data_size; |
|
458 |
|
459 if (last_fragment) { |
|
460 // update statistics |
|
461 eoe->stats.rx_packets++; |
|
462 eoe->stats.rx_bytes += eoe->rx_skb->len; |
|
463 |
|
464 #if EOE_DEBUG_LEVEL > 0 |
|
465 EC_DBG("EoE RX frame completed with %u octets.\n", |
|
466 eoe->rx_skb->len); |
|
467 #endif |
|
468 |
|
469 // pass socket buffer to network stack |
|
470 eoe->rx_skb->dev = eoe->dev; |
|
471 eoe->rx_skb->protocol = eth_type_trans(eoe->rx_skb, eoe->dev); |
|
472 eoe->rx_skb->ip_summed = CHECKSUM_UNNECESSARY; |
|
473 if (netif_rx(eoe->rx_skb)) { |
|
474 EC_WARN("EoE RX netif_rx failed.\n"); |
|
475 } |
|
476 eoe->rx_skb = NULL; |
|
477 |
|
478 eoe->state = ec_eoe_state_tx_start; |
|
479 } |
|
480 else { |
|
481 eoe->rx_expected_fragment++; |
|
482 #if EOE_DEBUG_LEVEL > 0 |
|
483 EC_DBG("EoE RX expecting fragment %i\n", |
|
484 eoe->rx_expected_fragment); |
|
485 #endif |
|
486 eoe->state = ec_eoe_state_rx_start; |
|
487 } |
|
488 } |
|
489 else { |
|
490 #if EOE_DEBUG_LEVEL > 0 |
388 #if EOE_DEBUG_LEVEL > 0 |
491 EC_DBG("other frame received.\n"); |
389 EC_DBG("other frame received.\n"); |
492 #endif |
390 #endif |
493 eoe->stats.rx_dropped++; |
391 eoe->stats.rx_dropped++; |
494 eoe->state = ec_eoe_state_tx_start; |
392 eoe->state = ec_eoe_state_tx_start; |
|
393 return; |
|
394 } |
|
395 |
|
396 // EoE Fragment Request received |
|
397 |
|
398 last_fragment = (EC_READ_U16(data) >> 8) & 0x0001; |
|
399 time_appended = (EC_READ_U16(data) >> 9) & 0x0001; |
|
400 fragment_number = EC_READ_U16(data + 2) & 0x003F; |
|
401 fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F; |
|
402 frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F; |
|
403 |
|
404 #if EOE_DEBUG_LEVEL > 0 |
|
405 EC_DBG("EoE RX fragment %i, offset %i, frame %i%s%s," |
|
406 " %i octets\n", fragment_number, fragment_offset, |
|
407 frame_number, |
|
408 last_fragment ? ", last fragment" : "", |
|
409 time_appended ? ", + timestamp" : "", |
|
410 time_appended ? rec_size - 8 : rec_size - 4); |
|
411 #endif |
|
412 |
|
413 #if EOE_DEBUG_LEVEL > 1 |
|
414 EC_DBG(""); |
|
415 for (i = 0; i < rec_size - 4; i++) { |
|
416 printk("%02X ", data[i + 4]); |
|
417 if ((i + 1) % 16 == 0) { |
|
418 printk("\n"); |
|
419 EC_DBG(""); |
|
420 } |
|
421 } |
|
422 printk("\n"); |
|
423 #endif |
|
424 |
|
425 data_size = time_appended ? rec_size - 8 : rec_size - 4; |
|
426 |
|
427 if (!fragment_number) { |
|
428 if (eoe->rx_skb) { |
|
429 EC_WARN("EoE RX freeing old socket buffer...\n"); |
|
430 dev_kfree_skb(eoe->rx_skb); |
|
431 } |
|
432 |
|
433 // new socket buffer |
|
434 if (!(eoe->rx_skb = dev_alloc_skb(fragment_offset * 32))) { |
|
435 if (printk_ratelimit()) |
|
436 EC_WARN("EoE RX low on mem. frame dropped.\n"); |
|
437 eoe->stats.rx_dropped++; |
|
438 eoe->state = ec_eoe_state_tx_start; |
|
439 return; |
|
440 } |
|
441 |
|
442 eoe->rx_skb_offset = 0; |
|
443 eoe->rx_skb_size = fragment_offset * 32; |
|
444 eoe->rx_expected_fragment = 0; |
|
445 } |
|
446 else { |
|
447 if (!eoe->rx_skb) { |
|
448 eoe->stats.rx_dropped++; |
|
449 eoe->state = ec_eoe_state_tx_start; |
|
450 return; |
|
451 } |
|
452 |
|
453 offset = fragment_offset * 32; |
|
454 if (offset != eoe->rx_skb_offset || |
|
455 offset + data_size > eoe->rx_skb_size || |
|
456 fragment_number != eoe->rx_expected_fragment) { |
|
457 dev_kfree_skb(eoe->rx_skb); |
|
458 eoe->rx_skb = NULL; |
|
459 eoe->stats.rx_errors++; |
|
460 eoe->state = ec_eoe_state_tx_start; |
|
461 return; |
|
462 } |
|
463 } |
|
464 |
|
465 // copy fragment into socket buffer |
|
466 memcpy(skb_put(eoe->rx_skb, data_size), data + 4, data_size); |
|
467 eoe->rx_skb_offset += data_size; |
|
468 |
|
469 if (last_fragment) { |
|
470 // update statistics |
|
471 eoe->stats.rx_packets++; |
|
472 eoe->stats.rx_bytes += eoe->rx_skb->len; |
|
473 |
|
474 #if EOE_DEBUG_LEVEL > 0 |
|
475 EC_DBG("EoE RX frame completed with %u octets.\n", |
|
476 eoe->rx_skb->len); |
|
477 #endif |
|
478 |
|
479 // pass socket buffer to network stack |
|
480 eoe->rx_skb->dev = eoe->dev; |
|
481 eoe->rx_skb->protocol = eth_type_trans(eoe->rx_skb, eoe->dev); |
|
482 eoe->rx_skb->ip_summed = CHECKSUM_UNNECESSARY; |
|
483 if (netif_rx(eoe->rx_skb)) { |
|
484 EC_WARN("EoE RX netif_rx failed.\n"); |
|
485 } |
|
486 eoe->rx_skb = NULL; |
|
487 |
|
488 eoe->state = ec_eoe_state_tx_start; |
|
489 } |
|
490 else { |
|
491 eoe->rx_expected_fragment++; |
|
492 #if EOE_DEBUG_LEVEL > 0 |
|
493 EC_DBG("EoE RX expecting fragment %i\n", |
|
494 eoe->rx_expected_fragment); |
|
495 #endif |
|
496 eoe->state = ec_eoe_state_rx_start; |
495 } |
497 } |
496 } |
498 } |
497 |
499 |
498 /*****************************************************************************/ |
500 /*****************************************************************************/ |
499 |
501 |