Skip to content

Commit b38a54e

Browse files
committed
Merge branch 'mlx4'
Or Gerlitz says: ==================== This series adds support for the SRIOV ndo_set_vf callbacks to the mlx4 driver. Series done against the net-next tree as of commit 37fe066 "net: fix address check in rtnl_fdb_del" We have successfully tested the series on net-next, except for getting the VF link info issue I have reported earlier today on netdev, we see the problem for both ixgbe and mlx4 VFs. Just to make sure get VF config is working OK with patch #6 - we have run it over 3.8.8 too. We added to the V1 series two patches that disable HW timestamping when running over a VF, as this isn't supported yet. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 50754d2 + 2cccb9e commit b38a54e

File tree

8 files changed

+383
-12
lines changed

8 files changed

+383
-12
lines changed

drivers/net/ethernet/mellanox/mlx4/cmd.c

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,6 +1490,69 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
14901490
return ret;
14911491
}
14921492

1493+
static int mlx4_master_activate_admin_state(struct mlx4_priv *priv, int slave)
1494+
{
1495+
int port, err;
1496+
struct mlx4_vport_state *vp_admin;
1497+
struct mlx4_vport_oper_state *vp_oper;
1498+
1499+
for (port = 1; port <= MLX4_MAX_PORTS; port++) {
1500+
vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
1501+
vp_admin = &priv->mfunc.master.vf_admin[slave].vport[port];
1502+
vp_oper->state = *vp_admin;
1503+
if (MLX4_VGT != vp_admin->default_vlan) {
1504+
err = __mlx4_register_vlan(&priv->dev, port,
1505+
vp_admin->default_vlan, &(vp_oper->vlan_idx));
1506+
if (err) {
1507+
vp_oper->vlan_idx = NO_INDX;
1508+
mlx4_warn((&priv->dev),
1509+
"No vlan resorces slave %d, port %d\n",
1510+
slave, port);
1511+
return err;
1512+
}
1513+
mlx4_dbg((&(priv->dev)), "alloc vlan %d idx %d slave %d port %d\n",
1514+
(int)(vp_oper->state.default_vlan),
1515+
vp_oper->vlan_idx, slave, port);
1516+
}
1517+
if (vp_admin->spoofchk) {
1518+
vp_oper->mac_idx = __mlx4_register_mac(&priv->dev,
1519+
port,
1520+
vp_admin->mac);
1521+
if (0 > vp_oper->mac_idx) {
1522+
err = vp_oper->mac_idx;
1523+
vp_oper->mac_idx = NO_INDX;
1524+
mlx4_warn((&priv->dev),
1525+
"No mac resorces slave %d, port %d\n",
1526+
slave, port);
1527+
return err;
1528+
}
1529+
mlx4_dbg((&(priv->dev)), "alloc mac %llx idx %d slave %d port %d\n",
1530+
vp_oper->state.mac, vp_oper->mac_idx, slave, port);
1531+
}
1532+
}
1533+
return 0;
1534+
}
1535+
1536+
static void mlx4_master_deactivate_admin_state(struct mlx4_priv *priv, int slave)
1537+
{
1538+
int port;
1539+
struct mlx4_vport_oper_state *vp_oper;
1540+
1541+
for (port = 1; port <= MLX4_MAX_PORTS; port++) {
1542+
vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
1543+
if (NO_INDX != vp_oper->vlan_idx) {
1544+
__mlx4_unregister_vlan(&priv->dev,
1545+
port, vp_oper->vlan_idx);
1546+
vp_oper->vlan_idx = NO_INDX;
1547+
}
1548+
if (NO_INDX != vp_oper->mac_idx) {
1549+
__mlx4_unregister_mac(&priv->dev, port, vp_oper->mac_idx);
1550+
vp_oper->mac_idx = NO_INDX;
1551+
}
1552+
}
1553+
return;
1554+
}
1555+
14931556
static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd,
14941557
u16 param, u8 toggle)
14951558
{
@@ -1510,6 +1573,7 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd,
15101573
if (cmd == MLX4_COMM_CMD_RESET) {
15111574
mlx4_warn(dev, "Received reset from slave:%d\n", slave);
15121575
slave_state[slave].active = false;
1576+
mlx4_master_deactivate_admin_state(priv, slave);
15131577
for (i = 0; i < MLX4_EVENT_TYPES_NUM; ++i) {
15141578
slave_state[slave].event_eq[i].eqn = -1;
15151579
slave_state[slave].event_eq[i].token = 0;
@@ -1556,6 +1620,8 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd,
15561620
if (slave_state[slave].last_cmd != MLX4_COMM_CMD_VHCR2)
15571621
goto reset_slave;
15581622
slave_state[slave].vhcr_dma |= param;
1623+
if (mlx4_master_activate_admin_state(priv, slave))
1624+
goto reset_slave;
15591625
slave_state[slave].active = true;
15601626
mlx4_dispatch_event(dev, MLX4_DEV_EVENT_SLAVE_INIT, slave);
15611627
break;
@@ -1732,6 +1798,18 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
17321798
if (!priv->mfunc.master.slave_state)
17331799
goto err_comm;
17341800

1801+
priv->mfunc.master.vf_admin =
1802+
kzalloc(dev->num_slaves *
1803+
sizeof(struct mlx4_vf_admin_state), GFP_KERNEL);
1804+
if (!priv->mfunc.master.vf_admin)
1805+
goto err_comm_admin;
1806+
1807+
priv->mfunc.master.vf_oper =
1808+
kzalloc(dev->num_slaves *
1809+
sizeof(struct mlx4_vf_oper_state), GFP_KERNEL);
1810+
if (!priv->mfunc.master.vf_oper)
1811+
goto err_comm_oper;
1812+
17351813
for (i = 0; i < dev->num_slaves; ++i) {
17361814
s_state = &priv->mfunc.master.slave_state[i];
17371815
s_state->last_cmd = MLX4_COMM_CMD_RESET;
@@ -1752,6 +1830,10 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
17521830
goto err_slaves;
17531831
}
17541832
INIT_LIST_HEAD(&s_state->mcast_filters[port]);
1833+
priv->mfunc.master.vf_admin[i].vport[port].default_vlan = MLX4_VGT;
1834+
priv->mfunc.master.vf_oper[i].vport[port].state.default_vlan = MLX4_VGT;
1835+
priv->mfunc.master.vf_oper[i].vport[port].vlan_idx = NO_INDX;
1836+
priv->mfunc.master.vf_oper[i].vport[port].mac_idx = NO_INDX;
17551837
}
17561838
spin_lock_init(&s_state->lock);
17571839
}
@@ -1800,6 +1882,10 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
18001882
for (port = 1; port <= MLX4_MAX_PORTS; port++)
18011883
kfree(priv->mfunc.master.slave_state[i].vlan_filter[port]);
18021884
}
1885+
kfree(priv->mfunc.master.vf_oper);
1886+
err_comm_oper:
1887+
kfree(priv->mfunc.master.vf_admin);
1888+
err_comm_admin:
18031889
kfree(priv->mfunc.master.slave_state);
18041890
err_comm:
18051891
iounmap(priv->mfunc.comm);
@@ -1874,6 +1960,8 @@ void mlx4_multi_func_cleanup(struct mlx4_dev *dev)
18741960
kfree(priv->mfunc.master.slave_state[i].vlan_filter[port]);
18751961
}
18761962
kfree(priv->mfunc.master.slave_state);
1963+
kfree(priv->mfunc.master.vf_admin);
1964+
kfree(priv->mfunc.master.vf_oper);
18771965
}
18781966

