aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-04-26 23:29:21 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-26 23:29:21 -0400
commitb38a54eaa0acc5991cbad93bf44b355aa43f6d6f (patch)
tree79524a1d906c0ab14331dea45e364f600c42b355
parent50754d2188b04a679a249fb57751542643a436e0 (diff)
parent2cccb9e4f3476da916146c2ec571c4f3eff738b1 (diff)
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 37fe0660981d7a "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>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c200
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c78
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c16
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h28
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/port.c19
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c44
-rw-r--r--include/linux/mlx4/cmd.h6
-rw-r--r--include/linux/mlx4/device.h4
8 files changed, 383 insertions, 12 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index 05267d716e86..1df56cc50ee9 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -1490,6 +1490,69 @@ out:
1490 return ret; 1490 return ret;
1491} 1491}
1492 1492
1493static 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
1536static 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
1493static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, 1556static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd,
1494 u16 param, u8 toggle) 1557 u16 param, u8 toggle)
1495{ 1558{
@@ -1510,6 +1573,7 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd,
1510 if (cmd == MLX4_COMM_CMD_RESET) { 1573 if (cmd == MLX4_COMM_CMD_RESET) {
1511 mlx4_warn(dev, "Received reset from slave:%d\n", slave); 1574 mlx4_warn(dev, "Received reset from slave:%d\n", slave);
1512 slave_state[slave].active = false; 1575 slave_state[slave].active = false;
1576 mlx4_master_deactivate_admin_state(priv, slave);
1513 for (i = 0; i < MLX4_EVENT_TYPES_NUM; ++i) { 1577 for (i = 0; i < MLX4_EVENT_TYPES_NUM; ++i) {
1514 slave_state[slave].event_eq[i].eqn = -1; 1578 slave_state[slave].event_eq[i].eqn = -1;
1515 slave_state[slave].event_eq[i].token = 0; 1579 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,
1556 if (slave_state[slave].last_cmd != MLX4_COMM_CMD_VHCR2) 1620 if (slave_state[slave].last_cmd != MLX4_COMM_CMD_VHCR2)
1557 goto reset_slave; 1621 goto reset_slave;
1558 slave_state[slave].vhcr_dma |= param; 1622 slave_state[slave].vhcr_dma |= param;
1623 if (mlx4_master_activate_admin_state(priv, slave))
1624 goto reset_slave;
1559 slave_state[slave].active = true; 1625 slave_state[slave].active = true;
1560 mlx4_dispatch_event(dev, MLX4_DEV_EVENT_SLAVE_INIT, slave); 1626 mlx4_dispatch_event(dev, MLX4_DEV_EVENT_SLAVE_INIT, slave);
1561 break; 1627 break;
@@ -1732,6 +1798,18 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
1732 if (!priv->mfunc.master.slave_state) 1798 if (!priv->mfunc.master.slave_state)
1733 goto err_comm; 1799 goto err_comm;
1734 1800
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
1735 for (i = 0; i < dev->num_slaves; ++i) { 1813 for (i = 0; i < dev->num_slaves; ++i) {
1736 s_state = &priv->mfunc.master.slave_state[i]; 1814 s_state = &priv->mfunc.master.slave_state[i];
1737 s_state->last_cmd = MLX4_COMM_CMD_RESET; 1815 s_state->last_cmd = MLX4_COMM_CMD_RESET;
@@ -1752,6 +1830,10 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
1752 goto err_slaves; 1830 goto err_slaves;
1753 } 1831 }
1754 INIT_LIST_HEAD(&s_state->mcast_filters[port]); 1832 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;
1755 } 1837 }
1756 spin_lock_init(&s_state->lock); 1838 spin_lock_init(&s_state->lock);
1757 } 1839 }
@@ -1800,6 +1882,10 @@ err_slaves:
1800 for (port = 1; port <= MLX4_MAX_PORTS; port++) 1882 for (port = 1; port <= MLX4_MAX_PORTS; port++)
1801 kfree(priv->mfunc.master.slave_state[i].vlan_filter[port]); 1883 kfree(priv->mfunc.master.slave_state[i].vlan_filter[port]);
1802 } 1884 }
1885 kfree(priv->mfunc.master.vf_oper);
1886err_comm_oper:
1887 kfree(priv->mfunc.master.vf_admin);
1888err_comm_admin:
1803 kfree(priv->mfunc.master.slave_state); 1889 kfree(priv->mfunc.master.slave_state);
1804err_comm: 1890err_comm:
1805 iounmap(priv->mfunc.comm); 1891 iounmap(priv->mfunc.comm);
@@ -1874,6 +1960,8 @@ void mlx4_multi_func_cleanup(struct mlx4_dev *dev)
1874 kfree(priv->mfunc.master.slave_state[i].vlan_filter[port]); 1960 kfree(priv->mfunc.master.slave_state[i].vlan_filter[port]);
1875 } 1961 }
1876 kfree(priv->mfunc.master.slave_state); 1962 kfree(priv->mfunc.master.slave_state);
1963 kfree(priv->mfunc.master.vf_admin);
1964 kfree(priv->mfunc.master.vf_oper);
1877 } 1965 }
1878 1966
1879 iounmap(priv->mfunc.comm); 1967 iounmap(priv->mfunc.comm);
@@ -1984,3 +2072,115 @@ u32 mlx4_comm_get_version(void)
1984{ 2072{
1985 return ((u32) CMD_CHAN_IF_REV << 8) | (u32) CMD_CHAN_VER; 2073 return ((u32) CMD_CHAN_IF_REV << 8) | (u32) CMD_CHAN_VER;
1986} 2074}
2075
2076static 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
2086int 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}
2105EXPORT_SYMBOL_GPL(mlx4_set_vf_mac);
2106
2107int 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}
2132EXPORT_SYMBOL_GPL(mlx4_set_vf_vlan);
2133
2134int 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}
2153EXPORT_SYMBOL_GPL(mlx4_set_vf_spoofchk);
2154
2155int 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}
2186EXPORT_SYMBOL_GPL(mlx4_get_vf_config);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index f4f88b846020..a69a908614e6 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1373,7 +1373,8 @@ static void mlx4_en_service_task(struct work_struct *work)
1373 1373
1374 mutex_lock(&mdev->state_lock); 1374 mutex_lock(&mdev->state_lock);
1375 if (mdev->device_up) { 1375 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);
1377 1378
1378 queue_delayed_work(mdev->workqueue, &priv->service_task, 1379 queue_delayed_work(mdev->workqueue, &priv->service_task,
1379 SERVICE_TASK_DELAY); 1380 SERVICE_TASK_DELAY);
@@ -2023,6 +2024,42 @@ static int mlx4_en_set_features(struct net_device *netdev,
2023 2024
2024} 2025}
2025 2026
2027static 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
2039static 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
2047static 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
2055static 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
2026static const struct net_device_ops mlx4_netdev_ops = { 2063static const struct net_device_ops mlx4_netdev_ops = {
2027 .ndo_open = mlx4_en_open, 2064 .ndo_open = mlx4_en_open,
2028 .ndo_stop = mlx4_en_close, 2065 .ndo_stop = mlx4_en_close,
@@ -2047,6 +2084,33 @@ static const struct net_device_ops mlx4_netdev_ops = {
2047#endif 2084#endif
2048}; 2085};
2049 2086
2087static 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
2050int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, 2114int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
2051 struct mlx4_en_port_profile *prof) 2115 struct mlx4_en_port_profile *prof)
2052{ 2116{
@@ -2163,7 +2227,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
2163 /* 2227 /*
2164 * Initialize netdev entry points 2228 * Initialize netdev entry points
2165 */ 2229 */
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;
2167 dev->watchdog_timeo = MLX4_EN_WATCHDOG_TIMEOUT; 2234 dev->watchdog_timeo = MLX4_EN_WATCHDOG_TIMEOUT;
2168 netif_set_real_num_tx_queues(dev, priv->tx_ring_num); 2235 netif_set_real_num_tx_queues(dev, priv->tx_ring_num);
2169 netif_set_real_num_rx_queues(dev, priv->rx_ring_num); 2236 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,
2228 } 2295 }
2229 mlx4_en_set_default_moderation(priv); 2296 mlx4_en_set_default_moderation(priv);
2230 queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY); 2297 queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
2231 queue_delayed_work(mdev->workqueue, &priv->service_task, 2298
2232 SERVICE_TASK_DELAY); 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
2233 return 0; 2303 return 0;
2234 2304
2235out: 2305out:
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 6776c257bd34..b147bdd40768 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -468,6 +468,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
468#define QUERY_DEV_CAP_RSVD_XRC_OFFSET 0x66 468#define QUERY_DEV_CAP_RSVD_XRC_OFFSET 0x66
469#define QUERY_DEV_CAP_MAX_XRC_OFFSET 0x67 469#define QUERY_DEV_CAP_MAX_XRC_OFFSET 0x67
470#define QUERY_DEV_CAP_MAX_COUNTERS_OFFSET 0x68 470#define QUERY_DEV_CAP_MAX_COUNTERS_OFFSET 0x68
471#define QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET 0x70
471#define QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET 0x76 472#define QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET 0x76
472#define QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET 0x77 473#define QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET 0x77
473#define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80 474#define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80
@@ -655,6 +656,12 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
655 MLX4_GET(dev_cap->max_counters, outbox, 656 MLX4_GET(dev_cap->max_counters, outbox,
656 QUERY_DEV_CAP_MAX_COUNTERS_OFFSET); 657 QUERY_DEV_CAP_MAX_COUNTERS_OFFSET);
657 658
659 MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET);
660 if (field32 & (1 << 26))
661 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_VLAN_CONTROL;
662 if (field32 & (1 << 20))
663 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_FSM;
664
658 if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) { 665 if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
659 for (i = 1; i <= dev_cap->num_ports; ++i) { 666 for (i = 1; i <= dev_cap->num_ports; ++i) {
660 MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET); 667 MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET);
@@ -784,6 +791,11 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
784 flags &= ~MLX4_DEV_CAP_FLAG_MEM_WINDOW; 791 flags &= ~MLX4_DEV_CAP_FLAG_MEM_WINDOW;
785 MLX4_PUT(outbox->buf, flags, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); 792 MLX4_PUT(outbox->buf, flags, QUERY_DEV_CAP_EXT_FLAGS_OFFSET);
786 793
794 /* For guests, disable timestamp */
795 MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET);
796 field &= 0x7f;
797 MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET);
798
787 /* For guests, report Blueflame disabled */ 799 /* For guests, report Blueflame disabled */
788 MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_BF_OFFSET); 800 MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_BF_OFFSET);
789 field &= 0x7f; 801 field &= 0x7f;
@@ -811,6 +823,7 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
811 struct mlx4_cmd_mailbox *outbox, 823 struct mlx4_cmd_mailbox *outbox,
812 struct mlx4_cmd_info *cmd) 824 struct mlx4_cmd_info *cmd)
813{ 825{
826 struct mlx4_priv *priv = mlx4_priv(dev);
814 u64 def_mac; 827 u64 def_mac;
815 u8 port_type; 828 u8 port_type;
816 u16 short_field; 829 u16 short_field;
@@ -828,6 +841,9 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
828 /* set slave default_mac address */ 841 /* set slave default_mac address */
829 MLX4_GET(def_mac, outbox->buf, QUERY_PORT_MAC_OFFSET); 842 MLX4_GET(def_mac, outbox->buf, QUERY_PORT_MAC_OFFSET);
830 def_mac += slave << 8; 843 def_mac += slave << 8;
844 /* if config MAC in DB use it */
845 if (priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.mac)
846 def_mac = priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.mac;
831 MLX4_PUT(outbox->buf, def_mac, QUERY_PORT_MAC_OFFSET); 847 MLX4_PUT(outbox->buf, def_mac, QUERY_PORT_MAC_OFFSET);
832 848
833 /* get port type - currently only eth is enabled */ 849 /* get port type - currently only eth is enabled */
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 0567f01938ed..eac3dae10efe 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -473,6 +473,30 @@ struct mlx4_slave_state {
473 enum slave_port_state port_state[MLX4_MAX_PORTS + 1]; 473 enum slave_port_state port_state[MLX4_MAX_PORTS + 1];
474}; 474};
475 475
476#define MLX4_VGT 4095
477#define NO_INDX (-1)
478
479struct mlx4_vport_state {
480 u64 mac;
481 u16 default_vlan;
482 u8 default_qos;
483 u32 tx_rate;
484 bool spoofchk;
485};
486
487struct mlx4_vf_admin_state {
488 struct mlx4_vport_state vport[MLX4_MAX_PORTS + 1];
489};
490
491struct mlx4_vport_oper_state {
492 struct mlx4_vport_state state;
493 int mac_idx;
494 int vlan_idx;
495};
496struct mlx4_vf_oper_state {
497 struct mlx4_vport_oper_state vport[MLX4_MAX_PORTS + 1];
498};
499
476struct slave_list { 500struct slave_list {
477 struct mutex mutex; 501 struct mutex mutex;
478 struct list_head res_list[MLX4_NUM_OF_RESOURCE_TYPE]; 502 struct list_head res_list[MLX4_NUM_OF_RESOURCE_TYPE];
@@ -503,6 +527,8 @@ struct mlx4_master_qp0_state {
503 527
504struct mlx4_mfunc_master_ctx { 528struct mlx4_mfunc_master_ctx {
505 struct mlx4_slave_state *slave_state; 529 struct mlx4_slave_state *slave_state;
530 struct mlx4_vf_admin_state *vf_admin;
531 struct mlx4_vf_oper_state *vf_oper;
506 struct mlx4_master_qp0_state qp0_state[MLX4_MAX_PORTS + 1]; 532 struct mlx4_master_qp0_state qp0_state[MLX4_MAX_PORTS + 1];
507 int init_port_ref[MLX4_MAX_PORTS + 1]; 533 int init_port_ref[MLX4_MAX_PORTS + 1];
508 u16 max_mtu[MLX4_MAX_PORTS + 1]; 534 u16 max_mtu[MLX4_MAX_PORTS + 1];
@@ -1131,6 +1157,8 @@ int mlx4_change_port_types(struct mlx4_dev *dev,
1131 1157
1132void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table); 1158void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table);
1133void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table); 1159void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table);
1160void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index);
1161int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index);
1134 1162
1135int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port, int pkey_tbl_sz); 1163int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port, int pkey_tbl_sz);
1136/* resource tracker functions*/ 1164/* resource tracker functions*/
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index 4b6aad39e72c..946e0af5faef 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -141,8 +141,9 @@ int __mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
141 } 141 }
142 142
143 if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) { 143 if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) {
144 /* MAC already registered, Must not have duplicates */ 144 /* MAC already registered, increment ref count */
145 err = -EEXIST; 145 err = i;
146 ++table->refs[i];
146 goto out; 147 goto out;
147 } 148 }
148 } 149 }
@@ -165,7 +166,7 @@ int __mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
165 table->entries[free] = 0; 166 table->entries[free] = 0;
166 goto out; 167 goto out;
167 } 168 }
168 169 table->refs[free] = 1;
169 err = free; 170 err = free;
170 ++table->total; 171 ++table->total;
171out: 172out:
@@ -206,12 +207,16 @@ void __mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
206 struct mlx4_mac_table *table = &info->mac_table; 207 struct mlx4_mac_table *table = &info->mac_table;
207 int index; 208 int index;
208 209
209 index = find_index(dev, table, mac);
210
211 mutex_lock(&table->mutex); 210 mutex_lock(&table->mutex);
211 index = find_index(dev, table, mac);
212 212
213 if (validate_index(dev, table, index)) 213 if (validate_index(dev, table, index))
214 goto out; 214 goto out;
215 if (--table->refs[index]) {
216 mlx4_dbg(dev, "Have more references for index %d,"
217 "no need to modify mac table\n", index);
218 goto out;
219 }
215 220
216 table->entries[index] = 0; 221 table->entries[index] = 0;
217 mlx4_set_port_mac_table(dev, port, table->entries); 222 mlx4_set_port_mac_table(dev, port, table->entries);
@@ -305,7 +310,7 @@ int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx)
305} 310}
306EXPORT_SYMBOL_GPL(mlx4_find_cached_vlan); 311EXPORT_SYMBOL_GPL(mlx4_find_cached_vlan);
307 312
308static int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, 313int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan,
309 int *index) 314 int *index)
310{ 315{
311 struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table; 316 struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
@@ -379,7 +384,7 @@ int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
379} 384}
380EXPORT_SYMBOL_GPL(mlx4_register_vlan); 385EXPORT_SYMBOL_GPL(mlx4_register_vlan);
381 386
382static void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index) 387void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
383{ 388{
384 struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table; 389 struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
385 390
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index f2d64435d8ef..e12e0d2e0ee0 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -353,6 +353,47 @@ static void update_gid(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *inbox,
353 } 353 }
354} 354}
355 355
356static int update_vport_qp_param(struct mlx4_dev *dev,
357 struct mlx4_cmd_mailbox *inbox,
358 u8 slave)
359{
360 struct mlx4_qp_context *qpc = inbox->buf + 8;
361 struct mlx4_vport_oper_state *vp_oper;
362 struct mlx4_priv *priv;
363 u32 qp_type;
364 int port;
365
366 port = (qpc->pri_path.sched_queue & 0x40) ? 2 : 1;
367 priv = mlx4_priv(dev);
368 vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
369
370 if (MLX4_VGT != vp_oper->state.default_vlan) {
371 qp_type = (be32_to_cpu(qpc->flags) >> 16) & 0xff;
372 if (MLX4_QP_ST_RC == qp_type)
373 return -EINVAL;
374
375 qpc->pri_path.vlan_index = vp_oper->vlan_idx;
376 qpc->pri_path.fl = (1 << 6) | (1 << 2); /* set cv bit and hide_cqe_vlan bit*/
377 qpc->pri_path.feup |= 1 << 3; /* set fvl bit */
378 qpc->pri_path.sched_queue &= 0xC7;
379 qpc->pri_path.sched_queue |= (vp_oper->state.default_qos) << 3;
380 mlx4_dbg(dev, "qp %d port %d Q 0x%x set vlan to %d vidx %d feup %x fl %x\n",
381 be32_to_cpu(qpc->local_qpn) & 0xffffff, port,
382 (int)(qpc->pri_path.sched_queue), vp_oper->state.default_vlan,
383 vp_oper->vlan_idx, (int)(qpc->pri_path.feup),
384 (int)(qpc->pri_path.fl));
385 }
386 if (vp_oper->state.spoofchk) {
387 qpc->pri_path.feup |= 1 << 5; /* set fsm bit */;
388 qpc->pri_path.grh_mylmc = (0x80 & qpc->pri_path.grh_mylmc) + vp_oper->mac_idx;
389 mlx4_dbg(dev, "spoof qp %d port %d feup 0x%x, myLmc 0x%x mindx %d\n",
390 be32_to_cpu(qpc->local_qpn) & 0xffffff, port,
391 (int)qpc->pri_path.feup, (int)qpc->pri_path.grh_mylmc,
392 vp_oper->mac_idx);
393 }
394 return 0;
395}
396
356static int mpt_mask(struct mlx4_dev *dev) 397static int mpt_mask(struct mlx4_dev *dev)
357{ 398{
358 return dev->caps.num_mpts - 1; 399 return dev->caps.num_mpts - 1;
@@ -2798,6 +2839,9 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave,
2798 update_pkey_index(dev, slave, inbox); 2839 update_pkey_index(dev, slave, inbox);
2799 update_gid(dev, inbox, (u8)slave); 2840 update_gid(dev, inbox, (u8)slave);
2800 adjust_proxy_tun_qkey(dev, vhcr, qpc); 2841 adjust_proxy_tun_qkey(dev, vhcr, qpc);
2842 err = update_vport_qp_param(dev, inbox, slave);
2843 if (err)
2844 return err;
2801 2845
2802 return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd); 2846 return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2803} 2847}
diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h
index 260695186256..adf6e0648f20 100644
--- a/include/linux/mlx4/cmd.h
+++ b/include/linux/mlx4/cmd.h
@@ -34,6 +34,7 @@
34#define MLX4_CMD_H 34#define MLX4_CMD_H
35 35
36#include <linux/dma-mapping.h> 36#include <linux/dma-mapping.h>
37#include <linux/if_link.h>
37 38
38enum { 39enum {
39 /* initialization and general commands */ 40 /* initialization and general commands */
@@ -232,6 +233,11 @@ struct mlx4_cmd_mailbox *mlx4_alloc_cmd_mailbox(struct mlx4_dev *dev);
232void mlx4_free_cmd_mailbox(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox); 233void mlx4_free_cmd_mailbox(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox);
233 234
234u32 mlx4_comm_get_version(void); 235u32 mlx4_comm_get_version(void);
236int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac);
237int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos);
238int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting);
239int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_info *ivf);
240
235 241
236#define MLX4_COMM_GET_IF_REV(cmd_chan_ver) (u8)((cmd_chan_ver) >> 8) 242#define MLX4_COMM_GET_IF_REV(cmd_chan_ver) (u8)((cmd_chan_ver) >> 8)
237 243
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 2fbc1464b53b..53acaf64189f 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -155,7 +155,9 @@ enum {
155 MLX4_DEV_CAP_FLAG2_RSS_XOR = 1LL << 2, 155 MLX4_DEV_CAP_FLAG2_RSS_XOR = 1LL << 2,
156 MLX4_DEV_CAP_FLAG2_FS_EN = 1LL << 3, 156 MLX4_DEV_CAP_FLAG2_FS_EN = 1LL << 3,
157 MLX4_DEV_CAP_FLAGS2_REASSIGN_MAC_EN = 1LL << 4, 157 MLX4_DEV_CAP_FLAGS2_REASSIGN_MAC_EN = 1LL << 4,
158 MLX4_DEV_CAP_FLAG2_TS = 1LL << 5 158 MLX4_DEV_CAP_FLAG2_TS = 1LL << 5,
159 MLX4_DEV_CAP_FLAG2_VLAN_CONTROL = 1LL << 6,
160 MLX4_DEV_CAP_FLAG2_FSM = 1LL << 7
159}; 161};
160 162
161enum { 163enum {