Lines Matching +full:bd +full:- +full:address
4 * PAPR Inter-VM Logical Lan, aka ibmveth
35 #include "hw/qdev-properties.h"
60 #define VLAN_BD_LEN(bd) (((bd) & VLAN_BD_LEN_MASK) >> 32) argument
62 #define VLAN_BD_ADDR(bd) ((bd) & VLAN_BD_ADDR_MASK) argument
83 #define VLAN_RX_BDS_LEN (SPAPR_TCE_PAGE_SIZE - VLAN_RX_BDS_OFF - 8)
86 #define TYPE_VIO_SPAPR_VLAN_DEVICE "spapr-vlan"
116 return dev->isopen && dev->rx_bufs > 0; in spapr_vlan_can_receive()
130 cnt = vio_ldq(&dev->sdev, dev->buf_list + 4096 - 8); in spapr_vlan_record_dropped_rx_frame()
131 vio_stq(&dev->sdev, dev->buf_list + 4096 - 8, cnt + 1); in spapr_vlan_record_dropped_rx_frame()
140 vlan_bd_t bd; in spapr_vlan_get_rx_bd_from_pool() local
144 if (dev->rx_pool[pool]->count > 0 && in spapr_vlan_get_rx_bd_from_pool()
145 dev->rx_pool[pool]->bufsize >= size + 8) { in spapr_vlan_get_rx_bd_from_pool()
156 dev->rx_pool[pool]->count, in spapr_vlan_get_rx_bd_from_pool()
157 dev->rx_bufs); in spapr_vlan_get_rx_bd_from_pool()
160 dev->rx_pool[pool]->count--; in spapr_vlan_get_rx_bd_from_pool()
161 bd = dev->rx_pool[pool]->bds[dev->rx_pool[pool]->count]; in spapr_vlan_get_rx_bd_from_pool()
162 dev->rx_pool[pool]->bds[dev->rx_pool[pool]->count] = 0; in spapr_vlan_get_rx_bd_from_pool()
164 return bd; in spapr_vlan_get_rx_bd_from_pool()
174 int buf_ptr = dev->use_buf_ptr; in spapr_vlan_get_rx_bd_from_page()
175 vlan_bd_t bd; in spapr_vlan_get_rx_bd_from_page() local
183 bd = vio_ldq(&dev->sdev, dev->buf_list + buf_ptr); in spapr_vlan_get_rx_bd_from_page()
185 trace_spapr_vlan_get_rx_bd_from_page(buf_ptr, (uint64_t)bd); in spapr_vlan_get_rx_bd_from_page()
186 } while ((!(bd & VLAN_BD_VALID) || VLAN_BD_LEN(bd) < size + 8) in spapr_vlan_get_rx_bd_from_page()
187 && buf_ptr != dev->use_buf_ptr); in spapr_vlan_get_rx_bd_from_page()
189 if (!(bd & VLAN_BD_VALID) || VLAN_BD_LEN(bd) < size + 8) { in spapr_vlan_get_rx_bd_from_page()
195 dev->use_buf_ptr = buf_ptr; in spapr_vlan_get_rx_bd_from_page()
196 vio_stq(&dev->sdev, dev->buf_list + dev->use_buf_ptr, 0); in spapr_vlan_get_rx_bd_from_page()
198 trace_spapr_vlan_get_rx_bd_from_page_found(dev->use_buf_ptr, dev->rx_bufs); in spapr_vlan_get_rx_bd_from_page()
200 return bd; in spapr_vlan_get_rx_bd_from_page()
208 vlan_bd_t rxq_bd = vio_ldq(sdev, dev->buf_list + VLAN_RXQ_BD_OFF); in spapr_vlan_receive()
209 vlan_bd_t bd; in spapr_vlan_receive() local
213 trace_spapr_vlan_receive(sdev->qdev.id, dev->rx_bufs); in spapr_vlan_receive()
215 if (!dev->isopen) { in spapr_vlan_receive()
216 return -1; in spapr_vlan_receive()
219 if (!dev->rx_bufs) { in spapr_vlan_receive()
224 if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) { in spapr_vlan_receive()
225 bd = spapr_vlan_get_rx_bd_from_pool(dev, size); in spapr_vlan_receive()
227 bd = spapr_vlan_get_rx_bd_from_page(dev, size); in spapr_vlan_receive()
229 if (!bd) { in spapr_vlan_receive()
234 dev->rx_bufs--; in spapr_vlan_receive()
237 if (spapr_vio_dma_write(sdev, VLAN_BD_ADDR(bd) + 8, buf, size) < 0) { in spapr_vlan_receive()
238 return -1; in spapr_vlan_receive()
249 handle = vio_ldq(sdev, VLAN_BD_ADDR(bd)); in spapr_vlan_receive()
250 vio_stq(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 8, handle); in spapr_vlan_receive()
251 vio_stl(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 4, size); in spapr_vlan_receive()
252 vio_sth(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 2, 8); in spapr_vlan_receive()
253 vio_stb(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr, control); in spapr_vlan_receive()
255 trace_spapr_vlan_receive_wrote(dev->rxq_ptr, in spapr_vlan_receive()
257 dev->rxq_ptr), in spapr_vlan_receive()
259 dev->rxq_ptr + 8)); in spapr_vlan_receive()
261 dev->rxq_ptr += 16; in spapr_vlan_receive()
262 if (dev->rxq_ptr >= VLAN_BD_LEN(rxq_bd)) { in spapr_vlan_receive()
263 dev->rxq_ptr = 0; in spapr_vlan_receive()
264 vio_stq(sdev, dev->buf_list + VLAN_RXQ_BD_OFF, rxq_bd ^ VLAN_BD_TOGGLE); in spapr_vlan_receive()
267 if (sdev->signal_state & 1) { in spapr_vlan_receive()
285 qemu_flush_queued_packets(qemu_get_queue(dev->nic)); in spapr_vlan_flush_rx_queue()
294 rxp->bufsize = INT_MAX; in spapr_vlan_reset_rx_pool()
295 rxp->count = 0; in spapr_vlan_reset_rx_pool()
296 memset(rxp->bds, 0, sizeof(rxp->bds)); in spapr_vlan_reset_rx_pool()
304 dev->buf_list = 0; in spapr_vlan_reset()
305 dev->rx_bufs = 0; in spapr_vlan_reset()
306 dev->isopen = 0; in spapr_vlan_reset()
308 if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) { in spapr_vlan_reset()
310 spapr_vlan_reset_rx_pool(dev->rx_pool[i]); in spapr_vlan_reset()
314 memcpy(&dev->nicconf.macaddr.a, &dev->perm_mac.a, in spapr_vlan_reset()
315 sizeof(dev->nicconf.macaddr.a)); in spapr_vlan_reset()
316 qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a); in spapr_vlan_reset()
323 qemu_macaddr_default_if_unset(&dev->nicconf.macaddr); in spapr_vlan_realize()
325 memcpy(&dev->perm_mac.a, &dev->nicconf.macaddr.a, sizeof(dev->perm_mac.a)); in spapr_vlan_realize()
327 dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf, in spapr_vlan_realize()
328 object_get_typename(OBJECT(sdev)), sdev->qdev.id, in spapr_vlan_realize()
329 &sdev->qdev.mem_reentrancy_guard, dev); in spapr_vlan_realize()
330 qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a); in spapr_vlan_realize()
332 dev->rxp_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, spapr_vlan_flush_rx_queue, in spapr_vlan_realize()
341 device_add_bootindex_property(obj, &dev->nicconf.bootindex, in spapr_vlan_instance_init()
345 if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) { in spapr_vlan_instance_init()
347 dev->rx_pool[i] = g_new(RxBufPool, 1); in spapr_vlan_instance_init()
348 spapr_vlan_reset_rx_pool(dev->rx_pool[i]); in spapr_vlan_instance_init()
358 if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) { in spapr_vlan_instance_finalize()
360 g_free(dev->rx_pool[i]); in spapr_vlan_instance_finalize()
361 dev->rx_pool[i] = NULL; in spapr_vlan_instance_finalize()
365 if (dev->rxp_timer) { in spapr_vlan_instance_finalize()
366 timer_free(dev->rxp_timer); in spapr_vlan_instance_finalize()
374 dev = qdev_new("spapr-vlan"); in spapr_vlan_create()
378 qdev_realize_and_unref(dev, &bus->bus, &error_fatal); in spapr_vlan_create()
387 /* Some old phyp versions give the mac address in an 8-byte in spapr_vlan_devnode()
391 * bits. If a correct 6-byte property has a different first byte in spapr_vlan_devnode()
392 * the kernel will get the wrong mac address, overrunning its in spapr_vlan_devnode()
395 * Here we return a 6-byte address unless that would break a pre-3.10 in spapr_vlan_devnode()
396 * driver. In that case we return a padded 8-byte address to allow the old in spapr_vlan_devnode()
398 if ((vdev->nicconf.macaddr.a[0] & 0x3) == 0x2) { in spapr_vlan_devnode()
399 ret = fdt_setprop(fdt, node_off, "local-mac-address", in spapr_vlan_devnode()
400 &vdev->nicconf.macaddr, ETH_ALEN); in spapr_vlan_devnode()
402 memcpy(&padded_mac[2], &vdev->nicconf.macaddr, ETH_ALEN); in spapr_vlan_devnode()
403 ret = fdt_setprop(fdt, node_off, "local-mac-address", in spapr_vlan_devnode()
410 ret = fdt_setprop_cell(fdt, node_off, "ibm,mac-address-filters", 0); in spapr_vlan_devnode()
418 static int check_bd(SpaprVioVlan *dev, vlan_bd_t bd, in check_bd() argument
421 if ((VLAN_BD_ADDR(bd) % alignment) in check_bd()
422 || (VLAN_BD_LEN(bd) % alignment)) { in check_bd()
423 return -1; in check_bd()
426 if (!spapr_vio_dma_valid(&dev->sdev, VLAN_BD_ADDR(bd), in check_bd()
427 VLAN_BD_LEN(bd), DMA_DIRECTION_FROM_DEVICE) in check_bd()
428 || !spapr_vio_dma_valid(&dev->sdev, VLAN_BD_ADDR(bd), in check_bd()
429 VLAN_BD_LEN(bd), DMA_DIRECTION_TO_DEVICE)) { in check_bd()
430 return -1; in check_bd()
445 SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg); in h_register_logical_lan()
453 if (dev->isopen) { in h_register_logical_lan()
477 dev->buf_list = buf_list; in h_register_logical_lan()
478 sdev->signal_state = 0; in h_register_logical_lan()
486 SPAPR_TCE_PAGE_SIZE - VLAN_RX_BDS_OFF); in h_register_logical_lan()
487 dev->add_buf_ptr = VLAN_RX_BDS_OFF - 8; in h_register_logical_lan()
488 dev->use_buf_ptr = VLAN_RX_BDS_OFF - 8; in h_register_logical_lan()
489 dev->rx_bufs = 0; in h_register_logical_lan()
490 dev->rxq_ptr = 0; in h_register_logical_lan()
495 dev->isopen = 1; in h_register_logical_lan()
496 qemu_flush_queued_packets(qemu_get_queue(dev->nic)); in h_register_logical_lan()
507 SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg); in h_free_logical_lan()
514 if (!dev->isopen) { in h_free_logical_lan()
532 if (pool1->bufsize < pool2->bufsize) { in rx_pool_size_compare()
533 return -1; in rx_pool_size_compare()
535 return pool1->bufsize > pool2->bufsize; in rx_pool_size_compare()
540 * or return -1 if no matching pool has been found.
547 if (dev->rx_pool[pool]->bufsize == size) { in spapr_vlan_get_rx_pool_id()
552 return -1; in spapr_vlan_get_rx_pool_id()
572 for (pool = RX_MAX_POOLS - 1; pool >= 0 ; pool--) { in spapr_vlan_add_rxbuf_to_pool()
573 if (dev->rx_pool[pool]->count == 0) { in spapr_vlan_add_rxbuf_to_pool()
574 dev->rx_pool[pool]->bufsize = size; in spapr_vlan_add_rxbuf_to_pool()
579 qsort(dev->rx_pool, RX_MAX_POOLS, sizeof(dev->rx_pool[0]), in spapr_vlan_add_rxbuf_to_pool()
589 if (pool < 0 || dev->rx_pool[pool]->count >= RX_POOL_MAX_BDS) { in spapr_vlan_add_rxbuf_to_pool()
594 dev->rx_pool[pool]->count); in spapr_vlan_add_rxbuf_to_pool()
596 dev->rx_pool[pool]->bds[dev->rx_pool[pool]->count++] = buf; in spapr_vlan_add_rxbuf_to_pool()
608 vlan_bd_t bd; in spapr_vlan_add_rxbuf_to_page() local
610 if (dev->rx_bufs >= VLAN_MAX_BUFS) { in spapr_vlan_add_rxbuf_to_page()
615 dev->add_buf_ptr += 8; in spapr_vlan_add_rxbuf_to_page()
616 if (dev->add_buf_ptr >= VLAN_RX_BDS_LEN + VLAN_RX_BDS_OFF) { in spapr_vlan_add_rxbuf_to_page()
617 dev->add_buf_ptr = VLAN_RX_BDS_OFF; in spapr_vlan_add_rxbuf_to_page()
620 bd = vio_ldq(&dev->sdev, dev->buf_list + dev->add_buf_ptr); in spapr_vlan_add_rxbuf_to_page()
621 } while (bd & VLAN_BD_VALID); in spapr_vlan_add_rxbuf_to_page()
623 vio_stq(&dev->sdev, dev->buf_list + dev->add_buf_ptr, buf); in spapr_vlan_add_rxbuf_to_page()
625 trace_spapr_vlan_add_rxbuf_to_page(dev->add_buf_ptr, dev->rx_bufs, buf); in spapr_vlan_add_rxbuf_to_page()
637 SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg); in h_add_logical_lan_buffer()
654 if (!dev->isopen) { in h_add_logical_lan_buffer()
658 if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) { in h_add_logical_lan_buffer()
667 dev->rx_bufs++; in h_add_logical_lan_buffer()
675 timer_mod(dev->rxp_timer, qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 500); in h_add_logical_lan_buffer()
687 SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg); in h_send_logical_lan()
701 trace_spapr_vlan_h_send_logical_lan_rxbufs(dev->rx_bufs); in h_send_logical_lan()
703 if (!dev->isopen) { in h_send_logical_lan()
744 qemu_send_packet(qemu_get_queue(dev->nic), lbuf, total_len); in h_send_logical_lan()
753 SpaprVioDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg); in h_multicast_ctrl()
769 SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg); in h_change_logical_lan_mac()
780 dev->nicconf.macaddr.a[ETH_ALEN - i - 1] = macaddr & 0xff; in h_change_logical_lan_mac()
784 qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a); in h_change_logical_lan_mac()
792 DEFINE_PROP_BIT("use-rx-buffer-pools", SpaprVioVlan,
801 return (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) != 0; in spapr_vlan_rx_buffer_pools_needed()
857 k->realize = spapr_vlan_realize; in spapr_vlan_class_init()
858 k->reset = spapr_vlan_reset; in spapr_vlan_class_init()
859 k->devnode = spapr_vlan_devnode; in spapr_vlan_class_init()
860 k->dt_name = "l-lan"; in spapr_vlan_class_init()
861 k->dt_type = "network"; in spapr_vlan_class_init()
862 k->dt_compatible = "IBM,l-lan"; in spapr_vlan_class_init()
863 k->signal_mask = 0x1; in spapr_vlan_class_init()
864 set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); in spapr_vlan_class_init()
866 k->rtce_window_size = 0x10000000; in spapr_vlan_class_init()
867 dc->vmsd = &vmstate_spapr_llan; in spapr_vlan_class_init()