From f2d218aebb5a1c099c34540ac2f70c06e9024bbf Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 6 Feb 2015 00:05:25 +0100 Subject: [PATCH] arp: manage the case when the target is unreacheable --- liteeth/core/arp.py | 23 +++++++++++++++++------ liteeth/core/ip.py | 17 +++++++++++++---- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/liteeth/core/arp.py b/liteeth/core/arp.py index 10ff1ad85..c223d8044 100644 --- a/liteeth/core/arp.py +++ b/liteeth/core/arp.py @@ -134,7 +134,7 @@ class LiteEthARPRX(Module): ) class LiteEthARPTable(Module): - def __init__(self, clk_freq): + def __init__(self, clk_freq, max_requests=8): self.sink = sink = Sink(_arp_table_layout) # from arp_rx self.source = source = Source(_arp_table_layout) # to arp_tx @@ -143,9 +143,10 @@ class LiteEthARPTable(Module): self.response = response = Source(arp_table_response_layout) ### request_timeout = Timeout(clk_freq//10) + request_counter = Counter(max=max_requests) request_pending = FlipFlop() - request_ip_address = FlipFlop(32, reset=0xffffffff) - self.submodules += request_timeout, request_pending, request_ip_address + request_ip_address = FlipFlop(32) + self.submodules += request_timeout, request_counter, request_pending, request_ip_address self.comb += [ request_timeout.ce.eq(request_pending.q), request_pending.d.eq(1), @@ -165,11 +166,13 @@ class LiteEthARPTable(Module): self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", # Note: for simplicicy, if APR table is busy response from arp_rx - # is lost. This is compensated by the protocol (retrys) + # is lost. This is compensated by the protocol (retry) If(sink.stb & sink.request, NextState("SEND_REPLY") ).Elif(sink.stb & sink.reply & request_pending.q, NextState("UPDATE_TABLE"), + ).Elif(request_counter.value == max_requests-1, + NextState("PRESENT_RESPONSE") ).Elif(request.stb | (request_pending.q & request_timeout.reached), NextState("CHECK_TABLE") ) @@ -224,15 +227,23 @@ class LiteEthARPTable(Module): source.ip_address.eq(request_ip_address.q), If(source.ack, request_timeout.reset.eq(1), + request_counter.reset.eq(request.stb), + request_counter.ce.eq(1), request_pending.ce.eq(1), request.ack.eq(1), NextState("IDLE") ) ) + self.comb += [ + If(request_counter == max_requests-1, + response.failed.eq(1), + request_counter.reset.eq(1), + request_pending.reset.eq(1) + ), + response.mac_address.eq(cached_mac_address) + ] fsm.act("PRESENT_RESPONSE", response.stb.eq(1), - response.failed.eq(0), # XXX add timeout to trigger failed - response.mac_address.eq(cached_mac_address), If(response.ack, NextState("IDLE") ) diff --git a/liteeth/core/ip.py b/liteeth/core/ip.py index baff81244..e0bde4b8e 100644 --- a/liteeth/core/ip.py +++ b/liteeth/core/ip.py @@ -42,6 +42,7 @@ class LiteEthIPTX(Module): def __init__(self, mac_address, ip_address, arp_table): self.sink = Sink(eth_ipv4_user_description(8)) self.source = Source(eth_mac_description(8)) + self.target_unreachable = Signal() ### packetizer = LiteEthIPV4Packetizer() self.submodules += packetizer @@ -87,11 +88,14 @@ class LiteEthIPTX(Module): ) ) fsm.act("WAIT_MAC_ADDRESS_RESPONSE", - # XXX add timeout If(arp_table.response.stb, arp_table.response.ack.eq(1), - # XXX manage failed - NextState("SEND") + If(arp_table.response.failed, + self.target_unreachable.eq(1), + NextState("DROP"), + ).Else( + NextState("SEND") + ) ) ) self.sync += If(arp_table.response.stb, target_mac.eq(arp_table.response.mac_address)) @@ -101,7 +105,12 @@ class LiteEthIPTX(Module): self.source.target_mac.eq(target_mac), self.source.sender_mac.eq(mac_address), If(self.source.stb & self.source.eop & self.source.ack, - # XXX manage failed + NextState("IDLE") + ) + ) + fsm.act("DROP", + packetizer.source.ack.eq(1), + If(packetizer.source.stb & packetizer.source.eop & packetizer.source.ack, NextState("IDLE") ) )