diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index 51779e2bc195..0d8e4a364ca6 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c @@ -66,8 +66,6 @@ * - MS-Windows drivers sometimes emit undocumented requests. */ -#define RNDIS_UL_MAX_PKT_PER_XFER 3 - struct f_rndis { struct gether port; u8 ctrl_id, data_id; @@ -673,7 +671,6 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) struct usb_string *us; int status; struct usb_ep *ep; - unsigned int max; struct f_rndis_opts *rndis_opts; @@ -799,11 +796,6 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) rndis_set_param_medium(rndis->params, RNDIS_MEDIUM_802_3, 0); rndis_set_host_mac(rndis->params, rndis->ethaddr); - max = gether_get_ul_max_pkts_per_xfer(rndis_opts->net); - if (!max) - max = RNDIS_UL_MAX_PKT_PER_XFER; - - rndis_set_max_pkt_xfer(rndis->params, max); if (rndis->manufacturer && rndis->vendorID && rndis_set_param_vendor(rndis->params, rndis->vendorID, @@ -884,10 +876,6 @@ USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, subclass); /* f_rndis_opts_protocol */ USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, protocol); -/* f_rndis_opts_ul_max_pkt_per_xfer */ -USB_ETHER_CONFIGFS_ITEM_ATTR_UL_MAX_PKT_PER_XFER(rndis); - - static struct configfs_attribute *rndis_attrs[] = { &rndis_opts_attr_dev_addr, &rndis_opts_attr_host_addr, @@ -896,7 +884,6 @@ static struct configfs_attribute *rndis_attrs[] = { &rndis_opts_attr_class, &rndis_opts_attr_subclass, &rndis_opts_attr_protocol, - &rndis_opts_attr_ul_max_pkt_per_xfer, NULL, }; @@ -1018,8 +1005,6 @@ static struct usb_function *rndis_alloc(struct usb_function_instance *fi) rndis->port.header_len = sizeof(struct rndis_packet_msg_type); rndis->port.wrap = rndis_add_header; rndis->port.unwrap = rndis_rm_hdr; - if (!gether_get_ul_max_pkts_per_xfer(opts->net)) - rndis->port.ul_max_pkts_per_xfer = RNDIS_UL_MAX_PKT_PER_XFER; rndis->port.func.name = "rndis"; /* descriptors are per-instance copies */ diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c index d568a44589b7..04c142c13075 100644 --- a/drivers/usb/gadget/function/rndis.c +++ b/drivers/usb/gadget/function/rndis.c @@ -39,6 +39,7 @@ #include "rndis.h" + /* The driver for your USB chip needs to support ep0 OUT to work with * RNDIS, plus all three CDC Ethernet endpoints (interrupt not optional). * @@ -573,12 +574,12 @@ static int rndis_init_response(struct rndis_params *params, resp->MinorVersion = cpu_to_le32(RNDIS_MINOR_VERSION); resp->DeviceFlags = cpu_to_le32(RNDIS_DF_CONNECTIONLESS); resp->Medium = cpu_to_le32(RNDIS_MEDIUM_802_3); - resp->MaxPacketsPerTransfer = cpu_to_le32(params->max_pkt_per_xfer); - resp->MaxTransferSize = cpu_to_le32(params->max_pkt_per_xfer * - (params->dev->mtu + resp->MaxPacketsPerTransfer = cpu_to_le32(1); + resp->MaxTransferSize = cpu_to_le32( + params->dev->mtu + sizeof(struct ethhdr) + sizeof(struct rndis_packet_msg_type) - + 22)); + + 22); resp->PacketAlignmentFactor = cpu_to_le32(0); resp->AFListOffset = cpu_to_le32(0); resp->AFListSize = cpu_to_le32(0); @@ -992,13 +993,6 @@ int rndis_set_param_medium(struct rndis_params *params, u32 medium, u32 speed) } EXPORT_SYMBOL_GPL(rndis_set_param_medium); -void rndis_set_max_pkt_xfer(struct rndis_params *params, u8 max_pkt_per_xfer) -{ - pr_debug("%s:\n", __func__); - - params->max_pkt_per_xfer = max_pkt_per_xfer; -} - void rndis_add_hdr(struct sk_buff *skb) { struct rndis_packet_msg_type *header; @@ -1065,63 +1059,23 @@ int rndis_rm_hdr(struct gether *port, struct sk_buff *skb, struct sk_buff_head *list) { - while (skb->len) { - struct rndis_packet_msg_type *hdr; - struct sk_buff *skb2; - u32 msg_len, data_offset, data_len; + /* tmp points to a struct rndis_packet_msg_type */ + __le32 *tmp = (void *)skb->data; - /* some rndis hosts send extra byte to avoid zlp, ignore it */ - if (skb->len == 1) { - dev_kfree_skb_any(skb); - return 0; - } - - if (skb->len < sizeof(*hdr)) { - pr_err("invalid rndis pkt: skblen:%u hdr_len:%lu\n", - skb->len, sizeof(*hdr)); - dev_kfree_skb_any(skb); - return -EINVAL; - } - - hdr = (void *)skb->data; - msg_len = le32_to_cpu(hdr->MessageLength); - data_offset = le32_to_cpu(hdr->DataOffset); - data_len = le32_to_cpu(hdr->DataLength); - - if (skb->len < msg_len || - ((data_offset + data_len + 8) > msg_len)) { - pr_err("invalid rndis message: %d/%d/%d/%d, len:%d\n", - le32_to_cpu(hdr->MessageType), msg_len, - data_offset, data_len, skb->len); - dev_kfree_skb_any(skb); - return -EOVERFLOW; - } - if (le32_to_cpu(hdr->MessageType) != RNDIS_MSG_PACKET) { - pr_err("invalid rndis message: %d/%d/%d/%d, len:%d\n", - le32_to_cpu(hdr->MessageType), msg_len, - data_offset, data_len, skb->len); - dev_kfree_skb_any(skb); - return -EINVAL; - } - - skb_pull(skb, data_offset + 8); - - if (msg_len == skb->len) { - skb_trim(skb, data_len); - break; - } - - skb2 = skb_clone(skb, GFP_ATOMIC); - if (!skb2) { - pr_err("%s:skb clone failed\n", __func__); - dev_kfree_skb_any(skb); - return -ENOMEM; - } - - skb_pull(skb, msg_len - sizeof(*hdr)); - skb_trim(skb2, data_len); - skb_queue_tail(list, skb2); + /* MessageType, MessageLength */ + if (cpu_to_le32(RNDIS_MSG_PACKET) + != get_unaligned(tmp++)) { + dev_kfree_skb_any(skb); + return -EINVAL; } + tmp++; + + /* DataOffset, DataLength */ + if (!skb_pull(skb, get_unaligned_le32(tmp++) + 8)) { + dev_kfree_skb_any(skb); + return -EOVERFLOW; + } + skb_trim(skb, get_unaligned_le32(tmp++)); skb_queue_tail(list, skb); return 0; diff --git a/drivers/usb/gadget/function/rndis.h b/drivers/usb/gadget/function/rndis.h index 4bd6dc918a38..c7e3a70ce6c1 100644 --- a/drivers/usb/gadget/function/rndis.h +++ b/drivers/usb/gadget/function/rndis.h @@ -170,7 +170,6 @@ typedef struct rndis_params { struct net_device *dev; u32 vendorID; - u8 max_pkt_per_xfer; const char *vendorDescr; void (*resp_avail)(void *v); void *v; @@ -187,7 +186,6 @@ int rndis_set_param_vendor(struct rndis_params *params, u32 vendorID, const char *vendorDescr); int rndis_set_param_medium(struct rndis_params *params, u32 medium, u32 speed); -void rndis_set_max_pkt_xfer(struct rndis_params *params, u8 max_pkt_per_xfer); void rndis_add_hdr(struct sk_buff *skb); int rndis_rm_hdr(struct gether *port, struct sk_buff *skb, struct sk_buff_head *list); diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index 05a01cce49b1..fbe96ef1ac7a 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -67,7 +67,6 @@ struct eth_dev { unsigned qmult; unsigned header_len; - unsigned int ul_max_pkts_per_xfer; struct sk_buff *(*wrap)(struct gether *, struct sk_buff *skb); int (*unwrap)(struct gether *, struct sk_buff *skb, @@ -214,14 +213,10 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) size -= size % out->maxpacket; } - if (dev->ul_max_pkts_per_xfer) - size *= dev->ul_max_pkts_per_xfer; - if (dev->port_usb->is_fixed) size = max_t(size_t, size, dev->port_usb->fixed_out_len); spin_unlock_irqrestore(&dev->lock, flags); - DBG(dev, "%s: size: %zd\n", __func__, size); skb = __netdev_alloc_skb(dev->net, size + NET_IP_ALIGN, gfp_flags); if (skb == NULL) { DBG(dev, "no rx skb\n"); @@ -1017,26 +1012,6 @@ int gether_get_ifname(struct net_device *net, char *name, int len) } EXPORT_SYMBOL_GPL(gether_get_ifname); -unsigned int gether_get_ul_max_pkts_per_xfer(struct net_device *net) -{ - struct eth_dev *dev; - - dev = netdev_priv(net); - return dev->ul_max_pkts_per_xfer; -} -EXPORT_SYMBOL(gether_get_ul_max_pkts_per_xfer); - -int gether_set_ul_max_pkts_per_xfer(struct net_device *net, unsigned int max) -{ - struct eth_dev *dev; - - dev = netdev_priv(net); - dev->ul_max_pkts_per_xfer = max; - - return 0; -} -EXPORT_SYMBOL(gether_set_ul_max_pkts_per_xfer); - /** * gether_cleanup - remove Ethernet-over-USB device * Context: may sleep @@ -1106,8 +1081,6 @@ struct net_device *gether_connect(struct gether *link) dev->header_len = link->header_len; dev->unwrap = link->unwrap; dev->wrap = link->wrap; - if (!dev->ul_max_pkts_per_xfer) - dev->ul_max_pkts_per_xfer = link->ul_max_pkts_per_xfer; spin_lock(&dev->lock); dev->port_usb = link; diff --git a/drivers/usb/gadget/function/u_ether.h b/drivers/usb/gadget/function/u_ether.h index 35810229ca48..332307d54292 100644 --- a/drivers/usb/gadget/function/u_ether.h +++ b/drivers/usb/gadget/function/u_ether.h @@ -69,10 +69,6 @@ struct gether { bool is_fixed; u32 fixed_out_len; u32 fixed_in_len; - unsigned int ul_max_pkts_per_xfer; -/* Max number of SKB packets to be used to create Multi Packet RNDIS */ -#define TX_SKB_HOLD_THRESHOLD 3 - bool multi_pkt_xfer; bool supports_multi_frame; struct sk_buff *(*wrap)(struct gether *port, struct sk_buff *skb); @@ -248,19 +244,6 @@ unsigned gether_get_qmult(struct net_device *net); */ int gether_get_ifname(struct net_device *net, char *name, int len); -/** - * gether_get_ul_max_pkts_per_xfer - get max pks/xfer for UL aggrregarion - * @net: device representing this link - */ -unsigned int gether_get_ul_max_pkts_per_xfer(struct net_device *net); - -/** - * gether_set_ul_max_pkts_per_xfer - set max pks/xfer for UL aggrregarion - * @net: device representing this link - * @max: max number of packets - */ -int gether_set_ul_max_pkts_per_xfer(struct net_device *net, unsigned int max); - void gether_cleanup(struct eth_dev *dev); /* connect/disconnect is handled by individual functions */ diff --git a/drivers/usb/gadget/function/u_ether_configfs.h b/drivers/usb/gadget/function/u_ether_configfs.h index 2a158b9f0afd..13b08ebfff57 100644 --- a/drivers/usb/gadget/function/u_ether_configfs.h +++ b/drivers/usb/gadget/function/u_ether_configfs.h @@ -220,45 +220,4 @@ out: \ \ CONFIGFS_ATTR(_f_##_opts_, _n_) -#define USB_ETHER_CONFIGFS_ITEM_ATTR_UL_MAX_PKT_PER_XFER(_f_) \ - static ssize_t \ - _f_##_opts_ul_max_pkt_per_xfer_show(struct config_item *item,\ - char *page) \ - { \ - struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ - unsigned int max; \ - \ - mutex_lock(&opts->lock); \ - max = gether_get_ul_max_pkts_per_xfer(opts->net); \ - mutex_unlock(&opts->lock); \ - return scnprintf(page, PAGE_SIZE, "%d\n", max); \ - } \ - \ - static ssize_t \ - _f_##_opts_ul_max_pkt_per_xfer_store(struct config_item *item,\ - const char *page, size_t len)\ - { \ - struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ - u8 val; \ - int ret; \ - \ - mutex_lock(&opts->lock); \ - if (opts->refcnt) { \ - ret = -EBUSY; \ - goto out; \ - } \ - \ - ret = kstrtou8(page, 0, &val); \ - if (ret) \ - goto out; \ - \ - gether_set_ul_max_pkts_per_xfer(opts->net, val); \ - ret = len; \ -out: \ - mutex_unlock(&opts->lock); \ - return ret; \ - } \ - \ - CONFIGFS_ATTR(_f_##_opts_, ul_max_pkt_per_xfer) - #endif /* __U_ETHER_CONFIGFS_H */