aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRony Efraim <ronye@mellanox.com>2013-04-25 01:22:28 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-26 23:29:13 -0400
commit3f7fb021d081c8aaac1d0cf69a288d21625e872e (patch)
tree6a3fd7ec98398d8715f026fecf8413c9124bb21b
parent8f7ba3ca12f6f16526fa4a8aaf2cae91563eee69 (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>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c72
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c9
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/port.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c36
-rw-r--r--include/linux/mlx4/cmd.h2
-rw-r--r--include/linux/mlx4/device.h3
8 files changed, 126 insertions, 7 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
1493static int mlx4_master_activate_admin_state(struct mlx4_priv *priv, int slave) 1493static 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
1521static 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
1503static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, 1537static 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}
2049EXPORT_SYMBOL_GPL(mlx4_set_vf_mac); 2086EXPORT_SYMBOL_GPL(mlx4_set_vf_mac);
2087
2088int 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}
2113EXPORT_SYMBOL_GPL(mlx4_set_vf_vlan);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 8293a92bf151..c1f2c5b34d95 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -2036,6 +2036,14 @@ static int mlx4_en_set_vf_mac(struct net_device *dev, int queue, u8 *mac)
2036 return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac_u64); 2036 return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac_u64);
2037} 2037}
2038 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
2039 2047
2040static const struct net_device_ops mlx4_netdev_ops = { 2048static const struct net_device_ops mlx4_netdev_ops = {
2041 .ndo_open = mlx4_en_open, 2049 .ndo_open = mlx4_en_open,
@@ -2075,6 +2083,7 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
2075 .ndo_vlan_rx_add_vid = mlx4_en_vlan_rx_add_vid, 2083 .ndo_vlan_rx_add_vid = mlx4_en_vlan_rx_add_vid,
2076 .ndo_vlan_rx_kill_vid = mlx4_en_vlan_rx_kill_vid, 2084 .ndo_vlan_rx_kill_vid = mlx4_en_vlan_rx_kill_vid,
2077 .ndo_set_vf_mac = mlx4_en_set_vf_mac, 2085 .ndo_set_vf_mac = mlx4_en_set_vf_mac,
2086 .ndo_set_vf_vlan = mlx4_en_set_vf_vlan,
2078#ifdef CONFIG_NET_POLL_CONTROLLER 2087#ifdef CONFIG_NET_POLL_CONTROLLER
2079 .ndo_poll_controller = mlx4_en_netpoll, 2088 .ndo_poll_controller = mlx4_en_netpoll,
2080#endif 2089#endif
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 70d44adddc39..d2d30c940790 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,10 @@ 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
658 if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) { 663 if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
659 for (i = 1; i <= dev_cap->num_ports; ++i) { 664 for (i = 1; i <= dev_cap->num_ports; ++i) {
660 MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET); 665 MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 7e1d10059eda..eac3dae10efe 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -1157,6 +1157,8 @@ int mlx4_change_port_types(struct mlx4_dev *dev,
1157 1157
1158void 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);
1159void 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);
1160 1162
1161int 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);
1162/* 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 d3408add8742..946e0af5faef 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -310,7 +310,7 @@ int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx)
310} 310}
311EXPORT_SYMBOL_GPL(mlx4_find_cached_vlan); 311EXPORT_SYMBOL_GPL(mlx4_find_cached_vlan);
312 312
313static int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, 313int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan,
314 int *index) 314 int *index)
315{ 315{
316 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;
@@ -384,7 +384,7 @@ int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
384} 384}
385EXPORT_SYMBOL_GPL(mlx4_register_vlan); 385EXPORT_SYMBOL_GPL(mlx4_register_vlan);
386 386
387static void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index) 387void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
388{ 388{
389 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;
390 390
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index f2d64435d8ef..5083d4babfe3 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -353,6 +353,39 @@ 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 return 0;
387}
388
356static int mpt_mask(struct mlx4_dev *dev) 389static int mpt_mask(struct mlx4_dev *dev)
357{ 390{
358 return dev->caps.num_mpts - 1; 391 return dev->caps.num_mpts - 1;
@@ -2798,6 +2831,9 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave,
2798 update_pkey_index(dev, slave, inbox); 2831 update_pkey_index(dev, slave, inbox);
2799 update_gid(dev, inbox, (u8)slave); 2832 update_gid(dev, inbox, (u8)slave);
2800 adjust_proxy_tun_qkey(dev, vhcr, qpc); 2833 adjust_proxy_tun_qkey(dev, vhcr, qpc);
2834 err = update_vport_qp_param(dev, inbox, slave);
2835 if (err)
2836 return err;
2801 2837
2802 return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd); 2838 return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2803} 2839}
diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h
index f21ddc6203bd..7daead75a6f5 100644
--- a/include/linux/mlx4/cmd.h
+++ b/include/linux/mlx4/cmd.h
@@ -233,6 +233,8 @@ void mlx4_free_cmd_mailbox(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbo
233 233
234u32 mlx4_comm_get_version(void); 234u32 mlx4_comm_get_version(void);
235int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac); 235int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac);
236int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos);
237
236 238
237#define MLX4_COMM_GET_IF_REV(cmd_chan_ver) (u8)((cmd_chan_ver) >> 8) 239#define MLX4_COMM_GET_IF_REV(cmd_chan_ver) (u8)((cmd_chan_ver) >> 8)
238 240
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 2fbc1464b53b..6606d8f5862a 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -155,7 +155,8 @@ 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
159}; 160};
160 161
161enum { 162enum {