from migen.bank.description import *
eth_mtu = 1532
+eth_min_len = 46
eth_preamble = 0xD555555555555555
buffer_depth = 2**log2_int(eth_mtu, need_pow2=False)
ipv4_header_len = 20
ipv4_header = {
- "version": HField(0, 4, 4), # XXX works on hardware but need to fix
- "ihl": HField(0, 0, 4), # header encoding/decoding when not aligned
- "diff_services": HField(1, 0, 6), # on bytes
- "ecn": HField(1, 6, 2),
+ "ihl": HField(0, 0, 4),
+ "version": HField(0, 4, 4),
"total_length": HField(2, 0, 16),
"identification": HField(4, 0, 16),
- "flags": HField(6, 0, 3),
- "fragment_offset": HField(6, 3, 13),
"ttl": HField(8, 0, 8),
"protocol": HField(9, 0, 8),
"checksum": HField(10, 0, 16),
self.submodules += packetizer
source = packetizer.sink
- counter = Counter(max=arp_header_len)
+ counter = Counter(max=max(arp_header_len, eth_min_len))
self.submodules += counter
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
fsm.act("SEND",
source.stb.eq(1),
source.sop.eq(counter.value == 0),
- source.eop.eq(counter.value == arp_header_len-1),
+ source.eop.eq(counter.value == max(arp_header_len, eth_min_len)-1),
Record.connect(packetizer.source, self.source),
self.source.target_mac.eq(source.target_mac),
self.source.sender_mac.eq(mac_address),
packetizer.sink.total_length.eq(self.sink.length + (0x5*4)),
packetizer.sink.version.eq(0x4), # ipv4
packetizer.sink.ihl.eq(0x5), # 20 bytes
- packetizer.sink.diff_services.eq(0),
- packetizer.sink.ecn.eq(0),
packetizer.sink.identification.eq(0),
- packetizer.sink.flags.eq(0),
- packetizer.sink.fragment_offset.eq(0),
packetizer.sink.ttl.eq(0x80),
packetizer.sink.sender_ip.eq(ip_address),
packetizer.sink.data.eq(self.sink.data)
from liteeth.mac.core import preamble, crc, last_be
class LiteEthMACCore(Module, AutoCSR):
- def __init__(self, phy, dw, endianness="be", with_hw_preamble_crc=True):
+ def __init__(self, phy, dw, endianness="big", with_hw_preamble_crc=True):
if dw < phy.dw:
raise ValueError("Core data width({}) must be larger than PHY data width({})".format(dw, phy.dw))
rx_pipeline = [phy]
tx_pipeline = [phy]
- # Preamble / CRC (optional)
+ # Preamble / CRC
if with_hw_preamble_crc:
self._hw_preamble_crc = CSRStatus(reset=1)
# Preamble insert/check
tx_pipeline += [preamble_inserter, crc32_inserter]
rx_pipeline += [preamble_checker, crc32_checker]
+ # Delimiters
if dw != 8:
- # Delimiters
tx_last_be = last_be.LiteEthMACTXLastBE(phy.dw)
rx_last_be = last_be.LiteEthMACRXLastBE(phy.dw)
self.submodules += RenameClockDomains(tx_last_be, "eth_tx")
tx_pipeline += [tx_last_be]
rx_pipeline += [rx_last_be]
+ # Converters
if dw != phy.dw:
- # Converters
- reverse = endianness == "be"
+ reverse = endianness == "big"
tx_converter = Converter(eth_phy_description(dw), eth_phy_description(phy.dw), reverse=reverse)
rx_converter = Converter(eth_phy_description(phy.dw), eth_phy_description(dw), reverse=reverse)
self.submodules += RenameClockDomains(tx_converter, "eth_tx")
selfp.ip.sink.sop = 1
selfp.ip.sink.eop = 1
selfp.ip.sink.ip_address = 0x12345678
- selfp.ip.sink.protocol = 0x11
+ selfp.ip.sink.protocol = udp_protocol
selfp.ip.source.ack = 1
if selfp.ip.source.stb == 1 and selfp.ip.source.sop == 1:
self.process(packet)
def process(self, packet):
- if len(packet) != arp_packet_length-arp_header_len:
+ if len(packet) != eth_min_len-arp_header_len:
raise ValueError
if packet.hwtype != arp_hwtype_ethernet:
raise ValueError
def process_request(self, request):
if request.target_ip == self.ip_address:
- reply = ARPPacket([0]*(arp_packet_length-arp_header_len))
+ reply = ARPPacket([0]*(eth_min_len-arp_header_len))
reply.hwtype = arp_hwtype_ethernet
reply.proto = arp_proto_ip
reply.opcode = arp_opcode_reply
self.table[reply.sender_ip] = reply.sender_mac
def request(self, ip_address):
- request = ARPPacket([0]*(arp_packet_length-arp_header_len))
+ request = ARPPacket([0]*(eth_min_len-arp_header_len))
request.hwtype = arp_hwtype_ethernet
request.proto = arp_proto_ip
request.opcode = arp_opcode_request
ip_packet = ip.IPPacket(packet)
ip_packet.version = 0x4
ip_packet.ihl = 0x5
- ip_packet.diff_services = 0x0
- ip_packet.ecn = 0x0
ip_packet.total_length = len(packet) + ip_packet.ihl
ip_packet.identification = 0
ip_packet.flags = 0