linux-user: Use direct syscall for utimensat
[qemu/ar7.git] / hw / net / spapr_llan.c
blob4bb95a51ddddd75d35dc98166895ce130379227d
1 /*
2 * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
4 * PAPR Inter-VM Logical Lan, aka ibmveth
6 * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
27 #include "qemu/osdep.h"
28 #include "qemu-common.h"
29 #include "cpu.h"
30 #include "hw/hw.h"
31 #include "qemu/log.h"
32 #include "net/net.h"
33 #include "hw/qdev.h"
34 #include "hw/ppc/spapr.h"
35 #include "hw/ppc/spapr_vio.h"
36 #include "sysemu/sysemu.h"
38 #include <libfdt.h>
40 #define ETH_ALEN 6
41 #define MAX_PACKET_SIZE 65536
43 /*#define DEBUG*/
45 #ifdef DEBUG
46 #define DPRINTF(fmt...) do { fprintf(stderr, fmt); } while (0)
47 #else
48 #define DPRINTF(fmt...)
49 #endif
51 /* Compatibility flags for migration */
52 #define SPAPRVLAN_FLAG_RX_BUF_POOLS_BIT 0
53 #define SPAPRVLAN_FLAG_RX_BUF_POOLS (1 << SPAPRVLAN_FLAG_RX_BUF_POOLS_BIT)
56 * Virtual LAN device
59 typedef uint64_t vlan_bd_t;
61 #define VLAN_BD_VALID 0x8000000000000000ULL
62 #define VLAN_BD_TOGGLE 0x4000000000000000ULL
63 #define VLAN_BD_NO_CSUM 0x0200000000000000ULL
64 #define VLAN_BD_CSUM_GOOD 0x0100000000000000ULL
65 #define VLAN_BD_LEN_MASK 0x00ffffff00000000ULL
66 #define VLAN_BD_LEN(bd) (((bd) & VLAN_BD_LEN_MASK) >> 32)
67 #define VLAN_BD_ADDR_MASK 0x00000000ffffffffULL
68 #define VLAN_BD_ADDR(bd) ((bd) & VLAN_BD_ADDR_MASK)
70 #define VLAN_VALID_BD(addr, len) (VLAN_BD_VALID | \
71 (((len) << 32) & VLAN_BD_LEN_MASK) | \
72 (addr & VLAN_BD_ADDR_MASK))
74 #define VLAN_RXQC_TOGGLE 0x80
75 #define VLAN_RXQC_VALID 0x40
76 #define VLAN_RXQC_NO_CSUM 0x02
77 #define VLAN_RXQC_CSUM_GOOD 0x01
79 #define VLAN_RQ_ALIGNMENT 16
80 #define VLAN_RXQ_BD_OFF 0
81 #define VLAN_FILTER_BD_OFF 8
82 #define VLAN_RX_BDS_OFF 16
84 * The final 8 bytes of the buffer list is a counter of frames dropped
85 * because there was not a buffer in the buffer list capable of holding
86 * the frame. We must avoid it, or the operating system will report garbage
87 * for this statistic.
89 #define VLAN_RX_BDS_LEN (SPAPR_TCE_PAGE_SIZE - VLAN_RX_BDS_OFF - 8)
90 #define VLAN_MAX_BUFS (VLAN_RX_BDS_LEN / 8)
92 #define TYPE_VIO_SPAPR_VLAN_DEVICE "spapr-vlan"
93 #define VIO_SPAPR_VLAN_DEVICE(obj) \
94 OBJECT_CHECK(VIOsPAPRVLANDevice, (obj), TYPE_VIO_SPAPR_VLAN_DEVICE)
96 #define RX_POOL_MAX_BDS 4096
97 #define RX_MAX_POOLS 5
99 typedef struct {
100 int32_t bufsize;
101 int32_t count;
102 vlan_bd_t bds[RX_POOL_MAX_BDS];
103 } RxBufPool;
105 typedef struct VIOsPAPRVLANDevice {
106 VIOsPAPRDevice sdev;
107 NICConf nicconf;
108 NICState *nic;
109 MACAddr perm_mac;
110 bool isopen;
111 hwaddr buf_list;
112 uint32_t add_buf_ptr, use_buf_ptr, rx_bufs;
113 hwaddr rxq_ptr;
114 QEMUTimer *rxp_timer;
115 uint32_t compat_flags; /* Compatability flags for migration */
116 RxBufPool *rx_pool[RX_MAX_POOLS]; /* Receive buffer descriptor pools */
117 } VIOsPAPRVLANDevice;
119 static int spapr_vlan_can_receive(NetClientState *nc)
121 VIOsPAPRVLANDevice *dev = qemu_get_nic_opaque(nc);
123 return (dev->isopen && dev->rx_bufs > 0);
127 * The last 8 bytes of the receive buffer list page (that has been
128 * supplied by the guest with the H_REGISTER_LOGICAL_LAN call) contain
129 * a counter for frames that have been dropped because there was no
130 * suitable receive buffer available. This function is used to increase
131 * this counter by one.
133 static void spapr_vlan_record_dropped_rx_frame(VIOsPAPRVLANDevice *dev)
135 uint64_t cnt;
137 cnt = vio_ldq(&dev->sdev, dev->buf_list + 4096 - 8);
138 vio_stq(&dev->sdev, dev->buf_list + 4096 - 8, cnt + 1);
142 * Get buffer descriptor from one of our receive buffer pools
144 static vlan_bd_t spapr_vlan_get_rx_bd_from_pool(VIOsPAPRVLANDevice *dev,
145 size_t size)
147 vlan_bd_t bd;
148 int pool;
150 for (pool = 0; pool < RX_MAX_POOLS; pool++) {
151 if (dev->rx_pool[pool]->count > 0 &&
152 dev->rx_pool[pool]->bufsize >= size + 8) {
153 break;
156 if (pool == RX_MAX_POOLS) {
157 /* Failed to find a suitable buffer */
158 return 0;
161 DPRINTF("Found buffer: pool=%d count=%d rxbufs=%d\n", pool,
162 dev->rx_pool[pool]->count, dev->rx_bufs);
164 /* Remove the buffer from the pool */
165 dev->rx_pool[pool]->count--;
166 bd = dev->rx_pool[pool]->bds[dev->rx_pool[pool]->count];
167 dev->rx_pool[pool]->bds[dev->rx_pool[pool]->count] = 0;
169 return bd;
173 * Get buffer descriptor from the receive buffer list page that has been
174 * supplied by the guest with the H_REGISTER_LOGICAL_LAN call
176 static vlan_bd_t spapr_vlan_get_rx_bd_from_page(VIOsPAPRVLANDevice *dev,
177 size_t size)
179 int buf_ptr = dev->use_buf_ptr;
180 vlan_bd_t bd;
182 do {
183 buf_ptr += 8;
184 if (buf_ptr >= VLAN_RX_BDS_LEN + VLAN_RX_BDS_OFF) {
185 buf_ptr = VLAN_RX_BDS_OFF;
188 bd = vio_ldq(&dev->sdev, dev->buf_list + buf_ptr);
189 DPRINTF("use_buf_ptr=%d bd=0x%016llx\n",
190 buf_ptr, (unsigned long long)bd);
191 } while ((!(bd & VLAN_BD_VALID) || VLAN_BD_LEN(bd) < size + 8)
192 && buf_ptr != dev->use_buf_ptr);
194 if (!(bd & VLAN_BD_VALID) || VLAN_BD_LEN(bd) < size + 8) {
195 /* Failed to find a suitable buffer */
196 return 0;
199 /* Remove the buffer from the pool */
200 dev->use_buf_ptr = buf_ptr;
201 vio_stq(&dev->sdev, dev->buf_list + dev->use_buf_ptr, 0);
203 DPRINTF("Found buffer: ptr=%d rxbufs=%d\n", dev->use_buf_ptr, dev->rx_bufs);
205 return bd;
208 static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
209 size_t size)
211 VIOsPAPRVLANDevice *dev = qemu_get_nic_opaque(nc);
212 VIOsPAPRDevice *sdev = VIO_SPAPR_DEVICE(dev);
213 vlan_bd_t rxq_bd = vio_ldq(sdev, dev->buf_list + VLAN_RXQ_BD_OFF);
214 vlan_bd_t bd;
215 uint64_t handle;
216 uint8_t control;
218 DPRINTF("spapr_vlan_receive() [%s] rx_bufs=%d\n", sdev->qdev.id,
219 dev->rx_bufs);
221 if (!dev->isopen) {
222 return -1;
225 if (!dev->rx_bufs) {
226 spapr_vlan_record_dropped_rx_frame(dev);
227 return 0;
230 if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
231 bd = spapr_vlan_get_rx_bd_from_pool(dev, size);
232 } else {
233 bd = spapr_vlan_get_rx_bd_from_page(dev, size);
235 if (!bd) {
236 spapr_vlan_record_dropped_rx_frame(dev);
237 return 0;
240 dev->rx_bufs--;
242 /* Transfer the packet data */
243 if (spapr_vio_dma_write(sdev, VLAN_BD_ADDR(bd) + 8, buf, size) < 0) {
244 return -1;
247 DPRINTF("spapr_vlan_receive: DMA write completed\n");
249 /* Update the receive queue */
250 control = VLAN_RXQC_TOGGLE | VLAN_RXQC_VALID;
251 if (rxq_bd & VLAN_BD_TOGGLE) {
252 control ^= VLAN_RXQC_TOGGLE;
255 handle = vio_ldq(sdev, VLAN_BD_ADDR(bd));
256 vio_stq(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 8, handle);
257 vio_stl(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 4, size);
258 vio_sth(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 2, 8);
259 vio_stb(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr, control);
261 DPRINTF("wrote rxq entry (ptr=0x%llx): 0x%016llx 0x%016llx\n",
262 (unsigned long long)dev->rxq_ptr,
263 (unsigned long long)vio_ldq(sdev, VLAN_BD_ADDR(rxq_bd) +
264 dev->rxq_ptr),
265 (unsigned long long)vio_ldq(sdev, VLAN_BD_ADDR(rxq_bd) +
266 dev->rxq_ptr + 8));
268 dev->rxq_ptr += 16;
269 if (dev->rxq_ptr >= VLAN_BD_LEN(rxq_bd)) {
270 dev->rxq_ptr = 0;
271 vio_stq(sdev, dev->buf_list + VLAN_RXQ_BD_OFF, rxq_bd ^ VLAN_BD_TOGGLE);
274 if (sdev->signal_state & 1) {
275 qemu_irq_pulse(spapr_vio_qirq(sdev));
278 return size;
281 static NetClientInfo net_spapr_vlan_info = {
282 .type = NET_CLIENT_DRIVER_NIC,
283 .size = sizeof(NICState),
284 .can_receive = spapr_vlan_can_receive,
285 .receive = spapr_vlan_receive,
288 static void spapr_vlan_flush_rx_queue(void *opaque)
290 VIOsPAPRVLANDevice *dev = opaque;
292 qemu_flush_queued_packets(qemu_get_queue(dev->nic));
295 static void spapr_vlan_reset_rx_pool(RxBufPool *rxp)
298 * Use INT_MAX as bufsize so that unused buffers are moved to the end
299 * of the list during the qsort in spapr_vlan_add_rxbuf_to_pool() later.
301 rxp->bufsize = INT_MAX;
302 rxp->count = 0;
303 memset(rxp->bds, 0, sizeof(rxp->bds));
306 static void spapr_vlan_reset(VIOsPAPRDevice *sdev)
308 VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
309 int i;
311 dev->buf_list = 0;
312 dev->rx_bufs = 0;
313 dev->isopen = 0;
315 if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
316 for (i = 0; i < RX_MAX_POOLS; i++) {
317 spapr_vlan_reset_rx_pool(dev->rx_pool[i]);
321 memcpy(&dev->nicconf.macaddr.a, &dev->perm_mac.a,
322 sizeof(dev->nicconf.macaddr.a));
323 qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
326 static void spapr_vlan_realize(VIOsPAPRDevice *sdev, Error **errp)
328 VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
330 qemu_macaddr_default_if_unset(&dev->nicconf.macaddr);
332 memcpy(&dev->perm_mac.a, &dev->nicconf.macaddr.a, sizeof(dev->perm_mac.a));
334 dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf,
335 object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev);
336 qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
338 dev->rxp_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, spapr_vlan_flush_rx_queue,
339 dev);
342 static void spapr_vlan_instance_init(Object *obj)
344 VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(obj);
345 int i;
347 device_add_bootindex_property(obj, &dev->nicconf.bootindex,
348 "bootindex", "",
349 DEVICE(dev), NULL);
351 if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
352 for (i = 0; i < RX_MAX_POOLS; i++) {
353 dev->rx_pool[i] = g_new(RxBufPool, 1);
354 spapr_vlan_reset_rx_pool(dev->rx_pool[i]);
359 static void spapr_vlan_instance_finalize(Object *obj)
361 VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(obj);
362 int i;
364 if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
365 for (i = 0; i < RX_MAX_POOLS; i++) {
366 g_free(dev->rx_pool[i]);
367 dev->rx_pool[i] = NULL;
371 if (dev->rxp_timer) {
372 timer_del(dev->rxp_timer);
373 timer_free(dev->rxp_timer);
377 void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd)
379 DeviceState *dev;
381 dev = qdev_create(&bus->bus, "spapr-vlan");
383 qdev_set_nic_properties(dev, nd);
385 qdev_init_nofail(dev);
388 static int spapr_vlan_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
390 VIOsPAPRVLANDevice *vdev = VIO_SPAPR_VLAN_DEVICE(dev);
391 uint8_t padded_mac[8] = {0, 0};
392 int ret;
394 /* Some old phyp versions give the mac address in an 8-byte
395 * property. The kernel driver has an insane workaround for this;
396 * rather than doing the obvious thing and checking the property
397 * length, it checks whether the first byte has 0b10 in the low
398 * bits. If a correct 6-byte property has a different first byte
399 * the kernel will get the wrong mac address, overrunning its
400 * buffer in the process (read only, thank goodness).
402 * Here we workaround the kernel workaround by always supplying an
403 * 8-byte property, with the mac address in the last six bytes */
404 memcpy(&padded_mac[2], &vdev->nicconf.macaddr, ETH_ALEN);
405 ret = fdt_setprop(fdt, node_off, "local-mac-address",
406 padded_mac, sizeof(padded_mac));
407 if (ret < 0) {
408 return ret;
411 ret = fdt_setprop_cell(fdt, node_off, "ibm,mac-address-filters", 0);
412 if (ret < 0) {
413 return ret;
416 return 0;
419 static int check_bd(VIOsPAPRVLANDevice *dev, vlan_bd_t bd,
420 target_ulong alignment)
422 if ((VLAN_BD_ADDR(bd) % alignment)
423 || (VLAN_BD_LEN(bd) % alignment)) {
424 return -1;
427 if (!spapr_vio_dma_valid(&dev->sdev, VLAN_BD_ADDR(bd),
428 VLAN_BD_LEN(bd), DMA_DIRECTION_FROM_DEVICE)
429 || !spapr_vio_dma_valid(&dev->sdev, VLAN_BD_ADDR(bd),
430 VLAN_BD_LEN(bd), DMA_DIRECTION_TO_DEVICE)) {
431 return -1;
434 return 0;
437 static target_ulong h_register_logical_lan(PowerPCCPU *cpu,
438 sPAPRMachineState *spapr,
439 target_ulong opcode,
440 target_ulong *args)
442 target_ulong reg = args[0];
443 target_ulong buf_list = args[1];
444 target_ulong rec_queue = args[2];
445 target_ulong filter_list = args[3];
446 VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
447 VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
448 vlan_bd_t filter_list_bd;
450 if (!dev) {
451 return H_PARAMETER;
454 if (dev->isopen) {
455 hcall_dprintf("H_REGISTER_LOGICAL_LAN called twice without "
456 "H_FREE_LOGICAL_LAN\n");
457 return H_RESOURCE;
460 if (check_bd(dev, VLAN_VALID_BD(buf_list, SPAPR_TCE_PAGE_SIZE),
461 SPAPR_TCE_PAGE_SIZE) < 0) {
462 hcall_dprintf("Bad buf_list 0x" TARGET_FMT_lx "\n", buf_list);
463 return H_PARAMETER;
466 filter_list_bd = VLAN_VALID_BD(filter_list, SPAPR_TCE_PAGE_SIZE);
467 if (check_bd(dev, filter_list_bd, SPAPR_TCE_PAGE_SIZE) < 0) {
468 hcall_dprintf("Bad filter_list 0x" TARGET_FMT_lx "\n", filter_list);
469 return H_PARAMETER;
472 if (!(rec_queue & VLAN_BD_VALID)
473 || (check_bd(dev, rec_queue, VLAN_RQ_ALIGNMENT) < 0)) {
474 hcall_dprintf("Bad receive queue\n");
475 return H_PARAMETER;
478 dev->buf_list = buf_list;
479 sdev->signal_state = 0;
481 rec_queue &= ~VLAN_BD_TOGGLE;
483 /* Initialize the buffer list */
484 vio_stq(sdev, buf_list, rec_queue);
485 vio_stq(sdev, buf_list + 8, filter_list_bd);
486 spapr_vio_dma_set(sdev, buf_list + VLAN_RX_BDS_OFF, 0,
487 SPAPR_TCE_PAGE_SIZE - VLAN_RX_BDS_OFF);
488 dev->add_buf_ptr = VLAN_RX_BDS_OFF - 8;
489 dev->use_buf_ptr = VLAN_RX_BDS_OFF - 8;
490 dev->rx_bufs = 0;
491 dev->rxq_ptr = 0;
493 /* Initialize the receive queue */
494 spapr_vio_dma_set(sdev, VLAN_BD_ADDR(rec_queue), 0, VLAN_BD_LEN(rec_queue));
496 dev->isopen = 1;
497 qemu_flush_queued_packets(qemu_get_queue(dev->nic));
499 return H_SUCCESS;
503 static target_ulong h_free_logical_lan(PowerPCCPU *cpu,
504 sPAPRMachineState *spapr,
505 target_ulong opcode, target_ulong *args)
507 target_ulong reg = args[0];
508 VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
509 VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
511 if (!dev) {
512 return H_PARAMETER;
515 if (!dev->isopen) {
516 hcall_dprintf("H_FREE_LOGICAL_LAN called without "
517 "H_REGISTER_LOGICAL_LAN\n");
518 return H_RESOURCE;
521 spapr_vlan_reset(sdev);
522 return H_SUCCESS;
526 * Used for qsort, this function compares two RxBufPools by size.
528 static int rx_pool_size_compare(const void *p1, const void *p2)
530 const RxBufPool *pool1 = *(RxBufPool **)p1;
531 const RxBufPool *pool2 = *(RxBufPool **)p2;
533 if (pool1->bufsize < pool2->bufsize) {
534 return -1;
536 return pool1->bufsize > pool2->bufsize;
540 * Search for a matching buffer pool with exact matching size,
541 * or return -1 if no matching pool has been found.
543 static int spapr_vlan_get_rx_pool_id(VIOsPAPRVLANDevice *dev, int size)
545 int pool;
547 for (pool = 0; pool < RX_MAX_POOLS; pool++) {
548 if (dev->rx_pool[pool]->bufsize == size) {
549 return pool;
553 return -1;
557 * Enqueuing receive buffer by adding it to one of our receive buffer pools
559 static target_long spapr_vlan_add_rxbuf_to_pool(VIOsPAPRVLANDevice *dev,
560 target_ulong buf)
562 int size = VLAN_BD_LEN(buf);
563 int pool;
565 pool = spapr_vlan_get_rx_pool_id(dev, size);
566 if (pool < 0) {
568 * No matching pool found? Try to use a new one. If the guest used all
569 * pools before, but changed the size of one pool inbetween, we might
570 * need to recycle that pool here (if it's empty already). Thus scan
571 * all buffer pools now, starting with the last (likely empty) one.
573 for (pool = RX_MAX_POOLS - 1; pool >= 0 ; pool--) {
574 if (dev->rx_pool[pool]->count == 0) {
575 dev->rx_pool[pool]->bufsize = size;
577 * Sort pools by size so that spapr_vlan_receive()
578 * can later find the smallest buffer pool easily.
580 qsort(dev->rx_pool, RX_MAX_POOLS, sizeof(dev->rx_pool[0]),
581 rx_pool_size_compare);
582 pool = spapr_vlan_get_rx_pool_id(dev, size);
583 DPRINTF("created RX pool %d for size %lld\n", pool,
584 VLAN_BD_LEN(buf));
585 break;
589 /* Still no usable pool? Give up */
590 if (pool < 0 || dev->rx_pool[pool]->count >= RX_POOL_MAX_BDS) {
591 return H_RESOURCE;
594 DPRINTF("h_add_llan_buf(): Add buf using pool %i (size %lli, count=%i)\n",
595 pool, VLAN_BD_LEN(buf), dev->rx_pool[pool]->count);
597 dev->rx_pool[pool]->bds[dev->rx_pool[pool]->count++] = buf;
599 return 0;
603 * This is the old way of enqueuing receive buffers: Add it to the rx queue
604 * page that has been supplied by the guest (which is quite limited in size).
606 static target_long spapr_vlan_add_rxbuf_to_page(VIOsPAPRVLANDevice *dev,
607 target_ulong buf)
609 vlan_bd_t bd;
611 if (dev->rx_bufs >= VLAN_MAX_BUFS) {
612 return H_RESOURCE;
615 do {
616 dev->add_buf_ptr += 8;
617 if (dev->add_buf_ptr >= VLAN_RX_BDS_LEN + VLAN_RX_BDS_OFF) {
618 dev->add_buf_ptr = VLAN_RX_BDS_OFF;
621 bd = vio_ldq(&dev->sdev, dev->buf_list + dev->add_buf_ptr);
622 } while (bd & VLAN_BD_VALID);
624 vio_stq(&dev->sdev, dev->buf_list + dev->add_buf_ptr, buf);
626 DPRINTF("h_add_llan_buf(): Added buf ptr=%d rx_bufs=%d bd=0x%016llx\n",
627 dev->add_buf_ptr, dev->rx_bufs, (unsigned long long)buf);
629 return 0;
632 static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu,
633 sPAPRMachineState *spapr,
634 target_ulong opcode,
635 target_ulong *args)
637 target_ulong reg = args[0];
638 target_ulong buf = args[1];
639 VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
640 VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
641 target_long ret;
643 DPRINTF("H_ADD_LOGICAL_LAN_BUFFER(0x" TARGET_FMT_lx
644 ", 0x" TARGET_FMT_lx ")\n", reg, buf);
646 if (!sdev) {
647 hcall_dprintf("Bad device\n");
648 return H_PARAMETER;
651 if ((check_bd(dev, buf, 4) < 0)
652 || (VLAN_BD_LEN(buf) < 16)) {
653 hcall_dprintf("Bad buffer enqueued\n");
654 return H_PARAMETER;
657 if (!dev->isopen) {
658 return H_RESOURCE;
661 if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
662 ret = spapr_vlan_add_rxbuf_to_pool(dev, buf);
663 } else {
664 ret = spapr_vlan_add_rxbuf_to_page(dev, buf);
666 if (ret) {
667 return ret;
670 dev->rx_bufs++;
673 * Give guest some more time to add additional RX buffers before we
674 * flush the receive queue, so that e.g. fragmented IP packets can
675 * be passed to the guest in one go later (instead of passing single
676 * fragments if there is only one receive buffer available).
678 timer_mod(dev->rxp_timer, qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 500);
680 return H_SUCCESS;
683 static target_ulong h_send_logical_lan(PowerPCCPU *cpu,
684 sPAPRMachineState *spapr,
685 target_ulong opcode, target_ulong *args)
687 target_ulong reg = args[0];
688 target_ulong *bufs = args + 1;
689 target_ulong continue_token = args[7];
690 VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
691 VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
692 unsigned total_len;
693 uint8_t *lbuf, *p;
694 int i, nbufs;
695 int ret;
697 DPRINTF("H_SEND_LOGICAL_LAN(0x" TARGET_FMT_lx ", <bufs>, 0x"
698 TARGET_FMT_lx ")\n", reg, continue_token);
700 if (!sdev) {
701 return H_PARAMETER;
704 DPRINTF("rxbufs = %d\n", dev->rx_bufs);
706 if (!dev->isopen) {
707 return H_DROPPED;
710 if (continue_token) {
711 return H_HARDWARE; /* FIXME actually handle this */
714 total_len = 0;
715 for (i = 0; i < 6; i++) {
716 DPRINTF(" buf desc: 0x" TARGET_FMT_lx "\n", bufs[i]);
717 if (!(bufs[i] & VLAN_BD_VALID)) {
718 break;
720 total_len += VLAN_BD_LEN(bufs[i]);
723 nbufs = i;
724 DPRINTF("h_send_logical_lan() %d buffers, total length 0x%x\n",
725 nbufs, total_len);
727 if (total_len == 0) {
728 return H_SUCCESS;
731 if (total_len > MAX_PACKET_SIZE) {
732 /* Don't let the guest force too large an allocation */
733 return H_RESOURCE;
736 lbuf = alloca(total_len);
737 p = lbuf;
738 for (i = 0; i < nbufs; i++) {
739 ret = spapr_vio_dma_read(sdev, VLAN_BD_ADDR(bufs[i]),
740 p, VLAN_BD_LEN(bufs[i]));
741 if (ret < 0) {
742 return ret;
745 p += VLAN_BD_LEN(bufs[i]);
748 qemu_send_packet(qemu_get_queue(dev->nic), lbuf, total_len);
750 return H_SUCCESS;
753 static target_ulong h_multicast_ctrl(PowerPCCPU *cpu, sPAPRMachineState *spapr,
754 target_ulong opcode, target_ulong *args)
756 target_ulong reg = args[0];
757 VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
759 if (!dev) {
760 return H_PARAMETER;
763 return H_SUCCESS;
766 static target_ulong h_change_logical_lan_mac(PowerPCCPU *cpu,
767 sPAPRMachineState *spapr,
768 target_ulong opcode,
769 target_ulong *args)
771 target_ulong reg = args[0];
772 target_ulong macaddr = args[1];
773 VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
774 VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
775 int i;
777 for (i = 0; i < ETH_ALEN; i++) {
778 dev->nicconf.macaddr.a[ETH_ALEN - i - 1] = macaddr & 0xff;
779 macaddr >>= 8;
782 qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
784 return H_SUCCESS;
787 static Property spapr_vlan_properties[] = {
788 DEFINE_SPAPR_PROPERTIES(VIOsPAPRVLANDevice, sdev),
789 DEFINE_NIC_PROPERTIES(VIOsPAPRVLANDevice, nicconf),
790 DEFINE_PROP_BIT("use-rx-buffer-pools", VIOsPAPRVLANDevice,
791 compat_flags, SPAPRVLAN_FLAG_RX_BUF_POOLS_BIT, true),
792 DEFINE_PROP_END_OF_LIST(),
795 static bool spapr_vlan_rx_buffer_pools_needed(void *opaque)
797 VIOsPAPRVLANDevice *dev = opaque;
799 return (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) != 0;
802 static const VMStateDescription vmstate_rx_buffer_pool = {
803 .name = "spapr_llan/rx_buffer_pool",
804 .version_id = 1,
805 .minimum_version_id = 1,
806 .needed = spapr_vlan_rx_buffer_pools_needed,
807 .fields = (VMStateField[]) {
808 VMSTATE_INT32(bufsize, RxBufPool),
809 VMSTATE_INT32(count, RxBufPool),
810 VMSTATE_UINT64_ARRAY(bds, RxBufPool, RX_POOL_MAX_BDS),
811 VMSTATE_END_OF_LIST()
815 static const VMStateDescription vmstate_rx_pools = {
816 .name = "spapr_llan/rx_pools",
817 .version_id = 1,
818 .minimum_version_id = 1,
819 .needed = spapr_vlan_rx_buffer_pools_needed,
820 .fields = (VMStateField[]) {
821 VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(rx_pool, VIOsPAPRVLANDevice,
822 RX_MAX_POOLS, 1,
823 vmstate_rx_buffer_pool, RxBufPool),
824 VMSTATE_END_OF_LIST()
828 static const VMStateDescription vmstate_spapr_llan = {
829 .name = "spapr_llan",
830 .version_id = 1,
831 .minimum_version_id = 1,
832 .fields = (VMStateField[]) {
833 VMSTATE_SPAPR_VIO(sdev, VIOsPAPRVLANDevice),
834 /* LLAN state */
835 VMSTATE_BOOL(isopen, VIOsPAPRVLANDevice),
836 VMSTATE_UINT64(buf_list, VIOsPAPRVLANDevice),
837 VMSTATE_UINT32(add_buf_ptr, VIOsPAPRVLANDevice),
838 VMSTATE_UINT32(use_buf_ptr, VIOsPAPRVLANDevice),
839 VMSTATE_UINT32(rx_bufs, VIOsPAPRVLANDevice),
840 VMSTATE_UINT64(rxq_ptr, VIOsPAPRVLANDevice),
842 VMSTATE_END_OF_LIST()
844 .subsections = (const VMStateDescription * []) {
845 &vmstate_rx_pools,
846 NULL
850 static void spapr_vlan_class_init(ObjectClass *klass, void *data)
852 DeviceClass *dc = DEVICE_CLASS(klass);
853 VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
855 k->realize = spapr_vlan_realize;
856 k->reset = spapr_vlan_reset;
857 k->devnode = spapr_vlan_devnode;
858 k->dt_name = "l-lan";
859 k->dt_type = "network";
860 k->dt_compatible = "IBM,l-lan";
861 k->signal_mask = 0x1;
862 set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
863 dc->props = spapr_vlan_properties;
864 k->rtce_window_size = 0x10000000;
865 dc->vmsd = &vmstate_spapr_llan;
868 static const TypeInfo spapr_vlan_info = {
869 .name = TYPE_VIO_SPAPR_VLAN_DEVICE,
870 .parent = TYPE_VIO_SPAPR_DEVICE,
871 .instance_size = sizeof(VIOsPAPRVLANDevice),
872 .class_init = spapr_vlan_class_init,
873 .instance_init = spapr_vlan_instance_init,
874 .instance_finalize = spapr_vlan_instance_finalize,
877 static void spapr_vlan_register_types(void)
879 spapr_register_hypercall(H_REGISTER_LOGICAL_LAN, h_register_logical_lan);
880 spapr_register_hypercall(H_FREE_LOGICAL_LAN, h_free_logical_lan);
881 spapr_register_hypercall(H_SEND_LOGICAL_LAN, h_send_logical_lan);
882 spapr_register_hypercall(H_ADD_LOGICAL_LAN_BUFFER,
883 h_add_logical_lan_buffer);
884 spapr_register_hypercall(H_MULTICAST_CTRL, h_multicast_ctrl);
885 spapr_register_hypercall(H_CHANGE_LOGICAL_LAN_MAC,
886 h_change_logical_lan_mac);
887 type_register_static(&spapr_vlan_info);
890 type_init(spapr_vlan_register_types)