xref: /openbmc/linux/net/ethernet/eth.c (revision ca958a1b)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * INET		An implementation of the TCP/IP protocol suite for the LINUX
41da177e4SLinus Torvalds  *		operating system.  INET is implemented using the  BSD Socket
51da177e4SLinus Torvalds  *		interface as the means of communication with the user level.
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  *		Ethernet-type device handling.
81da177e4SLinus Torvalds  *
91da177e4SLinus Torvalds  * Version:	@(#)eth.c	1.0.7	05/25/93
101da177e4SLinus Torvalds  *
1102c30a84SJesper Juhl  * Authors:	Ross Biro
121da177e4SLinus Torvalds  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
131da177e4SLinus Torvalds  *		Mark Evans, <evansmp@uhura.aston.ac.uk>
141da177e4SLinus Torvalds  *		Florian  La Roche, <rzsfl@rz.uni-sb.de>
151da177e4SLinus Torvalds  *		Alan Cox, <gw4pts@gw4pts.ampr.org>
161da177e4SLinus Torvalds  *
171da177e4SLinus Torvalds  * Fixes:
181da177e4SLinus Torvalds  *		Mr Linux	: Arp problems
191da177e4SLinus Torvalds  *		Alan Cox	: Generic queue tidyup (very tiny here)
201da177e4SLinus Torvalds  *		Alan Cox	: eth_header ntohs should be htons
211da177e4SLinus Torvalds  *		Alan Cox	: eth_rebuild_header missing an htons and
221da177e4SLinus Torvalds  *				  minor other things.
231da177e4SLinus Torvalds  *		Tegge		: Arp bug fixes.
241da177e4SLinus Torvalds  *		Florian		: Removed many unnecessary functions, code cleanup
251da177e4SLinus Torvalds  *				  and changes for new arp and skbuff.
261da177e4SLinus Torvalds  *		Alan Cox	: Redid header building to reflect new format.
271da177e4SLinus Torvalds  *		Alan Cox	: ARP only when compiled with CONFIG_INET
281da177e4SLinus Torvalds  *		Greg Page	: 802.2 and SNAP stuff.
291da177e4SLinus Torvalds  *		Alan Cox	: MAC layer pointers/new format.
301da177e4SLinus Torvalds  *		Paul Gortmaker	: eth_copy_and_sum shouldn't csum padding.
311da177e4SLinus Torvalds  *		Alan Cox	: Protect against forwarding explosions with
321da177e4SLinus Torvalds  *				  older network drivers and IFF_ALLMULTI.
331da177e4SLinus Torvalds  *	Christer Weinigel	: Better rebuild header message.
341da177e4SLinus Torvalds  *             Andrew Morton    : 26Feb01: kill ether_setup() - use netdev_boot_setup().
351da177e4SLinus Torvalds  */
361da177e4SLinus Torvalds #include <linux/module.h>
371da177e4SLinus Torvalds #include <linux/types.h>
381da177e4SLinus Torvalds #include <linux/kernel.h>
391da177e4SLinus Torvalds #include <linux/string.h>
401da177e4SLinus Torvalds #include <linux/mm.h>
411da177e4SLinus Torvalds #include <linux/socket.h>
421da177e4SLinus Torvalds #include <linux/in.h>
431da177e4SLinus Torvalds #include <linux/inet.h>
441da177e4SLinus Torvalds #include <linux/ip.h>
451da177e4SLinus Torvalds #include <linux/netdevice.h>
460e839df9SBartosz Golaszewski #include <linux/nvmem-consumer.h>
471da177e4SLinus Torvalds #include <linux/etherdevice.h>
481da177e4SLinus Torvalds #include <linux/skbuff.h>
491da177e4SLinus Torvalds #include <linux/errno.h>
501da177e4SLinus Torvalds #include <linux/init.h>
5146f25dffSKris Katterjohn #include <linux/if_ether.h>
52c7f5d105SDavid S. Miller #include <linux/of_net.h>
53c7f5d105SDavid S. Miller #include <linux/pci.h>
54433baf07SJakub Kicinski #include <linux/property.h>
551da177e4SLinus Torvalds #include <net/dst.h>
561da177e4SLinus Torvalds #include <net/arp.h>
571da177e4SLinus Torvalds #include <net/sock.h>
581da177e4SLinus Torvalds #include <net/ipv6.h>
591da177e4SLinus Torvalds #include <net/ip.h>
60cf85d08fSLennert Buytenhek #include <net/dsa.h>
6110b89ee4SJiri Pirko #include <net/flow_dissector.h>
625588796eSAlexander Lobakin #include <net/gro.h>
63118a7b0eSAvinash Kumar #include <linux/uaccess.h>
64d0a81f67SJesper Dangaard Brouer #include <net/pkt_sched.h>
651da177e4SLinus Torvalds 
66d3e01f71SStephen Hemminger /**
67d3e01f71SStephen Hemminger  * eth_header - create the Ethernet header
68d3e01f71SStephen Hemminger  * @skb:	buffer to alter
69d3e01f71SStephen Hemminger  * @dev:	source device
70d3e01f71SStephen Hemminger  * @type:	Ethernet type field
71d3e01f71SStephen Hemminger  * @daddr: destination address (NULL leave destination address)
72d3e01f71SStephen Hemminger  * @saddr: source address (NULL use device source address)
73d3e01f71SStephen Hemminger  * @len:   packet length (<= skb->len)
741da177e4SLinus Torvalds  *
75d3e01f71SStephen Hemminger  *
76bf9ae538SOctavian Purdila  * Set the protocol type. For a packet of type ETH_P_802_3/2 we put the length
77bf9ae538SOctavian Purdila  * in here instead.
781da177e4SLinus Torvalds  */
eth_header(struct sk_buff * skb,struct net_device * dev,unsigned short type,const void * daddr,const void * saddr,unsigned int len)793b04dddeSStephen Hemminger int eth_header(struct sk_buff *skb, struct net_device *dev,
803b04dddeSStephen Hemminger 	       unsigned short type,
8195c96174SEric Dumazet 	       const void *daddr, const void *saddr, unsigned int len)
821da177e4SLinus Torvalds {
83d58ff351SJohannes Berg 	struct ethhdr *eth = skb_push(skb, ETH_HLEN);
841da177e4SLinus Torvalds 
85bf9ae538SOctavian Purdila 	if (type != ETH_P_802_3 && type != ETH_P_802_2)
861da177e4SLinus Torvalds 		eth->h_proto = htons(type);
871da177e4SLinus Torvalds 	else
881da177e4SLinus Torvalds 		eth->h_proto = htons(len);
891da177e4SLinus Torvalds 
901da177e4SLinus Torvalds 	/*
911da177e4SLinus Torvalds 	 *      Set the source hardware address.
921da177e4SLinus Torvalds 	 */
931da177e4SLinus Torvalds 
94ff593c59SDenis Vlasenko 	if (!saddr)
95ff593c59SDenis Vlasenko 		saddr = dev->dev_addr;
9623f1f4efSStephen Hemminger 	memcpy(eth->h_source, saddr, ETH_ALEN);
971da177e4SLinus Torvalds 
982e4ca75bSStephen Hemminger 	if (daddr) {
9923f1f4efSStephen Hemminger 		memcpy(eth->h_dest, daddr, ETH_ALEN);
100f8d0e3f1SJamal Hadi Salim 		return ETH_HLEN;
101f8d0e3f1SJamal Hadi Salim 	}
102f8d0e3f1SJamal Hadi Salim 
1031da177e4SLinus Torvalds 	/*
1041da177e4SLinus Torvalds 	 *      Anyway, the loopback-device should never use this function...
1051da177e4SLinus Torvalds 	 */
1061da177e4SLinus Torvalds 
1072e4ca75bSStephen Hemminger 	if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
108afc130ddSJoe Perches 		eth_zero_addr(eth->h_dest);
1091da177e4SLinus Torvalds 		return ETH_HLEN;
1101da177e4SLinus Torvalds 	}
1111da177e4SLinus Torvalds 
1121da177e4SLinus Torvalds 	return -ETH_HLEN;
1131da177e4SLinus Torvalds }
1143b04dddeSStephen Hemminger EXPORT_SYMBOL(eth_header);
1151da177e4SLinus Torvalds 
116d3e01f71SStephen Hemminger /**
117ecea4991SMasanari Iida  * eth_get_headlen - determine the length of header for an ethernet frame
118c43f1255SStanislav Fomichev  * @dev: pointer to network device
11956193d1bSAlexander Duyck  * @data: pointer to start of frame
12056193d1bSAlexander Duyck  * @len: total length of frame
12156193d1bSAlexander Duyck  *
12256193d1bSAlexander Duyck  * Make a best effort attempt to pull the length for all of the headers for
12356193d1bSAlexander Duyck  * a given frame in a linear buffer.
12456193d1bSAlexander Duyck  */
eth_get_headlen(const struct net_device * dev,const void * data,u32 len)12559753ce8SAlexander Lobakin u32 eth_get_headlen(const struct net_device *dev, const void *data, u32 len)
12656193d1bSAlexander Duyck {
127d975ddd6SAlexander Duyck 	const unsigned int flags = FLOW_DISSECTOR_F_PARSE_1ST_FRAG;
12856193d1bSAlexander Duyck 	const struct ethhdr *eth = (const struct ethhdr *)data;
12972a338bcSPaolo Abeni 	struct flow_keys_basic keys;
13056193d1bSAlexander Duyck 
13156193d1bSAlexander Duyck 	/* this should never happen, but better safe than sorry */
1328a4683a5SJesper Dangaard Brouer 	if (unlikely(len < sizeof(*eth)))
13356193d1bSAlexander Duyck 		return len;
13456193d1bSAlexander Duyck 
13556193d1bSAlexander Duyck 	/* parse any remaining L2/L3 headers, check for L4 */
136c43f1255SStanislav Fomichev 	if (!skb_flow_dissect_flow_keys_basic(dev_net(dev), NULL, &keys, data,
1373cbf4ffbSStanislav Fomichev 					      eth->h_proto, sizeof(*eth),
1383cbf4ffbSStanislav Fomichev 					      len, flags))
139c3f83241STom Herbert 		return max_t(u32, keys.control.thoff, sizeof(*eth));
14056193d1bSAlexander Duyck 
14156193d1bSAlexander Duyck 	/* parse for any L4 headers */
14256193d1bSAlexander Duyck 	return min_t(u32, __skb_get_poff(NULL, data, &keys, len), len);
14356193d1bSAlexander Duyck }
14456193d1bSAlexander Duyck EXPORT_SYMBOL(eth_get_headlen);
14556193d1bSAlexander Duyck 
14656193d1bSAlexander Duyck /**
147d3e01f71SStephen Hemminger  * eth_type_trans - determine the packet's protocol ID.
148d3e01f71SStephen Hemminger  * @skb: received socket data
149d3e01f71SStephen Hemminger  * @dev: receiving network device
150d3e01f71SStephen Hemminger  *
151d3e01f71SStephen Hemminger  * The rule here is that we
1521da177e4SLinus Torvalds  * assume 802.3 if the type field is short enough to be a length.
1531da177e4SLinus Torvalds  * This is normal practice and works for any 'now in use' protocol.
1541da177e4SLinus Torvalds  */
eth_type_trans(struct sk_buff * skb,struct net_device * dev)155ab611487SAlexey Dobriyan __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
1561da177e4SLinus Torvalds {
1570864c158SEric Dumazet 	unsigned short _service_access_point;
1580864c158SEric Dumazet 	const unsigned short *sap;
1590864c158SEric Dumazet 	const struct ethhdr *eth;
1601da177e4SLinus Torvalds 
1614c13eb66SArnaldo Carvalho de Melo 	skb->dev = dev;
162459a98edSArnaldo Carvalho de Melo 	skb_reset_mac_header(skb);
163610986e7SAlexander Duyck 
164610986e7SAlexander Duyck 	eth = (struct ethhdr *)skb->data;
16547d29646SDavid S. Miller 	skb_pull_inline(skb, ETH_HLEN);
1661da177e4SLinus Torvalds 
167ca958a1bSRahul Rameshbabu 	eth_skb_pkt_type(skb, dev);
1681da177e4SLinus Torvalds 
169cf85d08fSLennert Buytenhek 	/*
170cf85d08fSLennert Buytenhek 	 * Some variants of DSA tagging don't have an ethertype field
171cf85d08fSLennert Buytenhek 	 * at all, so we check here whether one of those tagging
172cf85d08fSLennert Buytenhek 	 * variants has been configured on the receiving interface,
173cf85d08fSLennert Buytenhek 	 * and if so, set skb->protocol without looking at the packet.
174cf85d08fSLennert Buytenhek 	 */
175edac6f63SVladimir Oltean 	if (unlikely(netdev_uses_dsa(dev)))
1763e8a72d1SFlorian Fainelli 		return htons(ETH_P_XDSA);
177cf85d08fSLennert Buytenhek 
1782c7a88c2SAlexander Duyck 	if (likely(eth_proto_is_802_3(eth->h_proto)))
1791da177e4SLinus Torvalds 		return eth->h_proto;
1801da177e4SLinus Torvalds 
1811da177e4SLinus Torvalds 	/*
1821da177e4SLinus Torvalds 	 *      This is a magic hack to spot IPX packets. Older Novell breaks
1831da177e4SLinus Torvalds 	 *      the protocol design and runs IPX over 802.3 without an 802.2 LLC
1841da177e4SLinus Torvalds 	 *      layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
1851da177e4SLinus Torvalds 	 *      won't work for fault tolerant netware but does for the rest.
1861da177e4SLinus Torvalds 	 */
1870864c158SEric Dumazet 	sap = skb_header_pointer(skb, 0, sizeof(*sap), &_service_access_point);
1880864c158SEric Dumazet 	if (sap && *sap == 0xFFFF)
1891da177e4SLinus Torvalds 		return htons(ETH_P_802_3);
1901da177e4SLinus Torvalds 
1911da177e4SLinus Torvalds 	/*
1921da177e4SLinus Torvalds 	 *      Real 802.2 LLC
1931da177e4SLinus Torvalds 	 */
1941da177e4SLinus Torvalds 	return htons(ETH_P_802_2);
1951da177e4SLinus Torvalds }
1962e4ca75bSStephen Hemminger EXPORT_SYMBOL(eth_type_trans);
1971da177e4SLinus Torvalds 
198d3e01f71SStephen Hemminger /**
199d3e01f71SStephen Hemminger  * eth_header_parse - extract hardware address from packet
200d3e01f71SStephen Hemminger  * @skb: packet to extract header from
201d3e01f71SStephen Hemminger  * @haddr: destination buffer
202d3e01f71SStephen Hemminger  */
eth_header_parse(const struct sk_buff * skb,unsigned char * haddr)2033b04dddeSStephen Hemminger int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr)
2041da177e4SLinus Torvalds {
205b95cce35SStephen Hemminger 	const struct ethhdr *eth = eth_hdr(skb);
2061da177e4SLinus Torvalds 	memcpy(haddr, eth->h_source, ETH_ALEN);
2071da177e4SLinus Torvalds 	return ETH_ALEN;
2081da177e4SLinus Torvalds }
2093b04dddeSStephen Hemminger EXPORT_SYMBOL(eth_header_parse);
2101da177e4SLinus Torvalds 
211d3e01f71SStephen Hemminger /**
212d3e01f71SStephen Hemminger  * eth_header_cache - fill cache entry from neighbour
213d3e01f71SStephen Hemminger  * @neigh: source neighbour
214d3e01f71SStephen Hemminger  * @hh: destination cache entry
21548daec03SRandy Dunlap  * @type: Ethernet type field
2162c53040fSBen Hutchings  *
217d3e01f71SStephen Hemminger  * Create an Ethernet header template from the neighbour.
218d3e01f71SStephen Hemminger  */
eth_header_cache(const struct neighbour * neigh,struct hh_cache * hh,__be16 type)219e69dd336SDavid S. Miller int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh, __be16 type)
2201da177e4SLinus Torvalds {
2211da177e4SLinus Torvalds 	struct ethhdr *eth;
2223b04dddeSStephen Hemminger 	const struct net_device *dev = neigh->dev;
2231da177e4SLinus Torvalds 
2241da177e4SLinus Torvalds 	eth = (struct ethhdr *)
2251da177e4SLinus Torvalds 	    (((u8 *) hh->hh_data) + (HH_DATA_OFF(sizeof(*eth))));
2261da177e4SLinus Torvalds 
227f576e24fSYOSHIFUJI Hideaki 	if (type == htons(ETH_P_802_3))
2281da177e4SLinus Torvalds 		return -1;
2291da177e4SLinus Torvalds 
2301da177e4SLinus Torvalds 	eth->h_proto = type;
23123f1f4efSStephen Hemminger 	memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
23223f1f4efSStephen Hemminger 	memcpy(eth->h_dest, neigh->ha, ETH_ALEN);
233c305c6aeSEric Dumazet 
234c305c6aeSEric Dumazet 	/* Pairs with READ_ONCE() in neigh_resolve_output(),
235c305c6aeSEric Dumazet 	 * neigh_hh_output() and neigh_update_hhs().
236c305c6aeSEric Dumazet 	 */
237c305c6aeSEric Dumazet 	smp_store_release(&hh->hh_len, ETH_HLEN);
238c305c6aeSEric Dumazet 
2391da177e4SLinus Torvalds 	return 0;
2401da177e4SLinus Torvalds }
2413b04dddeSStephen Hemminger EXPORT_SYMBOL(eth_header_cache);
2421da177e4SLinus Torvalds 
243d3e01f71SStephen Hemminger /**
244d3e01f71SStephen Hemminger  * eth_header_cache_update - update cache entry
245d3e01f71SStephen Hemminger  * @hh: destination cache entry
246d3e01f71SStephen Hemminger  * @dev: network device
247d3e01f71SStephen Hemminger  * @haddr: new hardware address
248d3e01f71SStephen Hemminger  *
2491da177e4SLinus Torvalds  * Called by Address Resolution module to notify changes in address.
2501da177e4SLinus Torvalds  */
eth_header_cache_update(struct hh_cache * hh,const struct net_device * dev,const unsigned char * haddr)2513b04dddeSStephen Hemminger void eth_header_cache_update(struct hh_cache *hh,
2523b04dddeSStephen Hemminger 			     const struct net_device *dev,
2533b04dddeSStephen Hemminger 			     const unsigned char *haddr)
2541da177e4SLinus Torvalds {
2551da177e4SLinus Torvalds 	memcpy(((u8 *) hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
25623f1f4efSStephen Hemminger 	       haddr, ETH_ALEN);
2571da177e4SLinus Torvalds }
2583b04dddeSStephen Hemminger EXPORT_SYMBOL(eth_header_cache_update);
2591da177e4SLinus Torvalds 
260d3e01f71SStephen Hemminger /**
261c1639be9SMauro Carvalho Chehab  * eth_header_parse_protocol - extract protocol from L2 header
262ace53b2eSMaxim Mikityanskiy  * @skb: packet to extract protocol from
263ace53b2eSMaxim Mikityanskiy  */
eth_header_parse_protocol(const struct sk_buff * skb)264ace53b2eSMaxim Mikityanskiy __be16 eth_header_parse_protocol(const struct sk_buff *skb)
265ace53b2eSMaxim Mikityanskiy {
266ace53b2eSMaxim Mikityanskiy 	const struct ethhdr *eth = eth_hdr(skb);
267ace53b2eSMaxim Mikityanskiy 
268ace53b2eSMaxim Mikityanskiy 	return eth->h_proto;
269ace53b2eSMaxim Mikityanskiy }
270ace53b2eSMaxim Mikityanskiy EXPORT_SYMBOL(eth_header_parse_protocol);
271ace53b2eSMaxim Mikityanskiy 
272ace53b2eSMaxim Mikityanskiy /**
273fa0879e3SStefan Hajnoczi  * eth_prepare_mac_addr_change - prepare for mac change
274fa0879e3SStefan Hajnoczi  * @dev: network device
275fa0879e3SStefan Hajnoczi  * @p: socket address
276fa0879e3SStefan Hajnoczi  */
eth_prepare_mac_addr_change(struct net_device * dev,void * p)277fa0879e3SStefan Hajnoczi int eth_prepare_mac_addr_change(struct net_device *dev, void *p)
278fa0879e3SStefan Hajnoczi {
279fa0879e3SStefan Hajnoczi 	struct sockaddr *addr = p;
280fa0879e3SStefan Hajnoczi 
281fa0879e3SStefan Hajnoczi 	if (!(dev->priv_flags & IFF_LIVE_ADDR_CHANGE) && netif_running(dev))
282fa0879e3SStefan Hajnoczi 		return -EBUSY;
283fa0879e3SStefan Hajnoczi 	if (!is_valid_ether_addr(addr->sa_data))
284fa0879e3SStefan Hajnoczi 		return -EADDRNOTAVAIL;
285fa0879e3SStefan Hajnoczi 	return 0;
286fa0879e3SStefan Hajnoczi }
287fa0879e3SStefan Hajnoczi EXPORT_SYMBOL(eth_prepare_mac_addr_change);
288fa0879e3SStefan Hajnoczi 
289fa0879e3SStefan Hajnoczi /**
290fa0879e3SStefan Hajnoczi  * eth_commit_mac_addr_change - commit mac change
291fa0879e3SStefan Hajnoczi  * @dev: network device
292fa0879e3SStefan Hajnoczi  * @p: socket address
293fa0879e3SStefan Hajnoczi  */
eth_commit_mac_addr_change(struct net_device * dev,void * p)294fa0879e3SStefan Hajnoczi void eth_commit_mac_addr_change(struct net_device *dev, void *p)
295fa0879e3SStefan Hajnoczi {
296fa0879e3SStefan Hajnoczi 	struct sockaddr *addr = p;
297fa0879e3SStefan Hajnoczi 
298a96d317fSJakub Kicinski 	eth_hw_addr_set(dev, addr->sa_data);
299fa0879e3SStefan Hajnoczi }
300fa0879e3SStefan Hajnoczi EXPORT_SYMBOL(eth_commit_mac_addr_change);
301fa0879e3SStefan Hajnoczi 
302fa0879e3SStefan Hajnoczi /**
303d3e01f71SStephen Hemminger  * eth_mac_addr - set new Ethernet hardware address
304d3e01f71SStephen Hemminger  * @dev: network device
305d3e01f71SStephen Hemminger  * @p: socket address
3062c53040fSBen Hutchings  *
307d3e01f71SStephen Hemminger  * Change hardware address of device.
308d3e01f71SStephen Hemminger  *
309d3e01f71SStephen Hemminger  * This doesn't change hardware matching, so needs to be overridden
310d3e01f71SStephen Hemminger  * for most real devices.
311d3e01f71SStephen Hemminger  */
eth_mac_addr(struct net_device * dev,void * p)312ccad637bSStephen Hemminger int eth_mac_addr(struct net_device *dev, void *p)
3131da177e4SLinus Torvalds {
314fa0879e3SStefan Hajnoczi 	int ret;
31571bffe55SPatrick McHardy 
316fa0879e3SStefan Hajnoczi 	ret = eth_prepare_mac_addr_change(dev, p);
317fa0879e3SStefan Hajnoczi 	if (ret < 0)
318fa0879e3SStefan Hajnoczi 		return ret;
319fa0879e3SStefan Hajnoczi 	eth_commit_mac_addr_change(dev, p);
3201da177e4SLinus Torvalds 	return 0;
3211da177e4SLinus Torvalds }
322ccad637bSStephen Hemminger EXPORT_SYMBOL(eth_mac_addr);
3231da177e4SLinus Torvalds 
eth_validate_addr(struct net_device * dev)324ccad637bSStephen Hemminger int eth_validate_addr(struct net_device *dev)
325bada339bSJeff Garzik {
326bada339bSJeff Garzik 	if (!is_valid_ether_addr(dev->dev_addr))
3272ed9926eSPatrick McHardy 		return -EADDRNOTAVAIL;
328bada339bSJeff Garzik 
329bada339bSJeff Garzik 	return 0;
330bada339bSJeff Garzik }
331ccad637bSStephen Hemminger EXPORT_SYMBOL(eth_validate_addr);
332bada339bSJeff Garzik 
3333b04dddeSStephen Hemminger const struct header_ops eth_header_ops ____cacheline_aligned = {
3343b04dddeSStephen Hemminger 	.create		= eth_header,
3353b04dddeSStephen Hemminger 	.parse		= eth_header_parse,
3363b04dddeSStephen Hemminger 	.cache		= eth_header_cache,
3373b04dddeSStephen Hemminger 	.cache_update	= eth_header_cache_update,
338ace53b2eSMaxim Mikityanskiy 	.parse_protocol	= eth_header_parse_protocol,
3393b04dddeSStephen Hemminger };
3403b04dddeSStephen Hemminger 
341d3e01f71SStephen Hemminger /**
342d3e01f71SStephen Hemminger  * ether_setup - setup Ethernet network device
343d3e01f71SStephen Hemminger  * @dev: network device
3442c53040fSBen Hutchings  *
345d3e01f71SStephen Hemminger  * Fill in the fields of the device structure with Ethernet-generic values.
3461da177e4SLinus Torvalds  */
ether_setup(struct net_device * dev)3471da177e4SLinus Torvalds void ether_setup(struct net_device *dev)
3481da177e4SLinus Torvalds {
3493b04dddeSStephen Hemminger 	dev->header_ops		= &eth_header_ops;
3501da177e4SLinus Torvalds 	dev->type		= ARPHRD_ETHER;
3511da177e4SLinus Torvalds 	dev->hard_header_len 	= ETH_HLEN;
352217e6fa2SWillem de Bruijn 	dev->min_header_len	= ETH_HLEN;
35346f25dffSKris Katterjohn 	dev->mtu		= ETH_DATA_LEN;
354a52ad514SJarod Wilson 	dev->min_mtu		= ETH_MIN_MTU;
355a52ad514SJarod Wilson 	dev->max_mtu		= ETH_DATA_LEN;
3561da177e4SLinus Torvalds 	dev->addr_len		= ETH_ALEN;
357d0a81f67SJesper Dangaard Brouer 	dev->tx_queue_len	= DEFAULT_TX_QUEUE_LEN;
3581da177e4SLinus Torvalds 	dev->flags		= IFF_BROADCAST|IFF_MULTICAST;
35931dda0aeSnhorman 	dev->priv_flags		|= IFF_TX_SKB_SHARING;
3601da177e4SLinus Torvalds 
361afc130ddSJoe Perches 	eth_broadcast_addr(dev->broadcast);
3621da177e4SLinus Torvalds 
3631da177e4SLinus Torvalds }
3641da177e4SLinus Torvalds EXPORT_SYMBOL(ether_setup);
3651da177e4SLinus Torvalds 
3661da177e4SLinus Torvalds /**
36736909ea4STom Herbert  * alloc_etherdev_mqs - Allocates and sets up an Ethernet device
3681da177e4SLinus Torvalds  * @sizeof_priv: Size of additional driver-private structure to be allocated
369d3e01f71SStephen Hemminger  *	for this Ethernet device
37036909ea4STom Herbert  * @txqs: The number of TX queues this device has.
3713806b4f3SRandy Dunlap  * @rxqs: The number of RX queues this device has.
3721da177e4SLinus Torvalds  *
373d3e01f71SStephen Hemminger  * Fill in the fields of the device structure with Ethernet-generic
3741da177e4SLinus Torvalds  * values. Basically does everything except registering the device.
3751da177e4SLinus Torvalds  *
3761da177e4SLinus Torvalds  * Constructs a new net device, complete with a private data area of
377d3e01f71SStephen Hemminger  * size (sizeof_priv).  A 32-byte (not bit) alignment is enforced for
3781da177e4SLinus Torvalds  * this private data area.
3791da177e4SLinus Torvalds  */
3801da177e4SLinus Torvalds 
alloc_etherdev_mqs(int sizeof_priv,unsigned int txqs,unsigned int rxqs)38136909ea4STom Herbert struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs,
38236909ea4STom Herbert 				      unsigned int rxqs)
3831da177e4SLinus Torvalds {
384e9f656b7SIan Wienand 	return alloc_netdev_mqs(sizeof_priv, "eth%d", NET_NAME_ENUM,
385c835a677STom Gundersen 				ether_setup, txqs, rxqs);
3861da177e4SLinus Torvalds }
38736909ea4STom Herbert EXPORT_SYMBOL(alloc_etherdev_mqs);
3880795af57SJoe Perches 
sysfs_format_mac(char * buf,const unsigned char * addr,int len)3897ffc49a6SMichael Chan ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len)
3907ffc49a6SMichael Chan {
39116dc16d9Sye xingchen 	return sysfs_emit(buf, "%*phC\n", len, addr);
3927ffc49a6SMichael Chan }
3937ffc49a6SMichael Chan EXPORT_SYMBOL(sysfs_format_mac);
3949b174d88SJesse Gross 
eth_gro_receive(struct list_head * head,struct sk_buff * skb)395d4546c25SDavid Miller struct sk_buff *eth_gro_receive(struct list_head *head, struct sk_buff *skb)
3969b174d88SJesse Gross {
3979b174d88SJesse Gross 	const struct packet_offload *ptype;
398d4546c25SDavid Miller 	unsigned int hlen, off_eth;
399d4546c25SDavid Miller 	struct sk_buff *pp = NULL;
400d4546c25SDavid Miller 	struct ethhdr *eh, *eh2;
401d4546c25SDavid Miller 	struct sk_buff *p;
4029b174d88SJesse Gross 	__be16 type;
4039b174d88SJesse Gross 	int flush = 1;
4049b174d88SJesse Gross 
4059b174d88SJesse Gross 	off_eth = skb_gro_offset(skb);
4069b174d88SJesse Gross 	hlen = off_eth + sizeof(*eh);
40735ffb665SRichard Gobert 	eh = skb_gro_header(skb, hlen, off_eth);
4089b174d88SJesse Gross 	if (unlikely(!eh))
4099b174d88SJesse Gross 		goto out;
4109b174d88SJesse Gross 
4119b174d88SJesse Gross 	flush = 0;
4129b174d88SJesse Gross 
413d4546c25SDavid Miller 	list_for_each_entry(p, head, list) {
4149b174d88SJesse Gross 		if (!NAPI_GRO_CB(p)->same_flow)
4159b174d88SJesse Gross 			continue;
4169b174d88SJesse Gross 
4179b174d88SJesse Gross 		eh2 = (struct ethhdr *)(p->data + off_eth);
4189b174d88SJesse Gross 		if (compare_ether_header(eh, eh2)) {
4199b174d88SJesse Gross 			NAPI_GRO_CB(p)->same_flow = 0;
4209b174d88SJesse Gross 			continue;
4219b174d88SJesse Gross 		}
4229b174d88SJesse Gross 	}
4239b174d88SJesse Gross 
4249b174d88SJesse Gross 	type = eh->h_proto;
4259b174d88SJesse Gross 
4269b174d88SJesse Gross 	ptype = gro_find_receive_by_type(type);
4279b174d88SJesse Gross 	if (ptype == NULL) {
4289b174d88SJesse Gross 		flush = 1;
429fc1ca334SEric Dumazet 		goto out;
4309b174d88SJesse Gross 	}
4319b174d88SJesse Gross 
4329b174d88SJesse Gross 	skb_gro_pull(skb, sizeof(*eh));
4339b174d88SJesse Gross 	skb_gro_postpull_rcsum(skb, eh, sizeof(*eh));
4345588796eSAlexander Lobakin 
4355588796eSAlexander Lobakin 	pp = indirect_call_gro_receive_inet(ptype->callbacks.gro_receive,
4365588796eSAlexander Lobakin 					    ipv6_gro_receive, inet_gro_receive,
4375588796eSAlexander Lobakin 					    head, skb);
4389b174d88SJesse Gross 
4399b174d88SJesse Gross out:
4405f114163SSteffen Klassert 	skb_gro_flush_final(skb, pp, flush);
4419b174d88SJesse Gross 
4429b174d88SJesse Gross 	return pp;
4439b174d88SJesse Gross }
4449b174d88SJesse Gross EXPORT_SYMBOL(eth_gro_receive);
4459b174d88SJesse Gross 
eth_gro_complete(struct sk_buff * skb,int nhoff)4469b174d88SJesse Gross int eth_gro_complete(struct sk_buff *skb, int nhoff)
4479b174d88SJesse Gross {
4489b174d88SJesse Gross 	struct ethhdr *eh = (struct ethhdr *)(skb->data + nhoff);
4499b174d88SJesse Gross 	__be16 type = eh->h_proto;
4509b174d88SJesse Gross 	struct packet_offload *ptype;
4519b174d88SJesse Gross 	int err = -ENOSYS;
4529b174d88SJesse Gross 
4539b174d88SJesse Gross 	if (skb->encapsulation)
4549b174d88SJesse Gross 		skb_set_inner_mac_header(skb, nhoff);
4559b174d88SJesse Gross 
4569b174d88SJesse Gross 	ptype = gro_find_complete_by_type(type);
4579b174d88SJesse Gross 	if (ptype != NULL)
4585588796eSAlexander Lobakin 		err = INDIRECT_CALL_INET(ptype->callbacks.gro_complete,
4595588796eSAlexander Lobakin 					 ipv6_gro_complete, inet_gro_complete,
4605588796eSAlexander Lobakin 					 skb, nhoff + sizeof(*eh));
4619b174d88SJesse Gross 
4629b174d88SJesse Gross 	return err;
4639b174d88SJesse Gross }
4649b174d88SJesse Gross EXPORT_SYMBOL(eth_gro_complete);
4659b174d88SJesse Gross 
4669b174d88SJesse Gross static struct packet_offload eth_packet_offload __read_mostly = {
4679b174d88SJesse Gross 	.type = cpu_to_be16(ETH_P_TEB),
468bdef7de4SDavid S. Miller 	.priority = 10,
4699b174d88SJesse Gross 	.callbacks = {
4709b174d88SJesse Gross 		.gro_receive = eth_gro_receive,
4719b174d88SJesse Gross 		.gro_complete = eth_gro_complete,
4729b174d88SJesse Gross 	},
4739b174d88SJesse Gross };
4749b174d88SJesse Gross 
eth_offload_init(void)4759b174d88SJesse Gross static int __init eth_offload_init(void)
4769b174d88SJesse Gross {
4779b174d88SJesse Gross 	dev_add_offload(&eth_packet_offload);
4789b174d88SJesse Gross 
4799b174d88SJesse Gross 	return 0;
4809b174d88SJesse Gross }
4819b174d88SJesse Gross 
4829b174d88SJesse Gross fs_initcall(eth_offload_init);
483c7f5d105SDavid S. Miller 
arch_get_platform_mac_address(void)484c7f5d105SDavid S. Miller unsigned char * __weak arch_get_platform_mac_address(void)
485c7f5d105SDavid S. Miller {
486c7f5d105SDavid S. Miller 	return NULL;
487c7f5d105SDavid S. Miller }
488c7f5d105SDavid S. Miller 
eth_platform_get_mac_address(struct device * dev,u8 * mac_addr)489c7f5d105SDavid S. Miller int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
490c7f5d105SDavid S. Miller {
49183216e39SMichael Walle 	unsigned char *addr;
49283216e39SMichael Walle 	int ret;
493c7f5d105SDavid S. Miller 
49483216e39SMichael Walle 	ret = of_get_mac_address(dev->of_node, mac_addr);
49583216e39SMichael Walle 	if (!ret)
49683216e39SMichael Walle 		return 0;
49783216e39SMichael Walle 
498c7f5d105SDavid S. Miller 	addr = arch_get_platform_mac_address();
499c7f5d105SDavid S. Miller 	if (!addr)
500c7f5d105SDavid S. Miller 		return -ENODEV;
501c7f5d105SDavid S. Miller 
502c7f5d105SDavid S. Miller 	ether_addr_copy(mac_addr, addr);
503db4bad07SHeiner Kallweit 
504c7f5d105SDavid S. Miller 	return 0;
505c7f5d105SDavid S. Miller }
506c7f5d105SDavid S. Miller EXPORT_SYMBOL(eth_platform_get_mac_address);
5070e839df9SBartosz Golaszewski 
5080e839df9SBartosz Golaszewski /**
509ba882580SJakub Kicinski  * platform_get_ethdev_address - Set netdev's MAC address from a given device
510ba882580SJakub Kicinski  * @dev:	Pointer to the device
511ba882580SJakub Kicinski  * @netdev:	Pointer to netdev to write the address to
512ba882580SJakub Kicinski  *
513ba882580SJakub Kicinski  * Wrapper around eth_platform_get_mac_address() which writes the address
514ba882580SJakub Kicinski  * directly to netdev->dev_addr.
515ba882580SJakub Kicinski  */
platform_get_ethdev_address(struct device * dev,struct net_device * netdev)516ba882580SJakub Kicinski int platform_get_ethdev_address(struct device *dev, struct net_device *netdev)
517ba882580SJakub Kicinski {
518ba882580SJakub Kicinski 	u8 addr[ETH_ALEN] __aligned(2);
519ba882580SJakub Kicinski 	int ret;
520ba882580SJakub Kicinski 
521ba882580SJakub Kicinski 	ret = eth_platform_get_mac_address(dev, addr);
522ba882580SJakub Kicinski 	if (!ret)
523ba882580SJakub Kicinski 		eth_hw_addr_set(netdev, addr);
524ba882580SJakub Kicinski 	return ret;
525ba882580SJakub Kicinski }
526ba882580SJakub Kicinski EXPORT_SYMBOL(platform_get_ethdev_address);
527ba882580SJakub Kicinski 
528ba882580SJakub Kicinski /**
529c1639be9SMauro Carvalho Chehab  * nvmem_get_mac_address - Obtain the MAC address from an nvmem cell named
530c1639be9SMauro Carvalho Chehab  * 'mac-address' associated with given device.
5310e839df9SBartosz Golaszewski  *
5320e839df9SBartosz Golaszewski  * @dev:	Device with which the mac-address cell is associated.
5330e839df9SBartosz Golaszewski  * @addrbuf:	Buffer to which the MAC address will be copied on success.
5340e839df9SBartosz Golaszewski  *
5350e839df9SBartosz Golaszewski  * Returns 0 on success or a negative error number on failure.
5360e839df9SBartosz Golaszewski  */
nvmem_get_mac_address(struct device * dev,void * addrbuf)5370e839df9SBartosz Golaszewski int nvmem_get_mac_address(struct device *dev, void *addrbuf)
5380e839df9SBartosz Golaszewski {
5390e839df9SBartosz Golaszewski 	struct nvmem_cell *cell;
5400e839df9SBartosz Golaszewski 	const void *mac;
5410e839df9SBartosz Golaszewski 	size_t len;
5420e839df9SBartosz Golaszewski 
5430e839df9SBartosz Golaszewski 	cell = nvmem_cell_get(dev, "mac-address");
5440e839df9SBartosz Golaszewski 	if (IS_ERR(cell))
5450e839df9SBartosz Golaszewski 		return PTR_ERR(cell);
5460e839df9SBartosz Golaszewski 
5470e839df9SBartosz Golaszewski 	mac = nvmem_cell_read(cell, &len);
5480e839df9SBartosz Golaszewski 	nvmem_cell_put(cell);
5490e839df9SBartosz Golaszewski 
5500e839df9SBartosz Golaszewski 	if (IS_ERR(mac))
5510e839df9SBartosz Golaszewski 		return PTR_ERR(mac);
5520e839df9SBartosz Golaszewski 
5530e839df9SBartosz Golaszewski 	if (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
5540e839df9SBartosz Golaszewski 		kfree(mac);
5550e839df9SBartosz Golaszewski 		return -EINVAL;
5560e839df9SBartosz Golaszewski 	}
5570e839df9SBartosz Golaszewski 
5580e839df9SBartosz Golaszewski 	ether_addr_copy(addrbuf, mac);
5590e839df9SBartosz Golaszewski 	kfree(mac);
5600e839df9SBartosz Golaszewski 
5610e839df9SBartosz Golaszewski 	return 0;
5620e839df9SBartosz Golaszewski }
563433baf07SJakub Kicinski 
fwnode_get_mac_addr(struct fwnode_handle * fwnode,const char * name,char * addr)5648017c4d8SJakub Kicinski static int fwnode_get_mac_addr(struct fwnode_handle *fwnode,
5650a14501eSJakub Kicinski 			       const char *name, char *addr)
566433baf07SJakub Kicinski {
5678017c4d8SJakub Kicinski 	int ret;
568433baf07SJakub Kicinski 
5690a14501eSJakub Kicinski 	ret = fwnode_property_read_u8_array(fwnode, name, addr, ETH_ALEN);
5708017c4d8SJakub Kicinski 	if (ret)
5718017c4d8SJakub Kicinski 		return ret;
5728017c4d8SJakub Kicinski 
5738017c4d8SJakub Kicinski 	if (!is_valid_ether_addr(addr))
5748017c4d8SJakub Kicinski 		return -EINVAL;
5758017c4d8SJakub Kicinski 	return 0;
576433baf07SJakub Kicinski }
577433baf07SJakub Kicinski 
578433baf07SJakub Kicinski /**
579433baf07SJakub Kicinski  * fwnode_get_mac_address - Get the MAC from the firmware node
580433baf07SJakub Kicinski  * @fwnode:	Pointer to the firmware node
581433baf07SJakub Kicinski  * @addr:	Address of buffer to store the MAC in
582433baf07SJakub Kicinski  *
583433baf07SJakub Kicinski  * Search the firmware node for the best MAC address to use.  'mac-address' is
584433baf07SJakub Kicinski  * checked first, because that is supposed to contain to "most recent" MAC
585433baf07SJakub Kicinski  * address. If that isn't set, then 'local-mac-address' is checked next,
586433baf07SJakub Kicinski  * because that is the default address.  If that isn't set, then the obsolete
587433baf07SJakub Kicinski  * 'address' is checked, just in case we're using an old device tree.
588433baf07SJakub Kicinski  *
589433baf07SJakub Kicinski  * Note that the 'address' property is supposed to contain a virtual address of
590433baf07SJakub Kicinski  * the register set, but some DTS files have redefined that property to be the
591433baf07SJakub Kicinski  * MAC address.
592433baf07SJakub Kicinski  *
593433baf07SJakub Kicinski  * All-zero MAC addresses are rejected, because those could be properties that
594433baf07SJakub Kicinski  * exist in the firmware tables, but were not updated by the firmware.  For
595433baf07SJakub Kicinski  * example, the DTS could define 'mac-address' and 'local-mac-address', with
596433baf07SJakub Kicinski  * zero MAC addresses.  Some older U-Boots only initialized 'local-mac-address'.
597433baf07SJakub Kicinski  * In this case, the real MAC is in 'local-mac-address', and 'mac-address'
598433baf07SJakub Kicinski  * exists but is all zeros.
599433baf07SJakub Kicinski  */
fwnode_get_mac_address(struct fwnode_handle * fwnode,char * addr)6000a14501eSJakub Kicinski int fwnode_get_mac_address(struct fwnode_handle *fwnode, char *addr)
601433baf07SJakub Kicinski {
6020a14501eSJakub Kicinski 	if (!fwnode_get_mac_addr(fwnode, "mac-address", addr) ||
6030a14501eSJakub Kicinski 	    !fwnode_get_mac_addr(fwnode, "local-mac-address", addr) ||
6040a14501eSJakub Kicinski 	    !fwnode_get_mac_addr(fwnode, "address", addr))
6058017c4d8SJakub Kicinski 		return 0;
606433baf07SJakub Kicinski 
6078017c4d8SJakub Kicinski 	return -ENOENT;
608433baf07SJakub Kicinski }
609433baf07SJakub Kicinski EXPORT_SYMBOL(fwnode_get_mac_address);
610433baf07SJakub Kicinski 
611433baf07SJakub Kicinski /**
612433baf07SJakub Kicinski  * device_get_mac_address - Get the MAC for a given device
613433baf07SJakub Kicinski  * @dev:	Pointer to the device
614433baf07SJakub Kicinski  * @addr:	Address of buffer to store the MAC in
615433baf07SJakub Kicinski  */
device_get_mac_address(struct device * dev,char * addr)6160a14501eSJakub Kicinski int device_get_mac_address(struct device *dev, char *addr)
617433baf07SJakub Kicinski {
6180a14501eSJakub Kicinski 	return fwnode_get_mac_address(dev_fwnode(dev), addr);
619433baf07SJakub Kicinski }
620433baf07SJakub Kicinski EXPORT_SYMBOL(device_get_mac_address);
621d9eb4490SJakub Kicinski 
622d9eb4490SJakub Kicinski /**
623d9eb4490SJakub Kicinski  * device_get_ethdev_address - Set netdev's MAC address from a given device
624d9eb4490SJakub Kicinski  * @dev:	Pointer to the device
625d9eb4490SJakub Kicinski  * @netdev:	Pointer to netdev to write the address to
626d9eb4490SJakub Kicinski  *
627d9eb4490SJakub Kicinski  * Wrapper around device_get_mac_address() which writes the address
628d9eb4490SJakub Kicinski  * directly to netdev->dev_addr.
629d9eb4490SJakub Kicinski  */
device_get_ethdev_address(struct device * dev,struct net_device * netdev)630d9eb4490SJakub Kicinski int device_get_ethdev_address(struct device *dev, struct net_device *netdev)
631d9eb4490SJakub Kicinski {
632d9eb4490SJakub Kicinski 	u8 addr[ETH_ALEN];
633d9eb4490SJakub Kicinski 	int ret;
634d9eb4490SJakub Kicinski 
635d9eb4490SJakub Kicinski 	ret = device_get_mac_address(dev, addr);
636d9eb4490SJakub Kicinski 	if (!ret)
637d9eb4490SJakub Kicinski 		eth_hw_addr_set(netdev, addr);
638d9eb4490SJakub Kicinski 	return ret;
639d9eb4490SJakub Kicinski }
640d9eb4490SJakub Kicinski EXPORT_SYMBOL(device_get_ethdev_address);
641