}
clib_error_t *
-avf_rxq_init (vlib_main_t * vm, avf_device_t * ad, u16 qid)
+avf_rxq_init (vlib_main_t * vm, avf_device_t * ad, u16 qid, u16 rxq_size)
{
avf_main_t *am = &avf_main;
avf_rxq_t *rxq;
vec_validate_aligned (ad->rxqs, qid, CLIB_CACHE_LINE_BYTES);
rxq = vec_elt_at_index (ad->rxqs, qid);
- rxq->size = AVF_RXQ_SZ;
+ rxq->size = rxq_size;
rxq->next = 0;
rxq->descs = vlib_physmem_alloc_aligned (vm, am->physmem_region, &error,
rxq->size * sizeof (avf_rx_desc_t),
2 * CLIB_CACHE_LINE_BYTES);
- memset (rxq->descs, 0, rxq->size * sizeof (avf_rx_desc_t));
+ memset ((void *) rxq->descs, 0, rxq->size * sizeof (avf_rx_desc_t));
vec_validate_aligned (rxq->bufs, rxq->size, CLIB_CACHE_LINE_BYTES);
rxq->qrx_tail = ad->bar0 + AVF_QRX_TAIL (qid);
if (n_alloc == 0)
return clib_error_return (0, "buffer allocation error");
- rxq->n_bufs = n_alloc;
+ rxq->n_enqueued = n_alloc;
avf_rx_desc_t *d = rxq->descs;
for (i = 0; i < n_alloc; i++)
{
}
clib_error_t *
-avf_txq_init (vlib_main_t * vm, avf_device_t * ad, u16 qid)
+avf_txq_init (vlib_main_t * vm, avf_device_t * ad, u16 qid, u16 txq_size)
{
avf_main_t *am = &avf_main;
avf_txq_t *txq;
vec_validate_aligned (ad->txqs, qid, CLIB_CACHE_LINE_BYTES);
txq = vec_elt_at_index (ad->txqs, qid);
- txq->size = AVF_TXQ_SZ;
+ txq->size = txq_size;
txq->next = 0;
txq->descs = vlib_physmem_alloc_aligned (vm, am->physmem_region, &error,
txq->size * sizeof (avf_tx_desc_t),
pa = avf_dma_addr (vm, ad, ad->atq);
avf_reg_write (ad, AVF_ATQT, 0); /* Tail */
avf_reg_write (ad, AVF_ATQH, 0); /* Head */
- avf_reg_write (ad, AVF_ATQLEN, AVF_MBOX_LEN | (1 << 31)); /* len & ena */
+ avf_reg_write (ad, AVF_ATQLEN, AVF_MBOX_LEN | (1ULL << 31)); /* len & ena */
avf_reg_write (ad, AVF_ATQBAL, (u32) pa); /* Base Address Low */
avf_reg_write (ad, AVF_ATQBAH, (u32) (pa >> 32)); /* Base Address High */
avf_reg_write (ad, AVF_ARQH, 0); /* Head */
avf_reg_write (ad, AVF_ARQT, 0); /* Head */
- avf_reg_write (ad, AVF_ARQLEN, AVF_MBOX_LEN | (1 << 31)); /* len & ena */
+ avf_reg_write (ad, AVF_ARQLEN, AVF_MBOX_LEN | (1ULL << 31)); /* len & ena */
avf_reg_write (ad, AVF_ARQBAL, (u32) pa); /* Base Address Low */
avf_reg_write (ad, AVF_ARQBAH, (u32) (pa >> 32)); /* Base Address High */
avf_reg_write (ad, AVF_ARQT, AVF_MBOX_LEN - 1); /* Tail */
if (d->v_opcode != op)
{
- err = clib_error_return (0, "unexpected message receiver [v_opcode = %u"
- "expected %u]", d->v_opcode, op);
+ err =
+ clib_error_return (0,
+ "unexpected message receiver [v_opcode = %u, "
+ "expected %u, v_retval %d]", d->v_opcode, op,
+ d->v_retval);
goto done;
}
avf_op_get_vf_resources (vlib_main_t * vm, avf_device_t * ad,
virtchnl_vf_resource_t * res)
{
- clib_error_t *err = 0;
- u32 bitmap = (VIRTCHNL_VF_OFFLOAD_L2 | VIRTCHNL_VF_OFFLOAD_RSS_AQ |
- VIRTCHNL_VF_OFFLOAD_RSS_REG | VIRTCHNL_VF_OFFLOAD_WB_ON_ITR |
- VIRTCHNL_VF_OFFLOAD_VLAN | VIRTCHNL_VF_OFFLOAD_RX_POLLING);
+ u32 bitmap = (VIRTCHNL_VF_OFFLOAD_L2 | VIRTCHNL_VF_OFFLOAD_RSS_PF |
+ VIRTCHNL_VF_OFFLOAD_WB_ON_ITR | VIRTCHNL_VF_OFFLOAD_VLAN |
+ VIRTCHNL_VF_OFFLOAD_RX_POLLING);
- err = avf_send_to_pf (vm, ad, VIRTCHNL_OP_GET_VF_RESOURCES, &bitmap,
- sizeof (u32), res, sizeof (virtchnl_vf_resource_t));
+ return avf_send_to_pf (vm, ad, VIRTCHNL_OP_GET_VF_RESOURCES, &bitmap,
+ sizeof (u32), res, sizeof (virtchnl_vf_resource_t));
+}
- if (err)
- return err;
+clib_error_t *
+avf_op_config_rss_lut (vlib_main_t * vm, avf_device_t * ad)
+{
+ int msg_len = sizeof (virtchnl_rss_lut_t) + ad->rss_lut_size - 1;
+ u8 msg[msg_len];
+ virtchnl_rss_lut_t *rl;
- return err;
+ memset (msg, 0, msg_len);
+ rl = (virtchnl_rss_lut_t *) msg;
+ rl->vsi_id = ad->vsi_id;
+ rl->lut_entries = ad->rss_lut_size;
+
+ return avf_send_to_pf (vm, ad, VIRTCHNL_OP_CONFIG_RSS_LUT, msg, msg_len, 0,
+ 0);
}
clib_error_t *
avf_rxq_t *q = vec_elt_at_index (ad->rxqs, i);
rxq->ring_len = q->size;
rxq->databuffer_size = VLIB_BUFFER_DEFAULT_FREE_LIST_BYTES;
- rxq->dma_ring_addr = avf_dma_addr (vm, ad, q->descs);
+ rxq->dma_ring_addr = avf_dma_addr (vm, ad, (void *) q->descs);
avf_reg_write (ad, AVF_QRX_TAIL (i), q->size - 1);
}
{
txq->queue_id = i;
txq->ring_len = q->size;
- txq->dma_ring_addr = avf_dma_addr (vm, ad, q->descs);
+ txq->dma_ring_addr = avf_dma_addr (vm, ad, (void *) q->descs);
}
}
qs.rx_queues = rx;
qs.tx_queues = tx;
avf_rxq_t *rxq = vec_elt_at_index (ad->rxqs, 0);
- avf_reg_write (ad, AVF_QRX_TAIL (0), rxq->n_bufs);
+ avf_reg_write (ad, AVF_QRX_TAIL (0), rxq->n_enqueued);
return avf_send_to_pf (vm, ad, VIRTCHNL_OP_ENABLE_QUEUES, &qs,
sizeof (virtchnl_queue_select_t), 0, 0);
}
}
clib_error_t *
-avf_device_init (vlib_main_t * vm, avf_device_t * ad)
+avf_device_init (vlib_main_t * vm, avf_device_t * ad,
+ avf_create_if_args_t * args)
{
virtchnl_version_info_t ver = { 0 };
virtchnl_vf_resource_t res = { 0 };
if ((error = avf_config_promisc_mode (vm, ad)))
return error;
- if ((error = avf_cmd_rx_ctl_reg_write (vm, ad, 0xc400, 0)))
- return error;
-
- if ((error = avf_cmd_rx_ctl_reg_write (vm, ad, 0xc404, 0)))
+ if ((ad->feature_bitmap & VIRTCHNL_VF_OFFLOAD_RSS_PF) &&
+ (error = avf_op_config_rss_lut (vm, ad)))
return error;
/*
* Init Queues
*/
- if ((error = avf_rxq_init (vm, ad, 0)))
+ if ((error = avf_rxq_init (vm, ad, 0, args->rxq_size)))
return error;
for (i = 0; i < tm->n_vlib_mains; i++)
- if ((error = avf_txq_init (vm, ad, i)))
+ if ((error = avf_txq_init (vm, ad, i, args->txq_size)))
return error;
if ((error = avf_op_config_vsi_queues (vm, ad)))
return error;
avf_irq_0_enable (ad);
- avf_irq_n_enable (ad, 0);
if ((error = avf_op_add_eth_addr (vm, ad, 1, ad->hwaddr)))
return error;
ASSERT (ad->error == 0);
r = avf_get_u32 (ad->bar0, AVF_ARQLEN);
- if ((r & 0xf0000000) != (1 << 31))
+ if ((r & 0xf0000000) != (1ULL << 31))
{
ad->error = clib_error_return (0, "arq not enabled, arqlen = 0x%x", r);
goto error;
}
r = avf_get_u32 (ad->bar0, AVF_ATQLEN);
- if ((r & 0xf0000000) != (1 << 31))
+ if ((r & 0xf0000000) != (1ULL << 31))
{
ad->error = clib_error_return (0, "atq not enabled, atqlen = 0x%x", r);
goto error;
static void
avf_irq_n_handler (vlib_pci_dev_handle_t h, u16 line)
{
+ vnet_main_t *vnm = vnet_get_main ();
vlib_main_t *vm = vlib_get_main ();
avf_main_t *am = &avf_main;
uword pd = vlib_pci_get_private_data (h);
ed->line = line;
}
+ vnet_device_input_set_interrupt_pending (vnm, ad->hw_if_index, 0);
avf_irq_n_enable (ad, 0);
}
vec_foreach_index (i, ad->rxqs)
{
avf_rxq_t *rxq = vec_elt_at_index (ad->rxqs, i);
- vlib_physmem_free (vm, am->physmem_region, rxq->descs);
- if (rxq->n_bufs)
+ vlib_physmem_free (vm, am->physmem_region, (void *) rxq->descs);
+ if (rxq->n_enqueued)
vlib_buffer_free_from_ring (vm, rxq->bufs, rxq->next, rxq->size,
- rxq->n_bufs);
+ rxq->n_enqueued);
vec_free (rxq->bufs);
}
/* *INDENT-ON* */
vec_foreach_index (i, ad->txqs)
{
avf_txq_t *txq = vec_elt_at_index (ad->txqs, i);
- vlib_physmem_free (vm, am->physmem_region, txq->descs);
- if (txq->n_bufs)
+ vlib_physmem_free (vm, am->physmem_region, (void *) txq->descs);
+ if (txq->n_enqueued)
{
- u16 first = (txq->next - txq->n_bufs) & (txq->size -1);
+ u16 first = (txq->next - txq->n_enqueued) & (txq->size -1);
vlib_buffer_free_from_ring (vm, txq->bufs, first, txq->size,
- txq->n_bufs);
+ txq->n_enqueued);
}
vec_free (txq->bufs);
}
vlib_pci_dev_handle_t h;
clib_error_t *error = 0;
+ /* check input args */
+ args->rxq_size = (args->rxq_size == 0) ? AVF_RXQ_SZ : args->rxq_size;
+ args->txq_size = (args->txq_size == 0) ? AVF_TXQ_SZ : args->txq_size;
+
+ if ((args->rxq_size & (args->rxq_size - 1))
+ || (args->txq_size & (args->txq_size - 1)))
+ {
+ args->rv = VNET_API_ERROR_INVALID_VALUE;
+ args->error =
+ clib_error_return (error, "queue size must be a power of two");
+ return;
+ }
+
pool_get (am->devices, ad);
ad->dev_instance = ad - am->devices;
ad->per_interface_next_index = ~0;
ad->flags |= AVF_DEVICE_F_ELOG;
if ((error = vlib_pci_device_open (&args->addr, avf_pci_device_ids, &h)))
- goto error;
+ {
+ pool_put (am->devices, ad);
+ args->rv = VNET_API_ERROR_INVALID_INTERFACE;
+ args->error =
+ clib_error_return (error, "pci-addr %U", format_vlib_pci_addr,
+ &args->addr);
+ return;
+ }
ad->pci_dev_handle = h;
vlib_pci_set_private_data (h, ad->dev_instance);
/* FIXME detect */
ad->flags |= AVF_DEVICE_F_IOVA;
- if ((error = avf_device_init (vm, ad)))
+ if ((error = avf_device_init (vm, ad, args)))
goto error;
/* create interface */
vnet_sw_interface_t *sw = vnet_get_hw_sw_interface (vnm, ad->hw_if_index);
ad->sw_if_index = sw->sw_if_index;
+ vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, ad->hw_if_index);
+ hw->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_INT_MODE;
vnet_hw_interface_set_input_node (vnm, ad->hw_if_index,
avf_input_node.index);