@@ -294,6 +294,9 @@ static int aqc111_bind(struct usbnet *dev, struct usb_interface *intf)
294294
295295 ether_addr_copy (dev -> net -> dev_addr , dev -> net -> perm_addr );
296296
297+ /* Set Rx urb size */
298+ dev -> rx_urb_size = URB_SIZE ;
299+
297300 /* Set TX needed headroom & tailroom */
298301 dev -> net -> needed_headroom += sizeof (u64 );
299302 dev -> net -> needed_tailroom += sizeof (u64 );
@@ -519,6 +522,8 @@ static int aqc111_reset(struct usbnet *dev)
519522 struct aqc111_data * aqc111_data = dev -> driver_priv ;
520523 u8 reg8 = 0 ;
521524
525+ dev -> rx_urb_size = URB_SIZE ;
526+
522527 if (usb_device_no_sg_constraint (dev -> udev ))
523528 dev -> can_dma_sg = 1 ;
524529
@@ -578,6 +583,102 @@ static int aqc111_stop(struct usbnet *dev)
578583 return 0 ;
579584}
580585
586+ static int aqc111_rx_fixup (struct usbnet * dev , struct sk_buff * skb )
587+ {
588+ struct sk_buff * new_skb = NULL ;
589+ u32 pkt_total_offset = 0 ;
590+ u64 * pkt_desc_ptr = NULL ;
591+ u32 start_of_descs = 0 ;
592+ u32 desc_offset = 0 ; /*RX Header Offset*/
593+ u16 pkt_count = 0 ;
594+ u64 desc_hdr = 0 ;
595+ u32 skb_len = 0 ;
596+
597+ if (!skb )
598+ goto err ;
599+
600+ if (skb -> len == 0 )
601+ goto err ;
602+
603+ skb_len = skb -> len ;
604+ /* RX Descriptor Header */
605+ skb_trim (skb , skb -> len - sizeof (desc_hdr ));
606+ desc_hdr = le64_to_cpup ((u64 * )skb_tail_pointer (skb ));
607+
608+ /* Check these packets */
609+ desc_offset = (desc_hdr & AQ_RX_DH_DESC_OFFSET_MASK ) >>
610+ AQ_RX_DH_DESC_OFFSET_SHIFT ;
611+ pkt_count = desc_hdr & AQ_RX_DH_PKT_CNT_MASK ;
612+ start_of_descs = skb_len - ((pkt_count + 1 ) * sizeof (desc_hdr ));
613+
614+ /* self check descs position */
615+ if (start_of_descs != desc_offset )
616+ goto err ;
617+
618+ /* self check desc_offset from header*/
619+ if (desc_offset >= skb_len )
620+ goto err ;
621+
622+ if (pkt_count == 0 )
623+ goto err ;
624+
625+ /* Get the first RX packet descriptor */
626+ pkt_desc_ptr = (u64 * )(skb -> data + desc_offset );
627+
628+ while (pkt_count -- ) {
629+ u64 pkt_desc = le64_to_cpup (pkt_desc_ptr );
630+ u32 pkt_len_with_padd = 0 ;
631+ u32 pkt_len = 0 ;
632+
633+ pkt_len = (u32 )((pkt_desc & AQ_RX_PD_LEN_MASK ) >>
634+ AQ_RX_PD_LEN_SHIFT );
635+ pkt_len_with_padd = ((pkt_len + 7 ) & 0x7FFF8 );
636+
637+ pkt_total_offset += pkt_len_with_padd ;
638+ if (pkt_total_offset > desc_offset ||
639+ (pkt_count == 0 && pkt_total_offset != desc_offset )) {
640+ goto err ;
641+ }
642+
643+ if (pkt_desc & AQ_RX_PD_DROP ||
644+ !(pkt_desc & AQ_RX_PD_RX_OK ) ||
645+ pkt_len > (dev -> hard_mtu + AQ_RX_HW_PAD )) {
646+ skb_pull (skb , pkt_len_with_padd );
647+ /* Next RX Packet Descriptor */
648+ pkt_desc_ptr ++ ;
649+ continue ;
650+ }
651+
652+ /* Clone SKB */
653+ new_skb = skb_clone (skb , GFP_ATOMIC );
654+
655+ if (!new_skb )
656+ goto err ;
657+
658+ new_skb -> len = pkt_len ;
659+ skb_pull (new_skb , AQ_RX_HW_PAD );
660+ skb_set_tail_pointer (new_skb , new_skb -> len );
661+
662+ new_skb -> truesize = SKB_TRUESIZE (new_skb -> len );
663+
664+ usbnet_skb_return (dev , new_skb );
665+ if (pkt_count == 0 )
666+ break ;
667+
668+ skb_pull (skb , pkt_len_with_padd );
669+
670+ /* Next RX Packet Header */
671+ pkt_desc_ptr ++ ;
672+
673+ new_skb = NULL ;
674+ }
675+
676+ return 1 ;
677+
678+ err :
679+ return 0 ;
680+ }
681+
581682static struct sk_buff * aqc111_tx_fixup (struct usbnet * dev , struct sk_buff * skb ,
582683 gfp_t flags )
583684{
@@ -637,6 +738,7 @@ static const struct driver_info aqc111_info = {
637738 .stop = aqc111_stop ,
638739 .flags = FLAG_ETHER | FLAG_FRAMING_AX |
639740 FLAG_AVOID_UNLINK_URBS | FLAG_MULTI_PACKET ,
741+ .rx_fixup = aqc111_rx_fixup ,
640742 .tx_fixup = aqc111_tx_fixup ,
641743};
642744
0 commit comments