Skip to content

Commit 47175e5

Browse files
bmorkdavem330
authored andcommitted
net: cdc_ncm: refactoring cdc_ncm_setup
Rewriting the "set max datagram" part of dc_ncm_setup to separate the selection and validatation of the size from the code which optionally informs the device of this value. This ensures that we use the correct value regardless of device support for the get and set commands. Removing some of the many indent levels while doing this to make the code more readable. Cc: Alexey Orishko <alexey.orishko@gmail.com> Signed-off-by: Bjørn Mork <bjorn@mork.no> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 6dd13e8 commit 47175e5

File tree

1 file changed

+44
-64
lines changed

1 file changed

+44
-64
lines changed

drivers/net/usb/cdc_ncm.c

Lines changed: 44 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ static u8 cdc_ncm_setup(struct usbnet *dev)
7676
int err;
7777
int eth_hlen;
7878
u16 ntb_fmt_supported;
79-
u32 min_dgram_size;
80-
u32 min_hdr_size;
79+
__le16 max_datagram_size;
8180

8281
iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
8382

@@ -101,20 +100,29 @@ static u8 cdc_ncm_setup(struct usbnet *dev)
101100
ctx->tx_max_datagrams = le16_to_cpu(ncm_parm.wNtbOutMaxDatagrams);
102101
ntb_fmt_supported = le16_to_cpu(ncm_parm.bmNtbFormatsSupported);
103102

104-
eth_hlen = ETH_HLEN;
105-
min_dgram_size = CDC_NCM_MIN_DATAGRAM_SIZE;
106-
min_hdr_size = CDC_NCM_MIN_HDR_SIZE;
107-
if (ctx->mbim_desc != NULL) {
108-
flags = ctx->mbim_desc->bmNetworkCapabilities;
103+
/* there are some minor differences in NCM and MBIM defaults */
104+
if (cdc_ncm_comm_intf_is_mbim(ctx->control->cur_altsetting)) {
105+
if (!ctx->mbim_desc)
106+
return -EINVAL;
109107
eth_hlen = 0;
110-
min_dgram_size = CDC_MBIM_MIN_DATAGRAM_SIZE;
111-
min_hdr_size = 0;
112-
} else if (ctx->func_desc != NULL) {
113-
flags = ctx->func_desc->bmNetworkCapabilities;
108+
flags = ctx->mbim_desc->bmNetworkCapabilities;
109+
ctx->max_datagram_size = le16_to_cpu(ctx->mbim_desc->wMaxSegmentSize);
110+
if (ctx->max_datagram_size < CDC_MBIM_MIN_DATAGRAM_SIZE)
111+
ctx->max_datagram_size = CDC_MBIM_MIN_DATAGRAM_SIZE;
114112
} else {
115-
flags = 0;
113+
if (!ctx->func_desc)
114+
return -EINVAL;
115+
eth_hlen = ETH_HLEN;
116+
flags = ctx->func_desc->bmNetworkCapabilities;
117+
ctx->max_datagram_size = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize);
118+
if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE)
119+
ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE;
116120
}
117121

122+
/* common absolute max for NCM and MBIM */
123+
if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE)
124+
ctx->max_datagram_size = CDC_NCM_MAX_DATAGRAM_SIZE;
125+
118126
dev_dbg(&dev->intf->dev,
119127
"dwNtbInMaxSize=%u dwNtbOutMaxSize=%u wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u wNdpOutAlignment=%u wNtbOutMaxDatagrams=%u flags=0x%x\n",
120128
ctx->rx_max, ctx->tx_max, ctx->tx_remainder, ctx->tx_modulus,
@@ -151,8 +159,7 @@ static u8 cdc_ncm_setup(struct usbnet *dev)
151159
}
152160

