aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/cdc_mbim.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/usb/cdc_mbim.c')
-rw-r--r--drivers/net/usb/cdc_mbim.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
index 80d27719ba38..bc23273d0455 100644
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -107,15 +107,54 @@ static const struct net_device_ops cdc_mbim_netdev_ops = {
107 .ndo_vlan_rx_kill_vid = cdc_mbim_rx_kill_vid, 107 .ndo_vlan_rx_kill_vid = cdc_mbim_rx_kill_vid,
108}; 108};
109 109
110/* Change the control interface altsetting and update the .driver_info
111 * pointer if the matching entry after changing class codes points to
112 * a different struct
113 */
114static int cdc_mbim_set_ctrlalt(struct usbnet *dev, struct usb_interface *intf, u8 alt)
115{
116 struct usb_driver *driver = to_usb_driver(intf->dev.driver);
117 const struct usb_device_id *id;
118 struct driver_info *info;
119 int ret;
120
121 ret = usb_set_interface(dev->udev,
122 intf->cur_altsetting->desc.bInterfaceNumber,
123 alt);
124 if (ret)
125 return ret;
126
127 id = usb_match_id(intf, driver->id_table);
128 if (!id)
129 return -ENODEV;
130
131 info = (struct driver_info *)id->driver_info;
132 if (info != dev->driver_info) {
133 dev_dbg(&intf->dev, "driver_info updated to '%s'\n",
134 info->description);
135 dev->driver_info = info;
136 }
137 return 0;
138}
139
110static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf) 140static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf)
111{ 141{
112 struct cdc_ncm_ctx *ctx; 142 struct cdc_ncm_ctx *ctx;
113 struct usb_driver *subdriver = ERR_PTR(-ENODEV); 143 struct usb_driver *subdriver = ERR_PTR(-ENODEV);
114 int ret = -ENODEV; 144 int ret = -ENODEV;
115 u8 data_altsetting = cdc_ncm_select_altsetting(dev, intf); 145 u8 data_altsetting = 1;
116 struct cdc_mbim_state *info = (void *)&dev->data; 146 struct cdc_mbim_state *info = (void *)&dev->data;
117 147
118 /* Probably NCM, defer for cdc_ncm_bind */ 148 /* should we change control altsetting on a NCM/MBIM function? */
149 if (cdc_ncm_select_altsetting(intf) == CDC_NCM_COMM_ALTSETTING_MBIM) {
150 data_altsetting = CDC_NCM_DATA_ALTSETTING_MBIM;
151 ret = cdc_mbim_set_ctrlalt(dev, intf, CDC_NCM_COMM_ALTSETTING_MBIM);
152 if (ret)
153 goto err;
154 ret = -ENODEV;
155 }
156
157 /* we will hit this for NCM/MBIM functions if prefer_mbim is false */
119 if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) 158 if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
120 goto err; 159 goto err;
121 160