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
ethernet_mac_api.c
00001 /* 00002 * Copyright (c) 2016-2018, 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_iid64[8]; 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 .tasklet_id = -1 00039 }; 00040 00041 #define ETH_INIT_EVENT 0 00042 #define ETH_DATA_IND_EVENT 1 00043 #define ETH_DATA_CNF_EVENT 2 00044 00045 00046 #define ETHERNET_HDROFF_DST_ADDR 0 00047 #define ETHERNET_HDROFF_SRC_ADDR 6 00048 #define ETHERNET_HDROFF_TYPE 12 00049 #define ETHERNET_HDRLEN 14 00050 00051 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); 00052 static void data_req(const eth_mac_api_t *api, const eth_data_req_t *data); 00053 static int8_t mac48_address_set(const eth_mac_api_t *api, const uint8_t *mac48); 00054 static int8_t mac48_address_get(const eth_mac_api_t *api, uint8_t *mac48_buf); 00055 static int8_t iid64_address_set(const eth_mac_api_t *api, const uint8_t *iid64); 00056 static int8_t iid64_address_get(const eth_mac_api_t *api, uint8_t *iid64_buf); 00057 00058 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); 00059 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); 00060 static void ethernet_mac_tasklet(arm_event_s *event); 00061 00062 int8_t ethernet_mac_destroy(eth_mac_api_t *mac_api) 00063 { 00064 if (!mac_api || mac_store.mac_api != mac_api) { 00065 return -1; 00066 } 00067 00068 mac_store.active_data_request = false; 00069 ns_dyn_mem_free(mac_store.mac_api); 00070 mac_store.mac_api = NULL; 00071 mac_store.dev_driver = NULL; 00072 ns_dyn_mem_free(mac_store.mtu_ptr); 00073 mac_store.mtu_ptr = NULL; 00074 mac_store.mtu_size = 0; 00075 return 0; 00076 } 00077 00078 00079 00080 eth_mac_api_t *ethernet_mac_create(int8_t driver_id) 00081 { 00082 //TODO: Refactor this away, Drivers should be stored in MAC layer in future 00083 arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(driver_id); 00084 if (!driver || !driver->phy_driver) { 00085 return NULL; 00086 } 00087 00088 //Accept to return same mac if mac is generated and driver is same 00089 if (mac_store.mac_api) { 00090 if (mac_store.dev_driver == driver) { 00091 return mac_store.mac_api; 00092 } 00093 return NULL; 00094 } 00095 00096 uint8_t *buffer_ptr = NULL; 00097 uint16_t buffer_length = 0; 00098 bool address_resolution_needed = true; 00099 00100 switch (driver->phy_driver->link_type) { 00101 00102 case PHY_LINK_SLIP: 00103 case PHY_LINK_PPP: 00104 //Do not Allocate 00105 address_resolution_needed = false; 00106 buffer_length = 0; 00107 break; 00108 00109 case PHY_LINK_TUN: 00110 address_resolution_needed = false; 00111 buffer_length = 1500 + 4; 00112 break; 00113 case PHY_LINK_ETHERNET_TYPE: 00114 00115 buffer_length = 1500 + ETHERNET_HDRLEN; 00116 00117 00118 00119 break; 00120 00121 default: 00122 return NULL; 00123 } 00124 if (buffer_length) { 00125 buffer_ptr = ns_dyn_mem_alloc(buffer_length); 00126 if (!buffer_ptr) { 00127 return NULL; 00128 } 00129 } 00130 00131 eth_mac_api_t *this = ns_dyn_mem_alloc(sizeof(eth_mac_api_t)); 00132 if (!this) { 00133 ns_dyn_mem_free(buffer_ptr); 00134 return NULL; 00135 } 00136 memset(this, 0, sizeof(eth_mac_api_t)); 00137 this->mac_initialize = ð_mac_api_init; 00138 this->data_req = &data_req; 00139 00140 if (driver->phy_driver->link_type == PHY_LINK_PPP) { 00141 this->iid64_get = &iid64_address_get; 00142 this->iid64_set = &iid64_address_set; 00143 } else { 00144 this->mac48_get = &mac48_address_get; 00145 this->mac48_set = &mac48_address_set; 00146 } 00147 00148 this->address_resolution_needed = address_resolution_needed; 00149 00150 memset(&mac_store.mac48_iid64, 0, 8); 00151 mac_store.active_data_request = false; 00152 mac_store.mac_api = this; 00153 mac_store.dev_driver = driver; 00154 mac_store.mtu_ptr = buffer_ptr; 00155 mac_store.mtu_size = buffer_length; 00156 00157 if (driver->phy_driver->link_type == PHY_LINK_PPP) { 00158 memcpy(&mac_store.mac48_iid64, mac_store.dev_driver->phy_driver->PHY_MAC, 8); 00159 } else { 00160 memcpy(&mac_store.mac48_iid64, mac_store.dev_driver->phy_driver->PHY_MAC, 6); 00161 } 00162 if (mac_store.tasklet_id == -1) { 00163 mac_store.tasklet_id = eventOS_event_handler_create(ðernet_mac_tasklet, ETH_INIT_EVENT); 00164 } 00165 arm_net_phy_init(driver->phy_driver, ð_mac_net_phy_rx, ð_mac_net_phy_tx_done); 00166 00167 return this; 00168 } 00169 00170 static void ethernet_mac_tasklet(arm_event_s *event) 00171 { 00172 uint8_t event_type = event->event_type; 00173 00174 switch (event_type) { 00175 case ETH_DATA_IND_EVENT: { 00176 eth_data_ind_t *data_ind = event->data_ptr; 00177 mac_store.mac_api->data_ind_cb(mac_store.mac_api, data_ind); 00178 ns_dyn_mem_free(((eth_data_ind_t *)event->data_ptr)->msdu); 00179 ns_dyn_mem_free(event->data_ptr); 00180 break; 00181 } 00182 case ETH_DATA_CNF_EVENT: { 00183 eth_data_conf_t *data_conf = event->data_ptr; 00184 mac_store.mac_api->data_conf_cb(mac_store.mac_api, data_conf); 00185 ns_dyn_mem_free(event->data_ptr); 00186 mac_store.active_data_request = false; 00187 break; 00188 } 00189 case ETH_INIT_EVENT: 00190 default: { 00191 break; 00192 } 00193 } 00194 } 00195 00196 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) 00197 { 00198 if (mac_store.mac_api != api) { 00199 return -1; 00200 } 00201 eth_mac_api_t *cur = mac_store.mac_api; 00202 cur->data_conf_cb = conf_cb; 00203 cur->data_ind_cb = ind_cb; 00204 cur->parent_id = parent_id; 00205 00206 return 0; 00207 } 00208 00209 static void data_req(const eth_mac_api_t *api, const eth_data_req_t *data) 00210 { 00211 if (mac_store.mac_api != api || !mac_store.dev_driver->phy_driver || !data || !data->msduLength) { 00212 return; 00213 } 00214 00215 00216 uint8_t *data_ptr; 00217 uint16_t data_length; 00218 00219 //Build header 00220 switch (mac_store.dev_driver->phy_driver->link_type) { 00221 case PHY_LINK_ETHERNET_TYPE: 00222 00223 if (data->msduLength + ETHERNET_HDRLEN > mac_store.mtu_size || !data->dstAddress || !data->srcAddress) { 00224 return; 00225 } 00226 00227 data_ptr = mac_store.mtu_ptr; 00228 data_length = data->msduLength + ETHERNET_HDRLEN; 00229 memcpy(data_ptr + ETHERNET_HDROFF_DST_ADDR, data->dstAddress, 6); 00230 memcpy(data_ptr + ETHERNET_HDROFF_SRC_ADDR, data->srcAddress, 6); 00231 common_write_16_bit(data->etehernet_type, data_ptr + ETHERNET_HDROFF_TYPE); 00232 memcpy(data_ptr + ETHERNET_HDRLEN, data->msdu, data->msduLength); 00233 break; 00234 00235 case PHY_LINK_TUN: 00236 if (data->msduLength + 4 > mac_store.mtu_size) { 00237 return; 00238 } 00239 data_ptr = mac_store.mtu_ptr; 00240 /* TUN header 00241 * [ TUN FLAGS 2B | PROTOCOL 2B | PAYLOAD ] 00242 * Tun flags may be 0, and protocol is same as in ether-type field, so 00243 * replace flags with e.g. IFF_TUN and packet is converted to TUN frame 00244 */ 00245 common_write_16_bit(0, data_ptr); 00246 common_write_16_bit(data->etehernet_type, data_ptr + 2); 00247 memcpy(data_ptr + 4, data->msdu, data->msduLength); 00248 data_length = data->msduLength + 4; 00249 break; 00250 00251 default: //SLIP 00252 data_ptr = data->msdu; 00253 data_length = data->msduLength; 00254 break; 00255 } 00256 00257 mac_store.active_data_request = true; 00258 mac_store.dev_driver->phy_driver->tx(data_ptr, data_length, 0, PHY_LAYER_PAYLOAD); 00259 } 00260 00261 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) 00262 { 00263 arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(driver_id); 00264 if (!data_ptr || !driver || driver != mac_store.dev_driver) { 00265 return -1; 00266 } 00267 00268 if (data_len == 0) { 00269 return -1; 00270 } 00271 00272 eth_data_ind_t *data_ind = ns_dyn_mem_temporary_alloc(sizeof(eth_data_ind_t)); 00273 if (!data_ind) { 00274 return -1; 00275 } 00276 memset(data_ind, 0, sizeof(eth_data_ind_t)); 00277 00278 if (driver->phy_driver->link_type == PHY_LINK_ETHERNET_TYPE) { 00279 if (data_len < ETHERNET_HDRLEN + 1) { 00280 ns_dyn_mem_free(data_ind); 00281 return -1; 00282 } 00283 00284 memcpy(data_ind->dstAddress, data_ptr + ETHERNET_HDROFF_DST_ADDR, 6); 00285 memcpy(data_ind->srcAddress, data_ptr + ETHERNET_HDROFF_SRC_ADDR, 6); 00286 00287 data_ind->etehernet_type = common_read_16_bit(data_ptr + ETHERNET_HDROFF_TYPE); 00288 00289 data_ptr += ETHERNET_HDRLEN; 00290 data_len -= ETHERNET_HDRLEN; 00291 00292 } else if (driver->phy_driver->link_type == PHY_LINK_TUN) { 00293 if (data_len < 5) { 00294 ns_dyn_mem_free(data_ind); 00295 return -1; 00296 } 00297 /* TUN header 00298 * [ TUN FLAGS 2B | PROTOCOL 2B | PAYLOAD ] 00299 * Protocol is ether-type id. 00300 */ 00301 data_ind->etehernet_type = common_read_16_bit(data_ptr + 2); 00302 00303 data_len -= 4; 00304 data_ptr += 4; 00305 } else if (driver->phy_driver->link_type == PHY_LINK_SLIP || driver->phy_driver->link_type == PHY_LINK_PPP) { 00306 data_ind->etehernet_type = ETHERTYPE_IPV6; 00307 } 00308 00309 data_ind->msdu = ns_dyn_mem_temporary_alloc(data_len); 00310 if (!data_ind->msdu) { 00311 ns_dyn_mem_free(data_ind); 00312 return -1; 00313 } 00314 memcpy(data_ind->msdu, data_ptr, data_len); 00315 data_ind->msduLength = data_len; 00316 data_ind->dbm = dbm; 00317 data_ind->link_quality = link_quality; 00318 00319 arm_event_s event = { 00320 .receiver = mac_store.tasklet_id, 00321 .sender = 0, 00322 .event_id = 0, 00323 .data_ptr = data_ind, 00324 .event_type = ETH_DATA_IND_EVENT, 00325 .priority = ARM_LIB_HIGH_PRIORITY_EVENT, 00326 }; 00327 00328 if (eventOS_event_send(&event)) { 00329 ns_dyn_mem_free(data_ind->msdu); 00330 ns_dyn_mem_free(data_ind); 00331 return -1; 00332 } 00333 00334 return 0; 00335 } 00336 00337 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) 00338 { 00339 (void)tx_handle; 00340 (void)cca_retry; 00341 (void)tx_retry; 00342 arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(driver_id); 00343 if (!driver) { 00344 return -1; 00345 } 00346 00347 if (mac_store.active_data_request) { 00348 mac_store.active_data_request = false; 00349 eth_data_conf_t *data_conf = ns_dyn_mem_temporary_alloc(sizeof(eth_data_conf_t)); 00350 if (!data_conf) { 00351 return -1; 00352 } 00353 data_conf->status = status; 00354 arm_event_s event = { 00355 .receiver = mac_store.tasklet_id, 00356 .sender = 0, 00357 .event_id = 0, 00358 .data_ptr = data_conf, 00359 .event_type = ETH_DATA_CNF_EVENT, 00360 .priority = ARM_LIB_HIGH_PRIORITY_EVENT, 00361 }; 00362 00363 return eventOS_event_send(&event); 00364 } 00365 return 0; 00366 } 00367 00368 static int8_t mac48_address_set(const eth_mac_api_t *api, const uint8_t *mac48) 00369 { 00370 if (!mac48 || !api || mac_store.mac_api != api) { 00371 return -1; 00372 } 00373 memcpy(mac_store.mac48_iid64, mac48, 6); 00374 phy_device_driver_s *driver = mac_store.dev_driver->phy_driver; 00375 if (driver->address_write) { 00376 driver->address_write(PHY_MAC_48BIT, mac_store.mac48_iid64); 00377 } 00378 return 0; 00379 } 00380 00381 static int8_t mac48_address_get(const eth_mac_api_t *api, uint8_t *mac48_buf) 00382 { 00383 if (!mac48_buf || !api || mac_store.mac_api != api) { 00384 return -1; 00385 } 00386 memcpy(&mac_store.mac48_iid64, mac_store.dev_driver->phy_driver->PHY_MAC, 6); 00387 memcpy(mac48_buf, mac_store.mac48_iid64, 6); 00388 return 0; 00389 } 00390 00391 static int8_t iid64_address_set(const eth_mac_api_t *api, const uint8_t *iid64) 00392 { 00393 if (!iid64 || !api || mac_store.mac_api != api) { 00394 return -1; 00395 } 00396 memcpy(mac_store.mac48_iid64, iid64, 8); 00397 phy_device_driver_s *driver = mac_store.dev_driver->phy_driver; 00398 if (driver->address_write) { 00399 driver->address_write(PHY_MAC_48BIT, mac_store.mac48_iid64); 00400 } 00401 return 0; 00402 } 00403 00404 static int8_t iid64_address_get(const eth_mac_api_t *api, uint8_t *iid64_buf) 00405 { 00406 if (!iid64_buf || !api || mac_store.mac_api != api) { 00407 return -1; 00408 } 00409 memcpy(&mac_store.mac48_iid64, mac_store.dev_driver->phy_driver->PHY_MAC, 8); 00410 memcpy(iid64_buf, mac_store.mac48_iid64, 8); 00411 return 0; 00412 }
Generated on Tue Jul 12 2022 13:54:18 by
