All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/5] liquidio CN23XX VF support
@ 2016-09-09 20:08 Raghu Vatsavayi
  2016-09-09 20:08 ` [PATCH net-next 1/5] liquidio CN23XX: VF config support Raghu Vatsavayi
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Raghu Vatsavayi @ 2016-09-09 20:08 UTC (permalink / raw)
  To: davem; +Cc: netdev, Raghu Vatsavayi

Dave,

Following is the initial patch series for adding support of
VF functionality on CN23XX devices. Please apply patches in
the following order as some of the patches depend on earlier
patches.

Raghu Vatsavayi (5):
  liquidio CN23XX: VF config support
  liquidio CN23XX: sriov enable
  liquidio CN23XX: Mailbox support
  liquidio CN23XX: mailbox interrupt processing
  liquidio CN23XX: VF related operations

 drivers/net/ethernet/cavium/liquidio/Makefile      |   1 +
 .../ethernet/cavium/liquidio/cn23xx_pf_device.c    | 700 +++++++++++++++------
 .../ethernet/cavium/liquidio/cn23xx_pf_device.h    |   3 +
 .../net/ethernet/cavium/liquidio/cn66xx_device.c   |  13 +-
 .../net/ethernet/cavium/liquidio/cn68xx_device.c   |  13 +-
 drivers/net/ethernet/cavium/liquidio/lio_core.c    |  32 +
 drivers/net/ethernet/cavium/liquidio/lio_main.c    | 366 +++++++++--
 .../net/ethernet/cavium/liquidio/liquidio_common.h |  11 +-
 .../net/ethernet/cavium/liquidio/octeon_config.h   |   8 +
 .../net/ethernet/cavium/liquidio/octeon_console.c  |  16 +-
 .../net/ethernet/cavium/liquidio/octeon_device.c   |  11 +-
 .../net/ethernet/cavium/liquidio/octeon_device.h   |  32 +-
 drivers/net/ethernet/cavium/liquidio/octeon_droq.c |  28 +-
 .../net/ethernet/cavium/liquidio/octeon_mailbox.c  | 322 ++++++++++
 .../net/ethernet/cavium/liquidio/octeon_mailbox.h  | 116 ++++
 drivers/net/ethernet/cavium/liquidio/octeon_main.h |  12 +-
 .../net/ethernet/cavium/liquidio/request_manager.c |   9 +-
 17 files changed, 1409 insertions(+), 284 deletions(-)
 create mode 100644 drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
 create mode 100644 drivers/net/ethernet/cavium/liquidio/octeon_mailbox.h

-- 
1.8.3.1

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

* [PATCH net-next 1/5] liquidio CN23XX: VF config support
  2016-09-09 20:08 [PATCH net-next 0/5] liquidio CN23XX VF support Raghu Vatsavayi
@ 2016-09-09 20:08 ` Raghu Vatsavayi
  2016-09-09 20:08 ` [PATCH net-next 2/5] liquidio CN23XX: sriov enable Raghu Vatsavayi
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Raghu Vatsavayi @ 2016-09-09 20:08 UTC (permalink / raw)
  To: davem
  Cc: netdev, Raghu Vatsavayi, Derek Chickles, Satanand Burla,
	Felix Manlunas, Raghu Vatsavayi

Adds support for VF configuration. It also limits the number
of rings per VF based on total number of VFs configured.

Signed-off-by: Derek Chickles <derek.chickles@caviumnetworks.com>
Signed-off-by: Satanand Burla <satananda.burla@caviumnetworks.com>
Signed-off-by: Felix Manlunas <felix.manlunas@caviumnetworks.com>
Signed-off-by: Raghu Vatsavayi <raghu.vatsavayi@caviumnetworks.com>
---
 .../ethernet/cavium/liquidio/cn23xx_pf_device.c    | 260 ++++++++++++++++-----
 .../net/ethernet/cavium/liquidio/cn66xx_device.c   |  13 +-
 .../net/ethernet/cavium/liquidio/octeon_config.h   |   5 +
 .../net/ethernet/cavium/liquidio/octeon_device.c   |  10 +-
 .../net/ethernet/cavium/liquidio/octeon_device.h   |   9 +-
 5 files changed, 228 insertions(+), 69 deletions(-)

diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
index bddb198..a2953d5 100644
--- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
+++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
@@ -312,11 +312,12 @@ static void cn23xx_setup_global_mac_regs(struct octeon_device *oct)
 	u64 reg_val;
 	u16 mac_no = oct->pcie_port;
 	u16 pf_num = oct->pf_num;
+	u64 temp;
 
 	/* programming SRN and TRS for each MAC(0..3)  */
 
-	dev_dbg(&oct->pci_dev->dev, "%s:Using pcie port %d\n",
-		__func__, mac_no);
+	pr_devel("%s:Using pcie port %d\n",
+		 __func__, mac_no);
 	/* By default, mapping all 64 IOQs to  a single MACs */
 
 	reg_val =
@@ -333,13 +334,21 @@ static void cn23xx_setup_global_mac_regs(struct octeon_device *oct)
 	/* setting TRS <23:16> */
 	reg_val = reg_val |
 		  (oct->sriov_info.trs << CN23XX_PKT_MAC_CTL_RINFO_TRS_BIT_POS);
+	/* setting RPVF <39:32> */
+	temp = oct->sriov_info.rings_per_vf & 0xff;
+	reg_val |= (temp << CN23XX_PKT_MAC_CTL_RINFO_RPVF_BIT_POS);
+
+	/* setting NVFS <55:48> */
+	temp = oct->sriov_info.num_vfs & 0xff;
+	reg_val |= (temp << CN23XX_PKT_MAC_CTL_RINFO_NVFS_BIT_POS);
+
 	/* write these settings to MAC register */
 	octeon_write_csr64(oct, CN23XX_SLI_PKT_MAC_RINFO64(mac_no, pf_num),
 			   reg_val);
 
-	dev_dbg(&oct->pci_dev->dev, "SLI_PKT_MAC(%d)_PF(%d)_RINFO : 0x%016llx\n",
-		mac_no, pf_num, (u64)octeon_read_csr64
-		(oct, CN23XX_SLI_PKT_MAC_RINFO64(mac_no, pf_num)));
+	pr_devel("SLI_PKT_MAC(%d)_PF(%d)_RINFO : 0x%016llx\n",
+		 mac_no, pf_num, (u64)octeon_read_csr64
+		 (oct, CN23XX_SLI_PKT_MAC_RINFO64(mac_no, pf_num)));
 }
 
 static int cn23xx_reset_io_queues(struct octeon_device *oct)
@@ -404,6 +413,7 @@ static int cn23xx_pf_setup_global_input_regs(struct octeon_device *oct)
 	u64 intr_threshold, reg_val;
 	struct octeon_instr_queue *iq;
 	struct octeon_cn23xx_pf *cn23xx = (struct octeon_cn23xx_pf *)oct->chip;
+	u64 vf_num;
 
 	pf_num = oct->pf_num;
 
@@ -420,6 +430,16 @@ static int cn23xx_pf_setup_global_input_regs(struct octeon_device *oct)
 	*/
 	for (q_no = 0; q_no < ern; q_no++) {
 		reg_val = oct->pcie_port << CN23XX_PKT_INPUT_CTL_MAC_NUM_POS;
+
+		/* for VF assigned queues. */
+		if (q_no < oct->sriov_info.pf_srn) {
+			vf_num = q_no / oct->sriov_info.rings_per_vf;
+			vf_num += 1; /* VF1, VF2,........ */
+		} else {
+			vf_num = 0;
+		}
+
+		reg_val |= vf_num << CN23XX_PKT_INPUT_CTL_VF_NUM_POS;
 		reg_val |= pf_num << CN23XX_PKT_INPUT_CTL_PF_NUM_POS;
 
 		octeon_write_csr64(oct, CN23XX_SLI_IQ_PKT_CONTROL64(q_no),
@@ -590,8 +610,8 @@ static void cn23xx_setup_iq_regs(struct octeon_device *oct, u32 iq_no)
 	    (u8 *)oct->mmio[0].hw_addr + CN23XX_SLI_IQ_DOORBELL(iq_no);
 	iq->inst_cnt_reg =
 	    (u8 *)oct->mmio[0].hw_addr + CN23XX_SLI_IQ_INSTR_COUNT64(iq_no);
-	dev_dbg(&oct->pci_dev->dev, "InstQ[%d]:dbell reg @ 0x%p instcnt_reg @ 0x%p\n",
-		iq_no, iq->doorbell_reg, iq->inst_cnt_reg);
+	pr_devel("InstQ[%d]:dbell reg @ 0x%p instcnt_reg @ 0x%p\n",
+		 iq_no, iq->doorbell_reg, iq->inst_cnt_reg);
 
 	/* Store the current instruction counter (used in flush_iq
 	 * calculation)
@@ -822,7 +842,7 @@ static u64 cn23xx_pf_msix_interrupt_handler(void *dev)
 	u64 ret = 0;
 	struct octeon_droq *droq = oct->droq[ioq_vector->droq_index];
 
-	dev_dbg(&oct->pci_dev->dev, "In %s octeon_dev @ %p\n", __func__, oct);
+	pr_devel("In %s octeon_dev @ %p\n", __func__, oct);
 
 	if (!droq) {
 		dev_err(&oct->pci_dev->dev, "23XX bringup FIXME: oct pfnum:%d ioq_vector->ioq_num :%d droq is NULL\n",
@@ -862,7 +882,7 @@ static irqreturn_t cn23xx_interrupt_handler(void *dev)
 	struct octeon_cn23xx_pf *cn23xx = (struct octeon_cn23xx_pf *)oct->chip;
 	u64 intr64;
 
-	dev_dbg(&oct->pci_dev->dev, "In %s octeon_dev @ %p\n", __func__, oct);
+	pr_devel("In %s octeon_dev @ %p\n", __func__, oct);
 	intr64 = readq(cn23xx->intr_sum_reg64);
 
 	oct->int_status = 0;
@@ -983,8 +1003,8 @@ static void cn23xx_get_pcie_qlmport(struct octeon_device *oct)
 {
 	oct->pcie_port = (octeon_read_csr(oct, CN23XX_SLI_MAC_NUMBER)) & 0xff;
 
-	dev_dbg(&oct->pci_dev->dev, "OCTEON: CN23xx uses PCIE Port %d\n",
-		oct->pcie_port);
+	pr_devel("OCTEON: CN23xx uses PCIE Port %d\n",
+		 oct->pcie_port);
 }
 
 static void cn23xx_get_pf_num(struct octeon_device *oct)
@@ -1046,11 +1066,27 @@ static void cn23xx_setup_reg_address(struct octeon_device *oct)
 	    CN23XX_SLI_MAC_PF_INT_ENB64(oct->pcie_port, oct->pf_num);
 }
 
+static u32 lower_pow(u32 num)
+{
+	u32 n = num > 0 ? num - 1 : 0;
+
+	n |= n >> 1;
+	n |= n >> 2;
+	n |= n >> 4;
+	n |= n >> 8;
+	n |= n >> 16;
+	n++;
+
+	return ((n > num) ? (n >> 1) : n);
+}
+
 static int cn23xx_sriov_config(struct octeon_device *oct)
 {
 	u32 total_rings;
 	struct octeon_cn23xx_pf *cn23xx = (struct octeon_cn23xx_pf *)oct->chip;
 	/* num_vfs is already filled for us */
+	u32 num_vfs = oct->sriov_info.num_vfs;
+	u32 rings_per_vf, max_vfs;
 	u32 pf_srn, num_pf_rings;
 
 	cn23xx->conf =
@@ -1058,40 +1094,150 @@ static int cn23xx_sriov_config(struct octeon_device *oct)
 	switch (oct->rev_id) {
 	case OCTEON_CN23XX_REV_1_0:
 		total_rings = CN23XX_MAX_RINGS_PER_PF_PASS_1_0;
+		max_vfs = CN23XX_MAX_VFS_PER_PF_PASS_1_0;
 		break;
 	case OCTEON_CN23XX_REV_1_1:
 		total_rings = CN23XX_MAX_RINGS_PER_PF_PASS_1_1;
+		max_vfs = CN23XX_MAX_VFS_PER_PF_PASS_1_1;
 		break;
 	default:
 		total_rings = CN23XX_MAX_RINGS_PER_PF;
+		max_vfs = CN23XX_MAX_VFS_PER_PF;
 		break;
 	}
-	if (!oct->sriov_info.num_pf_rings) {
-		if (total_rings > num_present_cpus())
-			num_pf_rings = num_present_cpus();
-		else
-			num_pf_rings = total_rings;
+
+	if (num_vfs > min((total_rings - 1), max_vfs)) {
+		dev_warn(&oct->pci_dev->dev, "num_vfs requested %u is more than available rings. Reducing to %u\n",
+			 num_vfs, min((total_rings - 1), max_vfs));
+		num_vfs = min((total_rings - 1), max_vfs);
+	}
+
+	if (!num_vfs) {
+		pr_devel("num_vfs is zero, SRIOV is not enabled...\n");
+
+		if (oct->sriov_info.rings_per_vf > 0)
+			dev_warn(&oct->pci_dev->dev, "num_queues_per_vf is ignored because num_vfs=0.\n");
+
+		rings_per_vf = 0;
+
+		if (!oct->sriov_info.num_pf_rings) {
+			if (total_rings > num_present_cpus())
+				num_pf_rings = num_present_cpus();
+			else
+				num_pf_rings = total_rings;
+		} else {
+			num_pf_rings = oct->sriov_info.num_pf_rings;
+
+			if (num_pf_rings > total_rings) {
+				dev_warn(&oct->pci_dev->dev,
+					 "num_queues_per_pf requested %u is more than available rings. Reducing to %u\n",
+					 num_pf_rings, total_rings);
+				num_pf_rings = total_rings;
+			}
+		}
+
+		total_rings = num_pf_rings;
+
 	} else {
-		num_pf_rings = oct->sriov_info.num_pf_rings;
+		if (!oct->sriov_info.rings_per_vf) {
+			if (oct->sriov_info.num_pf_rings > 0) {
+				num_pf_rings = oct->sriov_info.num_pf_rings;
+				if (num_pf_rings > (total_rings - num_vfs)) {
+					num_pf_rings = total_rings - num_vfs;
+					dev_warn(&oct->pci_dev->dev,
+						 "num_queues_per_pf requested %u is more than available rings. Reducing to %u\n",
+						 oct->sriov_info.num_pf_rings,
+						 num_pf_rings);
+				}
+				rings_per_vf = lower_pow(
+						(total_rings - num_pf_rings) /
+						num_vfs);
+				rings_per_vf = min_t(u32, rings_per_vf,
+						     CN23XX_MAX_RINGS_PER_VF);
+			} else {
+				if ((oct->rev_id == OCTEON_CN23XX_REV_1_0) &&
+				    (num_vfs >= LIOLUT_RING_DISTRIBUTION)) {
+					rings_per_vf = 1;
+					total_rings = num_vfs + 1;
+				} else if (oct->rev_id ==
+					   OCTEON_CN23XX_REV_1_0) {
+					rings_per_vf =
+						liolut_num_vfs_to_rings_per_vf
+						[num_vfs];
+				} else {
+					rings_per_vf = lower_pow(total_rings /
+								 (num_vfs + 1));
+				}
+				rings_per_vf = min_t(u32, rings_per_vf,
+						     CN23XX_MAX_RINGS_PER_VF);
+				num_pf_rings = total_rings -
+					(rings_per_vf * num_vfs);
+
+				if (num_pf_rings > num_present_cpus()) {
+					num_pf_rings = num_present_cpus();
+					total_rings = num_pf_rings +
+						rings_per_vf * num_vfs;
+				}
+			}
+		} else {
+			u32 i;
+
+			i = lower_pow((total_rings - 1) / num_vfs);
+
+			if (oct->sriov_info.rings_per_vf >
+			    min_t(u32, i, CN23XX_MAX_RINGS_PER_VF)) {
+				rings_per_vf = min_t(u32, i,
+						     CN23XX_MAX_RINGS_PER_VF);
+				dev_warn(&oct->pci_dev->dev,
+					 "num_queues_per_vf requested %u is more than available rings. Reducing to %u\n",
+					 oct->sriov_info.rings_per_vf,
+					 rings_per_vf);
+			} else {
+				rings_per_vf = lower_pow(
+						oct->sriov_info.rings_per_vf);
+
+				if (rings_per_vf !=
+				    oct->sriov_info.rings_per_vf) {
+					dev_warn(&oct->pci_dev->dev,
+						 "num_queues_per_vf requested %u is not power of two. Reducing to %u\n",
+						 oct->sriov_info.rings_per_vf,
+						 rings_per_vf);
+				}
+			}
 
-		if (num_pf_rings > total_rings) {
-			dev_warn(&oct->pci_dev->dev,
-				 "num_queues_per_pf requested %u is more than available rings. Reducing to %u\n",
-				 num_pf_rings, total_rings);
-			num_pf_rings = total_rings;
+			if (!oct->sriov_info.num_pf_rings) {
+				num_pf_rings = total_rings -
+					(rings_per_vf * num_vfs);
+			} else {
+				num_pf_rings = oct->sriov_info.num_pf_rings;
+
+				if ((num_pf_rings + (num_vfs * rings_per_vf)) >
+				    total_rings) {
+					num_pf_rings = total_rings -
+						(rings_per_vf * num_vfs);
+					dev_warn(&oct->pci_dev->dev,
+						 "num_queues_per_pf requested %u is more than available rings. Reducing to %u\n",
+						 oct->sriov_info.num_pf_rings,
+						 num_pf_rings);
+				}
+			}
 		}
 	}
 
-	total_rings = num_pf_rings;
+	total_rings = num_pf_rings + (num_vfs * rings_per_vf);
+
 	/* the first ring of the pf */
 	pf_srn = total_rings - num_pf_rings;
 
 	oct->sriov_info.trs = total_rings;
+	oct->sriov_info.num_vfs = num_vfs;
+	oct->sriov_info.rings_per_vf = rings_per_vf;
 	oct->sriov_info.pf_srn = pf_srn;
 	oct->sriov_info.num_pf_rings = num_pf_rings;
-	dev_dbg(&oct->pci_dev->dev, "trs:%d pf_srn:%d num_pf_rings:%d\n",
-		oct->sriov_info.trs, oct->sriov_info.pf_srn,
-		oct->sriov_info.num_pf_rings);
+	pr_devel("trs:%d num_vfs:%d rings_per_vf:%d pf_srn:%d num_pf_rings:%d\n",
+		 oct->sriov_info.trs, oct->sriov_info.num_vfs,
+		 oct->sriov_info.rings_per_vf, oct->sriov_info.pf_srn,
+		 oct->sriov_info.num_pf_rings);
 	return 0;
 }
 
@@ -1187,45 +1333,45 @@ void cn23xx_dump_iq_regs(struct octeon_device *oct)
 {
 	u32 regval, q_no;
 
-	dev_dbg(&oct->pci_dev->dev, "SLI_IQ_DOORBELL_0 [0x%x]: 0x%016llx\n",
-		CN23XX_SLI_IQ_DOORBELL(0),
-		CVM_CAST64(octeon_read_csr64
-			(oct, CN23XX_SLI_IQ_DOORBELL(0))));
+	pr_devel("SLI_IQ_DOORBELL_0 [0x%x]: 0x%016llx\n",
+		 CN23XX_SLI_IQ_DOORBELL(0),
+		 CVM_CAST64(octeon_read_csr64
+			 (oct, CN23XX_SLI_IQ_DOORBELL(0))));
 
-	dev_dbg(&oct->pci_dev->dev, "SLI_IQ_BASEADDR_0 [0x%x]: 0x%016llx\n",
-		CN23XX_SLI_IQ_BASE_ADDR64(0),
-		CVM_CAST64(octeon_read_csr64
-			(oct, CN23XX_SLI_IQ_BASE_ADDR64(0))));
+	pr_devel("SLI_IQ_BASEADDR_0 [0x%x]: 0x%016llx\n",
+		 CN23XX_SLI_IQ_BASE_ADDR64(0),
+		 CVM_CAST64(octeon_read_csr64
+			 (oct, CN23XX_SLI_IQ_BASE_ADDR64(0))));
 
-	dev_dbg(&oct->pci_dev->dev, "SLI_IQ_FIFO_RSIZE_0 [0x%x]: 0x%016llx\n",
-		CN23XX_SLI_IQ_SIZE(0),
-		CVM_CAST64(octeon_read_csr64(oct, CN23XX_SLI_IQ_SIZE(0))));
+	pr_devel("SLI_IQ_FIFO_RSIZE_0 [0x%x]: 0x%016llx\n",
+		 CN23XX_SLI_IQ_SIZE(0),
+		 CVM_CAST64(octeon_read_csr64(oct, CN23XX_SLI_IQ_SIZE(0))));
 
-	dev_dbg(&oct->pci_dev->dev, "SLI_CTL_STATUS [0x%x]: 0x%016llx\n",
-		CN23XX_SLI_CTL_STATUS,
-		CVM_CAST64(octeon_read_csr64(oct, CN23XX_SLI_CTL_STATUS)));
+	pr_devel("SLI_CTL_STATUS [0x%x]: 0x%016llx\n",
+		 CN23XX_SLI_CTL_STATUS,
+		 CVM_CAST64(octeon_read_csr64(oct, CN23XX_SLI_CTL_STATUS)));
 
 	for (q_no = 0; q_no < CN23XX_MAX_INPUT_QUEUES; q_no++) {
-		dev_dbg(&oct->pci_dev->dev, "SLI_PKT[%d]_INPUT_CTL [0x%x]: 0x%016llx\n",
-			q_no, CN23XX_SLI_IQ_PKT_CONTROL64(q_no),
-			CVM_CAST64(octeon_read_csr64
-				(oct,
-					CN23XX_SLI_IQ_PKT_CONTROL64(q_no))));
+		pr_devel("SLI_PKT[%d]_INPUT_CTL [0x%x]: 0x%016llx\n",
+			 q_no, CN23XX_SLI_IQ_PKT_CONTROL64(q_no),
+			 CVM_CAST64(octeon_read_csr64
+				 (oct,
+					 CN23XX_SLI_IQ_PKT_CONTROL64(q_no))));
 	}
 
 	pci_read_config_dword(oct->pci_dev, CN23XX_CONFIG_PCIE_DEVCTL, &regval);
-	dev_dbg(&oct->pci_dev->dev, "Config DevCtl [0x%x]: 0x%08x\n",
-		CN23XX_CONFIG_PCIE_DEVCTL, regval);
-
-	dev_dbg(&oct->pci_dev->dev, "SLI_PRT[%d]_CFG [0x%llx]: 0x%016llx\n",
-		oct->pcie_port, CN23XX_DPI_SLI_PRTX_CFG(oct->pcie_port),
-		CVM_CAST64(lio_pci_readq(
-			oct, CN23XX_DPI_SLI_PRTX_CFG(oct->pcie_port))));
-
-	dev_dbg(&oct->pci_dev->dev, "SLI_S2M_PORT[%d]_CTL [0x%x]: 0x%016llx\n",
-		oct->pcie_port, CN23XX_SLI_S2M_PORTX_CTL(oct->pcie_port),
-		CVM_CAST64(octeon_read_csr64(
-			oct, CN23XX_SLI_S2M_PORTX_CTL(oct->pcie_port))));
+	pr_devel("Config DevCtl [0x%x]: 0x%08x\n",
+		 CN23XX_CONFIG_PCIE_DEVCTL, regval);
+
+	pr_devel("SLI_PRT[%d]_CFG [0x%llx]: 0x%016llx\n",
+		 oct->pcie_port, CN23XX_DPI_SLI_PRTX_CFG(oct->pcie_port),
+		 CVM_CAST64(lio_pci_readq(
+			 oct, CN23XX_DPI_SLI_PRTX_CFG(oct->pcie_port))));
+
+	pr_devel("SLI_S2M_PORT[%d]_CTL [0x%x]: 0x%016llx\n",
+		 oct->pcie_port, CN23XX_SLI_S2M_PORTX_CTL(oct->pcie_port),
+		 CVM_CAST64(octeon_read_csr64(
+			 oct, CN23XX_SLI_S2M_PORTX_CTL(oct->pcie_port))));
 }
 
 int cn23xx_fw_loaded(struct octeon_device *oct)
diff --git a/drivers/net/ethernet/cavium/liquidio/cn66xx_device.c b/drivers/net/ethernet/cavium/liquidio/cn66xx_device.c
index e779af8..9fb788d 100644
--- a/drivers/net/ethernet/cavium/liquidio/cn66xx_device.c
+++ b/drivers/net/ethernet/cavium/liquidio/cn66xx_device.c
@@ -19,6 +19,7 @@
 * This file may also be available under a different license from Cavium.
 * Contact Cavium, Inc. for more information
 **********************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include "liquidio_common.h"
@@ -34,7 +35,7 @@ int lio_cn6xxx_soft_reset(struct octeon_device *oct)
 {
 	octeon_write_csr64(oct, CN6XXX_WIN_WR_MASK_REG, 0xFF);
 
-	dev_dbg(&oct->pci_dev->dev, "BIST enabled for soft reset\n");
+	pr_devel("BIST enabled for soft reset\n");
 
 	lio_pci_writeq(oct, 1, CN6XXX_CIU_SOFT_BIST);
 	octeon_write_csr64(oct, CN6XXX_SLI_SCRATCH1, 0x1234ULL);
@@ -53,7 +54,7 @@ int lio_cn6xxx_soft_reset(struct octeon_device *oct)
 		return 1;
 	}
 
-	dev_dbg(&oct->pci_dev->dev, "Reset completed\n");
+	pr_devel("Reset completed\n");
 	octeon_write_csr64(oct, CN6XXX_WIN_WR_MASK_REG, 0xFF);
 
 	return 0;
@@ -71,7 +72,7 @@ void lio_cn6xxx_enable_error_reporting(struct octeon_device *oct)
 
 	val |= 0xf;          /* Enable Link error reporting */
 
-	dev_dbg(&oct->pci_dev->dev, "Enabling PCI-E error reporting..\n");
+	pr_devel("Enabling PCI-E error reporting..\n");
 	pci_write_config_dword(oct->pci_dev, CN6XXX_PCIE_DEVCTL, val);
 }
 
@@ -289,8 +290,8 @@ void lio_cn6xxx_setup_iq_regs(struct octeon_device *oct, u32 iq_no)
 	iq->doorbell_reg = oct->mmio[0].hw_addr + CN6XXX_SLI_IQ_DOORBELL(iq_no);
 	iq->inst_cnt_reg = oct->mmio[0].hw_addr
 			   + CN6XXX_SLI_IQ_INSTR_COUNT(iq_no);
-	dev_dbg(&oct->pci_dev->dev, "InstQ[%d]:dbell reg @ 0x%p instcnt_reg @ 0x%p\n",
-		iq_no, iq->doorbell_reg, iq->inst_cnt_reg);
+	pr_devel("InstQ[%d]:dbell reg @ 0x%p instcnt_reg @ 0x%p\n",
+		 iq_no, iq->doorbell_reg, iq->inst_cnt_reg);
 
 	/* Store the current instruction counter
 	 * (used in flush_iq calculation)
@@ -508,7 +509,7 @@ static void lio_cn6xxx_get_pcie_qlmport(struct octeon_device *oct)
 	 */
 	oct->pcie_port = octeon_read_csr(oct, CN6XXX_SLI_MAC_NUMBER) & 0xff;
 
-	dev_dbg(&oct->pci_dev->dev, "Using PCIE Port %d\n", oct->pcie_port);
+	pr_devel("Using PCIE Port %d\n", oct->pcie_port);
 }
 
 static void
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_config.h b/drivers/net/ethernet/cavium/liquidio/octeon_config.h
index c765568..0127a0e 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_config.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_config.h
@@ -65,6 +65,11 @@
 #define   DEFAULT_NUM_NIC_PORTS_68XX_210NV  2
 
 /* CN23xx  IQ configuration macros */
+#define   CN23XX_MAX_VFS_PER_PF_PASS_1_0 8
+#define   CN23XX_MAX_VFS_PER_PF_PASS_1_1 31
+#define   CN23XX_MAX_VFS_PER_PF          63
+#define   CN23XX_MAX_RINGS_PER_VF        8
+
 #define   CN23XX_MAX_RINGS_PER_PF_PASS_1_0 12
 #define   CN23XX_MAX_RINGS_PER_PF_PASS_1_1 32
 #define   CN23XX_MAX_RINGS_PER_PF          64
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.c b/drivers/net/ethernet/cavium/liquidio/octeon_device.c
index 586b688..03a4eac 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_device.c
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.c
@@ -19,6 +19,7 @@
 * This file may also be available under a different license from Cavium.
 * Contact Cavium, Inc. for more information
 **********************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
@@ -1028,8 +1029,7 @@ octeon_register_dispatch_fn(struct octeon_device *oct,
 	if (!pfn) {
 		struct octeon_dispatch *dispatch;
 
-		dev_dbg(&oct->pci_dev->dev,
-			"Adding opcode to dispatch list linked list\n");
+		pr_devel("Adding opcode to dispatch list linked list\n");
 		dispatch = (struct octeon_dispatch *)
 			   vmalloc(sizeof(struct octeon_dispatch));
 		if (!dispatch) {
@@ -1113,9 +1113,9 @@ int octeon_core_drv_init(struct octeon_recv_info *recv_info, void *buf)
 	cs = &core_setup[oct->octeon_id];
 
 	if (recv_pkt->buffer_size[0] != sizeof(*cs)) {
-		dev_dbg(&oct->pci_dev->dev, "Core setup bytes expected %u found %d\n",
-			(u32)sizeof(*cs),
-			recv_pkt->buffer_size[0]);
+		pr_devel("Core setup bytes expected %u found %d\n",
+			 (u32)sizeof(*cs),
+			 recv_pkt->buffer_size[0]);
 	}
 
 	memcpy(cs, get_rbd(recv_pkt->buffer_ptr[0]), sizeof(*cs));
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.h b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
index da15c2a..89381ba 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_device.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
@@ -322,11 +322,18 @@ struct octeon_pf_vf_hs_word {
 };
 
 struct octeon_sriov_info {
+	/* Number of rings assigned to VF */
+	u32	rings_per_vf;
+
+	/* Number of VF devices enabled */
+	u32	num_vfs;
+
 	/* Actual rings left for PF device */
 	u32	num_pf_rings;
 
-	/* SRN of PF usable IO queues   */
+	/* SRN of PF usable IO queues */
 	u32	pf_srn;
+
 	/* total pf rings */
 	u32	trs;
 
-- 
1.8.3.1

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

* [PATCH net-next 2/5] liquidio CN23XX: sriov enable
  2016-09-09 20:08 [PATCH net-next 0/5] liquidio CN23XX VF support Raghu Vatsavayi
  2016-09-09 20:08 ` [PATCH net-next 1/5] liquidio CN23XX: VF config support Raghu Vatsavayi
