Skip to content

Commit 389cc2f

Browse files
committed
Merge branch 'devlink-Support-get-set-mac-address-of-a-port-function'
Parav Pandit says: ==================== devlink: Support get,set mac address of a port function Currently, ip link set dev <pfndev> vf <vf_num> <param> <value> has below few limitations. 1. Command is limited to set VF parameters only. It cannot set the default MAC address for the PCI PF. 2. It can be set only on system where PCI SR-IOV capability exists. In smartnic based system, eswitch of a NIC resides on a different embedded cpu which has the VF and PF representors for the SR-IOV functions of a host system in which this smartnic is plugged-in. 3. It cannot setup the function attributes of sub-function described in detail in comprehensive RFC [1] and [2]. This series covers the first small part to let user query and set MAC address (hardware address) of a PCI PF/VF which is represented by devlink port pcipf, pcivf port flavours respectively. Whenever a devlink port manages a function connected to a devlink port, it allows to query and set its hardware address. Driver implements necessary get/set callback functions if it supports port function for a given port type. Patch summary: Patch-1 Prepares devlink port fill routines for extack Patch-2 and 3 extended devlink interface to get/set port function attributes, mainly hardware address to start with. Patch-2 Extended port dump command to query port function hardware address Patch-3 Introduces a command to set the hardware address of a port function Patch-4 to 9 refactors and implement devlink callbacks in mlx5_core driver. Patch-4 Constify the mac address pointer in set routines Patch-5 Introduces eswich check helper to use in devlink facing callbacks Patch-6 Moves port index, port number conversion routine to eswitch header file Patch-7 Implements port function query devlink callback Patch-8 Refactors mac address setting routine to uniformly use state_lock Patch-9 Implements port function set devlink callback [1] https://lore.kernel.org/netdev/20200519092258.GF4655@nanopsycho/ [2] https://marc.info/?l=linux-netdev&m=158555928517777&w=2 ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 29a720c + 330077d commit 389cc2f

File tree

10 files changed

+343
-69
lines changed

10 files changed

+343
-69
lines changed

drivers/net/ethernet/mellanox/mlx5/core/devlink.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ static const struct devlink_ops mlx5_devlink_ops = {
113113
.eswitch_inline_mode_get = mlx5_devlink_eswitch_inline_mode_get,
114114
.eswitch_encap_mode_set = mlx5_devlink_eswitch_encap_mode_set,
115115
.eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get,
116+
.port_function_hw_addr_get = mlx5_devlink_port_function_hw_addr_get,
117+
.port_function_hw_addr_set = mlx5_devlink_port_function_hw_addr_set,
116118
#endif
117119
.flash_update = mlx5_devlink_flash_update,
118120
.info_get = mlx5_devlink_info_get,

drivers/net/ethernet/mellanox/mlx5/core/en_rep.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,12 +1181,6 @@ is_devlink_port_supported(const struct mlx5_core_dev *dev,
11811181
mlx5_eswitch_is_vf_vport(dev->priv.eswitch, rpriv->rep->vport);
11821182
}
11831183

1184-
static unsigned int
1185-
vport_to_devlink_port_index(const struct mlx5_core_dev *dev, u16 vport_num)
1186-
{
1187-
return (MLX5_CAP_GEN(dev, vhca_id) << 16) | vport_num;
1188-
}
1189-
11901184
static int register_devlink_port(struct mlx5_core_dev *dev,
11911185
struct mlx5e_rep_priv *rpriv)
11921186
{
@@ -1200,7 +1194,7 @@ static int register_devlink_port(struct mlx5_core_dev *dev,
12001194
return 0;
12011195

12021196
mlx5e_rep_get_port_parent_id(rpriv->netdev, &ppid);
1203-
dl_port_index = vport_to_devlink_port_index(dev, rep->vport);
1197+
dl_port_index = mlx5_esw_vport_to_devlink_port_index(dev, rep->vport);
12041198
pfnum = PCI_FUNC(dev->pdev->devfn);
12051199

12061200
if (rep->vport == MLX5_VPORT_UPLINK)

drivers/net/ethernet/mellanox/mlx5/core/eswitch.c

Lines changed: 127 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,29 @@ struct vport_addr {
6363
static void esw_destroy_legacy_fdb_table(struct mlx5_eswitch *esw);
6464
static void esw_cleanup_vepa_rules(struct mlx5_eswitch *esw);
6565

66+
static int mlx5_eswitch_check(const struct mlx5_core_dev *dev)
67+
{
68+
if (MLX5_CAP_GEN(dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
69+
return -EOPNOTSUPP;
70+
71+
if (!MLX5_ESWITCH_MANAGER(dev))
72+
return -EPERM;
73+
74+
return 0;
75+
}
76+
77+
struct mlx5_eswitch *mlx5_devlink_eswitch_get(struct devlink *devlink)
78+
{
79+
struct mlx5_core_dev *dev = devlink_priv(devlink);
80+
int err;
81+
82+
err = mlx5_eswitch_check(dev);
83+
if (err)
84+
return ERR_PTR(err);
85+
86+
return dev->priv.eswitch;
87+
}
88+
6689
struct mlx5_vport *__must_check
6790
mlx5_eswitch_get_vport(struct mlx5_eswitch *esw, u16 vport_num)
6891
{
@@ -1127,7 +1150,7 @@ int mlx5_esw_modify_vport_rate(struct mlx5_eswitch *esw, u16 vport_num,
11271150
MODIFY_SCHEDULING_ELEMENT_IN_MODIFY_BITMASK_MAX_AVERAGE_BW);
11281151
}
11291152

1130-
static void node_guid_gen_from_mac(u64 *node_guid, u8 mac[ETH_ALEN])
1153+
static void node_guid_gen_from_mac(u64 *node_guid, const u8 *mac)
11311154
{
11321155
((u8 *)node_guid)[7] = mac[0];
11331156
((u8 *)node_guid)[6] = mac[1];
@@ -1778,46 +1801,135 @@ void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw)
17781801
}
17791802

17801803
/* Vport Administration */
1781-
int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
1782-
u16 vport, u8 mac[ETH_ALEN])
1804+
static int
1805+
mlx5_esw_set_vport_mac_locked(struct mlx5_eswitch *esw,
1806+
struct mlx5_vport *evport, const u8 *mac)
17831807
{
1784-
struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport);
1808+
u16 vport_num = evport->vport;
17851809
u64 node_guid;
17861810
int err = 0;
17871811

1788-
if (IS_ERR(evport))
1789-
return PTR_ERR(evport);
17901812
if (is_multicast_ether_addr(mac))
17911813
return -EINVAL;
17921814

1793-
mutex_lock(&esw->state_lock);
1794-
17951815
if (evport->info.spoofchk && !is_valid_ether_addr(mac))
17961816
mlx5_core_warn(esw->dev,
17971817
"Set invalid MAC while spoofchk is on, vport(%d)\n",
1798-
vport);
1818+
vport_num);
17991819

1800-
err = mlx5_modify_nic_vport_mac_address(esw->dev, vport, mac);
1820+
err = mlx5_modify_nic_vport_mac_address(esw->dev, vport_num, mac);
18011821
if (err) {
18021822
mlx5_core_warn(esw->dev,
18031823
"Failed to mlx5_modify_nic_vport_mac vport(%d) err=(%d)\n",
1804-
vport, err);
1805-
goto unlock;
1824+
vport_num, err);
1825+
return err;
18061826
}
18071827

18081828
node_guid_gen_from_mac(&node_guid, mac);
1809-
err = mlx5_modify_nic_vport_node_guid(esw->dev, vport, node_guid);
1829+
err = mlx5_modify_nic_vport_node_guid(esw->dev, vport_num, node_guid);
18101830
if (err)
18111831
mlx5_core_warn(esw->dev,
18121832
"Failed to set vport %d node guid, err = %d. RDMA_CM will not function properly for this VF.\n",
1813-
vport, err);
1833+
vport_num, err);
18141834

18151835
ether_addr_copy(evport->info.mac, mac);
18161836
evport->info.node_guid = node_guid;
18171837
if (evport->enabled && esw->mode == MLX5_ESWITCH_LEGACY)
18181838
err = esw_acl_ingress_lgcy_setup(esw, evport);
18191839

1820-
unlock:
1840+
return err;
1841+
}
1842+
1843+
int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
1844+
u16 vport, const u8 *mac)
1845+
{
1846+
struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport);
1847+
int err = 0;
1848+
1849+
if (IS_ERR(evport))
1850+
return PTR_ERR(evport);
1851+
1852+
mutex_lock(&esw->state_lock);
1853+
err = mlx5_esw_set_vport_mac_locked(esw, evport, mac);
1854+
mutex_unlock(&esw->state_lock);
1855+
return err;
1856+
}
1857+
1858+
static bool
1859+
is_port_function_supported(const struct mlx5_eswitch *esw, u16 vport_num)
1860+
{
1861+
return vport_num == MLX5_VPORT_PF ||
1862+
mlx5_eswitch_is_vf_vport(esw, vport_num);
1863+
}
1864+
1865+
int mlx5_devlink_port_function_hw_addr_get(struct devlink *devlink,
1866+
struct devlink_port *port,
1867+
u8 *hw_addr, int *hw_addr_len,
1868+
struct netlink_ext_ack *extack)
1869+
{
1870+
struct mlx5_eswitch *esw;
1871+
struct mlx5_vport *vport;
1872+
int err = -EOPNOTSUPP;
1873+
u16 vport_num;
1874+
1875+
esw = mlx5_devlink_eswitch_get(devlink);
1876+
if (IS_ERR(esw))
1877+
return PTR_ERR(esw);
1878+
1879+
vport_num = mlx5_esw_devlink_port_index_to_vport_num(port->index);
1880+
if (!is_port_function_supported(esw, vport_num))
1881+
return -EOPNOTSUPP;
1882+
1883+
vport = mlx5_eswitch_get_vport(esw, vport_num);
1884+
if (IS_ERR(vport)) {
1885+
NL_SET_ERR_MSG_MOD(extack, "Invalid port");
1886+
return PTR_ERR(vport);
1887+
}
1888+
1889+
mutex_lock(&esw->state_lock);
1890+
if (vport->enabled) {
1891+
ether_addr_copy(hw_addr, vport->info.mac);
1892+
*hw_addr_len = ETH_ALEN;
1893+
err = 0;
1894+
} else {
1895+
NL_SET_ERR_MSG_MOD(extack, "Eswitch vport is disabled");
1896+
}
1897+
mutex_unlock(&esw->state_lock);
1898+
return err;
1899+
}
1900+
1901+
int mlx5_devlink_port_function_hw_addr_set(struct devlink *devlink,
1902+
struct devlink_port *port,
1903+
const u8 *hw_addr, int hw_addr_len,
1904+
struct netlink_ext_ack *extack)
1905+
{
1906+
struct mlx5_eswitch *esw;
1907+
struct mlx5_vport *vport;
1908+
int err = -EOPNOTSUPP;
1909+
u16 vport_num;
1910+
1911+
esw = mlx5_devlink_eswitch_get(devlink);
1912+
if (IS_ERR(esw)) {
1913+
NL_SET_ERR_MSG_MOD(extack, "Eswitch doesn't support set hw_addr");
1914+
return PTR_ERR(esw);
1915+
}
1916+
1917+
vport_num = mlx5_esw_devlink_port_index_to_vport_num(port->index);
1918+
if (!is_port_function_supported(esw, vport_num)) {
1919+
NL_SET_ERR_MSG_MOD(extack, "Port doesn't support set hw_addr");
1920+
return -EINVAL;
1921+
}
1922+
vport = mlx5_eswitch_get_vport(esw, vport_num);
1923+
if (IS_ERR(vport)) {
1924+
NL_SET_ERR_MSG_MOD(extack, "Invalid port");
1925+
return PTR_ERR(vport);
1926+
}
1927+
1928+
mutex_lock(&esw->state_lock);
1929+
if (vport->enabled)
1930+
err = mlx5_esw_set_vport_mac_locked(esw, vport, hw_addr);
1931+
else
1932+
NL_SET_ERR_MSG_MOD(extack, "Eswitch vport is disabled");
18211933
mutex_unlock(&esw->state_lock);
18221934
return err;
18231935
}

