#pragma once #include namespace w6300 { constexpr int SOCK_COUNT = 8; enum class socket_id : uint8_t {}; enum class port_num : uint16_t {}; enum chip_ctl { CW_SYS_LOCK, CW_SYS_UNLOCK, CW_GET_SYSLOCK, CW_RESET_WIZCHIP, CW_INIT_WIZCHIP, CW_GET_INTERRUPT, CW_CLR_INTERRUPT, CW_SET_INTRMASK, CW_GET_INTRMASK, CW_SET_INTRTIME, CW_GET_INTRTIME, CW_SET_IEN, CW_GET_IEN, CW_GET_ID, CW_GET_VER, CW_SET_SYSCLK, CW_GET_SYSCLK, CW_RESET_PHY, CW_SET_PHYCONF, CW_GET_PHYCONF, CW_GET_PHYSTATUS, CW_SET_PHYPOWMODE, CW_GET_PHYPOWMODE, CW_GET_PHYLINK }; enum net_ctl { CN_SET_NETINFO, CN_GET_NETINFO, CN_SET_NETMODE, CN_GET_NETMODE, CN_SET_TIMEOUT, CN_GET_TIMEOUT, CN_SET_PREFER, CN_GET_PREFER, }; enum net_service_ctl { CNS_ARP, CNS_PING, CNS_DAD, CNS_SLAAC, CNS_UNSOL_NA, CNS_GET_PREFIX }; enum intr_kind : uint32_t { IK_PPPOE_TERMINATED = (1 << 0), IK_DEST_UNREACH = (1 << 1), IK_IP_CONFLICT = (1 << 2), IK_DEST_UNREACH6 = (1 << 4), IK_WOL = (1 << 7), IK_NET_ALL = 0x97, IK_SOCK_0 = (1 << 8), IK_SOCK_1 = (1 << 9), IK_SOCK_2 = (1 << 10), IK_SOCK_3 = (1 << 11), IK_SOCK_4 = (1 << 12), IK_SOCK_5 = (1 << 13), IK_SOCK_6 = (1 << 14), IK_SOCK_7 = (1 << 15), IK_SOCK_ALL = (0xFF << 8), IK_SOCKL_TOUT = (1 << 16), IK_SOCKL_ARP4 = (1 << 17), IK_SOCKL_PING4 = (1 << 18), IK_SOCKL_ARP6 = (1 << 19), IK_SOCKL_PING6 = (1 << 20), IK_SOCKL_NS = (1 << 21), IK_SOCKL_RS = (1 << 22), IK_SOCKL_RA = (1 << 23), IK_SOCKL_ALL = (0xFF << 16), IK_INT_ALL = 0x00FFFF97 }; constexpr uint8_t SYS_CHIP_LOCK = (1 << 2); constexpr uint8_t SYS_NET_LOCK = (1 << 1); constexpr uint8_t SYS_PHY_LOCK = (1 << 0); constexpr uint8_t PHY_MODE_MANUAL = 0; constexpr uint8_t PHY_MODE_AUTONEGO = 1; constexpr uint8_t PHY_MODE_TE = 2; constexpr uint8_t PHY_CONFBY_HW = 0; constexpr uint8_t PHY_CONFBY_SW = 1; constexpr uint8_t PHY_SPEED_10 = 0; constexpr uint8_t PHY_SPEED_100 = 1; constexpr uint8_t PHY_DUPLEX_HALF = 0; constexpr uint8_t PHY_DUPLEX_FULL = 1; constexpr uint8_t PHY_LINK_OFF = 0; constexpr uint8_t PHY_LINK_ON = 1; constexpr uint8_t PHY_POWER_NORM = 0; constexpr uint8_t PHY_POWER_DOWN = 1; struct phy_conf { uint8_t by; uint8_t mode; uint8_t speed; uint8_t duplex; }; enum ipconf_mode : uint8_t { NETINFO_NONE = 0x00, NETINFO_STATIC_V4 = 0x01, NETINFO_STATIC_V6 = 0x02, NETINFO_STATIC_ALL = 0x03, NETINFO_SLAAC_V6 = 0x04, NETINFO_DHCP_V4 = 0x10, NETINFO_DHCP_V6 = 0x20, NETINFO_DHCP_ALL = 0x30 }; enum dhcp_mode : uint8_t { NETINFO_STATIC = 1, NETINFO_DHCP }; struct net_info { uint8_t mac[6]; uint8_t ip[4]; uint8_t sn[4]; uint8_t gw[4]; uint8_t lla[16]; uint8_t gua[16]; uint8_t sn6[16]; uint8_t gw6[16]; uint8_t dns[4]; uint8_t dns6[16]; ipconf_mode ipmode; dhcp_mode dhcp; }; enum netmode_type : uint32_t { NM_IPB_V4 = (1 << 0), NM_IPB_V6 = (1 << 1), NM_WOL = (1 << 2), NM_PB6_MULTI = (1 << 4), NM_PB6_ALLNODE = (1 << 5), NM_MR_MASK = 0x37, NM_PPPoE = (1 << 8), NM_DHA_SELECT = (1 << 15), NM_MR2_MASK = (0x09 << 8), NM_PB4_ALL = (1 << 16), NM_TRSTB_V4 = (1 << 17), NM_PARP_V4 = (1 << 18), NM_UNRB_V4 = (1 << 19), NM_NET4_MASK = (0x0F << 16), NM_PB6_ALL = (1 << 24), NM_TRSTB_V6 = (1 << 25), NM_PARP_V6 = (1 << 26), NM_UNRB_V6 = (1 << 27), NM_NET6_MASK = (0x0F << 24), NM_MASK_ALL = 0x0F0F0937 }; struct net_timeout { uint8_t s_retry_cnt; uint16_t s_time_100us; uint8_t sl_retry_cnt; uint16_t sl_time_100us; }; struct ip_address { uint8_t ip[16]; uint8_t len; }; struct prefix { uint8_t len; uint8_t flag; uint32_t valid_lifetime; uint32_t preferred_lifetime; uint8_t prefix[16]; }; struct arp_request { ip_address destinfo; uint8_t dha[6]; }; struct ping_request { uint16_t id; uint16_t seq; ip_address destinfo; }; int8_t ctl_chip(chip_ctl type, void* arg); int8_t ctl_net(net_ctl type, void* arg); int8_t ctl_net_service(net_service_ctl type, void* arg); void soft_reset(); int8_t init_buffers(uint8_t* txsize, uint8_t* rxsize); void clear_interrupt(intr_kind intr); intr_kind get_interrupt(); void set_interrupt_mask(intr_kind intr); intr_kind get_interrupt_mask(); int8_t get_phy_link(); int8_t get_phy_power_mode(); void reset_phy(); void set_phy_conf(phy_conf* conf); void get_phy_conf(phy_conf* conf); void get_phy_status(phy_conf* conf); void set_phy_power_mode(uint8_t pmode); void set_net_info(net_info* info); void get_net_info(net_info* info); void set_net_mode(netmode_type mode); netmode_type get_net_mode(); void set_timeout(net_timeout* timeout); void get_timeout(net_timeout* timeout); int8_t send_arp(arp_request* arp); int8_t send_ping(ping_request* ping); int8_t send_dad(uint8_t* ipv6); int8_t send_slaac(prefix* pfx); int8_t send_unsolicited(); int8_t get_prefix(prefix* pfx); void init_spi(); void init_critical_section(); void reset(); void init(); bool check(); void init_net(net_info info); using iodata_t = uint8_t; using datasize_t = int16_t; constexpr int16_t SOCK_OK = 1; constexpr int16_t SOCK_BUSY = 0; constexpr int16_t SOCK_FATAL = -1000; constexpr int16_t SOCK_ERROR = 0; constexpr int16_t SOCKERR_SOCKNUM = SOCK_ERROR - 1; constexpr int16_t SOCKERR_SOCKOPT = SOCK_ERROR - 2; constexpr int16_t SOCKERR_SOCKINIT = SOCK_ERROR - 3; constexpr int16_t SOCKERR_SOCKCLOSED = SOCK_ERROR - 4; constexpr int16_t SOCKERR_SOCKMODE = SOCK_ERROR - 5; constexpr int16_t SOCKERR_SOCKFLAG = SOCK_ERROR - 6; constexpr int16_t SOCKERR_SOCKSTATUS = SOCK_ERROR - 7; constexpr int16_t SOCKERR_ARG = SOCK_ERROR - 10; constexpr int16_t SOCKERR_PORTZERO = SOCK_ERROR - 11; constexpr int16_t SOCKERR_IPINVALID = SOCK_ERROR - 12; constexpr int16_t SOCKERR_TIMEOUT = SOCK_ERROR - 13; constexpr int16_t SOCKERR_DATALEN = SOCK_ERROR - 14; constexpr int16_t SOCKERR_BUFFER = SOCK_ERROR - 15; constexpr int16_t SOCKFATAL_PACKLEN = SOCK_FATAL - 1; constexpr uint8_t SF_MULTI_ENABLE = 1 << 7; constexpr uint8_t SF_ETHER_OWN = 1 << 7; constexpr uint8_t SF_BROAD_BLOCK = 1 << 6; constexpr uint8_t SF_TCP_FPSH = 1 << 6; constexpr uint8_t SF_TCP_NODELAY = 1 << 5; constexpr uint8_t SF_IGMP_VER2 = 1 << 5; constexpr uint8_t SF_SOLICIT_BLOCK = 1 << 5; constexpr uint8_t SF_ETHER_MULTI4B = 1 << 5; constexpr uint8_t SF_UNI_BLOCK = 1 << 4; constexpr uint8_t SF_ETHER_MULIT6B = 1 << 4; constexpr uint8_t SF_FORCE_ARP = 1 << 0; constexpr uint8_t SF_DHA_MANUAL = 1 << 1; constexpr uint8_t SF_IO_NONBLOCK = 1 << 3; constexpr uint8_t PACK_IPv6 = 1 << 7; constexpr uint8_t PACK_IPV6_ALLNODE = PACK_IPv6 | (1 << 6); constexpr uint8_t PACK_IPV6_MULTI = PACK_IPv6 | (1 << 5); constexpr uint8_t PACK_IPV6_LLA = PACK_IPv6 | (1 << 4); constexpr uint8_t PACK_COMPLETED = 1 << 3; constexpr uint8_t PACK_REMAINED = 1 << 2; constexpr uint8_t PACK_FIRST = 1 << 1; constexpr uint8_t PACK_NONE = 0x00; constexpr uint8_t SRCV6_PREFER_AUTO = 0x00; constexpr uint8_t SRCV6_PREFER_LLA = 0x02; constexpr uint8_t SRCV6_PREFER_GUA = 0x03; constexpr uint8_t TCPSOCK_MODE = 1 << 2; constexpr uint8_t TCPSOCK_OP = 1 << 1; constexpr uint8_t TCPSOCK_SIP = 1 << 0; constexpr uint8_t SOCK_IO_BLOCK = 0; constexpr uint8_t SOCK_IO_NONBLOCK = 1; int8_t open_socket(socket_id sn, uint8_t protocol, port_num port, uint8_t flag); int8_t close(socket_id sn); int8_t listen(socket_id sn); int8_t disconnect(socket_id sn); int32_t send(socket_id sn, uint8_t* buf, uint16_t len); int32_t recv(socket_id sn, uint8_t* buf, uint16_t len); enum sockint_kind { SIK_CONNECTED = (1 << 0), SIK_DISCONNECTED = (1 << 1), SIK_RECEIVED = (1 << 2), SIK_TIMEOUT = (1 << 3), SIK_SENT = (1 << 4), SIK_ALL = 0x1F }; enum sock_ctl { CS_SET_IOMODE, CS_GET_IOMODE, CS_GET_MAXTXBUF, CS_GET_MAXRXBUF, CS_CLR_INTERRUPT, CS_GET_INTERRUPT, CS_SET_PREFER, CS_GET_PREFER, CS_SET_INTMASK, CS_GET_INTMASK }; enum sockopt_type { SO_FLAG, SO_TTL, SO_TOS, SO_MSS, SO_DESTIP, SO_DESTPORT, SO_KEEPALIVESEND, SO_KEEPALIVEAUTO, SO_SENDBUF, SO_RECVBUF, SO_STATUS, SO_EXTSTATUS, SO_MODE, SO_REMAINSIZE, SO_PACKINFO }; int8_t ctl_socket(socket_id sn, sock_ctl type, void* arg); int8_t set_sockopt(socket_id sn, sockopt_type type, void* arg); int8_t get_sockopt(socket_id sn, sockopt_type type, void* arg); int16_t peek_socket_msg(socket_id sn, uint8_t* submsg, uint16_t subsize); int8_t connect(socket_id sn, uint8_t* addr, port_num port, uint8_t addrlen); int32_t sendto(socket_id sn, uint8_t* buf, uint16_t len, uint8_t* addr, port_num port, uint8_t addrlen); int32_t recvfrom(socket_id sn, uint8_t* buf, uint16_t len, uint8_t* addr, port_num* port, uint8_t* addrlen); } // namespace w6300