net: Add layer 2 hardware acceleration operations for macvlan devices
[cascardo/linux.git] / include / linux / netdevice.h
index 27f62f7..15fa01c 100644 (file)
@@ -483,6 +483,7 @@ void napi_hash_del(struct napi_struct *napi);
  */
 static inline void napi_disable(struct napi_struct *n)
 {
+       might_sleep();
        set_bit(NAPI_STATE_DISABLE, &n->state);
        while (test_and_set_bit(NAPI_STATE_SCHED, &n->state))
                msleep(1);
@@ -961,6 +962,25 @@ struct netdev_phys_port_id {
  *     Called by vxlan to notify the driver about a UDP port and socket
  *     address family that vxlan is not listening to anymore. The operation
  *     is protected by the vxlan_net->sock_lock.
+ *
+ * void* (*ndo_dfwd_add_station)(struct net_device *pdev,
+ *                              struct net_device *dev)
+ *     Called by upper layer devices to accelerate switching or other
+ *     station functionality into hardware. 'pdev is the lowerdev
+ *     to use for the offload and 'dev' is the net device that will
+ *     back the offload. Returns a pointer to the private structure
+ *     the upper layer will maintain.
+ * void (*ndo_dfwd_del_station)(struct net_device *pdev, void *priv)
+ *     Called by upper layer device to delete the station created
+ *     by 'ndo_dfwd_add_station'. 'pdev' is the net device backing
+ *     the station and priv is the structure returned by the add
+ *     operation.
+ * netdev_tx_t (*ndo_dfwd_start_xmit)(struct sk_buff *skb,
+ *                                   struct net_device *dev,
+ *                                   void *priv);
+ *     Callback to use for xmit over the accelerated station. This
+ *     is used in place of ndo_start_xmit on accelerated net
+ *     devices.
  */
 struct net_device_ops {
        int                     (*ndo_init)(struct net_device *dev);
@@ -1097,6 +1117,15 @@ struct net_device_ops {
        void                    (*ndo_del_vxlan_port)(struct  net_device *dev,
                                                      sa_family_t sa_family,
                                                      __be16 port);
+
+       void*                   (*ndo_dfwd_add_station)(struct net_device *pdev,
+                                                       struct net_device *dev);
+       void                    (*ndo_dfwd_del_station)(struct net_device *pdev,
+                                                       void *priv);
+
+       netdev_tx_t             (*ndo_dfwd_start_xmit) (struct sk_buff *skb,
+                                                       struct net_device *dev,
+                                                       void *priv);
 };
 
 /*
@@ -1131,7 +1160,7 @@ struct net_device {
        unsigned long           mem_end;        /* shared mem end       */
        unsigned long           mem_start;      /* shared mem start     */
        unsigned long           base_addr;      /* device I/O address   */
-       unsigned int            irq;            /* device IRQ number    */
+       int                     irq;            /* device IRQ number    */
 
        /*
         *      Some hardware also needs these fields, but they are not
@@ -1194,6 +1223,7 @@ struct net_device {
        /* Management operations */
        const struct net_device_ops *netdev_ops;
        const struct ethtool_ops *ethtool_ops;
+       const struct forwarding_accel_ops *fwd_ops;
 
        /* Hardware header description */
        const struct header_ops *header_ops;
@@ -1799,6 +1829,7 @@ static inline void unregister_netdevice(struct net_device *dev)
 
 int netdev_refcnt_read(const struct net_device *dev);
 void free_netdev(struct net_device *dev);
+void netdev_freemem(struct net_device *dev);
 void synchronize_net(void);
 int init_dummy_netdev(struct net_device *dev);
 
@@ -2386,7 +2417,7 @@ int dev_change_carrier(struct net_device *, bool new_carrier);
 int dev_get_phys_port_id(struct net_device *dev,
                         struct netdev_phys_port_id *ppid);
 int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
-                       struct netdev_queue *txq);
+                       struct netdev_queue *txq, void *accel_priv);
 int dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
 
 extern int             netdev_budget;
@@ -2965,6 +2996,11 @@ static inline void netif_set_gso_max_size(struct net_device *dev,
        dev->gso_max_size = size;
 }
 
+static inline bool netif_is_macvlan(struct net_device *dev)
+{
+       return dev->priv_flags & IFF_MACVLAN;
+}
+
 static inline bool netif_is_bond_master(struct net_device *dev)
 {
        return dev->flags & IFF_MASTER && dev->priv_flags & IFF_BONDING;