diff mbox series

[net-next,09/10] net: mhi_net: create default link via WWAN core

Message ID 20210615003016.477-10-ryazanov.s.a@gmail.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series net: WWAN link creation improvements | expand

Checks

Context Check Description
netdev/cover_letter success Link
netdev/fixes_present success Link
netdev/patch_count success Link
netdev/tree_selection success Clearly marked for net-next
netdev/subject_prefix success Link
netdev/cc_maintainers warning 1 maintainers not CCed: yangyingliang@huawei.com
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff success Link
netdev/module_param success Was 0 now: 0
netdev/build_32bit success Errors and warnings before: 1 this patch: 0
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/verify_fixes success Link
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 88 lines checked
netdev/build_allmodconfig_warn success Errors and warnings before: 1 this patch: 0
netdev/header_inline success Link

Commit Message

Sergey Ryazanov June 15, 2021, 12:30 a.m. UTC
Utilize the just introduced WWAN core feature to create a default netdev
for the default data channel. Since the netdev is now created via the
WWAN core, rely on it ability to destroy all child netdevs on ops
unregistering.

While at it, remove the RTNL lock acquiring hacks that were earlier used
to call addlink/dellink without holding the RTNL lock. Also make the
WWAN netdev ops structure static to make sparse happy.

Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
---
 drivers/net/mhi/net.c | 54 +++++--------------------------------------
 1 file changed, 6 insertions(+), 48 deletions(-)

Comments

Loic Poulain June 15, 2021, 7:17 a.m. UTC | #1
Hi Sergey,

