Skip to content

Commit

Permalink
Improved link down/up recovery
Browse files Browse the repository at this point in the history
  • Loading branch information
vanvught committed May 7, 2024
1 parent 049c85f commit 3a25056
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 91 deletions.
25 changes: 23 additions & 2 deletions lib-network/include/emac/emac.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
/*
* emac.h
/**
* @file emac.h
*
*/
/* Copyright (C) 2024 by Arjan van Vught mailto:[email protected]
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#ifndef EMAC_EMAC_H_
Expand Down
6 changes: 6 additions & 0 deletions lib-network/include/emac/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
# error This file should not be included
#endif

#if !defined (HAVE_NET_HANDLE)
# define HAVE_NET_HANDLE
#endif

#include <cstdint>
#include <cstring>
#include <cassert>
Expand All @@ -48,6 +52,7 @@ class Network {
Network();
~Network() = default;

void Start(const net::Link link);
void Print();

void Shutdown() {
Expand Down Expand Up @@ -267,6 +272,7 @@ class Network {
uint32_t m_nIfIndex { 1 };
uint32_t m_nNtpServerIp { 0 };
float m_fNtpUtcOffset { 0 };
uint8_t m_nDhcpRetryTime { 0 };

struct IpInfo m_IpInfo;

Expand Down
5 changes: 3 additions & 2 deletions lib-network/include/emac/phy.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @file phy.h
*
*/
/* Copyright (C) 2023 by Arjan van Vught mailto:[email protected]
/* Copyright (C) 2023-2024 by Arjan van Vught mailto:[email protected]
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -30,7 +30,7 @@

namespace net {
enum class Link {
STATE_UP, STATE_DOWN
STATE_DOWN, STATE_UP
};

enum class Duplex {
Expand Down Expand Up @@ -59,6 +59,7 @@ struct PhyIdentifier {
*/

bool phy_get_id(const uint32_t nAddress, PhyIdentifier& phyIdentifier);
Link phy_get_link(const uint32_t nAddress);

