Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
NanostackEMACInterface.cpp
00001 /* 00002 * Copyright (c) 2017 ARM Limited. All rights reserved. 00003 */ 00004 00005 #include "NanostackEthernetInterface.h" 00006 #include "NanostackEthernetPhy.h" 00007 #include "nsdynmemLIB.h" 00008 #include "arm_hal_phy.h" 00009 #include "EMAC.h" 00010 #include "enet_tasklet.h" 00011 #include "mbed_interface.h" 00012 00013 class EMACPhy : public NanostackEthernetPhy { 00014 public: 00015 EMACPhy(NanostackMemoryManager &mem, EMAC &m); 00016 virtual int8_t phy_register(); 00017 virtual void get_mac_address(uint8_t *mac); 00018 virtual void set_mac_address(uint8_t *mac); 00019 00020 int8_t address_write(phy_address_type_e, uint8_t *); 00021 int8_t tx(uint8_t *data_ptr, uint16_t data_len, uint8_t tx_handle, data_protocol_e data_flow); 00022 00023 void emac_phy_rx(emac_mem_buf_t *mem); 00024 00025 private: 00026 NanostackMemoryManager &memory_manager; 00027 EMAC &emac; 00028 uint8_t mac_addr[6]; 00029 int8_t device_id; 00030 phy_device_driver_s phy; 00031 }; 00032 00033 // GAH! no handles on the callback. Force a single interface 00034 static EMACPhy *single_phy; 00035 00036 extern "C" 00037 { 00038 static int8_t emac_phy_address_write(phy_address_type_e address_type, uint8_t *address_ptr) 00039 { 00040 return single_phy->address_write(address_type, address_ptr); 00041 } 00042 00043 static int8_t emac_phy_interface_state_control(phy_interface_state_e, uint8_t) 00044 { 00045 return -1; 00046 } 00047 00048 static int8_t emac_phy_tx(uint8_t *data_ptr, uint16_t data_len, uint8_t tx_handle, data_protocol_e data_flow) 00049 { 00050 return single_phy->tx(data_ptr, data_len, tx_handle, data_flow); 00051 } 00052 00053 EMACPhy::EMACPhy(NanostackMemoryManager &mem, EMAC &m) : memory_manager(mem), emac(m), device_id(-1) 00054 { 00055 /* Same default address logic as lwIP glue uses */ 00056 #if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE) 00057 mac_addr[0] = MBED_MAC_ADDR_0; 00058 mac_addr[1] = MBED_MAC_ADDR_1; 00059 mac_addr[2] = MBED_MAC_ADDR_2; 00060 mac_addr[3] = MBED_MAC_ADDR_3; 00061 mac_addr[4] = MBED_MAC_ADDR_4; 00062 mac_addr[5] = MBED_MAC_ADDR_5; 00063 #else 00064 mbed_mac_address((char *) mac_addr); 00065 #endif 00066 /* We have a default MAC address, so do don't force them to supply one */ 00067 /* They may or may not update hwaddr with their address */ 00068 emac.get_hwaddr(mac_addr); 00069 } 00070 00071 00072 void EMACPhy::emac_phy_rx(emac_mem_buf_t *mem) 00073 { 00074 const uint8_t *ptr = NULL; 00075 uint8_t *tmpbuf = NULL; 00076 uint32_t total_len; 00077 00078 if (memory_manager.get_next(mem) == NULL) { 00079 // Easy contiguous case 00080 ptr = static_cast<const uint8_t *>(memory_manager.get_ptr(mem)); 00081 total_len = memory_manager.get_len(mem); 00082 } else { 00083 // Nanostack can't accept chunked data - make temporary contiguous copy 00084 total_len = memory_manager.get_total_len(mem); 00085 ptr = tmpbuf = static_cast<uint8_t *>(ns_dyn_mem_temporary_alloc(total_len)); 00086 if (tmpbuf) { 00087 memory_manager.copy_from_buf(tmpbuf, total_len, mem); 00088 } 00089 } 00090 00091 if (ptr && phy.phy_rx_cb) { 00092 phy.phy_rx_cb(ptr, total_len, 0xff, 0, device_id); 00093 } 00094 ns_dyn_mem_free(tmpbuf); 00095 memory_manager.free(mem); 00096 } 00097 00098 } // extern "C" 00099 00100 int8_t EMACPhy::address_write(phy_address_type_e address_type, uint8_t *address_ptr) 00101 { 00102 if (address_type != PHY_MAC_48BIT) { 00103 return -1; 00104 } 00105 memcpy(mac_addr, address_ptr, 6); 00106 emac.set_hwaddr(address_ptr); 00107 return 0; 00108 } 00109 00110 int8_t EMACPhy::tx(uint8_t *data_ptr, uint16_t data_len, uint8_t tx_handle, data_protocol_e data_flow) 00111 { 00112 emac_mem_buf_t *mem = memory_manager.alloc_pool(data_len, 0); 00113 if (!mem) { 00114 return -1; 00115 } 00116 memory_manager.copy_to_buf(mem, data_ptr, data_len); 00117 00118 // They take ownership - their responsibility to free 00119 emac.link_out(mem); 00120 00121 return 0; 00122 } 00123 00124 int8_t EMACPhy::phy_register() 00125 { 00126 if (device_id < 0) { 00127 00128 phy.PHY_MAC = mac_addr; 00129 phy.address_write = emac_phy_address_write; 00130 phy.driver_description = const_cast<char *>("ETH"); 00131 phy.link_type = PHY_LINK_ETHERNET_TYPE; 00132 phy.phy_MTU = 0; 00133 phy.phy_header_length = 0; 00134 phy.phy_tail_length = 0; 00135 phy.state_control = emac_phy_interface_state_control; 00136 phy.tx = emac_phy_tx; 00137 phy.phy_rx_cb = NULL; 00138 phy.phy_tx_done_cb = NULL; 00139 00140 emac.set_memory_manager(memory_manager); 00141 emac.set_link_input_cb(mbed::callback(this, &EMACPhy::emac_phy_rx)); 00142 emac.set_link_state_cb(enet_tasklet_link_state_changed); 00143 00144 if (!emac.power_up()) { 00145 return -1; 00146 } 00147 00148 phy.phy_MTU = emac.get_mtu_size(); 00149 /* Set the address - this could be either board default, what they 00150 * told us with EMAC::get_mac_address, or something manually specified 00151 * with EMACPhy::set_mac_address 00152 */ 00153 emac.set_hwaddr(mac_addr); 00154 00155 emac.set_all_multicast(true); 00156 00157 device_id = arm_net_phy_register(&phy); 00158 // driver_readiness_status_callback = driver_status_cb; 00159 00160 if (device_id < 0) { 00161 //tr_error("Ethernet Driver failed to register with Stack. RetCode=%i", eth_driver_enabled); 00162 //driver_readiness_status_callback(0, eth_interface_id); 00163 emac.power_down(); 00164 return -1; 00165 } 00166 } 00167 00168 return device_id; 00169 } 00170 00171 void EMACPhy::get_mac_address(uint8_t *mac) 00172 { 00173 memcpy(mac, mac_addr, sizeof mac_addr); 00174 } 00175 00176 void EMACPhy::set_mac_address(uint8_t *mac) 00177 { 00178 memcpy(mac_addr, mac, sizeof mac_addr); 00179 } 00180 00181 nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, Nanostack::EthernetInterface **interface_out, const uint8_t *mac_addr) 00182 { 00183 if (single_phy) { 00184 return NSAPI_ERROR_DEVICE_ERROR ; 00185 } 00186 00187 single_phy = new (std::nothrow) EMACPhy(this->memory_manager, emac); 00188 if (!single_phy) { 00189 return NSAPI_ERROR_NO_MEMORY ; 00190 } 00191 00192 if (mac_addr) { 00193 single_phy->set_mac_address(const_cast<uint8_t *>(mac_addr)); 00194 } 00195 00196 Nanostack::EthernetInterface *interface; 00197 00198 interface = new (std::nothrow) Nanostack::EthernetInterface(*single_phy); 00199 if (!interface) { 00200 return NSAPI_ERROR_NO_MEMORY ; 00201 } 00202 00203 nsapi_error_t err = interface->initialize(); 00204 if (err) { 00205 delete interface; 00206 return err; 00207 } 00208 00209 *interface_out = interface; 00210 00211 return NSAPI_ERROR_OK ; 00212 00213 } 00214 00215 nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out) 00216 { 00217 Nanostack::EthernetInterface *interface; 00218 nsapi_error_t err = add_ethernet_interface(emac, default_if, &interface); 00219 *interface_out = interface; 00220 return err; 00221 }
Generated on Tue Jul 12 2022 13:54:35 by
1.7.2