mbed-os/features/nanostack/sal-stack-nanostack/source/MAC/rf_driver_storage.c

204 lines
5.4 KiB
C

/*
* Copyright (c) 2016-2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nsconfig.h"
#include "string.h"
#include "ns_types.h"
#include "common_functions.h"
#include "nsdynmemLIB.h"
#include "MAC/rf_driver_storage.h"
static arm_device_driver_list_s *dev_driver_dynamically_allocate(void);
static int8_t dev_driver_get_free_id(void);
static NS_LIST_DEFINE(arm_device_driver_list, arm_device_driver_list_s, link);
arm_device_driver_list_s *arm_net_phy_driver_pointer(int8_t id)
{
ns_list_foreach(arm_device_driver_list_s, cur, &arm_device_driver_list) {
if (cur->id == id) {
return cur;
}
}
return NULL;
}
static arm_device_driver_list_s *dev_driver_dynamically_allocate(void)
{
arm_device_driver_list_s *event = 0;
event = ns_dyn_mem_alloc(sizeof(arm_device_driver_list_s));
if (event) {
event->phy_sap_identifier = NULL;
event->phy_sap_upper_cb = NULL;
event->mlme_observer_cb = NULL;
ns_list_link_init(event, link);
}
return event;
}
static int8_t dev_driver_get_free_id(void)
{
uint_fast8_t id; // Must be unsigned for loop test to work...
for (id = 0; id <= INT8_MAX; id++) {
if (!arm_net_phy_driver_pointer(id)) {
return id;
}
}
return -1;
}
int8_t arm_net_phy_register(phy_device_driver_s *phy_driver)
{
arm_device_driver_list_s *new;
if (!phy_driver) {
return -1;
}
ns_list_foreach(arm_device_driver_list_s, cur, &arm_device_driver_list) {
if (cur->phy_driver == phy_driver) {
return -1;
}
}
/* Validate That Channel page is defined for RF driver */
if (phy_driver->link_type == PHY_LINK_15_4_2_4GHZ_TYPE || phy_driver->link_type == PHY_LINK_15_4_SUBGHZ_TYPE) {
if (!phy_driver->phy_channel_pages || !phy_driver->phy_channel_pages->rf_channel_configuration) {
return -1;
}
}
//Allocate new
new = dev_driver_dynamically_allocate();
if (!new) {
return -2;
}
new->id = dev_driver_get_free_id();
new->phy_driver = phy_driver;
if (new->phy_driver->state_control) {
new->phy_driver->state_control(PHY_INTERFACE_RESET, 0);
}
ns_list_add_to_end(&arm_device_driver_list, new);
return new->id;
}
int8_t arm_net_phy_mac64_set(uint8_t *MAC, int8_t id)
{
arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(id);
if (!driver || !driver->phy_driver->PHY_MAC || !MAC) {
return -1;
}
memcpy(driver->phy_driver->PHY_MAC, MAC, 8);
return 0;
}
uint8_t *arm_net_phy_mac64_get(int8_t id)
{
arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(id);
if (!driver) {
return NULL;
}
return driver->phy_driver->PHY_MAC;
}
int arm_net_phy_rf_type(int8_t id)
{
arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(id);
if (!driver) {
return -1;
}
return driver->phy_driver->link_type;
}
uint16_t arm_net_phy_mtu_size(int8_t id)
{
arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(id);
if (!driver) {
return 0;
}
return driver->phy_driver->phy_MTU;
}
void arm_net_phy_unregister(int8_t driver_id)
{
ns_list_foreach_safe(arm_device_driver_list_s, cur, &arm_device_driver_list) {
if (cur->id == driver_id) {
ns_list_remove(&arm_device_driver_list, cur);
ns_dyn_mem_free(cur);
cur = NULL;
}
}
}
int8_t arm_net_phy_init(phy_device_driver_s *phy_driver, arm_net_phy_rx_fn *rx_cb, arm_net_phy_tx_done_fn *done_cb)
{
if (!phy_driver) {
return -1;
}
phy_driver->phy_rx_cb = rx_cb;
phy_driver->phy_tx_done_cb = done_cb;
return 0;
}
void arm_net_observer_cb_set(int8_t id, internal_mib_observer *observer_cb)
{
arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(id);
if (!driver) {
return;
}
driver->mlme_observer_cb = observer_cb;
}
void arm_net_virtual_config_rx_cb_set(phy_device_driver_s *phy_driver, arm_net_virtual_config_rx_fn *virtual_config_rx)
{
if (!phy_driver) {
return;
}
phy_driver->virtual_config_rx_cb = virtual_config_rx;
}
void arm_net_virtual_confirmation_rx_cb_set(phy_device_driver_s *phy_driver, arm_net_virtual_confirmation_rx_fn *virtual_confirmation_rx)
{
if (!phy_driver) {
return;
}
phy_driver->virtual_confirmation_rx_cb = virtual_confirmation_rx;
}
uint32_t dev_get_phy_datarate(phy_device_driver_s *phy_driver, channel_page_e channel_page)
{
uint32_t retval = 0;
const phy_device_channel_page_s *phy_ch_pages = phy_driver->phy_channel_pages;
while (1) {
if (phy_ch_pages->rf_channel_configuration == NULL) {
break;
}
if (phy_ch_pages->channel_page == channel_page) {
retval = phy_ch_pages->rf_channel_configuration->datarate;
break;
}
phy_ch_pages++;
}
return retval;
}