Skip to content

Commit bcd4a1c

Browse files
Andrzej PietrasiewiczFelipe Balbi
authored andcommitted
usb: gadget: u_ether: construct with default values and add setters/getters
Add an interface to create a struct netdev_dev filled with default values, an interface which makes it an interface to fill the struct with useful values and an interface to read the values set. The patch also adds an interface to register the net device associated with an ethernet-over-usb link. Signed-off-by: Andrzej Pietrasiewicz <[email protected]> Signed-off-by: Kyungmin Park <[email protected]> Signed-off-by: Felipe Balbi <[email protected]>
1 parent cbbd14a commit bcd4a1c

File tree

2 files changed

+307
-1
lines changed

2 files changed

+307
-1
lines changed

drivers/usb/gadget/u_ether.c

Lines changed: 184 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ struct eth_dev {
7878

7979
bool zlp;
8080
u8 host_mac[ETH_ALEN];
81+
u8 dev_mac[ETH_ALEN];
8182
};
8283

8384
/*-------------------------------------------------------------------------*/
@@ -716,6 +717,17 @@ static int get_ether_addr(const char *str, u8 *dev_addr)
716717
return 1;
717718
}
718719

720+
static int get_ether_addr_str(u8 dev_addr[ETH_ALEN], char *str, int len)
721+
{
722+
if (len < 18)
723+
return -EINVAL;
724+
725+
snprintf(str, len, "%02x:%02x:%02x:%02x:%02x:%02x",
726+
dev_addr[0], dev_addr[1], dev_addr[2],
727+
dev_addr[3], dev_addr[4], dev_addr[5]);
728+
return 18;
729+
}
730+
719731
static const struct net_device_ops eth_netdev_ops = {
720732
.ndo_open = eth_open,
721733
.ndo_stop = eth_stop,
@@ -796,7 +808,8 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g,
796808
INFO(dev, "MAC %pM\n", net->dev_addr);
797809
INFO(dev, "HOST MAC %pM\n", dev->host_mac);
798810

799-
/* two kinds of host-initiated state changes:
811+
/*
812+
* two kinds of host-initiated state changes:
800813
* - iff DATA transfer is active, carrier is "on"
801814
* - tx queueing enabled if open *and* carrier is "on"
802815
*/
@@ -807,6 +820,176 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g,
807820
}
808821
EXPORT_SYMBOL(gether_setup_name);
809822

