- struct odp_vport_stats_req stats_req;
- struct vport *vport;
- int err;
-
- if (copy_from_user(&stats_req, ustats_req, sizeof(struct odp_vport_stats_req)))
- return -EFAULT;
-
- stats_req.devname[IFNAMSIZ - 1] = '\0';
-
- vport_lock();
-
- vport = vport_locate(stats_req.devname);
- if (!vport) {
- err = -ENODEV;
- goto out;
- }
-
- if (vport->ops->get_stats) {
- rcu_read_lock();
- err = vport->ops->get_stats(vport, &stats_req.stats);
- rcu_read_unlock();
-
- } else if (vport->ops->flags & VPORT_F_GEN_STATS) {
- int i;
-
- memset(&stats_req.stats, 0, sizeof(struct odp_vport_stats));
-
- for_each_possible_cpu(i) {
- const struct vport_percpu_stats *percpu_stats;
-
- percpu_stats = per_cpu_ptr(vport->percpu_stats, i);
- stats_req.stats.rx_bytes += percpu_stats->rx_bytes;
- stats_req.stats.rx_packets += percpu_stats->rx_packets;
- stats_req.stats.tx_bytes += percpu_stats->tx_bytes;
- stats_req.stats.tx_packets += percpu_stats->tx_packets;
- }
-
- spin_lock_bh(&vport->err_stats.lock);
-
- stats_req.stats.rx_dropped = vport->err_stats.rx_dropped;
- stats_req.stats.rx_errors = vport->err_stats.rx_errors
- + vport->err_stats.rx_frame_err
- + vport->err_stats.rx_over_err
- + vport->err_stats.rx_crc_err;
- stats_req.stats.rx_frame_err = vport->err_stats.rx_frame_err;
- stats_req.stats.rx_over_err = vport->err_stats.rx_over_err;
- stats_req.stats.rx_crc_err = vport->err_stats.rx_crc_err;
- stats_req.stats.tx_dropped = vport->err_stats.tx_dropped;
- stats_req.stats.tx_errors = vport->err_stats.tx_errors;
- stats_req.stats.collisions = vport->err_stats.collisions;
-
- spin_unlock_bh(&vport->err_stats.lock);
-
- err = 0;
- } else
- err = -EOPNOTSUPP;
-
-out:
- vport_unlock();
-
- if (!err)
- if (copy_to_user(ustats_req, &stats_req, sizeof(struct odp_vport_stats_req)))
- err = -EFAULT;
-
- return err;
-}
-
-/**
- * vport_ether_get - retrieve device Ethernet address (for userspace callers)
- *
- * @uvport_ether: Ethernet address request parameters.
- *
- * Retrieves the Ethernet address of the given device. This function is for
- * userspace callers and assumes no locks are held.
- */
-int
-vport_ether_get(struct odp_vport_ether __user *uvport_ether)
-{
- struct odp_vport_ether vport_ether;
- struct vport *vport;
- int err = 0;
-
- if (copy_from_user(&vport_ether, uvport_ether, sizeof(struct odp_vport_ether)))
- return -EFAULT;
-
- vport_ether.devname[IFNAMSIZ - 1] = '\0';
-
- vport_lock();
-
- vport = vport_locate(vport_ether.devname);
- if (!vport) {
- err = -ENODEV;
- goto out;
- }
-
- rcu_read_lock();
- memcpy(vport_ether.ether_addr, vport_get_addr(vport), ETH_ALEN);
- rcu_read_unlock();
-
-out:
- vport_unlock();
-
- if (!err)
- if (copy_to_user(uvport_ether, &vport_ether, sizeof(struct odp_vport_ether)))
- err = -EFAULT;
-
- return err;
-}
-
-/**
- * vport_ether_set - set device Ethernet address (for userspace callers)
- *
- * @uvport_ether: Ethernet address request parameters.
- *
- * Sets the Ethernet address of the given device. Some devices may not support
- * setting the Ethernet address, in which case the result will always be
- * -EOPNOTSUPP. This function is for userspace callers and assumes no locks
- * are held.
- */
-int
-vport_ether_set(struct odp_vport_ether __user *uvport_ether)
-{
- struct odp_vport_ether vport_ether;
- struct vport *vport;
- int err;
-
- if (copy_from_user(&vport_ether, uvport_ether, sizeof(struct odp_vport_ether)))
- return -EFAULT;
-
- vport_ether.devname[IFNAMSIZ - 1] = '\0';
-
- rtnl_lock();
- vport_lock();
-
- vport = vport_locate(vport_ether.devname);
- if (!vport) {
- err = -ENODEV;
- goto out;
- }
-
- err = vport_set_addr(vport, vport_ether.ether_addr);
-
-out:
- vport_unlock();
- rtnl_unlock();
- return err;
-}
-
-/**
- * vport_mut_get - retrieve device MTU (for userspace callers)
- *
- * @uvport_mtu: MTU request parameters.
- *
- * Retrieves the MTU of the given device. This function is for userspace
- * callers and assumes no locks are held.
- */
-int
-vport_mtu_get(struct odp_vport_mtu __user *uvport_mtu)
-{
- struct odp_vport_mtu vport_mtu;
- struct vport *vport;
- int err = 0;
-
- if (copy_from_user(&vport_mtu, uvport_mtu, sizeof(struct odp_vport_mtu)))
- return -EFAULT;
-
- vport_mtu.devname[IFNAMSIZ - 1] = '\0';
-
- vport_lock();
-
- vport = vport_locate(vport_mtu.devname);
- if (!vport) {
- err = -ENODEV;
- goto out;
- }
-
- vport_mtu.mtu = vport_get_mtu(vport);
-
-out:
- vport_unlock();
-
- if (!err)
- if (copy_to_user(uvport_mtu, &vport_mtu, sizeof(struct odp_vport_mtu)))
- err = -EFAULT;
-
- return err;
-}
-
-/**
- * vport_mtu_set - set device MTU (for userspace callers)
- *
- * @uvport_mtu: MTU request parameters.
- *
- * Sets the MTU of the given device. Some devices may not support setting the
- * MTU, in which case the result will always be -EOPNOTSUPP. This function is
- * for userspace callers and assumes no locks are held.
- */
-int
-vport_mtu_set(struct odp_vport_mtu __user *uvport_mtu)
-{
- struct odp_vport_mtu vport_mtu;
- struct vport *vport;
- int err;
-
- if (copy_from_user(&vport_mtu, uvport_mtu, sizeof(struct odp_vport_mtu)))
- return -EFAULT;
-
- vport_mtu.devname[IFNAMSIZ - 1] = '\0';
-
- rtnl_lock();
- vport_lock();
-
- vport = vport_locate(vport_mtu.devname);
- if (!vport) {
- err = -ENODEV;
- goto out;
- }
-
- err = vport_set_mtu(vport, vport_mtu.mtu);
-
-out:
- vport_unlock();
- rtnl_unlock();
- return err;
-}
-
-static struct hlist_head *
-hash_bucket(const char *name)
-{
- unsigned int hash = full_name_hash(name, strlen(name));