@ 2016-09-09 20:08 ` Raghu Vatsavayi
  2016-09-11 12:53   ` Yuval Mintz
  2016-09-09 20:08 ` [PATCH net-next 3/5] liquidio CN23XX: Mailbox support Raghu Vatsavayi
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Raghu Vatsavayi @ 2016-09-09 20:08 UTC (permalink / raw)
  To: davem
  Cc: netdev, Raghu Vatsavayi, Derek Chickles, Satanand Burla,
	Felix Manlunas, Raghu Vatsavayi

Adds support for enabling sriov on CN23XX cards.

Signed-off-by: Derek Chickles <derek.chickles@caviumnetworks.com>
Signed-off-by: Satanand Burla <satananda.burla@caviumnetworks.com>
Signed-off-by: Felix Manlunas <felix.manlunas@caviumnetworks.com>
Signed-off-by: Raghu Vatsavayi <raghu.vatsavayi@caviumnetworks.com>
---
 .../ethernet/cavium/liquidio/cn23xx_pf_device.c    | 257 +++++++++++----------
 drivers/net/ethernet/cavium/liquidio/lio_main.c    | 147 ++++++++----
 .../net/ethernet/cavium/liquidio/octeon_config.h   |   3 +
 .../net/ethernet/cavium/liquidio/octeon_device.h   |   5 +
 4 files changed, 241 insertions(+), 171 deletions(-)

diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
index a2953d5..deec869 100644
--- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
+++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
@@ -19,7 +19,7 @@
 * This file may also be available under a different license from Cavium.
 * Contact Cavium, Inc. for more information
 **********************************************************************/
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
@@ -52,174 +52,174 @@ void cn23xx_dump_pf_initialized_regs(struct octeon_device *oct)
 	struct octeon_cn23xx_pf *cn23xx = (struct octeon_cn23xx_pf *)oct->chip;
 
 	/*In cn23xx_soft_reset*/
-	dev_dbg(&oct->pci_dev->dev, "%s[%llx] : 0x%llx\n",
-		"CN23XX_WIN_WR_MASK_REG", CVM_CAST64(CN23XX_WIN_WR_MASK_REG),
-		CVM_CAST64(octeon_read_csr64(oct, CN23XX_WIN_WR_MASK_REG)));
-	dev_dbg(&oct->pci_dev->dev, "%s[%llx] : 0x%016llx\n",
-		"CN23XX_SLI_SCRATCH1", CVM_CAST64(CN23XX_SLI_SCRATCH1),
-		CVM_CAST64(octeon_read_csr64(oct, CN23XX_SLI_SCRATCH1)));
-	dev_dbg(&oct->pci_dev->dev, "%s[%llx] : 0x%016llx\n",
-		"CN23XX_RST_SOFT_RST", CN23XX_RST_SOFT_RST,
-		lio_pci_readq(oct, CN23XX_RST_SOFT_RST));
+	pr_devel("%s[%llx] : 0x%llx\n",
+		 "CN23XX_WIN_WR_MASK_REG", CVM_CAST64(CN23XX_WIN_WR_MASK_REG),
+		 CVM_CAST64(octeon_read_csr64(oct, CN23XX_WIN_WR_MASK_REG)));
+	pr_devel("%s[%llx] : 0x%016llx\n",
+		 "CN23XX_SLI_SCRATCH1", CVM_CAST64(CN23XX_SLI_SCRATCH1),
+		 CVM_CAST64(octeon_read_csr64(oct, CN23XX_SLI_SCRATCH1)));
+	pr_devel("%s[%llx] : 0x%016llx\n",
+		 "CN23XX_RST_SOFT_RST", CN23XX_RST_SOFT_RST,
+		 lio_pci_readq(oct, CN23XX_RST_SOFT_RST));
 
 	/*In cn23xx_set_dpi_regs*/
-	dev_dbg(&oct->pci_dev->dev, "%s[%llx] : 0x%016llx\n",
-		"CN23XX_DPI_DMA_CONTROL", CN23XX_DPI_DMA_CONTROL,
-		lio_pci_readq(oct, CN23XX_DPI_DMA_CONTROL));
+	pr_devel("%s[%llx] : 0x%016llx\n",
+		 "CN23XX_DPI_DMA_CONTROL", CN23XX_DPI_DMA_CONTROL,
+		 lio_pci_readq(oct, CN23XX_DPI_DMA_CONTROL));
 
 	for (i = 0; i < 6; i++) {
-		dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-			"CN23XX_DPI_DMA_ENG_ENB", i,
-			CN23XX_DPI_DMA_ENG_ENB(i),
-			lio_pci_readq(oct, CN23XX_DPI_DMA_ENG_ENB(i)));
-		dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-			"CN23XX_DPI_DMA_ENG_BUF", i,
-			CN23XX_DPI_DMA_ENG_BUF(i),
-			lio_pci_readq(oct, CN23XX_DPI_DMA_ENG_BUF(i)));
+		pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+			 "CN23XX_DPI_DMA_ENG_ENB", i,
+			 CN23XX_DPI_DMA_ENG_ENB(i),
+			 lio_pci_readq(oct, CN23XX_DPI_DMA_ENG_ENB(i)));
+		pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+			 "CN23XX_DPI_DMA_ENG_BUF", i,
+			 CN23XX_DPI_DMA_ENG_BUF(i),
+			 lio_pci_readq(oct, CN23XX_DPI_DMA_ENG_BUF(i)));
 	}
 
-	dev_dbg(&oct->pci_dev->dev, "%s[%llx] : 0x%016llx\n", "CN23XX_DPI_CTL",
-		CN23XX_DPI_CTL, lio_pci_readq(oct, CN23XX_DPI_CTL));
+	pr_devel("%s[%llx] : 0x%016llx\n", "CN23XX_DPI_CTL",
+		 CN23XX_DPI_CTL, lio_pci_readq(oct, CN23XX_DPI_CTL));
 
 	/*In cn23xx_setup_pcie_mps and cn23xx_setup_pcie_mrrs */
 	pci_read_config_dword(oct->pci_dev, CN23XX_CONFIG_PCIE_DEVCTL, &regval);
-	dev_dbg(&oct->pci_dev->dev, "%s[%llx] : 0x%016llx\n",
-		"CN23XX_CONFIG_PCIE_DEVCTL",
-		CVM_CAST64(CN23XX_CONFIG_PCIE_DEVCTL), CVM_CAST64(regval));
+	pr_devel("%s[%llx] : 0x%016llx\n",
+		 "CN23XX_CONFIG_PCIE_DEVCTL",
+		 CVM_CAST64(CN23XX_CONFIG_PCIE_DEVCTL), CVM_CAST64(regval));
 
-	dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-		"CN23XX_DPI_SLI_PRTX_CFG", oct->pcie_port,
-		CN23XX_DPI_SLI_PRTX_CFG(oct->pcie_port),
-		lio_pci_readq(oct, CN23XX_DPI_SLI_PRTX_CFG(oct->pcie_port)));
+	pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+		 "CN23XX_DPI_SLI_PRTX_CFG", oct->pcie_port,
+		 CN23XX_DPI_SLI_PRTX_CFG(oct->pcie_port),
+		 lio_pci_readq(oct, CN23XX_DPI_SLI_PRTX_CFG(oct->pcie_port)));
 
 	/*In cn23xx_specific_regs_setup */
-	dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-		"CN23XX_SLI_S2M_PORTX_CTL", oct->pcie_port,
-		CVM_CAST64(CN23XX_SLI_S2M_PORTX_CTL(oct->pcie_port)),
-		CVM_CAST64(octeon_read_csr64(
-			oct, CN23XX_SLI_S2M_PORTX_CTL(oct->pcie_port))));
+	pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+		 "CN23XX_SLI_S2M_PORTX_CTL", oct->pcie_port,
+		 CVM_CAST64(CN23XX_SLI_S2M_PORTX_CTL(oct->pcie_port)),
+		 CVM_CAST64(octeon_read_csr64(
+			 oct, CN23XX_SLI_S2M_PORTX_CTL(oct->pcie_port))));
 
-	dev_dbg(&oct->pci_dev->dev, "%s[%llx] : 0x%016llx\n",
-		"CN23XX_SLI_RING_RST", CVM_CAST64(CN23XX_SLI_PKT_IOQ_RING_RST),
-		(u64)octeon_read_csr64(oct, CN23XX_SLI_PKT_IOQ_RING_RST));
+	pr_devel("%s[%llx] : 0x%016llx\n",
+		 "CN23XX_SLI_RING_RST", CVM_CAST64(CN23XX_SLI_PKT_IOQ_RING_RST),
+		 (u64)octeon_read_csr64(oct, CN23XX_SLI_PKT_IOQ_RING_RST));
 
 	/*In cn23xx_setup_global_mac_regs*/
 	for (i = 0; i < CN23XX_MAX_MACS; i++) {
-		dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-			"CN23XX_SLI_PKT_MAC_RINFO64", i,
-			CVM_CAST64(CN23XX_SLI_PKT_MAC_RINFO64(i, oct->pf_num)),
-			CVM_CAST64(octeon_read_csr64
-				(oct, CN23XX_SLI_PKT_MAC_RINFO64
-					(i, oct->pf_num))));
+		pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+			 "CN23XX_SLI_PKT_MAC_RINFO64", i,
+			 CVM_CAST64(CN23XX_SLI_PKT_MAC_RINFO64(i, oct->pf_num)),
+			 CVM_CAST64(octeon_read_csr64
+				 (oct, CN23XX_SLI_PKT_MAC_RINFO64
+					 (i, oct->pf_num))));
 	}
 
 	/*In cn23xx_setup_global_input_regs*/
 	for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
-		dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-			"CN23XX_SLI_IQ_PKT_CONTROL64", i,
-			CVM_CAST64(CN23XX_SLI_IQ_PKT_CONTROL64(i)),
-			CVM_CAST64(octeon_read_csr64
-				(oct, CN23XX_SLI_IQ_PKT_CONTROL64(i))));
+		pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+			 "CN23XX_SLI_IQ_PKT_CONTROL64", i,
+			 CVM_CAST64(CN23XX_SLI_IQ_PKT_CONTROL64(i)),
+			 CVM_CAST64(octeon_read_csr64
+				 (oct, CN23XX_SLI_IQ_PKT_CONTROL64(i))));
 	}
 
 	/*In cn23xx_setup_global_output_regs*/
-	dev_dbg(&oct->pci_dev->dev, "%s[%llx] : 0x%016llx\n",
-		"CN23XX_SLI_OQ_WMARK", CVM_CAST64(CN23XX_SLI_OQ_WMARK),
-		CVM_CAST64(octeon_read_csr64(oct, CN23XX_SLI_OQ_WMARK)));
+	pr_devel("%s[%llx] : 0x%016llx\n",
+		 "CN23XX_SLI_OQ_WMARK", CVM_CAST64(CN23XX_SLI_OQ_WMARK),
+		 CVM_CAST64(octeon_read_csr64(oct, CN23XX_SLI_OQ_WMARK)));
 
 	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
-		dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-			"CN23XX_SLI_OQ_PKT_CONTROL", i,
-			CVM_CAST64(CN23XX_SLI_OQ_PKT_CONTROL(i)),
-			CVM_CAST64(octeon_read_csr(
-				oct, CN23XX_SLI_OQ_PKT_CONTROL(i))));
-		dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-			"CN23XX_SLI_OQ_PKT_INT_LEVELS", i,
-			CVM_CAST64(CN23XX_SLI_OQ_PKT_INT_LEVELS(i)),
-			CVM_CAST64(octeon_read_csr64(
-				oct, CN23XX_SLI_OQ_PKT_INT_LEVELS(i))));
+		pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+			 "CN23XX_SLI_OQ_PKT_CONTROL", i,
+			 CVM_CAST64(CN23XX_SLI_OQ_PKT_CONTROL(i)),
+			 CVM_CAST64(octeon_read_csr(
+				 oct, CN23XX_SLI_OQ_PKT_CONTROL(i))));
+		pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+			 "CN23XX_SLI_OQ_PKT_INT_LEVELS", i,
+			 CVM_CAST64(CN23XX_SLI_OQ_PKT_INT_LEVELS(i)),
+			 CVM_CAST64(octeon_read_csr64(
+				 oct, CN23XX_SLI_OQ_PKT_INT_LEVELS(i))));
 	}
 
 	/*In cn23xx_enable_interrupt and cn23xx_disable_interrupt*/
-	dev_dbg(&oct->pci_dev->dev, "%s[%llx] : 0x%016llx\n",
-		"cn23xx->intr_enb_reg64",
-		CVM_CAST64((long)(cn23xx->intr_enb_reg64)),
-		CVM_CAST64(readq(cn23xx->intr_enb_reg64)));
+	pr_devel("%s[%llx] : 0x%016llx\n",
+		 "cn23xx->intr_enb_reg64",
+		 CVM_CAST64((long)(cn23xx->intr_enb_reg64)),
+		 CVM_CAST64(readq(cn23xx->intr_enb_reg64)));
 
-	dev_dbg(&oct->pci_dev->dev, "%s[%llx] : 0x%016llx\n",
-		"cn23xx->intr_sum_reg64",
-		CVM_CAST64((long)(cn23xx->intr_sum_reg64)),
-		CVM_CAST64(readq(cn23xx->intr_sum_reg64)));
+	pr_devel("%s[%llx] : 0x%016llx\n",
+		 "cn23xx->intr_sum_reg64",
+		 CVM_CAST64((long)(cn23xx->intr_sum_reg64)),
+		 CVM_CAST64(readq(cn23xx->intr_sum_reg64)));
 
 	/*In cn23xx_setup_iq_regs*/
 	for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
-		dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-			"CN23XX_SLI_IQ_BASE_ADDR64", i,
-			CVM_CAST64(CN23XX_SLI_IQ_BASE_ADDR64(i)),
-			CVM_CAST64(octeon_read_csr64(
-				oct, CN23XX_SLI_IQ_BASE_ADDR64(i))));
-		dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-			"CN23XX_SLI_IQ_SIZE", i,
-			CVM_CAST64(CN23XX_SLI_IQ_SIZE(i)),
-			CVM_CAST64(octeon_read_csr
-				(oct, CN23XX_SLI_IQ_SIZE(i))));
-		dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-			"CN23XX_SLI_IQ_DOORBELL", i,
-			CVM_CAST64(CN23XX_SLI_IQ_DOORBELL(i)),
-			CVM_CAST64(octeon_read_csr64(
-				oct, CN23XX_SLI_IQ_DOORBELL(i))));
-		dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-			"CN23XX_SLI_IQ_INSTR_COUNT64", i,
-			CVM_CAST64(CN23XX_SLI_IQ_INSTR_COUNT64(i)),
-			CVM_CAST64(octeon_read_csr64(
-				oct, CN23XX_SLI_IQ_INSTR_COUNT64(i))));
+		pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+			 "CN23XX_SLI_IQ_BASE_ADDR64", i,
+			 CVM_CAST64(CN23XX_SLI_IQ_BASE_ADDR64(i)),
+			 CVM_CAST64(octeon_read_csr64(
+				 oct, CN23XX_SLI_IQ_BASE_ADDR64(i))));
+		pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+			 "CN23XX_SLI_IQ_SIZE", i,
+			 CVM_CAST64(CN23XX_SLI_IQ_SIZE(i)),
+			 CVM_CAST64(octeon_read_csr
+				 (oct, CN23XX_SLI_IQ_SIZE(i))));
+		pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+			 "CN23XX_SLI_IQ_DOORBELL", i,
+			 CVM_CAST64(CN23XX_SLI_IQ_DOORBELL(i)),
+			 CVM_CAST64(octeon_read_csr64(
+				 oct, CN23XX_SLI_IQ_DOORBELL(i))));
+		pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+			 "CN23XX_SLI_IQ_INSTR_COUNT64", i,
+			 CVM_CAST64(CN23XX_SLI_IQ_INSTR_COUNT64(i)),
+			 CVM_CAST64(octeon_read_csr64(
+				 oct, CN23XX_SLI_IQ_INSTR_COUNT64(i))));
 	}
 
 	/*In cn23xx_setup_oq_regs*/
 	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
-		dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-			"CN23XX_SLI_OQ_BASE_ADDR64", i,
-			CVM_CAST64(CN23XX_SLI_OQ_BASE_ADDR64(i)),
-			CVM_CAST64(octeon_read_csr64(
-				oct, CN23XX_SLI_OQ_BASE_ADDR64(i))));
-		dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-			"CN23XX_SLI_OQ_SIZE", i,
-			CVM_CAST64(CN23XX_SLI_OQ_SIZE(i)),
-			CVM_CAST64(octeon_read_csr
-				(oct, CN23XX_SLI_OQ_SIZE(i))));
-		dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-			"CN23XX_SLI_OQ_BUFF_INFO_SIZE", i,
-			CVM_CAST64(CN23XX_SLI_OQ_BUFF_INFO_SIZE(i)),
-			CVM_CAST64(octeon_read_csr(
-				oct, CN23XX_SLI_OQ_BUFF_INFO_SIZE(i))));
-		dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-			"CN23XX_SLI_OQ_PKTS_SENT", i,
-			CVM_CAST64(CN23XX_SLI_OQ_PKTS_SENT(i)),
-			CVM_CAST64(octeon_read_csr64(
-				oct, CN23XX_SLI_OQ_PKTS_SENT(i))));
-		dev_dbg(&oct->pci_dev->dev, "%s(%d)[%llx] : 0x%016llx\n",
-			"CN23XX_SLI_OQ_PKTS_CREDIT", i,
-			CVM_CAST64(CN23XX_SLI_OQ_PKTS_CREDIT(i)),
-			CVM_CAST64(octeon_read_csr64(
-				oct, CN23XX_SLI_OQ_PKTS_CREDIT(i))));
+		pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+			 "CN23XX_SLI_OQ_BASE_ADDR64", i,
+			 CVM_CAST64(CN23XX_SLI_OQ_BASE_ADDR64(i)),
+			 CVM_CAST64(octeon_read_csr64(
+				 oct, CN23XX_SLI_OQ_BASE_ADDR64(i))));
+		pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+			 "CN23XX_SLI_OQ_SIZE", i,
+			 CVM_CAST64(CN23XX_SLI_OQ_SIZE(i)),
+			 CVM_CAST64(octeon_read_csr
+				 (oct, CN23XX_SLI_OQ_SIZE(i))));
+		pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+			 "CN23XX_SLI_OQ_BUFF_INFO_SIZE", i,
+			 CVM_CAST64(CN23XX_SLI_OQ_BUFF_INFO_SIZE(i)),
+			 CVM_CAST64(octeon_read_csr(
+				 oct, CN23XX_SLI_OQ_BUFF_INFO_SIZE(i))));
+		pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+			 "CN23XX_SLI_OQ_PKTS_SENT", i,
+			 CVM_CAST64(CN23XX_SLI_OQ_PKTS_SENT(i)),
+			 CVM_CAST64(octeon_read_csr64(
+				 oct, CN23XX_SLI_OQ_PKTS_SENT(i))));
+		pr_devel("%s(%d)[%llx] : 0x%016llx\n",
+			 "CN23XX_SLI_OQ_PKTS_CREDIT", i,
+			 CVM_CAST64(CN23XX_SLI_OQ_PKTS_CREDIT(i)),
+			 CVM_CAST64(octeon_read_csr64(
+				 oct, CN23XX_SLI_OQ_PKTS_CREDIT(i))));
 	}
 
-	dev_dbg(&oct->pci_dev->dev, "%s[%llx] : 0x%016llx\n",
-		"CN23XX_SLI_PKT_TIME_INT",
-		CVM_CAST64(CN23XX_SLI_PKT_TIME_INT),
-		CVM_CAST64(octeon_read_csr64(oct, CN23XX_SLI_PKT_TIME_INT)));
-	dev_dbg(&oct->pci_dev->dev, "%s[%llx] : 0x%016llx\n",
-		"CN23XX_SLI_PKT_CNT_INT",
-		CVM_CAST64(CN23XX_SLI_PKT_CNT_INT),
-		CVM_CAST64(octeon_read_csr64(oct, CN23XX_SLI_PKT_CNT_INT)));
+	pr_devel("%s[%llx] : 0x%016llx\n",
+		 "CN23XX_SLI_PKT_TIME_INT",
+		 CVM_CAST64(CN23XX_SLI_PKT_TIME_INT),
+		 CVM_CAST64(octeon_read_csr64(oct, CN23XX_SLI_PKT_TIME_INT)));
+	pr_devel("%s[%llx] : 0x%016llx\n",
+		 "CN23XX_SLI_PKT_CNT_INT",
+		 CVM_CAST64(CN23XX_SLI_PKT_CNT_INT),
+		 CVM_CAST64(octeon_read_csr64(oct, CN23XX_SLI_PKT_CNT_INT)));
 }
 
 static int cn23xx_pf_soft_reset(struct octeon_device *oct)
 {
 	octeon_write_csr64(oct, CN23XX_WIN_WR_MASK_REG, 0xFF);
 
-	dev_dbg(&oct->pci_dev->dev, "OCTEON[%d]: BIST enabled for CN23XX soft reset\n",
-		oct->octeon_id);
+	pr_devel("OCTEON[%d]: BIST enabled for CN23XX soft reset\n",
+		 oct->octeon_id);
 
 	octeon_write_csr64(oct, CN23XX_SLI_SCRATCH1, 0x1234ULL);
 
@@ -236,8 +236,8 @@ static int cn23xx_pf_soft_reset(struct octeon_device *oct)
 		return 1;
 	}
 
-	dev_dbg(&oct->pci_dev->dev, "OCTEON[%d]: Reset completed\n",
-		oct->octeon_id);
+	pr_devel("OCTEON[%d]: Reset completed\n",
+		 oct->octeon_id);
 
 	/* restore the  reset value*/
 	octeon_write_csr64(oct, CN23XX_WIN_WR_MASK_REG, 0xFF);
@@ -1238,6 +1238,9 @@ static int cn23xx_sriov_config(struct octeon_device *oct)
 		 oct->sriov_info.trs, oct->sriov_info.num_vfs,
 		 oct->sriov_info.rings_per_vf, oct->sriov_info.pf_srn,
 		 oct->sriov_info.num_pf_rings);
+
+	oct->sriov_info.sriov_enabled = 0;
+
 	return 0;
 }
 
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index afc6f9d..438d32f 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -19,6 +19,7 @@
 * This file may also be available under a different license from Cavium.
 * Contact Cavium, Inc. for more information
 **********************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/version.h>
 #include <linux/pci.h>
 #include <linux/firmware.h>
@@ -69,6 +70,18 @@ static int conf_type;
 module_param(conf_type, int, 0);
 MODULE_PARM_DESC(conf_type, "select octeon configuration 0 default 1 ovs");
 
+static unsigned int num_vfs[2] = { 0, 0 };
+module_param_array(num_vfs, uint, NULL, 0444);
+MODULE_PARM_DESC(num_vfs, "two comma-separated unsigned integers that specify number of VFs for PF0 (left of the comma) and PF1 (right of the comma); for 23xx only");
+
+static unsigned int num_queues_per_pf[2] = { 0, 0 };
+module_param_array(num_queues_per_pf, uint, NULL, 0444);
+MODULE_PARM_DESC(num_queues_per_pf, "two comma-separated unsigned integers that specify number of queues per PF0 (left of the comma) and PF1 (right of the comma); for 23xx only");
+
+static unsigned int num_queues_per_vf[2] = { 0, 0 };
+module_param_array(num_queues_per_vf, uint, NULL, 0444);
+MODULE_PARM_DESC(num_queues_per_vf, "two comma-separated unsigned integers that specify number of queues per VFs for PF0 (left of the comma) and PF1 (right of the comma); for 23xx only");
+
 static int ptp_enable = 1;
 
 /* Bit mask values for lio->ifstate */
@@ -379,8 +392,8 @@ static void stop_pci_io(struct octeon_device *oct)
 	if (oct->flags & LIO_FLAG_MSI_ENABLED)
 		pci_disable_msi(oct->pci_dev);
 
-	dev_dbg(&oct->pci_dev->dev, "Device state is now %s\n",
-		lio_get_state_string(&oct->status));
+	pr_devel("Device state is now %s\n",
+		 lio_get_state_string(&oct->status));
 
 	/* cn63xx_cleanup_aer_uncorrect_error_status(oct->pci_dev); */
 	/* making it a common function for all OCTEON models */
@@ -1111,7 +1124,7 @@ static int octeon_setup_interrupt(struct octeon_device *oct)
 			oct->msix_entries = NULL;
 			return 1;
 		}
-		dev_dbg(&oct->pci_dev->dev, "OCTEON: Enough MSI-X interrupts are allocated...\n");
+		pr_devel("OCTEON: Enough MSI-X interrupts are allocated...\n");
 
 		num_ioq_vectors = oct->num_msix_irqs;
 
@@ -1161,8 +1174,8 @@ static int octeon_setup_interrupt(struct octeon_device *oct)
 					msix_entries[i].vector,
 					(&oct->ioq_vector[i].affinity_mask));
 		}
-		dev_dbg(&oct->pci_dev->dev, "OCTEON[%d]: MSI-X enabled\n",
-			oct->octeon_id);
+		pr_devel("OCTEON[%d]: MSI-X enabled\n",
+			 oct->octeon_id);
 	} else {
 		err = pci_enable_msi(oct->pci_dev);
 		if (err)
@@ -1353,7 +1366,7 @@ liquidio_probe(struct pci_dev *pdev,
 	oct_dev->rx_pause = 1;
 	oct_dev->tx_pause = 1;
 
-	dev_dbg(&oct_dev->pci_dev->dev, "Device is ready\n");
+	pr_devel("Device is ready\n");
 
 	return 0;
 }
@@ -1380,8 +1393,8 @@ static void octeon_destroy_resources(struct octeon_device *oct)
 		atomic_set(&oct->status, OCT_DEV_IN_RESET);
 
 		oct->app_mode = CVM_DRV_INVALID_APP;
-		dev_dbg(&oct->pci_dev->dev, "Device state is now %s\n",
-			lio_get_state_string(&oct->status));
+		pr_devel("Device state is now %s\n",
+			 lio_get_state_string(&oct->status));
 
 		schedule_timeout_uninterruptible(HZ / 10);
 
@@ -1472,6 +1485,8 @@ static void octeon_destroy_resources(struct octeon_device *oct)
 				continue;
 			octeon_delete_instr_queue(oct, i);
 		}
+		if (oct->sriov_info.sriov_enabled)
+			pci_disable_sriov(oct->pci_dev);
 		/* fallthrough */
 	case OCT_DEV_SC_BUFF_POOL_INIT_DONE:
 		octeon_free_sc_buffer_pool(oct);
@@ -1610,7 +1625,7 @@ static void liquidio_destroy_nic_device(struct octeon_device *oct, int ifidx)
 
 	lio = GET_LIO(netdev);
 
-	dev_dbg(&oct->pci_dev->dev, "NIC device cleanup\n");
+	pr_devel("NIC device cleanup\n");
 
 	if (atomic_read(&lio->ifstate) & LIO_IFSTATE_RUNNING)
 		liquidio_stop(netdev);
@@ -1648,7 +1663,7 @@ static int liquidio_stop_nic_module(struct octeon_device *oct)
 	int i, j;
 	struct lio *lio;
 
-	dev_dbg(&oct->pci_dev->dev, "Stopping network interfaces\n");
+	pr_devel("Stopping network interfaces\n");
 	if (!oct->ifcount) {
 		dev_err(&oct->pci_dev->dev, "Init for Octeon was not completed\n");
 		return 1;
@@ -1668,7 +1683,7 @@ static int liquidio_stop_nic_module(struct octeon_device *oct)
 	for (i = 0; i < oct->ifcount; i++)
 		liquidio_destroy_nic_device(oct, i);
 
-	dev_dbg(&oct->pci_dev->dev, "Network interfaces stopped\n");
+	pr_devel("Network interfaces stopped\n");
 	return 0;
 }
 
@@ -1680,7 +1695,7 @@ static void liquidio_remove(struct pci_dev *pdev)
 {
 	struct octeon_device *oct_dev = pci_get_drvdata(pdev);
 
-	dev_dbg(&oct_dev->pci_dev->dev, "Stopping device\n");
+	pr_devel("Stopping device\n");
 
 	if (oct_dev->watchdog_task)
 		kthread_stop(oct_dev->watchdog_task);
@@ -1730,6 +1745,15 @@ static int octeon_chip_specific_setup(struct octeon_device *oct)
 
 	case OCTEON_CN23XX_PCIID_PF:
 		oct->chip_id = OCTEON_CN23XX_PF_VID;
+		oct->sriov_info.num_vfs = num_vfs[oct->pci_dev->devfn];
+		if (num_queues_per_vf[oct->pci_dev->devfn] > 0) {
+			oct->sriov_info.rings_per_vf =
+			    num_queues_per_vf[oct->pci_dev->devfn];
+		}
+		if (num_queues_per_pf[oct->pci_dev->devfn] > 0) {
+			oct->sriov_info.num_pf_rings =
+			    num_queues_per_pf[oct->pci_dev->devfn];
+		}
 		ret = setup_cn23xx_octeon_pf_device(oct);
 		s = "CN23XX";
 		break;
@@ -2146,14 +2170,14 @@ static int octeon_setup_droq(struct octeon_device *oct, int q_no, int num_descs,
 {
 	int ret_val = 0;
 
-	dev_dbg(&oct->pci_dev->dev, "Creating Droq: %d\n", q_no);
+	pr_devel("Creating Droq: %d\n", q_no);
 	/* droq creation and local register settings. */
 	ret_val = octeon_create_droq(oct, q_no, num_descs, desc_size, app_ctx);
 	if (ret_val < 0)
 		return ret_val;
 
 	if (ret_val == 1) {
-		dev_dbg(&oct->pci_dev->dev, "Using default droq %d\n", q_no);
+		pr_devel("Using default droq %d\n", q_no);
 		return 0;
 	}
 	/* tasklet creation for the droq */
@@ -2481,9 +2505,8 @@ static inline int setup_io_queues(struct octeon_device *octeon_dev,
 	/* set up DROQs. */
 	for (q = 0; q < lio->linfo.num_rxpciq; q++) {
 		q_no = lio->linfo.rxpciq[q].s.q_no;
-		dev_dbg(&octeon_dev->pci_dev->dev,
-			"setup_io_queues index:%d linfo.rxpciq.s.q_no:%d\n",
-			q, q_no);
+		pr_devel("setup_io_queues index:%d linfo.rxpciq.s.q_no:%d\n",
+			 q, q_no);
 		retval = octeon_setup_droq(octeon_dev, q_no,
 					   CFG_GET_NUM_RX_DESCS_NIC_IF
 						   (octeon_get_conf(octeon_dev),
@@ -2500,8 +2523,8 @@ static inline int setup_io_queues(struct octeon_device *octeon_dev,
 
 		droq = octeon_dev->droq[q_no];
 		napi = &droq->napi;
-		dev_dbg(&octeon_dev->pci_dev->dev, "netif_napi_add netdev:%llx oct:%llx pf_num:%d\n",
-			(u64)netdev, (u64)octeon_dev, octeon_dev->pf_num);
+		pr_devel("netif_napi_add netdev:%llx oct:%llx pf_num:%d\n",
+			 (u64)netdev, (u64)octeon_dev, octeon_dev->pf_num);
 		netif_napi_add(netdev, napi, liquidio_napi_poll, 64);
 
 		/* designate a CPU for this droq */
@@ -3744,9 +3767,8 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
 			ifidx_or_pfnum = i;
 		}
 
-		dev_dbg(&octeon_dev->pci_dev->dev,
-			"requesting config for interface %d, iqs %d, oqs %d\n",
-			ifidx_or_pfnum, num_iqueues, num_oqueues);
+		pr_devel("requesting config for interface %d, iqs %d, oqs %d\n",
+			 ifidx_or_pfnum, num_iqueues, num_oqueues);
 		WRITE_ONCE(ctx->cond, 0);
 		ctx->octeon_id = lio_get_device_id(octeon_dev);
 		init_waitqueue_head(&ctx->wc);
@@ -3803,10 +3825,9 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
 				resp->cfg_info.oqmask);
 			goto setup_nic_dev_fail;
 		}
-		dev_dbg(&octeon_dev->pci_dev->dev,
-			"interface %d, iqmask %016llx, oqmask %016llx, numiqueues %d, numoqueues %d\n",
-			i, resp->cfg_info.iqmask, resp->cfg_info.oqmask,
-			num_iqueues, num_oqueues);
+		pr_devel("interface %d, iqmask %016llx, oqmask %016llx, numiqueues %d, numoqueues %d\n",
+			 i, resp->cfg_info.iqmask, resp->cfg_info.oqmask,
+			 num_iqueues, num_oqueues);
 		netdev = alloc_etherdev_mq(LIO_SIZE, num_iqueues);
 
 		if (!netdev) {
@@ -3898,9 +3919,8 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
 		lio->octprops = props;
 		lio->netdev = netdev;
 
-		dev_dbg(&octeon_dev->pci_dev->dev,
-			"if%d gmx: %d hw_addr: 0x%llx\n", i,
-			lio->linfo.gmxport, CVM_CAST64(lio->linfo.hw_addr));
+		pr_devel("if%d gmx: %d hw_addr: 0x%llx\n", i,
+			 lio->linfo.gmxport, CVM_CAST64(lio->linfo.hw_addr));
 
 		/* 64-bit swap required on LE machines */
 		octeon_swap_8B_data(&lio->linfo.hw_addr, 1);
@@ -3958,9 +3978,8 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
 			goto setup_nic_dev_fail;
 		}
 
-		dev_dbg(&octeon_dev->pci_dev->dev,
-			"Setup NIC ifidx:%d mac:%02x%02x%02x%02x%02x%02x\n",
-			i, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+		pr_devel("Setup NIC ifidx:%d mac:%02x%02x%02x%02x%02x%02x\n",
+			 i, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 		netif_carrier_off(netdev);
 		lio->link_changes++;
 
@@ -3975,8 +3994,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
 		liquidio_set_feature(netdev, OCTNET_CMD_TNL_TX_CSUM_CTL,
 				     OCTNET_CMD_TXCSUM_ENABLE);
 
-		dev_dbg(&octeon_dev->pci_dev->dev,
-			"NIC ifidx:%d Setup successful\n", i);
+		pr_devel("NIC ifidx:%d Setup successful\n", i);
 
 		octeon_free_soft_command(octeon_dev, sc);
 	}
@@ -3997,6 +4015,43 @@ setup_nic_wait_intr:
 	return -ENODEV;
 }
 
+static int octeon_enable_sriov(struct octeon_device *oct)
+{
+	int err;
+	unsigned int num_vfs = oct->sriov_info.num_vfs;
+	struct pci_dev *vfdev;
+	u32 u;
+
+	if (OCTEON_CN23XX_PF(oct) && num_vfs) {
+		err = pci_enable_sriov(oct->pci_dev, oct->sriov_info.num_vfs);
+		if (err) {
+			dev_err(&oct->pci_dev->dev,
+				"OCTEON: Failed to enable PCI sriov: %d\n",
+				err);
+			return err;
+		}
+		oct->sriov_info.sriov_enabled = 1;
+
+		/* init lookup table that maps DPI ring number to VF pci_dev
+		 * struct pointer
+		 */
+		u = 0;
+		vfdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
+				       OCTEON_CN23XX_VF_VID, NULL);
+		while (vfdev) {
+			if (vfdev->is_virtfn &&
+			    (vfdev->physfn == oct->pci_dev)) {
+				oct->sriov_info.dpiring_to_vfpcidev_lut[u] =
+					vfdev;
+				u += oct->sriov_info.rings_per_vf;
+			}
+			vfdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
+					       OCTEON_CN23XX_VF_VID, vfdev);
+		}
+	}
+	return 0;
+}
+
 /**
  * \brief initialize the NIC
  * @param oct octeon device
@@ -4010,7 +4065,7 @@ static int liquidio_init_nic_module(struct octeon_device *oct)
 	int i, retval = 0;
 	int num_nic_ports = CFG_GET_NUM_NIC_PORTS(octeon_get_conf(oct));
 
-	dev_dbg(&oct->pci_dev->dev, "Initializing network interfaces\n");
+	pr_devel("Initializing network interfaces\n");
 
 	/* only default iq and oq were initialized
 	 * initialize the rest as well
@@ -4047,7 +4102,7 @@ static int liquidio_init_nic_module(struct octeon_device *oct)
 	intrmod_cfg->rx_frames = CFG_GET_OQ_INTR_PKT(octeon_get_conf(oct));
 	intrmod_cfg->rx_usecs = CFG_GET_OQ_INTR_TIME(octeon_get_conf(oct));
 	intrmod_cfg->tx_frames = CFG_GET_IQ_INTR_PKT(octeon_get_conf(oct));
-	dev_dbg(&oct->pci_dev->dev, "Network interfaces ready\n");
+	pr_devel("Network interfaces ready\n");
 
 	return retval;
 
@@ -4087,12 +4142,16 @@ static void nic_starter(struct work_struct *work)
 	atomic_set(&oct->status, OCT_DEV_RUNNING);
 
 	if (oct->app_mode && oct->app_mode == CVM_DRV_NIC_APP) {
-		dev_dbg(&oct->pci_dev->dev, "Starting NIC module\n");
+		pr_devel("Starting NIC module\n");
 
-		if (liquidio_init_nic_module(oct))
+		if (liquidio_init_nic_module(oct)) {
 			dev_err(&oct->pci_dev->dev, "NIC initialization failed\n");
-		else
-			handshake[oct->octeon_id].started_ok = 1;
+		} else {
+			if (octeon_enable_sriov(oct))
+				handshake[oct->octeon_id].started_ok = 0;
+			else
+				handshake[oct->octeon_id].started_ok = 1;
+		}
 	} else {
 		dev_err(&oct->pci_dev->dev,
 			"Unexpected application running on NIC (%d). Check firmware.\n",
@@ -4235,7 +4294,7 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
 	}
 
 	/* Initialize the tasklet that handles output queue packet processing.*/
-	dev_dbg(&octeon_dev->pci_dev->dev, "Initializing droq tasklet\n");
+	pr_devel("Initializing droq tasklet\n");
 	tasklet_init(&oct_priv->droq_tasklet, octeon_droq_bh,
 		     (unsigned long)octeon_dev);
 
@@ -4257,7 +4316,7 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
 	atomic_set(&octeon_dev->status, OCT_DEV_IO_QUEUES_DONE);
 
 	if ((!OCTEON_CN23XX_PF(octeon_dev)) || !fw_loaded) {
-		dev_dbg(&octeon_dev->pci_dev->dev, "Waiting for DDR initialization...\n");
+		pr_devel("Waiting for DDR initialization...\n");
 		if (!ddr_timeout) {
 			dev_info(&octeon_dev->pci_dev->dev,
 				 "WAITING. Set ddr_timeout to non-zero value to proceed with initialization.\n");
@@ -4289,7 +4348,7 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
 		/* Divert uboot to take commands from host instead. */
 		ret = octeon_console_send_cmd(octeon_dev, bootcmd, 50);
 
-		dev_dbg(&octeon_dev->pci_dev->dev, "Initializing consoles\n");
+		pr_devel("Initializing consoles\n");
 		ret = octeon_init_consoles(octeon_dev);
 		if (ret) {
 			dev_err(&octeon_dev->pci_dev->dev, "Could not access board consoles\n");
@@ -4303,7 +4362,7 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
 
 		atomic_set(&octeon_dev->status, OCT_DEV_CONSOLE_INIT_DONE);
 
-		dev_dbg(&octeon_dev->pci_dev->dev, "Loading firmware\n");
+		pr_devel("Loading firmware\n");
 		ret = load_firmware(octeon_dev);
 		if (ret) {
 			dev_err(&octeon_dev->pci_dev->dev, "Could not load firmware to board\n");
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_config.h b/drivers/net/ethernet/cavium/liquidio/octeon_config.h
index 0127a0e..8871fb5 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_config.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_config.h
@@ -471,4 +471,7 @@ struct octeon_config {
 
 #define MAX_POSSIBLE_OCTEON_INSTR_QUEUES	CN23XX_MAX_INPUT_QUEUES
 #define MAX_POSSIBLE_OCTEON_OUTPUT_QUEUES	CN23XX_MAX_OUTPUT_QUEUES
+
+#define MAX_POSSIBLE_VFS			64
+
 #endif /* __OCTEON_CONFIG_H__  */
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.h b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
index 89381ba..18e3050 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_device.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
@@ -38,6 +38,7 @@
 #define  OCTEON_CN68XX                0x0091
 #define  OCTEON_CN66XX                0x0092
 #define  OCTEON_CN23XX_PF_VID         0x9702
+#define  OCTEON_CN23XX_VF_VID         0x9712
 
 /**RevisionId for the chips */
 #define  OCTEON_CN23XX_REV_1_0        0x00
@@ -337,6 +338,10 @@ struct octeon_sriov_info {
 	/* total pf rings */
 	u32	trs;
 
+	u32	sriov_enabled;
+
+	/*lookup table that maps DPI ring number to VF pci_dev struct pointer*/
+	struct pci_dev *dpiring_to_vfpcidev_lut[MAX_POSSIBLE_VFS];
 };
 
 struct octeon_ioq_vector {
-- 
1.8.3.1

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

* [PATCH net-next 3/5] liquidio CN23XX: Mailbox support
  2016-09-09 20:08 [PATCH net-next 0/5] liquidio CN23XX VF support Raghu Vatsavayi
  2016-09-09 20:08 ` [PATCH net-next 1/5] liquidio CN23XX: VF config support Raghu Vatsavayi
  2016-09-09 20:08 ` [PATCH net-next 2/5] liquidio CN23XX: sriov enable Raghu Vatsavayi
@ 2016-09-09 20:08 ` Raghu Vatsavayi
  2016-09-11  4:42   ` David Miller
  2016-09-09 20:08 ` [PATCH net-next 4/5] liquidio CN23XX: mailbox interrupt processing Raghu Vatsavayi
  2016-09-09 20:08 ` [PATCH net-next 5/5] liquidio CN23XX: VF related operations Raghu Vatsavayi
  4 siblings, 1 reply; 9+ messages in thread
From: Raghu Vatsavayi @ 2016-09-09 20:08 UTC (permalink / raw)
  To: davem
  Cc: netdev, Raghu Vatsavayi, Derek Chickles, Satanand Burla,
	Felix Manlunas, Raghu Vatsavayi

Adds support for mailbox communication between PF and VF.

Signed-off-by: Derek Chickles <derek.chickles@caviumnetworks.com>
Signed-off-by: Satanand Burla <satananda.burla@caviumnetworks.com>
Signed-off-by: Felix Manlunas <felix.manlunas@caviumnetworks.com>
Signed-off-by: Raghu Vatsavayi <raghu.vatsavayi@caviumnetworks.com>
---
 drivers/net/ethernet/cavium/liquidio/Makefile      |   1 +
 .../ethernet/cavium/liquidio/cn23xx_pf_device.c    |   4 +-
 .../net/ethernet/cavium/liquidio/cn68xx_device.c   |  13 +-
 drivers/net/ethernet/cavium/liquidio/lio_core.c    |  32 ++
 .../net/ethernet/cavium/liquidio/liquidio_common.h |   6 +-
 .../net/ethernet/cavium/liquidio/octeon_console.c  |  16 +-
 .../net/ethernet/cavium/liquidio/octeon_device.h   |   4 +
 .../net/ethernet/cavium/liquidio/octeon_mailbox.c  | 322 +++++++++++++++++++++
 .../net/ethernet/cavium/liquidio/octeon_mailbox.h  | 116 ++++++++
 drivers/net/ethernet/cavium/liquidio/octeon_main.h |  12 +-
 .../net/ethernet/cavium/liquidio/request_manager.c |   9 +-
 11 files changed, 507 insertions(+), 28 deletions(-)
 create mode 100644 drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
 create mode 100644 drivers/net/ethernet/cavium/liquidio/octeon_mailbox.h

diff --git a/drivers/net/ethernet/cavium/liquidio/Makefile b/drivers/net/ethernet/cavium/liquidio/Makefile
index 5a27b2a..14958de 100644
--- a/drivers/net/ethernet/cavium/liquidio/Makefile
+++ b/drivers/net/ethernet/cavium/liquidio/Makefile
@@ -11,6 +11,7 @@ liquidio-$(CONFIG_LIQUIDIO) += lio_ethtool.o \
 			cn66xx_device.o    \
 			cn68xx_device.o    \
 			cn23xx_pf_device.o \
+			octeon_mailbox.o   \
 			octeon_mem_ops.o   \
 			octeon_droq.o      \
 			octeon_nic.o
diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
index deec869..b3c61302 100644
--- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
+++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
@@ -270,8 +270,8 @@ static void cn23xx_enable_error_reporting(struct octeon_device *oct)
 
 	regval |= 0xf; /* Enable Link error reporting */
 
-	dev_dbg(&oct->pci_dev->dev, "OCTEON[%d]: Enabling PCI-E error reporting..\n",
-		oct->octeon_id);
+	pr_devel("OCTEON[%d]: Enabling PCI-E error reporting..\n",
+		 oct->octeon_id);
 	pci_write_config_dword(oct->pci_dev, CN23XX_CONFIG_PCIE_DEVCTL, regval);
 }
 
diff --git a/drivers/net/ethernet/cavium/liquidio/cn68xx_device.c b/drivers/net/ethernet/cavium/liquidio/cn68xx_device.c
index dbf3566..424125e 100644
--- a/drivers/net/ethernet/cavium/liquidio/cn68xx_device.c
+++ b/drivers/net/ethernet/cavium/liquidio/cn68xx_device.c
@@ -19,6 +19,7 @@
 * This file may also be available under a different license from Cavium.
 * Contact Cavium, Inc. for more information
 **********************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include "liquidio_common.h"
@@ -37,8 +38,8 @@ static void lio_cn68xx_set_dpi_regs(struct octeon_device *oct)
 	u32 fifo_sizes[6] = { 3, 3, 1, 1, 1, 8 };
 
 	lio_pci_writeq(oct, CN6XXX_DPI_DMA_CTL_MASK, CN6XXX_DPI_DMA_CONTROL);
-	dev_dbg(&oct->pci_dev->dev, "DPI_DMA_CONTROL: 0x%016llx\n",
-		lio_pci_readq(oct, CN6XXX_DPI_DMA_CONTROL));
+	pr_devel("DPI_DMA_CONTROL: 0x%016llx\n",
+		 lio_pci_readq(oct, CN6XXX_DPI_DMA_CONTROL));
 
 	for (i = 0; i < 6; i++) {
 		/* Prevent service of instruction queue for all DMA engines
@@ -47,8 +48,8 @@ static void lio_cn68xx_set_dpi_regs(struct octeon_device *oct)
 		 */
 		lio_pci_writeq(oct, 0, CN6XXX_DPI_DMA_ENG_ENB(i));
 		lio_pci_writeq(oct, fifo_sizes[i], CN6XXX_DPI_DMA_ENG_BUF(i));
-		dev_dbg(&oct->pci_dev->dev, "DPI_ENG_BUF%d: 0x%016llx\n", i,
-			lio_pci_readq(oct, CN6XXX_DPI_DMA_ENG_BUF(i)));
+		pr_devel("DPI_ENG_BUF%d: 0x%016llx\n", i,
+			 lio_pci_readq(oct, CN6XXX_DPI_DMA_ENG_BUF(i)));
 	}
 
 	/* DPI_SLI_PRT_CFG has MPS and MRRS settings that will be set
@@ -56,8 +57,8 @@ static void lio_cn68xx_set_dpi_regs(struct octeon_device *oct)
 	 */
 
 	lio_pci_writeq(oct, 1, CN6XXX_DPI_CTL);
-	dev_dbg(&oct->pci_dev->dev, "DPI_CTL: 0x%016llx\n",
-		lio_pci_readq(oct, CN6XXX_DPI_CTL));
+	pr_devel("DPI_CTL: 0x%016llx\n",
+		 lio_pci_readq(oct, CN6XXX_DPI_CTL));
 }
 
 static int lio_cn68xx_soft_reset(struct octeon_device *oct)
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_core.c b/drivers/net/ethernet/cavium/liquidio/lio_core.c
index 201eddb..4626b1f 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_core.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_core.c
@@ -264,3 +264,35 @@ void liquidio_link_ctrl_cmd_completion(void *nctrl_ptr)
 			nctrl->ncmd.s.cmd);
 	}
 }
+
+void octeon_pf_changed_vf_macaddr(struct octeon_device *oct, u8 *mac)
+{
+	struct net_device *netdev;
+	struct lio *lio;
+	bool macaddr_changed = false;
+
+	rtnl_lock();
+
+	netdev = oct->props[0].netdev;
+	lio = GET_LIO(netdev);
+
+	lio->linfo.macaddr_is_admin_asgnd = true;
+
+	if (ether_addr_equal(netdev->dev_addr, mac)) {
+		macaddr_changed = true;
+		ether_addr_copy(netdev->dev_addr, mac);
+		ether_addr_copy(((u8 *)&lio->linfo.hw_addr) + 2, mac);
+		call_netdevice_notifiers(NETDEV_CHANGEADDR, netdev);
+	}
+
+	rtnl_unlock();
+
+	if (macaddr_changed)
+		dev_info(&oct->pci_dev->dev,
+			 "PF changed VF's MAC address to %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
+			 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+	/* no need to notify the firmware of the macaddr change because
+	 * the PF did that already
+	 */
+}
diff --git a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h
index 0d990ac..caeff9a 100644
--- a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h
+++ b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h
@@ -731,13 +731,15 @@ struct oct_link_info {
 
 #ifdef __BIG_ENDIAN_BITFIELD
 	u64 gmxport:16;
-	u64 rsvd:32;
+	u64 macaddr_is_admin_asgnd:1;
+	u64 rsvd:31;
 	u64 num_txpciq:8;
 	u64 num_rxpciq:8;
 #else
 	u64 num_rxpciq:8;
 	u64 num_txpciq:8;
-	u64 rsvd:32;
+	u64 rsvd:31;
+	u64 macaddr_is_admin_asgnd:1;
 	u64 gmxport:16;
 #endif
 
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_console.c b/drivers/net/ethernet/cavium/liquidio/octeon_console.c
index 01a50f3..edbbda4 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_console.c
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_console.c
@@ -19,10 +19,10 @@
 * This file may also be available under a different license from Cavium.
 * Contact Cavium, Inc. for more information
 **********************************************************************/
-
 /**
  * @file octeon_console.c
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/crc32.h>
@@ -267,8 +267,8 @@ static int __cvmx_bootmem_check_version(struct octeon_device *oct,
 		(u32)CVMX_BOOTMEM_DESC_GET_FIELD(oct, major_version);
 	minor_version =
 		(u32)CVMX_BOOTMEM_DESC_GET_FIELD(oct, minor_version);
-	dev_dbg(&oct->pci_dev->dev, "%s: major_version=%d\n", __func__,
-		major_version);
+	pr_devel("%s: major_version=%d\n", __func__,
+		 major_version);
 	if ((major_version > 3) ||
 	    (exact_match && major_version != exact_match)) {
 		dev_err(&oct->pci_dev->dev, "bootmem ver mismatch %d.%d addr:0x%llx\n",
@@ -391,7 +391,7 @@ int octeon_console_send_cmd(struct octeon_device *oct, char *cmd_str,
 {
 	u32 len = (u32)strlen(cmd_str);
 
-	dev_dbg(&oct->pci_dev->dev, "sending \"%s\" to bootloader\n", cmd_str);
+	pr_devel("sending \"%s\" to bootloader\n", cmd_str);
 
 	if (len > BOOTLOADER_PCI_WRITE_BUFFER_STR_LEN - 1) {
 		dev_err(&oct->pci_dev->dev, "Command string too long, max length is: %d\n",
@@ -428,8 +428,8 @@ int octeon_console_send_cmd(struct octeon_device *oct, char *cmd_str,
 int octeon_wait_for_bootloader(struct octeon_device *oct,
 			       u32 wait_time_hundredths)
 {
-	dev_dbg(&oct->pci_dev->dev, "waiting %d0 ms for bootloader\n",
-		wait_time_hundredths);
+	pr_devel("waiting %d0 ms for bootloader\n",
+		 wait_time_hundredths);
 
 	if (octeon_mem_access_ok(oct))
 		return -1;
@@ -569,8 +569,8 @@ int octeon_init_consoles(struct octeon_device *oct)
 			num_consoles));
 	oct->console_desc_addr = addr;
 
-	dev_dbg(&oct->pci_dev->dev, "Initialized consoles. %d available\n",
-		oct->num_consoles);
+	pr_devel("Initialized consoles. %d available\n",
+		 oct->num_consoles);
 
 	return ret;
 }
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.h b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
index 18e3050..3a71451 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_device.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
@@ -486,6 +486,9 @@ struct octeon_device {
 
 	int msix_on;
 
+	/** Mail Box details of each octeon queue. */
+	struct octeon_mbox  *mbox[MAX_POSSIBLE_VFS];
+
 	/** IOq information of it's corresponding MSI-X interrupt. */
 	struct octeon_ioq_vector    *ioq_vector;
 
@@ -505,6 +508,7 @@ struct octeon_device {
 #define  OCTEON_CN6XXX(oct)           ((oct->chip_id == OCTEON_CN66XX) || \
 				       (oct->chip_id == OCTEON_CN68XX))
 #define  OCTEON_CN23XX_PF(oct)        (oct->chip_id == OCTEON_CN23XX_PF_VID)
+#define  OCTEON_CN23XX_VF(oct)        (oct->chip_id == OCTEON_CN23XX_VF_VID)
 #define CHIP_FIELD(oct, TYPE, field)             \
 	(((struct octeon_ ## TYPE  *)(oct->chip))->field)
 
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
new file mode 100644
index 0000000..178f4f5
--- /dev/null
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
@@ -0,0 +1,322 @@
+/**********************************************************************
+* Author: Cavium, Inc.
+*
+* Contact: support@cavium.com
+*          Please include "LiquidIO" in the subject.
+*
+* Copyright (c) 2003-2015 Cavium, Inc.
+*
+* This file is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License, Version 2, as
+* published by the Free Software Foundation.
+*
+* This file is distributed in the hope that it will be useful, but
+* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+* NONINFRINGEMENT.  See the GNU General Public License for more
+* details.
+*
+* This file may also be available under a different license from Cavium.
+* Contact Cavium, Inc. for more information
+**********************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include "liquidio_common.h"
+#include "octeon_droq.h"
+#include "octeon_iq.h"
+#include "response_manager.h"
+#include "octeon_device.h"
+#include "octeon_main.h"
+#include "octeon_mailbox.h"
+
+/**
+ * octeon_mbox_read:
+ * @oct: Pointer mailbox
+ *
+ * Reads the 8-bytes of data from the mbox register
+ * Writes back the acknowldgement inidcating completion of read
+ */
+int octeon_mbox_read(struct octeon_mbox *mbox)
+{
+	int ret = 0;
+	union octeon_mbox_message msg;
+
+	spin_lock(&mbox->lock);
+
+	msg.u64 = readq(mbox->mbox_read_reg);
+
+	if ((msg.u64 == OCTEON_PFVFACK) || (msg.u64 == OCTEON_PFVFSIG)) {
+		spin_unlock(&mbox->lock);
+		return 0;
+	}
+
+	if (mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVING) {
+		mbox->mbox_req.data[mbox->mbox_req.recv_len - 1] = msg.u64;
+		mbox->mbox_req.recv_len++;
+	} else {
+		if (mbox->state & OCTEON_MBOX_STATE_RESPONSE_RECEIVING) {
+			mbox->mbox_resp.data[mbox->mbox_resp.recv_len - 1] =
+				msg.u64;
+			mbox->mbox_resp.recv_len++;
+		} else {
+			if ((mbox->state & OCTEON_MBOX_STATE_IDLE) &&
+			    (msg.s.type == OCTEON_MBOX_REQUEST)) {
+				mbox->state &= ~OCTEON_MBOX_STATE_IDLE;
+				mbox->state |=
+				    OCTEON_MBOX_STATE_REQUEST_RECEIVING;
+				mbox->mbox_req.msg.u64 = msg.u64;
+				mbox->mbox_req.q_no = mbox->q_no;
+				mbox->mbox_req.recv_len = 1;
+			} else {
+				if ((mbox->state &
+				     OCTEON_MBOX_STATE_RESPONSE_PENDING) &&
+				    (msg.s.type == OCTEON_MBOX_RESPONSE)) {
+					mbox->state &=
+					    ~OCTEON_MBOX_STATE_RESPONSE_PENDING;
+					mbox->state |=
+					    OCTEON_MBOX_STATE_RESPONSE_RECEIVING
+					    ;
+					mbox->mbox_resp.msg.u64 = msg.u64;
+					mbox->mbox_resp.q_no = mbox->q_no;
+					mbox->mbox_resp.recv_len = 1;
+				} else {
+					writeq(OCTEON_PFVFERR,
+					       mbox->mbox_read_reg);
+					mbox->state |= OCTEON_MBOX_STATE_ERROR;
+					spin_unlock(&mbox->lock);
+					return 1;
+				}
+			}
+		}
+	}
+
+	if (mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVING) {
+		if (mbox->mbox_req.recv_len < msg.s.len) {
+			ret = 0;
+		} else {
+			mbox->state &= ~OCTEON_MBOX_STATE_REQUEST_RECEIVING;
+			mbox->state |= OCTEON_MBOX_STATE_REQUEST_RECEIVED;
+			ret = 1;
+		}
+	} else {
+		if (mbox->state & OCTEON_MBOX_STATE_RESPONSE_RECEIVING) {
+			if (mbox->mbox_resp.recv_len < msg.s.len) {
+				ret = 0;
+			} else {
+				mbox->state &=
+				    ~OCTEON_MBOX_STATE_RESPONSE_RECEIVING;
+				mbox->state |=
+				    OCTEON_MBOX_STATE_RESPONSE_RECEIVED;
+				ret = 1;
+			}
+		} else {
+			WARN_ON(1);
+		}
+	}
+
+	writeq(OCTEON_PFVFACK, mbox->mbox_read_reg);
+
+	spin_unlock(&mbox->lock);
+
+	return ret;
+}
+
+/**
+ * octeon_mbox_write:
+ * @oct: Pointer Octeon Device
+ * @mbox_cmd: Cmd to send to mailbox.
+ *
+ * Populates the queue specific mbox structure
+ * with cmd information.
+ * Write the cmd to mbox register
+ */
+int octeon_mbox_write(struct octeon_device *oct,
+		      struct octeon_mbox_cmd *mbox_cmd)
+{
+	struct octeon_mbox *mbox = oct->mbox[mbox_cmd->q_no];
+	unsigned long flags;
+	u32 count, i, ret = OCTEON_MBOX_STATUS_SUCCESS;
+
+	spin_lock_irqsave(&mbox->lock, flags);
+
+	if ((mbox_cmd->msg.s.type == OCTEON_MBOX_RESPONSE) &&
+	    !(mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVED)) {
+		spin_unlock_irqrestore(&mbox->lock, flags);
+		return OCTEON_MBOX_STATUS_FAILED;
+	}
+
+	if ((mbox_cmd->msg.s.type == OCTEON_MBOX_REQUEST) &&
+	    !(mbox->state & OCTEON_MBOX_STATE_IDLE)) {
+		spin_unlock_irqrestore(&mbox->lock, flags);
+		return OCTEON_MBOX_STATUS_BUSY;
+	}
+
+	if (mbox_cmd->msg.s.type == OCTEON_MBOX_REQUEST) {
+		memcpy(&mbox->mbox_resp, mbox_cmd,
+		       sizeof(struct octeon_mbox_cmd));
+		mbox->state = OCTEON_MBOX_STATE_RESPONSE_PENDING;
+	}
+
+	spin_unlock_irqrestore(&mbox->lock, flags);
+
+	count = 0;
+
+	while (readq(mbox->mbox_write_reg) != OCTEON_PFVFSIG) {
+		schedule_timeout_uninterruptible(10);
+		if (count++ == 1000) {
+			ret = OCTEON_MBOX_STATUS_FAILED;
+			break;
+		}
+	}
+
+	if (ret == OCTEON_MBOX_STATUS_SUCCESS) {
+		writeq(mbox_cmd->msg.u64, mbox->mbox_write_reg);
+		for (i = 0; i < (u32)(mbox_cmd->msg.s.len - 1); i++) {
+			count = 0;
+			while (readq(mbox->mbox_write_reg) !=
+			       OCTEON_PFVFACK) {
+				schedule_timeout_uninterruptible(10);
+				if (count++ == 1000) {
+					ret = OCTEON_MBOX_STATUS_FAILED;
+					break;
+				}
+			}
+			writeq(mbox_cmd->data[i], mbox->mbox_write_reg);
+		}
+	}
+
+	spin_lock_irqsave(&mbox->lock, flags);
+	if (mbox_cmd->msg.s.type == OCTEON_MBOX_RESPONSE) {
+		mbox->state = OCTEON_MBOX_STATE_IDLE;
+		writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
+	} else {
+		if ((!mbox_cmd->msg.s.resp_needed) ||
+		    (ret == OCTEON_MBOX_STATUS_FAILED)) {
+			mbox->state &= ~OCTEON_MBOX_STATE_RESPONSE_PENDING;
+			if (!(mbox->state &
+			      (OCTEON_MBOX_STATE_REQUEST_RECEIVING |
+			       OCTEON_MBOX_STATE_REQUEST_RECEIVED)))
+				mbox->state = OCTEON_MBOX_STATE_IDLE;
+		}
+	}
+	spin_unlock_irqrestore(&mbox->lock, flags);
+
+	return ret;
+}
+
+/**
+ * octeon_mbox_process_cmd:
+ * @mbox: Pointer mailbox
+ * @mbox_cmd: Pointer to command received
+ *
+ * Process the cmd received in mbox
+ */
+static int octeon_mbox_process_cmd(struct octeon_mbox *mbox,
+				   struct octeon_mbox_cmd *mbox_cmd)
+{
+	struct octeon_device *oct = mbox->oct_dev;
+
+	switch (mbox_cmd->msg.s.cmd) {
+	case OCTEON_VF_ACTIVE:
+		pr_devel("got vfactive sending data back\n");
+		mbox_cmd->msg.s.type = OCTEON_MBOX_RESPONSE;
+		mbox_cmd->msg.s.resp_needed = 1;
+		mbox_cmd->msg.s.len = 2;
+		mbox_cmd->data[0] = 0; /* VF version is in mbox_cmd->data[0] */
+		((struct lio_version *)&mbox_cmd->data[0])->major =
+			LIQUIDIO_BASE_MAJOR_VERSION;
+		((struct lio_version *)&mbox_cmd->data[0])->minor =
+			LIQUIDIO_BASE_MINOR_VERSION;
+		((struct lio_version *)&mbox_cmd->data[0])->micro =
+			LIQUIDIO_BASE_MICRO_VERSION;
+		memcpy(mbox_cmd->msg.s.params, (uint8_t *)&oct->pfvf_hsword, 6);
+		/* Sending core cofig info to the corresponding active VF.*/
+		octeon_mbox_write(oct, mbox_cmd);
+		break;
+
+	case OCTEON_VF_FLR_REQUEST:
+		dev_info(&oct->pci_dev->dev,
+			 "got a request for FLR from VF that owns DPI ring %u\n",
+			 mbox->q_no);
+		pci_reset_function(
+			oct->sriov_info.dpiring_to_vfpcidev_lut[mbox->q_no]);
+		break;
+
+	case OCTEON_PF_CHANGED_VF_MACADDR:
+		if (OCTEON_CN23XX_VF(oct))
+			octeon_pf_changed_vf_macaddr(oct,
+						     mbox_cmd->msg.s.params);
+		break;
+
+	default:
+		break;
+	}
+	return 0;
+}
+
+/**
+ *octeon_mbox_process_message:
+ *
+ * Process the received mbox message.
+ */
+int octeon_mbox_process_message(struct octeon_mbox *mbox)
+{
+	struct octeon_mbox_cmd mbox_cmd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mbox->lock, flags);
+
+	if (mbox->state & OCTEON_MBOX_STATE_ERROR) {
+		if (mbox->state & (OCTEON_MBOX_STATE_RESPONSE_PENDING |
+				   OCTEON_MBOX_STATE_RESPONSE_RECEIVING)) {
+			memcpy(&mbox_cmd, &mbox->mbox_resp,
+			       sizeof(struct octeon_mbox_cmd));
+			mbox->state = OCTEON_MBOX_STATE_IDLE;
+			writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
+			spin_unlock_irqrestore(&mbox->lock, flags);
+			mbox_cmd.recv_status = 1;
+			if (mbox_cmd.fn)
+				mbox_cmd.fn(mbox->oct_dev, &mbox_cmd,
+					    mbox_cmd.fn_arg);
+			return 0;
+		}
+
+		mbox->state = OCTEON_MBOX_STATE_IDLE;
+		writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
+		spin_unlock_irqrestore(&mbox->lock, flags);
+		return 0;
+	}
+
+	if (mbox->state & OCTEON_MBOX_STATE_RESPONSE_RECEIVED) {
+		memcpy(&mbox_cmd, &mbox->mbox_resp,
+		       sizeof(struct octeon_mbox_cmd));
+		mbox->state = OCTEON_MBOX_STATE_IDLE;
+		writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
+		spin_unlock_irqrestore(&mbox->lock, flags);
+		mbox_cmd.recv_status = 0;
+		if (mbox_cmd.fn)
+			mbox_cmd.fn(mbox->oct_dev, &mbox_cmd, mbox_cmd.fn_arg);
+		return 0;
+	}
+
+	if (mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVED) {
+		memcpy(&mbox_cmd, &mbox->mbox_req,
+		       sizeof(struct octeon_mbox_cmd));
+		if (!mbox_cmd.msg.s.resp_needed) {
+			mbox->state &= ~OCTEON_MBOX_STATE_REQUEST_RECEIVED;
+			if (!(mbox->state &&
+			      OCTEON_MBOX_STATE_RESPONSE_PENDING))
+				mbox->state = OCTEON_MBOX_STATE_IDLE;
+			writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
+		}
+
+		spin_unlock_irqrestore(&mbox->lock, flags);
+		octeon_mbox_process_cmd(mbox, &mbox_cmd);
+		return 0;
+	}
+
+	WARN_ON(1);
+
+	return 0;
+}
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.h b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.h
new file mode 100644
index 0000000..9a3bdec
--- /dev/null
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.h
@@ -0,0 +1,116 @@
+/**********************************************************************
+* Author: Cavium, Inc.
+*
+* Contact: support@cavium.com
+*          Please include "LiquidIO" in the subject.
+*
+* Copyright (c) 2003-2015 Cavium, Inc.
+*
+* This file is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License, Version 2, as
+* published by the Free Software Foundation.
+*
+* This file is distributed in the hope that it will be useful, but
+* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+* NONINFRINGEMENT.  See the GNU General Public License for more
+* details.
+*
+* This file may also be available under a different license from Cavium.
+* Contact Cavium, Inc. for more information
+**********************************************************************/
+#ifndef __MAILBOX_H__
+#define __MAILBOX_H__
+
+/* Macros for Mail Box Communication */
+
+#define OCTEON_MBOX_DATA_MAX	32
+
+#define OCTEON_VF_ACTIVE		0x1
+#define OCTEON_VF_FLR_REQUEST		0x2
+#define OCTEON_PF_CHANGED_VF_MACADDR	0x4
+
+/*Macro for Read acknowldgement*/
+#define OCTEON_PFVFACK			0xffffffffffffffff
+#define OCTEON_PFVFSIG			0x1122334455667788
+#define OCTEON_PFVFERR			0xDEADDEADDEADDEAD
+
+enum octeon_mbox_cmd_status {
+	OCTEON_MBOX_STATUS_SUCCESS = 0,
+	OCTEON_MBOX_STATUS_FAILED = 1,
+	OCTEON_MBOX_STATUS_BUSY = 2
+};
+
+enum octeon_mbox_message_type {
+	OCTEON_MBOX_REQUEST = 0,
+	OCTEON_MBOX_RESPONSE = 1
+};
+
+union octeon_mbox_message {
+	u64 u64;
+	struct {
+		u16 type : 1;
+		u16 resp_needed : 1;
+		u16 cmd : 6;
+		u16 len : 8;
+		u8 params[6];
+	} s;
+};
+
+typedef void (*octeon_mbox_callback_t)(void *, void *, void *);
+
+struct octeon_mbox_cmd {
+	union octeon_mbox_message msg;
+	u64 data[OCTEON_MBOX_DATA_MAX];
+	u32 q_no;
+	u32 recv_len;
+	u32 recv_status;
+	octeon_mbox_callback_t fn;
+	void *fn_arg;
+};
+
+enum octeon_mbox_state {
+	OCTEON_MBOX_STATE_IDLE = 1,
+	OCTEON_MBOX_STATE_REQUEST_RECEIVING = 2,
+	OCTEON_MBOX_STATE_REQUEST_RECEIVED = 4,
+	OCTEON_MBOX_STATE_RESPONSE_PENDING = 8,
+	OCTEON_MBOX_STATE_RESPONSE_RECEIVING = 16,
+	OCTEON_MBOX_STATE_RESPONSE_RECEIVED = 16,
+	OCTEON_MBOX_STATE_ERROR = 32
+};
+
+struct octeon_mbox {
+	/** A spinlock to protect access to this q_mbox. */
+	spinlock_t lock;
+
+	struct octeon_device *oct_dev;
+
+	u32 q_no;
+
+	enum octeon_mbox_state state;
+
+	struct cavium_wk mbox_poll_wk;
+
+	/** SLI_MAC_PF_MBOX_INT for PF, SLI_PKT_MBOX_INT for VF. */
+	void *mbox_int_reg;
+
+	/** SLI_PKT_PF_VF_MBOX_SIG(0) for PF, SLI_PKT_PF_VF_MBOX_SIG(1) for VF.
+	 */
+	void *mbox_write_reg;
+
+	/** SLI_PKT_PF_VF_MBOX_SIG(1) for PF, SLI_PKT_PF_VF_MBOX_SIG(0) for VF.
+	 */
+	void *mbox_read_reg;
+
+	struct octeon_mbox_cmd mbox_req;
+
+	struct octeon_mbox_cmd mbox_resp;
+
+};
+
+int octeon_mbox_read(struct octeon_mbox *mbox);
+int octeon_mbox_write(struct octeon_device *oct,
+		      struct octeon_mbox_cmd *mbox_cmd);
+int octeon_mbox_process_message(struct octeon_mbox *mbox);
+
+#endif
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_main.h b/drivers/net/ethernet/cavium/liquidio/octeon_main.h
index 366298f..4ad9d67 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_main.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_main.h
@@ -66,7 +66,7 @@ void octeon_update_tx_completion_counters(void *buf, int reqtype,
 					  unsigned int *bytes_compl);
 void octeon_report_tx_completion_to_bql(void *txq, unsigned int pkts_compl,
 					unsigned int bytes_compl);
-
+void octeon_pf_changed_vf_macaddr(struct octeon_device *oct, u8 *mac);
 /** Swap 8B blocks */
 static inline void octeon_swap_8B_data(u64 *data, u32 blocks)
 {
@@ -84,8 +84,8 @@ static inline void octeon_swap_8B_data(u64 *data, u32 blocks)
   */
 static inline void octeon_unmap_pci_barx(struct octeon_device *oct, int baridx)
 {
-	dev_dbg(&oct->pci_dev->dev, "Freeing PCI mapped regions for Bar%d\n",
-		baridx);
+	pr_devel("Freeing PCI mapped regions for Bar%d\n",
+		 baridx);
 
 	if (oct->mmio[baridx].done)
 		iounmap(oct->mmio[baridx].hw_addr);
@@ -125,9 +125,9 @@ static inline int octeon_map_pci_barx(struct octeon_device *oct,
 		ioremap(oct->mmio[baridx].start, mapped_len);
 	oct->mmio[baridx].mapped_len = mapped_len;
 
-	dev_dbg(&oct->pci_dev->dev, "BAR%d start: 0x%llx mapped %u of %u bytes\n",
-		baridx, oct->mmio[baridx].start, mapped_len,
-		oct->mmio[baridx].len);
+	pr_devel("BAR%d start: 0x%llx mapped %u of %u bytes\n",
+		 baridx, oct->mmio[baridx].start, mapped_len,
+		 oct->mmio[baridx].len);
 
 	if (!oct->mmio[baridx].hw_addr) {
 		dev_err(&oct->pci_dev->dev, "error ioremap for bar %d\n",
diff --git a/drivers/net/ethernet/cavium/liquidio/request_manager.c b/drivers/net/ethernet/cavium/liquidio/request_manager.c
index 90866bb..4291b37 100644
--- a/drivers/net/ethernet/cavium/liquidio/request_manager.c
+++ b/drivers/net/ethernet/cavium/liquidio/request_manager.c
@@ -19,6 +19,7 @@
  * This file may also be available under a different license from Cavium.
  * Contact Cavium, Inc. for more information
  **********************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
@@ -125,8 +126,8 @@ int octeon_init_instr_queue(struct octeon_device *oct,
 
 	memset(iq->request_list, 0, sizeof(*iq->request_list) * num_descs);
 
-	dev_dbg(&oct->pci_dev->dev, "IQ[%d]: base: %p basedma: %llx count: %d\n",
-		iq_no, iq->base_addr, iq->base_addr_dma, iq->max_count);
+	pr_devel("IQ[%d]: base: %p basedma: %llx count: %d\n",
+		 iq_no, iq->base_addr, iq->base_addr_dma, iq->max_count);
 
 	iq->txpciq.u64 = txpciq.u64;
 	iq->fill_threshold = (u32)conf->db_min;
@@ -211,8 +212,8 @@ int octeon_setup_iq(struct octeon_device *oct,
 	int numa_node = cpu_to_node(iq_no % num_online_cpus());
 
 	if (oct->instr_queue[iq_no]) {
-		dev_dbg(&oct->pci_dev->dev, "IQ is in use. Cannot create the IQ: %d again\n",
-			iq_no);
+		pr_devel("IQ is in use. Cannot create the IQ: %d again\n",
+			 iq_no);
 		oct->instr_queue[iq_no]->txpciq.u64 = txpciq.u64;
 		oct->instr_queue[iq_no]->app_ctx = app_ctx;
 		return 0;
-- 
1.8.3.1

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

* [PATCH net-next 4/5] liquidio CN23XX: mailbox interrupt processing
  2016-09-09 20:08 [PATCH net-next 0/5] liquidio CN23XX VF support Raghu Vatsavayi
                   ` (2 preceding siblings ...)
  2016-09-09 20:08 ` [PATCH net-next 3/5] liquidio CN23XX: Mailbox support Raghu Vatsavayi
@ 2016-09-09 20:08 ` Raghu Vatsavayi
  2016-09-09 20:08 ` [PATCH net-next 5/5] liquidio CN23XX: VF related operations Raghu Vatsavayi
  4 siblings, 0 replies; 9+ messages in thread
From: Raghu Vatsavayi @ 2016-09-09 20:08 UTC (permalink / raw)
  To: davem
  Cc: netdev, Raghu Vatsavayi, Derek Chickles, Satanand Burla,
	Felix Manlunas, Raghu Vatsavayi

Adds support for mailbox interrupt processing of various
commands.

Signed-off-by: Derek Chickles <derek.chickles@caviumnetworks.com>
Signed-off-by: Satanand Burla <satananda.burla@caviumnetworks.com>
Signed-off-by: Felix Manlunas <felix.manlunas@caviumnetworks.com>
Signed-off-by: Raghu Vatsavayi <raghu.vatsavayi@caviumnetworks.com>
---
 .../ethernet/cavium/liquidio/cn23xx_pf_device.c    | 157 +++++++++++++++++++++
 drivers/net/ethernet/cavium/liquidio/lio_main.c    |   8 +-
 .../net/ethernet/cavium/liquidio/octeon_device.c   |   1 +
 .../net/ethernet/cavium/liquidio/octeon_device.h   |   6 +
 drivers/net/ethernet/cavium/liquidio/octeon_droq.c |  28 ++--
 5 files changed, 184 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
index b3c61302..4d975d8 100644
--- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
+++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
@@ -30,6 +30,7 @@
 #include "octeon_device.h"
 #include "cn23xx_pf_device.h"
 #include "octeon_main.h"
+#include "octeon_mailbox.h"
 
 #define RESET_NOTDONE 0
 #define RESET_DONE 1
@@ -682,6 +683,118 @@ static void cn23xx_setup_oq_regs(struct octeon_device *oct, u32 oq_no)
 	}
 }
 
+static void cn23xx_pf_mbox_thread(struct work_struct *work)
+{
+	struct cavium_wk *wk = (struct cavium_wk *)work;
+	struct octeon_mbox *mbox = (struct octeon_mbox *)wk->ctxptr;
+	struct octeon_device *oct = mbox->oct_dev;
+	u64 mbox_int_val, val64;
+	u32 q_no, i;
+
+	if (oct->rev_id < OCTEON_CN23XX_REV_1_1) {
+		/*read and clear by writing 1*/
+		mbox_int_val = readq(mbox->mbox_int_reg);
+		writeq(mbox_int_val, mbox->mbox_int_reg);
+
+		for (i = 0; i < oct->sriov_info.num_vfs; i++) {
+			q_no = i * oct->sriov_info.rings_per_vf;
+
+			val64 = readq(oct->mbox[q_no]->mbox_write_reg);
+
+			if (val64 && (val64 != OCTEON_PFVFACK)) {
+				if (octeon_mbox_read(oct->mbox[q_no]))
+					octeon_mbox_process_message(
+					    oct->mbox[q_no]);
+			}
+		}
+
+		schedule_delayed_work(&wk->work, msecs_to_jiffies(10));
+	} else {
+		octeon_mbox_process_message(mbox);
+	}
+}
+
+static int cn23xx_setup_pf_mbox(struct octeon_device *oct)
+{
+	u32 q_no, i;
+	u16 mac_no = oct->pcie_port;
+	u16 pf_num = oct->pf_num;
+	struct octeon_mbox *mbox = NULL;
+
+	if (!oct->sriov_info.num_vfs)
+		return 0;
+
+	for (i = 0; i < oct->sriov_info.num_vfs; i++) {
+		q_no = i * oct->sriov_info.rings_per_vf;
+
+		mbox = vmalloc(sizeof(*mbox));
+		if (!mbox)
+			goto free_mbox;
+
+		memset(mbox, 0, sizeof(struct octeon_mbox));
+
+		spin_lock_init(&mbox->lock);
+
+		mbox->oct_dev = oct;
+
+		mbox->q_no = q_no;
+
+		mbox->state = OCTEON_MBOX_STATE_IDLE;
+
+		/* PF mbox interrupt reg */
+		mbox->mbox_int_reg = (u8 *)oct->mmio[0].hw_addr +
+				     CN23XX_SLI_MAC_PF_MBOX_INT(mac_no, pf_num);
+
+		/* PF writes into SIG0 reg */
+		mbox->mbox_write_reg = (u8 *)oct->mmio[0].hw_addr +
+				       CN23XX_SLI_PKT_PF_VF_MBOX_SIG(q_no, 0);
+
+		/* PF reads from SIG1 reg */
+		mbox->mbox_read_reg = (u8 *)oct->mmio[0].hw_addr +
+				      CN23XX_SLI_PKT_PF_VF_MBOX_SIG(q_no, 1);
+
+		/*Mail Box Thread creation*/
+		INIT_DELAYED_WORK(&mbox->mbox_poll_wk.work,
+				  cn23xx_pf_mbox_thread);
+		mbox->mbox_poll_wk.ctxptr = (void *)mbox;
+
+		oct->mbox[q_no] = mbox;
+
+		writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
+	}
+
+	if (oct->rev_id < OCTEON_CN23XX_REV_1_1)
+		schedule_delayed_work(&oct->mbox[0]->mbox_poll_wk.work,
+				      msecs_to_jiffies(0));
+
+	return 0;
+
+free_mbox:
+	while (i) {
+		i--;
+		vfree(oct->mbox[i]);
+	}
+
+	return 1;
+}
+
+static int cn23xx_free_pf_mbox(struct octeon_device *oct)
+{
+	u32 q_no, i;
+
+	if (!oct->sriov_info.num_vfs)
+		return 0;
+
+	for (i = 0; i < oct->sriov_info.num_vfs; i++) {
+		q_no = i * oct->sriov_info.rings_per_vf;
+		cancel_delayed_work_sync(
+		    &oct->mbox[q_no]->mbox_poll_wk.work);
+		vfree(oct->mbox[q_no]);
+	}
+
+	return 0;
+}
+
 static int cn23xx_enable_io_queues(struct octeon_device *oct)
 {
 	u64 reg_val;
@@ -876,6 +989,29 @@ static u64 cn23xx_pf_msix_interrupt_handler(void *dev)
 	return ret;
 }
 
+static void cn23xx_handle_pf_mbox_intr(struct octeon_device *oct)
+{
+	u64 mbox_int_val;
+	u32 i, q_no;
+	struct delayed_work *work;
+
+	mbox_int_val = readq(oct->mbox[0]->mbox_int_reg);
+
+	for (i = 0; i < oct->sriov_info.num_vfs; i++) {
+		q_no = i * oct->sriov_info.rings_per_vf;
+
+		if (mbox_int_val & BIT_ULL(q_no)) {
+			writeq(BIT_ULL(q_no),
+			       oct->mbox[0]->mbox_int_reg);
+			if (octeon_mbox_read(oct->mbox[q_no])) {
+				work = &oct->mbox[q_no]->mbox_poll_wk.work;
+				schedule_delayed_work(work,
+						      msecs_to_jiffies(0));
+			}
+		}
+	}
+}
+
 static irqreturn_t cn23xx_interrupt_handler(void *dev)
 {
 	struct octeon_device *oct = (struct octeon_device *)dev;
@@ -891,6 +1027,10 @@ static irqreturn_t cn23xx_interrupt_handler(void *dev)
 		dev_err(&oct->pci_dev->dev, "OCTEON[%d]: Error Intr: 0x%016llx\n",
 			oct->octeon_id, CVM_CAST64(intr64));
 
+	/* When VFs write into MBOX_SIG2 reg,these intr is set in PF */
+	if (intr64 & CN23XX_INTR_VF_MBOX)
+		cn23xx_handle_pf_mbox_intr(oct);
+
 	if (oct->msix_on != LIO_FLAG_MSIX_ENABLED) {
 		if (intr64 & CN23XX_INTR_PKT_DATA)
 			oct->int_status |= OCT_DEV_INTR_PKT_DATA;
@@ -981,6 +1121,13 @@ static void cn23xx_enable_pf_interrupt(struct octeon_device *oct, u8 intr_flag)
 		intr_val = readq(cn23xx->intr_enb_reg64);
 		intr_val |= CN23XX_INTR_PKT_DATA;
 		writeq(intr_val, cn23xx->intr_enb_reg64);
+	} else if ((intr_flag & OCTEON_MBOX_INTR) &&
+		   (oct->sriov_info.num_vfs > 0)) {
+		if (oct->rev_id >= OCTEON_CN23XX_REV_1_1) {
+			intr_val = readq(cn23xx->intr_enb_reg64);
+			intr_val |= CN23XX_INTR_VF_MBOX;
+			writeq(intr_val, cn23xx->intr_enb_reg64);
+		}
 	}
 }
 
@@ -996,6 +1143,13 @@ static void cn23xx_disable_pf_interrupt(struct octeon_device *oct, u8 intr_flag)
 		intr_val = readq(cn23xx->intr_enb_reg64);
 		intr_val &= ~CN23XX_INTR_PKT_DATA;
 		writeq(intr_val, cn23xx->intr_enb_reg64);
+	} else if ((intr_flag & OCTEON_MBOX_INTR) &&
+		   (oct->sriov_info.num_vfs > 0)) {
+		if (oct->rev_id >= OCTEON_CN23XX_REV_1_1) {
+			intr_val = readq(cn23xx->intr_enb_reg64);
+			intr_val &= ~CN23XX_INTR_VF_MBOX;
+			writeq(intr_val, cn23xx->intr_enb_reg64);
+		}
 	}
 }
 
@@ -1268,6 +1422,9 @@ int setup_cn23xx_octeon_pf_device(struct octeon_device *oct)
 
 	oct->fn_list.setup_iq_regs = cn23xx_setup_iq_regs;
 	oct->fn_list.setup_oq_regs = cn23xx_setup_oq_regs;
+	oct->fn_list.setup_mbox = cn23xx_setup_pf_mbox;
+	oct->fn_list.free_mbox = cn23xx_free_pf_mbox;
+
 	oct->fn_list.process_interrupt_regs = cn23xx_interrupt_handler;
 	oct->fn_list.msix_interrupt_handler = cn23xx_pf_msix_interrupt_handler;
 
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index 438d32f..e480c23 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -1449,8 +1449,10 @@ static void octeon_destroy_resources(struct octeon_device *oct)
 				pci_disable_msi(oct->pci_dev);
 		}
 
-		if (OCTEON_CN23XX_PF(oct))
+		if (OCTEON_CN23XX_PF(oct)) {
 			octeon_free_ioq_vector(oct);
+			oct->fn_list.free_mbox(oct);
+		}
 	/* fallthrough */
 	case OCT_DEV_IN_RESET:
 	case OCT_DEV_DROQ_INIT_DONE:
@@ -4275,6 +4277,10 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
 	atomic_set(&octeon_dev->status, OCT_DEV_DROQ_INIT_DONE);
 
 	if (OCTEON_CN23XX_PF(octeon_dev)) {
+		if (octeon_dev->fn_list.setup_mbox(octeon_dev)) {
+			dev_err(&octeon_dev->pci_dev->dev, "OCTEON: Mailbox setup failed\n");
+			return 1;
+		}
 		if (octeon_allocate_ioq_vector(octeon_dev)) {
 			dev_err(&octeon_dev->pci_dev->dev, "OCTEON: ioq vector allocation failed\n");
 			return 1;
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.c b/drivers/net/ethernet/cavium/liquidio/octeon_device.c
index 03a4eac..1136801 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_device.c
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.c
@@ -768,6 +768,7 @@ octeon_allocate_ioq_vector(struct octeon_device  *oct)
 		ioq_vector->oct_dev	= oct;
 		ioq_vector->iq_index	= i;
 		ioq_vector->droq_index	= i;
+		ioq_vector->mbox	= oct->mbox[i];
 
 		cpu_num = i % num_online_cpus();
 		cpumask_set_cpu(cpu_num, &ioq_vector->affinity_mask);
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.h b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
index 3a71451..fc62d7d 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_device.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
@@ -54,6 +54,7 @@ enum octeon_pci_swap_mode {
 };
 
 #define  OCTEON_OUTPUT_INTR   (2)
+#define  OCTEON_MBOX_INTR     (4)
 #define  OCTEON_ALL_INTR      0xff
 
 /*---------------   PCI BAR1 index registers -------------*/
@@ -209,6 +210,10 @@ struct octeon_fn_list {
 
 	irqreturn_t (*process_interrupt_regs)(void *);
 	u64 (*msix_interrupt_handler)(void *);
+
+	int (*setup_mbox)(struct octeon_device *);
+	int (*free_mbox)(struct octeon_device *);
+
 	int (*soft_reset)(struct octeon_device *);
 	int (*setup_device_regs)(struct octeon_device *);
 	void (*bar1_idx_setup)(struct octeon_device *, u64, u32, int);
@@ -349,6 +354,7 @@ struct octeon_ioq_vector {
 	int		        iq_index;
 	int		        droq_index;
 	int			vector;
+	struct octeon_mbox     *mbox;
 	struct cpumask		affinity_mask;
 	u32			ioq_num;
 };
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_droq.c b/drivers/net/ethernet/cavium/liquidio/octeon_droq.c
index f60e532..924f158 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_droq.c
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_droq.c
@@ -19,6 +19,7 @@
 * This file may also be available under a different license from Cavium.
 * Contact Cavium, Inc. for more information
 **********************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
@@ -211,7 +212,7 @@ int octeon_delete_droq(struct octeon_device *oct, u32 q_no)
 {
 	struct octeon_droq *droq = oct->droq[q_no];
 
-	dev_dbg(&oct->pci_dev->dev, "%s[%d]\n", __func__, q_no);
+	pr_devel("%s[%d]\n", __func__, q_no);
 
 	octeon_droq_destroy_ring_buffers(oct, droq);
 	vfree(droq->recv_buf_list);
@@ -243,7 +244,7 @@ int octeon_init_droq(struct octeon_device *oct,
 	int orig_node = dev_to_node(&oct->pci_dev->dev);
 	int numa_node = cpu_to_node(q_no % num_online_cpus());
 
-	dev_dbg(&oct->pci_dev->dev, "%s[%d]\n", __func__, q_no);
+	pr_devel("%s[%d]\n", __func__, q_no);
 
 	droq = oct->droq[q_no];
 	memset(droq, 0, OCT_DROQ_SIZE);
@@ -290,10 +291,10 @@ int octeon_init_droq(struct octeon_device *oct,
 		return 1;
 	}
 
-	dev_dbg(&oct->pci_dev->dev, "droq[%d]: desc_ring: virt: 0x%p, dma: %lx\n",
-		q_no, droq->desc_ring, droq->desc_ring_dma);
-	dev_dbg(&oct->pci_dev->dev, "droq[%d]: num_desc: %d\n", q_no,
-		droq->max_count);
+	pr_devel("droq[%d]: desc_ring: virt: 0x%p, dma: %lx\n",
+		 q_no, droq->desc_ring, droq->desc_ring_dma);
+	pr_devel("droq[%d]: num_desc: %d\n", q_no,
+		 droq->max_count);
 
 	droq->info_list =
 		cnnic_numa_alloc_aligned_dma((droq->max_count *
@@ -327,8 +328,8 @@ int octeon_init_droq(struct octeon_device *oct,
 	droq->pkts_per_intr = c_pkts_per_intr;
 	droq->refill_threshold = c_refill_threshold;
 
-	dev_dbg(&oct->pci_dev->dev, "DROQ INIT: max_empty_descs: %d\n",
-		droq->max_empty_descs);
+	pr_devel("DROQ INIT: max_empty_descs: %d\n",
+		 droq->max_empty_descs);
 
 	spin_lock_init(&droq->lock);
 
@@ -628,9 +629,6 @@ octeon_droq_fast_process_packets(struct octeon_device *oct,
 			dev_err(&oct->pci_dev->dev,
 				"DROQ[%d] idx: %d len:0, pkt_cnt: %d\n",
 				droq->q_no, droq->read_idx, pkt_count);
-			print_hex_dump_bytes("", DUMP_PREFIX_ADDRESS,
-					     (u8 *)info,
-					     OCT_DROQ_INFO_SIZE);
 			break;
 		}
 
@@ -978,8 +976,8 @@ int octeon_create_droq(struct octeon_device *oct,
 	int numa_node = cpu_to_node(q_no % num_online_cpus());
 
 	if (oct->droq[q_no]) {
-		dev_dbg(&oct->pci_dev->dev, "Droq already in use. Cannot create droq %d again\n",
-			q_no);
+		pr_devel("Droq already in use. Cannot create droq %d again\n",
+			 q_no);
 		return 1;
 	}
 
@@ -1000,8 +998,8 @@ int octeon_create_droq(struct octeon_device *oct,
 
 	oct->num_oqs++;
 
-	dev_dbg(&oct->pci_dev->dev, "%s: Total number of OQ: %d\n", __func__,
-		oct->num_oqs);
+	pr_devel("%s: Total number of OQ: %d\n", __func__,
+		 oct->num_oqs);
 
 	/* Global Droq register settings */
 
-- 
1.8.3.1

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

* [PATCH net-next 5/5] liquidio CN23XX: VF related operations
  2016-09-09 20:08 [PATCH net-next 0/5] liquidio CN23XX VF support Raghu Vatsavayi
                   ` (3 preceding siblings ...)
  2016-09-09 20:08 ` [PATCH net-next 4/5] liquidio CN23XX: mailbox interrupt processing Raghu Vatsavayi
@ 2016-09-09 20:08 ` Raghu Vatsavayi
  4 siblings, 0 replies; 9+ messages in thread
From: Raghu Vatsavayi @ 2016-09-09 20:08 UTC (permalink / raw)
  To: davem
  Cc: netdev, Raghu Vatsavayi, Derek Chickles, Satanand Burla,
	Felix Manlunas, Raghu Vatsavayi

Adds support for VF related operations like mac address vlan
and link changes.

Signed-off-by: Derek Chickles <derek.chickles@caviumnetworks.com>
Signed-off-by: Satanand Burla <satananda.burla@caviumnetworks.com>
Signed-off-by: Felix Manlunas <felix.manlunas@caviumnetworks.com>
Signed-off-by: Raghu Vatsavayi <raghu.vatsavayi@caviumnetworks.com>
---
 .../ethernet/cavium/liquidio/cn23xx_pf_device.c    |  22 +++
 .../ethernet/cavium/liquidio/cn23xx_pf_device.h    |   3 +
 drivers/net/ethernet/cavium/liquidio/lio_main.c    | 211 +++++++++++++++++++++
 .../net/ethernet/cavium/liquidio/liquidio_common.h |   5 +
 .../net/ethernet/cavium/liquidio/octeon_device.h   |   8 +
 5 files changed, 249 insertions(+)

diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
index 4d975d8..49efce1 100644
--- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
+++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
@@ -23,6 +23,7 @@
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
+#include <linux/etherdevice.h>
 #include "liquidio_common.h"
 #include "octeon_droq.h"
 #include "octeon_iq.h"
