aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorYauheni Kaliuta <yauheni.kaliuta@nokia.com>2010-12-08 06:12:04 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-12-10 17:29:42 -0500
commit5c1168dbc508282f7717a4472477d52d64403060 (patch)
treef551a1d844ec74fdc85d3992f4b37dcd762f0920 /drivers/usb/gadget
parentff176a4e2972bdc7a8d65cdcb0bd0d26ab1528cf (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.c14
-rw-r--r--drivers/usb/gadget/u_ether.h4
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,