aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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 }