From f64e189442332f198cea239eee4da6f72465059e Mon Sep 17 00:00:00 2001 From: Grzegorz Nitka Date: Wed, 6 Dec 2023 20:29:17 +0100 Subject: ice: introduce new E825C devices family Introduce new Intel Ethernet E825C family devices. Add new PCI device IDs which are going to be supported by the driver: - 579C: Intel(R) Ethernet Connection E825-C for backplane - 579D: Intel(R) Ethernet Connection E825-C for QSFP - 579E: Intel(R) Ethernet Connection E825-C for SFP - 579F: Intel(R) Ethernet Connection E825-C for SGMII Add helper function ice_is_e825c() to verify if the running device belongs to E825C family. Co-developed-by: Jan Glaza Signed-off-by: Jan Glaza Co-developed-by: Michal Michalik Signed-off-by: Michal Michalik Signed-off-by: Grzegorz Nitka Reviewed-by: Simon Horman Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ice/ice_common.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers/net/ethernet/intel/ice/ice_common.c') diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index 10c32cd80fff..cc8c9f2b72f5 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -240,6 +240,25 @@ bool ice_is_e823(struct ice_hw *hw) } } +/** + * ice_is_e825c - Check if a device is E825C family device + * @hw: pointer to the hardware structure + * + * Return: true if the device is E825-C based, false if not. + */ +bool ice_is_e825c(struct ice_hw *hw) +{ + switch (hw->device_id) { + case ICE_DEV_ID_E825C_BACKPLANE: + case ICE_DEV_ID_E825C_QSFP: + case ICE_DEV_ID_E825C_SFP: + case ICE_DEV_ID_E825C_SGMII: + return true; + default: + return false; + } +} + /** * ice_clear_pf_cfg - Clear PF configuration * @hw: pointer to the hardware structure -- cgit v1.2.3 From 7a15668f665c014f345761fdc283051b97a48e00 Mon Sep 17 00:00:00 2001 From: Grzegorz Nitka Date: Wed, 6 Dec 2023 20:29:18 +0100 Subject: ice: Add helper function ice_is_generic_mac E800 series devices have a couple of quirks: 1. Sideband control queues are not supported 2. The registers that the driver needs to program for the "Precision Time Protocol (PTP)" feature are different for E800 series devices compared to other devices supported by this driver. Both these require conditional logic based on the underlying device we are dealing with. The function ice_is_sbq_supported added by commit 8f5ee3c477a8 ("ice: add support for sideband messages") addresses (1). The same function can be used to address (2) as well but this just looks weird readability wise in cases that have nothing to do with sideband control queues: if (ice_is_sbq_supported(hw)) /* program register A */ else /* program register B */ For these cases, the function ice_is_generic_mac introduced by this patch communicates the idea/intention better. Also rework ice_is_sbq_supported to use this new function. As side-band queue is supported for E825C devices, it's mac_type is considered as generic mac_type. Co-developed-by: Anirudh Venkataramanan Signed-off-by: Anirudh Venkataramanan Signed-off-by: Grzegorz Nitka Reviewed-by: Simon Horman Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ice/ice_common.c | 12 ++++++++++++ drivers/net/ethernet/intel/ice/ice_common.h | 1 + drivers/net/ethernet/intel/ice/ice_controlq.c | 2 +- drivers/net/ethernet/intel/ice/ice_main.c | 6 ++++-- drivers/net/ethernet/intel/ice/ice_type.h | 1 + 5 files changed, 19 insertions(+), 3 deletions(-) (limited to 'drivers/net/ethernet/intel/ice/ice_common.c') diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index cc8c9f2b72f5..a7e6e5c1d06e 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -169,6 +169,18 @@ static int ice_set_mac_type(struct ice_hw *hw) return 0; } +/** + * ice_is_generic_mac - check if device's mac_type is generic + * @hw: pointer to the hardware structure + * + * Return: true if mac_type is generic (with SBQ support), false if not + */ +bool ice_is_generic_mac(struct ice_hw *hw) +{ + return (hw->mac_type == ICE_MAC_GENERIC || + hw->mac_type == ICE_MAC_GENERIC_3K_E825); +} + /** * ice_is_e810 * @hw: pointer to the hardware structure diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h index 42d45a73359c..32fd10de620c 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.h +++ b/drivers/net/ethernet/intel/ice/ice_common.h @@ -112,6 +112,7 @@ ice_update_phy_type(u64 *phy_type_low, u64 *phy_type_high, int ice_aq_manage_mac_write(struct ice_hw *hw, const u8 *mac_addr, u8 flags, struct ice_sq_cd *cd); +bool ice_is_generic_mac(struct ice_hw *hw); bool ice_is_e810(struct ice_hw *hw); int ice_clear_pf_cfg(struct ice_hw *hw); int diff --git a/drivers/net/ethernet/intel/ice/ice_controlq.c b/drivers/net/ethernet/intel/ice/ice_controlq.c index e7d2474c431c..ffe660f34992 100644 --- a/drivers/net/ethernet/intel/ice/ice_controlq.c +++ b/drivers/net/ethernet/intel/ice/ice_controlq.c @@ -666,7 +666,7 @@ bool ice_is_sbq_supported(struct ice_hw *hw) /* The device sideband queue is only supported on devices with the * generic MAC type. */ - return hw->mac_type == ICE_MAC_GENERIC; + return ice_is_generic_mac(hw); } /** diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index b3c24e40ccb6..1fa3f40743f5 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -1649,8 +1649,10 @@ static void ice_clean_sbq_subtask(struct ice_pf *pf) { struct ice_hw *hw = &pf->hw; - /* Nothing to do here if sideband queue is not supported */ - if (!ice_is_sbq_supported(hw)) { + /* if mac_type is not generic, sideband is not supported + * and there's nothing to do here + */ + if (!ice_is_generic_mac(hw)) { clear_bit(ICE_SIDEBANDQ_EVENT_PENDING, pf->state); return; } diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h index a508e917ce5f..9ff92dba5823 100644 --- a/drivers/net/ethernet/intel/ice/ice_type.h +++ b/drivers/net/ethernet/intel/ice/ice_type.h @@ -132,6 +132,7 @@ enum ice_mac_type { ICE_MAC_E810, ICE_MAC_E830, ICE_MAC_GENERIC, + ICE_MAC_GENERIC_3K_E825, }; /* Media Types */ -- cgit v1.2.3 From 372e27de4ca8e5f22586198cd9429bfea75021ac Mon Sep 17 00:00:00 2001 From: Grzegorz Nitka Date: Wed, 6 Dec 2023 20:29:19 +0100 Subject: ice: add support for 3k signing DDP sections for E825C E825C devices shall support the new signing type of RSA 3K for new DDP section (SEGMENT_SIGN_TYPE_RSA3K_E825 (5) - already in the code). The driver is responsible to verify the presence of correct signing type. Add 3k signinig support for E825C devices based on mac_type: ICE_MAC_GENERIC_3K_E825; Signed-off-by: Grzegorz Nitka Reviewed-by: Simon Horman Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ice/ice_common.c | 6 ++++++ drivers/net/ethernet/intel/ice/ice_ddp.c | 4 ++++ 2 files changed, 10 insertions(+) (limited to 'drivers/net/ethernet/intel/ice/ice_common.c') diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index a7e6e5c1d06e..9266f25a9978 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -154,6 +154,12 @@ static int ice_set_mac_type(struct ice_hw *hw) case ICE_DEV_ID_E823L_SFP: hw->mac_type = ICE_MAC_GENERIC; break; + case ICE_DEV_ID_E825C_BACKPLANE: + case ICE_DEV_ID_E825C_QSFP: + case ICE_DEV_ID_E825C_SFP: + case ICE_DEV_ID_E825C_SGMII: + hw->mac_type = ICE_MAC_GENERIC_3K_E825; + break; case ICE_DEV_ID_E830_BACKPLANE: case ICE_DEV_ID_E830_QSFP56: case ICE_DEV_ID_E830_SFP: diff --git a/drivers/net/ethernet/intel/ice/ice_ddp.c b/drivers/net/ethernet/intel/ice/ice_ddp.c index 8b7504a9df31..7532d11ad7f3 100644 --- a/drivers/net/ethernet/intel/ice/ice_ddp.c +++ b/drivers/net/ethernet/intel/ice/ice_ddp.c @@ -1825,6 +1825,7 @@ static u32 ice_get_pkg_segment_id(enum ice_mac_type mac_type) seg_id = SEGMENT_TYPE_ICE_E830; break; case ICE_MAC_GENERIC: + case ICE_MAC_GENERIC_3K_E825: default: seg_id = SEGMENT_TYPE_ICE_E810; break; @@ -1845,6 +1846,9 @@ static u32 ice_get_pkg_sign_type(enum ice_mac_type mac_type) case ICE_MAC_E830: sign_type = SEGMENT_SIGN_TYPE_RSA3K_SBB; break; + case ICE_MAC_GENERIC_3K_E825: + sign_type = SEGMENT_SIGN_TYPE_RSA3K_E825; + break; case ICE_MAC_GENERIC: default: sign_type = SEGMENT_SIGN_TYPE_RSA2K; -- cgit v1.2.3 From 1260b45dbe2dbc415f3bc1e841c6c098083bcfb8 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Mon, 26 Feb 2024 16:14:54 -0800 Subject: ice: rename ice_write_* functions to ice_pack_ctx_* In ice_common.c there are 4 functions used for converting the unpacked software Tx and Rx context structure data into the packed format used by hardware. These functions have extremely generic names: * ice_write_byte * ice_write_word * ice_write_dword * ice_write_qword When I saw these function names my first thought was "write what? to where?". Understanding what these functions do requires looking at the implementation details. The functions take bits from an unpacked structure and copy them into the packed layout used by hardware. As part of live migration, we will want functions which perform the inverse operation of reading bits from the packed layout and copying them into the unpacked format. Naming these as "ice_read_byte", etc would be very confusing since they appear to write data. In preparation for adding this new inverse operation, rename the existing functions to use the prefix "ice_pack_ctx_". This makes it clear that they perform the bit packing while copying from the unpacked software context structure to the packed hardware context. The inverse operations can then neatly be named ice_unpack_ctx_*, clearly indicating they perform the bit unpacking while copying from the packed hardware context to the unpacked software context structure. Signed-off-by: Jacob Keller Reviewed-by: Przemek Kitszel Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ice/ice_common.c | 56 ++++++++++++++--------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers/net/ethernet/intel/ice/ice_common.c') diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index 9266f25a9978..3622079cb506 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -4362,13 +4362,13 @@ ice_aq_add_rdma_qsets(struct ice_hw *hw, u8 num_qset_grps, /* End of FW Admin Queue command wrappers */ /** - * ice_write_byte - write a byte to a packed context structure - * @src_ctx: the context structure to read from - * @dest_ctx: the context to be written to - * @ce_info: a description of the struct to be filled + * ice_pack_ctx_byte - write a byte to a packed context structure + * @src_ctx: unpacked source context structure + * @dest_ctx: packed destination context data + * @ce_info: context element description */ -static void -ice_write_byte(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info) +static void ice_pack_ctx_byte(u8 *src_ctx, u8 *dest_ctx, + const struct ice_ctx_ele *ce_info) { u8 src_byte, dest_byte, mask; u8 *from, *dest; @@ -4401,13 +4401,13 @@ ice_write_byte(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info) } /** - * ice_write_word - write a word to a packed context structure - * @src_ctx: the context structure to read from - * @dest_ctx: the context to be written to - * @ce_info: a description of the struct to be filled + * ice_pack_ctx_word - write a word to a packed context structure + * @src_ctx: unpacked source context structure + * @dest_ctx: packed destination context data + * @ce_info: context element description */ -static void -ice_write_word(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info) +static void ice_pack_ctx_word(u8 *src_ctx, u8 *dest_ctx, + const struct ice_ctx_ele *ce_info) { u16 src_word, mask; __le16 dest_word; @@ -4444,13 +4444,13 @@ ice_write_word(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info) } /** - * ice_write_dword - write a dword to a packed context structure - * @src_ctx: the context structure to read from - * @dest_ctx: the context to be written to - * @ce_info: a description of the struct to be filled + * ice_pack_ctx_dword - write a dword to a packed context structure + * @src_ctx: unpacked source context structure + * @dest_ctx: packed destination context data + * @ce_info: context element description */ -static void -ice_write_dword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info) +static void ice_pack_ctx_dword(u8 *src_ctx, u8 *dest_ctx, + const struct ice_ctx_ele *ce_info) { u32 src_dword, mask; __le32 dest_dword; @@ -4495,13 +4495,13 @@ ice_write_dword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info) } /** - * ice_write_qword - write a qword to a packed context structure - * @src_ctx: the context structure to read from - * @dest_ctx: the context to be written to - * @ce_info: a description of the struct to be filled + * ice_pack_ctx_qword - write a qword to a packed context structure + * @src_ctx: unpacked source context structure + * @dest_ctx: packed destination context data + * @ce_info: context element description */ -static void -ice_write_qword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info) +static void ice_pack_ctx_qword(u8 *src_ctx, u8 *dest_ctx, + const struct ice_ctx_ele *ce_info) { u64 src_qword, mask; __le64 dest_qword; @@ -4570,16 +4570,16 @@ ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx, } switch (ce_info[f].size_of) { case sizeof(u8): - ice_write_byte(src_ctx, dest_ctx, &ce_info[f]); + ice_pack_ctx_byte(src_ctx, dest_ctx, &ce_info[f]); break; case sizeof(u16): - ice_write_word(src_ctx, dest_ctx, &ce_info[f]); + ice_pack_ctx_word(src_ctx, dest_ctx, &ce_info[f]); break; case sizeof(u32): - ice_write_dword(src_ctx, dest_ctx, &ce_info[f]); + ice_pack_ctx_dword(src_ctx, dest_ctx, &ce_info[f]); break; case sizeof(u64): - ice_write_qword(src_ctx, dest_ctx, &ce_info[f]); + ice_pack_ctx_qword(src_ctx, dest_ctx, &ce_info[f]); break; default: return -EINVAL; -- cgit v1.2.3 From a45d1bf516c097bb7ae4983d3128ebf139be952c Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Mon, 26 Feb 2024 16:14:55 -0800 Subject: ice: use GENMASK instead of BIT(n) - 1 in pack functions The functions used to pack the Tx and Rx context into the hardware format rely on using BIT() and then subtracting 1 to get a bitmask. These functions even have a comment about how x86 machines can't use this method for certain widths because the SHL instructions will not work properly. The Linux kernel already provides the GENMASK macro for generating a suitable bitmask. Further, GENMASK is capable of generating the mask including the shift_width. Since width is the total field width, take care to subtract one to get the final bit position. Since we now include the shifted bits as part of the mask, shift the source value first before applying the mask. Signed-off-by: Jacob Keller Reviewed-by: Przemek Kitszel Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ice/ice_common.c | 44 ++++++----------------------- 1 file changed, 8 insertions(+), 36 deletions(-) (limited to 'drivers/net/ethernet/intel/ice/ice_common.c') diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index 3622079cb506..e9e4a8ef7904 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -4379,14 +4379,11 @@ static void ice_pack_ctx_byte(u8 *src_ctx, u8 *dest_ctx, /* prepare the bits and mask */ shift_width = ce_info->lsb % 8; - mask = (u8)(BIT(ce_info->width) - 1); + mask = GENMASK(ce_info->width - 1 + shift_width, shift_width); src_byte = *from; - src_byte &= mask; - - /* shift to correct alignment */ - mask <<= shift_width; src_byte <<= shift_width; + src_byte &= mask; /* get the current bits from the target bit string */ dest = dest_ctx + (ce_info->lsb / 8); @@ -4419,17 +4416,14 @@ static void ice_pack_ctx_word(u8 *src_ctx, u8 *dest_ctx, /* prepare the bits and mask */ shift_width = ce_info->lsb % 8; - mask = BIT(ce_info->width) - 1; + mask = GENMASK(ce_info->width - 1 + shift_width, shift_width); /* don't swizzle the bits until after the mask because the mask bits * will be in a different bit position on big endian machines */ src_word = *(u16 *)from; - src_word &= mask; - - /* shift to correct alignment */ - mask <<= shift_width; src_word <<= shift_width; + src_word &= mask; /* get the current bits from the target bit string */ dest = dest_ctx + (ce_info->lsb / 8); @@ -4462,25 +4456,14 @@ static void ice_pack_ctx_dword(u8 *src_ctx, u8 *dest_ctx, /* prepare the bits and mask */ shift_width = ce_info->lsb % 8; - - /* if the field width is exactly 32 on an x86 machine, then the shift - * operation will not work because the SHL instructions count is masked - * to 5 bits so the shift will do nothing - */ - if (ce_info->width < 32) - mask = BIT(ce_info->width) - 1; - else - mask = (u32)~0; + mask = GENMASK(ce_info->width - 1 + shift_width, shift_width); /* don't swizzle the bits until after the mask because the mask bits * will be in a different bit position on big endian machines */ src_dword = *(u32 *)from; - src_dword &= mask; - - /* shift to correct alignment */ - mask <<= shift_width; src_dword <<= shift_width; + src_dword &= mask; /* get the current bits from the target bit string */ dest = dest_ctx + (ce_info->lsb / 8); @@ -4513,25 +4496,14 @@ static void ice_pack_ctx_qword(u8 *src_ctx, u8 *dest_ctx, /* prepare the bits and mask */ shift_width = ce_info->lsb % 8; - - /* if the field width is exactly 64 on an x86 machine, then the shift - * operation will not work because the SHL instructions count is masked - * to 6 bits so the shift will do nothing - */ - if (ce_info->width < 64) - mask = BIT_ULL(ce_info->width) - 1; - else - mask = (u64)~0; + mask = GENMASK_ULL(ce_info->width - 1 + shift_width, shift_width); /* don't swizzle the bits until after the mask because the mask bits * will be in a different bit position on big endian machines */ src_qword = *(u64 *)from; - src_qword &= mask; - - /* shift to correct alignment */ - mask <<= shift_width; src_qword <<= shift_width; + src_qword &= mask; /* get the current bits from the target bit string */ dest = dest_ctx + (ce_info->lsb / 8); -- cgit v1.2.3 From 979c2c049fbea107ce9f8d31f3ba9dba83ddb0a2 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Mon, 26 Feb 2024 16:14:56 -0800 Subject: ice: cleanup line splitting for context set functions The indentation for ice_set_ctx and ice_write_rxq_ctx breaks the function name after the return type. This style of breaking is used a lot throughout the ice driver, even in cases where its not actually helpful for readability. We no longer prefer this style of line splitting in the driver, and new code is avoiding it. Normally, I would leave this alone unless the actual function contents or description needed updating. However, a future change is going to add inverse functions for converting packed context to unpacked context structures. To keep this code uniform with the existing set functions, fix up the style to the modern format of keeping the type on the same line. Signed-off-by: Jacob Keller Reviewed-by: Przemek Kitszel Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ice/ice_common.c | 12 +++++------- drivers/net/ethernet/intel/ice/ice_common.h | 10 ++++------ 2 files changed, 9 insertions(+), 13 deletions(-) (limited to 'drivers/net/ethernet/intel/ice/ice_common.c') diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index e9e4a8ef7904..7d9315ffae57 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -1399,9 +1399,8 @@ static const struct ice_ctx_ele ice_rlan_ctx_info[] = { * it to HW register space and enables the hardware to prefetch descriptors * instead of only fetching them on demand */ -int -ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx, - u32 rxq_index) +int ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx, + u32 rxq_index) { u8 ctx_buf[ICE_RXQ_CTX_SZ] = { 0 }; @@ -4522,11 +4521,10 @@ static void ice_pack_ctx_qword(u8 *src_ctx, u8 *dest_ctx, * @hw: pointer to the hardware structure * @src_ctx: pointer to a generic non-packed context structure * @dest_ctx: pointer to memory for the packed structure - * @ce_info: a description of the structure to be transformed + * @ce_info: List of Rx context elements */ -int -ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx, - const struct ice_ctx_ele *ce_info) +int ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx, + const struct ice_ctx_ele *ce_info) { int f; diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h index 32fd10de620c..ffb22c7ce28b 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.h +++ b/drivers/net/ethernet/intel/ice/ice_common.h @@ -53,9 +53,8 @@ int ice_get_caps(struct ice_hw *hw); void ice_set_safe_mode_caps(struct ice_hw *hw); -int -ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx, - u32 rxq_index); +int ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx, + u32 rxq_index); int ice_aq_get_rss_lut(struct ice_hw *hw, struct ice_aq_get_set_rss_lut_params *get_params); @@ -72,9 +71,8 @@ bool ice_check_sq_alive(struct ice_hw *hw, struct ice_ctl_q_info *cq); int ice_aq_q_shutdown(struct ice_hw *hw, bool unloading); void ice_fill_dflt_direct_cmd_desc(struct ice_aq_desc *desc, u16 opcode); extern const struct ice_ctx_ele ice_tlan_ctx_info[]; -int -ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx, - const struct ice_ctx_ele *ce_info); +int ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx, + const struct ice_ctx_ele *ce_info); extern struct mutex ice_global_cfg_lock_sw; -- cgit v1.2.3 From 90f821d72e112d5e4e4214a3704935283cc53375 Mon Sep 17 00:00:00 2001 From: Maciej Fijalkowski Date: Fri, 23 Feb 2024 17:06:28 +0100 Subject: ice: avoid unnecessary devm_ usage 1. pcaps are free'd right after AQ routines are done, no need for devm_'s 2. a test frame for loopback test in ethtool -t is destroyed at the end of the test so we don't need devm_ here either. Signed-off-by: Maciej Fijalkowski Reviewed-by: Przemek Kitszel Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ice/ice_common.c | 34 +++++++++------------------- drivers/net/ethernet/intel/ice/ice_ethtool.c | 10 +++----- 2 files changed, 14 insertions(+), 30 deletions(-) (limited to 'drivers/net/ethernet/intel/ice/ice_common.c') diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index 7d9315ffae57..4d8111aeb0ff 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -1002,9 +1002,9 @@ static void ice_get_itr_intrl_gran(struct ice_hw *hw) */ int ice_init_hw(struct ice_hw *hw) { - struct ice_aqc_get_phy_caps_data *pcaps; + struct ice_aqc_get_phy_caps_data *pcaps __free(kfree); + void *mac_buf __free(kfree); u16 mac_buf_len; - void *mac_buf; int status; /* Set MAC type based on DeviceID */ @@ -1082,7 +1082,7 @@ int ice_init_hw(struct ice_hw *hw) if (status) goto err_unroll_sched; - pcaps = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*pcaps), GFP_KERNEL); + pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL); if (!pcaps) { status = -ENOMEM; goto err_unroll_sched; @@ -1092,7 +1092,6 @@ int ice_init_hw(struct ice_hw *hw) status = ice_aq_get_phy_caps(hw->port_info, false, ICE_AQC_REPORT_TOPO_CAP_MEDIA, pcaps, NULL); - devm_kfree(ice_hw_to_dev(hw), pcaps); if (status) dev_warn(ice_hw_to_dev(hw), "Get PHY capabilities failed status = %d, continuing anyway\n", status); @@ -1119,18 +1118,15 @@ int ice_init_hw(struct ice_hw *hw) /* Get MAC information */ /* A single port can report up to two (LAN and WoL) addresses */ - mac_buf = devm_kcalloc(ice_hw_to_dev(hw), 2, - sizeof(struct ice_aqc_manage_mac_read_resp), - GFP_KERNEL); - mac_buf_len = 2 * sizeof(struct ice_aqc_manage_mac_read_resp); - + mac_buf = kcalloc(2, sizeof(struct ice_aqc_manage_mac_read_resp), + GFP_KERNEL); if (!mac_buf) { status = -ENOMEM; goto err_unroll_fltr_mgmt_struct; } + mac_buf_len = 2 * sizeof(struct ice_aqc_manage_mac_read_resp); status = ice_aq_manage_mac_read(hw, mac_buf, mac_buf_len, NULL); - devm_kfree(ice_hw_to_dev(hw), mac_buf); if (status) goto err_unroll_fltr_mgmt_struct; @@ -3276,19 +3272,14 @@ int ice_update_link_info(struct ice_port_info *pi) return status; if (li->link_info & ICE_AQ_MEDIA_AVAILABLE) { - struct ice_aqc_get_phy_caps_data *pcaps; - struct ice_hw *hw; + struct ice_aqc_get_phy_caps_data *pcaps __free(kfree); - hw = pi->hw; - pcaps = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*pcaps), - GFP_KERNEL); + pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL); if (!pcaps) return -ENOMEM; status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP_MEDIA, pcaps, NULL); - - devm_kfree(ice_hw_to_dev(hw), pcaps); } return status; @@ -3429,8 +3420,8 @@ ice_cfg_phy_fc(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg, int ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update) { + struct ice_aqc_get_phy_caps_data *pcaps __free(kfree); struct ice_aqc_set_phy_cfg_data cfg = { 0 }; - struct ice_aqc_get_phy_caps_data *pcaps; struct ice_hw *hw; int status; @@ -3440,7 +3431,7 @@ ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update) *aq_failures = 0; hw = pi->hw; - pcaps = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*pcaps), GFP_KERNEL); + pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL); if (!pcaps) return -ENOMEM; @@ -3492,7 +3483,6 @@ ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update) } out: - devm_kfree(ice_hw_to_dev(hw), pcaps); return status; } @@ -3571,7 +3561,7 @@ int ice_cfg_phy_fec(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg, enum ice_fec_mode fec) { - struct ice_aqc_get_phy_caps_data *pcaps; + struct ice_aqc_get_phy_caps_data *pcaps __free(kfree); struct ice_hw *hw; int status; @@ -3640,8 +3630,6 @@ ice_cfg_phy_fec(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg, } out: - kfree(pcaps); - return status; } diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c index 3cc364a4d682..bb912155676e 100644 --- a/drivers/net/ethernet/intel/ice/ice_ethtool.c +++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c @@ -802,7 +802,7 @@ static int ice_lbtest_create_frame(struct ice_pf *pf, u8 **ret_data, u16 size) if (!pf) return -EINVAL; - data = devm_kzalloc(ice_pf_to_dev(pf), size, GFP_KERNEL); + data = kzalloc(size, GFP_KERNEL); if (!data) return -ENOMEM; @@ -945,11 +945,9 @@ static u64 ice_loopback_test(struct net_device *netdev) int num_frames, valid_frames; struct ice_tx_ring *tx_ring; struct ice_rx_ring *rx_ring; - struct device *dev; - u8 *tx_frame; + u8 *tx_frame __free(kfree); int i; - dev = ice_pf_to_dev(pf); netdev_info(netdev, "loopback test\n"); test_vsi = ice_lb_vsi_setup(pf, pf->hw.port_info); @@ -994,7 +992,7 @@ static u64 ice_loopback_test(struct net_device *netdev) for (i = 0; i < num_frames; i++) { if (ice_diag_send(tx_ring, tx_frame, ICE_LB_FRAME_SIZE)) { ret = 8; - goto lbtest_free_frame; + goto remove_mac_filters; } } @@ -1004,8 +1002,6 @@ static u64 ice_loopback_test(struct net_device *netdev) else if (valid_frames != num_frames) ret = 10; -lbtest_free_frame: - devm_kfree(dev, tx_frame); remove_mac_filters: if (ice_fltr_remove_mac(test_vsi, broadcast, ICE_FWD_TO_VSI)) netdev_err(netdev, "Could not remove MAC filter for the test VSI\n"); -- cgit v1.2.3 From d8e45f2929b94099913eb66c3ebb18b5063e9421 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 6 Mar 2024 15:51:36 -0800 Subject: overflow: Change DEFINE_FLEX to take __counted_by member The norm should be flexible array structures with __counted_by annotations, so DEFINE_FLEX() is updated to expect that. Rename the non-annotated version to DEFINE_RAW_FLEX(), and update the few existing users. Additionally add selftests for the macros. Reviewed-by: Gustavo A. R. Silva Link: https://lore.kernel.org/r/20240306235128.it.933-kees@kernel.org Reviewed-by: Przemek Kitszel Signed-off-by: Kees Cook --- drivers/net/ethernet/intel/ice/ice_base.c | 4 ++-- drivers/net/ethernet/intel/ice/ice_common.c | 4 ++-- drivers/net/ethernet/intel/ice/ice_ddp.c | 8 ++++---- drivers/net/ethernet/intel/ice/ice_lag.c | 6 +++--- drivers/net/ethernet/intel/ice/ice_sched.c | 4 ++-- drivers/net/ethernet/intel/ice/ice_switch.c | 10 +++++----- include/linux/overflow.h | 25 +++++++++++++++++++++---- lib/overflow_kunit.c | 19 +++++++++++++++++++ 8 files changed, 58 insertions(+), 22 deletions(-) (limited to 'drivers/net/ethernet/intel/ice/ice_common.c') diff --git a/drivers/net/ethernet/intel/ice/ice_base.c b/drivers/net/ethernet/intel/ice/ice_base.c index d2fd315556a3..a545a7917e4f 100644 --- a/drivers/net/ethernet/intel/ice/ice_base.c +++ b/drivers/net/ethernet/intel/ice/ice_base.c @@ -956,7 +956,7 @@ ice_vsi_cfg_txq(struct ice_vsi *vsi, struct ice_tx_ring *ring, int ice_vsi_cfg_single_txq(struct ice_vsi *vsi, struct ice_tx_ring **tx_rings, u16 q_idx) { - DEFINE_FLEX(struct ice_aqc_add_tx_qgrp, qg_buf, txqs, 1); + DEFINE_RAW_FLEX(struct ice_aqc_add_tx_qgrp, qg_buf, txqs, 1); if (q_idx >= vsi->alloc_txq || !tx_rings || !tx_rings[q_idx]) return -EINVAL; @@ -978,7 +978,7 @@ int ice_vsi_cfg_single_txq(struct ice_vsi *vsi, struct ice_tx_ring **tx_rings, static int ice_vsi_cfg_txqs(struct ice_vsi *vsi, struct ice_tx_ring **rings, u16 count) { - DEFINE_FLEX(struct ice_aqc_add_tx_qgrp, qg_buf, txqs, 1); + DEFINE_RAW_FLEX(struct ice_aqc_add_tx_qgrp, qg_buf, txqs, 1); int err = 0; u16 q_idx; diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index 4d8111aeb0ff..db4b2844e1f7 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -4695,7 +4695,7 @@ ice_dis_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_queues, enum ice_disq_rst_src rst_src, u16 vmvf_num, struct ice_sq_cd *cd) { - DEFINE_FLEX(struct ice_aqc_dis_txq_item, qg_list, q_id, 1); + DEFINE_RAW_FLEX(struct ice_aqc_dis_txq_item, qg_list, q_id, 1); u16 i, buf_size = __struct_size(qg_list); struct ice_q_ctx *q_ctx; int status = -ENOENT; @@ -4917,7 +4917,7 @@ int ice_dis_vsi_rdma_qset(struct ice_port_info *pi, u16 count, u32 *qset_teid, u16 *q_id) { - DEFINE_FLEX(struct ice_aqc_dis_txq_item, qg_list, q_id, 1); + DEFINE_RAW_FLEX(struct ice_aqc_dis_txq_item, qg_list, q_id, 1); u16 qg_size = __struct_size(qg_list); struct ice_hw *hw; int status = 0; diff --git a/drivers/net/ethernet/intel/ice/ice_ddp.c b/drivers/net/ethernet/intel/ice/ice_ddp.c index 7532d11ad7f3..fc91c4d41186 100644 --- a/drivers/net/ethernet/intel/ice/ice_ddp.c +++ b/drivers/net/ethernet/intel/ice/ice_ddp.c @@ -1938,8 +1938,8 @@ static enum ice_ddp_state ice_init_pkg_info(struct ice_hw *hw, */ static enum ice_ddp_state ice_get_pkg_info(struct ice_hw *hw) { - DEFINE_FLEX(struct ice_aqc_get_pkg_info_resp, pkg_info, pkg_info, - ICE_PKG_CNT); + DEFINE_RAW_FLEX(struct ice_aqc_get_pkg_info_resp, pkg_info, pkg_info, + ICE_PKG_CNT); u16 size = __struct_size(pkg_info); u32 i; @@ -1990,8 +1990,8 @@ static enum ice_ddp_state ice_chk_pkg_compat(struct ice_hw *hw, struct ice_pkg_hdr *ospkg, struct ice_seg **seg) { - DEFINE_FLEX(struct ice_aqc_get_pkg_info_resp, pkg, pkg_info, - ICE_PKG_CNT); + DEFINE_RAW_FLEX(struct ice_aqc_get_pkg_info_resp, pkg, pkg_info, + ICE_PKG_CNT); u16 size = __struct_size(pkg); enum ice_ddp_state state; u32 i; diff --git a/drivers/net/ethernet/intel/ice/ice_lag.c b/drivers/net/ethernet/intel/ice/ice_lag.c index 467372d541d2..f97128b69f87 100644 --- a/drivers/net/ethernet/intel/ice/ice_lag.c +++ b/drivers/net/ethernet/intel/ice/ice_lag.c @@ -491,7 +491,7 @@ static void ice_lag_move_vf_node_tc(struct ice_lag *lag, u8 oldport, u8 newport, u16 vsi_num, u8 tc) { - DEFINE_FLEX(struct ice_aqc_move_elem, buf, teid, 1); + DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1); struct device *dev = ice_pf_to_dev(lag->pf); u16 numq, valq, num_moved, qbuf_size; u16 buf_size = __struct_size(buf); @@ -849,7 +849,7 @@ static void ice_lag_reclaim_vf_tc(struct ice_lag *lag, struct ice_hw *src_hw, u16 vsi_num, u8 tc) { - DEFINE_FLEX(struct ice_aqc_move_elem, buf, teid, 1); + DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1); struct device *dev = ice_pf_to_dev(lag->pf); u16 numq, valq, num_moved, qbuf_size; u16 buf_size = __struct_size(buf); @@ -1873,7 +1873,7 @@ static void ice_lag_move_vf_nodes_tc_sync(struct ice_lag *lag, struct ice_hw *dest_hw, u16 vsi_num, u8 tc) { - DEFINE_FLEX(struct ice_aqc_move_elem, buf, teid, 1); + DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1); struct device *dev = ice_pf_to_dev(lag->pf); u16 numq, valq, num_moved, qbuf_size; u16 buf_size = __struct_size(buf); diff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c index d174a4eeb899..a1525992d14b 100644 --- a/drivers/net/ethernet/intel/ice/ice_sched.c +++ b/drivers/net/ethernet/intel/ice/ice_sched.c @@ -237,7 +237,7 @@ static int ice_sched_remove_elems(struct ice_hw *hw, struct ice_sched_node *parent, u32 node_teid) { - DEFINE_FLEX(struct ice_aqc_delete_elem, buf, teid, 1); + DEFINE_RAW_FLEX(struct ice_aqc_delete_elem, buf, teid, 1); u16 buf_size = __struct_size(buf); u16 num_groups_removed = 0; int status; @@ -2219,7 +2219,7 @@ int ice_sched_move_nodes(struct ice_port_info *pi, struct ice_sched_node *parent, u16 num_items, u32 *list) { - DEFINE_FLEX(struct ice_aqc_move_elem, buf, teid, 1); + DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1); u16 buf_len = __struct_size(buf); struct ice_sched_node *node; u16 i, grps_movd = 0; diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c index f84bab80ca42..d4baae8c3b72 100644 --- a/drivers/net/ethernet/intel/ice/ice_switch.c +++ b/drivers/net/ethernet/intel/ice/ice_switch.c @@ -1812,7 +1812,7 @@ ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type, enum ice_adminq_opc opc) { - DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1); + DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1); u16 buf_len = __struct_size(sw_buf); struct ice_aqc_res_elem *vsi_ele; int status; @@ -2081,7 +2081,7 @@ ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap, */ int ice_alloc_recipe(struct ice_hw *hw, u16 *rid) { - DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1); + DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1); u16 buf_len = __struct_size(sw_buf); int status; @@ -4418,7 +4418,7 @@ int ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, u16 *counter_id) { - DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1); + DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1); u16 buf_len = __struct_size(buf); int status; @@ -4446,7 +4446,7 @@ int ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, u16 counter_id) { - DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1); + DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1); u16 buf_len = __struct_size(buf); int status; @@ -4476,7 +4476,7 @@ ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, */ int ice_share_res(struct ice_hw *hw, u16 type, u8 shared, u16 res_id) { - DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1); + DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1); u16 buf_len = __struct_size(buf); u16 res_type; int status; diff --git a/include/linux/overflow.h b/include/linux/overflow.h index aa691f2119b0..0c7e3dcfe867 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h @@ -398,7 +398,7 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend) * @count: Number of elements in the array; must be compile-time const. * @initializer: initializer expression (could be empty for no init). */ -#define _DEFINE_FLEX(type, name, member, count, initializer) \ +#define _DEFINE_FLEX(type, name, member, count, initializer...) \ _Static_assert(__builtin_constant_p(count), \ "onstack flex array members require compile-time const count"); \ union { \ @@ -408,8 +408,8 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend) type *name = (type *)&name##_u /** - * DEFINE_FLEX() - Define an on-stack instance of structure with a trailing - * flexible array member. + * DEFINE_RAW_FLEX() - Define an on-stack instance of structure with a trailing + * flexible array member, when it does not have a __counted_by annotation. * * @type: structure type name, including "struct" keyword. * @name: Name for a variable to define. @@ -420,7 +420,24 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend) * flexible array member. * Use __struct_size(@name) to get compile-time size of it afterwards. */ -#define DEFINE_FLEX(type, name, member, count) \ +#define DEFINE_RAW_FLEX(type, name, member, count) \ _DEFINE_FLEX(type, name, member, count, = {}) +/** + * DEFINE_FLEX() - Define an on-stack instance of structure with a trailing + * flexible array member. + * + * @TYPE: structure type name, including "struct" keyword. + * @NAME: Name for a variable to define. + * @MEMBER: Name of the array member. + * @COUNTER: Name of the __counted_by member. + * @COUNT: Number of elements in the array; must be compile-time const. + * + * Define a zeroed, on-stack, instance of @TYPE structure with a trailing + * flexible array member. + * Use __struct_size(@NAME) to get compile-time size of it afterwards. + */ +#define DEFINE_FLEX(TYPE, NAME, MEMBER, COUNTER, COUNT) \ + _DEFINE_FLEX(TYPE, NAME, MEMBER, COUNT, = { .obj.COUNTER = COUNT, }) + #endif /* __LINUX_OVERFLOW_H */ diff --git a/lib/overflow_kunit.c b/lib/overflow_kunit.c index 65e8a72a83bf..4ef31b0bb74d 100644 --- a/lib/overflow_kunit.c +++ b/lib/overflow_kunit.c @@ -1172,6 +1172,24 @@ static void castable_to_type_test(struct kunit *test) #undef TEST_CASTABLE_TO_TYPE } +struct foo { + int a; + u32 counter; + s16 array[] __counted_by(counter); +}; + +static void DEFINE_FLEX_test(struct kunit *test) +{ + DEFINE_RAW_FLEX(struct foo, two, array, 2); + DEFINE_FLEX(struct foo, eight, array, counter, 8); + DEFINE_FLEX(struct foo, empty, array, counter, 0); + + KUNIT_EXPECT_EQ(test, __struct_size(two), + sizeof(struct foo) + sizeof(s16) + sizeof(s16)); + KUNIT_EXPECT_EQ(test, __struct_size(eight), 24); + KUNIT_EXPECT_EQ(test, __struct_size(empty), sizeof(struct foo)); +} + static struct kunit_case overflow_test_cases[] = { KUNIT_CASE(u8_u8__u8_overflow_test), KUNIT_CASE(s8_s8__s8_overflow_test), @@ -1194,6 +1212,7 @@ static struct kunit_case overflow_test_cases[] = { KUNIT_CASE(overflows_type_test), KUNIT_CASE(same_type_test), KUNIT_CASE(castable_to_type_test), + KUNIT_CASE(DEFINE_FLEX_test), {} }; -- cgit v1.2.3