Loading drivers/usb/gadget/android.c +16 −0 Original line number Diff line number Diff line Loading @@ -1920,12 +1920,28 @@ static DEVICE_ATTR(max_pkt_per_xfer, S_IRUGO | S_IWUSR, rndis_max_pkt_per_xfer_show, rndis_max_pkt_per_xfer_store); static ssize_t rndis_rx_trigger_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { int value; if (sscanf(buf, "%d", &value) == 1) { rndis_rx_trigger(); return size; } return -EINVAL; } static DEVICE_ATTR(rx_trigger, S_IWUSR, NULL, rndis_rx_trigger_store); static struct device_attribute *rndis_function_attributes[] = { &dev_attr_manufacturer, &dev_attr_wceis, &dev_attr_ethaddr, &dev_attr_vendorID, &dev_attr_max_pkt_per_xfer, &dev_attr_rx_trigger, NULL }; Loading drivers/usb/gadget/f_rndis.c +32 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,10 @@ module_param(rndis_ul_max_pkt_per_xfer, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(rndis_ul_max_pkt_per_xfer, "Maximum packets per transfer for UL aggregation"); static unsigned int rx_trigger_enabled; module_param(rx_trigger_enabled, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(rx_trigger_enabled, "rx trigger_enable"); struct f_rndis { struct gether port; u8 ctrl_id, data_id; Loading @@ -89,6 +93,28 @@ struct f_rndis { atomic_t notify_count; }; static struct f_rndis *__rndis; int rndis_rx_trigger(void) { struct f_rndis *rndis = __rndis; if (!rx_trigger_enabled || !rndis) { pr_err("can't set rx trigger\n"); return -EINVAL; } if (rndis->port.rx_triggered) return 0; rndis->port.rx_triggered = true; gether_up(&rndis->port); return 0; } static inline struct f_rndis *func_to_rndis(struct usb_function *f) { return container_of(f, struct f_rndis, port.func); Loading Loading @@ -592,6 +618,8 @@ static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt) } else if (intf == rndis->data_id) { struct net_device *net; rndis->port.rx_triggered = false; if (rndis->port.in_ep->driver_data) { DBG(cdev, "reset rndis\n"); gether_disconnect(&rndis->port); Loading Loading @@ -839,6 +867,7 @@ rndis_unbind(struct usb_configuration *c, struct usb_function *f) usb_ep_free_request(rndis->notify, rndis->notify_req); kfree(rndis); __rndis = NULL; } /* Some controllers can't support RNDIS ... */ Loading Loading @@ -879,6 +908,8 @@ rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], if (!rndis) goto fail; __rndis = rndis; memcpy(rndis->ethaddr, ethaddr, ETH_ALEN); rndis->vendorID = vendorID; rndis->manufacturer = manufacturer; Loading @@ -893,6 +924,7 @@ rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], rndis->port.unwrap = rndis_rm_hdr; rndis->port.ul_max_pkts_per_xfer = rndis_ul_max_pkt_per_xfer; rndis->port.dl_max_pkts_per_xfer = rndis_dl_max_pkt_per_xfer; rndis->port.rx_trigger_enabled = rx_trigger_enabled; rndis->port.func.name = "rndis"; rndis->port.func.strings = rndis_strings; Loading drivers/usb/gadget/u_ether.c +29 −3 Original line number Diff line number Diff line Loading @@ -73,6 +73,7 @@ struct eth_dev { unsigned header_len; unsigned int ul_max_pkts_per_xfer; unsigned int dl_max_pkts_per_xfer; bool rx_trigger_enabled; struct sk_buff *(*wrap)(struct gether *, struct sk_buff *skb); int (*unwrap)(struct gether *, struct sk_buff *skb, Loading Loading @@ -831,13 +832,21 @@ static int eth_open(struct net_device *net) { struct eth_dev *dev = netdev_priv(net); struct gether *link; bool wait_for_rx_trigger; DBG(dev, "%s\n", __func__); if (netif_carrier_ok(dev->net)) eth_start(dev, GFP_KERNEL); spin_lock_irq(&dev->lock); link = dev->port_usb; spin_unlock_irq(&dev->lock); wait_for_rx_trigger = dev->rx_trigger_enabled && link && !link->rx_triggered; if (netif_carrier_ok(dev->net) && !wait_for_rx_trigger) eth_start(dev, GFP_KERNEL); spin_lock_irq(&dev->lock); if (link && link->open) link->open(link); spin_unlock_irq(&dev->lock); Loading Loading @@ -1060,6 +1069,7 @@ struct net_device *gether_connect(struct gether *link) { struct eth_dev *dev = link->ioport; int result = 0; bool wait_for_rx_trigger; if (!dev) return ERR_PTR(-EINVAL); Loading Loading @@ -1092,6 +1102,7 @@ struct net_device *gether_connect(struct gether *link) dev->wrap = link->wrap; dev->ul_max_pkts_per_xfer = link->ul_max_pkts_per_xfer; dev->dl_max_pkts_per_xfer = link->dl_max_pkts_per_xfer; dev->rx_trigger_enabled = link->rx_trigger_enabled; spin_lock(&dev->lock); dev->tx_skb_hold_count = 0; Loading @@ -1108,7 +1119,11 @@ struct net_device *gether_connect(struct gether *link) spin_unlock(&dev->lock); netif_carrier_on(dev->net); if (netif_running(dev->net)) wait_for_rx_trigger = dev->rx_trigger_enabled && !link->rx_triggered; if (netif_running(dev->net) && !wait_for_rx_trigger) eth_start(dev, GFP_ATOMIC); /* on error, disable any endpoints */ Loading Loading @@ -1196,12 +1211,23 @@ void gether_disconnect(struct gether *link) dev->header_len = 0; dev->unwrap = NULL; dev->wrap = NULL; dev->rx_trigger_enabled = 0; spin_lock(&dev->lock); dev->port_usb = NULL; spin_unlock(&dev->lock); } int gether_up(struct gether *link) { struct eth_dev *dev = link->ioport; if (dev && netif_carrier_ok(dev->net)) eth_start(dev, GFP_KERNEL); return 0; } static int __init gether_init(void) { uether_wq = create_singlethread_workqueue("uether"); Loading drivers/usb/gadget/u_ether.h +10 −1 Original line number Diff line number Diff line Loading @@ -58,6 +58,8 @@ struct gether { unsigned ul_max_pkts_per_xfer; unsigned dl_max_pkts_per_xfer; bool multi_pkt_xfer; bool rx_trigger_enabled; bool rx_triggered; struct sk_buff *(*wrap)(struct gether *port, struct sk_buff *skb); int (*unwrap)(struct gether *port, Loading Loading @@ -102,6 +104,7 @@ void gether_cleanup(struct eth_dev *dev); /* connect/disconnect is handled by individual functions */ struct net_device *gether_connect(struct gether *); void gether_disconnect(struct gether *); int gether_up(struct gether *); /* Some controllers can't support CDC Ethernet (ECM) ... */ static inline bool can_support_ecm(struct usb_gadget *gadget) Loading Loading @@ -129,6 +132,7 @@ int eem_bind_config(struct usb_configuration *c, struct eth_dev *dev); int rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], u32 vendorID, const char *manufacturer, struct eth_dev *dev); int rndis_rx_trigger(void); #else Loading @@ -139,6 +143,12 @@ rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], return 0; } static inline int rndis_rx_trigger(void) { return 0; } #endif /** Loading @@ -159,5 +169,4 @@ static inline int rndis_bind_config(struct usb_configuration *c, return rndis_bind_config_vendor(c, ethaddr, 0, NULL, dev); } #endif /* __U_ETHER_H */ Loading
drivers/usb/gadget/android.c +16 −0 Original line number Diff line number Diff line Loading @@ -1920,12 +1920,28 @@ static DEVICE_ATTR(max_pkt_per_xfer, S_IRUGO | S_IWUSR, rndis_max_pkt_per_xfer_show, rndis_max_pkt_per_xfer_store); static ssize_t rndis_rx_trigger_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { int value; if (sscanf(buf, "%d", &value) == 1) { rndis_rx_trigger(); return size; } return -EINVAL; } static DEVICE_ATTR(rx_trigger, S_IWUSR, NULL, rndis_rx_trigger_store); static struct device_attribute *rndis_function_attributes[] = { &dev_attr_manufacturer, &dev_attr_wceis, &dev_attr_ethaddr, &dev_attr_vendorID, &dev_attr_max_pkt_per_xfer, &dev_attr_rx_trigger, NULL }; Loading
drivers/usb/gadget/f_rndis.c +32 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,10 @@ module_param(rndis_ul_max_pkt_per_xfer, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(rndis_ul_max_pkt_per_xfer, "Maximum packets per transfer for UL aggregation"); static unsigned int rx_trigger_enabled; module_param(rx_trigger_enabled, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(rx_trigger_enabled, "rx trigger_enable"); struct f_rndis { struct gether port; u8 ctrl_id, data_id; Loading @@ -89,6 +93,28 @@ struct f_rndis { atomic_t notify_count; }; static struct f_rndis *__rndis; int rndis_rx_trigger(void) { struct f_rndis *rndis = __rndis; if (!rx_trigger_enabled || !rndis) { pr_err("can't set rx trigger\n"); return -EINVAL; } if (rndis->port.rx_triggered) return 0; rndis->port.rx_triggered = true; gether_up(&rndis->port); return 0; } static inline struct f_rndis *func_to_rndis(struct usb_function *f) { return container_of(f, struct f_rndis, port.func); Loading Loading @@ -592,6 +618,8 @@ static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt) } else if (intf == rndis->data_id) { struct net_device *net; rndis->port.rx_triggered = false; if (rndis->port.in_ep->driver_data) { DBG(cdev, "reset rndis\n"); gether_disconnect(&rndis->port); Loading Loading @@ -839,6 +867,7 @@ rndis_unbind(struct usb_configuration *c, struct usb_function *f) usb_ep_free_request(rndis->notify, rndis->notify_req); kfree(rndis); __rndis = NULL; } /* Some controllers can't support RNDIS ... */ Loading Loading @@ -879,6 +908,8 @@ rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], if (!rndis) goto fail; __rndis = rndis; memcpy(rndis->ethaddr, ethaddr, ETH_ALEN); rndis->vendorID = vendorID; rndis->manufacturer = manufacturer; Loading @@ -893,6 +924,7 @@ rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], rndis->port.unwrap = rndis_rm_hdr; rndis->port.ul_max_pkts_per_xfer = rndis_ul_max_pkt_per_xfer; rndis->port.dl_max_pkts_per_xfer = rndis_dl_max_pkt_per_xfer; rndis->port.rx_trigger_enabled = rx_trigger_enabled; rndis->port.func.name = "rndis"; rndis->port.func.strings = rndis_strings; Loading
drivers/usb/gadget/u_ether.c +29 −3 Original line number Diff line number Diff line Loading @@ -73,6 +73,7 @@ struct eth_dev { unsigned header_len; unsigned int ul_max_pkts_per_xfer; unsigned int dl_max_pkts_per_xfer; bool rx_trigger_enabled; struct sk_buff *(*wrap)(struct gether *, struct sk_buff *skb); int (*unwrap)(struct gether *, struct sk_buff *skb, Loading Loading @@ -831,13 +832,21 @@ static int eth_open(struct net_device *net) { struct eth_dev *dev = netdev_priv(net); struct gether *link; bool wait_for_rx_trigger; DBG(dev, "%s\n", __func__); if (netif_carrier_ok(dev->net)) eth_start(dev, GFP_KERNEL); spin_lock_irq(&dev->lock); link = dev->port_usb; spin_unlock_irq(&dev->lock); wait_for_rx_trigger = dev->rx_trigger_enabled && link && !link->rx_triggered; if (netif_carrier_ok(dev->net) && !wait_for_rx_trigger) eth_start(dev, GFP_KERNEL); spin_lock_irq(&dev->lock); if (link && link->open) link->open(link); spin_unlock_irq(&dev->lock); Loading Loading @@ -1060,6 +1069,7 @@ struct net_device *gether_connect(struct gether *link) { struct eth_dev *dev = link->ioport; int result = 0; bool wait_for_rx_trigger; if (!dev) return ERR_PTR(-EINVAL); Loading Loading @@ -1092,6 +1102,7 @@ struct net_device *gether_connect(struct gether *link) dev->wrap = link->wrap; dev->ul_max_pkts_per_xfer = link->ul_max_pkts_per_xfer; dev->dl_max_pkts_per_xfer = link->dl_max_pkts_per_xfer; dev->rx_trigger_enabled = link->rx_trigger_enabled; spin_lock(&dev->lock); dev->tx_skb_hold_count = 0; Loading @@ -1108,7 +1119,11 @@ struct net_device *gether_connect(struct gether *link) spin_unlock(&dev->lock); netif_carrier_on(dev->net); if (netif_running(dev->net)) wait_for_rx_trigger = dev->rx_trigger_enabled && !link->rx_triggered; if (netif_running(dev->net) && !wait_for_rx_trigger) eth_start(dev, GFP_ATOMIC); /* on error, disable any endpoints */ Loading Loading @@ -1196,12 +1211,23 @@ void gether_disconnect(struct gether *link) dev->header_len = 0; dev->unwrap = NULL; dev->wrap = NULL; dev->rx_trigger_enabled = 0; spin_lock(&dev->lock); dev->port_usb = NULL; spin_unlock(&dev->lock); } int gether_up(struct gether *link) { struct eth_dev *dev = link->ioport; if (dev && netif_carrier_ok(dev->net)) eth_start(dev, GFP_KERNEL); return 0; } static int __init gether_init(void) { uether_wq = create_singlethread_workqueue("uether"); Loading
drivers/usb/gadget/u_ether.h +10 −1 Original line number Diff line number Diff line Loading @@ -58,6 +58,8 @@ struct gether { unsigned ul_max_pkts_per_xfer; unsigned dl_max_pkts_per_xfer; bool multi_pkt_xfer; bool rx_trigger_enabled; bool rx_triggered; struct sk_buff *(*wrap)(struct gether *port, struct sk_buff *skb); int (*unwrap)(struct gether *port, Loading Loading @@ -102,6 +104,7 @@ void gether_cleanup(struct eth_dev *dev); /* connect/disconnect is handled by individual functions */ struct net_device *gether_connect(struct gether *); void gether_disconnect(struct gether *); int gether_up(struct gether *); /* Some controllers can't support CDC Ethernet (ECM) ... */ static inline bool can_support_ecm(struct usb_gadget *gadget) Loading Loading @@ -129,6 +132,7 @@ int eem_bind_config(struct usb_configuration *c, struct eth_dev *dev); int rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], u32 vendorID, const char *manufacturer, struct eth_dev *dev); int rndis_rx_trigger(void); #else Loading @@ -139,6 +143,12 @@ rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], return 0; } static inline int rndis_rx_trigger(void) { return 0; } #endif /** Loading @@ -159,5 +169,4 @@ static inline int rndis_bind_config(struct usb_configuration *c, return rndis_bind_config_vendor(c, ethaddr, 0, NULL, dev); } #endif /* __U_ETHER_H */