.. | .. |
---|
17 | 17 | #include <linux/etherdevice.h> |
---|
18 | 18 | #include <linux/ethtool.h> |
---|
19 | 19 | #include <linux/if_vlan.h> |
---|
| 20 | +#include <linux/string_helpers.h> |
---|
20 | 21 | |
---|
21 | 22 | #include "u_ether.h" |
---|
22 | 23 | |
---|
.. | .. |
---|
80 | 81 | |
---|
81 | 82 | bool zlp; |
---|
82 | 83 | bool no_skb_reserve; |
---|
| 84 | + bool ifname_set; |
---|
83 | 85 | u8 host_mac[ETH_ALEN]; |
---|
84 | 86 | u8 dev_mac[ETH_ALEN]; |
---|
85 | 87 | }; |
---|
.. | .. |
---|
322 | 324 | /* data overrun */ |
---|
323 | 325 | case -EOVERFLOW: |
---|
324 | 326 | dev->net->stats.rx_over_errors++; |
---|
325 | | - /* FALLTHROUGH */ |
---|
| 327 | + fallthrough; |
---|
326 | 328 | |
---|
327 | 329 | default: |
---|
328 | 330 | dev->net->stats.rx_errors++; |
---|
.. | .. |
---|
445 | 447 | default: |
---|
446 | 448 | dev->net->stats.tx_errors++; |
---|
447 | 449 | VDBG(dev, "tx err %d\n", req->status); |
---|
448 | | - /* FALLTHROUGH */ |
---|
| 450 | + fallthrough; |
---|
449 | 451 | case -ECONNRESET: /* unlink */ |
---|
450 | 452 | case -ESHUTDOWN: /* disconnect etc */ |
---|
451 | 453 | dev_kfree_skb_any(skb); |
---|
.. | .. |
---|
732 | 734 | .name = "gadget", |
---|
733 | 735 | }; |
---|
734 | 736 | |
---|
735 | | -/** |
---|
| 737 | +/* |
---|
736 | 738 | * gether_setup_name - initialize one ethernet-over-usb link |
---|
737 | 739 | * @g: gadget to associated with these links |
---|
738 | 740 | * @ethaddr: NULL, or a buffer in which the ethernet address of the |
---|
.. | .. |
---|
772 | 774 | dev->qmult = qmult; |
---|
773 | 775 | snprintf(net->name, sizeof(net->name), "%s%%d", netname); |
---|
774 | 776 | |
---|
775 | | - if (get_ether_addr(dev_addr, net->dev_addr)) |
---|
| 777 | + if (get_ether_addr(dev_addr, net->dev_addr)) { |
---|
| 778 | + net->addr_assign_type = NET_ADDR_RANDOM; |
---|
776 | 779 | dev_warn(&g->dev, |
---|
777 | 780 | "using random %s ethernet address\n", "self"); |
---|
| 781 | + } else { |
---|
| 782 | + net->addr_assign_type = NET_ADDR_SET; |
---|
| 783 | + } |
---|
778 | 784 | if (get_ether_addr(host_addr, dev->host_mac)) |
---|
779 | 785 | dev_warn(&g->dev, |
---|
780 | 786 | "using random %s ethernet address\n", "host"); |
---|
.. | .. |
---|
831 | 837 | INIT_LIST_HEAD(&dev->tx_reqs); |
---|
832 | 838 | INIT_LIST_HEAD(&dev->rx_reqs); |
---|
833 | 839 | |
---|
| 840 | + /* by default we always have a random MAC address */ |
---|
| 841 | + net->addr_assign_type = NET_ADDR_RANDOM; |
---|
| 842 | + |
---|
834 | 843 | skb_queue_head_init(&dev->rx_frames); |
---|
835 | 844 | |
---|
836 | 845 | /* network device setup */ |
---|
.. | .. |
---|
868 | 877 | g = dev->gadget; |
---|
869 | 878 | |
---|
870 | 879 | memcpy(net->dev_addr, dev->dev_mac, ETH_ALEN); |
---|
871 | | - net->addr_assign_type = NET_ADDR_RANDOM; |
---|
872 | 880 | |
---|
873 | 881 | status = register_netdev(net); |
---|
874 | 882 | if (status < 0) { |
---|
.. | .. |
---|
908 | 916 | if (get_ether_addr(dev_addr, new_addr)) |
---|
909 | 917 | return -EINVAL; |
---|
910 | 918 | memcpy(dev->dev_mac, new_addr, ETH_ALEN); |
---|
| 919 | + net->addr_assign_type = NET_ADDR_SET; |
---|
911 | 920 | return 0; |
---|
912 | 921 | } |
---|
913 | 922 | EXPORT_SYMBOL_GPL(gether_set_dev_addr); |
---|
.. | .. |
---|
967 | 976 | dev = netdev_priv(net); |
---|
968 | 977 | snprintf(host_addr, len, "%pm", dev->host_mac); |
---|
969 | 978 | |
---|
| 979 | + string_upper(host_addr, host_addr); |
---|
| 980 | + |
---|
970 | 981 | return strlen(host_addr); |
---|
971 | 982 | } |
---|
972 | 983 | EXPORT_SYMBOL_GPL(gether_get_host_addr_cdc); |
---|
.. | .. |
---|
1000 | 1011 | |
---|
1001 | 1012 | int gether_get_ifname(struct net_device *net, char *name, int len) |
---|
1002 | 1013 | { |
---|
| 1014 | + struct eth_dev *dev = netdev_priv(net); |
---|
1003 | 1015 | int ret; |
---|
1004 | 1016 | |
---|
1005 | 1017 | rtnl_lock(); |
---|
1006 | | - ret = snprintf(name, len, "%s\n", netdev_name(net)); |
---|
| 1018 | + ret = scnprintf(name, len, "%s\n", |
---|
| 1019 | + dev->ifname_set ? net->name : netdev_name(net)); |
---|
1007 | 1020 | rtnl_unlock(); |
---|
1008 | | - return ret < len ? ret : len; |
---|
| 1021 | + return ret; |
---|
1009 | 1022 | } |
---|
1010 | 1023 | EXPORT_SYMBOL_GPL(gether_get_ifname); |
---|
1011 | 1024 | |
---|
1012 | | -/** |
---|
| 1025 | +int gether_set_ifname(struct net_device *net, const char *name, int len) |
---|
| 1026 | +{ |
---|
| 1027 | + struct eth_dev *dev = netdev_priv(net); |
---|
| 1028 | + char tmp[IFNAMSIZ]; |
---|
| 1029 | + const char *p; |
---|
| 1030 | + |
---|
| 1031 | + if (name[len - 1] == '\n') |
---|
| 1032 | + len--; |
---|
| 1033 | + |
---|
| 1034 | + if (len >= sizeof(tmp)) |
---|
| 1035 | + return -E2BIG; |
---|
| 1036 | + |
---|
| 1037 | + strscpy(tmp, name, len + 1); |
---|
| 1038 | + if (!dev_valid_name(tmp)) |
---|
| 1039 | + return -EINVAL; |
---|
| 1040 | + |
---|
| 1041 | + /* Require exactly one %d, so binding will not fail with EEXIST. */ |
---|
| 1042 | + p = strchr(name, '%'); |
---|
| 1043 | + if (!p || p[1] != 'd' || strchr(p + 2, '%')) |
---|
| 1044 | + return -EINVAL; |
---|
| 1045 | + |
---|
| 1046 | + strncpy(net->name, tmp, sizeof(net->name)); |
---|
| 1047 | + dev->ifname_set = true; |
---|
| 1048 | + |
---|
| 1049 | + return 0; |
---|
| 1050 | +} |
---|
| 1051 | +EXPORT_SYMBOL_GPL(gether_set_ifname); |
---|
| 1052 | + |
---|
| 1053 | +/* |
---|
1013 | 1054 | * gether_cleanup - remove Ethernet-over-USB device |
---|
1014 | 1055 | * Context: may sleep |
---|
1015 | 1056 | * |
---|