| 1095 | } |
| 1096 | |
| 1097 | static int |
| 1098 | virtio_ethdev_negotiate_features(struct virtio_hw *hw, uint64_t req_features) |
| 1099 | { |
| 1100 | uint64_t host_features; |
| 1101 | |
| 1102 | /* Prepare guest_features: feature that driver wants to support */ |
| 1103 | PMD_INIT_LOG(DEBUG, "guest_features before negotiate = %" PRIx64, |
| 1104 | req_features); |
| 1105 | |
| 1106 | /* Read device(host) feature bits */ |
| 1107 | host_features = VIRTIO_OPS(hw)->get_features(hw); |
| 1108 | PMD_INIT_LOG(DEBUG, "host_features before negotiate = %" PRIx64, |
| 1109 | host_features); |
| 1110 | |
| 1111 | /* If supported, ensure MTU value is valid before acknowledging it. */ |
| 1112 | if (host_features & req_features & (1ULL << VIRTIO_NET_F_MTU)) { |
| 1113 | struct virtio_net_config config; |
| 1114 | |
| 1115 | virtio_read_dev_config(hw, |
| 1116 | offsetof(struct virtio_net_config, mtu), |
| 1117 | &config.mtu, sizeof(config.mtu)); |
| 1118 | |
| 1119 | if (config.mtu < RTE_ETHER_MIN_MTU) |
| 1120 | req_features &= ~(1ULL << VIRTIO_NET_F_MTU); |
| 1121 | } |
| 1122 | |
| 1123 | /* |
| 1124 | * Negotiate features: Subset of device feature bits are written back |
| 1125 | * guest feature bits. |
| 1126 | */ |
| 1127 | hw->guest_features = req_features; |
| 1128 | hw->guest_features = virtio_negotiate_features(hw, host_features); |
| 1129 | PMD_INIT_LOG(DEBUG, "features after negotiate = %" PRIx64, |
| 1130 | hw->guest_features); |
| 1131 | |
| 1132 | if (VIRTIO_OPS(hw)->features_ok(hw) < 0) |
| 1133 | return -1; |
| 1134 | |
| 1135 | if (virtio_with_feature(hw, VIRTIO_F_VERSION_1)) { |
| 1136 | virtio_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK); |
| 1137 | |
| 1138 | if (!(virtio_get_status(hw) & VIRTIO_CONFIG_STATUS_FEATURES_OK)) { |
| 1139 | PMD_INIT_LOG(ERR, "Failed to set FEATURES_OK status!"); |
| 1140 | return -1; |
| 1141 | } |
| 1142 | } |
| 1143 | |
| 1144 | hw->req_guest_features = req_features; |
| 1145 | |
| 1146 | return 0; |
| 1147 | } |
| 1148 | |
| 1149 | static void |
| 1150 | virtio_notify_peers(struct rte_eth_dev *dev) |
no test coverage detected