| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * USB Network driver infrastructure |
|---|
| 3 | 4 | * Copyright (C) 2000-2005 by David Brownell |
|---|
| 4 | 5 | * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com> |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 7 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 8 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 9 | | - * (at your option) any later version. |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 14 | | - * GNU General Public License for more details. |
|---|
| 15 | | - * |
|---|
| 16 | | - * You should have received a copy of the GNU General Public License |
|---|
| 17 | | - * along with this program; if not, see <http://www.gnu.org/licenses/>. |
|---|
| 18 | 6 | */ |
|---|
| 19 | 7 | |
|---|
| 20 | 8 | /* |
|---|
| .. | .. |
|---|
| 45 | 33 | #include <linux/slab.h> |
|---|
| 46 | 34 | #include <linux/kernel.h> |
|---|
| 47 | 35 | #include <linux/pm_runtime.h> |
|---|
| 48 | | - |
|---|
| 49 | | -#define DRIVER_VERSION "22-Aug-2005" |
|---|
| 50 | | - |
|---|
| 51 | 36 | |
|---|
| 52 | 37 | /*-------------------------------------------------------------------------*/ |
|---|
| 53 | 38 | |
|---|
| .. | .. |
|---|
| 122 | 107 | if (!usb_endpoint_dir_in(&e->desc)) |
|---|
| 123 | 108 | continue; |
|---|
| 124 | 109 | intr = 1; |
|---|
| 125 | | - /* FALLTHROUGH */ |
|---|
| 110 | + fallthrough; |
|---|
| 126 | 111 | case USB_ENDPOINT_XFER_BULK: |
|---|
| 127 | 112 | break; |
|---|
| 128 | 113 | default: |
|---|
| .. | .. |
|---|
| 609 | 594 | case -EPIPE: |
|---|
| 610 | 595 | dev->net->stats.rx_errors++; |
|---|
| 611 | 596 | usbnet_defer_kevent (dev, EVENT_RX_HALT); |
|---|
| 612 | | - // FALLTHROUGH |
|---|
| 597 | + fallthrough; |
|---|
| 613 | 598 | |
|---|
| 614 | 599 | /* software-driven interface shutdown */ |
|---|
| 615 | 600 | case -ECONNRESET: /* async unlink */ |
|---|
| .. | .. |
|---|
| 640 | 625 | /* data overrun ... flush fifo? */ |
|---|
| 641 | 626 | case -EOVERFLOW: |
|---|
| 642 | 627 | dev->net->stats.rx_over_errors++; |
|---|
| 643 | | - // FALLTHROUGH |
|---|
| 628 | + fallthrough; |
|---|
| 644 | 629 | |
|---|
| 645 | 630 | default: |
|---|
| 646 | 631 | state = rx_cleanup; |
|---|
| .. | .. |
|---|
| 811 | 796 | int usbnet_stop (struct net_device *net) |
|---|
| 812 | 797 | { |
|---|
| 813 | 798 | struct usbnet *dev = netdev_priv(net); |
|---|
| 814 | | - struct driver_info *info = dev->driver_info; |
|---|
| 799 | + const struct driver_info *info = dev->driver_info; |
|---|
| 815 | 800 | int retval, pm, mpn; |
|---|
| 816 | 801 | |
|---|
| 817 | 802 | clear_bit(EVENT_DEV_OPEN, &dev->flags); |
|---|
| .. | .. |
|---|
| 845 | 830 | |
|---|
| 846 | 831 | mpn = !test_and_clear_bit(EVENT_NO_RUNTIME_PM, &dev->flags); |
|---|
| 847 | 832 | |
|---|
| 848 | | - /* deferred work (task, timer, softirq) must also stop. |
|---|
| 849 | | - * can't flush_scheduled_work() until we drop rtnl (later), |
|---|
| 850 | | - * else workers could deadlock; so make workers a NOP. |
|---|
| 851 | | - */ |
|---|
| 833 | + /* deferred work (timer, softirq, task) must also stop */ |
|---|
| 852 | 834 | dev->flags = 0; |
|---|
| 853 | 835 | del_timer_sync (&dev->delay); |
|---|
| 854 | 836 | tasklet_kill (&dev->bh); |
|---|
| 837 | + cancel_work_sync(&dev->kevent); |
|---|
| 855 | 838 | if (!pm) |
|---|
| 856 | 839 | usb_autopm_put_interface(dev->intf); |
|---|
| 857 | 840 | |
|---|
| .. | .. |
|---|
| 874 | 857 | { |
|---|
| 875 | 858 | struct usbnet *dev = netdev_priv(net); |
|---|
| 876 | 859 | int retval; |
|---|
| 877 | | - struct driver_info *info = dev->driver_info; |
|---|
| 860 | + const struct driver_info *info = dev->driver_info; |
|---|
| 878 | 861 | |
|---|
| 879 | 862 | if ((retval = usb_autopm_get_interface(dev->intf)) < 0) { |
|---|
| 880 | 863 | netif_info(dev, ifup, dev->net, |
|---|
| .. | .. |
|---|
| 998 | 981 | void usbnet_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats) |
|---|
| 999 | 982 | { |
|---|
| 1000 | 983 | struct usbnet *dev = netdev_priv(net); |
|---|
| 1001 | | - unsigned int start; |
|---|
| 1002 | | - int cpu; |
|---|
| 1003 | 984 | |
|---|
| 1004 | 985 | netdev_stats_to_stats64(stats, &net->stats); |
|---|
| 1005 | | - |
|---|
| 1006 | | - for_each_possible_cpu(cpu) { |
|---|
| 1007 | | - struct pcpu_sw_netstats *stats64; |
|---|
| 1008 | | - u64 rx_packets, rx_bytes; |
|---|
| 1009 | | - u64 tx_packets, tx_bytes; |
|---|
| 1010 | | - |
|---|
| 1011 | | - stats64 = per_cpu_ptr(dev->stats64, cpu); |
|---|
| 1012 | | - |
|---|
| 1013 | | - do { |
|---|
| 1014 | | - start = u64_stats_fetch_begin_irq(&stats64->syncp); |
|---|
| 1015 | | - rx_packets = stats64->rx_packets; |
|---|
| 1016 | | - rx_bytes = stats64->rx_bytes; |
|---|
| 1017 | | - tx_packets = stats64->tx_packets; |
|---|
| 1018 | | - tx_bytes = stats64->tx_bytes; |
|---|
| 1019 | | - } while (u64_stats_fetch_retry_irq(&stats64->syncp, start)); |
|---|
| 1020 | | - |
|---|
| 1021 | | - stats->rx_packets += rx_packets; |
|---|
| 1022 | | - stats->rx_bytes += rx_bytes; |
|---|
| 1023 | | - stats->tx_packets += tx_packets; |
|---|
| 1024 | | - stats->tx_bytes += tx_bytes; |
|---|
| 1025 | | - } |
|---|
| 986 | + dev_fetch_sw_netstats(stats, dev->stats64); |
|---|
| 1026 | 987 | } |
|---|
| 1027 | 988 | EXPORT_SYMBOL_GPL(usbnet_get_stats64); |
|---|
| 1028 | 989 | |
|---|
| .. | .. |
|---|
| 1059 | 1020 | struct usbnet *dev = netdev_priv(net); |
|---|
| 1060 | 1021 | |
|---|
| 1061 | 1022 | strlcpy (info->driver, dev->driver_name, sizeof info->driver); |
|---|
| 1062 | | - strlcpy (info->version, DRIVER_VERSION, sizeof info->version); |
|---|
| 1063 | 1023 | strlcpy (info->fw_version, dev->driver_info->description, |
|---|
| 1064 | 1024 | sizeof info->fw_version); |
|---|
| 1065 | 1025 | usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info); |
|---|
| .. | .. |
|---|
| 1120 | 1080 | clear_bit(EVENT_LINK_CHANGE, &dev->flags); |
|---|
| 1121 | 1081 | } |
|---|
| 1122 | 1082 | |
|---|
| 1123 | | -static void usbnet_set_rx_mode(struct net_device *net) |
|---|
| 1083 | +void usbnet_set_rx_mode(struct net_device *net) |
|---|
| 1124 | 1084 | { |
|---|
| 1125 | 1085 | struct usbnet *dev = netdev_priv(net); |
|---|
| 1126 | 1086 | |
|---|
| 1127 | 1087 | usbnet_defer_kevent(dev, EVENT_SET_RX_MODE); |
|---|
| 1128 | 1088 | } |
|---|
| 1089 | +EXPORT_SYMBOL_GPL(usbnet_set_rx_mode); |
|---|
| 1129 | 1090 | |
|---|
| 1130 | 1091 | static void __handle_set_rx_mode(struct usbnet *dev) |
|---|
| 1131 | 1092 | { |
|---|
| .. | .. |
|---|
| 1214 | 1175 | } |
|---|
| 1215 | 1176 | |
|---|
| 1216 | 1177 | if (test_bit (EVENT_LINK_RESET, &dev->flags)) { |
|---|
| 1217 | | - struct driver_info *info = dev->driver_info; |
|---|
| 1178 | + const struct driver_info *info = dev->driver_info; |
|---|
| 1218 | 1179 | int retval = 0; |
|---|
| 1219 | 1180 | |
|---|
| 1220 | 1181 | clear_bit (EVENT_LINK_RESET, &dev->flags); |
|---|
| .. | .. |
|---|
| 1305 | 1266 | |
|---|
| 1306 | 1267 | /*-------------------------------------------------------------------------*/ |
|---|
| 1307 | 1268 | |
|---|
| 1308 | | -void usbnet_tx_timeout (struct net_device *net) |
|---|
| 1269 | +void usbnet_tx_timeout (struct net_device *net, unsigned int txqueue) |
|---|
| 1309 | 1270 | { |
|---|
| 1310 | 1271 | struct usbnet *dev = netdev_priv(net); |
|---|
| 1311 | 1272 | |
|---|
| .. | .. |
|---|
| 1344 | 1305 | total_len += skb_headlen(skb); |
|---|
| 1345 | 1306 | |
|---|
| 1346 | 1307 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { |
|---|
| 1347 | | - struct skb_frag_struct *f = &skb_shinfo(skb)->frags[i]; |
|---|
| 1308 | + skb_frag_t *f = &skb_shinfo(skb)->frags[i]; |
|---|
| 1348 | 1309 | |
|---|
| 1349 | 1310 | total_len += skb_frag_size(f); |
|---|
| 1350 | | - sg_set_page(&urb->sg[i + s], f->page.p, f->size, |
|---|
| 1351 | | - f->page_offset); |
|---|
| 1311 | + sg_set_page(&urb->sg[i + s], skb_frag_page(f), skb_frag_size(f), |
|---|
| 1312 | + skb_frag_off(f)); |
|---|
| 1352 | 1313 | } |
|---|
| 1353 | 1314 | urb->transfer_buffer_length = total_len; |
|---|
| 1354 | 1315 | |
|---|
| .. | .. |
|---|
| 1362 | 1323 | unsigned int length; |
|---|
| 1363 | 1324 | struct urb *urb = NULL; |
|---|
| 1364 | 1325 | struct skb_data *entry; |
|---|
| 1365 | | - struct driver_info *info = dev->driver_info; |
|---|
| 1326 | + const struct driver_info *info = dev->driver_info; |
|---|
| 1366 | 1327 | unsigned long flags; |
|---|
| 1367 | 1328 | int retval; |
|---|
| 1368 | 1329 | |
|---|
| .. | .. |
|---|
| 1541 | 1502 | continue; |
|---|
| 1542 | 1503 | case tx_done: |
|---|
| 1543 | 1504 | kfree(entry->urb->sg); |
|---|
| 1505 | + fallthrough; |
|---|
| 1544 | 1506 | case rx_cleanup: |
|---|
| 1545 | 1507 | usb_free_urb (entry->urb); |
|---|
| 1546 | 1508 | dev_kfree_skb (skb); |
|---|
| .. | .. |
|---|
| 1605 | 1567 | struct usbnet *dev; |
|---|
| 1606 | 1568 | struct usb_device *xdev; |
|---|
| 1607 | 1569 | struct net_device *net; |
|---|
| 1570 | + struct urb *urb; |
|---|
| 1608 | 1571 | |
|---|
| 1609 | 1572 | dev = usb_get_intfdata(intf); |
|---|
| 1610 | 1573 | usb_set_intfdata(intf, NULL); |
|---|
| .. | .. |
|---|
| 1621 | 1584 | net = dev->net; |
|---|
| 1622 | 1585 | unregister_netdev (net); |
|---|
| 1623 | 1586 | |
|---|
| 1624 | | - cancel_work_sync(&dev->kevent); |
|---|
| 1625 | | - |
|---|
| 1626 | | - usb_scuttle_anchored_urbs(&dev->deferred); |
|---|
| 1587 | + while ((urb = usb_get_from_anchor(&dev->deferred))) { |
|---|
| 1588 | + dev_kfree_skb(urb->context); |
|---|
| 1589 | + kfree(urb->sg); |
|---|
| 1590 | + usb_free_urb(urb); |
|---|
| 1591 | + } |
|---|
| 1627 | 1592 | |
|---|
| 1628 | 1593 | if (dev->driver_info->unbind) |
|---|
| 1629 | 1594 | dev->driver_info->unbind (dev, intf); |
|---|
| .. | .. |
|---|
| 1667 | 1632 | struct usbnet *dev; |
|---|
| 1668 | 1633 | struct net_device *net; |
|---|
| 1669 | 1634 | struct usb_host_interface *interface; |
|---|
| 1670 | | - struct driver_info *info; |
|---|
| 1635 | + const struct driver_info *info; |
|---|
| 1671 | 1636 | struct usb_device *xdev; |
|---|
| 1672 | 1637 | int status; |
|---|
| 1673 | 1638 | const char *name; |
|---|
| .. | .. |
|---|
| 1683 | 1648 | } |
|---|
| 1684 | 1649 | |
|---|
| 1685 | 1650 | name = udev->dev.driver->name; |
|---|
| 1686 | | - info = (struct driver_info *) prod->driver_info; |
|---|
| 1651 | + info = (const struct driver_info *) prod->driver_info; |
|---|
| 1687 | 1652 | if (!info) { |
|---|
| 1688 | 1653 | dev_dbg (&udev->dev, "blacklisted by %s\n", name); |
|---|
| 1689 | 1654 | return -ENODEV; |
|---|
| .. | .. |
|---|
| 1762 | 1727 | /* WWAN devices should always be named "wwan%d" */ |
|---|
| 1763 | 1728 | if ((dev->driver_info->flags & FLAG_WWAN) != 0) |
|---|
| 1764 | 1729 | strcpy(net->name, "wwan%d"); |
|---|
| 1765 | | - |
|---|
| 1766 | | - /* LTE devices should always be named "lte%d" */ |
|---|
| 1767 | | - if ((dev->driver_info->flags & FLAG_LTE) != 0) |
|---|
| 1768 | | - strcpy(net->name, "lte%d"); |
|---|
| 1769 | 1730 | |
|---|
| 1770 | 1731 | /* devices that cannot do ARP */ |
|---|
| 1771 | 1732 | if ((dev->driver_info->flags & FLAG_NOARP) != 0) |
|---|
| .. | .. |
|---|
| 2009 | 1970 | cmd, reqtype, value, index, size); |
|---|
| 2010 | 1971 | |
|---|
| 2011 | 1972 | if (size) { |
|---|
| 2012 | | - buf = kmalloc(size, GFP_KERNEL); |
|---|
| 1973 | + buf = kmalloc(size, GFP_NOIO); |
|---|
| 2013 | 1974 | if (!buf) |
|---|
| 2014 | 1975 | goto out; |
|---|
| 2015 | 1976 | } |
|---|
| .. | .. |
|---|
| 2041 | 2002 | cmd, reqtype, value, index, size); |
|---|
| 2042 | 2003 | |
|---|
| 2043 | 2004 | if (data) { |
|---|
| 2044 | | - buf = kmemdup(data, size, GFP_KERNEL); |
|---|
| 2005 | + buf = kmemdup(data, size, GFP_NOIO); |
|---|
| 2045 | 2006 | if (!buf) |
|---|
| 2046 | 2007 | goto out; |
|---|
| 2047 | 2008 | } else { |
|---|
| .. | .. |
|---|
| 2142 | 2103 | int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype, |
|---|
| 2143 | 2104 | u16 value, u16 index, const void *data, u16 size) |
|---|
| 2144 | 2105 | { |
|---|
| 2145 | | - struct usb_ctrlrequest *req = NULL; |
|---|
| 2106 | + struct usb_ctrlrequest *req; |
|---|
| 2146 | 2107 | struct urb *urb; |
|---|
| 2147 | 2108 | int err = -ENOMEM; |
|---|
| 2148 | 2109 | void *buf = NULL; |
|---|
| .. | .. |
|---|
| 2160 | 2121 | if (!buf) { |
|---|
| 2161 | 2122 | netdev_err(dev->net, "Error allocating buffer" |
|---|
| 2162 | 2123 | " in %s!\n", __func__); |
|---|
| 2163 | | - goto fail_free; |
|---|
| 2124 | + goto fail_free_urb; |
|---|
| 2164 | 2125 | } |
|---|
| 2165 | 2126 | } |
|---|
| 2166 | 2127 | |
|---|
| .. | .. |
|---|
| 2184 | 2145 | if (err < 0) { |
|---|
| 2185 | 2146 | netdev_err(dev->net, "Error submitting the control" |
|---|
| 2186 | 2147 | " message: status=%d\n", err); |
|---|
| 2187 | | - goto fail_free; |
|---|
| 2148 | + goto fail_free_all; |
|---|
| 2188 | 2149 | } |
|---|
| 2189 | 2150 | return 0; |
|---|
| 2190 | 2151 | |
|---|
| 2152 | +fail_free_all: |
|---|
| 2153 | + kfree(req); |
|---|
| 2191 | 2154 | fail_free_buf: |
|---|
| 2192 | 2155 | kfree(buf); |
|---|
| 2193 | | -fail_free: |
|---|
| 2194 | | - kfree(req); |
|---|
| 2156 | + /* |
|---|
| 2157 | + * avoid a double free |
|---|
| 2158 | + * needed because the flag can be set only |
|---|
| 2159 | + * after filling the URB |
|---|
| 2160 | + */ |
|---|
| 2161 | + urb->transfer_flags = 0; |
|---|
| 2162 | +fail_free_urb: |
|---|
| 2195 | 2163 | usb_free_urb(urb); |
|---|
| 2196 | 2164 | fail: |
|---|
| 2197 | 2165 | return err; |
|---|
| .. | .. |
|---|
| 2204 | 2172 | { |
|---|
| 2205 | 2173 | /* Compiler should optimize this out. */ |
|---|
| 2206 | 2174 | BUILD_BUG_ON( |
|---|
| 2207 | | - FIELD_SIZEOF(struct sk_buff, cb) < sizeof(struct skb_data)); |
|---|
| 2175 | + sizeof_field(struct sk_buff, cb) < sizeof(struct skb_data)); |
|---|
| 2208 | 2176 | |
|---|
| 2209 | 2177 | eth_random_addr(node_id); |
|---|
| 2210 | 2178 | return 0; |
|---|