Introduce the core 9P network protocol client implementation.

9P is a network filesystem protocol originally developed for the
Plan 9 operating system. Add the baseline 9P2000.L protocol handling,
including message serialization, DM UCLASS_9P transport management,
and basic transport operations.

Signed-off-by: Kuan-Wei Chiu <[email protected]>
---
Changes in v2:
- Consistently use 9P2000.L instead of 9P2000 in subject and Kconfig.
- Add kerneldoc comments in include/9p.h.
- Move filesystem declarations to include/9pfs.h.
- Add LOG_CATEGORY and drop #include <config.h>.
- Return -ecode from P9_RLERROR in p9_check_error().
- Check memalign() return for NULL and return -ENOMEM.
- Parse server msize and version string in Rversion.
- Check return value of strlcpy() in p9_client_walk().
- Check nwqid == nwname in Rwalk reply.
- Validate count <= read_len before memcpy in read/readdir.
- Implement DM UCLASS_9P.
---
 include/9p.h           | 203 ++++++++++++++++++++
 include/dm/uclass-id.h |   1 +
 net/9p/Kconfig         |   5 +
 net/9p/Makefile        |   5 +
 net/9p/client.c        | 408 +++++++++++++++++++++++++++++++++++++++++
 net/Kconfig            |   2 +
 net/Makefile           |   1 +
 7 files changed, 625 insertions(+)
 create mode 100644 include/9p.h
 create mode 100644 net/9p/Kconfig
 create mode 100644 net/9p/Makefile
 create mode 100644 net/9p/client.c

