[PATCH 06/11] PCI: endpoint: pci-epf-vntb: Add outbound MW group commands
Koichiro Den <[email protected]> Tue, 4 Aug 2026 03:04:33 +0900
| Newsgroups | dev.linux.lists.ntb,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci |
|---|---|
| Message-ID | <[email protected]> |
Packed logical MWs share one contiguous EPC address range. Their outbound translations can therefore use one mapping as well. Add commands to map or unmap a complete group in one operation. Keep the existing commands for singleton MWs. Signed-off-by: Koichiro Den <[email protected]> --- drivers/pci/endpoint/functions/pci-epf-vntb.c | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c index aa8d304fe861..526cc31d9435 100644 --- a/drivers/pci/endpoint/functions/pci-epf-vntb.c +++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c @@ -56,6 +56,8 @@ static struct workqueue_struct *kpcintb_workqueue; #define COMMAND_TEARDOWN_MW 4 #define COMMAND_LINK_UP 5 #define COMMAND_LINK_DOWN 6 +#define COMMAND_CONFIGURE_MW_GROUP 7 +#define COMMAND_TEARDOWN_MW_GROUP 8 #define COMMAND_STATUS_OK 1 #define COMMAND_STATUS_ERROR 2 @@ -319,6 +321,50 @@ static int epf_ntb_teardown_mw(struct epf_ntb *ntb, u32 mw) return 0; } +static int epf_ntb_configure_mw_group(struct epf_ntb *ntb, u32 mw) +{ + unsigned int first, count; + u64 addr, size; + int ret; + + ret = epf_ntb_get_mw_group(ntb, mw, &first, &count); + if (ret) + return ret; + if (count <= 1) + return -EOPNOTSUPP; + if (mw != first) + return -EINVAL; + + addr = ntb->reg->addr; + size = ntb->reg->size; + if (!IS_ALIGNED(addr, SZ_4K) || + size != epf_ntb_mw_group_size(ntb, first, count)) + return -EINVAL; + + return pci_epc_map_addr(ntb->epf->epc, ntb->epf->func_no, + ntb->epf->vfunc_no, ntb->vpci_mw_phy[first], + addr, size); +} + +static int epf_ntb_teardown_mw_group(struct epf_ntb *ntb, u32 mw) +{ + unsigned int first, count; + int ret; + + ret = epf_ntb_get_mw_group(ntb, mw, &first, &count); + if (ret) + return ret; + if (count <= 1) + return -EOPNOTSUPP; + if (mw != first) + return -EINVAL; + + pci_epc_unmap_addr(ntb->epf->epc, ntb->epf->func_no, + ntb->epf->vfunc_no, ntb->vpci_mw_phy[first]); + + return 0; +} + /** * epf_ntb_cmd_handler() - Handle commands provided by the NTB HOST * @work: work_struct for the epf_ntb_epc @@ -378,6 +424,14 @@ static void epf_ntb_cmd_handler(struct work_struct *work) ret = epf_ntb_teardown_mw(ntb, argument); ctrl->command_status = ret ? COMMAND_STATUS_ERROR : COMMAND_STATUS_OK; break; + case COMMAND_CONFIGURE_MW_GROUP: + ret = epf_ntb_configure_mw_group(ntb, argument); + ctrl->command_status = ret ? COMMAND_STATUS_ERROR : COMMAND_STATUS_OK; + break; + case COMMAND_TEARDOWN_MW_GROUP: + ret = epf_ntb_teardown_mw_group(ntb, argument); + ctrl->command_status = ret ? COMMAND_STATUS_ERROR : COMMAND_STATUS_OK; + break; case COMMAND_LINK_UP: ntb->linkup = true; ret = epf_ntb_link_up(ntb, true); @@ -388,6 +442,8 @@ static void epf_ntb_cmd_handler(struct work_struct *work) goto reset_handler; case COMMAND_LINK_DOWN: ntb->linkup = false; + if (ntb->packed_mws) + epf_ntb_teardown_mw_group(ntb, 0); ret = epf_ntb_link_up(ntb, false); if (ret < 0) ctrl->command_status = COMMAND_STATUS_ERROR; @@ -976,6 +1032,9 @@ static void epf_ntb_mw_bar_clear(struct epf_ntb *ntb, int num_mws) unsigned int count; int i; + if (ntb->packed_mws) + epf_ntb_teardown_mw_group(ntb, 0); + for (i = 0; i < num_mws; i++) { barno = ntb->mw_layout[i].barno; if (!bar_cleared[barno]) { -- 2.51.0