]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
fru: ops: Add support to read mac addresses from multirecord
authorAshok Reddy Soma <ashok.reddy.soma@xilinx.com>
Wed, 23 Feb 2022 14:00:59 +0000 (15:00 +0100)
committerMichal Simek <michal.simek@xilinx.com>
Mon, 7 Mar 2022 07:48:22 +0000 (08:48 +0100)
Add support to read MAC addresses from mac address multirecord.
Check if multi record is found, then jump to mac address multirecord by
comparing the record type field. If it matches mac address
multirecord(0xD2), then copy mac addresses.

Copy these read MAC address in xilinx_read_eeprom_fru so that they are
updated to eth*addr in board_late_init_xilinx().

Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Link: https://lore.kernel.org/r/18f31bc528820934854ea5fd9dc581778fc1e40c.1645624855.git.michal.simek@xilinx.com
board/xilinx/common/board.c
board/xilinx/common/fru.h
board/xilinx/common/fru_ops.c

index db089c4a0b171dadebd5ff0ac305ff0ca1c380c6..0769189dcf215a84a701292cb17ef2126fb696d7 100644 (file)
@@ -171,6 +171,7 @@ static int xilinx_read_eeprom_fru(struct udevice *dev, char *name,
 {
        int i, ret, eeprom_size;
        u8 *fru_content;
+       u8 id = 0;
 
        /* FIXME this is shortcut - if eeprom type is wrong it will fail */
        eeprom_size = i2c_eeprom_size(dev);
@@ -218,6 +219,14 @@ static int xilinx_read_eeprom_fru(struct udevice *dev, char *name,
                sizeof(desc->revision));
        strncpy(desc->serial, (char *)fru_data.brd.serial_number,
                sizeof(desc->serial));
+
+       while (id < EEPROM_HDR_NO_OF_MAC_ADDR) {
+               if (is_valid_ethaddr((const u8 *)fru_data.mac.macid[id]))
+                       memcpy(&desc->mac_addr[id],
+                              (char *)fru_data.mac.macid[id], ETH_ALEN);
+               id++;
+       }
+
        desc->header = EEPROM_HEADER_MAGIC;
 
 end:
index e7284709ddea161067e90a9b0bf8cdb085f4b681..59f6b722cf12033a27530f8201ae089748eea179 100644 (file)
@@ -6,6 +6,7 @@
 
 #ifndef __FRU_H
 #define __FRU_H
+#include <net.h>
 
 struct fru_common_hdr {
        u8 version;
@@ -19,6 +20,7 @@ struct fru_common_hdr {
 };
 
 #define FRU_BOARD_MAX_LEN      32
+#define FRU_MAX_NO_OF_MAC_ADDR 4
 
 struct __packed fru_board_info_header {
        u8 ver;
@@ -56,9 +58,24 @@ struct fru_board_data {
        u8 uuid[FRU_BOARD_MAX_LEN];
 };
 
+struct fru_multirec_hdr {
+       u8 rec_type;
+       u8 type;
+       u8 len;
+       u8 csum;
+       u8 hdr_csum;
+};
+
+struct fru_multirec_mac {
+       u8 xlnx_iana_id[3];
+       u8 ver;
+       u8 macid[FRU_MAX_NO_OF_MAC_ADDR][ETH_ALEN];
+};
+
 struct fru_table {
        struct fru_common_hdr hdr;
        struct fru_board_data brd;
+       struct fru_multirec_mac mac;
        bool captured;
 };
 
@@ -69,6 +86,10 @@ struct fru_table {
 #define FRU_LANG_CODE_ENGLISH          0
 #define FRU_LANG_CODE_ENGLISH_1                25
 #define FRU_TYPELEN_EOF                        0xC1
+#define FRU_MULTIREC_TYPE_OEM          0xD2
+#define FRU_MULTIREC_MAC_OFFSET                4
+#define FRU_LAST_REC                   BIT(7)
+#define FRU_DUT_MACID                  0x31
 
 /* This should be minimum of fields */
 #define FRU_BOARD_AREA_TOTAL_FIELDS    5
index 058e750c442f50c347d4abadb0a3fd5a227b3912..49846ae3d660c213926b3ce2660be6e9b9c87cb6 100644 (file)
@@ -9,6 +9,7 @@
 #include <fdtdec.h>
 #include <log.h>
 #include <malloc.h>
+#include <net.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 
@@ -218,10 +219,43 @@ static int fru_parse_board(unsigned long addr)
        return 0;
 }
 
+static int fru_parse_multirec(unsigned long addr)
+{
+       struct fru_multirec_hdr mrc;
+       u8 checksum = 0;
+       u8 hdr_len = sizeof(struct fru_multirec_hdr);
+       int mac_len = 0;
+
+       debug("%s: multirec addr %lx\n", __func__, addr);
+
+       do {
+               memcpy(&mrc.rec_type, (void *)addr, hdr_len);
+
+               checksum = fru_checksum((u8 *)addr, hdr_len);
+               if (checksum) {
+                       debug("%s header CRC error\n", __func__);
+                       return -EINVAL;
+               }
+
+               if (mrc.rec_type == FRU_MULTIREC_TYPE_OEM) {
+                       struct fru_multirec_mac *mac = (void *)addr + hdr_len;
+
+                       if (mac->ver == FRU_DUT_MACID) {
+                               mac_len = mrc.len - FRU_MULTIREC_MAC_OFFSET;
+                               memcpy(&fru_data.mac.macid, mac->macid, mac_len);
+                       }
+               }
+               addr += mrc.len + hdr_len;
+       } while (!(mrc.type & FRU_LAST_REC));
+
+       return 0;
+}
+
 int fru_capture(unsigned long addr)
 {
        struct fru_common_hdr *hdr;
        u8 checksum = 0;
+       unsigned long multirec_addr = addr;
 
        checksum = fru_checksum((u8 *)addr, sizeof(struct fru_common_hdr));
        if (checksum) {
@@ -243,6 +277,11 @@ int fru_capture(unsigned long addr)
 
        env_set_hex("fru_addr", addr);
 
+       if (hdr->off_multirec) {
+               multirec_addr += fru_cal_area_len(hdr->off_multirec);
+               fru_parse_multirec(multirec_addr);
+       }
+
        return 0;
 }