823+
struct net_device *gether_setup_name_default(const char *netname)
824+
{
825+
struct net_device *net;
826+
struct eth_dev *dev;
827+
828+
net = alloc_etherdev(sizeof(*dev));
829+
if (!net)
830+
return ERR_PTR(-ENOMEM);
831+
832+
dev = netdev_priv(net);
833+
spin_lock_init(&dev->lock);
834+
spin_lock_init(&dev->req_lock);
835+
INIT_WORK(&dev->work, eth_work);
836+
INIT_LIST_HEAD(&dev->tx_reqs);
837+
INIT_LIST_HEAD(&dev->rx_reqs);
838+
839+
skb_queue_head_init(&dev->rx_frames);
840+
841+
/* network device setup */
842+
dev->net = net;
843+
dev->qmult = QMULT_DEFAULT;
844+
snprintf(net->name, sizeof(net->name), "%s%%d", netname);
845+
846+
eth_random_addr(dev->dev_mac);
847+
pr_warn("using random %s ethernet address\n", "self");
848+
eth_random_addr(dev->host_mac);
849+
pr_warn("using random %s ethernet address\n", "host");
850+
851+
net->netdev_ops = &eth_netdev_ops;
852+
853+
SET_ETHTOOL_OPS(net, &ops);
854+
SET_NETDEV_DEVTYPE(net, &gadget_type);
855+
856+
return net;
857+
}
858+
EXPORT_SYMBOL(gether_setup_name_default);
859+
860+
int gether_register_netdev(struct net_device *net)
861+
{
862+
struct eth_dev *dev;
863+
struct usb_gadget *g;
864+
struct sockaddr sa;
865+
int status;
866+
867+
if (!net->dev.parent)
868+
return -EINVAL;
869+
dev = netdev_priv(net);
870+
g = dev->gadget;
871+
status = register_netdev(net);
872+
if (status < 0) {
873+
dev_dbg(&g->dev, "register_netdev failed, %d\n", status);
874+
return status;
875+
} else {
876+
INFO(dev, "HOST MAC %pM\n", dev->host_mac);
877+
878+
/* two kinds of host-initiated state changes:
879+
* - iff DATA transfer is active, carrier is "on"
880+
* - tx queueing enabled if open *and* carrier is "on"
881+
*/
882+
netif_carrier_off(net);
883+
}
884+
sa.sa_family = net->type;
885+
memcpy(sa.sa_data, dev->dev_mac, ETH_ALEN);
886+
rtnl_lock();
887+
status = dev_set_mac_address(net, &sa);
888+
rtnl_unlock();
889+
if (status)
890+
pr_warn("cannot set self ethernet address: %d\n", status);
891+
else
892+
INFO(dev, "MAC %pM\n", dev->dev_mac);
893+
894+
return status;
895+
}
896+
EXPORT_SYMBOL(gether_register_netdev);
897+
898+
void gether_set_gadget(struct net_device *net, struct usb_gadget *g)
899+
{
900+
struct eth_dev *dev;
901+
902+
dev = netdev_priv(net);
903+
dev->gadget = g;
904+
SET_NETDEV_DEV(net, &g->dev);
905+
}
906+
EXPORT_SYMBOL(gether_set_gadget);
907+
908+
int gether_set_dev_addr(struct net_device *net, const char *dev_addr)
909+
{
910+
struct eth_dev *dev;
911+
u8 new_addr[ETH_ALEN];
912+
913+
dev = netdev_priv(net);
914+
if (get_ether_addr(dev_addr, new_addr))
915+
return -EINVAL;
916+
memcpy(dev->dev_mac, new_addr, ETH_ALEN);
917+
return 0;
918+
}
919+
EXPORT_SYMBOL(gether_set_dev_addr);
920+
921+
int gether_get_dev_addr(struct net_device *net, char *dev_addr, int len)
922+
{
923+
struct eth_dev *dev;
924+
925+
dev = netdev_priv(net);
926+
return get_ether_addr_str(dev->dev_mac, dev_addr, len);
927+
}
928+
EXPORT_SYMBOL(gether_get_dev_addr);
929+
930+
int gether_set_host_addr(struct net_device *net, const char *host_addr)
931+
{
932+
struct eth_dev *dev;
933+
u8 new_addr[ETH_ALEN];
934+
935+
dev = netdev_priv(net);
936+
if (get_ether_addr(host_addr, new_addr))
937+
return -EINVAL;
938+
memcpy(dev->host_mac, new_addr, ETH_ALEN);
939+
return 0;
940+
}
941+
EXPORT_SYMBOL(gether_set_host_addr);
942+
943+
int gether_get_host_addr(struct net_device *net, char *host_addr, int len)
944+
{
945+
struct eth_dev *dev;
946+
947+
dev = netdev_priv(net);
948+
return get_ether_addr_str(dev->host_mac, host_addr, len);
949+
}
950+
EXPORT_SYMBOL(gether_get_host_addr);
951+
952+
int gether_get_host_addr_cdc(struct net_device *net, char *host_addr, int len)
953+
{
954+
struct eth_dev *dev;
955+
956+
if (len < 13)
957+
return -EINVAL;
958+
959+
dev = netdev_priv(net);
960+
snprintf(host_addr, len, "%pm", dev->host_mac);
961+
962+
return strlen(host_addr);
963+
}
964+
EXPORT_SYMBOL(gether_get_host_addr_cdc);
965+
966+
void gether_set_qmult(struct net_device *net, unsigned qmult)
967+
{
968+
struct eth_dev *dev;
969+
970+
dev = netdev_priv(net);
971+
dev->qmult = qmult;
972+
}
973+
EXPORT_SYMBOL(gether_set_qmult);
974+
975+
unsigned gether_get_qmult(struct net_device *net)
976+
{
977+
struct eth_dev *dev;
978+
979+
dev = netdev_priv(net);
980+
return dev->qmult;
981+
}
982+
EXPORT_SYMBOL(gether_get_qmult);
983+
984+
int gether_get_ifname(struct net_device *net, char *name, int len)
985+
{
986+
rtnl_lock();
987+
strlcpy(name, netdev_name(net), len);
988+
rtnl_unlock();
989+
return strlen(name);
990+
}
991+
EXPORT_SYMBOL(gether_get_ifname);
992+
810993
/**
811994
* gether_cleanup - remove Ethernet-over-USB device
812995
* Context: may sleep

drivers/usb/gadget/u_ether.h

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,129 @@ static inline struct eth_dev *gether_setup(struct usb_gadget *g,
115115
return gether_setup_name(g, dev_addr, host_addr, ethaddr, qmult, "usb");
116116
}
117117

118+
/*
119+
* variant of gether_setup_default that allows customizing
120+
* network device name
121+
*/
122+
struct net_device *gether_setup_name_default(const char *netname);
123+
124+
/*
125+
* gether_register_netdev - register the net device
126+
* @net: net device to register
127+
*
128+
* Registers the net device associated with this ethernet-over-usb link
129+
*
130+
*/
131+
int gether_register_netdev(struct net_device *net);
132+
133+
/* gether_setup_default - initialize one ethernet-over-usb link
134+
* Context: may sleep
135+
*
136+
* This sets up the single network link that may be exported by a
137+
* gadget driver using this framework. The link layer addresses
138+
* are set to random values.
139+
*
140+
* Returns negative errno, or zero on success
141+
*/
142+
static inline struct net_device *gether_setup_default(void)
143+
{
144+
return gether_setup_name_default("usb");
145+
}
146+
147+
/**
148+
* gether_set_gadget - initialize one ethernet-over-usb link with a gadget
149+
* @net: device representing this link
150+
* @g: the gadget to initialize with
151+
*
152+
* This associates one ethernet-over-usb link with a gadget.
153+
*/
154+
void gether_set_gadget(struct net_device *net, struct usb_gadget *g);
155+
156+
/**
157+
* gether_set_dev_addr - initialize an ethernet-over-usb link with eth address
158+
* @net: device representing this link
159+
* @dev_addr: eth address of this device
160+
*
161+
* This sets the device-side Ethernet address of this ethernet-over-usb link
162+
* if dev_addr is correct.
163+
* Returns negative errno if the new address is incorrect.
164+
*/
165+
int gether_set_dev_addr(struct net_device *net, const char *dev_addr);
166+
167+
/**
168+
* gether_get_dev_addr - get an ethernet-over-usb link eth address
169+
* @net: device representing this link
170+
* @dev_addr: place to store device's eth address
171+
* @len: length of the @dev_addr buffer
172+
*
173+
* This gets the device-side Ethernet address of this ethernet-over-usb link.
174+
* Returns zero on success, else negative errno.
175+
*/
176+
int gether_get_dev_addr(struct net_device *net, char *dev_addr, int len);
177+
178+
/**
179+
* gether_set_host_addr - initialize an ethernet-over-usb link with host address
180+
* @net: device representing this link
181+
* @host_addr: eth address of the host
182+
*
183+
* This sets the host-side Ethernet address of this ethernet-over-usb link
184+
* if host_addr is correct.
185+
* Returns negative errno if the new address is incorrect.
186+
*/
187+
int gether_set_host_addr(struct net_device *net, const char *host_addr);
188+
189+
/**
190+
* gether_get_host_addr - get an ethernet-over-usb link host address
191+
* @net: device representing this link
192+
* @host_addr: place to store eth address of the host
193+
* @len: length of the @host_addr buffer
194+
*
195+
* This gets the host-side Ethernet address of this ethernet-over-usb link.
196+
* Returns zero on success, else negative errno.
197+
*/
198+
int gether_get_host_addr(struct net_device *net, char *host_addr, int len);
199+
200+
/**
201+
* gether_get_host_addr_cdc - get an ethernet-over-usb link host address
202+
* @net: device representing this link
203+
* @host_addr: place to store eth address of the host
204+
* @len: length of the @host_addr buffer
205+
*
206+
* This gets the CDC formatted host-side Ethernet address of this
207+
* ethernet-over-usb link.
208+
* Returns zero on success, else negative errno.
209+
*/
210+
int gether_get_host_addr_cdc(struct net_device *net, char *host_addr, int len);
211+
212+
/**
213+
* gether_set_qmult - initialize an ethernet-over-usb link with a multiplier
214+
* @net: device representing this link
215+
* @qmult: queue multiplier
216+
*
217+
* This sets the queue length multiplier of this ethernet-over-usb link.
218+
* For higher speeds use longer queues.
219+
*/
220+
void gether_set_qmult(struct net_device *net, unsigned qmult);
221+
222+
/**
223+
* gether_get_qmult - get an ethernet-over-usb link multiplier
224+
* @net: device representing this link
225+
*
226+
* This gets the queue length multiplier of this ethernet-over-usb link.
227+
*/
228+
unsigned gether_get_qmult(struct net_device *net);
229+
230+
/**
231+
* gether_get_ifname - get an ethernet-over-usb link interface name
232+
* @net: device representing this link
233+
* @name: place to store the interface name
234+
* @len: length of the @name buffer
235+
*
236+
* This gets the interface name of this ethernet-over-usb link.
237+
* Returns zero on success, else negative errno.
238+
*/
239+
int gether_get_ifname(struct net_device *net, char *name, int len);
240+
118241
void gether_cleanup(struct eth_dev *dev);
119242

120243
/* connect/disconnect is handled by individual functions */

0 commit comments

Comments
 (0)