aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorEugenia Emantayev <eugenia@mellanox.co.il>2011-12-12 23:16:21 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-13 13:56:07 -0500
commitffe455ad04681f3fc48eef595fe526a795f809a3 (patch)
treeba21abb4371d780357dd1a91810dd171ce3b05b2 /drivers/net/ethernet
parent0ec2c0f86d31ab36547307f133b0016006bdc6b5 (diff)
mlx4: Ethernet port management modifications
The physical port is now common to the PF and VFs. The port resources and configuration is managed by the PF, VFs can only influence the MTU of the port, it is set as max among all functions, Each function allocates RX buffers of required size to meet it's MTU enforcement. Port management code was moved to mlx4_core, as the mlx4_en module is virtualization unaware Move handling qp functionality to mlx4_get_eth_qp/mlx4_put_eth_qp including reserve/release range and add/release unicast steering. Let mlx4_register/unregister_mac deal only with MAC (un)registration. Signed-off-by: Eugenia Emantayev <eugenia@mellanox.co.il> Signed-off-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c37
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c32
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_port.c77
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_port.h37
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mcg.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h53
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/port.c606
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c33
8 files changed, 621 insertions, 258 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index 0f2069d98274..8e6e4b20b0e2 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -654,6 +654,15 @@ static struct mlx4_cmd_info cmd_info[] = {
654 .wrapper = mlx4_QUERY_PORT_wrapper 654 .wrapper = mlx4_QUERY_PORT_wrapper
655 }, 655 },
656 { 656 {
657 .opcode = MLX4_CMD_SET_PORT,
658 .has_inbox = true,
659 .has_outbox = false,
660 .out_is_imm = false,
661 .encode_slave_id = false,
662 .verify = NULL,
663 .wrapper = mlx4_SET_PORT_wrapper
664 },
665 {
657 .opcode = MLX4_CMD_MAP_EQ, 666 .opcode = MLX4_CMD_MAP_EQ,
658 .has_inbox = false, 667 .has_inbox = false,
659 .has_outbox = false, 668 .has_outbox = false,
@@ -1005,6 +1014,34 @@ static struct mlx4_cmd_info cmd_info[] = {
1005 .verify = NULL, 1014 .verify = NULL,
1006 .wrapper = mlx4_PROMISC_wrapper 1015 .wrapper = mlx4_PROMISC_wrapper
1007 }, 1016 },
1017 /* Ethernet specific commands */
1018 {
1019 .opcode = MLX4_CMD_SET_VLAN_FLTR,
1020 .has_inbox = true,
1021 .has_outbox = false,
1022 .out_is_imm = false,
1023 .encode_slave_id = false,
1024 .verify = NULL,
1025 .wrapper = mlx4_SET_VLAN_FLTR_wrapper
1026 },
1027 {
1028 .opcode = MLX4_CMD_SET_MCAST_FLTR,
1029 .has_inbox = false,
1030 .has_outbox = false,
1031 .out_is_imm = false,
1032 .encode_slave_id = false,
1033 .verify = NULL,
1034 .wrapper = mlx4_SET_MCAST_FLTR_wrapper
1035 },
1036 {
1037 .opcode = MLX4_CMD_DUMP_ETH_STATS,
1038 .has_inbox = false,
1039 .has_outbox = true,
1040 .out_is_imm = false,
1041 .encode_slave_id = false,
1042 .verify = NULL,
1043 .wrapper = mlx4_DUMP_ETH_STATS_wrapper
1044 },
1008 { 1045 {
1009 .opcode = MLX4_CMD_INFORM_FLR_DONE, 1046 .opcode = MLX4_CMD_INFORM_FLR_DONE,
1010 .has_inbox = false, 1047 .has_inbox = false,
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 2083f3b5d689..1db6fea495bf 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -136,7 +136,7 @@ static void mlx4_en_do_set_mac(struct work_struct *work)
136 if (priv->port_up) { 136 if (priv->port_up) {
137 /* Remove old MAC and insert the new one */ 137 /* Remove old MAC and insert the new one */
138 err = mlx4_replace_mac(mdev->dev, priv->port, 138 err = mlx4_replace_mac(mdev->dev, priv->port,
139 priv->base_qpn, priv->mac, 0); 139 priv->base_qpn, priv->mac);
140 if (err) 140 if (err)
141 en_err(priv, "Failed changing HW MAC address\n"); 141 en_err(priv, "Failed changing HW MAC address\n");
142 } else 142 } else
@@ -207,6 +207,16 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
207 goto out; 207 goto out;
208 } 208 }
209 209
210 if (!netif_carrier_ok(dev)) {
211 if (!mlx4_en_QUERY_PORT(mdev, priv->port)) {
212 if (priv->port_state.link_state) {
213 priv->last_link_state = MLX4_DEV_EVENT_PORT_UP;
214 netif_carrier_on(dev);
215 en_dbg(LINK, priv, "Link Up\n");
216 }
217 }
218 }
219
210 /* 220 /*
211 * Promsicuous mode: disable all filters 221 * Promsicuous mode: disable all filters
212 */ 222 */
@@ -602,12 +612,12 @@ int mlx4_en_start_port(struct net_device *dev)
602 ++rx_index; 612 ++rx_index;
603 } 613 }
604 614
605 /* Set port mac number */ 615 /* Set qp number */
606 en_dbg(DRV, priv, "Setting mac for port %d\n", priv->port); 616 en_dbg(DRV, priv, "Getting qp number for port %d\n", priv->port);
607 err = mlx4_register_mac(mdev->dev, priv->port, 617 err = mlx4_get_eth_qp(mdev->dev, priv->port,
608 priv->mac, &priv->base_qpn, 0); 618 priv->mac, &priv->base_qpn);
609 if (err) { 619 if (err) {
610 en_err(priv, "Failed setting port mac\n"); 620 en_err(priv, "Failed getting eth qp\n");
611 goto cq_err; 621 goto cq_err;
612 } 622 }
613 mdev->mac_removed[priv->port] = 0; 623 mdev->mac_removed[priv->port] = 0;
@@ -702,7 +712,7 @@ tx_err:
702 712
703 mlx4_en_release_rss_steer(priv); 713 mlx4_en_release_rss_steer(priv);
704mac_err: 714mac_err:
705 mlx4_unregister_mac(mdev->dev, priv->port, priv->base_qpn); 715 mlx4_put_eth_qp(mdev->dev, priv->port, priv->mac, priv->base_qpn);
706cq_err: 716cq_err:
707 while (rx_index--) 717 while (rx_index--)
708 mlx4_en_deactivate_cq(priv, &priv->rx_cq[rx_index]); 718 mlx4_en_deactivate_cq(priv, &priv->rx_cq[rx_index]);
@@ -748,10 +758,6 @@ void mlx4_en_stop_port(struct net_device *dev)
748 /* Flush multicast filter */ 758 /* Flush multicast filter */
749 mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 1, MLX4_MCAST_CONFIG); 759 mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 1, MLX4_MCAST_CONFIG);
750 760
751 /* Unregister Mac address for the port */
752 mlx4_unregister_mac(mdev->dev, priv->port, priv->base_qpn);
753 mdev->mac_removed[priv->port] = 1;
754
755 /* Free TX Rings */ 761 /* Free TX Rings */
756 for (i = 0; i < priv->tx_ring_num; i++) { 762 for (i = 0; i < priv->tx_ring_num; i++) {
757 mlx4_en_deactivate_tx_ring(priv, &priv->tx_ring[i]); 763 mlx4_en_deactivate_tx_ring(priv, &priv->tx_ring[i]);
@@ -765,6 +771,10 @@ void mlx4_en_stop_port(struct net_device *dev)
765 /* Free RSS qps */ 771 /* Free RSS qps */
766 mlx4_en_release_rss_steer(priv); 772 mlx4_en_release_rss_steer(priv);
767 773
774 /* Unregister Mac address for the port */
775 mlx4_put_eth_qp(mdev->dev, priv->port, priv->mac, priv->base_qpn);
776 mdev->mac_removed[priv->port] = 1;
777
768 /* Free RX Rings */ 778 /* Free RX Rings */
769 for (i = 0; i < priv->rx_ring_num; i++) { 779 for (i = 0; i < priv->rx_ring_num; i++) {
770 mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]); 780 mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.c b/drivers/net/ethernet/mellanox/mlx4/en_port.c
index ae120effb8a5..331791467a22 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_port.c
@@ -41,14 +41,6 @@
41#include "mlx4_en.h" 41#include "mlx4_en.h"
42 42
43 43
44int mlx4_SET_MCAST_FLTR(struct mlx4_dev *dev, u8 port,
45 u64 mac, u64 clear, u8 mode)
46{
47 return mlx4_cmd(dev, (mac | (clear << 63)), port, mode,
48 MLX4_CMD_SET_MCAST_FLTR, MLX4_CMD_TIME_CLASS_B,
49 MLX4_CMD_WRAPPED);
50}
51
52int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, struct mlx4_en_priv *priv) 44int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, struct mlx4_en_priv *priv)
53{ 45{
54 struct mlx4_cmd_mailbox *mailbox; 46 struct mlx4_cmd_mailbox *mailbox;
@@ -78,75 +70,6 @@ int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, struct mlx4_en_priv *priv)
78 return err; 70 return err;
79} 71}
80 72
81
82int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu,
83 u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx)
84{
85 struct mlx4_cmd_mailbox *mailbox;
86 struct mlx4_set_port_general_context *context;
87 int err;
88 u32 in_mod;
89
90 mailbox = mlx4_alloc_cmd_mailbox(dev);
91 if (IS_ERR(mailbox))
92 return PTR_ERR(mailbox);
93 context = mailbox->buf;
94 memset(context, 0, sizeof *context);
95
96 context->flags = SET_PORT_GEN_ALL_VALID;
97 context->mtu = cpu_to_be16(mtu);
98 context->pptx = (pptx * (!pfctx)) << 7;
99 context->pfctx = pfctx;
100 context->pprx = (pprx * (!pfcrx)) << 7;
101 context->pfcrx = pfcrx;
102
103 in_mod = MLX4_SET_PORT_GENERAL << 8 | port;
104 err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
105 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
106
107 mlx4_free_cmd_mailbox(dev, mailbox);
108 return err;
109}
110
111int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
112 u8 promisc)
113{
114 struct mlx4_cmd_mailbox *mailbox;
115 struct mlx4_set_port_rqp_calc_context *context;
116 int err;
117 u32 in_mod;
118 u32 m_promisc = (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) ?
119 MCAST_DIRECT : MCAST_DEFAULT;
120
121 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER &&
122 dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)
123 return 0;
124
125 mailbox = mlx4_alloc_cmd_mailbox(dev);
126 if (IS_ERR(mailbox))
127 return PTR_ERR(mailbox);
128 context = mailbox->buf;
129 memset(context, 0, sizeof *context);
130
131 context->base_qpn = cpu_to_be32(base_qpn);
132 context->n_mac = dev->caps.log_num_macs;
133 context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_SHIFT |
134 base_qpn);
135 context->mcast = cpu_to_be32(m_promisc << SET_PORT_MC_PROMISC_SHIFT |
136 base_qpn);
137 context->intra_no_vlan = 0;
138 context->no_vlan = MLX4_NO_VLAN_IDX;
139 context->intra_vlan_miss = 0;
140 context->vlan_miss = MLX4_VLAN_MISS_IDX;
141
142 in_mod = MLX4_SET_PORT_RQP_CALC << 8 | port;
143 err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
144 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
145
146 mlx4_free_cmd_mailbox(dev, mailbox);
147 return err;
148}
149
150int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port) 73int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port)
151{ 74{
152 struct mlx4_en_query_port_context *qport_context; 75 struct mlx4_en_query_port_context *qport_context;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.h b/drivers/net/ethernet/mellanox/mlx4/en_port.h
index c1bb834414b5..6934fd7e66ed 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_port.h
+++ b/drivers/net/ethernet/mellanox/mlx4/en_port.h
@@ -39,43 +39,6 @@
39#define SET_PORT_PROMISC_SHIFT 31 39#define SET_PORT_PROMISC_SHIFT 31
40#define SET_PORT_MC_PROMISC_SHIFT 30 40#define SET_PORT_MC_PROMISC_SHIFT 30
41 41
42enum {
43 MCAST_DIRECT_ONLY = 0,
44 MCAST_DIRECT = 1,
45 MCAST_DEFAULT = 2
46};
47
48struct mlx4_set_port_general_context {
49 u8 reserved[3];
50 u8 flags;
51 u16 reserved2;
52 __be16 mtu;
53 u8 pptx;
54 u8 pfctx;
55 u16 reserved3;
56 u8 pprx;
57 u8 pfcrx;
58 u16 reserved4;
59};
60
61struct mlx4_set_port_rqp_calc_context {
62 __be32 base_qpn;
63 u8 rererved;
64 u8 n_mac;
65 u8 n_vlan;
66 u8 n_prio;
67 u8 reserved2[3];
68 u8 mac_miss;
69 u8 intra_no_vlan;
70 u8 no_vlan;
71 u8 intra_vlan_miss;
72 u8 vlan_miss;
73 u8 reserved3[3];
74 u8 no_vlan_prio;
75 __be32 promisc;
76 __be32 mcast;
77};
78
79#define VLAN_FLTR_SIZE 128 42#define VLAN_FLTR_SIZE 128
80struct mlx4_set_vlan_fltr_mbox { 43struct mlx4_set_vlan_fltr_mbox {
81 __be32 entry[VLAN_FLTR_SIZE]; 44 __be32 entry[VLAN_FLTR_SIZE];
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index b36c279bcca0..0785d9b2a265 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -913,7 +913,7 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
913} 913}
914EXPORT_SYMBOL_GPL(mlx4_multicast_detach); 914EXPORT_SYMBOL_GPL(mlx4_multicast_detach);
915 915
916static int mlx4_unicast_attach(struct mlx4_dev *dev, 916int mlx4_unicast_attach(struct mlx4_dev *dev,
917 struct mlx4_qp *qp, u8 gid[16], 917 struct mlx4_qp *qp, u8 gid[16],
918 int block_mcast_loopback, enum mlx4_protocol prot) 918 int block_mcast_loopback, enum mlx4_protocol prot)
919{ 919{
@@ -933,7 +933,7 @@ static int mlx4_unicast_attach(struct mlx4_dev *dev,
933} 933}
934EXPORT_SYMBOL_GPL(mlx4_unicast_attach); 934EXPORT_SYMBOL_GPL(mlx4_unicast_attach);
935 935
936static int mlx4_unicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, 936int mlx4_unicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp,
937 u8 gid[16], enum mlx4_protocol prot) 937 u8 gid[16], enum mlx4_protocol prot)
938{ 938{
939 if (prot == MLX4_PROT_ETH && 939 if (prot == MLX4_PROT_ETH &&
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index a38ffc997367..abf65d8af48d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -419,12 +419,23 @@ struct mlx4_comm {
419 u32 slave_read; 419 u32 slave_read;
420}; 420};
421 421
422enum {
423 MLX4_MCAST_CONFIG = 0,
424 MLX4_MCAST_DISABLE = 1,
425 MLX4_MCAST_ENABLE = 2,
426};
427
422#define VLAN_FLTR_SIZE 128 428#define VLAN_FLTR_SIZE 128
423 429
424struct mlx4_vlan_fltr { 430struct mlx4_vlan_fltr {
425 __be32 entry[VLAN_FLTR_SIZE]; 431 __be32 entry[VLAN_FLTR_SIZE];
426}; 432};
427 433
434struct mlx4_mcast_entry {
435 struct list_head list;
436 u64 addr;
437};
438
428struct mlx4_promisc_qp { 439struct mlx4_promisc_qp {
429 struct list_head list; 440 struct list_head list;
430 u32 qpn; 441 u32 qpn;
@@ -615,6 +626,48 @@ struct mlx4_vlan_table {
615 int max; 626 int max;
616}; 627};
617 628
629#define SET_PORT_GEN_ALL_VALID 0x7
630#define SET_PORT_PROMISC_SHIFT 31
631#define SET_PORT_MC_PROMISC_SHIFT 30
632
633enum {
634 MCAST_DIRECT_ONLY = 0,
635 MCAST_DIRECT = 1,
636 MCAST_DEFAULT = 2
637};
638
639
640struct mlx4_set_port_general_context {
641 u8 reserved[3];
642 u8 flags;
643 u16 reserved2;
644 __be16 mtu;
645 u8 pptx;
646 u8 pfctx;
647 u16 reserved3;
648 u8 pprx;
649 u8 pfcrx;
650 u16 reserved4;
651};
652
653struct mlx4_set_port_rqp_calc_context {
654 __be32 base_qpn;
655 u8 rererved;
656 u8 n_mac;
657 u8 n_vlan;
658 u8 n_prio;
659 u8 reserved2[3];
660 u8 mac_miss;
661 u8 intra_no_vlan;
662 u8 no_vlan;
663 u8 intra_vlan_miss;
664 u8 vlan_miss;
665 u8 reserved3[3];
666 u8 no_vlan_prio;
667 __be32 promisc;
668 __be32 mcast;
669};
670
618struct mlx4_mac_entry { 671struct mlx4_mac_entry {
619 u64 mac; 672 u64 mac;
620}; 673};
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index da9f85c6da7e..00a9547773c1 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -70,41 +70,12 @@ void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table)
70 table->total = 0; 70 table->total = 0;
71} 71}
72 72
73static int mlx4_set_port_mac_table(struct mlx4_dev *dev, u8 port, 73static int mlx4_uc_steer_add(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn)
74 __be64 *entries)
75{
76 struct mlx4_cmd_mailbox *mailbox;
77 u32 in_mod;
78 int err;
79
80 mailbox = mlx4_alloc_cmd_mailbox(dev);
81 if (IS_ERR(mailbox))
82 return PTR_ERR(mailbox);
83
84 memcpy(mailbox->buf, entries, MLX4_MAC_TABLE_SIZE);
85
86 in_mod = MLX4_SET_PORT_MAC_TABLE << 8 | port;
87 err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
88 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
89
90 mlx4_free_cmd_mailbox(dev, mailbox);
91 return err;
92}
93
94static int mlx4_uc_steer_add(struct mlx4_dev *dev, u8 port,
95 u64 mac, int *qpn, u8 reserve)
96{ 74{
97 struct mlx4_qp qp; 75 struct mlx4_qp qp;
98 u8 gid[16] = {0}; 76 u8 gid[16] = {0};
99 int err; 77 int err;
100 78
101 if (reserve) {
102 err = mlx4_qp_reserve_range(dev, 1, 1, qpn);
103 if (err) {
104 mlx4_err(dev, "Failed to reserve qp for mac registration\n");
105 return err;
106 }
107 }
108 qp.qpn = *qpn; 79 qp.qpn = *qpn;
109 80
110 mac &= 0xffffffffffffULL; 81 mac &= 0xffffffffffffULL;
@@ -113,16 +84,15 @@ static int mlx4_uc_steer_add(struct mlx4_dev *dev, u8 port,
113 gid[5] = port; 84 gid[5] = port;
114 gid[7] = MLX4_UC_STEER << 1; 85 gid[7] = MLX4_UC_STEER << 1;
115 86
116 err = mlx4_qp_attach_common(dev, &qp, gid, 0, 87 err = mlx4_unicast_attach(dev, &qp, gid, 0, MLX4_PROT_ETH);
117 MLX4_PROT_ETH, MLX4_UC_STEER); 88 if (err)
118 if (err && reserve) 89 mlx4_warn(dev, "Failed Attaching Unicast\n");
119 mlx4_qp_release_range(dev, *qpn, 1);
120 90
121 return err; 91 return err;
122} 92}
123 93
124static void mlx4_uc_steer_release(struct mlx4_dev *dev, u8 port, 94static void mlx4_uc_steer_release(struct mlx4_dev *dev, u8 port,
125 u64 mac, int qpn, u8 free) 95 u64 mac, int qpn)
126{ 96{
127 struct mlx4_qp qp; 97 struct mlx4_qp qp;
128 u8 gid[16] = {0}; 98 u8 gid[16] = {0};
@@ -134,60 +104,164 @@ static void mlx4_uc_steer_release(struct mlx4_dev *dev, u8 port,
134 gid[5] = port; 104 gid[5] = port;
135 gid[7] = MLX4_UC_STEER << 1; 105 gid[7] = MLX4_UC_STEER << 1;
136 106
137 mlx4_qp_detach_common(dev, &qp, gid, MLX4_PROT_ETH, MLX4_UC_STEER); 107 mlx4_unicast_detach(dev, &qp, gid, MLX4_PROT_ETH);
138 if (free) 108}
139 mlx4_qp_release_range(dev, qpn, 1); 109
110static int validate_index(struct mlx4_dev *dev,
111 struct mlx4_mac_table *table, int index)
112{
113 int err = 0;
114
115 if (index < 0 || index >= table->max || !table->entries[index]) {
116 mlx4_warn(dev, "No valid Mac entry for the given index\n");
117 err = -EINVAL;
118 }
119 return err;
120}
121
122static int find_index(struct mlx4_dev *dev,
123 struct mlx4_mac_table *table, u64 mac)
124{
125 int i;
126
127 for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
128 if ((mac & MLX4_MAC_MASK) ==
129 (MLX4_MAC_MASK & be64_to_cpu(table->entries[i])))
130 return i;
131 }
132 /* Mac not found */
133 return -EINVAL;
140} 134}
141 135
142int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn, u8 wrap) 136int mlx4_get_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn)
143{ 137{
144 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port]; 138 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
145 struct mlx4_mac_table *table = &info->mac_table;
146 struct mlx4_mac_entry *entry; 139 struct mlx4_mac_entry *entry;
147 int i, err = 0; 140 int index = 0;
148 int free = -1; 141 int err = 0;
149 142
150 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) { 143 mlx4_dbg(dev, "Registering MAC: 0x%llx for adding\n",
151 err = mlx4_uc_steer_add(dev, port, mac, qpn, 1); 144 (unsigned long long) mac);
152 if (err) 145 index = mlx4_register_mac(dev, port, mac);
153 return err; 146 if (index < 0) {
147 err = index;
148 mlx4_err(dev, "Failed adding MAC: 0x%llx\n",
149 (unsigned long long) mac);
150 return err;
151 }
154 152
155 entry = kmalloc(sizeof *entry, GFP_KERNEL); 153 if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) {
156 if (!entry) { 154 *qpn = info->base_qpn + index;
157 mlx4_uc_steer_release(dev, port, mac, *qpn, 1); 155 return 0;
158 return -ENOMEM; 156 }
159 } 157
158 err = mlx4_qp_reserve_range(dev, 1, 1, qpn);
159 mlx4_dbg(dev, "Reserved qp %d\n", *qpn);
160 if (err) {
161 mlx4_err(dev, "Failed to reserve qp for mac registration\n");
162 goto qp_err;
163 }
164
165 err = mlx4_uc_steer_add(dev, port, mac, qpn);
166 if (err)
167 goto steer_err;
168
169 entry = kmalloc(sizeof *entry, GFP_KERNEL);
170 if (!entry) {
171 err = -ENOMEM;
172 goto alloc_err;
173 }
174 entry->mac = mac;
175 err = radix_tree_insert(&info->mac_tree, *qpn, entry);
176 if (err)
177 goto insert_err;
178 return 0;
179
180insert_err:
181 kfree(entry);
182
183alloc_err:
184 mlx4_uc_steer_release(dev, port, mac, *qpn);
185
186steer_err:
187 mlx4_qp_release_range(dev, *qpn, 1);
160 188
161 entry->mac = mac; 189qp_err:
162 err = radix_tree_insert(&info->mac_tree, *qpn, entry); 190 mlx4_unregister_mac(dev, port, mac);
163 if (err) { 191 return err;
192}
193EXPORT_SYMBOL_GPL(mlx4_get_eth_qp);
194
195void mlx4_put_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int qpn)
196{
197 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
198 struct mlx4_mac_entry *entry;
199
200 mlx4_dbg(dev, "Registering MAC: 0x%llx for deleting\n",
201 (unsigned long long) mac);
202 mlx4_unregister_mac(dev, port, mac);
203
204 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) {
205 entry = radix_tree_lookup(&info->mac_tree, qpn);
206 if (entry) {
207 mlx4_dbg(dev, "Releasing qp: port %d, mac 0x%llx,"
208 " qpn %d\n", port,
209 (unsigned long long) mac, qpn);
210 mlx4_uc_steer_release(dev, port, entry->mac, qpn);
211 mlx4_qp_release_range(dev, qpn, 1);
212 radix_tree_delete(&info->mac_tree, qpn);
164 kfree(entry); 213 kfree(entry);
165 mlx4_uc_steer_release(dev, port, mac, *qpn, 1);
166 return err;
167 } 214 }
168 } 215 }
216}
217EXPORT_SYMBOL_GPL(mlx4_put_eth_qp);
218
219static int mlx4_set_port_mac_table(struct mlx4_dev *dev, u8 port,
220 __be64 *entries)
221{
222 struct mlx4_cmd_mailbox *mailbox;
223 u32 in_mod;
224 int err;
225
226 mailbox = mlx4_alloc_cmd_mailbox(dev);
227 if (IS_ERR(mailbox))
228 return PTR_ERR(mailbox);
229
230 memcpy(mailbox->buf, entries, MLX4_MAC_TABLE_SIZE);
231
232 in_mod = MLX4_SET_PORT_MAC_TABLE << 8 | port;
169 233
170 mlx4_dbg(dev, "Registering MAC: 0x%llx\n", (unsigned long long) mac); 234 err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
235 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
236
237 mlx4_free_cmd_mailbox(dev, mailbox);
238 return err;
239}
240
241int __mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
242{
243 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
244 struct mlx4_mac_table *table = &info->mac_table;
245 int i, err = 0;
246 int free = -1;
247
248 mlx4_dbg(dev, "Registering MAC: 0x%llx for port %d\n",
249 (unsigned long long) mac, port);
171 250
172 mutex_lock(&table->mutex); 251 mutex_lock(&table->mutex);
173 for (i = 0; i < MLX4_MAX_MAC_NUM - 1; i++) { 252 for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
174 if (free < 0 && !table->refs[i]) { 253 if (free < 0 && !table->entries[i]) {
175 free = i; 254 free = i;
176 continue; 255 continue;
177 } 256 }
178 257
179 if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) { 258 if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) {
180 /* MAC already registered, increase references count */ 259 /* MAC already registered, Must not have duplicates */
181 ++table->refs[i]; 260 err = -EEXIST;
182 goto out; 261 goto out;
183 } 262 }
184 } 263 }
185 264
186 if (free < 0) {
187 err = -ENOMEM;
188 goto out;
189 }
190
191 mlx4_dbg(dev, "Free MAC index is %d\n", free); 265 mlx4_dbg(dev, "Free MAC index is %d\n", free);
192 266
193 if (table->total == table->max) { 267 if (table->total == table->max) {
@@ -197,103 +271,103 @@ int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn, u8 wrap)
197 } 271 }
198 272
199 /* Register new MAC */ 273 /* Register new MAC */
200 table->refs[free] = 1;
201 table->entries[free] = cpu_to_be64(mac | MLX4_MAC_VALID); 274 table->entries[free] = cpu_to_be64(mac | MLX4_MAC_VALID);
202 275
203 err = mlx4_set_port_mac_table(dev, port, table->entries); 276 err = mlx4_set_port_mac_table(dev, port, table->entries);
204 if (unlikely(err)) { 277 if (unlikely(err)) {
205 mlx4_err(dev, "Failed adding MAC: 0x%llx\n", (unsigned long long) mac); 278 mlx4_err(dev, "Failed adding MAC: 0x%llx\n",
206 table->refs[free] = 0; 279 (unsigned long long) mac);
207 table->entries[free] = 0; 280 table->entries[free] = 0;
208 goto out; 281 goto out;
209 } 282 }
210 283
211 if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) 284 err = free;
212 *qpn = info->base_qpn + free;
213 ++table->total; 285 ++table->total;
214out: 286out:
215 mutex_unlock(&table->mutex); 287 mutex_unlock(&table->mutex);
216 return err; 288 return err;
217} 289}
218EXPORT_SYMBOL_GPL(mlx4_register_mac); 290EXPORT_SYMBOL_GPL(__mlx4_register_mac);
219 291
220static int validate_index(struct mlx4_dev *dev, 292int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
221 struct mlx4_mac_table *table, int index)
222{ 293{
223 int err = 0; 294 u64 out_param;
295 int err;
224 296
225 if (index < 0 || index >= table->max || !table->entries[index]) { 297 if (mlx4_is_mfunc(dev)) {
226 mlx4_warn(dev, "No valid Mac entry for the given index\n"); 298 set_param_l(&out_param, port);
227 err = -EINVAL; 299 err = mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
228 } 300 RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
229 return err; 301 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
230} 302 if (err)
303 return err;
231 304
232static int find_index(struct mlx4_dev *dev, 305 return get_param_l(&out_param);
233 struct mlx4_mac_table *table, u64 mac)
234{
235 int i;
236 for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
237 if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i])))
238 return i;
239 } 306 }
240 /* Mac not found */ 307 return __mlx4_register_mac(dev, port, mac);
241 return -EINVAL;
242} 308}
309EXPORT_SYMBOL_GPL(mlx4_register_mac);
310
243 311
244void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int qpn) 312void __mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
245{ 313{
246 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port]; 314 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
247 struct mlx4_mac_table *table = &info->mac_table; 315 struct mlx4_mac_table *table = &info->mac_table;
248 int index = qpn - info->base_qpn; 316 int index;
249 struct mlx4_mac_entry *entry;
250 317
251 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) { 318 index = find_index(dev, table, mac);
252 entry = radix_tree_lookup(&info->mac_tree, qpn);
253 if (entry) {
254 mlx4_uc_steer_release(dev, port, entry->mac, qpn, 1);
255 radix_tree_delete(&info->mac_tree, qpn);
256 index = find_index(dev, table, entry->mac);
257 kfree(entry);
258 }
259 }
260 319
261 mutex_lock(&table->mutex); 320 mutex_lock(&table->mutex);
262 321
263 if (validate_index(dev, table, index)) 322 if (validate_index(dev, table, index))
264 goto out; 323 goto out;
265 324
266 /* Check whether this address has reference count */ 325 table->entries[index] = 0;
267 if (!(--table->refs[index])) { 326 mlx4_set_port_mac_table(dev, port, table->entries);
268 table->entries[index] = 0; 327 --table->total;
269 mlx4_set_port_mac_table(dev, port, table->entries);
270 --table->total;
271 }
272out: 328out:
273 mutex_unlock(&table->mutex); 329 mutex_unlock(&table->mutex);
274} 330}
331EXPORT_SYMBOL_GPL(__mlx4_unregister_mac);
332
333void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
334{
335 u64 out_param;
336 int err;
337
338 if (mlx4_is_mfunc(dev)) {
339 set_param_l(&out_param, port);
340 err = mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
341 RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES,
342 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
343 return;
344 }
345 __mlx4_unregister_mac(dev, port, mac);
346 return;
347}
275EXPORT_SYMBOL_GPL(mlx4_unregister_mac); 348EXPORT_SYMBOL_GPL(mlx4_unregister_mac);
276 349
277int mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac, u8 wrap) 350int mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac)
278{ 351{
279 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port]; 352 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
280 struct mlx4_mac_table *table = &info->mac_table; 353 struct mlx4_mac_table *table = &info->mac_table;
281 int index = qpn - info->base_qpn;
282 struct mlx4_mac_entry *entry; 354 struct mlx4_mac_entry *entry;
283 int err; 355 int index = qpn - info->base_qpn;
356 int err = 0;
284 357
285 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) { 358 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) {
286 entry = radix_tree_lookup(&info->mac_tree, qpn); 359 entry = radix_tree_lookup(&info->mac_tree, qpn);
287 if (!entry) 360 if (!entry)
288 return -EINVAL; 361 return -EINVAL;
289 index = find_index(dev, table, entry->mac); 362 mlx4_uc_steer_release(dev, port, entry->mac, qpn);
290 mlx4_uc_steer_release(dev, port, entry->mac, qpn, 0); 363 mlx4_unregister_mac(dev, port, entry->mac);
291 entry->mac = new_mac; 364 entry->mac = new_mac;
292 err = mlx4_uc_steer_add(dev, port, entry->mac, &qpn, 0); 365 mlx4_register_mac(dev, port, new_mac);
293 if (err || index < 0) 366 err = mlx4_uc_steer_add(dev, port, entry->mac, &qpn);
294 return err; 367 return err;
295 } 368 }
296 369
370 /* CX1 doesn't support multi-functions */
297 mutex_lock(&table->mutex); 371 mutex_lock(&table->mutex);
298 372
299 err = validate_index(dev, table, index); 373 err = validate_index(dev, table, index);
@@ -304,7 +378,8 @@ int mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac, u8 wra
304 378
305 err = mlx4_set_port_mac_table(dev, port, table->entries); 379 err = mlx4_set_port_mac_table(dev, port, table->entries);
306 if (unlikely(err)) { 380 if (unlikely(err)) {
307 mlx4_err(dev, "Failed adding MAC: 0x%llx\n", (unsigned long long) new_mac); 381 mlx4_err(dev, "Failed adding MAC: 0x%llx\n",
382 (unsigned long long) new_mac);
308 table->entries[index] = 0; 383 table->entries[index] = 0;
309 } 384 }
310out: 385out:
@@ -312,6 +387,7 @@ out:
312 return err; 387 return err;
313} 388}
314EXPORT_SYMBOL_GPL(mlx4_replace_mac); 389EXPORT_SYMBOL_GPL(mlx4_replace_mac);
390
315static int mlx4_set_port_vlan_table(struct mlx4_dev *dev, u8 port, 391static int mlx4_set_port_vlan_table(struct mlx4_dev *dev, u8 port,
316 __be32 *entries) 392 __be32 *entries)
317{ 393{
@@ -352,7 +428,8 @@ int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx)
352} 428}
353EXPORT_SYMBOL_GPL(mlx4_find_cached_vlan); 429EXPORT_SYMBOL_GPL(mlx4_find_cached_vlan);
354 430
355int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index) 431static int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan,
432 int *index)
356{ 433{
357 struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table; 434 struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
358 int i, err = 0; 435 int i, err = 0;
@@ -387,7 +464,7 @@ int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
387 goto out; 464 goto out;
388 } 465 }
389 466
390 /* Register new MAC */ 467 /* Register new VLAN */
391 table->refs[free] = 1; 468 table->refs[free] = 1;
392 table->entries[free] = cpu_to_be32(vlan | MLX4_VLAN_VALID); 469 table->entries[free] = cpu_to_be32(vlan | MLX4_VLAN_VALID);
393 470
@@ -405,9 +482,27 @@ out:
405 mutex_unlock(&table->mutex); 482 mutex_unlock(&table->mutex);
406 return err; 483 return err;
407} 484}
485
486int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
487{
488 u64 out_param;
489 int err;
490
491 if (mlx4_is_mfunc(dev)) {
492 set_param_l(&out_param, port);
493 err = mlx4_cmd_imm(dev, vlan, &out_param, RES_VLAN,
494 RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
495 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
496 if (!err)
497 *index = get_param_l(&out_param);
498
499 return err;
500 }
501 return __mlx4_register_vlan(dev, port, vlan, index);
502}
408EXPORT_SYMBOL_GPL(mlx4_register_vlan); 503EXPORT_SYMBOL_GPL(mlx4_register_vlan);
409 504
410void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index) 505static void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
411{ 506{
412 struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table; 507 struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
413 508
@@ -432,6 +527,25 @@ void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
432out: 527out:
433 mutex_unlock(&table->mutex); 528 mutex_unlock(&table->mutex);
434} 529}
530
531void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
532{
533 u64 in_param;
534 int err;
535
536 if (mlx4_is_mfunc(dev)) {
537 set_param_l(&in_param, port);
538 err = mlx4_cmd(dev, in_param, RES_VLAN, RES_OP_RESERVE_AND_MAP,
539 MLX4_CMD_FREE_RES, MLX4_CMD_TIME_CLASS_A,
540 MLX4_CMD_WRAPPED);
541 if (!err)
542 mlx4_warn(dev, "Failed freeing vlan at index:%d\n",
543 index);
544
545 return;
546 }
547 __mlx4_unregister_vlan(dev, port, index);
548}
435EXPORT_SYMBOL_GPL(mlx4_unregister_vlan); 549EXPORT_SYMBOL_GPL(mlx4_unregister_vlan);
436 550
437int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps) 551int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps)
@@ -514,6 +628,139 @@ int mlx4_check_ext_port_caps(struct mlx4_dev *dev, u8 port)
514 return err; 628 return err;
515} 629}
516 630
631static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
632 u8 op_mod, struct mlx4_cmd_mailbox *inbox)
633{
634 struct mlx4_priv *priv = mlx4_priv(dev);
635 struct mlx4_port_info *port_info;
636 struct mlx4_mfunc_master_ctx *master = &priv->mfunc.master;
637 struct mlx4_slave_state *slave_st = &master->slave_state[slave];
638 struct mlx4_set_port_rqp_calc_context *qpn_context;
639 struct mlx4_set_port_general_context *gen_context;
640 int reset_qkey_viols;
641 int port;
642 int is_eth;
643 u32 in_modifier;
644 u32 promisc;
645 u16 mtu, prev_mtu;
646 int err;
647 int i;
648 __be32 agg_cap_mask;
649 __be32 slave_cap_mask;
650 __be32 new_cap_mask;
651
652 port = in_mod & 0xff;
653 in_modifier = in_mod >> 8;
654 is_eth = op_mod;
655 port_info = &priv->port[port];
656
657 /* Slaves cannot perform SET_PORT operations except changing MTU */
658 if (is_eth) {
659 if (slave != dev->caps.function &&
660 in_modifier != MLX4_SET_PORT_GENERAL) {
661 mlx4_warn(dev, "denying SET_PORT for slave:%d\n",
662 slave);
663 return -EINVAL;
664 }
665 switch (in_modifier) {
666 case MLX4_SET_PORT_RQP_CALC:
667 qpn_context = inbox->buf;
668 qpn_context->base_qpn =
669 cpu_to_be32(port_info->base_qpn);
670 qpn_context->n_mac = 0x7;
671 promisc = be32_to_cpu(qpn_context->promisc) >>
672 SET_PORT_PROMISC_SHIFT;
673 qpn_context->promisc = cpu_to_be32(
674 promisc << SET_PORT_PROMISC_SHIFT |
675 port_info->base_qpn);
676 promisc = be32_to_cpu(qpn_context->mcast) >>
677 SET_PORT_MC_PROMISC_SHIFT;
678 qpn_context->mcast = cpu_to_be32(
679 promisc << SET_PORT_MC_PROMISC_SHIFT |
680 port_info->base_qpn);
681 break;
682 case MLX4_SET_PORT_GENERAL:
683 gen_context = inbox->buf;
684 /* Mtu is configured as the max MTU among all the
685 * the functions on the port. */
686 mtu = be16_to_cpu(gen_context->mtu);
687 mtu = min_t(int, mtu, dev->caps.eth_mtu_cap[port]);
688 prev_mtu = slave_st->mtu[port];
689 slave_st->mtu[port] = mtu;
690 if (mtu > master->max_mtu[port])
691 master->max_mtu[port] = mtu;
692 if (mtu < prev_mtu && prev_mtu ==
693 master->max_mtu[port]) {
694 slave_st->mtu[port] = mtu;
695 master->max_mtu[port] = mtu;
696 for (i = 0; i < dev->num_slaves; i++) {
697 master->max_mtu[port] =
698 max(master->max_mtu[port],
699 master->slave_state[i].mtu[port]);
700 }
701 }
702
703 gen_context->mtu = cpu_to_be16(master->max_mtu[port]);
704 break;
705 }
706 return mlx4_cmd(dev, inbox->dma, in_mod, op_mod,
707 MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
708 MLX4_CMD_NATIVE);
709 }
710
711 /* For IB, we only consider:
712 * - The capability mask, which is set to the aggregate of all
713 * slave function capabilities
714 * - The QKey violatin counter - reset according to each request.
715 */
716
717 if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
718 reset_qkey_viols = (*(u8 *) inbox->buf) & 0x40;
719 new_cap_mask = ((__be32 *) inbox->buf)[2];
720 } else {
721 reset_qkey_viols = ((u8 *) inbox->buf)[3] & 0x1;
722 new_cap_mask = ((__be32 *) inbox->buf)[1];
723 }
724
725 agg_cap_mask = 0;
726 slave_cap_mask =
727 priv->mfunc.master.slave_state[slave].ib_cap_mask[port];
728 priv->mfunc.master.slave_state[slave].ib_cap_mask[port] = new_cap_mask;
729 for (i = 0; i < dev->num_slaves; i++)
730 agg_cap_mask |=
731 priv->mfunc.master.slave_state[i].ib_cap_mask[port];
732
733 /* only clear mailbox for guests. Master may be setting
734 * MTU or PKEY table size
735 */
736 if (slave != dev->caps.function)
737 memset(inbox->buf, 0, 256);
738 if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
739 *(u8 *) inbox->buf = !!reset_qkey_viols << 6;
740 ((__be32 *) inbox->buf)[2] = agg_cap_mask;
741 } else {
742 ((u8 *) inbox->buf)[3] = !!reset_qkey_viols;
743 ((__be32 *) inbox->buf)[1] = agg_cap_mask;
744 }
745
746 err = mlx4_cmd(dev, inbox->dma, port, is_eth, MLX4_CMD_SET_PORT,
747 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
748 if (err)
749 priv->mfunc.master.slave_state[slave].ib_cap_mask[port] =
750 slave_cap_mask;
751 return err;
752}
753
754int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave,
755 struct mlx4_vhcr *vhcr,
756 struct mlx4_cmd_mailbox *inbox,
757 struct mlx4_cmd_mailbox *outbox,
758 struct mlx4_cmd_info *cmd)
759{
760 return mlx4_common_set_port(dev, slave, vhcr->in_modifier,
761 vhcr->op_modifier, inbox);
762}
763
517int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) 764int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port)
518{ 765{
519 struct mlx4_cmd_mailbox *mailbox; 766 struct mlx4_cmd_mailbox *mailbox;
@@ -535,3 +782,122 @@ int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port)
535 mlx4_free_cmd_mailbox(dev, mailbox); 782 mlx4_free_cmd_mailbox(dev, mailbox);
536 return err; 783 return err;
537} 784}
785
786static int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu,
787 u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx)
788{
789 struct mlx4_cmd_mailbox *mailbox;
790 struct mlx4_set_port_general_context *context;
791 int err;
792 u32 in_mod;
793
794 mailbox = mlx4_alloc_cmd_mailbox(dev);
795 if (IS_ERR(mailbox))
796 return PTR_ERR(mailbox);
797 context = mailbox->buf;
798 memset(context, 0, sizeof *context);
799
800 context->flags = SET_PORT_GEN_ALL_VALID;
801 context->mtu = cpu_to_be16(mtu);
802 context->pptx = (pptx * (!pfctx)) << 7;
803 context->pfctx = pfctx;
804 context->pprx = (pprx * (!pfcrx)) << 7;
805 context->pfcrx = pfcrx;
806
807 in_mod = MLX4_SET_PORT_GENERAL << 8 | port;
808 err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
809 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
810
811 mlx4_free_cmd_mailbox(dev, mailbox);
812 return err;
813}
814EXPORT_SYMBOL(mlx4_SET_PORT_general);
815
816static int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
817 u8 promisc)
818{
819 struct mlx4_cmd_mailbox *mailbox;
820 struct mlx4_set_port_rqp_calc_context *context;
821 int err;
822 u32 in_mod;
823 u32 m_promisc = (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) ?
824 MCAST_DIRECT : MCAST_DEFAULT;
825
826 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER &&
827 dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)
828 return 0;
829
830 mailbox = mlx4_alloc_cmd_mailbox(dev);
831 if (IS_ERR(mailbox))
832 return PTR_ERR(mailbox);
833 context = mailbox->buf;
834 memset(context, 0, sizeof *context);
835
836 context->base_qpn = cpu_to_be32(base_qpn);
837 context->n_mac = dev->caps.log_num_macs;
838 context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_SHIFT |
839 base_qpn);
840 context->mcast = cpu_to_be32(m_promisc << SET_PORT_MC_PROMISC_SHIFT |
841 base_qpn);
842 context->intra_no_vlan = 0;
843 context->no_vlan = MLX4_NO_VLAN_IDX;
844 context->intra_vlan_miss = 0;
845 context->vlan_miss = MLX4_VLAN_MISS_IDX;
846
847 in_mod = MLX4_SET_PORT_RQP_CALC << 8 | port;
848 err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
849 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
850
851 mlx4_free_cmd_mailbox(dev, mailbox);
852 return err;
853}
854EXPORT_SYMBOL(mlx4_SET_PORT_qpn_calc);
855
856int mlx4_SET_MCAST_FLTR_wrapper(struct mlx4_dev *dev, int slave,
857 struct mlx4_vhcr *vhcr,
858 struct mlx4_cmd_mailbox *inbox,
859 struct mlx4_cmd_mailbox *outbox,
860 struct mlx4_cmd_info *cmd)
861{
862 int err = 0;
863
864 return err;
865}
866
867int mlx4_SET_MCAST_FLTR(struct mlx4_dev *dev, u8 port,
868 u64 mac, u64 clear, u8 mode)
869{
870 return mlx4_cmd(dev, (mac | (clear << 63)), port, mode,
871 MLX4_CMD_SET_MCAST_FLTR, MLX4_CMD_TIME_CLASS_B,
872 MLX4_CMD_WRAPPED);
873}
874EXPORT_SYMBOL(mlx4_SET_MCAST_FLTR);
875
876int mlx4_SET_VLAN_FLTR_wrapper(struct mlx4_dev *dev, int slave,
877 struct mlx4_vhcr *vhcr,
878 struct mlx4_cmd_mailbox *inbox,
879 struct mlx4_cmd_mailbox *outbox,
880 struct mlx4_cmd_info *cmd)
881{
882 int err = 0;
883
884 return err;
885}
886
887int mlx4_common_dump_eth_stats(struct mlx4_dev *dev, int slave,
888 u32 in_mod, struct mlx4_cmd_mailbox *outbox)
889{
890 return mlx4_cmd_box(dev, 0, outbox->dma, in_mod, 0,
891 MLX4_CMD_DUMP_ETH_STATS, MLX4_CMD_TIME_CLASS_B,
892 MLX4_CMD_NATIVE);
893}
894
895int mlx4_DUMP_ETH_STATS_wrapper(struct mlx4_dev *dev, int slave,
896 struct mlx4_vhcr *vhcr,
897 struct mlx4_cmd_mailbox *inbox,
898 struct mlx4_cmd_mailbox *outbox,
899 struct mlx4_cmd_info *cmd)
900{
901 return mlx4_common_dump_eth_stats(dev, slave,
902 vhcr->in_modifier, outbox);
903}
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 59fc35ee66ad..0d99f57f9c8c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -223,17 +223,6 @@ static const char *ResourceType(enum mlx4_resource rt)
223 }; 223 };
224} 224}
225 225
226/* dummy procedures */
227int __mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
228{
229 return 0;
230}
231
232void __mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
233{
234}
235/* end dummies */
236
237int mlx4_init_resource_tracker(struct mlx4_dev *dev) 226int mlx4_init_resource_tracker(struct mlx4_dev *dev)
238{ 227{
239 struct mlx4_priv *priv = mlx4_priv(dev); 228 struct mlx4_priv *priv = mlx4_priv(dev);
@@ -1271,6 +1260,12 @@ static int mac_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1271 return err; 1260 return err;
1272} 1261}
1273 1262
1263static int vlan_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1264 u64 in_param, u64 *out_param)
1265{
1266 return 0;
1267}
1268
1274int mlx4_ALLOC_RES_wrapper(struct mlx4_dev *dev, int slave, 1269int mlx4_ALLOC_RES_wrapper(struct mlx4_dev *dev, int slave,
1275 struct mlx4_vhcr *vhcr, 1270 struct mlx4_vhcr *vhcr,
1276 struct mlx4_cmd_mailbox *inbox, 1271 struct mlx4_cmd_mailbox *inbox,
@@ -1311,6 +1306,11 @@ int mlx4_ALLOC_RES_wrapper(struct mlx4_dev *dev, int slave,
1311 vhcr->in_param, &vhcr->out_param); 1306 vhcr->in_param, &vhcr->out_param);
1312 break; 1307 break;
1313 1308
1309 case RES_VLAN:
1310 err = vlan_alloc_res(dev, slave, vhcr->op_modifier, alop,
1311 vhcr->in_param, &vhcr->out_param);
1312 break;
1313
1314 default: 1314 default:
1315 err = -EINVAL; 1315 err = -EINVAL;
1316 break; 1316 break;
@@ -1487,6 +1487,12 @@ static int mac_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1487 1487
1488} 1488}
1489 1489
1490static int vlan_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1491 u64 in_param, u64 *out_param)
1492{
1493 return 0;
1494}
1495
1490int mlx4_FREE_RES_wrapper(struct mlx4_dev *dev, int slave, 1496int mlx4_FREE_RES_wrapper(struct mlx4_dev *dev, int slave,
1491 struct mlx4_vhcr *vhcr, 1497 struct mlx4_vhcr *vhcr,
1492 struct mlx4_cmd_mailbox *inbox, 1498 struct mlx4_cmd_mailbox *inbox,
@@ -1527,6 +1533,11 @@ int mlx4_FREE_RES_wrapper(struct mlx4_dev *dev, int slave,
1527 vhcr->in_param, &vhcr->out_param); 1533 vhcr->in_param, &vhcr->out_param);
1528 break; 1534 break;
1529 1535
1536 case RES_VLAN:
1537 err = vlan_free_res(dev, slave, vhcr->op_modifier, alop,
1538 vhcr->in_param, &vhcr->out_param);
1539 break;
1540
1530 default: 1541 default:
1531 break; 1542 break;
1532 } 1543 }