Changes in uspace/drv/nic/virtio-net/virtio-net.c [1e472ee:417aaafb] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/nic/virtio-net/virtio-net.c
r1e472ee r417aaafb 69 69 .driver_ops = &virtio_net_driver_ops 70 70 }; 71 72 /** Allocate DMA buffers 73 * 74 * @param buffers[in] Number of buffers to allocate. 75 * @param size[in] Size of each buffer. 76 * @param write[in] True if the buffers are writable by the driver, false 77 * otherwise. 78 * @param buf[out] Output array holding virtual addresses of the allocated 79 * buffers. 80 * @param buf_p[out] Output array holding physical addresses of the allocated 81 * buffers. 82 * 83 * The buffers can be deallocated by virtio_net_teardown_bufs(). 84 * 85 * @return EOK on success or error code. 86 */ 87 static errno_t virtio_net_setup_bufs(unsigned int buffers, size_t size, 88 bool write, void *buf[], uintptr_t buf_p[]) 89 { 90 /* 91 * Allocate all buffers at once in one large chunk. 92 */ 93 void *virt = AS_AREA_ANY; 94 uintptr_t phys; 95 errno_t rc = dmamem_map_anonymous(buffers * size, 0, 96 write ? AS_AREA_WRITE : AS_AREA_READ, 0, &phys, &virt); 97 if (rc != EOK) 98 return rc; 99 100 ddf_msg(LVL_NOTE, "DMA buffers: %p-%p", virt, virt + buffers * size); 101 102 /* 103 * Calculate addresses of the individual buffers for easy access. 104 */ 105 for (unsigned i = 0; i < buffers; i++) { 106 buf[i] = virt + i * size; 107 buf_p[i] = phys + i * size; 108 } 109 110 return EOK; 111 } 112 113 /** Deallocate DMA buffers 114 * 115 * @param buf[in] Array holding the virtual addresses of the DMA buffers 116 * previously allocated by virtio_net_setup_bufs(). 117 */ 118 static void virtio_net_teardown_bufs(void *buf[]) 119 { 120 if (buf[0]) { 121 dmamem_unmap_anonymous(buf[0]); 122 buf[0] = NULL; 123 } 124 } 125 126 /** Create free descriptor list from the unused VIRTIO descriptors 127 * 128 * @param vdev[in] VIRTIO device for which the free list will be created. 129 * @param num[in] Index of the virtqueue for which the free list will be 130 * created. 131 * @param size[in] Number of descriptors on the free list. The free list will 132 * contain descriptors starting from 0 to \a size - 1. 133 * @param head[out] Variable that will hold the VIRTIO descriptor at the head 134 * of the free list. 135 */ 136 static void virtio_net_create_desc_free_list(virtio_dev_t *vdev, uint16_t num, 137 uint16_t size, uint16_t *head) 138 { 139 for (unsigned i = 0; i < size; i++) { 140 virtio_virtq_desc_set(vdev, num, i, 0, 0, 141 VIRTQ_DESC_F_NEXT, (i + 1 == size) ? -1U : i + 1); 142 } 143 *head = 0; 144 } 145 146 /** Allocate a descriptor from the free list 147 * 148 * @param vdev[in] VIRTIO device with the free list. 149 * @param num[in] Index of the virtqueue with free list. 150 * @param head[in,out] Head of the free list. 151 * 152 * @return Allocated descriptor or 0xFFFF if the list is empty. 153 */ 154 static uint16_t virtio_net_alloc_desc(virtio_dev_t *vdev, uint16_t num, 155 uint16_t *head) 156 { 157 virtq_t *q = &vdev->queues[num]; 158 fibril_mutex_lock(&q->lock); 159 uint16_t descno = *head; 160 if (descno != (uint16_t) -1U) 161 *head = virtio_virtq_desc_get_next(vdev, num, descno); 162 fibril_mutex_unlock(&q->lock); 163 return descno; 164 } 165 166 /** Free a descriptor into the free list 167 * 168 * @param vdev[in] VIRTIO device with the free list. 169 * @param num[in] Index of the virtqueue with free list. 170 * @param head[in,out] Head of the free list. 171 * @param descno[in] The freed descriptor. 172 */ 173 static void virtio_net_free_desc(virtio_dev_t *vdev, uint16_t num, 174 uint16_t *head, uint16_t descno) 175 { 176 virtq_t *q = &vdev->queues[num]; 177 fibril_mutex_lock(&q->lock); 178 virtio_virtq_desc_set(vdev, num, descno, 0, 0, VIRTQ_DESC_F_NEXT, 179 *head); 180 *head = descno; 181 fibril_mutex_unlock(&q->lock); 182 } 71 183 72 184 static void virtio_net_irq_handler(ipc_call_t *icall, ddf_dev_t *dev) … … 102 214 103 215 while (virtio_virtq_consume_used(vdev, TX_QUEUE_1, &descno, &len)) { 104 virtio_ free_desc(vdev, TX_QUEUE_1, &virtio_net->tx_free_head,105 descno);216 virtio_net_free_desc(vdev, TX_QUEUE_1, 217 &virtio_net->tx_free_head, descno); 106 218 } 107 219 while (virtio_virtq_consume_used(vdev, CT_QUEUE_1, &descno, &len)) { 108 virtio_ free_desc(vdev, CT_QUEUE_1, &virtio_net->ct_free_head,109 descno);220 virtio_net_free_desc(vdev, CT_QUEUE_1, 221 &virtio_net->ct_free_head, descno); 110 222 } 111 223 } … … 233 345 * Setup DMA buffers 234 346 */ 235 rc = virtio_ setup_dma_bufs(RX_BUFFERS, RX_BUF_SIZE, false,347 rc = virtio_net_setup_bufs(RX_BUFFERS, RX_BUF_SIZE, false, 236 348 virtio_net->rx_buf, virtio_net->rx_buf_p); 237 349 if (rc != EOK) 238 350 goto fail; 239 rc = virtio_ setup_dma_bufs(TX_BUFFERS, TX_BUF_SIZE, true,351 rc = virtio_net_setup_bufs(TX_BUFFERS, TX_BUF_SIZE, true, 240 352 virtio_net->tx_buf, virtio_net->tx_buf_p); 241 353 if (rc != EOK) 242 354 goto fail; 243 rc = virtio_ setup_dma_bufs(CT_BUFFERS, CT_BUF_SIZE, true,355 rc = virtio_net_setup_bufs(CT_BUFFERS, CT_BUF_SIZE, true, 244 356 virtio_net->ct_buf, virtio_net->ct_buf_p); 245 357 if (rc != EOK) … … 267 379 * Put all TX and CT buffers on a free list 268 380 */ 269 virtio_ create_desc_free_list(vdev, TX_QUEUE_1, TX_BUFFERS,381 virtio_net_create_desc_free_list(vdev, TX_QUEUE_1, TX_BUFFERS, 270 382 &virtio_net->tx_free_head); 271 virtio_ create_desc_free_list(vdev, CT_QUEUE_1, CT_BUFFERS,383 virtio_net_create_desc_free_list(vdev, CT_QUEUE_1, CT_BUFFERS, 272 384 &virtio_net->ct_free_head); 273 385 … … 302 414 303 415 fail: 304 virtio_ teardown_dma_bufs(virtio_net->rx_buf);305 virtio_ teardown_dma_bufs(virtio_net->tx_buf);306 virtio_ teardown_dma_bufs(virtio_net->ct_buf);416 virtio_net_teardown_bufs(virtio_net->rx_buf); 417 virtio_net_teardown_bufs(virtio_net->tx_buf); 418 virtio_net_teardown_bufs(virtio_net->ct_buf); 307 419 308 420 virtio_device_setup_fail(vdev); … … 316 428 virtio_net_t *virtio_net = (virtio_net_t *) nic_get_specific(nic); 317 429 318 virtio_ teardown_dma_bufs(virtio_net->rx_buf);319 virtio_ teardown_dma_bufs(virtio_net->tx_buf);320 virtio_ teardown_dma_bufs(virtio_net->ct_buf);430 virtio_net_teardown_bufs(virtio_net->rx_buf); 431 virtio_net_teardown_bufs(virtio_net->tx_buf); 432 virtio_net_teardown_bufs(virtio_net->ct_buf); 321 433 322 434 virtio_device_setup_fail(&virtio_net->virtio_dev); … … 334 446 } 335 447 336 uint16_t descno = virtio_ alloc_desc(vdev, TX_QUEUE_1,448 uint16_t descno = virtio_net_alloc_desc(vdev, TX_QUEUE_1, 337 449 &virtio_net->tx_free_head); 338 450 if (descno == (uint16_t) -1U) {
Note:
See TracChangeset
for help on using the changeset viewer.