LCOV - code coverage report
Current view: top level - vnet/devices/virtio - virtio_pci_legacy.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 0 159 0.0 %
Date: 2023-07-05 22:20:52 Functions: 0 23 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2018 Cisco and/or its affiliates.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this file except in compliance with the License.
       5             :  * You may obtain a copy of the License at:
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       9             :  * Unless required by applicable law or agreed to in writing, software
      10             :  * distributed under the License is distributed on an "AS IS" BASIS,
      11             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             :  * See the License for the specific language governing permissions and
      13             :  * limitations under the License.
      14             :  */
      15             : 
      16             : #include <vlib/vlib.h>
      17             : #include <vlib/pci/pci.h>
      18             : #include <vnet/ethernet/ethernet.h>
      19             : #include <vnet/ip/ip4_packet.h>
      20             : #include <vnet/ip/ip6_packet.h>
      21             : #include <vnet/devices/virtio/virtio.h>
      22             : #include <vnet/devices/virtio/virtio_pci_legacy.h>
      23             : #include <vnet/devices/virtio/pci.h>
      24             : 
      25             : #define PCI_CONFIG_SIZE(vif) ((vif->msix_enabled == VIRTIO_MSIX_ENABLED) ? \
      26             :   24 : 20)
      27             : 
      28             : static void
      29           0 : virtio_pci_legacy_read_config (vlib_main_t * vm, virtio_if_t * vif, void *dst,
      30             :                                int len, u32 addr)
      31             : {
      32           0 :   u32 size = 0;
      33           0 :   vlib_pci_dev_handle_t h = vif->pci_dev_handle;
      34             : 
      35           0 :   while (len > 0)
      36             :     {
      37           0 :       if (len >= 4)
      38             :         {
      39           0 :           size = 4;
      40           0 :           vlib_pci_read_io_u32 (vm, h, PCI_CONFIG_SIZE (vif) + addr, dst);
      41             :         }
      42           0 :       else if (len >= 2)
      43             :         {
      44           0 :           size = 2;
      45           0 :           vlib_pci_read_io_u16 (vm, h, PCI_CONFIG_SIZE (vif) + addr, dst);
      46             :         }
      47             :       else
      48             :         {
      49           0 :           size = 1;
      50           0 :           vlib_pci_read_io_u8 (vm, h, PCI_CONFIG_SIZE (vif) + addr, dst);
      51             :         }
      52           0 :       dst = (u8 *) dst + size;
      53           0 :       addr += size;
      54           0 :       len -= size;
      55             :     }
      56           0 : }
      57             : 
      58             : static void
      59           0 : virtio_pci_legacy_write_config (vlib_main_t * vm, virtio_if_t * vif,
      60             :                                 void *src, int len, u32 addr)
      61             : {
      62           0 :   u32 size = 0;
      63           0 :   vlib_pci_dev_handle_t h = vif->pci_dev_handle;
      64             : 
      65           0 :   while (len > 0)
      66             :     {
      67           0 :       if (len >= 4)
      68             :         {
      69           0 :           size = 4;
      70           0 :           vlib_pci_write_io_u32 (vm, h, PCI_CONFIG_SIZE (vif) + addr, src);
      71             :         }
      72           0 :       else if (len >= 2)
      73             :         {
      74           0 :           size = 2;
      75           0 :           vlib_pci_write_io_u16 (vm, h, PCI_CONFIG_SIZE (vif) + addr, src);
      76             :         }
      77             :       else
      78             :         {
      79           0 :           size = 1;
      80           0 :           vlib_pci_write_io_u8 (vm, h, PCI_CONFIG_SIZE (vif) + addr, src);
      81             :         }
      82           0 :       src = (u8 *) src + size;
      83           0 :       addr += size;
      84           0 :       len -= size;
      85             :     }
      86           0 : }
      87             : 
      88             : static u64
      89           0 : virtio_pci_legacy_get_host_features (vlib_main_t * vm, virtio_if_t * vif)
      90             : {
      91             :   u32 host_features;
      92           0 :   vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_HOST_FEATURES,
      93             :                         &host_features);
      94           0 :   return host_features;
      95             : }
      96             : 
      97             : static u64
      98           0 : virtio_pci_legacy_get_guest_features (vlib_main_t * vm, virtio_if_t * vif)
      99             : {
     100           0 :   u32 guest_features = 0;
     101           0 :   vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_GUEST_FEATURES,
     102             :                         &guest_features);
     103           0 :   vif->features = guest_features;
     104           0 :   return guest_features;
     105             : }
     106             : 
     107             : static void
     108           0 : virtio_pci_legacy_set_guest_features (vlib_main_t * vm, virtio_if_t * vif,
     109             :                                       u64 guest_features)
     110             : {
     111           0 :   if ((guest_features >> 32) != 0)
     112             :     {
     113           0 :       clib_warning ("only 32 bit features are allowed for legacy virtio!");
     114             :     }
     115           0 :   u32 features = 0;
     116           0 :   u32 gf = (u32) guest_features;
     117             : 
     118           0 :   vlib_pci_write_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_GUEST_FEATURES,
     119             :                          &gf);
     120           0 :   vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_GUEST_FEATURES,
     121             :                         &features);
     122           0 :   if (features != (u32) guest_features)
     123             :     {
     124           0 :       clib_warning ("legacy set guest features failed!");
     125             :     }
     126           0 : }
     127             : 
     128             : static u8
     129           0 : virtio_pci_legacy_get_status (vlib_main_t * vm, virtio_if_t * vif)
     130             : {
     131           0 :   u8 status = 0;
     132           0 :   vlib_pci_read_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_STATUS, &status);
     133           0 :   return status;
     134             : }
     135             : 
     136             : static void
     137           0 : virtio_pci_legacy_set_status (vlib_main_t * vm, virtio_if_t * vif, u8 status)
     138             : {
     139           0 :   if (status != VIRTIO_CONFIG_STATUS_RESET)
     140           0 :     status |= virtio_pci_legacy_get_status (vm, vif);
     141           0 :   vlib_pci_write_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_STATUS, &status);
     142           0 : }
     143             : 
     144             : static u8
     145           0 : virtio_pci_legacy_reset (vlib_main_t * vm, virtio_if_t * vif)
     146             : {
     147           0 :   virtio_pci_legacy_set_status (vm, vif, VIRTIO_CONFIG_STATUS_RESET);
     148           0 :   return virtio_pci_legacy_get_status (vm, vif);
     149             : }
     150             : 
     151             : static u8
     152           0 : virtio_pci_legacy_get_isr (vlib_main_t * vm, virtio_if_t * vif)
     153             : {
     154           0 :   u8 isr = 0;
     155           0 :   vlib_pci_read_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_ISR, &isr);
     156           0 :   return isr;
     157             : }
     158             : 
     159             : static u16
     160           0 : virtio_pci_legacy_get_queue_num (vlib_main_t * vm, virtio_if_t * vif,
     161             :                                  u16 queue_id)
     162             : {
     163           0 :   u16 queue_num = 0;
     164           0 :   vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL,
     165             :                          &queue_id);
     166           0 :   vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NUM,
     167             :                         &queue_num);
     168           0 :   return queue_num;
     169             : }
     170             : 
     171             : static void
     172           0 : virtio_pci_legacy_set_queue_num (vlib_main_t * vm, virtio_if_t * vif,
     173             :                                  u16 queue_id, u16 queue_size)
     174             : {
     175             :   /* do nothing */
     176           0 : }
     177             : 
     178             : static u8
     179           0 : virtio_pci_legacy_setup_queue (vlib_main_t *vm, virtio_if_t *vif, u16 queue_id,
     180             :                                vnet_virtio_vring_t *vring)
     181             : {
     182           0 :   u64 addr =
     183           0 :     vlib_physmem_get_pa (vm, vring->desc) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT;
     184           0 :   u32 addr2 = 0, a = (u32) addr;
     185           0 :   vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL,
     186             :                          &queue_id);
     187           0 :   vlib_pci_write_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN, &a);
     188           0 :   vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN,
     189             :                         &addr2);
     190           0 :   if (addr == addr2)
     191           0 :     return 0;
     192             : 
     193           0 :   clib_warning ("legacy queue setup failed!");
     194           0 :   return 1;
     195             : }
     196             : 
     197             : static void
     198           0 : virtio_pci_legacy_del_queue (vlib_main_t * vm, virtio_if_t * vif,
     199             :                              u16 queue_id)
     200             : {
     201           0 :   u32 src = 0;
     202           0 :   vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL,
     203             :                          &queue_id);
     204           0 :   vlib_pci_write_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN, &src);
     205           0 : }
     206             : 
     207             : static u16
     208           0 : virtio_pci_legacy_get_queue_notify_off (vlib_main_t * vm, virtio_if_t * vif,
     209             :                                         u16 queue_id)
     210             : {
     211           0 :   return 0;
     212             : }
     213             : 
     214             : inline void
     215           0 : virtio_pci_legacy_notify_queue (vlib_main_t * vm, virtio_if_t * vif,
     216             :                                 u16 queue_id, u16 queue_notify_off)
     217             : {
     218           0 :   vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NOTIFY,
     219             :                          &queue_id);
     220           0 : }
     221             : 
     222             : /* Enable one vector (0) for Link State Intrerrupt */
     223             : static u16
     224           0 : virtio_pci_legacy_set_config_irq (vlib_main_t * vm, virtio_if_t * vif,
     225             :                                   u16 vec)
     226             : {
     227           0 :   vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_CONFIG_VECTOR,
     228             :                          &vec);
     229           0 :   vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_CONFIG_VECTOR,
     230             :                         &vec);
     231           0 :   return vec;
     232             : }
     233             : 
     234             : static u16
     235           0 : virtio_pci_legacy_set_queue_irq (vlib_main_t * vm, virtio_if_t * vif, u16 vec,
     236             :                                  u16 queue_id)
     237             : {
     238           0 :   vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL,
     239             :                          &queue_id);
     240           0 :   vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_QUEUE_VECTOR,
     241             :                          &vec);
     242           0 :   vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_QUEUE_VECTOR,
     243             :                         &vec);
     244           0 :   return vec;
     245             : }
     246             : 
     247             : static void
     248           0 : virtio_pci_legacy_get_mac (vlib_main_t * vm, virtio_if_t * vif)
     249             : {
     250           0 :   virtio_pci_legacy_read_config (vm, vif, vif->mac_addr,
     251             :                                  sizeof (vif->mac_addr), 0);
     252           0 : }
     253             : 
     254             : static void
     255           0 : virtio_pci_legacy_set_mac (vlib_main_t * vm, virtio_if_t * vif)
     256             : {
     257           0 :   virtio_pci_legacy_write_config (vm, vif, vif->mac_addr,
     258             :                                   sizeof (vif->mac_addr), 0);
     259           0 : }
     260             : 
     261             : static u16
     262           0 : virtio_pci_legacy_get_device_status (vlib_main_t * vm, virtio_if_t * vif)
     263             : {
     264           0 :   u16 status = 0;
     265           0 :   virtio_pci_legacy_read_config (vm, vif, &status,
     266             :                                  sizeof (status),
     267             :                                  STRUCT_OFFSET_OF
     268             :                                  (virtio_net_config_t, status));
     269           0 :   return status;
     270             : }
     271             : 
     272             : static u16
     273           0 : virtio_pci_legacy_get_max_queue_pairs (vlib_main_t * vm, virtio_if_t * vif)
     274             : {
     275             :   virtio_net_config_t config;
     276           0 :   virtio_pci_legacy_read_config (vm, vif, &config.max_virtqueue_pairs,
     277             :                                  sizeof (config.max_virtqueue_pairs),
     278             :                                  STRUCT_OFFSET_OF
     279             :                                  (virtio_net_config_t, max_virtqueue_pairs));
     280           0 :   return config.max_virtqueue_pairs;
     281             : }
     282             : 
     283             : static u16
     284           0 : virtio_pci_legacy_get_mtu (vlib_main_t * vm, virtio_if_t * vif)
     285             : {
     286             :   virtio_net_config_t config;
     287           0 :   virtio_pci_legacy_read_config (vm, vif, &config.mtu,
     288             :                                  sizeof (config.mtu),
     289             :                                  STRUCT_OFFSET_OF (virtio_net_config_t, mtu));
     290           0 :   return config.mtu;
     291             : }
     292             : 
     293             : 
     294             : static void
     295           0 : virtio_pci_legacy_device_debug_config_space (vlib_main_t * vm,
     296             :                                              virtio_if_t * vif)
     297             : {
     298             :   u32 data_u32;
     299             :   u16 data_u16;
     300             :   u8 data_u8;
     301           0 :   vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_HOST_FEATURES,
     302             :                         &data_u32);
     303           0 :   vlib_cli_output (vm, "remote features 0x%lx", data_u32);
     304           0 :   vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_GUEST_FEATURES,
     305             :                         &data_u32);
     306           0 :   vlib_cli_output (vm, "guest features 0x%lx", data_u32);
     307           0 :   vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN,
     308             :                         &data_u32);
     309           0 :   vlib_cli_output (vm, "queue address 0x%lx", data_u32);
     310           0 :   vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NUM,
     311             :                         &data_u16);
     312           0 :   vlib_cli_output (vm, "queue size 0x%x", data_u16);
     313           0 :   vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL,
     314             :                         &data_u16);
     315           0 :   vlib_cli_output (vm, "queue select 0x%x", data_u16);
     316           0 :   vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NOTIFY,
     317             :                         &data_u16);
     318           0 :   vlib_cli_output (vm, "queue notify 0x%x", data_u16);
     319           0 :   vlib_pci_read_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_STATUS, &data_u8);
     320           0 :   vlib_cli_output (vm, "status 0x%x", data_u8);
     321           0 :   vlib_pci_read_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_ISR, &data_u8);
     322           0 :   vlib_cli_output (vm, "isr 0x%x", data_u8);
     323             : 
     324           0 :   if (vif->msix_enabled == VIRTIO_MSIX_ENABLED)
     325             :     {
     326           0 :       vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_CONFIG_VECTOR,
     327             :                             &data_u16);
     328           0 :       vlib_cli_output (vm, "config vector 0x%x", data_u16);
     329           0 :       u16 queue_id = 0;
     330           0 :       vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL,
     331             :                              &queue_id);
     332           0 :       vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_QUEUE_VECTOR,
     333             :                             &data_u16);
     334           0 :       vlib_cli_output (vm, "queue vector for queue (0) 0x%x", data_u16);
     335             :     }
     336             : 
     337             :   u8 mac[6];
     338           0 :   virtio_pci_legacy_read_config (vm, vif, mac, sizeof (mac), 0);
     339           0 :   vlib_cli_output (vm, "mac %U", format_ethernet_address, mac);
     340           0 :   virtio_pci_legacy_read_config (vm, vif, &data_u16, sizeof (u16),  /* offset to status */
     341             :                                  6);
     342           0 :   vlib_cli_output (vm, "link up/down status 0x%x", data_u16);
     343           0 :   virtio_pci_legacy_read_config (vm, vif, &data_u16, sizeof (u16),
     344             :                                  /* offset to max_virtqueue */ 8);
     345           0 :   vlib_cli_output (vm, "num of virtqueue 0x%x", data_u16);
     346           0 :   virtio_pci_legacy_read_config (vm, vif, &data_u16, sizeof (u16),  /* offset to mtu */
     347             :                                  10);
     348           0 :   vlib_cli_output (vm, "mtu 0x%x", data_u16);
     349             : 
     350           0 :   u32 i = PCI_CONFIG_SIZE (vif) + 12, a = 4;
     351           0 :   i += a;
     352           0 :   i &= ~a;
     353           0 :   for (; i < 64; i += 4)
     354             :     {
     355           0 :       u32 data = 0;
     356           0 :       vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, i, &data);
     357           0 :       vlib_cli_output (vm, "0x%lx", data);
     358             :     }
     359           0 : }
     360             : 
     361             : const virtio_pci_func_t virtio_pci_legacy_func = {
     362             :   .read_config = virtio_pci_legacy_read_config,
     363             :   .write_config = virtio_pci_legacy_write_config,
     364             :   .get_device_features = virtio_pci_legacy_get_host_features,
     365             :   .get_driver_features = virtio_pci_legacy_get_guest_features,
     366             :   .set_driver_features = virtio_pci_legacy_set_guest_features,
     367             :   .get_status = virtio_pci_legacy_get_status,
     368             :   .set_status = virtio_pci_legacy_set_status,
     369             :   .device_reset = virtio_pci_legacy_reset,
     370             :   .get_isr = virtio_pci_legacy_get_isr,
     371             :   .get_queue_size = virtio_pci_legacy_get_queue_num,
     372             :   .set_queue_size = virtio_pci_legacy_set_queue_num,
     373             :   .setup_queue = virtio_pci_legacy_setup_queue,
     374             :   .del_queue = virtio_pci_legacy_del_queue,
     375             :   .get_queue_notify_off = virtio_pci_legacy_get_queue_notify_off,
     376             :   .notify_queue = virtio_pci_legacy_notify_queue,
     377             :   .set_config_irq = virtio_pci_legacy_set_config_irq,
     378             :   .set_queue_irq = virtio_pci_legacy_set_queue_irq,
     379             :   .get_mac = virtio_pci_legacy_get_mac,
     380             :   .set_mac = virtio_pci_legacy_set_mac,
     381             :   .get_device_status = virtio_pci_legacy_get_device_status,
     382             :   .get_max_queue_pairs = virtio_pci_legacy_get_max_queue_pairs,
     383             :   .get_mtu = virtio_pci_legacy_get_mtu,
     384             :   .device_debug_config_space = virtio_pci_legacy_device_debug_config_space,
     385             : };
     386             : 
     387             : /*
     388             :  * fd.io coding-style-patch-verification: ON
     389             :  *
     390             :  * Local Variables:
     391             :  * eval: (c-set-style "gnu")
     392             :  * End:
     393             :  */

Generated by: LCOV version 1.14