Changeset cbcb34c in mainline
- Timestamp:
- 2018-05-22T19:06:50Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 341df5f
- Parents:
- 1c53d93
- git-author:
- Jakub Jermar <jakub@…> (2018-05-05 14:43:51)
- git-committer:
- Jakub Jermar <jakub@…> (2018-05-22 19:06:50)
- Location:
- uspace
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/nic/virtio-net/virtio-net.c
r1c53d93 rcbcb34c 43 43 #define NAME "virtio-net" 44 44 45 #define VIRTIO_NET_NUM_QUEUES 3 46 47 #define RECVQ1 0 48 #define TRANSQ1 1 49 #define CTRLQ1 2 50 51 #define RECVQ_SIZE 8 52 #define TRANSQ_SIZE 8 53 #define CTRLQ_SIZE 4 54 45 55 static errno_t virtio_net_initialize(ddf_dev_t *dev) 46 56 { … … 61 71 return rc; 62 72 73 virtio_dev_t *vdev = &virtio_net->virtio_dev; 63 74 virtio_pci_common_cfg_t *cfg = virtio_net->virtio_dev.common_cfg; 64 75 virtio_net_cfg_t *netcfg = virtio_net->virtio_dev.device_cfg; … … 86 97 87 98 ddf_msg(LVL_NOTE, "offered features %x", features); 88 features &= (1U << VIRTIO_NET_F_MAC) ;99 features &= (1U << VIRTIO_NET_F_MAC) | (1U << VIRTIO_NET_F_CTRL_VQ); 89 100 90 101 if (!features) { … … 96 107 pio_write_32(&cfg->driver_feature_select, VIRTIO_NET_F_SELECT_PAGE_0); 97 108 pio_write_32(&cfg->driver_feature, features); 109 110 ddf_msg(LVL_NOTE, "accepted features %x", features); 98 111 99 112 /* 5. Set FEATURES_OK */ … … 109 122 110 123 /* 7. Perform device-specific setup */ 124 125 /* 126 * Discover and configure the virtqueues 127 */ 128 uint16_t num_queues = pio_read_16(&cfg->num_queues); 129 if (num_queues != VIRTIO_NET_NUM_QUEUES) { 130 ddf_msg(LVL_NOTE, "Unsupported number of virtqueues: %u", 131 num_queues); 132 goto fail; 133 } 134 135 vdev->queues = calloc(sizeof(virtq_t), num_queues); 136 if (!vdev->queues) { 137 rc = ENOMEM; 138 goto fail; 139 } 140 141 rc = virtio_virtq_setup(vdev, RECVQ1, RECVQ_SIZE, 1500, 142 VIRTQ_DESC_F_WRITE); 143 if (rc != EOK) 144 goto fail; 145 rc = virtio_virtq_setup(vdev, TRANSQ1, TRANSQ_SIZE, 1500, 0); 146 if (rc != EOK) 147 goto fail; 148 rc = virtio_virtq_setup(vdev, CTRLQ1, CTRLQ_SIZE, 512, 0); 149 if (rc != EOK) 150 goto fail; 151 152 /* 153 * Read the MAC address 154 */ 111 155 nic_address_t nic_addr; 112 156 for (unsigned i = 0; i < 6; i++) 113 nic_addr.address[i] = netcfg->mac[i];157 nic_addr.address[i] = pio_read_8(&netcfg->mac[i]); 114 158 rc = nic_report_address(nic_data, &nic_addr); 115 159 if (rc != EOK) -
uspace/drv/nic/virtio-net/virtio-net.h
r1c53d93 rcbcb34c 40 40 /** Device has given MAC address. */ 41 41 #define VIRTIO_NET_F_MAC 5 42 /** Control channel is available */ 43 #define VIRTIO_NET_F_CTRL_VQ 17 42 44 43 45 typedef struct { -
uspace/lib/virtio/virtio-pci.c
r1c53d93 rcbcb34c 32 32 #include "virtio-pci.h" 33 33 34 #include <as.h> 35 #include <align.h> 36 #include <macros.h> 37 34 38 #include <ddf/driver.h> 35 39 #include <ddf/log.h> … … 173 177 174 178 return EOK; 179 } 180 181 errno_t virtio_virtq_setup(virtio_dev_t *vdev, uint16_t num, uint16_t size, 182 size_t buf_size, uint16_t buf_flags) 183 { 184 virtq_t *q = &vdev->queues[num]; 185 virtio_pci_common_cfg_t *cfg = vdev->common_cfg; 186 187 /* Program the queue of our interest */ 188 pio_write_16(&cfg->queue_select, num); 189 190 /* Trim the size of the queue as needed */ 191 size = min(pio_read_16(&cfg->queue_size), size); 192 pio_write_16(&cfg->queue_size, size); 193 ddf_msg(LVL_NOTE, "Virtq %u: %u buffers", num, (unsigned) size); 194 195 /* Allocate array to hold virtual addresses of DMA buffers */ 196 void **buffers = calloc(sizeof(void *), size); 197 if (!buffers) 198 return ENOMEM; 199 200 size_t avail_offset = 0; 201 size_t used_offset = 0; 202 size_t buffers_offset = 0; 203 204 /* 205 * Compute the size of the needed DMA memory and also the offsets of 206 * the individual components 207 */ 208 size_t mem_size = sizeof(virtq_desc_t[size]); 209 mem_size = ALIGN_UP(mem_size, _Alignof(virtq_avail_t)); 210 avail_offset = mem_size; 211 mem_size += sizeof(virtq_avail_t) + sizeof(ioport16_t[size]) + 212 sizeof(ioport16_t); 213 mem_size = ALIGN_UP(mem_size, _Alignof(virtq_used_t)); 214 used_offset = mem_size; 215 mem_size += sizeof(virtq_used_t) + sizeof(virtq_used_elem_t[size]) + 216 sizeof(ioport16_t); 217 buffers_offset = mem_size; 218 mem_size += size * buf_size; 219 220 /* 221 * Allocate DMA memory for the virtqueues and the buffers 222 */ 223 q->virt = AS_AREA_ANY; 224 errno_t rc = dmamem_map_anonymous(mem_size, DMAMEM_4GiB, 225 AS_AREA_READ | AS_AREA_WRITE, 0, &q->phys, &q->virt); 226 if (rc != EOK) { 227 free(buffers); 228 q->virt = NULL; 229 return rc; 230 } 231 232 q->size = mem_size; 233 q->queue_size = size; 234 q->desc = q->virt; 235 q->avail = q->virt + avail_offset; 236 q->used = q->virt + used_offset; 237 q->buffers = buffers; 238 239 memset(q->virt, 0, q->size); 240 241 /* 242 * Initialize the descriptor table and the buffers array 243 */ 244 for (unsigned i = 0; i < size; i++) { 245 q->desc[i].addr = q->phys + buffers_offset + i * buf_size; 246 q->desc[i].len = buf_size; 247 q->desc[i].flags = buf_flags; 248 249 q->buffers[i] = q->virt + buffers_offset + i * buf_size; 250 } 251 252 /* 253 * Write the configured addresses to device's common config 254 */ 255 pio_write_64(&cfg->queue_desc, q->phys); 256 pio_write_64(&cfg->queue_avail, q->phys + avail_offset); 257 pio_write_64(&cfg->queue_used, q->phys + used_offset); 258 259 ddf_msg(LVL_NOTE, "DMA memory for virtq %d: virt=%p, phys=%p, size=%zu", 260 num, q->virt, (void *) q->phys, q->size); 261 262 return rc; 263 } 264 265 void virtio_virtq_teardown(virtio_dev_t *vdev, uint16_t num) 266 { 267 virtq_t *q = &vdev->queues[num]; 268 if (q->size) 269 dmamem_unmap_anonymous(q->virt); 270 if (q->buffers) 271 free(q->buffers); 175 272 } 176 273 … … 279 376 errno_t virtio_pci_dev_cleanup(virtio_dev_t *vdev) 280 377 { 378 if (vdev->queues) { 379 for (unsigned i = 0; 380 i < pio_read_16(&vdev->common_cfg->num_queues); i++) 381 virtio_virtq_teardown(vdev, i); 382 free(vdev->queues); 383 } 281 384 return disable_resources(vdev); 282 385 } -
uspace/lib/virtio/virtio-pci.h
r1c53d93 rcbcb34c 124 124 } virtq_used_t; 125 125 126 typedef struct { 127 void *virt; 128 uintptr_t phys; 129 size_t size; 130 131 /** 132 * Size of the queue which determines the number of descriptors and 133 * DMA buffers. 134 */ 135 size_t queue_size; 136 137 /** Virtual address of queue size virtq descriptors */ 138 virtq_desc_t *desc; 139 /** Virtual address of the available ring */ 140 virtq_avail_t *avail; 141 /** Virtual address of the used ring */ 142 virtq_used_t *used; 143 144 /** 145 * Queue-size-sized array of virtual addresses of the atcual DMA 146 * buffers. 147 */ 148 void **buffers; 149 } virtq_t; 150 126 151 /** VIRTIO-device specific data associated with the NIC framework nic_t */ 127 152 typedef struct { … … 145 170 /** Device-specific configuration */ 146 171 void *device_cfg; 172 173 /** Virtqueues */ 174 virtq_t *queues; 147 175 } virtio_dev_t; 176 177 extern errno_t virtio_virtq_setup(virtio_dev_t *, uint16_t, uint16_t, size_t, 178 uint16_t); 179 extern void virtio_virtq_teardown(virtio_dev_t *, uint16_t); 148 180 149 181 extern errno_t virtio_pci_dev_initialize(ddf_dev_t *, virtio_dev_t *);
Note:
See TracChangeset
for help on using the changeset viewer.