Claude review: accel/amdxdna: Add basic support for AIE4 devices

Claude Code Review Bot
2026-03-31T07:05:09Z

Patch Review

This is the largest patch — adds aie4_pci.c, aie4_sriov.c, aie4_message.c, npu3_regs.c, mailbox changes, PCI driver changes, and UAPI change.

**Issue 1 — Duplicate struct names:**
```c
// aie4_pci.h:
struct amdxdna_dev_priv {
u32 mbox_bar;
u32 mbox_rbuf_bar;
u64 mbox_info_off;
};

struct amdxdna_dev_hdl {
struct aie_device aie;
const struct amdxdna_dev_priv *priv;
...
};
```
These shadow the identically-named structs in `aie2_pci.h`. This means any `.c` file can only include one of these headers. This is a maintenance hazard — if someone adds a shared helper that needs `ndev->xdna`, it will silently pick the wrong struct depending on includes. Consider `aie2_dev_hdl` / `aie4_dev_hdl` or a union/opaque pattern.

**Issue 2 — UAPI gap in device type enum:**
```c
enum amdxdna_device_type {
AMDXDNA_DEV_TYPE_UNKNOWN = -1,
AMDXDNA_DEV_TYPE_KMQ = 0,
AMDXDNA_DEV_TYPE_PF = 2,
};
```
Value 1 is skipped. This is ABI — once merged it can't change. If value 1 was intentionally reserved, document it. If not, use value 1.

**Issue 3 — PCI ID case inconsistency:**
```c
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x17f2) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1B0B) },
```
`0x17f2` is lowercase, `0x1B0B` is mixed case. Should be consistent (kernel convention is lowercase hex).

**Issue 4 — `aie4_sriov_stop` returning error but continuing:**
```c
int aie4_sriov_stop(struct amdxdna_dev_hdl *ndev)
{
...
pci_disable_sriov(pdev);
return aie4_destroy_vfs(ndev);
}
```
If `pci_disable_sriov` succeeds but `aie4_destroy_vfs` fails, the VFs are already disabled at the PCI level but the firmware still thinks they exist. The error handling needs consideration here.

**Issue 5 — `readx_poll_timeout` with pointer arithmetic on `__iomem`:**
```c
src = ndev->rbuf_base + npriv->mbox_info_off;

ret = readx_poll_timeout(readl, src + offsetof(struct mailbox_info, valid),
```
`src` is `u32 __iomem *`, so `+ offsetof(...)` does pointer arithmetic in units of `u32`, not bytes. `offsetof` returns bytes. This would read the wrong offset. Either `src` should be `void __iomem *` or the offset should be divided by `sizeof(u32)`.

**Issue 6 — `aie4_sriov_configure` return value for enable:**
```c
static int aie4_sriov_start(...)
{
...
return num_vfs;
}
```
Returning `num_vfs` on success is correct per the `sriov_configure` API, good.

**Issue 7 — Mailbox iohub helpers:**
```c
static inline u32 mailbox_irq_status(struct mailbox_channel *mb_chann)
{
return (mb_chann->iohub_int_addr) ?
mailbox_reg_read(mb_chann, mb_chann->iohub_int_addr) : 0;
}
```
Returning 0 when there's no iohub means the "check again" loop in `mailbox_rx_worker` will never re-enter via the `mailbox_irq_status` path. This seems intentional for AIE4 (no iohub), but the worker would then potentially miss messages that arrive during the window between processing and the status check. Worth a comment explaining why this is safe.

**Issue 8 — Missing `MODULE_FIRMWARE` for NPU3:**
New firmware paths are introduced but no `MODULE_FIRMWARE()` declarations are added for the NPU3 firmware files.

---
Generated by Claude Code Patch Reviewer