[PATCH iwl-next v1 07/10] libie, idpf: move parsing alloc vectors command to libie
From: Michal Swiatkowski <hidden>
Date: 2026-09-07 11:04:32
Also in:
intel-wired-lan
Subsystem:
intel ethernet drivers, libie common intel ethernet library, networking drivers, the rest · Maintainers:
Tony Nguyen, Przemek Kitszel, Alexander Lobakin, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
No functional changes. Just moving to make it available from other ipu drivers. Reviewed-by: Aleksandr Loktionov <redacted> Reviewed-by: Ahmed Zaki <redacted> Signed-off-by: Michal Swiatkowski <redacted> --- .../net/ethernet/intel/idpf/idpf_virtchnl.c | 85 +---------------- drivers/net/ethernet/intel/libie/irq.c | 91 +++++++++++++++++++ include/linux/net/intel/libie/irq.h | 7 ++ 3 files changed, 101 insertions(+), 82 deletions(-)
diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
index 9377af87125f..c7bdd323ed85 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c@@ -2229,83 +2229,6 @@ int idpf_send_add_queues_msg(struct idpf_adapter *adapter, return err; } -/** - * idpf_create_vectors_info - Save vectors information from firmware - * @info: parsed information is stored here - * @caps: virtchannel capabilities - * @vectors: vector information from firmware to be parsed - * @num_vectors: number of vectors - * - * Returns 0 on success, negative on failure. - */ -static int idpf_create_vectors_info(struct libie_irq_info *info, - const struct virtchnl2_get_capabilities *caps, - const struct virtchnl2_alloc_vectors *vectors, - const u16 num_vectors) -{ - const struct virtchnl2_vector_chunks *chunks = &vectors->vchunks; - int all_vectors = num_vectors + IDPF_MBX_Q_VEC; - struct libie_hw_vector *vector; - int reg_cnt; - - if (le16_to_cpu(vectors->num_vectors) < num_vectors) - return -EINVAL; - - info->vectors = kzalloc_objs(*info->vectors, all_vectors); - if (!info->vectors) - return -ENOMEM; - /* Mailbox irq information are stored in different places. Fill index 0 - * of our vectors info with capabilities and rest with information - * from vector chunks. - */ - vector = &info->vectors[0]; - vector->idx = le16_to_cpu(caps->mailbox_vector_id); - vector->regs.dyn_ctl = le32_to_cpu(caps->mailbox_dyn_ctl); - reg_cnt = IDPF_MBX_Q_VEC; - - for (int i = 0; i < le16_to_cpu(chunks->num_vchunks); i++) { - const struct virtchnl2_vector_chunk *chunk = &chunks->vchunks[i]; - u32 dyn_spacing, itrn_spacing; - struct libie_vec_regs reg_val; - u16 vec_id; - - reg_val.dyn_ctl = le32_to_cpu(chunk->dynctl_reg_start); - reg_val.itrn = le32_to_cpu(chunk->itrn_reg_start); - reg_val.itrn_index_spacing = - le32_to_cpu(chunk->itrn_index_spacing); - - dyn_spacing = le32_to_cpu(chunk->dynctl_reg_spacing); - itrn_spacing = le32_to_cpu(chunk->itrn_reg_spacing); - vec_id = le16_to_cpu(chunk->start_vector_id); - - for (int j = 0; j < le16_to_cpu(chunk->num_vectors); j++) { - if (reg_cnt >= all_vectors) - break; - - vector = &info->vectors[reg_cnt]; - - vector->regs = reg_val; - vector->idx = vec_id; - - reg_val.dyn_ctl += dyn_spacing; - reg_val.itrn += itrn_spacing; - - vec_id += 1; - reg_cnt += 1; - } - } - - if (reg_cnt != all_vectors) { - kfree(info->vectors); - info->vectors = NULL; - return -EINVAL; - } - - info->num = num_vectors + IDPF_MBX_Q_VEC; - - return 0; -} - /** * idpf_send_alloc_vectors_msg - Send virtchnl alloc vectors message * @adapter: Driver specific private structure
@@ -2350,8 +2273,8 @@ int idpf_send_alloc_vectors_msg(struct idpf_adapter *adapter, u16 num_vectors) goto free_rx_buf; } - err = idpf_create_vectors_info(&adapter->irq_info, &adapter->caps, - rcvd_vec, num_vectors); + err = libie_irq_create_info(&adapter->irq_info, &adapter->caps, + rcvd_vec, num_vectors); if (err) /* Unroll getting vectors and leave it in clean state for * the next try.
@@ -2381,9 +2304,7 @@ int idpf_send_dealloc_vectors_msg(struct idpf_adapter *adapter) int buf_size, err; /* dealloc vectors can fail, but irq_info still needs to be cleaned */ - kfree(adapter->irq_info.vectors); - adapter->irq_info.vectors = NULL; - adapter->irq_info.num = 0; + libie_irq_destroy_info(&adapter->irq_info); buf_size = struct_size(&ac->vchunks, vchunks, le16_to_cpu(ac->vchunks.num_vchunks));
diff --git a/drivers/net/ethernet/intel/libie/irq.c b/drivers/net/ethernet/intel/libie/irq.c
index eb47bfd34cdd..b8c144329aac 100644
--- a/drivers/net/ethernet/intel/libie/irq.c
+++ b/drivers/net/ethernet/intel/libie/irq.c@@ -246,6 +246,97 @@ int libie_irq_reserve(struct libie_irq *irq) } EXPORT_SYMBOL_NS_GPL(libie_irq_reserve, "LIBIE_IRQ"); +/** + * libie_irq_create_info - Save vectors information from firmware + * @info: parsed information is stored here + * @caps: virtchannel capabilities + * @vectors: vector information from firmware to be parsed + * @num_vectors: number of vectors + * + * Returns 0 on success, negative on failure. + */ +int libie_irq_create_info(struct libie_irq_info *info, + const struct virtchnl2_get_capabilities *caps, + const struct virtchnl2_alloc_vectors *vectors, + const u16 num_vectors) +{ + const struct virtchnl2_vector_chunks *chunks = &vectors->vchunks; + struct libie_hw_vector *vector; + const int mb_vectors = 1; + int reg_cnt, all_vectors; + + if (le16_to_cpu(vectors->num_vectors) < num_vectors) + return -EINVAL; + + all_vectors = num_vectors + mb_vectors; + info->vectors = kzalloc_objs(*info->vectors, all_vectors); + if (!info->vectors) + return -ENOMEM; + /* Mailbox irq information are stored in different places. Fill index 0 + * of our vectors info with capabilities and rest with information + * from vector chunks. + */ + vector = &info->vectors[0]; + vector->idx = le16_to_cpu(caps->mailbox_vector_id); + vector->regs.dyn_ctl = le32_to_cpu(caps->mailbox_dyn_ctl); + reg_cnt = mb_vectors; + + for (int i = 0; i < le16_to_cpu(chunks->num_vchunks); i++) { + const struct virtchnl2_vector_chunk *chunk = &chunks->vchunks[i]; + u32 dyn_spacing, itrn_spacing; + struct libie_vec_regs reg_val; + u16 vec_id; + + reg_val.dyn_ctl = le32_to_cpu(chunk->dynctl_reg_start); + reg_val.itrn = le32_to_cpu(chunk->itrn_reg_start); + reg_val.itrn_index_spacing = + le32_to_cpu(chunk->itrn_index_spacing); + + dyn_spacing = le32_to_cpu(chunk->dynctl_reg_spacing); + itrn_spacing = le32_to_cpu(chunk->itrn_reg_spacing); + vec_id = le16_to_cpu(chunk->start_vector_id); + + for (int j = 0; j < le16_to_cpu(chunk->num_vectors); j++) { + if (reg_cnt >= all_vectors) + break; + + vector = &info->vectors[reg_cnt]; + + vector->regs = reg_val; + vector->idx = vec_id; + + reg_val.dyn_ctl += dyn_spacing; + reg_val.itrn += itrn_spacing; + + vec_id += 1; + reg_cnt += 1; + } + } + + if (reg_cnt != all_vectors) { + kfree(info->vectors); + info->vectors = NULL; + return -EINVAL; + } + + info->num = all_vectors; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(libie_irq_create_info, "LIBIE_IRQ"); + +/** + * libie_irq_destroy_info - free memory allocated during building irq_info + * @info: libie_irq_info struct to be freed + */ +void libie_irq_destroy_info(struct libie_irq_info *info) +{ + kfree(info->vectors); + info->vectors = NULL; + info->num = 0; +} +EXPORT_SYMBOL_NS_GPL(libie_irq_destroy_info, "LIBIE_IRQ"); + /* Module */ MODULE_DESCRIPTION("Helper functions for managing MSI-X in driver");
diff --git a/include/linux/net/intel/libie/irq.h b/include/linux/net/intel/libie/irq.h
index e219fde575d8..47f3cdcd30b4 100644
--- a/include/linux/net/intel/libie/irq.h
+++ b/include/linux/net/intel/libie/irq.h@@ -5,6 +5,7 @@ #define __LIBIE_IRQ_H #include <linux/pci.h> +#include <linux/net/intel/virtchnl2.h> /* In whole code in libie_irq index means the software 0-based irq index * for driver purpose, virq means the linux irq line number. Index can be used
@@ -105,5 +106,11 @@ struct msi_map libie_irq_alloc(struct libie_irq *irq, enum libie_irq_type type); void libie_irq_free(struct libie_irq *irq, struct msi_map map); int libie_irq_reserve(struct libie_irq *irq); void libie_put_irq(struct libie_irq *irq, unsigned int index); +/* IPU specific functions. */ +void libie_irq_destroy_info(struct libie_irq_info *info); +int libie_irq_create_info(struct libie_irq_info *info, + const struct virtchnl2_get_capabilities *caps, + const struct virtchnl2_alloc_vectors *vectors, + const u16 num_vectors); #endif /* __LIBIE_IRQ_H */
--
2.49.0