1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2024 PHYTEC Messtechnik GmbH 4 * Author: Daniel Schultz <d.schultz@phytec.de> 5 */ 6 7 #include <env.h> 8 #include <malloc.h> 9 #include <u-boot/crc.h> 10 #include <net.h> 11 #include <vsprintf.h> 12 13 #include "phytec_som_detection_blocks.h" 14 15 #if IS_ENABLED(CONFIG_PHYTEC_SOM_DETECTION_BLOCKS) 16 17 struct phytec_api3_element * phytec_blocks_init_mac(struct phytec_api3_block_header * header,uint8_t * payload)18 phytec_blocks_init_mac(struct phytec_api3_block_header *header, 19 uint8_t *payload) 20 { 21 struct phytec_api3_element *element; 22 struct phytec_api3_block_mac *mac; 23 unsigned int crc; 24 unsigned int len = sizeof(struct phytec_api3_block_mac); 25 26 if (!header) 27 return NULL; 28 if (!payload) 29 return NULL; 30 31 element = (struct phytec_api3_element *) 32 calloc(8, PHYTEC_API3_ELEMENT_HEADER_SIZE + len); 33 if (!element) { 34 pr_err("%s: Unable to allocate memory\n", __func__); 35 return NULL; 36 } 37 element->block_type = header->block_type; 38 memcpy(&element->block.mac, payload, len); 39 mac = &element->block.mac; 40 41 debug("%s: interface: %i\n", __func__, mac->interface); 42 debug("%s: MAC %pM\n", __func__, mac->address); 43 44 crc = crc8(0, (const unsigned char *)mac, len); 45 debug("%s: crc: %x\n", __func__, crc); 46 if (crc) { 47 pr_err("%s: CRC mismatch. API3 block payload is unusable\n", 48 __func__); 49 return NULL; 50 } 51 52 return element; 53 } 54 55 int __maybe_unused phytec_blocks_add_mac_to_env(struct phytec_api3_element * element)56 phytec_blocks_add_mac_to_env(struct phytec_api3_element *element) 57 { 58 char enetenv[9] = "ethaddr"; 59 char buf[ARP_HLEN_ASCII + 1]; 60 struct phytec_api3_block_mac *block = &element->block.mac; 61 int ret; 62 63 if (!is_valid_ethaddr(block->address)) { 64 pr_err("%s: Invalid MAC address in block.\n", __func__); 65 return -1; 66 } 67 68 if (block->interface > 0) { 69 ret = sprintf(enetenv, "eth%iaddr", block->interface); 70 if (ret != 8) { 71 pr_err("%s: Unable to create env string\n", __func__); 72 return -1; 73 } 74 } 75 76 ret = sprintf(buf, "%pM", block->address); 77 if (ret != ARP_HLEN_ASCII) { 78 pr_err("%s: Unable to convert MAC address\n", __func__); 79 return -1; 80 } 81 ret = env_set(enetenv, buf); 82 if (ret) { 83 pr_err("%s: Failed to set MAC address to env.\n", __func__); 84 return -1; 85 } 86 87 debug("%s: Added %s to %s\n", __func__, buf, enetenv); 88 return 0; 89 } 90 91 #else 92 93 inline struct phytec_api3_element * phytec_api3_init_mac_block(struct phytec_api3_block_header * header,uint8_t * payload)94 phytec_api3_init_mac_block(struct phytec_api3_block_header *header, 95 uint8_t *payload) 96 { 97 return NULL; 98 } 99 100 inline int __maybe_unused phytec_blocks_add_mac_to_env(struct phytec_api3_element * element)101 phytec_blocks_add_mac_to_env(struct phytec_api3_element *element) 102 { 103 return -1; 104 } 105 106 #endif 107