/**
*
Expand Down
2 changes: 1 addition & 1 deletion lib-network/src/apps/tftp/tftpdaemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ void TFTPDaemon::DoRead() {
FileClose();
}

DEBUG_PRINTF("m_nDataLength=%u, m_nPacketLength=%d, m_bIsLastBlock=%d", static_cast<unsigned>(m_nDataLength), m_nPacketLength, m_bIsLastBlock);
DEBUG_PRINTF("m_nDataLength=%u, m_nPacketLength=%d, m_bIsLastBlock=%d", m_nDataLength, m_nPacketLength, m_bIsLastBlock);
}

DEBUG_PRINTF("Sending to " IPSTR ":%d", IP2STR(m_nFromIp), m_nFromPort);
Expand Down
29 changes: 18 additions & 11 deletions lib-network/src/emac/gd32/emac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,13 @@ void __attribute__((cold)) emac_config() {
DEBUG_EXIT
}

void __attribute__((cold)) emac_start(uint8_t mac_address[], net::Link& link) {
void emac_adjust_link(const net::PhyStatus phyStatus) {
DEBUG_ENTRY
DEBUG_PRINTF("ENET_RXBUF_NUM=%u, ENET_TXBUF_NUM=%u", ENET_RXBUF_NUM, ENET_TXBUF_NUM);

net::PhyStatus phyStatus;
net::phy_start(PHY_ADDRESS, phyStatus);

link = phyStatus.link;
printf("Link %s, %d, %s\n",
phyStatus.link == net::Link::STATE_UP ? "Up" : "Down",
phyStatus.speed == net::Speed::SPEED10 ? 10 : 100,
phyStatus.duplex == net::Duplex::DUPLEX_HALF ? "HALF" : "FULL");

#ifndef NDEBUG
{
Expand Down Expand Up @@ -113,11 +112,6 @@ void __attribute__((cold)) emac_start(uint8_t mac_address[], net::Link& link) {
mediamode = ENET_10M_FULLDUPLEX;
}

printf("Link %s, %d, %s\n",
phyStatus.link == net::Link::STATE_UP ? "Up" : "Down",
phyStatus.speed == net::Speed::SPEED10 ? 10 : 100,
phyStatus.duplex == net::Duplex::DUPLEX_HALF ? "HALF" : "FULL");

#if defined (GD32H7XX)
const auto enet_init_status = enet_init(ENETx, mediamode, ENET_AUTOCHECKSUM_DROP_FAILFRAMES, ENET_CUSTOM);
#else
Expand Down Expand Up @@ -147,6 +141,19 @@ void __attribute__((cold)) emac_start(uint8_t mac_address[], net::Link& link) {
printf("BSR: %.4x %s\n", phy_value & (PHY_AUTONEGO_COMPLETE | PHY_LINKED_STATUS | PHY_JABBER_DETECTION), phy_state == SUCCESS ? "SUCCES" : "ERROR" );
}
#endif
DEBUG_EXIT
}

void __attribute__((cold)) emac_start(uint8_t mac_address[], net::Link& link) {
DEBUG_ENTRY
DEBUG_PRINTF("ENET_RXBUF_NUM=%u, ENET_TXBUF_NUM=%u", ENET_RXBUF_NUM, ENET_TXBUF_NUM);

net::PhyStatus phyStatus;
net::phy_start(PHY_ADDRESS, phyStatus);

link = phyStatus.link;

emac_adjust_link(phyStatus);

mac_address_get(mac_address);

Expand Down
1 change: 1 addition & 0 deletions lib-network/src/emac/gd32/net_link_check.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include <cstdint>

#include "emac/phy.h"
#include "emac/net_link_check.h"

#include "gd32.h"
Expand Down
34 changes: 13 additions & 21 deletions lib-network/src/emac/h3/emac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @file emac.cpp
*
*/
/* Copyright (C) 2018-2023 by Arjan van Vught mailto:[email protected]
/* Copyright (C) 2018-2024 by Arjan van Vught mailto:[email protected]
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -54,30 +54,30 @@

coherent_region *p_coherent_region = nullptr;

static void adjust_link(bool duplex, uint32_t speed) {
void emac_adjust_link(const net::PhyStatus phyStatus) {
DEBUG_ENTRY
DEBUG_PRINTF("duplex=%u, speed=%u", duplex, speed);

uint32_t value = H3_EMAC->CTL0;
printf("Link %s, %d, %s\n",
phyStatus.link == net::Link::STATE_UP ? "Up" : "Down",
phyStatus.speed == net::Speed::SPEED10 ? 10 : 100,
phyStatus.duplex == net::Duplex::DUPLEX_HALF ? "HALF" : "FULL");

auto value = H3_EMAC->CTL0;

if (duplex) {
if (phyStatus.duplex == net::Duplex::DUPLEX_FULL) {
value |= CTL0_DUPLEX_FULL_DUPLEX;
} else {
value &= (uint32_t)~CTL0_DUPLEX_FULL_DUPLEX;
}

value &= (uint32_t)~(CTL0_SPEED_MASK << CTL0_SPEED_SHIFT);

switch (speed) {
case 1000:
break;
case 100:
value |= CTL0_SPEED_100M;
break;
case 10:
switch (phyStatus.speed) {
case net::Speed::SPEED10:
value |= CTL0_SPEED_10M;
break;
default:
value |= CTL0_SPEED_100M;
break;
}

Expand Down Expand Up @@ -171,15 +171,7 @@ void __attribute__((cold)) emac_start(uint8_t macAddress[], net::Link& link) {

link = phyStatus.link;

const bool fullDuplex = (phyStatus.duplex == net::Duplex::DUPLEX_FULL);
const uint32_t speed = (phyStatus.speed == net::Speed::SPEED10 ? 10 : 100);

DEBUG_PRINTF("%s, %d, %s",
phyStatus.link == net::Link::STATE_UP ? "Up" : "Down",
speed == 10 ? 10 : 100,
fullDuplex ? "FULL" : "HALF" );

adjust_link(fullDuplex, speed);
emac_adjust_link(phyStatus);

#ifndef NDEBUG
printf("sizeof(struct coherent_region)=%u\n", sizeof(struct coherent_region));
Expand Down
37 changes: 22 additions & 15 deletions lib-network/src/emac/network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,6 @@ Network::Network() {
NetworkParams params;
params.Load();

m_IpInfo.ip.addr = params.GetIpAddress();
m_IpInfo.netmask.addr = params.GetNetMask();
m_IpInfo.gw.addr = params.GetDefaultGateway();
m_IsDhcpUsed = params.isDhcpUsed();
m_nNtpServerIp = params.GetNtpServer();
m_fNtpUtcOffset = params.GetNtpUtcOffset();

Expand Down Expand Up @@ -118,11 +114,28 @@ Network::Network() {
net::link_status_read();
#endif

network::display_emac_status(net::Link::STATE_UP == s_lastState);
Start(s_lastState);
}

void Network::Start(const net::Link link) {
DEBUG_PRINTF("Link %s", link == net::Link::STATE_UP ? "Up" : "Down");

if (net::Link::STATE_UP == s_lastState) {
DEBUG_PUTS("net::Link::STATE_UP");
NetworkParams params;
params.Load();

m_IpInfo.ip.addr = params.GetIpAddress();
m_IpInfo.netmask.addr = params.GetNetMask();
m_IpInfo.gw.addr = params.GetDefaultGateway();
m_IsDhcpUsed = params.isDhcpUsed();
m_nDhcpRetryTime = params.GetDhcpRetryTime();

#ifndef NDEBUG
Print();
#endif

network::display_emac_status(net::Link::STATE_UP == link);

if (net::Link::STATE_UP == link) {
if (!m_IsDhcpUsed) {
DEBUG_PUTS("");
if (m_IpInfo.ip.addr == 0) {
Expand All @@ -143,17 +156,13 @@ Network::Network() {
network::display_dhcp_status(network::dhcp::ClientStatus::FAILED);
}

const auto nRetryTime = params.GetDhcpRetryTime();
const auto bUseDhcp = params.isDhcpUsed();

while (m_IsZeroconfUsed && (nRetryTime != 0) && bUseDhcp) {
while (m_IsZeroconfUsed && (m_nDhcpRetryTime != 0) && m_IsDhcpUsed) {
Hardware::Get()->SetMode(hardware::ledblink::Mode::FAST);

network::display_dhcp_status(network::dhcp::ClientStatus::RETRYING);

DEBUG_PUTS("");
auto nTime = time(nullptr);
while ((time(nullptr) - nTime) < (nRetryTime * 60)) {
while ((time(nullptr) - nTime) < (m_nDhcpRetryTime * 60)) {
Hardware::Get()->Run();
}

Expand All @@ -171,8 +180,6 @@ Network::Network() {
}
}
} else {
DEBUG_PUTS("net::Link::STATE_DOWN");

if (m_IsDhcpUsed) {
DEBUG_PUTS("m_IsDhcpUsed=true");
m_IpInfo.ip.addr = 0;
Expand Down
34 changes: 26 additions & 8 deletions lib-network/src/emac/phy/link_handle_change.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* link_handle_change.cpp
*
*/
/* Copyright (C) 2022 by Arjan van Vught mailto:[email protected]
/* Copyright (C) 2022-2024 by Arjan van Vught mailto:[email protected]
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand All @@ -23,22 +23,40 @@
* THE SOFTWARE.
*/

