diff --git a/features/net/FEATURE_IPV4/lwip-interface/EthernetInterface.cpp b/features/net/FEATURE_IPV4/lwip-interface/EthernetInterface.cpp index ba40a801ff..3c89951346 100644 --- a/features/net/FEATURE_IPV4/lwip-interface/EthernetInterface.cpp +++ b/features/net/FEATURE_IPV4/lwip-interface/EthernetInterface.cpp @@ -21,7 +21,7 @@ /* Interface implementation */ int EthernetInterface::connect() { - return lwip_bringup(); + return lwip_bringup(NULL); } int EthernetInterface::disconnect() diff --git a/features/net/FEATURE_IPV4/lwip-interface/LWIPIPStack.cpp b/features/net/FEATURE_IPV4/lwip-interface/LWIPIPStack.cpp new file mode 100644 index 0000000000..e4a907f090 --- /dev/null +++ b/features/net/FEATURE_IPV4/lwip-interface/LWIPIPStack.cpp @@ -0,0 +1,40 @@ +/* LWIPIPStackInterface + * Copyright (c) 2015 - 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "IPStackInterface.h" +#include "lwip_stack.h" + +/** LWIP specific implementation of IPStackInterface */ + +void IPStackInterface::bringup(emac_interface_t *emac) +{ + lwip_bringup(emac); +} + +void IPStackInterface::bringdown() +{ + lwip_bringdown(); +} + +const char * IPStackInterface::get_mac_address() +{ + return lwip_get_mac_address(); +} + +const char * IPStackInterface::get_ip_address() +{ + return lwip_get_ip_address(); +} diff --git a/features/net/FEATURE_IPV4/lwip-interface/emac_lwip.c b/features/net/FEATURE_IPV4/lwip-interface/emac_lwip.c new file mode 100644 index 0000000000..bcec801095 --- /dev/null +++ b/features/net/FEATURE_IPV4/lwip-interface/emac_lwip.c @@ -0,0 +1,111 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "platform.h" + +#if DEVICE_EMAC + +#include "emac_api.h" +#include "emac_stack_mem.h" +#include "lwip/tcpip.h" +#include "lwip/tcp.h" +#include "lwip/ip.h" +#include "netif/etharp.h" +#include "netif/ppp_oe.h" + +static err_t emac_lwip_low_level_output(struct netif *netif, struct pbuf *p) +{ + emac_interface_t *mac = (emac_interface_t *)netif->state; + bool ret = mac->ops.link_out(mac, (emac_stack_mem_t *)p); + + return ret ? ERR_OK : ERR_IF; +} + +static err_t emac_lwip_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) +{ + /* Only send packets if the link is up */ + if (netif->flags & NETIF_FLAG_UP) { + return etharp_output(netif, q, ipaddr); + } + + return ERR_CONN; +} + +static void emac_lwip_input(void *data, emac_stack_t *buf) +{ + struct eth_hdr *ethhdr; + struct pbuf *p = (struct pbuf *)buf; + struct netif *netif = (struct netif *)data; + + /* pass all packets to ethernet_input, which decides what packets it supports */ + if (netif->input(p, netif) != ERR_OK) { + LWIP_DEBUGF(NETIF_DEBUG, ("Emac LWIP: IP input error\n")); + + pbuf_free(p); + } +} + +static void emac_lwip_state_change(void *data, bool up) +{ + struct netif *netif = (struct netif *)data; + + if (up) { + tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_up, netif, 1); + } else { + tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_down, netif, 1); + } +} + +err_t emac_lwip_if_init(struct netif *netif) +{ + int err = ERR_OK; + emac_interface_t *mac = (emac_interface_t *)netif->state; + + mac->ops.set_link_input_cb(mac, emac_lwip_input, netif); + mac->ops.set_link_state_cb(mac, emac_lwip_state_change, netif); + + netif->hwaddr_len = mac->ops.get_hwaddr_size(mac); + mac->ops.get_hwaddr(mac, netif->hwaddr); + + netif->mtu = mac->ops.get_mtu_size(mac); + + /* Interface capabilities */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP; + + mac->ops.get_ifname(mac, netif->name, 2); + + netif->output = emac_lwip_output; + netif->linkoutput = emac_lwip_low_level_output; + + if (!mac->ops.power_up(mac)) { + err = ERR_IF; + } + + return err; +} + +/* That's a compatibility layer for lwip_stack.c, it's already done by emac_interface in power_up and power_down */ +void eth_arch_enable_interrupts(void) +{ + +} + +void eth_arch_disable_interrupts(void) +{ + +} + +#endif /* DEVICE_EMAC */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/emac_stack_lwip.cpp b/features/net/FEATURE_IPV4/lwip-interface/emac_stack_lwip.cpp new file mode 100644 index 0000000000..8042a81d2e --- /dev/null +++ b/features/net/FEATURE_IPV4/lwip-interface/emac_stack_lwip.cpp @@ -0,0 +1,83 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "platform.h" + +#if DEVICE_EMAC + +#include "emac_stack_mem.h" +#include "pbuf.h" + +emac_stack_mem_t *emac_stack_mem_alloc(emac_stack_t* stack, uint32_t size, uint32_t align) +{ + + struct pbuf *pbuf = pbuf_alloc(PBUF_RAW, size + align, PBUF_RAM); + if (pbuf == NULL) { + return NULL; + } + + if (align) { + uint32_t remainder = (uint32_t)pbuf->payload % align; + uint32_t offset = align - remainder; + if (offset >= align) { + offset = align; + } + + pbuf->payload = (void*)((char*)pbuf->payload + offset); + pbuf->tot_len -= offset; + pbuf->len -= offset; + } + + return (emac_stack_mem_t*)pbuf; +} + +void emac_stack_mem_free(emac_stack_t* stack, emac_stack_mem_t *mem) +{ + pbuf_free((struct pbuf*)mem); +} + +void *emac_stack_mem_ptr(emac_stack_t* stack, emac_stack_mem_t *mem) +{ + return ((struct pbuf*)mem)->payload; +} + +uint32_t emac_stack_mem_len(emac_stack_t* stack, emac_stack_mem_t *mem) +{ + return ((struct pbuf*)mem)->len; +} + +void emac_stack_mem_set_len(emac_stack_t* stack, emac_stack_mem_t *mem, uint32_t len) +{ + struct pbuf *pbuf = (struct pbuf*)mem; + + pbuf->len = len; +} + +emac_stack_mem_t *emac_stack_mem_chain_dequeue(emac_stack_t* stack, emac_stack_mem_chain_t **chain) +{ + struct pbuf **list = (struct pbuf**)chain; + struct pbuf *head = *list; + *list = (*list)->next; + + return (emac_stack_mem_t *)head; +} + +uint32_t emac_stack_mem_chain_len(emac_stack_t* stack, emac_stack_mem_chain_t *chain) +{ + return ((struct pbuf*)chain)->tot_len; +} + +#endif /* DEVICE_EMAC */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/eth_arch.h b/features/net/FEATURE_IPV4/lwip-interface/eth_arch.h index 1ff54b1d38..d334713636 100644 --- a/features/net/FEATURE_IPV4/lwip-interface/eth_arch.h +++ b/features/net/FEATURE_IPV4/lwip-interface/eth_arch.h @@ -31,7 +31,12 @@ extern "C" { void eth_arch_enable_interrupts(void); void eth_arch_disable_interrupts(void); + +#if DEVICE_EMAC +err_t emac_lwip_if_init(struct netif *netif); +#else /* DEVICE_EMAC */ err_t eth_arch_enetif_init(struct netif *netif); +#endif /* DEVICE_MAC */ #ifdef __cplusplus } diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip_stack.c b/features/net/FEATURE_IPV4/lwip-interface/lwip_stack.c index 50b377052b..6c77711a44 100644 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip_stack.c +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip_stack.c @@ -30,6 +30,7 @@ #include "lwip/tcp.h" #include "lwip/ip.h" +#include "emac_api.h" /* Static arena of sockets */ static struct lwip_socket { @@ -142,7 +143,7 @@ const char *lwip_get_ip_address(void) return lwip_ip_addr[0] ? lwip_ip_addr : 0; } -int lwip_bringup(void) +int lwip_bringup(emac_interface_t *emac) { // Check if we've already connected if (!lwip_get_mac_address()) { @@ -157,7 +158,11 @@ int lwip_bringup(void) sys_arch_sem_wait(&lwip_tcpip_inited, 0); memset(&lwip_netif, 0, sizeof lwip_netif); +#if DEVICE_EMAC + netif_add(&lwip_netif, 0, 0, 0, emac, emac_lwip_if_init, tcpip_input); +#else /* DEVICE_EMAC */ netif_add(&lwip_netif, 0, 0, 0, NULL, eth_arch_enetif_init, tcpip_input); +#endif /* DEVICE_EMAC */ netif_set_default(&lwip_netif); netif_set_link_callback (&lwip_netif, lwip_netif_link_irq); diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip_stack.h b/features/net/FEATURE_IPV4/lwip-interface/lwip_stack.h index f09e73a8e8..08d44e2dbe 100644 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip_stack.h +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip_stack.h @@ -18,6 +18,7 @@ #define LWIP_STACK_H #include "nsapi.h" +#include "emac_api.h" #ifdef __cplusplus extern "C" { @@ -25,7 +26,7 @@ extern "C" { // Access to lwip through the nsapi -int lwip_bringup(void); +int lwip_bringup(emac_interface_t *emac); void lwip_bringdown(void); extern nsapi_stack_t lwip_stack; diff --git a/features/net/network-socket/IPStackInterface.h b/features/net/network-socket/IPStackInterface.h new file mode 100644 index 0000000000..a407c7448d --- /dev/null +++ b/features/net/network-socket/IPStackInterface.h @@ -0,0 +1,57 @@ +/* IPStackInterface + * Copyright (c) 2015 - 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IP_STACK_INTERFACE_H +#define IP_STACK_INTERFACE_H + +#include "emac_api.h" + +/** + * IPStackInterface + * + * Abstraction class on top of IP stack, enables WiFiInterface implementation to setup IP stack + */ +class IPStackInterface +{ +public: + /** + * Brings up the IP stack using provided @a emac interface + * + * @param emac Emack backend to use + */ + virtual void bringup(emac_interface_t *emac); + + /** + * Brings down the IP stack + */ + virtual void bringdown(); + + /** + * Returns MAC address + * + * @return MAC address in "00:11:22:33:44:55" form + */ + virtual const char *get_mac_address(); + + /** + * Returns interfaces IP address + * + * @return IP address in "10.11.12.13" form + */ + virtual const char *get_ip_address(); +}; + +#endif /* IP_STACK_INTERFACE_H */ diff --git a/features/net/network-socket/WiFiInterface.h b/features/net/network-socket/WiFiInterface.h index 21e4f10ca4..b928480004 100644 --- a/features/net/network-socket/WiFiInterface.h +++ b/features/net/network-socket/WiFiInterface.h @@ -29,7 +29,7 @@ typedef struct wifi_ap { } wifi_ap_t; typedef void (*wifi_ap_scan_cb_t)(wifi_ap_t *ap, void *data); -typedef void (*wifi_connect_cb_t)(nsapi_error_t res, void *data); +typedef void (*wifi_connect_cb_t)(nsapi_error_t res, wifi_ap_t *ap, void *data); /** WiFiInterface class * @@ -44,30 +44,34 @@ public: * * @param ssid Name of the network to connect to * @param pass Security passphrase to connect to the network - * @param security Type of encryption for connection - * @param timeout Timeout in milliseconds; 0 for no timeout + * @param security Type of encryption for connection (Default: NSAPI_SECURITY_NONE) + * @param channel Channel on which the connection is to be made, or 0 for any (Default: 0) + * @param timeout Timeout in milliseconds; 0 for no timeout (Default: 0) * @return 0 on success, or error code on failure */ virtual nsapi_error_t connect(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE, - unsigned timeout = 0) = 0; + uint8_t channel = 0, unsigned timeout = 0) = 0; /** Start the interface * * Attempts to connect to a WiFi network asynchronously, the call will return straight away. If the @a cb was NULL * you'll need to query @a get_state until it's in NSAPI_IF_STATE_CONNECTED state, otherwise the @a cb will be - * called with connection results. + * called with connection results, connected AP details and user data. * * Note: @a ssid and @a pass must be kept until the connection is made, that is the callback has been called or the * state changed to @a NSAPI_IF_STATE_CONNECTED as they are passed by value. * * @param ssid Name of the network to connect to * @param pass Security passphrase to connect to the network - * @param security Type of encryption for connection - * @param cb Function to be called when the connect finishes - * @param data Arbitrary user data to pass to @a cb function + * @param channel Channel on which the connection is to be made, or 0 for any (Default: 0) + * @param security Type of encryption for connection (Default: NSAPI_SECURITY_NONE) + * @param cb Function to be called when the connect finishes (Default: NULL) + * @param data Arbitrary user data to pass to @a cb function (Default: NULL) + * @param timeout Timeout in milliseconds; 0 for no timeout (Default: 0) */ virtual void connect_async(const char *ssid, const char *pass,nsapi_security_t security = NSAPI_SECURITY_NONE, - wifi_connect_cb_t cb = NULL, void *data = NULL) = 0; + uint8_t channel = 0, wifi_connect_cb_t cb = NULL, void *data = NULL, + unsigned timeout = 0) = 0; /** Stop the interface * @@ -77,7 +81,7 @@ public: /** Get the local MAC address * - * @return Null-terminated representation of the local MAC address + * @return Null-terminated representation of the local MAC address in "00:11:22:33:44:55" form */ virtual const char *get_mac_address() = 0; @@ -99,7 +103,7 @@ public: * * @param ap Pointer to allocated array to store discovered AP * @param count Size of allocated @a res array, or 0 to only count available AP - * @param timeout Timeout in milliseconds; 0 for no timeout + * @param timeout Timeout in milliseconds; 0 for no timeout (Default: 0) * @return Number of entries in @a, or if @a count was 0 number of available networks, negative on error * see @a nsapi_error */ @@ -112,9 +116,10 @@ public: * will be always called at least once. * * @param cb Function to be called for every discovered network - * @param data A user handle that will be passed to @a cb along with the AP data + * @param data User handle that will be passed to @a cb along with the AP data (Default: NULL) + * @param timeout Timeout in milliseconds; 0 for no timeout (Default: 0) */ - virtual void scan_async(wifi_ap_scan_cb_t cb, void *data = NULL) = 0; + virtual void scan_async(wifi_ap_scan_cb_t cb, void *data = NULL, unsigned timeout = 0) = 0; }; #endif diff --git a/features/net/network-socket/emac_stack_mem.h b/features/net/network-socket/emac_stack_mem.h new file mode 100644 index 0000000000..edf48b5464 --- /dev/null +++ b/features/net/network-socket/emac_stack_mem.h @@ -0,0 +1,95 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_EMAC_STACK_MEM_H +#define MBED_EMAC_STACK_MEM_H + +#include + +/** + * Stack memory module + * + * This interface provides abstraction for memory modules used in different IP stacks (often to accommodate zero copy). + * Emac interface may be required to accept output packets and provide received data using this stack specific API. + * This header should be implemented for each IP stack, so that we keep emacs module independent. + */ +typedef void emac_stack_mem_t; +typedef void emac_stack_mem_chain_t; +typedef void emac_stack_t; + +/** + * Allocates stack memory + * + * @param stack Emac stack context + * @param size Size of memory to allocate + * @param align Memory alignment requirements + * @return Allocated memory struct, or NULL in case of error + */ +emac_stack_mem_t *emac_stack_mem_alloc(emac_stack_t* stack, uint32_t size, uint32_t align); + +/** + * Free memory allocated using @a stack_mem_alloc + * + * @param stack Emac stack context + * @param mem Memory to be freed + */ +void emac_stack_mem_free(emac_stack_t* stack, emac_stack_mem_t *mem); + +/** + * Return pointer to the payload + * + * @param stack Emac stack context + * @param mem Memory structure + * @return Pointer to the payload + */ +void *emac_stack_mem_ptr(emac_stack_t* stack, emac_stack_mem_t *mem); + +/** + * Return actual payload size + * + * @param stack Emac stack context + * @param mem Memory structure + * @return Size in bytes + */ +uint32_t emac_stack_mem_len(emac_stack_t* stack, emac_stack_mem_t *mem); + +/** + * Sets the actual payload size (the allocated payload size will not change) + * + * @param stack Emac stack context + * @param mem Memory structure + * @param len Actual payload size + */ +void emac_stack_mem_set_len(emac_stack_t* stack, emac_stack_mem_t *mem, uint32_t len); + +/** + * Returns first memory structure from the list and move the head to point to the next node + * + * @param stack Emac stack context + * @param list Pointer to the list + * @return First memory structure from the list + */ +emac_stack_mem_t *emac_stack_mem_chain_dequeue(emac_stack_t* stack, emac_stack_mem_chain_t **chain); + +/** + * Return total length of the memory chain + * + * @param stack Emac stack context + * @param chain Memory chain + * @return Chain length + */ +uint32_t emac_stack_mem_chain_len(emac_stack_t* stack, emac_stack_mem_chain_t *chain); + +#endif /* EMAC_MBED_STACK_MEM_h */ diff --git a/hal/hal/emac_api.h b/hal/hal/emac_api.h new file mode 100644 index 0000000000..9f1db4a1ec --- /dev/null +++ b/hal/hal/emac_api.h @@ -0,0 +1,158 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBED_EMAC_API_H +#define MBED_EMAC_API_H + +#include "platform.h" + +#if DEVICE_EMAC + +#include +#include "emac_stack_mem.h" + +typedef struct emac_interface emac_interface_t; + +/** + * EmacInterface + * + * This interface should be used to abstract low level access to networking hardware + */ + +/** + * Callback to be register with Emac interface and to be called fore received packets + * + * @param data Arbitrary user data (IP stack) + * @param buf Received data + */ +typedef void (*emac_link_input_fn)(void *data, emac_stack_mem_chain_t *buf); + +/** + * Callback to be register with Emac interface and to be called for link status changes + * + * @param data Arbitrary user data (IP stack) + * @param up Link status + */ +typedef void (*emac_link_state_change_fn)(void *data, bool up); + +/** + * Return maximum transmission unit + * + * @param emac Emac interface + * @return MTU in bytes + */ +typedef uint32_t (*emac_get_mtu_size_fn)(emac_interface_t *emac); + +/** + * Return interface name + * + * @param emac Emac interface + * @param name Pointer to where the name should be written + * @param size Maximum number of character to copy + */ +typedef void (*emac_get_ifname_fn)(emac_interface_t *emac, char *name, uint8_t size); + +/** + * Returns size of the underlying interface HW address size + * + * @param emac Emac interface + * @return HW address size in bytes + */ +typedef uint8_t (*emac_get_hwaddr_size_fn)(emac_interface_t *emac); + +/** + * Return interface hw address + * + * Copies HW address to provided memory, @param addr has to be of correct size see @a get_hwaddr_size + * + * @param emac Emac interface + * @param addr HW address for underlying interface + */ +typedef void (*emac_get_hwaddr_fn)(emac_interface_t *emac, uint8_t *addr); + +/** + * Set HW address for interface + * + * Provided address has to be of correct size, see @a get_hwaddr_size + * + * @param emac Emac interface + * @param addr Address to be set + */ +typedef void (*emac_set_hwaddr_fn)(emac_interface_t *emac, uint8_t *addr); + +/** + * Sends the packet over the link + * + * That can not be called from an interrupt context. + * + * @param emac Emac interface + * @param buf Packet to be send + * @return True if the packet was send successfully, False otherwise + */ +typedef bool (*emac_link_out_fn)(emac_interface_t *emac, emac_stack_mem_t *buf); + +/** + * Initializes the HW + * + * @return True on success, False in case of an error. + */ +typedef bool (*emac_power_up_fn)(emac_interface_t *emac); + +/** + * Deinitializes the HW + * + * @param emac Emac interface + */ +typedef void (*emac_power_down_fn)(emac_interface_t *emac); + +/** + * Sets a callback that needs to be called for packets received for that interface + * + * @param emac Emac interface + * @param input_cb Function to be register as a callback + * @param data Arbitrary user data to be passed to the callback + */ +typedef void (*emac_set_link_input_cb_fn)(emac_interface_t *emac, emac_link_input_fn input_cb, void *data); + +/** + * Sets a callback that needs to be called on link status changes for given interface + * + * @param emac Emac interface + * @param state_cb Function to be register as a callback + * @param data Arbitrary user data to be passed to the callback + */ +typedef void (*emac_set_link_state_cb_fn)(emac_interface_t *emac, emac_link_state_change_fn state_cb, void *data); + +typedef struct emac_interface_ops { + emac_get_mtu_size_fn get_mtu_size; + emac_get_ifname_fn get_ifname; + emac_get_hwaddr_size_fn get_hwaddr_size; + emac_get_hwaddr_fn get_hwaddr; + emac_set_hwaddr_fn set_hwaddr; + emac_link_out_fn link_out; + emac_power_up_fn power_up; + emac_power_down_fn power_down; + emac_set_link_input_cb_fn set_link_input_cb; + emac_set_link_state_cb_fn set_link_state_cb; +} emac_interface_ops_t; + +typedef struct emac_interface { + const emac_interface_ops_t ops; + void *hw; +} emac_interface_t; + +#endif /* DEVICE_EMAC */ +#endif /* MBED_EMAC_API_H */