#define IAVF_FRAME_SIZE_MAX 9728
#define IAVF_QUEUE_BASE_ADDR_UNIT 128
-#define IAVF_MAX_NUM_QUEUES 16
+#define IAVF_MAX_NUM_QUEUES_DFLT 16
+#define IAVF_MAX_NUM_QUEUES_LV 256
#define IAVF_NUM_MACADDR_MAX 64
uint8_t *rss_key;
uint16_t nb_msix; /* number of MSI-X interrupts on Rx */
uint16_t msix_base; /* msix vector base from */
+ uint16_t max_rss_qregion; /* max RSS queue region supported by PF */
/* queue bitmask for each vector */
uint16_t rxq_map[IAVF_MAX_MSIX_VECTORS];
struct iavf_flow_list flow_list;
struct iavf_parser_list dist_parser_list;
struct iavf_fdir_info fdir; /* flow director info */
+ /* indicate large VF support enabled or not */
+ bool lv_enabled;
};
#define IAVF_MAX_PKT_TYPE 1024
struct rte_ether_addr *mc_addrs,
uint32_t mc_addrs_num, bool add);
int iavf_request_queues(struct iavf_adapter *adapter, uint16_t num);
+int iavf_get_max_rss_queue_region(struct iavf_adapter *adapter);
#endif /* _IAVF_ETHDEV_H_ */
rss_conf = &adapter->eth_dev->data->dev_conf.rx_adv_conf.rss_conf;
nb_q = RTE_MIN(adapter->eth_dev->data->nb_rx_queues,
- IAVF_MAX_NUM_QUEUES);
+ vf->max_rss_qregion);
if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF)) {
PMD_DRV_LOG(DEBUG, "RSS is not supported");
return 0;
}
+static int
+iavf_queues_req_reset(struct rte_eth_dev *dev, uint16_t num)
+{
+ struct iavf_adapter *ad =
+ IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
+ int ret;
+
+ ret = iavf_request_queues(ad, num);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "request queues from PF failed");
+ return ret;
+ }
+ PMD_DRV_LOG(INFO, "change queue pairs from %u to %u",
+ vf->vsi_res->num_queue_pairs, num);
+
+ ret = iavf_dev_reset(dev);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "vf reset failed");
+ return ret;
+ }
+
+ return 0;
+}
+
static int
iavf_dev_configure(struct rte_eth_dev *dev)
{
IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
+ uint16_t num_queue_pairs = RTE_MAX(dev->data->nb_rx_queues,
+ dev->data->nb_tx_queues);
+ int ret;
ad->rx_bulk_alloc_allowed = true;
/* Initialize to TRUE. If any of Rx queues doesn't meet the
if (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)
dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_RSS_HASH;
+ /* Large VF setting */
+ if (num_queue_pairs > IAVF_MAX_NUM_QUEUES_DFLT) {
+ if (!(vf->vf_res->vf_cap_flags &
+ VIRTCHNL_VF_LARGE_NUM_QPAIRS)) {
+ PMD_DRV_LOG(ERR, "large VF is not supported");
+ return -1;
+ }
+
+ if (num_queue_pairs > IAVF_MAX_NUM_QUEUES_LV) {
+ PMD_DRV_LOG(ERR, "queue pairs number cannot be larger than %u",
+ IAVF_MAX_NUM_QUEUES_LV);
+ return -1;
+ }
+
+ ret = iavf_queues_req_reset(dev, num_queue_pairs);
+ if (ret)
+ return ret;
+
+ ret = iavf_get_max_rss_queue_region(ad);
+ if (ret) {
+ PMD_INIT_LOG(ERR, "get max rss queue region failed");
+ return ret;
+ }
+
+ vf->lv_enabled = true;
+ } else {
+ /* Check if large VF is already enabled. If so, disable and
+ * release redundant queue resource.
+ */
+ if (vf->lv_enabled) {
+ ret = iavf_queues_req_reset(dev, num_queue_pairs);
+ if (ret)
+ return ret;
+
+ vf->lv_enabled = false;
+ }
+ /* if large VF is not required, use default rss queue region */
+ vf->max_rss_qregion = IAVF_MAX_NUM_QUEUES_DFLT;
+ }
+
/* Vlan stripping setting */
if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) {
if (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
{
struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
- dev_info->max_rx_queues = vf->vsi_res->num_queue_pairs;
- dev_info->max_tx_queues = vf->vsi_res->num_queue_pairs;
+ dev_info->max_rx_queues = IAVF_MAX_NUM_QUEUES_LV;
+ dev_info->max_tx_queues = IAVF_MAX_NUM_QUEUES_LV;
dev_info->min_rx_bufsize = IAVF_BUF_SIZE_MIN;
dev_info->max_rx_pktlen = IAVF_FRAME_SIZE_MAX;
dev_info->max_mtu = dev_info->max_rx_pktlen - IAVF_ETH_OVERHEAD;
VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC |
VIRTCHNL_VF_OFFLOAD_FDIR_PF |
VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF |
- VIRTCHNL_VF_OFFLOAD_REQ_QUEUES;
+ VIRTCHNL_VF_OFFLOAD_REQ_QUEUES |
+ VIRTCHNL_VF_LARGE_NUM_QPAIRS;
args.in_args = (uint8_t *)∩︀
args.in_args_size = sizeof(caps);
return -1;
}
+
+int
+iavf_get_max_rss_queue_region(struct iavf_adapter *adapter)
+{
+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
+ struct iavf_cmd_info args;
+ uint16_t qregion_width;
+ int err;
+
+ args.ops = VIRTCHNL_OP_GET_MAX_RSS_QREGION;
+ args.in_args = NULL;
+ args.in_args_size = 0;
+ args.out_buffer = vf->aq_resp;
+ args.out_size = IAVF_AQ_BUF_SZ;
+
+ err = iavf_execute_vf_cmd(adapter, &args);
+ if (err) {
+ PMD_DRV_LOG(ERR, "Failed to execute command of VIRTCHNL_OP_GET_MAX_RSS_QREGION");
+ return err;
+ }
+
+ qregion_width =
+ ((struct virtchnl_max_rss_qregion *)args.out_buffer)->qregion_width;
+
+ vf->max_rss_qregion = (uint16_t)(1 << qregion_width);
+
+ return 0;
+}