@@ -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