get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.2/patches/2225604/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2225604,
    "url": "http://patchwork.ozlabs.org/api/1.2/patches/2225604/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/a85b2e6bac5df2addc20154d3b2a73f7ec5a9642.1776762022.git.vjardin@free.fr/",
    "project": {
        "id": 18,
        "url": "http://patchwork.ozlabs.org/api/1.2/projects/18/?format=api",
        "name": "U-Boot",
        "link_name": "uboot",
        "list_id": "u-boot.lists.denx.de",
        "list_email": "u-boot@lists.denx.de",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<a85b2e6bac5df2addc20154d3b2a73f7ec5a9642.1776762022.git.vjardin@free.fr>",
    "list_archive_url": null,
    "date": "2026-04-21T09:04:58",
    "name": "[v2,4/5] board: freebox: nbx10g: add device serial and MAC address initialization",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "dd6a8bc9ade8ee1a2507b1bee713fc609947922c",
    "submitter": {
        "id": 89131,
        "url": "http://patchwork.ozlabs.org/api/1.2/people/89131/?format=api",
        "name": "Vincent Jardin",
        "email": "vjardin@free.fr"
    },
    "delegate": {
        "id": 1696,
        "url": "http://patchwork.ozlabs.org/api/1.2/users/1696/?format=api",
        "username": "stroese",
        "first_name": "Stefan",
        "last_name": "Roese",
        "email": "sr@denx.de"
    },
    "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/a85b2e6bac5df2addc20154d3b2a73f7ec5a9642.1776762022.git.vjardin@free.fr/mbox/",
    "series": [
        {
            "id": 500764,
            "url": "http://patchwork.ozlabs.org/api/1.2/series/500764/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=500764",
            "date": "2026-04-21T09:04:54",
            "name": "NBX10G: Marvell Armada 8040 Nodebox 10G board support",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/500764/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2225604/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2225604/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<u-boot-bounces@lists.denx.de>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=free.fr header.i=@free.fr header.a=rsa-sha256\n header.s=smtp-20201208 header.b=TA6xYBeS;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)",
            "phobos.denx.de;\n dmarc=pass (p=quarantine dis=none) header.from=free.fr",
            "phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de",
            "phobos.denx.de;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=free.fr header.i=@free.fr header.b=\"TA6xYBeS\";\n\tdkim-atps=neutral",
            "phobos.denx.de;\n dmarc=pass (p=quarantine dis=none) header.from=free.fr",
            "phobos.denx.de; spf=pass smtp.mailfrom=vjardin@free.fr"
        ],
        "Received": [
            "from phobos.denx.de (phobos.denx.de\n [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g0Gfn5qWkz1yCv\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 21 Apr 2026 19:05:53 +1000 (AEST)",
            "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id 41FE08444D;\n\tTue, 21 Apr 2026 11:05:36 +0200 (CEST)",
            "by phobos.denx.de (Postfix, from userid 109)\n id 896D58445A; Tue, 21 Apr 2026 11:05:35 +0200 (CEST)",
            "from smtp6-g21.free.fr (smtp6-g21.free.fr [212.27.42.6])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id 47CB984390\n for <u-boot@lists.denx.de>; Tue, 21 Apr 2026 11:05:33 +0200 (CEST)",
            "from y14 (unknown [IPv6:2a01:e0a:2af:22b0:6ee8:ae48:54aa:4eff])\n (Authenticated sender: vjardin@free.fr)\n by smtp6-g21.free.fr (Postfix) with ESMTPSA id F0EF47803A2;\n Tue, 21 Apr 2026 11:05:27 +0200 (CEST)"
        ],
        "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de",
        "X-Spam-Level": "",
        "X-Spam-Status": "No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,\n RCVD_IN_DNSWL_BLOCKED,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,\n SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=free.fr;\n s=smtp-20201208; t=1776762333;\n bh=twuSOWwVDjmBD0qc5byhz9+cCtnaj2Kbdrp1tiR2/7o=;\n h=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n b=TA6xYBeSlBuWeVm1Geek+J5RfY912l4t+899eh1C0UDujDQGUWYhfgnkRkNkbWeAA\n +iTZf3VUKo5TRWBGpnbSFsARtbuXoNUEGEzqONVnB5S55HfjG5v0iayv5VS5UKqUbr\n EI6EfJU5lBFsyxzRNAZnCxqZGR0iEC3XLEsmMRepyLjS+qKaucgIIILp6VcZAGs0CQ\n RoftOhmhfa2dKNPsGKm0UNBr/KwSj9ykjdKSHx+7OJNTmkjo2QMyupl8pbH+FGCwk+\n l30nusvgpBlupGWfEiWLdoa6uH8CCJcZAUDw7IwOdGzMytDQ5gPrc4ZqukS3GHg8nc\n cdWu/9aAzKSzA==",
        "From": "Vincent Jardin <vjardin@free.fr>",
        "To": "u-boot@lists.denx.de",
        "Cc": "Stefan Roese <stefan.roese@mailbox.org>, Tom Rini <trini@konsulko.com>,\n Vincent Jardin <vjardin@free.fr>",
        "Subject": "[PATCH v2 4/5] board: freebox: nbx10g: add device serial and MAC\n address initialization",
        "Date": "Tue, 21 Apr 2026 11:04:58 +0200",
        "Message-ID": "\n <a85b2e6bac5df2addc20154d3b2a73f7ec5a9642.1776762022.git.vjardin@free.fr>",
        "X-Mailer": "git-send-email 2.53.0",
        "In-Reply-To": "<cover.1776762022.git.vjardin@free.fr>",
        "References": "<cover.1776762022.git.vjardin@free.fr>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "u-boot@lists.denx.de",
        "X-Mailman-Version": "2.1.39",
        "Precedence": "list",
        "List-Id": "U-Boot discussion <u-boot.lists.denx.de>",
        "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>",
        "List-Archive": "<https://lists.denx.de/pipermail/u-boot/>",
        "List-Post": "<mailto:u-boot@lists.denx.de>",
        "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>",
        "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>",
        "Errors-To": "u-boot-bounces@lists.denx.de",
        "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>",
        "X-Virus-Scanned": "clamav-milter 0.103.8 at phobos.denx.de",
        "X-Virus-Status": "Clean"
    },
    "content": "Read device identification data from a dedicated eMMC region. This\nprovides:\n\n- Unique device serial number for identification and tracking\n- Factory-programmed MAC address for network interfaces\n- Bundle information for device variant identification\n\nThe serial structure includes CRC32 validation to detect corruption.\nOn read failure or invalid data, sensible defaults are used to ensure\nthe system remains bootable.\n\nThe fbxserial command provides two subcommands:\n- fbxserial show: Display serial info (default)\n- fbxserial init: Initialize ethaddr from serial info\n\nUse CONFIG_PREBOOT=\"fbxserial init\" to automatically set MAC addresses\nduring boot. This approach avoids patching shared board code.\n\nSigned-off-by: Vincent Jardin <vjardin@free.fr>\n---\n board/freebox/nbx10g/Kconfig         |  29 +++\n board/freebox/nbx10g/Makefile        |   1 +\n board/freebox/nbx10g/nbx_fbxserial.c | 286 +++++++++++++++++++++++++++\n board/freebox/nbx10g/nbx_fbxserial.h | 156 +++++++++++++++\n 4 files changed, 472 insertions(+)\n create mode 100644 board/freebox/nbx10g/nbx_fbxserial.c\n create mode 100644 board/freebox/nbx10g/nbx_fbxserial.h",
    "diff": "diff --git a/board/freebox/nbx10g/Kconfig b/board/freebox/nbx10g/Kconfig\nindex d21153eae75..958c8fdd4c3 100644\n--- a/board/freebox/nbx10g/Kconfig\n+++ b/board/freebox/nbx10g/Kconfig\n@@ -62,4 +62,33 @@ config NBX_MMC_PART_BANK1_SIZE\n \n endif\n \n+config CMD_NBX_FBXSERIAL\n+\tbool \"fbxserial command\"\n+\tdepends on MMC_SDHCI_XENON\n+\thelp\n+\t  Enable the fbxserial command to read and display device\n+\t  serial information from eMMC. This includes:\n+\t  - Device serial number (type, version, manufacturer, date, number)\n+\t  - MAC address (used to set ethaddr environment variables)\n+\t  - Bundle information (if present)\n+\n+\t  The serial info is stored at a fixed offset in the eMMC user area.\n+\n+\t  Subcommands:\n+\t  - fbxserial show: display serial info (default)\n+\t  - fbxserial init: initialize ethaddr from serial info\n+\n+\t  Use CONFIG_PREBOOT=\"fbxserial init\" to auto-initialize at boot.\n+\n+if CMD_NBX_FBXSERIAL\n+\n+config NBX_MMC_PART_SERIAL_OFFSET\n+\thex \"Serial info offset in eMMC\"\n+\tdefault 0x800000\n+\thelp\n+\t  Byte offset in eMMC where the serial info structure is stored.\n+\t  Default: 0x800000 (8MB)\n+\n+endif\n+\n endif\ndiff --git a/board/freebox/nbx10g/Makefile b/board/freebox/nbx10g/Makefile\nindex a3b3d3a1fe3..4b70d94e14d 100644\n--- a/board/freebox/nbx10g/Makefile\n+++ b/board/freebox/nbx10g/Makefile\n@@ -2,3 +2,4 @@\n \n obj-y\t:= board.o\n obj-$(CONFIG_CMD_NBX_EMMCBOOT)\t+= nbx_emmcboot.o\n+obj-$(CONFIG_CMD_NBX_FBXSERIAL)\t+= nbx_fbxserial.o\ndiff --git a/board/freebox/nbx10g/nbx_fbxserial.c b/board/freebox/nbx10g/nbx_fbxserial.c\nnew file mode 100644\nindex 00000000000..088133a9496\n--- /dev/null\n+++ b/board/freebox/nbx10g/nbx_fbxserial.c\n@@ -0,0 +1,286 @@\n+// SPDX-License-Identifier: GPL-2.0+\n+/*\n+ * NBX Freebox Serial Info Support\n+ *\n+ * Copyright (C) 2025 Free Mobile, Freebox\n+ *\n+ * Reads device serial number and MAC address from eMMC.\n+ * The serial info is stored at a fixed offset in the eMMC user area.\n+ *\n+ * Serial format: TTTT-VV-M-(YY)WW-NN-NNNNN / FLAGS\n+ * Where:\n+ *   TTTT  = Device type (e.g., 9018)\n+ *   VV    = Board version\n+ *   M     = Manufacturer code (ASCII)\n+ *   YY    = Year (BCD)\n+ *   WW    = Week (1-53)\n+ *   NNNNN = Serial number\n+ *   FLAGS = Feature flags\n+ */\n+\n+#include <command.h>\n+#include <dm/device.h>\n+#include <env.h>\n+#include <event.h>\n+#include <mmc.h>\n+#include <malloc.h>\n+#include <memalign.h>\n+#include <vsprintf.h>\n+#include <u-boot/crc.h>\n+#include <asm/byteorder.h>\n+#include <linux/ctype.h>\n+#include <linux/errno.h>\n+#include \"nbx_fbxserial.h\"\n+\n+/* Partition offset defined in Kconfig (CONFIG_NBX_MMC_PART_SERIAL_OFFSET) */\n+\n+/*\n+ * Validate serial info structure\n+ */\n+static int nbx_fbx_check_serial(struct nbx_fbx_serial *fs)\n+{\n+\tunsigned int sum, len;\n+\n+\t/* Check magic first */\n+\tif (be32_to_cpu(fs->magic) != NBX_FBXSERIAL_MAGIC) {\n+\t\tprintf(\"Invalid magic for serial info (%08x != %08x)!\\n\",\n+\t\t       be32_to_cpu(fs->magic), NBX_FBXSERIAL_MAGIC);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Check struct version */\n+\tif (be32_to_cpu(fs->struct_version) > NBX_FBXSERIAL_VERSION) {\n+\t\tprintf(\"Version too big for fbxserial info (0x%08x)!\\n\",\n+\t\t       be32_to_cpu(fs->struct_version));\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Check for silly len */\n+\tlen = be32_to_cpu(fs->len);\n+\tif (len > NBX_FBXSERIAL_MAX_SIZE) {\n+\t\tprintf(\"Silly len for serial info (%d)\\n\", len);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Validate CRC (crc32_no_comp: no one's complement) */\n+\tsum = crc32_no_comp(0, (void *)fs + 4, len - 4);\n+\tif (be32_to_cpu(fs->crc32) != sum) {\n+\t\tprintf(\"Invalid checksum for serial info (%08x != %08x)\\n\",\n+\t\t       sum, be32_to_cpu(fs->crc32));\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int nbx_fbx_read_serial(int dev_num, unsigned long offset,\n+\t\t\tstruct nbx_fbx_serial *fs)\n+{\n+\tstruct mmc *mmc;\n+\tstruct blk_desc *bd;\n+\tuint blk_start, blk_cnt;\n+\tuint n;\n+\n+\tALLOC_CACHE_ALIGN_BUFFER(char, buf, ALIGN(sizeof(*fs), 512));\n+\tmmc = find_mmc_device(dev_num);\n+\tif (!mmc) {\n+\t\tprintf(\"No MMC device %d found\\n\", dev_num);\n+\t\tnbx_fbxserial_set_default(fs);\n+\t\treturn -ENODEV;\n+\t}\n+\n+\tif (mmc_init(mmc)) {\n+\t\tputs(\"MMC init failed\\n\");\n+\t\tnbx_fbxserial_set_default(fs);\n+\t\treturn -EIO;\n+\t}\n+\n+\t/* Switch to partition 0 (user data area) */\n+\tif (blk_select_hwpart_devnum(UCLASS_MMC, dev_num, 0)) {\n+\t\tputs(\"MMC partition switch failed\\n\");\n+\t\tnbx_fbxserial_set_default(fs);\n+\t\treturn -EIO;\n+\t}\n+\n+\tbd = mmc_get_blk_desc(mmc);\n+\tif (!bd) {\n+\t\tputs(\"Failed to get MMC block descriptor\\n\");\n+\t\tnbx_fbxserial_set_default(fs);\n+\t\treturn -EIO;\n+\t}\n+\n+\tblk_start = ALIGN(offset, bd->blksz) / bd->blksz;\n+\tblk_cnt = ALIGN(sizeof(*fs), bd->blksz) / bd->blksz;\n+\n+\tmemset(fs, 0x42, sizeof(*fs));\n+\n+\tn = blk_dread(bd, blk_start, blk_cnt, buf);\n+\tif (n != blk_cnt) {\n+\t\tprintf(\"Failed to read serial info from MMC\\n\");\n+\t\tnbx_fbxserial_set_default(fs);\n+\t\treturn -EIO;\n+\t}\n+\n+\tmemcpy(fs, buf, sizeof(*fs));\n+\n+\tif (nbx_fbx_check_serial(fs) != 0) {\n+\t\tnbx_fbxserial_set_default(fs);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+void nbx_fbx_dump_serial(struct nbx_fbx_serial *fs)\n+{\n+\tint i;\n+\n+\tprintf(\"Serial: %04u-%02u-%c-(%02u)%02u-%02u-%05u / %08x\\n\",\n+\t       ntohs(fs->type),\n+\t       fs->version,\n+\t       isprint(fs->manufacturer) ? fs->manufacturer : '?',\n+\t       ntohs(fs->year) / 100,\n+\t       ntohs(fs->year) % 100,\n+\t       fs->week,\n+\t       ntohl(fs->number),\n+\t       ntohl(fs->flags));\n+\n+\tprintf(\"Mac:    %02X:%02X:%02X:%02X:%02X:%02X\\n\",\n+\t       fs->mac_addr_base[0],\n+\t       fs->mac_addr_base[1],\n+\t       fs->mac_addr_base[2],\n+\t       fs->mac_addr_base[3],\n+\t       fs->mac_addr_base[4],\n+\t       fs->mac_addr_base[5]);\n+\n+\t/* Show bundle info */\n+\tfor (i = 0; i < be32_to_cpu(fs->extinfo_count); i++) {\n+\t\tstruct nbx_serial_extinfo *p;\n+\n+\t\tif (i >= NBX_EXTINFO_MAX_COUNT)\n+\t\t\tbreak;\n+\n+\t\tp = &fs->extinfos[i];\n+\t\tif (be32_to_cpu(p->type) == NBX_EXTINFO_TYPE_EXTDEV &&\n+\t\t    be32_to_cpu(p->u.extdev.type) == NBX_EXTDEV_TYPE_BUNDLE) {\n+\t\t\t/* Ensure null termination */\n+\t\t\tp->u.extdev.serial[sizeof(p->u.extdev.serial) - 1] = 0;\n+\t\t\tprintf(\"Bundle: %s\\n\", p->u.extdev.serial);\n+\t\t}\n+\t}\n+\n+\tprintf(\"\\n\");\n+}\n+\n+int nbx_fbx_init_ethaddr(int dev_num, unsigned long offset)\n+{\n+\tstruct nbx_fbx_serial fs;\n+\tchar mac[32];\n+\tint ret;\n+\n+\tret = nbx_fbx_read_serial(dev_num, offset, &fs);\n+\n+\t/* Even on error, fs has default values set */\n+\tsnprintf(mac, sizeof(mac), \"%02x:%02x:%02x:%02x:%02x:%02x\",\n+\t\t fs.mac_addr_base[0], fs.mac_addr_base[1],\n+\t\t fs.mac_addr_base[2], fs.mac_addr_base[3],\n+\t\t fs.mac_addr_base[4], fs.mac_addr_base[5]);\n+\n+\tnbx_fbx_dump_serial(&fs);\n+\n+\tenv_set(\"ethaddr\", mac);\n+\tenv_set(\"eth1addr\", mac);\n+\tenv_set(\"eth2addr\", mac);\n+\n+\treturn ret;\n+}\n+\n+/*\n+ * fbxserial show - display serial info from eMMC\n+ */\n+static int do_fbxserial_show(struct cmd_tbl *cmdtp, int flag, int argc,\n+\t\t\t     char *const argv[])\n+{\n+\tstruct nbx_fbx_serial fs;\n+\tint dev = 0;\n+\tunsigned long offset = CONFIG_NBX_MMC_PART_SERIAL_OFFSET;\n+\n+\tif (argc >= 1)\n+\t\tdev = dectoul(argv[0], NULL);\n+\n+\tif (argc >= 2)\n+\t\toffset = hextoul(argv[1], NULL);\n+\n+\tif (nbx_fbx_read_serial(dev, offset, &fs) != 0)\n+\t\tprintf(\"Warning: Using default serial info\\n\");\n+\n+\tnbx_fbx_dump_serial(&fs);\n+\n+\treturn CMD_RET_SUCCESS;\n+}\n+\n+/*\n+ * fbxserial init - initialize ethaddr from serial info\n+ */\n+static int do_fbxserial_init(struct cmd_tbl *cmdtp, int flag, int argc,\n+\t\t\t     char *const argv[])\n+{\n+\tint dev = 0;\n+\tunsigned long offset = CONFIG_NBX_MMC_PART_SERIAL_OFFSET;\n+\n+\tif (argc >= 1)\n+\t\tdev = dectoul(argv[0], NULL);\n+\n+\tif (argc >= 2)\n+\t\toffset = hextoul(argv[1], NULL);\n+\n+\treturn nbx_fbx_init_ethaddr(dev, offset);\n+}\n+\n+static struct cmd_tbl cmd_fbxserial_sub[] = {\n+\tU_BOOT_CMD_MKENT(show, 3, 0, do_fbxserial_show, \"\", \"\"),\n+\tU_BOOT_CMD_MKENT(init, 3, 0, do_fbxserial_init, \"\", \"\"),\n+};\n+\n+static int do_fbxserial(struct cmd_tbl *cmdtp, int flag, int argc,\n+\t\t\tchar *const argv[])\n+{\n+\tstruct cmd_tbl *cp;\n+\n+\t/* Default to 'show' if no subcommand */\n+\tif (argc < 2)\n+\t\treturn do_fbxserial_show(cmdtp, flag, 0, NULL);\n+\n+\tcp = find_cmd_tbl(argv[1], cmd_fbxserial_sub,\n+\t\t\t  ARRAY_SIZE(cmd_fbxserial_sub));\n+\n+\tif (!cp)\n+\t\treturn CMD_RET_USAGE;\n+\n+\treturn cp->cmd(cmdtp, flag, argc - 2, argv + 2);\n+}\n+\n+U_BOOT_CMD(\n+\tfbxserial, 5, 0, do_fbxserial,\n+\t\"NBX serial info and MAC address initialization\",\n+\t\"show [dev] [offset] - display serial info from eMMC\\n\"\n+\t\"fbxserial init [dev] [offset] - initialize ethaddr from serial info\\n\"\n+\t\"    dev    - MMC device number (default 0)\\n\"\n+\t\"    offset - offset in eMMC in hex (default from Kconfig)\"\n+);\n+\n+/*\n+ * Early init hook: Set MAC address from eMMC serial info before\n+ * network driver probes. EVT_SETTINGS_R is triggered after MMC\n+ * is available but before initr_net().\n+ */\n+static int nbx_fbx_settings_r(void)\n+{\n+\tif (!of_machine_is_compatible(\"nbx,armada8040\"))\n+\t\treturn 0;\n+\n+\tnbx_fbx_init_ethaddr(0, CONFIG_NBX_MMC_PART_SERIAL_OFFSET);\n+\treturn 0;\n+}\n+\n+EVENT_SPY_SIMPLE(EVT_SETTINGS_R, nbx_fbx_settings_r);\ndiff --git a/board/freebox/nbx10g/nbx_fbxserial.h b/board/freebox/nbx10g/nbx_fbxserial.h\nnew file mode 100644\nindex 00000000000..7bcaef09fe3\n--- /dev/null\n+++ b/board/freebox/nbx10g/nbx_fbxserial.h\n@@ -0,0 +1,156 @@\n+/* SPDX-License-Identifier: GPL-2.0+ */\n+/*\n+ * NBX Freebox Serial Info Support\n+ *\n+ * Copyright (C) 2025 Free Mobile, Freebox\n+ *\n+ * Reads device serial number and MAC address from eMMC.\n+ * Used to identify the board and set network MAC addresses.\n+ */\n+\n+#ifndef NBX_FBXSERIAL_H\n+#define NBX_FBXSERIAL_H\n+\n+#include <linux/types.h>\n+\n+/*\n+ * Extended info structure - variable data depending on type\n+ */\n+#define NBX_EXTINFO_SIZE\t\t128\n+#define NBX_EXTINFO_MAX_COUNT\t\t16\n+\n+/* Extended info types */\n+#define NBX_EXTINFO_TYPE_EXTDEV\t\t1\n+\n+/* Extended device types */\n+#define NBX_EXTDEV_TYPE_BUNDLE\t\t1\n+#define NBX_EXTDEV_TYPE_MAX\t\t2\n+\n+struct nbx_serial_extinfo {\n+\tu32 type;\n+\n+\tunion {\n+\t\t/* extdev */\n+\t\tstruct {\n+\t\t\tu32 type;\n+\t\t\tu32 model;\n+\t\t\tchar serial[64];\n+\t\t} extdev;\n+\n+\t\t/* raw access */\n+\t\tunsigned char data[NBX_EXTINFO_SIZE];\n+\t} u;\n+} __packed;\n+\n+/*\n+ * Master serial structure\n+ */\n+#define NBX_FBXSERIAL_VERSION\t\t1\n+#define NBX_FBXSERIAL_MAGIC\t\t0x2d9521ab\n+\n+#define NBX_MAC_ADDR_SIZE\t\t6\n+#define NBX_RANDOM_DATA_SIZE\t\t32\n+\n+/* Maximum size for CRC validation */\n+#define NBX_FBXSERIAL_MAX_SIZE\t\t8192\n+\n+struct nbx_fbx_serial {\n+\tu32 crc32;\n+\tu32 magic;\n+\tu32 struct_version;\n+\tu32 len;\n+\n+\t/* Board serial */\n+\tu16 type;\n+\tu8 version;\n+\tu8 manufacturer;\n+\tu16 year;\n+\tu8 week;\n+\tu32 number;\n+\tu32 flags;\n+\n+\t/* MAC address base */\n+\tu8 mac_addr_base[NBX_MAC_ADDR_SIZE];\n+\n+\t/* MAC address count */\n+\tu8 mac_count;\n+\n+\t/* Random data used to derive keys */\n+\tu8 random_data[NBX_RANDOM_DATA_SIZE];\n+\n+\t/* Last update of data (seconds since epoch) */\n+\tu32 last_modified;\n+\n+\t/* Count of following extinfo tags */\n+\tu32 extinfo_count;\n+\n+\t/* Beginning of extended info */\n+\tstruct nbx_serial_extinfo extinfos[NBX_EXTINFO_MAX_COUNT];\n+} __packed;\n+\n+/**\n+ * nbx_fbxserial_set_default() - Initialize serial structure with defaults\n+ * @serial: Pointer to serial structure to initialize\n+ *\n+ * Sets the serial structure to default values (Freebox OUI, type 9018).\n+ * Used as fallback when serial info cannot be read from eMMC.\n+ */\n+static inline void nbx_fbxserial_set_default(struct nbx_fbx_serial *serial)\n+{\n+\tstatic const struct nbx_fbx_serial def = {\n+\t\t.crc32\t\t= 0,\n+\t\t.magic\t\t= NBX_FBXSERIAL_MAGIC,\n+\t\t.struct_version\t= NBX_FBXSERIAL_VERSION,\n+\t\t.len\t\t= sizeof(struct nbx_fbx_serial),\n+\t\t.type\t\t= 9018,\n+\t\t.version\t= 0,\n+\t\t.manufacturer\t= '_',\n+\t\t.year\t\t= 0,\n+\t\t.week\t\t= 0,\n+\t\t.number\t\t= 0,\n+\t\t.flags\t\t= 0,\n+\t\t.mac_addr_base\t= { 0x00, 0x07, 0xCB, 0x00, 0x00, 0xFD },\n+\t\t.mac_count\t= 1,\n+\t\t.random_data\t= { 0 },\n+\t\t.last_modified\t= 0,\n+\t\t.extinfo_count\t= 0,\n+\t};\n+\n+\tmemcpy(serial, &def, sizeof(def));\n+}\n+\n+/**\n+ * nbx_fbx_read_serial() - Read serial info from eMMC\n+ * @dev_num: MMC device number\n+ * @offset: Byte offset in eMMC where serial info is stored\n+ * @fs: Pointer to serial structure to fill\n+ *\n+ * Reads and validates the serial info from eMMC. On failure,\n+ * the structure is filled with default values.\n+ *\n+ * Return: 0 on success, negative on error (defaults still set)\n+ */\n+int nbx_fbx_read_serial(int dev_num, unsigned long offset,\n+\t\t\tstruct nbx_fbx_serial *fs);\n+\n+/**\n+ * nbx_fbx_dump_serial() - Print serial info to console\n+ * @fs: Pointer to serial structure to display\n+ *\n+ * Prints the serial number, MAC address, and bundle info (if present).\n+ */\n+void nbx_fbx_dump_serial(struct nbx_fbx_serial *fs);\n+\n+/**\n+ * nbx_fbx_init_ethaddr() - Initialize Ethernet addresses from serial info\n+ * @dev_num: MMC device number\n+ * @offset: Byte offset in eMMC where serial info is stored\n+ *\n+ * Reads serial info and sets ethaddr, eth1addr, eth2addr environment\n+ * variables from the MAC address in the serial structure.\n+ *\n+ * Return: 0 on success, negative on error\n+ */\n+int nbx_fbx_init_ethaddr(int dev_num, unsigned long offset);\n+\n+#endif /* NBX_FBXSERIAL_H */\n",
    "prefixes": [
        "v2",
        "4/5"
    ]
}