linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/9] octeon_ep: Update PF mailbox for VF
@ 2022-11-29 13:09 Veerasenareddy Burru
  2022-11-29 13:09 ` [PATCH net-next v2 1/9] octeon_ep: defer probe if firmware not ready Veerasenareddy Burru
                   ` (8 more replies)
  0 siblings, 9 replies; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-11-29 13:09 UTC (permalink / raw)
  To: netdev, linux-kernel, lironh, aayarekar, sedara, sburla
  Cc: linux-doc, Veerasenareddy Burru, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni

Update PF mailbox for VF support.
Octeon VF driver will be submitted as separate patchset.

v1 -> v2:
   - remove separate workqueue task to wait for firmware ready.
     instead defer probe when firmware is not ready.
     Reported-by: Leon Romanovsky <leon@kernel.org>
   - This change has resulted in update of 0001-xxx.patch and 
     all other patches in the patchset.

Veerasenareddy Burru (9):
  octeon_ep: defer probe if firmware not ready
  octeon_ep: poll for control messages
  octeon_ep: control mailbox for multiple PFs
  octeon_ep: enhance control mailbox for VF support
  octeon_ep: support asynchronous notifications
  octeon_ep: control mbox support for VF stats and link info
  octeon_ep: add SRIOV VF creation
  octeon_ep: add PF-VF mailbox communication
  octeon_ep: add heartbeat monitor

 .../net/ethernet/marvell/octeon_ep/Makefile   |   3 +-
 .../marvell/octeon_ep/octep_cn9k_pf.c         | 114 +++--
 .../ethernet/marvell/octeon_ep/octep_config.h |   6 +
 .../marvell/octeon_ep/octep_ctrl_mbox.c       | 318 ++++++++------
 .../marvell/octeon_ep/octep_ctrl_mbox.h       | 102 +++--
 .../marvell/octeon_ep/octep_ctrl_net.c        | 404 ++++++++++++------
 .../marvell/octeon_ep/octep_ctrl_net.h        | 196 +++++----
 .../marvell/octeon_ep/octep_ethtool.c         |  12 +-
 .../ethernet/marvell/octeon_ep/octep_main.c   | 246 ++++++++---
 .../ethernet/marvell/octeon_ep/octep_main.h   |  62 ++-
 .../marvell/octeon_ep/octep_pfvf_mbox.c       | 305 +++++++++++++
 .../marvell/octeon_ep/octep_pfvf_mbox.h       | 126 ++++++
 .../marvell/octeon_ep/octep_regs_cn9k_pf.h    |  15 +
 .../net/ethernet/marvell/octeon_ep/octep_tx.h |  24 +-
 14 files changed, 1427 insertions(+), 506 deletions(-)
 create mode 100644 drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.c
 create mode 100644 drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.h


base-commit: 7a168f560e3c3829b74a893d3655caab14a7aef8
-- 
2.36.0


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH net-next v2 1/9] octeon_ep: defer probe if firmware not ready
  2022-11-29 13:09 [PATCH net-next v2 0/9] octeon_ep: Update PF mailbox for VF Veerasenareddy Burru
@ 2022-11-29 13:09 ` Veerasenareddy Burru
  2022-11-30  9:24   ` Leon Romanovsky
  2022-11-29 13:09 ` [PATCH net-next v2 2/9] octeon_ep: poll for control messages Veerasenareddy Burru
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-11-29 13:09 UTC (permalink / raw)
  To: netdev, linux-kernel, lironh, aayarekar, sedara, sburla
  Cc: linux-doc, Veerasenareddy Burru, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni

Defer probe if firmware is not ready for device usage.

Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
Signed-off-by: Abhijit Ayarekar <aayarekar@marvell.com>
Signed-off-by: Satananda Burla <sburla@marvell.com>
---
v1 -> v2:
 * was scheduling workqueue task to wait for firmware ready,
   to probe/initialize the device.
 * now, removed the workqueue task; the probe returns EPROBE_DEFER,
   if firmware is not ready.
 * removed device status oct->status, as it is not required with the
   modified implementation.

 .../ethernet/marvell/octeon_ep/octep_main.c   | 26 +++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
index 5a898fb88e37..aa7d0ced9807 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
@@ -1017,6 +1017,25 @@ static void octep_device_cleanup(struct octep_device *oct)
 	oct->conf = NULL;
 }
 
+static u8 get_fw_ready_status(struct pci_dev *pdev)
+{
+	u32 pos = 0;
+	u16 vsec_id;
+	u8 status;
+
+	while ((pos = pci_find_next_ext_capability(pdev, pos,
+						   PCI_EXT_CAP_ID_VNDR))) {
+		pci_read_config_word(pdev, pos + 4, &vsec_id);
+#define FW_STATUS_VSEC_ID  0xA3
+		if (vsec_id == FW_STATUS_VSEC_ID) {
+			pci_read_config_byte(pdev, (pos + 8), &status);
+			dev_info(&pdev->dev, "Firmware ready %u\n", status);
+			return status;
+		}
+	}
+	return 0;
+}
+
 /**
  * octep_probe() - Octeon PCI device probe handler.
  *
@@ -1053,6 +1072,13 @@ static int octep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	pci_enable_pcie_error_reporting(pdev);
 	pci_set_master(pdev);
 
+#define FW_STATUS_READY    1
+	if (get_fw_ready_status(pdev) != FW_STATUS_READY) {
+		dev_notice(&pdev->dev, "Firmware not ready; defer probe.\n");
+		err = -EPROBE_DEFER;
+		goto err_alloc_netdev;
+	}
+
 	netdev = alloc_etherdev_mq(sizeof(struct octep_device),
 				   OCTEP_MAX_QUEUES);
 	if (!netdev) {
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v2 2/9] octeon_ep: poll for control messages
  2022-11-29 13:09 [PATCH net-next v2 0/9] octeon_ep: Update PF mailbox for VF Veerasenareddy Burru
  2022-11-29 13:09 ` [PATCH net-next v2 1/9] octeon_ep: defer probe if firmware not ready Veerasenareddy Burru
