avf: api fix
[vpp.git] / src / plugins / avf / device.c
index c73cf1e..0e9a8bf 100644 (file)
@@ -213,7 +213,7 @@ avf_cmd_rx_ctl_reg_write (vlib_main_t * vm, avf_device_t * ad, u32 reg,
 }
 
 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;
@@ -222,12 +222,12 @@ avf_rxq_init (vlib_main_t * vm, avf_device_t * ad, u16 qid)
 
   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);
 
@@ -236,7 +236,7 @@ avf_rxq_init (vlib_main_t * vm, avf_device_t * ad, u16 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++)
     {
@@ -254,7 +254,7 @@ avf_rxq_init (vlib_main_t * vm, avf_device_t * ad, u16 qid)
 }
 
 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;
@@ -272,7 +272,7 @@ avf_txq_init (vlib_main_t * vm, avf_device_t * ad, u16 qid)
 
   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),
@@ -323,7 +323,7 @@ avf_adminq_init (vlib_main_t * vm, avf_device_t * ad)
   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 */
 
@@ -338,7 +338,7 @@ avf_adminq_init (vlib_main_t * vm, avf_device_t * ad)
 
   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 */
@@ -398,8 +398,11 @@ retry:
 
   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;
     }
 
@@ -549,7 +552,7 @@ avf_op_config_vsi_queues (vlib_main_t * vm, avf_device_t * ad)
          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);
        }
 
@@ -559,7 +562,7 @@ avf_op_config_vsi_queues (vlib_main_t * vm, avf_device_t * ad)
        {
          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);
        }
     }
 
@@ -615,7 +618,7 @@ avf_op_enable_queues (vlib_main_t * vm, avf_device_t * ad, u32 rx, u32 tx)
   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);
 }
@@ -658,7 +661,8 @@ retry:
 }
 
 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 };
@@ -719,11 +723,11 @@ avf_device_init (vlib_main_t * vm, avf_device_t * ad)
   /*
    * 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)))
@@ -733,7 +737,6 @@ avf_device_init (vlib_main_t * vm, avf_device_t * 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;
@@ -765,14 +768,14 @@ avf_process_one_device (vlib_main_t * vm, avf_device_t * ad, int is_irq)
   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;
@@ -975,6 +978,7 @@ avf_irq_0_handler (vlib_pci_dev_handle_t h, u16 line)
 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);
@@ -1000,6 +1004,7 @@ avf_irq_n_handler (vlib_pci_dev_handle_t h, u16 line)
       ed->line = line;
     }
 
+  vnet_device_input_set_interrupt_pending (vnm, ad->hw_if_index, 0);
   avf_irq_n_enable (ad, 0);
 }
 
@@ -1028,10 +1033,10 @@ avf_delete_if (vlib_main_t * vm, avf_device_t * ad)
   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* */
@@ -1041,12 +1046,12 @@ avf_delete_if (vlib_main_t * vm, avf_device_t * ad)
   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);
     }
@@ -1067,6 +1072,19 @@ avf_create_if (vlib_main_t * vm, avf_create_if_args_t * args)
   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;
@@ -1075,7 +1093,14 @@ avf_create_if (vlib_main_t * vm, avf_create_if_args_t * args)
     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);
@@ -1134,7 +1159,7 @@ avf_create_if (vlib_main_t * vm, avf_create_if_args_t * args)
   /* 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 */
@@ -1146,8 +1171,10 @@ avf_create_if (vlib_main_t * vm, avf_create_if_args_t * args)
     goto error;
 
   vnet_sw_interface_t *sw = vnet_get_hw_sw_interface (vnm, ad->hw_if_index);
-  ad->sw_if_index = sw->sw_if_index;
+  args->sw_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);