* [PATCH net-next 11/11] selftests: mlxsw: Check device info on activated line card
From: Ido Schimmel @ 2022-04-25 3:44 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, pabeni, jiri, petrm, dsahern, andrew, mlxsw,
Ido Schimmel
In-Reply-To: <20220425034431.3161260-1-idosch@nvidia.com>
From: Jiri Pirko <jiri@nvidia.com>
Once line card is activated, check the device FW version is exposed.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
.../drivers/net/mlxsw/devlink_linecard.sh | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_linecard.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_linecard.sh
index 04bedd98eb8b..53a65f416770 100755
--- a/tools/testing/selftests/drivers/net/mlxsw/devlink_linecard.sh
+++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_linecard.sh
@@ -259,6 +259,26 @@ interface_check()
setup_wait
}
+lc_devices_info_check()
+{
+ local lc=$1
+ local expected_device_count=$2
+ local device_count
+ local device
+ local running_device_fw
+
+ device_count=$(devlink lc info $DEVLINK_DEV lc $lc -j | \
+ jq -e -r ".[][][].devices |length")
+ check_err $? "Failed to get linecard $lc device count"
+ for (( device=0; device<device_count; device++ ))
+ do
+ running_device_fw=$(devlink lc -v info $DEVLINK_DEV lc $lc -j | \
+ jq -e -r ".[][][].devices[$device].versions.running.fw")
+ check_err $? "Failed to get linecard $lc device $device running fw version"
+ log_info "Linecard $lc device $device running.fw: \"$running_device_fw\""
+ done
+}
+
activation_16x100G_test()
{
RET=0
@@ -275,6 +295,8 @@ activation_16x100G_test()
$ACTIVATION_TIMEOUT)
check_err $? "Failed to get linecard $lc activated (timeout)"
+ lc_devices_info_check $lc $LC_16X100G_DEVICE_COUNT
+
interface_check
log_test "Activation 16x100G"
--
2.33.1
^ permalink raw reply related
* [PATCH net-next 10/11] mlxsw: core_linecards: Expose device FW version over device info
From: Ido Schimmel @ 2022-04-25 3:44 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, pabeni, jiri, petrm, dsahern, andrew, mlxsw,
Ido Schimmel
In-Reply-To: <20220425034431.3161260-1-idosch@nvidia.com>
From: Jiri Pirko <jiri@nvidia.com>
Extend MDDQ to obtain FW version of line card device and implement
device_info_get() op to fill up the info with that.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
Documentation/networking/devlink/mlxsw.rst | 15 +++
.../ethernet/mellanox/mlxsw/core_linecards.c | 108 +++++++++++++++++-
2 files changed, 119 insertions(+), 4 deletions(-)
diff --git a/Documentation/networking/devlink/mlxsw.rst b/Documentation/networking/devlink/mlxsw.rst
index da1fbb265a11..0af345680510 100644
--- a/Documentation/networking/devlink/mlxsw.rst
+++ b/Documentation/networking/devlink/mlxsw.rst
@@ -76,6 +76,21 @@ The ``mlxsw`` driver reports the following versions for line cards
- running
- Version of line card INI loaded
+Line card device info versions
+==============================
+
+The ``mlxsw`` driver reports the following versions for line card devices
+
+.. list-table:: devlink line card device info versions implemented
+ :widths: 5 5 90
+
+ * - Name
+ - Type
+ - Description
+ * - ``fw.version``
+ - running
+ - Three digit firmware version
+
Driver-specific Traps
=====================
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
index 42fe93ac629d..2abd31a62776 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
@@ -87,13 +87,31 @@ static const char *mlxsw_linecard_type_name(struct mlxsw_linecard *linecard)
return linecard->name;
}
+struct mlxsw_linecard_device_info {
+ u16 fw_major;
+ u16 fw_minor;
+ u16 fw_sub_minor;
+};
+
struct mlxsw_linecard_device {
struct list_head list;
u8 index;
struct mlxsw_linecard *linecard;
struct devlink_linecard_device *devlink_device;
+ struct mlxsw_linecard_device_info info;
};
+static struct mlxsw_linecard_device *
+mlxsw_linecard_device_lookup(struct mlxsw_linecard *linecard, u8 index)
+{
+ struct mlxsw_linecard_device *device;
+
+ list_for_each_entry(device, &linecard->device_list, list)
+ if (device->index == index)
+ return device;
+ return NULL;
+}
+
static int mlxsw_linecard_device_attach(struct mlxsw_core *mlxsw_core,
struct mlxsw_linecard *linecard,
u8 device_index, bool flash_owner)
@@ -108,7 +126,7 @@ static int mlxsw_linecard_device_attach(struct mlxsw_core *mlxsw_core,
device->linecard = linecard;
device->devlink_device = devlink_linecard_device_create(linecard->devlink_linecard,
- device_index, NULL);
+ device_index, device);
if (IS_ERR(device->devlink_device)) {
err = PTR_ERR(device->devlink_device);
goto err_devlink_linecard_device_attach;
@@ -177,6 +195,77 @@ static int mlxsw_linecard_devices_attach(struct mlxsw_linecard *linecard)
return err;
}
+static void mlxsw_linecard_device_update(struct mlxsw_linecard *linecard,
+ u8 device_index,
+ struct mlxsw_linecard_device_info *info)
+{
+ struct mlxsw_linecard_device *device;
+
+ device = mlxsw_linecard_device_lookup(linecard, device_index);
+ if (!device)
+ return;
+ device->info = *info;
+}
+
+static int mlxsw_linecard_devices_update(struct mlxsw_linecard *linecard)
+{
+ struct mlxsw_core *mlxsw_core = linecard->linecards->mlxsw_core;
+ u8 msg_seq = 0;
+
+ do {
+ struct mlxsw_linecard_device_info info;
+ char mddq_pl[MLXSW_REG_MDDQ_LEN];
+ bool data_valid;
+ u8 device_index;
+ int err;
+
+ mlxsw_reg_mddq_device_info_pack(mddq_pl, linecard->slot_index,
+ msg_seq);
+ err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mddq), mddq_pl);
+ if (err)
+ return err;
+ mlxsw_reg_mddq_device_info_unpack(mddq_pl, &msg_seq,
+ &data_valid, NULL,
+ &device_index,
+ &info.fw_major,
+ &info.fw_minor,
+ &info.fw_sub_minor);
+ if (!data_valid)
+ break;
+ mlxsw_linecard_device_update(linecard, device_index, &info);
+ } while (msg_seq);
+
+ return 0;
+}
+
+static int
+mlxsw_linecard_device_info_get(struct devlink_linecard_device *devlink_linecard_device,
+ void *priv, struct devlink_info_req *req,
+ struct netlink_ext_ack *extack)
+{
+ struct mlxsw_linecard_device *device = priv;
+ struct mlxsw_linecard_device_info *info;
+ struct mlxsw_linecard *linecard;
+ char buf[32];
+
+ linecard = device->linecard;
+ mutex_lock(&linecard->lock);
+ if (!linecard->active) {
+ mutex_unlock(&linecard->lock);
+ return 0;
+ }
+
+ info = &device->info;
+
+ sprintf(buf, "%u.%u.%u", info->fw_major, info->fw_minor,
+ info->fw_sub_minor);
+ mutex_unlock(&linecard->lock);
+
+ return devlink_info_version_running_put(req,
+ DEVLINK_INFO_VERSION_GENERIC_FW,
+ buf);
+}
+
static void mlxsw_linecard_provision_fail(struct mlxsw_linecard *linecard)
{
linecard->provisioned = false;
@@ -390,11 +479,18 @@ static int mlxsw_linecard_ready_clear(struct mlxsw_linecard *linecard)
return 0;
}
-static void mlxsw_linecard_active_set(struct mlxsw_linecard *linecard)
+static int mlxsw_linecard_active_set(struct mlxsw_linecard *linecard)
{
+ int err;
+
+ err = mlxsw_linecard_devices_update(linecard);
+ if (err)
+ return err;
+
mlxsw_linecard_active_ops_call(linecard);
linecard->active = true;
devlink_linecard_activate(linecard->devlink_linecard);
+ return 0;
}
static void mlxsw_linecard_active_clear(struct mlxsw_linecard *linecard)
@@ -443,8 +539,11 @@ static int mlxsw_linecard_status_process(struct mlxsw_linecards *linecards,
goto out;
}
- if (active && linecard->active != active)
- mlxsw_linecard_active_set(linecard);
+ if (active && linecard->active != active) {
+ err = mlxsw_linecard_active_set(linecard);
+ if (err)
+ goto out;
+ }
if (!active && linecard->active != active)
mlxsw_linecard_active_clear(linecard);
@@ -872,6 +971,7 @@ static const struct devlink_linecard_ops mlxsw_linecard_ops = {
.types_count = mlxsw_linecard_types_count,
.types_get = mlxsw_linecard_types_get,
.info_get = mlxsw_linecard_info_get,
+ .device_info_get = mlxsw_linecard_device_info_get,
};
struct mlxsw_linecard_status_event {
--
2.33.1
^ permalink raw reply related
* [PATCH net-next 09/11] mlxsw: reg: Extend MDDQ device_info by FW version fields
From: Ido Schimmel @ 2022-04-25 3:44 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, pabeni, jiri, petrm, dsahern, andrew, mlxsw,
Ido Schimmel
In-Reply-To: <20220425034431.3161260-1-idosch@nvidia.com>
From: Jiri Pirko <jiri@nvidia.com>
Add FW version fields to MDDQ device_info.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
.../ethernet/mellanox/mlxsw/core_linecards.c | 3 ++-
drivers/net/ethernet/mellanox/mlxsw/reg.h | 27 ++++++++++++++++++-
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
index b5f5b31bd31e..42fe93ac629d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
@@ -160,7 +160,8 @@ static int mlxsw_linecard_devices_attach(struct mlxsw_linecard *linecard)
return err;
mlxsw_reg_mddq_device_info_unpack(mddq_pl, &msg_seq,
&data_valid, &flash_owner,
- &device_index);
+ &device_index, NULL,
+ NULL, NULL);
if (!data_valid)
break;
err = mlxsw_linecard_device_attach(mlxsw_core, linecard,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index 521c1b195a3e..04c4d7a4bd83 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -11782,6 +11782,24 @@ MLXSW_ITEM32(reg, mddq, device_info_flash_owner, 0x10, 30, 1);
*/
MLXSW_ITEM32(reg, mddq, device_info_device_index, 0x10, 0, 8);
+/* reg_mddq_device_info_fw_major
+ * Major FW version number.
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mddq, device_info_fw_major, 0x14, 16, 16);
+
+/* reg_mddq_device_info_fw_minor
+ * Minor FW version number.
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mddq, device_info_fw_minor, 0x18, 16, 16);
+
+/* reg_mddq_device_info_fw_sub_minor
+ * Sub-minor FW version number.
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mddq, device_info_fw_sub_minor, 0x18, 0, 16);
+
static inline void
mlxsw_reg_mddq_device_info_pack(char *payload, u8 slot_index,
u8 request_msg_seq)
@@ -11794,13 +11812,20 @@ mlxsw_reg_mddq_device_info_pack(char *payload, u8 slot_index,
static inline void
mlxsw_reg_mddq_device_info_unpack(const char *payload, u8 *p_response_msg_seq,
bool *p_data_valid, bool *p_flash_owner,
- u8 *p_device_index)
+ u8 *p_device_index, u16 *p_fw_major,
+ u16 *p_fw_minor, u16 *p_fw_sub_minor)
{
*p_response_msg_seq = mlxsw_reg_mddq_response_msg_seq_get(payload);
*p_data_valid = mlxsw_reg_mddq_data_valid_get(payload);
if (p_flash_owner)
*p_flash_owner = mlxsw_reg_mddq_device_info_flash_owner_get(payload);
*p_device_index = mlxsw_reg_mddq_device_info_device_index_get(payload);
+ if (p_fw_major)
+ *p_fw_major = mlxsw_reg_mddq_device_info_fw_major_get(payload);
+ if (p_fw_minor)
+ *p_fw_minor = mlxsw_reg_mddq_device_info_fw_minor_get(payload);
+ if (p_fw_sub_minor)
+ *p_fw_sub_minor = mlxsw_reg_mddq_device_info_fw_sub_minor_get(payload);
}
#define MLXSW_REG_MDDQ_SLOT_ASCII_NAME_LEN 20
--
2.33.1
^ permalink raw reply related
* [PATCH net-next 08/11] selftests: mlxsw: Check line card info on provisioned line card
From: Ido Schimmel @ 2022-04-25 3:44 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, pabeni, jiri, petrm, dsahern, andrew, mlxsw,
Ido Schimmel
In-Reply-To: <20220425034431.3161260-1-idosch@nvidia.com>
From: Jiri Pirko <jiri@nvidia.com>
Once line card is provisioned, check if HW revision and INI version
are exposed.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
.../drivers/net/mlxsw/devlink_linecard.sh | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_linecard.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_linecard.sh
index 67b0e56cb413..04bedd98eb8b 100755
--- a/tools/testing/selftests/drivers/net/mlxsw/devlink_linecard.sh
+++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_linecard.sh
@@ -178,6 +178,22 @@ supported_types_check()
check_err $? "16X100G not found between supported types of linecard $lc"
}
+lc_info_check()
+{
+ local lc=$1
+ local fixed_hw_revision
+ local running_ini_version
+
+ fixed_hw_revision=$(devlink lc -v info $DEVLINK_DEV lc $lc -j | \
+ jq -e -r '.[][][].versions.fixed."hw.revision"')
+ check_err $? "Failed to get linecard $lc fixed.hw.revision"
+ log_info "Linecard $lc fixed.hw.revision: \"$fixed_hw_revision\""
+ running_ini_version=$(devlink lc -v info $DEVLINK_DEV lc $lc -j | \
+ jq -e -r '.[][][].versions.running."ini.version"')
+ check_err $? "Failed to get linecard $lc running.ini.version"
+ log_info "Linecard $lc running.ini.version: \"$running_ini_version\""
+}
+
lc_devices_check()
{
local lc=$1
@@ -228,6 +244,7 @@ provision_test()
fi
provision_one $lc $LC_16X100G_TYPE
lc_devices_check $lc $LC_16X100G_DEVICE_COUNT
+ lc_info_check $lc
ports_check $lc $LC_16X100G_PORT_COUNT
log_test "Provision"
}
--
2.33.1
^ permalink raw reply related
* [PATCH net-next 07/11] mlxsw: core_linecards: Expose HW revision and INI version
From: Ido Schimmel @ 2022-04-25 3:44 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, pabeni, jiri, petrm, dsahern, andrew, mlxsw,
Ido Schimmel
In-Reply-To: <20220425034431.3161260-1-idosch@nvidia.com>
From: Jiri Pirko <jiri@nvidia.com>
Implement info_get() to expose HW revision of a linecard and loaded INI
version.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
Documentation/networking/devlink/mlxsw.rst | 18 +++++++++++
.../ethernet/mellanox/mlxsw/core_linecards.c | 31 +++++++++++++++++++
2 files changed, 49 insertions(+)
diff --git a/Documentation/networking/devlink/mlxsw.rst b/Documentation/networking/devlink/mlxsw.rst
index cf857cb4ba8f..da1fbb265a11 100644
--- a/Documentation/networking/devlink/mlxsw.rst
+++ b/Documentation/networking/devlink/mlxsw.rst
@@ -58,6 +58,24 @@ The ``mlxsw`` driver reports the following versions
- running
- Three digit firmware version
+Line card info versions
+=======================
+
+The ``mlxsw`` driver reports the following versions for line cards
+
+.. list-table:: devlink line card info versions implemented
+ :widths: 5 5 90
+
+ * - Name
+ - Type
+ - Description
+ * - ``hw.revision``
+ - fixed
+ - The hardware revision for this line card
+ * - ``ini.version``
+ - running
+ - Version of line card INI loaded
+
Driver-specific Traps
=====================
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
index 9dd8a56add4a..b5f5b31bd31e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
@@ -834,12 +834,43 @@ static void mlxsw_linecard_types_get(struct devlink_linecard *devlink_linecard,
*type_priv = ini_file;
}
+static int
+mlxsw_linecard_info_get(struct devlink_linecard *devlink_linecard, void *priv,
+ struct devlink_info_req *req,
+ struct netlink_ext_ack *extack)
+{
+ struct mlxsw_linecard *linecard = priv;
+ char buf[32];
+ int err;
+
+ mutex_lock(&linecard->lock);
+ if (!linecard->provisioned) {
+ err = 0;
+ goto unlock;
+ }
+
+ sprintf(buf, "%d", linecard->hw_revision);
+ err = devlink_info_version_fixed_put(req, "hw.revision", buf);
+ if (err)
+ goto unlock;
+
+ sprintf(buf, "%d", linecard->ini_version);
+ err = devlink_info_version_running_put(req, "ini.version", buf);
+ if (err)
+ goto unlock;
+
+unlock:
+ mutex_unlock(&linecard->lock);
+ return err;
+}
+
static const struct devlink_linecard_ops mlxsw_linecard_ops = {
.provision = mlxsw_linecard_provision,
.unprovision = mlxsw_linecard_unprovision,
.same_provision = mlxsw_linecard_same_provision,
.types_count = mlxsw_linecard_types_count,
.types_get = mlxsw_linecard_types_get,
+ .info_get = mlxsw_linecard_info_get,
};
struct mlxsw_linecard_status_event {
--
2.33.1
^ permalink raw reply related
* [PATCH net-next 06/11] selftests: mlxsw: Check devices on provisioned line card
From: Ido Schimmel @ 2022-04-25 3:44 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, pabeni, jiri, petrm, dsahern, andrew, mlxsw,
Ido Schimmel
In-Reply-To: <20220425034431.3161260-1-idosch@nvidia.com>
From: Jiri Pirko <jiri@nvidia.com>
Once line card is provisioned, check the count of devices on it and
print them out.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
.../drivers/net/mlxsw/devlink_linecard.sh | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_linecard.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_linecard.sh
index 08a922d8b86a..67b0e56cb413 100755
--- a/tools/testing/selftests/drivers/net/mlxsw/devlink_linecard.sh
+++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_linecard.sh
@@ -152,6 +152,7 @@ unprovision_test()
LC_16X100G_TYPE="16x100G"
LC_16X100G_PORT_COUNT=16
+LC_16X100G_DEVICE_COUNT=4
supported_types_check()
{
@@ -177,6 +178,26 @@ supported_types_check()
check_err $? "16X100G not found between supported types of linecard $lc"
}
+lc_devices_check()
+{
+ local lc=$1
+ local expected_device_count=$2
+ local device_count
+ local device
+
+ device_count=$(devlink lc show $DEVLINK_DEV lc $lc -j | \
+ jq -e -r ".[][][].devices |length")
+ check_err $? "Failed to get linecard $lc device count"
+ [ $device_count != 0 ]
+ check_err $? "No device found on linecard $lc"
+ [ $device_count == $expected_device_count ]
+ check_err $? "Unexpected device count on linecard $lc (got $expected_device_count, expected $device_count)"
+ for (( device=0; device<device_count; device++ ))
+ do
+ log_info "Linecard $lc device $device"
+ done
+}
+
ports_check()
{
local lc=$1
@@ -206,6 +227,7 @@ provision_test()
unprovision_one $lc
fi
provision_one $lc $LC_16X100G_TYPE
+ lc_devices_check $lc $LC_16X100G_DEVICE_COUNT
ports_check $lc $LC_16X100G_PORT_COUNT
log_test "Provision"
}
--
2.33.1
^ permalink raw reply related
* [PATCH net-next 05/11] mlxsw: core_linecards: Probe provisioned line cards for devices and attach them
From: Ido Schimmel @ 2022-04-25 3:44 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, pabeni, jiri, petrm, dsahern, andrew, mlxsw,
Ido Schimmel
In-Reply-To: <20220425034431.3161260-1-idosch@nvidia.com>
From: Jiri Pirko <jiri@nvidia.com>
In case the line card is provisioned, go over all possible existing
devices (gearboxes) on it and attach them, so devlink core is aware of
them.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
drivers/net/ethernet/mellanox/mlxsw/core.h | 1 +
.../ethernet/mellanox/mlxsw/core_linecards.c | 99 +++++++++++++++++++
2 files changed, 100 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
index c2a891287047..d008282d7f2e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
@@ -581,6 +581,7 @@ struct mlxsw_linecard {
active:1;
u16 hw_revision;
u16 ini_version;
+ struct list_head device_list;
};
struct mlxsw_linecard_types_info;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
index 5c9869dcf674..9dd8a56add4a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
@@ -87,11 +87,101 @@ static const char *mlxsw_linecard_type_name(struct mlxsw_linecard *linecard)
return linecard->name;
}
+struct mlxsw_linecard_device {
+ struct list_head list;
+ u8 index;
+ struct mlxsw_linecard *linecard;
+ struct devlink_linecard_device *devlink_device;
+};
+
+static int mlxsw_linecard_device_attach(struct mlxsw_core *mlxsw_core,
+ struct mlxsw_linecard *linecard,
+ u8 device_index, bool flash_owner)
+{
+ struct mlxsw_linecard_device *device;
+ int err;
+
+ device = kzalloc(sizeof(*device), GFP_KERNEL);
+ if (!device)
+ return -ENOMEM;
+ device->index = device_index;
+ device->linecard = linecard;
+
+ device->devlink_device = devlink_linecard_device_create(linecard->devlink_linecard,
+ device_index, NULL);
+ if (IS_ERR(device->devlink_device)) {
+ err = PTR_ERR(device->devlink_device);
+ goto err_devlink_linecard_device_attach;
+ }
+
+ list_add_tail(&device->list, &linecard->device_list);
+ return 0;
+
+err_devlink_linecard_device_attach:
+ kfree(device);
+ return err;
+}
+
+static void mlxsw_linecard_device_detach(struct mlxsw_core *mlxsw_core,
+ struct mlxsw_linecard *linecard,
+ struct mlxsw_linecard_device *device)
+{
+ list_del(&device->list);
+ devlink_linecard_device_destroy(linecard->devlink_linecard,
+ device->devlink_device);
+ kfree(device);
+}
+
+static void mlxsw_linecard_devices_detach(struct mlxsw_linecard *linecard)
+{
+ struct mlxsw_core *mlxsw_core = linecard->linecards->mlxsw_core;
+ struct mlxsw_linecard_device *device, *tmp;
+
+ list_for_each_entry_safe(device, tmp, &linecard->device_list, list)
+ mlxsw_linecard_device_detach(mlxsw_core, linecard, device);
+}
+
+static int mlxsw_linecard_devices_attach(struct mlxsw_linecard *linecard)
+{
+ struct mlxsw_core *mlxsw_core = linecard->linecards->mlxsw_core;
+ u8 msg_seq = 0;
+ int err;
+
+ do {
+ char mddq_pl[MLXSW_REG_MDDQ_LEN];
+ bool flash_owner;
+ bool data_valid;
+ u8 device_index;
+
+ mlxsw_reg_mddq_device_info_pack(mddq_pl, linecard->slot_index,
+ msg_seq);
+ err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mddq), mddq_pl);
+ if (err)
+ return err;
+ mlxsw_reg_mddq_device_info_unpack(mddq_pl, &msg_seq,
+ &data_valid, &flash_owner,
+ &device_index);
+ if (!data_valid)
+ break;
+ err = mlxsw_linecard_device_attach(mlxsw_core, linecard,
+ device_index, flash_owner);
+ if (err)
+ goto rollback;
+ } while (msg_seq);
+
+ return 0;
+
+rollback:
+ mlxsw_linecard_devices_detach(linecard);
+ return err;
+}
+
static void mlxsw_linecard_provision_fail(struct mlxsw_linecard *linecard)
{
linecard->provisioned = false;
linecard->ready = false;
linecard->active = false;
+ mlxsw_linecard_devices_detach(linecard);
devlink_linecard_provision_fail(linecard->devlink_linecard);
}
@@ -232,6 +322,7 @@ mlxsw_linecard_provision_set(struct mlxsw_linecard *linecard, u8 card_type,
{
struct mlxsw_linecards *linecards = linecard->linecards;
const char *type;
+ int err;
type = mlxsw_linecard_types_lookup(linecards, card_type);
mlxsw_linecard_status_event_done(linecard,
@@ -249,6 +340,11 @@ mlxsw_linecard_provision_set(struct mlxsw_linecard *linecard, u8 card_type,
return PTR_ERR(type);
}
}
+ err = mlxsw_linecard_devices_attach(linecard);
+ if (err) {
+ mlxsw_linecard_provision_fail(linecard);
+ return err;
+ }
linecard->provisioned = true;
linecard->hw_revision = hw_revision;
linecard->ini_version = ini_version;
@@ -261,6 +357,7 @@ static void mlxsw_linecard_provision_clear(struct mlxsw_linecard *linecard)
mlxsw_linecard_status_event_done(linecard,
MLXSW_LINECARD_STATUS_EVENT_TYPE_UNPROVISION);
linecard->provisioned = false;
+ mlxsw_linecard_devices_detach(linecard);
devlink_linecard_provision_clear(linecard->devlink_linecard);
}
@@ -840,6 +937,7 @@ static int mlxsw_linecard_init(struct mlxsw_core *mlxsw_core,
linecard->slot_index = slot_index;
linecard->linecards = linecards;
mutex_init(&linecard->lock);
+ INIT_LIST_HEAD(&linecard->device_list);
devlink_linecard = devlink_linecard_create(priv_to_devlink(mlxsw_core),
slot_index, &mlxsw_linecard_ops,
@@ -885,6 +983,7 @@ static void mlxsw_linecard_fini(struct mlxsw_core *mlxsw_core,
mlxsw_core_flush_owq();
if (linecard->active)
mlxsw_linecard_active_clear(linecard);
+ mlxsw_linecard_devices_detach(linecard);
devlink_linecard_destroy(linecard->devlink_linecard);
mutex_destroy(&linecard->lock);
}
--
2.33.1
^ permalink raw reply related
* [PATCH net-next 04/11] mlxsw: reg: Extend MDDQ by device_info
From: Ido Schimmel @ 2022-04-25 3:44 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, pabeni, jiri, petrm, dsahern, andrew, mlxsw,
Ido Schimmel
In-Reply-To: <20220425034431.3161260-1-idosch@nvidia.com>
From: Jiri Pirko <jiri@nvidia.com>
Extend existing MDDQ register by possibility to query information about
devices residing on a line card.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
drivers/net/ethernet/mellanox/mlxsw/reg.h | 62 ++++++++++++++++++++++-
1 file changed, 61 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index 23589d3b160a..521c1b195a3e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -11643,7 +11643,11 @@ MLXSW_ITEM32(reg, mddq, sie, 0x00, 31, 1);
enum mlxsw_reg_mddq_query_type {
MLXSW_REG_MDDQ_QUERY_TYPE_SLOT_INFO = 1,
- MLXSW_REG_MDDQ_QUERY_TYPE_SLOT_NAME = 3,
+ MLXSW_REG_MDDQ_QUERY_TYPE_DEVICE_INFO, /* If there are no devices
+ * on the slot, data_valid
+ * will be '0'.
+ */
+ MLXSW_REG_MDDQ_QUERY_TYPE_SLOT_NAME,
};
/* reg_mddq_query_type
@@ -11657,6 +11661,28 @@ MLXSW_ITEM32(reg, mddq, query_type, 0x00, 16, 8);
*/
MLXSW_ITEM32(reg, mddq, slot_index, 0x00, 0, 4);
+/* reg_mddq_response_msg_seq
+ * Response message sequential number. For a specific request, the response
+ * message sequential number is the following one. In addition, the last
+ * message should be 0.
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mddq, response_msg_seq, 0x04, 16, 8);
+
+/* reg_mddq_request_msg_seq
+ * Request message sequential number.
+ * The first message number should be 0.
+ * Access: Index
+ */
+MLXSW_ITEM32(reg, mddq, request_msg_seq, 0x04, 0, 8);
+
+/* reg_mddq_data_valid
+ * If set, the data in the data field is valid and contain the information
+ * for the queried index.
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mddq, data_valid, 0x08, 31, 1);
+
/* reg_mddq_slot_info_provisioned
* If set, the INI file is applied and the card is provisioned.
* Access: RO
@@ -11743,6 +11769,40 @@ mlxsw_reg_mddq_slot_info_unpack(const char *payload, u8 *p_slot_index,
*p_card_type = mlxsw_reg_mddq_slot_info_card_type_get(payload);
}
+/* reg_mddq_device_info_flash_owner
+ * If set, the device is the flash owner. Otherwise, a shared flash
+ * is used by this device (another device is the flash owner).
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mddq, device_info_flash_owner, 0x10, 30, 1);
+
+/* reg_mddq_device_info_device_index
+ * Device index. The first device should number 0.
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mddq, device_info_device_index, 0x10, 0, 8);
+
+static inline void
+mlxsw_reg_mddq_device_info_pack(char *payload, u8 slot_index,
+ u8 request_msg_seq)
+{
+ __mlxsw_reg_mddq_pack(payload, slot_index,
+ MLXSW_REG_MDDQ_QUERY_TYPE_DEVICE_INFO);
+ mlxsw_reg_mddq_request_msg_seq_set(payload, request_msg_seq);
+}
+
+static inline void
+mlxsw_reg_mddq_device_info_unpack(const char *payload, u8 *p_response_msg_seq,
+ bool *p_data_valid, bool *p_flash_owner,
+ u8 *p_device_index)
+{
+ *p_response_msg_seq = mlxsw_reg_mddq_response_msg_seq_get(payload);
+ *p_data_valid = mlxsw_reg_mddq_data_valid_get(payload);
+ if (p_flash_owner)
+ *p_flash_owner = mlxsw_reg_mddq_device_info_flash_owner_get(payload);
+ *p_device_index = mlxsw_reg_mddq_device_info_device_index_get(payload);
+}
+
#define MLXSW_REG_MDDQ_SLOT_ASCII_NAME_LEN 20
/* reg_mddq_slot_ascii_name
--
2.33.1
^ permalink raw reply related
* [PATCH net-next 03/11] devlink: introduce line card device info infrastructure
From: Ido Schimmel @ 2022-04-25 3:44 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, pabeni, jiri, petrm, dsahern, andrew, mlxsw,
Ido Schimmel
In-Reply-To: <20220425034431.3161260-1-idosch@nvidia.com>
From: Jiri Pirko <jiri@nvidia.com>
Extend the line card info message with information (e.g., FW version)
about devices found on the line card.
Example:
$ devlink lc info pci/0000:01:00.0 lc 8
pci/0000:01:00.0:
lc 8
versions:
fixed:
hw.revision 0
running:
ini.version 4
devices:
device 0
versions:
running:
fw 19.2010.1310
device 1
versions:
running:
fw 19.2010.1310
device 2
versions:
running:
fw 19.2010.1310
device 3
versions:
running:
fw 19.2010.1310
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
.../networking/devlink/devlink-linecard.rst | 2 +-
include/net/devlink.h | 8 ++-
net/core/devlink.c | 71 ++++++++++++++++++-
3 files changed, 77 insertions(+), 4 deletions(-)
diff --git a/Documentation/networking/devlink/devlink-linecard.rst b/Documentation/networking/devlink/devlink-linecard.rst
index 5a8d5989702a..a98b468ad479 100644
--- a/Documentation/networking/devlink/devlink-linecard.rst
+++ b/Documentation/networking/devlink/devlink-linecard.rst
@@ -14,7 +14,7 @@ system. Following operations are provided:
* Get a list of supported line card types.
* Provision of a slot with specific line card type.
* Get and monitor of line card state and its change.
- * Get information about line card versions.
+ * Get information about line card versions and devices.
Line card according to the type may contain one or more gearboxes
to mux the lanes with certain speed to multiple ports with lanes
diff --git a/include/net/devlink.h b/include/net/devlink.h
index f96dcb376630..062895973656 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -151,6 +151,7 @@ struct devlink_port_new_attrs {
};
struct devlink_info_req;
+struct devlink_linecard_device;
/**
* struct devlink_linecard_ops - Linecard operations
@@ -171,6 +172,7 @@ struct devlink_info_req;
* @types_count: callback to get number of supported types
* @types_get: callback to get next type in list
* @info_get: callback to get linecard info
+ * @device_info_get: callback to get linecard device info
*/
struct devlink_linecard_ops {
int (*provision)(struct devlink_linecard *linecard, void *priv,
@@ -188,6 +190,9 @@ struct devlink_linecard_ops {
int (*info_get)(struct devlink_linecard *linecard, void *priv,
struct devlink_info_req *req,
struct netlink_ext_ack *extack);
+ int (*device_info_get)(struct devlink_linecard_device *device,
+ void *priv, struct devlink_info_req *req,
+ struct netlink_ext_ack *extack);
};
struct devlink_sb_pool_info {
@@ -1583,10 +1588,9 @@ struct devlink_linecard *
devlink_linecard_create(struct devlink *devlink, unsigned int linecard_index,
const struct devlink_linecard_ops *ops, void *priv);
void devlink_linecard_destroy(struct devlink_linecard *linecard);
-struct devlink_linecard_device;
struct devlink_linecard_device *
devlink_linecard_device_create(struct devlink_linecard *linecard,
- unsigned int device_index);
+ unsigned int device_index, void *priv);
void
devlink_linecard_device_destroy(struct devlink_linecard *linecard,
struct devlink_linecard_device *linecard_device);
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 5facd10de64a..5f441a0e34f4 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -2062,6 +2062,7 @@ struct devlink_linecard_type {
struct devlink_linecard_device {
struct list_head list;
unsigned int index;
+ void *priv;
};
static int
@@ -2428,6 +2429,68 @@ struct devlink_info_req {
struct sk_buff *msg;
};
+static int
+devlink_nl_linecard_device_info_fill(struct sk_buff *msg,
+ struct devlink_linecard *linecard,
+ struct devlink_linecard_device *linecard_device,
+ struct netlink_ext_ack *extack)
+{
+ struct nlattr *attr;
+
+ attr = nla_nest_start(msg, DEVLINK_ATTR_LINECARD_DEVICE);
+ if (!attr)
+ return -EMSGSIZE;
+ if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_DEVICE_INDEX,
+ linecard_device->index)) {
+ nla_nest_cancel(msg, attr);
+ return -EMSGSIZE;
+ }
+ if (linecard->ops->device_info_get) {
+ struct devlink_info_req req;
+ int err;
+
+ req.msg = msg;
+ err = linecard->ops->device_info_get(linecard_device,
+ linecard_device->priv,
+ &req, extack);
+ if (err) {
+ nla_nest_cancel(msg, attr);
+ return err;
+ }
+ }
+ nla_nest_end(msg, attr);
+
+ return 0;
+}
+
+static int devlink_nl_linecard_devices_info_fill(struct sk_buff *msg,
+ struct devlink_linecard *linecard,
+ struct netlink_ext_ack *extack)
+{
+ struct devlink_linecard_device *linecard_device;
+ struct nlattr *attr;
+ int err;
+
+ if (list_empty(&linecard->device_list))
+ return 0;
+
+ attr = nla_nest_start(msg, DEVLINK_ATTR_LINECARD_DEVICE_LIST);
+ if (!attr)
+ return -EMSGSIZE;
+ list_for_each_entry(linecard_device, &linecard->device_list, list) {
+ err = devlink_nl_linecard_device_info_fill(msg, linecard,
+ linecard_device,
+ extack);
+ if (err) {
+ nla_nest_cancel(msg, attr);
+ return err;
+ }
+ }
+ nla_nest_end(msg, attr);
+
+ return 0;
+}
+
static int
devlink_nl_linecard_info_fill(struct sk_buff *msg, struct devlink *devlink,
struct devlink_linecard *linecard,
@@ -2453,6 +2516,10 @@ devlink_nl_linecard_info_fill(struct sk_buff *msg, struct devlink *devlink,
if (err)
goto nla_put_failure;
+ err = devlink_nl_linecard_devices_info_fill(msg, linecard, extack);
+ if (err)
+ goto nla_put_failure;
+
genlmsg_end(msg, hdr);
return 0;
@@ -10483,12 +10550,13 @@ EXPORT_SYMBOL_GPL(devlink_linecard_destroy);
*
* @linecard: devlink linecard
* @device_index: index of the linecard device
+ * @priv: user priv pointer
*
* Return: Line card device structure or an ERR_PTR() encoded error code.
*/
struct devlink_linecard_device *
devlink_linecard_device_create(struct devlink_linecard *linecard,
- unsigned int device_index)
+ unsigned int device_index, void *priv)
{
struct devlink_linecard_device *linecard_device;
@@ -10496,6 +10564,7 @@ devlink_linecard_device_create(struct devlink_linecard *linecard,
if (!linecard_device)
return ERR_PTR(-ENOMEM);
linecard_device->index = device_index;
+ linecard_device->priv = priv;
mutex_lock(&linecard->state_lock);
list_add_tail(&linecard_device->list, &linecard->device_list);
devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
--
2.33.1
^ permalink raw reply related
* [PATCH net-next 02/11] devlink: introduce line card info get message
From: Ido Schimmel @ 2022-04-25 3:44 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, pabeni, jiri, petrm, dsahern, andrew, mlxsw,
Ido Schimmel
In-Reply-To: <20220425034431.3161260-1-idosch@nvidia.com>
From: Jiri Pirko <jiri@nvidia.com>
Allow the driver to provide per line card info get op to fill-up info,
similar to the "devlink dev info".
Example:
$ devlink lc info pci/0000:01:00.0 lc 8
pci/0000:01:00.0:
lc 8
versions:
fixed:
hw.revision 0
running:
ini.version 4
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
.../networking/devlink/devlink-linecard.rst | 4 +
include/net/devlink.h | 7 +-
include/uapi/linux/devlink.h | 2 +
net/core/devlink.c | 130 +++++++++++++++++-
4 files changed, 138 insertions(+), 5 deletions(-)
diff --git a/Documentation/networking/devlink/devlink-linecard.rst b/Documentation/networking/devlink/devlink-linecard.rst
index 6c0b8928bc13..5a8d5989702a 100644
--- a/Documentation/networking/devlink/devlink-linecard.rst
+++ b/Documentation/networking/devlink/devlink-linecard.rst
@@ -14,6 +14,7 @@ system. Following operations are provided:
* Get a list of supported line card types.
* Provision of a slot with specific line card type.
* Get and monitor of line card state and its change.
+ * Get information about line card versions.
Line card according to the type may contain one or more gearboxes
to mux the lanes with certain speed to multiple ports with lanes
@@ -120,3 +121,6 @@ Example usage
# Set slot 8 to be unprovisioned:
$ devlink lc set pci/0000:01:00.0 lc 8 notype
+
+ # Set info for slot 8:
+ $ devlink lc info pci/0000:01:00.0 lc 8
diff --git a/include/net/devlink.h b/include/net/devlink.h
index c84b52fb9ff0..f96dcb376630 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -150,6 +150,8 @@ struct devlink_port_new_attrs {
sfnum_valid:1;
};
+struct devlink_info_req;
+
/**
* struct devlink_linecard_ops - Linecard operations
* @provision: callback to provision the linecard slot with certain
@@ -168,6 +170,7 @@ struct devlink_port_new_attrs {
* provisioned.
* @types_count: callback to get number of supported types
* @types_get: callback to get next type in list
+ * @info_get: callback to get linecard info
*/
struct devlink_linecard_ops {
int (*provision)(struct devlink_linecard *linecard, void *priv,
@@ -182,6 +185,9 @@ struct devlink_linecard_ops {
void (*types_get)(struct devlink_linecard *linecard,
void *priv, unsigned int index, const char **type,
const void **type_priv);
+ int (*info_get)(struct devlink_linecard *linecard, void *priv,
+ struct devlink_info_req *req,
+ struct netlink_ext_ack *extack);
};
struct devlink_sb_pool_info {
@@ -628,7 +634,6 @@ struct devlink_flash_update_params {
#define DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK BIT(1)
struct devlink_region;
-struct devlink_info_req;
/**
* struct devlink_region_ops - Region operations
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index cd578645f94f..fb8c3864457f 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -136,6 +136,8 @@ enum devlink_command {
DEVLINK_CMD_LINECARD_NEW,
DEVLINK_CMD_LINECARD_DEL,
+ DEVLINK_CMD_LINECARD_INFO_GET, /* can dump */
+
/* add new commands above here */
__DEVLINK_CMD_MAX,
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 41d9631ceada..5facd10de64a 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -2424,6 +2424,125 @@ static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb,
return 0;
}
+struct devlink_info_req {
+ struct sk_buff *msg;
+};
+
+static int
+devlink_nl_linecard_info_fill(struct sk_buff *msg, struct devlink *devlink,
+ struct devlink_linecard *linecard,
+ enum devlink_command cmd, u32 portid,
+ u32 seq, int flags, struct netlink_ext_ack *extack)
+{
+ struct devlink_info_req req;
+ void *hdr;
+ int err;
+
+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
+ if (!hdr)
+ return -EMSGSIZE;
+
+ err = -EMSGSIZE;
+ if (devlink_nl_put_handle(msg, devlink))
+ goto nla_put_failure;
+ if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, linecard->index))
+ goto nla_put_failure;
+
+ req.msg = msg;
+ err = linecard->ops->info_get(linecard, linecard->priv, &req, extack);
+ if (err)
+ goto nla_put_failure;
+
+ genlmsg_end(msg, hdr);
+ return 0;
+
+nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ return err;
+}
+
+static int devlink_nl_cmd_linecard_info_get_doit(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct devlink_linecard *linecard = info->user_ptr[1];
+ struct devlink *devlink = linecard->devlink;
+ struct sk_buff *msg;
+ int err;
+
+ if (!linecard->ops->info_get)
+ return -EOPNOTSUPP;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ mutex_lock(&linecard->state_lock);
+ err = devlink_nl_linecard_info_fill(msg, devlink, linecard,
+ DEVLINK_CMD_LINECARD_INFO_GET,
+ info->snd_portid, info->snd_seq, 0,
+ info->extack);
+ mutex_unlock(&linecard->state_lock);
+ if (err) {
+ nlmsg_free(msg);
+ return err;
+ }
+
+ return genlmsg_reply(msg, info);
+}
+
+static int devlink_nl_cmd_linecard_info_get_dumpit(struct sk_buff *msg,
+ struct netlink_callback *cb)
+{
+ struct devlink_linecard *linecard;
+ struct devlink *devlink;
+ int start = cb->args[0];
+ unsigned long index;
+ int idx = 0;
+ int err = 0;
+
+ mutex_lock(&devlink_mutex);
+ xa_for_each_marked(&devlinks, index, devlink, DEVLINK_REGISTERED) {
+ if (!devlink_try_get(devlink))
+ continue;
+
+ if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
+ goto retry;
+
+ mutex_lock(&devlink->linecards_lock);
+ list_for_each_entry(linecard, &devlink->linecard_list, list) {
+ if (idx < start || !linecard->ops->info_get) {
+ idx++;
+ continue;
+ }
+ mutex_lock(&linecard->state_lock);
+ err = devlink_nl_linecard_info_fill(msg, devlink, linecard,
+ DEVLINK_CMD_LINECARD_INFO_GET,
+ NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq,
+ NLM_F_MULTI,
+ cb->extack);
+ mutex_unlock(&linecard->state_lock);
+ if (err) {
+ mutex_unlock(&devlink->linecards_lock);
+ devlink_put(devlink);
+ goto out;
+ }
+ idx++;
+ }
+ mutex_unlock(&devlink->linecards_lock);
+retry:
+ devlink_put(devlink);
+ }
+out:
+ mutex_unlock(&devlink_mutex);
+
+ if (err != -EMSGSIZE)
+ return err;
+
+ cb->args[0] = idx;
+ return msg->len;
+}
+
static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
struct devlink_sb *devlink_sb,
enum devlink_command cmd, u32 portid,
@@ -6416,10 +6535,6 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
return err;
}
-struct devlink_info_req {
- struct sk_buff *msg;
-};
-
int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name)
{
return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name);
@@ -9139,6 +9254,13 @@ static const struct genl_small_ops devlink_nl_ops[] = {
.flags = GENL_ADMIN_PERM,
.internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
},
+ {
+ .cmd = DEVLINK_CMD_LINECARD_INFO_GET,
+ .doit = devlink_nl_cmd_linecard_info_get_doit,
+ .dumpit = devlink_nl_cmd_linecard_info_get_dumpit,
+ .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
+ /* can be retrieved by unprivileged users */
+ },
{
.cmd = DEVLINK_CMD_SB_GET,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
--
2.33.1
^ permalink raw reply related
* [PATCH net-next 01/11] devlink: introduce line card devices support
From: Ido Schimmel @ 2022-04-25 3:44 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, pabeni, jiri, petrm, dsahern, andrew, mlxsw,
Ido Schimmel
In-Reply-To: <20220425034431.3161260-1-idosch@nvidia.com>
From: Jiri Pirko <jiri@nvidia.com>
Line card can contain one or more devices that makes sense to make
visible to the user. For example, this can be a gearbox with
flash memory, which could be updated.
Provide the driver possibility to attach such devices to a line card
and expose those to user.
Example:
$ devlink lc show pci/0000:01:00.0 lc 8
pci/0000:01:00.0:
lc 8 state active type 16x100G
supported_types:
16x100G
devices:
device 0
device 1
device 2
device 3
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
include/net/devlink.h | 7 +++
include/uapi/linux/devlink.h | 3 +
net/core/devlink.c | 104 ++++++++++++++++++++++++++++++++++-
3 files changed, 113 insertions(+), 1 deletion(-)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 2a2a2a0c93f7..c84b52fb9ff0 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -1578,6 +1578,13 @@ struct devlink_linecard *
devlink_linecard_create(struct devlink *devlink, unsigned int linecard_index,
const struct devlink_linecard_ops *ops, void *priv);
void devlink_linecard_destroy(struct devlink_linecard *linecard);
+struct devlink_linecard_device;
+struct devlink_linecard_device *
+devlink_linecard_device_create(struct devlink_linecard *linecard,
+ unsigned int device_index);
+void
+devlink_linecard_device_destroy(struct devlink_linecard *linecard,
+ struct devlink_linecard_device *linecard_device);
void devlink_linecard_provision_set(struct devlink_linecard *linecard,
const char *type);
void devlink_linecard_provision_clear(struct devlink_linecard *linecard);
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index b3d40a5d72ff..cd578645f94f 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -575,6 +575,9 @@ enum devlink_attr {
DEVLINK_ATTR_LINECARD_STATE, /* u8 */
DEVLINK_ATTR_LINECARD_TYPE, /* string */
DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES, /* nested */
+ DEVLINK_ATTR_LINECARD_DEVICE_LIST, /* nested */
+ DEVLINK_ATTR_LINECARD_DEVICE, /* nested */
+ DEVLINK_ATTR_LINECARD_DEVICE_INDEX, /* u32 */
/* add new attributes above here, update the policy in devlink.c */
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 5cc88490f18f..41d9631ceada 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -83,10 +83,11 @@ struct devlink_linecard {
const struct devlink_linecard_ops *ops;
void *priv;
enum devlink_linecard_state state;
- struct mutex state_lock; /* Protects state */
+ struct mutex state_lock; /* Protects state and device_list */
const char *type;
struct devlink_linecard_type *types;
unsigned int types_count;
+ struct list_head device_list;
};
/**
@@ -2058,6 +2059,55 @@ struct devlink_linecard_type {
const void *priv;
};
+struct devlink_linecard_device {
+ struct list_head list;
+ unsigned int index;
+};
+
+static int
+devlink_nl_linecard_device_fill(struct sk_buff *msg,
+ struct devlink_linecard_device *linecard_device)
+{
+ struct nlattr *attr;
+
+ attr = nla_nest_start(msg, DEVLINK_ATTR_LINECARD_DEVICE);
+ if (!attr)
+ return -EMSGSIZE;
+ if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_DEVICE_INDEX,
+ linecard_device->index)) {
+ nla_nest_cancel(msg, attr);
+ return -EMSGSIZE;
+ }
+ nla_nest_end(msg, attr);
+
+ return 0;
+}
+
+static int devlink_nl_linecard_devices_fill(struct sk_buff *msg,
+ struct devlink_linecard *linecard)
+{
+ struct devlink_linecard_device *linecard_device;
+ struct nlattr *attr;
+ int err;
+
+ if (list_empty(&linecard->device_list))
+ return 0;
+
+ attr = nla_nest_start(msg, DEVLINK_ATTR_LINECARD_DEVICE_LIST);
+ if (!attr)
+ return -EMSGSIZE;
+ list_for_each_entry(linecard_device, &linecard->device_list, list) {
+ err = devlink_nl_linecard_device_fill(msg, linecard_device);
+ if (err) {
+ nla_nest_cancel(msg, attr);
+ return err;
+ }
+ }
+ nla_nest_end(msg, attr);
+
+ return 0;
+}
+
static int devlink_nl_linecard_fill(struct sk_buff *msg,
struct devlink *devlink,
struct devlink_linecard *linecard,
@@ -2068,6 +2118,7 @@ static int devlink_nl_linecard_fill(struct sk_buff *msg,
struct devlink_linecard_type *linecard_type;
struct nlattr *attr;
void *hdr;
+ int err;
int i;
hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
@@ -2100,6 +2151,10 @@ static int devlink_nl_linecard_fill(struct sk_buff *msg,
nla_nest_end(msg, attr);
}
+ err = devlink_nl_linecard_devices_fill(msg, linecard);
+ if (err)
+ goto nla_put_failure;
+
genlmsg_end(msg, hdr);
return 0;
@@ -10264,6 +10319,7 @@ devlink_linecard_create(struct devlink *devlink, unsigned int linecard_index,
linecard->priv = priv;
linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
mutex_init(&linecard->state_lock);
+ INIT_LIST_HEAD(&linecard->device_list);
err = devlink_linecard_types_init(linecard);
if (err) {
@@ -10291,6 +10347,7 @@ void devlink_linecard_destroy(struct devlink_linecard *linecard)
struct devlink *devlink = linecard->devlink;
devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL);
+ WARN_ON(!list_empty(&linecard->device_list));
mutex_lock(&devlink->linecards_lock);
list_del(&linecard->list);
devlink_linecard_types_fini(linecard);
@@ -10299,6 +10356,50 @@ void devlink_linecard_destroy(struct devlink_linecard *linecard)
}
EXPORT_SYMBOL_GPL(devlink_linecard_destroy);
+/**
+ * devlink_linecard_device_create - Create a device on linecard
+ *
+ * @linecard: devlink linecard
+ * @device_index: index of the linecard device
+ *
+ * Return: Line card device structure or an ERR_PTR() encoded error code.
+ */
+struct devlink_linecard_device *
+devlink_linecard_device_create(struct devlink_linecard *linecard,
+ unsigned int device_index)
+{
+ struct devlink_linecard_device *linecard_device;
+
+ linecard_device = kzalloc(sizeof(*linecard_device), GFP_KERNEL);
+ if (!linecard_device)
+ return ERR_PTR(-ENOMEM);
+ linecard_device->index = device_index;
+ mutex_lock(&linecard->state_lock);
+ list_add_tail(&linecard_device->list, &linecard->device_list);
+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
+ mutex_unlock(&linecard->state_lock);
+ return linecard_device;
+}
+EXPORT_SYMBOL_GPL(devlink_linecard_device_create);
+
+/**
+ * devlink_linecard_device_destroy - Destroy device on linecard
+ *
+ * @linecard: devlink linecard
+ * @linecard_device: devlink linecard device
+ */
+void
+devlink_linecard_device_destroy(struct devlink_linecard *linecard,
+ struct devlink_linecard_device *linecard_device)
+{
+ mutex_lock(&linecard->state_lock);
+ list_del(&linecard_device->list);
+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
+ mutex_unlock(&linecard->state_lock);
+ kfree(linecard_device);
+}
+EXPORT_SYMBOL_GPL(devlink_linecard_device_destroy);
+
/**
* devlink_linecard_provision_set - Set provisioning on linecard
*
@@ -10331,6 +10432,7 @@ EXPORT_SYMBOL_GPL(devlink_linecard_provision_set);
void devlink_linecard_provision_clear(struct devlink_linecard *linecard)
{
mutex_lock(&linecard->state_lock);
+ WARN_ON(!list_empty(&linecard->device_list));
linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
linecard->type = NULL;
devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
--
2.33.1
^ permalink raw reply related
* [PATCH net-next 00/11] mlxsw: extend line card model by devices and info
From: Ido Schimmel @ 2022-04-25 3:44 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, pabeni, jiri, petrm, dsahern, andrew, mlxsw,
Ido Schimmel
Jiri says:
This patchset is extending the line card model by three items:
1) line card devices
2) line card info
3) line card device info
First three patches are introducing the necessary changes in devlink
core.
Then, all three extensions are implemented in mlxsw alongside with
selftest.
Examples:
$ devlink lc show pci/0000:01:00.0 lc 8
pci/0000:01:00.0:
lc 8 state active type 16x100G
supported_types:
16x100G
devices:
device 0
device 1
device 2
device 3
$ devlink lc info pci/0000:01:00.0 lc 8
pci/0000:01:00.0:
lc 8
versions:
fixed:
hw.revision 0
running:
ini.version 4
devices:
device 0
versions:
running:
fw 19.2010.1310
device 1
versions:
running:
fw 19.2010.1310
device 2
versions:
running:
fw 19.2010.1310
device 3
versions:
running:
fw 19.2010.1310
Note that device FW flashing is going to be implemented in the follow-up
patchset.
Jiri Pirko (11):
devlink: introduce line card devices support
devlink: introduce line card info get message
devlink: introduce line card device info infrastructure
mlxsw: reg: Extend MDDQ by device_info
mlxsw: core_linecards: Probe provisioned line cards for devices and
attach them
selftests: mlxsw: Check devices on provisioned line card
mlxsw: core_linecards: Expose HW revision and INI version
selftests: mlxsw: Check line card info on provisioned line card
mlxsw: reg: Extend MDDQ device_info by FW version fields
mlxsw: core_linecards: Expose device FW version over device info
selftests: mlxsw: Check device info on activated line card
.../networking/devlink/devlink-linecard.rst | 4 +
Documentation/networking/devlink/mlxsw.rst | 33 ++
drivers/net/ethernet/mellanox/mlxsw/core.h | 1 +
.../ethernet/mellanox/mlxsw/core_linecards.c | 237 +++++++++++++-
drivers/net/ethernet/mellanox/mlxsw/reg.h | 87 ++++-
include/net/devlink.h | 18 +-
include/uapi/linux/devlink.h | 5 +
net/core/devlink.c | 303 +++++++++++++++++-
.../drivers/net/mlxsw/devlink_linecard.sh | 61 ++++
9 files changed, 739 insertions(+), 10 deletions(-)
--
2.33.1
^ permalink raw reply
* Re:Re: [PATCH v2] mediatek/mt7601u: add debugfs exit function
From: z @ 2022-04-25 3:40 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Kalle Valo, David S. Miller, Paolo Abeni, Matthias Brugger,
linux-wireless, netdev, linux-arm-kernel, linux-mediatek,
linux-kernel, bernard
In-Reply-To: <20220422124704.259244e7@kicinski-fedora-PC1C0HJN>
At 2022-04-23 03:47:04, "Jakub Kicinski" <kubakici@wp.pl> wrote:
>On Fri, 22 Apr 2022 01:08:54 -0700 Bernard Zhao wrote:
>> When mt7601u loaded, there are two cases:
>> First when mt7601u is loaded, in function mt7601u_probe, if
>> function mt7601u_probe run into error lable err_hw,
>> mt7601u_cleanup didn`t cleanup the debugfs node.
>> Second when the module disconnect, in function mt7601u_disconnect,
>> mt7601u_cleanup didn`t cleanup the debugfs node.
>> This patch add debugfs exit function and try to cleanup debugfs
>> node when mt7601u loaded fail or unloaded.
>>
>> Signed-off-by: Bernard Zhao <zhaojunkui2008@126.com>
>
>Ah, missed that there was a v2. My point stands, wiphy debugfs dir
>should do the cleanup.
>
>Do you encounter problems in practice or are you sending this patches
>based on reading / static analysis of the code only.
Hi Jakub Kicinski:
The issue here is found by reading code.
I read the drivers/net/wireless code and found that many modules are not cleanup the debugfs.
I sorted out the modules that were not cleaned up the debugfs:
./ti/wl18xx
./ti/wl12xx
./intel/iwlwifi
./intel/iwlwifi
./mediatek/mt76
I am not sure whether this part is welcome to kernel so I submitted a patch.
If you have any suggestions, welcome to put forward for discussion, thank you!
BR//Bernard
^ permalink raw reply
* RE: [PATCH net-next 1/4] net: pcs: xpcs: add CL37 1000BASE-X AN support
From: Ong, Boon Leong @ 2022-04-25 3:30 UTC (permalink / raw)
To: 'Russell King'
Cc: Alexandre Torgue, Jose Abreu, Andrew Lunn, Heiner Kallweit,
Paolo Abeni, David S . Miller, Jakub Kicinski, Maxime Coquelin,
Alexandre Torgue, Giuseppe Cavallaro, netdev@vger.kernel.org,
linux-stm32@st-md-mailman.stormreply.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
In-Reply-To: <YmJgqSdF7LMxoSXv@shell.armlinux.org.uk>
>On Fri, Apr 22, 2022 at 03:35:02PM +0800, Ong Boon Leong wrote:
>> @@ -774,6 +788,58 @@ static int xpcs_config_aneg_c37_sgmii(struct
>dw_xpcs *xpcs, unsigned int mode)
>> return ret;
>> }
>>
>> +static int xpcs_config_aneg_c37_1000basex(struct dw_xpcs *xpcs, unsigned
>int mode,
>> + const unsigned long *advertising)
>> +{
>> + int ret, mdio_ctrl;
>> +
>> + /* For AN for 1000BASE-X mode, the settings are :-
>> + * 1) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 0b (Disable C37 AN in
>case
>> + * it is already enabled)
>> + * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 00b (1000BASE-X C37)
>> + * 3) SR_MII_AN_ADV Bit(6)[FD] = 1b (Full Duplex)
>> + * Note: Half Duplex is rarely used, so don't advertise.
>> + * 4) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 1b (Enable C37 AN)
>
>So if this function gets called to update the advertisement - even if
>there is no actual change - we go through a AN-disable..AN-enable
>dance and cause the link to re-negotiate. That doesn't sound like nice
>behaviour.
Good feedback. Will look into this part.
>
>> + */
>> + mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2,
>DW_VR_MII_MMD_CTRL);
>> + if (mdio_ctrl < 0)
>> + return mdio_ctrl;
>> +
>> + if (mdio_ctrl & AN_CL37_EN) {
>> + ret = xpcs_write(xpcs, MDIO_MMD_VEND2,
>DW_VR_MII_MMD_CTRL,
>> + mdio_ctrl & ~AN_CL37_EN);
>> + if (ret < 0)
>> + return ret;
>> + }
>> +
>> + ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL);
>> + if (ret < 0)
>> + return ret;
>> +
>> + ret &= ~DW_VR_MII_PCS_MODE_MASK;
>> + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL,
>ret);
>> + if (ret < 0)
>> + return ret;
>> +
>> + ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_ADVERTISE);
>> + ret |= ADVERTISE_1000XFULL;
>> + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MII_ADVERTISE, ret);
>
>What if other bits are already set in the MII_ADVERTISE register?
>Maybe consider using phylink_mii_c22_pcs_encode_advertisement()?
The IP supports C45 MII MMD access and not C22. Your feedback does
make sense to strengthen the logics here. Thanks
>
>The pcs_config() method is also supposed to return either a negative
>error, 0 for no advertisement change, or positive for an advertisement
>change, in which case phylink will trigger a call to pcs_an_restart().
>
>> +static int xpcs_get_state_c37_1000basex(struct dw_xpcs *xpcs,
>> + struct phylink_link_state *state)
>> +{
>> + int lpa, adv;
>> + int ret;
>> +
>> + ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
>> + if (ret < 0)
>> + return ret;
>> +
>> + if (ret & AN_CL37_EN) {
>> + /* Reset link_state */
>> + state->link = false;
>> + state->speed = SPEED_UNKNOWN;
>> + state->duplex = DUPLEX_UNKNOWN;
>> + state->pause = 0;
>
>Phylink guarantees that speed, duplex and pause are set to something
>sensible - please remove these. The only one you probably need here
>is state->link.
Thanks for the input here.
>
>> +
>> + lpa = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_LPA);
>> + if (lpa < 0 || lpa & LPA_RFAULT)
>> + return false;
>
>This function does not return a boolean. Returning "false" is the same
>as returning 0, which means "no error" but an error has occurred.
Good catch.
>
>> +
>> + adv = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_ADVERTISE);
>> + if (adv < 0)
>> + return false;
>
>Ditto.
>
>> +
>> + if (lpa & ADVERTISE_1000XFULL &&
>> + adv & ADVERTISE_1000XFULL) {
>> + state->speed = SPEED_1000;
>> + state->duplex = DUPLEX_FULL;
>> + state->link = true;
>> + }
>> +
>> + /* Clear CL37 AN complete status */
>> + ret = xpcs_write(xpcs, MDIO_MMD_VEND2,
>DW_VR_MII_AN_INTR_STS, 0);
>> + } else {
>> + state->link = true;
>> + state->speed = SPEED_1000;
>> + state->duplex = DUPLEX_FULL;
>> + state->pause = 0;
>
>If we're in AN-disabled mode, phylink will set state->speed and
>state->duplex according to the user's parameters, so there should be no
>need to do it here.
Thanks for the input.
>
>> @@ -994,9 +1143,21 @@ void xpcs_link_up(struct phylink_pcs *pcs,
>unsigned int mode,
>> return xpcs_config_usxgmii(xpcs, speed);
>> if (interface == PHY_INTERFACE_MODE_SGMII)
>> return xpcs_link_up_sgmii(xpcs, mode, speed, duplex);
>> + if (interface == PHY_INTERFACE_MODE_1000BASEX)
>> + return xpcs_link_up_1000basex(xpcs, speed, duplex);
>> }
>> EXPORT_SYMBOL_GPL(xpcs_link_up);
>>
>> +static void xpcs_an_restart(struct phylink_pcs *pcs)
>> +{
>> + struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
>> + int ret;
>> +
>> + ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1);
>> + ret |= BMCR_ANRESTART;
>> + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, ret);
>
>If xpcs_read() returns an error, we try to write the error back to
>the control register? Is that a good idea/
Thanks! I will fix this.
^ permalink raw reply
* Re: [PATCH] FDDI: defxx: simplify if-if to if-else
From: Jiabing Wan @ 2022-04-25 3:27 UTC (permalink / raw)
To: Maciej W. Rozycki, Andrew Lunn
Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, netdev,
linux-kernel, kael_w
In-Reply-To: <alpine.DEB.2.21.2204250009240.9383@angie.orcam.me.uk>
On 2022/4/25 7:26, Maciej W. Rozycki wrote:
> On Mon, 25 Apr 2022, Andrew Lunn wrote:
>
>>> NAK. The first conditional optionally sets `bp->mmio = false', which
>>> changes the value of `dfx_use_mmio' in some configurations:
>>>
>>> #if defined(CONFIG_EISA) || defined(CONFIG_PCI)
>>> #define dfx_use_mmio bp->mmio
>>> #else
>>> #define dfx_use_mmio true
>>> #endif
Yes, it's my fault. I didn't notice "dfx_use_mmio" is a MACRO,
sorry for this wrong patch.
>> It probably won't stop the robots finding this if (x) if (!x), but
>> there is a chance the robot drivers will wonder why it is upper case.
> Well, blindly relying on automation is bound to cause trouble. There has
> to be a piece of intelligence signing the results off at the end.
You are right and I'll be more careful to review the result before
submitting.
>
> And there's nothing wrong with if (x) if (!x) in the first place; any
> sane compiler will produce reasonable output from it. Don't fix what
> ain't broke! And watch out for volatiles!
Yes, there's nothing wrong with if (x) if (!x), but I want to do is
reducing the complexity of the code.
There would be less instructions when using "if and else" rather
than "if (A) and if (!A)" as I tested:
Use if(A) and if(!A):
ldr w0, [sp, 28]
cmp w0, 0
beq .L2
ldr w0, [sp, 28]
add w0, w0, 1
str w0, [sp, 28]
.L2:
ldr w0, [sp, 28] <------ one more ldr instruction
cmp w0, 0 <------ one more cmp instruction
bne .L3
ldr w0, [sp, 28]
add w0, w0, 2
str w0, [sp, 28]
.L3:
ldr w0, [sp, 28]
mov w1, w0
adrp x0, .LC1
add x0, x0, :lo12:.LC1
bl printf
Use if(A) and else:
ldr w0, [sp, 28]
cmp w0, 0
beq .L2
ldr w0, [sp, 28]
add w0, w0, 1
str w0, [sp, 28] <------ reduce two instructions
b .L3
.L2:
ldr w0, [sp, 28]
add w0, w0, 2
str w0, [sp, 28]
.L3:
ldr w0, [sp, 28]
mov w1, w0
adrp x0, .LC1
add x0, x0, :lo12:.LC1
bl printf
I also use "pmccabe" , a tool from gcc, to calculate the complexity of the code.
It shows this patch can reduce the statements in function.
Use if(A) and if(!A):
pmccabe -v test.c Modified McCabe Cyclomatic Complexity
| Traditional McCabe Cyclomatic Complexity
| | # Statements in function
| | | First line of function
| | | | # lines in function
| | | | | filename(definition line number):function
| | | | | |
3 3 8 4 17 test.c(4): main
Use if(A) and else:
pmccabe -v test.c
Modified McCabe Cyclomatic Complexity
| Traditional McCabe Cyclomatic Complexity
| | # Statements in function
| | | First line of function
| | | | # lines in function
| | | | | filename(definition line number):function
| | | | | |
2 2 7 4 16 test.c(4): main
So I think this type of patchs is meaningful.
Thanks,
Wan Jiabing
^ permalink raw reply
* Re: [PATCH v2] rtlwifi: btcoex: fix if == else warning
From: Pkshih @ 2022-04-25 3:20 UTC (permalink / raw)
To: davem@davemloft.net, kvalo@kernel.org, guozhengkui@vivo.com,
linux-kernel@vger.kernel.org, linux-wireless@vger.kernel.org,
pabeni@redhat.com, netdev@vger.kernel.org, kuba@kernel.org
Cc: zhengkui_guo@outlook.com
In-Reply-To: <20220425031725.5808-1-guozhengkui@vivo.com>
On Mon, 2022-04-25 at 11:17 +0800, Guo Zhengkui wrote:
> Fix the following coccicheck warning:
>
> drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c:1604:2-4:
> WARNING: possible condition with no effect (if == else).
>
> Signed-off-by: Guo Zhengkui <guozhengkui@vivo.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Thank you
> ---
> v1 -> v2: Modify the comment according to Ping-Ke's suggestion.
>
> .../realtek/rtlwifi/btcoexist/halbtc8821a1ant.c | 16 ++++------------
> 1 file changed, 4 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c
> b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c
> index a18dffc8753a..67d0b9aee064 100644
> --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c
> +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c
> @@ -1600,18 +1600,10 @@ static void btc8821a1ant_act_wifi_con_bt_acl_busy(struct btc_coexist
> *btcoexist,
> coex_dm->auto_tdma_adjust = false;
> }
> } else if (bt_link_info->hid_exist && bt_link_info->a2dp_exist) {
> - /* HID+A2DP */
> - if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
> - (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
> - btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
> - true, 14);
> - coex_dm->auto_tdma_adjust = false;
> - } else {
> - /*for low BT RSSI*/
> - btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
> - true, 14);
> - coex_dm->auto_tdma_adjust = false;
> - }
> + /* HID+A2DP (no need to consider BT RSSI) */
> + btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
> + true, 14);
> + coex_dm->auto_tdma_adjust = false;
>
> btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
> } else if ((bt_link_info->pan_only) ||
^ permalink raw reply
* [PATCH v2] rtlwifi: btcoex: fix if == else warning
From: Guo Zhengkui @ 2022-04-25 3:17 UTC (permalink / raw)
To: Ping-Ke Shih, Kalle Valo, David S. Miller, Jakub Kicinski,
Paolo Abeni, Guo Zhengkui,
open list:REALTEK WIRELESS DRIVER (rtlwifi family),
open list:NETWORKING DRIVERS, open list
Cc: zhengkui_guo
In-Reply-To: <0355f52ad7bf46454af4d5cb28fd6d59f678c25f.camel@realtek.com>
Fix the following coccicheck warning:
drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c:1604:2-4:
WARNING: possible condition with no effect (if == else).
Signed-off-by: Guo Zhengkui <guozhengkui@vivo.com>
---
v1 -> v2: Modify the comment according to Ping-Ke's suggestion.
.../realtek/rtlwifi/btcoexist/halbtc8821a1ant.c | 16 ++++------------
1 file changed, 4 insertions(+), 12 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c
index a18dffc8753a..67d0b9aee064 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c
@@ -1600,18 +1600,10 @@ static void btc8821a1ant_act_wifi_con_bt_acl_busy(struct btc_coexist *btcoexist,
coex_dm->auto_tdma_adjust = false;
}
} else if (bt_link_info->hid_exist && bt_link_info->a2dp_exist) {
- /* HID+A2DP */
- if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
- (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
- btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
- true, 14);
- coex_dm->auto_tdma_adjust = false;
- } else {
- /*for low BT RSSI*/
- btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
- true, 14);
- coex_dm->auto_tdma_adjust = false;
- }
+ /* HID+A2DP (no need to consider BT RSSI) */
+ btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 14);
+ coex_dm->auto_tdma_adjust = false;
btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
} else if ((bt_link_info->pan_only) ||
--
2.20.1
^ permalink raw reply related
* [PATCH] add support for Sierra Wireless EM7590 0xc081 composition.
From: Ethan Yang @ 2022-04-25 3:14 UTC (permalink / raw)
To: bjorn, davem, kuba, pabeni, netdev, linux-usb, linux-kernel
Cc: gchiang, Ethan Yang
add support for Sierra Wireless EM7590 0xc081 composition.
Signed-off-by: Ethan Yang <etyang@sierrawireless.com>
---
drivers/net/usb/qmi_wwan.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 3353e761016d..fa220a13edb6 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -1351,6 +1351,7 @@ static const struct usb_device_id products[] = {
{QMI_QUIRK_SET_DTR(0x1199, 0x907b, 8)}, /* Sierra Wireless EM74xx */
{QMI_QUIRK_SET_DTR(0x1199, 0x907b, 10)},/* Sierra Wireless EM74xx */
{QMI_QUIRK_SET_DTR(0x1199, 0x9091, 8)}, /* Sierra Wireless EM7565 */
+ {QMI_QUIRK_SET_DTR(0x1199, 0xc081, 8)}, /* Sierra Wireless EM7590 */
{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
{QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */
{QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */
--
2.17.1
^ permalink raw reply related
* Re: [PATCH net-next v1 1/4] net: phy: broadcom: Add PTP support for some Broadcom PHYs.
From: Richard Cochran @ 2022-04-25 3:12 UTC (permalink / raw)
To: Jonathan Lemon
Cc: f.fainelli, bcm-kernel-feedback-list, andrew, hkallweit1, linux,
netdev, kernel-team
In-Reply-To: <20220424022356.587949-2-jonathan.lemon@gmail.com>
On Sat, Apr 23, 2022 at 07:23:53PM -0700, Jonathan Lemon wrote:
> +static int bcm_ptp_settime_locked(struct bcm_ptp_private *priv,
> + const struct timespec64 *ts)
> +{
> + struct phy_device *phydev = priv->phydev;
> + u16 ctrl;
> +
> + /* set up time code */
> + bcm_phy_write_exp(phydev, TIME_CODE_0, ts->tv_nsec);
> + bcm_phy_write_exp(phydev, TIME_CODE_1, ts->tv_nsec >> 16);
> + bcm_phy_write_exp(phydev, TIME_CODE_2, ts->tv_sec);
> + bcm_phy_write_exp(phydev, TIME_CODE_3, ts->tv_sec >> 16);
> + bcm_phy_write_exp(phydev, TIME_CODE_4, ts->tv_sec >> 32);
> +
> + /* zero out NCO counter */
> + bcm_phy_write_exp(phydev, NCO_TIME_0, 0);
> + bcm_phy_write_exp(phydev, NCO_TIME_1, 0);
> + bcm_phy_write_exp(phydev, NCO_TIME_2_CTRL, 0);
You are setting the 48 bit counter to zero.
But Lasse's version does this:
// Assign original time codes (48 bit)
local_time_codes[2] = 0x4000;
local_time_codes[1] = (u16)(ts->tv_nsec >> 20);
local_time_codes[0] = (u16)(ts->tv_nsec >> 4);
...
// Write Local Time Code Register
bcm_phy_write_exp(phydev, NSE_DPPL_NCO_2_0_REG, local_time_codes[0]);
bcm_phy_write_exp(phydev, NSE_DPPL_NCO_2_1_REG, local_time_codes[1]);
bcm_phy_write_exp(phydev, NSE_DPPL_NCO_2_2_REG, local_time_codes[2]);
My understanding is that the PPS output function uses the 48 bit
counter, and so it ought to be set to a non-zero value.
In any case, it would be nice to have the 80/48 bit register usage
clearly explained.
> + /* set up load on next frame sync */
> + bcm_phy_write_exp(phydev, SHADOW_LOAD, TIME_CODE_LOAD | NCO_TIME_LOAD);
> +
> + ctrl = priv->nse_ctrl;
> + return bcm_ptp_framesync(phydev, NULL, ctrl | NSE_INIT);
> +}
Thanks,
Richard
^ permalink raw reply
* [PATCH] drivers: nfc: nfcmrvl: reorder destructive operations in nfcmrvl_nci_unregister_dev to avoid bugs
From: Duoming Zhou @ 2022-04-25 3:10 UTC (permalink / raw)
To: krzysztof.kozlowski, linux-kernel
Cc: netdev, broonie, akpm, alexander.deucher, gregkh, davem, linma,
Duoming Zhou
There are destructive operations such as nfcmrvl_fw_dnld_abort and
gpio_free in nfcmrvl_nci_unregister_dev. The resources such as firmware,
gpio and so on could be destructed while the upper layer functions such as
nfcmrvl_fw_dnld_start and nfcmrvl_nci_recv_frame is executing, which leads
to double-free, use-after-free and null-ptr-deref bugs.
There are three situations that could lead to double-free bugs.
The first situation is shown below:
(Thread 1) | (Thread 2)
nfcmrvl_fw_dnld_start |
... | nfcmrvl_nci_unregister_dev
release_firmware() | nfcmrvl_fw_dnld_abort
kfree(fw) //(1) | fw_dnld_over
| release_firmware
... | kfree(fw) //(2)
| ...
The second situation is shown below:
(Thread 1) | (Thread 2)
nfcmrvl_fw_dnld_start |
... |
mod_timer |
(wait a time) |
fw_dnld_timeout | nfcmrvl_nci_unregister_dev
fw_dnld_over | nfcmrvl_fw_dnld_abort
release_firmware | fw_dnld_over
kfree(fw) //(1) | release_firmware
... | kfree(fw) //(2)
The third situation is shown below:
(Thread 1) | (Thread 2)
nfcmrvl_nci_recv_frame |
if(..->fw_download_in_progress)|
nfcmrvl_fw_dnld_recv_frame |
queue_work |
|
fw_dnld_rx_work | nfcmrvl_nci_unregister_dev
fw_dnld_over | nfcmrvl_fw_dnld_abort
release_firmware | fw_dnld_over
kfree(fw) //(1) | release_firmware
| kfree(fw) //(2)
The firmware struct is deallocated in position (1) and deallocated
in position (2) again.
The crash trace triggered by POC is like below:
[ 122.640457] BUG: KASAN: double-free or invalid-free in fw_dnld_over+0x28/0xf0
[ 122.640457] Call Trace:
[ 122.640457] <TASK>
[ 122.640457] kfree+0xb0/0x330
[ 122.640457] fw_dnld_over+0x28/0xf0
[ 122.640457] nfcmrvl_nci_unregister_dev+0x61/0x70
[ 122.640457] nci_uart_tty_close+0x87/0xd0
[ 122.640457] tty_ldisc_kill+0x3e/0x80
[ 122.640457] tty_ldisc_hangup+0x1b2/0x2c0
[ 122.640457] __tty_hangup.part.0+0x316/0x520
[ 122.640457] tty_release+0x200/0x670
[ 122.640457] __fput+0x110/0x410
[ 122.640457] task_work_run+0x86/0xd0
[ 122.640457] exit_to_user_mode_prepare+0x1aa/0x1b0
[ 122.640457] syscall_exit_to_user_mode+0x19/0x50
[ 122.640457] do_syscall_64+0x48/0x90
[ 122.640457] entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 122.640457] RIP: 0033:0x7f68433f6beb
What's more, there are also use-after-free and null-ptr-deref bugs
in nfcmrvl_fw_dnld_start. If we deallocate firmware struct, gpio or
set null to the members of priv->fw_dnld in nfcmrvl_nci_unregister_dev,
then, we dereference firmware, gpio or the members of priv->fw_dnld in
nfcmrvl_fw_dnld_start, the UAF or NPD bugs will happen.
This patch reorders destructive operations after nci_unregister_device
to avoid the double-free, UAF and NPD bugs, as nci_unregister_device
is well synchronized and won't return if there is a running routine.
This was mentioned in commit 3e3b5dfcd16a ("NFC: reorder the logic in
nfc_{un,}register_device").
Fixes: 3194c6870158 ("NFC: nfcmrvl: add firmware download support")
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
Reviewed-by: Lin Ma <linma@zju.edu.cn>
---
drivers/nfc/nfcmrvl/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c
index 2fcf545012b..1a5284de434 100644
--- a/drivers/nfc/nfcmrvl/main.c
+++ b/drivers/nfc/nfcmrvl/main.c
@@ -183,6 +183,7 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv)
{
struct nci_dev *ndev = priv->ndev;
+ nci_unregister_device(ndev);
if (priv->ndev->nfc_dev->fw_download_in_progress)
nfcmrvl_fw_dnld_abort(priv);
@@ -191,7 +192,6 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv)
if (gpio_is_valid(priv->config.reset_n_io))
gpio_free(priv->config.reset_n_io);
- nci_unregister_device(ndev);
nci_free_device(ndev);
kfree(priv);
}
--
2.17.1
^ permalink raw reply related
* [PATCH] drivers: net: bluetooth: centralize function exit and print error
From: Ian Cowan @ 2022-04-25 3:00 UTC (permalink / raw)
To: Marcel Holtmann
Cc: Johan Hedberg, Luiz Augusto von Dentz, David S. Miller,
Jakub Kicinski, Paolo Abeni, linux-bluetooth, netdev,
linux-kernel, Ian Cowan
Centralize the return for this one function, and this will add the error
being printed if it occurs earlier in the function. The same thing will
be returned with the logic, so the only thing that will differ is an
extra debugging output for an error.
Signed-off-by: Ian Cowan <ian@linux.cowan.aero>
---
net/bluetooth/6lowpan.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 215af9b3b589..15928e9ce088 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -516,7 +516,7 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev)
err = setup_header(skb, netdev, &addr, &addr_type);
if (err < 0) {
kfree_skb(skb);
- return NET_XMIT_DROP;
+ goto output_error_ret;
}
if (err) {
@@ -537,6 +537,7 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev)
dev_kfree_skb(skb);
+output_error_ret:
if (err)
BT_DBG("ERROR: xmit failed (%d)", err);
--
2.35.1
^ permalink raw reply related
* [PATCH] net: appletalk: cleanup brace styling
From: Ian Cowan @ 2022-04-25 2:35 UTC (permalink / raw)
To: David S. Miller
Cc: Jakub Kicinski, Paolo Abeni, netdev, linux-kernel, Ian Cowan
This cleans up some brace styling to meet the style guide. There is one
exception where the compiler wants unnecessary braces to prevent
multiple if/else ambiguity.
Signed-off-by: Ian Cowan <ian@linux.cowan.aero>
---
net/appletalk/ddp.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index bf5736c1d458..2709d9621b25 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -161,8 +161,9 @@ static void atalk_destroy_timer(struct timer_list *t)
if (sk_has_allocations(sk)) {
sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME;
add_timer(&sk->sk_timer);
- } else
+ } else {
sock_put(sk);
+ }
}
static inline void atalk_destroy_socket(struct sock *sk)
@@ -174,8 +175,9 @@ static inline void atalk_destroy_socket(struct sock *sk)
timer_setup(&sk->sk_timer, atalk_destroy_timer, 0);
sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME;
add_timer(&sk->sk_timer);
- } else
+ } else {
sock_put(sk);
+ }
}
/**************************************************************************\
@@ -211,8 +213,9 @@ static void atif_drop_device(struct net_device *dev)
dev_put(dev);
kfree(tmp);
dev->atalk_ptr = NULL;
- } else
+ } else {
iface = &tmp->next;
+ }
}
write_unlock_bh(&atalk_interfaces_lock);
}
@@ -444,12 +447,13 @@ static struct atalk_route *atrtr_find(struct atalk_addr *target)
*/
if (r->target.s_node == target->s_node)
goto out;
- } else
+ } else {
/*
* this route will work if there isn't a
* direct host route, so cache it
*/
net_route = r;
+ }
}
}
@@ -615,8 +619,9 @@ static void atrtr_device_down(struct net_device *dev)
*r = tmp->next;
dev_put(dev);
kfree(tmp);
- } else
+ } else {
r = &tmp->next;
+ }
}
write_unlock_bh(&atalk_routes_lock);
@@ -1386,8 +1391,9 @@ static int atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
struct sk_buff *nskb = skb_realloc_headroom(skb, 32);
kfree_skb(skb);
skb = nskb;
- } else
+ } else {
skb = skb_unshare(skb, GFP_ATOMIC);
+ }
/*
* If the buffer didn't vanish into the lack of space bitbucket we can
--
2.35.1
^ permalink raw reply related
* [PATCH] ath10k: skip ath10k_halt during suspend for driver state RESTARTING
From: Abhishek Kumar @ 2022-04-25 2:15 UTC (permalink / raw)
To: kvalo
Cc: kuabhs, linux-kernel, linux-wireless, briannorris, ath10k, netdev,
Wen Gong, David S. Miller, Jakub Kicinski, Paolo Abeni
Double free crash is observed when FW recovery(caused by wmi
timeout/crash) is followed by immediate suspend event. The FW recovery
is triggered by ath10k_core_restart() which calls driver clean up via
ath10k_halt(). When the suspend event occurs between the FW recovery,
the restart worker thread is put into frozen state until suspend completes.
The suspend event triggers ath10k_stop() which again triggers ath10k_halt()
The double invocation of ath10k_halt() causes ath10k_htt_rx_free() to be
called twice(Note: ath10k_htt_rx_alloc was not called by restart worker
thread because of its frozen state), causing the crash.
To fix this, during the suspend flow, skip call to ath10k_halt() in
ath10k_stop() when the current driver state is ATH10K_STATE_RESTARTING.
Also, for driver state ATH10K_STATE_RESTARTING, call
ath10k_wait_for_suspend() in ath10k_stop(). This is because call to
ath10k_wait_for_suspend() is skipped later in
[ath10k_halt() > ath10k_core_stop()] for the driver state
ATH10K_STATE_RESTARTING.
The frozen restart worker thread will be cancelled during resume when the
device comes out of suspend.
Below is the crash stack for reference:
[ 428.469167] ------------[ cut here ]------------
[ 428.469180] kernel BUG at mm/slub.c:4150!
[ 428.469193] invalid opcode: 0000 [#1] PREEMPT SMP NOPTI
[ 428.469219] Workqueue: events_unbound async_run_entry_fn
[ 428.469230] RIP: 0010:kfree+0x319/0x31b
[ 428.469241] RSP: 0018:ffffa1fac015fc30 EFLAGS: 00010246
[ 428.469247] RAX: ffffedb10419d108 RBX: ffff8c05262b0000
[ 428.469252] RDX: ffff8c04a8c07000 RSI: 0000000000000000
[ 428.469256] RBP: ffffa1fac015fc78 R08: 0000000000000000
[ 428.469276] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 428.469285] Call Trace:
[ 428.469295] ? dma_free_attrs+0x5f/0x7d
[ 428.469320] ath10k_core_stop+0x5b/0x6f
[ 428.469336] ath10k_halt+0x126/0x177
[ 428.469352] ath10k_stop+0x41/0x7e
[ 428.469387] drv_stop+0x88/0x10e
[ 428.469410] __ieee80211_suspend+0x297/0x411
[ 428.469441] rdev_suspend+0x6e/0xd0
[ 428.469462] wiphy_suspend+0xb1/0x105
[ 428.469483] ? name_show+0x2d/0x2d
[ 428.469490] dpm_run_callback+0x8c/0x126
[ 428.469511] ? name_show+0x2d/0x2d
[ 428.469517] __device_suspend+0x2e7/0x41b
[ 428.469523] async_suspend+0x1f/0x93
[ 428.469529] async_run_entry_fn+0x3d/0xd1
[ 428.469535] process_one_work+0x1b1/0x329
[ 428.469541] worker_thread+0x213/0x372
[ 428.469547] kthread+0x150/0x15f
[ 428.469552] ? pr_cont_work+0x58/0x58
[ 428.469558] ? kthread_blkcg+0x31/0x31
Signed-off-by: Abhishek Kumar <kuabhs@chromium.org>
Co-developed-by: Wen Gong <quic_wgong@quicinc.com>
Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
---
drivers/net/wireless/ath/ath10k/mac.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index d804e19a742a..57ba27c46371 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -5345,8 +5345,22 @@ static void ath10k_stop(struct ieee80211_hw *hw)
mutex_lock(&ar->conf_mutex);
if (ar->state != ATH10K_STATE_OFF) {
- if (!ar->hw_rfkill_on)
- ath10k_halt(ar);
+ if (!ar->hw_rfkill_on) {
+ /* If the current driver state is RESTARTING but not yet
+ * fully RESTARTED because of incoming suspend event,
+ * then ath11k_halt is already called via
+ * ath10k_core_restart and should not be called here.
+ */
+ if (ar->state != ATH10K_STATE_RESTARTING)
+ ath10k_halt(ar);
+ else
+ /* Suspending here, because when in RESTARTING
+ * state, ath11k_core_stop skips
+ * ath10k_wait_for_suspend.
+ */
+ ath10k_wait_for_suspend(ar,
+ WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
+ }
ar->state = ATH10K_STATE_OFF;
}
mutex_unlock(&ar->conf_mutex);
--
2.36.0.rc2.479.g8af0fa9b8e-goog
^ permalink raw reply related
* [PATCHv2 net-next] net/af_packet: add VLAN support for AF_PACKET SOCK_RAW GSO
From: Hangbin Liu @ 2022-04-25 1:45 UTC (permalink / raw)
To: netdev
Cc: Michael S . Tsirkin, Jason Wang, David S . Miller, Jakub Kicinski,
Paolo Abeni, Maxim Mikityanskiy, Willem de Bruijn, Balazs Nemeth,
Mike Pattrick, Eric Dumazet, Hangbin Liu
Currently, the kernel drops GSO VLAN tagged packet if it's created with
socket(AF_PACKET, SOCK_RAW, 0) plus virtio_net_hdr.
The reason is AF_PACKET doesn't adjust the skb network header if there is
a VLAN tag. Then after virtio_net_hdr_set_proto() called, the skb->protocol
will be set to ETH_P_IP/IPv6. And in later inet/ipv6_gso_segment() the skb
is dropped as network header position is invalid.
Let's handle VLAN packets by adjusting network header position in
packet_parse_headers(). The adjustment is safe and does not affect the
later xmit as tap device also did that.
In packet_snd(), packet_parse_headers() need to be moved before calling
virtio_net_hdr_set_proto(), so we can set correct skb->protocol and
network header first.
There is no need to update tpacket_snd() as it calls packet_parse_headers()
in tpacket_fill_skb(), which is already before calling virtio_net_hdr_*
functions.
skb->no_fcs setting is also moved upper to make all skb settings together
and keep consistency with function packet_sendmsg_spkt().
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
---
v2: Rewrite commit description, no code update.
---
net/packet/af_packet.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 243566129784..fd31334cf688 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1924,12 +1924,20 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,
static void packet_parse_headers(struct sk_buff *skb, struct socket *sock)
{
+ int depth;
+
if ((!skb->protocol || skb->protocol == htons(ETH_P_ALL)) &&
sock->type == SOCK_RAW) {
skb_reset_mac_header(skb);
skb->protocol = dev_parse_header_protocol(skb);
}
+ /* Move network header to the right position for VLAN tagged packets */
+ if (likely(skb->dev->type == ARPHRD_ETHER) &&
+ eth_type_vlan(skb->protocol) &&
+ __vlan_get_protocol(skb, skb->protocol, &depth) != 0)
+ skb_set_network_header(skb, depth);
+
skb_probe_transport_header(skb);
}
@@ -3047,6 +3055,11 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
skb->mark = sockc.mark;
skb->tstamp = sockc.transmit_time;
+ if (unlikely(extra_len == 4))
+ skb->no_fcs = 1;
+
+ packet_parse_headers(skb, sock);
+
if (has_vnet_hdr) {
err = virtio_net_hdr_to_skb(skb, &vnet_hdr, vio_le());
if (err)
@@ -3055,11 +3068,6 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
virtio_net_hdr_set_proto(skb, &vnet_hdr);
}
- packet_parse_headers(skb, sock);
-
- if (unlikely(extra_len == 4))
- skb->no_fcs = 1;
-
err = po->xmit(skb);
if (unlikely(err != 0)) {
if (err > 0)
--
2.35.1
^ permalink raw reply related
* Re: [PATCH net-next v1 1/4] net: phy: broadcom: Add PTP support for some Broadcom PHYs.
From: Richard Cochran @ 2022-04-25 1:38 UTC (permalink / raw)
To: Jonathan Lemon
Cc: f.fainelli, bcm-kernel-feedback-list, andrew, hkallweit1, linux,
netdev, kernel-team
In-Reply-To: <20220424022356.587949-2-jonathan.lemon@gmail.com>
On Sat, Apr 23, 2022 at 07:23:53PM -0700, Jonathan Lemon wrote:
> +static bool bcm_ptp_get_tstamp(struct bcm_ptp_private *priv,
> + struct bcm_ptp_capture *capts)
> +{
> + struct phy_device *phydev = priv->phydev;
> + u16 ts[4], reg;
> + u32 sec, nsec;
> +
> + mutex_lock(&priv->mutex);
> +
> + reg = bcm_phy_read_exp(phydev, INTR_STATUS);
> + if ((reg & INTC_SOP) == 0) {
> + mutex_unlock(&priv->mutex);
> + return false;
> + }
> +
> + bcm_phy_write_exp(phydev, TS_READ_CTRL, TS_READ_START);
> +
> + ts[0] = bcm_phy_read_exp(phydev, TS_REG_0);
> + ts[1] = bcm_phy_read_exp(phydev, TS_REG_1);
> + ts[2] = bcm_phy_read_exp(phydev, TS_REG_2);
> + ts[3] = bcm_phy_read_exp(phydev, TS_REG_3);
> +
> + /* not in be32 format for some reason */
> + capts->seq_id = bcm_phy_read_exp(priv->phydev, TS_INFO_0);
> +
> + reg = bcm_phy_read_exp(phydev, TS_INFO_1);
> + capts->msgtype = reg >> 12;
> + capts->tx_dir = !!(reg & BIT(11));
Okay, so now I am sad. The 541xx has:
TIMESTAMP_INFO_1 0xA8C bit 0 DIR, bits 1-2 msg_type, etc
TIMESTAMP_INFO_2 0xA8D sequence ID
It is the same info, but randomly shuffled among the two registers in
a different way.
So much for supporting multiple devices with a common code base. :(
> + bcm_phy_write_exp(phydev, TS_READ_CTRL, TS_READ_END);
> + bcm_phy_write_exp(phydev, TS_READ_CTRL, 0);
> +
> + mutex_unlock(&priv->mutex);
> +
> + sec = (ts[3] << 16) | ts[2];
> + nsec = (ts[1] << 16) | ts[0];
> + capts->hwtstamp = ktime_set(sec, nsec);
> +
> + return true;
> +}
Thanks,
Richard
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox