34 #include <linux/string.h>
38 #include <linux/export.h>
42 #define MGM_QPN_MASK 0x00FFFFFF
43 #define MGM_BLCK_LB_BIT 30
45 static const u8 zero_gid[16];
57 if (dev->
caps.steering_mode ==
70 static int mlx4_QP_FLOW_STEERING_ATTACH(
struct mlx4_dev *
dev,
78 err = mlx4_cmd_imm(dev, mailbox->
dma, &imm, size, 0,
118 in_mod = (
u32) port << 16 | steer << 1;
130 err = mlx4_cmd_imm(dev, mailbox->
dma, &imm, 0, op_mod,
159 static int new_steering_entry(
struct mlx4_dev *dev,
u8 port,
174 new_entry = kzalloc(
sizeof *new_entry,
GFP_KERNEL);
185 pqp = get_promisc_qp(dev, port, steer, qpn);
204 if (IS_ERR(mailbox)) {
210 err = mlx4_READ_ENTRY(dev, index, mailbox);
220 if (members_count == dev->
caps.num_qp_per_mgm) {
231 err = mlx4_WRITE_ENTRY(dev, index, mailbox);
248 static int existing_steering_entry(
struct mlx4_dev *dev,
u8 port,
250 unsigned int index,
u32 qpn)
259 pqp = get_promisc_qp(dev, port, steer, qpn);
264 if (tmp_entry->
index == index) {
270 mlx4_warn(dev,
"Steering entry at index %x is not registered\n", index);
294 static bool check_duplicate_entry(
struct mlx4_dev *dev,
u8 port,
296 unsigned int index,
u32 qpn)
305 if (!get_promisc_qp(dev, port, steer, qpn))
311 if (tmp_entry->
index == index) {
317 mlx4_warn(dev,
"Steering entry for index %x is not registered\n", index);
321 if (dqp->
qpn == qpn) {
330 static bool can_remove_steering_entry(
struct mlx4_dev *dev,
u8 port,
332 unsigned int index,
u32 tqpn)
350 if (mlx4_READ_ENTRY(dev, index, mailbox))
353 for (i = 0; i < members_count; i++) {
355 if (!get_promisc_qp(dev, port, steer, qpn) && qpn != tqpn) {
364 if (entry->
index == index) {
381 static int add_promisc_qp(
struct mlx4_dev *dev,
u8 port,
401 if (get_promisc_qp(dev, port, steer, qpn)) {
414 if (IS_ERR(mailbox)) {
424 err = mlx4_READ_ENTRY(dev, entry->
index, mailbox);
431 for (i = 0; i < members_count; i++) {
446 if (members_count == dev->
caps.num_qp_per_mgm) {
453 err = mlx4_WRITE_ENTRY(dev, entry->
index, mailbox);
462 memset(mgm, 0,
sizeof *mgm);
465 mgm->qp[members_count++] =
cpu_to_be32(dqp->qpn & MGM_QPN_MASK);
468 err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox);
499 bool back_to_list =
false;
506 pqp = get_promisc_qp(dev, port, steer, qpn);
508 mlx4_warn(dev,
"QP %x is not promiscuous QP\n", qpn);
519 if (IS_ERR(mailbox)) {
525 memset(mgm, 0,
sizeof *mgm);
528 mgm->qp[members_count++] =
cpu_to_be32(dqp->qpn & MGM_QPN_MASK);
529 mgm->members_count =
cpu_to_be32(members_count | MLX4_PROT_ETH << 30);
531 err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox);
539 if (dqp->
qpn == qpn) {
550 err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
554 for (loc = -1, i = 0; i < members_count; ++
i)
559 (MLX4_PROT_ETH << 30));
563 err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox);
597 static int find_entry(
struct mlx4_dev *dev,
u8 port,
600 int *
prev,
int *index)
617 err = mlx4_GID_HASH(dev, mailbox, &hash, op_mod);
623 mlx4_dbg(dev,
"Hash for %pI6 is %04x\n", gid, hash);
629 err = mlx4_READ_ENTRY(dev, *index, mgm_mailbox);
634 if (*index != hash) {
635 mlx4_err(dev,
"Found zero MGID in AMGM.\n");
656 static const u8 __promisc_mode[] = {
688 static const size_t __rule_hw_sz[] = {
702 mlx4_err(dev,
"Invalid network rule id. id = %d\n", spec->
id);
705 memset(rule_hw, 0, __rule_hw_sz[spec->
id]);
707 rule_hw->
size = __rule_hw_sz[spec->
id] >> 2;
717 if (spec->
eth.ether_type_enable) {
718 rule_hw->
eth.ether_type_enable = 1;
719 rule_hw->
eth.ether_type = spec->
eth.ether_type;
721 rule_hw->
eth.vlan_id = spec->
eth.vlan_id;
722 rule_hw->
eth.vlan_id_msk = spec->
eth.vlan_id_msk;
726 rule_hw->
ib.qpn = spec->
ib.r_qpn;
727 rule_hw->
ib.qpn_mask = spec->
ib.qpn_msk;
728 memcpy(&rule_hw->
ib.dst_gid, &spec->
ib.dst_gid, 16);
729 memcpy(&rule_hw->
ib.dst_gid_msk, &spec->
ib.dst_gid_msk, 16);
736 rule_hw->
ipv4.src_ip = spec->
ipv4.src_ip;
737 rule_hw->
ipv4.src_ip_msk = spec->
ipv4.src_ip_msk;
738 rule_hw->
ipv4.dst_ip = spec->
ipv4.dst_ip;
739 rule_hw->
ipv4.dst_ip_msk = spec->
ipv4.dst_ip_msk;
754 return __rule_hw_sz[spec->
id];
757 static void mlx4_err_rule(
struct mlx4_dev *dev,
char *
str,
766 len +=
snprintf(buf + len, BUF_SIZE - len,
767 "port = %d prio = 0x%x qp = 0x%x ",
773 len +=
snprintf(buf + len, BUF_SIZE - len,
774 "dmac = %pM ", &cur->
eth.dst_mac);
775 if (cur->
eth.ether_type)
776 len +=
snprintf(buf + len, BUF_SIZE - len,
779 if (cur->
eth.vlan_id)
780 len +=
snprintf(buf + len, BUF_SIZE - len,
786 if (cur->
ipv4.src_ip)
787 len +=
snprintf(buf + len, BUF_SIZE - len,
790 if (cur->
ipv4.dst_ip)
791 len +=
snprintf(buf + len, BUF_SIZE - len,
799 len +=
snprintf(buf + len, BUF_SIZE - len,
803 len +=
snprintf(buf + len, BUF_SIZE - len,
809 len +=
snprintf(buf + len, BUF_SIZE - len,
810 "dst-gid = %pI6\n", cur->
ib.dst_gid);
811 len +=
snprintf(buf + len, BUF_SIZE - len,
812 "dst-gid-mask = %pI6\n",
813 cur->
ib.dst_gid_msk);
823 len +=
snprintf(buf + len, BUF_SIZE - len,
"\n");
827 mlx4_err(dev,
"Network rule error message was truncated, print buffer is too small.\n");
840 return PTR_ERR(mailbox);
843 trans_rule_ctrl_to_hw(rule, mailbox->
buf);
848 ret = parse_trans_rule(dev, cur, mailbox->
buf + size);
856 ret = mlx4_QP_FLOW_STEERING_ATTACH(dev, mailbox, size >> 2, reg_id);
859 "mcg table is full. Fail to register network rule.\n",
862 mlx4_err_rule(dev,
"Fail to register network rule.\n", rule);
874 err = mlx4_QP_FLOW_STEERING_DETACH(dev, reg_id);
876 mlx4_err(dev,
"Fail to detach network rule. registration id = 0x%llx\n",
899 return PTR_ERR(mailbox);
903 err = find_entry(dev, port, gid, prot,
904 mailbox, &prev, &index);
918 mlx4_err(dev,
"No AMGM entries left\n");
922 index += dev->
caps.num_mgms;
925 memset(mgm, 0,
sizeof *mgm);
930 if (members_count == dev->
caps.num_qp_per_mgm) {
931 mlx4_err(dev,
"MGM at index %x is full.\n", index);
938 mlx4_dbg(dev,
"QP %06x already a member of MGM\n", qp->
qpn);
943 if (block_mcast_loopback)
951 err = mlx4_WRITE_ENTRY(dev, index, mailbox);
958 err = mlx4_READ_ENTRY(dev, prev, mailbox);
964 err = mlx4_WRITE_ENTRY(dev, prev, mailbox);
969 if (prot == MLX4_PROT_ETH) {
972 new_steering_entry(dev, port, steer, index, qp->
qpn);
974 existing_steering_entry(dev, port, steer,
977 if (err && link && index != -1) {
978 if (index < dev->
caps.num_mgms)
980 index, dev->
caps.num_mgms);
983 index - dev->
caps.num_mgms);
1002 bool removed_entry =
false;
1005 if (IS_ERR(mailbox))
1006 return PTR_ERR(mailbox);
1011 err = find_entry(dev, port, gid, prot,
1012 mailbox, &prev, &index);
1017 mlx4_err(dev,
"MGID %pI6 not found\n", gid);
1023 if (prot == MLX4_PROT_ETH &&
1024 check_duplicate_entry(dev, port, steer, index, qp->
qpn))
1033 mlx4_err(dev,
"QP %06x not found in MGM\n", qp->
qpn);
1040 mgm->
qp[
loc] = mgm->
qp[i - 1];
1043 if (prot == MLX4_PROT_ETH)
1044 removed_entry = can_remove_steering_entry(dev, port, steer,
1046 if (i != 1 && (prot != MLX4_PROT_ETH || !removed_entry)) {
1047 err = mlx4_WRITE_ENTRY(dev, index, mailbox);
1058 err = mlx4_READ_ENTRY(dev, amgm_index, mailbox);
1064 err = mlx4_WRITE_ENTRY(dev, index, mailbox);
1069 if (amgm_index < dev->
caps.num_mgms)
1070 mlx4_warn(dev,
"MGM entry %d had AMGM index %d < %d",
1071 index, amgm_index, dev->
caps.num_mgms);
1074 amgm_index - dev->
caps.num_mgms);
1079 err = mlx4_READ_ENTRY(dev, prev, mailbox);
1085 err = mlx4_WRITE_ENTRY(dev, prev, mailbox);
1089 if (index < dev->
caps.num_mgms)
1090 mlx4_warn(dev,
"entry %d had next AMGM index %d < %d",
1091 prev, index, dev->
caps.num_mgms);
1094 index - dev->
caps.num_mgms);
1112 if (!mlx4_is_mfunc(dev))
1116 if (IS_ERR(mailbox))
1117 return PTR_ERR(mailbox);
1121 qpn |= (prot << 28);
1122 if (attach && block_loopback)
1134 u8 port,
int block_mcast_loopback,
1138 switch (dev->
caps.steering_mode) {
1140 if (prot == MLX4_PROT_ETH)
1144 if (prot == MLX4_PROT_ETH)
1147 if (mlx4_is_mfunc(dev))
1148 return mlx4_QP_ATTACH(dev, qp, gid, 1,
1149 block_mcast_loopback, prot);
1151 block_mcast_loopback, prot,
1168 INIT_LIST_HEAD(&rule.
list);
1180 memset(&spec.
ib.dst_gid_msk, 0xff, 16);
1199 switch (dev->
caps.steering_mode) {
1201 if (prot == MLX4_PROT_ETH)
1205 if (prot == MLX4_PROT_ETH)
1208 if (mlx4_is_mfunc(dev))
1209 return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot);
1247 INIT_LIST_HEAD(&rule.
list);
1248 mlx4_err(dev,
"going promisc on %x\n", port);
1287 if (prot == MLX4_PROT_ETH)
1290 if (mlx4_is_mfunc(dev))
1291 return mlx4_QP_ATTACH(dev, qp, gid, 1,
1292 block_mcast_loopback, prot);
1302 if (prot == MLX4_PROT_ETH)
1305 if (mlx4_is_mfunc(dev))
1306 return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot);
1327 return add_promisc_qp(dev, port, steer, qpn);
1329 return remove_promisc_qp(dev, port, steer, qpn);
1332 static int mlx4_PROMISC(
struct mlx4_dev *dev,
u32 qpn,
1342 if (mlx4_is_mfunc(dev))
1351 if (mlx4_is_mfunc(dev))
1360 if (mlx4_is_mfunc(dev))
1369 if (mlx4_is_mfunc(dev))
1382 if (dev->
caps.steering_mode ==
1386 dev->
caps.num_amgms - 1, 0, 0);
1397 if (dev->
caps.steering_mode !=