18791967
iounmap(priv->mfunc.comm);
@@ -1984,3 +2072,115 @@ u32 mlx4_comm_get_version(void)
19842072
{
19852073
return ((u32) CMD_CHAN_IF_REV << 8) | (u32) CMD_CHAN_VER;
19862074
}
2075+
2076+
static int mlx4_get_slave_indx(struct mlx4_dev *dev, int vf)
2077+
{
2078+
if ((vf < 0) || (vf >= dev->num_vfs)) {
2079+
mlx4_err(dev, "Bad vf number:%d (number of activated vf: %d)\n", vf, dev->num_vfs);
2080+
return -EINVAL;
2081+
}
2082+
2083+
return vf+1;
2084+
}
2085+
2086+
int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac)
2087+
{
2088+
struct mlx4_priv *priv = mlx4_priv(dev);
2089+
struct mlx4_vport_state *s_info;
2090+
int slave;
2091+
2092+
if (!mlx4_is_master(dev))
2093+
return -EPROTONOSUPPORT;
2094+
2095+
slave = mlx4_get_slave_indx(dev, vf);
2096+
if (slave < 0)
2097+
return -EINVAL;
2098+
2099+
s_info = &priv->mfunc.master.vf_admin[slave].vport[port];
2100+
s_info->mac = mac;
2101+
mlx4_info(dev, "default mac on vf %d port %d to %llX will take afect only after vf restart\n",
2102+
vf, port, s_info->mac);
2103+
return 0;
2104+
}
2105+
EXPORT_SYMBOL_GPL(mlx4_set_vf_mac);
2106+
2107+
int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos)
2108+
{
2109+
struct mlx4_priv *priv = mlx4_priv(dev);
2110+
struct mlx4_vport_state *s_info;
2111+
int slave;
2112+
2113+
if ((!mlx4_is_master(dev)) ||
2114+
!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_VLAN_CONTROL))
2115+
return -EPROTONOSUPPORT;
2116+
2117+
if ((vlan > 4095) || (qos > 7))
2118+
return -EINVAL;
2119+
2120+
slave = mlx4_get_slave_indx(dev, vf);
2121+
if (slave < 0)
2122+
return -EINVAL;
2123+
2124+
s_info = &priv->mfunc.master.vf_admin[slave].vport[port];
2125+
if ((0 == vlan) && (0 == qos))
2126+
s_info->default_vlan = MLX4_VGT;
2127+
else
2128+
s_info->default_vlan = vlan;
2129+
s_info->default_qos = qos;
2130+
return 0;
2131+
}
2132+
EXPORT_SYMBOL_GPL(mlx4_set_vf_vlan);
2133+
2134+
int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting)
2135+
{
2136+
struct mlx4_priv *priv = mlx4_priv(dev);
2137+
struct mlx4_vport_state *s_info;
2138+
int slave;
2139+
2140+
if ((!mlx4_is_master(dev)) ||
2141+
!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FSM))
2142+
return -EPROTONOSUPPORT;
2143+
2144+
slave = mlx4_get_slave_indx(dev, vf);
2145+
if (slave < 0)
2146+
return -EINVAL;
2147+
2148+
s_info = &priv->mfunc.master.vf_admin[slave].vport[port];
2149+
s_info->spoofchk = setting;
2150+
2151+
return 0;
2152+
}
2153+
EXPORT_SYMBOL_GPL(mlx4_set_vf_spoofchk);
2154+
2155+
int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_info *ivf)
2156+
{
2157+
struct mlx4_priv *priv = mlx4_priv(dev);
2158+
struct mlx4_vport_state *s_info;
2159+
int slave;
2160+
2161+
if (!mlx4_is_master(dev))
2162+
return -EPROTONOSUPPORT;
2163+
2164+
slave = mlx4_get_slave_indx(dev, vf);
2165+
if (slave < 0)
2166+
return -EINVAL;
2167+
2168+
s_info = &priv->mfunc.master.vf_admin[slave].vport[port];
2169+
ivf->vf = vf;
2170+
2171+
/* need to convert it to a func */
2172+
ivf->mac[0] = ((s_info->mac >> (5*8)) & 0xff);
2173+
ivf->mac[1] = ((s_info->mac >> (4*8)) & 0xff);
2174+
ivf->mac[2] = ((s_info->mac >> (3*8)) & 0xff);
2175+
ivf->mac[3] = ((s_info->mac >> (2*8)) & 0xff);
2176+
ivf->mac[4] = ((s_info->mac >> (1*8)) & 0xff);
2177+
ivf->mac[5] = ((s_info->mac) & 0xff);
2178+
2179+
ivf->vlan = s_info->default_vlan;
2180+
ivf->qos = s_info->default_qos;
2181+
ivf->tx_rate = s_info->tx_rate;
2182+
ivf->spoofchk = s_info->spoofchk;
2183+
2184+
return 0;
2185+
}
2186+
EXPORT_SYMBOL_GPL(mlx4_get_vf_config);

