123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- // SPDX-License-Identifier: GPL-2.0+
- /*
- * Copyright 2020 SolidRun
- */
- #include <common.h>
- #include <tlv_eeprom.h>
- #include "tlv_data.h"
- #define SR_TLV_CODE_RAM_SIZE 0x81
- static void store_product_name(struct tlvinfo_tlv *tlv_entry,
- struct tlv_data *td)
- {
- int len;
- char *dest;
- if (strlen(td->tlv_product_name[0]) == 0)
- dest = td->tlv_product_name[0];
- else if (strlen(td->tlv_product_name[1]) == 0)
- dest = td->tlv_product_name[1];
- else
- return;
- len = min_t(unsigned int, tlv_entry->length,
- sizeof(td->tlv_product_name[0]) - 1);
- memcpy(dest, tlv_entry->value, len);
- }
- static void parse_tlv_vendor_ext(struct tlvinfo_tlv *tlv_entry,
- struct tlv_data *td)
- {
- u8 *val = tlv_entry->value;
- u32 pen; /* IANA Private Enterprise Numbers */
- if (tlv_entry->length < 5) /* 4 bytes PEN + at least 1 byte type */
- return;
- /* PEN is big endian */
- pen = (val[0] << 24) | (val[1] << 16) | (val[2] << 8) | val[3];
- /* Not a real PEN */
- if (pen != 0xffffffff)
- return;
- if (val[4] != SR_TLV_CODE_RAM_SIZE)
- return;
- if (tlv_entry->length != 6)
- return;
- td->ram_size = val[5];
- }
- static void parse_tlv_data(u8 *eeprom, struct tlvinfo_header *hdr,
- struct tlvinfo_tlv *entry, struct tlv_data *td)
- {
- unsigned int tlv_offset, tlv_len;
- tlv_offset = sizeof(struct tlvinfo_header);
- tlv_len = sizeof(struct tlvinfo_header) + be16_to_cpu(hdr->totallen);
- while (tlv_offset < tlv_len) {
- entry = (struct tlvinfo_tlv *)&eeprom[tlv_offset];
- switch (entry->type) {
- case TLV_CODE_PRODUCT_NAME:
- store_product_name(entry, td);
- break;
- case TLV_CODE_VENDOR_EXT:
- parse_tlv_vendor_ext(entry, td);
- break;
- default:
- break;
- }
- tlv_offset += sizeof(struct tlvinfo_tlv) + entry->length;
- }
- }
- void read_tlv_data(struct tlv_data *td)
- {
- u8 eeprom_data[TLV_TOTAL_LEN_MAX];
- struct tlvinfo_header *tlv_hdr;
- struct tlvinfo_tlv *tlv_entry;
- int ret, i;
- for (i = 0; i < 2; i++) {
- ret = read_tlvinfo_tlv_eeprom(eeprom_data, &tlv_hdr,
- &tlv_entry, i);
- if (ret < 0)
- continue;
- parse_tlv_data(eeprom_data, tlv_hdr, tlv_entry, td);
- }
- }
- bool sr_product_is(const struct tlv_data *td, const char *product)
- {
- /* Allow prefix sub-string match */
- if (strncmp(td->tlv_product_name[0], product, strlen(product)) == 0)
- return true;
- if (strncmp(td->tlv_product_name[1], product, strlen(product)) == 0)
- return true;
- return false;
- }
|