mlx5_destroy_flow_table(ndev->rxft);
}
-static virtio_net_ctrl_ack handle_ctrl_mac(struct mlx5_vdpa_dev *mvdev, u8 cmd)
+static int mlx5_vdpa_change_mac(struct mlx5_vdpa_net *ndev,
+ struct mlx5_core_dev *pfmdev,
+ const u8 *new_mac)
{
- struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
- struct mlx5_control_vq *cvq = &mvdev->cvq;
- virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
- struct mlx5_core_dev *pfmdev;
- size_t read;
- u8 mac[ETH_ALEN], mac_back[ETH_ALEN];
+ struct mlx5_vdpa_dev *mvdev = &ndev->mvdev;
+ u8 old_mac[ETH_ALEN];
- pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev));
- switch (cmd) {
- case VIRTIO_NET_CTRL_MAC_ADDR_SET:
- read = vringh_iov_pull_iotlb(&cvq->vring, &cvq->riov, (void *)mac, ETH_ALEN);
- if (read != ETH_ALEN)
- break;
+ if (is_zero_ether_addr(new_mac))
+ return -EINVAL;
- if (!memcmp(ndev->config.mac, mac, 6)) {
- status = VIRTIO_NET_OK;
- break;
+ if (!is_zero_ether_addr(ndev->config.mac)) {
+ if (mlx5_mpfs_del_mac(pfmdev, ndev->config.mac)) {
+ mlx5_vdpa_warn(mvdev, "failed to delete old MAC %pM from MPFS table\n",
+ ndev->config.mac);
+ return -EIO;
}
+ }
- if (is_zero_ether_addr(mac))
- break;
+ if (mlx5_mpfs_add_mac(pfmdev, (u8 *)new_mac)) {
+ mlx5_vdpa_warn(mvdev, "failed to insert new MAC %pM into MPFS table\n",
+ new_mac);
+ return -EIO;
+ }
- if (!is_zero_ether_addr(ndev->config.mac)) {
- if (mlx5_mpfs_del_mac(pfmdev, ndev->config.mac)) {
- mlx5_vdpa_warn(mvdev, "failed to delete old MAC %pM from MPFS table\n",
- ndev->config.mac);
- break;
- }
- }
+ /* backup the original mac address so that if failed to add the forward rules
+ * we could restore it
+ */
+ ether_addr_copy(old_mac, ndev->config.mac);
- if (mlx5_mpfs_add_mac(pfmdev, mac)) {
- mlx5_vdpa_warn(mvdev, "failed to insert new MAC %pM into MPFS table\n",
- mac);
- break;
- }
+ ether_addr_copy(ndev->config.mac, new_mac);
- /* backup the original mac address so that if failed to add the forward rules
- * we could restore it
- */
- memcpy(mac_back, ndev->config.mac, ETH_ALEN);
+ /* Need recreate the flow table entry, so that the packet could forward back
+ */
+ mac_vlan_del(ndev, old_mac, 0, false);
- memcpy(ndev->config.mac, mac, ETH_ALEN);
+ if (mac_vlan_add(ndev, ndev->config.mac, 0, false)) {
+ mlx5_vdpa_warn(mvdev, "failed to insert forward rules, try to restore\n");
- /* Need recreate the flow table entry, so that the packet could forward back
+ /* Although it hardly run here, we still need double check */
+ if (is_zero_ether_addr(old_mac)) {
+ mlx5_vdpa_warn(mvdev, "restore mac failed: Original MAC is zero\n");
+ return -EIO;
+ }
+
+ /* Try to restore original mac address to MFPS table, and try to restore
+ * the forward rule entry.
*/
- mac_vlan_del(ndev, mac_back, 0, false);
+ if (mlx5_mpfs_del_mac(pfmdev, ndev->config.mac)) {
+ mlx5_vdpa_warn(mvdev, "restore mac failed: delete MAC %pM from MPFS table failed\n",
+ ndev->config.mac);
+ }
- if (mac_vlan_add(ndev, ndev->config.mac, 0, false)) {
- mlx5_vdpa_warn(mvdev, "failed to insert forward rules, try to restore\n");
+ if (mlx5_mpfs_add_mac(pfmdev, old_mac)) {
+ mlx5_vdpa_warn(mvdev, "restore mac failed: insert old MAC %pM into MPFS table failed\n",
+ old_mac);
+ }
- /* Although it hardly run here, we still need double check */
- if (is_zero_ether_addr(mac_back)) {
- mlx5_vdpa_warn(mvdev, "restore mac failed: Original MAC is zero\n");
- break;
- }
+ ether_addr_copy(ndev->config.mac, old_mac);
- /* Try to restore original mac address to MFPS table, and try to restore
- * the forward rule entry.
- */
- if (mlx5_mpfs_del_mac(pfmdev, ndev->config.mac)) {
- mlx5_vdpa_warn(mvdev, "restore mac failed: delete MAC %pM from MPFS table failed\n",
- ndev->config.mac);
- }
+ if (mac_vlan_add(ndev, ndev->config.mac, 0, false))
+ mlx5_vdpa_warn(mvdev, "restore forward rules failed: insert forward rules failed\n");
- if (mlx5_mpfs_add_mac(pfmdev, mac_back)) {
- mlx5_vdpa_warn(mvdev, "restore mac failed: insert old MAC %pM into MPFS table failed\n",
- mac_back);
- }
+ return -EIO;
+ }
- memcpy(ndev->config.mac, mac_back, ETH_ALEN);
+ return 0;
+}
- if (mac_vlan_add(ndev, ndev->config.mac, 0, false))
- mlx5_vdpa_warn(mvdev, "restore forward rules failed: insert forward rules failed\n");
+static virtio_net_ctrl_ack handle_ctrl_mac(struct mlx5_vdpa_dev *mvdev, u8 cmd)
+{
+ struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
+ struct mlx5_control_vq *cvq = &mvdev->cvq;
+ virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
+ struct mlx5_core_dev *pfmdev;
+ size_t read;
+ u8 mac[ETH_ALEN];
+ pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev));
+ switch (cmd) {
+ case VIRTIO_NET_CTRL_MAC_ADDR_SET:
+ read = vringh_iov_pull_iotlb(&cvq->vring, &cvq->riov,
+ (void *)mac, ETH_ALEN);
+ if (read != ETH_ALEN)
break;
- }
- status = VIRTIO_NET_OK;
+ if (!memcmp(ndev->config.mac, mac, 6)) {
+ status = VIRTIO_NET_OK;
+ break;
+ }
+ status = mlx5_vdpa_change_mac(ndev, pfmdev, mac) ? VIRTIO_NET_ERR :
+ VIRTIO_NET_OK;
break;
default: