| // SPDX-License-Identifier: GPL-2.0-or-later |
| /* |
| * Copyright (C) 2024 PHYTEC Messtechnik GmbH |
| * Author: Daniel Schultz <d.schultz@phytec.de> |
| */ |
| |
| #include <malloc.h> |
| #include <u-boot/crc.h> |
| #include <net.h> |
| #include <vsprintf.h> |
| |
| #include "phytec_som_detection_blocks.h" |
| |
| #if IS_ENABLED(CONFIG_PHYTEC_SOM_DETECTION_BLOCKS) |
| |
| struct phytec_api3_element * |
| phytec_blocks_init_mac(struct phytec_api3_block_header *header, |
| uint8_t *payload) |
| { |
| struct phytec_api3_element *element; |
| struct phytec_api3_block_mac *mac; |
| unsigned int crc; |
| unsigned int len = sizeof(struct phytec_api3_block_mac); |
| |
| if (!header) |
| return NULL; |
| if (!payload) |
| return NULL; |
| |
| element = (struct phytec_api3_element *) |
| calloc(8, PHYTEC_API3_ELEMENT_HEADER_SIZE + len); |
| if (!element) { |
| pr_err("%s: Unable to allocate memory\n", __func__); |
| return NULL; |
| } |
| element->block_type = header->block_type; |
| memcpy(&element->block.mac, payload, len); |
| mac = &element->block.mac; |
| |
| debug("%s: interface: %i\n", __func__, mac->interface); |
| debug("%s: MAC %pM\n", __func__, mac->address); |
| |
| crc = crc8(0, (const unsigned char *)mac, len); |
| debug("%s: crc: %x\n", __func__, crc); |
| if (crc) { |
| pr_err("%s: CRC mismatch. API3 block payload is unusable\n", |
| __func__); |
| return NULL; |
| } |
| |
| return element; |
| } |
| |
| int __maybe_unused |
| phytec_blocks_add_mac_to_env(struct phytec_api3_element *element) |
| { |
| char enetenv[9] = "ethaddr"; |
| char buf[ARP_HLEN_ASCII + 1]; |
| struct phytec_api3_block_mac *block = &element->block.mac; |
| int ret; |
| |
| if (!is_valid_ethaddr(block->address)) { |
| pr_err("%s: Invalid MAC address in block.\n", __func__); |
| return -1; |
| } |
| |
| if (block->interface > 0) { |
| ret = sprintf(enetenv, "eth%iaddr", block->interface); |
| if (ret != 8) { |
| pr_err("%s: Unable to create env string\n", __func__); |
| return -1; |
| } |
| } |
| |
| ret = sprintf(buf, "%pM", block->address); |
| if (ret != ARP_HLEN_ASCII) { |
| pr_err("%s: Unable to convert MAC address\n", __func__); |
| return -1; |
| } |
| ret = env_set(enetenv, buf); |
| if (ret) { |
| pr_err("%s: Failed to set MAC address to env.\n", __func__); |
| return -1; |
| } |
| |
| debug("%s: Added %s to %s\n", __func__, buf, enetenv); |
| return 0; |
| } |
| |
| #else |
| |
| inline struct phytec_api3_element * |
| phytec_api3_init_mac_block(struct phytec_api3_block_header *header, |
| uint8_t *payload) |
| { |
| return NULL; |
| } |
| |
| inline int __maybe_unused |
| phytec_blocks_add_mac_to_env(struct phytec_api3_element *element) |
| { |
| return -1; |
| } |
| |
| #endif |