drivers/net/ethernet/mellanox/mlx5/core/eswitch.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs);
311311
void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw, bool clear_vf);
312312
void mlx5_eswitch_disable(struct mlx5_eswitch *esw, bool clear_vf);
313313
int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
314-
u16 vport, u8 mac[ETH_ALEN]);
314+
u16 vport, const u8 *mac);
315315
int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
316316
u16 vport, int link_state);
317317
int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
@@ -450,6 +450,15 @@ int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink,
450450
struct netlink_ext_ack *extack);
451451
int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink,
452452
enum devlink_eswitch_encap_mode *encap);
453+
int mlx5_devlink_port_function_hw_addr_get(struct devlink *devlink,
454+
struct devlink_port *port,
455+
u8 *hw_addr, int *hw_addr_len,
456+
struct netlink_ext_ack *extack);
457+
int mlx5_devlink_port_function_hw_addr_set(struct devlink *devlink,
458+
struct devlink_port *port,
459+
const u8 *hw_addr, int hw_addr_len,
460+
struct netlink_ext_ack *extack);
461+
453462
void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type);
454463

455464
int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw,
@@ -565,6 +574,19 @@ static inline u16 mlx5_eswitch_index_to_vport_num(struct mlx5_eswitch *esw,
565574
return index;
566575
}
567576

577+
static inline unsigned int
578+
mlx5_esw_vport_to_devlink_port_index(const struct mlx5_core_dev *dev,
579+
u16 vport_num)
580+
{
581+
return (MLX5_CAP_GEN(dev, vhca_id) << 16) | vport_num;
582+
}
583+
584+
static inline u16
585+
mlx5_esw_devlink_port_index_to_vport_num(unsigned int dl_port_index)
586+
{
587+
return dl_port_index & 0xffff;
588+
}
589+
568590
/* TODO: This mlx5e_tc function shouldn't be called by eswitch */
569591
void mlx5e_tc_clean_fdb_peer_flows(struct mlx5_eswitch *esw);
570592

@@ -634,6 +656,7 @@ void mlx5e_tc_clean_fdb_peer_flows(struct mlx5_eswitch *esw);
634656
for ((vport) = (nvfs); \
635657
(vport) >= (esw)->first_host_vport; (vport)--)
636658

659+
struct mlx5_eswitch *mlx5_devlink_eswitch_get(struct devlink *devlink);
637660
struct mlx5_vport *__must_check
638661
mlx5_eswitch_get_vport(struct mlx5_eswitch *esw, u16 vport_num);
639662

0 commit comments

Comments
 (0)