|
@@ -178,7 +178,8 @@ hwinfo_db_validate(struct nfp_cpp *cpp, struct nfp_hwinfo *db, u32 len)
|
|
|
return hwinfo_db_walk(cpp, db, size);
|
|
|
}
|
|
|
|
|
|
-static int hwinfo_try_fetch(struct nfp_cpp *cpp, size_t *cpp_size)
|
|
|
+static struct nfp_hwinfo *
|
|
|
+hwinfo_try_fetch(struct nfp_cpp *cpp, size_t *cpp_size)
|
|
|
{
|
|
|
struct nfp_hwinfo *header;
|
|
|
struct nfp_resource *res;
|
|
@@ -196,7 +197,7 @@ static int hwinfo_try_fetch(struct nfp_cpp *cpp, size_t *cpp_size)
|
|
|
nfp_resource_release(res);
|
|
|
|
|
|
if (*cpp_size < HWINFO_SIZE_MIN)
|
|
|
- return -ENOENT;
|
|
|
+ return NULL;
|
|
|
} else if (PTR_ERR(res) == -ENOENT) {
|
|
|
/* Try getting the HWInfo table from the 'classic' location */
|
|
|
cpp_id = NFP_CPP_ISLAND_ID(NFP_CPP_TARGET_MU,
|
|
@@ -204,101 +205,86 @@ static int hwinfo_try_fetch(struct nfp_cpp *cpp, size_t *cpp_size)
|
|
|
cpp_addr = 0x30000;
|
|
|
*cpp_size = 0x0e000;
|
|
|
} else {
|
|
|
- return PTR_ERR(res);
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
db = kmalloc(*cpp_size + 1, GFP_KERNEL);
|
|
|
if (!db)
|
|
|
- return -ENOMEM;
|
|
|
+ return NULL;
|
|
|
|
|
|
err = nfp_cpp_read(cpp, cpp_id, cpp_addr, db, *cpp_size);
|
|
|
- if (err != *cpp_size) {
|
|
|
- kfree(db);
|
|
|
- return err < 0 ? err : -EIO;
|
|
|
- }
|
|
|
+ if (err != *cpp_size)
|
|
|
+ goto exit_free;
|
|
|
|
|
|
header = (void *)db;
|
|
|
- if (nfp_hwinfo_is_updating(header)) {
|
|
|
- kfree(db);
|
|
|
- return -EBUSY;
|
|
|
- }
|
|
|
+ if (nfp_hwinfo_is_updating(header))
|
|
|
+ goto exit_free;
|
|
|
|
|
|
if (le32_to_cpu(header->version) != NFP_HWINFO_VERSION_2) {
|
|
|
nfp_err(cpp, "Unknown HWInfo version: 0x%08x\n",
|
|
|
le32_to_cpu(header->version));
|
|
|
- kfree(db);
|
|
|
- return -EINVAL;
|
|
|
+ goto exit_free;
|
|
|
}
|
|
|
|
|
|
/* NULL-terminate for safety */
|
|
|
db[*cpp_size] = '\0';
|
|
|
|
|
|
- nfp_hwinfo_cache_set(cpp, db);
|
|
|
-
|
|
|
- return 0;
|
|
|
+ return (void *)db;
|
|
|
+exit_free:
|
|
|
+ kfree(db);
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
-static int hwinfo_fetch(struct nfp_cpp *cpp, size_t *hwdb_size)
|
|
|
+static struct nfp_hwinfo *hwinfo_fetch(struct nfp_cpp *cpp, size_t *hwdb_size)
|
|
|
{
|
|
|
const unsigned long wait_until = jiffies + HWINFO_WAIT * HZ;
|
|
|
+ struct nfp_hwinfo *db;
|
|
|
int err;
|
|
|
|
|
|
for (;;) {
|
|
|
const unsigned long start_time = jiffies;
|
|
|
|
|
|
- err = hwinfo_try_fetch(cpp, hwdb_size);
|
|
|
- if (!err)
|
|
|
- return 0;
|
|
|
+ db = hwinfo_try_fetch(cpp, hwdb_size);
|
|
|
+ if (db)
|
|
|
+ return db;
|
|
|
|
|
|
err = msleep_interruptible(100);
|
|
|
if (err || time_after(start_time, wait_until)) {
|
|
|
nfp_err(cpp, "NFP access error\n");
|
|
|
- return -EIO;
|
|
|
+ return NULL;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static int nfp_hwinfo_load(struct nfp_cpp *cpp)
|
|
|
+struct nfp_hwinfo *nfp_hwinfo_read(struct nfp_cpp *cpp)
|
|
|
{
|
|
|
struct nfp_hwinfo *db;
|
|
|
size_t hwdb_size = 0;
|
|
|
int err;
|
|
|
|
|
|
- err = hwinfo_fetch(cpp, &hwdb_size);
|
|
|
- if (err)
|
|
|
- return err;
|
|
|
+ db = hwinfo_fetch(cpp, &hwdb_size);
|
|
|
+ if (!db)
|
|
|
+ return NULL;
|
|
|
|
|
|
- db = nfp_hwinfo_cache(cpp);
|
|
|
err = hwinfo_db_validate(cpp, db, hwdb_size);
|
|
|
if (err) {
|
|
|
kfree(db);
|
|
|
- nfp_hwinfo_cache_set(cpp, NULL);
|
|
|
- return err;
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
- return 0;
|
|
|
+ return db;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* nfp_hwinfo_lookup() - Find a value in the HWInfo table by name
|
|
|
- * @cpp: NFP CPP handle
|
|
|
+ * @hwinfo: NFP HWinfo table
|
|
|
* @lookup: HWInfo name to search for
|
|
|
*
|
|
|
* Return: Value of the HWInfo name, or NULL
|
|
|
*/
|
|
|
-const char *nfp_hwinfo_lookup(struct nfp_cpp *cpp, const char *lookup)
|
|
|
+const char *nfp_hwinfo_lookup(struct nfp_hwinfo *hwinfo, const char *lookup)
|
|
|
{
|
|
|
const char *key, *val, *end;
|
|
|
- struct nfp_hwinfo *hwinfo;
|
|
|
- int err;
|
|
|
-
|
|
|
- hwinfo = nfp_hwinfo_cache(cpp);
|
|
|
- if (!hwinfo) {
|
|
|
- err = nfp_hwinfo_load(cpp);
|
|
|
- if (err)
|
|
|
- return NULL;
|
|
|
- hwinfo = nfp_hwinfo_cache(cpp);
|
|
|
- }
|
|
|
|
|
|
if (!hwinfo || !lookup)
|
|
|
return NULL;
|