diff options
author | Rony Efraim <ronye@mellanox.com> | 2013-04-25 01:22:28 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-26 23:29:13 -0400 |
commit | 3f7fb021d081c8aaac1d0cf69a288d21625e872e (patch) | |
tree | 6a3fd7ec98398d8715f026fecf8413c9124bb21b /drivers/net/ethernet/mellanox/mlx4/cmd.c | |
parent | 8f7ba3ca12f6f16526fa4a8aaf2cae91563eee69 (diff) |
net/mlx4: Add set VF default vlan ID and priority support
Add support to ndo_set_vf_vlan in the driver. Once this call is used the vport
is considered to be in VST mode. In this mode, the PPF driver configures
Ethernet QPs created by this VF to use this vlan id and priority. Currently
RoCE isn't supported on that mode.
The special values of VID=4095 or VID=0,UP=0 are considered as VGT.
Signed-off-by: Rony Efraim <ronye@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/cmd.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cmd.c | 72 |
1 files changed, 68 insertions, 4 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index a029124fe2f8..aad6f8dbfb4c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c | |||
@@ -1492,14 +1492,48 @@ out: | |||
1492 | 1492 | ||
1493 | static int mlx4_master_activate_admin_state(struct mlx4_priv *priv, int slave) | 1493 | static int mlx4_master_activate_admin_state(struct mlx4_priv *priv, int slave) |
1494 | { | 1494 | { |
1495 | int port; | 1495 | int port, err; |
1496 | struct mlx4_vport_state *vp_admin; | ||
1497 | struct mlx4_vport_oper_state *vp_oper; | ||
1498 | |||
1496 | for (port = 1; port <= MLX4_MAX_PORTS; port++) { | 1499 | for (port = 1; port <= MLX4_MAX_PORTS; port++) { |
1497 | priv->mfunc.master.vf_oper[slave].vport[port].state = | 1500 | vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; |
1498 | priv->mfunc.master.vf_admin[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 | } | ||
1499 | } | 1517 | } |
1500 | return 0; | 1518 | return 0; |
1501 | } | 1519 | } |
1502 | 1520 | ||
1521 | static void mlx4_master_deactivate_admin_state(struct mlx4_priv *priv, int slave) | ||
1522 | { | ||
1523 | int port; | ||
1524 | struct mlx4_vport_oper_state *vp_oper; | ||
1525 | |||
1526 | for (port = 1; port <= MLX4_MAX_PORTS; port++) { | ||
1527 | vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; | ||
1528 | if (NO_INDX != vp_oper->vlan_idx) { | ||
1529 | __mlx4_unregister_vlan(&priv->dev, | ||
1530 | port, vp_oper->vlan_idx); | ||
1531 | vp_oper->vlan_idx = NO_INDX; | ||
1532 | } | ||
1533 | } | ||
1534 | return; | ||
1535 | } | ||
1536 | |||
1503 | static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, | 1537 | static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, |
1504 | u16 param, u8 toggle) | 1538 | u16 param, u8 toggle) |
1505 | { | 1539 | { |
@@ -1520,6 +1554,7 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, | |||
1520 | if (cmd == MLX4_COMM_CMD_RESET) { | 1554 | if (cmd == MLX4_COMM_CMD_RESET) { |
1521 | mlx4_warn(dev, "Received reset from slave:%d\n", slave); | 1555 | mlx4_warn(dev, "Received reset from slave:%d\n", slave); |
1522 | slave_state[slave].active = false; | 1556 | slave_state[slave].active = false; |
1557 | mlx4_master_deactivate_admin_state(priv, slave); | ||
1523 | for (i = 0; i < MLX4_EVENT_TYPES_NUM; ++i) { | 1558 | for (i = 0; i < MLX4_EVENT_TYPES_NUM; ++i) { |
1524 | slave_state[slave].event_eq[i].eqn = -1; | 1559 | slave_state[slave].event_eq[i].eqn = -1; |
1525 | slave_state[slave].event_eq[i].token = 0; | 1560 | slave_state[slave].event_eq[i].token = 0; |
@@ -1566,7 +1601,8 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, | |||
1566 | if (slave_state[slave].last_cmd != MLX4_COMM_CMD_VHCR2) | 1601 | if (slave_state[slave].last_cmd != MLX4_COMM_CMD_VHCR2) |
1567 | goto reset_slave; | 1602 | goto reset_slave; |
1568 | slave_state[slave].vhcr_dma |= param; | 1603 | slave_state[slave].vhcr_dma |= param; |
1569 | mlx4_master_activate_admin_state(priv, slave); | 1604 | if (mlx4_master_activate_admin_state(priv, slave)) |
1605 | goto reset_slave; | ||
1570 | slave_state[slave].active = true; | 1606 | slave_state[slave].active = true; |
1571 | mlx4_dispatch_event(dev, MLX4_DEV_EVENT_SLAVE_INIT, slave); | 1607 | mlx4_dispatch_event(dev, MLX4_DEV_EVENT_SLAVE_INIT, slave); |
1572 | break; | 1608 | break; |
@@ -1776,6 +1812,7 @@ int mlx4_multi_func_init(struct mlx4_dev *dev) | |||
1776 | } | 1812 | } |
1777 | INIT_LIST_HEAD(&s_state->mcast_filters[port]); | 1813 | INIT_LIST_HEAD(&s_state->mcast_filters[port]); |
1778 | priv->mfunc.master.vf_admin[i].vport[port].default_vlan = MLX4_VGT; | 1814 | priv->mfunc.master.vf_admin[i].vport[port].default_vlan = MLX4_VGT; |
1815 | priv->mfunc.master.vf_oper[i].vport[port].state.default_vlan = MLX4_VGT; | ||
1779 | priv->mfunc.master.vf_oper[i].vport[port].vlan_idx = NO_INDX; | 1816 | priv->mfunc.master.vf_oper[i].vport[port].vlan_idx = NO_INDX; |
1780 | priv->mfunc.master.vf_oper[i].vport[port].mac_idx = NO_INDX; | 1817 | priv->mfunc.master.vf_oper[i].vport[port].mac_idx = NO_INDX; |
1781 | } | 1818 | } |
@@ -2047,3 +2084,30 @@ int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac) | |||
2047 | return 0; | 2084 | return 0; |
2048 | } | 2085 | } |
2049 | EXPORT_SYMBOL_GPL(mlx4_set_vf_mac); | 2086 | EXPORT_SYMBOL_GPL(mlx4_set_vf_mac); |
2087 | |||
2088 | int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos) | ||
2089 | { | ||
2090 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
2091 | struct mlx4_vport_state *s_info; | ||
2092 | int slave; | ||
2093 | |||
2094 | if ((!mlx4_is_master(dev)) || | ||
2095 | !(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_VLAN_CONTROL)) | ||
2096 | return -EPROTONOSUPPORT; | ||
2097 | |||
2098 | if ((vlan > 4095) || (qos > 7)) | ||
2099 | return -EINVAL; | ||
2100 | |||
2101 | slave = mlx4_get_slave_indx(dev, vf); | ||
2102 | if (slave < 0) | ||
2103 | return -EINVAL; | ||
2104 | |||
2105 | s_info = &priv->mfunc.master.vf_admin[slave].vport[port]; | ||
2106 | if ((0 == vlan) && (0 == qos)) | ||
2107 | s_info->default_vlan = MLX4_VGT; | ||
2108 | else | ||
2109 | s_info->default_vlan = vlan; | ||
2110 | s_info->default_qos = qos; | ||
2111 | return 0; | ||
2112 | } | ||
2113 | EXPORT_SYMBOL_GPL(mlx4_set_vf_vlan); | ||