[PATCH 06/11] PCI: endpoint: pci-epf-vntb: Add outbound MW group commands

Koichiro Den <[email protected]>
Newsgroups gmane.linux.kernel.pci,gmane.linux.documentation,gmane.linux.kernel
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.