diff options
author | Yauheni Kaliuta <yauheni.kaliuta@nokia.com> | 2010-12-08 06:12:04 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-12-10 17:29:42 -0500 |
commit | 5c1168dbc508282f7717a4472477d52d64403060 (patch) | |
tree | f551a1d844ec74fdc85d3992f4b37dcd762f0920 /drivers/usb/gadget | |
parent | ff176a4e2972bdc7a8d65cdcb0bd0d26ab1528cf (diff) |
usb: gadget: u_ether: prepare for NCM
NCM is a Network Control Model, subclass of USB CDC class,
specification is available at http://www.usb.org/developers/devclass_docs
This patch makes possible for u_ether to use multiply of wMaxPacketSize
predefined size transfers without ZLP (Zero Length Packet), required
by NCM spec.
Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@nokia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/u_ether.c | 14 | ||||
-rw-r--r-- | drivers/usb/gadget/u_ether.h | 4 |
2 files changed, 16 insertions, 2 deletions
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index cb23355f52d3..a7826a6dcd8c 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
@@ -240,6 +240,9 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) | |||
240 | size += out->maxpacket - 1; | 240 | size += out->maxpacket - 1; |
241 | size -= size % out->maxpacket; | 241 | size -= size % out->maxpacket; |
242 | 242 | ||
243 | if (dev->port_usb->is_fixed) | ||
244 | size = max(size, dev->port_usb->fixed_out_len); | ||
245 | |||
243 | skb = alloc_skb(size + NET_IP_ALIGN, gfp_flags); | 246 | skb = alloc_skb(size + NET_IP_ALIGN, gfp_flags); |
244 | if (skb == NULL) { | 247 | if (skb == NULL) { |
245 | DBG(dev, "no rx skb\n"); | 248 | DBG(dev, "no rx skb\n"); |
@@ -578,12 +581,19 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, | |||
578 | req->context = skb; | 581 | req->context = skb; |
579 | req->complete = tx_complete; | 582 | req->complete = tx_complete; |
580 | 583 | ||
584 | /* NCM requires no zlp if transfer is dwNtbInMaxSize */ | ||
585 | if (dev->port_usb->is_fixed && | ||
586 | length == dev->port_usb->fixed_in_len && | ||
587 | (length % in->maxpacket) == 0) | ||
588 | req->zero = 0; | ||
589 | else | ||
590 | req->zero = 1; | ||
591 | |||
581 | /* use zlp framing on tx for strict CDC-Ether conformance, | 592 | /* use zlp framing on tx for strict CDC-Ether conformance, |
582 | * though any robust network rx path ignores extra padding. | 593 | * though any robust network rx path ignores extra padding. |
583 | * and some hardware doesn't like to write zlps. | 594 | * and some hardware doesn't like to write zlps. |
584 | */ | 595 | */ |
585 | req->zero = 1; | 596 | if (req->zero && !dev->zlp && (length % in->maxpacket) == 0) |
586 | if (!dev->zlp && (length % in->maxpacket) == 0) | ||
587 | length++; | 597 | length++; |
588 | 598 | ||
589 | req->length = length; | 599 | req->length = length; |
diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h index 3c8c0c9f9d72..75219708abb8 100644 --- a/drivers/usb/gadget/u_ether.h +++ b/drivers/usb/gadget/u_ether.h | |||
@@ -62,6 +62,10 @@ struct gether { | |||
62 | 62 | ||
63 | /* hooks for added framing, as needed for RNDIS and EEM. */ | 63 | /* hooks for added framing, as needed for RNDIS and EEM. */ |
64 | u32 header_len; | 64 | u32 header_len; |
65 | /* NCM requires fixed size bundles */ | ||
66 | bool is_fixed; | ||
67 | u32 fixed_out_len; | ||
68 | u32 fixed_in_len; | ||
65 | struct sk_buff *(*wrap)(struct gether *port, | 69 | struct sk_buff *(*wrap)(struct gether *port, |
66 | struct sk_buff *skb); | 70 | struct sk_buff *skb); |
67 | int (*unwrap)(struct gether *port, | 71 | int (*unwrap)(struct gether *port, |