@@ -230,34 +230,70 @@ rte_fslmc_parse(const char *name, void *addr)
{
uint16_t dev_id;
char *t_ptr;
+ char *sep = NULL;
+ uint8_t sep_exists = 0;
- /* 'name' is expected to contain name of device, for example, dpio.1,
- * dpni.2, etc.
+ DPAA2_BUS_DEBUG("Parsing dev=(%s)", name);
+
+ /* There are multiple ways this can be called, with bus:dev, name=dev
+ * or just dev. In all cases, the 'addr' is actually a string.
+ */
+ sep = strchr(name, ':');
+ if (!sep) {
+ /* check for '=' */
+ sep = strchr(name, '=');
+ if (!sep)
+ sep_exists = 0;
+ else
+ sep_exists = 1;
+ } else
+ sep_exists = 1;
+
+ /* Check if starting part if either of 'fslmc:' or 'name=', separator
+ * exists.
*/
- if (strncmp("dpni", name, 4) &&
- strncmp("dpseci", name, 6) &&
- strncmp("dpcon", name, 5) &&
- strncmp("dpbp", name, 4) &&
- strncmp("dpio", name, 4) &&
- strncmp("dpci", name, 4) &&
- strncmp("dpmcp", name, 5) &&
- strncmp("dpdmai", name, 6) &&
- strncmp("dpdmux", name, 6)) {
- DPAA2_BUS_DEBUG("Unknown or unsupported device (%s)", name);
+ if (sep_exists) {
+ /* If either of "fslmc" or "name" are starting part */
+ if (!strncmp(name, RTE_STR(FSLMC_BUS_NAME),
+ strlen(RTE_STR(FSLMC_BUS_NAME))) ||
+ (!strncmp(name, "name", strlen("name")))) {
+ goto jump_out;
+ } else {
+ DPAA2_BUS_DEBUG("Invalid device for matching (%s).",
+ name);
+ goto err_out;
+ }
+ } else
+ sep = strdup(name);
+
+jump_out:
+ /* Validate device name */
+ if (strncmp("dpni", sep, 4) &&
+ strncmp("dpseci", sep, 6) &&
+ strncmp("dpcon", sep, 5) &&
+ strncmp("dpbp", sep, 4) &&
+ strncmp("dpio", sep, 4) &&
+ strncmp("dpci", sep, 4) &&
+ strncmp("dpmcp", sep, 5) &&
+ strncmp("dpdmai", sep, 6) &&
+ strncmp("dpdmux", sep, 6)) {
+ DPAA2_BUS_DEBUG("Unknown or unsupported device (%s)", sep);
goto err_out;
}
- t_ptr = strchr(name, '.');
+ t_ptr = strchr(sep, '.');
if (!t_ptr || sscanf(t_ptr + 1, "%hu", &dev_id) != 1) {
- DPAA2_BUS_ERR("Missing device id in device name (%s)", name);
+ DPAA2_BUS_ERR("Missing device id in device name (%s)", sep);
goto err_out;
}
if (addr)
- strcpy(addr, name);
+ strcpy(addr, sep);
return 0;
err_out:
+ if (sep)
+ free(sep);
return -EINVAL;
}
@@ -430,6 +466,13 @@ rte_fslmc_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
const struct rte_dpaa2_device *dstart;
struct rte_dpaa2_device *dev;
+ DPAA2_BUS_DEBUG("Finding a device named %s\n", (const char *)data);
+
+ /* find_device is always called with an opaque object which should be
+ * passed along to the 'cmp' function iterating over all device obj
+ * on the bus.
+ */
+
if (start != NULL) {
dstart = RTE_DEV_TO_FSLMC_CONST(start);
dev = TAILQ_NEXT(dstart, next);
@@ -437,8 +480,11 @@ rte_fslmc_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
dev = TAILQ_FIRST(&rte_fslmc_bus.device_list);
}
while (dev != NULL) {
- if (cmp(&dev->device, data) == 0)
+ if (cmp(&dev->device, data) == 0) {
+ DPAA2_BUS_DEBUG("Found device (%s)\n",
+ dev->device.name);
return &dev->device;
+ }
dev = TAILQ_NEXT(dev, next);
}
@@ -527,6 +573,57 @@ rte_dpaa2_get_iommu_class(void)
return RTE_IOVA_PA;
}
+static int
+fslmc_bus_plug(struct rte_device *dev __rte_unused)
+{
+ /* No operation is performed while plugging the device */
+ return 0;
+}
+
+static int
+fslmc_bus_unplug(struct rte_device *dev __rte_unused)
+{
+ /* No operation is performed while unplugging the device */
+ return 0;
+}
+
+static void *
+fslmc_bus_dev_iterate(const void *start, const char *str,
+ const struct rte_dev_iterator *it __rte_unused)
+{
+ const struct rte_dpaa2_device *dstart;
+ struct rte_dpaa2_device *dev;
+ char *dup, *dev_name = NULL;
+
+ /* Expectation is that device would be name=device_name */
+ if (strncmp(str, "name=", 5) != 0) {
+ DPAA2_BUS_ERR("Invalid device string (%s)\n", str);
+ return NULL;
+ }
+
+ /* Now that name=device_name format is available, split */
+ dup = strdup(str);
+ dev_name = dup + strlen("name=");
+
+ if (start != NULL) {
+ dstart = RTE_DEV_TO_FSLMC_CONST(start);
+ dev = TAILQ_NEXT(dstart, next);
+ } else {
+ dev = TAILQ_FIRST(&rte_fslmc_bus.device_list);
+ }
+
+ while (dev != NULL) {
+ if (strcmp(dev->device.name, dev_name) == 0) {
+ free(dup);
+ return &dev->device;
+ }
+ dev = TAILQ_NEXT(dev, next);
+ }
+
+ free(dup);
+ return NULL;
+}
+
struct rte_fslmc_bus rte_fslmc_bus = {
.bus = {
.scan = rte_fslmc_scan,
@@ -534,6 +631,9 @@ struct rte_fslmc_bus rte_fslmc_bus = {
.parse = rte_fslmc_parse,
.find_device = rte_fslmc_find_device,
.get_iommu_class = rte_dpaa2_get_iommu_class,
+ .plug = fslmc_bus_plug,
+ .unplug = fslmc_bus_unplug,
+ .dev_iterate = fslmc_bus_dev_iterate,
},
.device_list = TAILQ_HEAD_INITIALIZER(rte_fslmc_bus.device_list),
.driver_list = TAILQ_HEAD_INITIALIZER(rte_fslmc_bus.driver_list),