@@ -1541,3 +1542,24 @@ int cn23xx_fw_loaded(struct octeon_device *oct)
 	val = octeon_read_csr64(oct, CN23XX_SLI_SCRATCH1);
 	return (val >> 1) & 1ULL;
 }
+
+void cn23xx_tell_vf_its_macaddr_changed(struct octeon_device *oct, int vfidx,
+					u8 *mac)
+{
+	if (oct->sriov_info.vf_drv_loaded_mask & BIT_ULL(vfidx)) {
+		struct octeon_mbox_cmd mbox_cmd;
+
+		mbox_cmd.msg.u64 = 0;
+		mbox_cmd.msg.s.type = OCTEON_MBOX_REQUEST;
+		mbox_cmd.msg.s.resp_needed = 0;
+		mbox_cmd.msg.s.cmd = OCTEON_PF_CHANGED_VF_MACADDR;
+		mbox_cmd.msg.s.len = 1;
+		mbox_cmd.recv_len = 0;
+		mbox_cmd.recv_status = 0;
+		mbox_cmd.fn = NULL;
+		mbox_cmd.fn_arg = 0;
+		ether_addr_copy(mbox_cmd.msg.s.params, mac);
+		mbox_cmd.q_no = vfidx * oct->sriov_info.rings_per_vf;
+		octeon_mbox_write(oct, &mbox_cmd);
+	}
+}
diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h
index 21b5c90..20a9dc5 100644
--- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h
+++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h
@@ -56,4 +56,7 @@ u32 cn23xx_pf_get_oq_ticks(struct octeon_device *oct, u32 time_intr_in_us);
 void cn23xx_dump_pf_initialized_regs(struct octeon_device *oct);
 
 int cn23xx_fw_loaded(struct octeon_device *oct);
