static struct i40e_client *registered_client;
 static LIST_HEAD(i40e_devices);
 static DEFINE_MUTEX(i40e_device_mutex);
+DEFINE_IDA(i40e_client_ida);
 
 static int i40e_client_virtchnl_send(struct i40e_info *ldev,
                                     struct i40e_client *client,
        cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector];
 }
 
+static void i40e_auxiliary_dev_release(struct device *dev)
+{
+       struct i40e_auxiliary_device *i40e_aux_dev =
+                       container_of(dev, struct i40e_auxiliary_device, aux_dev.dev);
+
+       ida_free(&i40e_client_ida, i40e_aux_dev->aux_dev.id);
+       kfree(i40e_aux_dev);
+}
+
+static int i40e_register_auxiliary_dev(struct i40e_info *ldev, const char *name)
+{
+       struct i40e_auxiliary_device *i40e_aux_dev;
+       struct pci_dev *pdev = ldev->pcidev;
+       struct auxiliary_device *aux_dev;
+       int ret;
+
+       i40e_aux_dev = kzalloc(sizeof(*i40e_aux_dev), GFP_KERNEL);
+       if (!i40e_aux_dev)
+               return -ENOMEM;
+
+       i40e_aux_dev->ldev = ldev;
+
+       aux_dev = &i40e_aux_dev->aux_dev;
+       aux_dev->name = name;
+       aux_dev->dev.parent = &pdev->dev;
+       aux_dev->dev.release = i40e_auxiliary_dev_release;
+       ldev->aux_dev = aux_dev;
+
+       ret = ida_alloc(&i40e_client_ida, GFP_KERNEL);
+       if (ret < 0) {
+               kfree(i40e_aux_dev);
+               return ret;
+       }
+       aux_dev->id = ret;
+
+       ret = auxiliary_device_init(aux_dev);
+       if (ret < 0) {
+               ida_free(&i40e_client_ida, aux_dev->id);
+               kfree(i40e_aux_dev);
+               return ret;
+       }
+
+       ret = auxiliary_device_add(aux_dev);
+       if (ret) {
+               auxiliary_device_uninit(aux_dev);
+               return ret;
+       }
+
+       return ret;
+}
+
 /**
  * i40e_client_add_instance - add a client instance struct to the instance list
  * @pf: pointer to the board struct
        struct netdev_hw_addr *mac = NULL;
        struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
 
-       if (!registered_client || pf->cinst)
-               return;
-
        cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
        if (!cdev)
                return;
        cdev->lan_info.fw_build = pf->hw.aq.fw_build;
        set_bit(__I40E_CLIENT_INSTANCE_NONE, &cdev->state);
 
-       if (i40e_client_get_params(vsi, &cdev->lan_info.params)) {
-               kfree(cdev);
-               cdev = NULL;
-               return;
-       }
+       if (i40e_client_get_params(vsi, &cdev->lan_info.params))
+               goto free_cdev;
 
        mac = list_first_entry(&cdev->lan_info.netdev->dev_addrs.list,
                               struct netdev_hw_addr, list);
        cdev->client = registered_client;
        pf->cinst = cdev;
 
-       i40e_client_update_msix_info(pf);
+       cdev->lan_info.msix_count = pf->num_iwarp_msix;
+       cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector];
+
+       if (i40e_register_auxiliary_dev(&cdev->lan_info, "iwarp"))
+               goto free_cdev;
+
+       return;
+
+free_cdev:
+       kfree(cdev);
+       pf->cinst = NULL;
 }
 
 /**
  **/
 void i40e_client_subtask(struct i40e_pf *pf)
 {
-       struct i40e_client *client = registered_client;
+       struct i40e_client *client;
        struct i40e_client_instance *cdev;
        struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
        int ret = 0;
            test_bit(__I40E_CONFIG_BUSY, pf->state))
                return;
 
-       if (!client || !cdev)
+       if (!cdev || !cdev->client)
                return;
 
+       client = cdev->client;
+
        /* Here we handle client opens. If the client is down, and
         * the netdev is registered, then open the client.
         */
                 pf->hw.pf_id, pf->hw.bus.bus_id,
                 pf->hw.bus.device, pf->hw.bus.func);
 
-       /* If a client has already been registered, we need to add an instance
-        * of it to our new LAN device.
-        */
-       if (registered_client)
-               i40e_client_add_instance(pf);
+       i40e_client_add_instance(pf);
 
-       /* Since in some cases register may have happened before a device gets
-        * added, we can schedule a subtask to go initiate the clients if
-        * they can be launched at probe time.
-        */
        set_bit(__I40E_CLIENT_SERVICE_REQUESTED, pf->state);
        i40e_service_event_schedule(pf);
 
  **/
 int i40e_lan_del_device(struct i40e_pf *pf)
 {
+       struct auxiliary_device *aux_dev = pf->cinst->lan_info.aux_dev;
        struct i40e_device *ldev, *tmp;
        int ret = -ENODEV;
 
+       auxiliary_device_delete(aux_dev);
+       auxiliary_device_uninit(aux_dev);
+
        /* First, remove any client instance. */
        i40e_client_del_instance(pf);
 
        return err;
 }
 
+void i40e_client_device_register(struct i40e_info *ldev, struct i40e_client *client)
+{
+       struct i40e_pf *pf = ldev->pf;
+
+       pf->cinst->client = client;
+       set_bit(__I40E_CLIENT_SERVICE_REQUESTED, pf->state);
+       i40e_service_event_schedule(pf);
+}
+EXPORT_SYMBOL_GPL(i40e_client_device_register);
+
+void i40e_client_device_unregister(struct i40e_info *ldev)
+{
+       struct i40e_pf *pf = ldev->pf;
+       struct i40e_client_instance *cdev = pf->cinst;
+
+       if (!cdev)
+               return;
+
+       while (test_and_set_bit(__I40E_SERVICE_SCHED, pf->state))
+               usleep_range(500, 1000);
+
+       if (test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) {
+               cdev->client->ops->close(&cdev->lan_info, cdev->client, false);
+               clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state);
+               i40e_client_release_qvlist(&cdev->lan_info);
+       }
+
+       pf->cinst->client = NULL;
+       clear_bit(__I40E_SERVICE_SCHED, pf->state);
+}
+EXPORT_SYMBOL_GPL(i40e_client_device_unregister);
+
+/* Retain these legacy global registration/unregistration calls till i40iw is
+ * removed from the kernel. The irdma unified driver does not use these
+ * exported symbols.
+ */
 /**
  * i40e_register_client - Register a i40e client driver with the L2 driver
  * @client: pointer to the i40e_client struct