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.
NanostackEMACInterface.cpp
00001 /* 00002 * Copyright (c) 2017 ARM Limited. All rights reserved. 00003 */ 00004 00005 #include "Nanostack.h" 00006 #include "NanostackEthernetInterface.h" 00007 #include "NanostackEthernetPhy.h" 00008 #include "EMAC.h" 00009 #include "nsdynmemLIB.h" 00010 #include "arm_hal_phy.h" 00011 00012 class EMACPhy : public NanostackEthernetPhy 00013 { 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(callback(this, &EMACPhy::emac_phy_rx)); 00142 00143 if (!emac.power_up()) { 00144 return -1; 00145 } 00146 00147 phy.phy_MTU = emac.get_mtu_size(); 00148 /* Set the address - this could be either board default, what they 00149 * told us with EMAC::get_mac_address, or something manually specified 00150 * with EMACPhy::set_mac_address 00151 */ 00152 emac.set_hwaddr(mac_addr); 00153 00154 emac.set_all_multicast(true); 00155 00156 device_id = arm_net_phy_register(&phy); 00157 // driver_readiness_status_callback = driver_status_cb; 00158 00159 if (device_id < 0){ 00160 //tr_error("Ethernet Driver failed to register with Stack. RetCode=%i", eth_driver_enabled); 00161 //driver_readiness_status_callback(0, eth_interface_id); 00162 emac.power_down(); 00163 return -1; 00164 } 00165 } 00166 00167 return device_id; 00168 } 00169 00170 void EMACPhy::get_mac_address(uint8_t *mac) 00171 { 00172 memcpy(mac, mac_addr, sizeof mac_addr); 00173 } 00174 00175 void EMACPhy::set_mac_address(uint8_t *mac) 00176 { 00177 memcpy(mac_addr, mac, sizeof mac_addr); 00178 } 00179 00180 nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, Nanostack::EthernetInterface **interface_out, const uint8_t *mac_addr) 00181 { 00182 if (single_phy) { 00183 return NSAPI_ERROR_DEVICE_ERROR ; 00184 } 00185 00186 single_phy = new (nothrow) EMACPhy(this->memory_manager, emac); 00187 if (!single_phy) { 00188 return NSAPI_ERROR_NO_MEMORY ; 00189 } 00190 00191 if (mac_addr) { 00192 single_phy->set_mac_address(const_cast<uint8_t*>(mac_addr)); 00193 } 00194 00195 Nanostack::EthernetInterface *interface; 00196 00197 interface = new (nothrow) Nanostack::EthernetInterface(*single_phy); 00198 if (!interface) { 00199 return NSAPI_ERROR_NO_MEMORY ; 00200 } 00201 00202 nsapi_error_t err = interface->initialize(); 00203 if (err) { 00204 return err; 00205 } 00206 00207 *interface_out = interface; 00208 00209 return NSAPI_ERROR_OK ; 00210 00211 } 00212 00213 nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out) 00214 { 00215 Nanostack::EthernetInterface *interface; 00216 nsapi_error_t err = add_ethernet_interface(emac, default_if, &interface); 00217 *interface_out = interface; 00218 return err; 00219 }
Generated on Tue Jul 12 2022 12:45:35 by