@ 2022-11-29 13:09 ` Veerasenareddy Burru
  2022-11-30  9:30   ` Leon Romanovsky
  2022-11-29 13:09 ` [PATCH net-next v2 3/9] octeon_ep: control mailbox for multiple PFs Veerasenareddy Burru
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-11-29 13:09 UTC (permalink / raw)
  To: netdev, linux-kernel, lironh, aayarekar, sedara, sburla
  Cc: linux-doc, Veerasenareddy Burru, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni

Poll for control messages until interrupts are enabled.
All the interrupts are enabled in ndo_open().
Add ability to listen for notifications from firmware before ndo_open().
Once interrupts are enabled, this polling is disabled and all the
messages are processed by bottom half of interrupt handler.

Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
Signed-off-by: Abhijit Ayarekar <aayarekar@marvell.com>
---
v1 -> v2:
 * removed device status oct->status, as it is not required with the
   modified implementation in 0001-xxxx.patch

 .../marvell/octeon_ep/octep_cn9k_pf.c         | 49 +++++++++----------
 .../ethernet/marvell/octeon_ep/octep_main.c   | 35 +++++++++++++
 .../ethernet/marvell/octeon_ep/octep_main.h   | 11 ++++-
 .../marvell/octeon_ep/octep_regs_cn9k_pf.h    |  4 ++
 4 files changed, 71 insertions(+), 28 deletions(-)

diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
index 6ad88d0fe43f..ace2dfd1e918 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
@@ -352,27 +352,36 @@ static void octep_setup_mbox_regs_cn93_pf(struct octep_device *oct, int q_no)
 	mbox->mbox_read_reg = oct->mmio[0].hw_addr + CN93_SDP_R_MBOX_VF_PF_DATA(q_no);
 }
 
-/* Mailbox Interrupt handler */
-static void cn93_handle_pf_mbox_intr(struct octep_device *oct)
+/* Process non-ioq interrupts required to keep pf interface running.
+ * OEI_RINT is needed for control mailbox
+ */
+static int octep_poll_non_ioq_interrupts_cn93_pf(struct octep_device *oct)
 {
-	u64 mbox_int_val = 0ULL, val = 0ULL, qno = 0ULL;
+	u64 reg0;
+	int handled = 0;
 
-	mbox_int_val = readq(oct->mbox[0]->mbox_int_reg);
-	for (qno = 0; qno < OCTEP_MAX_VF; qno++) {
-		val = readq(oct->mbox[qno]->mbox_read_reg);
-		dev_dbg(&oct->pdev->dev,
-			"PF MBOX READ: val:%llx from VF:%llx\n", val, qno);
+	/* Check for OEI INTR */
+	reg0 = octep_read_csr64(oct, CN93_SDP_EPF_OEI_RINT);
+	if (reg0) {
+		dev_info(&oct->pdev->dev,
+			 "Received OEI_RINT intr: 0x%llx\n",
+			 reg0);
+		octep_write_csr64(oct, CN93_SDP_EPF_OEI_RINT, reg0);
+		if (reg0 & CN93_SDP_EPF_OEI_RINT_DATA_BIT_MBOX)
+			queue_work(octep_wq, &oct->ctrl_mbox_task);
+
+		handled = 1;
 	}
 
-	writeq(mbox_int_val, oct->mbox[0]->mbox_int_reg);
+	return handled;
 }
 
 /* Interrupts handler for all non-queue generic interrupts. */
 static irqreturn_t octep_non_ioq_intr_handler_cn93_pf(void *dev)
 {
 	struct octep_device *oct = (struct octep_device *)dev;
-	struct pci_dev *pdev = oct->pdev;
 	u64 reg_val = 0;
+	struct pci_dev *pdev = oct->pdev;
 	int i = 0;
 
 	/* Check for IRERR INTR */
@@ -434,24 +443,9 @@ static irqreturn_t octep_non_ioq_intr_handler_cn93_pf(void *dev)
 		goto irq_handled;
 	}
 
-	/* Check for MBOX INTR */
-	reg_val = octep_read_csr64(oct, CN93_SDP_EPF_MBOX_RINT(0));
-	if (reg_val) {
-		dev_info(&pdev->dev,
-			 "Received MBOX_RINT intr: 0x%llx\n", reg_val);
-		cn93_handle_pf_mbox_intr(oct);
+	/* Check for MBOX INTR and OEI INTR */
+	if (octep_poll_non_ioq_interrupts_cn93_pf(oct))
 		goto irq_handled;
-	}
-
-	/* Check for OEI INTR */
-	reg_val = octep_read_csr64(oct, CN93_SDP_EPF_OEI_RINT);
-	if (reg_val) {
-		dev_info(&pdev->dev,
-			 "Received OEI_EINT intr: 0x%llx\n", reg_val);
-		octep_write_csr64(oct, CN93_SDP_EPF_OEI_RINT, reg_val);
-		queue_work(octep_wq, &oct->ctrl_mbox_task);
-		goto irq_handled;
-	}
 
 	/* Check for DMA INTR */
 	reg_val = octep_read_csr64(oct, CN93_SDP_EPF_DMA_RINT);
@@ -712,6 +706,7 @@ void octep_device_setup_cn93_pf(struct octep_device *oct)
 
 	oct->hw_ops.enable_interrupts = octep_enable_interrupts_cn93_pf;
 	oct->hw_ops.disable_interrupts = octep_disable_interrupts_cn93_pf;
+	oct->hw_ops.poll_non_ioq_interrupts = octep_poll_non_ioq_interrupts_cn93_pf;
 
 	oct->hw_ops.update_iq_read_idx = octep_update_iq_read_index_cn93_pf;
 
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
index aa7d0ced9807..c07588461030 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
@@ -18,6 +18,7 @@
 #include "octep_main.h"
 #include "octep_ctrl_net.h"
 
+#define OCTEP_INTR_POLL_TIME_MSECS    100
 struct workqueue_struct *octep_wq;
 
 /* Supported Devices */
@@ -512,6 +513,7 @@ static int octep_open(struct net_device *netdev)
 	ret = octep_get_link_status(oct);
 	if (!ret)
 		octep_set_link_status(oct, true);
+	oct->poll_non_ioq_intr = false;
 
 	/* Enable the input and output queues for this Octeon device */
 	oct->hw_ops.enable_io_queues(oct);
@@ -573,6 +575,11 @@ static int octep_stop(struct net_device *netdev)
 	oct->hw_ops.reset_io_queues(oct);
 	octep_free_oqs(oct);
 	octep_free_iqs(oct);
+
+	oct->poll_non_ioq_intr = true;
+	queue_delayed_work(octep_wq, &oct->intr_poll_task,
+			   msecs_to_jiffies(OCTEP_INTR_POLL_TIME_MSECS));
+
 	netdev_info(netdev, "Device stopped !!\n");
 	return 0;
 }
@@ -865,6 +872,28 @@ static const struct net_device_ops octep_netdev_ops = {
 	.ndo_change_mtu          = octep_change_mtu,
 };
 
+/**
+ * octep_intr_poll_task - work queue task to process non-ioq interrupts.
+ *
+ * @work: pointer to mbox work_struct
+ *
+ * Process non-ioq interrupts to handle control mailbox, pfvf mailbox.
+ **/
+static void octep_intr_poll_task(struct work_struct *work)
+{
+	struct octep_device *oct = container_of(work, struct octep_device,
+						intr_poll_task.work);
+
+	if (!oct->poll_non_ioq_intr) {
+		dev_info(&oct->pdev->dev, "Interrupt poll task stopped.\n");
+		return;
+	}
+
+	oct->hw_ops.poll_non_ioq_interrupts(oct);
+	queue_delayed_work(octep_wq, &oct->intr_poll_task,
+			   msecs_to_jiffies(OCTEP_INTR_POLL_TIME_MSECS));
+}
+
 /**
  * octep_ctrl_mbox_task - work queue task to handle ctrl mbox messages.
  *
@@ -1101,6 +1130,10 @@ static int octep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 	INIT_WORK(&octep_dev->tx_timeout_task, octep_tx_timeout_task);
 	INIT_WORK(&octep_dev->ctrl_mbox_task, octep_ctrl_mbox_task);
+	INIT_DELAYED_WORK(&octep_dev->intr_poll_task, octep_intr_poll_task);
+	octep_dev->poll_non_ioq_intr = true;
+	queue_delayed_work(octep_wq, &octep_dev->intr_poll_task,
+			   msecs_to_jiffies(OCTEP_INTR_POLL_TIME_MSECS));
 
 	netdev->netdev_ops = &octep_netdev_ops;
 	octep_set_ethtool_ops(netdev);
@@ -1162,6 +1195,8 @@ static void octep_remove(struct pci_dev *pdev)
 	if (netdev->reg_state == NETREG_REGISTERED)
 		unregister_netdev(netdev);
 
+	oct->poll_non_ioq_intr = false;
+	cancel_delayed_work_sync(&oct->intr_poll_task);
 	octep_device_cleanup(oct);
 	pci_release_mem_regions(pdev);
 	free_netdev(netdev);
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.h b/drivers/net/ethernet/marvell/octeon_ep/octep_main.h
index 123ffc13754d..70cc3e236cb4 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.h
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.h
@@ -73,6 +73,7 @@ struct octep_hw_ops {
 
 	void (*enable_interrupts)(struct octep_device *oct);
 	void (*disable_interrupts)(struct octep_device *oct);
+	int (*poll_non_ioq_interrupts)(struct octep_device *oct);
 
 	void (*enable_io_queues)(struct octep_device *oct);
 	void (*disable_io_queues)(struct octep_device *oct);
@@ -270,7 +271,15 @@ struct octep_device {
 
 	/* Work entry to handle ctrl mbox interrupt */
 	struct work_struct ctrl_mbox_task;
-
+	/* Wait queue for host to firmware requests */
+	wait_queue_head_t ctrl_req_wait_q;
+	/* List of objects waiting for h2f response */
+	struct list_head ctrl_req_wait_list;
+
+	/* Enable non-ioq interrupt polling */
+	bool poll_non_ioq_intr;
+	/* Work entry to poll non-ioq interrupts */
+	struct delayed_work intr_poll_task;
 };
 
 static inline u16 OCTEP_MAJOR_REV(struct octep_device *oct)
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_regs_cn9k_pf.h b/drivers/net/ethernet/marvell/octeon_ep/octep_regs_cn9k_pf.h
index 3d5d39a52fe6..0466fd9a002d 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_regs_cn9k_pf.h
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_regs_cn9k_pf.h
@@ -364,4 +364,8 @@
 
 /* Number of non-queue interrupts in CN93xx */
 #define    CN93_NUM_NON_IOQ_INTR    16
+
+/* bit 0 for control mbox interrupt */
+#define CN93_SDP_EPF_OEI_RINT_DATA_BIT_MBOX	BIT_ULL(0)
+
 #endif /* _OCTEP_REGS_CN9K_PF_H_ */
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v2 3/9] octeon_ep: control mailbox for multiple PFs
  2022-11-29 13:09 [PATCH net-next v2 0/9] octeon_ep: Update PF mailbox for VF Veerasenareddy Burru
  2022-11-29 13:09 ` [PATCH net-next v2 1/9] octeon_ep: defer probe if firmware not ready Veerasenareddy Burru
  2022-11-29 13:09 ` [PATCH net-next v2 2/9] octeon_ep: poll for control messages Veerasenareddy Burru
@ 2022-11-29 13:09 ` Veerasenareddy Burru
  2022-11-29 13:09 ` [PATCH net-next v2 4/9] octeon_ep: enhance control mailbox for VF support Veerasenareddy Burru
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-11-29 13:09 UTC (permalink / raw)
  To: netdev, linux-kernel, lironh, aayarekar, sedara, sburla
  Cc: linux-doc, Veerasenareddy Burru, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni

Add control mailbox support for multiple PFs.
Update control mbox base address calculation based on PF function link.

Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
Signed-off-by: Abhijit Ayarekar <aayarekar@marvell.com>
---
v1 -> v2:
 * no change

 .../ethernet/marvell/octeon_ep/octep_cn9k_pf.c   | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
index ace2dfd1e918..e307bae62673 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
@@ -13,6 +13,9 @@
 #include "octep_main.h"
 #include "octep_regs_cn9k_pf.h"
 
+#define CTRL_MBOX_MAX_PF	128
+#define CTRL_MBOX_SZ		((size_t)(0x400000 / CTRL_MBOX_MAX_PF))
+
 /* Names of Hardware non-queue generic interrupts */
 static char *cn93_non_ioq_msix_names[] = {
 	"epf_ire_rint",
@@ -199,6 +202,8 @@ static void octep_init_config_cn93_pf(struct octep_device *oct)
 	struct octep_config *conf = oct->conf;
 	struct pci_dev *pdev = oct->pdev;
 	u64 val;
+	int pos;
+	u8 link = 0;
 
 	/* Read ring configuration:
 	 * PF ring count, number of VFs and rings per VF supported
@@ -234,7 +239,16 @@ static void octep_init_config_cn93_pf(struct octep_device *oct)
 	conf->msix_cfg.ioq_msix = conf->pf_ring_cfg.active_io_rings;
 	conf->msix_cfg.non_ioq_msix_names = cn93_non_ioq_msix_names;
 
-	conf->ctrl_mbox_cfg.barmem_addr = (void __iomem *)oct->mmio[2].hw_addr + (0x400000ull * 7);
+	pos = pci_find_ext_capability(oct->pdev, PCI_EXT_CAP_ID_SRIOV);
+	if (pos) {
+		pci_read_config_byte(oct->pdev,
+				     pos + PCI_SRIOV_FUNC_LINK,
+				     &link);
+		link = PCI_DEVFN(PCI_SLOT(oct->pdev->devfn), link);
+	}
+	conf->ctrl_mbox_cfg.barmem_addr = (void __iomem *)oct->mmio[2].hw_addr +
+					   (0x400000ull * 8) +
+					   (link * CTRL_MBOX_SZ);
 }
 
 /* Setup registers for a hardware Tx Queue  */
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v2 4/9] octeon_ep: enhance control mailbox for VF support
  2022-11-29 13:09 [PATCH net-next v2 0/9] octeon_ep: Update PF mailbox for VF Veerasenareddy Burru
                   ` (2 preceding siblings ...)
  2022-11-29 13:09 ` [PATCH net-next v2 3/9] octeon_ep: control mailbox for multiple PFs Veerasenareddy Burru
@ 2022-11-29 13:09 ` Veerasenareddy Burru
  2022-11-29 13:09 ` [PATCH net-next v2 5/9] octeon_ep: support asynchronous notifications Veerasenareddy Burru
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-11-29 13:09 UTC (permalink / raw)
  To: netdev, linux-kernel, lironh, aayarekar, sedara, sburla
  Cc: linux-doc, Veerasenareddy Burru, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni

Enhance control mailbox protocol to support following
 - separate command and response queues
    * command queue to send control commands to firmware.
    * response queue to receive responses and notifications from
      firmware.
 - variable size messages using scatter/gather
 - VF support
    * extend control command structure to include vfid.
    * update APIs to accept VF ID.

Signed-off-by: Abhijit Ayarekar <aayarekar@marvell.com>
Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
---
v1 -> v2:
 * modified the patch to work with device status "oct->status" removed.

 .../marvell/octeon_ep/octep_ctrl_mbox.c       | 318 +++++++++-------
 .../marvell/octeon_ep/octep_ctrl_mbox.h       | 102 ++---
 .../marvell/octeon_ep/octep_ctrl_net.c        | 349 ++++++++++++------
 .../marvell/octeon_ep/octep_ctrl_net.h        | 176 +++++----
 .../marvell/octeon_ep/octep_ethtool.c         |   7 +-
 .../ethernet/marvell/octeon_ep/octep_main.c   |  80 ++--
 6 files changed, 619 insertions(+), 413 deletions(-)

diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.c b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.c
index 39322e4dd100..cda252fc8f54 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.c
@@ -24,41 +24,49 @@
 /* Time in msecs to wait for message response */
 #define OCTEP_CTRL_MBOX_MSG_WAIT_MS			10
 
-#define OCTEP_CTRL_MBOX_INFO_MAGIC_NUM_OFFSET(m)	(m)
-#define OCTEP_CTRL_MBOX_INFO_BARMEM_SZ_OFFSET(m)	((m) + 8)
-#define OCTEP_CTRL_MBOX_INFO_HOST_STATUS_OFFSET(m)	((m) + 24)
-#define OCTEP_CTRL_MBOX_INFO_FW_STATUS_OFFSET(m)	((m) + 144)
-
-#define OCTEP_CTRL_MBOX_H2FQ_INFO_OFFSET(m)		((m) + OCTEP_CTRL_MBOX_INFO_SZ)
-#define OCTEP_CTRL_MBOX_H2FQ_PROD_OFFSET(m)		(OCTEP_CTRL_MBOX_H2FQ_INFO_OFFSET(m))
-#define OCTEP_CTRL_MBOX_H2FQ_CONS_OFFSET(m)		((OCTEP_CTRL_MBOX_H2FQ_INFO_OFFSET(m)) + 4)
-#define OCTEP_CTRL_MBOX_H2FQ_ELEM_SZ_OFFSET(m)		((OCTEP_CTRL_MBOX_H2FQ_INFO_OFFSET(m)) + 8)
-#define OCTEP_CTRL_MBOX_H2FQ_ELEM_CNT_OFFSET(m)		((OCTEP_CTRL_MBOX_H2FQ_INFO_OFFSET(m)) + 12)
-
-#define OCTEP_CTRL_MBOX_F2HQ_INFO_OFFSET(m)		((m) + \
-							 OCTEP_CTRL_MBOX_INFO_SZ + \
-							 OCTEP_CTRL_MBOX_H2FQ_INFO_SZ)
-#define OCTEP_CTRL_MBOX_F2HQ_PROD_OFFSET(m)		(OCTEP_CTRL_MBOX_F2HQ_INFO_OFFSET(m))
-#define OCTEP_CTRL_MBOX_F2HQ_CONS_OFFSET(m)		((OCTEP_CTRL_MBOX_F2HQ_INFO_OFFSET(m)) + 4)
-#define OCTEP_CTRL_MBOX_F2HQ_ELEM_SZ_OFFSET(m)		((OCTEP_CTRL_MBOX_F2HQ_INFO_OFFSET(m)) + 8)
-#define OCTEP_CTRL_MBOX_F2HQ_ELEM_CNT_OFFSET(m)		((OCTEP_CTRL_MBOX_F2HQ_INFO_OFFSET(m)) + 12)
-
-#define OCTEP_CTRL_MBOX_Q_OFFSET(m, i)			((m) + \
-							 (sizeof(struct octep_ctrl_mbox_msg) * (i)))
-
-static u32 octep_ctrl_mbox_circq_inc(u32 index, u32 mask)
+/* Size of mbox info in bytes */
+#define OCTEP_CTRL_MBOX_INFO_SZ				256
+/* Size of mbox host to fw queue info in bytes */
+#define OCTEP_CTRL_MBOX_H2FQ_INFO_SZ			16
+/* Size of mbox fw to host queue info in bytes */
+#define OCTEP_CTRL_MBOX_F2HQ_INFO_SZ			16
+
+#define OCTEP_CTRL_MBOX_TOTAL_INFO_SZ	(OCTEP_CTRL_MBOX_INFO_SZ + \
+					 OCTEP_CTRL_MBOX_H2FQ_INFO_SZ + \
+					 OCTEP_CTRL_MBOX_F2HQ_INFO_SZ)
+
+#define OCTEP_CTRL_MBOX_INFO_MAGIC_NUM(m)	(m)
+#define OCTEP_CTRL_MBOX_INFO_BARMEM_SZ(m)	((m) + 8)
+#define OCTEP_CTRL_MBOX_INFO_HOST_STATUS(m)	((m) + 24)
+#define OCTEP_CTRL_MBOX_INFO_FW_STATUS(m)	((m) + 144)
+
+#define OCTEP_CTRL_MBOX_H2FQ_INFO(m)	((m) + OCTEP_CTRL_MBOX_INFO_SZ)
+#define OCTEP_CTRL_MBOX_H2FQ_PROD(m)	(OCTEP_CTRL_MBOX_H2FQ_INFO(m))
+#define OCTEP_CTRL_MBOX_H2FQ_CONS(m)	((OCTEP_CTRL_MBOX_H2FQ_INFO(m)) + 4)
+#define OCTEP_CTRL_MBOX_H2FQ_SZ(m)	((OCTEP_CTRL_MBOX_H2FQ_INFO(m)) + 8)
+
+#define OCTEP_CTRL_MBOX_F2HQ_INFO(m)	((m) + \
+					 OCTEP_CTRL_MBOX_INFO_SZ + \
+					 OCTEP_CTRL_MBOX_H2FQ_INFO_SZ)
+#define OCTEP_CTRL_MBOX_F2HQ_PROD(m)	(OCTEP_CTRL_MBOX_F2HQ_INFO(m))
+#define OCTEP_CTRL_MBOX_F2HQ_CONS(m)	((OCTEP_CTRL_MBOX_F2HQ_INFO(m)) + 4)
+#define OCTEP_CTRL_MBOX_F2HQ_SZ(m)	((OCTEP_CTRL_MBOX_F2HQ_INFO(m)) + 8)
+
+static const u32 mbox_hdr_sz = sizeof(union octep_ctrl_mbox_msg_hdr);
+
+static u32 octep_ctrl_mbox_circq_inc(u32 index, u32 inc, u32 sz)
 {
-	return (index + 1) & mask;
+	return (index + inc) % sz;
 }
 
-static u32 octep_ctrl_mbox_circq_space(u32 pi, u32 ci, u32 mask)
+static u32 octep_ctrl_mbox_circq_space(u32 pi, u32 ci, u32 sz)
 {
-	return mask - ((pi - ci) & mask);
+	return sz - (abs(pi - ci) % sz);
 }
 
-static u32 octep_ctrl_mbox_circq_depth(u32 pi, u32 ci, u32 mask)
+static u32 octep_ctrl_mbox_circq_depth(u32 pi, u32 ci, u32 sz)
 {
-	return ((pi - ci) & mask);
+	return (abs(pi - ci) % sz);
 }
 
 int octep_ctrl_mbox_init(struct octep_ctrl_mbox *mbox)
@@ -73,172 +81,228 @@ int octep_ctrl_mbox_init(struct octep_ctrl_mbox *mbox)
 		return -EINVAL;
 	}
 
-	magic_num = readq(OCTEP_CTRL_MBOX_INFO_MAGIC_NUM_OFFSET(mbox->barmem));
+	magic_num = readq(OCTEP_CTRL_MBOX_INFO_MAGIC_NUM(mbox->barmem));
 	if (magic_num != OCTEP_CTRL_MBOX_MAGIC_NUMBER) {
-		pr_info("octep_ctrl_mbox : Invalid magic number %llx\n", magic_num);
+		pr_info("octep_ctrl_mbox : Invalid magic number %llx\n",
+			magic_num);
 		return -EINVAL;
 	}
 
-	status = readq(OCTEP_CTRL_MBOX_INFO_FW_STATUS_OFFSET(mbox->barmem));
+	status = readq(OCTEP_CTRL_MBOX_INFO_FW_STATUS(mbox->barmem));
 	if (status != OCTEP_CTRL_MBOX_STATUS_READY) {
 		pr_info("octep_ctrl_mbox : Firmware is not ready.\n");
 		return -EINVAL;
 	}
 
-	mbox->barmem_sz = readl(OCTEP_CTRL_MBOX_INFO_BARMEM_SZ_OFFSET(mbox->barmem));
+	mbox->barmem_sz = readl(OCTEP_CTRL_MBOX_INFO_BARMEM_SZ(mbox->barmem));
 
-	writeq(OCTEP_CTRL_MBOX_STATUS_INIT, OCTEP_CTRL_MBOX_INFO_HOST_STATUS_OFFSET(mbox->barmem));
+	writeq(OCTEP_CTRL_MBOX_STATUS_INIT,
+	       OCTEP_CTRL_MBOX_INFO_HOST_STATUS(mbox->barmem));
 
-	mbox->h2fq.elem_cnt = readl(OCTEP_CTRL_MBOX_H2FQ_ELEM_CNT_OFFSET(mbox->barmem));
-	mbox->h2fq.elem_sz = readl(OCTEP_CTRL_MBOX_H2FQ_ELEM_SZ_OFFSET(mbox->barmem));
-	mbox->h2fq.mask = (mbox->h2fq.elem_cnt - 1);
-	mutex_init(&mbox->h2fq_lock);
+	mbox->h2fq.sz = readl(OCTEP_CTRL_MBOX_H2FQ_SZ(mbox->barmem));
+	mbox->h2fq.hw_prod = OCTEP_CTRL_MBOX_H2FQ_PROD(mbox->barmem);
+	mbox->h2fq.hw_cons = OCTEP_CTRL_MBOX_H2FQ_CONS(mbox->barmem);
+	mbox->h2fq.hw_q = mbox->barmem + OCTEP_CTRL_MBOX_TOTAL_INFO_SZ;
 
-	mbox->f2hq.elem_cnt = readl(OCTEP_CTRL_MBOX_F2HQ_ELEM_CNT_OFFSET(mbox->barmem));
-	mbox->f2hq.elem_sz = readl(OCTEP_CTRL_MBOX_F2HQ_ELEM_SZ_OFFSET(mbox->barmem));
-	mbox->f2hq.mask = (mbox->f2hq.elem_cnt - 1);
-	mutex_init(&mbox->f2hq_lock);
-
-	mbox->h2fq.hw_prod = OCTEP_CTRL_MBOX_H2FQ_PROD_OFFSET(mbox->barmem);
-	mbox->h2fq.hw_cons = OCTEP_CTRL_MBOX_H2FQ_CONS_OFFSET(mbox->barmem);
-	mbox->h2fq.hw_q = mbox->barmem +
-			  OCTEP_CTRL_MBOX_INFO_SZ +
-			  OCTEP_CTRL_MBOX_H2FQ_INFO_SZ +
-			  OCTEP_CTRL_MBOX_F2HQ_INFO_SZ;
-
-	mbox->f2hq.hw_prod = OCTEP_CTRL_MBOX_F2HQ_PROD_OFFSET(mbox->barmem);
-	mbox->f2hq.hw_cons = OCTEP_CTRL_MBOX_F2HQ_CONS_OFFSET(mbox->barmem);
-	mbox->f2hq.hw_q = mbox->h2fq.hw_q +
-			  ((mbox->h2fq.elem_sz + sizeof(union octep_ctrl_mbox_msg_hdr)) *
-			   mbox->h2fq.elem_cnt);
+	mbox->f2hq.sz = readl(OCTEP_CTRL_MBOX_F2HQ_SZ(mbox->barmem));
+	mbox->f2hq.hw_prod = OCTEP_CTRL_MBOX_F2HQ_PROD(mbox->barmem);
+	mbox->f2hq.hw_cons = OCTEP_CTRL_MBOX_F2HQ_CONS(mbox->barmem);
+	mbox->f2hq.hw_q = mbox->barmem +
+			  OCTEP_CTRL_MBOX_TOTAL_INFO_SZ +
+			  mbox->h2fq.sz;
 
 	/* ensure ready state is seen after everything is initialized */
 	wmb();
-	writeq(OCTEP_CTRL_MBOX_STATUS_READY, OCTEP_CTRL_MBOX_INFO_HOST_STATUS_OFFSET(mbox->barmem));
+	writeq(OCTEP_CTRL_MBOX_STATUS_READY,
+	       OCTEP_CTRL_MBOX_INFO_HOST_STATUS(mbox->barmem));
 
 	pr_info("Octep ctrl mbox : Init successful.\n");
 
 	return 0;
 }
 
-int octep_ctrl_mbox_send(struct octep_ctrl_mbox *mbox, struct octep_ctrl_mbox_msg *msg)
+static int write_mbox_data(struct octep_ctrl_mbox_q *q, u32 *pi,
+			   u32 ci, void *buf, u32 w_sz)
+{
+	u32 cp_sz;
+	u8 __iomem *qbuf;
+
+	/* Assumption: Caller has ensured enough write space */
+	qbuf = (q->hw_q + *pi);
+	if (*pi < ci) {
+		/* copy entire w_sz */
+		memcpy_toio(qbuf, buf, w_sz);
+		*pi = octep_ctrl_mbox_circq_inc(*pi, w_sz, q->sz);
+	} else {
+		/* copy up to end of queue */
+		cp_sz = min((q->sz - *pi), w_sz);
+		memcpy_toio(qbuf, buf, cp_sz);
+		w_sz -= cp_sz;
+		*pi = octep_ctrl_mbox_circq_inc(*pi, cp_sz, q->sz);
+		if (w_sz) {
+			/* roll over and copy remaining w_sz */
+			buf += cp_sz;
+			qbuf = (q->hw_q + *pi);
+			memcpy_toio(qbuf, buf, w_sz);
+			*pi = octep_ctrl_mbox_circq_inc(*pi, w_sz, q->sz);
+		}
+	}
+
+	return 0;
+}
+
+int octep_ctrl_mbox_send(struct octep_ctrl_mbox *mbox,
+			 struct octep_ctrl_mbox_msg *msgs,
+			 int num)
 {
-	unsigned long timeout = msecs_to_jiffies(OCTEP_CTRL_MBOX_MSG_TIMEOUT_MS);
-	unsigned long period = msecs_to_jiffies(OCTEP_CTRL_MBOX_MSG_WAIT_MS);
+	struct octep_ctrl_mbox_msg_buf *sg;
+	struct octep_ctrl_mbox_msg *msg;
 	struct octep_ctrl_mbox_q *q;
-	unsigned long expire;
-	u64 *mbuf, *word0;
-	u8 __iomem *qidx;
-	u16 pi, ci;
-	int i;
+	u32 pi, ci, prev_pi, buf_sz, w_sz;
+	int m, s;
 
-	if (!mbox || !msg)
+	if (!mbox || !msgs)
 		return -EINVAL;
 
+	if (readq(OCTEP_CTRL_MBOX_INFO_FW_STATUS(mbox->barmem)) !=
+	    OCTEP_CTRL_MBOX_STATUS_READY)
+		return -EIO;
+
+	mutex_lock(&mbox->h2fq_lock);
 	q = &mbox->h2fq;
 	pi = readl(q->hw_prod);
 	ci = readl(q->hw_cons);
+	for (m = 0; m < num; m++) {
+		msg = &msgs[m];
+		if (!msg)
+			break;
 
-	if (!octep_ctrl_mbox_circq_space(pi, ci, q->mask))
-		return -ENOMEM;
-
-	qidx = OCTEP_CTRL_MBOX_Q_OFFSET(q->hw_q, pi);
-	mbuf = (u64 *)msg->msg;
-	word0 = &msg->hdr.word0;
-
-	mutex_lock(&mbox->h2fq_lock);
-	for (i = 1; i <= msg->hdr.sizew; i++)
-		writeq(*mbuf++, (qidx + (i * 8)));
-
-	writeq(*word0, qidx);
+		/* not enough space for next message */
+		if (octep_ctrl_mbox_circq_space(pi, ci, q->sz) <
+		    (msg->hdr.s.sz + mbox_hdr_sz))
+			break;
 
-	pi = octep_ctrl_mbox_circq_inc(pi, q->mask);
+		prev_pi = pi;
+		write_mbox_data(q, &pi, ci, (void *)&msg->hdr, mbox_hdr_sz);
+		buf_sz = msg->hdr.s.sz;
+		for (s = 0; ((s < msg->sg_num) && (buf_sz > 0)); s++) {
+			sg = &msg->sg_list[s];
+			w_sz = (sg->sz <= buf_sz) ? sg->sz : buf_sz;
+			write_mbox_data(q, &pi, ci, sg->msg, w_sz);
+			buf_sz -= w_sz;
+		}
+		if (buf_sz) {
+			/* we did not write entire message */
+			pi = prev_pi;
+			break;
+		}
+	}
 	writel(pi, q->hw_prod);
 	mutex_unlock(&mbox->h2fq_lock);
 
-	/* don't check for notification response */
-	if (msg->hdr.flags & OCTEP_CTRL_MBOX_MSG_HDR_FLAG_NOTIFY)
-		return 0;
+	return (m) ? m : -EAGAIN;
+}
 
-	expire = jiffies + timeout;
-	while (true) {
-		*word0 = readq(qidx);
-		if (msg->hdr.flags == OCTEP_CTRL_MBOX_MSG_HDR_FLAG_RESP)
-			break;
-		schedule_timeout_interruptible(period);
-		if (signal_pending(current) || time_after(jiffies, expire)) {
-			pr_info("octep_ctrl_mbox: Timed out\n");
-			return -EBUSY;
+static int read_mbox_data(struct octep_ctrl_mbox_q *q, u32 pi,
+			  u32 *ci, void *buf, u32 r_sz)
+{
+	u32 cp_sz;
+	u8 __iomem *qbuf;
+
+	/* Assumption: Caller has ensured enough read space */
+	qbuf = (q->hw_q + *ci);
+	if (*ci < pi) {
+		/* copy entire r_sz */
+		memcpy_fromio(buf, qbuf, r_sz);
+		*ci = octep_ctrl_mbox_circq_inc(*ci, r_sz, q->sz);
+	} else {
+		/* copy up to end of queue */
+		cp_sz = min((q->sz - *ci), r_sz);
+		memcpy_fromio(buf, qbuf, cp_sz);
+		r_sz -= cp_sz;
+		*ci = octep_ctrl_mbox_circq_inc(*ci, cp_sz, q->sz);
+		if (r_sz) {
+			/* roll over and copy remaining r_sz */
+			buf += cp_sz;
+			qbuf = (q->hw_q + *ci);
+			memcpy_fromio(buf, qbuf, r_sz);
+			*ci = octep_ctrl_mbox_circq_inc(*ci, r_sz, q->sz);
 		}
 	}
-	mbuf = (u64 *)msg->msg;
-	for (i = 1; i <= msg->hdr.sizew; i++)
-		*mbuf++ = readq(qidx + (i * 8));
 
 	return 0;
 }
 
-int octep_ctrl_mbox_recv(struct octep_ctrl_mbox *mbox, struct octep_ctrl_mbox_msg *msg)
+int octep_ctrl_mbox_recv(struct octep_ctrl_mbox *mbox,
+			 struct octep_ctrl_mbox_msg *msgs,
+			 int num)
 {
+	struct octep_ctrl_mbox_msg_buf *sg;
+	struct octep_ctrl_mbox_msg *msg;
 	struct octep_ctrl_mbox_q *q;
-	u32 count, pi, ci;
-	u8 __iomem *qidx;
-	u64 *mbuf;
-	int i;
+	u32 pi, ci, q_depth, r_sz, buf_sz, prev_ci;
+	int s, m;
 
-	if (!mbox || !msg)
+	if (!mbox || !msgs)
 		return -EINVAL;
 
+	if (readq(OCTEP_CTRL_MBOX_INFO_FW_STATUS(mbox->barmem)) !=
+	    OCTEP_CTRL_MBOX_STATUS_READY)
+		return -EIO;
+
+	mutex_lock(&mbox->f2hq_lock);
 	q = &mbox->f2hq;
 	pi = readl(q->hw_prod);
 	ci = readl(q->hw_cons);
-	count = octep_ctrl_mbox_circq_depth(pi, ci, q->mask);
-	if (!count)
-		return -EAGAIN;
-
-	qidx = OCTEP_CTRL_MBOX_Q_OFFSET(q->hw_q, ci);
-	mbuf = (u64 *)msg->msg;
-
-	mutex_lock(&mbox->f2hq_lock);
+	for (m = 0; m < num; m++) {
+		q_depth = octep_ctrl_mbox_circq_depth(pi, ci, q->sz);
+		if (q_depth < mbox_hdr_sz)
+			break;
 
-	msg->hdr.word0 = readq(qidx);
-	for (i = 1; i <= msg->hdr.sizew; i++)
-		*mbuf++ = readq(qidx + (i * 8));
+		msg = &msgs[m];
+		if (!msg)
+			break;
 
-	ci = octep_ctrl_mbox_circq_inc(ci, q->mask);
+		prev_ci = ci;
+		read_mbox_data(q, pi, &ci, (void *)&msg->hdr, mbox_hdr_sz);
+		buf_sz = msg->hdr.s.sz;
+		if (q_depth < (mbox_hdr_sz + buf_sz)) {
+			ci = prev_ci;
+			break;
+		}
+		for (s = 0; ((s < msg->sg_num) && (buf_sz > 0)); s++) {
+			sg = &msg->sg_list[s];
+			r_sz = (sg->sz <= buf_sz) ? sg->sz : buf_sz;
+			read_mbox_data(q, pi, &ci, sg->msg, r_sz);
+			buf_sz -= r_sz;
+		}
+		if (buf_sz) {
+			/* we did not read entire message */
+			ci = prev_ci;
+			break;
+		}
+	}
 	writel(ci, q->hw_cons);
-
 	mutex_unlock(&mbox->f2hq_lock);
 
-	if (msg->hdr.flags != OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ || !mbox->process_req)
-		return 0;
-
-	mbox->process_req(mbox->user_ctx, msg);
-	mbuf = (u64 *)msg->msg;
-	for (i = 1; i <= msg->hdr.sizew; i++)
-		writeq(*mbuf++, (qidx + (i * 8)));
-
-	writeq(msg->hdr.word0, qidx);
-
-	return 0;
+	return (m) ? m : -EAGAIN;
 }
 
 int octep_ctrl_mbox_uninit(struct octep_ctrl_mbox *mbox)
 {
 	if (!mbox)
 		return -EINVAL;
+	if (!mbox->barmem)
+		return -EINVAL;
 
-	writeq(OCTEP_CTRL_MBOX_STATUS_UNINIT,
-	       OCTEP_CTRL_MBOX_INFO_HOST_STATUS_OFFSET(mbox->barmem));
+	writeq(OCTEP_CTRL_MBOX_STATUS_INVALID,
+	       OCTEP_CTRL_MBOX_INFO_HOST_STATUS(mbox->barmem));
 	/* ensure uninit state is written before uninitialization */
 	wmb();
 
 	mutex_destroy(&mbox->h2fq_lock);
 	mutex_destroy(&mbox->f2hq_lock);
 
-	writeq(OCTEP_CTRL_MBOX_STATUS_INVALID,
-	       OCTEP_CTRL_MBOX_INFO_HOST_STATUS_OFFSET(mbox->barmem));
-
 	pr_info("Octep ctrl mbox : Uninit successful.\n");
 
 	return 0;
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.h b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.h
index 2dc5753cfec6..6ee0345d4436 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.h
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.h
@@ -27,50 +27,39 @@
  * |-------------------------------------------|
  * |producer index (4 bytes)                   |
  * |consumer index (4 bytes)                   |
- * |element size (4 bytes)                     |
- * |element count (4 bytes)                    |
+ * |max element size (4 bytes)                 |
+ * |reserved (4 bytes)                         |
  * |===========================================|
  * |Fw to Host Queue info (16 bytes)           |
  * |-------------------------------------------|
  * |producer index (4 bytes)                   |
  * |consumer index (4 bytes)                   |
- * |element size (4 bytes)                     |
- * |element count (4 bytes)                    |
+ * |max element size (4 bytes)                 |
+ * |reserved (4 bytes)                         |
  * |===========================================|
- * |Host to Fw Queue                           |
+ * |Host to Fw Queue ((total size-288/2) bytes)|
  * |-------------------------------------------|
- * |((elem_sz + hdr(8 bytes)) * elem_cnt) bytes|
+ * |                                           |
  * |===========================================|
  * |===========================================|
- * |Fw to Host Queue                           |
+ * |Fw to Host Queue ((total size-288/2) bytes)|
  * |-------------------------------------------|
- * |((elem_sz + hdr(8 bytes)) * elem_cnt) bytes|
+ * |                                           |
  * |===========================================|
  */
 
 #define OCTEP_CTRL_MBOX_MAGIC_NUMBER			0xdeaddeadbeefbeefull
 
-/* Size of mbox info in bytes */
-#define OCTEP_CTRL_MBOX_INFO_SZ				256
-/* Size of mbox host to target queue info in bytes */
-#define OCTEP_CTRL_MBOX_H2FQ_INFO_SZ			16
-/* Size of mbox target to host queue info in bytes */
-#define OCTEP_CTRL_MBOX_F2HQ_INFO_SZ			16
-/* Size of mbox queue in bytes */
-#define OCTEP_CTRL_MBOX_Q_SZ(sz, cnt)			(((sz) + 8) * (cnt))
-/* Size of mbox in bytes */
-#define OCTEP_CTRL_MBOX_SZ(hsz, hcnt, fsz, fcnt)	(OCTEP_CTRL_MBOX_INFO_SZ + \
-							 OCTEP_CTRL_MBOX_H2FQ_INFO_SZ + \
-							 OCTEP_CTRL_MBOX_F2HQ_INFO_SZ + \
-							 OCTEP_CTRL_MBOX_Q_SZ(hsz, hcnt) + \
-							 OCTEP_CTRL_MBOX_Q_SZ(fsz, fcnt))
-
 /* Valid request message */
 #define OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ		BIT(0)
 /* Valid response message */
 #define OCTEP_CTRL_MBOX_MSG_HDR_FLAG_RESP		BIT(1)
 /* Valid notification, no response required */
 #define OCTEP_CTRL_MBOX_MSG_HDR_FLAG_NOTIFY		BIT(2)
+/* Valid custom message */
+#define OCTEP_CTRL_MBOX_MSG_HDR_FLAG_CUSTOM		BIT(3)
+
+#define OCTEP_CTRL_MBOX_MSG_DESC_MAX			4
 
 enum octep_ctrl_mbox_status {
 	OCTEP_CTRL_MBOX_STATUS_INVALID = 0,
@@ -81,31 +70,48 @@ enum octep_ctrl_mbox_status {
 
 /* mbox message */
 union octep_ctrl_mbox_msg_hdr {
-	u64 word0;
+	u64 words[2];
 	struct {
+		/* must be 0 */
+		u16 reserved1:15;
+		/* vf_idx is valid if 1 */
+		u16 is_vf:1;
+		/* sender vf index 0-(n-1), 0 if (is_vf==0) */
+		u16 vf_idx;
+		/* total size of message excluding header */
+		u32 sz;
 		/* OCTEP_CTRL_MBOX_MSG_HDR_FLAG_* */
 		u32 flags;
-		/* size of message in words excluding header */
-		u32 sizew;
-	};
+		/* identifier to match responses */
+		u16 msg_id;
+		u16 reserved2;
+	} s;
+};
+
+/* mbox message buffer */
+struct octep_ctrl_mbox_msg_buf {
+	u32 reserved1;
+	u16 reserved2;
+	/* size of buffer */
+	u16 sz;
+	/* pointer to message buffer */
+	void *msg;
 };
 
 /* mbox message */
 struct octep_ctrl_mbox_msg {
 	/* mbox transaction header */
 	union octep_ctrl_mbox_msg_hdr hdr;
-	/* pointer to message buffer */
-	void *msg;
+	/* number of sg buffer's */
+	int sg_num;
+	/* message buffer's */
+	struct octep_ctrl_mbox_msg_buf sg_list[OCTEP_CTRL_MBOX_MSG_DESC_MAX];
 };
 
 /* Mbox queue */
 struct octep_ctrl_mbox_q {
-	/* q element size, should be aligned to unsigned long */
-	u16 elem_sz;
-	/* q element count, should be power of 2 */
-	u16 elem_cnt;
-	/* q mask */
-	u16 mask;
+	/* size of queue buffer */
+	u32 sz;
 	/* producer address in bar mem */
 	u8 __iomem *hw_prod;
 	/* consumer address in bar mem */
@@ -115,16 +121,10 @@ struct octep_ctrl_mbox_q {
 };
 
 struct octep_ctrl_mbox {
-	/* host driver version */
-	u64 version;
 	/* size of bar memory */
 	u32 barmem_sz;
 	/* pointer to BAR memory */
 	u8 __iomem *barmem;
-	/* user context for callback, can be null */
-	void *user_ctx;
-	/* callback handler for processing request, called from octep_ctrl_mbox_recv */
-	int (*process_req)(void *user_ctx, struct octep_ctrl_mbox_msg *msg);
 	/* host-to-fw queue */
 	struct octep_ctrl_mbox_q h2fq;
 	/* fw-to-host queue */
@@ -146,22 +146,32 @@ int octep_ctrl_mbox_init(struct octep_ctrl_mbox *mbox);
 /* Send mbox message.
  *
  * @param mbox: non-null pointer to struct octep_ctrl_mbox.
+ * @param msgs: Array of non-null pointers to struct octep_ctrl_mbox_msg.
+ *             Caller should fill msg.sz and msg.desc.sz for each message.
+ * @param num: Size of msg array.
  *
- * return value: 0 on success, -errno on failure.
+ * return value: number of messages sent on success, -errno on failure.
  */
-int octep_ctrl_mbox_send(struct octep_ctrl_mbox *mbox, struct octep_ctrl_mbox_msg *msg);
+int octep_ctrl_mbox_send(struct octep_ctrl_mbox *mbox,
+			 struct octep_ctrl_mbox_msg *msgs,
+			 int num);
 
 /* Retrieve mbox message.
  *
  * @param mbox: non-null pointer to struct octep_ctrl_mbox.
+ * @param msgs: Array of non-null pointers to struct octep_ctrl_mbox_msg.
+ *             Caller should fill msg.sz and msg.desc.sz for each message.
+ * @param num: Size of msg array.
  *
- * return value: 0 on success, -errno on failure.
+ * return value: number of messages received on success, -errno on failure.
  */
-int octep_ctrl_mbox_recv(struct octep_ctrl_mbox *mbox, struct octep_ctrl_mbox_msg *msg);
+int octep_ctrl_mbox_recv(struct octep_ctrl_mbox *mbox,
+			 struct octep_ctrl_mbox_msg *msgs,
+			 int num);
 
 /* Uninitialize control mbox.
  *
- * @param ep: non-null pointer to struct octep_ctrl_mbox.
+ * @param mbox: non-null pointer to struct octep_ctrl_mbox.
  *
  * return value: 0 on success, -errno on failure.
  */
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c
index 7c00c896ab98..715af1891d0d 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c
@@ -8,134 +8,199 @@
 #include <linux/types.h>
 #include <linux/etherdevice.h>
 #include <linux/pci.h>
+#include <linux/wait.h>
 
 #include "octep_config.h"
 #include "octep_main.h"
 #include "octep_ctrl_net.h"
 
-int octep_get_link_status(struct octep_device *oct)
+static const u32 req_hdr_sz = sizeof(union octep_ctrl_net_req_hdr);
+static const u32 mtu_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_mtu);
+static const u32 mac_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_mac);
+static const u32 state_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_state);
+static const u32 link_info_sz = sizeof(struct octep_ctrl_net_link_info);
+static const u32 get_stats_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_get_stats);
+static atomic_t ctrl_net_msg_id;
+
+static void init_send_req(struct octep_ctrl_mbox_msg *msg, void *buf,
+			  u16 sz, int vfid)
 {
-	struct octep_ctrl_net_h2f_req req = {};
-	struct octep_ctrl_net_h2f_resp *resp;
-	struct octep_ctrl_mbox_msg msg = {};
-	int err;
+	msg->hdr.s.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
+	msg->hdr.s.msg_id = atomic_inc_return(&ctrl_net_msg_id) &
+			    GENMASK(sizeof(msg->hdr.s.msg_id) * BITS_PER_BYTE, 0);
+	msg->hdr.s.sz = req_hdr_sz + sz;
+	msg->sg_num = 1;
+	msg->sg_list[0].msg = buf;
+	msg->sg_list[0].sz = msg->hdr.s.sz;
+	if (vfid != OCTEP_CTRL_NET_INVALID_VFID) {
+		msg->hdr.s.is_vf = 1;
+		msg->hdr.s.vf_idx = vfid;
+	}
+}
 
-	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS;
-	req.link.cmd = OCTEP_CTRL_NET_CMD_GET;
+static int send_mbox_req(struct octep_device *oct,
+			 struct octep_ctrl_net_wait_data *d,
+			 bool wait_for_response)
+{
+	int err, ret;
 
-	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
-	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_STATE_REQ_SZW;
-	msg.msg = &req;
-	err = octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
-	if (err)
+	err = octep_ctrl_mbox_send(&oct->ctrl_mbox, &d->msg, 1);
+	if (err < 0)
 		return err;
 
-	resp = (struct octep_ctrl_net_h2f_resp *)&req;
-	return resp->link.state;
+	if (!wait_for_response)
+		return 0;
+
+	d->done = 0;
+	INIT_LIST_HEAD(&d->list);
+	list_add_tail(&d->list, &oct->ctrl_req_wait_list);
+	ret = wait_event_interruptible_timeout(oct->ctrl_req_wait_q,
+					       (d->done != 0),
+					       jiffies + msecs_to_jiffies(500));
+	list_del(&d->list);
+	if (ret == 0 || ret == 1)
+		return -EAGAIN;
+
+	/**
+	 * (ret == 0)  cond = false && timeout, return 0
+	 * (ret < 0) interrupted by signal, return 0
+	 * (ret == 1) cond = true && timeout, return 1
+	 * (ret >= 1) cond = true && !timeout, return 1
+	 */
+
+	if (d->data.resp.hdr.s.reply != OCTEP_CTRL_NET_REPLY_OK)
+		return -EAGAIN;
+
+	return 0;
 }
 
-void octep_set_link_status(struct octep_device *oct, bool up)
+int octep_ctrl_net_init(struct octep_device *oct)
 {
-	struct octep_ctrl_net_h2f_req req = {};
-	struct octep_ctrl_mbox_msg msg = {};
+	struct pci_dev *pdev = oct->pdev;
+	struct octep_ctrl_mbox *ctrl_mbox;
+	int ret;
+
+	init_waitqueue_head(&oct->ctrl_req_wait_q);
+	INIT_LIST_HEAD(&oct->ctrl_req_wait_list);
+
+	/* Initialize control mbox */
+	ctrl_mbox = &oct->ctrl_mbox;
+	ctrl_mbox->barmem = CFG_GET_CTRL_MBOX_MEM_ADDR(oct->conf);
+	ret = octep_ctrl_mbox_init(ctrl_mbox);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to initialize control mbox\n");
+		return ret;
+	}
+	oct->ctrl_mbox_ifstats_offset = ctrl_mbox->barmem_sz;
+
+	return 0;
+}
 
-	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS;
-	req.link.cmd = OCTEP_CTRL_NET_CMD_SET;
-	req.link.state = (up) ? OCTEP_CTRL_NET_STATE_UP : OCTEP_CTRL_NET_STATE_DOWN;
+int octep_ctrl_net_get_link_status(struct octep_device *oct, int vfid)
+{
+	struct octep_ctrl_net_wait_data d = {0};
+	struct octep_ctrl_net_h2f_req *req = &d.data.req;
+	int err;
 
-	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
-	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_STATE_REQ_SZW;
-	msg.msg = &req;
-	octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
+	init_send_req(&d.msg, (void *)req, state_sz, vfid);
+	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS;
+	req->link.cmd = OCTEP_CTRL_NET_CMD_GET;
+	err = send_mbox_req(oct, &d, true);
+	if (err < 0)
+		return err;
+
+	return d.data.resp.link.state;
 }
 
-void octep_set_rx_state(struct octep_device *oct, bool up)
+int octep_ctrl_net_set_link_status(struct octep_device *oct, int vfid, bool up,
+				   bool wait_for_response)
 {
-	struct octep_ctrl_net_h2f_req req = {};
-	struct octep_ctrl_mbox_msg msg = {};
+	struct octep_ctrl_net_wait_data d = {0};
+	struct octep_ctrl_net_h2f_req *req = &d.data.req;
 
-	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_RX_STATE;
-	req.link.cmd = OCTEP_CTRL_NET_CMD_SET;
-	req.link.state = (up) ? OCTEP_CTRL_NET_STATE_UP : OCTEP_CTRL_NET_STATE_DOWN;
+	init_send_req(&d.msg, req, state_sz, vfid);
+	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS;
+	req->link.cmd = OCTEP_CTRL_NET_CMD_SET;
+	req->link.state = (up) ? OCTEP_CTRL_NET_STATE_UP :
+				OCTEP_CTRL_NET_STATE_DOWN;
 
-	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
-	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_STATE_REQ_SZW;
-	msg.msg = &req;
-	octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
+	return send_mbox_req(oct, &d, wait_for_response);
 }
 
-int octep_get_mac_addr(struct octep_device *oct, u8 *addr)
+int octep_ctrl_net_set_rx_state(struct octep_device *oct, int vfid, bool up,
+				bool wait_for_response)
 {
-	struct octep_ctrl_net_h2f_req req = {};
-	struct octep_ctrl_net_h2f_resp *resp;
-	struct octep_ctrl_mbox_msg msg = {};
-	int err;
+	struct octep_ctrl_net_wait_data d = {0};
+	struct octep_ctrl_net_h2f_req *req = &d.data.req;
+
+	init_send_req(&d.msg, req, state_sz, vfid);
+	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_RX_STATE;
+	req->link.cmd = OCTEP_CTRL_NET_CMD_SET;
+	req->link.state = (up) ? OCTEP_CTRL_NET_STATE_UP :
+				OCTEP_CTRL_NET_STATE_DOWN;
 
-	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_MAC;
-	req.link.cmd = OCTEP_CTRL_NET_CMD_GET;
+	return send_mbox_req(oct, &d, wait_for_response);
+}
+
+int octep_ctrl_net_get_mac_addr(struct octep_device *oct, int vfid, u8 *addr)
+{
+	struct octep_ctrl_net_wait_data d = {0};
+	struct octep_ctrl_net_h2f_req *req = &d.data.req;
+	int err;
 
-	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
-	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_MAC_REQ_SZW;
-	msg.msg = &req;
-	err = octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
-	if (err)
+	init_send_req(&d.msg, req, mac_sz, vfid);
+	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_MAC;
+	req->link.cmd = OCTEP_CTRL_NET_CMD_GET;
+	err = send_mbox_req(oct, &d, true);
+	if (err < 0)
 		return err;
 
-	resp = (struct octep_ctrl_net_h2f_resp *)&req;
-	memcpy(addr, resp->mac.addr, ETH_ALEN);
+	memcpy(addr, d.data.resp.mac.addr, ETH_ALEN);
 
-	return err;
+	return 0;
 }
 
-int octep_set_mac_addr(struct octep_device *oct, u8 *addr)
+int octep_ctrl_net_set_mac_addr(struct octep_device *oct, int vfid, u8 *addr,
+				bool wait_for_response)
 {
-	struct octep_ctrl_net_h2f_req req = {};
-	struct octep_ctrl_mbox_msg msg = {};
+	struct octep_ctrl_net_wait_data d = {0};
+	struct octep_ctrl_net_h2f_req *req = &d.data.req;
 
-	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_MAC;
-	req.mac.cmd = OCTEP_CTRL_NET_CMD_SET;
-	memcpy(&req.mac.addr, addr, ETH_ALEN);
+	init_send_req(&d.msg, req, mac_sz, vfid);
+	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_MAC;
+	req->mac.cmd = OCTEP_CTRL_NET_CMD_SET;
+	memcpy(&req->mac.addr, addr, ETH_ALEN);
 
-	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
-	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_MAC_REQ_SZW;
-	msg.msg = &req;
-
-	return octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
+	return send_mbox_req(oct, &d, wait_for_response);
 }
 
-int octep_set_mtu(struct octep_device *oct, int mtu)
+int octep_ctrl_net_set_mtu(struct octep_device *oct, int vfid, int mtu,
+			   bool wait_for_response)
 {
-	struct octep_ctrl_net_h2f_req req = {};
-	struct octep_ctrl_mbox_msg msg = {};
-
-	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_MTU;
-	req.mtu.cmd = OCTEP_CTRL_NET_CMD_SET;
-	req.mtu.val = mtu;
+	struct octep_ctrl_net_wait_data d = {0};
+	struct octep_ctrl_net_h2f_req *req = &d.data.req;
 
-	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
-	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_MTU_REQ_SZW;
-	msg.msg = &req;
+	init_send_req(&d.msg, req, mtu_sz, vfid);
+	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_MTU;
+	req->mtu.cmd = OCTEP_CTRL_NET_CMD_SET;
+	req->mtu.val = mtu;
 
-	return octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
+	return send_mbox_req(oct, &d, wait_for_response);
 }
 
-int octep_get_if_stats(struct octep_device *oct)
+int octep_ctrl_net_get_if_stats(struct octep_device *oct, int vfid)
 {
 	void __iomem *iface_rx_stats;
 	void __iomem *iface_tx_stats;
-	struct octep_ctrl_net_h2f_req req = {};
-	struct octep_ctrl_mbox_msg msg = {};
+	struct octep_ctrl_net_wait_data d = {0};
+	struct octep_ctrl_net_h2f_req *req = &d.data.req;
 	int err;
 
-	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_GET_IF_STATS;
-	req.mac.cmd = OCTEP_CTRL_NET_CMD_GET;
-	req.get_stats.offset = oct->ctrl_mbox_ifstats_offset;
-
-	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
-	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_GET_STATS_REQ_SZW;
-	msg.msg = &req;
-	err = octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
-	if (err)
+	init_send_req(&d.msg, req, get_stats_sz, vfid);
+	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_GET_IF_STATS;
+	req->get_stats.offset = oct->ctrl_mbox_ifstats_offset;
+	err = send_mbox_req(oct, &d, true);
+	if (err < 0)
 		return err;
 
 	iface_rx_stats = oct->ctrl_mbox.barmem + oct->ctrl_mbox_ifstats_offset;
@@ -144,51 +209,115 @@ int octep_get_if_stats(struct octep_device *oct)
 	memcpy_fromio(&oct->iface_rx_stats, iface_rx_stats, sizeof(struct octep_iface_rx_stats));
 	memcpy_fromio(&oct->iface_tx_stats, iface_tx_stats, sizeof(struct octep_iface_tx_stats));
 
-	return err;
+	return 0;
 }
 
-int octep_get_link_info(struct octep_device *oct)
+int octep_ctrl_net_get_link_info(struct octep_device *oct, int vfid)
 {
-	struct octep_ctrl_net_h2f_req req = {};
+	struct octep_ctrl_net_wait_data d = {0};
+	struct octep_ctrl_net_h2f_req *req = &d.data.req;
 	struct octep_ctrl_net_h2f_resp *resp;
-	struct octep_ctrl_mbox_msg msg = {};
 	int err;
 
-	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_INFO;
-	req.mac.cmd = OCTEP_CTRL_NET_CMD_GET;
-
-	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
-	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_LINK_INFO_REQ_SZW;
-	msg.msg = &req;
-	err = octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
-	if (err)
+	init_send_req(&d.msg, req, link_info_sz, vfid);
+	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_INFO;
+	req->link_info.cmd = OCTEP_CTRL_NET_CMD_GET;
+	err = send_mbox_req(oct, &d, true);
+	if (err < 0)
 		return err;
 
-	resp = (struct octep_ctrl_net_h2f_resp *)&req;
+	resp = &d.data.resp;
 	oct->link_info.supported_modes = resp->link_info.supported_modes;
 	oct->link_info.advertised_modes = resp->link_info.advertised_modes;
 	oct->link_info.autoneg = resp->link_info.autoneg;
 	oct->link_info.pause = resp->link_info.pause;
 	oct->link_info.speed = resp->link_info.speed;
 
-	return err;
+	return 0;
 }
 
-int octep_set_link_info(struct octep_device *oct, struct octep_iface_link_info *link_info)
+int octep_ctrl_net_set_link_info(struct octep_device *oct, int vfid,
+				 struct octep_iface_link_info *link_info,
+				 bool wait_for_response)
 {
-	struct octep_ctrl_net_h2f_req req = {};
-	struct octep_ctrl_mbox_msg msg = {};
+	struct octep_ctrl_net_wait_data d = {0};
+	struct octep_ctrl_net_h2f_req *req = &d.data.req;
+
+	init_send_req(&d.msg, req, link_info_sz, vfid);
+	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_INFO;
+	req->link_info.cmd = OCTEP_CTRL_NET_CMD_SET;
+	req->link_info.info.advertised_modes = link_info->advertised_modes;
+	req->link_info.info.autoneg = link_info->autoneg;
+	req->link_info.info.pause = link_info->pause;
+	req->link_info.info.speed = link_info->speed;
+
+	return send_mbox_req(oct, &d, wait_for_response);
+}
+
+static int process_mbox_req(struct octep_device *oct,
+			    struct octep_ctrl_mbox_msg *msg)
+{
+	return 0;
+}
+
+static int process_mbox_resp(struct octep_device *oct,
+			     struct octep_ctrl_mbox_msg *msg)
+{
+	struct octep_ctrl_net_wait_data *pos, *n;
+
+	list_for_each_entry_safe(pos, n, &oct->ctrl_req_wait_list, list) {
+		if (pos->msg.hdr.s.msg_id == msg->hdr.s.msg_id) {
+			memcpy(&pos->data.resp,
+			       msg->sg_list[0].msg,
+			       msg->hdr.s.sz);
+			pos->done = 1;
+			wake_up_interruptible_all(&oct->ctrl_req_wait_q);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+int octep_ctrl_net_recv_fw_messages(struct octep_device *oct)
+{
+	static u16 msg_sz = sizeof(union octep_ctrl_net_max_data);
+	union octep_ctrl_net_max_data data = {0};
+	struct octep_ctrl_mbox_msg msg = {0};
+	int ret;
+
+	msg.hdr.s.sz = msg_sz;
+	msg.sg_num = 1;
+	msg.sg_list[0].sz = msg_sz;
+	msg.sg_list[0].msg = &data;
+	while (true) {
+		/* mbox will overwrite msg.hdr.s.sz so initialize it */
+		msg.hdr.s.sz = msg_sz;
+		ret = octep_ctrl_mbox_recv(&oct->ctrl_mbox,
+					   (struct octep_ctrl_mbox_msg *)&msg,
+					   1);
+		if (ret <= 0)
+			break;
+
+		if (msg.hdr.s.flags & OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ)
+			process_mbox_req(oct, &msg);
+		else if (msg.hdr.s.flags & OCTEP_CTRL_MBOX_MSG_HDR_FLAG_RESP)
+			process_mbox_resp(oct, &msg);
+	}
+
+	return 0;
+}
+
+int octep_ctrl_net_uninit(struct octep_device *oct)
+{
+	struct octep_ctrl_net_wait_data *pos, *n;
+
+	list_for_each_entry_safe(pos, n, &oct->ctrl_req_wait_list, list)
+		pos->done = 1;
 
-	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_INFO;
-	req.link_info.cmd = OCTEP_CTRL_NET_CMD_SET;
-	req.link_info.info.advertised_modes = link_info->advertised_modes;
-	req.link_info.info.autoneg = link_info->autoneg;
-	req.link_info.info.pause = link_info->pause;
-	req.link_info.info.speed = link_info->speed;
+	wake_up_interruptible_all(&oct->ctrl_req_wait_q);
 
-	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
-	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_LINK_INFO_REQ_SZW;
-	msg.msg = &req;
+	octep_ctrl_mbox_uninit(&oct->ctrl_mbox);
 
-	return octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
+	return 0;
 }
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.h b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.h
index f23b58381322..c68cdaa1738b 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.h
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.h
@@ -7,6 +7,8 @@
 #ifndef __OCTEP_CTRL_NET_H__
 #define __OCTEP_CTRL_NET_H__
 
+#define OCTEP_CTRL_NET_INVALID_VFID	(-1)
+
 /* Supported commands */
 enum octep_ctrl_net_cmd {
 	OCTEP_CTRL_NET_CMD_GET = 0,
@@ -45,15 +47,18 @@ enum octep_ctrl_net_f2h_cmd {
 	OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS,
 };
 
-struct octep_ctrl_net_req_hdr {
-	/* sender id */
-	u16 sender;
-	/* receiver id */
-	u16 receiver;
-	/* octep_ctrl_net_h2t_cmd */
-	u16 cmd;
-	/* reserved */
-	u16 rsvd0;
+union octep_ctrl_net_req_hdr {
+	u64 words[1];
+	struct {
+		/* sender id */
+		u16 sender;
+		/* receiver id */
+		u16 receiver;
+		/* octep_ctrl_net_h2t_cmd */
+		u16 cmd;
+		/* reserved */
+		u16 rsvd0;
+	} s;
 };
 
 /* get/set mtu request */
@@ -110,7 +115,7 @@ struct octep_ctrl_net_h2f_req_cmd_link_info {
 
 /* Host to fw request data */
 struct octep_ctrl_net_h2f_req {
-	struct octep_ctrl_net_req_hdr hdr;
+	union octep_ctrl_net_req_hdr hdr;
 	union {
 		struct octep_ctrl_net_h2f_req_cmd_mtu mtu;
 		struct octep_ctrl_net_h2f_req_cmd_mac mac;
@@ -121,15 +126,18 @@ struct octep_ctrl_net_h2f_req {
 	};
 } __packed;
 
-struct octep_ctrl_net_resp_hdr {
-	/* sender id */
-	u16 sender;
-	/* receiver id */
-	u16 receiver;
-	/* octep_ctrl_net_h2t_cmd */
-	u16 cmd;
-	/* octep_ctrl_net_reply */
-	u16 reply;
+union octep_ctrl_net_resp_hdr {
+	u64 words[1];
+	struct {
+		/* sender id */
+		u16 sender;
+		/* receiver id */
+		u16 receiver;
+		/* octep_ctrl_net_h2t_cmd */
+		u16 cmd;
+		/* octep_ctrl_net_reply */
+		u16 reply;
+	} s;
 };
 
 /* get mtu response */
@@ -152,7 +160,7 @@ struct octep_ctrl_net_h2f_resp_cmd_state {
 
 /* Host to fw response data */
 struct octep_ctrl_net_h2f_resp {
-	struct octep_ctrl_net_resp_hdr hdr;
+	union octep_ctrl_net_resp_hdr hdr;
 	union {
 		struct octep_ctrl_net_h2f_resp_cmd_mtu mtu;
 		struct octep_ctrl_net_h2f_resp_cmd_mac mac;
@@ -170,7 +178,7 @@ struct octep_ctrl_net_f2h_req_cmd_state {
 
 /* Fw to host request data */
 struct octep_ctrl_net_f2h_req {
-	struct octep_ctrl_net_req_hdr hdr;
+	union octep_ctrl_net_req_hdr hdr;
 	union {
 		struct octep_ctrl_net_f2h_req_cmd_state link;
 	};
@@ -178,122 +186,146 @@ struct octep_ctrl_net_f2h_req {
 
 /* Fw to host response data */
 struct octep_ctrl_net_f2h_resp {
-	struct octep_ctrl_net_resp_hdr hdr;
+	union octep_ctrl_net_resp_hdr hdr;
 };
 
-/* Size of host to fw octep_ctrl_mbox queue element */
-union octep_ctrl_net_h2f_data_sz {
+/* Max data size to be transferred over mbox */
+union octep_ctrl_net_max_data {
 	struct octep_ctrl_net_h2f_req h2f_req;
 	struct octep_ctrl_net_h2f_resp h2f_resp;
-};
-
-/* Size of fw to host octep_ctrl_mbox queue element */
-union octep_ctrl_net_f2h_data_sz {
 	struct octep_ctrl_net_f2h_req f2h_req;
 	struct octep_ctrl_net_f2h_resp f2h_resp;
 };
 
-/* size of host to fw data in words */
-#define OCTEP_CTRL_NET_H2F_DATA_SZW		((sizeof(union octep_ctrl_net_h2f_data_sz)) / \
-						 (sizeof(unsigned long)))
-
-/* size of fw to host data in words */
-#define OCTEP_CTRL_NET_F2H_DATA_SZW		((sizeof(union octep_ctrl_net_f2h_data_sz)) / \
-						 (sizeof(unsigned long)))
-
-/* size in words of get/set mtu request */
-#define OCTEP_CTRL_NET_H2F_MTU_REQ_SZW			2
-/* size in words of get/set mac request */
-#define OCTEP_CTRL_NET_H2F_MAC_REQ_SZW			2
-/* size in words of get stats request */
-#define OCTEP_CTRL_NET_H2F_GET_STATS_REQ_SZW		2
-/* size in words of get/set state request */
-#define OCTEP_CTRL_NET_H2F_STATE_REQ_SZW		2
-/* size in words of get/set link info request */
-#define OCTEP_CTRL_NET_H2F_LINK_INFO_REQ_SZW		4
-
-/* size in words of get mtu response */
-#define OCTEP_CTRL_NET_H2F_GET_MTU_RESP_SZW		2
-/* size in words of set mtu response */
-#define OCTEP_CTRL_NET_H2F_SET_MTU_RESP_SZW		1
-/* size in words of get mac response */
-#define OCTEP_CTRL_NET_H2F_GET_MAC_RESP_SZW		2
-/* size in words of set mac response */
-#define OCTEP_CTRL_NET_H2F_SET_MAC_RESP_SZW		1
-/* size in words of get state request */
-#define OCTEP_CTRL_NET_H2F_GET_STATE_RESP_SZW		2
-/* size in words of set state request */
-#define OCTEP_CTRL_NET_H2F_SET_STATE_RESP_SZW		1
-/* size in words of get link info request */
-#define OCTEP_CTRL_NET_H2F_GET_LINK_INFO_RESP_SZW	4
-/* size in words of set link info request */
-#define OCTEP_CTRL_NET_H2F_SET_LINK_INFO_RESP_SZW	1
+struct octep_ctrl_net_wait_data {
+	struct list_head list;
+	int done;
+	struct octep_ctrl_mbox_msg msg;
+	union {
+		struct octep_ctrl_net_h2f_req req;
+		struct octep_ctrl_net_h2f_resp resp;
+	} data;
+};
+
+/** Initialize data for ctrl net.
+ *
+ * @param oct: non-null pointer to struct octep_device.
+ *
+ * return value: 0 on success, -errno on error.
+ */
+int octep_ctrl_net_init(struct octep_device *oct);
 
 /** Get link status from firmware.
  *
  * @param oct: non-null pointer to struct octep_device.
+ * @param vfid: Index of virtual function.
  *
  * return value: link status 0=down, 1=up.
  */
-int octep_get_link_status(struct octep_device *oct);
+int octep_ctrl_net_get_link_status(struct octep_device *oct, int vfid);
 
 /** Set link status in firmware.
  *
  * @param oct: non-null pointer to struct octep_device.
+ * @param vfid: Index of virtual function.
  * @param up: boolean status.
+ * @param wait_for_response: poll for response.
+ *
+ * return value: 0 on success, -errno on failure
  */
-void octep_set_link_status(struct octep_device *oct, bool up);
+int octep_ctrl_net_set_link_status(struct octep_device *oct, int vfid, bool up,
+				   bool wait_for_response);
 
 /** Set rx state in firmware.
  *
  * @param oct: non-null pointer to struct octep_device.
+ * @param vfid: Index of virtual function.
  * @param up: boolean status.
+ * @param wait_for_response: poll for response.
+ *
+ * return value: 0 on success, -errno on failure.
  */
-void octep_set_rx_state(struct octep_device *oct, bool up);
+int octep_ctrl_net_set_rx_state(struct octep_device *oct, int vfid, bool up,
+				bool wait_for_response);
 
 /** Get mac address from firmware.
  *
  * @param oct: non-null pointer to struct octep_device.
+ * @param vfid: Index of virtual function.
  * @param addr: non-null pointer to mac address.
  *
  * return value: 0 on success, -errno on failure.
  */
-int octep_get_mac_addr(struct octep_device *oct, u8 *addr);
+int octep_ctrl_net_get_mac_addr(struct octep_device *oct, int vfid, u8 *addr);
 
 /** Set mac address in firmware.
  *
  * @param oct: non-null pointer to struct octep_device.
+ * @param vfid: Index of virtual function.
  * @param addr: non-null pointer to mac address.
+ * @param wait_for_response: poll for response.
+ *
+ * return value: 0 on success, -errno on failure.
  */
-int octep_set_mac_addr(struct octep_device *oct, u8 *addr);
+int octep_ctrl_net_set_mac_addr(struct octep_device *oct, int vfid, u8 *addr,
+				bool wait_for_response);
 
 /** Set mtu in firmware.
  *
  * @param oct: non-null pointer to struct octep_device.
+ * @param vfid: Index of virtual function.
  * @param mtu: mtu.
+ * @param wait_for_response: poll for response.
+ *
+ * return value: 0 on success, -errno on failure.
  */
-int octep_set_mtu(struct octep_device *oct, int mtu);
+int octep_ctrl_net_set_mtu(struct octep_device *oct, int vfid, int mtu,
+			   bool wait_for_response);
 
 /** Get interface statistics from firmware.
  *
  * @param oct: non-null pointer to struct octep_device.
+ * @param vfid: Index of virtual function.
  *
  * return value: 0 on success, -errno on failure.
  */
-int octep_get_if_stats(struct octep_device *oct);
+int octep_ctrl_net_get_if_stats(struct octep_device *oct, int vfid);
 
 /** Get link info from firmware.
  *
  * @param oct: non-null pointer to struct octep_device.
+ * @param vfid: Index of virtual function.
  *
  * return value: 0 on success, -errno on failure.
  */
-int octep_get_link_info(struct octep_device *oct);
+int octep_ctrl_net_get_link_info(struct octep_device *oct, int vfid);
 
 /** Set link info in firmware.
  *
  * @param oct: non-null pointer to struct octep_device.
+ * @param vfid: Index of virtual function.
+ * @param link_info: non-null pointer to struct octep_iface_link_info.
+ * @param wait_for_response: poll for response.
+ *
+ * return value: 0 on success, -errno on failure.
+ */
+int octep_ctrl_net_set_link_info(struct octep_device *oct,
+				 int vfid,
+				 struct octep_iface_link_info *link_info,
+				 bool wait_for_response);
+
+/** Poll for firmware messages and process them.
+ *
+ * @param oct: non-null pointer to struct octep_device.
+ */
+int octep_ctrl_net_recv_fw_messages(struct octep_device *oct);
+
+/** Uninitialize data for ctrl net.
+ *
+ * @param oct: non-null pointer to struct octep_device.
+ *
+ * return value: 0 on success, -errno on error.
  */
-int octep_set_link_info(struct octep_device *oct, struct octep_iface_link_info *link_info);
+int octep_ctrl_net_uninit(struct octep_device *oct);
 
 #endif /* __OCTEP_CTRL_NET_H__ */
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c b/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c
index 87ef129b269a..389042b57787 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c
@@ -150,7 +150,7 @@ octep_get_ethtool_stats(struct net_device *netdev,
 	rx_packets = 0;
 	rx_bytes = 0;
 
-	octep_get_if_stats(oct);
+	octep_ctrl_net_get_if_stats(oct, OCTEP_CTRL_NET_INVALID_VFID);
 	iface_tx_stats = &oct->iface_tx_stats;
 	iface_rx_stats = &oct->iface_rx_stats;
 
@@ -283,7 +283,7 @@ static int octep_get_link_ksettings(struct net_device *netdev,
 	ethtool_link_ksettings_zero_link_mode(cmd, supported);
 	ethtool_link_ksettings_zero_link_mode(cmd, advertising);
 
-	octep_get_link_info(oct);
+	octep_ctrl_net_get_link_info(oct, OCTEP_CTRL_NET_INVALID_VFID);
 
 	advertised_modes = oct->link_info.advertised_modes;
 	supported_modes = oct->link_info.supported_modes;
@@ -439,7 +439,8 @@ static int octep_set_link_ksettings(struct net_device *netdev,
 	link_info_new.speed = cmd->base.speed;
 	link_info_new.autoneg = autoneg;
 
-	err = octep_set_link_info(oct, &link_info_new);
+	err = octep_ctrl_net_set_link_info(oct, OCTEP_CTRL_NET_INVALID_VFID,
+					   &link_info_new, true);
 	if (err)
 		return err;
 
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
index c07588461030..32e2ca24849a 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
@@ -508,11 +508,10 @@ static int octep_open(struct net_device *netdev)
 	octep_napi_enable(oct);
 
 	oct->link_info.admin_up = 1;
-	octep_set_rx_state(oct, true);
-
-	ret = octep_get_link_status(oct);
-	if (!ret)
-		octep_set_link_status(oct, true);
+	octep_ctrl_net_set_rx_state(oct, OCTEP_CTRL_NET_INVALID_VFID, true,
+				    false);
+	octep_ctrl_net_set_link_status(oct, OCTEP_CTRL_NET_INVALID_VFID, true,
+				       false);
 	oct->poll_non_ioq_intr = false;
 
 	/* Enable the input and output queues for this Octeon device */
@@ -523,7 +522,7 @@ static int octep_open(struct net_device *netdev)
 
 	octep_oq_dbell_init(oct);
 
-	ret = octep_get_link_status(oct);
+	ret = octep_ctrl_net_get_link_status(oct, OCTEP_CTRL_NET_INVALID_VFID);
 	if (ret > 0)
 		octep_link_up(netdev);
 
@@ -553,14 +552,16 @@ static int octep_stop(struct net_device *netdev)
 
 	netdev_info(netdev, "Stopping the device ...\n");
 
+	octep_ctrl_net_set_link_status(oct, OCTEP_CTRL_NET_INVALID_VFID, false,
+				       false);
+	octep_ctrl_net_set_rx_state(oct, OCTEP_CTRL_NET_INVALID_VFID, false,
+				    false);
+
 	/* Stop Tx from stack */
 	netif_tx_stop_all_queues(netdev);
 	netif_carrier_off(netdev);
 	netif_tx_disable(netdev);
 
-	octep_set_link_status(oct, false);
-	octep_set_rx_state(oct, false);
-
 	oct->link_info.admin_up = 0;
 	oct->link_info.oper_up = 0;
 
@@ -762,7 +763,9 @@ static void octep_get_stats64(struct net_device *netdev,
 	struct octep_device *oct = netdev_priv(netdev);
 	int q;
 
-	octep_get_if_stats(oct);
+	if (netif_running(netdev))
+		octep_ctrl_net_get_if_stats(oct, OCTEP_CTRL_NET_INVALID_VFID);
+
 	tx_packets = 0;
 	tx_bytes = 0;
 	rx_packets = 0;
@@ -833,7 +836,8 @@ static int octep_set_mac(struct net_device *netdev, void *p)
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
-	err = octep_set_mac_addr(oct, addr->sa_data);
+	err = octep_ctrl_net_set_mac_addr(oct, OCTEP_CTRL_NET_INVALID_VFID,
+					  addr->sa_data, true);
 	if (err)
 		return err;
 
@@ -853,7 +857,8 @@ static int octep_change_mtu(struct net_device *netdev, int new_mtu)
 	if (link_info->mtu == new_mtu)
 		return 0;
 
-	err = octep_set_mtu(oct, new_mtu);
+	err = octep_ctrl_net_set_mtu(oct, OCTEP_CTRL_NET_INVALID_VFID, new_mtu,
+				     true);
 	if (!err) {
 		oct->link_info.mtu = new_mtu;
 		netdev->mtu = new_mtu;
@@ -905,34 +910,8 @@ static void octep_ctrl_mbox_task(struct work_struct *work)
 {
 	struct octep_device *oct = container_of(work, struct octep_device,
 						ctrl_mbox_task);
-	struct net_device *netdev = oct->netdev;
-	struct octep_ctrl_net_f2h_req req = {};
-	struct octep_ctrl_mbox_msg msg;
-	int ret = 0;
-
-	msg.msg = &req;
-	while (true) {
-		ret = octep_ctrl_mbox_recv(&oct->ctrl_mbox, &msg);
-		if (ret)
-			break;
-
-		switch (req.hdr.cmd) {
-		case OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS:
-			if (netif_running(netdev)) {
-				if (req.link.state) {
-					dev_info(&oct->pdev->dev, "netif_carrier_on\n");
-					netif_carrier_on(netdev);
-				} else {
-					dev_info(&oct->pdev->dev, "netif_carrier_off\n");
-					netif_carrier_off(netdev);
-				}
-			}
-			break;
-		default:
-			pr_info("Unknown mbox req : %u\n", req.hdr.cmd);
-			break;
-		}
-	}
+
+	octep_ctrl_net_recv_fw_messages(oct);
 }
 
 static const char *octep_devid_to_str(struct octep_device *oct)
@@ -956,7 +935,6 @@ static const char *octep_devid_to_str(struct octep_device *oct)
  */
 int octep_device_setup(struct octep_device *oct)
 {
-	struct octep_ctrl_mbox *ctrl_mbox;
 	struct pci_dev *pdev = oct->pdev;
 	int i, ret;
 
@@ -993,18 +971,9 @@ int octep_device_setup(struct octep_device *oct)
 
 	oct->pkind = CFG_GET_IQ_PKIND(oct->conf);
 
-	/* Initialize control mbox */
-	ctrl_mbox = &oct->ctrl_mbox;
-	ctrl_mbox->barmem = CFG_GET_CTRL_MBOX_MEM_ADDR(oct->conf);
-	ret = octep_ctrl_mbox_init(ctrl_mbox);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to initialize control mbox\n");
-		goto unsupported_dev;
-	}
-	oct->ctrl_mbox_ifstats_offset = OCTEP_CTRL_MBOX_SZ(ctrl_mbox->h2fq.elem_sz,
-							   ctrl_mbox->h2fq.elem_cnt,
-							   ctrl_mbox->f2hq.elem_sz,
-							   ctrl_mbox->f2hq.elem_cnt);
+	ret = octep_ctrl_net_init(oct);
+	if (ret)
+		return ret;
 
 	return 0;
 
@@ -1034,7 +1003,7 @@ static void octep_device_cleanup(struct octep_device *oct)
 		oct->mbox[i] = NULL;
 	}
 
-	octep_ctrl_mbox_uninit(&oct->ctrl_mbox);
+	octep_ctrl_net_uninit(oct);
 
 	oct->hw_ops.soft_reset(oct);
 	for (i = 0; i < OCTEP_MMIO_REGIONS; i++) {
@@ -1145,7 +1114,8 @@ static int octep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev->max_mtu = OCTEP_MAX_MTU;
 	netdev->mtu = OCTEP_DEFAULT_MTU;
 
-	err = octep_get_mac_addr(octep_dev, octep_dev->mac_addr);
+	err = octep_ctrl_net_get_mac_addr(octep_dev, OCTEP_CTRL_NET_INVALID_VFID,
+					  octep_dev->mac_addr);
 	if (err) {
 		dev_err(&pdev->dev, "Failed to get mac address\n");
 		goto register_dev_err;
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v2 5/9] octeon_ep: support asynchronous notifications
  2022-11-29 13:09 [PATCH net-next v2 0/9] octeon_ep: Update PF mailbox for VF Veerasenareddy Burru
                   ` (3 preceding siblings ...)
  2022-11-29 13:09 ` [PATCH net-next v2 4/9] octeon_ep: enhance control mailbox for VF support Veerasenareddy Burru
@ 2022-11-29 13:09 ` Veerasenareddy Burru
  2022-11-29 13:09 ` [PATCH net-next v2 6/9] octeon_ep: control mbox support for VF stats and link info Veerasenareddy Burru
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-11-29 13:09 UTC (permalink / raw)
  To: netdev, linux-kernel, lironh, aayarekar, sedara, sburla
  Cc: linux-doc, Veerasenareddy Burru, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni

Add asynchronous notification support to the control mailbox.

Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
Signed-off-by: Abhijit Ayarekar <aayarekar@marvell.com>
---
v1 -> v2:
 * no change

 .../marvell/octeon_ep/octep_ctrl_net.c        | 29 +++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c
index 715af1891d0d..80bcd6cd4732 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c
@@ -279,6 +279,33 @@ static int process_mbox_resp(struct octep_device *oct,
 	return 0;
 }
 
+static int process_mbox_notify(struct octep_device *oct,
+			       struct octep_ctrl_mbox_msg *msg)
+{
+	struct octep_ctrl_net_f2h_req *req;
+	struct net_device *netdev = oct->netdev;
+
+	req = (struct octep_ctrl_net_f2h_req *)msg->sg_list[0].msg;
+	switch (req->hdr.s.cmd) {
+	case OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS:
+		if (netif_running(netdev)) {
+			if (req->link.state) {
+				dev_info(&oct->pdev->dev, "netif_carrier_on\n");
+				netif_carrier_on(netdev);
+			} else {
+				dev_info(&oct->pdev->dev, "netif_carrier_off\n");
+				netif_carrier_off(netdev);
+			}
+		}
+		break;
+	default:
+		pr_info("Unknown mbox req : %u\n", req->hdr.s.cmd);
+		break;
+	}
+
+	return 0;
+}
+
 int octep_ctrl_net_recv_fw_messages(struct octep_device *oct)
 {
 	static u16 msg_sz = sizeof(union octep_ctrl_net_max_data);
@@ -303,6 +330,8 @@ int octep_ctrl_net_recv_fw_messages(struct octep_device *oct)
 			process_mbox_req(oct, &msg);
 		else if (msg.hdr.s.flags & OCTEP_CTRL_MBOX_MSG_HDR_FLAG_RESP)
 			process_mbox_resp(oct, &msg);
+		else if (msg.hdr.s.flags & OCTEP_CTRL_MBOX_MSG_HDR_FLAG_NOTIFY)
+			process_mbox_notify(oct, &msg);
 	}
 
 	return 0;
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v2 6/9] octeon_ep: control mbox support for VF stats and link info
  2022-11-29 13:09 [PATCH net-next v2 0/9] octeon_ep: Update PF mailbox for VF Veerasenareddy Burru
                   ` (4 preceding siblings ...)
  2022-11-29 13:09 ` [PATCH net-next v2 5/9] octeon_ep: support asynchronous notifications Veerasenareddy Burru
@ 2022-11-29 13:09 ` Veerasenareddy Burru
  2022-11-29 13:09 ` [PATCH net-next v2 7/9] octeon_ep: add SRIOV VF creation Veerasenareddy Burru
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-11-29 13:09 UTC (permalink / raw)
  To: netdev, linux-kernel, lironh, aayarekar, sedara, sburla
  Cc: linux-doc, Veerasenareddy Burru, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni

Update control mailbox API to get stats and link info for VFs.

Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
Signed-off-by: Abhijit Ayarekar <aayarekar@marvell.com>
---
v1 -> v2:
 * no change

 .../marvell/octeon_ep/octep_ctrl_net.c        | 36 ++++++++++---------
 .../marvell/octeon_ep/octep_ctrl_net.h        | 24 ++++++++-----
 .../marvell/octeon_ep/octep_ethtool.c         |  9 +++--
 .../ethernet/marvell/octeon_ep/octep_main.c   |  5 ++-
 4 files changed, 44 insertions(+), 30 deletions(-)

diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c
index 80bcd6cd4732..faaaf326fedd 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c
@@ -19,7 +19,6 @@ static const u32 mtu_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_mtu);
 static const u32 mac_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_mac);
 static const u32 state_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_state);
 static const u32 link_info_sz = sizeof(struct octep_ctrl_net_link_info);
-static const u32 get_stats_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_get_stats);
 static atomic_t ctrl_net_msg_id;
 
 static void init_send_req(struct octep_ctrl_mbox_msg *msg, void *buf,
@@ -188,31 +187,34 @@ int octep_ctrl_net_set_mtu(struct octep_device *oct, int vfid, int mtu,
 	return send_mbox_req(oct, &d, wait_for_response);
 }
 
-int octep_ctrl_net_get_if_stats(struct octep_device *oct, int vfid)
+int octep_ctrl_net_get_if_stats(struct octep_device *oct, int vfid,
+				struct octep_iface_rx_stats *rx_stats,
+				struct octep_iface_tx_stats *tx_stats)
 {
-	void __iomem *iface_rx_stats;
-	void __iomem *iface_tx_stats;
 	struct octep_ctrl_net_wait_data d = {0};
 	struct octep_ctrl_net_h2f_req *req = &d.data.req;
+	struct octep_ctrl_net_h2f_resp *resp;
 	int err;
 
-	init_send_req(&d.msg, req, get_stats_sz, vfid);
+	init_send_req(&d.msg, req, 0, vfid);
 	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_GET_IF_STATS;
-	req->get_stats.offset = oct->ctrl_mbox_ifstats_offset;
 	err = send_mbox_req(oct, &d, true);
 	if (err < 0)
 		return err;
 
-	iface_rx_stats = oct->ctrl_mbox.barmem + oct->ctrl_mbox_ifstats_offset;
-	iface_tx_stats = oct->ctrl_mbox.barmem + oct->ctrl_mbox_ifstats_offset +
-			 sizeof(struct octep_iface_rx_stats);
-	memcpy_fromio(&oct->iface_rx_stats, iface_rx_stats, sizeof(struct octep_iface_rx_stats));
-	memcpy_fromio(&oct->iface_tx_stats, iface_tx_stats, sizeof(struct octep_iface_tx_stats));
+	resp = &d.data.resp;
+	memcpy(rx_stats,
+	       &resp->if_stats.rx_stats,
+	       sizeof(struct octep_iface_rx_stats));
+	memcpy(tx_stats,
+	       &resp->if_stats.tx_stats,
+	       sizeof(struct octep_iface_tx_stats));
 
 	return 0;
 }
 
-int octep_ctrl_net_get_link_info(struct octep_device *oct, int vfid)
+int octep_ctrl_net_get_link_info(struct octep_device *oct, int vfid,
+				 struct octep_iface_link_info *link_info)
 {
 	struct octep_ctrl_net_wait_data d = {0};
 	struct octep_ctrl_net_h2f_req *req = &d.data.req;
@@ -227,11 +229,11 @@ int octep_ctrl_net_get_link_info(struct octep_device *oct, int vfid)
 		return err;
 
 	resp = &d.data.resp;
-	oct->link_info.supported_modes = resp->link_info.supported_modes;
-	oct->link_info.advertised_modes = resp->link_info.advertised_modes;
-	oct->link_info.autoneg = resp->link_info.autoneg;
-	oct->link_info.pause = resp->link_info.pause;
-	oct->link_info.speed = resp->link_info.speed;
+	link_info->supported_modes = resp->link_info.supported_modes;
+	link_info->advertised_modes = resp->link_info.advertised_modes;
+	link_info->autoneg = resp->link_info.autoneg;
+	link_info->pause = resp->link_info.pause;
+	link_info->speed = resp->link_info.speed;
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.h b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.h
index c68cdaa1738b..f0ad6d6e2af5 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.h
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.h
@@ -77,12 +77,6 @@ struct octep_ctrl_net_h2f_req_cmd_mac {
 	u8 addr[ETH_ALEN];
 };
 
-/* get if_stats, xstats, q_stats request */
-struct octep_ctrl_net_h2f_req_cmd_get_stats {
-	/* offset into barmem where fw should copy over stats */
-	u32 offset;
-};
-
 /* get/set link state, rx state */
 struct octep_ctrl_net_h2f_req_cmd_state {
 	/* enum octep_ctrl_net_cmd */
@@ -119,7 +113,6 @@ struct octep_ctrl_net_h2f_req {
 	union {
 		struct octep_ctrl_net_h2f_req_cmd_mtu mtu;
 		struct octep_ctrl_net_h2f_req_cmd_mac mac;
-		struct octep_ctrl_net_h2f_req_cmd_get_stats get_stats;
 		struct octep_ctrl_net_h2f_req_cmd_state link;
 		struct octep_ctrl_net_h2f_req_cmd_state rx;
 		struct octep_ctrl_net_h2f_req_cmd_link_info link_info;
@@ -152,6 +145,12 @@ struct octep_ctrl_net_h2f_resp_cmd_mac {
 	u8 addr[ETH_ALEN];
 };
 
+/* get if_stats, xstats, q_stats request */
+struct octep_ctrl_net_h2f_resp_cmd_get_stats {
+	struct octep_iface_rx_stats rx_stats;
+	struct octep_iface_tx_stats tx_stats;
+};
+
 /* get link state, rx state response */
 struct octep_ctrl_net_h2f_resp_cmd_state {
 	/* enum octep_ctrl_net_state */
@@ -164,6 +163,7 @@ struct octep_ctrl_net_h2f_resp {
 	union {
 		struct octep_ctrl_net_h2f_resp_cmd_mtu mtu;
 		struct octep_ctrl_net_h2f_resp_cmd_mac mac;
+		struct octep_ctrl_net_h2f_resp_cmd_get_stats if_stats;
 		struct octep_ctrl_net_h2f_resp_cmd_state link;
 		struct octep_ctrl_net_h2f_resp_cmd_state rx;
 		struct octep_ctrl_net_link_info link_info;
@@ -286,19 +286,25 @@ int octep_ctrl_net_set_mtu(struct octep_device *oct, int vfid, int mtu,
  *
  * @param oct: non-null pointer to struct octep_device.
  * @param vfid: Index of virtual function.
+ * @param rx_stats: non-null pointer struct octep_iface_rx_stats.
+ * @param tx_stats: non-null pointer struct octep_iface_tx_stats.
  *
  * return value: 0 on success, -errno on failure.
  */
-int octep_ctrl_net_get_if_stats(struct octep_device *oct, int vfid);
+int octep_ctrl_net_get_if_stats(struct octep_device *oct, int vfid,
+				struct octep_iface_rx_stats *rx_stats,
+				struct octep_iface_tx_stats *tx_stats);
 
 /** Get link info from firmware.
  *
  * @param oct: non-null pointer to struct octep_device.
  * @param vfid: Index of virtual function.
+ * @param link_info: non-null pointer to struct octep_iface_link_info.
  *
  * return value: 0 on success, -errno on failure.
  */
-int octep_ctrl_net_get_link_info(struct octep_device *oct, int vfid);
+int octep_ctrl_net_get_link_info(struct octep_device *oct, int vfid,
+				 struct octep_iface_link_info *link_info);
 
 /** Set link info in firmware.
  *
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c b/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c
index 389042b57787..7d0124b283da 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c
@@ -150,9 +150,12 @@ octep_get_ethtool_stats(struct net_device *netdev,
 	rx_packets = 0;
 	rx_bytes = 0;
 
-	octep_ctrl_net_get_if_stats(oct, OCTEP_CTRL_NET_INVALID_VFID);
 	iface_tx_stats = &oct->iface_tx_stats;
 	iface_rx_stats = &oct->iface_rx_stats;
+	octep_ctrl_net_get_if_stats(oct,
+				    OCTEP_CTRL_NET_INVALID_VFID,
+				    iface_rx_stats,
+				    iface_tx_stats);
 
 	for (q = 0; q < oct->num_oqs; q++) {
 		struct octep_iq *iq = oct->iq[q];
@@ -283,11 +286,11 @@ static int octep_get_link_ksettings(struct net_device *netdev,
 	ethtool_link_ksettings_zero_link_mode(cmd, supported);
 	ethtool_link_ksettings_zero_link_mode(cmd, advertising);
 
-	octep_ctrl_net_get_link_info(oct, OCTEP_CTRL_NET_INVALID_VFID);
+	link_info = &oct->link_info;
+	octep_ctrl_net_get_link_info(oct, OCTEP_CTRL_NET_INVALID_VFID, link_info);
 
 	advertised_modes = oct->link_info.advertised_modes;
 	supported_modes = oct->link_info.supported_modes;
-	link_info = &oct->link_info;
 
 	OCTEP_SET_ETHTOOL_LINK_MODES_BITMAP(supported_modes, cmd, supported);
 	OCTEP_SET_ETHTOOL_LINK_MODES_BITMAP(advertised_modes, cmd, advertising);
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
index 32e2ca24849a..069c4d18cf37 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
@@ -764,7 +764,10 @@ static void octep_get_stats64(struct net_device *netdev,
 	int q;
 
 	if (netif_running(netdev))
-		octep_ctrl_net_get_if_stats(oct, OCTEP_CTRL_NET_INVALID_VFID);
+		octep_ctrl_net_get_if_stats(oct,
+					    OCTEP_CTRL_NET_INVALID_VFID,
+					    &oct->iface_rx_stats,
+					    &oct->iface_tx_stats);
 
 	tx_packets = 0;
 	tx_bytes = 0;
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v2 7/9] octeon_ep: add SRIOV VF creation
  2022-11-29 13:09 [PATCH net-next v2 0/9] octeon_ep: Update PF mailbox for VF Veerasenareddy Burru
                   ` (5 preceding siblings ...)
  2022-11-29 13:09 ` [PATCH net-next v2 6/9] octeon_ep: control mbox support for VF stats and link info Veerasenareddy Burru
@ 2022-11-29 13:09 ` Veerasenareddy Burru
  2022-11-29 13:09 ` [PATCH net-next v2 8/9] octeon_ep: add PF-VF mailbox communication Veerasenareddy Burru
  2022-11-29 13:09 ` [PATCH net-next v2 9/9] octeon_ep: add heartbeat monitor Veerasenareddy Burru
  8 siblings, 0 replies; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-11-29 13:09 UTC (permalink / raw)
  To: netdev, linux-kernel, lironh, aayarekar, sedara, sburla
  Cc: linux-doc, Veerasenareddy Burru, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni

Add support to create SRIOV VFs.

Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
Signed-off-by: Sathesh Edara <sedara@marvell.com>
---
v1 -> v2:
 * no change

 .../ethernet/marvell/octeon_ep/octep_main.c   | 50 +++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
index 069c4d18cf37..d43161d1e38a 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
@@ -1177,11 +1177,61 @@ static void octep_remove(struct pci_dev *pdev)
 	pci_disable_device(pdev);
 }
 
+static int octep_sriov_disable(struct octep_device *oct)
+{
+	struct pci_dev *pdev = oct->pdev;
+
+	if (pci_vfs_assigned(oct->pdev)) {
+		dev_warn(&pdev->dev, "Can't disable SRIOV while VFs are assigned\n");
+		return -EPERM;
+	}
+
+	pci_disable_sriov(pdev);
+	CFG_GET_ACTIVE_VFS(oct->conf) = 0;
+
+	return 0;
+}
+
+static int octep_sriov_enable(struct octep_device *oct, int num_vfs)
+{
+	struct pci_dev *pdev = oct->pdev;
+	int err;
+
+	err = pci_enable_sriov(pdev, num_vfs);
+	if (err) {
+		dev_warn(&pdev->dev, "Failed to enable SRIOV err=%d\n", err);
+		return err;
+	}
+	CFG_GET_ACTIVE_VFS(oct->conf) = num_vfs;
+
+	return num_vfs;
+}
+
+static int octep_sriov_configure(struct pci_dev *pdev, int num_vfs)
+{
+	struct octep_device *oct = pci_get_drvdata(pdev);
+	int max_nvfs;
+
+	if (num_vfs == 0)
+		return octep_sriov_disable(oct);
+
+	max_nvfs = CFG_GET_MAX_VFS(oct->conf);
+
+	if (num_vfs > max_nvfs) {
+		dev_err(&pdev->dev, "Invalid VF count Max supported VFs = %d\n",
+			max_nvfs);
+		return -EINVAL;
+	}
+
+	return octep_sriov_enable(oct, num_vfs);
+}
+
 static struct pci_driver octep_driver = {
 	.name = OCTEP_DRV_NAME,
 	.id_table = octep_pci_id_tbl,
 	.probe = octep_probe,
 	.remove = octep_remove,
+	.sriov_configure = octep_sriov_configure,
 };
 
 /**
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v2 8/9] octeon_ep: add PF-VF mailbox communication
  2022-11-29 13:09 [PATCH net-next v2 0/9] octeon_ep: Update PF mailbox for VF Veerasenareddy Burru
                   ` (6 preceding siblings ...)
  2022-11-29 13:09 ` [PATCH net-next v2 7/9] octeon_ep: add SRIOV VF creation Veerasenareddy Burru
@ 2022-11-29 13:09 ` Veerasenareddy Burru
  2022-12-09  8:48   ` Dan Carpenter
  2022-11-29 13:09 ` [PATCH net-next v2 9/9] octeon_ep: add heartbeat monitor Veerasenareddy Burru
  8 siblings, 1 reply; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-11-29 13:09 UTC (permalink / raw)
  To: netdev, linux-kernel, lironh, aayarekar, sedara, sburla
  Cc: linux-doc, Veerasenareddy Burru, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni

Implement mailbox communication between PF and VFs.
PF-VF mailbox is used for all control commands from VF to PF and
asynchronous notification messages from PF to VF.

Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
Signed-off-by: Sathesh Edara <sedara@marvell.com>
Signed-off-by: Abhijit Ayarekar <aayarekar@marvell.com>
---
v1 -> v2:
 * reworked the patch for changes made to preceding patches.
 * removed device status oct->status, as it is not required with the
   modified implementation.

 .../net/ethernet/marvell/octeon_ep/Makefile   |   3 +-
 .../marvell/octeon_ep/octep_cn9k_pf.c         |  42 ++-
 .../ethernet/marvell/octeon_ep/octep_main.c   |  15 +-
 .../ethernet/marvell/octeon_ep/octep_main.h   |  44 +--
 .../marvell/octeon_ep/octep_pfvf_mbox.c       | 305 ++++++++++++++++++
 .../marvell/octeon_ep/octep_pfvf_mbox.h       | 126 ++++++++
 .../marvell/octeon_ep/octep_regs_cn9k_pf.h    |   9 +
 .../net/ethernet/marvell/octeon_ep/octep_tx.h |  24 +-
 8 files changed, 523 insertions(+), 45 deletions(-)
 create mode 100644 drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.c
 create mode 100644 drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.h

diff --git a/drivers/net/ethernet/marvell/octeon_ep/Makefile b/drivers/net/ethernet/marvell/octeon_ep/Makefile
index 2026c8118158..6cfa7198fdbd 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/Makefile
+++ b/drivers/net/ethernet/marvell/octeon_ep/Makefile
@@ -6,4 +6,5 @@
 obj-$(CONFIG_OCTEON_EP) += octeon_ep.o
 
 octeon_ep-y := octep_main.o octep_cn9k_pf.o octep_tx.o octep_rx.o \
-	       octep_ethtool.o octep_ctrl_mbox.o octep_ctrl_net.o
+	       octep_ethtool.o octep_ctrl_mbox.o octep_ctrl_net.o \
+	       octep_pfvf_mbox.o
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
index e307bae62673..4840133477dc 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
@@ -354,26 +354,50 @@ static void octep_setup_mbox_regs_cn93_pf(struct octep_device *oct, int q_no)
 {
 	struct octep_mbox *mbox = oct->mbox[q_no];
 
-	mbox->q_no = q_no;
-
-	/* PF mbox interrupt reg */
-	mbox->mbox_int_reg = oct->mmio[0].hw_addr + CN93_SDP_EPF_MBOX_RINT(0);
-
 	/* PF to VF DATA reg. PF writes into this reg */
-	mbox->mbox_write_reg = oct->mmio[0].hw_addr + CN93_SDP_R_MBOX_PF_VF_DATA(q_no);
+	mbox->pf_vf_data_reg = oct->mmio[0].hw_addr + CN93_SDP_MBOX_PF_VF_DATA(q_no);
 
 	/* VF to PF DATA reg. PF reads from this reg */
-	mbox->mbox_read_reg = oct->mmio[0].hw_addr + CN93_SDP_R_MBOX_VF_PF_DATA(q_no);
+	mbox->vf_pf_data_reg = oct->mmio[0].hw_addr + CN93_SDP_MBOX_VF_PF_DATA(q_no);
 }
 
 /* Process non-ioq interrupts required to keep pf interface running.
  * OEI_RINT is needed for control mailbox
+ * MBOX_RINT is needed for pfvf mailbox
  */
 static int octep_poll_non_ioq_interrupts_cn93_pf(struct octep_device *oct)
 {
-	u64 reg0;
+	u32 vf, active_vfs, active_rings_per_vf, vf_mbox_queue;
+	u64 reg0, reg1;
 	int handled = 0;
 
+	reg0 = octep_read_csr64(oct, CN93_SDP_EPF_MBOX_RINT(0));
+	reg1 = octep_read_csr64(oct, CN93_SDP_EPF_MBOX_RINT(1));
+	if (reg0 || reg1) {
+		dev_info(&oct->pdev->dev,
+			 "Received MBOX_RINT intr: reg0 0x%llx reg1 0x%llx\n",
+			 reg0, reg1);
+
+		active_vfs = CFG_GET_ACTIVE_VFS(oct->conf);
+		active_rings_per_vf = CFG_GET_ACTIVE_RPVF(oct->conf);
+		for (vf = 0; vf < active_vfs; vf++) {
+			vf_mbox_queue = vf * active_rings_per_vf;
+			if (!(reg0 & (0x1UL << vf_mbox_queue)))
+				continue;
+
+			if (!oct->mbox[vf_mbox_queue]) {
+				dev_err(&oct->pdev->dev, "bad mbox vf %d\n", vf);
+				continue;
+			}
+			schedule_work(&oct->mbox[vf_mbox_queue]->wk.work);
+		}
+		if (reg0)
+			octep_write_csr64(oct, CN93_SDP_EPF_MBOX_RINT(0), reg0);
+		if (reg1)
+			octep_write_csr64(oct, CN93_SDP_EPF_MBOX_RINT(1), reg1);
+
+		handled = 1;
+	}
 	/* Check for OEI INTR */
 	reg0 = octep_read_csr64(oct, CN93_SDP_EPF_OEI_RINT);
 	if (reg0) {
@@ -562,6 +586,8 @@ static void octep_enable_interrupts_cn93_pf(struct octep_device *oct)
 	octep_write_csr64(oct, CN93_SDP_EPF_OEI_RINT_ENA_W1S, -1ULL);
 	octep_write_csr64(oct, CN93_SDP_EPF_MISC_RINT_ENA_W1S, intr_mask);
 	octep_write_csr64(oct, CN93_SDP_EPF_DMA_RINT_ENA_W1S, intr_mask);
+	octep_write_csr64(oct, CN93_SDP_EPF_MBOX_RINT_ENA_W1S(0), -1ULL);
+	octep_write_csr64(oct, CN93_SDP_EPF_MBOX_RINT_ENA_W1S(1), -1ULL);
 }
 
 /* Disable all interrupts */
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
index d43161d1e38a..cd0d77ceb868 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
@@ -17,6 +17,7 @@
 #include "octep_config.h"
 #include "octep_main.h"
 #include "octep_ctrl_net.h"
+#include "octep_pfvf_mbox.h"
 
 #define OCTEP_INTR_POLL_TIME_MSECS    100
 struct workqueue_struct *octep_wq;
@@ -1001,11 +1002,7 @@ static void octep_device_cleanup(struct octep_device *oct)
 
 	dev_info(&oct->pdev->dev, "Cleaning up Octeon Device ...\n");
 
-	for (i = 0; i < OCTEP_MAX_VF; i++) {
-		vfree(oct->mbox[i]);
-		oct->mbox[i] = NULL;
-	}
-
+	octep_delete_pfvf_mbox(oct);
 	octep_ctrl_net_uninit(oct);
 
 	oct->hw_ops.soft_reset(oct);
@@ -1100,6 +1097,14 @@ static int octep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		dev_err(&pdev->dev, "Device setup failed\n");
 		goto err_octep_config;
 	}