#include "hardware.h"
#include "network.h"

#include "debug.h"

/**
* Default implementation
*/
#if !defined(PHY_ADDRESS)
# define PHY_ADDRESS 1
#endif

extern void emac_adjust_link(const net::PhyStatus);

namespace net {
void __attribute__((weak)) link_handle_change(const net::Link state) {
void link_handle_change(const net::Link state) {
DEBUG_PRINTF("net::Link %s", state == net::Link::STATE_UP ? "UP" : "DOWN");

if (net::Link::STATE_UP == state) {
if (Network::Get()->IsDhcpUsed()) {
DEBUG_PUTS("Enable DHCP");
Network::Get()->EnableDhcp();
const bool isWatchdog = Hardware::Get()->IsWatchdog();
if (isWatchdog) {
Hardware::Get()->WatchdogStop();
}

net::PhyStatus phyStatus;
net::phy_start(PHY_ADDRESS, phyStatus);

emac_adjust_link(phyStatus);

Network::Get()->Start(net::Link::STATE_UP);

network::mdns_announcement();

Network::Get()->Print();

if (isWatchdog) {
Hardware::Get()->WatchdogInit();
}
}
}
Expand Down
11 changes: 2 additions & 9 deletions lib-network/src/emac/phy/net_link_check.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* net_link_check.cpp
*
*/
/* Copyright (C) 2022-2023 by Arjan van Vught mailto:[email protected]
/* Copyright (C) 2022-2024 by Arjan van Vught mailto:[email protected]
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -48,13 +48,6 @@ void link_pin_poll_init() {
#endif

net::Link link_status_read() {
uint16_t nValue = 0;
phy_read(PHY_ADDRESS, mmi::REG_BMSR, nValue);

if (mmi::BMSR_LINKED_STATUS == (nValue & mmi::BMSR_LINKED_STATUS)) {
return net::Link::STATE_UP;
}

return net::Link::STATE_DOWN;
return net::phy_get_link(PHY_ADDRESS);
}
} // namespace net
Loading

0 comments on commit 3a25056

Please sign in to comment.