Extend iavf_configure_queues() to support more than 31 queues. Virtchnl opcode used was already generic, but we have just not needed more than one message before. Add helper, iavf_max_vc_entries(), that determines how many entries we could fit into virtchnl message (ending by flex array member). Will be also used on another op later in this series. Signed-off-by: Przemek Kitszel --- .../net/ethernet/intel/iavf/iavf_virtchnl.c | 55 +++++++++++++++---- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c index a2f75bb4a74e..7a97fc76420f 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c @@ -8,6 +8,11 @@ #include "iavf_ptp.h" #include "iavf_prototype.h" +/* how many Flex Array Member entires do fit into VC message of type *ptr */ +#define iavf_max_vc_entries(ptr, flex_member) \ + ((IAVF_MAX_AQ_BUF_SIZE - virtchnl_struct_size(ptr, flex_member, 1)) / \ + sizeof(ptr->flex_member[0]) + 1) + /** * iavf_send_pf_msg * @adapter: adapter structure @@ -366,6 +371,14 @@ int iavf_get_vf_ptp_caps(struct iavf_adapter *adapter) return err; } +static bool iavf_match_vc_op_cb(struct iavf_adapter *adapter, const void *data, + enum virtchnl_ops recv_op) +{ + enum virtchnl_ops wanted_op = (enum virtchnl_ops)data; + + return recv_op == wanted_op; +} + /** * iavf_configure_queues * @adapter: adapter structure @@ -377,8 +390,9 @@ void iavf_configure_queues(struct iavf_adapter *adapter) struct virtchnl_vsi_queue_config_info *vqci; int pairs = adapter->num_active_queues; struct virtchnl_queue_pair_info *vqpi; - u32 i, max_frame; u8 rx_flags = 0; + u32 max_frame; + int max_pairs; size_t len; max_frame = LIBIE_MAX_RX_FRM_LEN(adapter->rx_rings->pp->p.offset); @@ -390,22 +404,22 @@ void iavf_configure_queues(struct iavf_adapter *adapter) adapter->current_op); return; } - adapter->current_op = VIRTCHNL_OP_CONFIG_VSI_QUEUES; - len = virtchnl_struct_size(vqci, qpair, pairs); + + max_pairs = iavf_max_vc_entries(vqci, qpair); + len = virtchnl_struct_size(vqci, qpair, min(pairs, max_pairs)); vqci = kzalloc(len, GFP_KERNEL); if (!vqci) return; if (iavf_ptp_cap_supported(adapter, VIRTCHNL_1588_PTP_CAP_RX_TSTAMP)) rx_flags |= VIRTCHNL_PTP_RX_TSTAMP; vqci->vsi_id = adapter->vsi_res->vsi_id; - vqci->num_queue_pairs = pairs; vqpi = vqci->qpair; - /* Size check is not needed here - HW max is 16 queue pairs, and we - * can fit info for 31 of them into the AQ buffer before it overflows. - */ - for (i = 0; i < pairs; i++) { + + for (int i = 0, in_msg = 0; i < pairs; i++) { + const bool last = i + 1 == pairs; + vqpi->txq.vsi_id = vqci->vsi_id; vqpi->txq.queue_id = i; vqpi->txq.ring_len = adapter->tx_rings[i].count; @@ -423,11 +437,32 @@ void iavf_configure_queues(struct iavf_adapter *adapter) NETIF_F_RXFCS); vqpi->rxq.flags = rx_flags; vqpi++; + in_msg++; + if (last || in_msg == max_pairs) { + int err; + + adapter->current_op = VIRTCHNL_OP_CONFIG_VSI_QUEUES; + vqci->num_queue_pairs = in_msg; + + iavf_send_pf_msg(adapter, + VIRTCHNL_OP_CONFIG_VSI_QUEUES, + (u8 *)vqci, + virtchnl_struct_size(vqci, qpair, in_msg)); + err = iavf_poll_virtchnl_response(adapter, + iavf_match_vc_op_cb, + (void *)VIRTCHNL_OP_CONFIG_VSI_QUEUES, + 1000); + if (err) + dev_warn(&adapter->pdev->dev, + "config queues poll failed, err: %d\n", + err); + + vqpi = vqci->qpair; + in_msg = 0; + } } adapter->aq_required &= ~IAVF_FLAG_AQ_CONFIGURE_QUEUES; - iavf_send_pf_msg(adapter, VIRTCHNL_OP_CONFIG_VSI_QUEUES, - (u8 *)vqci, len); kfree(vqci); } -- 2.39.3