+
+	err = octep_setup_pfvf_mbox(octep_dev);
+	if (err) {
+		dev_err(&pdev->dev, " pfvf mailbox setup failed\n");
+		octep_ctrl_net_uninit(octep_dev);
+		return err;
+	}
+
 	INIT_WORK(&octep_dev->tx_timeout_task, octep_tx_timeout_task);
 	INIT_WORK(&octep_dev->ctrl_mbox_task, octep_ctrl_mbox_task);
 	INIT_DELAYED_WORK(&octep_dev->intr_poll_task, octep_intr_poll_task);
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.h b/drivers/net/ethernet/marvell/octeon_ep/octep_main.h
index 70cc3e236cb4..ad6d324bd525 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.h
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.h
@@ -94,28 +94,27 @@ struct octep_mbox_data {
 	u64 *data;
 };
 
+#define MAX_VF_PF_MBOX_DATA_SIZE 384
+/* wrappers around work structs */
+struct octep_pfvf_mbox_wk {
+	struct work_struct work;
+	void *ctxptr;
+	u64 ctxul;
+};
+
 /* Octeon device mailbox */
 struct octep_mbox {
-	/* A spinlock to protect access to this q_mbox. */
-	spinlock_t lock;
-
-	u32 q_no;
-	u32 state;
-
-	/* SLI_MAC_PF_MBOX_INT for PF, SLI_PKT_MBOX_INT for VF. */
-	u8 __iomem *mbox_int_reg;
-
-	/* SLI_PKT_PF_VF_MBOX_SIG(0) for PF,
-	 * SLI_PKT_PF_VF_MBOX_SIG(1) for VF.
-	 */
-	u8 __iomem *mbox_write_reg;
-
-	/* SLI_PKT_PF_VF_MBOX_SIG(1) for PF,
-	 * SLI_PKT_PF_VF_MBOX_SIG(0) for VF.
-	 */
-	u8 __iomem *mbox_read_reg;
-
+	/* A mutex to protect access to this q_mbox. */
+	struct mutex lock;
+	u32 vf_id;
+	u32 config_data_index;
+	u32 message_len;
+	u8 __iomem *pf_vf_data_reg;
+	u8 __iomem *vf_pf_data_reg;
+	struct octep_pfvf_mbox_wk wk;
+	struct octep_device *oct;
 	struct octep_mbox_data mbox_data;
+	u8 config_data[MAX_VF_PF_MBOX_DATA_SIZE];
 };
 
 /* Tx/Rx queue vector per interrupt. */
@@ -193,6 +192,11 @@ struct octep_iface_link_info {
 	u8  oper_up;
 };
 
+/* The Octeon VF device specific info data structure.*/
+struct octep_pfvf_info {
+	u8 mac_addr[ETH_ALEN];
+};
+
 /* The Octeon device specific private data structure.
  * Each Octeon device has this structure to represent all its components.
  */
