[v3,10/15] bus/vmbus: get subchannel info

Message ID 20220217160613.70161-11-srikanth.k@oneconvergence.com (mailing list archive)
State Superseded, archived
Headers
Series add FreeBSD support to VMBUS & NetVSC PMDs |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Srikanth Kaka Feb. 17, 2022, 4:06 p.m. UTC
  Using sysctl, all the subchannel information is fetched

Signed-off-by: Srikanth Kaka <srikanth.k@oneconvergence.com>
Signed-off-by: Vag Singh <vag.singh@oneconvergence.com>
Signed-off-by: Anand Thulasiram <avelu@juniper.net>
---
 drivers/bus/vmbus/freebsd/vmbus_uio.c | 85 +++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)
  

Patch

diff --git a/drivers/bus/vmbus/freebsd/vmbus_uio.c b/drivers/bus/vmbus/freebsd/vmbus_uio.c
index affc0a3f4f..ca6f5fac59 100644
--- a/drivers/bus/vmbus/freebsd/vmbus_uio.c
+++ b/drivers/bus/vmbus/freebsd/vmbus_uio.c
@@ -308,6 +308,91 @@  bool vmbus_uio_subchannels_supported(const struct rte_vmbus_device *dev,
 	return true;
 }
 
+static bool vmbus_isnew_subchannel(struct vmbus_channel *primary,
+				   uint16_t id)
+{
+	const struct vmbus_channel *c;
+
+	STAILQ_FOREACH(c, &primary->subchannel_list, next) {
+		if (c->relid == id)
+			return false;
+	}
+	return true;
+}
+
+int vmbus_uio_get_subchan(struct vmbus_channel *primary,
+			  struct vmbus_channel **subchan)
+{
+	const struct rte_vmbus_device *dev = primary->device;
+	char sysctlBuffer[PATH_MAX], sysctlVar[PATH_MAX];
+	size_t len = PATH_MAX, sysctl_len;
+	/* nr_schan, relid, subid & monid datatype must match kernel's for sysctl */
+	uint32_t relid, subid, nr_schan, i;
+	uint8_t monid;
+	int err;
+
+	/* get no. of sub-channels opened by hv_uio
+	 * dev.hv_uio.0.subchan_cnt
+	 */
+	snprintf(sysctlVar, len, "dev.%s.%d.subchan_cnt", driver_name,
+		 dev->uio_num);
+	sysctl_len = sizeof(nr_schan);
+	if (sysctlbyname(sysctlVar, &nr_schan, &sysctl_len, NULL, 0) < 0) {
+		VMBUS_LOG(ERR, "could not read %s : %s", sysctlVar,
+				strerror(errno));
+		return -1;
+	}
+
+	/* dev.hv_uio.0.channel.14.sub */
+	snprintf(sysctlBuffer, len, "dev.%s.%d.channel.%u.sub", driver_name,
+		 dev->uio_num, primary->relid);
+	for (i = 1; i <= nr_schan; i++) {
+		/* get relid */
+		snprintf(sysctlVar, len, "%s.%u.chanid", sysctlBuffer, i);
+		sysctl_len = sizeof(relid);
+		if (sysctlbyname(sysctlVar, &relid, &sysctl_len, NULL, 0) < 0) {
+			VMBUS_LOG(ERR, "could not read %s : %s", sysctlVar,
+					strerror(errno));
+			goto error;
+		}
+
+		if (!vmbus_isnew_subchannel(primary, (uint16_t)relid)) {
+			VMBUS_LOG(DEBUG, "skip already found channel: %u",
+					relid);
+			continue;
+		}
+
+		/* get sub-channel id */
+		snprintf(sysctlVar, len, "%s.%u.ch_subidx", sysctlBuffer, i);
+		sysctl_len = sizeof(subid);
+		if (sysctlbyname(sysctlVar, &subid, &sysctl_len, NULL, 0) < 0) {
+			VMBUS_LOG(ERR, "could not read %s : %s", sysctlVar,
+					strerror(errno));
+			goto error;
+		}
+
+		/* get monitor id */
+		snprintf(sysctlVar, len, "%s.%u.monitor_id", sysctlBuffer, i);
+		sysctl_len = sizeof(monid);
+		if (sysctlbyname(sysctlVar, &monid, &sysctl_len, NULL, 0) < 0) {
+			VMBUS_LOG(ERR, "could not read %s : %s", sysctlVar,
+					strerror(errno));
+			goto error;
+		}
+
+		err = vmbus_chan_create(dev, (uint16_t)relid, (uint16_t)subid,
+					monid, subchan);
+		if (err) {
+			VMBUS_LOG(ERR, "subchannel setup failed");
+			return err;
+		}
+		break;
+	}
+	return 0;
+error:
+	return -1;
+}
+
 int vmbus_uio_subchan_open(struct rte_vmbus_device *dev, uint32_t subchan)
 {
 	struct mapped_vmbus_resource *uio_res;