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.
ethernet_mac_api.c
00001 /* 00002 * Copyright (c) 2016-2017, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #include "nsconfig.h" 00019 #include <string.h> 00020 #include "ethernet_mac_api.h" 00021 #include "eventOS_event.h" 00022 #include "nsdynmemLIB.h" 00023 #include "common_functions.h" 00024 #include "MAC/rf_driver_storage.h" 00025 00026 typedef struct eth_mac_internal_s { 00027 eth_mac_api_t *mac_api; 00028 arm_device_driver_list_s *dev_driver; 00029 uint8_t *mtu_ptr; 00030 uint16_t mtu_size; 00031 uint8_t mac48[6]; 00032 bool active_data_request; 00033 int8_t tasklet_id; 00034 //linked list link 00035 }eth_mac_internal_t; 00036 00037 static eth_mac_internal_t mac_store = //Hack only at this point, later put into linked list 00038 { 00039 .tasklet_id = -1 00040 }; 00041 00042 #define ETH_INIT_EVENT 0 00043 #define ETH_DATA_IND_EVENT 1 00044 #define ETH_DATA_CNF_EVENT 2 00045 00046 00047 #define ETHERNET_HDROFF_DST_ADDR 0 00048 #define ETHERNET_HDROFF_SRC_ADDR 6 00049 #define ETHERNET_HDROFF_TYPE 12 00050 #define ETHERNET_HDRLEN 14 00051 00052 static int8_t eth_mac_api_init(eth_mac_api_t *api, eth_mac_data_confirm *conf_cb, eth_mac_data_indication *ind_cb, uint8_t parent_id); 00053 static void data_req(const eth_mac_api_t* api, const eth_data_req_t *data); 00054 static int8_t mac48_address_set( const eth_mac_api_t* api, const uint8_t *mac48); 00055 static int8_t mac48_address_get( const eth_mac_api_t* api, uint8_t *mac48_buf); 00056 00057 static int8_t eth_mac_net_phy_rx(const uint8_t *data_ptr, uint16_t data_len, uint8_t link_quality, int8_t dbm, int8_t driver_id); 00058 static int8_t eth_mac_net_phy_tx_done(int8_t driver_id, uint8_t tx_handle, phy_link_tx_status_e status, uint8_t cca_retry, uint8_t tx_retry); 00059 static void ethernet_mac_tasklet(arm_event_s *event); 00060 00061 int8_t ethernet_mac_destroy(eth_mac_api_t *mac_api) 00062 { 00063 if( !mac_api || mac_store.mac_api != mac_api ){ 00064 return -1; 00065 } 00066 00067 mac_store.active_data_request = false; 00068 ns_dyn_mem_free(mac_store.mac_api); 00069 mac_store.mac_api = NULL; 00070 mac_store.dev_driver = NULL; 00071 ns_dyn_mem_free(mac_store.mtu_ptr); 00072 mac_store.mtu_ptr = NULL; 00073 mac_store.mtu_size = 0; 00074 return 0; 00075 } 00076 00077 00078 00079 eth_mac_api_t *ethernet_mac_create(int8_t driver_id) 00080 { 00081 //TODO: Refactor this away, Drivers should be stored in MAC layer in future 00082 arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(driver_id); 00083 if( !driver || !driver->phy_driver){ 00084 return NULL; 00085 } 00086 00087 //Accept to return same mac if mac is generated and driver is same 00088 if (mac_store.mac_api) { 00089 if (mac_store.dev_driver == driver) { 00090 return mac_store.mac_api; 00091 } 00092 return NULL; 00093 } 00094 00095 uint8_t *buffer_ptr = NULL; 00096 uint16_t buffer_length = 0; 00097 bool address_resolution_needed = true; 00098 00099 switch (driver->phy_driver->link_type) { 00100 00101 case PHY_LINK_SLIP: 00102 //Do not Allocate 00103 address_resolution_needed = false; 00104 buffer_length = 0; 00105 break; 00106 00107 case PHY_LINK_TUN: 00108 address_resolution_needed = false; 00109 buffer_length = 1500 + 4; 00110 break; 00111 case PHY_LINK_ETHERNET_TYPE: 00112 00113 buffer_length = 1500 + ETHERNET_HDRLEN; 00114 00115 00116 00117 break; 00118 00119 default: 00120 return NULL; 00121 } 00122 if (buffer_length) { 00123 buffer_ptr = ns_dyn_mem_alloc(buffer_length); 00124 if (!buffer_ptr) { 00125 return NULL; 00126 } 00127 } 00128 00129 eth_mac_api_t *this = ns_dyn_mem_alloc(sizeof(eth_mac_api_t)); 00130 if( !this ){ 00131 ns_dyn_mem_free(buffer_ptr); 00132 return NULL; 00133 } 00134 memset(this, 0, sizeof(eth_mac_api_t)); 00135 this->mac_initialize = ð_mac_api_init; 00136 this->data_req = &data_req; 00137 this->mac48_get = &mac48_address_get; 00138 this->mac48_set = &mac48_address_set; 00139 00140 this->address_resolution_needed = address_resolution_needed; 00141 00142 memset(&mac_store.mac48, 0, 6); 00143 mac_store.active_data_request = false; 00144 mac_store.mac_api = this; 00145 mac_store.dev_driver = driver; 00146 mac_store.mtu_ptr = buffer_ptr; 00147 mac_store.mtu_size = buffer_length; 00148 00149 memcpy(&mac_store.mac48, mac_store.dev_driver->phy_driver->PHY_MAC, 6); 00150 if (mac_store.tasklet_id == -1) { 00151 mac_store.tasklet_id = eventOS_event_handler_create(ðernet_mac_tasklet, ETH_INIT_EVENT); 00152 } 00153 arm_net_phy_init(driver->phy_driver, ð_mac_net_phy_rx, ð_mac_net_phy_tx_done); 00154 00155 return this; 00156 } 00157 00158 static void ethernet_mac_tasklet(arm_event_s *event) 00159 { 00160 uint8_t event_type = event->event_type; 00161 00162 switch (event_type) { 00163 case ETH_DATA_IND_EVENT:{ 00164 eth_data_ind_t *data_ind = event->data_ptr; 00165 mac_store.mac_api->data_ind_cb(mac_store.mac_api, data_ind); 00166 ns_dyn_mem_free(((eth_data_ind_t*)event->data_ptr)->msdu); 00167 ns_dyn_mem_free(event->data_ptr); 00168 break; 00169 } 00170 case ETH_DATA_CNF_EVENT:{ 00171 eth_data_conf_t *data_conf = event->data_ptr; 00172 mac_store.mac_api->data_conf_cb(mac_store.mac_api, data_conf); 00173 ns_dyn_mem_free(event->data_ptr); 00174 mac_store.active_data_request = false; 00175 break; 00176 } 00177 case ETH_INIT_EVENT: 00178 default:{ 00179 break; 00180 } 00181 } 00182 } 00183 00184 static int8_t eth_mac_api_init( eth_mac_api_t *api, eth_mac_data_confirm *conf_cb, eth_mac_data_indication *ind_cb, uint8_t parent_id) 00185 { 00186 if( mac_store.mac_api != api ){ 00187 return -1; 00188 } 00189 eth_mac_api_t *cur = mac_store.mac_api; 00190 cur->data_conf_cb = conf_cb; 00191 cur->data_ind_cb = ind_cb; 00192 cur->parent_id = parent_id; 00193 00194 return 0; 00195 } 00196 00197 static void data_req(const eth_mac_api_t* api, const eth_data_req_t *data) 00198 { 00199 if( mac_store.mac_api != api || !mac_store.dev_driver->phy_driver || !data || !data->msduLength){ 00200 return; 00201 } 00202 00203 00204 uint8_t *data_ptr; 00205 uint16_t data_length; 00206 00207 //Build header 00208 switch (mac_store.dev_driver->phy_driver->link_type) { 00209 case PHY_LINK_ETHERNET_TYPE: 00210 00211 if (data->msduLength + ETHERNET_HDRLEN > mac_store.mtu_size || !data->dstAddress || !data->srcAddress ) { 00212 return; 00213 } 00214 00215 data_ptr = mac_store.mtu_ptr; 00216 data_length = data->msduLength + ETHERNET_HDRLEN; 00217 memcpy(data_ptr + ETHERNET_HDROFF_DST_ADDR, data->dstAddress, 6); 00218 memcpy(data_ptr + ETHERNET_HDROFF_SRC_ADDR, data->srcAddress, 6); 00219 common_write_16_bit(data->etehernet_type, data_ptr + ETHERNET_HDROFF_TYPE); 00220 memcpy(data_ptr + ETHERNET_HDRLEN, data->msdu, data->msduLength); 00221 break; 00222 00223 case PHY_LINK_TUN: 00224 if (data->msduLength + 4 > mac_store.mtu_size) { 00225 return; 00226 } 00227 data_ptr = mac_store.mtu_ptr; 00228 /* TUN header 00229 * [ TUN FLAGS 2B | PROTOCOL 2B | PAYLOAD ] 00230 * Tun flags may be 0, and protocol is same as in ether-type field, so 00231 * replace flags with e.g. IFF_TUN and packet is converted to TUN frame 00232 */ 00233 common_write_16_bit(0, data_ptr); 00234 common_write_16_bit(data->etehernet_type, data_ptr + 2); 00235 memcpy(data_ptr + 4, data->msdu, data->msduLength); 00236 data_length = data->msduLength + 4; 00237 break; 00238 00239 default: //SLIP 00240 data_ptr = data->msdu; 00241 data_length = data->msduLength; 00242 break; 00243 } 00244 00245 mac_store.active_data_request = true; 00246 mac_store.dev_driver->phy_driver->tx(data_ptr, data_length, 0, PHY_LAYER_PAYLOAD); 00247 } 00248 00249 static int8_t eth_mac_net_phy_rx(const uint8_t *data_ptr, uint16_t data_len, uint8_t link_quality, int8_t dbm, int8_t driver_id) 00250 { 00251 arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(driver_id); 00252 if (!data_ptr || !driver || driver != mac_store.dev_driver) { 00253 return -1; 00254 } 00255 00256 if (data_len == 0) { 00257 return -1; 00258 } 00259 00260 eth_data_ind_t *data_ind = ns_dyn_mem_temporary_alloc(sizeof(eth_data_ind_t)); 00261 if (!data_ind){ 00262 return -1; 00263 } 00264 memset(data_ind, 0, sizeof(eth_data_ind_t)); 00265 00266 if (driver->phy_driver->link_type == PHY_LINK_ETHERNET_TYPE) { 00267 if (data_len < ETHERNET_HDRLEN + 1) { 00268 ns_dyn_mem_free(data_ind); 00269 return -1; 00270 } 00271 00272 memcpy(data_ind->dstAddress,data_ptr + ETHERNET_HDROFF_DST_ADDR, 6); 00273 memcpy(data_ind->srcAddress,data_ptr + ETHERNET_HDROFF_SRC_ADDR, 6); 00274 00275 data_ind->etehernet_type = common_read_16_bit(data_ptr + ETHERNET_HDROFF_TYPE); 00276 00277 data_ptr += ETHERNET_HDRLEN; 00278 data_len -= ETHERNET_HDRLEN; 00279 00280 } else if (driver->phy_driver->link_type == PHY_LINK_TUN) { 00281 if (data_len < 5) { 00282 ns_dyn_mem_free(data_ind); 00283 return -1; 00284 } 00285 /* TUN header 00286 * [ TUN FLAGS 2B | PROTOCOL 2B | PAYLOAD ] 00287 * Protocol is ether-type id. 00288 */ 00289 data_ind->etehernet_type = common_read_16_bit(data_ptr + 2); 00290 00291 data_len -= 4; 00292 data_ptr += 4; 00293 } else if (driver->phy_driver->link_type == PHY_LINK_SLIP) { 00294 data_ind->etehernet_type = ETHERTYPE_IPV6; 00295 } 00296 00297 data_ind->msdu = ns_dyn_mem_temporary_alloc(data_len); 00298 if(!data_ind->msdu){ 00299 ns_dyn_mem_free(data_ind); 00300 return -1; 00301 } 00302 memcpy(data_ind->msdu, data_ptr, data_len); 00303 data_ind->msduLength = data_len; 00304 data_ind->dbm = dbm; 00305 data_ind->link_quality = link_quality; 00306 00307 arm_event_s event = { 00308 .receiver = mac_store.tasklet_id, 00309 .sender = 0, 00310 .event_id = 0, 00311 .data_ptr = data_ind, 00312 .event_type = ETH_DATA_IND_EVENT, 00313 .priority = ARM_LIB_HIGH_PRIORITY_EVENT, 00314 }; 00315 00316 if (eventOS_event_send(&event)) { 00317 ns_dyn_mem_free(data_ind->msdu); 00318 ns_dyn_mem_free(data_ind); 00319 return -1; 00320 } 00321 00322 return 0; 00323 } 00324 00325 static int8_t eth_mac_net_phy_tx_done(int8_t driver_id, uint8_t tx_handle, phy_link_tx_status_e status, uint8_t cca_retry, uint8_t tx_retry) 00326 { 00327 (void)tx_handle; 00328 (void)cca_retry; 00329 (void)tx_retry; 00330 arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(driver_id); 00331 if (!driver) { 00332 return -1; 00333 } 00334 00335 if( mac_store.active_data_request ){ 00336 mac_store.active_data_request = false; 00337 eth_data_conf_t *data_conf = ns_dyn_mem_temporary_alloc(sizeof(eth_data_conf_t)); 00338 if (!data_conf){ 00339 return -1; 00340 } 00341 data_conf->status = status; 00342 arm_event_s event = { 00343 .receiver = mac_store.tasklet_id, 00344 .sender = 0, 00345 .event_id = 0, 00346 .data_ptr = data_conf, 00347 .event_type = ETH_DATA_CNF_EVENT, 00348 .priority = ARM_LIB_HIGH_PRIORITY_EVENT, 00349 }; 00350 00351 return eventOS_event_send(&event); 00352 } 00353 return 0; 00354 } 00355 00356 static int8_t mac48_address_set( const eth_mac_api_t* api, const uint8_t *mac48) 00357 { 00358 if(!mac48 || !api || mac_store.mac_api != api ){ 00359 return -1; 00360 } 00361 memcpy(mac_store.mac48, mac48, 6); 00362 phy_device_driver_s *driver = mac_store.dev_driver->phy_driver; 00363 if (driver->address_write) { 00364 driver->address_write(PHY_MAC_48BIT, mac_store.mac48); 00365 } 00366 return 0; 00367 } 00368 00369 static int8_t mac48_address_get(const eth_mac_api_t* api, uint8_t *mac48_buf) 00370 { 00371 if(!mac48_buf || !api || mac_store.mac_api != api ){ 00372 return -1; 00373 } 00374 memcpy(&mac_store.mac48, mac_store.dev_driver->phy_driver->PHY_MAC, 6); 00375 memcpy(mac48_buf, mac_store.mac48, 6); 00376 return 0; 00377 }
Generated on Tue Jul 12 2022 12:21:49 by
