Revision 1773d9ee hw/net/virtio-net.c
b/hw/net/virtio-net.c | ||
---|---|---|
1273 | 1273 |
n->config_size = config_size; |
1274 | 1274 |
} |
1275 | 1275 |
|
1276 |
static VirtIODevice *virtio_net_common_init(DeviceState *dev, NICConf *conf, |
|
1277 |
virtio_net_conf *net, |
|
1278 |
uint32_t host_features, |
|
1279 |
VirtIONet **pn) |
|
1276 |
static int virtio_net_device_init(VirtIODevice *vdev) |
|
1280 | 1277 |
{ |
1281 |
VirtIONet *n = *pn; |
|
1282 |
VirtIODevice *vdev = VIRTIO_DEVICE(dev); |
|
1283 |
int i, config_size = 0; |
|
1278 |
int i; |
|
1284 | 1279 |
|
1285 |
/* |
|
1286 |
* We have two cases here: the old virtio-net-pci device, and the |
|
1287 |
* refactored virtio-net. |
|
1288 |
*/ |
|
1289 |
if (n == NULL) { |
|
1290 |
/* virtio-net-pci */ |
|
1291 |
for (i = 0; feature_sizes[i].flags != 0; i++) { |
|
1292 |
if (host_features & feature_sizes[i].flags) { |
|
1293 |
config_size = MAX(feature_sizes[i].end, config_size); |
|
1294 |
} |
|
1295 |
} |
|
1296 |
n = (VirtIONet *)virtio_common_init("virtio-net", VIRTIO_ID_NET, |
|
1297 |
config_size, sizeof(VirtIONet)); |
|
1298 |
n->config_size = config_size; |
|
1299 |
} else { |
|
1300 |
/* virtio-net */ |
|
1301 |
virtio_init(VIRTIO_DEVICE(n), "virtio-net", VIRTIO_ID_NET, |
|
1302 |
n->config_size); |
|
1303 |
} |
|
1280 |
DeviceState *qdev = DEVICE(vdev); |
|
1281 |
VirtIONet *n = VIRTIO_NET(vdev); |
|
1282 |
|
|
1283 |
virtio_init(VIRTIO_DEVICE(n), "virtio-net", VIRTIO_ID_NET, |
|
1284 |
n->config_size); |
|
1304 | 1285 |
|
1305 | 1286 |
vdev->get_config = virtio_net_get_config; |
1306 | 1287 |
vdev->set_config = virtio_net_set_config; |
... | ... | |
1311 | 1292 |
vdev->set_status = virtio_net_set_status; |
1312 | 1293 |
vdev->guest_notifier_mask = virtio_net_guest_notifier_mask; |
1313 | 1294 |
vdev->guest_notifier_pending = virtio_net_guest_notifier_pending; |
1314 |
n->max_queues = MAX(conf->queues, 1);
|
|
1295 |
n->max_queues = MAX(n->nic_conf.queues, 1);
|
|
1315 | 1296 |
n->vqs = g_malloc0(sizeof(VirtIONetQueue) * n->max_queues); |
1316 | 1297 |
n->vqs[0].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx); |
1317 | 1298 |
n->curr_queues = 1; |
1318 | 1299 |
n->vqs[0].n = n; |
1319 |
n->tx_timeout = net->txtimer;
|
|
1300 |
n->tx_timeout = n->net_conf.txtimer;
|
|
1320 | 1301 |
|
1321 |
if (net->tx && strcmp(net->tx, "timer") && strcmp(net->tx, "bh")) { |
|
1302 |
if (n->net_conf.tx && strcmp(n->net_conf.tx, "timer") |
|
1303 |
&& strcmp(n->net_conf.tx, "bh")) { |
|
1322 | 1304 |
error_report("virtio-net: " |
1323 | 1305 |
"Unknown option tx=%s, valid options: \"timer\" \"bh\"", |
1324 |
net->tx);
|
|
1306 |
n->net_conf.tx);
|
|
1325 | 1307 |
error_report("Defaulting to \"bh\""); |
1326 | 1308 |
} |
1327 | 1309 |
|
1328 |
if (net->tx && !strcmp(net->tx, "timer")) {
|
|
1310 |
if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) {
|
|
1329 | 1311 |
n->vqs[0].tx_vq = virtio_add_queue(vdev, 256, |
1330 | 1312 |
virtio_net_handle_tx_timer); |
1331 | 1313 |
n->vqs[0].tx_timer = qemu_new_timer_ns(vm_clock, virtio_net_tx_timer, |
... | ... | |
1336 | 1318 |
n->vqs[0].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[0]); |
1337 | 1319 |
} |
1338 | 1320 |
n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl); |
1339 |
qemu_macaddr_default_if_unset(&conf->macaddr);
|
|
1340 |
memcpy(&n->mac[0], &conf->macaddr, sizeof(n->mac));
|
|
1321 |
qemu_macaddr_default_if_unset(&n->nic_conf.macaddr);
|
|
1322 |
memcpy(&n->mac[0], &n->nic_conf.macaddr, sizeof(n->mac));
|
|
1341 | 1323 |
n->status = VIRTIO_NET_S_LINK_UP; |
1342 | 1324 |
|
1343 |
n->nic = qemu_new_nic(&net_virtio_info, conf, object_get_typename(OBJECT(dev)), dev->id, n); |
|
1325 |
n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf, |
|
1326 |
object_get_typename(OBJECT(qdev)), qdev->id, n); |
|
1344 | 1327 |
peer_test_vnet_hdr(n); |
1345 | 1328 |
if (peer_has_vnet_hdr(n)) { |
1346 | 1329 |
for (i = 0; i < n->max_queues; i++) { |
... | ... | |
1351 | 1334 |
n->host_hdr_len = 0; |
1352 | 1335 |
} |
1353 | 1336 |
|
1354 |
qemu_format_nic_info_str(qemu_get_queue(n->nic), conf->macaddr.a);
|
|
1337 |
qemu_format_nic_info_str(qemu_get_queue(n->nic), n->nic_conf.macaddr.a);
|
|
1355 | 1338 |
|
1356 | 1339 |
n->vqs[0].tx_waiting = 0; |
1357 |
n->tx_burst = net->txburst;
|
|
1340 |
n->tx_burst = n->net_conf.txburst;
|
|
1358 | 1341 |
virtio_net_set_mrg_rx_bufs(n, 0); |
1359 | 1342 |
n->promisc = 1; /* for compatibility */ |
1360 | 1343 |
|
... | ... | |
1362 | 1345 |
|
1363 | 1346 |
n->vlans = g_malloc0(MAX_VLAN >> 3); |
1364 | 1347 |
|
1365 |
n->qdev = dev; |
|
1366 |
register_savevm(dev, "virtio-net", -1, VIRTIO_NET_VM_VERSION, |
|
1348 |
n->qdev = qdev;
|
|
1349 |
register_savevm(qdev, "virtio-net", -1, VIRTIO_NET_VM_VERSION,
|
|
1367 | 1350 |
virtio_net_save, virtio_net_load, n); |
1368 | 1351 |
|
1369 |
add_boot_device_path(conf->bootindex, dev, "/ethernet-phy@0"); |
|
1370 |
|
|
1371 |
return vdev; |
|
1372 |
} |
|
1373 |
|
|
1374 |
VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf, |
|
1375 |
virtio_net_conf *net, uint32_t host_features) |
|
1376 |
{ |
|
1377 |
VirtIONet *n = NULL; |
|
1378 |
return virtio_net_common_init(dev, conf, net, host_features, &n); |
|
1379 |
} |
|
1380 |
|
|
1381 |
void virtio_net_exit(VirtIODevice *vdev) |
|
1382 |
{ |
|
1383 |
VirtIONet *n = VIRTIO_NET(vdev); |
|
1384 |
int i; |
|
1385 |
|
|
1386 |
/* This will stop vhost backend if appropriate. */ |
|
1387 |
virtio_net_set_status(vdev, 0); |
|
1388 |
|
|
1389 |
unregister_savevm(n->qdev, "virtio-net", n); |
|
1390 |
|
|
1391 |
g_free(n->mac_table.macs); |
|
1392 |
g_free(n->vlans); |
|
1393 |
|
|
1394 |
for (i = 0; i < n->max_queues; i++) { |
|
1395 |
VirtIONetQueue *q = &n->vqs[i]; |
|
1396 |
NetClientState *nc = qemu_get_subqueue(n->nic, i); |
|
1397 |
|
|
1398 |
qemu_purge_queued_packets(nc); |
|
1399 |
|
|
1400 |
if (q->tx_timer) { |
|
1401 |
qemu_del_timer(q->tx_timer); |
|
1402 |
qemu_free_timer(q->tx_timer); |
|
1403 |
} else { |
|
1404 |
qemu_bh_delete(q->tx_bh); |
|
1405 |
} |
|
1406 |
} |
|
1407 |
|
|
1408 |
g_free(n->vqs); |
|
1409 |
qemu_del_nic(n->nic); |
|
1410 |
virtio_cleanup(vdev); |
|
1411 |
} |
|
1412 |
|
|
1413 |
static int virtio_net_device_init(VirtIODevice *vdev) |
|
1414 |
{ |
|
1415 |
DeviceState *qdev = DEVICE(vdev); |
|
1416 |
VirtIONet *n = VIRTIO_NET(vdev); |
|
1417 |
|
|
1418 |
/* |
|
1419 |
* Initially, the new VirtIONet device will have a config size = |
|
1420 |
* sizeof(struct config), because we can't get host_features here. |
|
1421 |
*/ |
|
1422 |
if (virtio_net_common_init(qdev, &(n->nic_conf), |
|
1423 |
&(n->net_conf), 0, &n) == NULL) { |
|
1424 |
return -1; |
|
1425 |
} |
|
1352 |
add_boot_device_path(n->nic_conf.bootindex, qdev, "/ethernet-phy@0"); |
|
1426 | 1353 |
return 0; |
1427 | 1354 |
} |
1428 | 1355 |
|
Also available in: Unified diff