[v5,11/14] bus/vmbus: get subchannel info

Message ID 20220423042849.7718-12-srikanth.k@oneconvergence.com (mailing list archive)
State Awaiting Upstream
Delegated to: Thomas Monjalon
Headers
Series add FreeBSD support to VMBUS & NetVSC PMDs |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Srikanth Kaka April 23, 2022, 4:28 a.m. UTC
Using sysctl, all the subchannel's attributes are 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 | 73 +++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)
  

Patch

diff --git a/drivers/bus/vmbus/freebsd/vmbus_uio.c b/drivers/bus/vmbus/freebsd/vmbus_uio.c
index 438db41..6a9a196 100644
--- a/drivers/bus/vmbus/freebsd/vmbus_uio.c
+++ b/drivers/bus/vmbus/freebsd/vmbus_uio.c
@@ -155,6 +155,79 @@  const char *get_devname_os(void)
 	return "/dev/hv_uio";
 }
 
+int vmbus_uio_get_subchan(struct vmbus_channel *primary,
+			  struct vmbus_channel **subchan)
+{
+	const struct rte_vmbus_device *dev = primary->device;
+	char sysctl_buf[PATH_MAX], sysctl_var[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(sysctl_var, len, "dev.%s.%d.subchan_cnt", driver_name,
+		 dev->uio_num);
+	sysctl_len = sizeof(nr_schan);
+	if (sysctlbyname(sysctl_var, &nr_schan, &sysctl_len, NULL, 0) < 0) {
+		VMBUS_LOG(ERR, "could not read %s : %s", sysctl_var,
+				strerror(errno));
+		return -1;
+	}
+
+	/* dev.hv_uio.0.channel.14.sub */
+	snprintf(sysctl_buf, len, "dev.%s.%d.channel.%u.sub", driver_name,
+		 dev->uio_num, primary->relid);
+	for (i = 1; i <= nr_schan; i++) {
+		/* get relid */
+		snprintf(sysctl_var, len, "%s.%u.chanid", sysctl_buf, i);
+		sysctl_len = sizeof(relid);
+		if (sysctlbyname(sysctl_var, &relid, &sysctl_len, NULL, 0) < 0) {
+			VMBUS_LOG(ERR, "could not read %s : %s", sysctl_var,
+					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(sysctl_var, len, "%s.%u.ch_subidx", sysctl_buf, i);
+		sysctl_len = sizeof(subid);
+		if (sysctlbyname(sysctl_var, &subid, &sysctl_len, NULL, 0) < 0) {
+			VMBUS_LOG(ERR, "could not read %s : %s", sysctl_var,
+					strerror(errno));
+			goto error;
+		}
+
+		/* get monitor id */
+		snprintf(sysctl_var, len, "%s.%u.monitor_id", sysctl_buf, i);
+		sysctl_len = sizeof(monid);
+		if (sysctlbyname(sysctl_var, &monid, &sysctl_len, NULL, 0) < 0) {
+			VMBUS_LOG(ERR, "could not read %s : %s", sysctl_var,
+					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;