On Tue, 15 Jun 2021 at 02:30, Sergey Ryazanov <ryazanov.s.a@gmail.com> wrote:
>
> Utilize the just introduced WWAN core feature to create a default netdev
> for the default data channel. Since the netdev is now created via the
> WWAN core, rely on it ability to destroy all child netdevs on ops
> unregistering.
>
> While at it, remove the RTNL lock acquiring hacks that were earlier used
> to call addlink/dellink without holding the RTNL lock. Also make the
> WWAN netdev ops structure static to make sparse happy.
>
> Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
> ---
>  drivers/net/mhi/net.c | 54 +++++--------------------------------------
>  1 file changed, 6 insertions(+), 48 deletions(-)
>
> diff --git a/drivers/net/mhi/net.c b/drivers/net/mhi/net.c
> index b003003cbd42..06253acecaa2 100644
> --- a/drivers/net/mhi/net.c
> +++ b/drivers/net/mhi/net.c
> @@ -342,10 +342,7 @@ static int mhi_net_newlink(void *ctxt, struct net_device *ndev, u32 if_id,
>         /* Number of transfer descriptors determines size of the queue */
>         mhi_netdev->rx_queue_sz = mhi_get_free_desc_count(mhi_dev, DMA_FROM_DEVICE);
>
> -       if (extack)
> -               err = register_netdevice(ndev);
> -       else
> -               err = register_netdev(ndev);
> +       err = register_netdevice(ndev);
>         if (err)
>                 goto out_err;
>
> @@ -370,10 +367,7 @@ static void mhi_net_dellink(void *ctxt, struct net_device *ndev,
>         struct mhi_net_dev *mhi_netdev = netdev_priv(ndev);
>         struct mhi_device *mhi_dev = ctxt;
>
> -       if (head)
> -               unregister_netdevice_queue(ndev, head);
> -       else
> -               unregister_netdev(ndev);
> +       unregister_netdevice_queue(ndev, head);
>
>         mhi_unprepare_from_transfer(mhi_dev);
>
> @@ -382,7 +376,7 @@ static void mhi_net_dellink(void *ctxt, struct net_device *ndev,
>         dev_set_drvdata(&mhi_dev->dev, NULL);
>  }
>
> -const struct wwan_ops mhi_wwan_ops = {
> +static const struct wwan_ops mhi_wwan_ops = {
>         .priv_size = sizeof(struct mhi_net_dev),
>         .setup = mhi_net_setup,
>         .newlink = mhi_net_newlink,
> @@ -392,55 +386,19 @@ const struct wwan_ops mhi_wwan_ops = {
>  static int mhi_net_probe(struct mhi_device *mhi_dev,
>                          const struct mhi_device_id *id)
>  {
> -       const struct mhi_device_info *info = (struct mhi_device_info *)id->driver_data;
>         struct mhi_controller *cntrl = mhi_dev->mhi_cntrl;
> -       struct net_device *ndev;
> -       int err;
> -
> -       err = wwan_register_ops(&cntrl->mhi_dev->dev, &mhi_wwan_ops, mhi_dev,
> -                               WWAN_NO_DEFAULT_LINK);
> -       if (err)
> -               return err;
> -
> -       if (!create_default_iface)
> -               return 0;
> -
> -       /* Create a default interface which is used as either RMNET real-dev,
> -        * MBIM link 0 or ip link 0)
> -        */
> -       ndev = alloc_netdev(sizeof(struct mhi_net_dev), info->netname,
> -                           NET_NAME_PREDICTABLE, mhi_net_setup);

I like the idea of the default link, but here we need to create the
netdev manually for several reasons:
- In case of QMAP/rmnet, this link is the lower netdev (transport
layer) and is not associated with any link id.
- In case of MBIM, it changes the netdev parent device from the MHI
dev to the WWAN dev, which (currently) breaks how ModemManager groups
ports/netdevs (based on bus).

For the last one, I don't think device hierarchy is considered as
UAPI, so we probably just need to add this new wwan link support to
user tools like MM. For the first one, I plan to split the mhi_net
driver into two different ones (mhi_net_qmap, mhi_net_mbim), and in
the case of qmap(rmnet) forward newlink/dellink call to rmnet
rtnetlink ops.

Regards,
Loic
Sergey Ryazanov June 20, 2021, 1:51 p.m. UTC | #2
Hi Loic,

CC Aleksander, as the talk drifts towards ModemManager.

On Tue, Jun 15, 2021 at 10:08 AM Loic Poulain <loic.poulain@linaro.org> wrote:
> On Tue, 15 Jun 2021 at 02:30, Sergey Ryazanov <ryazanov.s.a@gmail.com> wrote:
>> Utilize the just introduced WWAN core feature to create a default netdev
>> for the default data channel. Since the netdev is now created via the
>> WWAN core, rely on it ability to destroy all child netdevs on ops
>> unregistering.
>>
>> While at it, remove the RTNL lock acquiring hacks that were earlier used
>> to call addlink/dellink without holding the RTNL lock. Also make the
>> WWAN netdev ops structure static to make sparse happy.
>>
>> Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
>> ---
>>  drivers/net/mhi/net.c | 54 +++++--------------------------------------
>>  1 file changed, 6 insertions(+), 48 deletions(-)
>>
>> diff --git a/drivers/net/mhi/net.c b/drivers/net/mhi/net.c
>> index b003003cbd42..06253acecaa2 100644
>> --- a/drivers/net/mhi/net.c
>> +++ b/drivers/net/mhi/net.c
>> @@ -342,10 +342,7 @@ static int mhi_net_newlink(void *ctxt, struct net_device *ndev, u32 if_id,
>>         /* Number of transfer descriptors determines size of the queue */
>>         mhi_netdev->rx_queue_sz = mhi_get_free_desc_count(mhi_dev, DMA_FROM_DEVICE);
>>
>> -       if (extack)
>> -               err = register_netdevice(ndev);
>> -       else
>> -               err = register_netdev(ndev);
>> +       err = register_netdevice(ndev);
>>         if (err)
>>                 goto out_err;
>>
>> @@ -370,10 +367,7 @@ static void mhi_net_dellink(void *ctxt, struct net_device *ndev,
>>         struct mhi_net_dev *mhi_netdev = netdev_priv(ndev);
>>         struct mhi_device *mhi_dev = ctxt;
>>
>> -       if (head)
>> -               unregister_netdevice_queue(ndev, head);
>> -       else
>> -               unregister_netdev(ndev);
>> +       unregister_netdevice_queue(ndev, head);
>>
>>         mhi_unprepare_from_transfer(mhi_dev);
>>
>> @@ -382,7 +376,7 @@ static void mhi_net_dellink(void *ctxt, struct net_device *ndev,
>>         dev_set_drvdata(&mhi_dev->dev, NULL);
>>  }
>>
>> -const struct wwan_ops mhi_wwan_ops = {
>> +static const struct wwan_ops mhi_wwan_ops = {
>>         .priv_size = sizeof(struct mhi_net_dev),
>>         .setup = mhi_net_setup,
>>         .newlink = mhi_net_newlink,
>> @@ -392,55 +386,19 @@ const struct wwan_ops mhi_wwan_ops = {
>>  static int mhi_net_probe(struct mhi_device *mhi_dev,
>>                          const struct mhi_device_id *id)
>>  {
>> -       const struct mhi_device_info *info = (struct mhi_device_info *)id->driver_data;
>>         struct mhi_controller *cntrl = mhi_dev->mhi_cntrl;
>> -       struct net_device *ndev;
>> -       int err;
>> -
>> -       err = wwan_register_ops(&cntrl->mhi_dev->dev, &mhi_wwan_ops, mhi_dev,
>> -                               WWAN_NO_DEFAULT_LINK);
>> -       if (err)
>> -               return err;
>> -
>> -       if (!create_default_iface)
>> -               return 0;
>> -
>> -       /* Create a default interface which is used as either RMNET real-dev,
>> -        * MBIM link 0 or ip link 0)
>> -        */
>> -       ndev = alloc_netdev(sizeof(struct mhi_net_dev), info->netname,
>> -                           NET_NAME_PREDICTABLE, mhi_net_setup);
>
> I like the idea of the default link, but here we need to create the
> netdev manually for several reasons:
> - In case of QMAP/rmnet, this link is the lower netdev (transport
> layer) and is not associated with any link id.
> - In case of MBIM, it changes the netdev parent device from the MHI
> dev to the WWAN dev, which (currently) breaks how ModemManager groups
> ports/netdevs (based on bus).
>
> For the last one, I don't think device hierarchy is considered as
> UAPI, so we probably just need to add this new wwan link support to
> user tools like MM. For the first one, I plan to split the mhi_net
> driver into two different ones (mhi_net_qmap, mhi_net_mbim), and in
> the case of qmap(rmnet) forward newlink/dellink call to rmnet
> rtnetlink ops.

Looks like I missed the complexity of WWAN devices handling. Thank you
for pointing that out. Now I will drop this patch from the series.

Just curious, am I right to say that any network interface created
with wwan-core is not usable with ModemManager at the moment? AFAIU,
ModemManager is unable to bundle a control port and a netdev into a
common "modem" object, even if they both have the same parent Linux
device, just because that device is not a physical USB device.

--
Sergey
Loic Poulain June 21, 2021, 6:53 a.m. UTC | #3
Hi Sergey,

On Sun, 20 Jun 2021 at 15:51, Sergey Ryazanov <ryazanov.s.a@gmail.com> wrote:
>
> Hi Loic,
>
> CC Aleksander, as the talk drifts towards ModemManager.
>
> On Tue, Jun 15, 2021 at 10:08 AM Loic Poulain <loic.poulain@linaro.org> wrote:
> > On Tue, 15 Jun 2021 at 02:30, Sergey Ryazanov <ryazanov.s.a@gmail.com> wrote:
> >> Utilize the just introduced WWAN core feature to create a default netdev
> >> for the default data channel. Since the netdev is now created via the
> >> WWAN core, rely on it ability to destroy all child netdevs on ops
> >> unregistering.
> >>
> >> While at it, remove the RTNL lock acquiring hacks that were earlier used
> >> to call addlink/dellink without holding the RTNL lock. Also make the
> >> WWAN netdev ops structure static to make sparse happy.
> >>
> >> Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
> >> ---
> >>  drivers/net/mhi/net.c | 54 +++++--------------------------------------
> >>  1 file changed, 6 insertions(+), 48 deletions(-)
> >>
> >> diff --git a/drivers/net/mhi/net.c b/drivers/net/mhi/net.c
> >> index b003003cbd42..06253acecaa2 100644
> >> --- a/drivers/net/mhi/net.c
> >> +++ b/drivers/net/mhi/net.c
> >> @@ -342,10 +342,7 @@ static int mhi_net_newlink(void *ctxt, struct net_device *ndev, u32 if_id,
> >>         /* Number of transfer descriptors determines size of the queue */
> >>         mhi_netdev->rx_queue_sz = mhi_get_free_desc_count(mhi_dev, DMA_FROM_DEVICE);
> >>
> >> -       if (extack)
> >> -               err = register_netdevice(ndev);
> >> -       else
> >> -               err = register_netdev(ndev);
> >> +       err = register_netdevice(ndev);
> >>         if (err)
> >>                 goto out_err;
> >>
> >> @@ -370,10 +367,7 @@ static void mhi_net_dellink(void *ctxt, struct net_device *ndev,
> >>         struct mhi_net_dev *mhi_netdev = netdev_priv(ndev);
> >>         struct mhi_device *mhi_dev = ctxt;
> >>
> >> -       if (head)
> >> -               unregister_netdevice_queue(ndev, head);
> >> -       else
> >> -               unregister_netdev(ndev);
> >> +       unregister_netdevice_queue(ndev, head);
> >>
> >>         mhi_unprepare_from_transfer(mhi_dev);
> >>
> >> @@ -382,7 +376,7 @@ static void mhi_net_dellink(void *ctxt, struct net_device *ndev,
> >>         dev_set_drvdata(&mhi_dev->dev, NULL);
> >>  }
> >>
> >> -const struct wwan_ops mhi_wwan_ops = {
> >> +static const struct wwan_ops mhi_wwan_ops = {
> >>         .priv_size = sizeof(struct mhi_net_dev),
> >>         .setup = mhi_net_setup,
> >>         .newlink = mhi_net_newlink,
> >> @@ -392,55 +386,19 @@ const struct wwan_ops mhi_wwan_ops = {
> >>  static int mhi_net_probe(struct mhi_device *mhi_dev,
> >>                          const struct mhi_device_id *id)
> >>  {
> >> -       const struct mhi_device_info *info = (struct mhi_device_info *)id->driver_data;
> >>         struct mhi_controller *cntrl = mhi_dev->mhi_cntrl;
> >> -       struct net_device *ndev;
> >> -       int err;
> >> -
> >> -       err = wwan_register_ops(&cntrl->mhi_dev->dev, &mhi_wwan_ops, mhi_dev,
> >> -                               WWAN_NO_DEFAULT_LINK);
> >> -       if (err)
> >> -               return err;
> >> -
> >> -       if (!create_default_iface)
> >> -               return 0;
> >> -
> >> -       /* Create a default interface which is used as either RMNET real-dev,
> >> -        * MBIM link 0 or ip link 0)
> >> -        */
> >> -       ndev = alloc_netdev(sizeof(struct mhi_net_dev), info->netname,
> >> -                           NET_NAME_PREDICTABLE, mhi_net_setup);
> >
> > I like the idea of the default link, but here we need to create the
> > netdev manually for several reasons:
> > - In case of QMAP/rmnet, this link is the lower netdev (transport
> > layer) and is not associated with any link id.
> > - In case of MBIM, it changes the netdev parent device from the MHI
> > dev to the WWAN dev, which (currently) breaks how ModemManager groups
> > ports/netdevs (based on bus).
> >
> > For the last one, I don't think device hierarchy is considered as
> > UAPI, so we probably just need to add this new wwan link support to
> > user tools like MM. For the first one, I plan to split the mhi_net
> > driver into two different ones (mhi_net_qmap, mhi_net_mbim), and in
> > the case of qmap(rmnet) forward newlink/dellink call to rmnet
> > rtnetlink ops.
>
> Looks like I missed the complexity of WWAN devices handling. Thank you
> for pointing that out. Now I will drop this patch from the series.
>
> Just curious, am I right to say that any network interface created
> with wwan-core is not usable with ModemManager at the moment? AFAIU,
> ModemManager is unable to bundle a control port and a netdev into a
> common "modem" object, even if they both have the same parent Linux
> device, just because that device is not a physical USB device.

Right, there is an ongoing discussion about supporting iosm:
https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/385#note_958408

So once we have it working for iosm, it should work for any WWAN
device using WWAN framework.

Regards,
Loic
Sergey Ryazanov June 21, 2021, 9:54 a.m. UTC | #4
Hi Loic,

On Mon, Jun 21, 2021 at 9:44 AM Loic Poulain <loic.poulain@linaro.org> wrote:
> On Sun, 20 Jun 2021 at 15:51, Sergey Ryazanov <ryazanov.s.a@gmail.com> wrote:
>> On Tue, Jun 15, 2021 at 10:08 AM Loic Poulain <loic.poulain@linaro.org> wrote:
>>> On Tue, 15 Jun 2021 at 02:30, Sergey Ryazanov <ryazanov.s.a@gmail.com> wrote:
>>>> Utilize the just introduced WWAN core feature to create a default netdev
>>>> for the default data channel. Since the netdev is now created via the
>>>> WWAN core, rely on it ability to destroy all child netdevs on ops
>>>> unregistering.
>>>>
>>>> While at it, remove the RTNL lock acquiring hacks that were earlier used
>>>> to call addlink/dellink without holding the RTNL lock. Also make the
>>>> WWAN netdev ops structure static to make sparse happy.
>>>>
>>>> Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
>>>> ---
>>>>  drivers/net/mhi/net.c | 54 +++++--------------------------------------
>>>>  1 file changed, 6 insertions(+), 48 deletions(-)
>>>>
>>>> diff --git a/drivers/net/mhi/net.c b/drivers/net/mhi/net.c
>>>> index b003003cbd42..06253acecaa2 100644
>>>> --- a/drivers/net/mhi/net.c
>>>> +++ b/drivers/net/mhi/net.c
>>>> @@ -342,10 +342,7 @@ static int mhi_net_newlink(void *ctxt, struct net_device *ndev, u32 if_id,
>>>>         /* Number of transfer descriptors determines size of the queue */
>>>>         mhi_netdev->rx_queue_sz = mhi_get_free_desc_count(mhi_dev, DMA_FROM_DEVICE);
>>>>
>>>> -       if (extack)
>>>> -               err = register_netdevice(ndev);
>>>> -       else
>>>> -               err = register_netdev(ndev);
>>>> +       err = register_netdevice(ndev);
>>>>         if (err)
>>>>                 goto out_err;
>>>>
>>>> @@ -370,10 +367,7 @@ static void mhi_net_dellink(void *ctxt, struct net_device *ndev,
>>>>         struct mhi_net_dev *mhi_netdev = netdev_priv(ndev);
>>>>         struct mhi_device *mhi_dev = ctxt;
>>>>
>>>> -       if (head)
>>>> -               unregister_netdevice_queue(ndev, head);
>>>> -       else
>>>> -               unregister_netdev(ndev);
>>>> +       unregister_netdevice_queue(ndev, head);
>>>>
>>>>         mhi_unprepare_from_transfer(mhi_dev);
>>>>
>>>> @@ -382,7 +376,7 @@ static void mhi_net_dellink(void *ctxt, struct net_device *ndev,
>>>>         dev_set_drvdata(&mhi_dev->dev, NULL);
>>>>  }
>>>>
>>>> -const struct wwan_ops mhi_wwan_ops = {
>>>> +static const struct wwan_ops mhi_wwan_ops = {
>>>>         .priv_size = sizeof(struct mhi_net_dev),
>>>>         .setup = mhi_net_setup,
>>>>         .newlink = mhi_net_newlink,
>>>> @@ -392,55 +386,19 @@ const struct wwan_ops mhi_wwan_ops = {
>>>>  static int mhi_net_probe(struct mhi_device *mhi_dev,
>>>>                          const struct mhi_device_id *id)
>>>>  {
>>>> -       const struct mhi_device_info *info = (struct mhi_device_info *)id->driver_data;
>>>>         struct mhi_controller *cntrl = mhi_dev->mhi_cntrl;
>>>> -       struct net_device *ndev;
>>>> -       int err;
>>>> -
>>>> -       err = wwan_register_ops(&cntrl->mhi_dev->dev, &mhi_wwan_ops, mhi_dev,
>>>> -                               WWAN_NO_DEFAULT_LINK);
>>>> -       if (err)
>>>> -               return err;
>>>> -
>>>> -       if (!create_default_iface)
>>>> -               return 0;
>>>> -
>>>> -       /* Create a default interface which is used as either RMNET real-dev,
>>>> -        * MBIM link 0 or ip link 0)
>>>> -        */
>>>> -       ndev = alloc_netdev(sizeof(struct mhi_net_dev), info->netname,
>>>> -                           NET_NAME_PREDICTABLE, mhi_net_setup);
>>>
>>> I like the idea of the default link, but here we need to create the
>>> netdev manually for several reasons:
>>> - In case of QMAP/rmnet, this link is the lower netdev (transport
>>> layer) and is not associated with any link id.
>>> - In case of MBIM, it changes the netdev parent device from the MHI
>>> dev to the WWAN dev, which (currently) breaks how ModemManager groups
>>> ports/netdevs (based on bus).
>>>
>>> For the last one, I don't think device hierarchy is considered as
>>> UAPI, so we probably just need to add this new wwan link support to
>>> user tools like MM. For the first one, I plan to split the mhi_net
>>> driver into two different ones (mhi_net_qmap, mhi_net_mbim), and in
>>> the case of qmap(rmnet) forward newlink/dellink call to rmnet
>>> rtnetlink ops.
>>
>> Looks like I missed the complexity of WWAN devices handling. Thank you
>> for pointing that out. Now I will drop this patch from the series.
>>
>> Just curious, am I right to say that any network interface created
>> with wwan-core is not usable with ModemManager at the moment? AFAIU,
>> ModemManager is unable to bundle a control port and a netdev into a
>> common "modem" object, even if they both have the same parent Linux
>> device, just because that device is not a physical USB device.
>
> Right, there is an ongoing discussion about supporting iosm:
> https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/385#note_958408
>
> So once we have it working for iosm, it should work for any WWAN
> device using WWAN framework.

Thank you for the clarification, I will keep in mind.
diff mbox series

Patch

diff --git a/drivers/net/mhi/net.c b/drivers/net/mhi/net.c
index b003003cbd42..06253acecaa2 100644
--- a/drivers/net/mhi/net.c
+++ b/drivers/net/mhi/net.c
@@ -342,10 +342,7 @@  static int mhi_net_newlink(void *ctxt, struct net_device *ndev, u32 if_id,
 	/* Number of transfer descriptors determines size of the queue */
 	mhi_netdev->rx_queue_sz = mhi_get_free_desc_count(mhi_dev, DMA_FROM_DEVICE);
 
-	if (extack)
-		err = register_netdevice(ndev);
-	else
-		err = register_netdev(ndev);
+	err = register_netdevice(ndev);
 	if (err)
 		goto out_err;
 
@@ -370,10 +367,7 @@  static void mhi_net_dellink(void *ctxt, struct net_device *ndev,
 	struct mhi_net_dev *mhi_netdev = netdev_priv(ndev);
 	struct mhi_device *mhi_dev = ctxt;
 
-	if (head)
-		unregister_netdevice_queue(ndev, head);
-	else
-		unregister_netdev(ndev);
+	unregister_netdevice_queue(ndev, head);
 
 	mhi_unprepare_from_transfer(mhi_dev);
 
@@ -382,7 +376,7 @@  static void mhi_net_dellink(void *ctxt, struct net_device *ndev,
 	dev_set_drvdata(&mhi_dev->dev, NULL);
 }
 
-const struct wwan_ops mhi_wwan_ops = {
+static const struct wwan_ops mhi_wwan_ops = {
 	.priv_size = sizeof(struct mhi_net_dev),
 	.setup = mhi_net_setup,
 	.newlink = mhi_net_newlink,
@@ -392,55 +386,19 @@  const struct wwan_ops mhi_wwan_ops = {
 static int mhi_net_probe(struct mhi_device *mhi_dev,
 			 const struct mhi_device_id *id)
 {
-	const struct mhi_device_info *info = (struct mhi_device_info *)id->driver_data;
 	struct mhi_controller *cntrl = mhi_dev->mhi_cntrl;
-	struct net_device *ndev;
-	int err;
-
-	err = wwan_register_ops(&cntrl->mhi_dev->dev, &mhi_wwan_ops, mhi_dev,
-				WWAN_NO_DEFAULT_LINK);
-	if (err)
-		return err;
-
-	if (!create_default_iface)
-		return 0;
-
-	/* Create a default interface which is used as either RMNET real-dev,
-	 * MBIM link 0 or ip link 0)
-	 */
-	ndev = alloc_netdev(sizeof(struct mhi_net_dev), info->netname,
-			    NET_NAME_PREDICTABLE, mhi_net_setup);
-	if (!ndev) {
-		err = -ENOMEM;
-		goto err_unregister;
-	}
-
-	SET_NETDEV_DEV(ndev, &mhi_dev->dev);
 
-	err = mhi_net_newlink(mhi_dev, ndev, 0, NULL);
-	if (err)
-		goto err_release;
-
-	return 0;
-
-err_release:
-	free_netdev(ndev);
-err_unregister:
-	wwan_unregister_ops(&cntrl->mhi_dev->dev);
-
-	return err;
+	return wwan_register_ops(&cntrl->mhi_dev->dev, &mhi_wwan_ops, mhi_dev,
+				 create_default_iface ? 0 :
+				 WWAN_NO_DEFAULT_LINK);
 }
 
 static void mhi_net_remove(struct mhi_device *mhi_dev)
 {
-	struct mhi_net_dev *mhi_netdev = dev_get_drvdata(&mhi_dev->dev);
 	struct mhi_controller *cntrl = mhi_dev->mhi_cntrl;
 
 	/* rtnetlink takes care of removing remaining links */
 	wwan_unregister_ops(&cntrl->mhi_dev->dev);
-
-	if (create_default_iface)
-		mhi_net_dellink(mhi_dev, mhi_netdev->ndev, NULL);
 }
 
 static const struct mhi_device_info mhi_hwip0 = {