153161
/* verify maximum size of transmitted NTB in bytes */
154-
if ((ctx->tx_max <
155-
(min_hdr_size + min_dgram_size)) ||
162+
if ((ctx->tx_max < (CDC_NCM_MIN_HDR_SIZE + ctx->max_datagram_size)) ||
156163
(ctx->tx_max > CDC_NCM_NTB_MAX_SIZE_TX)) {
157164
dev_dbg(&dev->intf->dev, "Using default maximum transmit length=%d\n",
158165
CDC_NCM_NTB_MAX_SIZE_TX);
@@ -229,60 +236,33 @@ static u8 cdc_ncm_setup(struct usbnet *dev)
229236
dev_dbg(&dev->intf->dev, "Setting NTB format to 16-bit failed\n");
230237
}
231238

232-
ctx->max_datagram_size = min_dgram_size;
239+
/* inform the device about the selected Max Datagram Size */
240+
if (!(flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE))
241+
goto out;
233242

234-
/* set Max Datagram Size (MTU) */
235-
if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) {
236-
__le16 max_datagram_size;
237-
u16 eth_max_sz;
238-
if (ctx->ether_desc != NULL)
239-
eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize);
240-
else if (ctx->mbim_desc != NULL)
241-
eth_max_sz = le16_to_cpu(ctx->mbim_desc->wMaxSegmentSize);
242-
else
243-
goto max_dgram_err;
244-
245-
err = usbnet_read_cmd(dev, USB_CDC_GET_MAX_DATAGRAM_SIZE,
246-
USB_TYPE_CLASS | USB_DIR_IN
247-
| USB_RECIP_INTERFACE,
248-
0, iface_no, &max_datagram_size, 2);
249-
if (err < 0) {
250-
dev_dbg(&dev->intf->dev, "GET_MAX_DATAGRAM_SIZE failed, use size=%u\n",
251-
min_dgram_size);
252-
} else {
253-
ctx->max_datagram_size =
254-
le16_to_cpu(max_datagram_size);
255-
/* Check Eth descriptor value */
256-
if (ctx->max_datagram_size > eth_max_sz)
257-
ctx->max_datagram_size = eth_max_sz;
258-
259-
if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE)
260-
ctx->max_datagram_size = CDC_NCM_MAX_DATAGRAM_SIZE;
261-
262-
if (ctx->max_datagram_size < min_dgram_size)
263-
ctx->max_datagram_size = min_dgram_size;
264-
265-
/* if value changed, update device */
266-
if (ctx->max_datagram_size !=
267-
le16_to_cpu(max_datagram_size)) {
268-
max_datagram_size = cpu_to_le16(ctx->max_datagram_size);
269-
err = usbnet_write_cmd(dev,
270-
USB_CDC_SET_MAX_DATAGRAM_SIZE,
271-
USB_TYPE_CLASS | USB_DIR_OUT
272-
| USB_RECIP_INTERFACE,
273-
0,
274-
iface_no, &max_datagram_size,
275-
2);
276-
if (err < 0)
277-
dev_dbg(&dev->intf->dev, "SET_MAX_DGRAM_SIZE failed\n");
278-
}
279-
}
243+
/* read current mtu value from device */
244+
err = usbnet_read_cmd(dev, USB_CDC_GET_MAX_DATAGRAM_SIZE,
245+
USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
246+
0, iface_no, &max_datagram_size, 2);
247+
if (err < 0) {
248+
dev_dbg(&dev->intf->dev, "GET_MAX_DATAGRAM_SIZE failed\n");
249+
goto out;
280250
}
281251

282-
max_dgram_err:
283-
if (dev->net->mtu != (ctx->max_datagram_size - eth_hlen))
284-
dev->net->mtu = ctx->max_datagram_size - eth_hlen;
252+
if (le16_to_cpu(max_datagram_size) == ctx->max_datagram_size)
253+
goto out;
254+
255+
max_datagram_size = cpu_to_le16(ctx->max_datagram_size);
256+
err = usbnet_write_cmd(dev, USB_CDC_SET_MAX_DATAGRAM_SIZE,
257+
USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE,
258+
0, iface_no, &max_datagram_size, 2);
259+
if (err < 0)
260+
dev_dbg(&dev->intf->dev, "SET_MAX_DATAGRAM_SIZE failed\n");
285261

262+
out:
263+
/* set MTU to max supported by the device if necessary */
264+
if (dev->net->mtu > ctx->max_datagram_size - eth_hlen)
265+
dev->net->mtu = ctx->max_datagram_size - eth_hlen;
286266
return 0;
287267
}
288268

0 commit comments

Comments
 (0)