+
+void cn23xx_tell_vf_its_macaddr_changed(struct octeon_device *oct, int vfidx,
+					u8 *mac);
 #endif
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index e480c23..3b92036 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -3592,6 +3592,148 @@ static void liquidio_del_vxlan_port(struct net_device *netdev,
 				    OCTNET_CMD_VXLAN_PORT_DEL);
 }
 
+static int __liquidio_set_vf_mac(struct net_device *netdev, int vfidx,
+				 u8 *mac, bool is_admin_assigned)
+{
+	struct lio *lio = GET_LIO(netdev);
+	struct octeon_device *oct = lio->oct_dev;
+	struct octnic_ctrl_pkt nctrl;
+
+	if (!is_valid_ether_addr(mac))
+		return -EINVAL;
+
+	if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs)
+		return -EINVAL;
+
+	memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
+
+	nctrl.ncmd.u64 = 0;
+	nctrl.ncmd.s.cmd = OCTNET_CMD_CHANGE_MACADDR;
+	/* vfidx is 0 based, but vf_num (param1) is 1 based */
+	nctrl.ncmd.s.param1 = vfidx + 1;
+	nctrl.ncmd.s.param2 = (is_admin_assigned ? 1 : 0);
+	nctrl.ncmd.s.more = 1;
+	nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
+	nctrl.cb_fn = 0;
+	nctrl.wait_time = 100;
+
+	nctrl.udd[0] = 0;
+	/* The MAC Address is presented in network byte order. */
+	ether_addr_copy((u8 *)&nctrl.udd[0] + 2, mac);
+
+	oct->sriov_info.vf_macaddr[vfidx] = nctrl.udd[0];
+
+	octnet_send_nic_ctrl_pkt(oct, &nctrl);
+
+	return 0;
+}
+
+static int liquidio_set_vf_mac(struct net_device *netdev, int vfidx, u8 *mac)
+{
+	struct lio *lio = GET_LIO(netdev);
+	struct octeon_device *oct = lio->oct_dev;
+	int retval;
+
+	retval = __liquidio_set_vf_mac(netdev, vfidx, mac, true);
+	if (!retval)
+		cn23xx_tell_vf_its_macaddr_changed(oct, vfidx, mac);
+
+	return retval;
+}
+
+static int liquidio_set_vf_vlan(struct net_device *netdev, int vfidx,
+				u16 vlan, u8 qos)
+{
+	struct lio *lio = GET_LIO(netdev);
+	struct octeon_device *oct = lio->oct_dev;
+	struct octnic_ctrl_pkt nctrl;
+	u16 vlantci;
+
+	if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs)
+		return -EINVAL;
+
+	if (vlan >= VLAN_N_VID || qos > 7)
+		return -EINVAL;
+
+	if (vlan)
+		vlantci = vlan | (u16)qos << VLAN_PRIO_SHIFT;
+	else
+		vlantci = 0;
+
+	if (oct->sriov_info.vf_vlantci[vfidx] == vlantci)
+		return 0;
+
+	memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
+
+	if (vlan)
+		nctrl.ncmd.s.cmd = OCTNET_CMD_ADD_VLAN_FILTER;
+	else
+		nctrl.ncmd.s.cmd = OCTNET_CMD_DEL_VLAN_FILTER;
+
+	nctrl.ncmd.s.param1 = vlantci;
+	nctrl.ncmd.s.param2 =
+	    vfidx + 1; /* vfidx is 0 based, but vf_num (param2) is 1 based */
+	nctrl.ncmd.s.more = 0;
+	nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
+	nctrl.cb_fn = 0;
+	nctrl.wait_time = 100;
+
+	octnet_send_nic_ctrl_pkt(oct, &nctrl);
+
+	oct->sriov_info.vf_vlantci[vfidx] = vlantci;
+
+	return 0;
+}
+
+static int liquidio_get_vf_config(struct net_device *netdev, int vfidx,
+				  struct ifla_vf_info *ivi)
+{
+	struct lio *lio = GET_LIO(netdev);
+	struct octeon_device *oct = lio->oct_dev;
+	u8 *macaddr;
+
+	if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs)
+		return -EINVAL;
+
+	ivi->vf = vfidx;
+	macaddr = 2 + (u8 *)&oct->sriov_info.vf_macaddr[vfidx];
+	ether_addr_copy(&ivi->mac[0], macaddr);
+	ivi->vlan = oct->sriov_info.vf_vlantci[vfidx] & VLAN_VID_MASK;
+	ivi->qos = oct->sriov_info.vf_vlantci[vfidx] >> VLAN_PRIO_SHIFT;
+	ivi->linkstate = oct->sriov_info.vf_linkstate[vfidx];
+	return 0;
+}
+
+static int liquidio_set_vf_link_state(struct net_device *netdev, int vfidx,
+				      int linkstate)
+{
+	struct lio *lio = GET_LIO(netdev);
+	struct octeon_device *oct = lio->oct_dev;
+	struct octnic_ctrl_pkt nctrl;
+
+	if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs)
+		return -EINVAL;
+
+	if (oct->sriov_info.vf_linkstate[vfidx] == linkstate)
+		return 0;
+
+	memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
+	nctrl.ncmd.s.cmd = OCTNET_CMD_SET_VF_LINKSTATE;
+	nctrl.ncmd.s.param1 =
+	    vfidx + 1; /* vfidx is 0 based, but vf_num (param1) is 1 based */
+	nctrl.ncmd.s.param2 = linkstate;
+	nctrl.ncmd.s.more = 0;
+	nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
+	nctrl.cb_fn = 0;
+	nctrl.wait_time = 100;
+
+	octnet_send_nic_ctrl_pkt(oct, &nctrl);
+
+	oct->sriov_info.vf_linkstate[vfidx] = linkstate;
+
+	return 0;
+}
+
 static struct net_device_ops lionetdevops = {
 	.ndo_open		= liquidio_open,
 	.ndo_stop		= liquidio_stop,
@@ -3609,6 +3751,10 @@ static struct net_device_ops lionetdevops = {
 	.ndo_set_features	= liquidio_set_features,
 	.ndo_udp_tunnel_add	= liquidio_add_vxlan_port,
 	.ndo_udp_tunnel_del	= liquidio_del_vxlan_port,
+	.ndo_set_vf_mac		= liquidio_set_vf_mac,
+	.ndo_set_vf_vlan	= liquidio_set_vf_vlan,
+	.ndo_get_vf_config	= liquidio_get_vf_config,
+	.ndo_set_vf_link_state  = liquidio_set_vf_link_state,
 };
 
 /** \brief Entry point for the liquidio module
@@ -3924,6 +4070,22 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
 		pr_devel("if%d gmx: %d hw_addr: 0x%llx\n", i,
 			 lio->linfo.gmxport, CVM_CAST64(lio->linfo.hw_addr));
 
+		for (j = 0; j < octeon_dev->sriov_info.num_vfs; j++) {
+			u8 vfmac[ETH_ALEN];
+
+			random_ether_addr(&vfmac[0]);
+			if (__liquidio_set_vf_mac(netdev, j,
+						  &vfmac[0], false)) {
+				dev_err(&octeon_dev->pci_dev->dev,
+					"Error setting VF%d MAC address\n",
+					j);
+				goto setup_nic_dev_fail;
+			}
+			dev_info(&octeon_dev->pci_dev->dev,
+				 "MAC Address %pM is configured for VF %d\n",
+				 &vfmac[0], j);
+		}
+
 		/* 64-bit swap required on LE machines */
 		octeon_swap_8B_data(&lio->linfo.hw_addr, 1);
 		for (j = 0; j < 6; j++)
@@ -4163,6 +4325,52 @@ static void nic_starter(struct work_struct *work)
 	complete(&handshake[oct->octeon_id].started);
 }
 
