Skip to content

Commit dad957d

Browse files
bmorkdavem330
authored andcommitted
net: cdc_ncm: workaround NTB input size firmware bug
Some devices do not support the 8 byte variants of the NTB input size control messages despite announcing such support in their NCM or MBIM functional descriptor. According to the NCM specification, all devices must support the 4 byte variant regardless of whether or not the flag is set: If bit D5 is set in the bmNetworkCapabilities field of function’s NCM Functional Descriptor, the host may set wLength either to 4 or to 8. If wLength is 4, the function shall assume that wNtbInMaxDatagrams is to be set to zero. If wLength is 8, then the function shall use the provided value as the limit. The function shall return an error response (a STALL PID) if wLength is set to any other value. We do not set wNtbInMaxDatagrams in any case, so we can just as well unconditionally use the 4 byte variant without losing any functionality. This works around the known firmware bug, and simplifies the code considerably. Signed-off-by: Bjørn Mork <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0668744 commit dad957d

File tree

1 file changed

+13
-33
lines changed

1 file changed

+13
-33
lines changed

drivers/net/usb/cdc_ncm.c

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -215,41 +215,21 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
215215

216216
/* inform device about NTB input size changes */
217217
if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) {
218+
__le32 *dwNtbInMaxSize;
218219

219-
if (flags & USB_CDC_NCM_NCAP_NTB_INPUT_SIZE) {
220-
struct usb_cdc_ncm_ndp_input_size *ndp_in_sz;
221-
222-
ndp_in_sz = kzalloc(sizeof(*ndp_in_sz), GFP_KERNEL);
223-
if (!ndp_in_sz) {
224-
err = -ENOMEM;
225-
goto size_err;
226-
}
227-
228-
err = usb_control_msg(ctx->udev,
229-
usb_sndctrlpipe(ctx->udev, 0),
230-
USB_CDC_SET_NTB_INPUT_SIZE,
231-
USB_TYPE_CLASS | USB_DIR_OUT
232-
| USB_RECIP_INTERFACE,
233-
0, iface_no, ndp_in_sz, 8, 1000);
234-
kfree(ndp_in_sz);
235-
} else {
236-
__le32 *dwNtbInMaxSize;
237-
dwNtbInMaxSize = kzalloc(sizeof(*dwNtbInMaxSize),
238-
GFP_KERNEL);
239-
if (!dwNtbInMaxSize) {
240-
err = -ENOMEM;
241-
goto size_err;
242-
}
243-
*dwNtbInMaxSize = cpu_to_le32(ctx->rx_max);
244-
245-
err = usb_control_msg(ctx->udev,
246-
usb_sndctrlpipe(ctx->udev, 0),
247-
USB_CDC_SET_NTB_INPUT_SIZE,
248-
USB_TYPE_CLASS | USB_DIR_OUT
249-
| USB_RECIP_INTERFACE,
250-
0, iface_no, dwNtbInMaxSize, 4, 1000);
251-
kfree(dwNtbInMaxSize);
220+
dwNtbInMaxSize = kzalloc(sizeof(*dwNtbInMaxSize), GFP_KERNEL);
221+
if (!dwNtbInMaxSize) {
222+
err = -ENOMEM;
223+
goto size_err;
252224
}
225+
*dwNtbInMaxSize = cpu_to_le32(ctx->rx_max);
226+
err = usb_control_msg(ctx->udev,
227+
usb_sndctrlpipe(ctx->udev, 0),
228+
USB_CDC_SET_NTB_INPUT_SIZE,
229+
USB_TYPE_CLASS | USB_DIR_OUT
230+
| USB_RECIP_INTERFACE,
231+
0, iface_no, dwNtbInMaxSize, 4, 1000);
232+
kfree(dwNtbInMaxSize);
253233
size_err:
254234
if (err < 0)
255235
pr_debug("Setting NTB Input Size failed\n");

0 commit comments

Comments
 (0)