5252#include <linux/ethtool.h>
5353#include <linux/usb.h>
5454#include <linux/workqueue.h>
55+ #include <linux/usb/cdc.h>
5556
5657#define USB_VENDOR_APPLE 0x05ac
5758
5859#define IPHETH_USBINTF_CLASS 255
5960#define IPHETH_USBINTF_SUBCLASS 253
6061#define IPHETH_USBINTF_PROTO 1
6162
62- #define IPHETH_BUF_SIZE 1514
6363#define IPHETH_IP_ALIGN 2 /* padding at front of URB */
64+ #define IPHETH_NCM_HEADER_SIZE (12 + 96) /* NCMH + NCM0 */
65+ #define IPHETH_TX_BUF_SIZE ETH_FRAME_LEN
66+ #define IPHETH_RX_BUF_SIZE_LEGACY (IPHETH_IP_ALIGN + ETH_FRAME_LEN)
67+ #define IPHETH_RX_BUF_SIZE_NCM 65536
68+
6469#define IPHETH_TX_TIMEOUT (5 * HZ)
6570
6671#define IPHETH_INTFNUM 2
7176#define IPHETH_CTRL_TIMEOUT (5 * HZ)
7277
7378#define IPHETH_CMD_GET_MACADDR 0x00
79+ #define IPHETH_CMD_ENABLE_NCM 0x04
7480#define IPHETH_CMD_CARRIER_CHECK 0x45
7581
7682#define IPHETH_CARRIER_CHECK_TIMEOUT round_jiffies_relative(1 * HZ)
@@ -97,6 +103,8 @@ struct ipheth_device {
97103 u8 bulk_out ;
98104 struct delayed_work carrier_work ;
99105 bool confirmed_pairing ;
106+ int (* rcvbulk_callback )(struct urb * urb );
107+ size_t rx_buf_len ;
100108};
101109
102110static int ipheth_rx_submit (struct ipheth_device * dev , gfp_t mem_flags );
@@ -116,12 +124,12 @@ static int ipheth_alloc_urbs(struct ipheth_device *iphone)
116124 if (rx_urb == NULL )
117125 goto free_tx_urb ;
118126
119- tx_buf = usb_alloc_coherent (iphone -> udev , IPHETH_BUF_SIZE ,
127+ tx_buf = usb_alloc_coherent (iphone -> udev , IPHETH_TX_BUF_SIZE ,
120128 GFP_KERNEL , & tx_urb -> transfer_dma );
121129 if (tx_buf == NULL )
122130 goto free_rx_urb ;
123131
124- rx_buf = usb_alloc_coherent (iphone -> udev , IPHETH_BUF_SIZE + IPHETH_IP_ALIGN ,
132+ rx_buf = usb_alloc_coherent (iphone -> udev , iphone -> rx_buf_len ,
125133 GFP_KERNEL , & rx_urb -> transfer_dma );
126134 if (rx_buf == NULL )
127135 goto free_tx_buf ;
@@ -134,7 +142,7 @@ static int ipheth_alloc_urbs(struct ipheth_device *iphone)
134142 return 0 ;
135143
136144free_tx_buf :
137- usb_free_coherent (iphone -> udev , IPHETH_BUF_SIZE , tx_buf ,
145+ usb_free_coherent (iphone -> udev , IPHETH_TX_BUF_SIZE , tx_buf ,
138146 tx_urb -> transfer_dma );
139147free_rx_urb :
140148 usb_free_urb (rx_urb );
@@ -146,9 +154,9 @@ static int ipheth_alloc_urbs(struct ipheth_device *iphone)
146154
147155static void ipheth_free_urbs (struct ipheth_device * iphone )
148156{
149- usb_free_coherent (iphone -> udev , IPHETH_BUF_SIZE + IPHETH_IP_ALIGN , iphone -> rx_buf ,
157+ usb_free_coherent (iphone -> udev , iphone -> rx_buf_len , iphone -> rx_buf ,
150158 iphone -> rx_urb -> transfer_dma );
151- usb_free_coherent (iphone -> udev , IPHETH_BUF_SIZE , iphone -> tx_buf ,
159+ usb_free_coherent (iphone -> udev , IPHETH_TX_BUF_SIZE , iphone -> tx_buf ,
152160 iphone -> tx_urb -> transfer_dma );
153161 usb_free_urb (iphone -> rx_urb );
154162 usb_free_urb (iphone -> tx_urb );
@@ -160,14 +168,105 @@ static void ipheth_kill_urbs(struct ipheth_device *dev)
160168 usb_kill_urb (dev -> rx_urb );
161169}
162170
163- static void ipheth_rcvbulk_callback ( struct urb * urb )
171+ static int ipheth_consume_skb ( char * buf , int len , struct ipheth_device * dev )
164172{
165- struct ipheth_device * dev ;
166173 struct sk_buff * skb ;
167- int status ;
174+
175+ skb = dev_alloc_skb (len );
176+ if (!skb ) {
177+ dev -> net -> stats .rx_dropped ++ ;
178+ return - ENOMEM ;
179+ }
180+
181+ skb_put_data (skb , buf , len );
182+ skb -> dev = dev -> net ;
183+ skb -> protocol = eth_type_trans (skb , dev -> net );
184+
185+ dev -> net -> stats .rx_packets ++ ;
186+ dev -> net -> stats .rx_bytes += len ;
187+ netif_rx (skb );
188+
189+ return 0 ;
190+ }
191+
192+ static int ipheth_rcvbulk_callback_legacy (struct urb * urb )
193+ {
194+ struct ipheth_device * dev ;
168195 char * buf ;
169196 int len ;
170197
198+ dev = urb -> context ;
199+
200+ if (urb -> actual_length <= IPHETH_IP_ALIGN ) {
201+ dev -> net -> stats .rx_length_errors ++ ;
202+ return - EINVAL ;
203+ }
204+ len = urb -> actual_length - IPHETH_IP_ALIGN ;
205+ buf = urb -> transfer_buffer + IPHETH_IP_ALIGN ;
206+
207+ return ipheth_consume_skb (buf , len , dev );
208+ }
209+
210+ static int ipheth_rcvbulk_callback_ncm (struct urb * urb )
211+ {
212+ struct usb_cdc_ncm_nth16 * ncmh ;
213+ struct usb_cdc_ncm_ndp16 * ncm0 ;
214+ struct usb_cdc_ncm_dpe16 * dpe ;
215+ struct ipheth_device * dev ;
216+ int retval = - EINVAL ;
217+ char * buf ;
218+ int len ;
219+
220+ dev = urb -> context ;
221+
222+ if (urb -> actual_length < IPHETH_NCM_HEADER_SIZE ) {
223+ dev -> net -> stats .rx_length_errors ++ ;
224+ return retval ;
225+ }
226+
227+ ncmh = urb -> transfer_buffer ;
228+ if (ncmh -> dwSignature != cpu_to_le32 (USB_CDC_NCM_NTH16_SIGN ) ||
229+ le16_to_cpu (ncmh -> wNdpIndex ) >= urb -> actual_length ) {
230+ dev -> net -> stats .rx_errors ++ ;
231+ return retval ;
232+ }
233+
234+ ncm0 = urb -> transfer_buffer + le16_to_cpu (ncmh -> wNdpIndex );
235+ if (ncm0 -> dwSignature != cpu_to_le32 (USB_CDC_NCM_NDP16_NOCRC_SIGN ) ||
236+ le16_to_cpu (ncmh -> wHeaderLength ) + le16_to_cpu (ncm0 -> wLength ) >=
237+ urb -> actual_length ) {
238+ dev -> net -> stats .rx_errors ++ ;
239+ return retval ;
240+ }
241+
242+ dpe = ncm0 -> dpe16 ;
243+ while (le16_to_cpu (dpe -> wDatagramIndex ) != 0 &&
244+ le16_to_cpu (dpe -> wDatagramLength ) != 0 ) {
245+ if (le16_to_cpu (dpe -> wDatagramIndex ) >= urb -> actual_length ||
246+ le16_to_cpu (dpe -> wDatagramIndex ) +
247+ le16_to_cpu (dpe -> wDatagramLength ) > urb -> actual_length ) {
248+ dev -> net -> stats .rx_length_errors ++ ;
249+ return retval ;
250+ }
251+
252+ buf = urb -> transfer_buffer + le16_to_cpu (dpe -> wDatagramIndex );
253+ len = le16_to_cpu (dpe -> wDatagramLength );
254+
255+ retval = ipheth_consume_skb (buf , len , dev );
256+ if (retval != 0 )
257+ return retval ;
258+
259+ dpe ++ ;
260+ }
261+
262+ return 0 ;
263+ }
264+
265+ static void ipheth_rcvbulk_callback (struct urb * urb )
266+ {
267+ struct ipheth_device * dev ;
268+ int retval , status ;
269+
171270 dev = urb -> context ;
172271 if (dev == NULL )
173272 return ;
@@ -191,25 +290,27 @@ static void ipheth_rcvbulk_callback(struct urb *urb)
191290 dev -> net -> stats .rx_length_errors ++ ;
192291 return ;
193292 }
194- len = urb -> actual_length - IPHETH_IP_ALIGN ;
195- buf = urb -> transfer_buffer + IPHETH_IP_ALIGN ;
196293
197- skb = dev_alloc_skb (len );
198- if (!skb ) {
199- dev_err (& dev -> intf -> dev , "%s: dev_alloc_skb: -ENOMEM\n" ,
200- __func__ );
201- dev -> net -> stats .rx_dropped ++ ;
294+ /* RX URBs starting with 0x00 0x01 do not encapsulate Ethernet frames,
295+ * but rather are control frames. Their purpose is not documented, and
296+ * they don't affect driver functionality, okay to drop them.
297+ * There is usually just one 4-byte control frame as the very first
298+ * URB received from the bulk IN endpoint.
299+ */
300+ if (unlikely
301+ (((char * )urb -> transfer_buffer )[0 ] == 0 &&
302+ ((char * )urb -> transfer_buffer )[1 ] == 1 ))
303+ goto rx_submit ;
304+
305+ retval = dev -> rcvbulk_callback (urb );
306+ if (retval != 0 ) {
307+ dev_err (& dev -> intf -> dev , "%s: callback retval: %d\n" ,
308+ __func__ , retval );
202309 return ;
203310 }
204311
205- skb_put_data (skb , buf , len );
206- skb -> dev = dev -> net ;
207- skb -> protocol = eth_type_trans (skb , dev -> net );
208-
209- dev -> net -> stats .rx_packets ++ ;
210- dev -> net -> stats .rx_bytes += len ;
312+ rx_submit :
211313 dev -> confirmed_pairing = true;
212- netif_rx (skb );
213314 ipheth_rx_submit (dev , GFP_ATOMIC );
214315}
215316
@@ -310,14 +411,35 @@ static int ipheth_get_macaddr(struct ipheth_device *dev)
310411 return retval ;
311412}
312413
414+ static int ipheth_enable_ncm (struct ipheth_device * dev )
415+ {
416+ struct usb_device * udev = dev -> udev ;
417+ int retval ;
418+
419+ retval = usb_control_msg (udev ,
420+ usb_sndctrlpipe (udev , IPHETH_CTRL_ENDP ),
421+ IPHETH_CMD_ENABLE_NCM , /* request */
422+ 0x41 , /* request type */
423+ 0x00 , /* value */
424+ 0x02 , /* index */
425+ NULL ,
426+ 0 ,
427+ IPHETH_CTRL_TIMEOUT );
428+
429+ dev_info (& dev -> intf -> dev , "%s: usb_control_msg: %d\n" ,
430+ __func__ , retval );
431+
432+ return retval ;
433+ }
434+
313435static int ipheth_rx_submit (struct ipheth_device * dev , gfp_t mem_flags )
314436{
315437 struct usb_device * udev = dev -> udev ;
316438 int retval ;
317439
318440 usb_fill_bulk_urb (dev -> rx_urb , udev ,
319441 usb_rcvbulkpipe (udev , dev -> bulk_in ),
320- dev -> rx_buf , IPHETH_BUF_SIZE + IPHETH_IP_ALIGN ,
442+ dev -> rx_buf , dev -> rx_buf_len ,
321443 ipheth_rcvbulk_callback ,
322444 dev );
323445 dev -> rx_urb -> transfer_flags |= URB_NO_TRANSFER_DMA_MAP ;
@@ -365,7 +487,7 @@ static netdev_tx_t ipheth_tx(struct sk_buff *skb, struct net_device *net)
365487 int retval ;
366488
367489 /* Paranoid */
368- if (skb -> len > IPHETH_BUF_SIZE ) {
490+ if (skb -> len > IPHETH_TX_BUF_SIZE ) {
369491 WARN (1 , "%s: skb too large: %d bytes\n" , __func__ , skb -> len );
370492 dev -> net -> stats .tx_dropped ++ ;
371493 dev_kfree_skb_any (skb );
@@ -448,6 +570,8 @@ static int ipheth_probe(struct usb_interface *intf,
448570 dev -> net = netdev ;
449571 dev -> intf = intf ;
450572 dev -> confirmed_pairing = false;
573+ dev -> rx_buf_len = IPHETH_RX_BUF_SIZE_LEGACY ;
574+ dev -> rcvbulk_callback = ipheth_rcvbulk_callback_legacy ;
451575 /* Set up endpoints */
452576 hintf = usb_altnum_to_altsetting (intf , IPHETH_ALT_INTFNUM );
453577 if (hintf == NULL ) {
@@ -479,6 +603,12 @@ static int ipheth_probe(struct usb_interface *intf,
479603 if (retval )
480604 goto err_get_macaddr ;
481605
606+ retval = ipheth_enable_ncm (dev );
607+ if (!retval ) {
608+ dev -> rx_buf_len = IPHETH_RX_BUF_SIZE_NCM ;
609+ dev -> rcvbulk_callback = ipheth_rcvbulk_callback_ncm ;
610+ }
611+
482612 INIT_DELAYED_WORK (& dev -> carrier_work , ipheth_carrier_check_work );
483613
484614 retval = ipheth_alloc_urbs (dev );
0 commit comments