+static int
+octeon_recv_vf_drv_notice(struct octeon_recv_info *recv_info, void *buf)
+{
+	struct octeon_device *oct = (struct octeon_device *)buf;
+	struct octeon_recv_pkt *recv_pkt = recv_info->recv_pkt;
+	int i, notice, vf_idx;
+	u64 *data, vf_num;
+
+	notice = recv_pkt->rh.r.ossp;
+	data = (u64 *)get_rbd(recv_pkt->buffer_ptr[0]);
+
+	/* the first 64-bit word of data is the vf_num */
+	vf_num = data[0];
+	octeon_swap_8B_data(&vf_num, 1);
+	vf_idx = (int)vf_num - 1;
+
+	if (notice == VF_DRV_LOADED) {
+		if (!(oct->sriov_info.vf_drv_loaded_mask & BIT_ULL(vf_idx))) {
+			oct->sriov_info.vf_drv_loaded_mask |= BIT_ULL(vf_idx);
+			dev_info(&oct->pci_dev->dev,
+				 "driver for VF%d was loaded\n", vf_idx);
+			try_module_get(THIS_MODULE);
+		}
+	} else if (notice == VF_DRV_REMOVED) {
+		if (oct->sriov_info.vf_drv_loaded_mask & BIT_ULL(vf_idx)) {
+			oct->sriov_info.vf_drv_loaded_mask &= ~BIT_ULL(vf_idx);
+			dev_info(&oct->pci_dev->dev,
+				 "driver for VF%d was removed\n", vf_idx);
+			module_put(THIS_MODULE);
+		}
+	} else if (notice == VF_DRV_MACADDR_CHANGED) {
+		u8 *b = (u8 *)&data[1];
+
+		oct->sriov_info.vf_macaddr[vf_idx] = data[1];
+		dev_info(&oct->pci_dev->dev,
+			 "VF driver changed VF%d's MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n",
+			 vf_idx, b[2], b[3], b[4], b[5], b[6], b[7]);
+	}
+
+	for (i = 0; i < recv_pkt->buffer_count; i++)
+		recv_buffer_free(recv_pkt->buffer_ptr[i]);
+	octeon_free_recv_info(recv_info);
+
+	return 0;
+}
+
 /**
  * \brief Device initialization for each Octeon device that is probed
  * @param octeon_dev  octeon device
@@ -4221,6 +4429,9 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
 				    octeon_core_drv_init,
 				    octeon_dev);
 
+	octeon_register_dispatch_fn(octeon_dev, OPCODE_NIC,
+				    OPCODE_NIC_VF_DRV_NOTICE,
+				    octeon_recv_vf_drv_notice, octeon_dev);
 	INIT_DELAYED_WORK(&octeon_dev->nic_poll_work.work, nic_starter);
 	octeon_dev->nic_poll_work.ctxptr = (void *)octeon_dev;
 	schedule_delayed_work(&octeon_dev->nic_poll_work.work,
diff --git a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h
index caeff9a..edf1282 100644
--- a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h
+++ b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h
@@ -89,6 +89,10 @@ enum octeon_tag_type {
 #define OPCODE_NIC_TIMESTAMP           0x07
 #define OPCODE_NIC_INTRMOD_CFG         0x08
 #define OPCODE_NIC_IF_CFG              0x09
+#define OPCODE_NIC_VF_DRV_NOTICE       0x0A
+#define VF_DRV_LOADED                  1
+#define VF_DRV_REMOVED                -1
+#define VF_DRV_MACADDR_CHANGED         2
 
 #define CORE_DRV_TEST_SCATTER_OP    0xFFF5
 
@@ -235,6 +239,7 @@ static inline void add_sg_size(struct octeon_sg_entry *sg_entry,
 
 #define   OCTNET_CMD_ID_ACTIVE         0x1a
 
+#define   OCTNET_CMD_SET_VF_LINKSTATE  0x1c
 #define   OCTNET_CMD_VXLAN_PORT_ADD    0x0
 #define   OCTNET_CMD_VXLAN_PORT_DEL    0x1
 #define   OCTNET_CMD_RXCSUM_ENABLE     0x0
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.h b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
index fc62d7d..f7e6df8 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_device.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
@@ -347,6 +347,14 @@ struct octeon_sriov_info {
 
 	/*lookup table that maps DPI ring number to VF pci_dev struct pointer*/
 	struct pci_dev *dpiring_to_vfpcidev_lut[MAX_POSSIBLE_VFS];
