#ifndef __CH390_RUNTIME_H__
#define __CH390_RUNTIME_H__

#include <stdbool.h>
#include <stdint.h>

#include "lwip/err.h"

struct netif;
struct pbuf;

typedef struct {
    uint16_t vendor_id;
    uint16_t product_id;
    uint8_t revision;
    uint16_t phy_bmcr;
    uint16_t phy_bmsr;
    uint16_t phy_id1;
    uint16_t phy_id2;
    uint16_t phy_anar;
    uint16_t phy_anlpar;
    uint16_t phy_aner;
    uint8_t nsr;
    uint8_t ncr;
    uint8_t rcr;
    uint8_t imr;
    uint8_t intcr;
    uint8_t gpr;
    uint8_t isr;
    uint8_t int_pin;
    uint8_t phy_speed_10m;
    uint8_t phy_full_duplex;
    uint8_t link_up;
    uint8_t id_valid;
    uint32_t rx_poll_calls;
    uint32_t rx_ready_hits;
    uint32_t rx_packets_ok;
    uint32_t rx_packets_drop;
    uint32_t tx_packets_ok;
    uint32_t tx_packets_timeout;
    uint32_t rx_pbuf_alloc_failed;
    uint32_t rx_filtered_frames;
    uint32_t rx_filtered_ipv6;
    uint32_t rx_filtered_udp;
    uint32_t rx_filtered_igmp;
    uint32_t rx_filtered_lldp;
    uint32_t rx_filtered_other_eth;
    uint32_t rx_filtered_other_ipv4;
    uint32_t rx_filtered_malformed;
    uint32_t rx_arp_frames;
    uint32_t rx_ip_frames;
    uint32_t rx_ipv4_icmp_frames;
    uint32_t rx_ipv4_tcp_frames;
    uint32_t rx_ipv4_udp_frames;
    uint32_t rx_other_frames;
    uint32_t rx_unicast_self_frames;
    uint32_t rx_broadcast_frames;
    uint32_t rx_multicast_frames;
    uint16_t last_frame_len;
    uint16_t last_payload_len;
    uint16_t last_eth_type;
} ch390_diag_t;

void ch390_runtime_init(struct netif *netif, const uint8_t *mac);
struct pbuf *ch390_runtime_input_frame(struct netif *netif);
void ch390_runtime_set_irq_pending(void);
uint8_t ch390_runtime_is_irq_pending(void);
void ch390_runtime_poll(struct netif *netif);
void ch390_runtime_check_link(struct netif *netif);
err_t ch390_runtime_output(struct netif *netif, struct pbuf *p);
void ch390_runtime_get_diag(ch390_diag_t *diag);
bool ch390_runtime_is_ready(void);
bool ch390_runtime_emergency_reset(struct netif *netif);
void ch390_runtime_health_check(struct netif *netif);
uint8_t ch390_runtime_get_reset_count(void);

#endif
