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