@@ -259,6 +263,8 @@ struct octep_device {
 
 	/* Mailbox to talk to VFs */
 	struct octep_mbox *mbox[OCTEP_MAX_VF];
+	/* VFs info */
+	struct octep_pfvf_info vf_info[OCTEP_MAX_VF];
 
 	/* Work entry to handle Tx timeout */
 	struct work_struct tx_timeout_task;
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.c b/drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.c
new file mode 100644
index 000000000000..01ead735a2e8
--- /dev/null
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.c
@@ -0,0 +1,305 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Marvell Octeon EP (EndPoint) Ethernet Driver
+ *
+ * Copyright (C) 2020 Marvell.
+ *
+ */
+#include <linux/types.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mutex.h>
+#include <linux/jiffies.h>
+#include <linux/sched.h>
+#include <linux/sched/signal.h>
+#include <linux/io.h>
+#include <linux/pci.h>
+#include <linux/etherdevice.h>
+
+#include "octep_config.h"
+#include "octep_main.h"
+#include "octep_pfvf_mbox.h"
+#include "octep_ctrl_net.h"
+
+static void octep_pfvf_validate_version(struct octep_device *oct,  u32 vf_id,
+					union octep_pfvf_mbox_word cmd,
+					union octep_pfvf_mbox_word *rsp)
+{
+	u32 vf_version = (u32)cmd.s_version.version;
+
+	if (vf_version <= OCTEP_PF_MBOX_VERSION)
+		rsp->s_version.type = OCTEP_PFVF_MBOX_TYPE_RSP_ACK;
+	else
+		rsp->s_version.type = OCTEP_PFVF_MBOX_TYPE_RSP_NACK;
+}
+
+static void octep_pfvf_get_link_status(struct octep_device *oct, u32 vf_id,
+				       union octep_pfvf_mbox_word cmd,
+				       union octep_pfvf_mbox_word *rsp)
+{
+	int status;
+
+	status = octep_ctrl_net_get_link_status(oct, vf_id);
+	if (status < 0) {
+		rsp->s_link_status.type = OCTEP_PFVF_MBOX_TYPE_RSP_NACK;
+		dev_err(&oct->pdev->dev, "Get VF link status failed via host control Mbox\n");
+		return;
+	}
+	rsp->s_link_status.type = OCTEP_PFVF_MBOX_TYPE_RSP_ACK;
+	rsp->s_link_status.status = status;
+}
+
+static void octep_pfvf_set_link_status(struct octep_device *oct, u32 vf_id,
+				       union octep_pfvf_mbox_word cmd,
+				       union octep_pfvf_mbox_word *rsp)
+{
+	int err;
+
+	err = octep_ctrl_net_set_link_status(oct, vf_id, cmd.s_link_status.status, true);
+	if (err) {
+		rsp->s_link_status.type = OCTEP_PFVF_MBOX_TYPE_RSP_NACK;
+		dev_err(&oct->pdev->dev, "Set VF link status failed via host control Mbox\n");
+		return;
+	}
+	rsp->s_link_status.type = OCTEP_PFVF_MBOX_TYPE_RSP_ACK;
+}
+
+static void octep_pfvf_set_rx_state(struct octep_device *oct, u32 vf_id,
+				    union octep_pfvf_mbox_word cmd,
+				    union octep_pfvf_mbox_word *rsp)
+{
+	int err;
+
+	err = octep_ctrl_net_set_rx_state(oct, vf_id, cmd.s_link_state.state, true);
+	if (err) {
+		rsp->s_link_state.type = OCTEP_PFVF_MBOX_TYPE_RSP_NACK;
+		dev_err(&oct->pdev->dev, "Set VF Rx link state failed via host control Mbox\n");
+		return;
+	}
+	rsp->s_link_state.type = OCTEP_PFVF_MBOX_TYPE_RSP_ACK;
+}
+
+static void octep_pfvf_set_mtu(struct octep_device *oct, u32 vf_id,
+			       union octep_pfvf_mbox_word cmd,
+			       union octep_pfvf_mbox_word *rsp)
+{
+	int err;
+
+	err = octep_ctrl_net_set_mtu(oct, vf_id, cmd.s_set_mtu.mtu, true);
+	if (err) {
+		rsp->s_set_mtu.type = OCTEP_PFVF_MBOX_TYPE_RSP_NACK;
+		dev_err(&oct->pdev->dev, "Set VF MTU failed via host control Mbox\n");
+		return;
+	}
+	rsp->s_set_mtu.type = OCTEP_PFVF_MBOX_TYPE_RSP_ACK;
+}
+
+static void octep_pfvf_set_mac_addr(struct octep_device *oct,  u32 vf_id,
+				    union octep_pfvf_mbox_word cmd,
+				    union octep_pfvf_mbox_word *rsp)
+{
+	int err;
+
+	err = octep_ctrl_net_set_mac_addr(oct, vf_id, cmd.s_set_mac.mac_addr, true);
+	if (err) {
+		rsp->s_set_mac.type = OCTEP_PFVF_MBOX_TYPE_RSP_NACK;
+		dev_err(&oct->pdev->dev, "Set VF MAC address failed via host control Mbox\n");
+		return;
+	}
+	rsp->s_set_mac.type = OCTEP_PFVF_MBOX_TYPE_RSP_ACK;
+}
+
+static void octep_pfvf_get_mac_addr(struct octep_device *oct,  u32 vf_id,
+				    union octep_pfvf_mbox_word cmd,
+				    union octep_pfvf_mbox_word *rsp)
+{
+	int err;
+
+	err = octep_ctrl_net_get_mac_addr(oct, vf_id, rsp->s_set_mac.mac_addr);
+	if (err) {
+		rsp->s_set_mac.type = OCTEP_PFVF_MBOX_TYPE_RSP_NACK;
+		dev_err(&oct->pdev->dev, "Get VF MAC address failed via host control Mbox\n");
+		return;
+	}
+	rsp->s_set_mac.type = OCTEP_PFVF_MBOX_TYPE_RSP_ACK;
+}
+
+int octep_setup_pfvf_mbox(struct octep_device *oct)
+{
+	int i = 0, num_vfs = 0, rings_per_vf = 0;
+	int ring = 0;
+
+	num_vfs = oct->conf->sriov_cfg.active_vfs;
+	rings_per_vf = oct->conf->sriov_cfg.max_rings_per_vf;
+
+	for (i = 0; i < num_vfs; i++) {
+		ring  = rings_per_vf * i;
+		oct->mbox[ring] = vzalloc(sizeof(*oct->mbox[ring]));
+
+		if (!oct->mbox[ring])
+			goto free_mbox;
+
+		memset(oct->mbox[ring], 0, sizeof(struct octep_mbox));
+		mutex_init(&oct->mbox[ring]->lock);
+		INIT_WORK(&oct->mbox[ring]->wk.work, octep_pfvf_mbox_work);
+		oct->mbox[ring]->wk.ctxptr = oct->mbox[i];
+
+		if (!oct->mbox[i])
+			oct->mbox[ring]->wk.ctxptr = oct->mbox[ring];
+
+		oct->mbox[ring]->oct = oct;
+		oct->mbox[ring]->vf_id = i;
+		oct->hw_ops.setup_mbox_regs(oct, ring);
+	}
+	return 0;
+
+free_mbox:
+	while (i) {
+		i--;
+		ring  = rings_per_vf * i;
+		cancel_work_sync(&oct->mbox[ring]->wk.work);
+		mutex_destroy(&oct->mbox[ring]->lock);
+		vfree(oct->mbox[ring]);
+		oct->mbox[ring] = NULL;
+	}
+	return 1;
+}
+
+void octep_delete_pfvf_mbox(struct octep_device *oct)
+{
+	int rings_per_vf = oct->conf->sriov_cfg.max_rings_per_vf;
+	int num_vfs = oct->conf->sriov_cfg.active_vfs;
+	int i = 0, ring = 0, vf_srn = 0;
+
+	for (i = 0; i < num_vfs; i++) {
+		ring  = vf_srn + rings_per_vf * i;
+		if (!oct->mbox[ring])
+			continue;
+
+		if (work_pending(&oct->mbox[ring]->wk.work))
+			cancel_work_sync(&oct->mbox[ring]->wk.work);
+		vfree(oct->mbox[ring]);
+		oct->mbox[ring] = NULL;
+	}
+}
+
+static void octep_pfvf_pf_get_data(struct octep_device *oct,
+				   struct octep_mbox *mbox, int vf_id,
+				   union octep_pfvf_mbox_word cmd,
+				   union octep_pfvf_mbox_word *rsp)
+{
+	int length = 0;
+	int i = 0;
+	int err;
+	struct octep_iface_link_info link_info;
+	struct octep_iface_rx_stats rx_stats;
+	struct octep_iface_tx_stats tx_stats;
+
+	rsp->s_data.type = OCTEP_PFVF_MBOX_TYPE_RSP_ACK;
+
+	if (cmd.s_data.frag != OCTEP_PFVF_MBOX_MORE_FRAG_FLAG) {
+		mbox->config_data_index = 0;
+		memset(mbox->config_data, 0, MAX_VF_PF_MBOX_DATA_SIZE);
+		/* Based on the OPCODE CMD the PF driver
+		 * specific API should be called to fetch
+		 * the requested data
+		 */
+		switch (cmd.s.opcode) {
+		case OCTEP_PFVF_MBOX_CMD_GET_LINK_INFO:
+			memset(&link_info, 0, sizeof(link_info));
+			err = octep_ctrl_net_get_link_info(oct, vf_id, &link_info);
+			if (!err) {
+				mbox->message_len = sizeof(link_info);
+				*((int32_t *)rsp->s_data.data) = mbox->message_len;
+				memcpy(mbox->config_data, (u8 *)&link_info, sizeof(link_info));
+			} else {
+				rsp->s_data.type = OCTEP_PFVF_MBOX_TYPE_RSP_NACK;
+				return;
+			}
+			break;
+		case OCTEP_PFVF_MBOX_CMD_GET_STATS:
+			memset(&rx_stats, 0, sizeof(rx_stats));
+			memset(&tx_stats, 0, sizeof(tx_stats));
+			err = octep_ctrl_net_get_if_stats(oct, vf_id, &rx_stats, &tx_stats);
+			if (!err) {
+				mbox->message_len = sizeof(rx_stats) + sizeof(tx_stats);
+				*((int32_t *)rsp->s_data.data) = mbox->message_len;
+				memcpy(mbox->config_data, (u8 *)&rx_stats, sizeof(rx_stats));
+				memcpy(mbox->config_data + sizeof(rx_stats), (u8 *)&tx_stats,
+				       sizeof(tx_stats));
+
+			} else {
+				rsp->s_data.type = OCTEP_PFVF_MBOX_TYPE_RSP_NACK;
+				return;
+			}
+			break;
+		}
+		*((int32_t *)rsp->s_data.data) = mbox->message_len;
+		return;
+	}
+
+	if (mbox->message_len > OCTEP_PFVF_MBOX_MAX_DATA_SIZE)
+		length = OCTEP_PFVF_MBOX_MAX_DATA_SIZE;
+	else
+		length = mbox->message_len;
+
+	mbox->message_len -= length;
+
+	for (i = 0; i < length; i++) {
+		rsp->s_data.data[i] =
+			mbox->config_data[mbox->config_data_index];
+		mbox->config_data_index++;
+	}
+}
+
+void octep_pfvf_mbox_work(struct work_struct *work)
+{
+	struct octep_pfvf_mbox_wk *wk = container_of(work, struct octep_pfvf_mbox_wk, work);
+	union octep_pfvf_mbox_word cmd = { 0 };
+	union octep_pfvf_mbox_word rsp = { 0 };
+	struct octep_mbox *mbox = NULL;
+	struct octep_device *oct = NULL;
+	int vf_id;
+
+	mbox = (struct octep_mbox *)wk->ctxptr;
+	oct = (struct octep_device *)mbox->oct;
+	vf_id = mbox->vf_id;
+
+	mutex_lock(&mbox->lock);
+	cmd.u64 = readq(mbox->vf_pf_data_reg);
+	rsp.u64 = 0;
+
+	switch (cmd.s.opcode) {
+	case OCTEP_PFVF_MBOX_CMD_VERSION:
+		octep_pfvf_validate_version(oct, vf_id, cmd, &rsp);
+		break;
+	case OCTEP_PFVF_MBOX_CMD_GET_LINK_STATUS:
+		octep_pfvf_get_link_status(oct, vf_id, cmd, &rsp);
+		break;
+	case OCTEP_PFVF_MBOX_CMD_SET_LINK_STATUS:
+		octep_pfvf_set_link_status(oct, vf_id, cmd, &rsp);
+		break;
+	case OCTEP_PFVF_MBOX_CMD_SET_RX_STATE:
+		octep_pfvf_set_rx_state(oct, vf_id, cmd, &rsp);
+		break;
+	case OCTEP_PFVF_MBOX_CMD_SET_MTU:
+		octep_pfvf_set_mtu(oct, vf_id, cmd, &rsp);
+		break;
+	case OCTEP_PFVF_MBOX_CMD_SET_MAC_ADDR:
+		octep_pfvf_set_mac_addr(oct, vf_id, cmd, &rsp);
+		break;
+	case OCTEP_PFVF_MBOX_CMD_GET_MAC_ADDR:
+		octep_pfvf_get_mac_addr(oct, vf_id, cmd, &rsp);
+		break;
+	case OCTEP_PFVF_MBOX_CMD_GET_LINK_INFO:
+	case OCTEP_PFVF_MBOX_CMD_GET_STATS:
+		octep_pfvf_pf_get_data(oct, mbox, vf_id, cmd, &rsp);
+		break;
+	default:
+		dev_err(&oct->pdev->dev, "PF-VF mailbox: invalid opcode %d\n", cmd.s.opcode);
+		rsp.s.type = OCTEP_PFVF_MBOX_TYPE_RSP_NACK;
+		break;
+	}
+	writeq(rsp.u64, mbox->vf_pf_data_reg);
+	mutex_unlock(&mbox->lock);
+}
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.h b/drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.h
new file mode 100644
index 000000000000..d113f1310655
--- /dev/null
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.h
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Marvell Octeon EP (EndPoint) Ethernet Driver
+ *
+ * Copyright (C) 2020 Marvell.
+ *
+ */
+#ifndef _OCTEP_PFVF_MBOX_H_
+#define _OCTEP_PFVF_MBOX_H_
+
+#define OCTEP_PF_MBOX_VERSION 1
+
+enum octep_pfvf_mbox_opcode {
+	OCTEP_PFVF_MBOX_CMD_VERSION,
+	OCTEP_PFVF_MBOX_CMD_SET_MTU,
+	OCTEP_PFVF_MBOX_CMD_SET_MAC_ADDR,
+	OCTEP_PFVF_MBOX_CMD_GET_MAC_ADDR,
+	OCTEP_PFVF_MBOX_CMD_GET_LINK_INFO,
+	OCTEP_PFVF_MBOX_CMD_GET_STATS,
+	OCTEP_PFVF_MBOX_CMD_SET_RX_STATE,
+	OCTEP_PFVF_MBOX_CMD_SET_LINK_STATUS,
+	OCTEP_PFVF_MBOX_CMD_GET_LINK_STATUS,
+	OCTEP_PFVF_MBOX_CMD_LAST,
+};
+
+enum octep_pfvf_mbox_word_type {
+	OCTEP_PFVF_MBOX_TYPE_CMD,
+	OCTEP_PFVF_MBOX_TYPE_RSP_ACK,
+	OCTEP_PFVF_MBOX_TYPE_RSP_NACK,
+};
+
+enum octep_pfvf_mbox_cmd_status {
+	OCTEP_PFVF_MBOX_CMD_STATUS_NOT_SETUP = 1,
+	OCTEP_PFVF_MBOX_CMD_STATUS_TIMEDOUT = 2,
+	OCTEP_PFVF_MBOX_CMD_STATUS_NACK = 3,
+	OCTEP_PFVF_MBOX_CMD_STATUS_BUSY = 4
+};
+
+enum octep_pfvf_mbox_state {
+	OCTEP_PFVF_MBOX_STATE_IDLE = 0,
+	OCTEP_PFVF_MBOX_STATE_BUSY = 1,
+};
+
+enum octep_pfvf_link_status {
+	OCTEP_PFVF_LINK_STATUS_DOWN,
+	OCTEP_PFVF_LINK_STATUS_UP,
+};
+
+enum octep_pfvf_link_speed {
+	OCTEP_PFVF_LINK_SPEED_NONE,
+	OCTEP_PFVF_LINK_SPEED_1000,
+	OCTEP_PFVF_LINK_SPEED_10000,
+	OCTEP_PFVF_LINK_SPEED_25000,
+	OCTEP_PFVF_LINK_SPEED_40000,
+	OCTEP_PFVF_LINK_SPEED_50000,
+	OCTEP_PFVF_LINK_SPEED_100000,
+	OCTEP_PFVF_LINK_SPEED_LAST,
+};
+
+enum octep_pfvf_link_duplex {
+	OCTEP_PFVF_LINK_HALF_DUPLEX,
+	OCTEP_PFVF_LINK_FULL_DUPLEX,
+};
+
+enum octep_pfvf_link_autoneg {
+	OCTEP_PFVF_LINK_AUTONEG,
+	OCTEP_PFVF_LINK_FIXED,
+};
+
+#define OCTEP_PFVF_MBOX_TIMEOUT_MS     500
+#define OCTEP_PFVF_MBOX_MAX_RETRIES    2
+#define OCTEP_PFVF_MBOX_VERSION        0
+#define OCTEP_PFVF_MBOX_MAX_DATA_SIZE  6
+#define OCTEP_PFVF_MBOX_MORE_FRAG_FLAG 1
+#define OCTEP_PFVF_MBOX_WRITE_WAIT_TIME msecs_to_jiffies(1)
+
+union octep_pfvf_mbox_word {
+	u64 u64;
+	struct {
+		u64 opcode:8;
+		u64 type:2;
+		u64 rsvd:6;
+		u64 data:48;
+	} s;
+	struct {
+		u64 opcode:8;
+		u64 type:2;
+		u64 frag:1;
+		u64 rsvd:5;
+		u8 data[6];
+	} s_data;
+	struct {
+		u64 opcode:8;
+		u64 type:2;
+		u64 rsvd:6;
+		u64 version:48;
+	} s_version;
+	struct {
+		u64 opcode:8;
+		u64 type:2;
+		u64 rsvd:6;
+		u8 mac_addr[6];
+	} s_set_mac;
+	struct {
+		u64 opcode:8;
+		u64 type:2;
+		u64 rsvd:6;
+		u64 mtu:48;
+	} s_set_mtu;
+	struct {
+		u64 opcode:8;
+		u64 type:2;
+		u64 state:1;
+		u64 rsvd:53;
+	} s_link_state;
+	struct {
+		u64 opcode:8;
+		u64 type:2;
+		u64 status:1;
+		u64 rsvd:53;
+	} s_link_status;
+} __packed;
+
+void octep_pfvf_mbox_work(struct work_struct *work);
+int octep_setup_pfvf_mbox(struct octep_device *oct);
+void octep_delete_pfvf_mbox(struct octep_device *oct);
+#endif
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_regs_cn9k_pf.h b/drivers/net/ethernet/marvell/octeon_ep/octep_regs_cn9k_pf.h
index 0466fd9a002d..f29c4344fc41 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_regs_cn9k_pf.h
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_regs_cn9k_pf.h
@@ -208,6 +208,9 @@
 #define    CN93_SDP_R_MBOX_PF_VF_INT_START        0x10220
 #define    CN93_SDP_R_MBOX_VF_PF_DATA_START       0x10230
 
+#define    CN93_SDP_MBOX_VF_PF_DATA_START       0x24000
+#define    CN93_SDP_MBOX_PF_VF_DATA_START       0x22000
+
 #define    CN93_SDP_R_MBOX_PF_VF_DATA(ring)		\
 	(CN93_SDP_R_MBOX_PF_VF_DATA_START + ((ring) * CN93_RING_OFFSET))
 
@@ -217,6 +220,12 @@
 #define    CN93_SDP_R_MBOX_VF_PF_DATA(ring)		\
 	(CN93_SDP_R_MBOX_VF_PF_DATA_START + ((ring) * CN93_RING_OFFSET))
 
+#define    CN93_SDP_MBOX_VF_PF_DATA(ring)          \
+	(CN93_SDP_MBOX_VF_PF_DATA_START + ((ring) * CN93_EPVF_RING_OFFSET))
+
+#define    CN93_SDP_MBOX_PF_VF_DATA(ring)      \
+	(CN93_SDP_MBOX_PF_VF_DATA_START + ((ring) * CN93_EPVF_RING_OFFSET))
+
 /* ##################### Interrupt Registers ########################## */
 #define	   CN93_SDP_R_ERR_TYPE_START	          0x10400
 
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_tx.h b/drivers/net/ethernet/marvell/octeon_ep/octep_tx.h
index 2ef57980eb47..05788bf2cf08 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_tx.h
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_tx.h
@@ -45,6 +45,18 @@ struct octep_tx_buffer {
 
 /* Hardware interface Tx statistics */
 struct octep_iface_tx_stats {
+	/* Total frames sent on the interface */
+	u64 pkts;
+
+	/* Total octets sent on the interface */
+	u64 octs;
+
+	/* Packets sent to a broadcast DMAC */
+	u64 bcst;
+
+	/* Packets sent to the multicast DMAC */
+	u64 mcst;
+
 	/* Packets dropped due to excessive collisions */
 	u64 xscol;
 
@@ -61,12 +73,6 @@ struct octep_iface_tx_stats {
 	 */
 	u64 scol;
 
-	/* Total octets sent on the interface */
-	u64 octs;
-
-	/* Total frames sent on the interface */
-	u64 pkts;
-
 	/* Packets sent with an octet count < 64 */
 	u64 hist_lt64;
 
@@ -91,12 +97,6 @@ struct octep_iface_tx_stats {
 	/* Packets sent with an octet count of > 1518 */
 	u64 hist_gt1518;
 
-	/* Packets sent to a broadcast DMAC */
-	u64 bcst;
-
-	/* Packets sent to the multicast DMAC */
-	u64 mcst;
-
 	/* Packets sent that experienced a transmit underflow and were
 	 * truncated
 	 */
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v2 9/9] octeon_ep: add heartbeat monitor
  2022-11-29 13:09 [PATCH net-next v2 0/9] octeon_ep: Update PF mailbox for VF Veerasenareddy Burru
                   ` (7 preceding siblings ...)
  2022-11-29 13:09 ` [PATCH net-next v2 8/9] octeon_ep: add PF-VF mailbox communication Veerasenareddy Burru
@ 2022-11-29 13:09 ` Veerasenareddy Burru
  8 siblings, 0 replies; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-11-29 13:09 UTC (permalink / raw)
  To: netdev, linux-kernel, lironh, aayarekar, sedara, sburla
  Cc: linux-doc, Veerasenareddy Burru, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni

Monitor periodic heartbeat messages from device firmware.
Presence of heartbeat indicates the device is active and running.
If the heartbeat is missed for configured interval indicates
firmware has crashed and device is unusable; in this case, PF driver
stops and uninitialize the device.

Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
Signed-off-by: Abhijit Ayarekar <aayarekar@marvell.com>
---
v1 -> v2:
 * reworked the patch for changes made to preceding patches.
 * removed device status oct->status, as it is not required with the
   modified implementation.

 .../marvell/octeon_ep/octep_cn9k_pf.c         |  9 +++++
 .../ethernet/marvell/octeon_ep/octep_config.h |  6 +++
 .../ethernet/marvell/octeon_ep/octep_main.c   | 37 +++++++++++++++++++
 .../ethernet/marvell/octeon_ep/octep_main.h   |  7 ++++
 .../marvell/octeon_ep/octep_regs_cn9k_pf.h    |  2 +
 5 files changed, 61 insertions(+)

diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
index 4840133477dc..9c6b2a95bc18 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
@@ -16,6 +16,9 @@
 #define CTRL_MBOX_MAX_PF	128
 #define CTRL_MBOX_SZ		((size_t)(0x400000 / CTRL_MBOX_MAX_PF))
 
+#define FW_HB_INTERVAL_IN_SECS		1
+#define FW_HB_MISS_COUNT		10
+
 /* Names of Hardware non-queue generic interrupts */
 static char *cn93_non_ioq_msix_names[] = {
 	"epf_ire_rint",
@@ -249,6 +252,10 @@ static void octep_init_config_cn93_pf(struct octep_device *oct)
 	conf->ctrl_mbox_cfg.barmem_addr = (void __iomem *)oct->mmio[2].hw_addr +
 					   (0x400000ull * 8) +
 					   (link * CTRL_MBOX_SZ);
+
+	conf->hb_interval = FW_HB_INTERVAL_IN_SECS;
+	conf->max_hb_miss_cnt = FW_HB_MISS_COUNT;
+
 }
 
 /* Setup registers for a hardware Tx Queue  */
@@ -407,6 +414,8 @@ static int octep_poll_non_ioq_interrupts_cn93_pf(struct octep_device *oct)
 		octep_write_csr64(oct, CN93_SDP_EPF_OEI_RINT, reg0);
 		if (reg0 & CN93_SDP_EPF_OEI_RINT_DATA_BIT_MBOX)
 			queue_work(octep_wq, &oct->ctrl_mbox_task);
+		else if (reg0 & CN93_SDP_EPF_OEI_RINT_DATA_BIT_HBEAT)
+			atomic_set(&oct->hb_miss_cnt, 0);
 
 		handled = 1;
 	}
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_config.h b/drivers/net/ethernet/marvell/octeon_ep/octep_config.h
index f208f3f9a447..df7cd39d9fce 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_config.h
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_config.h
@@ -200,5 +200,11 @@ struct octep_config {
 
 	/* ctrl mbox config */
 	struct octep_ctrl_mbox_config ctrl_mbox_cfg;
+
+	/* Configured maximum heartbeat miss count */
+	u32 max_hb_miss_cnt;
+
+	/* Configured firmware heartbeat interval in secs */
+	u32 hb_interval;
 };
 #endif /* _OCTEP_CONFIG_H_ */
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
index cd0d77ceb868..751a3a9c576f 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
@@ -903,6 +903,38 @@ static void octep_intr_poll_task(struct work_struct *work)
 			   msecs_to_jiffies(OCTEP_INTR_POLL_TIME_MSECS));
 }
 
+/**
+ * octep_hb_timeout_task - work queue task to check firmware heartbeat.
+ *
+ * @work: pointer to hb work_struct
+ *
+ * Check for heartbeat miss count. Uninitialize oct device if miss count
+ * exceeds configured max heartbeat miss count.
+ *
+ **/
+static void octep_hb_timeout_task(struct work_struct *work)
+{
+	struct octep_device *oct = container_of(work, struct octep_device,
+						hb_task.work);
+
+	int miss_cnt;
+
+	atomic_inc(&oct->hb_miss_cnt);
+	miss_cnt = atomic_read(&oct->hb_miss_cnt);
+	if (miss_cnt < oct->conf->max_hb_miss_cnt) {
+		queue_delayed_work(octep_wq, &oct->hb_task,
+				   msecs_to_jiffies(oct->conf->hb_interval * 1000));
+		return;
+	}
+
+	dev_err(&oct->pdev->dev, "Missed %u heartbeats. Uninitializing\n",
+		miss_cnt);
+	rtnl_lock();
+	if (netif_running(oct->netdev))
+		octep_stop(oct->netdev);
+	rtnl_unlock();
+}
+
 /**
  * octep_ctrl_mbox_task - work queue task to handle ctrl mbox messages.
  *
@@ -979,6 +1011,10 @@ int octep_device_setup(struct octep_device *oct)
 	if (ret)
 		return ret;
 
+	atomic_set(&oct->hb_miss_cnt, 0);
+	INIT_DELAYED_WORK(&oct->hb_task, octep_hb_timeout_task);
+	queue_delayed_work(octep_wq, &oct->hb_task,
+			   msecs_to_jiffies(oct->conf->hb_interval * 1000));
 	return 0;
 
 unsupported_dev:
@@ -1004,6 +1040,7 @@ static void octep_device_cleanup(struct octep_device *oct)
 
 	octep_delete_pfvf_mbox(oct);
 	octep_ctrl_net_uninit(oct);
+	cancel_delayed_work_sync(&oct->hb_task);
 
 	oct->hw_ops.soft_reset(oct);
 	for (i = 0; i < OCTEP_MMIO_REGIONS; i++) {
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.h b/drivers/net/ethernet/marvell/octeon_ep/octep_main.h
index ad6d324bd525..beedf8dc841d 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.h
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.h
@@ -286,6 +286,13 @@ struct octep_device {
 	bool poll_non_ioq_intr;
 	/* Work entry to poll non-ioq interrupts */
 	struct delayed_work intr_poll_task;
+
+	/* Firmware heartbeat timer */
+	struct timer_list hb_timer;
+	/* Firmware heartbeat miss count tracked by timer */
+	atomic_t hb_miss_cnt;
+	/* Task to reset device on heartbeat miss */
+	struct delayed_work hb_task;
 };
 
 static inline u16 OCTEP_MAJOR_REV(struct octep_device *oct)
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_regs_cn9k_pf.h b/drivers/net/ethernet/marvell/octeon_ep/octep_regs_cn9k_pf.h
index f29c4344fc41..48051e23ef18 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_regs_cn9k_pf.h
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_regs_cn9k_pf.h
@@ -376,5 +376,7 @@
 
 /* bit 0 for control mbox interrupt */
 #define CN93_SDP_EPF_OEI_RINT_DATA_BIT_MBOX	BIT_ULL(0)
+/* bit 1 for firmware heartbeat interrupt */
+#define CN93_SDP_EPF_OEI_RINT_DATA_BIT_HBEAT	BIT_ULL(1)
 
 #endif /* _OCTEP_REGS_CN9K_PF_H_ */
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next v2 1/9] octeon_ep: defer probe if firmware not ready
  2022-11-29 13:09 ` [PATCH net-next v2 1/9] octeon_ep: defer probe if firmware not ready Veerasenareddy Burru
@ 2022-11-30  9:24   ` Leon Romanovsky
  2022-11-30 15:50     ` [EXT] " Veerasenareddy Burru
  0 siblings, 1 reply; 28+ messages in thread
From: Leon Romanovsky @ 2022-11-30  9:24 UTC (permalink / raw)
  To: Veerasenareddy Burru
  Cc: netdev, linux-kernel, lironh, aayarekar, sedara, sburla,
	linux-doc, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni

On Tue, Nov 29, 2022 at 05:09:24AM -0800, Veerasenareddy Burru wrote:
> Defer probe if firmware is not ready for device usage.
> 
> Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
> Signed-off-by: Abhijit Ayarekar <aayarekar@marvell.com>
> Signed-off-by: Satananda Burla <sburla@marvell.com>
> ---
> v1 -> v2:
>  * was scheduling workqueue task to wait for firmware ready,
>    to probe/initialize the device.
>  * now, removed the workqueue task; the probe returns EPROBE_DEFER,
>    if firmware is not ready.
>  * removed device status oct->status, as it is not required with the
>    modified implementation.
> 
>  .../ethernet/marvell/octeon_ep/octep_main.c   | 26 +++++++++++++++++++
>  1 file changed, 26 insertions(+)
> 
> diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
> index 5a898fb88e37..aa7d0ced9807 100644
> --- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
> +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
> @@ -1017,6 +1017,25 @@ static void octep_device_cleanup(struct octep_device *oct)
>  	oct->conf = NULL;
>  }
>  
> +static u8 get_fw_ready_status(struct pci_dev *pdev)

Please change this function to return bool, you are not interested in
status.

> +{
> +	u32 pos = 0;
> +	u16 vsec_id;
> +	u8 status;
> +
> +	while ((pos = pci_find_next_ext_capability(pdev, pos,
> +						   PCI_EXT_CAP_ID_VNDR))) {
> +		pci_read_config_word(pdev, pos + 4, &vsec_id);
> +#define FW_STATUS_VSEC_ID  0xA3
> +		if (vsec_id == FW_STATUS_VSEC_ID) {

Success oriented flow, plase
if (vsec_id != FW_STATUS_VSEC_ID)
 cotitnue;

....

> +			pci_read_config_byte(pdev, (pos + 8), &status);
> +			dev_info(&pdev->dev, "Firmware ready %u\n", status);
> +			return status;
> +		}
> +	}
> +	return 0;
> +}
> +
>  /**
>   * octep_probe() - Octeon PCI device probe handler.
>   *
> @@ -1053,6 +1072,13 @@ static int octep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>  	pci_enable_pcie_error_reporting(pdev);
>  	pci_set_master(pdev);
>  
> +#define FW_STATUS_READY    1
> +	if (get_fw_ready_status(pdev) != FW_STATUS_READY) {

No need to this new define if you change get_fw_ready_status() to return
true/false.

And I think that you can put this check earlier in octep_probe().

Thanks

> +		dev_notice(&pdev->dev, "Firmware not ready; defer probe.\n");
> +		err = -EPROBE_DEFER;
> +		goto err_alloc_netdev;
> +	}
> +
>  	netdev = alloc_etherdev_mq(sizeof(struct octep_device),
>  				   OCTEP_MAX_QUEUES);
>  	if (!netdev) {
> -- 
> 2.36.0
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next v2 2/9] octeon_ep: poll for control messages
  2022-11-29 13:09 ` [PATCH net-next v2 2/9] octeon_ep: poll for control messages Veerasenareddy Burru
@ 2022-11-30  9:30   ` Leon Romanovsky
  2022-11-30 15:44     ` [EXT] " Veerasenareddy Burru
  0 siblings, 1 reply; 28+ messages in thread
From: Leon Romanovsky @ 2022-11-30  9:30 UTC (permalink / raw)
  To: Veerasenareddy Burru
  Cc: netdev, linux-kernel, lironh, aayarekar, sedara, sburla,
	linux-doc, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni

On Tue, Nov 29, 2022 at 05:09:25AM -0800, Veerasenareddy Burru wrote:
> Poll for control messages until interrupts are enabled.
> All the interrupts are enabled in ndo_open().

So what are you saying if I have your device and didn't enable network
device, you will poll forever?

> Add ability to listen for notifications from firmware before ndo_open().
> Once interrupts are enabled, this polling is disabled and all the
> messages are processed by bottom half of interrupt handler.
> 
> Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
> Signed-off-by: Abhijit Ayarekar <aayarekar@marvell.com>
> ---
> v1 -> v2:
>  * removed device status oct->status, as it is not required with the
>    modified implementation in 0001-xxxx.patch
> 
>  .../marvell/octeon_ep/octep_cn9k_pf.c         | 49 +++++++++----------
>  .../ethernet/marvell/octeon_ep/octep_main.c   | 35 +++++++++++++
>  .../ethernet/marvell/octeon_ep/octep_main.h   | 11 ++++-
>  .../marvell/octeon_ep/octep_regs_cn9k_pf.h    |  4 ++
>  4 files changed, 71 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
> index 6ad88d0fe43f..ace2dfd1e918 100644
> --- a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
> +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
> @@ -352,27 +352,36 @@ static void octep_setup_mbox_regs_cn93_pf(struct octep_device *oct, int q_no)
>  	mbox->mbox_read_reg = oct->mmio[0].hw_addr + CN93_SDP_R_MBOX_VF_PF_DATA(q_no);
>  }
>  
> -/* Mailbox Interrupt handler */
> -static void cn93_handle_pf_mbox_intr(struct octep_device *oct)
> +/* Process non-ioq interrupts required to keep pf interface running.
> + * OEI_RINT is needed for control mailbox
> + */
> +static int octep_poll_non_ioq_interrupts_cn93_pf(struct octep_device *oct)
>  {
> -	u64 mbox_int_val = 0ULL, val = 0ULL, qno = 0ULL;
> +	u64 reg0;
> +	int handled = 0;

Reversed Christmas tree.

Thanks

^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control messages
  2022-11-30  9:30   ` Leon Romanovsky
@ 2022-11-30 15:44     ` Veerasenareddy Burru
  2022-12-01  8:11       ` Leon Romanovsky
  0 siblings, 1 reply; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-11-30 15:44 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: netdev, linux-kernel, Liron Himi, Abhijit Ayarekar,
	Sathesh B Edara, Satananda Burla, linux-doc, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni



> -----Original Message-----
> From: Leon Romanovsky <leon@kernel.org>
> Sent: Wednesday, November 30, 2022 1:30 AM
> To: Veerasenareddy Burru <vburru@marvell.com>
> Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Liron Himi
> <lironh@marvell.com>; Abhijit Ayarekar <aayarekar@marvell.com>; Sathesh
> B Edara <sedara@marvell.com>; Satananda Burla <sburla@marvell.com>;
> linux-doc@vger.kernel.org; David S. Miller <davem@davemloft.net>; Eric
> Dumazet <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>;
> Paolo Abeni <pabeni@redhat.com>
> Subject: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control
> messages
> 
> External Email
> 
> ----------------------------------------------------------------------
> On Tue, Nov 29, 2022 at 05:09:25AM -0800, Veerasenareddy Burru wrote:
> > Poll for control messages until interrupts are enabled.
> > All the interrupts are enabled in ndo_open().
> 
> So what are you saying if I have your device and didn't enable network
> device, you will poll forever?
Yes, Leon. It will poll periodically until network interface is enabled.
> 
> > Add ability to listen for notifications from firmware before ndo_open().
> > Once interrupts are enabled, this polling is disabled and all the
> > messages are processed by bottom half of interrupt handler.
> >
> > Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
> > Signed-off-by: Abhijit Ayarekar <aayarekar@marvell.com>
> > ---
> > v1 -> v2:
> >  * removed device status oct->status, as it is not required with the
> >    modified implementation in 0001-xxxx.patch
> >
> >  .../marvell/octeon_ep/octep_cn9k_pf.c         | 49 +++++++++----------
> >  .../ethernet/marvell/octeon_ep/octep_main.c   | 35 +++++++++++++
> >  .../ethernet/marvell/octeon_ep/octep_main.h   | 11 ++++-
> >  .../marvell/octeon_ep/octep_regs_cn9k_pf.h    |  4 ++
> >  4 files changed, 71 insertions(+), 28 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
> > b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
> > index 6ad88d0fe43f..ace2dfd1e918 100644
> > --- a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
> > +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
> > @@ -352,27 +352,36 @@ static void
> octep_setup_mbox_regs_cn93_pf(struct octep_device *oct, int q_no)
> >  	mbox->mbox_read_reg = oct->mmio[0].hw_addr +
> > CN93_SDP_R_MBOX_VF_PF_DATA(q_no);  }
> >
> > -/* Mailbox Interrupt handler */
> > -static void cn93_handle_pf_mbox_intr(struct octep_device *oct)
> > +/* Process non-ioq interrupts required to keep pf interface running.
> > + * OEI_RINT is needed for control mailbox  */ static int
> > +octep_poll_non_ioq_interrupts_cn93_pf(struct octep_device *oct)
> >  {
> > -	u64 mbox_int_val = 0ULL, val = 0ULL, qno = 0ULL;
> > +	u64 reg0;
> > +	int handled = 0;
> 
> Reversed Christmas tree.
Thanks for the feedback. Will revise the patch.
> 
> Thanks

^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [EXT] Re: [PATCH net-next v2 1/9] octeon_ep: defer probe if firmware not ready
  2022-11-30  9:24   ` Leon Romanovsky
@ 2022-11-30 15:50     ` Veerasenareddy Burru
  0 siblings, 0 replies; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-11-30 15:50 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: netdev, linux-kernel, Liron Himi, Abhijit Ayarekar,
	Sathesh B Edara, Satananda Burla, linux-doc, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni



> -----Original Message-----
> From: Leon Romanovsky <leon@kernel.org>
> Sent: Wednesday, November 30, 2022 1:25 AM
> To: Veerasenareddy Burru <vburru@marvell.com>
> Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Liron Himi
> <lironh@marvell.com>; Abhijit Ayarekar <aayarekar@marvell.com>; Sathesh
> B Edara <sedara@marvell.com>; Satananda Burla <sburla@marvell.com>;
> linux-doc@vger.kernel.org; David S. Miller <davem@davemloft.net>; Eric
> Dumazet <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>;
> Paolo Abeni <pabeni@redhat.com>
> Subject: [EXT] Re: [PATCH net-next v2 1/9] octeon_ep: defer probe if
> firmware not ready
> 
> External Email
> 
> ----------------------------------------------------------------------
> On Tue, Nov 29, 2022 at 05:09:24AM -0800, Veerasenareddy Burru wrote:
> > Defer probe if firmware is not ready for device usage.
> >
> > Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
> > Signed-off-by: Abhijit Ayarekar <aayarekar@marvell.com>
> > Signed-off-by: Satananda Burla <sburla@marvell.com>
> > ---
> > v1 -> v2:
> >  * was scheduling workqueue task to wait for firmware ready,
> >    to probe/initialize the device.
> >  * now, removed the workqueue task; the probe returns EPROBE_DEFER,
> >    if firmware is not ready.
> >  * removed device status oct->status, as it is not required with the
> >    modified implementation.
> >
> >  .../ethernet/marvell/octeon_ep/octep_main.c   | 26
> +++++++++++++++++++
> >  1 file changed, 26 insertions(+)
> >
> > diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
> > b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
> > index 5a898fb88e37..aa7d0ced9807 100644
> > --- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
> > +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
> > @@ -1017,6 +1017,25 @@ static void octep_device_cleanup(struct
> octep_device *oct)
> >  	oct->conf = NULL;
> >  }
> >
> > +static u8 get_fw_ready_status(struct pci_dev *pdev)
> 
> Please change this function to return bool, you are not interested in status.
> 
Yes, we can just return bool; Thanks for the suggestion. Will implement this.
> > +{
> > +	u32 pos = 0;
> > +	u16 vsec_id;
> > +	u8 status;
> > +
> > +	while ((pos = pci_find_next_ext_capability(pdev, pos,
> > +						   PCI_EXT_CAP_ID_VNDR))) {
> > +		pci_read_config_word(pdev, pos + 4, &vsec_id); #define
> > +FW_STATUS_VSEC_ID  0xA3
> > +		if (vsec_id == FW_STATUS_VSEC_ID) {
> 
> Success oriented flow, plase
> if (vsec_id != FW_STATUS_VSEC_ID)
>  cotitnue;
> 
> ....
> 
Sure, will change this.
> > +			pci_read_config_byte(pdev, (pos + 8), &status);
> > +			dev_info(&pdev->dev, "Firmware ready %u\n",
> status);
> > +			return status;
> > +		}
> > +	}
> > +	return 0;
> > +}
> > +
> >  /**
> >   * octep_probe() - Octeon PCI device probe handler.
> >   *
> > @@ -1053,6 +1072,13 @@ static int octep_probe(struct pci_dev *pdev,
> const struct pci_device_id *ent)
> >  	pci_enable_pcie_error_reporting(pdev);
> >  	pci_set_master(pdev);
> >
> > +#define FW_STATUS_READY    1
> > +	if (get_fw_ready_status(pdev) != FW_STATUS_READY) {
> 
> No need to this new define if you change get_fw_ready_status() to return
> true/false.
We will change this to true/false.
> 
> And I think that you can put this check earlier in octep_probe().
We will check and move this to earlier point in octep_probe().

Thanks
> 
> Thanks
> 
> > +		dev_notice(&pdev->dev, "Firmware not ready; defer
> probe.\n");
> > +		err = -EPROBE_DEFER;
> > +		goto err_alloc_netdev;
> > +	}
> > +
> >  	netdev = alloc_etherdev_mq(sizeof(struct octep_device),
> >  				   OCTEP_MAX_QUEUES);
> >  	if (!netdev) {
> > --
> > 2.36.0
> >

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control messages
  2022-11-30 15:44     ` [EXT] " Veerasenareddy Burru
@ 2022-12-01  8:11       ` Leon Romanovsky
  2022-12-05  4:46         ` Veerasenareddy Burru
  0 siblings, 1 reply; 28+ messages in thread
From: Leon Romanovsky @ 2022-12-01  8:11 UTC (permalink / raw)
  To: Veerasenareddy Burru
  Cc: netdev, linux-kernel, Liron Himi, Abhijit Ayarekar,
	Sathesh B Edara, Satananda Burla, linux-doc, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni

On Wed, Nov 30, 2022 at 03:44:30PM +0000, Veerasenareddy Burru wrote:
> 
> 
> > -----Original Message-----
> > From: Leon Romanovsky <leon@kernel.org>
> > Sent: Wednesday, November 30, 2022 1:30 AM
> > To: Veerasenareddy Burru <vburru@marvell.com>
> > Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Liron Himi
> > <lironh@marvell.com>; Abhijit Ayarekar <aayarekar@marvell.com>; Sathesh
> > B Edara <sedara@marvell.com>; Satananda Burla <sburla@marvell.com>;
> > linux-doc@vger.kernel.org; David S. Miller <davem@davemloft.net>; Eric
> > Dumazet <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>;
> > Paolo Abeni <pabeni@redhat.com>
> > Subject: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control
> > messages
> > 
> > External Email
> > 
> > ----------------------------------------------------------------------
> > On Tue, Nov 29, 2022 at 05:09:25AM -0800, Veerasenareddy Burru wrote:
> > > Poll for control messages until interrupts are enabled.
> > > All the interrupts are enabled in ndo_open().
> > 
> > So what are you saying if I have your device and didn't enable network
> > device, you will poll forever?
> Yes, Leon. It will poll periodically until network interface is enabled.

I don't know if it is acceptable behaviour in netdev, but it doesn't
sound right to me. What type of control messages will be sent by FW,
which PF should listen to them?

> > 
> > > Add ability to listen for notifications from firmware before ndo_open().
> > > Once interrupts are enabled, this polling is disabled and all the
> > > messages are processed by bottom half of interrupt handler.
> > >
> > > Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
> > > Signed-off-by: Abhijit Ayarekar <aayarekar@marvell.com>
> > > ---
> > > v1 -> v2:
> > >  * removed device status oct->status, as it is not required with the
> > >    modified implementation in 0001-xxxx.patch
> > >
> > >  .../marvell/octeon_ep/octep_cn9k_pf.c         | 49 +++++++++----------
> > >  .../ethernet/marvell/octeon_ep/octep_main.c   | 35 +++++++++++++
> > >  .../ethernet/marvell/octeon_ep/octep_main.h   | 11 ++++-
> > >  .../marvell/octeon_ep/octep_regs_cn9k_pf.h    |  4 ++
> > >  4 files changed, 71 insertions(+), 28 deletions(-)
> > >
> > > diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
> > > b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
> > > index 6ad88d0fe43f..ace2dfd1e918 100644
> > > --- a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
> > > +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
> > > @@ -352,27 +352,36 @@ static void
> > octep_setup_mbox_regs_cn93_pf(struct octep_device *oct, int q_no)
> > >  	mbox->mbox_read_reg = oct->mmio[0].hw_addr +
> > > CN93_SDP_R_MBOX_VF_PF_DATA(q_no);  }
> > >
> > > -/* Mailbox Interrupt handler */
> > > -static void cn93_handle_pf_mbox_intr(struct octep_device *oct)
> > > +/* Process non-ioq interrupts required to keep pf interface running.
> > > + * OEI_RINT is needed for control mailbox  */ static int
> > > +octep_poll_non_ioq_interrupts_cn93_pf(struct octep_device *oct)
> > >  {
> > > -	u64 mbox_int_val = 0ULL, val = 0ULL, qno = 0ULL;
> > > +	u64 reg0;
> > > +	int handled = 0;
> > 
> > Reversed Christmas tree.
> Thanks for the feedback. Will revise the patch.

It is applicable to all patches.

And please fix your email client to properly add blank lines between
replies.

Thanks

> > 
> > Thanks

^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control messages
  2022-12-01  8:11       ` Leon Romanovsky
@ 2022-12-05  4:46         ` Veerasenareddy Burru
  2022-12-05  8:10           ` Leon Romanovsky
  0 siblings, 1 reply; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-12-05  4:46 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: netdev, linux-kernel, Liron Himi, Abhijit Ayarekar,
	Sathesh B Edara, Satananda Burla, linux-doc, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni



> -----Original Message-----
> From: Leon Romanovsky <leon@kernel.org>
> Sent: Thursday, December 1, 2022 12:11 AM
> To: Veerasenareddy Burru <vburru@marvell.com>
> Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Liron Himi
> <lironh@marvell.com>; Abhijit Ayarekar <aayarekar@marvell.com>; Sathesh
> B Edara <sedara@marvell.com>; Satananda Burla <sburla@marvell.com>;
> linux-doc@vger.kernel.org; David S. Miller <davem@davemloft.net>; Eric
> Dumazet <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>;
> Paolo Abeni <pabeni@redhat.com>
> Subject: Re: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control
> messages
> 
> On Wed, Nov 30, 2022 at 03:44:30PM +0000, Veerasenareddy Burru wrote:
> >
> >
> > > -----Original Message-----
> > > From: Leon Romanovsky <leon@kernel.org>
> > > Sent: Wednesday, November 30, 2022 1:30 AM
> > > To: Veerasenareddy Burru <vburru@marvell.com>
> > > Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Liron Himi
> > > <lironh@marvell.com>; Abhijit Ayarekar <aayarekar@marvell.com>;
> > > Sathesh B Edara <sedara@marvell.com>; Satananda Burla
> > > <sburla@marvell.com>; linux-doc@vger.kernel.org; David S. Miller
> > > <davem@davemloft.net>; Eric Dumazet <edumazet@google.com>;
> Jakub
> > > Kicinski <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>
> > > Subject: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for
> > > control messages
> > >
> > > External Email
> > >
> > > --------------------------------------------------------------------
> > > -- On Tue, Nov 29, 2022 at 05:09:25AM -0800, Veerasenareddy Burru
> > > wrote:
> > > > Poll for control messages until interrupts are enabled.
> > > > All the interrupts are enabled in ndo_open().
> > >
> > > So what are you saying if I have your device and didn't enable
> > > network device, you will poll forever?
> > Yes, Leon. It will poll periodically until network interface is enabled.
> 
> I don't know if it is acceptable behaviour in netdev, but it doesn't sound right
> to me. What type of control messages will be sent by FW, which PF should
> listen to them?
> 

These messages include periodic keep alive (heartbeat) messages from FW and control messages from VFs.
Every PF will be listening for its own control messages.

Thank you.

> > >
> > > > Add ability to listen for notifications from firmware before ndo_open().
> > > > Once interrupts are enabled, this polling is disabled and all the
> > > > messages are processed by bottom half of interrupt handler.
> > > >
> > > > Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
> > > > Signed-off-by: Abhijit Ayarekar <aayarekar@marvell.com>
> > > > ---
> > > > v1 -> v2:
> > > >  * removed device status oct->status, as it is not required with the
> > > >    modified implementation in 0001-xxxx.patch
> > > >
> > > >  .../marvell/octeon_ep/octep_cn9k_pf.c         | 49 +++++++++----------
> > > >  .../ethernet/marvell/octeon_ep/octep_main.c   | 35 +++++++++++++
> > > >  .../ethernet/marvell/octeon_ep/octep_main.h   | 11 ++++-
> > > >  .../marvell/octeon_ep/octep_regs_cn9k_pf.h    |  4 ++
> > > >  4 files changed, 71 insertions(+), 28 deletions(-)
> > > >
> > > > diff --git
> > > > a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
> > > > b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
> > > > index 6ad88d0fe43f..ace2dfd1e918 100644
> > > > --- a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
> > > > +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
> > > > @@ -352,27 +352,36 @@ static void
> > > octep_setup_mbox_regs_cn93_pf(struct octep_device *oct, int q_no)
> > > >  	mbox->mbox_read_reg = oct->mmio[0].hw_addr +
> > > > CN93_SDP_R_MBOX_VF_PF_DATA(q_no);  }
> > > >
> > > > -/* Mailbox Interrupt handler */
> > > > -static void cn93_handle_pf_mbox_intr(struct octep_device *oct)
> > > > +/* Process non-ioq interrupts required to keep pf interface running.
> > > > + * OEI_RINT is needed for control mailbox  */ static int
> > > > +octep_poll_non_ioq_interrupts_cn93_pf(struct octep_device *oct)
> > > >  {
> > > > -	u64 mbox_int_val = 0ULL, val = 0ULL, qno = 0ULL;
> > > > +	u64 reg0;
> > > > +	int handled = 0;
> > >
> > > Reversed Christmas tree.
> > Thanks for the feedback. Will revise the patch.
> 
> It is applicable to all patches.
> 
> And please fix your email client to properly add blank lines between replies.
> 
> Thanks
> 
> > >
> > > Thanks

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control messages
  2022-12-05  4:46         ` Veerasenareddy Burru
@ 2022-12-05  8:10           ` Leon Romanovsky
  2022-12-06  0:16             ` Jakub Kicinski
  0 siblings, 1 reply; 28+ messages in thread
From: Leon Romanovsky @ 2022-12-05  8:10 UTC (permalink / raw)
  To: Veerasenareddy Burru, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni
  Cc: netdev, linux-kernel, Liron Himi, Abhijit Ayarekar,
	Sathesh B Edara, Satananda Burla, linux-doc

On Mon, Dec 05, 2022 at 04:46:31AM +0000, Veerasenareddy Burru wrote:
> 
> 
> > -----Original Message-----
> > From: Leon Romanovsky <leon@kernel.org>
> > Sent: Thursday, December 1, 2022 12:11 AM
> > To: Veerasenareddy Burru <vburru@marvell.com>
> > Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Liron Himi
> > <lironh@marvell.com>; Abhijit Ayarekar <aayarekar@marvell.com>; Sathesh
> > B Edara <sedara@marvell.com>; Satananda Burla <sburla@marvell.com>;
> > linux-doc@vger.kernel.org; David S. Miller <davem@davemloft.net>; Eric
> > Dumazet <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>;
> > Paolo Abeni <pabeni@redhat.com>
> > Subject: Re: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control
> > messages
> > 
> > On Wed, Nov 30, 2022 at 03:44:30PM +0000, Veerasenareddy Burru wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Leon Romanovsky <leon@kernel.org>
> > > > Sent: Wednesday, November 30, 2022 1:30 AM
> > > > To: Veerasenareddy Burru <vburru@marvell.com>
> > > > Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Liron Himi
> > > > <lironh@marvell.com>; Abhijit Ayarekar <aayarekar@marvell.com>;
> > > > Sathesh B Edara <sedara@marvell.com>; Satananda Burla
> > > > <sburla@marvell.com>; linux-doc@vger.kernel.org; David S. Miller
> > > > <davem@davemloft.net>; Eric Dumazet <edumazet@google.com>;
> > Jakub
> > > > Kicinski <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>
> > > > Subject: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for
> > > > control messages
> > > >
> > > > External Email
> > > >
> > > > --------------------------------------------------------------------
> > > > -- On Tue, Nov 29, 2022 at 05:09:25AM -0800, Veerasenareddy Burru
> > > > wrote:
> > > > > Poll for control messages until interrupts are enabled.
> > > > > All the interrupts are enabled in ndo_open().
> > > >
> > > > So what are you saying if I have your device and didn't enable
> > > > network device, you will poll forever?
> > > Yes, Leon. It will poll periodically until network interface is enabled.
> > 
> > I don't know if it is acceptable behaviour in netdev, but it doesn't sound right
> > to me. What type of control messages will be sent by FW, which PF should
> > listen to them?
> > 
> 
> These messages include periodic keep alive (heartbeat) messages from FW and control messages from VFs.
> Every PF will be listening for its own control messages.

@netdev, as I said, I don't know if it is valid behaviour in netdev.
Can you please comment?

Thanks

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control messages
  2022-12-05  8:10           ` Leon Romanovsky
@ 2022-12-06  0:16             ` Jakub Kicinski
  2022-12-06  8:58               ` Leon Romanovsky
  0 siblings, 1 reply; 28+ messages in thread
From: Jakub Kicinski @ 2022-12-06  0:16 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: Veerasenareddy Burru, David S. Miller, Eric Dumazet, Paolo Abeni,
	netdev, linux-kernel, Liron Himi, Abhijit Ayarekar,
	Sathesh B Edara, Satananda Burla, linux-doc

On Mon, 5 Dec 2022 10:10:34 +0200 Leon Romanovsky wrote:
> > These messages include periodic keep alive (heartbeat) messages
> > from FW and control messages from VFs. Every PF will be listening
> > for its own control messages.  
> 
> @netdev, as I said, I don't know if it is valid behaviour in netdev.
> Can you please comment?

Polling for control messages every 100ms?  Sure.

You say "valid in netdev" so perhaps you can educate us where/why it
would not be?

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control messages
  2022-12-06  0:16             ` Jakub Kicinski
@ 2022-12-06  8:58               ` Leon Romanovsky
  2022-12-06 17:23                 ` Jakub Kicinski
  0 siblings, 1 reply; 28+ messages in thread
From: Leon Romanovsky @ 2022-12-06  8:58 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Veerasenareddy Burru, David S. Miller, Eric Dumazet, Paolo Abeni,
	netdev, linux-kernel, Liron Himi, Abhijit Ayarekar,
	Sathesh B Edara, Satananda Burla, linux-doc

On Mon, Dec 05, 2022 at 04:16:26PM -0800, Jakub Kicinski wrote:
> On Mon, 5 Dec 2022 10:10:34 +0200 Leon Romanovsky wrote:
> > > These messages include periodic keep alive (heartbeat) messages
> > > from FW and control messages from VFs. Every PF will be listening
> > > for its own control messages.  
> > 
> > @netdev, as I said, I don't know if it is valid behaviour in netdev.
> > Can you please comment?
> 
> Polling for control messages every 100ms?  Sure.
> 
> You say "valid in netdev" so perhaps you can educate us where/why it
> would not be?

It doesn't seem right to me that idle device burns CPU cycles, while it
supports interrupts. If it needs "listen to FW", it will be much nicer to
install interrupts immediately and don't wait for netdev.

Thanks

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control messages
  2022-12-06  8:58               ` Leon Romanovsky
@ 2022-12-06 17:23                 ` Jakub Kicinski
  2022-12-06 21:19                   ` Veerasenareddy Burru
  0 siblings, 1 reply; 28+ messages in thread
From: Jakub Kicinski @ 2022-12-06 17:23 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: Veerasenareddy Burru, David S. Miller, Eric Dumazet, Paolo Abeni,
	netdev, linux-kernel, Liron Himi, Abhijit Ayarekar,
	Sathesh B Edara, Satananda Burla, linux-doc

On Tue, 6 Dec 2022 10:58:47 +0200 Leon Romanovsky wrote:
> > Polling for control messages every 100ms?  Sure.
> > 
> > You say "valid in netdev" so perhaps you can educate us where/why it
> > would not be?  
> 
> It doesn't seem right to me that idle device burns CPU cycles, while it
> supports interrupts. If it needs "listen to FW", it will be much nicer to
> install interrupts immediately and don't wait for netdev.

No doubt, if there is an alternative we can push for it to be
implemented. I guess this being yet another "IPU" there could
be possible workarounds in FW? As always with IPUs - hard to tell :/

If there is no alternative - it is what it is. 
It's up to customers to buy good HW.

That said, looking at what this set does - how are the VFs configured?
That's the showstopper for the series in my mind.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control messages
  2022-12-06 17:23                 ` Jakub Kicinski
@ 2022-12-06 21:19                   ` Veerasenareddy Burru
  2022-12-07  1:26                     ` Jakub Kicinski
  0 siblings, 1 reply; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-12-06 21:19 UTC (permalink / raw)
  To: Jakub Kicinski, Leon Romanovsky
  Cc: David S. Miller, Eric Dumazet, Paolo Abeni, netdev, linux-kernel,
	Liron Himi, Abhijit Ayarekar, Sathesh B Edara, Satananda Burla,
	linux-doc



> -----Original Message-----
> From: Jakub Kicinski <kuba@kernel.org>
> Sent: Tuesday, December 6, 2022 9:24 AM
> To: Leon Romanovsky <leon@kernel.org>
> Cc: Veerasenareddy Burru <vburru@marvell.com>; David S. Miller
> <davem@davemloft.net>; Eric Dumazet <edumazet@google.com>; Paolo
> Abeni <pabeni@redhat.com>; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; Liron Himi <lironh@marvell.com>; Abhijit Ayarekar
> <aayarekar@marvell.com>; Sathesh B Edara <sedara@marvell.com>;
> Satananda Burla <sburla@marvell.com>; linux-doc@vger.kernel.org
> Subject: Re: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control
> messages
> 
> On Tue, 6 Dec 2022 10:58:47 +0200 Leon Romanovsky wrote:
> > > Polling for control messages every 100ms?  Sure.
> > >
> > > You say "valid in netdev" so perhaps you can educate us where/why it
> > > would not be?
> >
> > It doesn't seem right to me that idle device burns CPU cycles, while
> > it supports interrupts. If it needs "listen to FW", it will be much
> > nicer to install interrupts immediately and don't wait for netdev.
> 
> No doubt, if there is an alternative we can push for it to be implemented. I
> guess this being yet another "IPU" there could be possible workarounds in
> FW? As always with IPUs - hard to tell :/
> 
> If there is no alternative - it is what it is.
> It's up to customers to buy good HW.
> 
> That said, looking at what this set does - how are the VFs configured?
> That's the showstopper for the series in my mind.

VFs are created by writing to sriov_numvfs.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control messages
  2022-12-06 21:19                   ` Veerasenareddy Burru
@ 2022-12-07  1:26                     ` Jakub Kicinski
  2022-12-08  3:17                       ` Veerasenareddy Burru
  0 siblings, 1 reply; 28+ messages in thread
From: Jakub Kicinski @ 2022-12-07  1:26 UTC (permalink / raw)
  To: Veerasenareddy Burru
  Cc: Leon Romanovsky, David S. Miller, Eric Dumazet, Paolo Abeni,
	netdev, linux-kernel, Liron Himi, Abhijit Ayarekar,
	Sathesh B Edara, Satananda Burla, linux-doc

On Tue, 6 Dec 2022 21:19:26 +0000 Veerasenareddy Burru wrote:
> > That said, looking at what this set does - how are the VFs configured?
> > That's the showstopper for the series in my mind.  
> 
> VFs are created by writing to sriov_numvfs.

Configured, not enabled.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control messages
  2022-12-07  1:26                     ` Jakub Kicinski
@ 2022-12-08  3:17                       ` Veerasenareddy Burru
  2022-12-08  4:02                         ` Jakub Kicinski
  0 siblings, 1 reply; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-12-08  3:17 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Leon Romanovsky, David S. Miller, Eric Dumazet, Paolo Abeni,
	netdev, linux-kernel, Liron Himi, Abhijit Ayarekar,
	Sathesh B Edara, Satananda Burla, linux-doc



> -----Original Message-----
> From: Jakub Kicinski <kuba@kernel.org>
> Sent: Tuesday, December 6, 2022 5:27 PM
> To: Veerasenareddy Burru <vburru@marvell.com>
> Cc: Leon Romanovsky <leon@kernel.org>; David S. Miller
> <davem@davemloft.net>; Eric Dumazet <edumazet@google.com>; Paolo
> Abeni <pabeni@redhat.com>; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; Liron Himi <lironh@marvell.com>; Abhijit Ayarekar
> <aayarekar@marvell.com>; Sathesh B Edara <sedara@marvell.com>;
> Satananda Burla <sburla@marvell.com>; linux-doc@vger.kernel.org
> Subject: Re: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control
> messages
> 
> On Tue, 6 Dec 2022 21:19:26 +0000 Veerasenareddy Burru wrote:
> > > That said, looking at what this set does - how are the VFs configured?
> > > That's the showstopper for the series in my mind.
> >
> > VFs are created by writing to sriov_numvfs.
> 
> Configured, not enabled.

We have a follow up patch after this series implementing ndo_get_vf_xxx() and ndo_set_vf_xxx().

Thanks


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control messages
  2022-12-08  3:17                       ` Veerasenareddy Burru
@ 2022-12-08  4:02                         ` Jakub Kicinski
  2022-12-08  4:41                           ` Veerasenareddy Burru
  0 siblings, 1 reply; 28+ messages in thread
From: Jakub Kicinski @ 2022-12-08  4:02 UTC (permalink / raw)
  To: Veerasenareddy Burru
  Cc: Leon Romanovsky, David S. Miller, Eric Dumazet, Paolo Abeni,
	netdev, linux-kernel, Liron Himi, Abhijit Ayarekar,
	Sathesh B Edara, Satananda Burla, linux-doc

On Thu, 8 Dec 2022 03:17:33 +0000 Veerasenareddy Burru wrote:
> We have a follow up patch after this series implementing
> ndo_get_vf_xxx() and ndo_set_vf_xxx().

We don't accept new drivers which use those interfaces.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control messages
  2022-12-08  4:02                         ` Jakub Kicinski
@ 2022-12-08  4:41                           ` Veerasenareddy Burru
  2022-12-08  4:47                             ` Jakub Kicinski
  0 siblings, 1 reply; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-12-08  4:41 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Leon Romanovsky, David S. Miller, Eric Dumazet, Paolo Abeni,
	netdev, linux-kernel, Liron Himi, Abhijit Ayarekar,
	Sathesh B Edara, Satananda Burla, linux-doc



> -----Original Message-----
> From: Jakub Kicinski <kuba@kernel.org>
> Sent: Wednesday, December 7, 2022 8:02 PM
> To: Veerasenareddy Burru <vburru@marvell.com>
> Cc: Leon Romanovsky <leon@kernel.org>; David S. Miller
> <davem@davemloft.net>; Eric Dumazet <edumazet@google.com>; Paolo
> Abeni <pabeni@redhat.com>; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; Liron Himi <lironh@marvell.com>; Abhijit Ayarekar
> <aayarekar@marvell.com>; Sathesh B Edara <sedara@marvell.com>;
> Satananda Burla <sburla@marvell.com>; linux-doc@vger.kernel.org
> Subject: Re: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control
> messages
> 
> On Thu, 8 Dec 2022 03:17:33 +0000 Veerasenareddy Burru wrote:
> > We have a follow up patch after this series implementing
> > ndo_get_vf_xxx() and ndo_set_vf_xxx().
> 
> We don't accept new drivers which use those interfaces.

Kindly suggest the acceptable interface.

Thanks.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control messages
  2022-12-08  4:41                           ` Veerasenareddy Burru
@ 2022-12-08  4:47                             ` Jakub Kicinski
  2022-12-14  7:15                               ` Veerasenareddy Burru
  0 siblings, 1 reply; 28+ messages in thread
From: Jakub Kicinski @ 2022-12-08  4:47 UTC (permalink / raw)
  To: Veerasenareddy Burru
  Cc: Leon Romanovsky, David S. Miller, Eric Dumazet, Paolo Abeni,
	netdev, linux-kernel, Liron Himi, Abhijit Ayarekar,
	Sathesh B Edara, Satananda Burla, linux-doc

On Thu, 8 Dec 2022 04:41:56 +0000 Veerasenareddy Burru wrote:
> > On Thu, 8 Dec 2022 03:17:33 +0000 Veerasenareddy Burru wrote:  
> > > We have a follow up patch after this series implementing
> > > ndo_get_vf_xxx() and ndo_set_vf_xxx().  
> > 
> > We don't accept new drivers which use those interfaces.  
> 
> Kindly suggest the acceptable interface.

Kindly make the minimal effort to follow the list :/

Perhaps others have the time to explain things to you, 
I believe my time is best spent elsewhere.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next v2 8/9] octeon_ep: add PF-VF mailbox communication
  2022-11-29 13:09 ` [PATCH net-next v2 8/9] octeon_ep: add PF-VF mailbox communication Veerasenareddy Burru
@ 2022-12-09  8:48   ` Dan Carpenter
  0 siblings, 0 replies; 28+ messages in thread
From: Dan Carpenter @ 2022-12-09  8:48 UTC (permalink / raw)
  To: oe-kbuild, Veerasenareddy Burru, netdev, linux-kernel, lironh,
	aayarekar, sedara, sburla
  Cc: lkp, oe-kbuild-all, linux-doc, Veerasenareddy Burru,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni

Hi Veerasenareddy,

url:    https://github.com/intel-lab-lkp/linux/commits/Veerasenareddy-Burru/octeon_ep-Update-PF-mailbox-for-VF/20221130-110134
base:   7a168f560e3c3829b74a893d3655caab14a7aef8
patch link:    https://lore.kernel.org/r/20221129130933.25231-9-vburru%40marvell.com
patch subject: [PATCH net-next v2 8/9] octeon_ep: add PF-VF mailbox communication
config: ia64-randconfig-m041-20221204
compiler: ia64-linux-gcc (GCC) 12.1.0

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <error27@gmail.com>

New smatch warnings:
drivers/net/ethernet/marvell/octeon_ep/octep_main.c:1105 octep_probe() warn: missing unwind goto?

vim +1105 drivers/net/ethernet/marvell/octeon_ep/octep_main.c

862cd659a6fbac Veerasenareddy Burru 2022-04-12  1046  static int octep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1047  {
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1048  	struct octep_device *octep_dev = NULL;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1049  	struct net_device *netdev;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1050  	int err;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1051  
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1052  	err = pci_enable_device(pdev);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1053  	if (err) {
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1054  		dev_err(&pdev->dev, "Failed to enable PCI device\n");
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1055  		return  err;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1056  	}
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1057  
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1058  	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1059  	if (err) {
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1060  		dev_err(&pdev->dev, "Failed to set DMA mask !!\n");
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1061  		goto err_dma_mask;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1062  	}
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1063  
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1064  	err = pci_request_mem_regions(pdev, OCTEP_DRV_NAME);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1065  	if (err) {
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1066  		dev_err(&pdev->dev, "Failed to map PCI memory regions\n");
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1067  		goto err_pci_regions;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1068  	}
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1069  
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1070  	pci_enable_pcie_error_reporting(pdev);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1071  	pci_set_master(pdev);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1072  
a36869e03997c0 Veerasenareddy Burru 2022-11-29  1073  #define FW_STATUS_READY    1
a36869e03997c0 Veerasenareddy Burru 2022-11-29  1074  	if (get_fw_ready_status(pdev) != FW_STATUS_READY) {
a36869e03997c0 Veerasenareddy Burru 2022-11-29  1075  		dev_notice(&pdev->dev, "Firmware not ready; defer probe.\n");
a36869e03997c0 Veerasenareddy Burru 2022-11-29  1076  		err = -EPROBE_DEFER;
a36869e03997c0 Veerasenareddy Burru 2022-11-29  1077  		goto err_alloc_netdev;
a36869e03997c0 Veerasenareddy Burru 2022-11-29  1078  	}
a36869e03997c0 Veerasenareddy Burru 2022-11-29  1079  
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1080  	netdev = alloc_etherdev_mq(sizeof(struct octep_device),
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1081  				   OCTEP_MAX_QUEUES);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1082  	if (!netdev) {
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1083  		dev_err(&pdev->dev, "Failed to allocate netdev\n");
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1084  		err = -ENOMEM;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1085  		goto err_alloc_netdev;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1086  	}
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1087  	SET_NETDEV_DEV(netdev, &pdev->dev);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1088  
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1089  	octep_dev = netdev_priv(netdev);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1090  	octep_dev->netdev = netdev;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1091  	octep_dev->pdev = pdev;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1092  	octep_dev->dev = &pdev->dev;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1093  	pci_set_drvdata(pdev, octep_dev);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1094  
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1095  	err = octep_device_setup(octep_dev);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1096  	if (err) {
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1097  		dev_err(&pdev->dev, "Device setup failed\n");
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1098  		goto err_octep_config;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1099  	}
f13f1764c1708a Veerasenareddy Burru 2022-11-29  1100  
f13f1764c1708a Veerasenareddy Burru 2022-11-29  1101  	err = octep_setup_pfvf_mbox(octep_dev);
f13f1764c1708a Veerasenareddy Burru 2022-11-29  1102  	if (err) {
f13f1764c1708a Veerasenareddy Burru 2022-11-29  1103  		dev_err(&pdev->dev, " pfvf mailbox setup failed\n");
f13f1764c1708a Veerasenareddy Burru 2022-11-29  1104  		octep_ctrl_net_uninit(octep_dev);
f13f1764c1708a Veerasenareddy Burru 2022-11-29 @1105  		return err;

This doesn't call free_netdev(netdev); so it's a leak.

The octep_device_cleanup() function calls octep_ctrl_net_uninit() but
presumably calling octep_device_cleanup() if octep_setup_pfvf_mbox()
fails is a bug...  Ideally there would be a function which could clean
up octep_device_setup() and a different function which could clean up
octep_setup_pfvf_mbox() but maybe that's impossible because of weird
ordering constraints.

f13f1764c1708a Veerasenareddy Burru 2022-11-29  1106  	}
f13f1764c1708a Veerasenareddy Burru 2022-11-29  1107  
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1108  	INIT_WORK(&octep_dev->tx_timeout_task, octep_tx_timeout_task);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1109  	INIT_WORK(&octep_dev->ctrl_mbox_task, octep_ctrl_mbox_task);
c310a95e2434e5 Veerasenareddy Burru 2022-11-29  1110  	INIT_DELAYED_WORK(&octep_dev->intr_poll_task, octep_intr_poll_task);
c310a95e2434e5 Veerasenareddy Burru 2022-11-29  1111  	octep_dev->poll_non_ioq_intr = true;
c310a95e2434e5 Veerasenareddy Burru 2022-11-29  1112  	queue_delayed_work(octep_wq, &octep_dev->intr_poll_task,
c310a95e2434e5 Veerasenareddy Burru 2022-11-29  1113  			   msecs_to_jiffies(OCTEP_INTR_POLL_TIME_MSECS));
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1114  
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1115  	netdev->netdev_ops = &octep_netdev_ops;
5cc256e79bff06 Veerasenareddy Burru 2022-04-12  1116  	octep_set_ethtool_ops(netdev);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1117  	netif_carrier_off(netdev);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1118  
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1119  	netdev->hw_features = NETIF_F_SG;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1120  	netdev->features |= netdev->hw_features;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1121  	netdev->min_mtu = OCTEP_MIN_MTU;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1122  	netdev->max_mtu = OCTEP_MAX_MTU;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1123  	netdev->mtu = OCTEP_DEFAULT_MTU;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1124  
6494f39ec1f4be Veerasenareddy Burru 2022-11-29  1125  	err = octep_ctrl_net_get_mac_addr(octep_dev, OCTEP_CTRL_NET_INVALID_VFID,
6494f39ec1f4be Veerasenareddy Burru 2022-11-29  1126  					  octep_dev->mac_addr);
848ffce2f0c93f Ziyang Xuan          2022-11-11  1127  	if (err) {
848ffce2f0c93f Ziyang Xuan          2022-11-11  1128  		dev_err(&pdev->dev, "Failed to get mac address\n");
848ffce2f0c93f Ziyang Xuan          2022-11-11  1129  		goto register_dev_err;
848ffce2f0c93f Ziyang Xuan          2022-11-11  1130  	}
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1131  	eth_hw_addr_set(netdev, octep_dev->mac_addr);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1132  
0a03f3c511f57d Yang Yingliang       2022-04-15  1133  	err = register_netdev(netdev);
0a03f3c511f57d Yang Yingliang       2022-04-15  1134  	if (err) {
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1135  		dev_err(&pdev->dev, "Failed to register netdev\n");
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1136  		goto register_dev_err;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1137  	}
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1138  	dev_info(&pdev->dev, "Device probe successful\n");
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1139  	return 0;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1140  
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1141  register_dev_err:
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1142  	octep_device_cleanup(octep_dev);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1143  err_octep_config:
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1144  	free_netdev(netdev);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1145  err_alloc_netdev:
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1146  	pci_disable_pcie_error_reporting(pdev);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1147  	pci_release_mem_regions(pdev);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1148  err_pci_regions:
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1149  err_dma_mask:
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1150  	pci_disable_device(pdev);
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1151  	return err;
862cd659a6fbac Veerasenareddy Burru 2022-04-12  1152  }

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp


^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control messages
  2022-12-08  4:47                             ` Jakub Kicinski
@ 2022-12-14  7:15                               ` Veerasenareddy Burru
  0 siblings, 0 replies; 28+ messages in thread
From: Veerasenareddy Burru @ 2022-12-14  7:15 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Leon Romanovsky, David S. Miller, Eric Dumazet, Paolo Abeni,
	netdev, linux-kernel, Liron Himi, Abhijit Ayarekar,
	Sathesh B Edara, Satananda Burla, linux-doc



> -----Original Message-----
> From: Jakub Kicinski <kuba@kernel.org>
> Sent: Wednesday, December 7, 2022 8:47 PM
> To: Veerasenareddy Burru <vburru@marvell.com>
> Cc: Leon Romanovsky <leon@kernel.org>; David S. Miller
> <davem@davemloft.net>; Eric Dumazet <edumazet@google.com>; Paolo
> Abeni <pabeni@redhat.com>; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; Liron Himi <lironh@marvell.com>; Abhijit Ayarekar
> <aayarekar@marvell.com>; Sathesh B Edara <sedara@marvell.com>;
> Satananda Burla <sburla@marvell.com>; linux-doc@vger.kernel.org
> Subject: Re: [EXT] Re: [PATCH net-next v2 2/9] octeon_ep: poll for control
> messages
> 
> On Thu, 8 Dec 2022 04:41:56 +0000 Veerasenareddy Burru wrote:
> > > On Thu, 8 Dec 2022 03:17:33 +0000 Veerasenareddy Burru wrote:
> > > > We have a follow up patch after this series implementing
> > > > ndo_get_vf_xxx() and ndo_set_vf_xxx().
> > >
> > > We don't accept new drivers which use those interfaces.
> >
> > Kindly suggest the acceptable interface.
> 
> Kindly make the minimal effort to follow the list :/
> 
> Perhaps others have the time to explain things to you, I believe my time is
> best spent elsewhere.

I see the new drivers have to implement VF representors.
Will resubmit the patchset with representor support.

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2022-12-14  7:15 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-29 13:09 [PATCH net-next v2 0/9] octeon_ep: Update PF mailbox for VF Veerasenareddy Burru
2022-11-29 13:09 ` [PATCH net-next v2 1/9] octeon_ep: defer probe if firmware not ready Veerasenareddy Burru
2022-11-30  9:24   ` Leon Romanovsky
2022-11-30 15:50     ` [EXT] " Veerasenareddy Burru
2022-11-29 13:09 ` [PATCH net-next v2 2/9] octeon_ep: poll for control messages Veerasenareddy Burru
2022-11-30  9:30   ` Leon Romanovsky
2022-11-30 15:44     ` [EXT] " Veerasenareddy Burru
2022-12-01  8:11       ` Leon Romanovsky
2022-12-05  4:46         ` Veerasenareddy Burru
2022-12-05  8:10           ` Leon Romanovsky
2022-12-06  0:16             ` Jakub Kicinski
2022-12-06  8:58               ` Leon Romanovsky
2022-12-06 17:23                 ` Jakub Kicinski
2022-12-06 21:19                   ` Veerasenareddy Burru
2022-12-07  1:26                     ` Jakub Kicinski
2022-12-08  3:17                       ` Veerasenareddy Burru
2022-12-08  4:02                         ` Jakub Kicinski
2022-12-08  4:41                           ` Veerasenareddy Burru
2022-12-08  4:47                             ` Jakub Kicinski
2022-12-14  7:15                               ` Veerasenareddy Burru
2022-11-29 13:09 ` [PATCH net-next v2 3/9] octeon_ep: control mailbox for multiple PFs Veerasenareddy Burru
2022-11-29 13:09 ` [PATCH net-next v2 4/9] octeon_ep: enhance control mailbox for VF support Veerasenareddy Burru
2022-11-29 13:09 ` [PATCH net-next v2 5/9] octeon_ep: support asynchronous notifications Veerasenareddy Burru
2022-11-29 13:09 ` [PATCH net-next v2 6/9] octeon_ep: control mbox support for VF stats and link info Veerasenareddy Burru
2022-11-29 13:09 ` [PATCH net-next v2 7/9] octeon_ep: add SRIOV VF creation Veerasenareddy Burru
2022-11-29 13:09 ` [PATCH net-next v2 8/9] octeon_ep: add PF-VF mailbox communication Veerasenareddy Burru
2022-12-09  8:48   ` Dan Carpenter
2022-11-29 13:09 ` [PATCH net-next v2 9/9] octeon_ep: add heartbeat monitor Veerasenareddy Burru

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).