From 0e839df92cf37be4adef7e661813206cd2b32d66 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Fri, 30 Nov 2018 09:20:57 +0100 Subject: net: ethernet: provide nvmem_get_mac_address() We already have of_get_nvmem_mac_address() but some non-DT systems want to read the MAC address from NVMEM too. Implement a generalized routine that takes struct device as argument. Signed-off-by: Bartosz Golaszewski Signed-off-by: David S. Miller --- include/linux/etherdevice.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/etherdevice.h') diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 572e11bb8696..2c0af7b00715 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -32,6 +32,7 @@ struct device; int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr); unsigned char *arch_get_platform_mac_address(void); +int nvmem_get_mac_address(struct device *dev, void *addrbuf); u32 eth_get_headlen(void *data, unsigned int max_len); __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev); extern const struct header_ops eth_header_ops; -- cgit v1.2.3-71-gd317 From ace53b2e2945c83850964070af158be01d564e67 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Thu, 21 Feb 2019 12:39:59 +0000 Subject: net/ethernet: Add parse_protocol header_ops support The previous commit introduced parse_protocol callback which should extract the protocol number from the L2 header. Make all Ethernet devices support it. Signed-off-by: Maxim Mikityanskiy Signed-off-by: David S. Miller --- include/linux/etherdevice.h | 1 + net/ethernet/eth.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) (limited to 'include/linux/etherdevice.h') diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 2c0af7b00715..e2f3b21cd72a 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -44,6 +44,7 @@ int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh, __be16 type); void eth_header_cache_update(struct hh_cache *hh, const struct net_device *dev, const unsigned char *haddr); +__be16 eth_header_parse_protocol(const struct sk_buff *skb); int eth_prepare_mac_addr_change(struct net_device *dev, void *p); void eth_commit_mac_addr_change(struct net_device *dev, void *p); int eth_mac_addr(struct net_device *dev, void *p); diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 4c520110b04f..f7a3d7a171c7 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -264,6 +264,18 @@ void eth_header_cache_update(struct hh_cache *hh, } EXPORT_SYMBOL(eth_header_cache_update); +/** + * eth_header_parser_protocol - extract protocol from L2 header + * @skb: packet to extract protocol from + */ +__be16 eth_header_parse_protocol(const struct sk_buff *skb) +{ + const struct ethhdr *eth = eth_hdr(skb); + + return eth->h_proto; +} +EXPORT_SYMBOL(eth_header_parse_protocol); + /** * eth_prepare_mac_addr_change - prepare for mac change * @dev: network device @@ -346,6 +358,7 @@ const struct header_ops eth_header_ops ____cacheline_aligned = { .parse = eth_header_parse, .cache = eth_header_cache, .cache_update = eth_header_cache_update, + .parse_protocol = eth_header_parse_protocol, }; /** -- cgit v1.2.3-71-gd317 From 1c5c12ee308aacf635c8819cd4baa3bd58f8a8b7 Mon Sep 17 00:00:00 2001 From: Tao Ren Date: Wed, 24 Apr 2019 01:43:32 +0000 Subject: net/ncsi: handle overflow when incrementing mac address Previously BMC's MAC address is calculated by simply adding 1 to the last byte of network controller's MAC address, and it produces incorrect result when network controller's MAC address ends with 0xFF. The problem can be fixed by calling eth_addr_inc() function to increment MAC address; besides, the MAC address is also validated before assigning to BMC. Fixes: cb10c7c0dfd9 ("net/ncsi: Add NCSI Broadcom OEM command") Signed-off-by: Tao Ren Acked-by: Jakub Kicinski Acked-by: Samuel Mendoza-Jonas Signed-off-by: David S. Miller --- include/linux/etherdevice.h | 12 ++++++++++++ net/ncsi/ncsi-rsp.c | 6 +++++- 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'include/linux/etherdevice.h') diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index e2f3b21cd72a..aa8bfd6f738c 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -448,6 +448,18 @@ static inline void eth_addr_dec(u8 *addr) u64_to_ether_addr(u, addr); } +/** + * eth_addr_inc() - Increment the given MAC address. + * @addr: Pointer to a six-byte array containing Ethernet address to increment. + */ +static inline void eth_addr_inc(u8 *addr) +{ + u64 u = ether_addr_to_u64(addr); + + u++; + u64_to_ether_addr(u, addr); +} + /** * is_etherdev_addr - Tell if given Ethernet address belongs to the device. * @dev: Pointer to a device structure diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c index dc07fcc7938e..802db01e3075 100644 --- a/net/ncsi/ncsi-rsp.c +++ b/net/ncsi/ncsi-rsp.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -667,7 +668,10 @@ static int ncsi_rsp_handler_oem_bcm_gma(struct ncsi_request *nr) ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; memcpy(saddr.sa_data, &rsp->data[BCM_MAC_ADDR_OFFSET], ETH_ALEN); /* Increase mac address by 1 for BMC's address */ - saddr.sa_data[ETH_ALEN - 1]++; + eth_addr_inc((u8 *)saddr.sa_data); + if (!is_valid_ether_addr((const u8 *)saddr.sa_data)) + return -ENXIO; + ret = ops->ndo_set_mac_address(ndev, &saddr); if (ret < 0) netdev_warn(ndev, "NCSI: 'Writing mac address to device failed\n"); -- cgit v1.2.3-71-gd317