#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/percpu.h>
-#include <linux/preempt.h>
#include <linux/rcupdate.h>
#include <linux/skbuff.h>
-#include <linux/workqueue.h>
#include "datapath.h"
#include "openvswitch/internal_dev.h"
+#include "vport-generic.h"
#include "vport-internal_dev.h"
#include "vport-netdev.h"
return 0;
}
-/* Not reentrant (because it is called with BHs disabled), but may be called
- * simultaneously on different CPUs. */
+/* Called with rcu_read_lock and bottom-halves disabled. */
static int internal_dev_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct internal_dev *internal_dev = internal_dev_priv(netdev);
lb_stats->tx_bytes += skb->len;
skb_reset_mac_header(skb);
- rcu_read_lock_bh();
+ compute_ip_summed(skb, true);
+
vport_receive(vport, skb);
- rcu_read_unlock_bh();
return 0;
}
}
static struct ethtool_ops internal_dev_ethtool_ops = {
- .get_drvinfo = internal_dev_getinfo,
- .get_link = ethtool_op_get_link,
- .get_sg = ethtool_op_get_sg,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .get_tso = ethtool_op_get_tso,
+ .get_drvinfo = internal_dev_getinfo,
+ .get_link = ethtool_op_get_link,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_hw_csum,
+ .get_tso = ethtool_op_get_tso,
+ .set_tso = ethtool_op_set_tso,
};
static int internal_dev_change_mtu(struct net_device *netdev, int new_mtu)
return -EINVAL;
if (dp_port) {
- int min_mtu;
-
- mutex_lock(&dp_port->dp->mutex);
- min_mtu = dp_min_mtu(dp_port->dp);
- mutex_unlock(&dp_port->dp->mutex);
-
- if (new_mtu > min_mtu)
+ if (new_mtu > dp_min_mtu(dp_port->dp))
return -EINVAL;
}
netdev->tx_queue_len = 0;
netdev->flags = IFF_BROADCAST | IFF_MULTICAST;
- netdev->features = NETIF_F_LLTX; /* XXX other features? */
+ netdev->features = NETIF_F_LLTX | NETIF_F_SG | NETIF_F_HIGHDMA
+ | NETIF_F_HW_CSUM | NETIF_F_TSO;
- vport_gen_ether_addr(netdev->dev_addr);
+ vport_gen_rand_ether_addr(netdev->dev_addr);
}
static struct vport *
netif_rx_ni(skb);
netdev->last_rx = jiffies;
- preempt_disable();
+ local_bh_disable();
lb_stats = per_cpu_ptr(internal_dev->lstats, smp_processor_id());
lb_stats->rx_packets++;
lb_stats->rx_bytes += len;
- preempt_enable();
+ local_bh_enable();
return len;
}