diff --git a/include/9p.h b/include/9p.h
new file mode 100644
index 00000000000..e755c78be0f
--- /dev/null
+++ b/include/9p.h
@@ -0,0 +1,203 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2026, Kuan-Wei Chiu <[email protected]>
+ */
+
+#ifndef __9P_H__
+#define __9P_H__
+
+#include <linux/types.h>
+
+#define P9_MSIZE            65536
+#define P9_NOFID            (~0U)
+#define P9_NOTAG            0xFFFF
+#define P9_REQ_TAG          1
+
+#define P9_RLERROR          7
+#define P9_TLOPEN           12
+#define P9_RLOPEN           13
+#define P9_TGETATTR         24
+#define P9_RGETATTR         25
+#define P9_TREADDIR         40
+#define P9_RREADDIR         41
+#define P9_TVERSION         100
+#define P9_RVERSION         101
+#define P9_TATTACH          104
+#define P9_RATTACH          105
+#define P9_TWALK            110
+#define P9_RWALK            111
+#define P9_TREAD            116
+#define P9_RREAD            117
+#define P9_TCLUNK           120
+#define P9_RCLUNK           121
+
+#define P9_O_RDONLY         00000000
+#define P9_GETATTR_SIZE     0x00000010ULL
+#define P9_GETATTR_SIZE_OFFSET  41
+#define P9_DT_DIR           4
+
+/**
+ * struct p9_dirent_hdr - 9P2000.L directory entry wire header
+ * @qid: File QID (13 bytes)
+ * @offset: Offset cookie for next readdir (8 bytes)
+ * @type: Directory entry type (1 byte)
+ * @name_len: Length of filename (2 bytes)
+ */
+struct p9_dirent_hdr {
+       u8  qid[13];
+       u64 offset;
+       u8  type;
+       u16 name_len;
+} __packed;
+
+/**
+ * struct p9_header - 9P message header
+ * @size: Total message size in bytes, including this header
+ * @id: Message type / opcode (e.g. P9_TVERSION)
+ * @tag: Message tag to match request and reply
+ */
+struct p9_header {
+       u32 size;
+       u8  id;
+       u16 tag;
+} __packed;
+
+struct udevice;
+
+/**
+ * struct dm_p9_ops - Driver model operations for 9P transports
+ * @request: Execute a transmit/receive transaction
+ * @get_mount_tag: (optional) Retrieve the mount tag string
+ */
+struct dm_p9_ops {
+       int (*request)(struct udevice *dev, void *tx, int tx_len, void *rx, int 
rx_len);
+       const char *(*get_mount_tag)(struct udevice *dev);
+};
+
+/**
+ * struct p9_client - 9P client state
+ * @dev: Underlying transport udevice
+ * @tx: Transmit buffer
+ * @rx: Receive buffer
+ * @next_fid: Next FID to allocate
+ * @msize: Negotiated maximum message size
+ */
+struct p9_client {
+       struct udevice *dev;
+       u8 *tx;
+       u8 *rx;
+       u32 next_fid;
+       u32 msize;
+};
+
+/**
+ * p9_get_device() - Find a 9P transport device by mount tag or default
+ * @tag: Mount tag to match, or NULL/"-" for default/first device
+ * @devp: Output pointer to the found udevice
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_get_device(const char *tag, struct udevice **devp);
+
+/**
+ * p9_get_client() - Get 9P client state from a transport udevice
+ * @dev: 9P transport udevice
+ *
+ * Return: Pointer to struct p9_client
+ */
+struct p9_client *p9_get_client(struct udevice *dev);
+
+/**
+ * p9_client_alloc_fid() - Allocate a unique FID
+ * @c: Pointer to 9P client
+ *
+ * Return: Newly allocated FID
+ */
+u32 p9_client_alloc_fid(struct p9_client *c);
+
+/**
+ * p9_client_version() - Negotiate 9P2000.L protocol version and msize
+ * @c: Pointer to 9P client
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_client_version(struct p9_client *c);
+
+/**
+ * p9_client_attach() - Attach to the root directory
+ * @c: Pointer to 9P client
+ * @fid: FID to assign to root
+ * @uname: User name
+ * @aname: File tree / mount point name
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_client_attach(struct p9_client *c, u32 fid, const char *uname, const 
char *aname);
+
+/**
+ * p9_client_walk() - Walk a path and associate with a new FID
+ * @c: Pointer to 9P client
+ * @base_fid: Starting directory FID
+ * @new_fid: New FID to associate with target path
+ * @path: Relative path to walk
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_client_walk(struct p9_client *c, u32 base_fid, u32 new_fid, const char 
*path);
+
+/**
+ * p9_client_lopen() - Open a file (9P2000.L)
+ * @c: Pointer to 9P client
+ * @fid: FID of file to open
+ * @flags: Open flags (e.g. P9_O_RDONLY)
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_client_lopen(struct p9_client *c, u32 fid, u32 flags);
+
+/**
+ * p9_client_clunk() - Forget / close a FID
+ * @c: Pointer to 9P client
+ * @fid: FID to clunk
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_client_clunk(struct p9_client *c, u32 fid);
+
+/**
+ * p9_client_stat() - Get file size attribute via Tgetattr
+ * @c: Pointer to 9P client
+ * @fid: FID of file
+ * @size: Output pointer for file size
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_client_stat(struct p9_client *c, u32 fid, loff_t *size);
+
+/**
+ * p9_client_read() - Read data from a file
+ * @c: Pointer to 9P client
+ * @fid: FID of file
+ * @offset: Byte offset in file to read from
+ * @count: Maximum number of bytes to read
+ * @buf: Destination buffer
+ * @actread: Output pointer for actual bytes read
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_client_read(struct p9_client *c, u32 fid, u64 offset, u32 count, void 
*buf, u32 *actread);
+
+/**
+ * p9_client_readdir() - Read directory entries
+ * @c: Pointer to 9P client
+ * @fid: FID of directory
+ * @offset: Directory offset / cookie
+ * @count: Maximum bytes of dirents to read
+ * @buf: Destination buffer
+ * @actread: Output pointer for actual bytes returned
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_client_readdir(struct p9_client *c, u32 fid, u64 offset, u32 count, 
void *buf, u32 *actread);
+
+#endif /* __9P_H__ */
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index fe0aae2720c..10680dc860c 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -108,6 +108,7 @@ enum uclass_id {
        UCLASS_PANEL,           /* Display panel, such as an LCD */
        UCLASS_PANEL_BACKLIGHT, /* Backlight controller for panel */
        UCLASS_PARTITION,       /* Logical disk partition device */
+       UCLASS_9P,              /* 9P protocol transport */
        UCLASS_PCH,             /* x86 platform controller hub */
        UCLASS_PCI,             /* PCI bus */
        UCLASS_PCI_EP,          /* PCI endpoint device */
diff --git a/net/9p/Kconfig b/net/9p/Kconfig
new file mode 100644
index 00000000000..5fda98cb23d
--- /dev/null
+++ b/net/9p/Kconfig
@@ -0,0 +1,5 @@
+config NET_9P
+       bool "9P2000.L protocol support"
+       help
+         This enables support for the 9P network protocol (9P2000.L).
+         It implements the core 9P2000.L client and protocol handling.
diff --git a/net/9p/Makefile b/net/9p/Makefile
new file mode 100644
index 00000000000..e9220b0826e
--- /dev/null
+++ b/net/9p/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2026, Kuan-Wei Chiu <[email protected]>
+
+obj-y += client.o
diff --git a/net/9p/client.c b/net/9p/client.c
new file mode 100644
index 00000000000..970cf4d6e8f
--- /dev/null
+++ b/net/9p/client.c
@@ -0,0 +1,408 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2026, Kuan-Wei Chiu <[email protected]>
+ */
+
+#define LOG_CATEGORY LOGC_NET
+
+#include <9p.h>
+#include <dm.h>
+#include <dm/device.h>
+#include <dm/device-internal.h>
+#include <dm/uclass.h>
+#include <log.h>
+#include <malloc.h>
+#include <asm/cache.h>
+#include <asm/unaligned.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+static int p9_post_probe(struct udevice *dev)
+{
+       struct p9_client *c = dev_get_uclass_priv(dev);
+
+       c->dev = dev;
+       return 0;
+}
+
+UCLASS_DRIVER(p9) = {
+       .name = "p9",
+       .id = UCLASS_9P,
+       .per_device_auto = sizeof(struct p9_client),
+       .post_probe = p9_post_probe,
+};
+
+struct p9_client *p9_get_client(struct udevice *dev)
+{
+       return dev_get_uclass_priv(dev);
+}
+
+int p9_get_device(const char *tag, struct udevice **devp)
+{
+       struct udevice *dev;
+       char *endp;
+       ulong num;
+       int ret;
+
+       if (!tag || !tag[0] || !strcmp(tag, "-"))
+               return uclass_first_device_err(UCLASS_9P, devp);
+
+       num = simple_strtoul(tag, &endp, 10);
+       if (*endp == '\0') {
+               ret = uclass_get_device(UCLASS_9P, num, devp);
+               if (!ret)
+                       return 0;
+       }
+
+       uclass_foreach_dev_probe(UCLASS_9P, dev) {
+               const struct dm_p9_ops *ops = device_get_ops(dev);
+
+               if (ops && ops->get_mount_tag) {
+                       const char *mtag = ops->get_mount_tag(dev);
+
+                       if (mtag && !strcmp(mtag, tag)) {
+                               *devp = dev;
+                               return 0;
+                       }
+               }
+
+               if (!strcmp(dev->name, tag)) {
+                       *devp = dev;
+                       return 0;
+               }
+       }
+
+       return -ENODEV;
+}
+
+u32 p9_client_alloc_fid(struct p9_client *c)
+{
+       if (c->next_fid >= 0xFFFF0000 || c->next_fid == 0)
+               c->next_fid = 2; /* fid 1 is reserved for root */
+       return c->next_fid++;
+}
+
+static void p9_put_u16(u8 **p, u16 v)
+{
+       put_unaligned_le16(v, *p);
+       *p += 2;
+}
+
+static void p9_put_u32(u8 **p, u32 v)
+{
+       put_unaligned_le32(v, *p);
+       *p += 4;
+}
+
+static void p9_put_u64(u8 **p, u64 v)
+{
+       put_unaligned_le64(v, *p);
+       *p += 8;
+}
+
+static void p9_put_str(u8 **p, const char *s)
+{
+       u16 len = strlen(s);
+
+       put_unaligned_le16(len, *p);
+       *p += 2;
+       memcpy(*p, s, len);
+       *p += len;
+}
+
+static int p9_request(struct p9_client *c, void *tx, int tx_len, void *rx, int 
rx_len)
+{
+       const struct dm_p9_ops *ops = device_get_ops(c->dev);
+
+       if (!ops || !ops->request)
+               return -ENOSYS;
+
+       return ops->request(c->dev, tx, tx_len, rx, rx_len);
+}
+
+static int p9_check_error(struct p9_client *c, int expected_id, const char 
*step)
+{
+       struct p9_header *rx_hdr = (struct p9_header *)c->rx;
+       u32 ecode;
+
+       if (rx_hdr->id == P9_RLERROR) {
+               ecode = get_unaligned_le32(c->rx + sizeof(struct p9_header));
+               log_err("9P Error: %s failed (ecode=%u)\n", step, ecode);
+               return -ecode;
+       } else if (rx_hdr->id != expected_id) {
+               log_err("9P Error: %s got id %d (expected %d)\n", step, 
rx_hdr->id, expected_id);
+               return -EIO;
+       }
+       return 0;
+}
+
+int p9_client_version(struct p9_client *c)
+{
+       struct p9_header *hdr;
+       u8 *ptr;
+       u32 server_msize;
+       u16 vlen;
+       int ret;
+
+       if (!c->tx) {
+               c->tx = memalign(ARCH_DMA_MINALIGN, P9_MSIZE);
+               if (!c->tx)
+                       return -ENOMEM;
+       }
+       if (!c->rx) {
+               c->rx = memalign(ARCH_DMA_MINALIGN, P9_MSIZE);
+               if (!c->rx) {
+                       free(c->tx);
+                       c->tx = NULL;
+                       return -ENOMEM;
+               }
+       }
+
+       hdr = (struct p9_header *)c->tx;
+       ptr = c->tx + sizeof(*hdr);
+       p9_put_u32(&ptr, P9_MSIZE);
+       p9_put_str(&ptr, "9P2000.L");
+
+       hdr->size = ptr - c->tx;
+       hdr->id = P9_TVERSION;
+       hdr->tag = P9_NOTAG;
+
+       ret = p9_request(c, c->tx, hdr->size, c->rx, P9_MSIZE);
+       if (ret < 0)
+               return ret;
+
+       ret = p9_check_error(c, P9_RVERSION, "Tversion");
+       if (ret < 0)
+               return ret;
+
+       ptr = c->rx + sizeof(*hdr);
+       server_msize = get_unaligned_le32(ptr);
+       ptr += 4;
+       vlen = get_unaligned_le16(ptr);
+       ptr += 2;
+
+       if (vlen != strlen("9P2000.L") || memcmp(ptr, "9P2000.L", vlen) != 0) {
+               log_err("9P: Unsupported server version: %.*s\n", vlen, ptr);
+               return -EPROTONOSUPPORT;
+       }
+
+       c->msize = min((u32)P9_MSIZE, server_msize);
+       return 0;
+}
+
+int p9_client_attach(struct p9_client *c, u32 fid, const char *uname, const 
char *aname)
+{
+       struct p9_header *hdr = (struct p9_header *)c->tx;
+       u8 *ptr = c->tx + sizeof(*hdr);
+       int ret;
+
+       p9_put_u32(&ptr, fid);
+       p9_put_u32(&ptr, P9_NOFID);
+       p9_put_str(&ptr, uname);
+       p9_put_str(&ptr, aname);
+       p9_put_u32(&ptr, 0);
+
+       hdr->size = ptr - c->tx;
+       hdr->id = P9_TATTACH;
+       hdr->tag = P9_REQ_TAG;
+
+       ret = p9_request(c, c->tx, hdr->size, c->rx, c->msize ? c->msize : 
P9_MSIZE);
+       if (ret < 0)
+               return ret;
+
+       return p9_check_error(c, P9_RATTACH, "Tattach");
+}
+
+int p9_client_walk(struct p9_client *c, u32 base_fid, u32 new_fid, const char 
*path)
+{
+       struct p9_header *hdr = (struct p9_header *)c->tx;
+       u8 *ptr = c->tx + sizeof(*hdr);
+       char path_buf[128];
+       char *wnames[16];
+       char *token, *p = path_buf;
+       int nwname = 0, i, ret;
+       u16 nwqid;
+
+       if (strlcpy(path_buf, path, sizeof(path_buf)) >= sizeof(path_buf)) {
+               log_err("9P: Path too long\n");
+               return -ENAMETOOLONG;
+       }
+
+       while ((token = strsep(&p, "/")) != NULL) {
+               if (*token == '\0' || strcmp(token, ".") == 0)
+                       continue;
+               if (nwname >= 16) {
+                       log_err("9P: Path too deep (max 16 levels)\n");
+                       return -EINVAL;
+               }
+               wnames[nwname++] = token;
+       }
+
+       p9_put_u32(&ptr, base_fid);
+       p9_put_u32(&ptr, new_fid);
+       p9_put_u16(&ptr, nwname);
+       for (i = 0; i < nwname; i++)
+               p9_put_str(&ptr, wnames[i]);
+
+       hdr->size = ptr - c->tx;
+       hdr->id = P9_TWALK;
+       hdr->tag = P9_REQ_TAG;
+
+       ret = p9_request(c, c->tx, hdr->size, c->rx, c->msize ? c->msize : 
P9_MSIZE);
+       if (ret < 0)
+               return ret;
+
+       ret = p9_check_error(c, P9_RWALK, "Twalk");
+       if (ret < 0)
+               return ret;
+
+       ptr = c->rx + sizeof(*hdr);
+       nwqid = get_unaligned_le16(ptr);
+       if (nwqid != nwname)
+               return -ENOENT;
+
+       return 0;
+}
+
+int p9_client_lopen(struct p9_client *c, u32 fid, u32 flags)
+{
+       struct p9_header *hdr = (struct p9_header *)c->tx;
+       u8 *ptr = c->tx + sizeof(*hdr);
+       int ret;
+
+       p9_put_u32(&ptr, fid);
+       p9_put_u32(&ptr, flags);
+
+       hdr->size = ptr - c->tx;
+       hdr->id = P9_TLOPEN;
+       hdr->tag = P9_REQ_TAG;
+
+       ret = p9_request(c, c->tx, hdr->size, c->rx, c->msize ? c->msize : 
P9_MSIZE);
+       if (ret < 0)
+               return ret;
+
+       return p9_check_error(c, P9_RLOPEN, "Tlopen");
+}
+
+int p9_client_clunk(struct p9_client *c, u32 fid)
+{
+       struct p9_header *hdr = (struct p9_header *)c->tx;
+       u8 *ptr = c->tx + sizeof(*hdr);
+
+       p9_put_u32(&ptr, fid);
+       hdr->size = ptr - c->tx;
+       hdr->id = P9_TCLUNK;
+       hdr->tag = P9_REQ_TAG;
+
+       return p9_request(c, c->tx, hdr->size, c->rx, c->msize ? c->msize : 
P9_MSIZE);
+}
+
+int p9_client_stat(struct p9_client *c, u32 fid, loff_t *size)
+{
+       struct p9_header *hdr = (struct p9_header *)c->tx;
+       u8 *ptr = c->tx + sizeof(*hdr);
+       u64 valid;
+       int ret;
+
+       p9_put_u32(&ptr, fid);
+       p9_put_u64(&ptr, P9_GETATTR_SIZE);
+
+       hdr->size = ptr - c->tx;
+       hdr->id = P9_TGETATTR;
+       hdr->tag = P9_REQ_TAG;
+
+       ret = p9_request(c, c->tx, hdr->size, c->rx, c->msize ? c->msize : 
P9_MSIZE);
+       if (ret < 0)
+               return ret;
+
+       ret = p9_check_error(c, P9_RGETATTR, "Tgetattr");
+       if (ret == 0) {
+               ptr = c->rx + sizeof(*hdr);
+               valid = get_unaligned_le64(ptr);
+               ptr += sizeof(valid);
+               ptr += P9_GETATTR_SIZE_OFFSET;
+               if (valid & P9_GETATTR_SIZE) {
+                       *size = get_unaligned_le64(ptr);
+                       return 0;
+               }
+       }
+       return ret ? ret : -EIO;
+}
+
+int p9_client_read(struct p9_client *c, u32 fid, u64 offset, u32 count, void 
*buf, u32 *actread)
+{
+       struct p9_header *hdr = (struct p9_header *)c->tx;
+       u8 *ptr = c->tx + sizeof(*hdr);
+       u32 max_read = (c->msize ? c->msize : P9_MSIZE) - 24;
+       u32 read_len = (count == 0 || count > max_read) ? max_read : count;
+       u32 count_rx;
+       int ret;
+
+       p9_put_u32(&ptr, fid);
+       p9_put_u64(&ptr, offset);
+       p9_put_u32(&ptr, read_len);
+
+       hdr->size = ptr - c->tx;
+       hdr->id = P9_TREAD;
+       hdr->tag = P9_REQ_TAG;
+
+       ret = p9_request(c, c->tx, hdr->size, c->rx, c->msize ? c->msize : 
P9_MSIZE);
+       if (ret < 0)
+               return ret;
+
+       ret = p9_check_error(c, P9_RREAD, "Tread");
+       if (ret < 0)
+               return ret;
+
+       ptr = c->rx + sizeof(*hdr);
+       count_rx = get_unaligned_le32(ptr);
+       ptr += 4;
+       if (count_rx > read_len) {
+               log_err("9P: Tread returned count %u > requested %u\n", 
count_rx, read_len);
+               return -EIO;
+       }
+
+       *actread = count_rx;
+       memcpy(buf, ptr, count_rx);
+       return 0;
+}
+
+int p9_client_readdir(struct p9_client *c, u32 fid, u64 offset, u32 count, 
void *buf, u32 *actread)
+{
+       struct p9_header *hdr = (struct p9_header *)c->tx;
+       u8 *ptr = c->tx + sizeof(*hdr);
+       u32 max_read = (c->msize ? c->msize : P9_MSIZE) - 24;
+       u32 read_len = (count == 0 || count > max_read) ? max_read : count;
+       u32 count_rx;
+       int ret;
+
+       p9_put_u32(&ptr, fid);
+       p9_put_u64(&ptr, offset);
+       p9_put_u32(&ptr, read_len);
+
+       hdr->size = ptr - c->tx;
+       hdr->id = P9_TREADDIR;
+       hdr->tag = P9_REQ_TAG;
+
+       ret = p9_request(c, c->tx, hdr->size, c->rx, c->msize ? c->msize : 
P9_MSIZE);
+       if (ret < 0)
+               return ret;
+
+       ret = p9_check_error(c, P9_RREADDIR, "Treaddir");
+       if (ret < 0)
+               return ret;
+
+       ptr = c->rx + sizeof(*hdr);
+       count_rx = get_unaligned_le32(ptr);
+       ptr += 4;
+       if (count_rx > read_len) {
+               log_err("9P: Treaddir returned count %u > requested %u\n", 
count_rx, read_len);
+               return -EIO;
+       }
+
+       *actread = count_rx;
+       memcpy(buf, ptr, count_rx);
+       return 0;
+}
diff --git a/net/Kconfig b/net/Kconfig
index 386376ce884..00448ab4cc6 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -236,6 +236,8 @@ endif   # if NET_LEGACY
 
 source "net/lwip/Kconfig"
 
+source "net/9p/Kconfig"
+
 config BOOTDEV_ETH
        bool "Enable bootdev for ethernet"
        depends on BOOTSTD
diff --git a/net/Makefile b/net/Makefile
index ceac6de6377..7745607248b 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -49,3 +49,4 @@ obj-y += net-common.o
 endif
 
 obj-$(CONFIG_NET_LWIP) += lwip/
+obj-$(CONFIG_NET_9P) += 9p/
-- 
2.55.0.897.gb25b4bd76c-goog

Reply via email to