/* Detach the netdev so tasks would not attempt to access it */
        mutex_lock(&mdev->state_lock);
        mdev->pndev[priv->port] = NULL;
+       mdev->upper[priv->port] = NULL;
        mutex_unlock(&mdev->state_lock);
 
        mlx4_en_free_resources(priv);
 #endif
 };
 
+struct mlx4_en_bond {
+       struct work_struct work;
+       struct mlx4_en_priv *priv;
+       int is_bonded;
+       struct mlx4_port_map port_map;
+};
+
+static void mlx4_en_bond_work(struct work_struct *work)
+{
+       struct mlx4_en_bond *bond = container_of(work,
+                                                    struct mlx4_en_bond,
+                                                    work);
+       int err = 0;
+       struct mlx4_dev *dev = bond->priv->mdev->dev;
+
+       if (bond->is_bonded) {
+               if (!mlx4_is_bonded(dev)) {
+                       err = mlx4_bond(dev);
+                       if (err)
+                               en_err(bond->priv, "Fail to bond device\n");
+               }
+               if (!err) {
+                       err = mlx4_port_map_set(dev, &bond->port_map);
+                       if (err)
+                               en_err(bond->priv, "Fail to set port map [%d][%d]: %d\n",
+                                      bond->port_map.port1,
+                                      bond->port_map.port2,
+                                      err);
+               }
+       } else if (mlx4_is_bonded(dev)) {
+               err = mlx4_unbond(dev);
+               if (err)
+                       en_err(bond->priv, "Fail to unbond device\n");
+       }
+       dev_put(bond->priv->dev);
+       kfree(bond);
+}
+
+static int mlx4_en_queue_bond_work(struct mlx4_en_priv *priv, int is_bonded,
+                                  u8 v2p_p1, u8 v2p_p2)
+{
+       struct mlx4_en_bond *bond = NULL;
+
+       bond = kzalloc(sizeof(*bond), GFP_ATOMIC);
+       if (!bond)
+               return -ENOMEM;
+
+       INIT_WORK(&bond->work, mlx4_en_bond_work);
+       bond->priv = priv;
+       bond->is_bonded = is_bonded;
+       bond->port_map.port1 = v2p_p1;
+       bond->port_map.port2 = v2p_p2;
+       dev_hold(priv->dev);
+       queue_work(priv->mdev->workqueue, &bond->work);
+       return 0;
+}
+
+int mlx4_en_netdev_event(struct notifier_block *this,
+                        unsigned long event, void *ptr)
+{
+       struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
+       u8 port = 0;
+       struct mlx4_en_dev *mdev;
+       struct mlx4_dev *dev;
+       int i, num_eth_ports = 0;
+       bool do_bond = true;
+       struct mlx4_en_priv *priv;
+       u8 v2p_port1 = 0;
+       u8 v2p_port2 = 0;
+
+       if (!net_eq(dev_net(ndev), &init_net))
+               return NOTIFY_DONE;
+
+       mdev = container_of(this, struct mlx4_en_dev, nb);
+       dev = mdev->dev;
+
+       /* Go into this mode only when two network devices set on two ports
+        * of the same mlx4 device are slaves of the same bonding master
+        */
+       mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) {
+               ++num_eth_ports;
+               if (!port && (mdev->pndev[i] == ndev))
+                       port = i;
+               mdev->upper[i] = mdev->pndev[i] ?
+                       netdev_master_upper_dev_get(mdev->pndev[i]) : NULL;
+               /* condition not met: network device is a slave */
+               if (!mdev->upper[i])
+                       do_bond = false;
+               if (num_eth_ports < 2)
+                       continue;
+               /* condition not met: same master */
+               if (mdev->upper[i] != mdev->upper[i-1])
+                       do_bond = false;
+       }
+       /* condition not met: 2 salves */
+       do_bond = (num_eth_ports ==  2) ? do_bond : false;
+
+       /* handle only events that come with enough info */
+       if ((do_bond && (event != NETDEV_BONDING_INFO)) || !port)
+               return NOTIFY_DONE;
+
+       priv = netdev_priv(ndev);
+       if (do_bond) {
+               struct netdev_notifier_bonding_info *notifier_info = ptr;
+               struct netdev_bonding_info *bonding_info =
+                       ¬ifier_info->bonding_info;
+
+               /* required mode 1, 2 or 4 */
+               if ((bonding_info->master.bond_mode != BOND_MODE_ACTIVEBACKUP) &&
+                   (bonding_info->master.bond_mode != BOND_MODE_XOR) &&
+                   (bonding_info->master.bond_mode != BOND_MODE_8023AD))
+                       do_bond = false;
+
+               /* require exactly 2 slaves */
+               if (bonding_info->master.num_slaves != 2)
+                       do_bond = false;
+
+               /* calc v2p */
+               if (do_bond) {
+                       if (bonding_info->master.bond_mode ==
+                           BOND_MODE_ACTIVEBACKUP) {
+                               /* in active-backup mode virtual ports are
+                                * mapped to the physical port of the active
+                                * slave */
+                               if (bonding_info->slave.state ==
+                                   BOND_STATE_BACKUP) {
+                                       if (port == 1) {
+                                               v2p_port1 = 2;
+                                               v2p_port2 = 2;
+                                       } else {
+                                               v2p_port1 = 1;
+                                               v2p_port2 = 1;
+                                       }
+                               } else { /* BOND_STATE_ACTIVE */
+                                       if (port == 1) {
+                                               v2p_port1 = 1;
+                                               v2p_port2 = 1;
+                                       } else {
+                                               v2p_port1 = 2;
+                                               v2p_port2 = 2;
+                                       }
+                               }
+                       } else { /* Active-Active */
+                               /* in active-active mode a virtual port is
+                                * mapped to the native physical port if and only
+                                * if the physical port is up */
+                               __s8 link = bonding_info->slave.link;
+
+                               if (port == 1)
+                                       v2p_port2 = 2;
+                               else
+                                       v2p_port1 = 1;
+                               if ((link == BOND_LINK_UP) ||
+                                   (link == BOND_LINK_FAIL)) {
+                                       if (port == 1)
+                                               v2p_port1 = 1;
+                                       else
+                                               v2p_port2 = 2;
+                               } else { /* BOND_LINK_DOWN || BOND_LINK_BACK */
+                                       if (port == 1)
+                                               v2p_port1 = 2;
+                                       else
+                                               v2p_port2 = 1;
+                               }
+                       }
+               }
+       }
+
+       mlx4_en_queue_bond_work(priv, do_bond,
+                               v2p_port1, v2p_port2);
+
+       return NOTIFY_DONE;
+}
+
 int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
                        struct mlx4_en_port_profile *prof)
 {
        }
 
        mdev->pndev[port] = dev;
+       mdev->upper[port] = NULL;
 
        netif_carrier_off(dev);
        mlx4_en_set_default_moderation(priv);