Commit f4e728ff authored by David S. Miller's avatar David S. Miller

Merge branch 'eth_hw_addr_gen-for-switches'

Jakub Kicinski says:

====================
ethernet: add eth_hw_addr_gen() for switches

While doing the last polishing of the drivers/ethernet
changes I realized we have a handful of drivers offsetting
some base MAC addr by an id. So I decided to add a helper
for it. The helper takes care of wrapping which is probably
not 100% necessary but seems like a good idea. And it saves
driver side LoC (the diffstat is actually negative if we
compare against the changes I'd have to make if I was to
convert all these drivers to not operate directly on
netdev->dev_addr).
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 867a9284 07a7ec9b
......@@ -1768,11 +1768,8 @@ static int fec_get_mac(struct net_device *ndev)
return 0;
}
eth_hw_addr_set(ndev, iap);
/* Adjust MAC if using macaddr */
if (iap == macaddr)
ndev->dev_addr[ETH_ALEN-1] = macaddr[ETH_ALEN-1] + fep->dev_id;
eth_hw_addr_gen(ndev, iap, iap == macaddr ? fep->dev_id : 0);
return 0;
}
......
......@@ -338,11 +338,14 @@ static int prestera_port_create(struct prestera_switch *sw, u32 id)
goto err_port_init;
}
eth_hw_addr_gen(dev, sw->base_mac, port->fp_id);
/* firmware requires that port's MAC address consist of the first
* 5 bytes of the base MAC address
*/
memcpy(dev->dev_addr, sw->base_mac, dev->addr_len - 1);
dev->dev_addr[dev->addr_len - 1] = port->fp_id;
if (memcmp(dev->dev_addr, sw->base_mac, ETH_ALEN - 1)) {
dev_warn(prestera_dev(sw), "Port MAC address wraps for port(%u)\n", id);
dev_addr_mod(dev, 0, sw->base_mac, ETH_ALEN - 1);
}
err = prestera_hw_port_mac_set(port, dev->dev_addr);
if (err) {
......
......@@ -200,20 +200,16 @@ static int
mlxsw_m_port_dev_addr_get(struct mlxsw_m_port *mlxsw_m_port)
{
struct mlxsw_m *mlxsw_m = mlxsw_m_port->mlxsw_m;
struct net_device *dev = mlxsw_m_port->dev;
char ppad_pl[MLXSW_REG_PPAD_LEN];
u8 addr[ETH_ALEN];
int err;
mlxsw_reg_ppad_pack(ppad_pl, false, 0);
err = mlxsw_reg_query(mlxsw_m->core, MLXSW_REG(ppad), ppad_pl);
if (err)
return err;
mlxsw_reg_ppad_mac_memcpy_from(ppad_pl, dev->dev_addr);
/* The last byte value in base mac address is guaranteed
* to be such it does not overflow when adding local_port
* value.
*/
dev->dev_addr[ETH_ALEN - 1] += mlxsw_m_port->module + 1;
mlxsw_reg_ppad_mac_memcpy_from(ppad_pl, addr);
eth_hw_addr_gen(mlxsw_m_port->dev, addr, mlxsw_m_port->module + 1);
return 0;
}
......
......@@ -316,11 +316,11 @@ static int mlxsw_sp_port_dev_addr_set(struct mlxsw_sp_port *mlxsw_sp_port,
static int mlxsw_sp_port_dev_addr_init(struct mlxsw_sp_port *mlxsw_sp_port)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
unsigned char *addr = mlxsw_sp_port->dev->dev_addr;
ether_addr_copy(addr, mlxsw_sp->base_mac);
addr[ETH_ALEN - 1] += mlxsw_sp_port->local_port;
return mlxsw_sp_port_dev_addr_set(mlxsw_sp_port, addr);
eth_hw_addr_gen(mlxsw_sp_port->dev, mlxsw_sp->base_mac,
mlxsw_sp_port->local_port);
return mlxsw_sp_port_dev_addr_set(mlxsw_sp_port,
mlxsw_sp_port->dev->dev_addr);
}
static int mlxsw_sp_port_max_mtu_get(struct mlxsw_sp_port *mlxsw_sp_port, int *p_max_mtu)
......
......@@ -200,7 +200,6 @@ struct net_device *sparx5_create_netdev(struct sparx5 *sparx5, u32 portno)
{
struct sparx5_port *spx5_port;
struct net_device *ndev;
u64 val;
ndev = devm_alloc_etherdev(sparx5->dev, sizeof(struct sparx5_port));
if (!ndev)
......@@ -216,8 +215,7 @@ struct net_device *sparx5_create_netdev(struct sparx5 *sparx5, u32 portno)
ndev->netdev_ops = &sparx5_port_netdev_ops;
ndev->ethtool_ops = &sparx5_ethtool_ops;
val = ether_addr_to_u64(sparx5->base_mac) + portno + 1;
u64_to_ether_addr(val, ndev->dev_addr);
eth_hw_addr_gen(ndev, sparx5->base_mac, portno + 1);
return ndev;
}
......
......@@ -1705,8 +1705,7 @@ int ocelot_probe_port(struct ocelot *ocelot, int port, struct regmap *target,
NETIF_F_HW_TC;
dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_TC;
eth_hw_addr_set(dev, ocelot->base_mac);
dev->dev_addr[ETH_ALEN - 1] += port;
eth_hw_addr_gen(dev, ocelot->base_mac, port);
ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr,
ocelot_port->pvid_vlan.vid, ENTRYTYPE_LOCKED);
......
......@@ -551,6 +551,27 @@ static inline unsigned long compare_ether_header(const void *a, const void *b)
#endif
}
/**
* eth_hw_addr_gen - Generate and assign Ethernet address to a port
* @dev: pointer to port's net_device structure
* @base_addr: base Ethernet address
* @id: offset to add to the base address
*
* Generate a MAC address using a base address and an offset and assign it
* to a net_device. Commonly used by switch drivers which need to compute
* addresses for all their ports. addr_assign_type is not changed.
*/
static inline void eth_hw_addr_gen(struct net_device *dev, const u8 *base_addr,
unsigned int id)
{
u64 u = ether_addr_to_u64(base_addr);
u8 addr[ETH_ALEN];
u += id;
u64_to_ether_addr(u, addr);
eth_hw_addr_set(dev, addr);
}
/**
* eth_skb_pad - Pad buffer to mininum number of octets for Ethernet frame
* @skb: Buffer to pad
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment