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.
Fork of OmniWheels by
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 Fri Jul 22 2022 04:53:48 by
1.7.2