+
+	u64	vf_macaddr[MAX_POSSIBLE_VFS];
+
+	u16	vf_vlantci[MAX_POSSIBLE_VFS];
+
+	int	vf_linkstate[MAX_POSSIBLE_VFS];
+
+	u64	vf_drv_loaded_mask;
 };
 
 struct octeon_ioq_vector {
-- 
1.8.3.1

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

* Re: [PATCH net-next 3/5] liquidio CN23XX: Mailbox support
  2016-09-09 20:08 ` [PATCH net-next 3/5] liquidio CN23XX: Mailbox support Raghu Vatsavayi
@ 2016-09-11  4:42   ` David Miller
  2016-09-14  1:25     ` Vatsavayi, Raghu
  0 siblings, 1 reply; 9+ messages in thread
From: David Miller @ 2016-09-11  4:42 UTC (permalink / raw)
  To: rvatsavayi
  Cc: netdev, derek.chickles, satananda.burla, felix.manlunas, raghu.vatsavayi

From: Raghu Vatsavayi <rvatsavayi@caviumnetworks.com>
Date: Fri, 9 Sep 2016 13:08:25 -0700

> +int octeon_mbox_read(struct octeon_mbox *mbox)
> +{
> +	int ret = 0;
> +	union octeon_mbox_message msg;
> +

Please always order local variable declarations from longest
to shortest line.

Please audit your entire submission for this problem.

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

* RE: [PATCH net-next 2/5] liquidio CN23XX: sriov enable
  2016-09-09 20:08 ` [PATCH net-next 2/5] liquidio CN23XX: sriov enable Raghu Vatsavayi
@ 2016-09-11 12:53   ` Yuval Mintz
  0 siblings, 0 replies; 9+ messages in thread
From: Yuval Mintz @ 2016-09-11 12:53 UTC (permalink / raw)
  To: Raghu Vatsavayi, David Miller
  Cc: netdev, Derek Chickles, Satanand Burla, Felix Manlunas, Raghu Vatsavayi

> -	dev_dbg(&oct->pci_dev->dev, "%s[%llx] : 0x%llx\n",
> -		"CN23XX_WIN_WR_MASK_REG",
....
> +	pr_devel("%s[%llx] : 0x%llx\n",
> +		 "CN23XX_WIN_WR_MASK_REG",
It looks like at least half of this patch [and I think it's also true for other
patches in this series] merely change debug prints.
Why not extract all of those to a single patch?

> +static unsigned int num_vfs[2] = { 0, 0 }; module_param_array(num_vfs,
> +uint, NULL, 0444); MODULE_PARM_DESC(num_vfs, "two comma-separated
> +unsigned integers that specify number of VFs for PF0 (left of the
> +comma) and PF1 (right of the comma); for 23xx only");

I believe we're way past the days where it's acceptable to enable IOV
Via module parameters; you have sysfs to dynamically enable VFs.

BTW, I glanced at pci-iov-howto.txt and noticed it still lists having a
module-parameter as control node for activating this feature;
But I believe it's been years since this has been considered a valid
Method for new drivers [I recall this was forbidden when we've added
bnx2x IOV support, and that was more than 3.5 years ago].
Perhaps it would be better to rephrase it so it would be obvious this
is a legacy sort of configuration [and not merely 'less preferable']?

> +static unsigned int num_queues_per_pf[2] = { 0, 0 };
> +module_param_array(num_queues_per_pf, uint, NULL, 0444);
> +MODULE_PARM_DESC(num_queues_per_pf, "two comma-separated unsigned
> +integers that specify number of queues per PF0 (left of the comma) and
> +PF1 (right of the comma); for 23xx only");
> +
> +static unsigned int num_queues_per_vf[2] = { 0, 0 };
> +module_param_array(num_queues_per_vf, uint, NULL, 0444);
> +MODULE_PARM_DESC(num_queues_per_vf, "two comma-separated unsigned
> +integers that specify number of queues per VFs for PF0 (left of the
> +comma) and PF1 (right of the comma); for 23xx only");

I don't believe this is a suitable solution as this is a generic problem -
how to split resources between PFs and their various VFs.
I don't believe there's good infrastructure for it today, though.
[Besides, you're introducing new module parameters...]

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

* RE: [PATCH net-next 3/5] liquidio CN23XX: Mailbox support
  2016-09-11  4:42   ` David Miller
@ 2016-09-14  1:25     ` Vatsavayi, Raghu
  0 siblings, 0 replies; 9+ messages in thread
From: Vatsavayi, Raghu @ 2016-09-14  1:25 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Chickles, Derek, Burla, Satananda, Manlunas, Felix

Sure Dave, Will submit new patches with these changes.
Thanks
Raghu.

> -----Original Message-----
> From: David Miller [mailto:davem@davemloft.net]
> Sent: Saturday, September 10, 2016 9:42 PM
> To: Vatsavayi, Raghu
> Cc: netdev@vger.kernel.org; Chickles, Derek; Burla, Satananda; Manlunas,
> Felix; Vatsavayi, Raghu
> Subject: Re: [PATCH net-next 3/5] liquidio CN23XX: Mailbox support
> 
> From: Raghu Vatsavayi <rvatsavayi@caviumnetworks.com>
> Date: Fri, 9 Sep 2016 13:08:25 -0700
> 
> > +int octeon_mbox_read(struct octeon_mbox *mbox) {
> > +	int ret = 0;
> > +	union octeon_mbox_message msg;
> > +
> 
> Please always order local variable declarations from longest to shortest line.
> 
> Please audit your entire submission for this problem.

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

end of thread, other threads:[~2016-09-14  1:25 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-09 20:08 [PATCH net-next 0/5] liquidio CN23XX VF support Raghu Vatsavayi
2016-09-09 20:08 ` [PATCH net-next 1/5] liquidio CN23XX: VF config support Raghu Vatsavayi
2016-09-09 20:08 ` [PATCH net-next 2/5] liquidio CN23XX: sriov enable Raghu Vatsavayi
2016-09-11 12:53   ` Yuval Mintz
2016-09-09 20:08 ` [PATCH net-next 3/5] liquidio CN23XX: Mailbox support Raghu Vatsavayi
2016-09-11  4:42   ` David Miller
2016-09-14  1:25     ` Vatsavayi, Raghu
2016-09-09 20:08 ` [PATCH net-next 4/5] liquidio CN23XX: mailbox interrupt processing Raghu Vatsavayi
2016-09-09 20:08 ` [PATCH net-next 5/5] liquidio CN23XX: VF related operations Raghu Vatsavayi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.