drivers/net/ethernet/mellanox/mlx4/en_netdev.c

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,7 +1373,8 @@ static void mlx4_en_service_task(struct work_struct *work)
13731373

13741374
mutex_lock(&mdev->state_lock);
13751375
if (mdev->device_up) {
1376-
mlx4_en_ptp_overflow_check(mdev);
1376+
if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
1377+
mlx4_en_ptp_overflow_check(mdev);
13771378

13781379
queue_delayed_work(mdev->workqueue, &priv->service_task,
13791380
SERVICE_TASK_DELAY);
@@ -2023,6 +2024,42 @@ static int mlx4_en_set_features(struct net_device *netdev,
20232024

20242025
}
20252026

2027+
static int mlx4_en_set_vf_mac(struct net_device *dev, int queue, u8 *mac)
2028+
{
2029+
struct mlx4_en_priv *en_priv = netdev_priv(dev);
2030+
struct mlx4_en_dev *mdev = en_priv->mdev;
2031+
u64 mac_u64 = mlx4_en_mac_to_u64(mac);
2032+
2033+
if (!is_valid_ether_addr(mac))
2034+
return -EINVAL;
2035+
2036+
return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac_u64);
2037+
}
2038+
2039+
static int mlx4_en_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos)
2040+
{
2041+
struct mlx4_en_priv *en_priv = netdev_priv(dev);
2042+
struct mlx4_en_dev *mdev = en_priv->mdev;
2043+
2044+
return mlx4_set_vf_vlan(mdev->dev, en_priv->port, vf, vlan, qos);
2045+
}
2046+
2047+
static int mlx4_en_set_vf_spoofchk(struct net_device *dev, int vf, bool setting)
2048+
{
2049+
struct mlx4_en_priv *en_priv = netdev_priv(dev);
2050+
struct mlx4_en_dev *mdev = en_priv->mdev;
2051+
2052+
return mlx4_set_vf_spoofchk(mdev->dev, en_priv->port, vf, setting);
2053+
}
2054+
2055+
static int mlx4_en_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_info *ivf)
2056+
{
2057+
struct mlx4_en_priv *en_priv = netdev_priv(dev);
2058+
struct mlx4_en_dev *mdev = en_priv->mdev;
2059+
2060+
return mlx4_get_vf_config(mdev->dev, en_priv->port, vf, ivf);
2061+
}
2062+
20262063
static const struct net_device_ops mlx4_netdev_ops = {
20272064
.ndo_open = mlx4_en_open,
20282065
.ndo_stop = mlx4_en_close,
@@ -2047,6 +2084,33 @@ static const struct net_device_ops mlx4_netdev_ops = {
20472084
#endif
20482085
};
20492086

2087+
static const struct net_device_ops mlx4_netdev_ops_master = {
2088+
.ndo_open = mlx4_en_open,
2089+
.ndo_stop = mlx4_en_close,
2090+
.ndo_start_xmit = mlx4_en_xmit,
2091+
.ndo_select_queue = mlx4_en_select_queue,
2092+
.ndo_get_stats = mlx4_en_get_stats,
2093+
.ndo_set_rx_mode = mlx4_en_set_rx_mode,
2094+
.ndo_set_mac_address = mlx4_en_set_mac,
2095+
.ndo_validate_addr = eth_validate_addr,
2096+
.ndo_change_mtu = mlx4_en_change_mtu,
2097+
.ndo_tx_timeout = mlx4_en_tx_timeout,
2098+
.ndo_vlan_rx_add_vid = mlx4_en_vlan_rx_add_vid,
2099+
.ndo_vlan_rx_kill_vid = mlx4_en_vlan_rx_kill_vid,
2100+
.ndo_set_vf_mac = mlx4_en_set_vf_mac,
2101+
.ndo_set_vf_vlan = mlx4_en_set_vf_vlan,
2102+
.ndo_set_vf_spoofchk = mlx4_en_set_vf_spoofchk,
2103+
.ndo_get_vf_config = mlx4_en_get_vf_config,
2104+
#ifdef CONFIG_NET_POLL_CONTROLLER
2105+
.ndo_poll_controller = mlx4_en_netpoll,
2106+
#endif
2107+
.ndo_set_features = mlx4_en_set_features,
2108+
.ndo_setup_tc = mlx4_en_setup_tc,
2109+
#ifdef CONFIG_RFS_ACCEL
2110+
.ndo_rx_flow_steer = mlx4_en_filter_rfs,
2111+
#endif
2112+
};
2113+
20502114
int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
20512115
struct mlx4_en_port_profile *prof)
20522116
{
@@ -2163,7 +2227,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
21632227
/*
21642228
* Initialize netdev entry points
21652229
*/
2166-
dev->netdev_ops = &mlx4_netdev_ops;
2230+
if (mlx4_is_master(priv->mdev->dev))
2231+
dev->netdev_ops = &mlx4_netdev_ops_master;
2232+
else
2233+
dev->netdev_ops = &mlx4_netdev_ops;
21672234
dev->watchdog_timeo = MLX4_EN_WATCHDOG_TIMEOUT;
21682235
netif_set_real_num_tx_queues(dev, priv->tx_ring_num);
21692236
netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
@@ -2228,8 +2295,11 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
22282295
}
22292296
mlx4_en_set_default_moderation(priv);
22302297
queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
2231-
queue_delayed_work(mdev->workqueue, &priv->service_task,
2232-
SERVICE_TASK_DELAY);
2298+
2299+
if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
2300+
queue_delayed_work(mdev->workqueue, &priv->service_task,
2301+
SERVICE_TASK_DELAY);
2302+
22332303
return 0;
22342304

22352305
out:

0 commit comments

Comments
 (0)