diff options
author | David S. Miller <davem@davemloft.net> | 2013-04-26 23:29:21 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-26 23:29:21 -0400 |
commit | b38a54eaa0acc5991cbad93bf44b355aa43f6d6f (patch) | |
tree | 79524a1d906c0ab14331dea45e364f600c42b355 | |
parent | 50754d2188b04a679a249fb57751542643a436e0 (diff) | |
parent | 2cccb9e4f3476da916146c2ec571c4f3eff738b1 (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.c | 200 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 78 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4.h | 28 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/port.c | 19 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 44 | ||||
-rw-r--r-- | include/linux/mlx4/cmd.h | 6 | ||||
-rw-r--r-- | include/linux/mlx4/device.h | 4 |
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 | ||
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 | |||
1493 | static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, | 1556 | static 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); | ||
1886 | err_comm_oper: | ||
1887 | kfree(priv->mfunc.master.vf_admin); | ||
1888 | err_comm_admin: | ||
1803 | kfree(priv->mfunc.master.slave_state); | 1889 | kfree(priv->mfunc.master.slave_state); |
1804 | err_comm: | 1890 | err_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 | |||
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); | ||
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 | ||
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 | |||
2026 | static const struct net_device_ops mlx4_netdev_ops = { | 2063 | static 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 | ||
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 | |||
2050 | int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | 2114 | int 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 | ||
2235 | out: | 2305 | out: |
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 | |||
479 | struct mlx4_vport_state { | ||
480 | u64 mac; | ||
481 | u16 default_vlan; | ||
482 | u8 default_qos; | ||
483 | u32 tx_rate; | ||
484 | bool spoofchk; | ||
485 | }; | ||
486 | |||
487 | struct mlx4_vf_admin_state { | ||
488 | struct mlx4_vport_state vport[MLX4_MAX_PORTS + 1]; | ||
489 | }; | ||
490 | |||
491 | struct mlx4_vport_oper_state { | ||
492 | struct mlx4_vport_state state; | ||
493 | int mac_idx; | ||
494 | int vlan_idx; | ||
495 | }; | ||
496 | struct mlx4_vf_oper_state { | ||
497 | struct mlx4_vport_oper_state vport[MLX4_MAX_PORTS + 1]; | ||
498 | }; | ||
499 | |||
476 | struct slave_list { | 500 | struct 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 | ||
504 | struct mlx4_mfunc_master_ctx { | 528 | struct 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 | ||
1132 | void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table); | 1158 | void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table); |
1133 | void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table); | 1159 | void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table); |
1160 | void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index); | ||
1161 | int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index); | ||
1134 | 1162 | ||
1135 | int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port, int pkey_tbl_sz); | 1163 | int 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; |
171 | out: | 172 | out: |
@@ -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 | } |
306 | EXPORT_SYMBOL_GPL(mlx4_find_cached_vlan); | 311 | EXPORT_SYMBOL_GPL(mlx4_find_cached_vlan); |
307 | 312 | ||
308 | static int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, | 313 | int __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 | } |
380 | EXPORT_SYMBOL_GPL(mlx4_register_vlan); | 385 | EXPORT_SYMBOL_GPL(mlx4_register_vlan); |
381 | 386 | ||
382 | static void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index) | 387 | void __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 | ||
356 | static 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 | |||
356 | static int mpt_mask(struct mlx4_dev *dev) | 397 | static 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 | ||
38 | enum { | 39 | enum { |
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); | |||
232 | void mlx4_free_cmd_mailbox(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox); | 233 | void mlx4_free_cmd_mailbox(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox); |
233 | 234 | ||
234 | u32 mlx4_comm_get_version(void); | 235 | u32 mlx4_comm_get_version(void); |
236 | int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac); | ||
237 | int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos); | ||
238 | int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting); | ||
239 | int 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 | ||
161 | enum { | 163 | enum { |